{"version":3,"sources":["../src/metadataQueryTool.ts"],"sourcesContent":["// The MDX metadata query tool (GROVE_AGENT_SPEC §4) — the agent-facing form of the\n// frontmatter index the platform already builds (`filesMetadata`).\n//\n// An embedded agent answers \"which entries are tagged `security` and updated since\n// June\" in ONE call against an in-sandbox index instead of N `read_entry` round-trips\n// over every file. SDK-LOCAL execution: a projection of the index the app already\n// holds — no host round-trip, no new authority. Results are INDEX ROWS (path +\n// frontmatter subset + the entry's heading list), never file bodies: the cheap call\n// stays cheap, and the read that taints is the explicit one (`read_entry`).\n//\n// SECURITY SHAPE (G-GA-3/G-GA-4/G-GA-11):\n//   • Declarative filters, never expressions — the arguments are DATA, validated at\n//     this boundary. Model-supplied arguments are untrusted input; a predicate DSL\n//     would be an interpreter fed by it (the BUNDLE_EMBEDDING §4.1 rejection,\n//     restated for tools: dotted own-property paths, `__proto__`/`constructor`/\n//     `prototype` segments rejected).\n//   • Execution is pure over the index — it cannot open a file body even by accident.\n//   • Rows are confined to a caller-supplied chroot: the raw index can span more than\n//     the corpus mount, and no row whose body the read tool cannot legally open may\n//     be returned.\n//\n// TAINT (GROVE_AGENT_SPEC §4, \"the enforceable statement\"): taint attaches where the\n// host can see — at the mount reads that BUILD the index — not at this query. An\n// external consumer executing the canonical descriptor must route through a\n// host-visible read of the backing mount, never a copy of this in-sandbox structure.\n\nimport type { FilesMetadata, Metadata } from './sandboxTypes';\nimport { fenceUntrusted } from './fence';\n\n/** The tool's canonical name — `metadata:query`, catalog-shaped. */\nexport const METADATA_QUERY_TOOL_NAME = 'metadata:query';\n\n/** One heading of an indexed entry — the additive index extension (GROVE_AGENT_SPEC\n * §4: `headings: [{id, text, depth}]`, ids from the mdx-plugins heading-anchor canon). */\nexport interface HeadingSummary {\n  id: string;\n  text: string;\n  /** 1–6, the ATX depth. */\n  depth: number;\n}\n\n/** The declarative filter set — the tool's whole argument vocabulary. */\nexport interface MetadataQueryInput {\n  /** Glob over the row's path RELATIVE to the chroot root (`*` within one segment,\n   * `**` across segments). Default: every row. */\n  pathGlob?: string;\n  /** Frontmatter filters, ANDed together. */\n  where?: Array<{\n    /** Dotted own-property path into the row's frontmatter (one nesting level is\n     * representable in frontmatter; deeper paths simply never match). */\n    key: string;\n    op: 'eq' | 'contains' | 'in' | 'exists';\n    /** For `eq`: a scalar. For `in`: an array of scalars. Unused by `exists`. */\n    value?: unknown;\n  }>;\n  /** Dotted frontmatter key to sort by (rows lacking it sort last, stably). */\n  sortBy?: string;\n  /** Default `'asc'`. */\n  order?: 'asc' | 'desc';\n  /** Cap on returned rows (default 100, max 500 — the cheap call stays cheap). */\n  limit?: number;\n  /** Frontmatter fields to include per row (dotted). Default: the whole record. */\n  select?: string[];\n}\n\n/** One query result row: the path (chroot-relative), the selected frontmatter (or\n * all of it), and the entry's headings when the index carries them. */\nexport interface MetadataQueryRow {\n  path: string;\n  meta: Metadata;\n  headings?: HeadingSummary[];\n}\n\n/** Canonical, catalog-shaped descriptor for the tool — the same definition every\n * consumer reads (the app's loop, the MCP bridge, a future external executor), so\n * there is exactly one `metadata:query` in the world. */\nexport const METADATA_QUERY_TOOL_DESCRIPTOR = {\n  name: METADATA_QUERY_TOOL_NAME,\n  description:\n    'Query the MDX corpus index: paths, frontmatter, and headings of entries. ' +\n    'Declarative filters only (no expressions). Returns index rows — never file bodies.',\n  paramsSchema: {\n    type: 'object',\n    additionalProperties: false,\n    properties: {\n      pathGlob: {\n        type: 'string',\n        description: 'Glob over the entry path relative to the corpus root (`*` one segment, `**` any).',\n      },\n      where: {\n        type: 'array',\n        items: {\n          type: 'object',\n          additionalProperties: false,\n          required: ['key', 'op'],\n          properties: {\n            key: { type: 'string', description: 'Dotted frontmatter field path.' },\n            op: { type: 'string', enum: ['eq', 'contains', 'in', 'exists'] },\n            value: {\n              description: 'Scalar for `eq`; array of scalars for `in`; unused by `exists`.',\n              anyOf: [\n                { type: ['string', 'number', 'boolean', 'null'] },\n                { type: 'array', items: { type: ['string', 'number', 'boolean', 'null'] } },\n              ],\n            },\n          },\n        },\n      },\n      sortBy: { type: 'string' },\n      order: { type: 'string', enum: ['asc', 'desc'] },\n      limit: { type: 'integer', minimum: 1, maximum: 500 },\n      select: { type: 'array', items: { type: 'string' } },\n    },\n  },\n} as const;\n\n/** A validation failure — the boundary's only error shape (`invalid-params`, the\n * platform's typed-error vocabulary). */\nexport class MetadataQueryError extends Error {\n  code = 'invalid-params' as const;\n}\n\n// ── boundary validation ────────────────────────────────────────────────────────\n\nconst RESERVED_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);\nconst SCALAR = new Set(['string', 'number', 'boolean']);\n\n/** BUNDLE_EMBEDDING §4.1 hygiene: a dotted path is own-property segments only, and\n * no segment may be `__proto__`/`constructor`/`prototype`. Rejecting the segment\n * names (rather than trusting `hasOwn` alone) is belt-and-braces: it keeps the\n * attack string out of the traversal entirely, the same way the projection parser\n * does. */\nfunction validateDottedKey(key: unknown, what: string): string {\n  if (typeof key !== 'string' || !key) throw new MetadataQueryError(`${what} must be a non-empty string`);\n  if (key.length > 128) throw new MetadataQueryError(`${what} is too long (max 128 chars)`);\n  if (/[/\\\\\\u0000-\\u001f]/.test(key))\n    throw new MetadataQueryError(`${what} must be a dotted path (no path separators)`);\n  for (const seg of key.split('.')) {\n    if (!seg) throw new MetadataQueryError(`${what} has an empty segment: ${JSON.stringify(key)}`);\n    if (RESERVED_SEGMENTS.has(seg)) throw new MetadataQueryError(`${what} contains a reserved segment: ${seg}`);\n  }\n  return key;\n}\n\nfunction validateInput(raw: unknown): MetadataQueryInput {\n  if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n    throw new MetadataQueryError('input must be an object');\n  }\n  const src = raw as Record<string, unknown>;\n  for (const k of Object.keys(src)) {\n    if (!['pathGlob', 'where', 'sortBy', 'order', 'limit', 'select'].includes(k)) {\n      throw new MetadataQueryError(`unknown argument: ${k}`);\n    }\n  }\n  const out: MetadataQueryInput = {};\n  if (src.pathGlob !== undefined) {\n    if (typeof src.pathGlob !== 'string' || !src.pathGlob || src.pathGlob.length > 256) {\n      throw new MetadataQueryError('pathGlob must be a non-empty string (≤256 chars)');\n    }\n    if (/[\\u0000\\n\\r]/.test(src.pathGlob)) throw new MetadataQueryError('pathGlob contains control characters');\n    out.pathGlob = src.pathGlob;\n  }\n  if (src.where !== undefined) {\n    if (!Array.isArray(src.where) || src.where.length > 32) {\n      throw new MetadataQueryError('where must be an array of at most 32 filters');\n    }\n    out.where = src.where.map((w, i) => {\n      if (typeof w !== 'object' || w === null || Array.isArray(w)) {\n        throw new MetadataQueryError(`where[${i}] must be an object`);\n      }\n      const { key, op, value } = w as Record<string, unknown>;\n      validateDottedKey(key, `where[${i}].key`);\n      if (op !== 'eq' && op !== 'contains' && op !== 'in' && op !== 'exists') {\n        throw new MetadataQueryError(`where[${i}].op must be eq|contains|in|exists`);\n      }\n      if (value !== undefined) {\n        if (typeof value === 'function') {\n          throw new MetadataQueryError(`where[${i}].value must be data, not a function`);\n        }\n        if (op === 'in') {\n          if (!Array.isArray(value) || value.length > 100 || value.some((v) => !SCALAR.has(typeof v) && v !== null)) {\n            throw new MetadataQueryError(`where[${i}].value for op=in must be an array of scalars`);\n          }\n        } else if (!SCALAR.has(typeof value) && value !== null) {\n          if (typeof value === 'object')\n            throw new MetadataQueryError(`where[${i}].value for op=${op} must be a scalar`);\n          throw new MetadataQueryError(`where[${i}].value for op=${op} must be a scalar`);\n        }\n      } else if (op !== 'exists') {\n        throw new MetadataQueryError(`where[${i}].value is required for op=${op}`);\n      }\n      return { key: key as string, op, ...(value !== undefined ? { value } : {}) };\n    });\n  }\n  if (src.sortBy !== undefined) out.sortBy = validateDottedKey(src.sortBy, 'sortBy');\n  if (src.order !== undefined) {\n    if (src.order !== 'asc' && src.order !== 'desc') throw new MetadataQueryError('order must be asc|desc');\n    out.order = src.order;\n  }\n  if (src.limit !== undefined) {\n    if (typeof src.limit !== 'number' || !Number.isInteger(src.limit) || src.limit < 1 || src.limit > 500) {\n      throw new MetadataQueryError('limit must be an integer 1–500');\n    }\n    out.limit = src.limit;\n  }\n  if (src.select !== undefined) {\n    if (!Array.isArray(src.select) || src.select.length > 64) {\n      throw new MetadataQueryError('select must be an array of at most 64 field paths');\n    }\n    out.select = src.select.map((k, i) => validateDottedKey(k, `select[${i}]`));\n  }\n  return out;\n}\n\n// ── evaluation (pure) ──────────────────────────────────────────────────────────\n\n/** Resolve a validated dotted key over a frontmatter record by own properties only.\n * `undefined` at any hop means \"absent\" (never a match, never a prototype value). */\nfunction resolveOwn(meta: Metadata, key: string): unknown {\n  let cur: unknown = meta;\n  for (const seg of key.split('.')) {\n    if (typeof cur !== 'object' || cur === null) return undefined;\n    cur = Object.prototype.hasOwnProperty.call(cur, seg) ? (cur as Record<string, unknown>)[seg] : undefined;\n    if (cur === undefined) return undefined;\n  }\n  return cur;\n}\n\n/** `*` within a segment, `**` across segments — the whole vocabulary. Compiled once\n * per query; anchored so `a/b` never matches `x/a/b`. */\nexport function globToRegExp(glob: string): RegExp {\n  const esc = glob.replace(/[.+^${}()|[\\]\\\\?]/g, '\\\\$&');\n  const re = esc\n    .replace(/\\*\\*/g, '\\u0000')\n    .replace(/\\*/g, '[^/]*')\n    .replace(/\\u0000/g, '.*');\n  return new RegExp(`^${re}$`);\n}\n\nfunction matches(row: Metadata, w: { key: string; op: string; value?: unknown }): boolean {\n  const v = resolveOwn(row, w.key);\n  switch (w.op) {\n    case 'exists':\n      return v !== undefined;\n    case 'eq':\n      return v === w.value || (v === null && w.value === null);\n    case 'contains': {\n      const needle = w.value;\n      if (typeof needle !== 'string') return false;\n      if (typeof v === 'string') return v.includes(needle);\n      if (Array.isArray(v)) return v.some((x) => typeof x === 'string' && x.includes(needle));\n      return false;\n    }\n    case 'in': {\n      if (!Array.isArray(w.value)) return false;\n      return w.value.some((needle) => v === needle);\n    }\n    default:\n      return false;\n  }\n}\n\nfunction compare(a: unknown, b: unknown): number {\n  // Scalars only (the boundary guarantees it for `value`; sortBy paths resolve to\n  // whatever frontmatter carries — non-scalars compare as their string form, last).\n  const rank = (v: unknown): number => (v === undefined ? 0 : 1);\n  if (rank(a) !== rank(b)) return rank(a) - rank(b);\n  if (a === undefined) return 0;\n  const as = typeof a === 'number' && typeof b === 'number' ? a : String(a);\n  const bs = typeof a === 'number' && typeof b === 'number' ? b : String(b);\n  return as < bs ? -1 : as > bs ? 1 : 0;\n}\n\n/** Normalize a chroot prefix to `starts-with` form: absolute, trailing slash. */\nfunction normalizeChroot(chroot: string): string {\n  const c = chroot.startsWith('/') ? chroot : `/${chroot}`;\n  return c.endsWith('/') ? c : `${c}/`;\n}\n\n/**\n * Run a metadata query over an index — PURE (G-GA-4: it cannot read a file body).\n *\n * @param index  the in-scope metadata store (`useAllMetadata()` / a scan result),\n *               keyed by absolute path.\n * @param chroot the corpus root rows are confined to (G-GA-11): the SAME root the\n *               app's `read_entry` chroots to, so the two tools describe one corpus.\n * @param raw    the model-supplied arguments, validated here at the boundary.\n * @param filter optional app row-policy (e.g. excluding `_`-prefixed structural\n *               files) applied after the chroot filter.\n * @throws {MetadataQueryError} (`code: 'invalid-params'`) on any non-declarative or\n *         proto-polluting argument.\n */\nexport function runMetadataQuery(\n  index: FilesMetadata,\n  chroot: string,\n  raw: unknown,\n  filter?: (absPath: string) => boolean,\n): MetadataQueryRow[] {\n  const input = validateInput(raw);\n  const root = normalizeChroot(chroot);\n  const globRe = input.pathGlob !== undefined ? globToRegExp(input.pathGlob) : null;\n\n  const rows: Array<{ rel: string; meta: Metadata; headings?: HeadingSummary[] }> = [];\n  for (const [abs, rowMeta] of Object.entries(index)) {\n    if (!abs.startsWith(root)) continue; // G-GA-11 — the chroot is the corpus\n    if (filter && !filter(abs)) continue;\n    const rel = abs.slice(root.length);\n    if (globRe && !globRe.test(rel)) continue;\n    const { headings, ...frontmatter } = rowMeta as Metadata & { headings?: HeadingSummary[] };\n    const meta = frontmatter as Metadata;\n    if (input.where && !input.where.every((w) => matches(meta, w))) continue;\n    rows.push({ rel, meta, headings: Array.isArray(headings) ? headings : undefined });\n  }\n\n  if (input.sortBy) {\n    const dir = input.order === 'desc' ? -1 : 1;\n    rows.sort(\n      (x, y) => dir * compare(resolveOwn(x.meta, input.sortBy as string), resolveOwn(y.meta, input.sortBy as string)),\n    );\n  }\n\n  const limit = input.limit ?? 100;\n  const sliced = rows.slice(0, limit);\n  return sliced.map(({ rel, meta, headings }) => {\n    let out: Metadata = meta;\n    if (input.select) {\n      out = {};\n      for (const key of input.select) {\n        const v = resolveOwn(meta, key);\n        if (v !== undefined) out[key] = v as never;\n      }\n    }\n    return { path: rel, meta: out, ...(headings ? { headings } : {}) };\n  });\n}\n\n/** The `headings` index field rides the row itself; `runMetadataQuery` hoists it out\n * of `meta`. Exported so scans (which BUILD rows) and queries (which read them) agree\n * on the key. */\nexport const METADATA_HEADINGS_KEY = 'headings';\n\n/** Execute the tool for an agent loop: validate, query, and return the fenced result\n * (index rows are corpus-derived bytes — R-GA-7 fences them where they enter the\n * loop). Errors come back as `isError` results, never thrown, so the model adapts. */\nexport function executeMetadataQuery(\n  index: FilesMetadata,\n  chroot: string,\n  raw: unknown,\n  filter?: (absPath: string) => boolean,\n): { content: string; isError?: boolean } {\n  try {\n    const rows = runMetadataQuery(index, chroot, raw, filter);\n    return { content: fenceUntrusted('tool-result: metadata rows', JSON.stringify(rows, null, 2)) };\n  } catch (e) {\n    const code = (e as { code?: string })?.code ?? 'invalid-params';\n    return { content: `${code}: ${(e as Error).message}`, isError: true };\n  }\n}\n\n/** A loop-ready tool over an index the app supplies per call (the metadata store can\n * be rescanned; the executor reads through the getter, so it never goes stale). */\nexport function createMetadataQueryTool(options: {\n  /** Absolute corpus root — rows outside it are invisible (G-GA-11). */\n  chroot: string;\n  /** The index to query (e.g. `useAllMetadata()` at call time, or a scan result). */\n  getIndex: () => FilesMetadata;\n  /** App row-policy after the chroot filter (e.g. no `_`-prefixed files). */\n  filter?: (absPath: string) => boolean;\n}): {\n  name: string;\n  description: string;\n  inputSchema: Record<string, unknown>;\n  execute: (raw: unknown) => { content: string; isError?: boolean };\n} {\n  const d = METADATA_QUERY_TOOL_DESCRIPTOR;\n  return {\n    name: d.name,\n    description: d.description,\n    inputSchema: d.paramsSchema as Record<string, unknown>,\n    execute: (raw: unknown) => executeMetadataQuery(options.getIndex(), options.chroot, raw, options.filter),\n  };\n}\n"],"mappings":"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","names":[]}