@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,252 @@
|
|
|
1
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { checkExecSafety, isProtectedDeleteTarget } from '../safety.js';
|
|
5
|
+
import { BASH_PATH } from '../utils.js';
|
|
6
|
+
import { execWithPty } from './exec-pty.js';
|
|
7
|
+
import { hasBackgroundExecIntent, makeExecStreamer } from './exec-utils.js';
|
|
8
|
+
import { isWithinDir, resolvePath } from './path-safety.js';
|
|
9
|
+
import { autoNoteSysChange } from './sys-notes.js';
|
|
10
|
+
import { stripAnsi, dedupeRepeats, collapseStackTraces, truncateBytes } from './text-utils.js';
|
|
11
|
+
const DEFAULT_MAX_EXEC_BYTES = 16384;
|
|
12
|
+
let ptyUnavailableWarned = false;
|
|
13
|
+
async function loadNodePty() {
|
|
14
|
+
try {
|
|
15
|
+
const mod = await import('node-pty');
|
|
16
|
+
return mod;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
if (!ptyUnavailableWarned) {
|
|
20
|
+
ptyUnavailableWarned = true;
|
|
21
|
+
console.error('[warn] node-pty not available; interactive sudo is disabled. Install build tools (python3, make, g++) and reinstall to enable it.');
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export async function execTool(ctx, args) {
|
|
27
|
+
const command = typeof args?.command === 'string' ? args.command : undefined;
|
|
28
|
+
const cwd = args?.cwd ? resolvePath(ctx, args.cwd) : ctx.cwd;
|
|
29
|
+
const defaultTimeout = ctx.mode === 'sys' ? 60 : 30;
|
|
30
|
+
const timeout = Math.min(args?.timeout ? Number(args.timeout) : defaultTimeout, 120);
|
|
31
|
+
if (!command)
|
|
32
|
+
throw new Error('exec: missing command');
|
|
33
|
+
const absCwd = path.resolve(ctx.cwd);
|
|
34
|
+
const allowOutsideCwd = ctx.approvalMode === 'yolo' || ctx.approvalMode === 'auto-edit';
|
|
35
|
+
let execCwdWarning = '';
|
|
36
|
+
if (args?.cwd) {
|
|
37
|
+
const absExecCwd = path.resolve(cwd);
|
|
38
|
+
if (!isWithinDir(absExecCwd, absCwd)) {
|
|
39
|
+
if (!allowOutsideCwd) {
|
|
40
|
+
throw new Error(`exec: BLOCKED — cwd "${absExecCwd}" is outside the working directory "${absCwd}". Use relative paths and work within the project directory.`);
|
|
41
|
+
}
|
|
42
|
+
execCwdWarning = `\n[WARNING] cwd "${absExecCwd}" is outside the working directory "${absCwd}". Proceeding due to ${ctx.approvalMode} mode.`;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (command) {
|
|
46
|
+
const cdPattern = /\bcd\s+(['"]?)(\/[^\s'";&|]+|[a-zA-Z]:[\\/][^\s'";&|]*)\1/g;
|
|
47
|
+
let cdMatch;
|
|
48
|
+
while ((cdMatch = cdPattern.exec(command)) !== null) {
|
|
49
|
+
const cdTarget = path.resolve(cdMatch[2]);
|
|
50
|
+
if (!isWithinDir(cdTarget, absCwd)) {
|
|
51
|
+
if (!allowOutsideCwd) {
|
|
52
|
+
throw new Error(`exec: BLOCKED — command navigates to "${cdTarget}" which is outside the working directory "${absCwd}". Use relative paths and work within the project directory.`);
|
|
53
|
+
}
|
|
54
|
+
execCwdWarning = `\n[WARNING] Command navigates to "${cdTarget}" which is outside the working directory "${absCwd}". Proceeding due to ${ctx.approvalMode} mode.`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const absPathPattern = /(?:mkdir|cat\s*>|tee|touch|cp|mv|rm|rmdir)\s+(?:-\S+\s+)*(['"]?)(\/[^\s'";&|]+|[a-zA-Z]:[\\/][^\s'";&|]*)\1/g;
|
|
58
|
+
let apMatch;
|
|
59
|
+
while ((apMatch = absPathPattern.exec(command)) !== null) {
|
|
60
|
+
const absTarget = path.resolve(apMatch[2]);
|
|
61
|
+
if (!isWithinDir(absTarget, absCwd)) {
|
|
62
|
+
if (!allowOutsideCwd) {
|
|
63
|
+
throw new Error(`exec: BLOCKED — command targets "${absTarget}" which is outside the working directory "${absCwd}". Use relative paths to work within the project directory.`);
|
|
64
|
+
}
|
|
65
|
+
execCwdWarning = `\n[WARNING] Command targets "${absTarget}" which is outside the working directory "${absCwd}". Proceeding due to ${ctx.approvalMode} mode.`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (hasBackgroundExecIntent(command)) {
|
|
70
|
+
throw new Error('exec: blocked background command (contains `&`). Long-running/background jobs can stall one-shot sessions. Run foreground smoke checks only, or use a dedicated service manager outside this task.');
|
|
71
|
+
}
|
|
72
|
+
const verdict = checkExecSafety(command);
|
|
73
|
+
if (verdict.tier === 'forbidden')
|
|
74
|
+
throw new Error(`exec: ${verdict.reason} — command: ${command}`);
|
|
75
|
+
if (isProtectedDeleteTarget(command)) {
|
|
76
|
+
throw new Error(`exec: BLOCKED: rm targeting protected directory — command: ${command}`);
|
|
77
|
+
}
|
|
78
|
+
if (verdict.tier === 'cautious' && !ctx.noConfirm) {
|
|
79
|
+
if (ctx.confirm) {
|
|
80
|
+
const ok = await ctx.confirm(verdict.prompt || `About to run:\n\n${command}\n\nProceed? (y/N) `, {
|
|
81
|
+
tool: 'exec',
|
|
82
|
+
args: { command },
|
|
83
|
+
});
|
|
84
|
+
if (!ok)
|
|
85
|
+
throw new Error(`exec: cancelled by user (${verdict.reason}): ${command}`);
|
|
86
|
+
}
|
|
87
|
+
else if (verdict.reason === 'package install/remove') {
|
|
88
|
+
throw new Error(`exec: blocked (${verdict.reason}) without --no-confirm/--yolo: ${command}\nSTOP: this is a session-level approval restriction. Adding --yolo/--no-confirm inside the shell command does NOT override it. Re-run the parent session with --no-confirm or --yolo to allow package operations. Alternatively, the user can install packages manually and re-run this task. Do NOT use spawn_task to bypass this restriction.`);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
throw new Error(`exec: blocked (${verdict.reason}) without --no-confirm/--yolo: ${command}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (ctx.dryRun)
|
|
95
|
+
return `dry-run: would exec in ${cwd}: ${command}`;
|
|
96
|
+
if (/^\s*sudo\s/.test(command) && !process.stdin.isTTY) {
|
|
97
|
+
try {
|
|
98
|
+
const probe = spawnSync('sudo', ['-n', 'true'], { timeout: 5000, stdio: 'ignore' });
|
|
99
|
+
if (probe.status !== 0) {
|
|
100
|
+
throw new Error('exec: sudo requires a TTY for password input, but stdin is not a TTY. Options: run idlehands interactively, configure NOPASSWD for this command, or pre-cache sudo credentials.');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
if (e.message?.includes('sudo requires a TTY'))
|
|
105
|
+
throw e;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const maxBytes = ctx.maxExecBytes ?? DEFAULT_MAX_EXEC_BYTES;
|
|
109
|
+
const captureLimit = ctx.maxExecCaptureBytes ?? Math.max(maxBytes * 64, 256 * 1024);
|
|
110
|
+
if (/^\s*sudo\s/.test(command) && process.stdin.isTTY) {
|
|
111
|
+
const pty = await loadNodePty();
|
|
112
|
+
if (!pty) {
|
|
113
|
+
throw new Error('exec: interactive sudo requires node-pty, but it is not installed. Install optional dependency `node-pty` (build tools: python3, make, g++) or use non-interactive sudo (NOPASSWD/cached credentials).');
|
|
114
|
+
}
|
|
115
|
+
return await execWithPty({
|
|
116
|
+
pty,
|
|
117
|
+
command,
|
|
118
|
+
cwd,
|
|
119
|
+
timeout,
|
|
120
|
+
maxBytes,
|
|
121
|
+
captureLimit,
|
|
122
|
+
signal: ctx.signal,
|
|
123
|
+
execCwdWarning,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
await fs.access(cwd);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
throw new Error(`exec: working directory does not exist: ${cwd}`);
|
|
131
|
+
}
|
|
132
|
+
const child = spawn(command, [], {
|
|
133
|
+
cwd,
|
|
134
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
135
|
+
shell: BASH_PATH,
|
|
136
|
+
detached: true,
|
|
137
|
+
});
|
|
138
|
+
const outChunks = [];
|
|
139
|
+
const errChunks = [];
|
|
140
|
+
let outSeen = 0;
|
|
141
|
+
let errSeen = 0;
|
|
142
|
+
let outCaptured = 0;
|
|
143
|
+
let errCaptured = 0;
|
|
144
|
+
let killed = false;
|
|
145
|
+
const killProcessGroup = () => {
|
|
146
|
+
const pid = child.pid;
|
|
147
|
+
if (!pid)
|
|
148
|
+
return;
|
|
149
|
+
try {
|
|
150
|
+
process.kill(-pid, 'SIGKILL');
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
try {
|
|
154
|
+
child.kill('SIGKILL');
|
|
155
|
+
}
|
|
156
|
+
catch { }
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
const killTimer = setTimeout(() => {
|
|
160
|
+
killed = true;
|
|
161
|
+
killProcessGroup();
|
|
162
|
+
}, Math.max(1, timeout) * 1000);
|
|
163
|
+
const onAbort = () => {
|
|
164
|
+
killed = true;
|
|
165
|
+
killProcessGroup();
|
|
166
|
+
};
|
|
167
|
+
ctx.signal?.addEventListener('abort', onAbort, { once: true });
|
|
168
|
+
const pushCapped = (chunks, buf, kind) => {
|
|
169
|
+
const n = buf.length;
|
|
170
|
+
if (kind === 'out')
|
|
171
|
+
outSeen += n;
|
|
172
|
+
else
|
|
173
|
+
errSeen += n;
|
|
174
|
+
const captured = kind === 'out' ? outCaptured : errCaptured;
|
|
175
|
+
const remaining = captureLimit - captured;
|
|
176
|
+
if (remaining <= 0)
|
|
177
|
+
return;
|
|
178
|
+
const take = n <= remaining ? buf : buf.subarray(0, remaining);
|
|
179
|
+
chunks.push(Buffer.from(take));
|
|
180
|
+
if (kind === 'out')
|
|
181
|
+
outCaptured += take.length;
|
|
182
|
+
else
|
|
183
|
+
errCaptured += take.length;
|
|
184
|
+
};
|
|
185
|
+
const streamer = makeExecStreamer(ctx);
|
|
186
|
+
child.stdout.on('data', (d) => {
|
|
187
|
+
pushCapped(outChunks, d, 'out');
|
|
188
|
+
streamer?.push('stdout', stripAnsi(d.toString('utf8')));
|
|
189
|
+
});
|
|
190
|
+
child.stderr.on('data', (d) => {
|
|
191
|
+
pushCapped(errChunks, d, 'err');
|
|
192
|
+
streamer?.push('stderr', stripAnsi(d.toString('utf8')));
|
|
193
|
+
});
|
|
194
|
+
const rc = await new Promise((resolve, reject) => {
|
|
195
|
+
child.on('error', (err) => {
|
|
196
|
+
clearTimeout(killTimer);
|
|
197
|
+
ctx.signal?.removeEventListener('abort', onAbort);
|
|
198
|
+
reject(new Error(`exec: failed to spawn shell (cwd=${cwd}): ${err.message} (${err.code ?? 'unknown'})`));
|
|
199
|
+
});
|
|
200
|
+
child.on('close', (code) => resolve(code ?? 0));
|
|
201
|
+
});
|
|
202
|
+
clearTimeout(killTimer);
|
|
203
|
+
ctx.signal?.removeEventListener('abort', onAbort);
|
|
204
|
+
streamer?.done();
|
|
205
|
+
const outRaw = stripAnsi(Buffer.concat(outChunks).toString('utf8'));
|
|
206
|
+
const errRaw = stripAnsi(Buffer.concat(errChunks).toString('utf8'));
|
|
207
|
+
const outLines = collapseStackTraces(dedupeRepeats(outRaw.split(/\r?\n/)))
|
|
208
|
+
.join('\n')
|
|
209
|
+
.trimEnd();
|
|
210
|
+
const errLines = collapseStackTraces(dedupeRepeats(errRaw.split(/\r?\n/)))
|
|
211
|
+
.join('\n')
|
|
212
|
+
.trimEnd();
|
|
213
|
+
const outT = truncateBytes(outLines, maxBytes, outSeen);
|
|
214
|
+
const errT = truncateBytes(errLines, maxBytes, errSeen);
|
|
215
|
+
let outText = outT.text;
|
|
216
|
+
let errText = errT.text;
|
|
217
|
+
const capOut = outSeen > outCaptured;
|
|
218
|
+
const capErr = errSeen > errCaptured;
|
|
219
|
+
if (capOut && !outT.truncated) {
|
|
220
|
+
outText = truncateBytes(outText + `\n[capture truncated, ${outSeen} bytes total]`, maxBytes, outSeen).text;
|
|
221
|
+
}
|
|
222
|
+
if (capErr && !errT.truncated) {
|
|
223
|
+
errText = truncateBytes(errText + `\n[capture truncated, ${errSeen} bytes total]`, maxBytes, errSeen).text;
|
|
224
|
+
}
|
|
225
|
+
if (killed)
|
|
226
|
+
errText = (errText ? errText + '\n' : '') + `[killed after ${timeout}s timeout]`;
|
|
227
|
+
if (!outText && !errText && !killed) {
|
|
228
|
+
if (rc === 0) {
|
|
229
|
+
outText =
|
|
230
|
+
'[command completed successfully with no output. Do NOT retry — the command worked but produced no output. Move on to the next step.]';
|
|
231
|
+
}
|
|
232
|
+
else if (rc === 1) {
|
|
233
|
+
outText =
|
|
234
|
+
'[no matches found — the command returned zero results (exit code 1). Do NOT retry this command with the same arguments. The target simply has no matches. Move on or try different search terms/parameters.]';
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
outText = `[command exited with code ${rc} and produced no output. Do NOT retry with identical arguments — diagnose the issue or try a different approach.]`;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const result = {
|
|
241
|
+
rc,
|
|
242
|
+
out: outText,
|
|
243
|
+
err: errText,
|
|
244
|
+
truncated: outT.truncated || errT.truncated || capOut || capErr,
|
|
245
|
+
...(execCwdWarning && { warnings: [execCwdWarning.trim()] }),
|
|
246
|
+
};
|
|
247
|
+
if (ctx.mode === 'sys' && ctx.vault && rc === 0) {
|
|
248
|
+
autoNoteSysChange(ctx.vault, command, outText).catch(() => { });
|
|
249
|
+
}
|
|
250
|
+
return JSON.stringify(result);
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=exec-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec-core.js","sourceRoot":"","sources":["../../src/tools/exec-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAExE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE/F,MAAM,sBAAsB,GAAG,KAAK,CAAC;AACrC,IAAI,oBAAoB,GAAG,KAAK,CAAC;AAEjC,KAAK,UAAU,WAAW;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAQ,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1C,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC1B,oBAAoB,GAAG,IAAI,CAAC;YAC5B,OAAO,CAAC,KAAK,CACX,mIAAmI,CACpI,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAwBD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAoB,EAAE,IAAS;IAC5D,MAAM,OAAO,GAAG,OAAO,IAAI,EAAE,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7E,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,GAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACpE,MAAM,cAAc,GAAG,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACrF,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAEvD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,eAAe,GAAG,GAAG,CAAC,YAAY,KAAK,MAAM,IAAI,GAAG,CAAC,YAAY,KAAK,WAAW,CAAC;IACxF,IAAI,cAAc,GAAG,EAAE,CAAC;IACxB,IAAI,IAAI,EAAE,GAAG,EAAE,CAAC;QACd,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CACb,wBAAwB,UAAU,uCAAuC,MAAM,8DAA8D,CAC9I,CAAC;YACJ,CAAC;YACD,cAAc,GAAG,oBAAoB,UAAU,uCAAuC,MAAM,wBAAwB,GAAG,CAAC,YAAY,QAAQ,CAAC;QAC/I,CAAC;IACH,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,4DAA4D,CAAC;QAC/E,IAAI,OAA+B,CAAC;QACpC,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;gBACnC,IAAI,CAAC,eAAe,EAAE,CAAC;oBACrB,MAAM,IAAI,KAAK,CACb,yCAAyC,QAAQ,6CAA6C,MAAM,8DAA8D,CACnK,CAAC;gBACJ,CAAC;gBACD,cAAc,GAAG,qCAAqC,QAAQ,6CAA6C,MAAM,wBAAwB,GAAG,CAAC,YAAY,QAAQ,CAAC;YACpK,CAAC;QACH,CAAC;QACD,MAAM,cAAc,GAClB,8GAA8G,CAAC;QACjH,IAAI,OAA+B,CAAC;QACpC,OAAO,CAAC,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACzD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;gBACpC,IAAI,CAAC,eAAe,EAAE,CAAC;oBACrB,MAAM,IAAI,KAAK,CACb,oCAAoC,SAAS,6CAA6C,MAAM,6DAA6D,CAC9J,CAAC;gBACJ,CAAC;gBACD,cAAc,GAAG,gCAAgC,SAAS,6CAA6C,MAAM,wBAAwB,GAAG,CAAC,YAAY,QAAQ,CAAC;YAChK,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,uBAAuB,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CACb,oMAAoM,CACrM,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW;QAC9B,MAAM,IAAI,KAAK,CAAC,SAAS,OAAO,CAAC,MAAM,eAAe,OAAO,EAAE,CAAC,CAAC;IACnE,IAAI,uBAAuB,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,8DAA8D,OAAO,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QAClD,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,OAAO,CAC1B,OAAO,CAAC,MAAM,IAAI,oBAAoB,OAAO,qBAAqB,EAClE;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,EAAE,OAAO,EAAE;aAClB,CACF,CAAC;YACF,IAAI,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,CAAC,MAAM,MAAM,OAAO,EAAE,CAAC,CAAC;QACtF,CAAC;aAAM,IAAI,OAAO,CAAC,MAAM,KAAK,wBAAwB,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CACb,kBAAkB,OAAO,CAAC,MAAM,kCAAkC,OAAO,kVAAkV,CAC5Z,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,kBAAkB,OAAO,CAAC,MAAM,kCAAkC,OAAO,EAAE,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,MAAM;QAAE,OAAO,0BAA0B,GAAG,KAAK,OAAO,EAAE,CAAC;IAEnE,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACpF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CACb,iLAAiL,CAClL,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,qBAAqB,CAAC;gBAAE,MAAM,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,IAAI,sBAAsB,CAAC;IAC5D,MAAM,YAAY,GAAG,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,EAAE,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC;IAEpF,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACtD,MAAM,GAAG,GAAG,MAAM,WAAW,EAAE,CAAC;QAChC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,wMAAwM,CACzM,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,WAAW,CAAC;YACvB,GAAG;YACH,OAAO;YACP,GAAG;YACH,OAAO;YACP,QAAQ;YACR,YAAY;YACZ,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,cAAc;SACf,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,2CAA2C,GAAG,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE;QAC/B,GAAG;QACH,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;QACjC,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,MAAM,gBAAgB,GAAG,GAAG,EAAE;QAC5B,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;QACtB,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC;gBACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,UAAU,CAC1B,GAAG,EAAE;QACH,MAAM,GAAG,IAAI,CAAC;QACd,gBAAgB,EAAE,CAAC;IACrB,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,IAAI,CAC5B,CAAC;IAEF,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,MAAM,GAAG,IAAI,CAAC;QACd,gBAAgB,EAAE,CAAC;IACrB,CAAC,CAAC;IACF,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/D,MAAM,UAAU,GAAG,CAAC,MAAgB,EAAE,GAAW,EAAE,IAAmB,EAAE,EAAE;QACxE,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;QACrB,IAAI,IAAI,KAAK,KAAK;YAAE,OAAO,IAAI,CAAC,CAAC;;YAC5B,OAAO,IAAI,CAAC,CAAC;QAClB,MAAM,QAAQ,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;QAC5D,MAAM,SAAS,GAAG,YAAY,GAAG,QAAQ,CAAC;QAC1C,IAAI,SAAS,IAAI,CAAC;YAAE,OAAO;QAC3B,MAAM,IAAI,GAAG,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAC/D,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/B,IAAI,IAAI,KAAK,KAAK;YAAE,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC;;YAC1C,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC;IAClC,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACvC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;QAC5B,UAAU,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAChC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;QAC5B,UAAU,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAChC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,MAAM,EAAE,GAAW,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACvD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;YAC/C,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,CACJ,IAAI,KAAK,CACP,oCAAoC,GAAG,MAAM,GAAG,CAAC,OAAO,KAAK,GAAG,CAAC,IAAI,IAAI,SAAS,GAAG,CACtF,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,YAAY,CAAC,SAAS,CAAC,CAAC;IACxB,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAClD,QAAQ,EAAE,IAAI,EAAE,CAAC;IAEjB,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;SACvE,IAAI,CAAC,IAAI,CAAC;SACV,OAAO,EAAE,CAAC;IACb,MAAM,QAAQ,GAAG,mBAAmB,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;SACvE,IAAI,CAAC,IAAI,CAAC;SACV,OAAO,EAAE,CAAC;IACb,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAExD,IAAI,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC;IACxB,IAAI,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC;IACxB,MAAM,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC;IACrC,MAAM,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC;IAErC,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QAC9B,OAAO,GAAG,aAAa,CACrB,OAAO,GAAG,yBAAyB,OAAO,eAAe,EACzD,QAAQ,EACR,OAAO,CACR,CAAC,IAAI,CAAC;IACT,CAAC;IACD,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QAC9B,OAAO,GAAG,aAAa,CACrB,OAAO,GAAG,yBAAyB,OAAO,eAAe,EACzD,QAAQ,EACR,OAAO,CACR,CAAC,IAAI,CAAC;IACT,CAAC;IAED,IAAI,MAAM;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,iBAAiB,OAAO,YAAY,CAAC;IAE7F,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACpC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;YACb,OAAO;gBACL,sIAAsI,CAAC;QAC3I,CAAC;aAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO;gBACL,8MAA8M,CAAC;QACnN,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,6BAA6B,EAAE,mHAAmH,CAAC;QAC/J,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAe;QACzB,EAAE;QACF,GAAG,EAAE,OAAO;QACZ,GAAG,EAAE,OAAO;QACZ,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,MAAM;QAC/D,GAAG,CAAC,cAAc,IAAI,EAAE,QAAQ,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;KAC7D,CAAC;IAEF,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;QAChD,iBAAiB,CAAC,GAAG,CAAC,KAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { BASH_PATH } from '../utils.js';
|
|
2
|
+
import { stripAnsi, dedupeRepeats, collapseStackTraces, truncateBytes } from './text-utils.js';
|
|
3
|
+
export async function execWithPty(args) {
|
|
4
|
+
const { pty, command, cwd, timeout, maxBytes, captureLimit, signal, execCwdWarning } = args;
|
|
5
|
+
const proc = pty.spawn(BASH_PATH, ['-c', command], {
|
|
6
|
+
name: 'xterm-color',
|
|
7
|
+
cwd,
|
|
8
|
+
cols: 120,
|
|
9
|
+
rows: 30,
|
|
10
|
+
env: process.env,
|
|
11
|
+
});
|
|
12
|
+
const chunks = [];
|
|
13
|
+
let seen = 0;
|
|
14
|
+
let captured = 0;
|
|
15
|
+
let killed = false;
|
|
16
|
+
const onDataDisposable = proc.onData((data) => {
|
|
17
|
+
if (process.stdout.isTTY)
|
|
18
|
+
process.stdout.write(data);
|
|
19
|
+
const n = Buffer.byteLength(data, 'utf8');
|
|
20
|
+
seen += n;
|
|
21
|
+
const remaining = captureLimit - captured;
|
|
22
|
+
if (remaining <= 0)
|
|
23
|
+
return;
|
|
24
|
+
if (n <= remaining) {
|
|
25
|
+
chunks.push(data);
|
|
26
|
+
captured += n;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const buf = Buffer.from(data, 'utf8');
|
|
30
|
+
const slice = buf.subarray(0, remaining).toString('utf8');
|
|
31
|
+
chunks.push(slice);
|
|
32
|
+
captured += Buffer.byteLength(slice, 'utf8');
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
const kill = () => {
|
|
36
|
+
killed = true;
|
|
37
|
+
try {
|
|
38
|
+
proc.kill();
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// ignore
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const killTimer = setTimeout(kill, Math.max(1, timeout) * 1000);
|
|
45
|
+
const onAbort = () => kill();
|
|
46
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
47
|
+
const rc = await new Promise((resolve) => {
|
|
48
|
+
proc.onExit((e) => resolve(Number(e?.exitCode ?? 0)));
|
|
49
|
+
});
|
|
50
|
+
clearTimeout(killTimer);
|
|
51
|
+
signal?.removeEventListener('abort', onAbort);
|
|
52
|
+
onDataDisposable?.dispose?.();
|
|
53
|
+
const raw = stripAnsi(chunks.join(''));
|
|
54
|
+
const lines = collapseStackTraces(dedupeRepeats(raw.split(/\r?\n/)))
|
|
55
|
+
.join('\n')
|
|
56
|
+
.trimEnd();
|
|
57
|
+
const outT = truncateBytes(lines, maxBytes, seen);
|
|
58
|
+
let outText = outT.text;
|
|
59
|
+
const cap = seen > captured;
|
|
60
|
+
if (cap && !outT.truncated) {
|
|
61
|
+
outText = truncateBytes(outText + `\n[capture truncated, ${seen} bytes total]`, maxBytes, seen).text;
|
|
62
|
+
}
|
|
63
|
+
let errText = '';
|
|
64
|
+
if (killed) {
|
|
65
|
+
errText = `[killed after ${timeout}s timeout]`;
|
|
66
|
+
}
|
|
67
|
+
if (!outText && !errText && !killed) {
|
|
68
|
+
if (rc === 0) {
|
|
69
|
+
outText =
|
|
70
|
+
'[command completed successfully with no output. Do NOT retry — the command worked but produced no output. Move on to the next step.]';
|
|
71
|
+
}
|
|
72
|
+
else if (rc === 1) {
|
|
73
|
+
outText =
|
|
74
|
+
'[no matches found — the command returned zero results (exit code 1). Do NOT retry this command with the same arguments. The target simply has no matches. Move on or try different search terms/parameters.]';
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
outText = `[command exited with code ${rc} and produced no output. Do NOT retry with identical arguments — diagnose the issue or try a different approach.]`;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const result = {
|
|
81
|
+
rc,
|
|
82
|
+
out: outText,
|
|
83
|
+
err: errText,
|
|
84
|
+
truncated: outT.truncated || cap || killed,
|
|
85
|
+
...(execCwdWarning && { warnings: [execCwdWarning.trim()] }),
|
|
86
|
+
};
|
|
87
|
+
return JSON.stringify(result);
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=exec-pty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec-pty.js","sourceRoot":"","sources":["../../src/tools/exec-pty.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/** Best-effort quote stripping for lightweight shell pattern checks. */
|
|
2
|
+
export function stripSimpleQuotedSegments(s) {
|
|
3
|
+
return s
|
|
4
|
+
.replace(/"(?:[^"\\]|\\.)*"/g, '""')
|
|
5
|
+
.replace(/'(?:[^'\\]|\\.)*'/g, "''")
|
|
6
|
+
.replace(/`(?:[^`\\]|\\.)*`/g, '``');
|
|
7
|
+
}
|
|
8
|
+
/** Detect standalone '&' background token (not &&, >&2, <&, &>). */
|
|
9
|
+
export function hasBackgroundExecIntent(command) {
|
|
10
|
+
const stripped = stripSimpleQuotedSegments(command);
|
|
11
|
+
return /(^|[;\s])&(?![&><\d])(?=($|[;\s]))/.test(stripped);
|
|
12
|
+
}
|
|
13
|
+
/** Fire-and-forget helper that safely swallows async/sync errors. */
|
|
14
|
+
export function safeFireAndForget(fn) {
|
|
15
|
+
if (!fn)
|
|
16
|
+
return;
|
|
17
|
+
try {
|
|
18
|
+
const r = fn();
|
|
19
|
+
if (r && typeof r.catch === 'function')
|
|
20
|
+
r.catch(() => { });
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// best effort only
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Build throttled stdout/stderr streaming callbacks for exec tool output. */
|
|
27
|
+
export function makeExecStreamer(ctx) {
|
|
28
|
+
const cb = ctx.onToolStream;
|
|
29
|
+
if (!cb)
|
|
30
|
+
return null;
|
|
31
|
+
const id = ctx.toolCallId ?? '';
|
|
32
|
+
const name = ctx.toolName ?? 'exec';
|
|
33
|
+
const intervalMs = Math.max(50, Math.floor(ctx.toolStreamIntervalMs ?? 750));
|
|
34
|
+
const maxChunkChars = Math.max(80, Math.floor(ctx.toolStreamMaxChunkChars ?? 900));
|
|
35
|
+
const maxBufferChars = Math.max(maxChunkChars, Math.floor(ctx.toolStreamMaxBufferChars ?? 12_000));
|
|
36
|
+
let outBuf = '';
|
|
37
|
+
let errBuf = '';
|
|
38
|
+
let lastEmit = 0;
|
|
39
|
+
let timer = null;
|
|
40
|
+
const emit = (stream, chunk) => {
|
|
41
|
+
const trimmed = chunk.length > maxChunkChars ? chunk.slice(-maxChunkChars) : chunk;
|
|
42
|
+
const ev = { id, name, stream, chunk: trimmed };
|
|
43
|
+
safeFireAndForget(() => cb(ev));
|
|
44
|
+
};
|
|
45
|
+
const schedule = () => {
|
|
46
|
+
if (timer)
|
|
47
|
+
return;
|
|
48
|
+
const delay = Math.max(0, intervalMs - (Date.now() - lastEmit));
|
|
49
|
+
timer = setTimeout(() => {
|
|
50
|
+
timer = null;
|
|
51
|
+
flush(false);
|
|
52
|
+
}, delay);
|
|
53
|
+
};
|
|
54
|
+
const flush = (force = false) => {
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
if (!force && now - lastEmit < intervalMs) {
|
|
57
|
+
schedule();
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
lastEmit = now;
|
|
61
|
+
if (outBuf) {
|
|
62
|
+
emit('stdout', outBuf);
|
|
63
|
+
outBuf = '';
|
|
64
|
+
}
|
|
65
|
+
if (errBuf) {
|
|
66
|
+
emit('stderr', errBuf);
|
|
67
|
+
errBuf = '';
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const push = (stream, textRaw) => {
|
|
71
|
+
// Keep raw chunks here; caller can pre-process if needed.
|
|
72
|
+
const text = textRaw.replace(/\r/g, '\n');
|
|
73
|
+
if (!text)
|
|
74
|
+
return;
|
|
75
|
+
if (stream === 'stdout')
|
|
76
|
+
outBuf += text;
|
|
77
|
+
else
|
|
78
|
+
errBuf += text;
|
|
79
|
+
if (outBuf.length > maxBufferChars)
|
|
80
|
+
outBuf = outBuf.slice(-maxBufferChars);
|
|
81
|
+
if (errBuf.length > maxBufferChars)
|
|
82
|
+
errBuf = errBuf.slice(-maxBufferChars);
|
|
83
|
+
schedule();
|
|
84
|
+
};
|
|
85
|
+
const done = () => {
|
|
86
|
+
if (timer) {
|
|
87
|
+
clearTimeout(timer);
|
|
88
|
+
timer = null;
|
|
89
|
+
}
|
|
90
|
+
flush(true);
|
|
91
|
+
};
|
|
92
|
+
return { push, done };
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=exec-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec-utils.js","sourceRoot":"","sources":["../../src/tools/exec-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { shellEscape } from '../utils.js';
|
|
4
|
+
import { resolvePath, redactPath } from './path-safety.js';
|
|
5
|
+
import { globishMatch, hasRg } from './search-utils.js';
|
|
6
|
+
import { ToolError } from './tool-error.js';
|
|
7
|
+
export async function listDirTool(ctx, args) {
|
|
8
|
+
const p = resolvePath(ctx, args?.path ?? '.');
|
|
9
|
+
const recursive = Boolean(args?.recursive);
|
|
10
|
+
const maxEntries = Math.min(args?.max_entries ? Number(args.max_entries) : 200, 500);
|
|
11
|
+
if (!p)
|
|
12
|
+
throw new Error('list_dir: missing path');
|
|
13
|
+
const absCwd = path.resolve(ctx.cwd);
|
|
14
|
+
const lines = [];
|
|
15
|
+
let count = 0;
|
|
16
|
+
async function walk(dir, depth) {
|
|
17
|
+
if (count >= maxEntries)
|
|
18
|
+
return;
|
|
19
|
+
const ents = await fs.readdir(dir, { withFileTypes: true }).catch((e) => {
|
|
20
|
+
throw new Error(`list_dir: cannot read ${dir}: ${e?.message ?? String(e)}`);
|
|
21
|
+
});
|
|
22
|
+
for (const ent of ents) {
|
|
23
|
+
if (count >= maxEntries)
|
|
24
|
+
return;
|
|
25
|
+
const full = path.join(dir, ent.name);
|
|
26
|
+
const st = await fs.lstat(full).catch(() => null);
|
|
27
|
+
const kind = ent.isDirectory() ? 'dir' : ent.isSymbolicLink() ? 'link' : 'file';
|
|
28
|
+
lines.push(`${kind}\t${st?.size ?? 0}\t${redactPath(full, absCwd)}`);
|
|
29
|
+
count++;
|
|
30
|
+
if (recursive && ent.isDirectory() && depth < 3) {
|
|
31
|
+
await walk(full, depth + 1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
await walk(p, 0);
|
|
36
|
+
if (count >= maxEntries)
|
|
37
|
+
lines.push(`[truncated after ${maxEntries} entries]`);
|
|
38
|
+
if (!lines.length)
|
|
39
|
+
return `[empty directory: ${redactPath(p, absCwd)}]`;
|
|
40
|
+
return lines.join('\n');
|
|
41
|
+
}
|
|
42
|
+
export async function searchFilesTool(ctx, args, execFn) {
|
|
43
|
+
const root = resolvePath(ctx, args?.path ?? '.');
|
|
44
|
+
const pattern = typeof args?.pattern === 'string' ? args.pattern : undefined;
|
|
45
|
+
const include = typeof args?.include === 'string' ? args.include : undefined;
|
|
46
|
+
const maxResults = Math.min(args?.max_results ? Number(args.max_results) : 50, 100);
|
|
47
|
+
if (!root)
|
|
48
|
+
throw new Error('search_files: missing path');
|
|
49
|
+
if (!pattern)
|
|
50
|
+
throw new Error('search_files: missing pattern');
|
|
51
|
+
const absCwd = path.resolve(ctx.cwd);
|
|
52
|
+
if (await hasRg()) {
|
|
53
|
+
const cmd = ['rg', '-n', '--no-heading', '--color', 'never', pattern, root];
|
|
54
|
+
if (include)
|
|
55
|
+
cmd.splice(1, 0, '-g', include);
|
|
56
|
+
try {
|
|
57
|
+
const rawJson = await execFn(ctx, { command: cmd.map(shellEscape).join(' '), timeout: 30 });
|
|
58
|
+
const parsed = JSON.parse(rawJson);
|
|
59
|
+
if (parsed.rc === 1 && !parsed.out?.trim()) {
|
|
60
|
+
return `No matches for pattern \"${pattern}\" in ${root}. STOP — do NOT read files individually to search. Try a broader regex pattern, different keywords, or use exec: grep -rn \"keyword\" ${root}`;
|
|
61
|
+
}
|
|
62
|
+
if (parsed.rc < 2) {
|
|
63
|
+
const rgOutput = parsed.out ?? '';
|
|
64
|
+
if (rgOutput) {
|
|
65
|
+
const lines = rgOutput.split(/\r?\n/).filter(Boolean).slice(0, maxResults);
|
|
66
|
+
if (lines.length >= maxResults)
|
|
67
|
+
lines.push(`[truncated after ${maxResults} results]`);
|
|
68
|
+
const redactedLines = lines.map((line) => {
|
|
69
|
+
const colonIdx = line.indexOf(':');
|
|
70
|
+
if (colonIdx === -1)
|
|
71
|
+
return line;
|
|
72
|
+
const filePath = line.substring(0, colonIdx);
|
|
73
|
+
const rest = line.substring(colonIdx + 1);
|
|
74
|
+
return redactPath(filePath, absCwd) + ':' + rest;
|
|
75
|
+
});
|
|
76
|
+
return redactedLines.join('\n');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// fall through
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
let re;
|
|
85
|
+
try {
|
|
86
|
+
re = new RegExp(pattern);
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
throw new ToolError('invalid_args', `search_files: invalid regex pattern: ${e?.message ?? String(e)}`, false, 'Escape regex metacharacters (\\\\, [, ], (, ), +, *, ?). If you intended literal text, use an escaped/literal pattern.');
|
|
90
|
+
}
|
|
91
|
+
const out = [];
|
|
92
|
+
async function walk(dir, depth) {
|
|
93
|
+
if (out.length >= maxResults)
|
|
94
|
+
return;
|
|
95
|
+
const ents = await fs.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
96
|
+
for (const ent of ents) {
|
|
97
|
+
if (out.length >= maxResults)
|
|
98
|
+
return;
|
|
99
|
+
const full = path.join(dir, ent.name);
|
|
100
|
+
if (ent.isDirectory()) {
|
|
101
|
+
if (ent.name === 'node_modules' ||
|
|
102
|
+
ent.name === '.git' ||
|
|
103
|
+
ent.name === 'dist' ||
|
|
104
|
+
ent.name === 'build')
|
|
105
|
+
continue;
|
|
106
|
+
if (depth < 6)
|
|
107
|
+
await walk(full, depth + 1);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (!ent.isFile())
|
|
111
|
+
continue;
|
|
112
|
+
if (include && !globishMatch(ent.name, include))
|
|
113
|
+
continue;
|
|
114
|
+
const rawBuf = await fs.readFile(full).catch(() => null);
|
|
115
|
+
if (!rawBuf)
|
|
116
|
+
continue;
|
|
117
|
+
let isBinary = false;
|
|
118
|
+
for (let bi = 0; bi < Math.min(rawBuf.length, 512); bi++) {
|
|
119
|
+
if (rawBuf[bi] === 0) {
|
|
120
|
+
isBinary = true;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (isBinary)
|
|
125
|
+
continue;
|
|
126
|
+
const buf = rawBuf.toString('utf8');
|
|
127
|
+
const lines = buf.split(/\r?\n/);
|
|
128
|
+
for (let i = 0; i < lines.length; i++) {
|
|
129
|
+
if (re.test(lines[i])) {
|
|
130
|
+
out.push(`${redactPath(full, absCwd)}:${i + 1}:${lines[i]}`);
|
|
131
|
+
if (out.length >= maxResults)
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
await walk(root, 0);
|
|
138
|
+
if (out.length >= maxResults)
|
|
139
|
+
out.push(`[truncated after ${maxResults} results]`);
|
|
140
|
+
if (!out.length)
|
|
141
|
+
return `No matches for pattern \"${pattern}\" in ${redactPath(root, absCwd)}.`;
|
|
142
|
+
return out.join('\n');
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=file-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-discovery.js","sourceRoot":"","sources":["../../src/tools/file-discovery.ts"],"names":[],"mappings":"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"}
|