omp-fabric 0.85.0 → 1.0.2
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 +57 -0
- package/dist/agents/manager.d.ts.map +1 -1
- package/dist/agents/transports/process-transport.d.ts.map +1 -1
- package/dist/agents/transports/process-utils.d.ts +6 -1
- package/dist/agents/transports/process-utils.d.ts.map +1 -1
- package/dist/agents/types.d.ts +1 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/audit/details.d.ts +10 -0
- package/dist/audit/details.d.ts.map +1 -1
- package/dist/chunks/{chunk-GKOFZ76R.js → chunk-2LGLDM34.js} +22 -4
- package/dist/chunks/chunk-2LGLDM34.js.map +7 -0
- package/dist/chunks/{chunk-T6OAX4FO.js → chunk-3TWC6XOS.js} +37 -9
- package/dist/chunks/chunk-3TWC6XOS.js.map +7 -0
- package/dist/chunks/{chunk-ZNAJDPT7.js → chunk-B2SQR2JY.js} +32 -24
- package/dist/chunks/{chunk-ZNAJDPT7.js.map → chunk-B2SQR2JY.js.map} +2 -2
- package/dist/chunks/{chunk-SXMWV447.js → chunk-DOKANNFC.js} +206 -3
- package/dist/chunks/chunk-DOKANNFC.js.map +7 -0
- package/dist/chunks/{chunk-UPCARIJP.js → chunk-FFWALVBN.js} +20 -9
- package/dist/chunks/chunk-FFWALVBN.js.map +7 -0
- package/dist/chunks/{chunk-4LEDA76O.js → chunk-HAJPYJPY.js} +3 -3
- package/dist/chunks/{chunk-ROKMBLGN.js → chunk-IFNDRFW7.js} +34 -14
- package/dist/chunks/chunk-IFNDRFW7.js.map +7 -0
- package/dist/chunks/{chunk-ZTM45GH5.js → chunk-JZWLICMS.js} +125 -42
- package/dist/chunks/chunk-JZWLICMS.js.map +7 -0
- package/dist/chunks/{chunk-5GTPD4BA.js → chunk-L2FNMIOW.js} +66 -22
- package/dist/chunks/chunk-L2FNMIOW.js.map +7 -0
- package/dist/chunks/chunk-NX4SNIMR.js +226 -0
- package/dist/chunks/chunk-NX4SNIMR.js.map +7 -0
- package/dist/chunks/{chunk-YZZIKJX6.js → chunk-RBA54WC7.js} +1 -1
- package/dist/chunks/{chunk-YZZIKJX6.js.map → chunk-RBA54WC7.js.map} +1 -1
- package/dist/chunks/{chunk-OPTP4PSE.js → chunk-YPYVUGON.js} +3 -23
- package/dist/chunks/chunk-YPYVUGON.js.map +7 -0
- package/dist/chunks/{chunk-JP4LIZFT.js → chunk-Z6HEQPXX.js} +23 -6
- package/dist/chunks/chunk-Z6HEQPXX.js.map +7 -0
- package/dist/commands/fabric.d.ts.map +1 -1
- package/dist/core/action-registry.d.ts +2 -1
- package/dist/core/action-registry.d.ts.map +1 -1
- package/dist/core/action-registry.js +2 -2
- package/dist/core/compact-controller.d.ts +28 -3
- package/dist/core/compact-controller.d.ts.map +1 -1
- package/dist/core/compact-outcome-store.d.ts +3 -0
- package/dist/core/compact-outcome-store.d.ts.map +1 -0
- package/dist/entropy/index.js +2 -2
- package/dist/entropy/sessions.d.ts.map +1 -1
- package/dist/execution-service.d.ts.map +1 -1
- package/dist/fabric-exec-tool.d.ts.map +1 -1
- package/dist/fabric-runtime-state.d.ts.map +1 -1
- package/dist/fabric-runtime-state.js +883 -367
- package/dist/fabric-runtime-state.js.map +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +116 -18
- package/dist/index.js.map +3 -3
- package/dist/memory/discovery.d.ts +28 -14
- package/dist/memory/discovery.d.ts.map +1 -1
- package/dist/memory/discovery.js +9 -5
- package/dist/protocol.d.ts +5 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +1 -1
- package/dist/providers/mcp-descriptor-cache.d.ts +2 -0
- package/dist/providers/mcp-descriptor-cache.d.ts.map +1 -1
- package/dist/providers/mcp-provider.d.ts +4 -2
- package/dist/providers/mcp-provider.d.ts.map +1 -1
- package/dist/providers/memory-provider.d.ts.map +1 -1
- package/dist/providers/memory-provider.js +2 -2
- package/dist/providers/omp-tools-provider.d.ts +1 -0
- package/dist/providers/omp-tools-provider.d.ts.map +1 -1
- package/dist/residency/host.js +5 -5
- package/dist/residency/omp-entry.js +5 -5
- 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-child-source.d.ts.map +1 -1
- package/dist/runtime/node-process-runtime.d.ts.map +1 -1
- package/dist/runtime/node-process-runtime.js +4 -2
- package/dist/runtime/node-process-runtime.js.map +2 -2
- package/dist/runtime/quickjs-runtime.d.ts +6 -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 +2 -0
- package/dist/speculation/guest-args.d.ts.map +1 -0
- package/dist/speculation/scanner.d.ts.map +1 -1
- package/dist/speculation/scanner.js +312 -14
- package/dist/speculation/scanner.js.map +3 -3
- package/dist/speculation/store.d.ts +2 -0
- package/dist/speculation/store.d.ts.map +1 -1
- package/dist/speculation/stream-tap.d.ts +1 -0
- package/dist/speculation/stream-tap.d.ts.map +1 -1
- package/dist/speculation/summary.d.ts +4 -0
- package/dist/speculation/summary.d.ts.map +1 -0
- package/dist/speculation/types.d.ts +4 -0
- package/dist/speculation/types.d.ts.map +1 -1
- package/dist/speculation/warmup.d.ts +17 -0
- package/dist/speculation/warmup.d.ts.map +1 -0
- package/dist/ui/settings.d.ts.map +1 -1
- package/dist/ui/settings.js +6 -6
- package/dist/ui/settings.js.map +2 -2
- package/docs/agents.md +1 -1
- package/docs/compaction.md +2 -2
- package/docs/configuration.md +26 -12
- package/docs/interface.md +2 -2
- package/docs/speculation.md +11 -6
- package/package.json +3 -2
- package/dist/chunks/chunk-5GTPD4BA.js.map +0 -7
- package/dist/chunks/chunk-7BIA5BJN.js +0 -112
- package/dist/chunks/chunk-7BIA5BJN.js.map +0 -7
- package/dist/chunks/chunk-GKOFZ76R.js.map +0 -7
- package/dist/chunks/chunk-JP4LIZFT.js.map +0 -7
- package/dist/chunks/chunk-OPTP4PSE.js.map +0 -7
- package/dist/chunks/chunk-ROKMBLGN.js.map +0 -7
- package/dist/chunks/chunk-SXMWV447.js.map +0 -7
- package/dist/chunks/chunk-T6OAX4FO.js.map +0 -7
- package/dist/chunks/chunk-UPCARIJP.js.map +0 -7
- package/dist/chunks/chunk-ZTM45GH5.js.map +0 -7
- /package/dist/chunks/{chunk-4LEDA76O.js.map → chunk-HAJPYJPY.js.map} +0 -0
package/docs/agents.md
CHANGED
|
@@ -120,7 +120,7 @@ In the guest, `agents.handoff()` resolves to `{ scheduled: true, status: "deferr
|
|
|
120
120
|
/fabric prewalk --enable
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
-
When you supply a task, Fabric arms prewalk and immediately submits the task to Main. Without a task, it captures the next user input. Select the executor in `/fabric settings` under **Prewalk**. **Always re-arm** uses `prewalk.model` to arm prewalk automatically at each session start without interaction. It also arms prewalk after each completed handoff. `/fabric prewalk --off` cancels only the current session arm. `/fabric prewalk --disable` persists the master switch to the
|
|
123
|
+
When you supply a task, Fabric arms prewalk and immediately submits the task to Main. Without a task, it captures the next user input. Select the executor in `/fabric settings` under **Prewalk**. **Always re-arm** uses `prewalk.model` to arm prewalk automatically at each session start without interaction. It also arms prewalk after each completed handoff. `/fabric prewalk --off` cancels only the current session arm. `/fabric prewalk --disable` persists the master switch to the global config, cancels any live arm, and keeps prewalk inert after restart; `--enable` reverses it.
|
|
124
124
|
|
|
125
125
|
Host extensions that must serialize work after prewalk can use the acknowledged protocol exported from `omp-fabric/protocol`. Emit `FABRIC_PREWALK_REQUEST_EVENT` with `{ version: 1, context, claim, respond }`. Fabric calls `claim()` synchronously; the first claimant owns the request. It calls `respond({ ok: true })` only after prewalk is armed, or `respond({ ok: false, error })` after cancellation or failure. A request that is not claimed means no compatible Fabric runtime is installed. The protocol intentionally arms without submitting a task, so the caller can deliver its next queued row only after the acknowledgment.
|
|
126
126
|
|
package/docs/compaction.md
CHANGED
|
@@ -4,13 +4,13 @@ OMP Fabric provides an LLM-free compactor through `session_before_compact`. This
|
|
|
4
4
|
|
|
5
5
|
Fabric keeps a bounded recent raw continuity tail after compaction. The tail uses OMP's active `keepRecentTokens` setting, which defaults to 20,000 tokens. Fabric rebuilds the older state into its deterministic summary. OMP's native cut and Codex-style checkpoint compaction use the same fresh-window principle. The summary carries durable state, and a small raw suffix keeps the recent conversation coherent for the model.
|
|
6
6
|
|
|
7
|
-
`compaction.targetContextRatio` sets a hard occupancy ceiling that applies after compaction. Fabric never treats the ceiling as space to fill. The value defaults to
|
|
7
|
+
`compaction.targetContextRatio` sets a hard occupancy ceiling that applies after compaction. Fabric never treats the ceiling as space to fill. The value defaults to 75%, and you can change it from `/fabric-settings` (shown as **Max occupancy**) or in JSON. Allowed values are bounded to `0.25`–`0.85`. The ceiling is one of four constraints and the smallest wins; in practice continuity binds first on a large-context model, so measured post-compaction occupancy usually lands far below this value and changing it alone has no effect:
|
|
8
8
|
|
|
9
9
|
```json
|
|
10
10
|
{
|
|
11
11
|
"compaction": {
|
|
12
12
|
"engine": "fabric",
|
|
13
|
-
"targetContextRatio": 0.
|
|
13
|
+
"targetContextRatio": 0.75
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
```
|
package/docs/configuration.md
CHANGED
|
@@ -5,7 +5,7 @@ OMP Fabric reads configuration from two JSON files. Project values override glob
|
|
|
5
5
|
1. `<active OMP agent dir>/fabric.json`: global defaults.
|
|
6
6
|
2. `<project>/.omp/fabric.json`: project overrides, only for **trusted** projects.
|
|
7
7
|
|
|
8
|
-
`/fabric settings` opens at
|
|
8
|
+
`/fabric settings` opens at global scope in every session. In a trusted project, press **Ctrl+G** anywhere in the settings view to move both the displayed values and the save destination between the global `<active OMP agent dir>/fabric.json` and `<project>/.omp/fabric.json`; project overrides are an explicit opt-in. The global view shows global defaults even when a project override stays effective in the current session, and the scope banner marks that precedence. Both views show persisted values. The affected setting notes when a runtime-only environment override still controls the live session. Untrusted sessions remain global-only. RPC hosts expose the same nested settings through standard select/input dialogs and provide a root save-scope action, so no terminal keybinding is required.
|
|
9
9
|
|
|
10
10
|
`configVersion` versions each configuration document. Fabric migrates each applicable file independently before it applies global/project precedence, then rewrites migrated files atomically. Version 0, the historical unversioned format, renames `subagents` to `agents`. Versions 2 and 3 rename legacy UI settings. Version 4 repairs `prewalk.enabled` string booleans emitted by the settings UI in affected builds. When both legacy and canonical sections exist, canonical values win conflicts and non-conflicting values survive. Fabric migrates trusted project files, and it never reads or rewrites untrusted project files. Add future schema changes as sequential migrations. Avoid runtime aliases.
|
|
11
11
|
|
|
@@ -50,13 +50,13 @@ where absent values do not participate. Orchestration programs (`agents.run` / `
|
|
|
50
50
|
```json
|
|
51
51
|
{
|
|
52
52
|
"configVersion": 4,
|
|
53
|
-
"fullCodeMode":
|
|
53
|
+
"fullCodeMode": true,
|
|
54
54
|
"executor": {
|
|
55
55
|
"runtime": "quickjs",
|
|
56
56
|
"timeoutMs": 120000,
|
|
57
57
|
"maxTimeoutMs": 900000,
|
|
58
58
|
"hostCallTimeouts": {},
|
|
59
|
-
"memoryLimitBytes":
|
|
59
|
+
"memoryLimitBytes": 268435456,
|
|
60
60
|
"maxOutputChars": 100000,
|
|
61
61
|
"maxNestedResultChars": 2000000,
|
|
62
62
|
"resultFormat": "auto"
|
|
@@ -93,7 +93,7 @@ where absent values do not participate. Orchestration programs (`agents.run` / `
|
|
|
93
93
|
"enabled": true,
|
|
94
94
|
"disableOAuth": true,
|
|
95
95
|
"allowDynamicServers": true,
|
|
96
|
-
"callTimeoutMs":
|
|
96
|
+
"callTimeoutMs": 90000,
|
|
97
97
|
"cache": {
|
|
98
98
|
"enabled": true,
|
|
99
99
|
"revalidate": "changed",
|
|
@@ -125,12 +125,12 @@ where absent values do not participate. Orchestration programs (`agents.run` / `
|
|
|
125
125
|
"persona": "navigator-chat"
|
|
126
126
|
},
|
|
127
127
|
"thinking": "medium",
|
|
128
|
-
"maxConcurrent":
|
|
128
|
+
"maxConcurrent": 8,
|
|
129
129
|
"maxPerExecution": 100,
|
|
130
|
-
"maxDepth":
|
|
130
|
+
"maxDepth": 3,
|
|
131
131
|
"timeoutMs": 3600000,
|
|
132
132
|
"extensions": true,
|
|
133
|
-
"defaultTools": ["read", "bash", "edit", "write", "grep", "find"
|
|
133
|
+
"defaultTools": ["read", "bash", "edit", "write", "grep", "find"],
|
|
134
134
|
"retainRuns": false,
|
|
135
135
|
"notifyOnComplete": true,
|
|
136
136
|
"budgetUsd": 0,
|
|
@@ -149,7 +149,7 @@ where absent values do not participate. Orchestration programs (`agents.run` / `
|
|
|
149
149
|
"ui": {
|
|
150
150
|
"enabled": true,
|
|
151
151
|
"widget": "auto",
|
|
152
|
-
"maxRows":
|
|
152
|
+
"maxRows": 10,
|
|
153
153
|
"refreshMs": 500,
|
|
154
154
|
"eventHistory": 80,
|
|
155
155
|
"haltOnEscape": true,
|
|
@@ -189,7 +189,7 @@ Unknown definitions stay visible as waiting. They do not fail the Fabric runtime
|
|
|
189
189
|
|
|
190
190
|
## Prewalk executor
|
|
191
191
|
|
|
192
|
-
`prewalk.enabled` defaults to `true` and is the persistent master switch. Turn it off under **Prewalk → Enabled** in `/fabric settings`, or run `/fabric prewalk --disable`;
|
|
192
|
+
`prewalk.enabled` defaults to `true` and is the persistent master switch. Turn it off under **Prewalk → Enabled** in `/fabric settings`, or run `/fabric prewalk --disable`; the command always saves to global scope, and the settings view saves to whichever scope it currently targets. Disabling also cancels any live arm. `/fabric prewalk --enable` turns it back on. `/fabric prewalk --off` only cancels the current arm for this session and does not change the saved master switch.
|
|
193
193
|
|
|
194
194
|
`prewalk.model` is the optional OMP `provider/model` that `/fabric prewalk` selects. `prewalk.mode` chooses how execution continues:
|
|
195
195
|
|
|
@@ -267,7 +267,7 @@ OMP core calls reject when the native tool reports an error. Successful `bash`,
|
|
|
267
267
|
|
|
268
268
|
### Full code mode
|
|
269
269
|
|
|
270
|
-
`fullCodeMode: true` is
|
|
270
|
+
`fullCodeMode: true` is the default. Fabric takes OMP's native core tools out of the model-facing set and exposes their implementations through `fabric_exec`; `omp.read()` and the other `omp.*` core calls route through the host adapter.
|
|
271
271
|
|
|
272
272
|
Fabric records which native core tools were active before it takes ownership. Switching to orchestration-only mode or unloading Fabric restores that selection. Fabric applies full-mode ownership only when the session initializes or the mode changes. It never resets an explicitly selected active tool set from input, agent-start, turn-end, or settled lifecycle hooks. The system prompt carries the full-mode execution rule.
|
|
273
273
|
|
|
@@ -293,7 +293,21 @@ In orchestration-only mode:
|
|
|
293
293
|
|
|
294
294
|
### Where to set `fullCodeMode`
|
|
295
295
|
|
|
296
|
-
`fullCodeMode` defaults to `
|
|
296
|
+
`fullCodeMode` defaults to `true`. Set it to `false` in `.omp/fabric.json` for one project, or globally in `<active OMP agent dir>/fabric.json` for every project. `/fabric settings` toggles it as well.
|
|
297
|
+
|
|
298
|
+
### Partial results
|
|
299
|
+
|
|
300
|
+
A guest core-tool call returns the whole result, or it says that it did not. When the host cut a payload, the returned string ends with one extra line:
|
|
301
|
+
|
|
302
|
+
```text
|
|
303
|
+
[[omp-fabric:truncated]] {"reasons":["matchLimit"],"perFileMatchLimit":200}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
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.
|
|
307
|
+
|
|
308
|
+
`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.
|
|
309
|
+
|
|
310
|
+
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.
|
|
297
311
|
|
|
298
312
|
## Captured extension tools
|
|
299
313
|
|
|
@@ -301,7 +315,7 @@ Fabric intercepts OMP's `ExtensionRunner.getAllRegisteredTools()` registry choke
|
|
|
301
315
|
|
|
302
316
|
Captured custom tools leave the model's active tool set by default. Their schemas, snippets, and guidelines stop consuming the parent model context, and the model reaches them only through `fabric_exec` when capture hiding is enabled. The tools stay registered in OMP's runtime, so the host tool registry keeps listing them. The owning extension remains loaded: its commands, event handlers, state, and UI continue to work.
|
|
303
317
|
|
|
304
|
-
The default
|
|
318
|
+
The shipped default enables capture and hands OMP's native core tools to `fabric_exec`. This avoids a second model-facing implementation of the same read, write, shell, search, and task surfaces. Set `fullCodeMode` to `false` to keep those native tools model-facing; `fabric_exec` is then additive and adds batching and typed orchestration without replacing them.
|
|
305
319
|
```ts
|
|
306
320
|
const matches = await tools.search({ query: "deployment status" });
|
|
307
321
|
const schema = await tools.describe({ ref: matches[0].ref });
|
package/docs/interface.md
CHANGED
|
@@ -77,11 +77,11 @@ Fabric ships a general-purpose, theme-aware activity surface that works with any
|
|
|
77
77
|
- The graph renders status-coloured node shapes, orthogonal connectors, animated traffic, an optional fixed-width selected-node inspector, and directional off-canvas summaries. Traffic follows the same structural branches through the source/target lowest common ancestor. It never draws direct lines through unrelated subtrees. A large or deeply recursive graph opens around the attention-priority node. When you move between nodes, a damped spring camera retargets smoothly and the viewport does not snap. Live and replay animation drives renders only while the dashboard is open. Narrow terminals keep the centred graph and drop the inspector.
|
|
78
78
|
- Retained-run selection works as a lens over the same topology. Pressing `[` or `]` changes the highlighted run and its phase context, and live actors and remote project participants stay visible. Route records remain selectable, and they aggregate repeated traffic by source, target, topic, and kind. The recent event feed is a bounded live window. It does not replace audit history.
|
|
79
79
|
- **Inspection and control** work the same way in both views. Agent detail includes Markdown-rendered tasks and results, highlighted YAML values, model, current tool, usage, worktree, and attach metadata. Tool-call details show highlighted command, file, and edit inputs, with Markdown or YAML outputs. Persisted bash calls keep their command text. Space peeks at an agent or actor transcript. `t` toggles between summary and transcript detail. The initial bounded tail is paged directly from OMP RPC, OMP session, and Claude stream-JSON logs. At the loaded top, `k` or Up fetches one older page, `g` loads and jumps to the true beginning, and `G` jumps to the growing tail and resumes follow mode. Assistant text uses native Markdown. Tool calls retain structured arguments and results, so they get the same read, bash, search, edit, and write previews as the parent card. Credential and token redaction applies before rendering. You can steer Main and active one-shot agents or queue them a follow-up, and one-shot agents can also be stopped safely. Persistent actors accept `s` mailbox messages. Where configured, they expose model (`m`), thinking (`e`), the complete session-bound OMP host-event catalog (`v`), instructions (`i`), mailbox clearing (`c`), and export (`x`). Remote participants expose only their advertised capabilities. Control resolves their owner and reports success after acknowledgement. From Activity, global templates stay available for import (`p`), instruction editing (`i`), and deletion (`d`).
|
|
80
|
-
- `/fabric settings` opens an inline settings view that mirrors OMP core's `/settings`, with top and bottom borders, fuzzy search, and section submenus, and it writes changes to `fabric.json`.
|
|
80
|
+
- `/fabric settings` opens an inline settings view that mirrors OMP core's `/settings`, with top and bottom borders, fuzzy search, and section submenus, and it writes changes to `fabric.json`. Every session opens at the global `<active OMP agent dir>/fabric.json`. In a trusted project, pressing **Ctrl+G** anywhere in the view switches both the displayed configuration layer and the save destination to the `<project>/.omp/fabric.json` overrides and back. The global view keeps global edits visible even when a project override remains effective, and its scope banner states that precedence explicitly. Untrusted sessions stay global-only. In RPC hosts, the same hierarchy is exposed through recursive select/input dialogs; a root save-scope action replaces the Ctrl+G shortcut, while Back returns one section at a time. Full code mode, capture, executor, approvals, and UI changes apply immediately when they change the effective configuration. Mesh, agent, retention, and MCP changes persist and take effect on the next `/fabric reload`. The UI section includes **Tool display** (`full` by default or `compact`), a default-on **Agent tool preview** toggle, and a global **Update debounce** (`0`/Off through `1000ms`, default `100ms`); all apply immediately. Compact display makes the declared Fabric display name/description the card header, hides outer TypeScript at every expansion level, and retains bounded nested tool details. The Agents section selects the default runner, keeps independent OMP and runtime-enumerated Claude model pickers, and exposes free-text Veda backend, persona, and model fields for the Veda runner. List editors for `agents.defaultTools` and `capture.keepVisible` toggle known tools on and off. The `keepVisible` candidates include `fabric_exec` plus every captured extension tool.
|
|
81
81
|
|
|
82
82
|
### Keybindings
|
|
83
83
|
|
|
84
|
-
- In `/fabric settings`, **Ctrl+G** switches the displayed values and the save destination
|
|
84
|
+
- In `/fabric settings`, the view starts at global defaults, and **Ctrl+G** switches the displayed values and the save destination to trusted-project overrides and back. Untrusted sessions remain global-only.
|
|
85
85
|
- Press `1` for Activity and `2` for the unified Topology. In Topology, arrow keys move spatially between graph nodes, `h`/`l` mirror left and right, `j`/`k` follow deterministic entity order, and Tab advances to the next node. In Activity, arrows or Tab switch panes and select rows. `g` and `G` jump to the first and last selectable entity, Enter inspects, `f` cycles status filters, `[`/`]` change the retained-run lens, and `?` opens contextual help.
|
|
86
86
|
- On Main, `s` sends a user-authored message or steer, and `u` queues a user-authored follow-up through OMP's host queue.
|
|
87
87
|
- On agents and actors, Space peeks at the transcript and `t` toggles transcript/summary detail. Inside a transcript, `g` loads and jumps to the true top, and `G` jumps to the bottom and follows new output. On active one-shot agents, `s` opens a steer editor, `u` queues a follow-up, and pressing `x` twice stops the run. Remote participants expose capability-aware, owner-acknowledged `s`, `u`, and `x` controls.
|
package/docs/speculation.md
CHANGED
|
@@ -18,7 +18,8 @@ PartialCodeFieldExtractor src/speculation/partial-json.ts
|
|
|
18
18
|
▼
|
|
19
19
|
LiteralCallScanner src/speculation/scanner.ts
|
|
20
20
|
│ reparses only when appended bytes contain `)`; emits completed
|
|
21
|
-
│ root.fn(
|
|
21
|
+
│ root.fn(...) calls whose arguments are entirely literals, in both
|
|
22
|
+
│ the object-literal and positional shorthand forms;
|
|
22
23
|
│ namespaces shadowed by local bindings are tainted for the stream
|
|
23
24
|
▼
|
|
24
25
|
eligibility gate src/speculation/eligibility.ts
|
|
@@ -114,11 +115,15 @@ read; keep the allowlist to stable, idempotent reads.
|
|
|
114
115
|
- `omp.edit`/`write`/`bash`, `state.transition`/`goal`/`verify`/`checkGoal`,
|
|
115
116
|
every `write`/`execute`/`agent` risk class, and `compact.cancel`
|
|
116
117
|
(reclassified from a historic mislabeled `"read"` to `"write"`).
|
|
117
|
-
- Calls with non-literal arguments,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
- Calls with non-literal arguments, and calls on namespace roots the program
|
|
119
|
+
shadows locally. These are Cases 2 and 3 in the blog (shadow-REPL dependency
|
|
120
|
+
resolution) and belong to later work. Literal arguments (Case 1) cover the
|
|
121
|
+
common generated shapes, including `Promise.all` fan-out. Positional
|
|
122
|
+
shorthand such as `omp.read("/abs/path")` is speculated: the guest-bridge
|
|
123
|
+
argument tables are mirrored in `src/speculation/guest-args.ts`, and
|
|
124
|
+
`tests/speculation-guest-args.test.ts` evaluates the real guest setup so
|
|
125
|
+
drift between the two is caught. Drift can only cost a miss, never a wrong
|
|
126
|
+
result.
|
|
122
127
|
- `agents.*` sub-calls, the blog's headline target: a wrong speculation
|
|
123
128
|
spends real tokens. A confirmer-backed variant belongs to a later phase,
|
|
124
129
|
keyed off the budget ledger.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omp-fabric",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "A programmable tool and agent runtime for Oh My Pi (OMP)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,11 +20,12 @@
|
|
|
20
20
|
"skills/",
|
|
21
21
|
"docs/",
|
|
22
22
|
"README.md",
|
|
23
|
+
"CHANGELOG.md",
|
|
23
24
|
"LICENSE",
|
|
24
25
|
"THIRD_PARTY_NOTICES.md"
|
|
25
26
|
],
|
|
26
27
|
"scripts": {
|
|
27
|
-
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json --emitDeclarationOnly && node scripts/build.mjs && bun scripts/assert-build-artifacts.mjs",
|
|
28
|
+
"build": "tsc -p tsconfig.build.json --noEmit && node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json --emitDeclarationOnly && node scripts/build.mjs && bun scripts/assert-build-artifacts.mjs",
|
|
28
29
|
"typecheck": "tsc --noEmit",
|
|
29
30
|
"test": "bun --bun node_modules/vitest/vitest.mjs run",
|
|
30
31
|
"test:changed": "node scripts/test-dirty.mjs",
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/runtime/quickjs-runtime.ts", "../../src/runtime/guest-stack-map.ts"],
|
|
4
|
-
"sourcesContent": ["import releaseSyncVariant from \"@jitl/quickjs-singlefile-mjs-release-sync\";\nimport { newQuickJSWASMModuleFromVariant } from \"quickjs-emscripten-core\";\nimport ts from \"typescript\";\nimport { runAbortable, settleWithin } from \"../async-settlement.js\";\nimport { ompBashExitMetadata } from \"../core/omp-bash-error.js\";\nimport { createGuestStackMap, remapGuestErrorText } from \"./guest-stack-map.js\";\nimport { OMP_GUEST_ENTRYPOINT, transpileFabricCodeWithSourceMap } from \"./type-checker.js\";\n\nexport type FabricSandboxTerminationReason =\n | \"completed\"\n | \"runtime_error\"\n | \"timed_out\"\n | \"aborted\";\n\nexport interface FabricSandboxResult {\n value: unknown;\n logs: string[];\n terminationReason: FabricSandboxTerminationReason;\n error?: string;\n}\n\nexport interface FabricSandboxOptions {\n timeoutMs: number;\n memoryLimitBytes: number;\n maxLogChars?: number;\n payloads?: Record<string, string>;\n tokenBudget?: number;\n signal?: AbortSignal;\n minimumTimeoutMsForHostCall?(\n ref: string,\n args: Record<string, unknown>,\n ): number | undefined;\n transpiledCode?: string;\n transpiledSourceMap?: string;\n}\n\nexport type FabricHostCall = (\n ref: string,\n args: Record<string, unknown>,\n signal: AbortSignal,\n) => Promise<unknown>;\n\ntype QuickJsModule = Awaited<ReturnType<typeof newQuickJSWASMModuleFromVariant>>;\n\nlet quickJsModulePromise: Promise<QuickJsModule> | undefined;\n\n// Static payloads.<identifier> references (bracket access like payloads[k] is not provable).\n// Parse instead of scanning text so examples inside strings and comments do not\n// become false missing-payload failures.\nconst referencedPayloadKeys = (code: string): string[] => {\n const source = ts.createSourceFile(\n \"fabric-exec.ts\",\n `async function __fabricProgram() {\\n${code}\\n}`,\n ts.ScriptTarget.Latest,\n false,\n ts.ScriptKind.TS,\n );\n const keys: string[] = [];\n const visit = (node: ts.Node): void => {\n if (\n ts.isPropertyAccessExpression(node) &&\n ts.isIdentifier(node.expression) &&\n node.expression.text === \"payloads\" &&\n !keys.includes(node.name.text)\n ) {\n keys.push(node.name.text);\n }\n ts.forEachChild(node, visit);\n };\n visit(source);\n return keys;\n};\n\n// Reject up front when a referenced key is statically provable missing, before\n// QuickJS is even loaded.\nconst missingPayloadKeys = (\n code: string,\n payloads: Record<string, string> | undefined,\n): string[] => {\n const provided = payloads ?? {};\n return referencedPayloadKeys(code).filter((key) => !(key in provided));\n};\nconst quickJsModule = (): Promise<QuickJsModule> => {\n quickJsModulePromise ??= newQuickJSWASMModuleFromVariant(releaseSyncVariant);\n return quickJsModulePromise;\n};\n\nexport 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\"];\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 max: \"limit\", 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\", \"limit\"],\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: [\"limit\", \"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 };\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 __providerProxy = (provider, 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 (args = {}) => __call(provider + \".\" + String(property), args);\n },\n});\nglobalThis.extensions = __providerProxy(\"extensions\");\nglobalThis.memory = __providerProxy(\"memory\", { walk: __memoryWalk });\nglobalThis.state = __providerProxy(\"state\");\nglobalThis.schema = __providerProxy(\"schema\");\nglobalThis.components = __providerProxy(\"components\");\nglobalThis.compact = __providerProxy(\"compact\");\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.\nglobalThis.mcp = new Proxy({}, {\n get(_target, server) {\n if (server === \"then\") return undefined;\n if (server === \"servers\") return () => __call(\"mcp.$servers\", {});\n if (server === \"reload\") return () => __call(\"mcp.$reload\", {});\n if (server === \"register\") return (args) => __call(\"mcp.$register\", args);\n if (server === \"call\") return (args) => __call(\"mcp.$call\", args);\n return new Proxy({}, {\n get(_serverTarget, tool) {\n if (tool === \"then\") return undefined;\n return (args = {}) => __call(\"mcp.\" + String(server) + \".\" + String(tool), args);\n },\n });\n },\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`;\n\nconst formatValue = (value: unknown): string => {\n if (typeof value === \"string\") return value;\n if (value instanceof Error) return value.stack ?? value.message;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n};\n\nconst jsonText = (value: unknown): string => {\n const serialized = JSON.stringify(value);\n if (serialized === undefined) return \"null\";\n return serialized;\n};\n\nconst jsonHandle = (\n context: any,\n jsonObject: any,\n jsonParse: any,\n value: unknown,\n): any => {\n if (value === undefined) return context.undefined;\n if (value === null) return context.null;\n if (typeof value === \"string\") return context.newString(value);\n if (typeof value === \"boolean\") return value ? context.true : context.false;\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? context.newNumber(value) : context.null;\n }\n const serialized = context.newString(jsonText(value));\n try {\n return context.unwrapResult(context.callFunction(jsonParse, jsonObject, serialized));\n } finally {\n serialized.dispose();\n }\n};\n\nconst HOST_TASK_SETTLE_GRACE_MS = 250;\n\n// The release-sync WASM variant otherwise exhausts the host stack before\n// QuickJS can throw its guest-catchable InternalError.\nconst QUICKJS_MAX_STACK_SIZE_BYTES = 256 * 1024;\nconst QUICKJS_GC_LIST_ASSERTION = \"list_empty(&rt->gc_obj_list)\";\n\n// Preserve an already-computed result for this known Emscripten teardown\n// assertion while allowing every unrelated disposal failure to escape.\nconst disposeQuickJsContext = (context: any): void => {\n try {\n context.dispose();\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.includes(QUICKJS_GC_LIST_ASSERTION) && message.includes(\"JS_FreeRuntime\")) return;\n throw error;\n }\n};\n\nexport class QuickJsRuntime {\n async execute(\n code: string,\n hostCall: FabricHostCall,\n options: FabricSandboxOptions,\n ): Promise<FabricSandboxResult> {\n if (options.signal?.aborted) {\n return {\n value: undefined,\n logs: [],\n terminationReason: \"aborted\",\n error: \"Execution cancelled\",\n };\n }\n const missingKeys = missingPayloadKeys(code, options.payloads);\n if (missingKeys.length > 0) {\n const provided = Object.keys(options.payloads ?? {});\n return {\n value: undefined,\n logs: [],\n terminationReason: \"runtime_error\",\n error:\n \"Pre-execution check: \" + missingKeys.map((key) => \"payloads.\" + key).join(\", \")\n + (missingKeys.length === 1 ? \" is referenced in code but its key is missing from the payloads parameter\"\n : \" are referenced in code but their keys are missing from the payloads parameter\")\n + (provided.length ? \" (provided: \" + provided.join(\", \") + \")\" : \" (none provided)\")\n + \". Add payloads: { \" + missingKeys.join(\": '...', \") + \": '...' } to the fabric_exec arguments, then reference the value as payloads.<key>.\"\n + \" For large or quote-heavy content, keep it in top-level payloads and reference payloads.<key> instead of escaping it inside code.\",\n };\n }\n if (\n !Number.isSafeInteger(options.memoryLimitBytes) ||\n options.memoryLimitBytes < 1 ||\n options.memoryLimitBytes > 0xffff_ffff\n ) {\n return {\n value: undefined,\n logs: [],\n terminationReason: \"runtime_error\",\n error: \"QuickJS memory limit must be an integer between 1 byte and 4294967295 bytes (WASM32 maximum)\",\n };\n }\n const module = await quickJsModule();\n const context = module.newContext();\n const runtime = context.runtime;\n const jsonObject = context.getProp(context.global, \"JSON\");\n const jsonParse = context.getProp(jsonObject, \"parse\");\n const executionStartedAt = Date.now();\n let effectiveTimeoutMs = options.timeoutMs;\n let executionDeadlineAt = executionStartedAt + effectiveTimeoutMs;\n let interruptedByDeadline = false;\n runtime.setMemoryLimit(options.memoryLimitBytes);\n runtime.setMaxStackSize(QUICKJS_MAX_STACK_SIZE_BYTES);\n runtime.setInterruptHandler(() => {\n if (options.signal?.aborted === true) return true;\n if (Date.now() <= executionDeadlineAt) return false;\n interruptedByDeadline = true;\n return true;\n });\n const logs: string[] = [];\n const maxLogChars = options.maxLogChars ?? 100_000;\n let logChars = 0;\n let logsTruncated = false;\n const pendingHostPromises = new Set<any>();\n const hostTasks = new Set<Promise<void>>();\n const pendingTimers = new Set<NodeJS.Timeout>();\n let closing = false;\n let cancelled = false;\n let timedOut = false;\n let timeout: NodeJS.Timeout | undefined;\n let rejectDeadline: ((error: Error) => void) | undefined;\n let abortHandler: (() => void) | undefined;\n let activePromiseHandle: any;\n let executionGate: any;\n let pendingResolution: Promise<any> | undefined;\n const hostAbortController = new AbortController();\n const abortHostCalls = (reason: string): void => {\n if (!hostAbortController.signal.aborted) {\n hostAbortController.abort(new Error(reason));\n }\n };\n\n const rejectExecutionGate = (message: string): void => {\n if (!executionGate || executionGate.alive === false) return;\n const errorHandle = context.newError(message);\n executionGate.reject(errorHandle);\n errorHandle.dispose();\n runtime.executePendingJobs();\n };\n\n const timeoutMessage = (): string =>\n `Execution timed out after ${effectiveTimeoutMs}ms`;\n const expireDeadline = (): void => {\n if (closing || cancelled || timedOut) return;\n timedOut = true;\n const message = timeoutMessage();\n abortHostCalls(message);\n rejectExecutionGate(message);\n rejectDeadline?.(new Error(message));\n };\n const scheduleDeadline = (): void => {\n if (!rejectDeadline || closing || cancelled || timedOut) return;\n if (timeout) clearTimeout(timeout);\n timeout = setTimeout(expireDeadline, Math.max(0, executionDeadlineAt - Date.now()));\n };\n const extendExecutionTimeout = (\n ref: string,\n args: Record<string, unknown>,\n ): void => {\n const requestedTimeoutMs = options.minimumTimeoutMsForHostCall?.(ref, args);\n if (\n typeof requestedTimeoutMs !== \"number\" ||\n !Number.isFinite(requestedTimeoutMs)\n ) {\n return;\n }\n const requestedDurationMs = Math.max(1, Math.floor(requestedTimeoutMs));\n const nextDeadlineAt = Date.now() + requestedDurationMs;\n const nextTimeoutMs = nextDeadlineAt - executionStartedAt;\n if (nextDeadlineAt <= executionDeadlineAt) return;\n effectiveTimeoutMs = nextTimeoutMs;\n executionDeadlineAt = nextDeadlineAt;\n scheduleDeadline();\n };\n\n try {\n const hostFunction = context.newFunction(\n \"__fabricHostCall\",\n (referenceHandle: any, argsHandle: any) => {\n const reference = context.getString(referenceHandle);\n const dumpedArgs = context.dump(argsHandle);\n const args =\n typeof dumpedArgs === \"object\" && dumpedArgs !== null && !Array.isArray(dumpedArgs)\n ? (dumpedArgs as Record<string, unknown>)\n : {};\n extendExecutionTimeout(reference, args);\n const promise = context.newPromise();\n pendingHostPromises.add(promise);\n void promise.settled.then(() => pendingHostPromises.delete(promise));\n if (reference === \"fabric.$timer\") {\n const ms = Math.max(0, Number(args.ms ?? 0));\n const timer = setTimeout(() => {\n if (closing || promise.alive === false) return;\n promise.resolve(context.undefined);\n runtime.executePendingJobs();\n }, ms);\n timer.unref?.();\n pendingTimers.add(timer);\n void promise.settled.then(() => pendingTimers.delete(timer));\n return promise.handle;\n }\n const task = runAbortable(hostAbortController.signal, () =>\n hostCall(reference, args, hostAbortController.signal),\n )\n .then((value) => {\n if (closing || promise.alive === false) return;\n const handle = jsonHandle(context, jsonObject, jsonParse, value);\n promise.resolve(handle);\n handle.dispose();\n })\n .catch((error) => {\n if (closing || promise.alive === false) return;\n const errorHandle = context.newError(\n error instanceof Error ? error.message : String(error),\n );\n const exit = reference === \"omp.bash\"\n ? ompBashExitMetadata(error)\n : undefined;\n if (exit) {\n const metadata = jsonHandle(context, jsonObject, jsonParse, exit);\n context.setProp(errorHandle, \"__fabricBashExit\", metadata);\n metadata.dispose();\n }\n promise.reject(errorHandle);\n errorHandle.dispose();\n })\n .finally(() => {\n if (!closing) runtime.executePendingJobs();\n });\n hostTasks.add(task);\n void task.finally(() => hostTasks.delete(task));\n return promise.handle;\n },\n );\n context.setProp(context.global, \"__fabricHostCall\", hostFunction);\n hostFunction.dispose();\n\n const printFunction = context.newFunction(\"print\", (...handles: any[]) => {\n if (logsTruncated) return;\n const line = handles.map((handle) => formatValue(context.dump(handle))).join(\" \");\n const remaining = maxLogChars - logChars;\n if (line.length > remaining) {\n if (remaining > 0) logs.push(line.slice(0, remaining));\n logs.push(\"[OMP Fabric log output truncated]\");\n logsTruncated = true;\n return;\n }\n logs.push(line);\n logChars += line.length;\n });\n context.setProp(context.global, \"print\", printFunction);\n printFunction.dispose();\n\n const payloads = jsonHandle(context, jsonObject, jsonParse, options.payloads ?? {});\n context.setProp(context.global, \"payloads\", payloads);\n payloads.dispose();\n const tokenBudget = context.newNumber(options.tokenBudget ?? Number.POSITIVE_INFINITY);\n context.setProp(context.global, \"__fabricTokenBudget\", tokenBudget);\n tokenBudget.dispose();\n\n const setupResult = context.evalCode(GUEST_SETUP, \"omp-fabric-setup.js\");\n if (setupResult.error) {\n const deadlineExceeded = interruptedByDeadline || Date.now() > executionDeadlineAt;\n if (deadlineExceeded) timedOut = true;\n const error = options.signal?.aborted\n ? \"Execution cancelled\"\n : deadlineExceeded\n ? timeoutMessage()\n : formatValue(context.dump(setupResult.error));\n setupResult.error.dispose();\n abortHostCalls(error);\n return {\n value: undefined,\n logs,\n terminationReason: options.signal?.aborted\n ? \"aborted\"\n : deadlineExceeded\n ? \"timed_out\"\n : \"runtime_error\",\n error,\n };\n }\n setupResult.value.dispose();\n\n executionGate = context.newPromise();\n context.setProp(context.global, \"__fabricExecutionGate\", executionGate.handle);\n const guestBundle = options.transpiledCode === undefined\n ? transpileFabricCodeWithSourceMap(code)\n : { code: options.transpiledCode, sourceMap: options.transpiledSourceMap };\n const guestStackMap = createGuestStackMap(guestBundle.sourceMap);\n const guestLineCount = guestBundle.code.split(\"\\n\").length;\n const wrappedCode = `${guestBundle.code}\\nPromise.race([${OMP_GUEST_ENTRYPOINT}(), globalThis.__fabricExecutionGate])`;\n const evaluation = context.evalCode(wrappedCode, \"omp-fabric-guest.js\");\n runtime.executePendingJobs();\n if (evaluation.error) {\n const deadlineExceeded = interruptedByDeadline || Date.now() > executionDeadlineAt;\n if (deadlineExceeded) timedOut = true;\n const error = options.signal?.aborted\n ? \"Execution cancelled\"\n : deadlineExceeded\n ? timeoutMessage()\n : remapGuestErrorText(formatValue(context.dump(evaluation.error)), guestStackMap, guestLineCount);\n evaluation.error.dispose();\n abortHostCalls(error);\n return {\n value: undefined,\n logs,\n terminationReason: options.signal?.aborted\n ? \"aborted\"\n : deadlineExceeded\n ? \"timed_out\"\n : \"runtime_error\",\n error,\n };\n }\n\n activePromiseHandle = evaluation.value;\n const cancellation = new Promise<never>((_resolve, reject) => {\n abortHandler = () => {\n cancelled = true;\n hostAbortController.abort(options.signal?.reason);\n rejectExecutionGate(\"Execution cancelled\");\n reject(new Error(\"Execution cancelled\"));\n };\n if (options.signal?.aborted) abortHandler();\n else options.signal?.addEventListener(\"abort\", abortHandler, { once: true });\n });\n void cancellation.catch(() => undefined);\n const deadline = new Promise<never>((_resolve, reject) => {\n rejectDeadline = reject;\n scheduleDeadline();\n });\n pendingResolution = context.resolvePromise(activePromiseHandle);\n runtime.executePendingJobs();\n const resolution = await Promise.race([pendingResolution, deadline, cancellation]);\n pendingResolution = undefined;\n activePromiseHandle.dispose();\n activePromiseHandle = undefined;\n if (resolution.error) {\n const deadlineExceeded = timedOut || interruptedByDeadline || Date.now() > executionDeadlineAt;\n if (deadlineExceeded) timedOut = true;\n const error = options.signal?.aborted\n ? \"Execution cancelled\"\n : deadlineExceeded\n ? timeoutMessage()\n : remapGuestErrorText(formatValue(context.dump(resolution.error)), guestStackMap, guestLineCount);\n resolution.error.dispose();\n abortHostCalls(error);\n return {\n value: undefined,\n logs,\n terminationReason: options.signal?.aborted\n ? \"aborted\"\n : deadlineExceeded\n ? \"timed_out\"\n : \"runtime_error\",\n error,\n };\n }\n const value = context.dump(resolution.value);\n resolution.value.dispose();\n return { value, logs, terminationReason: \"completed\" };\n } catch (error) {\n const deadlineExceeded = timedOut || interruptedByDeadline || Date.now() > executionDeadlineAt;\n if (deadlineExceeded) timedOut = true;\n abortHostCalls(error instanceof Error ? error.message : String(error));\n return {\n value: undefined,\n logs,\n terminationReason: cancelled ? \"aborted\" : deadlineExceeded ? \"timed_out\" : \"runtime_error\",\n error: cancelled\n ? \"Execution cancelled\"\n : deadlineExceeded\n ? timeoutMessage()\n : error instanceof Error\n ? error.message\n : String(error),\n };\n } finally {\n if (timeout) clearTimeout(timeout);\n for (const timer of pendingTimers) clearTimeout(timer);\n if (abortHandler) options.signal?.removeEventListener(\"abort\", abortHandler);\n if (hostTasks.size > 0) {\n const settled = await settleWithin(hostTasks, HOST_TASK_SETTLE_GRACE_MS);\n if (!settled) {\n abortHostCalls(\"Fabric guest execution ended before its host calls settled\");\n await settleWithin(hostTasks, HOST_TASK_SETTLE_GRACE_MS);\n }\n runtime.executePendingJobs();\n }\n closing = true;\n if (timedOut || cancelled || pendingHostPromises.size > 0) {\n const cleanupMessage = cancelled\n ? \"Execution cancelled\"\n : timedOut\n ? timeoutMessage()\n : \"Fabric guest execution ended before its host calls settled\";\n if (!hostAbortController.signal.aborted) hostAbortController.abort(new Error(cleanupMessage));\n rejectExecutionGate(cleanupMessage);\n const errorHandle = context.newError(cleanupMessage);\n for (const promise of pendingHostPromises) promise.reject(errorHandle);\n errorHandle.dispose();\n runtime.executePendingJobs();\n await new Promise((resolve) => setImmediate(resolve));\n const settled = await Promise.race<any>([\n pendingResolution ? pendingResolution.catch(() => undefined) : Promise.resolve(undefined),\n new Promise<undefined>((resolve) => {\n const timer = setTimeout(() => resolve(undefined), 1_000);\n timer.unref?.();\n }),\n ]);\n if (settled?.error) settled.error.dispose();\n if (settled?.value) settled.value.dispose();\n for (const promise of pendingHostPromises) {\n if (promise.alive !== false) promise.dispose();\n }\n }\n if (activePromiseHandle?.alive !== false) activePromiseHandle?.dispose();\n if (executionGate?.alive !== false) executionGate?.dispose();\n runtime.executePendingJobs();\n jsonParse.dispose();\n jsonObject.dispose();\n disposeQuickJsContext(context);\n }\n }\n}\n", "// Stack frames captured from the executed guest bundle reference the emitted\n// omp-fabric-guest.js (wrapper header plus TypeScript printer layout), not the\n// author's program. These helpers decode the transpile source map and rewrite\n// error text so stack positions point back at the user-submitted code.\n\ninterface GuestSourcePosition {\n line: number;\n column: number;\n}\n\nexport interface GuestStackMap {\n lookup(line: number, column: number): GuestSourcePosition | undefined;\n}\n\ninterface GuestSourceMapJson {\n mappings?: unknown;\n}\n\ninterface MappingSegment {\n generatedColumn: number;\n sourceLine: number;\n sourceColumn: number;\n}\n\nconst BASE64_VALUES = (() => {\n const alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n const table = new Map<string, number>();\n for (let index = 0; index < alphabet.length; index += 1) {\n table.set(alphabet[index] as string, index);\n }\n return table;\n})();\n\nconst decodeVlqSegment = (segment: string): number[] => {\n const values: number[] = [];\n let index = 0;\n while (index < segment.length) {\n let value = 0;\n let shift = 0;\n let continuation = true;\n while (continuation) {\n const digit = BASE64_VALUES.get(segment[index] as string);\n if (digit === undefined) return values;\n index += 1;\n continuation = (digit & 32) !== 0;\n value += (digit & 31) * 2 ** shift;\n shift += 5;\n }\n values.push((value & 1) === 1 ? -(value >> 1) : value >> 1);\n }\n return values;\n};\n\nconst decodeMappings = (mappings: string): MappingSegment[][] => {\n const lines: MappingSegment[][] = [];\n let sourceLine = 0;\n let sourceColumn = 0;\n for (const line of mappings.split(\";\")) {\n const segments: MappingSegment[] = [];\n let generatedColumn = 0;\n for (const rawSegment of line.split(\",\")) {\n if (!rawSegment) continue;\n const values = decodeVlqSegment(rawSegment);\n // values[1] is the source index delta; single-source guest maps never\n // need it, so only generated column and source position accumulate.\n if (values.length < 4) continue;\n generatedColumn += values[0] as number;\n sourceLine += values[2] as number;\n sourceColumn += values[3] as number;\n segments.push({ generatedColumn, sourceLine, sourceColumn });\n }\n lines.push(segments);\n }\n return lines;\n};\n\nexport const createGuestStackMap = (\n sourceMapText: string | undefined,\n): GuestStackMap | undefined => {\n if (!sourceMapText) return undefined;\n let mappings: string;\n try {\n const parsed = JSON.parse(sourceMapText) as GuestSourceMapJson;\n if (typeof parsed.mappings !== \"string\") return undefined;\n mappings = parsed.mappings;\n } catch {\n return undefined;\n }\n // Validating the envelope above is cheap; decoding the VLQ mappings defers\n // to the first error lookup so clean executions pay almost nothing for\n // diagnostics they never render.\n let decoded: MappingSegment[][] | undefined;\n return {\n lookup(line, column) {\n decoded ??= decodeMappings(mappings);\n const segments = decoded[line - 1];\n if (!segments) return undefined;\n const target = column - 1;\n let best: MappingSegment | undefined;\n for (const segment of segments) {\n if (segment.generatedColumn > target) break;\n best = segment;\n }\n // Columns before the first segment point at line indentation; anchor\n // them to the first statement segment rather than leaving the frame\n // in emitted-file coordinates.\n best ??= segments[0];\n if (!best) return undefined;\n // The wrapper header occupies source line 1, so the zero-based source\n // line already equals the author's one-based program line.\n return { line: best.sourceLine, column: best.sourceColumn + 1 };\n },\n };\n};\n\nconst GUEST_FRAME_PATTERN = /omp-fabric-guest\\.js:(\\d+):(\\d+)/g;\n\nexport const remapGuestErrorText = (\n text: string,\n stackMap: GuestStackMap | undefined,\n guestLineCount?: number,\n): string => {\n if (!stackMap || !text.includes(\"omp-fabric-guest.js:\")) return text;\n return text.replace(GUEST_FRAME_PATTERN, (match, lineText, columnText) => {\n const line = Number(lineText);\n const mapped = stackMap.lookup(line, Number(columnText));\n if (mapped) return `guest code:${mapped.line}:${mapped.column}`;\n // Both runtimes append their driver call after the emitted bundle, so\n // frames beyond it can only be harness machinery, never user statements.\n if (guestLineCount !== undefined && line > guestLineCount) return \"fabric driver\";\n return match;\n });\n};\n"],
|
|
5
|
-
"mappings": "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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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",
|
|
6
|
-
"names": ["value"]
|
|
7
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
readSessionHeader
|
|
3
|
-
} from "./chunk-6QBPSZJ5.js";
|
|
4
|
-
|
|
5
|
-
// src/memory/discovery.ts
|
|
6
|
-
import fs from "node:fs";
|
|
7
|
-
import path from "node:path";
|
|
8
|
-
var SESSIONS_SUBDIR = "sessions";
|
|
9
|
-
var isJsonlFile = (name) => name.endsWith(".jsonl");
|
|
10
|
-
var encodeCwdDir = (cwd) => `--${path.resolve(cwd).replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
|
|
11
|
-
var sessionDirForCwd = (cwd, agentDir) => path.join(agentDir, SESSIONS_SUBDIR, encodeCwdDir(cwd));
|
|
12
|
-
var listJsonlInDir = (dir) => {
|
|
13
|
-
try {
|
|
14
|
-
return fs.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isFile() && isJsonlFile(entry.name)).map((entry) => path.join(dir, entry.name));
|
|
15
|
-
} catch {
|
|
16
|
-
return [];
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
var statMtime = (file) => {
|
|
20
|
-
try {
|
|
21
|
-
return fs.statSync(file).mtimeMs;
|
|
22
|
-
} catch {
|
|
23
|
-
return 0;
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
var refFromFile = (file) => {
|
|
27
|
-
const header = readSessionHeader(file);
|
|
28
|
-
return {
|
|
29
|
-
id: header?.sessionId ?? path.basename(file, ".jsonl"),
|
|
30
|
-
file,
|
|
31
|
-
cwd: header?.cwd ?? "",
|
|
32
|
-
mtime: statMtime(file)
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
var sessionsDirRoot = (agentDir) => path.join(agentDir, SESSIONS_SUBDIR);
|
|
36
|
-
var compareRefsByRecency = (left, right) => {
|
|
37
|
-
if (right.mtime !== left.mtime) return right.mtime - left.mtime;
|
|
38
|
-
return left.file < right.file ? -1 : left.file > right.file ? 1 : 0;
|
|
39
|
-
};
|
|
40
|
-
var enumerateAllSessions = (agentDir, maxSessions) => {
|
|
41
|
-
const root = sessionsDirRoot(agentDir);
|
|
42
|
-
let projectDirs = [];
|
|
43
|
-
try {
|
|
44
|
-
projectDirs = fs.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => path.join(root, entry.name));
|
|
45
|
-
} catch {
|
|
46
|
-
return [];
|
|
47
|
-
}
|
|
48
|
-
const files = [];
|
|
49
|
-
for (const dir of projectDirs) {
|
|
50
|
-
for (const file of listJsonlInDir(dir)) files.push(file);
|
|
51
|
-
}
|
|
52
|
-
return files.map(refFromFile).sort(compareRefsByRecency).slice(0, Math.max(1, maxSessions));
|
|
53
|
-
};
|
|
54
|
-
var newestSessionInDir = (dir) => {
|
|
55
|
-
const files = listJsonlInDir(dir);
|
|
56
|
-
if (files.length === 0) return null;
|
|
57
|
-
return files.map(refFromFile).sort(compareRefsByRecency)[0];
|
|
58
|
-
};
|
|
59
|
-
var AmbiguousSessionError = class extends Error {
|
|
60
|
-
constructor(session, candidates) {
|
|
61
|
-
super(`Session id ${JSON.stringify(session)} is ambiguous; use an exact session file path.`);
|
|
62
|
-
this.session = session;
|
|
63
|
-
this.candidates = candidates;
|
|
64
|
-
this.name = "AmbiguousSessionError";
|
|
65
|
-
}
|
|
66
|
-
code = "ambiguous_session";
|
|
67
|
-
};
|
|
68
|
-
var resolveSessionTarget = (agentDir, target) => {
|
|
69
|
-
if (target.endsWith(".jsonl") && fs.existsSync(target)) {
|
|
70
|
-
return refFromFile(path.resolve(target));
|
|
71
|
-
}
|
|
72
|
-
const all = enumerateAllSessions(agentDir, Number.MAX_SAFE_INTEGER);
|
|
73
|
-
const byId = all.filter((ref) => ref.id === target);
|
|
74
|
-
if (byId.length > 1) throw new AmbiguousSessionError(target, byId.map((ref) => ref.file));
|
|
75
|
-
if (byId.length === 1) return byId[0];
|
|
76
|
-
const byStem = all.filter((ref) => path.basename(ref.file, ".jsonl") === target);
|
|
77
|
-
if (byStem.length > 1) throw new AmbiguousSessionError(target, byStem.map((ref) => ref.file));
|
|
78
|
-
return byStem[0] ?? null;
|
|
79
|
-
};
|
|
80
|
-
var resolveScope = (input) => {
|
|
81
|
-
const scope = input.scope?.trim();
|
|
82
|
-
if (scope.startsWith("session:")) {
|
|
83
|
-
const target = scope.slice("session:".length).trim();
|
|
84
|
-
const ref = resolveSessionTarget(input.agentDir, target);
|
|
85
|
-
return ref ? [ref] : [];
|
|
86
|
-
}
|
|
87
|
-
if (scope === "global") {
|
|
88
|
-
return enumerateAllSessions(input.agentDir, input.maxSessions);
|
|
89
|
-
}
|
|
90
|
-
if (scope === "project") {
|
|
91
|
-
const dir2 = sessionDirForCwd(input.cwd, input.agentDir);
|
|
92
|
-
return listJsonlInDir(dir2).map(refFromFile).sort(compareRefsByRecency).slice(0, Math.max(1, input.maxSessions));
|
|
93
|
-
}
|
|
94
|
-
if (input.sessionFile) {
|
|
95
|
-
const ref = refFromFile(input.sessionFile);
|
|
96
|
-
return [ref];
|
|
97
|
-
}
|
|
98
|
-
const dir = sessionDirForCwd(input.cwd, input.agentDir);
|
|
99
|
-
const newest = newestSessionInDir(dir);
|
|
100
|
-
return newest ? [newest] : [];
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export {
|
|
104
|
-
encodeCwdDir,
|
|
105
|
-
sessionDirForCwd,
|
|
106
|
-
sessionsDirRoot,
|
|
107
|
-
enumerateAllSessions,
|
|
108
|
-
AmbiguousSessionError,
|
|
109
|
-
resolveSessionTarget,
|
|
110
|
-
resolveScope
|
|
111
|
-
};
|
|
112
|
-
//# sourceMappingURL=chunk-7BIA5BJN.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/memory/discovery.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { readSessionHeader } from \"./normalize.js\";\n\nexport interface SessionRef {\n id: string;\n file: string;\n cwd: string;\n mtime: number;\n}\n\nexport interface ResolveScopeInput {\n agentDir: string;\n cwd: string;\n scope: string;\n sessionId?: string;\n sessionFile?: string;\n maxSessions: number;\n}\n\nconst SESSIONS_SUBDIR = \"sessions\";\n\nconst isJsonlFile = (name: string): boolean => name.endsWith(\".jsonl\");\n\n/** Encode a cwd into the safe directory name OMP stores session files under. */\nexport const encodeCwdDir = (cwd: string): string =>\n `--${path.resolve(cwd).replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n\n/** Directory OMP stores this project's session JSONL files under. */\nexport const sessionDirForCwd = (cwd: string, agentDir: string): string =>\n path.join(agentDir, SESSIONS_SUBDIR, encodeCwdDir(cwd));\n\nconst listJsonlInDir = (dir: string): string[] => {\n try {\n return fs\n .readdirSync(dir, { withFileTypes: true })\n .filter((entry) => entry.isFile() && isJsonlFile(entry.name))\n .map((entry) => path.join(dir, entry.name));\n } catch {\n return [];\n }\n};\n\nconst statMtime = (file: string): number => {\n try {\n return fs.statSync(file).mtimeMs;\n } catch {\n return 0;\n }\n};\n\nconst refFromFile = (file: string): SessionRef => {\n const header = readSessionHeader(file);\n return {\n id: header?.sessionId ?? path.basename(file, \".jsonl\"),\n file,\n cwd: header?.cwd ?? \"\",\n mtime: statMtime(file),\n };\n};\n\nexport const sessionsDirRoot = (agentDir: string): string => path.join(agentDir, SESSIONS_SUBDIR);\n\nconst compareRefsByRecency = (left: SessionRef, right: SessionRef): number => {\n if (right.mtime !== left.mtime) return right.mtime - left.mtime;\n return left.file < right.file ? -1 : left.file > right.file ? 1 : 0;\n};\n\n/**\n * Enumerate every session JSONL file under the agent dir, newest first by\n * file mtime. Bounded by `maxSessions`. Returns refs with resolved cwd and\n * sessionId from each file header (falling back to the file stem).\n */\nexport const enumerateAllSessions = (agentDir: string, maxSessions: number): SessionRef[] => {\n const root = sessionsDirRoot(agentDir);\n let projectDirs: string[] = [];\n try {\n projectDirs = fs\n .readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => path.join(root, entry.name));\n } catch {\n return [];\n }\n const files: string[] = [];\n for (const dir of projectDirs) {\n for (const file of listJsonlInDir(dir)) files.push(file);\n }\n return files\n .map(refFromFile)\n .sort(compareRefsByRecency)\n .slice(0, Math.max(1, maxSessions));\n};\n\nconst newestSessionInDir = (dir: string): SessionRef | null => {\n const files = listJsonlInDir(dir);\n if (files.length === 0) return null;\n return files\n .map(refFromFile)\n .sort(compareRefsByRecency)[0]!;\n};\n\nexport class AmbiguousSessionError extends Error {\n readonly code = \"ambiguous_session\";\n\n constructor(\n readonly session: string,\n readonly candidates: string[],\n ) {\n super(`Session id ${JSON.stringify(session)} is ambiguous; use an exact session file path.`);\n this.name = \"AmbiguousSessionError\";\n }\n}\n\nexport const resolveSessionTarget = (\n agentDir: string,\n target: string,\n): SessionRef | null => {\n if (target.endsWith(\".jsonl\") && fs.existsSync(target)) {\n return refFromFile(path.resolve(target));\n }\n const all = enumerateAllSessions(agentDir, Number.MAX_SAFE_INTEGER);\n const byId = all.filter((ref) => ref.id === target);\n if (byId.length > 1) throw new AmbiguousSessionError(target, byId.map((ref) => ref.file));\n if (byId.length === 1) return byId[0]!;\n const byStem = all.filter((ref) => path.basename(ref.file, \".jsonl\") === target);\n if (byStem.length > 1) throw new AmbiguousSessionError(target, byStem.map((ref) => ref.file));\n return byStem[0] ?? null;\n};\n\n/**\n * Resolve a scope string into the concrete set of session files to search.\n *\n * - `session` (default): the current session file (from invocation context\n * if available, else the newest session for the current cwd).\n * - `project`: all sessions stored under the current cwd's default session dir.\n * - `global`: all sessions under the agent dir, bounded by `maxSessions`.\n * - `session:<id-or-path>`: one specific session by id or file path.\n */\nexport const resolveScope = (input: ResolveScopeInput): SessionRef[] => {\n const scope = input.scope?.trim();\n if (scope.startsWith(\"session:\")) {\n const target = scope.slice(\"session:\".length).trim();\n const ref = resolveSessionTarget(input.agentDir, target);\n return ref ? [ref] : [];\n }\n if (scope === \"global\") {\n return enumerateAllSessions(input.agentDir, input.maxSessions);\n }\n if (scope === \"project\") {\n const dir = sessionDirForCwd(input.cwd, input.agentDir);\n return listJsonlInDir(dir)\n .map(refFromFile)\n .sort(compareRefsByRecency)\n .slice(0, Math.max(1, input.maxSessions));\n }\n // default: session\n if (input.sessionFile) {\n const ref = refFromFile(input.sessionFile);\n return [ref];\n }\n const dir = sessionDirForCwd(input.cwd, input.agentDir);\n const newest = newestSessionInDir(dir);\n return newest ? [newest] : [];\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["dir"]
|
|
7
|
-
}
|