@immediately-run/sdk 0.57.1 → 0.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agentChatClient.cjs +112 -0
- package/dist/agentChatClient.cjs.map +1 -0
- package/dist/agentChatClient.d.cts +9 -0
- package/dist/agentChatClient.d.ts +9 -0
- package/dist/agentChatClient.js +89 -0
- package/dist/agentChatClient.js.map +1 -0
- package/dist/agentContext.cjs +69 -0
- package/dist/agentContext.cjs.map +1 -0
- package/dist/agentContext.d.cts +45 -0
- package/dist/agentContext.d.ts +45 -0
- package/dist/agentContext.js +45 -0
- package/dist/agentContext.js.map +1 -0
- package/dist/agentLoop.cjs +301 -0
- package/dist/agentLoop.cjs.map +1 -0
- package/dist/agentLoop.d.cts +267 -0
- package/dist/agentLoop.d.ts +267 -0
- package/dist/agentLoop.js +271 -0
- package/dist/agentLoop.js.map +1 -0
- package/dist/agentSteering.cjs +127 -0
- package/dist/agentSteering.cjs.map +1 -0
- package/dist/agentSteering.d.cts +80 -0
- package/dist/agentSteering.d.ts +80 -0
- package/dist/agentSteering.js +98 -0
- package/dist/agentSteering.js.map +1 -0
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +33 -2
- package/dist/auth.d.ts +33 -2
- package/dist/auth.js.map +1 -1
- package/dist/bundle.cjs +91 -0
- package/dist/bundle.cjs.map +1 -0
- package/dist/bundle.d.cts +63 -0
- package/dist/bundle.d.ts +63 -0
- package/dist/bundle.js +62 -0
- package/dist/bundle.js.map +1 -0
- package/dist/collectHeadings.cjs +59 -0
- package/dist/collectHeadings.cjs.map +1 -0
- package/dist/collectHeadings.d.cts +16 -0
- package/dist/collectHeadings.d.ts +16 -0
- package/dist/collectHeadings.js +36 -0
- package/dist/collectHeadings.js.map +1 -0
- package/dist/corpus.cjs +9 -58
- package/dist/corpus.cjs.map +1 -1
- package/dist/corpus.d.cts +3 -63
- package/dist/corpus.d.ts +3 -63
- package/dist/corpus.js +15 -57
- package/dist/corpus.js.map +1 -1
- package/dist/debug.cjs +115 -0
- package/dist/debug.cjs.map +1 -1
- package/dist/debug.js +115 -0
- package/dist/debug.js.map +1 -1
- package/dist/fence.cjs +49 -0
- package/dist/fence.cjs.map +1 -0
- package/dist/fence.d.cts +4 -0
- package/dist/fence.d.ts +4 -0
- package/dist/fence.js +26 -0
- package/dist/fence.js.map +1 -0
- package/dist/formFactor.cjs.map +1 -1
- package/dist/formFactor.d.cts +11 -2
- package/dist/formFactor.d.ts +11 -2
- package/dist/formFactor.js.map +1 -1
- package/dist/fs.cjs.map +1 -1
- package/dist/fs.d.cts +16 -6
- package/dist/fs.d.ts +16 -6
- package/dist/fs.js.map +1 -1
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +7 -0
- package/dist/hooks.d.ts +7 -0
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +21 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/launch.cjs +45 -6
- package/dist/launch.cjs.map +1 -1
- package/dist/launch.d.cts +3 -0
- package/dist/launch.d.ts +3 -0
- package/dist/launch.js +45 -6
- package/dist/launch.js.map +1 -1
- package/dist/llm.cjs.map +1 -1
- package/dist/llm.d.cts +20 -3
- package/dist/llm.d.ts +20 -3
- package/dist/llm.js.map +1 -1
- package/dist/metadataQueryTool.cjs +271 -0
- package/dist/metadataQueryTool.cjs.map +1 -0
- package/dist/metadataQueryTool.d.cts +159 -0
- package/dist/metadataQueryTool.d.ts +159 -0
- package/dist/metadataQueryTool.js +241 -0
- package/dist/metadataQueryTool.js.map +1 -0
- package/dist/mounts.cjs.map +1 -1
- package/dist/mounts.d.cts +22 -3
- package/dist/mounts.d.ts +22 -3
- package/dist/mounts.js.map +1 -1
- package/dist/onFsChange.cjs +13 -1
- package/dist/onFsChange.cjs.map +1 -1
- package/dist/onFsChange.d.cts +21 -1
- package/dist/onFsChange.d.ts +21 -1
- package/dist/onFsChange.js +13 -1
- package/dist/onFsChange.js.map +1 -1
- package/dist/protocolSchemes.cjs +1 -0
- package/dist/protocolSchemes.cjs.map +1 -1
- package/dist/protocolSchemes.d.cts +1 -0
- package/dist/protocolSchemes.d.ts +1 -0
- package/dist/protocolSchemes.js +2 -0
- package/dist/protocolSchemes.js.map +1 -1
- package/dist/recents.cjs +41 -0
- package/dist/recents.cjs.map +1 -0
- package/dist/recents.d.cts +23 -0
- package/dist/recents.d.ts +23 -0
- package/dist/recents.js +17 -0
- package/dist/recents.js.map +1 -0
- package/dist/tasks.cjs +41 -7
- package/dist/tasks.cjs.map +1 -1
- package/dist/tasks.d.cts +136 -7
- package/dist/tasks.d.ts +136 -7
- package/dist/tasks.js +39 -7
- package/dist/tasks.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/workspace.cjs +53 -0
- package/dist/workspace.cjs.map +1 -0
- package/dist/workspace.d.cts +58 -0
- package/dist/workspace.d.ts +58 -0
- package/dist/workspace.js +28 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +6 -5
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { Metadata, FilesMetadata } from './sandboxTypes.js';
|
|
2
|
+
|
|
3
|
+
/** The tool's canonical name — `metadata:query`, catalog-shaped. */
|
|
4
|
+
declare const METADATA_QUERY_TOOL_NAME = "metadata:query";
|
|
5
|
+
/** One heading of an indexed entry — the additive index extension (GROVE_AGENT_SPEC
|
|
6
|
+
* §4: `headings: [{id, text, depth}]`, ids from the mdx-plugins heading-anchor canon). */
|
|
7
|
+
interface HeadingSummary {
|
|
8
|
+
id: string;
|
|
9
|
+
text: string;
|
|
10
|
+
/** 1–6, the ATX depth. */
|
|
11
|
+
depth: number;
|
|
12
|
+
}
|
|
13
|
+
/** The declarative filter set — the tool's whole argument vocabulary. */
|
|
14
|
+
interface MetadataQueryInput {
|
|
15
|
+
/** Glob over the row's path RELATIVE to the chroot root (`*` within one segment,
|
|
16
|
+
* `**` across segments). Default: every row. */
|
|
17
|
+
pathGlob?: string;
|
|
18
|
+
/** Frontmatter filters, ANDed together. */
|
|
19
|
+
where?: Array<{
|
|
20
|
+
/** Dotted own-property path into the row's frontmatter (one nesting level is
|
|
21
|
+
* representable in frontmatter; deeper paths simply never match). */
|
|
22
|
+
key: string;
|
|
23
|
+
op: 'eq' | 'contains' | 'in' | 'exists';
|
|
24
|
+
/** For `eq`: a scalar. For `in`: an array of scalars. Unused by `exists`. */
|
|
25
|
+
value?: unknown;
|
|
26
|
+
}>;
|
|
27
|
+
/** Dotted frontmatter key to sort by (rows lacking it sort last, stably). */
|
|
28
|
+
sortBy?: string;
|
|
29
|
+
/** Default `'asc'`. */
|
|
30
|
+
order?: 'asc' | 'desc';
|
|
31
|
+
/** Cap on returned rows (default 100, max 500 — the cheap call stays cheap). */
|
|
32
|
+
limit?: number;
|
|
33
|
+
/** Frontmatter fields to include per row (dotted). Default: the whole record. */
|
|
34
|
+
select?: string[];
|
|
35
|
+
}
|
|
36
|
+
/** One query result row: the path (chroot-relative), the selected frontmatter (or
|
|
37
|
+
* all of it), and the entry's headings when the index carries them. */
|
|
38
|
+
interface MetadataQueryRow {
|
|
39
|
+
path: string;
|
|
40
|
+
meta: Metadata;
|
|
41
|
+
headings?: HeadingSummary[];
|
|
42
|
+
}
|
|
43
|
+
/** Canonical, catalog-shaped descriptor for the tool — the same definition every
|
|
44
|
+
* consumer reads (the app's loop, the MCP bridge, a future external executor), so
|
|
45
|
+
* there is exactly one `metadata:query` in the world. */
|
|
46
|
+
declare const METADATA_QUERY_TOOL_DESCRIPTOR: {
|
|
47
|
+
readonly name: "metadata:query";
|
|
48
|
+
readonly description: string;
|
|
49
|
+
readonly paramsSchema: {
|
|
50
|
+
readonly type: "object";
|
|
51
|
+
readonly additionalProperties: false;
|
|
52
|
+
readonly properties: {
|
|
53
|
+
readonly pathGlob: {
|
|
54
|
+
readonly type: "string";
|
|
55
|
+
readonly description: "Glob over the entry path relative to the corpus root (`*` one segment, `**` any).";
|
|
56
|
+
};
|
|
57
|
+
readonly where: {
|
|
58
|
+
readonly type: "array";
|
|
59
|
+
readonly items: {
|
|
60
|
+
readonly type: "object";
|
|
61
|
+
readonly additionalProperties: false;
|
|
62
|
+
readonly required: readonly ["key", "op"];
|
|
63
|
+
readonly properties: {
|
|
64
|
+
readonly key: {
|
|
65
|
+
readonly type: "string";
|
|
66
|
+
readonly description: "Dotted frontmatter field path.";
|
|
67
|
+
};
|
|
68
|
+
readonly op: {
|
|
69
|
+
readonly type: "string";
|
|
70
|
+
readonly enum: readonly ["eq", "contains", "in", "exists"];
|
|
71
|
+
};
|
|
72
|
+
readonly value: {
|
|
73
|
+
readonly description: "Scalar for `eq`; array of scalars for `in`; unused by `exists`.";
|
|
74
|
+
readonly anyOf: readonly [{
|
|
75
|
+
readonly type: readonly ["string", "number", "boolean", "null"];
|
|
76
|
+
}, {
|
|
77
|
+
readonly type: "array";
|
|
78
|
+
readonly items: {
|
|
79
|
+
readonly type: readonly ["string", "number", "boolean", "null"];
|
|
80
|
+
};
|
|
81
|
+
}];
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
readonly sortBy: {
|
|
87
|
+
readonly type: "string";
|
|
88
|
+
};
|
|
89
|
+
readonly order: {
|
|
90
|
+
readonly type: "string";
|
|
91
|
+
readonly enum: readonly ["asc", "desc"];
|
|
92
|
+
};
|
|
93
|
+
readonly limit: {
|
|
94
|
+
readonly type: "integer";
|
|
95
|
+
readonly minimum: 1;
|
|
96
|
+
readonly maximum: 500;
|
|
97
|
+
};
|
|
98
|
+
readonly select: {
|
|
99
|
+
readonly type: "array";
|
|
100
|
+
readonly items: {
|
|
101
|
+
readonly type: "string";
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
/** A validation failure — the boundary's only error shape (`invalid-params`, the
|
|
108
|
+
* platform's typed-error vocabulary). */
|
|
109
|
+
declare class MetadataQueryError extends Error {
|
|
110
|
+
code: "invalid-params";
|
|
111
|
+
}
|
|
112
|
+
/** `*` within a segment, `**` across segments — the whole vocabulary. Compiled once
|
|
113
|
+
* per query; anchored so `a/b` never matches `x/a/b`. */
|
|
114
|
+
declare function globToRegExp(glob: string): RegExp;
|
|
115
|
+
/**
|
|
116
|
+
* Run a metadata query over an index — PURE (G-GA-4: it cannot read a file body).
|
|
117
|
+
*
|
|
118
|
+
* @param index the in-scope metadata store (`useAllMetadata()` / a scan result),
|
|
119
|
+
* keyed by absolute path.
|
|
120
|
+
* @param chroot the corpus root rows are confined to (G-GA-11): the SAME root the
|
|
121
|
+
* app's `read_entry` chroots to, so the two tools describe one corpus.
|
|
122
|
+
* @param raw the model-supplied arguments, validated here at the boundary.
|
|
123
|
+
* @param filter optional app row-policy (e.g. excluding `_`-prefixed structural
|
|
124
|
+
* files) applied after the chroot filter.
|
|
125
|
+
* @throws {MetadataQueryError} (`code: 'invalid-params'`) on any non-declarative or
|
|
126
|
+
* proto-polluting argument.
|
|
127
|
+
*/
|
|
128
|
+
declare function runMetadataQuery(index: FilesMetadata, chroot: string, raw: unknown, filter?: (absPath: string) => boolean): MetadataQueryRow[];
|
|
129
|
+
/** The `headings` index field rides the row itself; `runMetadataQuery` hoists it out
|
|
130
|
+
* of `meta`. Exported so scans (which BUILD rows) and queries (which read them) agree
|
|
131
|
+
* on the key. */
|
|
132
|
+
declare const METADATA_HEADINGS_KEY = "headings";
|
|
133
|
+
/** Execute the tool for an agent loop: validate, query, and return the fenced result
|
|
134
|
+
* (index rows are corpus-derived bytes — R-GA-7 fences them where they enter the
|
|
135
|
+
* loop). Errors come back as `isError` results, never thrown, so the model adapts. */
|
|
136
|
+
declare function executeMetadataQuery(index: FilesMetadata, chroot: string, raw: unknown, filter?: (absPath: string) => boolean): {
|
|
137
|
+
content: string;
|
|
138
|
+
isError?: boolean;
|
|
139
|
+
};
|
|
140
|
+
/** A loop-ready tool over an index the app supplies per call (the metadata store can
|
|
141
|
+
* be rescanned; the executor reads through the getter, so it never goes stale). */
|
|
142
|
+
declare function createMetadataQueryTool(options: {
|
|
143
|
+
/** Absolute corpus root — rows outside it are invisible (G-GA-11). */
|
|
144
|
+
chroot: string;
|
|
145
|
+
/** The index to query (e.g. `useAllMetadata()` at call time, or a scan result). */
|
|
146
|
+
getIndex: () => FilesMetadata;
|
|
147
|
+
/** App row-policy after the chroot filter (e.g. no `_`-prefixed files). */
|
|
148
|
+
filter?: (absPath: string) => boolean;
|
|
149
|
+
}): {
|
|
150
|
+
name: string;
|
|
151
|
+
description: string;
|
|
152
|
+
inputSchema: Record<string, unknown>;
|
|
153
|
+
execute: (raw: unknown) => {
|
|
154
|
+
content: string;
|
|
155
|
+
isError?: boolean;
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export { type HeadingSummary, METADATA_HEADINGS_KEY, METADATA_QUERY_TOOL_DESCRIPTOR, METADATA_QUERY_TOOL_NAME, MetadataQueryError, type MetadataQueryInput, type MetadataQueryRow, createMetadataQueryTool, executeMetadataQuery, globToRegExp, runMetadataQuery };
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import "./chunk-VHAA22YE.js";
|
|
2
|
+
import { fenceUntrusted } from "./fence";
|
|
3
|
+
const METADATA_QUERY_TOOL_NAME = "metadata:query";
|
|
4
|
+
const METADATA_QUERY_TOOL_DESCRIPTOR = {
|
|
5
|
+
name: METADATA_QUERY_TOOL_NAME,
|
|
6
|
+
description: "Query the MDX corpus index: paths, frontmatter, and headings of entries. Declarative filters only (no expressions). Returns index rows \u2014 never file bodies.",
|
|
7
|
+
paramsSchema: {
|
|
8
|
+
type: "object",
|
|
9
|
+
additionalProperties: false,
|
|
10
|
+
properties: {
|
|
11
|
+
pathGlob: {
|
|
12
|
+
type: "string",
|
|
13
|
+
description: "Glob over the entry path relative to the corpus root (`*` one segment, `**` any)."
|
|
14
|
+
},
|
|
15
|
+
where: {
|
|
16
|
+
type: "array",
|
|
17
|
+
items: {
|
|
18
|
+
type: "object",
|
|
19
|
+
additionalProperties: false,
|
|
20
|
+
required: ["key", "op"],
|
|
21
|
+
properties: {
|
|
22
|
+
key: { type: "string", description: "Dotted frontmatter field path." },
|
|
23
|
+
op: { type: "string", enum: ["eq", "contains", "in", "exists"] },
|
|
24
|
+
value: {
|
|
25
|
+
description: "Scalar for `eq`; array of scalars for `in`; unused by `exists`.",
|
|
26
|
+
anyOf: [
|
|
27
|
+
{ type: ["string", "number", "boolean", "null"] },
|
|
28
|
+
{ type: "array", items: { type: ["string", "number", "boolean", "null"] } }
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
sortBy: { type: "string" },
|
|
35
|
+
order: { type: "string", enum: ["asc", "desc"] },
|
|
36
|
+
limit: { type: "integer", minimum: 1, maximum: 500 },
|
|
37
|
+
select: { type: "array", items: { type: "string" } }
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
class MetadataQueryError extends Error {
|
|
42
|
+
constructor() {
|
|
43
|
+
super(...arguments);
|
|
44
|
+
this.code = "invalid-params";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const RESERVED_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
48
|
+
const SCALAR = /* @__PURE__ */ new Set(["string", "number", "boolean"]);
|
|
49
|
+
function validateDottedKey(key, what) {
|
|
50
|
+
if (typeof key !== "string" || !key) throw new MetadataQueryError(`${what} must be a non-empty string`);
|
|
51
|
+
if (key.length > 128) throw new MetadataQueryError(`${what} is too long (max 128 chars)`);
|
|
52
|
+
if (/[/\\\u0000-\u001f]/.test(key))
|
|
53
|
+
throw new MetadataQueryError(`${what} must be a dotted path (no path separators)`);
|
|
54
|
+
for (const seg of key.split(".")) {
|
|
55
|
+
if (!seg) throw new MetadataQueryError(`${what} has an empty segment: ${JSON.stringify(key)}`);
|
|
56
|
+
if (RESERVED_SEGMENTS.has(seg)) throw new MetadataQueryError(`${what} contains a reserved segment: ${seg}`);
|
|
57
|
+
}
|
|
58
|
+
return key;
|
|
59
|
+
}
|
|
60
|
+
function validateInput(raw) {
|
|
61
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
62
|
+
throw new MetadataQueryError("input must be an object");
|
|
63
|
+
}
|
|
64
|
+
const src = raw;
|
|
65
|
+
for (const k of Object.keys(src)) {
|
|
66
|
+
if (!["pathGlob", "where", "sortBy", "order", "limit", "select"].includes(k)) {
|
|
67
|
+
throw new MetadataQueryError(`unknown argument: ${k}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const out = {};
|
|
71
|
+
if (src.pathGlob !== void 0) {
|
|
72
|
+
if (typeof src.pathGlob !== "string" || !src.pathGlob || src.pathGlob.length > 256) {
|
|
73
|
+
throw new MetadataQueryError("pathGlob must be a non-empty string (\u2264256 chars)");
|
|
74
|
+
}
|
|
75
|
+
if (/[\u0000\n\r]/.test(src.pathGlob)) throw new MetadataQueryError("pathGlob contains control characters");
|
|
76
|
+
out.pathGlob = src.pathGlob;
|
|
77
|
+
}
|
|
78
|
+
if (src.where !== void 0) {
|
|
79
|
+
if (!Array.isArray(src.where) || src.where.length > 32) {
|
|
80
|
+
throw new MetadataQueryError("where must be an array of at most 32 filters");
|
|
81
|
+
}
|
|
82
|
+
out.where = src.where.map((w, i) => {
|
|
83
|
+
if (typeof w !== "object" || w === null || Array.isArray(w)) {
|
|
84
|
+
throw new MetadataQueryError(`where[${i}] must be an object`);
|
|
85
|
+
}
|
|
86
|
+
const { key, op, value } = w;
|
|
87
|
+
validateDottedKey(key, `where[${i}].key`);
|
|
88
|
+
if (op !== "eq" && op !== "contains" && op !== "in" && op !== "exists") {
|
|
89
|
+
throw new MetadataQueryError(`where[${i}].op must be eq|contains|in|exists`);
|
|
90
|
+
}
|
|
91
|
+
if (value !== void 0) {
|
|
92
|
+
if (typeof value === "function") {
|
|
93
|
+
throw new MetadataQueryError(`where[${i}].value must be data, not a function`);
|
|
94
|
+
}
|
|
95
|
+
if (op === "in") {
|
|
96
|
+
if (!Array.isArray(value) || value.length > 100 || value.some((v) => !SCALAR.has(typeof v) && v !== null)) {
|
|
97
|
+
throw new MetadataQueryError(`where[${i}].value for op=in must be an array of scalars`);
|
|
98
|
+
}
|
|
99
|
+
} else if (!SCALAR.has(typeof value) && value !== null) {
|
|
100
|
+
if (typeof value === "object")
|
|
101
|
+
throw new MetadataQueryError(`where[${i}].value for op=${op} must be a scalar`);
|
|
102
|
+
throw new MetadataQueryError(`where[${i}].value for op=${op} must be a scalar`);
|
|
103
|
+
}
|
|
104
|
+
} else if (op !== "exists") {
|
|
105
|
+
throw new MetadataQueryError(`where[${i}].value is required for op=${op}`);
|
|
106
|
+
}
|
|
107
|
+
return { key, op, ...value !== void 0 ? { value } : {} };
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (src.sortBy !== void 0) out.sortBy = validateDottedKey(src.sortBy, "sortBy");
|
|
111
|
+
if (src.order !== void 0) {
|
|
112
|
+
if (src.order !== "asc" && src.order !== "desc") throw new MetadataQueryError("order must be asc|desc");
|
|
113
|
+
out.order = src.order;
|
|
114
|
+
}
|
|
115
|
+
if (src.limit !== void 0) {
|
|
116
|
+
if (typeof src.limit !== "number" || !Number.isInteger(src.limit) || src.limit < 1 || src.limit > 500) {
|
|
117
|
+
throw new MetadataQueryError("limit must be an integer 1\u2013500");
|
|
118
|
+
}
|
|
119
|
+
out.limit = src.limit;
|
|
120
|
+
}
|
|
121
|
+
if (src.select !== void 0) {
|
|
122
|
+
if (!Array.isArray(src.select) || src.select.length > 64) {
|
|
123
|
+
throw new MetadataQueryError("select must be an array of at most 64 field paths");
|
|
124
|
+
}
|
|
125
|
+
out.select = src.select.map((k, i) => validateDottedKey(k, `select[${i}]`));
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
function resolveOwn(meta, key) {
|
|
130
|
+
let cur = meta;
|
|
131
|
+
for (const seg of key.split(".")) {
|
|
132
|
+
if (typeof cur !== "object" || cur === null) return void 0;
|
|
133
|
+
cur = Object.prototype.hasOwnProperty.call(cur, seg) ? cur[seg] : void 0;
|
|
134
|
+
if (cur === void 0) return void 0;
|
|
135
|
+
}
|
|
136
|
+
return cur;
|
|
137
|
+
}
|
|
138
|
+
function globToRegExp(glob) {
|
|
139
|
+
const esc = glob.replace(/[.+^${}()|[\]\\?]/g, "\\$&");
|
|
140
|
+
const re = esc.replace(/\*\*/g, "\0").replace(/\*/g, "[^/]*").replace(/\u0000/g, ".*");
|
|
141
|
+
return new RegExp(`^${re}$`);
|
|
142
|
+
}
|
|
143
|
+
function matches(row, w) {
|
|
144
|
+
const v = resolveOwn(row, w.key);
|
|
145
|
+
switch (w.op) {
|
|
146
|
+
case "exists":
|
|
147
|
+
return v !== void 0;
|
|
148
|
+
case "eq":
|
|
149
|
+
return v === w.value || v === null && w.value === null;
|
|
150
|
+
case "contains": {
|
|
151
|
+
const needle = w.value;
|
|
152
|
+
if (typeof needle !== "string") return false;
|
|
153
|
+
if (typeof v === "string") return v.includes(needle);
|
|
154
|
+
if (Array.isArray(v)) return v.some((x) => typeof x === "string" && x.includes(needle));
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
case "in": {
|
|
158
|
+
if (!Array.isArray(w.value)) return false;
|
|
159
|
+
return w.value.some((needle) => v === needle);
|
|
160
|
+
}
|
|
161
|
+
default:
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function compare(a, b) {
|
|
166
|
+
const rank = (v) => v === void 0 ? 0 : 1;
|
|
167
|
+
if (rank(a) !== rank(b)) return rank(a) - rank(b);
|
|
168
|
+
if (a === void 0) return 0;
|
|
169
|
+
const as = typeof a === "number" && typeof b === "number" ? a : String(a);
|
|
170
|
+
const bs = typeof a === "number" && typeof b === "number" ? b : String(b);
|
|
171
|
+
return as < bs ? -1 : as > bs ? 1 : 0;
|
|
172
|
+
}
|
|
173
|
+
function normalizeChroot(chroot) {
|
|
174
|
+
const c = chroot.startsWith("/") ? chroot : `/${chroot}`;
|
|
175
|
+
return c.endsWith("/") ? c : `${c}/`;
|
|
176
|
+
}
|
|
177
|
+
function runMetadataQuery(index, chroot, raw, filter) {
|
|
178
|
+
const input = validateInput(raw);
|
|
179
|
+
const root = normalizeChroot(chroot);
|
|
180
|
+
const globRe = input.pathGlob !== void 0 ? globToRegExp(input.pathGlob) : null;
|
|
181
|
+
const rows = [];
|
|
182
|
+
for (const [abs, rowMeta] of Object.entries(index)) {
|
|
183
|
+
if (!abs.startsWith(root)) continue;
|
|
184
|
+
if (filter && !filter(abs)) continue;
|
|
185
|
+
const rel = abs.slice(root.length);
|
|
186
|
+
if (globRe && !globRe.test(rel)) continue;
|
|
187
|
+
const { headings, ...frontmatter } = rowMeta;
|
|
188
|
+
const meta = frontmatter;
|
|
189
|
+
if (input.where && !input.where.every((w) => matches(meta, w))) continue;
|
|
190
|
+
rows.push({ rel, meta, headings: Array.isArray(headings) ? headings : void 0 });
|
|
191
|
+
}
|
|
192
|
+
if (input.sortBy) {
|
|
193
|
+
const dir = input.order === "desc" ? -1 : 1;
|
|
194
|
+
rows.sort(
|
|
195
|
+
(x, y) => dir * compare(resolveOwn(x.meta, input.sortBy), resolveOwn(y.meta, input.sortBy))
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
const limit = input.limit ?? 100;
|
|
199
|
+
const sliced = rows.slice(0, limit);
|
|
200
|
+
return sliced.map(({ rel, meta, headings }) => {
|
|
201
|
+
let out = meta;
|
|
202
|
+
if (input.select) {
|
|
203
|
+
out = {};
|
|
204
|
+
for (const key of input.select) {
|
|
205
|
+
const v = resolveOwn(meta, key);
|
|
206
|
+
if (v !== void 0) out[key] = v;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return { path: rel, meta: out, ...headings ? { headings } : {} };
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
const METADATA_HEADINGS_KEY = "headings";
|
|
213
|
+
function executeMetadataQuery(index, chroot, raw, filter) {
|
|
214
|
+
try {
|
|
215
|
+
const rows = runMetadataQuery(index, chroot, raw, filter);
|
|
216
|
+
return { content: fenceUntrusted("tool-result: metadata rows", JSON.stringify(rows, null, 2)) };
|
|
217
|
+
} catch (e) {
|
|
218
|
+
const code = e?.code ?? "invalid-params";
|
|
219
|
+
return { content: `${code}: ${e.message}`, isError: true };
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function createMetadataQueryTool(options) {
|
|
223
|
+
const d = METADATA_QUERY_TOOL_DESCRIPTOR;
|
|
224
|
+
return {
|
|
225
|
+
name: d.name,
|
|
226
|
+
description: d.description,
|
|
227
|
+
inputSchema: d.paramsSchema,
|
|
228
|
+
execute: (raw) => executeMetadataQuery(options.getIndex(), options.chroot, raw, options.filter)
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
export {
|
|
232
|
+
METADATA_HEADINGS_KEY,
|
|
233
|
+
METADATA_QUERY_TOOL_DESCRIPTOR,
|
|
234
|
+
METADATA_QUERY_TOOL_NAME,
|
|
235
|
+
MetadataQueryError,
|
|
236
|
+
createMetadataQueryTool,
|
|
237
|
+
executeMetadataQuery,
|
|
238
|
+
globToRegExp,
|
|
239
|
+
runMetadataQuery
|
|
240
|
+
};
|
|
241
|
+
//# sourceMappingURL=metadataQueryTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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":[]}
|