@visorcraft/idlehands 1.4.6 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/constants.js +12 -0
- package/dist/agent/constants.js.map +1 -0
- package/dist/agent/context-budget.js +103 -0
- package/dist/agent/context-budget.js.map +1 -0
- package/dist/agent/errors.js +8 -0
- package/dist/agent/errors.js.map +1 -0
- package/dist/agent/exec-helpers.js +105 -0
- package/dist/agent/exec-helpers.js.map +1 -0
- package/dist/agent/model-pick.js +21 -0
- package/dist/agent/model-pick.js.map +1 -0
- package/dist/agent/session-utils.js +63 -0
- package/dist/agent/session-utils.js.map +1 -0
- package/dist/agent/subagent-context.js +78 -0
- package/dist/agent/subagent-context.js.map +1 -0
- package/dist/agent/tool-loop-detection.js +91 -20
- package/dist/agent/tool-loop-detection.js.map +1 -1
- package/dist/agent/tool-loop-guard.js.map +1 -1
- package/dist/agent/tool-policy.js +54 -0
- package/dist/agent/tool-policy.js.map +1 -0
- package/dist/agent/tools-schema.js +281 -0
- package/dist/agent/tools-schema.js.map +1 -0
- package/dist/agent.js +191 -641
- package/dist/agent.js.map +1 -1
- package/dist/anton/controller.js +235 -163
- package/dist/anton/controller.js.map +1 -1
- package/dist/anton/lint-baseline.js +64 -0
- package/dist/anton/lint-baseline.js.map +1 -0
- package/dist/anton/preflight.js +7 -0
- package/dist/anton/preflight.js.map +1 -1
- package/dist/anton/prompt.js +71 -71
- package/dist/anton/reporter.js.map +1 -1
- package/dist/anton/runtime-ready.js +120 -0
- package/dist/anton/runtime-ready.js.map +1 -0
- package/dist/anton/session.js +7 -1
- package/dist/anton/session.js.map +1 -1
- package/dist/anton/verifier-utils.js +148 -0
- package/dist/anton/verifier-utils.js.map +1 -0
- package/dist/anton/verifier.js +26 -227
- package/dist/anton/verifier.js.map +1 -1
- package/dist/bot/anton-auto-pin.js +12 -0
- package/dist/bot/anton-auto-pin.js.map +1 -0
- package/dist/bot/anton-commands.js +137 -0
- package/dist/bot/anton-commands.js.map +1 -0
- package/dist/bot/anton-run.js +155 -0
- package/dist/bot/anton-run.js.map +1 -0
- package/dist/bot/anton-status-format.js +18 -0
- package/dist/bot/anton-status-format.js.map +1 -0
- package/dist/bot/basic-commands.js +114 -0
- package/dist/bot/basic-commands.js.map +1 -0
- package/dist/bot/command-format.js.map +1 -1
- package/dist/bot/command-logic.js +8 -728
- package/dist/bot/command-logic.js.map +1 -1
- package/dist/bot/commands.js +18 -1
- package/dist/bot/commands.js.map +1 -1
- package/dist/bot/discord-anton-autopin.js +29 -0
- package/dist/bot/discord-anton-autopin.js.map +1 -0
- package/dist/bot/discord-anton.js +45 -0
- package/dist/bot/discord-anton.js.map +1 -0
- package/dist/bot/discord-commands.js +20 -52
- package/dist/bot/discord-commands.js.map +1 -1
- package/dist/bot/discord-result.js +9 -0
- package/dist/bot/discord-result.js.map +1 -0
- package/dist/bot/discord-routing.js.map +1 -1
- package/dist/bot/discord.js +55 -12
- package/dist/bot/discord.js.map +1 -1
- package/dist/bot/escalation-commands.js +145 -0
- package/dist/bot/escalation-commands.js.map +1 -0
- package/dist/bot/escalation.js.map +1 -1
- package/dist/bot/format.js +0 -5
- package/dist/bot/format.js.map +1 -1
- package/dist/bot/git-status-command.js +28 -0
- package/dist/bot/git-status-command.js.map +1 -0
- package/dist/bot/model-endpoint.js +25 -0
- package/dist/bot/model-endpoint.js.map +1 -0
- package/dist/bot/session-history.js +61 -0
- package/dist/bot/session-history.js.map +1 -0
- package/dist/bot/session-settings.js +89 -0
- package/dist/bot/session-settings.js.map +1 -0
- package/dist/bot/telegram-commands.js +15 -7
- package/dist/bot/telegram-commands.js.map +1 -1
- package/dist/bot/telegram.js +15 -29
- package/dist/bot/telegram.js.map +1 -1
- package/dist/cli/agent-turn.js +8 -2
- package/dist/cli/agent-turn.js.map +1 -1
- package/dist/cli/commands/anton.js +6 -1
- package/dist/cli/commands/anton.js.map +1 -1
- package/dist/cli/commands/model.js +1 -3
- package/dist/cli/commands/model.js.map +1 -1
- package/dist/cli/commands/project.js +1 -1
- package/dist/cli/commands/project.js.map +1 -1
- package/dist/cli/commands/secrets.js +1 -1
- package/dist/cli/commands/secrets.js.map +1 -1
- package/dist/cli/commands/session.js +22 -12
- package/dist/cli/commands/session.js.map +1 -1
- package/dist/cli/guided-onboarding.js +20 -0
- package/dist/cli/guided-onboarding.js.map +1 -0
- package/dist/cli/runtime-cmds.js +8 -133
- package/dist/cli/runtime-cmds.js.map +1 -1
- package/dist/cli/runtime-common.js +35 -0
- package/dist/cli/runtime-common.js.map +1 -0
- package/dist/cli/runtime-detect.js +12 -0
- package/dist/cli/runtime-detect.js.map +1 -0
- package/dist/cli/runtime-host-command.js +7 -0
- package/dist/cli/runtime-host-command.js.map +1 -0
- package/dist/cli/runtime-probe-defaults.js +63 -0
- package/dist/cli/runtime-probe-defaults.js.map +1 -0
- package/dist/cli/runtime-scan-ports.js +30 -0
- package/dist/cli/runtime-scan-ports.js.map +1 -0
- package/dist/cli/setup-bot-step.js +51 -0
- package/dist/cli/setup-bot-step.js.map +1 -0
- package/dist/cli/setup-runtime-forms.js +214 -0
- package/dist/cli/setup-runtime-forms.js.map +1 -0
- package/dist/cli/setup-style.js +8 -0
- package/dist/cli/setup-style.js.map +1 -0
- package/dist/cli/setup-ui.js +146 -0
- package/dist/cli/setup-ui.js.map +1 -0
- package/dist/cli/setup.js +11 -449
- package/dist/cli/setup.js.map +1 -1
- package/dist/client/error-utils.js +37 -0
- package/dist/client/error-utils.js.map +1 -0
- package/dist/client/pressure.js +77 -0
- package/dist/client/pressure.js.map +1 -0
- package/dist/client.js +24 -122
- package/dist/client.js.map +1 -1
- package/dist/config.js +31 -14
- package/dist/config.js.map +1 -1
- package/dist/git.js +8 -2
- package/dist/git.js.map +1 -1
- package/dist/history.js +418 -0
- package/dist/history.js.map +1 -1
- package/dist/hooks/types.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/progress/message-edit-scheduler.js.map +1 -1
- package/dist/progress/turn-progress.js.map +1 -1
- package/dist/runtime/executor.js +4 -1
- package/dist/runtime/executor.js.map +1 -1
- package/dist/runtime/health.js.map +1 -1
- package/dist/runtime/host-runner.js.map +1 -1
- package/dist/safety.js +3 -2
- package/dist/safety.js.map +1 -1
- package/dist/shared/config-utils.js.map +1 -1
- package/dist/tools/exec-core.js +252 -0
- package/dist/tools/exec-core.js.map +1 -0
- package/dist/tools/exec-pty.js +89 -0
- package/dist/tools/exec-pty.js.map +1 -0
- package/dist/tools/exec-utils.js +94 -0
- package/dist/tools/exec-utils.js.map +1 -0
- package/dist/tools/file-discovery.js +144 -0
- package/dist/tools/file-discovery.js.map +1 -0
- package/dist/tools/file-mutations.js +326 -0
- package/dist/tools/file-mutations.js.map +1 -0
- package/dist/tools/file-read.js +133 -0
- package/dist/tools/file-read.js.map +1 -0
- package/dist/tools/patch-apply.js +168 -0
- package/dist/tools/patch-apply.js.map +1 -0
- package/dist/tools/path-safety.js.map +1 -1
- package/dist/tools/replay-utils.js +25 -0
- package/dist/tools/replay-utils.js.map +1 -0
- package/dist/tools/search-utils.js +55 -0
- package/dist/tools/search-utils.js.map +1 -0
- package/dist/tools/sys-notes.js +34 -0
- package/dist/tools/sys-notes.js.map +1 -0
- package/dist/tools/text-utils.js +164 -0
- package/dist/tools/text-utils.js.map +1 -0
- package/dist/tools/undo.js +1 -1
- package/dist/tools/undo.js.map +1 -1
- package/dist/tools/vault-tools.js +36 -0
- package/dist/tools/vault-tools.js.map +1 -0
- package/dist/tools.js +19 -1460
- package/dist/tools.js.map +1 -1
- package/dist/tui/controller.js +5 -2
- package/dist/tui/controller.js.map +1 -1
- package/dist/tui/render.js.map +1 -1
- package/dist/utils.js +2 -2
- package/dist/utils.js.map +1 -1
- package/dist/vault.js +134 -1
- package/dist/vault.js.map +1 -1
- package/dist/watchdog.js +1 -3
- package/dist/watchdog.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { checkPathSafety } from '../safety.js';
|
|
4
|
+
import { checkCwdWarning, enforceMutationWithinCwd, redactPath, resolvePath, } from './path-safety.js';
|
|
5
|
+
import { checkpointReplay } from './replay-utils.js';
|
|
6
|
+
import { bigramSimilarity } from './search-utils.js';
|
|
7
|
+
import { snapshotBeforeEdit } from './sys-notes.js';
|
|
8
|
+
import { mutationReadback } from './text-utils.js';
|
|
9
|
+
import { atomicWrite, backupFile } from './undo.js';
|
|
10
|
+
export async function writeFileTool(ctx, args) {
|
|
11
|
+
const p = resolvePath(ctx, args?.path);
|
|
12
|
+
const absCwd = path.resolve(ctx.cwd);
|
|
13
|
+
const redactedPath = redactPath(p, absCwd);
|
|
14
|
+
const raw = args?.content;
|
|
15
|
+
const contentWasObject = raw != null && typeof raw === 'object';
|
|
16
|
+
const content = typeof raw === 'string' ? raw : contentWasObject ? JSON.stringify(raw, null, 2) : undefined;
|
|
17
|
+
if (contentWasObject) {
|
|
18
|
+
console.warn(`[write_file] Warning: content for "${args?.path}" arrived as ${typeof raw} — auto-serialized to JSON string. If this was intentional (e.g. package.json), the write succeeded.`);
|
|
19
|
+
}
|
|
20
|
+
if (!p)
|
|
21
|
+
throw new Error('write_file: missing path');
|
|
22
|
+
if (content == null)
|
|
23
|
+
throw new Error('write_file: missing content (got ' + typeof raw + ')');
|
|
24
|
+
const overwrite = Boolean(args?.overwrite ?? args?.force);
|
|
25
|
+
enforceMutationWithinCwd('write_file', p, ctx);
|
|
26
|
+
const cwdWarning = checkCwdWarning('write_file', p, ctx);
|
|
27
|
+
const pathVerdict = checkPathSafety(p);
|
|
28
|
+
if (pathVerdict.tier === 'forbidden')
|
|
29
|
+
throw new Error(`write_file: ${pathVerdict.reason}`);
|
|
30
|
+
if (pathVerdict.tier === 'cautious' && !ctx.noConfirm) {
|
|
31
|
+
if (ctx.confirm) {
|
|
32
|
+
const ok = await ctx.confirm(pathVerdict.prompt || `Write to ${redactedPath}?`, {
|
|
33
|
+
tool: 'write_file',
|
|
34
|
+
args: { path: p },
|
|
35
|
+
});
|
|
36
|
+
if (!ok)
|
|
37
|
+
throw new Error(`write_file: cancelled by user (${pathVerdict.reason})`);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
throw new Error(`write_file: blocked (${pathVerdict.reason}) without --no-confirm/--yolo`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const existingStat = await fs.stat(p).catch(() => null);
|
|
44
|
+
if (existingStat?.isFile() && existingStat.size > 0 && !overwrite) {
|
|
45
|
+
throw new Error(`write_file: refusing to overwrite existing non-empty file ${redactedPath} without explicit overwrite=true (or force=true). ` +
|
|
46
|
+
`Use edit_range/apply_patch for surgical edits, or set overwrite=true for intentional full-file replacement.`);
|
|
47
|
+
}
|
|
48
|
+
if (ctx.dryRun) {
|
|
49
|
+
const mode = existingStat?.isFile()
|
|
50
|
+
? existingStat.size > 0
|
|
51
|
+
? 'overwrite'
|
|
52
|
+
: 'update-empty'
|
|
53
|
+
: 'create';
|
|
54
|
+
return `dry-run: would write ${p} (${Buffer.byteLength(content, 'utf8')} bytes, mode=${mode}${overwrite ? ', explicit-overwrite' : ''})${cwdWarning}`;
|
|
55
|
+
}
|
|
56
|
+
if (ctx.mode === 'sys' && ctx.vault)
|
|
57
|
+
await snapshotBeforeEdit(ctx.vault, p).catch(() => { });
|
|
58
|
+
const beforeBuf = await fs.readFile(p).catch(() => Buffer.from(''));
|
|
59
|
+
await backupFile(p, ctx);
|
|
60
|
+
await atomicWrite(p, content);
|
|
61
|
+
ctx.onMutation?.(p);
|
|
62
|
+
const replayNote = await checkpointReplay(ctx, {
|
|
63
|
+
op: 'write_file',
|
|
64
|
+
filePath: p,
|
|
65
|
+
before: beforeBuf,
|
|
66
|
+
after: Buffer.from(content, 'utf8'),
|
|
67
|
+
});
|
|
68
|
+
const contentLines = content.split(/\r?\n/);
|
|
69
|
+
const readback = contentLines.length <= 40
|
|
70
|
+
? mutationReadback(content, 0, contentLines.length)
|
|
71
|
+
: mutationReadback(content, 0, 20) +
|
|
72
|
+
'\n...\n' +
|
|
73
|
+
mutationReadback(content, contentLines.length - 10, contentLines.length);
|
|
74
|
+
return `wrote ${redactedPath} (${Buffer.byteLength(content, 'utf8')} bytes)${replayNote}${cwdWarning}${readback}`;
|
|
75
|
+
}
|
|
76
|
+
export async function insertFileTool(ctx, args) {
|
|
77
|
+
const p = resolvePath(ctx, args?.path);
|
|
78
|
+
const absCwd = path.resolve(ctx.cwd);
|
|
79
|
+
const redactedPath = redactPath(p, absCwd);
|
|
80
|
+
const line = Number(args?.line);
|
|
81
|
+
const rawText = args?.text;
|
|
82
|
+
const text = typeof rawText === 'string'
|
|
83
|
+
? rawText
|
|
84
|
+
: rawText != null && typeof rawText === 'object'
|
|
85
|
+
? JSON.stringify(rawText, null, 2)
|
|
86
|
+
: undefined;
|
|
87
|
+
if (!p)
|
|
88
|
+
throw new Error('insert_file: missing path');
|
|
89
|
+
if (!Number.isFinite(line))
|
|
90
|
+
throw new Error('insert_file: missing/invalid line');
|
|
91
|
+
if (text == null)
|
|
92
|
+
throw new Error('insert_file: missing text (got ' + typeof rawText + ')');
|
|
93
|
+
enforceMutationWithinCwd('insert_file', p, ctx);
|
|
94
|
+
const pathVerdict = checkPathSafety(p);
|
|
95
|
+
if (pathVerdict.tier === 'forbidden')
|
|
96
|
+
throw new Error(`insert_file: ${pathVerdict.reason}`);
|
|
97
|
+
if (pathVerdict.tier === 'cautious' && !ctx.noConfirm) {
|
|
98
|
+
if (ctx.confirm) {
|
|
99
|
+
const ok = await ctx.confirm(pathVerdict.prompt || `Insert into ${redactedPath}?`, {
|
|
100
|
+
tool: 'insert_file',
|
|
101
|
+
args: { path: p },
|
|
102
|
+
});
|
|
103
|
+
if (!ok)
|
|
104
|
+
throw new Error(`insert_file: cancelled by user (${pathVerdict.reason})`);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
throw new Error(`insert_file: blocked (${pathVerdict.reason}) without --no-confirm/--yolo`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (ctx.dryRun)
|
|
111
|
+
return `dry-run: would insert into ${redactedPath} at line=${line} (${Buffer.byteLength(text, 'utf8')} bytes)`;
|
|
112
|
+
if (ctx.mode === 'sys' && ctx.vault)
|
|
113
|
+
await snapshotBeforeEdit(ctx.vault, p).catch(() => { });
|
|
114
|
+
const beforeText = await fs.readFile(p, 'utf8').catch(() => '');
|
|
115
|
+
const eol = beforeText.includes('\r\n') ? '\r\n' : '\n';
|
|
116
|
+
if (beforeText === '') {
|
|
117
|
+
const out = text;
|
|
118
|
+
await backupFile(p, ctx);
|
|
119
|
+
await atomicWrite(p, out);
|
|
120
|
+
ctx.onMutation?.(p);
|
|
121
|
+
const replayNote = await checkpointReplay(ctx, {
|
|
122
|
+
op: 'insert_file',
|
|
123
|
+
filePath: p,
|
|
124
|
+
before: Buffer.from(beforeText, 'utf8'),
|
|
125
|
+
after: Buffer.from(out, 'utf8'),
|
|
126
|
+
});
|
|
127
|
+
const cwdWarning = checkCwdWarning('insert_file', p, ctx);
|
|
128
|
+
const readback = mutationReadback(out, 0, out.split(/\r?\n/).length);
|
|
129
|
+
return `inserted into ${redactedPath} at 0${replayNote}${cwdWarning}${readback}`;
|
|
130
|
+
}
|
|
131
|
+
const lines = beforeText.split(/\r?\n/);
|
|
132
|
+
let idx;
|
|
133
|
+
if (line === -1)
|
|
134
|
+
idx = lines.length;
|
|
135
|
+
else
|
|
136
|
+
idx = Math.max(0, Math.min(lines.length, line));
|
|
137
|
+
if (line === -1 && lines.length > 0 && lines[lines.length - 1] === '')
|
|
138
|
+
idx = lines.length - 1;
|
|
139
|
+
const insertLines = text.split(/\r?\n/);
|
|
140
|
+
lines.splice(idx, 0, ...insertLines);
|
|
141
|
+
const out = lines.join(eol);
|
|
142
|
+
await backupFile(p, ctx);
|
|
143
|
+
await atomicWrite(p, out);
|
|
144
|
+
ctx.onMutation?.(p);
|
|
145
|
+
const replayNote = await checkpointReplay(ctx, {
|
|
146
|
+
op: 'insert_file',
|
|
147
|
+
filePath: p,
|
|
148
|
+
before: Buffer.from(beforeText, 'utf8'),
|
|
149
|
+
after: Buffer.from(out, 'utf8'),
|
|
150
|
+
});
|
|
151
|
+
const cwdWarning = checkCwdWarning('insert_file', p, ctx);
|
|
152
|
+
const insertEndLine = idx + insertLines.length;
|
|
153
|
+
const readback = mutationReadback(out, idx, insertEndLine);
|
|
154
|
+
return `inserted into ${redactedPath} at ${idx}${replayNote}${cwdWarning}${readback}`;
|
|
155
|
+
}
|
|
156
|
+
export async function editFileTool(ctx, args) {
|
|
157
|
+
const p = resolvePath(ctx, args?.path);
|
|
158
|
+
const absCwd = path.resolve(ctx.cwd);
|
|
159
|
+
const redactedPath = redactPath(p, absCwd);
|
|
160
|
+
const rawOld = args?.old_text;
|
|
161
|
+
const oldText = typeof rawOld === 'string'
|
|
162
|
+
? rawOld
|
|
163
|
+
: rawOld != null && typeof rawOld === 'object'
|
|
164
|
+
? JSON.stringify(rawOld, null, 2)
|
|
165
|
+
: undefined;
|
|
166
|
+
const rawNew = args?.new_text;
|
|
167
|
+
const newText = typeof rawNew === 'string'
|
|
168
|
+
? rawNew
|
|
169
|
+
: rawNew != null && typeof rawNew === 'object'
|
|
170
|
+
? JSON.stringify(rawNew, null, 2)
|
|
171
|
+
: undefined;
|
|
172
|
+
const replaceAll = Boolean(args?.replace_all);
|
|
173
|
+
if (!p)
|
|
174
|
+
throw new Error('edit_file: missing path');
|
|
175
|
+
if (oldText == null)
|
|
176
|
+
throw new Error('edit_file: missing old_text');
|
|
177
|
+
if (newText == null)
|
|
178
|
+
throw new Error('edit_file: missing new_text');
|
|
179
|
+
enforceMutationWithinCwd('edit_file', p, ctx);
|
|
180
|
+
const pathVerdict = checkPathSafety(p);
|
|
181
|
+
if (pathVerdict.tier === 'forbidden')
|
|
182
|
+
throw new Error(`edit_file: ${pathVerdict.reason}`);
|
|
183
|
+
if (pathVerdict.tier === 'cautious' && !ctx.noConfirm) {
|
|
184
|
+
if (ctx.confirm) {
|
|
185
|
+
const ok = await ctx.confirm(pathVerdict.prompt || `Edit ${redactedPath}?`, {
|
|
186
|
+
tool: 'edit_file',
|
|
187
|
+
args: { path: p, old_text: oldText, new_text: newText },
|
|
188
|
+
});
|
|
189
|
+
if (!ok)
|
|
190
|
+
throw new Error(`edit_file: cancelled by user (${pathVerdict.reason})`);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
throw new Error(`edit_file: blocked (${pathVerdict.reason}) without --no-confirm/--yolo`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (ctx.mode === 'sys' && ctx.vault)
|
|
197
|
+
await snapshotBeforeEdit(ctx.vault, p).catch(() => { });
|
|
198
|
+
const cur = await fs.readFile(p, 'utf8').catch((e) => {
|
|
199
|
+
throw new Error(`edit_file: cannot read ${redactedPath}: ${e?.message ?? String(e)}`);
|
|
200
|
+
});
|
|
201
|
+
const idx = cur.indexOf(oldText);
|
|
202
|
+
if (idx === -1) {
|
|
203
|
+
const normalize = (s) => s.replace(/\s+/g, ' ').trim().toLowerCase();
|
|
204
|
+
const needle = normalize(oldText);
|
|
205
|
+
const curLines = cur.split(/\r?\n/);
|
|
206
|
+
const needleLines = oldText.split(/\r?\n/).length;
|
|
207
|
+
let bestScore = 0;
|
|
208
|
+
let bestLine = -1;
|
|
209
|
+
let bestText = '';
|
|
210
|
+
for (let i = 0; i < curLines.length; i++) {
|
|
211
|
+
const windowEnd = Math.min(curLines.length, i + needleLines);
|
|
212
|
+
const window = curLines.slice(i, windowEnd).join('\n');
|
|
213
|
+
const score = bigramSimilarity(needle, normalize(window));
|
|
214
|
+
if (score > bestScore) {
|
|
215
|
+
bestScore = score;
|
|
216
|
+
bestLine = i + 1;
|
|
217
|
+
bestText = window;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
let hint = '';
|
|
221
|
+
if (bestScore > 0.3 && bestLine > 0) {
|
|
222
|
+
const preview = bestText.length > 600 ? bestText.slice(0, 600) + '…' : bestText;
|
|
223
|
+
hint = `\nClosest match at line ${bestLine} (${Math.round(bestScore * 100)}% similarity):\n${preview}`;
|
|
224
|
+
}
|
|
225
|
+
else if (!cur.trim()) {
|
|
226
|
+
hint = `\nFile is empty.`;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
hint = `\nFile head (first 400 chars):\n${cur.slice(0, 400)}`;
|
|
230
|
+
}
|
|
231
|
+
throw new Error(`edit_file: old_text not found in ${redactedPath}. Re-read the file and retry with exact text.${hint}`);
|
|
232
|
+
}
|
|
233
|
+
const next = replaceAll
|
|
234
|
+
? cur.split(oldText).join(newText)
|
|
235
|
+
: cur.slice(0, idx) + newText + cur.slice(idx + oldText.length);
|
|
236
|
+
if (ctx.dryRun)
|
|
237
|
+
return `dry-run: would edit ${redactedPath} (replace_all=${replaceAll})`;
|
|
238
|
+
await backupFile(p, ctx);
|
|
239
|
+
await atomicWrite(p, next);
|
|
240
|
+
ctx.onMutation?.(p);
|
|
241
|
+
const replayNote = await checkpointReplay(ctx, {
|
|
242
|
+
op: 'edit_file',
|
|
243
|
+
filePath: p,
|
|
244
|
+
before: Buffer.from(cur, 'utf8'),
|
|
245
|
+
after: Buffer.from(next, 'utf8'),
|
|
246
|
+
});
|
|
247
|
+
const cwdWarning = checkCwdWarning('edit_file', p, ctx);
|
|
248
|
+
const editStartLine = next.slice(0, idx).split(/\r?\n/).length - 1;
|
|
249
|
+
const editEndLine = editStartLine + newText.split(/\r?\n/).length;
|
|
250
|
+
const readback = mutationReadback(next, editStartLine, editEndLine);
|
|
251
|
+
return `edited ${redactedPath} (replace_all=${replaceAll})${replayNote}${cwdWarning}${readback}`;
|
|
252
|
+
}
|
|
253
|
+
export async function editRangeTool(ctx, args) {
|
|
254
|
+
const p = resolvePath(ctx, args?.path);
|
|
255
|
+
const startLine = Number(args?.start_line);
|
|
256
|
+
const endLine = Number(args?.end_line);
|
|
257
|
+
const rawReplacement = args?.replacement;
|
|
258
|
+
const replacement = typeof rawReplacement === 'string'
|
|
259
|
+
? rawReplacement
|
|
260
|
+
: rawReplacement != null && typeof rawReplacement === 'object'
|
|
261
|
+
? JSON.stringify(rawReplacement, null, 2)
|
|
262
|
+
: undefined;
|
|
263
|
+
if (!p)
|
|
264
|
+
throw new Error('edit_range: missing path');
|
|
265
|
+
if (!Number.isFinite(startLine) || startLine < 1)
|
|
266
|
+
throw new Error('edit_range: missing/invalid start_line');
|
|
267
|
+
if (!Number.isFinite(endLine) || endLine < startLine)
|
|
268
|
+
throw new Error('edit_range: missing/invalid end_line');
|
|
269
|
+
if (replacement == null)
|
|
270
|
+
throw new Error('edit_range: missing replacement (got ' + typeof rawReplacement + ')');
|
|
271
|
+
const hasLiteralEscapedNewlines = replacement.includes('\\n');
|
|
272
|
+
const hasRealNewlines = replacement.includes('\n') || replacement.includes('\r');
|
|
273
|
+
if (hasLiteralEscapedNewlines && !hasRealNewlines) {
|
|
274
|
+
throw new Error('edit_range: replacement appears double-escaped (contains literal "\\n" sequences). ' +
|
|
275
|
+
'Resend replacement with REAL newline characters (multi-line string), not escaped backslash-n text.');
|
|
276
|
+
}
|
|
277
|
+
enforceMutationWithinCwd('edit_range', p, ctx);
|
|
278
|
+
const pathVerdict = checkPathSafety(p);
|
|
279
|
+
if (pathVerdict.tier === 'forbidden')
|
|
280
|
+
throw new Error(`edit_range: ${pathVerdict.reason}`);
|
|
281
|
+
if (pathVerdict.tier === 'cautious' && !ctx.noConfirm) {
|
|
282
|
+
if (ctx.confirm) {
|
|
283
|
+
const ok = await ctx.confirm(pathVerdict.prompt || `Edit range in ${p}?`, {
|
|
284
|
+
tool: 'edit_range',
|
|
285
|
+
args: { path: p, start_line: startLine, end_line: endLine },
|
|
286
|
+
});
|
|
287
|
+
if (!ok)
|
|
288
|
+
throw new Error(`edit_range: cancelled by user (${pathVerdict.reason})`);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
throw new Error(`edit_range: blocked (${pathVerdict.reason}) without --no-confirm/--yolo`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (ctx.dryRun)
|
|
295
|
+
return `dry-run: would edit_range ${p} lines ${startLine}-${endLine} (${Buffer.byteLength(replacement, 'utf8')} bytes)`;
|
|
296
|
+
if (ctx.mode === 'sys' && ctx.vault)
|
|
297
|
+
await snapshotBeforeEdit(ctx.vault, p).catch(() => { });
|
|
298
|
+
const beforeText = await fs.readFile(p, 'utf8').catch((e) => {
|
|
299
|
+
throw new Error(`edit_range: cannot read ${p}: ${e?.message ?? String(e)}`);
|
|
300
|
+
});
|
|
301
|
+
const eol = beforeText.includes('\r\n') ? '\r\n' : '\n';
|
|
302
|
+
const lines = beforeText.split(/\r?\n/);
|
|
303
|
+
if (startLine > lines.length)
|
|
304
|
+
throw new Error(`edit_range: start_line ${startLine} out of range (file has ${lines.length} lines)`);
|
|
305
|
+
if (endLine > lines.length)
|
|
306
|
+
throw new Error(`edit_range: end_line ${endLine} out of range (file has ${lines.length} lines)`);
|
|
307
|
+
const startIdx = startLine - 1;
|
|
308
|
+
const deleteCount = endLine - startLine + 1;
|
|
309
|
+
const replacementLines = replacement === '' ? [] : replacement.split(/\r?\n/);
|
|
310
|
+
lines.splice(startIdx, deleteCount, ...replacementLines);
|
|
311
|
+
const out = lines.join(eol);
|
|
312
|
+
await backupFile(p, ctx);
|
|
313
|
+
await atomicWrite(p, out);
|
|
314
|
+
ctx.onMutation?.(p);
|
|
315
|
+
const replayNote = await checkpointReplay(ctx, {
|
|
316
|
+
op: 'edit_range',
|
|
317
|
+
filePath: p,
|
|
318
|
+
before: Buffer.from(beforeText, 'utf8'),
|
|
319
|
+
after: Buffer.from(out, 'utf8'),
|
|
320
|
+
});
|
|
321
|
+
const cwdWarning = checkCwdWarning('edit_range', p, ctx);
|
|
322
|
+
const rangeEndLine = startIdx + replacementLines.length;
|
|
323
|
+
const readback = mutationReadback(out, startIdx, rangeEndLine);
|
|
324
|
+
return `edited ${p} lines ${startLine}-${endLine}${replayNote}${cwdWarning}${readback}`;
|
|
325
|
+
}
|
|
326
|
+
//# sourceMappingURL=file-mutations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-mutations.js","sourceRoot":"","sources":["../../src/tools/file-mutations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { resolvePath, redactPath } from './path-safety.js';
|
|
4
|
+
import { guessMimeType, truncateBytes } from './text-utils.js';
|
|
5
|
+
import { ToolError } from './tool-error.js';
|
|
6
|
+
export async function readFileTool(ctx, args) {
|
|
7
|
+
const p = resolvePath(ctx, args?.path);
|
|
8
|
+
const absCwd = path.resolve(ctx.cwd);
|
|
9
|
+
const redactedPath = redactPath(p, absCwd);
|
|
10
|
+
const offset = args?.offset != null ? Number(args.offset) : undefined;
|
|
11
|
+
const rawLimit = args?.limit != null ? Number(args.limit) : undefined;
|
|
12
|
+
let limit = Number.isFinite(rawLimit) && rawLimit > 0
|
|
13
|
+
? Math.max(1, Math.floor(rawLimit))
|
|
14
|
+
: 200;
|
|
15
|
+
if (ctx.maxReadLines != null && ctx.maxReadLines > 0) {
|
|
16
|
+
limit = Math.min(limit, ctx.maxReadLines);
|
|
17
|
+
}
|
|
18
|
+
const search = typeof args?.search === 'string' ? args.search : undefined;
|
|
19
|
+
const rawContext = args?.context != null ? Number(args.context) : undefined;
|
|
20
|
+
const context = Number.isFinite(rawContext) && rawContext >= 0
|
|
21
|
+
? Math.max(0, Math.min(200, Math.floor(rawContext)))
|
|
22
|
+
: 10;
|
|
23
|
+
const formatRaw = typeof args?.format === 'string' ? args.format.trim().toLowerCase() : 'numbered';
|
|
24
|
+
const format = formatRaw === 'plain' || formatRaw === 'numbered' || formatRaw === 'sparse'
|
|
25
|
+
? formatRaw
|
|
26
|
+
: 'numbered';
|
|
27
|
+
const rawMaxBytes = args?.max_bytes != null ? Number(args.max_bytes) : undefined;
|
|
28
|
+
const maxBytes = Number.isFinite(rawMaxBytes) && rawMaxBytes > 0
|
|
29
|
+
? Math.min(256 * 1024, Math.max(256, Math.floor(rawMaxBytes)))
|
|
30
|
+
: 20 * 1024;
|
|
31
|
+
if (!p)
|
|
32
|
+
throw new Error('read_file: missing path');
|
|
33
|
+
try {
|
|
34
|
+
const stat = await fs.stat(p);
|
|
35
|
+
if (stat.isDirectory()) {
|
|
36
|
+
return `read_file: "${redactedPath}" is a directory, not a file. Use list_dir to see its contents, or search_files to find specific code.`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// let readFile error path handle ENOENT/etc
|
|
41
|
+
}
|
|
42
|
+
const buf = await fs.readFile(p).catch((e) => {
|
|
43
|
+
throw new Error(`read_file: cannot read ${p}: ${e?.message ?? String(e)}`);
|
|
44
|
+
});
|
|
45
|
+
for (let i = 0; i < Math.min(buf.length, 512); i++) {
|
|
46
|
+
if (buf[i] === 0) {
|
|
47
|
+
const mimeGuess = guessMimeType(p, buf);
|
|
48
|
+
return `[binary file, ${buf.length} bytes, detected type: ${mimeGuess}]`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const text = buf.toString('utf8');
|
|
52
|
+
if (!text)
|
|
53
|
+
return `# ${p}\n[file is empty (0 bytes)]`;
|
|
54
|
+
const lines = text.split(/\r?\n/);
|
|
55
|
+
let start = 1;
|
|
56
|
+
let end = Math.min(lines.length, limit);
|
|
57
|
+
let matchLines = [];
|
|
58
|
+
if (search) {
|
|
59
|
+
matchLines = [];
|
|
60
|
+
for (let i = 0; i < lines.length; i++) {
|
|
61
|
+
if (lines[i].includes(search))
|
|
62
|
+
matchLines.push(i + 1);
|
|
63
|
+
}
|
|
64
|
+
if (!matchLines.length) {
|
|
65
|
+
return truncateBytes(`# ${p}\n# search not found: ${JSON.stringify(search)}\n# file has ${lines.length} lines`, maxBytes).text;
|
|
66
|
+
}
|
|
67
|
+
const firstIdx = matchLines[0];
|
|
68
|
+
start = Math.max(1, firstIdx - context);
|
|
69
|
+
end = Math.min(lines.length, firstIdx + context);
|
|
70
|
+
if (end - start + 1 > limit) {
|
|
71
|
+
const half = Math.floor(limit / 2);
|
|
72
|
+
start = Math.max(1, firstIdx - half);
|
|
73
|
+
end = Math.min(lines.length, start + limit - 1);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else if (offset && offset >= 1) {
|
|
77
|
+
start = Math.max(1, Math.floor(offset));
|
|
78
|
+
end = Math.min(lines.length, start + limit - 1);
|
|
79
|
+
}
|
|
80
|
+
const matchSet = new Set(matchLines);
|
|
81
|
+
const out = [];
|
|
82
|
+
out.push(`# ${p} (lines ${start}-${end} of ${lines.length})`);
|
|
83
|
+
if (search) {
|
|
84
|
+
const shown = matchLines.slice(0, 20);
|
|
85
|
+
out.push(`# matches at lines: ${shown.join(', ')}${matchLines.length > shown.length ? ' …' : ''}`);
|
|
86
|
+
}
|
|
87
|
+
const renderNumbered = (ln, body) => `${ln}| ${body}`;
|
|
88
|
+
for (let ln = start; ln <= end; ln++) {
|
|
89
|
+
const body = lines[ln - 1] ?? '';
|
|
90
|
+
if (format === 'plain') {
|
|
91
|
+
out.push(body);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (format === 'numbered') {
|
|
95
|
+
out.push(renderNumbered(ln, body));
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const isAnchor = ln === start || ln === end || (ln - start) % 10 === 0;
|
|
99
|
+
if (isAnchor || matchSet.has(ln))
|
|
100
|
+
out.push(renderNumbered(ln, body));
|
|
101
|
+
else
|
|
102
|
+
out.push(body);
|
|
103
|
+
}
|
|
104
|
+
if (end < lines.length)
|
|
105
|
+
out.push(`# ... (${lines.length - end} more lines)`);
|
|
106
|
+
return truncateBytes(out.join('\n'), maxBytes).text;
|
|
107
|
+
}
|
|
108
|
+
export async function readFilesTool(ctx, args) {
|
|
109
|
+
const reqs = Array.isArray(args?.requests) ? args.requests : [];
|
|
110
|
+
if (!reqs.length) {
|
|
111
|
+
throw new ToolError('invalid_args', 'read_files: missing requests[]', false, 'Provide requests as an array of {path, limit,...} objects.');
|
|
112
|
+
}
|
|
113
|
+
const parts = [];
|
|
114
|
+
let failures = 0;
|
|
115
|
+
for (let i = 0; i < reqs.length; i++) {
|
|
116
|
+
const r = reqs[i];
|
|
117
|
+
const p = typeof r?.path === 'string' ? r.path : `request[${i}]`;
|
|
118
|
+
try {
|
|
119
|
+
parts.push(await readFileTool(ctx, r));
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
failures++;
|
|
123
|
+
const te = ToolError.fromError(e, 'internal');
|
|
124
|
+
parts.push(`[file:${p}] ERROR: code=${te.code} msg=${te.message}`);
|
|
125
|
+
}
|
|
126
|
+
parts.push('');
|
|
127
|
+
}
|
|
128
|
+
if (failures > 0) {
|
|
129
|
+
parts.push(`# read_files completed with partial failures: ${failures}/${reqs.length}`);
|
|
130
|
+
}
|
|
131
|
+
return parts.join('\n');
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=file-read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-read.js","sourceRoot":"","sources":["../../src/tools/file-read.ts"],"names":[],"mappings":"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"}
|