fixo-cli 1.0.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of fixo-cli might be problematic. Click here for more details.
- package/CHANGELOG.md +62 -0
- package/README.md +18 -14
- package/dist/agent/agent-client.d.ts +28 -6
- package/dist/agent/agent-client.d.ts.map +1 -1
- package/dist/agent/agent-client.js +118 -39
- package/dist/agent/agent-client.js.map +1 -1
- package/dist/agent/agent-pool.d.ts +55 -6
- package/dist/agent/agent-pool.d.ts.map +1 -1
- package/dist/agent/agent-pool.js +120 -20
- package/dist/agent/agent-pool.js.map +1 -1
- package/dist/agent/auto-verifier.d.ts +55 -0
- package/dist/agent/auto-verifier.d.ts.map +1 -0
- package/dist/agent/auto-verifier.js +50 -0
- package/dist/agent/auto-verifier.js.map +1 -0
- package/dist/agent/command-parser.d.ts +37 -0
- package/dist/agent/command-parser.d.ts.map +1 -1
- package/dist/agent/command-parser.js +473 -1
- package/dist/agent/command-parser.js.map +1 -1
- package/dist/agent/context-builder.d.ts +24 -0
- package/dist/agent/context-builder.d.ts.map +1 -0
- package/dist/agent/context-builder.js +197 -0
- package/dist/agent/context-builder.js.map +1 -0
- package/dist/agent/conversation.d.ts +32 -2
- package/dist/agent/conversation.d.ts.map +1 -1
- package/dist/agent/conversation.js +84 -9
- package/dist/agent/conversation.js.map +1 -1
- package/dist/agent/duration.d.ts +24 -0
- package/dist/agent/duration.d.ts.map +1 -0
- package/dist/agent/duration.js +42 -0
- package/dist/agent/duration.js.map +1 -0
- package/dist/agent/file-writing-rules.d.ts +19 -0
- package/dist/agent/file-writing-rules.d.ts.map +1 -0
- package/dist/agent/file-writing-rules.js +31 -0
- package/dist/agent/file-writing-rules.js.map +1 -0
- package/dist/agent/mcp-bridge.js +1 -1
- package/dist/agent/mcp-bridge.js.map +1 -1
- package/dist/agent/orchestrator.d.ts +45 -0
- package/dist/agent/orchestrator.d.ts.map +1 -1
- package/dist/agent/orchestrator.js +140 -3
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/parser-adapter.d.ts +17 -0
- package/dist/agent/parser-adapter.d.ts.map +1 -1
- package/dist/agent/parser-adapter.js +311 -7
- package/dist/agent/parser-adapter.js.map +1 -1
- package/dist/agent/predictive-gate.d.ts.map +1 -1
- package/dist/agent/predictive-gate.js +4 -1
- package/dist/agent/predictive-gate.js.map +1 -1
- package/dist/agent/provider-cooldown.d.ts.map +1 -1
- package/dist/agent/provider-cooldown.js +3 -2
- package/dist/agent/provider-cooldown.js.map +1 -1
- package/dist/agent/providers-manager.d.ts +5 -0
- package/dist/agent/providers-manager.d.ts.map +1 -1
- package/dist/agent/providers-manager.js +119 -8
- package/dist/agent/providers-manager.js.map +1 -1
- package/dist/agent/repo-map.d.ts +18 -1
- package/dist/agent/repo-map.d.ts.map +1 -1
- package/dist/agent/repo-map.js +144 -54
- package/dist/agent/repo-map.js.map +1 -1
- package/dist/agent/retry.js +1 -2
- package/dist/agent/retry.js.map +1 -1
- package/dist/agent/single-agent.d.ts +13 -0
- package/dist/agent/single-agent.d.ts.map +1 -1
- package/dist/agent/single-agent.js +225 -37
- package/dist/agent/single-agent.js.map +1 -1
- package/dist/agent/skills.d.ts.map +1 -1
- package/dist/agent/skills.js +2 -1
- package/dist/agent/skills.js.map +1 -1
- package/dist/agent/subagent.js +2 -2
- package/dist/agent/subagent.js.map +1 -1
- package/dist/agent/task-router.d.ts +46 -0
- package/dist/agent/task-router.d.ts.map +1 -0
- package/dist/agent/task-router.js +352 -0
- package/dist/agent/task-router.js.map +1 -0
- package/dist/agent/telemetry.d.ts +29 -1
- package/dist/agent/telemetry.d.ts.map +1 -1
- package/dist/agent/telemetry.js +29 -11
- package/dist/agent/telemetry.js.map +1 -1
- package/dist/agent/tool-definitions.d.ts +3 -0
- package/dist/agent/tool-definitions.d.ts.map +1 -0
- package/dist/agent/tool-definitions.js +519 -0
- package/dist/agent/tool-definitions.js.map +1 -0
- package/dist/agent/tool-executor.d.ts +6 -1
- package/dist/agent/tool-executor.d.ts.map +1 -1
- package/dist/agent/tool-executor.js +99 -553
- package/dist/agent/tool-executor.js.map +1 -1
- package/dist/agent/tools/command-tools.d.ts +6 -0
- package/dist/agent/tools/command-tools.d.ts.map +1 -0
- package/dist/agent/tools/command-tools.js +104 -0
- package/dist/agent/tools/command-tools.js.map +1 -0
- package/dist/agent/tools/file-tools.d.ts +15 -0
- package/dist/agent/tools/file-tools.d.ts.map +1 -0
- package/dist/agent/tools/file-tools.js +551 -0
- package/dist/agent/tools/file-tools.js.map +1 -0
- package/dist/agent/tools/todo-tools.d.ts +3 -0
- package/dist/agent/tools/todo-tools.d.ts.map +1 -0
- package/dist/agent/tools/todo-tools.js +70 -0
- package/dist/agent/tools/todo-tools.js.map +1 -0
- package/dist/agent/web-impl.d.ts.map +1 -1
- package/dist/agent/web-impl.js +45 -0
- package/dist/agent/web-impl.js.map +1 -1
- package/dist/agent/worker-agent.d.ts +3 -1
- package/dist/agent/worker-agent.d.ts.map +1 -1
- package/dist/agent/worker-agent.js +56 -16
- package/dist/agent/worker-agent.js.map +1 -1
- package/dist/config.d.ts +253 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +81 -1
- package/dist/config.js.map +1 -1
- package/dist/git/git-manager.d.ts +33 -2
- package/dist/git/git-manager.d.ts.map +1 -1
- package/dist/git/git-manager.js +111 -15
- package/dist/git/git-manager.js.map +1 -1
- package/dist/git/git-ops.d.ts.map +1 -1
- package/dist/git/git-ops.js +2 -1
- package/dist/git/git-ops.js.map +1 -1
- package/dist/index.js +89 -8
- package/dist/index.js.map +1 -1
- package/dist/lsp/lsp-manager.js +1 -1
- package/dist/lsp/lsp-manager.js.map +1 -1
- package/dist/model-outcomes.d.ts.map +1 -1
- package/dist/model-outcomes.js +2 -1
- package/dist/model-outcomes.js.map +1 -1
- package/dist/planner.d.ts +0 -9
- package/dist/planner.d.ts.map +1 -1
- package/dist/planner.js +0 -9
- package/dist/planner.js.map +1 -1
- package/dist/project-memory.d.ts +12 -1
- package/dist/project-memory.d.ts.map +1 -1
- package/dist/project-memory.js +8 -6
- package/dist/project-memory.js.map +1 -1
- package/dist/runtime/loop-mitigation.d.ts +119 -0
- package/dist/runtime/loop-mitigation.d.ts.map +1 -0
- package/dist/runtime/loop-mitigation.js +192 -0
- package/dist/runtime/loop-mitigation.js.map +1 -0
- package/dist/runtime/os-sandbox.d.ts +100 -0
- package/dist/runtime/os-sandbox.d.ts.map +1 -0
- package/dist/runtime/os-sandbox.js +246 -0
- package/dist/runtime/os-sandbox.js.map +1 -0
- package/dist/runtime/run-inventory.d.ts +17 -0
- package/dist/runtime/run-inventory.d.ts.map +1 -0
- package/dist/runtime/run-inventory.js +49 -0
- package/dist/runtime/run-inventory.js.map +1 -0
- package/dist/runtime/session-snapshots.d.ts +52 -2
- package/dist/runtime/session-snapshots.d.ts.map +1 -1
- package/dist/runtime/session-snapshots.js +76 -1
- package/dist/runtime/session-snapshots.js.map +1 -1
- package/dist/runtime/staging.d.ts.map +1 -1
- package/dist/runtime/staging.js +4 -1
- package/dist/runtime/staging.js.map +1 -1
- package/dist/runtime/task-session.d.ts +14 -0
- package/dist/runtime/task-session.d.ts.map +1 -1
- package/dist/runtime/task-session.js +26 -0
- package/dist/runtime/task-session.js.map +1 -1
- package/dist/setup-wizard.d.ts +11 -3
- package/dist/setup-wizard.d.ts.map +1 -1
- package/dist/setup-wizard.js +113 -15
- package/dist/setup-wizard.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/commands/context-commands.d.ts +7 -0
- package/dist/ui/commands/context-commands.d.ts.map +1 -0
- package/dist/ui/commands/context-commands.js +241 -0
- package/dist/ui/commands/context-commands.js.map +1 -0
- package/dist/ui/commands/index.d.ts +3 -0
- package/dist/ui/commands/index.d.ts.map +1 -0
- package/dist/ui/commands/index.js +46 -0
- package/dist/ui/commands/index.js.map +1 -0
- package/dist/ui/commands/info-commands.d.ts +15 -0
- package/dist/ui/commands/info-commands.d.ts.map +1 -0
- package/dist/ui/commands/info-commands.js +122 -0
- package/dist/ui/commands/info-commands.js.map +1 -0
- package/dist/ui/commands/model-commands.d.ts +5 -0
- package/dist/ui/commands/model-commands.d.ts.map +1 -0
- package/dist/ui/commands/model-commands.js +417 -0
- package/dist/ui/commands/model-commands.js.map +1 -0
- package/dist/ui/commands/session-commands.d.ts +5 -0
- package/dist/ui/commands/session-commands.d.ts.map +1 -0
- package/dist/ui/commands/session-commands.js +154 -0
- package/dist/ui/commands/session-commands.js.map +1 -0
- package/dist/ui/commands/task-commands.d.ts +8 -0
- package/dist/ui/commands/task-commands.d.ts.map +1 -0
- package/dist/ui/commands/task-commands.js +152 -0
- package/dist/ui/commands/task-commands.js.map +1 -0
- package/dist/ui/commands/types.d.ts +46 -0
- package/dist/ui/commands/types.d.ts.map +1 -0
- package/dist/ui/commands/types.js +2 -0
- package/dist/ui/commands/types.js.map +1 -0
- package/dist/ui/commands/workspace-commands.d.ts +8 -0
- package/dist/ui/commands/workspace-commands.d.ts.map +1 -0
- package/dist/ui/commands/workspace-commands.js +131 -0
- package/dist/ui/commands/workspace-commands.js.map +1 -0
- package/dist/ui/loading-animation.d.ts +24 -0
- package/dist/ui/loading-animation.d.ts.map +1 -0
- package/dist/ui/loading-animation.js +123 -0
- package/dist/ui/loading-animation.js.map +1 -0
- package/dist/ui/markdown-stream.js +2 -2
- package/dist/ui/markdown-stream.js.map +1 -1
- package/dist/ui/prompt.d.ts +7 -0
- package/dist/ui/prompt.d.ts.map +1 -1
- package/dist/ui/prompt.js +461 -1143
- package/dist/ui/prompt.js.map +1 -1
- package/dist/ui/render-primitives.d.ts +6 -0
- package/dist/ui/render-primitives.d.ts.map +1 -1
- package/dist/ui/render-primitives.js +30 -13
- package/dist/ui/render-primitives.js.map +1 -1
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +2 -0
- package/dist/ui/render.js.map +1 -1
- package/dist/ui/session-header.d.ts +13 -0
- package/dist/ui/session-header.d.ts.map +1 -1
- package/dist/ui/session-header.js +6 -0
- package/dist/ui/session-header.js.map +1 -1
- package/package.json +22 -4
- package/scripts/check-vendor-wasm.js +55 -0
- package/vendor/tree-sitter-bash.wasm +0 -0
- package/vendor/tree-sitter-go.wasm +0 -0
- package/vendor/tree-sitter-javascript.wasm +0 -0
- package/vendor/tree-sitter-python.wasm +0 -0
- package/vendor/tree-sitter-rust.wasm +0 -0
- package/vendor/tree-sitter-tsx.wasm +0 -0
- package/vendor/tree-sitter-typescript.wasm +0 -0
- package/vendor/tree-sitter.wasm +0 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* os-sandbox.ts — Phase 1.2 OS-level sandbox wrapper for `run_command`.
|
|
3
|
+
*
|
|
4
|
+
* The CLI already enforces a regex-based command-parser layer and
|
|
5
|
+
* a WorkspaceGuard path-boundary check before any shell command runs.
|
|
6
|
+
* That stops the obvious cases (`> /etc/passwd`, `sed -i ../foo`) but
|
|
7
|
+
* is not a complete defence against a confused or prompt-injected
|
|
8
|
+
* model — a regex blocklist is a speed bump, not a wall.
|
|
9
|
+
*
|
|
10
|
+
* This module adds an OS-enforced second layer that the model has no
|
|
11
|
+
* way around: `sandbox-exec` on macOS, `bwrap` on Linux. Both use the
|
|
12
|
+
* same OS primitives Apple's own `xcrun` and Flatpak rely on, so the
|
|
13
|
+
* deny semantics are exactly the kernel's, not a JavaScript regex.
|
|
14
|
+
*
|
|
15
|
+
* Design choices, deliberate:
|
|
16
|
+
*
|
|
17
|
+
* - Default is OFF (config `safety.sandboxMode === 'guard'`). Turning
|
|
18
|
+
* it on changes runtime behaviour and we want users to opt in
|
|
19
|
+
* explicitly, not be surprised by a build that suddenly fails
|
|
20
|
+
* because their `npm test` script writes to `~/.npm/_cacache`.
|
|
21
|
+
*
|
|
22
|
+
* - When ON and the platform binary is missing, we surface a clear
|
|
23
|
+
* structured error instead of silently downgrading. A user who
|
|
24
|
+
* opted into `os-sandbox` and got the regex layer would have the
|
|
25
|
+
* worst of both worlds — false safety.
|
|
26
|
+
*
|
|
27
|
+
* - Network is allowed by default — most legitimate build/test
|
|
28
|
+
* commands need it (npm install, cargo fetch, pip). Callers that
|
|
29
|
+
* want strict isolation can pass `allowNetwork: false`.
|
|
30
|
+
*
|
|
31
|
+
* - Reads are unrestricted. The agent legitimately needs to inspect
|
|
32
|
+
* the system to plan its work. Writes are the dangerous side.
|
|
33
|
+
*
|
|
34
|
+
* - The macOS profile is generated at runtime into the OS temp dir
|
|
35
|
+
* from a template (no static `.sb` file shipped) so allow-write
|
|
36
|
+
* paths can be parameterised per-invocation without macros.
|
|
37
|
+
* `sandbox-exec` is technically deprecated by Apple but still
|
|
38
|
+
* ships and works on darwin 25; what's available today wins.
|
|
39
|
+
*/
|
|
40
|
+
import { spawnSync } from 'node:child_process';
|
|
41
|
+
import fs from 'node:fs';
|
|
42
|
+
import os from 'node:os';
|
|
43
|
+
import path from 'node:path';
|
|
44
|
+
/**
|
|
45
|
+
* Why a sandboxed `run_command` couldn't actually be wrapped in an
|
|
46
|
+
* OS sandbox. Distinct from a *command-failed-inside-the-sandbox*
|
|
47
|
+
* error, which surfaces through {@link SpawnSyncReturns.status} as
|
|
48
|
+
* usual.
|
|
49
|
+
*/
|
|
50
|
+
export class SandboxUnavailableError extends Error {
|
|
51
|
+
platform;
|
|
52
|
+
reason;
|
|
53
|
+
constructor(platform, reason) {
|
|
54
|
+
super(`OS sandbox unavailable on ${platform}: ${reason}`);
|
|
55
|
+
this.platform = platform;
|
|
56
|
+
this.reason = reason;
|
|
57
|
+
this.name = 'SandboxUnavailableError';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/* ──────────────────────── Public entry point ──────────────────────── */
|
|
61
|
+
/**
|
|
62
|
+
* Run a shell command inside an OS-enforced sandbox.
|
|
63
|
+
*
|
|
64
|
+
* Throws {@link SandboxUnavailableError} if the current platform has
|
|
65
|
+
* no supported wrapper or the required binary is not on `$PATH`.
|
|
66
|
+
* Otherwise returns the same {@link SpawnSyncReturns} shape the
|
|
67
|
+
* caller would get from a plain `spawnSync(command, { shell: true })`
|
|
68
|
+
* call — so the call site only differs by routing decision, not by
|
|
69
|
+
* result handling.
|
|
70
|
+
*/
|
|
71
|
+
export function runSandboxed(command, opts) {
|
|
72
|
+
const platform = process.platform;
|
|
73
|
+
if (platform === 'darwin') {
|
|
74
|
+
return runSandboxedMacos(command, opts);
|
|
75
|
+
}
|
|
76
|
+
if (platform === 'linux') {
|
|
77
|
+
return runSandboxedLinux(command, opts);
|
|
78
|
+
}
|
|
79
|
+
throw new SandboxUnavailableError(platform, 'no supported OS sandbox wrapper for this platform');
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Best-effort probe: would {@link runSandboxed} succeed on this
|
|
83
|
+
* machine without actually running a command? Used by the CLI's
|
|
84
|
+
* startup sanity check so we can warn at boot rather than at the
|
|
85
|
+
* first command. Returns `null` on success, a structured reason on
|
|
86
|
+
* failure.
|
|
87
|
+
*/
|
|
88
|
+
export function probeSandbox() {
|
|
89
|
+
const platform = process.platform;
|
|
90
|
+
if (platform === 'darwin') {
|
|
91
|
+
const which = whichBinary('sandbox-exec');
|
|
92
|
+
return which ? { ok: true } : { ok: false, reason: '`sandbox-exec` not on $PATH (macOS system tool)' };
|
|
93
|
+
}
|
|
94
|
+
if (platform === 'linux') {
|
|
95
|
+
const which = whichBinary('bwrap');
|
|
96
|
+
if (which)
|
|
97
|
+
return { ok: true };
|
|
98
|
+
return {
|
|
99
|
+
ok: false,
|
|
100
|
+
reason: '`bwrap` (bubblewrap) not installed. Install with: apt install bubblewrap | dnf install bubblewrap | apk add bubblewrap',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return { ok: false, reason: `unsupported platform: ${platform}` };
|
|
104
|
+
}
|
|
105
|
+
/* ──────────────────────── macOS: sandbox-exec ──────────────────────── */
|
|
106
|
+
function runSandboxedMacos(command, opts) {
|
|
107
|
+
if (!whichBinary('sandbox-exec')) {
|
|
108
|
+
throw new SandboxUnavailableError('darwin', '`sandbox-exec` not on $PATH');
|
|
109
|
+
}
|
|
110
|
+
const profile = buildMacosProfile({
|
|
111
|
+
allowedWritePaths: dedupeAndResolve([...opts.allowedWritePaths, os.tmpdir()]),
|
|
112
|
+
allowNetwork: opts.allowNetwork,
|
|
113
|
+
});
|
|
114
|
+
// Write the profile to a temp file. sandbox-exec will read it
|
|
115
|
+
// before exec; we delete it immediately after the child returns.
|
|
116
|
+
const profilePath = path.join(os.tmpdir(), `fixo-sandbox-${process.pid}-${Date.now()}.sb`);
|
|
117
|
+
fs.writeFileSync(profilePath, profile, { encoding: 'utf-8', mode: 0o600 });
|
|
118
|
+
try {
|
|
119
|
+
return spawnSync('sandbox-exec', ['-f', profilePath, '/bin/sh', '-c', command], {
|
|
120
|
+
cwd: opts.cwd,
|
|
121
|
+
encoding: 'utf-8',
|
|
122
|
+
timeout: opts.timeout ?? 60_000,
|
|
123
|
+
maxBuffer: opts.maxBuffer ?? 1024 * 1024,
|
|
124
|
+
env: opts.env ?? process.env,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
try {
|
|
129
|
+
fs.unlinkSync(profilePath);
|
|
130
|
+
}
|
|
131
|
+
catch { /* safe: best-effort cleanup of tmp profile */ }
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function buildMacosProfile(opts) {
|
|
135
|
+
// Quote each allow-write path in TinyScheme-style string literal
|
|
136
|
+
// form. sandbox-exec uses backslash-escaped double-quoted strings.
|
|
137
|
+
const writeRoots = opts.allowedWritePaths
|
|
138
|
+
.map((p) => ` (subpath ${quoteSb(p)})`)
|
|
139
|
+
.join('\n');
|
|
140
|
+
const networkRule = opts.allowNetwork ? '(allow network*)' : '(deny network*)';
|
|
141
|
+
// Inspired by Apple's own /System/Library/Sandbox/Profiles seed
|
|
142
|
+
// profiles. `allow file-read*` is total because the agent must be
|
|
143
|
+
// able to read the system to do useful work; writes are the side
|
|
144
|
+
// we lock down. The auxiliary `allow` rules (sysctl, mach-lookup,
|
|
145
|
+
// process-fork, ipc-posix-shm) are the bare minimum a `/bin/sh`
|
|
146
|
+
// exec of a typical build command needs to not crash.
|
|
147
|
+
return `(version 1)
|
|
148
|
+
(deny default)
|
|
149
|
+
|
|
150
|
+
; Reads: unrestricted. The agent needs to inspect the system.
|
|
151
|
+
(allow file-read*)
|
|
152
|
+
|
|
153
|
+
; Writes: only inside the explicitly-allowed roots.
|
|
154
|
+
(allow file-write*
|
|
155
|
+
${writeRoots})
|
|
156
|
+
|
|
157
|
+
; Process / sysctl / IPC: required for /bin/sh to execute a command.
|
|
158
|
+
(allow process-fork)
|
|
159
|
+
(allow process-exec*)
|
|
160
|
+
(allow sysctl-read)
|
|
161
|
+
(allow mach-lookup)
|
|
162
|
+
(allow file-ioctl)
|
|
163
|
+
(allow ipc-posix-shm)
|
|
164
|
+
(allow signal (target self))
|
|
165
|
+
|
|
166
|
+
; Network rule (gated by caller).
|
|
167
|
+
${networkRule}
|
|
168
|
+
`;
|
|
169
|
+
}
|
|
170
|
+
function quoteSb(s) {
|
|
171
|
+
// sandbox-exec strings use double-quotes with backslash escaping.
|
|
172
|
+
return `"${s.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
|
173
|
+
}
|
|
174
|
+
/* ──────────────────────── Linux: bubblewrap ──────────────────────── */
|
|
175
|
+
function runSandboxedLinux(command, opts) {
|
|
176
|
+
if (!whichBinary('bwrap')) {
|
|
177
|
+
throw new SandboxUnavailableError('linux', '`bwrap` (bubblewrap) not installed. Install with: apt install bubblewrap | dnf install bubblewrap | apk add bubblewrap');
|
|
178
|
+
}
|
|
179
|
+
const writeRoots = dedupeAndResolve([...opts.allowedWritePaths, os.tmpdir()]);
|
|
180
|
+
const args = [
|
|
181
|
+
// Read-only mount the standard system tree. /usr is the
|
|
182
|
+
// important one — that's where /bin/sh, coreutils, etc. live.
|
|
183
|
+
'--ro-bind', '/usr', '/usr',
|
|
184
|
+
'--ro-bind', '/bin', '/bin',
|
|
185
|
+
'--ro-bind', '/sbin', '/sbin',
|
|
186
|
+
'--ro-bind', '/lib', '/lib',
|
|
187
|
+
'--symlink', 'usr/lib64', '/lib64',
|
|
188
|
+
'--ro-bind', '/etc', '/etc',
|
|
189
|
+
// Procfs + devtmpfs: needed by virtually every binary.
|
|
190
|
+
'--proc', '/proc',
|
|
191
|
+
'--dev', '/dev',
|
|
192
|
+
// Tmpfs for /run and /var so the child can drop pidfiles.
|
|
193
|
+
'--tmpfs', '/run',
|
|
194
|
+
'--tmpfs', '/var',
|
|
195
|
+
];
|
|
196
|
+
for (const wr of writeRoots) {
|
|
197
|
+
args.push('--bind', wr, wr);
|
|
198
|
+
}
|
|
199
|
+
if (!opts.allowNetwork) {
|
|
200
|
+
args.push('--unshare-net');
|
|
201
|
+
}
|
|
202
|
+
// PID + user namespaces — cheap isolation that doesn't break
|
|
203
|
+
// most build tools.
|
|
204
|
+
args.push('--unshare-pid');
|
|
205
|
+
args.push('--die-with-parent');
|
|
206
|
+
args.push('--chdir', opts.cwd);
|
|
207
|
+
args.push('/bin/sh', '-c', command);
|
|
208
|
+
return spawnSync('bwrap', args, {
|
|
209
|
+
cwd: opts.cwd,
|
|
210
|
+
encoding: 'utf-8',
|
|
211
|
+
timeout: opts.timeout ?? 60_000,
|
|
212
|
+
maxBuffer: opts.maxBuffer ?? 1024 * 1024,
|
|
213
|
+
env: opts.env ?? process.env,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
/* ──────────────────────── Helpers ──────────────────────── */
|
|
217
|
+
function whichBinary(name) {
|
|
218
|
+
const which = spawnSync('which', [name], { encoding: 'utf-8' });
|
|
219
|
+
return which.status === 0 && which.stdout.trim().length > 0;
|
|
220
|
+
}
|
|
221
|
+
function dedupeAndResolve(paths) {
|
|
222
|
+
const seen = new Set();
|
|
223
|
+
const out = [];
|
|
224
|
+
for (const p of paths) {
|
|
225
|
+
// Canonicalize: on macOS `/var/folders/...` is actually
|
|
226
|
+
// `/private/var/folders/...`; sandbox-exec matches on the
|
|
227
|
+
// canonical path, so an allow rule written against the symlink
|
|
228
|
+
// path silently denies. Same trap exists for `/tmp` →
|
|
229
|
+
// `/private/tmp`. realpathSync resolves both. Fall back to the
|
|
230
|
+
// resolved-but-uncanonicalized path if the directory does not
|
|
231
|
+
// exist yet (callers may pass it before creation).
|
|
232
|
+
let abs;
|
|
233
|
+
try {
|
|
234
|
+
abs = fs.realpathSync(path.resolve(p));
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
abs = path.resolve(p);
|
|
238
|
+
}
|
|
239
|
+
if (seen.has(abs))
|
|
240
|
+
continue;
|
|
241
|
+
seen.add(abs);
|
|
242
|
+
out.push(abs);
|
|
243
|
+
}
|
|
244
|
+
return out;
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=os-sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"os-sandbox.js","sourceRoot":"","sources":["../../src/runtime/os-sandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
/**
|
|
3
|
+
* Phase 4b — Shared per-run file inventory cache.
|
|
4
|
+
* Memoizes listDir and fileStats for the duration of an orchestrator run
|
|
5
|
+
* to reduce redundant fs calls from parallel workers.
|
|
6
|
+
*/
|
|
7
|
+
export declare class RunInventory {
|
|
8
|
+
readonly runId: string;
|
|
9
|
+
private dirCache;
|
|
10
|
+
private statCache;
|
|
11
|
+
constructor(runId: string);
|
|
12
|
+
listDir(dirPath: string): fs.Dirent[];
|
|
13
|
+
fileStats(filePath: string): fs.Stats;
|
|
14
|
+
invalidate(filePath: string): void;
|
|
15
|
+
}
|
|
16
|
+
export declare function getRunInventory(runId: string): RunInventory;
|
|
17
|
+
//# sourceMappingURL=run-inventory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-inventory.d.ts","sourceRoot":"","sources":["../../src/runtime/run-inventory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAGzB;;;;GAIG;AACH,qBAAa,YAAY;aAIK,KAAK,EAAE,MAAM;IAHzC,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,SAAS,CAA+B;gBAEpB,KAAK,EAAE,MAAM;IAEzC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE;IASrC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,CAAC,KAAK;IASrC,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;CASnC;AAID,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAO3D"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Phase 4b — Shared per-run file inventory cache.
|
|
5
|
+
* Memoizes listDir and fileStats for the duration of an orchestrator run
|
|
6
|
+
* to reduce redundant fs calls from parallel workers.
|
|
7
|
+
*/
|
|
8
|
+
export class RunInventory {
|
|
9
|
+
runId;
|
|
10
|
+
dirCache = new Map();
|
|
11
|
+
statCache = new Map();
|
|
12
|
+
constructor(runId) {
|
|
13
|
+
this.runId = runId;
|
|
14
|
+
}
|
|
15
|
+
listDir(dirPath) {
|
|
16
|
+
const cached = this.dirCache.get(dirPath);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
const list = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
20
|
+
this.dirCache.set(dirPath, list);
|
|
21
|
+
return list;
|
|
22
|
+
}
|
|
23
|
+
fileStats(filePath) {
|
|
24
|
+
const cached = this.statCache.get(filePath);
|
|
25
|
+
if (cached)
|
|
26
|
+
return cached;
|
|
27
|
+
const stats = fs.statSync(filePath);
|
|
28
|
+
this.statCache.set(filePath, stats);
|
|
29
|
+
return stats;
|
|
30
|
+
}
|
|
31
|
+
invalidate(filePath) {
|
|
32
|
+
this.statCache.delete(filePath);
|
|
33
|
+
// Invalidate the parent directory's listing so it gets re-read
|
|
34
|
+
const parentDir = path.dirname(filePath);
|
|
35
|
+
this.dirCache.delete(parentDir);
|
|
36
|
+
// Also invalidate the file itself in case it was considered a directory
|
|
37
|
+
this.dirCache.delete(filePath);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const instances = new Map();
|
|
41
|
+
export function getRunInventory(runId) {
|
|
42
|
+
let inv = instances.get(runId);
|
|
43
|
+
if (!inv) {
|
|
44
|
+
inv = new RunInventory(runId);
|
|
45
|
+
instances.set(runId, inv);
|
|
46
|
+
}
|
|
47
|
+
return inv;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=run-inventory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-inventory.js","sourceRoot":"","sources":["../../src/runtime/run-inventory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;GAIG;AACH,MAAM,OAAO,YAAY;IAIK;IAHpB,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC1C,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAEhD,YAA4B,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IAE7C,OAAO,CAAC,OAAe;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAC,QAAgB;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,UAAU,CAAC,QAAgB;QACzB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAEhC,+DAA+D;QAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAChC,wEAAwE;QACxE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;CACF;AAED,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwB,CAAC;AAElD,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;QAC9B,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { ChatContentBlock } from '../shared/types.js';
|
|
1
2
|
import { type TodoList } from '../context/todo.js';
|
|
2
3
|
export declare const SNAPSHOT_VERSION: 1;
|
|
3
4
|
export declare const SNAPSHOT_KIND: "fixo-cli-session";
|
|
4
5
|
export type AgentMode = 'PLAN' | 'BUILD' | 'EXPLORE' | 'SCOUT';
|
|
5
6
|
export interface SessionMessage {
|
|
6
7
|
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
7
|
-
content: string;
|
|
8
|
+
content: string | ChatContentBlock[];
|
|
8
9
|
/** Tool name for `role === 'tool'` messages. */
|
|
9
10
|
name?: string;
|
|
10
11
|
/** Monotonic per-conversation index. */
|
|
@@ -29,8 +30,17 @@ export interface SessionSnapshot {
|
|
|
29
30
|
mode: AgentMode;
|
|
30
31
|
/** Files the user had selected (e.g. via `--files` or the file picker). */
|
|
31
32
|
selectedFiles: string[];
|
|
32
|
-
/** Optional user-supplied session summary
|
|
33
|
+
/** Optional user-supplied session summary (auto-derived from the
|
|
34
|
+
* first user prompt when not set). */
|
|
33
35
|
summary?: string;
|
|
36
|
+
/**
|
|
37
|
+
* User-chosen human-readable label for this session — what the user
|
|
38
|
+
* sees in the header, in `/sessions`, and what they pass to `/resume`.
|
|
39
|
+
* Distinct from {@link summary} (auto-derived) and {@link id} (file
|
|
40
|
+
* basename); ids are kept stable across renames so existing resume
|
|
41
|
+
* links never break.
|
|
42
|
+
*/
|
|
43
|
+
label?: string;
|
|
34
44
|
/** Optional system-prompt override (FIXO.md block stripped, but
|
|
35
45
|
* the caller's original override preserved). */
|
|
36
46
|
fixedInstructions?: string;
|
|
@@ -47,6 +57,10 @@ export interface SaveInput {
|
|
|
47
57
|
mode: AgentMode;
|
|
48
58
|
selectedFiles: string[];
|
|
49
59
|
summary?: string;
|
|
60
|
+
/** User-chosen session label. See {@link SessionSnapshot.label}. */
|
|
61
|
+
label?: string;
|
|
62
|
+
/** Reuse a specific id (only used by /resume to overwrite in place). */
|
|
63
|
+
id?: string;
|
|
50
64
|
fixedInstructions?: string;
|
|
51
65
|
/** If omitted, the todo list is reloaded from disk. */
|
|
52
66
|
todo?: TodoList;
|
|
@@ -71,6 +85,42 @@ export interface SnapshotListEntry {
|
|
|
71
85
|
tokens: number;
|
|
72
86
|
items: number;
|
|
73
87
|
summary?: string;
|
|
88
|
+
label?: string;
|
|
74
89
|
}
|
|
75
90
|
export declare function listSnapshots(cwd: string): SnapshotListEntry[];
|
|
91
|
+
/**
|
|
92
|
+
* Maximum label length. Long enough for "clinic-website-accessibility-audit"
|
|
93
|
+
* but short enough to fit in a session header pill on a 100-col terminal.
|
|
94
|
+
*/
|
|
95
|
+
export declare const MAX_LABEL_LENGTH = 64;
|
|
96
|
+
/**
|
|
97
|
+
* Returns true if the label is safe to store, render, and search.
|
|
98
|
+
*
|
|
99
|
+
* Rules:
|
|
100
|
+
* - 1..MAX_LABEL_LENGTH characters
|
|
101
|
+
* - letters, digits, dash, underscore, dot, and spaces only
|
|
102
|
+
* - no path separators (`/`, `\`) so a label can never affect
|
|
103
|
+
* where the snapshot file lives on disk
|
|
104
|
+
* - no shell metacharacters (backtick, `$`, `;`, `|`, `&`, `<`, `>`)
|
|
105
|
+
* so a future render path that interpolates the label cannot be
|
|
106
|
+
* hijacked
|
|
107
|
+
*
|
|
108
|
+
* The validator is conservative on purpose — labels are user-facing,
|
|
109
|
+
* not creative writing. The file id stays as the durable identifier.
|
|
110
|
+
*/
|
|
111
|
+
export declare function isValidSessionLabel(label: string): boolean;
|
|
112
|
+
export interface RenameResult {
|
|
113
|
+
ok: boolean;
|
|
114
|
+
id: string;
|
|
115
|
+
label?: string;
|
|
116
|
+
error?: string;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Atomically rewrite the `label` field of an existing snapshot.
|
|
120
|
+
* The on-disk file basename (the snapshot id) is **never** renamed —
|
|
121
|
+
* existing `/resume <id>` invocations keep working after a relabel.
|
|
122
|
+
*
|
|
123
|
+
* Pass `label: undefined` to clear an existing label.
|
|
124
|
+
*/
|
|
125
|
+
export declare function renameSnapshot(cwd: string, id: string, label: string | undefined): RenameResult;
|
|
76
126
|
//# sourceMappingURL=session-snapshots.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-snapshots.d.ts","sourceRoot":"","sources":["../../src/runtime/session-snapshots.ts"],"names":[],"mappings":"AA4BA,OAAO,EAGL,KAAK,QAAQ,EACd,MAAM,oBAAoB,CAAC;AAM5B,eAAO,MAAM,gBAAgB,EAAG,CAAU,CAAC;AAC3C,eAAO,MAAM,aAAa,EAAG,kBAA2B,CAAC;AAEzD,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"session-snapshots.d.ts","sourceRoot":"","sources":["../../src/runtime/session-snapshots.ts"],"names":[],"mappings":"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"}
|
|
@@ -51,7 +51,7 @@ export function snapshotPath(cwd, id) {
|
|
|
51
51
|
return path.join(dirForCwd(cwd), `${id}.json`);
|
|
52
52
|
}
|
|
53
53
|
export function saveSnapshot(input, now = new Date()) {
|
|
54
|
-
const id = makeSnapshotId(now);
|
|
54
|
+
const id = input.id ?? makeSnapshotId(now);
|
|
55
55
|
const file = snapshotPath(input.cwd, id);
|
|
56
56
|
const dir = path.dirname(file);
|
|
57
57
|
try {
|
|
@@ -73,6 +73,7 @@ export function saveSnapshot(input, now = new Date()) {
|
|
|
73
73
|
mode: input.mode,
|
|
74
74
|
selectedFiles: input.selectedFiles,
|
|
75
75
|
summary: input.summary,
|
|
76
|
+
label: input.label,
|
|
76
77
|
fixedInstructions: input.fixedInstructions,
|
|
77
78
|
todo,
|
|
78
79
|
};
|
|
@@ -154,6 +155,7 @@ export function listSnapshots(cwd) {
|
|
|
154
155
|
tokens: typeof obj.tokens === 'number' ? obj.tokens : 0,
|
|
155
156
|
items,
|
|
156
157
|
summary: typeof obj.summary === 'string' ? obj.summary : undefined,
|
|
158
|
+
label: typeof obj.label === 'string' ? obj.label : undefined,
|
|
157
159
|
});
|
|
158
160
|
}
|
|
159
161
|
catch {
|
|
@@ -163,4 +165,77 @@ export function listSnapshots(cwd) {
|
|
|
163
165
|
out.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
164
166
|
return out;
|
|
165
167
|
}
|
|
168
|
+
/* ──────────────────────── rename ──────────────────────── */
|
|
169
|
+
/**
|
|
170
|
+
* Maximum label length. Long enough for "clinic-website-accessibility-audit"
|
|
171
|
+
* but short enough to fit in a session header pill on a 100-col terminal.
|
|
172
|
+
*/
|
|
173
|
+
export const MAX_LABEL_LENGTH = 64;
|
|
174
|
+
/**
|
|
175
|
+
* Returns true if the label is safe to store, render, and search.
|
|
176
|
+
*
|
|
177
|
+
* Rules:
|
|
178
|
+
* - 1..MAX_LABEL_LENGTH characters
|
|
179
|
+
* - letters, digits, dash, underscore, dot, and spaces only
|
|
180
|
+
* - no path separators (`/`, `\`) so a label can never affect
|
|
181
|
+
* where the snapshot file lives on disk
|
|
182
|
+
* - no shell metacharacters (backtick, `$`, `;`, `|`, `&`, `<`, `>`)
|
|
183
|
+
* so a future render path that interpolates the label cannot be
|
|
184
|
+
* hijacked
|
|
185
|
+
*
|
|
186
|
+
* The validator is conservative on purpose — labels are user-facing,
|
|
187
|
+
* not creative writing. The file id stays as the durable identifier.
|
|
188
|
+
*/
|
|
189
|
+
export function isValidSessionLabel(label) {
|
|
190
|
+
if (typeof label !== 'string')
|
|
191
|
+
return false;
|
|
192
|
+
const trimmed = label.trim();
|
|
193
|
+
if (trimmed.length === 0 || trimmed.length > MAX_LABEL_LENGTH)
|
|
194
|
+
return false;
|
|
195
|
+
// Allow Unicode letters/digits + space + dash + underscore + dot.
|
|
196
|
+
return /^[\p{L}\p{N}._\- ]+$/u.test(trimmed);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Atomically rewrite the `label` field of an existing snapshot.
|
|
200
|
+
* The on-disk file basename (the snapshot id) is **never** renamed —
|
|
201
|
+
* existing `/resume <id>` invocations keep working after a relabel.
|
|
202
|
+
*
|
|
203
|
+
* Pass `label: undefined` to clear an existing label.
|
|
204
|
+
*/
|
|
205
|
+
export function renameSnapshot(cwd, id, label) {
|
|
206
|
+
if (label !== undefined && !isValidSessionLabel(label)) {
|
|
207
|
+
return {
|
|
208
|
+
ok: false,
|
|
209
|
+
id,
|
|
210
|
+
error: `invalid label: must be 1..${MAX_LABEL_LENGTH} chars, letters/digits/space/dash/underscore/dot only`,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
const loaded = loadSnapshot(cwd, id);
|
|
214
|
+
if (!loaded.ok || !loaded.snapshot) {
|
|
215
|
+
return { ok: false, id, error: loaded.error ?? 'snapshot not found' };
|
|
216
|
+
}
|
|
217
|
+
const updated = {
|
|
218
|
+
...loaded.snapshot,
|
|
219
|
+
label: label?.trim() || undefined,
|
|
220
|
+
};
|
|
221
|
+
const file = snapshotPath(cwd, id);
|
|
222
|
+
const tmp = `${file}.tmp`;
|
|
223
|
+
try {
|
|
224
|
+
fs.writeFileSync(tmp, JSON.stringify(updated, null, 2), {
|
|
225
|
+
encoding: 'utf-8',
|
|
226
|
+
mode: 0o600,
|
|
227
|
+
});
|
|
228
|
+
fs.renameSync(tmp, file);
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
try {
|
|
232
|
+
fs.unlinkSync(tmp);
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
/* ignore tmp cleanup failure */
|
|
236
|
+
}
|
|
237
|
+
return { ok: false, id, error: err.message };
|
|
238
|
+
}
|
|
239
|
+
return { ok: true, id, label: updated.label };
|
|
240
|
+
}
|
|
166
241
|
//# sourceMappingURL=session-snapshots.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-snapshots.js","sourceRoot":"","sources":["../../src/runtime/session-snapshots.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,MAAM,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"session-snapshots.js","sourceRoot":"","sources":["../../src/runtime/session-snapshots.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staging.d.ts","sourceRoot":"","sources":["../../src/runtime/staging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;
|
|
1
|
+
{"version":3,"file":"staging.d.ts","sourceRoot":"","sources":["../../src/runtime/staging.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/staging.js
CHANGED
|
@@ -35,6 +35,7 @@ import crypto from 'node:crypto';
|
|
|
35
35
|
import fs from 'node:fs';
|
|
36
36
|
import path from 'node:path';
|
|
37
37
|
import { WorkspaceGuard } from '../workspace-guard.js';
|
|
38
|
+
import { getRunInventory } from './run-inventory.js';
|
|
38
39
|
// ---------------------------------------------------------------------------
|
|
39
40
|
// Errors
|
|
40
41
|
// ---------------------------------------------------------------------------
|
|
@@ -52,7 +53,7 @@ export class PreCommitHookRejectedError extends Error {
|
|
|
52
53
|
id;
|
|
53
54
|
cause;
|
|
54
55
|
constructor(id, cause) {
|
|
55
|
-
super(`
|
|
56
|
+
super(`Write rejected by pre-commit hook. Reason: ${String(cause)}. (Staged write id: ${id})`);
|
|
56
57
|
this.name = 'PreCommitHookRejectedError';
|
|
57
58
|
this.id = id;
|
|
58
59
|
this.cause = cause;
|
|
@@ -303,6 +304,7 @@ export class AtomicStagingManager {
|
|
|
303
304
|
const bytes = Buffer.byteLength(fs.readFileSync(target, 'utf-8'), 'utf-8');
|
|
304
305
|
// Tidy up the meta sidecar.
|
|
305
306
|
rmSafe(entry.metaPath);
|
|
307
|
+
getRunInventory(this.runId).invalidate(target);
|
|
306
308
|
return {
|
|
307
309
|
committed: true,
|
|
308
310
|
targetPath: target,
|
|
@@ -404,6 +406,7 @@ export class AtomicStagingManager {
|
|
|
404
406
|
rmSafe(backup);
|
|
405
407
|
rmSafe(metaPath);
|
|
406
408
|
const bytes = Buffer.byteLength(fs.readFileSync(resolved, 'utf-8'), 'utf-8');
|
|
409
|
+
getRunInventory(this.runId).invalidate(resolved);
|
|
407
410
|
return { ok: true, path: resolved, bytes };
|
|
408
411
|
}
|
|
409
412
|
catch (err) {
|