fixo-cli 1.0.4 → 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.map +1 -1
- package/dist/agent/command-parser.js +176 -0
- 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 +14 -1
- package/dist/agent/conversation.d.ts.map +1 -1
- package/dist/agent/conversation.js +53 -7
- package/dist/agent/conversation.js.map +1 -1
- 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 +254 -2
- 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/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.map +1 -1
- package/dist/agent/single-agent.js +129 -22
- 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 +25 -10
- 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 +51 -14
- package/dist/agent/worker-agent.js.map +1 -1
- package/dist/config.d.ts +242 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +79 -0
- 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 +85 -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 +78 -7
- package/dist/runtime/loop-mitigation.d.ts.map +1 -1
- package/dist/runtime/loop-mitigation.js +122 -9
- package/dist/runtime/loop-mitigation.js.map +1 -1
- 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/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 +435 -1214
- 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/package.json +17 -3
- package/scripts/check-vendor-wasm.js +11 -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
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { spawnSync } from 'child_process';
|
|
4
|
+
import { colors } from '../../ui/colors.js';
|
|
5
|
+
import { WorkspaceGuard } from '../../workspace-guard.js';
|
|
6
|
+
import { AtomicStagingManager } from '../../runtime/staging.js';
|
|
7
|
+
import { PlatformPathLockedError } from '../../workspace-guard.js';
|
|
8
|
+
import { ParserFactory, } from '../parser-adapter.js';
|
|
9
|
+
export function executeReadFile(filePath, cwd, session, largeFileGateBytes = 15 * 1024, largeFileGateLines = 350) {
|
|
10
|
+
const guard = new WorkspaceGuard(cwd);
|
|
11
|
+
const resolved = guard.resolve(filePath, 'file');
|
|
12
|
+
if (!fs.existsSync(resolved)) {
|
|
13
|
+
return `Error: File not found: ${filePath}`;
|
|
14
|
+
}
|
|
15
|
+
const stat = fs.statSync(resolved);
|
|
16
|
+
if (stat.isDirectory()) {
|
|
17
|
+
return `Error: "${filePath}" is a directory, not a file. Use list_dir instead.`;
|
|
18
|
+
}
|
|
19
|
+
// Skip binary files
|
|
20
|
+
if (stat.size > 500_000) {
|
|
21
|
+
return `Error: File is too large (${(stat.size / 1024).toFixed(0)} KB). Read a smaller file or search for specific content.`;
|
|
22
|
+
}
|
|
23
|
+
if (guard.isBinaryFile(resolved)) {
|
|
24
|
+
return `Error: File appears to be binary: ${filePath}`;
|
|
25
|
+
}
|
|
26
|
+
// Pillar 3 — Context-Budget Guard. When a file exceeds either
|
|
27
|
+
// the byte or line gate we refuse to return the full body and
|
|
28
|
+
// instead hand the LLM a synthetic directive telling it to use
|
|
29
|
+
// the structural pre-scan tools (`extract_symbols` /
|
|
30
|
+
// `extract_imports`) instead. This prevents an LLM from
|
|
31
|
+
// dumping half the workspace into the context window.
|
|
32
|
+
if (stat.size > largeFileGateBytes ||
|
|
33
|
+
// Read just enough to count lines without holding the file in
|
|
34
|
+
// memory twice. `readFileSync` is unavoidable for the content
|
|
35
|
+
// path below, so accept the cost here.
|
|
36
|
+
countLines(resolved) > largeFileGateLines) {
|
|
37
|
+
return buildContextBudgetGuardDirective(resolved, stat.size, largeFileGateBytes, largeFileGateLines);
|
|
38
|
+
}
|
|
39
|
+
const content = fs.readFileSync(resolved, 'utf-8');
|
|
40
|
+
session?.noteRead(resolved);
|
|
41
|
+
return content;
|
|
42
|
+
}
|
|
43
|
+
export async function executeExtractSymbols(filePath, cwd, session) {
|
|
44
|
+
const guard = new WorkspaceGuard(cwd);
|
|
45
|
+
const resolved = guard.resolve(filePath, 'file');
|
|
46
|
+
if (!fs.existsSync(resolved)) {
|
|
47
|
+
return `Error: File not found: ${filePath}`;
|
|
48
|
+
}
|
|
49
|
+
if (guard.isBinaryFile(resolved)) {
|
|
50
|
+
return `Error: File appears to be binary: ${filePath}`;
|
|
51
|
+
}
|
|
52
|
+
const content = fs.readFileSync(resolved, 'utf-8');
|
|
53
|
+
const language = resolveLanguageId(resolved);
|
|
54
|
+
const parser = await ParserFactory.getParser();
|
|
55
|
+
const symbols = parser.extractSymbols(content, language);
|
|
56
|
+
session?.noteStructuralMap?.(resolved, { symbols: true, imports: false });
|
|
57
|
+
if (symbols.length === 0) {
|
|
58
|
+
return `No symbols detected in '${filePath}' (language=${language}).`;
|
|
59
|
+
}
|
|
60
|
+
const lines = symbols.map((s) => `- [${s.kind}${s.exported ? ', exported' : ''}] ${s.name} (line ${s.line})`);
|
|
61
|
+
return `Symbols in '${filePath}' (${symbols.length}):\n${lines.join('\n')}`;
|
|
62
|
+
}
|
|
63
|
+
export async function executeExtractImports(filePath, cwd, session) {
|
|
64
|
+
const guard = new WorkspaceGuard(cwd);
|
|
65
|
+
const resolved = guard.resolve(filePath, 'file');
|
|
66
|
+
if (!fs.existsSync(resolved)) {
|
|
67
|
+
return `Error: File not found: ${filePath}`;
|
|
68
|
+
}
|
|
69
|
+
if (guard.isBinaryFile(resolved)) {
|
|
70
|
+
return `Error: File appears to be binary: ${filePath}`;
|
|
71
|
+
}
|
|
72
|
+
const content = fs.readFileSync(resolved, 'utf-8');
|
|
73
|
+
const language = resolveLanguageId(resolved);
|
|
74
|
+
const parser = await ParserFactory.getParser();
|
|
75
|
+
const imports = parser.extractImports(content, language);
|
|
76
|
+
session?.noteStructuralMap?.(resolved, { symbols: false, imports: true });
|
|
77
|
+
if (imports.length === 0) {
|
|
78
|
+
return `No imports detected in '${filePath}' (language=${language}).`;
|
|
79
|
+
}
|
|
80
|
+
const lines = imports.map((i) => {
|
|
81
|
+
const tag = i.isTypeOnly ? ' [type-only]' : '';
|
|
82
|
+
const syms = i.symbols.length > 0 ? ` {${i.symbols.join(', ')}}` : '';
|
|
83
|
+
return `- '${i.source}'${tag}${syms} (line ${i.line})`;
|
|
84
|
+
});
|
|
85
|
+
return `Imports in '${filePath}' (${imports.length}):\n${lines.join('\n')}`;
|
|
86
|
+
}
|
|
87
|
+
export function executeWriteFile(filePath, content, cwd, options = {}) {
|
|
88
|
+
const guard = new WorkspaceGuard(cwd);
|
|
89
|
+
const resolved = guard.resolve(filePath, 'file');
|
|
90
|
+
// Pillar 5 / Protection 1 — refuse to mutate the platform's
|
|
91
|
+
// own runtime. This is the guard that prevents an autonomous
|
|
92
|
+
// agent from corrupting `src/agent/tool-executor.ts` and
|
|
93
|
+
// breaking its own host.
|
|
94
|
+
try {
|
|
95
|
+
guard.assertNotPlatformPath(resolved);
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
if (err instanceof PlatformPathLockedError) {
|
|
99
|
+
return Promise.resolve(err.message);
|
|
100
|
+
}
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
const mutation = options.session?.canMutate(resolved);
|
|
104
|
+
if (mutation && !mutation.ok)
|
|
105
|
+
return Promise.resolve(`Error: ${mutation.reason}`);
|
|
106
|
+
options.session?.captureBefore(resolved);
|
|
107
|
+
const existed = fs.existsSync(resolved);
|
|
108
|
+
return applyAtomicWrite(cwd, filePath, content, options.safety, options.session)
|
|
109
|
+
.then(() => {
|
|
110
|
+
if (!existed)
|
|
111
|
+
return `File created: ${filePath}`;
|
|
112
|
+
// Existing file — print the diff for the user.
|
|
113
|
+
try {
|
|
114
|
+
const relativePath = guard.relative(resolved);
|
|
115
|
+
const result = spawnSync('git', ['diff', '--color=always', '--', relativePath], { cwd, encoding: 'utf-8' });
|
|
116
|
+
if (result.status === 0 && result.stdout) {
|
|
117
|
+
const diffOutput = result.stdout.trim();
|
|
118
|
+
if (diffOutput) {
|
|
119
|
+
console.log(`\n${colors.cyan}--- File Changes Diff ---${colors.reset}`);
|
|
120
|
+
const lines = diffOutput.split('\n');
|
|
121
|
+
if (lines.length > 50) {
|
|
122
|
+
console.log(lines.slice(0, 48).join('\n') + `\n${colors.yellow}... (diff truncated)${colors.reset}`);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
console.log(diffOutput);
|
|
126
|
+
}
|
|
127
|
+
console.log(`${colors.cyan}-------------------------${colors.reset}\n`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Fail-safe diff printing
|
|
133
|
+
}
|
|
134
|
+
return `File updated: ${filePath}`;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
export function executeSearchCode(query, searchPath, filePattern, cwd) {
|
|
138
|
+
const guard = new WorkspaceGuard(cwd);
|
|
139
|
+
const targetDir = searchPath ? guard.resolve(searchPath, 'search path') : cwd;
|
|
140
|
+
// Try ripgrep first
|
|
141
|
+
let hasRg = false;
|
|
142
|
+
try {
|
|
143
|
+
const which = spawnSync('which', ['rg'], { encoding: 'utf-8' });
|
|
144
|
+
if (which.status === 0 && which.stdout.trim()) {
|
|
145
|
+
hasRg = true;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
if (process.env.DEBUG || process.env.VERBOSE || process.argv.includes('--verbose')) {
|
|
150
|
+
console.warn(`[Debug Warning] Failed to determine if ripgrep (rg) is installed: ${error.message || error}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
let output = '';
|
|
154
|
+
if (hasRg) {
|
|
155
|
+
const args = ['-n', '--no-heading', '--color', 'never', query];
|
|
156
|
+
if (filePattern) {
|
|
157
|
+
args.push('-g', filePattern);
|
|
158
|
+
}
|
|
159
|
+
args.push(targetDir);
|
|
160
|
+
const result = spawnSync('rg', args, {
|
|
161
|
+
encoding: 'utf-8',
|
|
162
|
+
cwd,
|
|
163
|
+
maxBuffer: 512 * 1024,
|
|
164
|
+
timeout: 15000,
|
|
165
|
+
});
|
|
166
|
+
output = result.stdout ?? '';
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
// Fallback to grep
|
|
170
|
+
const args = ['-rn', query];
|
|
171
|
+
if (filePattern) {
|
|
172
|
+
args.push(`--include=${filePattern}`);
|
|
173
|
+
}
|
|
174
|
+
args.push(targetDir);
|
|
175
|
+
const result = spawnSync('grep', args, {
|
|
176
|
+
encoding: 'utf-8',
|
|
177
|
+
cwd,
|
|
178
|
+
maxBuffer: 512 * 1024,
|
|
179
|
+
timeout: 15000,
|
|
180
|
+
});
|
|
181
|
+
output = result.stdout ?? '';
|
|
182
|
+
}
|
|
183
|
+
if (!output.trim()) {
|
|
184
|
+
return `No matches found for "${query}"`;
|
|
185
|
+
}
|
|
186
|
+
// Make paths relative to workspace and limit to 50 results
|
|
187
|
+
const lines = output.trim().split('\n').slice(0, 50).map((line) => {
|
|
188
|
+
if (line.startsWith(cwd)) {
|
|
189
|
+
return line.slice(cwd.length + 1);
|
|
190
|
+
}
|
|
191
|
+
return line;
|
|
192
|
+
});
|
|
193
|
+
return lines.join('\n');
|
|
194
|
+
}
|
|
195
|
+
export function executeListDir(dirPath, cwd) {
|
|
196
|
+
const guard = new WorkspaceGuard(cwd);
|
|
197
|
+
const resolved = dirPath ? guard.resolve(dirPath, 'directory') : cwd;
|
|
198
|
+
if (!fs.existsSync(resolved)) {
|
|
199
|
+
return `Error: Directory not found: ${dirPath ?? '.'}`;
|
|
200
|
+
}
|
|
201
|
+
const stat = fs.statSync(resolved);
|
|
202
|
+
if (!stat.isDirectory()) {
|
|
203
|
+
return `Error: "${dirPath}" is a file, not a directory. Use read_file instead.`;
|
|
204
|
+
}
|
|
205
|
+
let entries;
|
|
206
|
+
try {
|
|
207
|
+
entries = fs.readdirSync(resolved, { withFileTypes: true });
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
return `Error: Cannot read directory: ${error instanceof Error ? error.message : String(error)}`;
|
|
211
|
+
}
|
|
212
|
+
// Filter and sort
|
|
213
|
+
const filtered = entries
|
|
214
|
+
.filter((e) => !e.name.startsWith('.') || e.name === '.env.example')
|
|
215
|
+
.filter((e) => e.name !== 'node_modules')
|
|
216
|
+
.sort((a, b) => {
|
|
217
|
+
if (a.isDirectory() !== b.isDirectory())
|
|
218
|
+
return a.isDirectory() ? -1 : 1;
|
|
219
|
+
return a.name.localeCompare(b.name);
|
|
220
|
+
});
|
|
221
|
+
const lines = [];
|
|
222
|
+
for (const entry of filtered) {
|
|
223
|
+
if (entry.isDirectory()) {
|
|
224
|
+
lines.push(`📁 ${entry.name}/`);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
let size = '';
|
|
228
|
+
try {
|
|
229
|
+
const s = fs.statSync(path.join(resolved, entry.name));
|
|
230
|
+
size = formatSize(s.size);
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
// Ignore
|
|
234
|
+
}
|
|
235
|
+
lines.push(` ${entry.name}${size ? ` (${size})` : ''}`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return lines.join('\n') || '(empty directory)';
|
|
239
|
+
}
|
|
240
|
+
export function executeDeleteFile(filePath, cwd, session) {
|
|
241
|
+
const guard = new WorkspaceGuard(cwd);
|
|
242
|
+
const resolved = guard.resolve(filePath, 'file');
|
|
243
|
+
const mutation = session?.canMutate(resolved);
|
|
244
|
+
if (mutation && !mutation.ok)
|
|
245
|
+
return `Error: ${mutation.reason}`;
|
|
246
|
+
session?.captureBefore(resolved);
|
|
247
|
+
if (!fs.existsSync(resolved)) {
|
|
248
|
+
return `Error: File not found: ${filePath}`;
|
|
249
|
+
}
|
|
250
|
+
const stat = fs.statSync(resolved);
|
|
251
|
+
if (stat.isDirectory()) {
|
|
252
|
+
return `Error: "${filePath}" is a directory. delete_file can only delete files.`;
|
|
253
|
+
}
|
|
254
|
+
fs.unlinkSync(resolved);
|
|
255
|
+
session?.noteChange(resolved);
|
|
256
|
+
return `File deleted: ${filePath}`;
|
|
257
|
+
}
|
|
258
|
+
export function executeApplyPatch(patch, cwd, options = {}) {
|
|
259
|
+
if (!patch?.trim())
|
|
260
|
+
return Promise.resolve('Error: patch is required.');
|
|
261
|
+
const guard = new WorkspaceGuard(cwd);
|
|
262
|
+
// Pillar 5 — refuse to apply patches that target platform
|
|
263
|
+
// runtime files. The `git apply` invocation would otherwise
|
|
264
|
+
// succeed in corrupting our own source.
|
|
265
|
+
for (const file of filesFromPatch(patch)) {
|
|
266
|
+
try {
|
|
267
|
+
const resolved = guard.resolve(file, 'patch target');
|
|
268
|
+
guard.assertNotPlatformPath(resolved);
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
if (err instanceof PlatformPathLockedError) {
|
|
272
|
+
return Promise.resolve(err.message);
|
|
273
|
+
}
|
|
274
|
+
if (err instanceof Error) {
|
|
275
|
+
return Promise.resolve(`Error: ${err.message}`);
|
|
276
|
+
}
|
|
277
|
+
throw err;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
for (const file of filesFromPatch(patch)) {
|
|
281
|
+
try {
|
|
282
|
+
options.session?.captureBefore(file);
|
|
283
|
+
}
|
|
284
|
+
catch { /* best effort */ }
|
|
285
|
+
}
|
|
286
|
+
const result = spawnSync('git', ['apply', '--whitespace=nowarn', '-'], {
|
|
287
|
+
cwd,
|
|
288
|
+
input: patch,
|
|
289
|
+
encoding: 'utf-8',
|
|
290
|
+
timeout: 30_000,
|
|
291
|
+
maxBuffer: 1024 * 1024,
|
|
292
|
+
});
|
|
293
|
+
if (result.status !== 0)
|
|
294
|
+
return Promise.resolve(`Patch failed:\n${result.stderr || result.stdout}`);
|
|
295
|
+
for (const file of filesFromPatch(patch)) {
|
|
296
|
+
try {
|
|
297
|
+
options.session?.noteChange(file);
|
|
298
|
+
}
|
|
299
|
+
catch { /* best effort */ }
|
|
300
|
+
}
|
|
301
|
+
return Promise.resolve('Patch applied.');
|
|
302
|
+
}
|
|
303
|
+
export function executeReplaceRange(filePath, startLine, endLine, content, cwd, options = {}) {
|
|
304
|
+
const guard = new WorkspaceGuard(cwd);
|
|
305
|
+
const resolved = guard.resolve(filePath, 'file');
|
|
306
|
+
try {
|
|
307
|
+
guard.assertNotPlatformPath(resolved);
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
if (err instanceof PlatformPathLockedError)
|
|
311
|
+
return Promise.resolve(err.message);
|
|
312
|
+
throw err;
|
|
313
|
+
}
|
|
314
|
+
const mutation = options.session?.canMutate(resolved);
|
|
315
|
+
if (mutation && !mutation.ok)
|
|
316
|
+
return Promise.resolve(`Error: ${mutation.reason}`);
|
|
317
|
+
options.session?.captureBefore(resolved);
|
|
318
|
+
const original = fs.readFileSync(resolved, 'utf-8');
|
|
319
|
+
const lines = original.split('\n');
|
|
320
|
+
if (!Number.isInteger(startLine) || !Number.isInteger(endLine) || startLine < 1 || endLine < startLine || endLine > lines.length) {
|
|
321
|
+
return Promise.resolve(`Error: invalid line range ${startLine}-${endLine}.`);
|
|
322
|
+
}
|
|
323
|
+
lines.splice(startLine - 1, endLine - startLine + 1, ...content.split('\n'));
|
|
324
|
+
return applyAtomicWrite(cwd, filePath, lines.join('\n'), options.safety, options.session)
|
|
325
|
+
.then(() => `Replaced ${filePath}:${startLine}-${endLine}.`);
|
|
326
|
+
}
|
|
327
|
+
export function executeInsertAfter(filePath, anchor, content, cwd, options = {}) {
|
|
328
|
+
const guard = new WorkspaceGuard(cwd);
|
|
329
|
+
const resolved = guard.resolve(filePath, 'file');
|
|
330
|
+
try {
|
|
331
|
+
guard.assertNotPlatformPath(resolved);
|
|
332
|
+
}
|
|
333
|
+
catch (err) {
|
|
334
|
+
if (err instanceof PlatformPathLockedError)
|
|
335
|
+
return Promise.resolve(err.message);
|
|
336
|
+
throw err;
|
|
337
|
+
}
|
|
338
|
+
const mutation = options.session?.canMutate(resolved);
|
|
339
|
+
if (mutation && !mutation.ok)
|
|
340
|
+
return Promise.resolve(`Error: ${mutation.reason}`);
|
|
341
|
+
options.session?.captureBefore(resolved);
|
|
342
|
+
const original = fs.readFileSync(resolved, 'utf-8');
|
|
343
|
+
const idx = original.indexOf(anchor);
|
|
344
|
+
if (idx === -1)
|
|
345
|
+
return Promise.resolve(`Error: anchor not found in ${filePath}.`);
|
|
346
|
+
const insertAt = idx + anchor.length;
|
|
347
|
+
const next = original.slice(0, insertAt) + content + original.slice(insertAt);
|
|
348
|
+
return applyAtomicWrite(cwd, filePath, next, options.safety, options.session)
|
|
349
|
+
.then(() => `Inserted content in ${filePath}.`);
|
|
350
|
+
}
|
|
351
|
+
export function executeRenameFile(from, to, cwd, options = {}) {
|
|
352
|
+
const guard = new WorkspaceGuard(cwd);
|
|
353
|
+
const source = guard.resolve(from, 'source file');
|
|
354
|
+
const target = guard.resolve(to, 'target file');
|
|
355
|
+
try {
|
|
356
|
+
guard.assertNotPlatformPath(source);
|
|
357
|
+
guard.assertNotPlatformPath(target);
|
|
358
|
+
}
|
|
359
|
+
catch (err) {
|
|
360
|
+
if (err instanceof PlatformPathLockedError)
|
|
361
|
+
return Promise.resolve(err.message);
|
|
362
|
+
throw err;
|
|
363
|
+
}
|
|
364
|
+
const mutation = options.session?.canMutate(source);
|
|
365
|
+
if (mutation && !mutation.ok)
|
|
366
|
+
return Promise.resolve(`Error: ${mutation.reason}`);
|
|
367
|
+
options.session?.captureBefore(source);
|
|
368
|
+
options.session?.captureBefore(target);
|
|
369
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
370
|
+
fs.renameSync(source, target);
|
|
371
|
+
options.session?.noteChange(source);
|
|
372
|
+
options.session?.noteChange(target);
|
|
373
|
+
return Promise.resolve(`Renamed ${from} -> ${to}.`);
|
|
374
|
+
}
|
|
375
|
+
export async function executeStrReplace(args, cwd, options = {}) {
|
|
376
|
+
const guard = new WorkspaceGuard(cwd);
|
|
377
|
+
// Validate the input.
|
|
378
|
+
if (typeof args.path !== 'string' || args.path.length === 0) {
|
|
379
|
+
return `Error: str_replace: "path" is required.`;
|
|
380
|
+
}
|
|
381
|
+
if (typeof args.oldString !== 'string') {
|
|
382
|
+
return `Error: str_replace: "oldString" is required.`;
|
|
383
|
+
}
|
|
384
|
+
if (typeof args.newString !== 'string') {
|
|
385
|
+
return `Error: str_replace: "newString" is required.`;
|
|
386
|
+
}
|
|
387
|
+
// Pillar 1 — refuse in PLAN mode.
|
|
388
|
+
if (options.mode === 'PLAN') {
|
|
389
|
+
const err = new SurgicalReplaceError(`str_replace is not allowed in PLAN mode (read-only). Switch to BUILD mode and retry.`, 'plan_mode_rejected', { mode: options.mode });
|
|
390
|
+
return `Error: ${err.message}`;
|
|
391
|
+
}
|
|
392
|
+
// Workspace boundary check.
|
|
393
|
+
let resolved;
|
|
394
|
+
try {
|
|
395
|
+
resolved = guard.resolve(args.path, 'str_replace target');
|
|
396
|
+
}
|
|
397
|
+
catch (err) {
|
|
398
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
399
|
+
return `Error: str_replace: ${msg}`;
|
|
400
|
+
}
|
|
401
|
+
// Pillar 5 — refuse platform-locked paths.
|
|
402
|
+
try {
|
|
403
|
+
guard.assertNotPlatformPath(resolved);
|
|
404
|
+
}
|
|
405
|
+
catch (err) {
|
|
406
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
407
|
+
return `Error: ${msg}`;
|
|
408
|
+
}
|
|
409
|
+
if (!fs.existsSync(resolved)) {
|
|
410
|
+
return `Error: str_replace: file not found: ${args.path}`;
|
|
411
|
+
}
|
|
412
|
+
if (guard.isBinaryFile(resolved)) {
|
|
413
|
+
return `Error: str_replace: file appears to be binary: ${args.path}`;
|
|
414
|
+
}
|
|
415
|
+
// Load the current content.
|
|
416
|
+
const content = fs.readFileSync(resolved, 'utf-8');
|
|
417
|
+
const occurrences = countOccurrences(content, args.oldString);
|
|
418
|
+
const replaceAll = args.replaceAll === true;
|
|
419
|
+
// The uniqueness gate only fires when the caller has not already
|
|
420
|
+
// opted in to non-unique semantics via `replaceAll` or by
|
|
421
|
+
// explicitly setting `expectUnique: false`.
|
|
422
|
+
const expectUnique = !replaceAll && args.expectUnique !== false;
|
|
423
|
+
if (occurrences === 0) {
|
|
424
|
+
return `Error: str_replace: oldString not found in ${args.path}.`;
|
|
425
|
+
}
|
|
426
|
+
if (occurrences > 1 && expectUnique) {
|
|
427
|
+
return `Error: str_replace: oldString appears ${occurrences} times in ${args.path}. ` +
|
|
428
|
+
`Pass replaceAll=true or expectUnique=false to proceed.`;
|
|
429
|
+
}
|
|
430
|
+
const newContent = applyReplacement(content, args.oldString, args.newString, replaceAll);
|
|
431
|
+
const bytes = Buffer.byteLength(newContent, 'utf-8');
|
|
432
|
+
// Pillar 3 — LSP pre-save compilation gate. The gate's
|
|
433
|
+
// `enforce` throws on `block`-mode failures; we surface the
|
|
434
|
+
// diagnostics to the LLM as a structured error.
|
|
435
|
+
if (options.safety?.lspPreSave && options.safety.lspPreSave !== 'off') {
|
|
436
|
+
try {
|
|
437
|
+
const gate = getOrCreateLspGate(cwd, options.safety);
|
|
438
|
+
const synthetic = {
|
|
439
|
+
id: 'surgical-' + Date.now().toString(36),
|
|
440
|
+
targetPath: resolved,
|
|
441
|
+
pendingPath: '<surgical>',
|
|
442
|
+
metaPath: '<surgical>',
|
|
443
|
+
createdAt: Date.now(),
|
|
444
|
+
mode: 0o644,
|
|
445
|
+
};
|
|
446
|
+
const result = await gate.check(synthetic);
|
|
447
|
+
gate.enforce(result, synthetic);
|
|
448
|
+
}
|
|
449
|
+
catch (err) {
|
|
450
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
451
|
+
return `Error: str_replace: ${msg}`;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
// Pillar 2 — atomic staging. Route the new content through the
|
|
455
|
+
// staging manager's new surgical-replace method.
|
|
456
|
+
try {
|
|
457
|
+
const mgr = new AtomicStagingManager(cwd, getOrCreateRunId());
|
|
458
|
+
const result = await mgr.applySurgicalReplace(resolved, newContent, {
|
|
459
|
+
runId: mgr.runId,
|
|
460
|
+
reason: 'str_replace',
|
|
461
|
+
actorId: options.session?.id ?? 'tool-executor',
|
|
462
|
+
});
|
|
463
|
+
// Telemetry.
|
|
464
|
+
try {
|
|
465
|
+
const { recordTelemetry, telemetry } = await import('./telemetry.js');
|
|
466
|
+
recordTelemetry(telemetry.surgicalEdit({
|
|
467
|
+
path: args.path,
|
|
468
|
+
occurrences: replaceAll ? occurrences : 1,
|
|
469
|
+
mode: options.safety?.lspPreSave ?? 'off',
|
|
470
|
+
bytes: result.bytes,
|
|
471
|
+
}));
|
|
472
|
+
}
|
|
473
|
+
catch {
|
|
474
|
+
// Telemetry must never break a tool call.
|
|
475
|
+
}
|
|
476
|
+
options.session?.noteChange(resolved);
|
|
477
|
+
return JSON.stringify({
|
|
478
|
+
ok: true,
|
|
479
|
+
path: args.path,
|
|
480
|
+
occurrences: replaceAll ? occurrences : 1,
|
|
481
|
+
mode: options.safety?.lspPreSave ?? 'off',
|
|
482
|
+
bytes: result.bytes,
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
catch (err) {
|
|
486
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
487
|
+
return `Error: str_replace: ${msg}`;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
export async function executeGlobFiles(args, cwd, _options = {}) {
|
|
491
|
+
if (typeof args.pattern !== 'string' || args.pattern.length === 0) {
|
|
492
|
+
return `Error: glob_files: "pattern" is required.`;
|
|
493
|
+
}
|
|
494
|
+
const guard = new WorkspaceGuard(cwd);
|
|
495
|
+
let scope;
|
|
496
|
+
try {
|
|
497
|
+
scope = args.cwd ? guard.resolve(args.cwd, 'glob scope') : cwd;
|
|
498
|
+
}
|
|
499
|
+
catch (err) {
|
|
500
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
501
|
+
return `Error: glob_files: ${msg}`;
|
|
502
|
+
}
|
|
503
|
+
const maxResults = Math.min(Math.max(args.maxResults ?? GLOB_DEFAULT_MAX_RESULTS, 1), GLOB_HARD_MAX_RESULTS);
|
|
504
|
+
const skipDirs = new Set(GLOB_DEFAULT_SKIP_DIRS);
|
|
505
|
+
for (const extra of splitIgnoreSpec(args.ignore)) {
|
|
506
|
+
skipDirs.add(extra);
|
|
507
|
+
}
|
|
508
|
+
const includeHidden = args.includeHidden === true;
|
|
509
|
+
const followSymlinks = args.followSymlinks === true;
|
|
510
|
+
// Collect matching paths.
|
|
511
|
+
let matches;
|
|
512
|
+
try {
|
|
513
|
+
matches = await collectGlobMatches({
|
|
514
|
+
pattern: args.pattern,
|
|
515
|
+
scope,
|
|
516
|
+
skipDirs,
|
|
517
|
+
includeHidden,
|
|
518
|
+
followSymlinks,
|
|
519
|
+
maxResults: maxResults + 1,
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
catch (err) {
|
|
523
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
524
|
+
return `Error: glob_files: ${msg}`;
|
|
525
|
+
}
|
|
526
|
+
const truncated = matches.length > maxResults;
|
|
527
|
+
const returned = truncated ? matches.slice(0, maxResults) : matches;
|
|
528
|
+
const total = matches.length;
|
|
529
|
+
// Telemetry.
|
|
530
|
+
try {
|
|
531
|
+
const { recordTelemetry, telemetry } = await import('./telemetry.js');
|
|
532
|
+
recordTelemetry(telemetry.glob({
|
|
533
|
+
pattern: args.pattern,
|
|
534
|
+
returned: returned.length,
|
|
535
|
+
truncated,
|
|
536
|
+
}));
|
|
537
|
+
}
|
|
538
|
+
catch {
|
|
539
|
+
// Telemetry must never break a tool call.
|
|
540
|
+
}
|
|
541
|
+
if (returned.length === 0) {
|
|
542
|
+
return JSON.stringify({ pattern: args.pattern, matches: [], total: 0, truncated: false });
|
|
543
|
+
}
|
|
544
|
+
return JSON.stringify({
|
|
545
|
+
pattern: args.pattern,
|
|
546
|
+
matches: returned.map((p) => path.relative(cwd, p) || p),
|
|
547
|
+
total,
|
|
548
|
+
truncated,
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
//# sourceMappingURL=file-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-tools.js","sourceRoot":"","sources":["../../../src/agent/tools/file-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todo-tools.d.ts","sourceRoot":"","sources":["../../../src/agent/tools/todo-tools.ts"],"names":[],"mappings":"AAqDA,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CAuEjB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { loadTodoList, saveTodoList, addItem, setItemStatus, removeItem, clearDoneItems, renderTodoList, summariseTodoList, } from '../../context/todo.js';
|
|
2
|
+
import { recordTelemetry, telemetry } from '../telemetry.js';
|
|
3
|
+
export function executeTodoRead(cwd) {
|
|
4
|
+
const list = loadTodoList(cwd);
|
|
5
|
+
return renderTodoList(list);
|
|
6
|
+
}
|
|
7
|
+
export async function executeTodoWrite(args, cwd, options = {}) {
|
|
8
|
+
if (options.mode === 'PLAN') {
|
|
9
|
+
return `Error: todo_write: rejected in PLAN mode (no on-disk mutations).`;
|
|
10
|
+
}
|
|
11
|
+
const op = args.op;
|
|
12
|
+
if (op !== 'add' && op !== 'set_status' && op !== 'remove' && op !== 'clear_done') {
|
|
13
|
+
throw new TodoWriteError(`todo_write: unknown op "${String(op)}"`, 'invalid_args', { op: String(op) });
|
|
14
|
+
}
|
|
15
|
+
let list = loadTodoList(cwd);
|
|
16
|
+
switch (op) {
|
|
17
|
+
case 'add': {
|
|
18
|
+
if (typeof args.content !== 'string' || args.content.trim().length === 0) {
|
|
19
|
+
throw new TodoWriteError('todo_write: "content" is required for op=add', 'invalid_args');
|
|
20
|
+
}
|
|
21
|
+
list = addItem(list, { content: args.content, blockedBy: args.blockedBy });
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
case 'set_status': {
|
|
25
|
+
if (typeof args.id !== 'string' || args.id.length === 0) {
|
|
26
|
+
throw new TodoWriteError('todo_write: "id" is required for op=set_status', 'invalid_args');
|
|
27
|
+
}
|
|
28
|
+
if (!args.status || !VALID_TODO_STATUSES.has(args.status)) {
|
|
29
|
+
throw new TodoWriteError(`todo_write: "status" must be one of pending|in_progress|done|cancelled (got "${String(args.status)}")`, 'invalid_args');
|
|
30
|
+
}
|
|
31
|
+
const exists = list.items.some((it) => it.id === args.id);
|
|
32
|
+
if (!exists) {
|
|
33
|
+
throw new TodoWriteError(`todo_write: item id "${args.id}" not found`, 'not_found');
|
|
34
|
+
}
|
|
35
|
+
list = setItemStatus(list, { id: args.id, status: args.status });
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
case 'remove': {
|
|
39
|
+
if (typeof args.id !== 'string' || args.id.length === 0) {
|
|
40
|
+
throw new TodoWriteError('todo_write: "id" is required for op=remove', 'invalid_args');
|
|
41
|
+
}
|
|
42
|
+
const exists = list.items.some((it) => it.id === args.id);
|
|
43
|
+
if (!exists) {
|
|
44
|
+
throw new TodoWriteError(`todo_write: item id "${args.id}" not found`, 'not_found');
|
|
45
|
+
}
|
|
46
|
+
list = removeItem(list, { id: args.id });
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case 'clear_done': {
|
|
50
|
+
list = clearDoneItems(list);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const save = saveTodoList(cwd, list);
|
|
55
|
+
if (!save.ok) {
|
|
56
|
+
throw new TodoWriteError(`todo_write: failed to persist: ${save.error ?? 'unknown'}`, 'io_failure', {
|
|
57
|
+
path: save.path,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const summary = summariseTodoList(list);
|
|
61
|
+
recordTelemetry(telemetry.todoMutation({
|
|
62
|
+
op,
|
|
63
|
+
items: list.items.length,
|
|
64
|
+
id: typeof args.id === 'string' ? args.id : undefined,
|
|
65
|
+
}));
|
|
66
|
+
// Echo the rendered list back so the LLM can confirm
|
|
67
|
+
// its mutation took effect in the same turn.
|
|
68
|
+
return `${renderTodoList(list)}\n\n(summary: ${summary})`;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=todo-tools.js.map
|