koneck 2.25.40 → 2.25.42

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.
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,UAAU,EAAE,IAAkC,CAAC;AAE5D,kGAAkG;AAClG,eAAO,MAAM,SAAS,KAAK,CAAC;AAc5B;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CA0BpE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAe/C;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAO9C;AAED,sFAAsF;AACtF,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAO1C"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,UAAU,EAAE,IAAkC,CAAC;AAE5D,kGAAkG;AAClG,eAAO,MAAM,SAAS,KAAK,CAAC;AAc5B;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAqCpE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAe/C;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAO9C;AAED,sFAAsF;AACtF,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAO1C"}
package/dist/plan.js CHANGED
@@ -36,7 +36,16 @@ function coerceState(value) {
36
36
  * the tool, and the tool only helps if it is used.
37
37
  */
38
38
  export function parsePlan(input, now) {
39
- const raw = input?.steps ?? input;
39
+ let raw = input?.steps ?? input;
40
+ // A numbered list in a string is a plan. A model that wrote one out has done the thinking the
41
+ // tool is for, and refusing it over the container teaches it to stop calling the tool — which
42
+ // is what happened: rejected, it went back to narrating and building nothing.
43
+ if (typeof raw === 'string') {
44
+ raw = raw
45
+ .split('\n')
46
+ .map(line => line.replace(/^\s*(?:[-*•]|\d+[.)])\s*/, '').trim())
47
+ .filter(Boolean);
48
+ }
40
49
  if (!Array.isArray(raw)) {
41
50
  return 'ERROR: plan needs a "steps" array, e.g. ' +
42
51
  '{"steps":[{"text":"design the ledger schema","state":"doing"}]}.';
package/dist/plan.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"plan.js","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * What a run is allowed to touch, and whether the operating system is enforcing it.
3
+ *
4
+ * There are two layers here and they are not equally strong, which matters enough to say plainly
5
+ * rather than bury. Path checks on KONECK's own file tools are certain: those tools are ours, and
6
+ * a refusal there is a refusal. A shell command is a different matter — once `bash -c` is running
7
+ * it can write anywhere the user can, and no amount of checking the command string changes that.
8
+ * The only real answer for commands is the operating system, so on Linux they are run inside
9
+ * bubblewrap where it is installed.
10
+ *
11
+ * Where no such facility exists — Windows, or a Linux box without bwrap — commands are not
12
+ * confined at all, and this module says so rather than implying a protection that is not there.
13
+ * A sandbox that is believed in but absent is worse than no sandbox, because it changes what
14
+ * people are willing to run.
15
+ */
16
+ export type SandboxMode = 'off' | 'workspace-write' | 'read-only';
17
+ export interface SandboxSpec {
18
+ mode: SandboxMode;
19
+ /** Absolute directories that may be written, in workspace-write. Empty in read-only. */
20
+ writableRoots: string[];
21
+ }
22
+ /** How commands are confined on this machine, if at all. */
23
+ export type Confinement = 'bubblewrap' | 'none';
24
+ export declare const SANDBOX_MODES: readonly SandboxMode[];
25
+ /**
26
+ * Whether a real sandbox is available for shell commands.
27
+ *
28
+ * Probed once by running it, not by looking for the binary: bubblewrap is present but unusable on
29
+ * plenty of systems — unprivileged user namespaces disabled, or a container that forbids nesting —
30
+ * and finding that out when the first command fails would break the run instead of degrading.
31
+ */
32
+ export declare function detectConfinement(platform?: string): Confinement;
33
+ /** Only for tests, which must be able to ask the question again. */
34
+ export declare function resetConfinementCache(): void;
35
+ export declare function resolveSandbox(mode: SandboxMode | undefined, cwd: string, extraDirs?: readonly string[]): SandboxSpec;
36
+ export interface PathVerdict {
37
+ allowed: boolean;
38
+ reason?: string;
39
+ }
40
+ /**
41
+ * Whether a file tool may write to a path.
42
+ *
43
+ * Reads are not restricted. An agent that cannot read outside its workspace cannot look up the
44
+ * library it is being asked to use, and confining reads buys little: the risk being managed here
45
+ * is a run that damages something, not one that learns something.
46
+ */
47
+ export declare function checkWrite(spec: SandboxSpec, absPath: string): PathVerdict;
48
+ /**
49
+ * The command line that runs a shell command under confinement, or null for none.
50
+ *
51
+ * Everything is bound read-only, the writable roots are bound read-write over the top, and /tmp is
52
+ * a fresh tmpfs. The network is left alone: an agent that cannot reach the network cannot install
53
+ * a dependency, which is most of what it is asked to do, and cutting it off would make the mode
54
+ * unusable rather than safe.
55
+ */
56
+ export declare function confineCommand(spec: SandboxSpec, cwd: string, file: string, args: readonly string[], confinement?: Confinement): {
57
+ file: string;
58
+ args: string[];
59
+ } | null;
60
+ /** What the mode actually gives you here, said without overstating it. */
61
+ export declare function describeSandbox(spec: SandboxSpec, confinement?: Confinement): string;
62
+ //# sourceMappingURL=sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,iBAAiB,GAAG,WAAW,CAAC;AAElE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,wFAAwF;IACxF,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,4DAA4D;AAC5D,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,MAAM,CAAC;AAEhD,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAA4C,CAAC;AAI7F;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,GAAE,MAAyB,GAAG,WAAW,CAWlF;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,IAAI,IAAI,CAA8B;AAE3E,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,GAAG,SAAS,EAC7B,GAAG,EAAE,MAAM,EACX,SAAS,GAAE,SAAS,MAAM,EAAO,GAChC,WAAW,CAKb;AAQD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,CAY1E;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,WAAW,GAAE,WAAiC,GAC7C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAazC;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,EAAE,WAAW,GAAE,WAAiC,GAAG,MAAM,CAezG"}
@@ -0,0 +1,102 @@
1
+ import path from 'path';
2
+ import { execaSync } from 'execa';
3
+ export const SANDBOX_MODES = ['off', 'workspace-write', 'read-only'];
4
+ let cachedConfinement = null;
5
+ /**
6
+ * Whether a real sandbox is available for shell commands.
7
+ *
8
+ * Probed once by running it, not by looking for the binary: bubblewrap is present but unusable on
9
+ * plenty of systems — unprivileged user namespaces disabled, or a container that forbids nesting —
10
+ * and finding that out when the first command fails would break the run instead of degrading.
11
+ */
12
+ export function detectConfinement(platform = process.platform) {
13
+ if (cachedConfinement !== null)
14
+ return cachedConfinement;
15
+ if (platform !== 'linux') {
16
+ cachedConfinement = 'none';
17
+ return cachedConfinement;
18
+ }
19
+ try {
20
+ const probe = execaSync('bwrap', ['--ro-bind', '/', '/', '--', '/bin/true'], { reject: false, timeout: 5_000 });
21
+ cachedConfinement = probe.exitCode === 0 ? 'bubblewrap' : 'none';
22
+ }
23
+ catch {
24
+ cachedConfinement = 'none';
25
+ }
26
+ return cachedConfinement;
27
+ }
28
+ /** Only for tests, which must be able to ask the question again. */
29
+ export function resetConfinementCache() { cachedConfinement = null; }
30
+ export function resolveSandbox(mode, cwd, extraDirs = []) {
31
+ const chosen = mode && SANDBOX_MODES.includes(mode) ? mode : 'off';
32
+ if (chosen === 'read-only')
33
+ return { mode: chosen, writableRoots: [] };
34
+ const roots = [cwd, ...extraDirs].map(d => path.resolve(d));
35
+ return { mode: chosen, writableRoots: chosen === 'off' ? [] : roots };
36
+ }
37
+ /** Whether one path sits inside one root, without `/work` matching `/workspace`. */
38
+ function within(root, target) {
39
+ const rel = path.relative(root, target);
40
+ return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));
41
+ }
42
+ /**
43
+ * Whether a file tool may write to a path.
44
+ *
45
+ * Reads are not restricted. An agent that cannot read outside its workspace cannot look up the
46
+ * library it is being asked to use, and confining reads buys little: the risk being managed here
47
+ * is a run that damages something, not one that learns something.
48
+ */
49
+ export function checkWrite(spec, absPath) {
50
+ if (spec.mode === 'off')
51
+ return { allowed: true };
52
+ if (spec.mode === 'read-only') {
53
+ return { allowed: false, reason: 'the sandbox is read-only, so nothing can be written or changed' };
54
+ }
55
+ const target = path.resolve(absPath);
56
+ if (spec.writableRoots.some(root => within(root, target)))
57
+ return { allowed: true };
58
+ return {
59
+ allowed: false,
60
+ reason: `${target} is outside the writable area (${spec.writableRoots.join(', ')}). ` +
61
+ 'Start KONECK with --add-dir to include another directory.',
62
+ };
63
+ }
64
+ /**
65
+ * The command line that runs a shell command under confinement, or null for none.
66
+ *
67
+ * Everything is bound read-only, the writable roots are bound read-write over the top, and /tmp is
68
+ * a fresh tmpfs. The network is left alone: an agent that cannot reach the network cannot install
69
+ * a dependency, which is most of what it is asked to do, and cutting it off would make the mode
70
+ * unusable rather than safe.
71
+ */
72
+ export function confineCommand(spec, cwd, file, args, confinement = detectConfinement()) {
73
+ if (spec.mode === 'off' || confinement !== 'bubblewrap')
74
+ return null;
75
+ const wrapper = [
76
+ '--ro-bind', '/', '/',
77
+ '--dev', '/dev',
78
+ '--proc', '/proc',
79
+ '--tmpfs', '/tmp',
80
+ '--die-with-parent', // the sandbox goes when the run does, rather than outliving it
81
+ ];
82
+ for (const root of spec.writableRoots)
83
+ wrapper.push('--bind', root, root);
84
+ wrapper.push('--chdir', path.resolve(cwd), '--', file, ...args);
85
+ return { file: 'bwrap', args: wrapper };
86
+ }
87
+ /** What the mode actually gives you here, said without overstating it. */
88
+ export function describeSandbox(spec, confinement = detectConfinement()) {
89
+ if (spec.mode === 'off')
90
+ return 'off — file tools and commands are unrestricted';
91
+ const files = spec.mode === 'read-only'
92
+ ? 'file tools cannot write anything'
93
+ : `file tools can write only inside ${spec.writableRoots.join(', ')}`;
94
+ const commands = confinement === 'bubblewrap'
95
+ ? spec.mode === 'read-only'
96
+ ? 'and commands run in a sandbox with no writable directory'
97
+ : 'and commands run in a sandbox with the same writable area'
98
+ : 'and commands are NOT confined here — no sandbox is available on this system, so a command ' +
99
+ 'can still write anywhere you can. They are gated by approval instead';
100
+ return `${spec.mode} — ${files}, ${commands}.`;
101
+ }
102
+ //# sourceMappingURL=sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"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"}
package/dist/tools.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { ToolDefinition, ReadFilesArgs, WriteFileArgs, ApplyDiffArgs, ExecuteCommandArgs, ListDirArgs, GlobSearchArgs, GrepSearchArgs, MoveFileArgs, DeleteFileArgs, SearchReplaceArgs, FetchUrlArgs, RememberArgs, WebSearchArgs } from './types.js';
2
+ import type { SandboxSpec } from './sandbox.js';
2
3
  export declare const TOOL_DEFINITIONS: ToolDefinition[];
3
4
  /**
4
5
  * Lines returned for one file unless a window is asked for.
@@ -54,7 +55,7 @@ export declare function shellFor(command: string, platform?: string, env?: NodeJ
54
55
  * that were neither — Windows built-ins piped through `2>nul`, run under bash.
55
56
  */
56
57
  export declare function describeShell(platform?: string, env?: NodeJS.ProcessEnv): string;
57
- export declare function executeCommand(args: ExecuteCommandArgs, cwd: string, requireApproval: boolean, onOutput?: (lastLine: string) => void): Promise<string>;
58
+ export declare function executeCommand(args: ExecuteCommandArgs, cwd: string, requireApproval: boolean, onOutput?: (lastLine: string) => void, sandbox?: SandboxSpec): Promise<string>;
58
59
  export declare function listDir(args: ListDirArgs, cwd: string): Promise<string>;
59
60
  export declare function globSearch(args: GlobSearchArgs, cwd: string): Promise<string>;
60
61
  export declare function grepSearch(args: GrepSearchArgs, cwd: string): Promise<string>;
@@ -111,5 +112,27 @@ export declare function unknownToolError(name: string, available: readonly strin
111
112
  * `command` has made the same mistake whatever name it used for the tool.
112
113
  */
113
114
  export declare function normalizeToolArgs(tool: string, argsJson: string): string;
114
- export declare function dispatchTool(name: string, argsJson: string, cwd: string, requireApproval: boolean, onOutput?: (lastLine: string) => void): Promise<string>;
115
+ /**
116
+ * Required arguments a call is missing, checked against the schema the model was given.
117
+ *
118
+ * Done once here rather than in each tool, because the failure is the same everywhere and the
119
+ * consequence was ugly: `write_file` without a path reached path.resolve and returned
120
+ * `The "paths[1]" argument must be of type string. Received undefined` — a Node internal naming
121
+ * an argument index and a parameter the tool does not have. A run hit that five times running,
122
+ * announcing each time that it would "create the project structure", because nothing in the
123
+ * message said what was wrong.
124
+ */
125
+ export declare function missingRequiredArgs(tool: string, parsed: unknown): string | null;
126
+ /** The paths a call would change, so the sandbox can be applied in one place. */
127
+ export declare function writeTargets(tool: string, parsed: unknown): string[];
128
+ /**
129
+ * Whether a tool result reports a failure.
130
+ *
131
+ * One definition, used by the engine and by everything that draws a result, because they had
132
+ * drifted: a sandbox denial was recorded as a failure by the engine and drawn with a green tick
133
+ * by the CI writer, which printed one unconditionally. The outcome a user most needs to see —
134
+ * "that write did not happen" — looked exactly like success.
135
+ */
136
+ export declare function isToolFailure(result: string): boolean;
137
+ export declare function dispatchTool(name: string, argsJson: string, cwd: string, requireApproval: boolean, onOutput?: (lastLine: string) => void, sandbox?: SandboxSpec): Promise<string>;
115
138
  //# sourceMappingURL=tools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/dist/tools.js CHANGED
@@ -7,6 +7,7 @@ import { validateCode } from './astValidator.js';
7
7
  import { tui } from './tui.js';
8
8
  import { appendMemory } from './memory.js';
9
9
  import { GIT_TOOL_DEFINITIONS, dispatchGitTool } from './git-tools.js';
10
+ import { checkWrite, confineCommand } from './sandbox.js';
10
11
  export const TOOL_DEFINITIONS = [
11
12
  {
12
13
  name: 'read_files',
@@ -338,6 +339,18 @@ function renderWindow(filePath, content, offset, limit) {
338
339
  `what you need instead of paging through it.`;
339
340
  return header + '\n' + body + footer;
340
341
  }
342
+ /**
343
+ * A missing required argument, said in a way the model can act on.
344
+ *
345
+ * Without this, `write_file` with no path reached path.resolve and came back as
346
+ * `The "paths[1]" argument must be of type string. Received undefined` — a Node internal about
347
+ * an argument index, mentioning a parameter the tool does not even have. A real run hit it five
348
+ * times in a row, each time announcing it would "create the project structure", because nothing
349
+ * in that message told it what was actually wrong.
350
+ */
351
+ function missingArg(tool, field, example) {
352
+ return `ERROR: ${tool} needs a "${field}". Example: ${example}`;
353
+ }
341
354
  export async function readFiles(args, cwd) {
342
355
  // Said plainly rather than thrown. A missing field used to surface as "Cannot read properties
343
356
  // of undefined (reading 'map')", which tells the model nothing it can act on.
@@ -361,6 +374,12 @@ export async function readFiles(args, cwd) {
361
374
  .join('\n\n');
362
375
  }
363
376
  export async function writeFile(args, cwd, requireApproval) {
377
+ if (typeof args.path !== 'string' || args.path.trim() === '') {
378
+ return missingArg('write_file', 'path', '{"path":"src/App.jsx","content":"…"}. One file per call — there is no way to write several at once.');
379
+ }
380
+ if (typeof args.content !== 'string') {
381
+ return missingArg('write_file', 'content', '{"path":"src/App.jsx","content":"the file contents"}');
382
+ }
364
383
  const abs = path.resolve(cwd, args.path);
365
384
  const validation = validateCode(args.content, abs);
366
385
  if (!validation.valid) {
@@ -479,7 +498,7 @@ export function describeShell(platform = process.platform, env = process.env) {
479
498
  ? (env['ComSpec'] ?? 'cmd.exe')
480
499
  : (env['SHELL'] ?? '/bin/sh');
481
500
  }
482
- export async function executeCommand(args, cwd, requireApproval, onOutput) {
501
+ export async function executeCommand(args, cwd, requireApproval, onOutput, sandbox = { mode: 'off', writableRoots: [] }) {
483
502
  if (requireApproval) {
484
503
  const approved = await tui.confirmCommand(args.command);
485
504
  if (!approved)
@@ -488,7 +507,10 @@ export async function executeCommand(args, cwd, requireApproval, onOutput) {
488
507
  const execCwd = args.cwd ? path.resolve(cwd, args.cwd) : cwd;
489
508
  const { ms, clamped } = resolveTimeout(args.timeout);
490
509
  const shell = shellFor(args.command);
491
- const child = execa(shell.file, shell.args, {
510
+ // Wrapped rather than trusted. Checking a command string for what it will touch is guesswork;
511
+ // running it where it cannot reach anything else is not.
512
+ const confined = confineCommand(sandbox, execCwd, shell.file, shell.args);
513
+ const child = execa(confined?.file ?? shell.file, confined?.args ?? shell.args, {
492
514
  cwd: execCwd,
493
515
  all: true,
494
516
  reject: false,
@@ -1099,7 +1121,75 @@ export function normalizeToolArgs(tool, argsJson) {
1099
1121
  }
1100
1122
  return JSON.stringify(out);
1101
1123
  }
1102
- export async function dispatchTool(name, argsJson, cwd, requireApproval, onOutput) {
1124
+ /**
1125
+ * Required arguments a call is missing, checked against the schema the model was given.
1126
+ *
1127
+ * Done once here rather than in each tool, because the failure is the same everywhere and the
1128
+ * consequence was ugly: `write_file` without a path reached path.resolve and returned
1129
+ * `The "paths[1]" argument must be of type string. Received undefined` — a Node internal naming
1130
+ * an argument index and a parameter the tool does not have. A run hit that five times running,
1131
+ * announcing each time that it would "create the project structure", because nothing in the
1132
+ * message said what was wrong.
1133
+ */
1134
+ export function missingRequiredArgs(tool, parsed) {
1135
+ const def = TOOL_DEFINITIONS.find(d => d.name === tool);
1136
+ const schema = def?.parameters;
1137
+ const required = schema?.required ?? [];
1138
+ if (required.length === 0)
1139
+ return null;
1140
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
1141
+ return `ERROR: ${tool} needs an object of arguments with: ${required.join(', ')}.`;
1142
+ }
1143
+ const args = parsed;
1144
+ const missing = required.filter(key => {
1145
+ const value = args[key];
1146
+ if (value === undefined || value === null)
1147
+ return true;
1148
+ const type = schema?.properties?.[key]?.type;
1149
+ if (type === 'string')
1150
+ return typeof value !== 'string' || value.trim() === '';
1151
+ if (type === 'array')
1152
+ return !Array.isArray(value) || value.length === 0;
1153
+ return false;
1154
+ });
1155
+ if (missing.length === 0)
1156
+ return null;
1157
+ const shape = Object.keys(args).length ? `You sent: ${Object.keys(args).join(', ')}.` : 'You sent nothing.';
1158
+ return `ERROR: ${tool} is missing ${missing.map(m => `"${m}"`).join(' and ')}. ` +
1159
+ `${shape} It needs: ${required.join(', ')}.`;
1160
+ }
1161
+ /** The paths a call would change, so the sandbox can be applied in one place. */
1162
+ export function writeTargets(tool, parsed) {
1163
+ const args = (parsed ?? {});
1164
+ const one = (value) => (typeof value === 'string' && value ? [value] : []);
1165
+ switch (tool) {
1166
+ case 'write_file':
1167
+ case 'apply_diff':
1168
+ case 'search_replace':
1169
+ case 'delete_file':
1170
+ return one(args['path']);
1171
+ case 'move_file':
1172
+ return [...one(args['source']), ...one(args['destination'])];
1173
+ default:
1174
+ // execute_command is not listed: a command declares no paths, and pretending to know what
1175
+ // it will touch by reading the string is exactly the false comfort this module avoids.
1176
+ return [];
1177
+ }
1178
+ }
1179
+ /**
1180
+ * Whether a tool result reports a failure.
1181
+ *
1182
+ * One definition, used by the engine and by everything that draws a result, because they had
1183
+ * drifted: a sandbox denial was recorded as a failure by the engine and drawn with a green tick
1184
+ * by the CI writer, which printed one unconditionally. The outcome a user most needs to see —
1185
+ * "that write did not happen" — looked exactly like success.
1186
+ */
1187
+ export function isToolFailure(result) {
1188
+ return result.startsWith('ERROR:')
1189
+ || result.startsWith('POLICY BLOCKED:')
1190
+ || result.startsWith('DENIED:');
1191
+ }
1192
+ export async function dispatchTool(name, argsJson, cwd, requireApproval, onOutput, sandbox = { mode: 'off', writableRoots: [] }) {
1103
1193
  let parsed;
1104
1194
  try {
1105
1195
  parsed = JSON.parse(normalizeToolArgs(name, argsJson));
@@ -1107,6 +1197,15 @@ export async function dispatchTool(name, argsJson, cwd, requireApproval, onOutpu
1107
1197
  catch {
1108
1198
  return `ERROR: Malformed JSON arguments for tool "${name}": ${argsJson.slice(0, 200)}`;
1109
1199
  }
1200
+ const missing = missingRequiredArgs(name, parsed);
1201
+ if (missing)
1202
+ return missing;
1203
+ // Checked here so no writing tool can be added later and quietly escape it.
1204
+ for (const target of writeTargets(name, parsed)) {
1205
+ const verdict = checkWrite(sandbox, path.resolve(cwd, target));
1206
+ if (!verdict.allowed)
1207
+ return `DENIED: ${verdict.reason}`;
1208
+ }
1110
1209
  switch (name) {
1111
1210
  case 'read_files':
1112
1211
  return readFiles(parsed, cwd);
@@ -1115,7 +1214,7 @@ export async function dispatchTool(name, argsJson, cwd, requireApproval, onOutpu
1115
1214
  case 'apply_diff':
1116
1215
  return applyDiff(parsed, cwd, requireApproval);
1117
1216
  case 'execute_command':
1118
- return executeCommand(parsed, cwd, requireApproval, onOutput);
1217
+ return executeCommand(parsed, cwd, requireApproval, onOutput, sandbox);
1119
1218
  case 'list_dir':
1120
1219
  return listDir(parsed, cwd);
1121
1220
  case 'glob_search':