omp-fabric 1.25.7 → 1.25.8
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/CHANGELOG.md +14 -0
- package/README.md +1 -1
- package/dist/audit/projection.d.ts.map +1 -1
- package/dist/chunks/{chunk-HAH64YUG.js → chunk-2C5YN36Y.js} +2 -2
- package/dist/chunks/chunk-2C5YN36Y.js.map +7 -0
- package/dist/chunks/{chunk-3BS4RMF4.js → chunk-AZBJNZS4.js} +2 -2
- package/dist/chunks/{chunk-EZRC24CX.js → chunk-BMSAIMFB.js} +2 -2
- package/dist/chunks/{chunk-63VIZJGS.js → chunk-BWLZ6VDQ.js} +2 -2
- package/dist/chunks/{chunk-BQG4LFAC.js → chunk-D55BFSFK.js} +2 -2
- package/dist/chunks/{chunk-WUPYPFAC.js → chunk-E3KTE736.js} +3 -3
- package/dist/chunks/{chunk-JBKYNJFN.js → chunk-FL4A542C.js} +2 -1
- package/dist/chunks/chunk-FL4A542C.js.map +7 -0
- package/dist/chunks/{chunk-REHGQCXU.js → chunk-J2BDKPO4.js} +4 -4
- package/dist/chunks/{chunk-3KORI7FQ.js → chunk-KLWNXXEI.js} +2 -2
- package/dist/chunks/{chunk-XLINRLLP.js → chunk-PIW2DEO2.js} +4 -4
- package/dist/chunks/{chunk-H3KRHDDF.js → chunk-QJKOPPW2.js} +2 -2
- package/dist/chunks/{chunk-MR5C7U5H.js → chunk-UKB5RJDP.js} +3 -3
- package/dist/chunks/chunk-UKB5RJDP.js.map +7 -0
- package/dist/chunks/{chunk-GPJV2FSP.js → chunk-WX6C7N3W.js} +2 -2
- package/dist/chunks/{chunk-ABBGHQVX.js → chunk-YAI5SCIE.js} +2 -2
- package/dist/chunks/{chunk-G3ELO3QC.js → chunk-Z6TTRT6Q.js} +2 -2
- package/dist/compaction/hook.js +3 -3
- package/dist/compaction/lcm-runtime.js +4 -4
- package/dist/core/action-registry.js +2 -2
- package/dist/core/system-guidance.d.ts.map +1 -1
- package/dist/entropy/index.js +5 -5
- package/dist/fabric-runtime-state.js +63 -27
- package/dist/fabric-runtime-state.js.map +2 -2
- package/dist/host-compatibility.d.ts +1 -1
- package/dist/index.js +17 -14
- package/dist/index.js.map +2 -2
- package/dist/memory/discovery.js +4 -4
- package/dist/memory/normalize.js +3 -3
- package/dist/memory/search.js +4 -4
- package/dist/providers/memory-provider.js +6 -6
- package/dist/providers/omp-tools-provider.d.ts.map +1 -1
- package/dist/residency/host.js +6 -6
- package/dist/residency/omp-entry.js +6 -6
- package/dist/runtime/core-override-guest-types.js +1 -1
- package/dist/runtime/guest-types.d.ts +2 -2
- package/dist/runtime/guest-types.d.ts.map +1 -1
- package/dist/runtime/guest-types.js +1 -1
- package/dist/runtime/node-process-runtime.js +1 -1
- package/dist/runtime/quickjs-runtime.d.ts +1 -1
- package/dist/runtime/quickjs-runtime.d.ts.map +1 -1
- package/dist/runtime/quickjs-runtime.js +1 -1
- package/dist/speculation/guest-args.d.ts.map +1 -1
- package/dist/speculation/scanner.js +2 -1
- package/dist/speculation/scanner.js.map +2 -2
- package/docs/audit-trace.md +1 -1
- package/docs/configuration.md +1 -1
- package/package.json +4 -4
- package/skills/fabric-exec/SKILL.md +4 -4
- package/dist/chunks/chunk-HAH64YUG.js.map +0 -7
- package/dist/chunks/chunk-JBKYNJFN.js.map +0 -7
- package/dist/chunks/chunk-MR5C7U5H.js.map +0 -7
- /package/dist/chunks/{chunk-3BS4RMF4.js.map → chunk-AZBJNZS4.js.map} +0 -0
- /package/dist/chunks/{chunk-EZRC24CX.js.map → chunk-BMSAIMFB.js.map} +0 -0
- /package/dist/chunks/{chunk-63VIZJGS.js.map → chunk-BWLZ6VDQ.js.map} +0 -0
- /package/dist/chunks/{chunk-BQG4LFAC.js.map → chunk-D55BFSFK.js.map} +0 -0
- /package/dist/chunks/{chunk-WUPYPFAC.js.map → chunk-E3KTE736.js.map} +0 -0
- /package/dist/chunks/{chunk-REHGQCXU.js.map → chunk-J2BDKPO4.js.map} +0 -0
- /package/dist/chunks/{chunk-3KORI7FQ.js.map → chunk-KLWNXXEI.js.map} +0 -0
- /package/dist/chunks/{chunk-XLINRLLP.js.map → chunk-PIW2DEO2.js.map} +0 -0
- /package/dist/chunks/{chunk-H3KRHDDF.js.map → chunk-QJKOPPW2.js.map} +0 -0
- /package/dist/chunks/{chunk-GPJV2FSP.js.map → chunk-WX6C7N3W.js.map} +0 -0
- /package/dist/chunks/{chunk-ABBGHQVX.js.map → chunk-YAI5SCIE.js.map} +0 -0
- /package/dist/chunks/{chunk-G3ELO3QC.js.map → chunk-Z6TTRT6Q.js.map} +0 -0
|
@@ -22,7 +22,7 @@ export interface FabricSandboxOptions {
|
|
|
22
22
|
transpiledSourceMap?: string;
|
|
23
23
|
}
|
|
24
24
|
export type FabricHostCall = (ref: string, args: Record<string, unknown>, signal: AbortSignal) => Promise<unknown>;
|
|
25
|
-
export declare const GUEST_SETUP = "\n(() => {\nconst __fabricBridge = globalThis.__fabricHostCall;\ndelete globalThis.__fabricHostCall;\nconst __successfulCalls = [];\nconst __resolvedCallRef = (ref, args) =>\n ref === \"fabric.$call\" && args && typeof args.ref === \"string\" ? args.ref : ref;\nconst __recordSuccessfulCall = (ref, args) => {\n __successfulCalls.push(Object.freeze({ ref: __resolvedCallRef(ref, args) }));\n};\nconst __handoffFacts = () => {\n const calls = Object.freeze(__successfulCalls.slice());\n const count = (ref) => {\n if (ref === undefined) return calls.length;\n const refs = new Set(Array.isArray(ref) ? ref : [ref]);\n return calls.reduce((total, call) => total + (refs.has(call.ref) ? 1 : 0), 0);\n };\n return Object.freeze({ calls, count });\n};\nconst __call = async (ref, args) => {\n const normalizedArgs = args ?? {};\n const value = await __fabricBridge(ref, normalizedArgs);\n __recordSuccessfulCall(ref, normalizedArgs);\n return value;\n};\nconst __ompToolNames = [\"read\",\"bash\",\"edit\",\"write\",\"grep\",\"find\",\"ls\",\"wait\"];\nconst __toolsBase = {\n providers: () => __call(\"fabric.$providers\", {}),\n catalog: (args = {}) => __call(\"fabric.$catalog\", args),\n list: (args = {}) => __call(\"fabric.$list\", args),\n search: (args) => __call(\n \"fabric.$search\",\n typeof args === \"string\" ? { query: args } : args,\n ),\n describe: (args) => __call(\"fabric.$describe\", args),\n call: (args) => __call(\"fabric.$call\", args),\n progress: (args) => __call(\"fabric.$progress\", args),\n models: () => __call(\"fabric.$models\", {}),\n};\n// tools is discovery + generic calls only. The proxy keeps the seven discovery\n// methods and turns a core-tool name (read/bash/edit/...) into an actionable\n// error pointing at omp.<name>, so a model that writes tools.read(...) learns\n// the fix in one turn instead of looping on \"tools.read is not a function\".\nglobalThis.tools = new Proxy(__toolsBase, {\n get(target, property) {\n if (property === \"then\" || typeof property === \"symbol\") return undefined;\n const name = String(property);\n if (__ompToolNames.indexOf(name) >= 0) {\n return () => {\n throw new Error(\n \"tools.\" + name + \" is not available on the discovery API. tools is discovery + generic calls only (providers/catalog/list/search/describe/call/models). For the OMP core tool, call omp.\" + name + \"(args), e.g. omp.\" + name + \"({ ... }).\"\n );\n };\n }\n return target[property];\n },\n set() { return true; },\n deleteProperty() { return true; },\n});\nconst __ompStringFields = { bash: \"command\", read: \"path\", ls: \"path\", grep: \"pattern\", find: \"pattern\" };\n// Per-tool key aliases. The runtime normalizes them to the canonical form\n// before the host validates args; unit-converting aliases are handled separately\n// in __normalizeOmpArgs. This lets a model that writes { query, regex, ... }\n// or { file } instead of { pattern } / { path } still succeeds on the first\n// call. Keep these in sync with the OmpToolsApi overloads in guest-types.ts so\n// the type-checker accepts the same spellings it coercion-handles at runtime.\nconst __ompArgAliases = {\n bash: {\n cmd: \"command\", shell: \"command\", cmdline: \"command\", script: \"command\",\n commandLine: \"command\",\n workdir: \"cwd\", directory: \"cwd\", workingDirectory: \"cwd\",\n },\n find: {\n query: \"pattern\", regex: \"pattern\", search: \"pattern\", name: \"pattern\",\n filename: \"pattern\", glob: \"pattern\", expression: \"pattern\", include: \"pattern\",\n max: \"limit\",\n },\n grep: {\n query: \"pattern\", regex: \"pattern\", search: \"pattern\", q: \"pattern\",\n expression: \"pattern\", text: \"pattern\",\n ic: \"ignoreCase\", caseInsensitive: \"ignoreCase\",\n globPattern: \"glob\",\n ctx: \"context\",\n },\n read: {\n file: \"path\", absolutePath: \"path\", file_path: \"path\", filePath: \"path\",\n filepath: \"path\", pathname: \"path\", target_file: \"path\", targetFile: \"path\",\n absolute_path: \"path\", fileAbsolutePath: \"path\",\n max: \"limit\", start: \"offset\",\n },\n ls: {\n dir: \"path\", file: \"path\", folder: \"path\", absolutePath: \"path\",\n file_path: \"path\", filePath: \"path\", filepath: \"path\", pathname: \"path\",\n target_file: \"path\", targetFile: \"path\", absolute_path: \"path\",\n fileAbsolutePath: \"path\", directory: \"path\", directoryPath: \"path\",\n max: \"limit\",\n },\n edit: {\n file: \"path\", absolutePath: \"path\", file_path: \"path\", filePath: \"path\",\n filepath: \"path\", pathname: \"path\", target_file: \"path\", targetFile: \"path\",\n absolute_path: \"path\", fileAbsolutePath: \"path\",\n old: \"oldText\", old_string: \"oldText\", oldString: \"oldText\",\n old_str: \"oldText\", oldStr: \"oldText\", from: \"oldText\",\n old_value: \"oldText\", old_text: \"oldText\", oldContent: \"oldText\",\n old_content: \"oldText\",\n new: \"newText\", replacement: \"newText\", new_string: \"newText\",\n newString: \"newText\", new_str: \"newText\", newStr: \"newText\",\n to: \"newText\", new_value: \"newText\", new_text: \"newText\",\n newContent: \"newText\", new_content: \"newText\",\n },\n write: {\n file: \"path\", absolutePath: \"path\", file_path: \"path\", filePath: \"path\",\n filepath: \"path\", pathname: \"path\", target_file: \"path\", targetFile: \"path\",\n absolute_path: \"path\", fileAbsolutePath: \"path\",\n contents: \"content\", body: \"content\", text: \"content\", data: \"content\",\n fileContent: \"content\",\n },\n};\n// Multi-arg positional order, used only when a call passes >= 2 args and the\n// (primary, options) merge in __positionalToArgs does not apply. One-field\n// tools (read/bash/ls) stay absent: their two-arg form is a bare string plus\n// an options object, repaired by the merge instead of a wrong-arity (2554)\n// type error; only a non-object second arg still fails 2554.\nconst __ompPositionalFields = {\n grep: [\"pattern\", \"path\", \"skip\"],\n find: [\"pattern\", \"path\", \"limit\"],\n write: [\"path\", \"content\"],\n edit: [\"path\", \"oldText\", \"newText\"],\n};\n// Models often pass numbers as strings (\"20\"); coerce the known numeric\n// option fields so the host schema sees a number. Non-numeric strings pass\n// through untouched and fail host validation exactly as before. Kept in sync\n// with the numeric optionals in the OmpToolsApi overloads in guest-types.ts.\nconst __ompNumericFields = {\n read: [\"offset\", \"limit\"],\n bash: [\"timeout\"],\n grep: [\"skip\", \"context\"],\n find: [\"limit\"],\n ls: [\"limit\"],\n};\nconst __ompOptionalFields = {\n read: [\"offset\", \"limit\"],\n grep: [\"path\", \"glob\", \"ignoreCase\", \"literal\", \"context\", \"limit\"],\n find: [\"path\", \"limit\"],\n ls: [\"path\", \"limit\"],\n};\n// (primary, options) two-arg merge for the string-primary tools:\n// omp.read(\"index.ts\", { limit: 120 }) becomes { path: \"index.ts\", limit: 120 }.\n// A plain-object second arg is never a valid positional value for these tools\n// (grep/find take (pattern, path, limit) strings/numbers), so merging is\n// unambiguous; the positional string wins the primary field on conflict. The\n// merged object flows through the same alias, unit, and numeric normalization\n// in __normalizeOmpArgs as any other options object.\nconst __positionalToArgs = (name, rest) => {\n const first = rest[0];\n const second = rest[1];\n const primaryField = __ompStringFields[name];\n if (\n rest.length === 2 &&\n typeof first === \"string\" &&\n primaryField !== undefined &&\n second !== null && typeof second === \"object\" && !Array.isArray(second)\n ) {\n const merged = Object.assign({}, second);\n merged[primaryField] = first;\n return merged;\n }\n const order = __ompPositionalFields[name];\n if (!order) return rest.length > 0 ? first : {};\n const out = {};\n for (let i = 0; i < rest.length && i < order.length; i++) {\n const v = rest[i];\n if (v !== undefined) out[order[i]] = v;\n }\n return out;\n};\nconst __normalizeOmpArgs = (name, args) => {\n const field = __ompStringFields[name];\n if (typeof args === \"string\" && field) return { [field]: args };\n if (args === null || typeof args !== \"object\" || Array.isArray(args)) return args;\n const aliases = __ompArgAliases[name];\n let out = args;\n if (name === \"bash\" && \"timeoutMs\" in out) {\n out = Object.assign({}, args);\n if (!(\"timeout\" in out)) {\n const timeoutMs = out.timeoutMs;\n if (timeoutMs !== null && timeoutMs !== undefined) {\n out.timeout = Number.isFinite(Number(timeoutMs)) ? Number(timeoutMs) / 1000 : timeoutMs;\n }\n }\n delete out.timeoutMs;\n }\n // settle is a guest-only directive (settles nonzero exits instead of\n // rejecting); strip it so it never reaches the host/bash schema.\n if (name === \"bash\" && \"settle\" in out) {\n if (out === args) out = Object.assign({}, args);\n delete out.settle;\n }\n if (aliases) {\n for (const alias in aliases) {\n const canonical = aliases[alias];\n if (alias in out) {\n if (out === args) out = Object.assign({}, args);\n if (!(canonical in out)) out[canonical] = out[alias];\n delete out[alias];\n }\n }\n }\n const numerics = __ompNumericFields[name];\n if (numerics) {\n for (const key of numerics) {\n const value = out[key];\n if (typeof value === \"string\" && value.trim() !== \"\" && Number.isFinite(Number(value))) {\n if (out === args) out = Object.assign({}, args);\n out[key] = Number(value);\n }\n }\n }\n const optionalFields = __ompOptionalFields[name];\n if (optionalFields) {\n for (const key of optionalFields) {\n if (out[key] !== null && out[key] !== undefined) continue;\n if (!(key in out)) continue;\n if (out === args) out = Object.assign({}, args);\n delete out[key];\n }\n }\n if (name === \"edit\" && Array.isArray(out.edits)) {\n let changed = false;\n const editAliases = __ompArgAliases.edit;\n const edits = out.edits.map((entry) => {\n if (entry === null || typeof entry !== \"object\" || Array.isArray(entry)) return entry;\n let edit = entry;\n for (const alias in editAliases) {\n const canonical = editAliases[alias];\n if (canonical !== \"oldText\" && canonical !== \"newText\") continue;\n if (!(alias in edit)) continue;\n if (edit === entry) edit = Object.assign({}, entry);\n if (!(canonical in edit)) edit[canonical] = edit[alias];\n delete edit[alias];\n changed = true;\n }\n return edit;\n });\n if (changed) {\n if (out === args) out = Object.assign({}, args);\n out.edits = edits;\n }\n }\n if (name === \"edit\" && !Array.isArray(out.edits) && (\"oldText\" in out || \"newText\" in out)) {\n if (out === args) out = Object.assign({}, args);\n const edit = {};\n if (\"oldText\" in out) edit.oldText = out.oldText;\n if (\"newText\" in out) edit.newText = out.newText;\n out.edits = [edit];\n delete out.oldText;\n delete out.newText;\n }\n return out;\n};\n// shell/edit/write resolve envelope objects { ok, output, details }, and the\n// type-checker deliberately suppresses property-miss (2339) diagnostics, so\n// result.trim() on an envelope typechecks and then dies with QuickJS's terse\n// \"not a function\" \u2014 an error models cannot localize (observed: misdirected\n// debugging spirals probing unrelated globals). Guard envelopes with a proxy\n// that throws an actionable TypeError for string-method access and iteration,\n// naming the tool and the .output fix. Ordinary reads (ok/output/details/\n// exitCode/error), destructuring, 'in' checks, and JSON marshaling pass through.\nconst __ompEnvelopeTools = { bash: true, edit: true, write: true, wait: true };\nconst __ompEnvelopeStringTraps = new Set([\n \"anchor\", \"at\", \"big\", \"blink\", \"bold\", \"charAt\", \"charCodeAt\", \"codePointAt\",\n \"concat\", \"endsWith\", \"fixed\", \"fontcolor\", \"fontsize\", \"includes\", \"indexOf\",\n \"italics\", \"lastIndexOf\", \"length\", \"link\", \"localeCompare\", \"match\", \"matchAll\",\n \"normalize\", \"padEnd\", \"padStart\", \"repeat\", \"replace\", \"replaceAll\", \"search\",\n \"slice\", \"small\", \"split\", \"startsWith\", \"strike\", \"sub\", \"substr\", \"substring\",\n \"sup\", \"toLocaleLowerCase\", \"toLocaleUpperCase\", \"toLowerCase\", \"toUpperCase\",\n \"trim\", \"trimEnd\", \"trimStart\",\n]);\nconst __ompEnvelopeGuard = (name, value) => {\n if (value === null || typeof value !== \"object\" || typeof value.ok !== \"boolean\") return value;\n return new Proxy(value, {\n get(target, property, receiver) {\n if (property === Symbol.iterator || property === Symbol.asyncIterator) {\n throw new TypeError(\n \"omp.\" + name + \"(...) resolves an envelope { ok, output, details }, which is not iterable. \" +\n \"Iterate the text instead: (await omp.\" + name + \"(...)).output.split('\\\\n')\"\n );\n }\n if (typeof property === \"string\" && __ompEnvelopeStringTraps.has(property)) {\n throw new TypeError(\n \"omp.\" + name + \"(...) resolves an envelope { ok, output, details }, not a string, so .\" + property +\n \" is unavailable on it. Read the text first: const out = (await omp.\" + name + \"(...)).output; then out.\" + property +\n \"(...). Shell commands reject on a nonzero exit \u2014 pass settle: true to receive an ok:false envelope instead.\"\n );\n }\n return Reflect.get(target, property, receiver);\n },\n });\n};\n// The omp proxy accepts: a bare string (primary field), an options object, a\n// (primary, options) two-arg merge for the string-primary tools, or a\n// positional spread mapped by __ompPositionalFields. 0/1 args preserve the\n// legacy (args = {}) default so existing programs are unchanged.\nglobalThis.omp = new Proxy({}, {\n get(_target, property) {\n if (property === \"then\") return undefined;\n const name = String(property);\n // fabric_exec payload values are readable directly on the omp surface\n // (documented for skills as payloads.<key>), while core tool names stay\n // callables. Only shadow a payload key that actually exists.\n const payloadValues = (typeof globalThis[\"payloads\"] === \"object\" && globalThis[\"payloads\"] !== null)\n ? globalThis[\"payloads\"]\n : {};\n if (__ompToolNames.indexOf(name) < 0 && Object.prototype.hasOwnProperty.call(payloadValues, name)) {\n return payloadValues[name];\n }\n return (...rest) => {\n let args;\n if (rest.length <= 1) {\n const first = rest.length === 1 ? rest[0] : undefined;\n args = first === undefined ? {} : first;\n } else {\n args = __positionalToArgs(name, rest);\n }\n // Shell tools reject on an ordinary nonzero exit; settle:true returns\n // {ok:false, exitCode, ...} instead (opt-in). Other failures still reject.\n const settle = name === \"bash\" &&\n typeof args === \"object\" && args !== null && args.settle === true;\n const call = __call(\"omp.\" + name, __normalizeOmpArgs(name, args));\n const promise = settle ? call.catch((error) => {\n // node-process bridge errors originate in a different VM realm.\n const message = typeof error?.message === \"string\" ? error.message : String(error);\n const exit = error?.__fabricBashExit;\n if (!exit || !Number.isSafeInteger(exit.exitCode) || exit.exitCode <= 0 ||\n typeof exit.output !== \"string\") throw error;\n return {\n ok: false,\n output: exit.output,\n details: null,\n exitCode: exit.exitCode,\n error: message,\n };\n }) : call;\n return __ompEnvelopeTools[name] === true\n ? promise.then((value) => __ompEnvelopeGuard(name, value))\n : promise;\n };\n },\n});\nconst __payloads = (typeof globalThis[\"payloads\"] === \"object\" && globalThis[\"payloads\"] !== null) ? globalThis[\"payloads\"] : {};\nglobalThis[\"payloads\"] = new Proxy(__payloads, {\n get(target, property) {\n if (typeof property === \"symbol\") return undefined;\n const name = String(property);\n if (name === \"then\" || name === \"toJSON\" || name === \"constructor\") return undefined;\n if (Object.prototype.hasOwnProperty.call(target, name)) return target[name];\n if (__ompToolNames.indexOf(name) >= 0) {\n throw new Error(\n \"payloads.\" + name + \" is the payloads accessor, not a tool. For the OMP core tool, call omp.\" + name + \"(args).\"\n );\n }\n const provided = Object.keys(target);\n throw new Error(\n \"payloads.\" + name + \" is not defined. payloads only exposes keys from the fabric_exec payloads parameter\" +\n (provided.length ? \" (provided: \" + provided.join(\", \") + \")\" : \" (none provided)\") +\n \". Pass payloads: { \" + name + \": '...' } to use payloads.\" + name + \".\" +\n \" For large or quote-heavy content, keep it in top-level payloads and reference payloads.\" + name + \" instead of escaping it inside code.\"\n );\n },\n ownKeys(target) { return Reflect.ownKeys(target); },\n getOwnPropertyDescriptor(target, prop) { return Reflect.getOwnPropertyDescriptor(target, prop); },\n has(target, prop) { return Object.prototype.hasOwnProperty.call(target, prop); }\n});\n// Stable providers share a lazy dispatch proxy; the guest declarations keep\n// their known actions typed while the registry remains the runtime authority.\n// extensions' per-tool surface is additionally rendered from the captured\n// catalog by guestTypeDeclarations (runtime/dynamic-guest-types.ts).\nconst __memorySelectionKeys = [\n \"indices\",\n \"entryIds\",\n \"operationAddresses\",\n \"entryRange\",\n \"index\",\n \"entry_ids\",\n \"operation_addresses\",\n \"entry_range\",\n];\nconst __hasMemorySelection = (args) => __memorySelectionKeys.some((key) => {\n const value = args[key];\n if (Array.isArray(value)) return value.length > 0;\n return value !== undefined && value !== null;\n});\nconst __memoryWalk = async (args, visitor) => {\n if (!args || typeof args !== \"object\" || Array.isArray(args)) {\n throw new TypeError(\"memory.walk expects an expansion options object\");\n }\n if (typeof visitor !== \"function\") {\n throw new TypeError(\"memory.walk expects a visitor function as its second argument\");\n }\n\n let request = { ...args };\n if (Number(request.textOffset ?? request.text_offset ?? 0) !== 0) {\n throw new TypeError(\"memory.walk must start at text offset 0 to yield complete entries\");\n }\n if (!__hasMemorySelection(request)) {\n if (request.entryOffset !== undefined || request.entry_offset !== undefined ||\n request.textOffset !== undefined || request.text_offset !== undefined) {\n throw new TypeError(\"memory.walk continuation offsets require an explicit selection\");\n }\n if (Number(request.before ?? 0) > 0 || Number(request.after ?? 0) > 0) {\n throw new TypeError(\"memory.walk before/after requires an explicit selection\");\n }\n const head = await __call(\"memory.expand\", request);\n if (!head || typeof head !== \"object\") {\n throw new Error(\"memory.expand returned an invalid metadata response\");\n }\n if (head.error) return { visited: 0, stopped: false, error: head.error };\n if (!Number.isSafeInteger(head.entryCount) || head.entryCount < 0) {\n throw new Error(\"memory.expand metadata omitted a valid entryCount\");\n }\n if (head.entryCount === 0) return { visited: 0, stopped: false };\n request = {\n ...request,\n session: head.session ?? request.session,\n expectedSourceHash: head.sourceHash,\n expectedLineageFingerprint: head.lineageFingerprint,\n branches: head.branches,\n entryRange: { first: 0, last: head.entryCount - 1 },\n };\n }\n\n let visited = 0;\n let pending = null;\n let pendingStart = 0;\n let pendingEnd = 0;\n let pendingTotal = 0;\n const seen = new Set([JSON.stringify({ ref: \"memory.expand\", args: request })]);\n let page = await __call(\"memory.expand\", request);\n\n while (true) {\n if (!page || typeof page !== \"object\") {\n throw new Error(\"memory.expand returned an invalid page\");\n }\n if (page.error) return { visited, stopped: false, error: page.error };\n if (!Array.isArray(page.entries)) {\n throw new Error(\"memory.expand page omitted entries\");\n }\n\n for (const chunk of page.entries) {\n if (!chunk || typeof chunk !== \"object\" || typeof chunk.text !== \"string\") {\n throw new Error(\"memory.expand returned an invalid entry chunk\");\n }\n const range = chunk.textRange;\n if (!range || typeof range !== \"object\" ||\n !Number.isSafeInteger(range.start) || !Number.isSafeInteger(range.end) ||\n !Number.isSafeInteger(range.total) || range.start < 0 ||\n range.end < range.start || range.total < range.end) {\n throw new Error(\"memory.expand returned an invalid textRange\");\n }\n if (chunk.text.length !== range.end - range.start) {\n throw new Error(\"memory.expand entry chunk disagrees with textRange\");\n }\n\n if (pending === null) {\n pending = { ...chunk, text: \"\" };\n pendingStart = range.start;\n pendingEnd = range.start;\n pendingTotal = range.total;\n } else if (pending.index !== chunk.index) {\n throw new Error(\"memory.expand advanced before completing an entry\");\n }\n if (range.start !== pendingEnd || range.total !== pendingTotal) {\n throw new Error(\"memory.expand returned discontinuous entry chunks\");\n }\n for (const key of Object.keys(chunk)) {\n if (pending[key] === undefined) pending[key] = chunk[key];\n }\n pending.text += chunk.text;\n pendingEnd = range.end;\n\n if (range.complete) {\n pending.textRange = {\n start: pendingStart,\n end: pendingEnd,\n total: pendingTotal,\n complete: true,\n };\n const entry = pending;\n pending = null;\n const keepGoing = await visitor(entry, visited);\n visited += 1;\n if (keepGoing === false) return { visited, stopped: true };\n }\n }\n\n if (page.next === null || page.next === undefined) {\n if (pending !== null) {\n throw new Error(\"memory.expand ended before completing an entry\");\n }\n return { visited, stopped: false };\n }\n if (page.next.ref !== \"memory.expand\" || !page.next.args ||\n typeof page.next.args !== \"object\" || Array.isArray(page.next.args)) {\n throw new Error(\"memory.expand returned an invalid continuation\");\n }\n const continuationKey = JSON.stringify(page.next);\n if (seen.has(continuationKey)) {\n throw new Error(\"memory.expand returned a cyclic continuation\");\n }\n seen.add(continuationKey);\n page = await __call(page.next.ref, page.next.args);\n }\n};\n\nconst __proxyNames = (() => {\n const raw = globalThis.__fabricProxyNames;\n delete globalThis.__fabricProxyNames;\n return raw && typeof raw === \"object\" ? raw : {};\n})();\nconst __nameList = (value) =>\n Array.isArray(value) ? value.filter((name) => typeof name === \"string\") : [];\nconst __lazyNamespace = (names, resolve, local = {}) => new Proxy(local, {\n get(target, property) {\n if (property === \"then\" || typeof property === \"symbol\") return undefined;\n if (Object.prototype.hasOwnProperty.call(target, property)) return target[property];\n return resolve(String(property));\n },\n ownKeys(target) {\n const own = Object.keys(target);\n return names.concat(own.filter((key) => names.indexOf(key) < 0));\n },\n getOwnPropertyDescriptor(target, property) {\n if (typeof property === \"symbol\") return undefined;\n const name = String(property);\n if (names.indexOf(name) < 0 && !Object.prototype.hasOwnProperty.call(target, name)) {\n return undefined;\n }\n const value = Object.prototype.hasOwnProperty.call(target, name)\n ? target[name]\n : resolve(name);\n return { value, writable: false, enumerable: true, configurable: true };\n },\n has(target, property) {\n if (typeof property === \"symbol\") return false;\n return names.indexOf(String(property)) >= 0\n || Object.prototype.hasOwnProperty.call(target, property);\n },\n});\nconst __providerProxy = (provider, local = {}, names = []) =>\n __lazyNamespace(names, (property) => (args = {}) => __call(provider + \".\" + property, args), local);\nglobalThis.extensions = __providerProxy(\"extensions\", {}, __nameList(__proxyNames.extensions));\nglobalThis.memory = __providerProxy(\"memory\", { walk: __memoryWalk });\nglobalThis.state = __providerProxy(\"state\");\nglobalThis.schema = __providerProxy(\"schema\");\nglobalThis.components = __providerProxy(\"components\");\nglobalThis.compact = __providerProxy(\"compact\");\nglobalThis.codemap = __providerProxy(\"codemap\");\nglobalThis.judgment = __providerProxy(\"judgment\");\nconst __chunkBatchItems = (items, maxItems = 25, maxBytes = 49152) => {\n const chunks = [];\n let current = [];\n let currentBytes = 2;\n for (const item of items) {\n let serialized = \"\";\n try {\n serialized = JSON.stringify(item) ?? \"null\";\n } catch {\n serialized = JSON.stringify(String(item));\n }\n let stateItem = item;\n if (serialized.length > 40960) {\n stateItem = typeof item === \"string\"\n ? item.slice(0, 40000) + \" [truncated]\"\n : String(item).slice(0, 40000) + \" [truncated]\";\n serialized = JSON.stringify(stateItem);\n }\n const itemBytes = serialized.length + 1;\n if (current.length > 0 && (current.length >= maxItems || currentBytes + itemBytes > maxBytes)) {\n chunks.push(current);\n current = [];\n currentBytes = 2;\n }\n current.push({ item, stateItem });\n currentBytes += itemBytes;\n }\n if (current.length > 0) chunks.push(current);\n return chunks;\n};\nconst __judgeAsk = (first, second) => {\n if (second !== undefined) {\n return globalThis.judgment.ask({ state: first, questions: second });\n }\n return globalThis.judgment.ask(first);\n};\nconst __judgeBool = async (state, instructions, options) => {\n try {\n const outcome = await globalThis.judgment.ask({\n state,\n questions: { q: { type: \"bool\", instructions: String(instructions) } },\n });\n if (outcome && outcome.ok && outcome.answers && outcome.answers.q && outcome.answers.q.type === \"bool\" && typeof outcome.answers.q.bool === \"number\") {\n return outcome.answers.q.bool;\n }\n } catch {}\n return options && typeof options.fallback === \"number\" ? options.fallback : undefined;\n};\nconst __judgeChoice = async (state, optionsListOrCriteria, instructions, config) => {\n let criteria = {};\n if (Array.isArray(optionsListOrCriteria)) {\n for (const opt of optionsListOrCriteria) criteria[String(opt)] = null;\n } else if (optionsListOrCriteria && typeof optionsListOrCriteria === \"object\") {\n criteria = optionsListOrCriteria;\n } else {\n throw new TypeError(\"judge.choice options must be an array or criteria object\");\n }\n if (Object.keys(criteria).length < 2) {\n throw new TypeError(\"judge.choice requires at least 2 unique options\");\n }\n try {\n const outcome = await globalThis.judgment.ask({\n state,\n questions: { q: { type: \"choice\", instructions: String(instructions), criteria } },\n });\n if (outcome && outcome.ok && outcome.answers && outcome.answers.q && outcome.answers.q.type === \"choice\" && typeof outcome.answers.q.choice === \"string\") {\n return outcome.answers.q.choice;\n }\n } catch {}\n return config && typeof config.fallback === \"string\" ? config.fallback : undefined;\n};\nconst __judgeScore = async (state, criteria, instructions, config) => {\n if (!Array.isArray(criteria) || criteria.length < 2) {\n throw new TypeError(\"judge.score requires at least 2 ordered criteria levels\");\n }\n try {\n const outcome = await globalThis.judgment.ask({\n state,\n questions: { q: { type: \"score\", instructions: String(instructions), criteria } },\n });\n if (outcome && outcome.ok && outcome.answers && outcome.answers.q && outcome.answers.q.type === \"score\" && typeof outcome.answers.q.score === \"number\") {\n return outcome.answers.q.score;\n }\n } catch {}\n return config && typeof config.fallback === \"number\" ? config.fallback : undefined;\n};\nconst __judgeFilter = async (items, instructions, options = {}) => {\n if (!Array.isArray(items) || items.length === 0) return [];\n const threshold = Number.isFinite(options.threshold) ? options.threshold : 0.7;\n const onFail = options.onFail || \"keep-all\";\n const chunks = __chunkBatchItems(items, options.maxItems || 25, options.maxBytes || 49152);\n const chunkPromises = chunks.map(async (chunk) => {\n const questions = {};\n chunk.forEach((_, idx) => {\n questions[\"item_\" + idx] = {\n type: \"bool\",\n instructions: \"Regarding items[\" + idx + \"]: \" + String(instructions),\n };\n });\n let outcome;\n try {\n outcome = await globalThis.judgment.ask({ state: { items: chunk.map((c) => c.stateItem) }, questions });\n } catch (err) {\n outcome = { ok: false, reason: \"failed\", detail: String(err && err.message ? err.message : err) };\n }\n if (!outcome || !outcome.ok) {\n if (onFail === \"throw\") {\n throw new Error(\"judge.filter failed: \" + (outcome && outcome.reason ? outcome.reason : \"unknown error\") + (outcome && outcome.detail ? \" (\" + outcome.detail + \")\" : \"\"));\n }\n return onFail === \"empty\" ? [] : chunk.map((c) => c.item);\n }\n return chunk\n .filter((_, idx) => {\n const ans = outcome.answers && outcome.answers[\"item_\" + idx];\n return ans && ans.type === \"bool\" && typeof ans.bool === \"number\" && ans.bool >= threshold;\n })\n .map((c) => c.item);\n });\n const results = await Promise.all(chunkPromises);\n return results.flat();\n};\nconst __judgeClassify = async (items, categories, instructions, options = {}) => {\n if (!Array.isArray(items) || items.length === 0) return [];\n if (!Array.isArray(categories) || categories.length < 2) {\n throw new TypeError(\"judge.classify requires at least 2 categories\");\n }\n const criteria = {};\n for (const cat of categories) criteria[String(cat)] = null;\n const onFail = options.onFail || \"keep-all\";\n const chunks = __chunkBatchItems(items, options.maxItems || 25, options.maxBytes || 49152);\n const chunkPromises = chunks.map(async (chunk) => {\n const questions = {};\n chunk.forEach((_, idx) => {\n questions[\"item_\" + idx] = {\n type: \"choice\",\n instructions: \"Regarding items[\" + idx + \"]: \" + String(instructions),\n criteria,\n };\n });\n let outcome;\n try {\n outcome = await globalThis.judgment.ask({ state: { items: chunk.map((c) => c.stateItem) }, questions });\n } catch (err) {\n outcome = { ok: false, reason: \"failed\", detail: String(err && err.message ? err.message : err) };\n }\n if (!outcome || !outcome.ok) {\n if (onFail === \"throw\") {\n throw new Error(\"judge.classify failed: \" + (outcome && outcome.reason ? outcome.reason : \"unknown error\") + (outcome && outcome.detail ? \" (\" + outcome.detail + \")\" : \"\"));\n }\n if (onFail === \"empty\") return [];\n return chunk.map((c) => ({ item: c.item, category: options.fallbackCategory, confidence: undefined }));\n }\n return chunk.map((c, idx) => {\n const ans = outcome.answers && outcome.answers[\"item_\" + idx];\n const category = ans && ans.type === \"choice\" && typeof ans.choice === \"string\" ? ans.choice : options.fallbackCategory;\n const confidence = ans && typeof ans.confidence === \"number\" ? ans.confidence : undefined;\n return { item: c.item, category, confidence };\n });\n });\n const results = await Promise.all(chunkPromises);\n return results.flat();\n};\nglobalThis.judge = Object.freeze({\n ask: __judgeAsk,\n bool: __judgeBool,\n choice: __judgeChoice,\n score: __judgeScore,\n filter: __judgeFilter,\n classify: __judgeClassify,\n});\nconst __createActor = async (args = {}) => {\n if (!args || typeof args !== \"object\" || Array.isArray(args)) {\n throw new TypeError(\"agents.create expects an options object\");\n }\n const request = { ...args };\n const validWhile = request.validWhile;\n if (validWhile !== undefined) {\n if (typeof validWhile !== \"function\") {\n throw new TypeError(\"agents.create validWhile must be a pure predicate function\");\n }\n const source = Function.prototype.toString.call(validWhile);\n if (source.trimStart().startsWith(\"async\")) {\n throw new TypeError(\"agents.create validWhile must be synchronous\");\n }\n request.validWhile = { version: 1, source };\n }\n return __call(\"agents.create\", request);\n};\nconst __handoff = async (args = {}) => {\n if (!args || typeof args !== \"object\" || Array.isArray(args)) {\n throw new TypeError(\"agents.handoff expects an options object\");\n }\n const request = { ...args };\n const when = request.when;\n delete request.when;\n if (when !== undefined) {\n if (typeof when !== \"function\") {\n throw new TypeError(\"agents.handoff when must be a pure predicate function\");\n }\n const decision = when(__handoffFacts());\n if (decision && typeof decision.then === \"function\") {\n throw new TypeError(\"agents.handoff when must return a boolean synchronously\");\n }\n if (decision !== true) {\n throw new Error(\"agents.handoff predicate returned false; no agent was started\");\n }\n }\n return __call(\"agents.handoff\", request);\n};\nglobalThis.agents = Object.freeze({\n run: (args) => __call(\"agents.run\", args),\n handoff: __handoff,\n spawn: (args) => __call(\"agents.spawn\", args),\n wait: (args) => __call(\"agents.wait\", args),\n status: (args) => __call(\"agents.status\", args),\n list: (args = {}) => __call(\"agents.list\", args),\n members: (args = {}) => __call(\"agents.members\", args),\n self: () => __call(\"agents.self\", {}),\n main: () => __call(\"agents.main\", {}),\n peers: () => __call(\"agents.peers\", {}),\n subscribe: (args) => __call(\"agents.subscribe\", args),\n subscriptions: (args = {}) => __call(\"agents.subscriptions\", args),\n unsubscribe: (args) => __call(\"agents.unsubscribe\", args),\n models: (args = {}) => __call(\"agents.models\", args),\n stop: (args) => __call(\"agents.stop\", args),\n cleanup: (args) => __call(\"agents.cleanup\", args),\n create: __createActor,\n ask: (args) => __call(\"agents.ask\", args),\n tell: (args) => __call(\"agents.tell\", args),\n steer: (args) => __call(\"agents.steer\", args),\n followUp: (args) => __call(\"agents.followUp\", args),\n setSteeringMode: (args) => __call(\"agents.setSteeringMode\", args),\n setFollowUpMode: (args) => __call(\"agents.setFollowUpMode\", args),\n actorStatus: (args) => __call(\"agents.actorStatus\", args),\n setModel: (args) => __call(\"agents.setModel\", args),\n switchModel: (args) => __call(\"agents.switchModel\", args),\n setThinking: (args) => __call(\"agents.setThinking\", args),\n setEvents: (args) => __call(\"agents.setEvents\", args),\n setInstructions: (args) => __call(\"agents.setInstructions\", args),\n actors: () => __call(\"agents.actors\", {}),\n messages: (args) => __call(\"agents.messages\", args),\n remove: (args) => __call(\"agents.remove\", args),\n log: (args) => __call(\"agents.log\", args),\n});\nglobalThis.mesh = Object.freeze({\n self: () => __call(\"mesh.self\", {}),\n publish: (args) => __call(\"mesh.publish\", args),\n read: (args = {}) => __call(\"mesh.read\", args),\n members: (args = {}) => __call(\"mesh.members\", args),\n get: (args) => __call(\"mesh.get\", args),\n list: (args = {}) => __call(\"mesh.list\", args),\n put: (args) => __call(\"mesh.put\", args),\n delete: (args) => __call(\"mesh.delete\", args),\n});\n// The mcp proxy itself stays schema-less \u2014 the registry validates args at\n// dispatch \u2014 but guestTypeDeclarations renders per-server argument types from\n// the live descriptor cache (runtime/dynamic-guest-types.ts), so known tools\n// fail type-check on argument-shape mistakes before this proxy ever runs.\nconst __mcpServerTools = (() => {\n const raw = __proxyNames.mcp;\n const out = {};\n if (raw && typeof raw === \"object\") {\n for (const server of Object.keys(raw)) out[server] = __nameList(raw[server]);\n }\n return out;\n})();\nconst __mcpManagement = {\n servers: () => __call(\"mcp.$servers\", {}),\n reload: () => __call(\"mcp.$reload\", {}),\n register: (args) => __call(\"mcp.$register\", args),\n call: (args) => __call(\"mcp.$call\", args),\n};\nglobalThis.mcp = __lazyNamespace(\n Object.keys(__mcpServerTools).sort(),\n (server) => __lazyNamespace(\n __mcpServerTools[server] ? __mcpServerTools[server].slice().sort() : [],\n (tool) => (args = {}) => __call(\"mcp.\" + server + \".\" + tool, args),\n ),\n __mcpManagement,\n);\nlet __workflowSpentTokens = 0;\nconst __workflowBudgetTotal = Number.isFinite(globalThis.__fabricTokenBudget)\n ? Math.max(0, globalThis.__fabricTokenBudget)\n : Number.POSITIVE_INFINITY;\nconst __recordAgentUsage = (result) => {\n const usage = result && result.usage;\n if (usage) __workflowSpentTokens += Number(usage.input || 0) + Number(usage.output || 0);\n return result;\n};\nconst __workflowAgent = async (prompt, options = {}) => {\n if (__workflowSpentTokens >= __workflowBudgetTotal) {\n throw new Error(\"Fabric workflow token budget exhausted\");\n }\n const { label, ...agentOptions } = options;\n const workerName = String(label || agentOptions.name || \"Fabric workflow agent\");\n const result = __recordAgentUsage(await agents.run({\n ...agentOptions,\n ...(label && !agentOptions.name ? { name: label } : {}),\n task: prompt,\n }));\n if (!result || result.status !== \"completed\") {\n const reason = result && result.error ? result.error : \"agent did not complete\";\n throw new Error(workerName + \" failed: \" + reason);\n }\n return result.value !== undefined ? result.value : result.text;\n};\n// Budget-aware agents.run used by council.run and rlm.query so their usage is\n// counted in budget.spent() and the tokenBudget guard can preempt them, just\n// like workflow.agent(). Without this, councils bypass the budget entirely.\nconst __budgetedRun = async (args) => {\n if (__workflowSpentTokens >= __workflowBudgetTotal) {\n throw new Error(\"Fabric workflow token budget exhausted\");\n }\n return __recordAgentUsage(await agents.run(args));\n};\nlet __nextWorkflowSpanId = 0;\nconst __workflowSpanMetadata = (kind, items, options, stageCount) => {\n const itemCount = Array.isArray(items) ? items.length : undefined;\n let concurrency;\n if (kind === \"parallel\" && itemCount !== undefined) {\n if (itemCount === 0) concurrency = 0;\n else {\n const concurrencyOpt = typeof options === \"number\" ? { concurrency: options } : options ?? {};\n const requested = Number(concurrencyOpt.concurrency ?? itemCount);\n if (Number.isFinite(requested) && requested >= 1) {\n concurrency = Math.max(1, Math.min(itemCount, Math.floor(requested)));\n }\n }\n }\n return {\n kind,\n ...(itemCount !== undefined ? { itemCount } : {}),\n ...(stageCount !== undefined ? { stageCount } : {}),\n ...(concurrency !== undefined ? { concurrency } : {}),\n };\n};\nconst __withWorkflowSpan = async (metadata, body) => {\n const id = \"span-\" + __nextWorkflowSpanId++;\n await __call(\"fabric.$spanStart\", { id, ...metadata });\n try {\n const value = await body();\n await __call(\"fabric.$spanEnd\", { id, outcome: \"succeeded\" });\n return value;\n } catch (error) {\n try { await __call(\"fabric.$spanEnd\", { id, outcome: \"failed\" }); } catch { /* preserve the workflow error */ }\n throw error;\n }\n};\nconst __runParallel = async (thunks, options) => {\n if (!Array.isArray(thunks) || thunks.some((thunk) => typeof thunk !== \"function\")) {\n throw new TypeError(\"workflow.parallel expects an array of functions or (items, mapper)\");\n }\n if (thunks.length === 0) return [];\n const concurrencyOpt = typeof options === \"number\" ? { concurrency: options } : options ?? {};\n const requestedConcurrency = Number(concurrencyOpt.concurrency ?? thunks.length);\n if (!Number.isFinite(requestedConcurrency) || requestedConcurrency < 1) {\n throw new RangeError(\"workflow.parallel concurrency must be a positive finite number\");\n }\n const concurrency = Math.max(1, Math.min(thunks.length || 1, Math.floor(requestedConcurrency)));\n const results = new Array(thunks.length);\n let cursor = 0;\n await Promise.all(Array.from({ length: concurrency }, async () => {\n while (cursor < thunks.length) {\n const index = cursor++;\n results[index] = await thunks[index]();\n }\n }));\n return results;\n};\nconst __workflowParallel = async (items, arg2, arg3) => {\n const options = typeof arg2 === \"function\" ? arg3 : arg2;\n return __withWorkflowSpan(\n __workflowSpanMetadata(\"parallel\", items, options),\n async () => {\n if (typeof arg2 === \"function\") {\n if (!Array.isArray(items)) throw new TypeError(\"workflow.parallel expects an array as the first argument\");\n return __runParallel(items.map((item, index) => () => arg2(item, index)), arg3);\n }\n return __runParallel(items, arg2);\n },\n );\n};\nconst __workflowPipeline = async (items, ...stages) =>\n __withWorkflowSpan(\n __workflowSpanMetadata(\"pipeline\", items, undefined, stages.length),\n async () => {\n if (!Array.isArray(items) || stages.some((stage) => typeof stage !== \"function\")) {\n throw new TypeError(\"workflow.pipeline expects an array followed by stage functions\");\n }\n return __workflowParallel(items.map((original, index) => async () => {\n let value = original;\n for (const stage of stages) value = await stage(value, original, index);\n return value;\n }));\n },\n );\nglobalThis.workflow = Object.freeze({\n agent: __workflowAgent,\n parallel: __workflowParallel,\n pipeline: __workflowPipeline,\n configure: (args) => __call(\"fabric.$configure\", args),\n phase: (nameOrInput, options = {}) => {\n const input =\n nameOrInput && typeof nameOrInput === \"object\" && !Array.isArray(nameOrInput)\n ? { ...nameOrInput }\n : { ...options, name: nameOrInput };\n return __call(\"fabric.$phase\", input);\n },\n item: (args) => __call(\"fabric.$item\", args),\n event: (args) => __call(\"fabric.$event\", args),\n log: (...values) => print(...values),\n budget: Object.freeze({\n total: __workflowBudgetTotal,\n spent: () => __workflowSpentTokens,\n remaining: () => Math.max(0, __workflowBudgetTotal - __workflowSpentTokens),\n }),\n});\nglobalThis.agent = __workflowAgent;\nglobalThis.parallel = __workflowParallel;\nglobalThis.pipeline = __workflowPipeline;\nglobalThis.phase = workflow.phase;\nglobalThis.log = workflow.log;\nglobalThis.budget = workflow.budget;\nglobalThis.rlm = Object.freeze({\n query: (args) => {\n if (args && args.runner && args.runner !== \"omp\") {\n throw new Error(\"rlm.query requires the OMP runner because recursive Fabric is unavailable in Claude Code\");\n }\n return __budgetedRun({ ...args, runner: \"omp\", recursive: true });\n },\n});\nglobalThis.council = Object.freeze({\n async run(args) {\n const { task, roles, synthesize = true, ...agentOptions } = args;\n const results = await Promise.all(roles.map((role) => __budgetedRun({\n ...agentOptions,\n name: role,\n task: \"Act as the \" + role + \" council member. Independently analyze this task:\\n\\n\" + task,\n })));\n if (!synthesize) return results;\n return __budgetedRun({\n ...agentOptions,\n name: \"council-synthesizer\",\n task: \"Synthesize the council's independent reports into one decision. Preserve disagreements and cite which role raised each concern.\\n\\nTask:\\n\" + task + \"\\n\\nReports:\\n\" + JSON.stringify(results),\n });\n },\n});\nglobalThis.console = Object.freeze({ log: print, info: print, warn: print, error: print });\nconst __timerCallbacks = new Map();\nlet __nextTimerId = 1;\nglobalThis.setTimeout = (callback, ms = 0) => {\n const id = __nextTimerId++;\n __timerCallbacks.set(id, { callback, interval: false });\n __call(\"fabric.$timer\", { ms }).then(() => {\n const entry = __timerCallbacks.get(id);\n if (!entry) return;\n __timerCallbacks.delete(id);\n try { entry.callback(); } catch { /* swallow timer callback errors */ }\n });\n return id;\n};\nglobalThis.setInterval = (callback, ms = 0) => {\n const id = __nextTimerId++;\n __timerCallbacks.set(id, { callback, interval: true });\n const schedule = () => {\n __call(\"fabric.$timer\", { ms }).then(() => {\n const entry = __timerCallbacks.get(id);\n if (!entry) return;\n try { entry.callback(); } catch { /* swallow timer callback errors */ }\n if (__timerCallbacks.has(id)) schedule();\n });\n };\n schedule();\n return id;\n};\nglobalThis.clearTimeout = (id) => { __timerCallbacks.delete(id); };\nglobalThis.clearInterval = (id) => { __timerCallbacks.delete(id); };\n})();\n";
|
|
25
|
+
export declare const GUEST_SETUP = "\n(() => {\nconst __fabricBridge = globalThis.__fabricHostCall;\ndelete globalThis.__fabricHostCall;\nconst __successfulCalls = [];\nconst __resolvedCallRef = (ref, args) =>\n ref === \"fabric.$call\" && args && typeof args.ref === \"string\" ? args.ref : ref;\nconst __recordSuccessfulCall = (ref, args) => {\n __successfulCalls.push(Object.freeze({ ref: __resolvedCallRef(ref, args) }));\n};\nconst __handoffFacts = () => {\n const calls = Object.freeze(__successfulCalls.slice());\n const count = (ref) => {\n if (ref === undefined) return calls.length;\n const refs = new Set(Array.isArray(ref) ? ref : [ref]);\n return calls.reduce((total, call) => total + (refs.has(call.ref) ? 1 : 0), 0);\n };\n return Object.freeze({ calls, count });\n};\nconst __call = async (ref, args) => {\n const normalizedArgs = args ?? {};\n const value = await __fabricBridge(ref, normalizedArgs);\n __recordSuccessfulCall(ref, normalizedArgs);\n return value;\n};\nconst __ompToolNames = [\"read\",\"bash\",\"edit\",\"write\",\"grep\",\"find\",\"ls\",\"wait\"];\nconst __toolsBase = {\n providers: () => __call(\"fabric.$providers\", {}),\n catalog: (args = {}) => __call(\"fabric.$catalog\", args),\n list: (args = {}) => __call(\"fabric.$list\", args),\n search: (args) => __call(\n \"fabric.$search\",\n typeof args === \"string\" ? { query: args } : args,\n ),\n describe: (args) => __call(\"fabric.$describe\", args),\n call: (args) => __call(\"fabric.$call\", args),\n progress: (args) => __call(\"fabric.$progress\", args),\n models: () => __call(\"fabric.$models\", {}),\n};\n// tools is discovery + generic calls only. The proxy keeps the seven discovery\n// methods and turns a core-tool name (read/bash/edit/...) into an actionable\n// error pointing at omp.<name>, so a model that writes tools.read(...) learns\n// the fix in one turn instead of looping on \"tools.read is not a function\".\nglobalThis.tools = new Proxy(__toolsBase, {\n get(target, property) {\n if (property === \"then\" || typeof property === \"symbol\") return undefined;\n const name = String(property);\n if (__ompToolNames.indexOf(name) >= 0) {\n return () => {\n throw new Error(\n \"tools.\" + name + \" is not available on the discovery API. tools is discovery + generic calls only (providers/catalog/list/search/describe/call/models). For the OMP core tool, call omp.\" + name + \"(args), e.g. omp.\" + name + \"({ ... }).\"\n );\n };\n }\n return target[property];\n },\n set() { return true; },\n deleteProperty() { return true; },\n});\nconst __ompStringFields = { bash: \"command\", read: \"path\", ls: \"path\", grep: \"pattern\", find: \"pattern\" };\n// Per-tool key aliases. The runtime normalizes them to the canonical form\n// before the host validates args; unit-converting aliases are handled separately\n// in __normalizeOmpArgs. This lets a model that writes { query, regex, ... }\n// or { file } instead of { pattern } / { path } still succeeds on the first\n// call. Keep these in sync with the OmpToolsApi overloads in guest-types.ts so\n// the type-checker accepts the same spellings it coercion-handles at runtime.\nconst __ompArgAliases = {\n bash: {\n cmd: \"command\", shell: \"command\", cmdline: \"command\", script: \"command\",\n commandLine: \"command\",\n workdir: \"cwd\", directory: \"cwd\", workingDirectory: \"cwd\",\n },\n find: {\n query: \"pattern\", regex: \"pattern\", search: \"pattern\", name: \"pattern\",\n filename: \"pattern\", glob: \"pattern\", expression: \"pattern\", include: \"pattern\",\n max: \"limit\",\n },\n grep: {\n query: \"pattern\", regex: \"pattern\", search: \"pattern\", q: \"pattern\",\n expression: \"pattern\", text: \"pattern\",\n ic: \"ignoreCase\", caseInsensitive: \"ignoreCase\",\n globPattern: \"glob\",\n ctx: \"context\",\n },\n read: {\n file: \"path\", absolutePath: \"path\", file_path: \"path\", filePath: \"path\",\n filepath: \"path\", pathname: \"path\", target_file: \"path\", targetFile: \"path\",\n absolute_path: \"path\", fileAbsolutePath: \"path\",\n max: \"limit\", start: \"offset\",\n },\n ls: {\n dir: \"path\", file: \"path\", folder: \"path\", absolutePath: \"path\",\n file_path: \"path\", filePath: \"path\", filepath: \"path\", pathname: \"path\",\n target_file: \"path\", targetFile: \"path\", absolute_path: \"path\",\n fileAbsolutePath: \"path\", directory: \"path\", directoryPath: \"path\",\n max: \"limit\",\n },\n edit: {\n file: \"path\", absolutePath: \"path\", file_path: \"path\", filePath: \"path\",\n filepath: \"path\", pathname: \"path\", target_file: \"path\", targetFile: \"path\",\n absolute_path: \"path\", fileAbsolutePath: \"path\",\n old: \"oldText\", old_string: \"oldText\", oldString: \"oldText\",\n old_str: \"oldText\", oldStr: \"oldText\", from: \"oldText\",\n old_value: \"oldText\", old_text: \"oldText\", oldContent: \"oldText\",\n old_content: \"oldText\",\n new: \"newText\", replacement: \"newText\", new_string: \"newText\",\n newString: \"newText\", new_str: \"newText\", newStr: \"newText\",\n to: \"newText\", new_value: \"newText\", new_text: \"newText\",\n newContent: \"newText\", new_content: \"newText\",\n },\n write: {\n file: \"path\", absolutePath: \"path\", file_path: \"path\", filePath: \"path\",\n filepath: \"path\", pathname: \"path\", target_file: \"path\", targetFile: \"path\",\n absolute_path: \"path\", fileAbsolutePath: \"path\",\n contents: \"content\", body: \"content\", text: \"content\", data: \"content\",\n fileContent: \"content\",\n },\n};\n// Multi-arg positional order, used only when a call passes >= 2 args and the\n// (primary, options) merge in __positionalToArgs does not apply. One-field\n// tools (read/bash/ls) stay absent: their two-arg form is a bare string plus\n// an options object, repaired by the merge instead of a wrong-arity (2554)\n// type error; only a non-object second arg still fails 2554.\nconst __ompPositionalFields = {\n grep: [\"pattern\", \"path\", \"skip\"],\n find: [\"pattern\", \"path\", \"limit\"],\n write: [\"path\", \"content\"],\n edit: [\"path\", \"oldText\", \"newText\"],\n};\n// Models often pass numbers as strings (\"20\"); coerce the known numeric\n// option fields so the host schema sees a number. Non-numeric strings pass\n// through untouched and fail host validation exactly as before. Kept in sync\n// with the numeric optionals in the OmpToolsApi overloads in guest-types.ts.\nconst __ompNumericFields = {\n read: [\"offset\", \"limit\"],\n bash: [\"timeout\"],\n grep: [\"skip\", \"context\", \"limit\"],\n find: [\"limit\"],\n ls: [\"limit\"],\n};\nconst __ompOptionalFields = {\n read: [\"offset\", \"limit\"],\n grep: [\"path\", \"glob\", \"ignoreCase\", \"literal\", \"context\", \"limit\"],\n find: [\"path\", \"limit\"],\n ls: [\"path\", \"limit\"],\n};\n// (primary, options) two-arg merge for the string-primary tools:\n// omp.read(\"index.ts\", { limit: 120 }) becomes { path: \"index.ts\", limit: 120 }.\n// A plain-object second arg is never a valid positional value for these tools\n// (grep/find take (pattern, path, limit) strings/numbers), so merging is\n// unambiguous; the positional string wins the primary field on conflict. The\n// merged object flows through the same alias, unit, and numeric normalization\n// in __normalizeOmpArgs as any other options object.\nconst __positionalToArgs = (name, rest) => {\n const first = rest[0];\n const second = rest[1];\n const primaryField = __ompStringFields[name];\n if (\n rest.length === 2 &&\n typeof first === \"string\" &&\n primaryField !== undefined &&\n second !== null && typeof second === \"object\" && !Array.isArray(second)\n ) {\n const merged = Object.assign({}, second);\n merged[primaryField] = first;\n return merged;\n }\n const order = __ompPositionalFields[name];\n if (!order) return rest.length > 0 ? first : {};\n const out = {};\n for (let i = 0; i < rest.length && i < order.length; i++) {\n const v = rest[i];\n if (v !== undefined) out[order[i]] = v;\n }\n return out;\n};\nconst __normalizeOmpArgs = (name, args) => {\n const field = __ompStringFields[name];\n if (typeof args === \"string\" && field) return { [field]: args };\n if (args === null || typeof args !== \"object\" || Array.isArray(args)) return args;\n const aliases = __ompArgAliases[name];\n let out = args;\n if (name === \"bash\" && \"timeoutMs\" in out) {\n out = Object.assign({}, args);\n if (!(\"timeout\" in out)) {\n const timeoutMs = out.timeoutMs;\n if (timeoutMs !== null && timeoutMs !== undefined) {\n out.timeout = Number.isFinite(Number(timeoutMs)) ? Number(timeoutMs) / 1000 : timeoutMs;\n }\n }\n delete out.timeoutMs;\n }\n // settle is a guest-only directive (settles nonzero exits instead of\n // rejecting); strip it so it never reaches the host/bash schema.\n if (name === \"bash\" && \"settle\" in out) {\n if (out === args) out = Object.assign({}, args);\n delete out.settle;\n }\n if (aliases) {\n for (const alias in aliases) {\n const canonical = aliases[alias];\n if (alias in out) {\n if (out === args) out = Object.assign({}, args);\n if (!(canonical in out)) out[canonical] = out[alias];\n delete out[alias];\n }\n }\n }\n const numerics = __ompNumericFields[name];\n if (numerics) {\n for (const key of numerics) {\n const value = out[key];\n if (typeof value === \"string\" && value.trim() !== \"\" && Number.isFinite(Number(value))) {\n if (out === args) out = Object.assign({}, args);\n out[key] = Number(value);\n }\n }\n }\n const optionalFields = __ompOptionalFields[name];\n if (optionalFields) {\n for (const key of optionalFields) {\n if (out[key] !== null && out[key] !== undefined) continue;\n if (!(key in out)) continue;\n if (out === args) out = Object.assign({}, args);\n delete out[key];\n }\n }\n if (name === \"edit\" && Array.isArray(out.edits)) {\n let changed = false;\n const editAliases = __ompArgAliases.edit;\n const edits = out.edits.map((entry) => {\n if (entry === null || typeof entry !== \"object\" || Array.isArray(entry)) return entry;\n let edit = entry;\n for (const alias in editAliases) {\n const canonical = editAliases[alias];\n if (canonical !== \"oldText\" && canonical !== \"newText\") continue;\n if (!(alias in edit)) continue;\n if (edit === entry) edit = Object.assign({}, entry);\n if (!(canonical in edit)) edit[canonical] = edit[alias];\n delete edit[alias];\n changed = true;\n }\n return edit;\n });\n if (changed) {\n if (out === args) out = Object.assign({}, args);\n out.edits = edits;\n }\n }\n if (name === \"edit\" && !Array.isArray(out.edits) && (\"oldText\" in out || \"newText\" in out)) {\n if (out === args) out = Object.assign({}, args);\n const edit = {};\n if (\"oldText\" in out) edit.oldText = out.oldText;\n if (\"newText\" in out) edit.newText = out.newText;\n out.edits = [edit];\n delete out.oldText;\n delete out.newText;\n }\n return out;\n};\n// shell/edit/write resolve envelope objects { ok, output, details }, and the\n// type-checker deliberately suppresses property-miss (2339) diagnostics, so\n// result.trim() on an envelope typechecks and then dies with QuickJS's terse\n// \"not a function\" \u2014 an error models cannot localize (observed: misdirected\n// debugging spirals probing unrelated globals). Guard envelopes with a proxy\n// that throws an actionable TypeError for string-method access and iteration,\n// naming the tool and the .output fix. Ordinary reads (ok/output/details/\n// exitCode/error), destructuring, 'in' checks, and JSON marshaling pass through.\nconst __ompEnvelopeTools = { bash: true, edit: true, write: true, wait: true };\nconst __ompEnvelopeStringTraps = new Set([\n \"anchor\", \"at\", \"big\", \"blink\", \"bold\", \"charAt\", \"charCodeAt\", \"codePointAt\",\n \"concat\", \"endsWith\", \"fixed\", \"fontcolor\", \"fontsize\", \"includes\", \"indexOf\",\n \"italics\", \"lastIndexOf\", \"length\", \"link\", \"localeCompare\", \"match\", \"matchAll\",\n \"normalize\", \"padEnd\", \"padStart\", \"repeat\", \"replace\", \"replaceAll\", \"search\",\n \"slice\", \"small\", \"split\", \"startsWith\", \"strike\", \"sub\", \"substr\", \"substring\",\n \"sup\", \"toLocaleLowerCase\", \"toLocaleUpperCase\", \"toLowerCase\", \"toUpperCase\",\n \"trim\", \"trimEnd\", \"trimStart\",\n]);\nconst __ompEnvelopeGuard = (name, value) => {\n if (value === null || typeof value !== \"object\" || typeof value.ok !== \"boolean\") return value;\n return new Proxy(value, {\n get(target, property, receiver) {\n if (property === Symbol.iterator || property === Symbol.asyncIterator) {\n throw new TypeError(\n \"omp.\" + name + \"(...) resolves an envelope { ok, output, details }, which is not iterable. \" +\n \"Iterate the text instead: (await omp.\" + name + \"(...)).output.split('\\\\n')\"\n );\n }\n if (typeof property === \"string\" && __ompEnvelopeStringTraps.has(property)) {\n throw new TypeError(\n \"omp.\" + name + \"(...) resolves an envelope { ok, output, details }, not a string, so .\" + property +\n \" is unavailable on it. Read the text first: const out = (await omp.\" + name + \"(...)).output; then out.\" + property +\n \"(...). Shell commands reject on a nonzero exit \u2014 pass settle: true to receive an ok:false envelope instead.\"\n );\n }\n return Reflect.get(target, property, receiver);\n },\n });\n};\n// The omp proxy accepts: a bare string (primary field), an options object, a\n// (primary, options) two-arg merge for the string-primary tools, or a\n// positional spread mapped by __ompPositionalFields. 0/1 args preserve the\n// legacy (args = {}) default so existing programs are unchanged.\nglobalThis.omp = new Proxy({}, {\n get(_target, property) {\n if (property === \"then\") return undefined;\n const name = String(property);\n // fabric_exec payload values are readable directly on the omp surface\n // (documented for skills as payloads.<key>), while core tool names stay\n // callables. Only shadow a payload key that actually exists.\n const payloadValues = (typeof globalThis[\"payloads\"] === \"object\" && globalThis[\"payloads\"] !== null)\n ? globalThis[\"payloads\"]\n : {};\n if (__ompToolNames.indexOf(name) < 0 && Object.prototype.hasOwnProperty.call(payloadValues, name)) {\n return payloadValues[name];\n }\n return (...rest) => {\n let args;\n if (rest.length <= 1) {\n const first = rest.length === 1 ? rest[0] : undefined;\n args = first === undefined ? {} : first;\n } else {\n args = __positionalToArgs(name, rest);\n }\n // Shell tools reject on an ordinary nonzero exit; settle:true returns\n // {ok:false, exitCode, ...} instead (opt-in). Other failures still reject.\n const settle = name === \"bash\" &&\n typeof args === \"object\" && args !== null && args.settle === true;\n const call = __call(\"omp.\" + name, __normalizeOmpArgs(name, args));\n const promise = settle ? call.catch((error) => {\n // node-process bridge errors originate in a different VM realm.\n const message = typeof error?.message === \"string\" ? error.message : String(error);\n const exit = error?.__fabricBashExit;\n if (!exit || !Number.isSafeInteger(exit.exitCode) || exit.exitCode <= 0 ||\n typeof exit.output !== \"string\") throw error;\n return {\n ok: false,\n output: exit.output,\n details: null,\n exitCode: exit.exitCode,\n error: message,\n };\n }) : call;\n return __ompEnvelopeTools[name] === true\n ? promise.then((value) => __ompEnvelopeGuard(name, value))\n : promise;\n };\n },\n});\nconst __payloads = (typeof globalThis[\"payloads\"] === \"object\" && globalThis[\"payloads\"] !== null) ? globalThis[\"payloads\"] : {};\nglobalThis[\"payloads\"] = new Proxy(__payloads, {\n get(target, property) {\n if (typeof property === \"symbol\") return undefined;\n const name = String(property);\n if (name === \"then\" || name === \"toJSON\" || name === \"constructor\") return undefined;\n if (Object.prototype.hasOwnProperty.call(target, name)) return target[name];\n if (__ompToolNames.indexOf(name) >= 0) {\n throw new Error(\n \"payloads.\" + name + \" is the payloads accessor, not a tool. For the OMP core tool, call omp.\" + name + \"(args).\"\n );\n }\n const provided = Object.keys(target);\n throw new Error(\n \"payloads.\" + name + \" is not defined. payloads only exposes keys from the fabric_exec payloads parameter\" +\n (provided.length ? \" (provided: \" + provided.join(\", \") + \")\" : \" (none provided)\") +\n \". Pass payloads: { \" + name + \": '...' } to use payloads.\" + name + \".\" +\n \" For large or quote-heavy content, keep it in top-level payloads and reference payloads.\" + name + \" instead of escaping it inside code.\"\n );\n },\n ownKeys(target) { return Reflect.ownKeys(target); },\n getOwnPropertyDescriptor(target, prop) { return Reflect.getOwnPropertyDescriptor(target, prop); },\n has(target, prop) { return Object.prototype.hasOwnProperty.call(target, prop); }\n});\n// Stable providers share a lazy dispatch proxy; the guest declarations keep\n// their known actions typed while the registry remains the runtime authority.\n// extensions' per-tool surface is additionally rendered from the captured\n// catalog by guestTypeDeclarations (runtime/dynamic-guest-types.ts).\nconst __memorySelectionKeys = [\n \"indices\",\n \"entryIds\",\n \"operationAddresses\",\n \"entryRange\",\n \"index\",\n \"entry_ids\",\n \"operation_addresses\",\n \"entry_range\",\n];\nconst __hasMemorySelection = (args) => __memorySelectionKeys.some((key) => {\n const value = args[key];\n if (Array.isArray(value)) return value.length > 0;\n return value !== undefined && value !== null;\n});\nconst __memoryWalk = async (args, visitor) => {\n if (!args || typeof args !== \"object\" || Array.isArray(args)) {\n throw new TypeError(\"memory.walk expects an expansion options object\");\n }\n if (typeof visitor !== \"function\") {\n throw new TypeError(\"memory.walk expects a visitor function as its second argument\");\n }\n\n let request = { ...args };\n if (Number(request.textOffset ?? request.text_offset ?? 0) !== 0) {\n throw new TypeError(\"memory.walk must start at text offset 0 to yield complete entries\");\n }\n if (!__hasMemorySelection(request)) {\n if (request.entryOffset !== undefined || request.entry_offset !== undefined ||\n request.textOffset !== undefined || request.text_offset !== undefined) {\n throw new TypeError(\"memory.walk continuation offsets require an explicit selection\");\n }\n if (Number(request.before ?? 0) > 0 || Number(request.after ?? 0) > 0) {\n throw new TypeError(\"memory.walk before/after requires an explicit selection\");\n }\n const head = await __call(\"memory.expand\", request);\n if (!head || typeof head !== \"object\") {\n throw new Error(\"memory.expand returned an invalid metadata response\");\n }\n if (head.error) return { visited: 0, stopped: false, error: head.error };\n if (!Number.isSafeInteger(head.entryCount) || head.entryCount < 0) {\n throw new Error(\"memory.expand metadata omitted a valid entryCount\");\n }\n if (head.entryCount === 0) return { visited: 0, stopped: false };\n request = {\n ...request,\n session: head.session ?? request.session,\n expectedSourceHash: head.sourceHash,\n expectedLineageFingerprint: head.lineageFingerprint,\n branches: head.branches,\n entryRange: { first: 0, last: head.entryCount - 1 },\n };\n }\n\n let visited = 0;\n let pending = null;\n let pendingStart = 0;\n let pendingEnd = 0;\n let pendingTotal = 0;\n const seen = new Set([JSON.stringify({ ref: \"memory.expand\", args: request })]);\n let page = await __call(\"memory.expand\", request);\n\n while (true) {\n if (!page || typeof page !== \"object\") {\n throw new Error(\"memory.expand returned an invalid page\");\n }\n if (page.error) return { visited, stopped: false, error: page.error };\n if (!Array.isArray(page.entries)) {\n throw new Error(\"memory.expand page omitted entries\");\n }\n\n for (const chunk of page.entries) {\n if (!chunk || typeof chunk !== \"object\" || typeof chunk.text !== \"string\") {\n throw new Error(\"memory.expand returned an invalid entry chunk\");\n }\n const range = chunk.textRange;\n if (!range || typeof range !== \"object\" ||\n !Number.isSafeInteger(range.start) || !Number.isSafeInteger(range.end) ||\n !Number.isSafeInteger(range.total) || range.start < 0 ||\n range.end < range.start || range.total < range.end) {\n throw new Error(\"memory.expand returned an invalid textRange\");\n }\n if (chunk.text.length !== range.end - range.start) {\n throw new Error(\"memory.expand entry chunk disagrees with textRange\");\n }\n\n if (pending === null) {\n pending = { ...chunk, text: \"\" };\n pendingStart = range.start;\n pendingEnd = range.start;\n pendingTotal = range.total;\n } else if (pending.index !== chunk.index) {\n throw new Error(\"memory.expand advanced before completing an entry\");\n }\n if (range.start !== pendingEnd || range.total !== pendingTotal) {\n throw new Error(\"memory.expand returned discontinuous entry chunks\");\n }\n for (const key of Object.keys(chunk)) {\n if (pending[key] === undefined) pending[key] = chunk[key];\n }\n pending.text += chunk.text;\n pendingEnd = range.end;\n\n if (range.complete) {\n pending.textRange = {\n start: pendingStart,\n end: pendingEnd,\n total: pendingTotal,\n complete: true,\n };\n const entry = pending;\n pending = null;\n const keepGoing = await visitor(entry, visited);\n visited += 1;\n if (keepGoing === false) return { visited, stopped: true };\n }\n }\n\n if (page.next === null || page.next === undefined) {\n if (pending !== null) {\n throw new Error(\"memory.expand ended before completing an entry\");\n }\n return { visited, stopped: false };\n }\n if (page.next.ref !== \"memory.expand\" || !page.next.args ||\n typeof page.next.args !== \"object\" || Array.isArray(page.next.args)) {\n throw new Error(\"memory.expand returned an invalid continuation\");\n }\n const continuationKey = JSON.stringify(page.next);\n if (seen.has(continuationKey)) {\n throw new Error(\"memory.expand returned a cyclic continuation\");\n }\n seen.add(continuationKey);\n page = await __call(page.next.ref, page.next.args);\n }\n};\n\nconst __proxyNames = (() => {\n const raw = globalThis.__fabricProxyNames;\n delete globalThis.__fabricProxyNames;\n return raw && typeof raw === \"object\" ? raw : {};\n})();\nconst __nameList = (value) =>\n Array.isArray(value) ? value.filter((name) => typeof name === \"string\") : [];\nconst __lazyNamespace = (names, resolve, local = {}) => new Proxy(local, {\n get(target, property) {\n if (property === \"then\" || typeof property === \"symbol\") return undefined;\n if (Object.prototype.hasOwnProperty.call(target, property)) return target[property];\n return resolve(String(property));\n },\n ownKeys(target) {\n const own = Object.keys(target);\n return names.concat(own.filter((key) => names.indexOf(key) < 0));\n },\n getOwnPropertyDescriptor(target, property) {\n if (typeof property === \"symbol\") return undefined;\n const name = String(property);\n if (names.indexOf(name) < 0 && !Object.prototype.hasOwnProperty.call(target, name)) {\n return undefined;\n }\n const value = Object.prototype.hasOwnProperty.call(target, name)\n ? target[name]\n : resolve(name);\n return { value, writable: false, enumerable: true, configurable: true };\n },\n has(target, property) {\n if (typeof property === \"symbol\") return false;\n return names.indexOf(String(property)) >= 0\n || Object.prototype.hasOwnProperty.call(target, property);\n },\n});\nconst __providerProxy = (provider, local = {}, names = []) =>\n __lazyNamespace(names, (property) => (args = {}) => __call(provider + \".\" + property, args), local);\nglobalThis.extensions = __providerProxy(\"extensions\", {}, __nameList(__proxyNames.extensions));\nglobalThis.memory = __providerProxy(\"memory\", { walk: __memoryWalk });\nglobalThis.state = __providerProxy(\"state\");\nglobalThis.schema = __providerProxy(\"schema\");\nglobalThis.components = __providerProxy(\"components\");\nglobalThis.compact = __providerProxy(\"compact\");\nglobalThis.codemap = __providerProxy(\"codemap\");\nglobalThis.judgment = __providerProxy(\"judgment\");\nconst __chunkBatchItems = (items, maxItems = 25, maxBytes = 49152) => {\n const chunks = [];\n let current = [];\n let currentBytes = 2;\n for (const item of items) {\n let serialized = \"\";\n try {\n serialized = JSON.stringify(item) ?? \"null\";\n } catch {\n serialized = JSON.stringify(String(item));\n }\n let stateItem = item;\n if (serialized.length > 40960) {\n stateItem = typeof item === \"string\"\n ? item.slice(0, 40000) + \" [truncated]\"\n : String(item).slice(0, 40000) + \" [truncated]\";\n serialized = JSON.stringify(stateItem);\n }\n const itemBytes = serialized.length + 1;\n if (current.length > 0 && (current.length >= maxItems || currentBytes + itemBytes > maxBytes)) {\n chunks.push(current);\n current = [];\n currentBytes = 2;\n }\n current.push({ item, stateItem });\n currentBytes += itemBytes;\n }\n if (current.length > 0) chunks.push(current);\n return chunks;\n};\nconst __judgeAsk = (first, second) => {\n if (second !== undefined) {\n return globalThis.judgment.ask({ state: first, questions: second });\n }\n return globalThis.judgment.ask(first);\n};\nconst __judgeBool = async (state, instructions, options) => {\n try {\n const outcome = await globalThis.judgment.ask({\n state,\n questions: { q: { type: \"bool\", instructions: String(instructions) } },\n });\n if (outcome && outcome.ok && outcome.answers && outcome.answers.q && outcome.answers.q.type === \"bool\" && typeof outcome.answers.q.bool === \"number\") {\n return outcome.answers.q.bool;\n }\n } catch {}\n return options && typeof options.fallback === \"number\" ? options.fallback : undefined;\n};\nconst __judgeChoice = async (state, optionsListOrCriteria, instructions, config) => {\n let criteria = {};\n if (Array.isArray(optionsListOrCriteria)) {\n for (const opt of optionsListOrCriteria) criteria[String(opt)] = null;\n } else if (optionsListOrCriteria && typeof optionsListOrCriteria === \"object\") {\n criteria = optionsListOrCriteria;\n } else {\n throw new TypeError(\"judge.choice options must be an array or criteria object\");\n }\n if (Object.keys(criteria).length < 2) {\n throw new TypeError(\"judge.choice requires at least 2 unique options\");\n }\n try {\n const outcome = await globalThis.judgment.ask({\n state,\n questions: { q: { type: \"choice\", instructions: String(instructions), criteria } },\n });\n if (outcome && outcome.ok && outcome.answers && outcome.answers.q && outcome.answers.q.type === \"choice\" && typeof outcome.answers.q.choice === \"string\") {\n return outcome.answers.q.choice;\n }\n } catch {}\n return config && typeof config.fallback === \"string\" ? config.fallback : undefined;\n};\nconst __judgeScore = async (state, criteria, instructions, config) => {\n if (!Array.isArray(criteria) || criteria.length < 2) {\n throw new TypeError(\"judge.score requires at least 2 ordered criteria levels\");\n }\n try {\n const outcome = await globalThis.judgment.ask({\n state,\n questions: { q: { type: \"score\", instructions: String(instructions), criteria } },\n });\n if (outcome && outcome.ok && outcome.answers && outcome.answers.q && outcome.answers.q.type === \"score\" && typeof outcome.answers.q.score === \"number\") {\n return outcome.answers.q.score;\n }\n } catch {}\n return config && typeof config.fallback === \"number\" ? config.fallback : undefined;\n};\nconst __judgeFilter = async (items, instructions, options = {}) => {\n if (!Array.isArray(items) || items.length === 0) return [];\n const threshold = Number.isFinite(options.threshold) ? options.threshold : 0.7;\n const onFail = options.onFail || \"keep-all\";\n const chunks = __chunkBatchItems(items, options.maxItems || 25, options.maxBytes || 49152);\n const chunkPromises = chunks.map(async (chunk) => {\n const questions = {};\n chunk.forEach((_, idx) => {\n questions[\"item_\" + idx] = {\n type: \"bool\",\n instructions: \"Regarding items[\" + idx + \"]: \" + String(instructions),\n };\n });\n let outcome;\n try {\n outcome = await globalThis.judgment.ask({ state: { items: chunk.map((c) => c.stateItem) }, questions });\n } catch (err) {\n outcome = { ok: false, reason: \"failed\", detail: String(err && err.message ? err.message : err) };\n }\n if (!outcome || !outcome.ok) {\n if (onFail === \"throw\") {\n throw new Error(\"judge.filter failed: \" + (outcome && outcome.reason ? outcome.reason : \"unknown error\") + (outcome && outcome.detail ? \" (\" + outcome.detail + \")\" : \"\"));\n }\n return onFail === \"empty\" ? [] : chunk.map((c) => c.item);\n }\n return chunk\n .filter((_, idx) => {\n const ans = outcome.answers && outcome.answers[\"item_\" + idx];\n return ans && ans.type === \"bool\" && typeof ans.bool === \"number\" && ans.bool >= threshold;\n })\n .map((c) => c.item);\n });\n const results = await Promise.all(chunkPromises);\n return results.flat();\n};\nconst __judgeClassify = async (items, categories, instructions, options = {}) => {\n if (!Array.isArray(items) || items.length === 0) return [];\n if (!Array.isArray(categories) || categories.length < 2) {\n throw new TypeError(\"judge.classify requires at least 2 categories\");\n }\n const criteria = {};\n for (const cat of categories) criteria[String(cat)] = null;\n const onFail = options.onFail || \"keep-all\";\n const chunks = __chunkBatchItems(items, options.maxItems || 25, options.maxBytes || 49152);\n const chunkPromises = chunks.map(async (chunk) => {\n const questions = {};\n chunk.forEach((_, idx) => {\n questions[\"item_\" + idx] = {\n type: \"choice\",\n instructions: \"Regarding items[\" + idx + \"]: \" + String(instructions),\n criteria,\n };\n });\n let outcome;\n try {\n outcome = await globalThis.judgment.ask({ state: { items: chunk.map((c) => c.stateItem) }, questions });\n } catch (err) {\n outcome = { ok: false, reason: \"failed\", detail: String(err && err.message ? err.message : err) };\n }\n if (!outcome || !outcome.ok) {\n if (onFail === \"throw\") {\n throw new Error(\"judge.classify failed: \" + (outcome && outcome.reason ? outcome.reason : \"unknown error\") + (outcome && outcome.detail ? \" (\" + outcome.detail + \")\" : \"\"));\n }\n if (onFail === \"empty\") return [];\n return chunk.map((c) => ({ item: c.item, category: options.fallbackCategory, confidence: undefined }));\n }\n return chunk.map((c, idx) => {\n const ans = outcome.answers && outcome.answers[\"item_\" + idx];\n const category = ans && ans.type === \"choice\" && typeof ans.choice === \"string\" ? ans.choice : options.fallbackCategory;\n const confidence = ans && typeof ans.confidence === \"number\" ? ans.confidence : undefined;\n return { item: c.item, category, confidence };\n });\n });\n const results = await Promise.all(chunkPromises);\n return results.flat();\n};\nglobalThis.judge = Object.freeze({\n ask: __judgeAsk,\n bool: __judgeBool,\n choice: __judgeChoice,\n score: __judgeScore,\n filter: __judgeFilter,\n classify: __judgeClassify,\n});\nconst __createActor = async (args = {}) => {\n if (!args || typeof args !== \"object\" || Array.isArray(args)) {\n throw new TypeError(\"agents.create expects an options object\");\n }\n const request = { ...args };\n const validWhile = request.validWhile;\n if (validWhile !== undefined) {\n if (typeof validWhile !== \"function\") {\n throw new TypeError(\"agents.create validWhile must be a pure predicate function\");\n }\n const source = Function.prototype.toString.call(validWhile);\n if (source.trimStart().startsWith(\"async\")) {\n throw new TypeError(\"agents.create validWhile must be synchronous\");\n }\n request.validWhile = { version: 1, source };\n }\n return __call(\"agents.create\", request);\n};\nconst __handoff = async (args = {}) => {\n if (!args || typeof args !== \"object\" || Array.isArray(args)) {\n throw new TypeError(\"agents.handoff expects an options object\");\n }\n const request = { ...args };\n const when = request.when;\n delete request.when;\n if (when !== undefined) {\n if (typeof when !== \"function\") {\n throw new TypeError(\"agents.handoff when must be a pure predicate function\");\n }\n const decision = when(__handoffFacts());\n if (decision && typeof decision.then === \"function\") {\n throw new TypeError(\"agents.handoff when must return a boolean synchronously\");\n }\n if (decision !== true) {\n throw new Error(\"agents.handoff predicate returned false; no agent was started\");\n }\n }\n return __call(\"agents.handoff\", request);\n};\nglobalThis.agents = Object.freeze({\n run: (args) => __call(\"agents.run\", args),\n handoff: __handoff,\n spawn: (args) => __call(\"agents.spawn\", args),\n wait: (args) => __call(\"agents.wait\", args),\n status: (args) => __call(\"agents.status\", args),\n list: (args = {}) => __call(\"agents.list\", args),\n members: (args = {}) => __call(\"agents.members\", args),\n self: () => __call(\"agents.self\", {}),\n main: () => __call(\"agents.main\", {}),\n peers: () => __call(\"agents.peers\", {}),\n subscribe: (args) => __call(\"agents.subscribe\", args),\n subscriptions: (args = {}) => __call(\"agents.subscriptions\", args),\n unsubscribe: (args) => __call(\"agents.unsubscribe\", args),\n models: (args = {}) => __call(\"agents.models\", args),\n stop: (args) => __call(\"agents.stop\", args),\n cleanup: (args) => __call(\"agents.cleanup\", args),\n create: __createActor,\n ask: (args) => __call(\"agents.ask\", args),\n tell: (args) => __call(\"agents.tell\", args),\n steer: (args) => __call(\"agents.steer\", args),\n followUp: (args) => __call(\"agents.followUp\", args),\n setSteeringMode: (args) => __call(\"agents.setSteeringMode\", args),\n setFollowUpMode: (args) => __call(\"agents.setFollowUpMode\", args),\n actorStatus: (args) => __call(\"agents.actorStatus\", args),\n setModel: (args) => __call(\"agents.setModel\", args),\n switchModel: (args) => __call(\"agents.switchModel\", args),\n setThinking: (args) => __call(\"agents.setThinking\", args),\n setEvents: (args) => __call(\"agents.setEvents\", args),\n setInstructions: (args) => __call(\"agents.setInstructions\", args),\n actors: () => __call(\"agents.actors\", {}),\n messages: (args) => __call(\"agents.messages\", args),\n remove: (args) => __call(\"agents.remove\", args),\n log: (args) => __call(\"agents.log\", args),\n});\nglobalThis.mesh = Object.freeze({\n self: () => __call(\"mesh.self\", {}),\n publish: (args) => __call(\"mesh.publish\", args),\n read: (args = {}) => __call(\"mesh.read\", args),\n members: (args = {}) => __call(\"mesh.members\", args),\n get: (args) => __call(\"mesh.get\", args),\n list: (args = {}) => __call(\"mesh.list\", args),\n put: (args) => __call(\"mesh.put\", args),\n delete: (args) => __call(\"mesh.delete\", args),\n});\n// The mcp proxy itself stays schema-less \u2014 the registry validates args at\n// dispatch \u2014 but guestTypeDeclarations renders per-server argument types from\n// the live descriptor cache (runtime/dynamic-guest-types.ts), so known tools\n// fail type-check on argument-shape mistakes before this proxy ever runs.\nconst __mcpServerTools = (() => {\n const raw = __proxyNames.mcp;\n const out = {};\n if (raw && typeof raw === \"object\") {\n for (const server of Object.keys(raw)) out[server] = __nameList(raw[server]);\n }\n return out;\n})();\nconst __mcpManagement = {\n servers: () => __call(\"mcp.$servers\", {}),\n reload: () => __call(\"mcp.$reload\", {}),\n register: (args) => __call(\"mcp.$register\", args),\n call: (args) => __call(\"mcp.$call\", args),\n};\nglobalThis.mcp = __lazyNamespace(\n Object.keys(__mcpServerTools).sort(),\n (server) => __lazyNamespace(\n __mcpServerTools[server] ? __mcpServerTools[server].slice().sort() : [],\n (tool) => (args = {}) => __call(\"mcp.\" + server + \".\" + tool, args),\n ),\n __mcpManagement,\n);\nlet __workflowSpentTokens = 0;\nconst __workflowBudgetTotal = Number.isFinite(globalThis.__fabricTokenBudget)\n ? Math.max(0, globalThis.__fabricTokenBudget)\n : Number.POSITIVE_INFINITY;\nconst __recordAgentUsage = (result) => {\n const usage = result && result.usage;\n if (usage) __workflowSpentTokens += Number(usage.input || 0) + Number(usage.output || 0);\n return result;\n};\nconst __workflowAgent = async (prompt, options = {}) => {\n if (__workflowSpentTokens >= __workflowBudgetTotal) {\n throw new Error(\"Fabric workflow token budget exhausted\");\n }\n const { label, ...agentOptions } = options;\n const workerName = String(label || agentOptions.name || \"Fabric workflow agent\");\n const result = __recordAgentUsage(await agents.run({\n ...agentOptions,\n ...(label && !agentOptions.name ? { name: label } : {}),\n task: prompt,\n }));\n if (!result || result.status !== \"completed\") {\n const reason = result && result.error ? result.error : \"agent did not complete\";\n throw new Error(workerName + \" failed: \" + reason);\n }\n return result.value !== undefined ? result.value : result.text;\n};\n// Budget-aware agents.run used by council.run and rlm.query so their usage is\n// counted in budget.spent() and the tokenBudget guard can preempt them, just\n// like workflow.agent(). Without this, councils bypass the budget entirely.\nconst __budgetedRun = async (args) => {\n if (__workflowSpentTokens >= __workflowBudgetTotal) {\n throw new Error(\"Fabric workflow token budget exhausted\");\n }\n return __recordAgentUsage(await agents.run(args));\n};\nlet __nextWorkflowSpanId = 0;\nconst __workflowSpanMetadata = (kind, items, options, stageCount) => {\n const itemCount = Array.isArray(items) ? items.length : undefined;\n let concurrency;\n if (kind === \"parallel\" && itemCount !== undefined) {\n if (itemCount === 0) concurrency = 0;\n else {\n const concurrencyOpt = typeof options === \"number\" ? { concurrency: options } : options ?? {};\n const requested = Number(concurrencyOpt.concurrency ?? itemCount);\n if (Number.isFinite(requested) && requested >= 1) {\n concurrency = Math.max(1, Math.min(itemCount, Math.floor(requested)));\n }\n }\n }\n return {\n kind,\n ...(itemCount !== undefined ? { itemCount } : {}),\n ...(stageCount !== undefined ? { stageCount } : {}),\n ...(concurrency !== undefined ? { concurrency } : {}),\n };\n};\nconst __withWorkflowSpan = async (metadata, body) => {\n const id = \"span-\" + __nextWorkflowSpanId++;\n await __call(\"fabric.$spanStart\", { id, ...metadata });\n try {\n const value = await body();\n await __call(\"fabric.$spanEnd\", { id, outcome: \"succeeded\" });\n return value;\n } catch (error) {\n try { await __call(\"fabric.$spanEnd\", { id, outcome: \"failed\" }); } catch { /* preserve the workflow error */ }\n throw error;\n }\n};\nconst __runParallel = async (thunks, options) => {\n if (!Array.isArray(thunks) || thunks.some((thunk) => typeof thunk !== \"function\")) {\n throw new TypeError(\"workflow.parallel expects an array of functions or (items, mapper)\");\n }\n if (thunks.length === 0) return [];\n const concurrencyOpt = typeof options === \"number\" ? { concurrency: options } : options ?? {};\n const requestedConcurrency = Number(concurrencyOpt.concurrency ?? thunks.length);\n if (!Number.isFinite(requestedConcurrency) || requestedConcurrency < 1) {\n throw new RangeError(\"workflow.parallel concurrency must be a positive finite number\");\n }\n const concurrency = Math.max(1, Math.min(thunks.length || 1, Math.floor(requestedConcurrency)));\n const results = new Array(thunks.length);\n let cursor = 0;\n await Promise.all(Array.from({ length: concurrency }, async () => {\n while (cursor < thunks.length) {\n const index = cursor++;\n results[index] = await thunks[index]();\n }\n }));\n return results;\n};\nconst __workflowParallel = async (items, arg2, arg3) => {\n const options = typeof arg2 === \"function\" ? arg3 : arg2;\n return __withWorkflowSpan(\n __workflowSpanMetadata(\"parallel\", items, options),\n async () => {\n if (typeof arg2 === \"function\") {\n if (!Array.isArray(items)) throw new TypeError(\"workflow.parallel expects an array as the first argument\");\n return __runParallel(items.map((item, index) => () => arg2(item, index)), arg3);\n }\n return __runParallel(items, arg2);\n },\n );\n};\nconst __workflowPipeline = async (items, ...stages) =>\n __withWorkflowSpan(\n __workflowSpanMetadata(\"pipeline\", items, undefined, stages.length),\n async () => {\n if (!Array.isArray(items) || stages.some((stage) => typeof stage !== \"function\")) {\n throw new TypeError(\"workflow.pipeline expects an array followed by stage functions\");\n }\n return __workflowParallel(items.map((original, index) => async () => {\n let value = original;\n for (const stage of stages) value = await stage(value, original, index);\n return value;\n }));\n },\n );\nglobalThis.workflow = Object.freeze({\n agent: __workflowAgent,\n parallel: __workflowParallel,\n pipeline: __workflowPipeline,\n configure: (args) => __call(\"fabric.$configure\", args),\n phase: (nameOrInput, options = {}) => {\n const input =\n nameOrInput && typeof nameOrInput === \"object\" && !Array.isArray(nameOrInput)\n ? { ...nameOrInput }\n : { ...options, name: nameOrInput };\n return __call(\"fabric.$phase\", input);\n },\n item: (args) => __call(\"fabric.$item\", args),\n event: (args) => __call(\"fabric.$event\", args),\n log: (...values) => print(...values),\n budget: Object.freeze({\n total: __workflowBudgetTotal,\n spent: () => __workflowSpentTokens,\n remaining: () => Math.max(0, __workflowBudgetTotal - __workflowSpentTokens),\n }),\n});\nglobalThis.agent = __workflowAgent;\nglobalThis.parallel = __workflowParallel;\nglobalThis.pipeline = __workflowPipeline;\nglobalThis.phase = workflow.phase;\nglobalThis.log = workflow.log;\nglobalThis.budget = workflow.budget;\nglobalThis.rlm = Object.freeze({\n query: (args) => {\n if (args && args.runner && args.runner !== \"omp\") {\n throw new Error(\"rlm.query requires the OMP runner because recursive Fabric is unavailable in Claude Code\");\n }\n return __budgetedRun({ ...args, runner: \"omp\", recursive: true });\n },\n});\nglobalThis.council = Object.freeze({\n async run(args) {\n const { task, roles, synthesize = true, ...agentOptions } = args;\n const results = await Promise.all(roles.map((role) => __budgetedRun({\n ...agentOptions,\n name: role,\n task: \"Act as the \" + role + \" council member. Independently analyze this task:\\n\\n\" + task,\n })));\n if (!synthesize) return results;\n return __budgetedRun({\n ...agentOptions,\n name: \"council-synthesizer\",\n task: \"Synthesize the council's independent reports into one decision. Preserve disagreements and cite which role raised each concern.\\n\\nTask:\\n\" + task + \"\\n\\nReports:\\n\" + JSON.stringify(results),\n });\n },\n});\nglobalThis.console = Object.freeze({ log: print, info: print, warn: print, error: print });\nconst __timerCallbacks = new Map();\nlet __nextTimerId = 1;\nglobalThis.setTimeout = (callback, ms = 0) => {\n const id = __nextTimerId++;\n __timerCallbacks.set(id, { callback, interval: false });\n __call(\"fabric.$timer\", { ms }).then(() => {\n const entry = __timerCallbacks.get(id);\n if (!entry) return;\n __timerCallbacks.delete(id);\n try { entry.callback(); } catch { /* swallow timer callback errors */ }\n });\n return id;\n};\nglobalThis.setInterval = (callback, ms = 0) => {\n const id = __nextTimerId++;\n __timerCallbacks.set(id, { callback, interval: true });\n const schedule = () => {\n __call(\"fabric.$timer\", { ms }).then(() => {\n const entry = __timerCallbacks.get(id);\n if (!entry) return;\n try { entry.callback(); } catch { /* swallow timer callback errors */ }\n if (__timerCallbacks.has(id)) schedule();\n });\n };\n schedule();\n return id;\n};\nglobalThis.clearTimeout = (id) => { __timerCallbacks.delete(id); };\nglobalThis.clearInterval = (id) => { __timerCallbacks.delete(id); };\n})();\n";
|
|
26
26
|
export declare class QuickJsRuntime {
|
|
27
27
|
execute(code: string, hostCall: FabricHostCall, options: FabricSandboxOptions): Promise<FabricSandboxResult>;
|
|
28
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quickjs-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/quickjs-runtime.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,8BAA8B,GACtC,WAAW,GACX,eAAe,GACf,WAAW,GACX,SAAS,CAAC;AAEd,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,iBAAiB,EAAE,8BAA8B,CAAC;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,2BAA2B,CAAC,CAC1B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,GAAG,SAAS,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,cAAc,GAAG,CAC3B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,OAAO,CAAC,CAAC;AA+CtB,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"quickjs-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/quickjs-runtime.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,8BAA8B,GACtC,WAAW,GACX,eAAe,GACf,WAAW,GACX,SAAS,CAAC;AAEd,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,iBAAiB,EAAE,8BAA8B,CAAC;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,2BAA2B,CAAC,CAC1B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,GAAG,SAAS,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,cAAc,GAAG,CAC3B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,OAAO,CAAC,CAAC;AA+CtB,eAAO,MAAM,WAAW,2s6CA4gCvB,CAAC;AA0DF,qBAAa,cAAc;IACnB,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC;CA0XhC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guest-args.d.ts","sourceRoot":"","sources":["../../src/speculation/guest-args.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"guest-args.d.ts","sourceRoot":"","sources":["../../src/speculation/guest-args.ts"],"names":[],"mappings":"AA6SA,eAAO,MAAM,YAAY,GACvB,MAAM,MAAM,EACZ,kBAAkB,SAAS,OAAO,EAAE,KACnC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAO5B,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/speculation/scanner.ts", "../../src/speculation/guest-args.ts"],
|
|
4
|
-
"sourcesContent": ["import ts from \"typescript\";\nimport { stableJsonHash } from \"../core/stable-hash.js\";\nimport { guestOmpArgs } from \"./guest-args.js\";\nimport type { FabricSpeculationCandidate } from \"./types.js\";\n\n// Root namespaces the model can call from a fabric program. Calls are emitted\n// as candidates regardless of action so the tap can apply its eligibility\n// policy in one place; args must still be fully literal.\nconst ROOTS = new Set([\"omp\", \"memory\", \"state\", \"schema\", \"compact\", \"components\", \"mcp\"]);\n\nconst LITERAL_FAIL = Symbol(\"literal-fail\");\n\ntype LiteralResult = { ok: true; value: unknown } | { ok: false };\n\nconst literalOk = (value: unknown): LiteralResult => ({ ok: true, value });\nconst LITERAL_FAIL_RESULT: LiteralResult = { ok: false };\n\n// Accept only values that survive a JSON round trip unchanged in structure so\n// the speculation key (stableJsonHash over prepared args) cannot drift from\n// what the real invocation produces.\nconst isJsonShape = (value: unknown): boolean => {\n if (value === null) return true;\n switch (typeof value) {\n case \"string\":\n case \"boolean\":\n return true;\n case \"number\":\n return Number.isFinite(value);\n case \"object\": {\n if (Array.isArray(value)) return value.every(isJsonShape);\n const record = value as Record<string, unknown>;\n return Object.values(record).every(isJsonShape);\n }\n default:\n return false;\n }\n};\n\nconst evalLiteral = (node: ts.Expression): LiteralResult => {\n if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {\n return literalOk(node.text);\n }\n if (ts.isNumericLiteral(node)) {\n if (node.text.endsWith(\"n\")) return LITERAL_FAIL_RESULT; // bigint\n const value = Number(node.text);\n return Number.isFinite(value) ? literalOk(value) : LITERAL_FAIL_RESULT;\n }\n if (\n ts.isPrefixUnaryExpression(node) &&\n (node.operator === ts.SyntaxKind.MinusToken || node.operator === ts.SyntaxKind.PlusToken) &&\n ts.isNumericLiteral(node.operand)\n ) {\n if (node.operand.text.endsWith(\"n\")) return LITERAL_FAIL_RESULT;\n const value = Number(node.operand.text);\n if (!Number.isFinite(value)) return LITERAL_FAIL_RESULT;\n return literalOk(node.operator === ts.SyntaxKind.MinusToken ? -value : value);\n }\n if (node.kind === ts.SyntaxKind.TrueKeyword) return literalOk(true);\n if (node.kind === ts.SyntaxKind.FalseKeyword) return literalOk(false);\n if (node.kind === ts.SyntaxKind.NullKeyword) return literalOk(null);\n if (ts.isArrayLiteralExpression(node)) {\n const items: unknown[] = [];\n for (const element of node.elements) {\n if (ts.isSpreadElement(element) || ts.isOmittedExpression(element)) return LITERAL_FAIL_RESULT;\n const item = evalLiteral(element);\n if (!item.ok) return item;\n items.push(item.value);\n }\n return literalOk(items);\n }\n if (ts.isObjectLiteralExpression(node)) {\n const record: Record<string, unknown> = {};\n for (const property of node.properties) {\n if (!ts.isPropertyAssignment(property)) return LITERAL_FAIL_RESULT;\n const name = property.name;\n if (!ts.isIdentifier(name) && !ts.isStringLiteral(name)) return LITERAL_FAIL_RESULT;\n const value = evalLiteral(property.initializer);\n if (!value.ok) return value;\n record[name.text] = value.value;\n }\n return literalOk(record);\n }\n return LITERAL_FAIL_RESULT;\n};\n\nconst collectBoundNames = (name: ts.BindingName, into: Set<string>): void => {\n if (ts.isIdentifier(name)) {\n into.add(name.text);\n return;\n }\n for (const element of name.elements) {\n if (ts.isBindingElement(element)) collectBoundNames(element.name, into);\n }\n};\n\n/** Property-access chain as segments, e.g. mcp.exa.search -> [\"mcp\",\"exa\",\"search\"]. */\nconst accessChain = (node: ts.Expression): string[] | undefined => {\n const segments: string[] = [];\n let current: ts.Expression = node;\n while (ts.isPropertyAccessExpression(current)) {\n segments.unshift(current.name.text);\n current = current.expression;\n }\n if (!ts.isIdentifier(current)) return undefined;\n segments.unshift(current.text);\n return segments;\n};\n\nconst refFromChain = (segments: string[], tainted: Set<string>): string | undefined => {\n const root = segments[0]!;\n if (!ROOTS.has(root) || tainted.has(root)) return undefined;\n if (segments.length === 2) return `${segments[0]}.${segments[1]}`;\n if (segments.length === 3 && root === \"mcp\") return segments.join(\".\");\n return undefined;\n};\n\n/**\n * Scans a growing partial TypeScript program for completed calls on the spec\n * namespaces whose arguments are all literals. Reparses the full prefix only\n * when newly appended text contains a \")\" \u2014 which is the earliest point a call\n * expression can complete \u2014 so streaming deltas inside string payloads cost a\n * substring scan, not an AST build.\n */\nexport class LiteralCallScanner {\n #scannedLength = 0;\n readonly #tainted = new Set<string>();\n readonly #emitted = new Set<string>();\n\n push(code: string): FabricSpeculationCandidate[] {\n const appended = code.slice(this.#scannedLength);\n const forceScan = code.length < this.#scannedLength;\n if (!forceScan && !appended.includes(\")\")) return [];\n this.#scannedLength = code.length;\n\n const source = ts.createSourceFile(\n \"speculation.ts\",\n code,\n ts.ScriptTarget.ESNext,\n true,\n ts.ScriptKind.TS,\n );\n\n // A local/declared binding that shares a namespace root makes dotted calls\n // ambiguous (e.g. `const omp = { read: () => ... }`); taint that root for\n // the rest of the stream.\n for (const statement of source.statements) {\n this.#collectStatementBindings(statement, this.#tainted);\n }\n\n const candidates: FabricSpeculationCandidate[] = [];\n const visit = (node: ts.Node): void => {\n if (ts.isCallExpression(node)) {\n const segments = accessChain(node.expression);\n if (segments) {\n const ref = refFromChain(segments, this.#tainted);\n if (ref) {\n const args = this.#literalArgs(ref, node);\n if (args !== undefined) {\n const key = `${ref}\\n${stableJsonHash(args)}`;\n if (!this.#emitted.has(key)) {\n this.#emitted.add(key);\n candidates.push({ ref, args });\n }\n }\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(source);\n return candidates;\n }\n\n #literalArgs(ref: string, node: ts.CallExpression): Record<string, unknown> | undefined {\n if (node.arguments.length === 0) return {};\n const values: unknown[] = [];\n for (const argument of node.arguments) {\n if (ts.isSpreadElement(argument)) return undefined;\n const value = evalLiteral(argument);\n if (!value.ok || !isJsonShape(value.value)) return undefined;\n values.push(value.value);\n }\n if (ref.startsWith(\"omp.\")) {\n const args = guestOmpArgs(ref.slice(\"omp.\".length), values);\n return args !== undefined && isJsonShape(args) ? args : undefined;\n }\n if (values.length !== 1) return undefined;\n const only = values[0];\n if (typeof only !== \"object\" || only === null || Array.isArray(only)) return undefined;\n return only as Record<string, unknown>;\n }\n\n #collectStatementBindings(node: ts.Node, into: Set<string>): void {\n const visit = (current: ts.Node): void => {\n if (ts.isVariableDeclaration(current)) collectBoundNames(current.name, into);\n else if (\n (ts.isFunctionDeclaration(current) || ts.isClassDeclaration(current)) &&\n current.name\n ) {\n into.add(current.name.text);\n } else if (\n ts.isFunctionExpression(current) ||\n ts.isArrowFunction(current) ||\n ts.isMethodDeclaration(current)\n ) {\n for (const parameter of current.parameters) collectBoundNames(parameter.name, into);\n } else if (ts.isImportDeclaration(current) && current.importClause) {\n const clause = current.importClause;\n if (clause.name) into.add(clause.name.text);\n if (clause.namedBindings) {\n if (ts.isNamespaceImport(clause.namedBindings)) {\n into.add(clause.namedBindings.name.text);\n } else {\n for (const element of clause.namedBindings.elements) into.add(element.name.text);\n }\n }\n }\n ts.forEachChild(current, visit);\n };\n visit(node);\n }\n}\n", "const STRING_FIELDS: Readonly<Record<string, string>> = {\n bash: \"command\",\n read: \"path\",\n ls: \"path\",\n grep: \"pattern\",\n find: \"pattern\"\n};\n\nconst POSITIONAL_FIELDS: Readonly<Record<string, readonly string[]>> = {\n grep: [\n \"pattern\",\n \"path\",\n \"skip\"\n ],\n find: [\n \"pattern\",\n \"path\",\n \"limit\"\n ],\n write: [\n \"path\",\n \"content\"\n ],\n edit: [\n \"path\",\n \"oldText\",\n \"newText\"\n ]\n};\n\nconst NUMERIC_FIELDS: Readonly<Record<string, readonly string[]>> = {\n read: [\n \"offset\",\n \"limit\"\n ],\n bash: [\n \"timeout\"\n ],\n grep: [\n \"skip\",\n \"context\"\n ],\n find: [\n \"limit\"\n ],\n ls: [\n \"limit\"\n ]\n};\n\nconst OPTIONAL_FIELDS: Readonly<Record<string, readonly string[]>> = {\n read: [\n \"offset\",\n \"limit\"\n ],\n grep: [\n \"path\",\n \"glob\",\n \"ignoreCase\",\n \"literal\",\n \"context\",\n \"limit\"\n ],\n find: [\n \"path\",\n \"limit\"\n ],\n ls: [\n \"path\",\n \"limit\"\n ]\n};\n\nconst ARG_ALIASES: Readonly<Record<string, Readonly<Record<string, string>>>> = {\n bash: {\n cmd: \"command\",\n shell: \"command\",\n cmdline: \"command\",\n script: \"command\",\n commandLine: \"command\",\n workdir: \"cwd\",\n directory: \"cwd\",\n workingDirectory: \"cwd\"\n },\n find: {\n query: \"pattern\",\n regex: \"pattern\",\n search: \"pattern\",\n name: \"pattern\",\n filename: \"pattern\",\n glob: \"pattern\",\n expression: \"pattern\",\n include: \"pattern\",\n max: \"limit\"\n },\n grep: {\n query: \"pattern\",\n regex: \"pattern\",\n search: \"pattern\",\n q: \"pattern\",\n expression: \"pattern\",\n text: \"pattern\",\n ic: \"ignoreCase\",\n caseInsensitive: \"ignoreCase\",\n globPattern: \"glob\",\n ctx: \"context\"\n },\n read: {\n file: \"path\",\n absolutePath: \"path\",\n file_path: \"path\",\n filePath: \"path\",\n filepath: \"path\",\n pathname: \"path\",\n target_file: \"path\",\n targetFile: \"path\",\n absolute_path: \"path\",\n fileAbsolutePath: \"path\",\n max: \"limit\",\n start: \"offset\"\n },\n ls: {\n dir: \"path\",\n file: \"path\",\n folder: \"path\",\n absolutePath: \"path\",\n file_path: \"path\",\n filePath: \"path\",\n filepath: \"path\",\n pathname: \"path\",\n target_file: \"path\",\n targetFile: \"path\",\n absolute_path: \"path\",\n fileAbsolutePath: \"path\",\n directory: \"path\",\n directoryPath: \"path\",\n max: \"limit\"\n },\n edit: {\n file: \"path\",\n absolutePath: \"path\",\n file_path: \"path\",\n filePath: \"path\",\n filepath: \"path\",\n pathname: \"path\",\n target_file: \"path\",\n targetFile: \"path\",\n absolute_path: \"path\",\n fileAbsolutePath: \"path\",\n old: \"oldText\",\n old_string: \"oldText\",\n oldString: \"oldText\",\n old_str: \"oldText\",\n oldStr: \"oldText\",\n from: \"oldText\",\n old_value: \"oldText\",\n old_text: \"oldText\",\n oldContent: \"oldText\",\n old_content: \"oldText\",\n new: \"newText\",\n replacement: \"newText\",\n new_string: \"newText\",\n newString: \"newText\",\n new_str: \"newText\",\n newStr: \"newText\",\n to: \"newText\",\n new_value: \"newText\",\n new_text: \"newText\",\n newContent: \"newText\",\n new_content: \"newText\"\n },\n write: {\n file: \"path\",\n absolutePath: \"path\",\n file_path: \"path\",\n filePath: \"path\",\n filepath: \"path\",\n pathname: \"path\",\n target_file: \"path\",\n targetFile: \"path\",\n absolute_path: \"path\",\n fileAbsolutePath: \"path\",\n contents: \"content\",\n body: \"content\",\n text: \"content\",\n data: \"content\",\n fileContent: \"content\"\n }\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst positionalToArgs = (name: string, rest: readonly unknown[]): unknown => {\n const first = rest[0];\n const second = rest[1];\n const primaryField = STRING_FIELDS[name];\n if (\n rest.length === 2 &&\n typeof first === \"string\" &&\n primaryField !== undefined &&\n isPlainObject(second)\n ) {\n return { ...second, [primaryField]: first };\n }\n const order = POSITIONAL_FIELDS[name];\n if (!order) return rest.length > 0 ? first : {};\n const out: Record<string, unknown> = {};\n for (let index = 0; index < rest.length && index < order.length; index += 1) {\n const value = rest[index];\n if (value !== undefined) out[order[index]!] = value;\n }\n return out;\n};\n\nconst normalizeOmpArgs = (name: string, args: unknown): unknown => {\n const field = STRING_FIELDS[name];\n if (typeof args === \"string\" && field) return { [field]: args };\n if (!isPlainObject(args)) return args;\n let out: Record<string, unknown> = args;\n const copy = (): void => {\n if (out === args) out = { ...args };\n };\n if (name === \"bash\" && \"timeoutMs\" in out) {\n copy();\n if (!(\"timeout\" in out)) {\n const timeoutMs = out.timeoutMs;\n if (timeoutMs !== null && timeoutMs !== undefined) {\n out.timeout = Number.isFinite(Number(timeoutMs)) ? Number(timeoutMs) / 1000 : timeoutMs;\n }\n }\n delete out.timeoutMs;\n }\n if (name === \"bash\" && \"settle\" in out) {\n copy();\n delete out.settle;\n }\n const aliases = ARG_ALIASES[name];\n if (aliases) {\n for (const alias of Object.keys(aliases)) {\n const canonical = aliases[alias]!;\n if (!(alias in out)) continue;\n copy();\n if (!(canonical in out)) out[canonical] = out[alias];\n delete out[alias];\n }\n }\n const numerics = NUMERIC_FIELDS[name];\n if (numerics) {\n for (const key of numerics) {\n const value = out[key];\n if (typeof value === \"string\" && value.trim() !== \"\" && Number.isFinite(Number(value))) {\n copy();\n out[key] = Number(value);\n }\n }\n }\n const optionals = OPTIONAL_FIELDS[name];\n if (optionals) {\n for (const key of optionals) {\n if (out[key] !== null && out[key] !== undefined) continue;\n if (!(key in out)) continue;\n copy();\n delete out[key];\n }\n }\n if (name === \"edit\" && Array.isArray(out.edits)) {\n let changed = false;\n const editAliases = ARG_ALIASES.edit!;\n const edits = out.edits.map((entry) => {\n if (!isPlainObject(entry)) return entry;\n let edit: Record<string, unknown> = entry;\n for (const alias of Object.keys(editAliases)) {\n const canonical = editAliases[alias]!;\n if (canonical !== \"oldText\" && canonical !== \"newText\") continue;\n if (!(alias in edit)) continue;\n if (edit === entry) edit = { ...entry };\n if (!(canonical in edit)) edit[canonical] = edit[alias];\n delete edit[alias];\n changed = true;\n }\n return edit;\n });\n if (changed) {\n copy();\n out.edits = edits;\n }\n }\n if (name === \"edit\" && !Array.isArray(out.edits) && (\"oldText\" in out || \"newText\" in out)) {\n copy();\n const edit: Record<string, unknown> = {};\n if (\"oldText\" in out) edit.oldText = out.oldText;\n if (\"newText\" in out) edit.newText = out.newText;\n out.edits = [edit];\n delete out.oldText;\n delete out.newText;\n }\n return out;\n};\n\nexport const guestOmpArgs = (\n name: string,\n literalArguments: readonly unknown[],\n): Record<string, unknown> | undefined => {\n const raw = literalArguments.length <= 1\n ? (literalArguments.length === 1 ? literalArguments[0] : undefined)\n : positionalToArgs(name, literalArguments);\n const args = raw === undefined ? {} : raw;\n const normalized = normalizeOmpArgs(name, args);\n return isPlainObject(normalized) ? normalized : undefined;\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import ts from \"typescript\";\nimport { stableJsonHash } from \"../core/stable-hash.js\";\nimport { guestOmpArgs } from \"./guest-args.js\";\nimport type { FabricSpeculationCandidate } from \"./types.js\";\n\n// Root namespaces the model can call from a fabric program. Calls are emitted\n// as candidates regardless of action so the tap can apply its eligibility\n// policy in one place; args must still be fully literal.\nconst ROOTS = new Set([\"omp\", \"memory\", \"state\", \"schema\", \"compact\", \"components\", \"mcp\"]);\n\nconst LITERAL_FAIL = Symbol(\"literal-fail\");\n\ntype LiteralResult = { ok: true; value: unknown } | { ok: false };\n\nconst literalOk = (value: unknown): LiteralResult => ({ ok: true, value });\nconst LITERAL_FAIL_RESULT: LiteralResult = { ok: false };\n\n// Accept only values that survive a JSON round trip unchanged in structure so\n// the speculation key (stableJsonHash over prepared args) cannot drift from\n// what the real invocation produces.\nconst isJsonShape = (value: unknown): boolean => {\n if (value === null) return true;\n switch (typeof value) {\n case \"string\":\n case \"boolean\":\n return true;\n case \"number\":\n return Number.isFinite(value);\n case \"object\": {\n if (Array.isArray(value)) return value.every(isJsonShape);\n const record = value as Record<string, unknown>;\n return Object.values(record).every(isJsonShape);\n }\n default:\n return false;\n }\n};\n\nconst evalLiteral = (node: ts.Expression): LiteralResult => {\n if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {\n return literalOk(node.text);\n }\n if (ts.isNumericLiteral(node)) {\n if (node.text.endsWith(\"n\")) return LITERAL_FAIL_RESULT; // bigint\n const value = Number(node.text);\n return Number.isFinite(value) ? literalOk(value) : LITERAL_FAIL_RESULT;\n }\n if (\n ts.isPrefixUnaryExpression(node) &&\n (node.operator === ts.SyntaxKind.MinusToken || node.operator === ts.SyntaxKind.PlusToken) &&\n ts.isNumericLiteral(node.operand)\n ) {\n if (node.operand.text.endsWith(\"n\")) return LITERAL_FAIL_RESULT;\n const value = Number(node.operand.text);\n if (!Number.isFinite(value)) return LITERAL_FAIL_RESULT;\n return literalOk(node.operator === ts.SyntaxKind.MinusToken ? -value : value);\n }\n if (node.kind === ts.SyntaxKind.TrueKeyword) return literalOk(true);\n if (node.kind === ts.SyntaxKind.FalseKeyword) return literalOk(false);\n if (node.kind === ts.SyntaxKind.NullKeyword) return literalOk(null);\n if (ts.isArrayLiteralExpression(node)) {\n const items: unknown[] = [];\n for (const element of node.elements) {\n if (ts.isSpreadElement(element) || ts.isOmittedExpression(element)) return LITERAL_FAIL_RESULT;\n const item = evalLiteral(element);\n if (!item.ok) return item;\n items.push(item.value);\n }\n return literalOk(items);\n }\n if (ts.isObjectLiteralExpression(node)) {\n const record: Record<string, unknown> = {};\n for (const property of node.properties) {\n if (!ts.isPropertyAssignment(property)) return LITERAL_FAIL_RESULT;\n const name = property.name;\n if (!ts.isIdentifier(name) && !ts.isStringLiteral(name)) return LITERAL_FAIL_RESULT;\n const value = evalLiteral(property.initializer);\n if (!value.ok) return value;\n record[name.text] = value.value;\n }\n return literalOk(record);\n }\n return LITERAL_FAIL_RESULT;\n};\n\nconst collectBoundNames = (name: ts.BindingName, into: Set<string>): void => {\n if (ts.isIdentifier(name)) {\n into.add(name.text);\n return;\n }\n for (const element of name.elements) {\n if (ts.isBindingElement(element)) collectBoundNames(element.name, into);\n }\n};\n\n/** Property-access chain as segments, e.g. mcp.exa.search -> [\"mcp\",\"exa\",\"search\"]. */\nconst accessChain = (node: ts.Expression): string[] | undefined => {\n const segments: string[] = [];\n let current: ts.Expression = node;\n while (ts.isPropertyAccessExpression(current)) {\n segments.unshift(current.name.text);\n current = current.expression;\n }\n if (!ts.isIdentifier(current)) return undefined;\n segments.unshift(current.text);\n return segments;\n};\n\nconst refFromChain = (segments: string[], tainted: Set<string>): string | undefined => {\n const root = segments[0]!;\n if (!ROOTS.has(root) || tainted.has(root)) return undefined;\n if (segments.length === 2) return `${segments[0]}.${segments[1]}`;\n if (segments.length === 3 && root === \"mcp\") return segments.join(\".\");\n return undefined;\n};\n\n/**\n * Scans a growing partial TypeScript program for completed calls on the spec\n * namespaces whose arguments are all literals. Reparses the full prefix only\n * when newly appended text contains a \")\" \u2014 which is the earliest point a call\n * expression can complete \u2014 so streaming deltas inside string payloads cost a\n * substring scan, not an AST build.\n */\nexport class LiteralCallScanner {\n #scannedLength = 0;\n readonly #tainted = new Set<string>();\n readonly #emitted = new Set<string>();\n\n push(code: string): FabricSpeculationCandidate[] {\n const appended = code.slice(this.#scannedLength);\n const forceScan = code.length < this.#scannedLength;\n if (!forceScan && !appended.includes(\")\")) return [];\n this.#scannedLength = code.length;\n\n const source = ts.createSourceFile(\n \"speculation.ts\",\n code,\n ts.ScriptTarget.ESNext,\n true,\n ts.ScriptKind.TS,\n );\n\n // A local/declared binding that shares a namespace root makes dotted calls\n // ambiguous (e.g. `const omp = { read: () => ... }`); taint that root for\n // the rest of the stream.\n for (const statement of source.statements) {\n this.#collectStatementBindings(statement, this.#tainted);\n }\n\n const candidates: FabricSpeculationCandidate[] = [];\n const visit = (node: ts.Node): void => {\n if (ts.isCallExpression(node)) {\n const segments = accessChain(node.expression);\n if (segments) {\n const ref = refFromChain(segments, this.#tainted);\n if (ref) {\n const args = this.#literalArgs(ref, node);\n if (args !== undefined) {\n const key = `${ref}\\n${stableJsonHash(args)}`;\n if (!this.#emitted.has(key)) {\n this.#emitted.add(key);\n candidates.push({ ref, args });\n }\n }\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(source);\n return candidates;\n }\n\n #literalArgs(ref: string, node: ts.CallExpression): Record<string, unknown> | undefined {\n if (node.arguments.length === 0) return {};\n const values: unknown[] = [];\n for (const argument of node.arguments) {\n if (ts.isSpreadElement(argument)) return undefined;\n const value = evalLiteral(argument);\n if (!value.ok || !isJsonShape(value.value)) return undefined;\n values.push(value.value);\n }\n if (ref.startsWith(\"omp.\")) {\n const args = guestOmpArgs(ref.slice(\"omp.\".length), values);\n return args !== undefined && isJsonShape(args) ? args : undefined;\n }\n if (values.length !== 1) return undefined;\n const only = values[0];\n if (typeof only !== \"object\" || only === null || Array.isArray(only)) return undefined;\n return only as Record<string, unknown>;\n }\n\n #collectStatementBindings(node: ts.Node, into: Set<string>): void {\n const visit = (current: ts.Node): void => {\n if (ts.isVariableDeclaration(current)) collectBoundNames(current.name, into);\n else if (\n (ts.isFunctionDeclaration(current) || ts.isClassDeclaration(current)) &&\n current.name\n ) {\n into.add(current.name.text);\n } else if (\n ts.isFunctionExpression(current) ||\n ts.isArrowFunction(current) ||\n ts.isMethodDeclaration(current)\n ) {\n for (const parameter of current.parameters) collectBoundNames(parameter.name, into);\n } else if (ts.isImportDeclaration(current) && current.importClause) {\n const clause = current.importClause;\n if (clause.name) into.add(clause.name.text);\n if (clause.namedBindings) {\n if (ts.isNamespaceImport(clause.namedBindings)) {\n into.add(clause.namedBindings.name.text);\n } else {\n for (const element of clause.namedBindings.elements) into.add(element.name.text);\n }\n }\n }\n ts.forEachChild(current, visit);\n };\n visit(node);\n }\n}\n", "const STRING_FIELDS: Readonly<Record<string, string>> = {\n bash: \"command\",\n read: \"path\",\n ls: \"path\",\n grep: \"pattern\",\n find: \"pattern\"\n};\n\nconst POSITIONAL_FIELDS: Readonly<Record<string, readonly string[]>> = {\n grep: [\n \"pattern\",\n \"path\",\n \"skip\"\n ],\n find: [\n \"pattern\",\n \"path\",\n \"limit\"\n ],\n write: [\n \"path\",\n \"content\"\n ],\n edit: [\n \"path\",\n \"oldText\",\n \"newText\"\n ]\n};\n\nconst NUMERIC_FIELDS: Readonly<Record<string, readonly string[]>> = {\n read: [\n \"offset\",\n \"limit\"\n ],\n bash: [\n \"timeout\"\n ],\n grep: [\n \"skip\",\n \"context\",\n \"limit\"\n ],\n find: [\n \"limit\"\n ],\n ls: [\n \"limit\"\n ]\n};\n\nconst OPTIONAL_FIELDS: Readonly<Record<string, readonly string[]>> = {\n read: [\n \"offset\",\n \"limit\"\n ],\n grep: [\n \"path\",\n \"glob\",\n \"ignoreCase\",\n \"literal\",\n \"context\",\n \"limit\"\n ],\n find: [\n \"path\",\n \"limit\"\n ],\n ls: [\n \"path\",\n \"limit\"\n ]\n};\n\nconst ARG_ALIASES: Readonly<Record<string, Readonly<Record<string, string>>>> = {\n bash: {\n cmd: \"command\",\n shell: \"command\",\n cmdline: \"command\",\n script: \"command\",\n commandLine: \"command\",\n workdir: \"cwd\",\n directory: \"cwd\",\n workingDirectory: \"cwd\"\n },\n find: {\n query: \"pattern\",\n regex: \"pattern\",\n search: \"pattern\",\n name: \"pattern\",\n filename: \"pattern\",\n glob: \"pattern\",\n expression: \"pattern\",\n include: \"pattern\",\n max: \"limit\"\n },\n grep: {\n query: \"pattern\",\n regex: \"pattern\",\n search: \"pattern\",\n q: \"pattern\",\n expression: \"pattern\",\n text: \"pattern\",\n ic: \"ignoreCase\",\n caseInsensitive: \"ignoreCase\",\n globPattern: \"glob\",\n ctx: \"context\"\n },\n read: {\n file: \"path\",\n absolutePath: \"path\",\n file_path: \"path\",\n filePath: \"path\",\n filepath: \"path\",\n pathname: \"path\",\n target_file: \"path\",\n targetFile: \"path\",\n absolute_path: \"path\",\n fileAbsolutePath: \"path\",\n max: \"limit\",\n start: \"offset\"\n },\n ls: {\n dir: \"path\",\n file: \"path\",\n folder: \"path\",\n absolutePath: \"path\",\n file_path: \"path\",\n filePath: \"path\",\n filepath: \"path\",\n pathname: \"path\",\n target_file: \"path\",\n targetFile: \"path\",\n absolute_path: \"path\",\n fileAbsolutePath: \"path\",\n directory: \"path\",\n directoryPath: \"path\",\n max: \"limit\"\n },\n edit: {\n file: \"path\",\n absolutePath: \"path\",\n file_path: \"path\",\n filePath: \"path\",\n filepath: \"path\",\n pathname: \"path\",\n target_file: \"path\",\n targetFile: \"path\",\n absolute_path: \"path\",\n fileAbsolutePath: \"path\",\n old: \"oldText\",\n old_string: \"oldText\",\n oldString: \"oldText\",\n old_str: \"oldText\",\n oldStr: \"oldText\",\n from: \"oldText\",\n old_value: \"oldText\",\n old_text: \"oldText\",\n oldContent: \"oldText\",\n old_content: \"oldText\",\n new: \"newText\",\n replacement: \"newText\",\n new_string: \"newText\",\n newString: \"newText\",\n new_str: \"newText\",\n newStr: \"newText\",\n to: \"newText\",\n new_value: \"newText\",\n new_text: \"newText\",\n newContent: \"newText\",\n new_content: \"newText\"\n },\n write: {\n file: \"path\",\n absolutePath: \"path\",\n file_path: \"path\",\n filePath: \"path\",\n filepath: \"path\",\n pathname: \"path\",\n target_file: \"path\",\n targetFile: \"path\",\n absolute_path: \"path\",\n fileAbsolutePath: \"path\",\n contents: \"content\",\n body: \"content\",\n text: \"content\",\n data: \"content\",\n fileContent: \"content\"\n }\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst positionalToArgs = (name: string, rest: readonly unknown[]): unknown => {\n const first = rest[0];\n const second = rest[1];\n const primaryField = STRING_FIELDS[name];\n if (\n rest.length === 2 &&\n typeof first === \"string\" &&\n primaryField !== undefined &&\n isPlainObject(second)\n ) {\n return { ...second, [primaryField]: first };\n }\n const order = POSITIONAL_FIELDS[name];\n if (!order) return rest.length > 0 ? first : {};\n const out: Record<string, unknown> = {};\n for (let index = 0; index < rest.length && index < order.length; index += 1) {\n const value = rest[index];\n if (value !== undefined) out[order[index]!] = value;\n }\n return out;\n};\n\nconst normalizeOmpArgs = (name: string, args: unknown): unknown => {\n const field = STRING_FIELDS[name];\n if (typeof args === \"string\" && field) return { [field]: args };\n if (!isPlainObject(args)) return args;\n let out: Record<string, unknown> = args;\n const copy = (): void => {\n if (out === args) out = { ...args };\n };\n if (name === \"bash\" && \"timeoutMs\" in out) {\n copy();\n if (!(\"timeout\" in out)) {\n const timeoutMs = out.timeoutMs;\n if (timeoutMs !== null && timeoutMs !== undefined) {\n out.timeout = Number.isFinite(Number(timeoutMs)) ? Number(timeoutMs) / 1000 : timeoutMs;\n }\n }\n delete out.timeoutMs;\n }\n if (name === \"bash\" && \"settle\" in out) {\n copy();\n delete out.settle;\n }\n const aliases = ARG_ALIASES[name];\n if (aliases) {\n for (const alias of Object.keys(aliases)) {\n const canonical = aliases[alias]!;\n if (!(alias in out)) continue;\n copy();\n if (!(canonical in out)) out[canonical] = out[alias];\n delete out[alias];\n }\n }\n const numerics = NUMERIC_FIELDS[name];\n if (numerics) {\n for (const key of numerics) {\n const value = out[key];\n if (typeof value === \"string\" && value.trim() !== \"\" && Number.isFinite(Number(value))) {\n copy();\n out[key] = Number(value);\n }\n }\n }\n const optionals = OPTIONAL_FIELDS[name];\n if (optionals) {\n for (const key of optionals) {\n if (out[key] !== null && out[key] !== undefined) continue;\n if (!(key in out)) continue;\n copy();\n delete out[key];\n }\n }\n if (name === \"edit\" && Array.isArray(out.edits)) {\n let changed = false;\n const editAliases = ARG_ALIASES.edit!;\n const edits = out.edits.map((entry) => {\n if (!isPlainObject(entry)) return entry;\n let edit: Record<string, unknown> = entry;\n for (const alias of Object.keys(editAliases)) {\n const canonical = editAliases[alias]!;\n if (canonical !== \"oldText\" && canonical !== \"newText\") continue;\n if (!(alias in edit)) continue;\n if (edit === entry) edit = { ...entry };\n if (!(canonical in edit)) edit[canonical] = edit[alias];\n delete edit[alias];\n changed = true;\n }\n return edit;\n });\n if (changed) {\n copy();\n out.edits = edits;\n }\n }\n if (name === \"edit\" && !Array.isArray(out.edits) && (\"oldText\" in out || \"newText\" in out)) {\n copy();\n const edit: Record<string, unknown> = {};\n if (\"oldText\" in out) edit.oldText = out.oldText;\n if (\"newText\" in out) edit.newText = out.newText;\n out.edits = [edit];\n delete out.oldText;\n delete out.newText;\n }\n return out;\n};\n\nexport const guestOmpArgs = (\n name: string,\n literalArguments: readonly unknown[],\n): Record<string, unknown> | undefined => {\n const raw = literalArguments.length <= 1\n ? (literalArguments.length === 1 ? literalArguments[0] : undefined)\n : positionalToArgs(name, literalArguments);\n const args = raw === undefined ? {} : raw;\n const normalized = normalizeOmpArgs(name, args);\n return isPlainObject(normalized) ? normalized : undefined;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/docs/audit-trace.md
CHANGED
|
@@ -57,7 +57,7 @@ The host bridge assigns `sequence` when it receives any durable operation. A par
|
|
|
57
57
|
V1 keeps `type: "call"` for wire compatibility. Exact internal refs separate discovery, lifecycle, and combinator operations from provider action calls. V1 also leaves `result` optional, and discovery, workflow lifecycle, and combinator operations never persist one. The generic recorder drops provider results, with a single exception: the exact `{ created: true }` creation outcome from `omp.write`. No output or provider details accompany that outcome. Argument projection follows the exact reference:
|
|
58
58
|
|
|
59
59
|
- `omp.read`: local `path`, numeric `offset`, numeric `limit`
|
|
60
|
-
- `omp.grep`: local `path`, numeric `context`, numeric `limit`. Drops pattern and query
|
|
60
|
+
- `omp.grep`: local `path`, numeric `context`, numeric `skip`, numeric `limit`. Drops pattern and query
|
|
61
61
|
- `omp.find`, `omp.ls`: local `path`, numeric `limit`. Drops pattern and query
|
|
62
62
|
- `omp.edit`, `omp.write`: local `path` only. Drops edit replacements and write content. `omp.write` can keep `{ created: true }`
|
|
63
63
|
- `omp.bash`: bounded command text
|
package/docs/configuration.md
CHANGED
|
@@ -313,7 +313,7 @@ A guest core-tool call returns the whole result, or it says that it did not. Whe
|
|
|
313
313
|
|
|
314
314
|
The marker is the last line, it is emitted only for a partial result, and a complete result is byte-identical to the file or command output. Programs that parse a whole file therefore keep working, and a program that must detect a cut branches on the marker.
|
|
315
315
|
|
|
316
|
-
`omp.read` pages internally, so the host's per-call line ceiling is not visible to a program; a marker appears only where paging cannot help, such as one line larger than the byte budget. `omp.grep` and `omp.find` carry host caps that Fabric cannot lift, so they signal. `omp.bash` recovers column-truncated output from its own artifact and marks only what it could not restore. The host also caps the artifact file itself at `tools.artifactMaxBytes` (16 MiB by default, read from host settings, so this session's override cannot lift it), keeping its head and tail with the middle dropped. When that cap hits, the marker note names the dropped bytes and the setting, and the column-cap restore refuses the holed file so no program reads it as the full output.
|
|
316
|
+
`omp.read` pages internally, so the host's per-call line ceiling is not visible to a program; a marker appears only where paging cannot help, such as one line larger than the byte budget. `omp.grep` and `omp.find` carry host caps that Fabric cannot lift, so they signal. `omp.bash` recovers column-truncated output from its own artifact and marks only what it could not restore. The host also caps the artifact file itself at `tools.artifactMaxBytes` (16 MiB by default, read from host settings, so this session's override cannot lift it), keeping its head and tail with the middle dropped. When that cap hits, the marker note names the dropped bytes and the setting, and the column-cap restore refuses the holed file so no program reads it as the full output. A capture the host failed to write is refused the same way: the note names the failed artifact operation, calls the full output unrecoverable, and offers no path, because the file the host abandoned is not the output. An intact artifact larger than `executor.maxNestedResultChars` is too large to inline, and there the note names the file on disk and the budget that blocked it.
|
|
317
317
|
|
|
318
318
|
A file the host cannot decode as text is an error, not content: `omp.read` throws with a message beginning `omp.read returned no text content:` and names the `:raw` selector that does work.
|
|
319
319
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omp-fabric",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.8",
|
|
4
4
|
"description": "A programmable tool and agent runtime for Oh My Pi (OMP)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -96,9 +96,9 @@
|
|
|
96
96
|
"yaml": "^2.9.0"
|
|
97
97
|
},
|
|
98
98
|
"peerDependencies": {
|
|
99
|
-
"@oh-my-pi/pi-coding-agent": ">=18.
|
|
100
|
-
"@oh-my-pi/pi-natives": ">=18.
|
|
101
|
-
"@oh-my-pi/pi-tui": ">=18.
|
|
99
|
+
"@oh-my-pi/pi-coding-agent": ">=18.4.4",
|
|
100
|
+
"@oh-my-pi/pi-natives": ">=18.4.4",
|
|
101
|
+
"@oh-my-pi/pi-tui": ">=18.4.4"
|
|
102
102
|
},
|
|
103
103
|
"devDependencies": {
|
|
104
104
|
"@oh-my-pi/omptype": "18.4.10",
|
|
@@ -12,14 +12,14 @@ description: >-
|
|
|
12
12
|
One type-checked TS program in a fresh executor (isolated QuickJS by default). Only the `return` value reaches the model; `print()`/`console.log` go to the activity panel. `payloads` is not a tool.
|
|
13
13
|
|
|
14
14
|
## `omp` core tools (full code mode only)
|
|
15
|
-
`omp.<tool>(arg)` — single arg: bare string (primary field) or options object, or a two-arg `(primary, options)` merge for the string-primary tools (`read`/`bash`/`ls`/`grep`/`find`): `omp.read('index.ts', { limit: 120 })` becomes `{ path: 'index.ts', limit: 120 }`, the positional string winning the primary field on conflict; a non-object second arg on those is still a type error. Positional tuple calls are accepted for `grep
|
|
15
|
+
`omp.<tool>(arg)` — single arg: bare string (primary field) or options object, or a two-arg `(primary, options)` merge for the string-primary tools (`read`/`bash`/`ls`/`grep`/`find`): `omp.read('index.ts', { limit: 120 })` becomes `{ path: 'index.ts', limit: 120 }`, the positional string winning the primary field on conflict; a non-object second arg on those is still a type error. Positional tuple calls are accepted for `grep` (`pattern, path, skip`), `find` (`pattern, path, limit`), `write` (`path, content`), and `edit` (`path, oldText, newText`).
|
|
16
16
|
|
|
17
17
|
| Tool | Form | Returns |
|
|
18
18
|
|------|------|---------|
|
|
19
19
|
| `read` | `path` \| `{path,offset?,limit?}` \| `(path, options?)` | `string` |
|
|
20
20
|
| `bash` | `command` \| `{command,timeout?,cwd?,async?}` \| `(command, options?)` | `{ok:true,output,details}`; rejects on a nonzero exit (`settle:true` returns `{ok:false,output,details:null,exitCode,error}` instead) |
|
|
21
|
-
| `grep` | `pattern` \| `{pattern,path?,glob?,ignoreCase?,literal?,context?,limit?}` \| `(pattern, path?,
|
|
22
|
-
| `find` | `pattern` \| `{pattern,path?,limit?}` \| `(pattern, path?, limit?)` | `string` |
|
|
21
|
+
| `grep` | `pattern` \| `{pattern,path?,glob?,ignoreCase?,literal?,context?,skip?,limit?,gitignore?}` \| `(pattern, path?, skip?)` | `string` |
|
|
22
|
+
| `find` | `pattern` \| `{pattern,path?,limit?,gitignore?,hidden?}` \| `(pattern, path?, limit?)` | `string` |
|
|
23
23
|
| `ls` | `path?` \| `{path?,limit?}` \| `(path, options?)` | `string` |
|
|
24
24
|
| `wait` | (no arguments) | `{ok,output,details}`; the next finished background job result owned by this session |
|
|
25
25
|
| `edit` | `{path,edits:[{oldText,newText,all?}],all?}` \| `{path,oldText,newText,all?}` \| `(path, oldText, newText)` | `{ok,output,details}` |
|
|
@@ -35,7 +35,7 @@ Aliases are normalized to canonical fields before host validation. Command alias
|
|
|
35
35
|
|
|
36
36
|
`async:true` starts the command as a host background job: the call resolves at once with `details.async.jobId`, the command keeps running past this program, and its output reaches the agent as a follow-up message. The program never sees that output, and `settle` has nothing to settle on a call that resolved, so await `omp.wait()` when a later step needs its result. `omp.wait()` takes no arguments and returns the next finished background job result owned by this session; never poll it with `sleep`, because every poll is a wasted turn. Foreground calls are never backgrounded on their own, whatever their duration; `executor.autoBackground` is the setting that arms the host handover. Both `async:true` and `omp.wait()` need this session to have a live owning agent with a host job manager, so start a new session; do not rely on one appearing mid-session. Where that owner is missing, parked, or has no manager, `async` leaves the schema and passing it anyway fails with `Async bash execution is disabled`, and `omp.wait()` returns "No running background jobs to wait for."
|
|
37
37
|
|
|
38
|
-
Shell `timeout` is in seconds; `timeoutMs` is converted from milliseconds. Numeric strings in `limit`, `timeout`, `offset`, and `context` coerce to numbers. `null`/`undefined` is omitted only for known optional fields; required fields remain invalid so authoritative host validation still reports them. Canonical fields win when both canonical and alias spellings are present. Unknown keys still fail the excess-property type check.
|
|
38
|
+
Shell `timeout` is in seconds; `timeoutMs` is converted from milliseconds. Numeric strings in `limit`, `timeout`, `offset`, `skip`, and `context` coerce to numbers. `null`/`undefined` is omitted only for known optional fields; required fields remain invalid so authoritative host validation still reports them. Canonical fields win when both canonical and alias spellings are present. Unknown keys still fail the excess-property type check.
|
|
39
39
|
|
|
40
40
|
`bash`/`edit`/`write` always resolve an envelope `{ ok, output, details }`, never a bare string, and the executor guards those envelopes: a string method or iteration applied to the envelope itself (`r.trim()`, `for (const line of r)`) throws a TypeError naming the fix (`.output`) instead of a context-free "not a function".
|
|
41
41
|
|