@gaunt-sloth/agent 2.0.0-alpha.2 → 2.0.0-alpha.4
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/README.md +9 -0
- package/dist/builtInToolsConfig.js +11 -2
- package/dist/builtInToolsConfig.js.map +1 -1
- package/dist/core/GthDeepAgent.d.ts +75 -0
- package/dist/core/GthDeepAgent.js +257 -21
- package/dist/core/GthDeepAgent.js.map +1 -1
- package/dist/core/deepAgentPermissions.d.ts +29 -11
- package/dist/core/deepAgentPermissions.js +67 -26
- package/dist/core/deepAgentPermissions.js.map +1 -1
- package/dist/mcp/OAuthClientProviderImpl.js +2 -2
- package/dist/mcp/OAuthClientProviderImpl.js.map +1 -1
- package/dist/middleware/registry.d.ts +1 -1
- package/dist/middleware/registry.js +1 -1
- package/dist/middleware/types.d.ts +1 -1
- package/dist/middleware/types.js +1 -1
- package/dist/modules/acpModule.d.ts +5 -2
- package/dist/modules/acpModule.js +5 -2
- package/dist/modules/acpModule.js.map +1 -1
- package/dist/modules/interactiveSessionModule.js +81 -4
- package/dist/modules/interactiveSessionModule.js.map +1 -1
- package/dist/tools/GthDevToolkit.d.ts +72 -1
- package/dist/tools/GthDevToolkit.js +230 -18
- package/dist/tools/GthDevToolkit.js.map +1 -1
- package/dist/tools/shell/allowlist.d.ts +11 -0
- package/dist/tools/shell/allowlist.js +12 -0
- package/dist/tools/shell/allowlist.js.map +1 -0
- package/dist/tools/shell/arity.d.ts +11 -0
- package/dist/tools/shell/arity.js +12 -0
- package/dist/tools/shell/arity.js.map +1 -0
- package/dist/tools/shell/env.d.ts +22 -0
- package/dist/tools/shell/env.js +110 -0
- package/dist/tools/shell/env.js.map +1 -0
- package/dist/tools/shell/hardline.d.ts +15 -0
- package/dist/tools/shell/hardline.js +88 -0
- package/dist/tools/shell/hardline.js.map +1 -0
- package/dist/tools/shell/normalize.d.ts +10 -0
- package/dist/tools/shell/normalize.js +11 -0
- package/dist/tools/shell/normalize.js.map +1 -0
- package/dist/tools/shell/outputBuffer.d.ts +53 -0
- package/dist/tools/shell/outputBuffer.js +157 -0
- package/dist/tools/shell/outputBuffer.js.map +1 -0
- package/package.json +8 -8
|
@@ -3,10 +3,109 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { BaseToolkit, tool } from '@langchain/core/tools';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
import { spawn } from 'child_process';
|
|
6
|
+
import { spawn, spawnSync } from 'child_process';
|
|
7
7
|
import path from 'node:path';
|
|
8
|
-
import { displayInfo, displayError } from '@gaunt-sloth/core/utils/consoleUtils.js';
|
|
9
|
-
import {
|
|
8
|
+
import { displayInfo, displayError, displayWarning } from '@gaunt-sloth/core/utils/consoleUtils.js';
|
|
9
|
+
import { getShellMaxOutputBytes, getShellTimeoutMs, isShellToolEnabled, } from '@gaunt-sloth/core/config.js';
|
|
10
|
+
import { stdout, getCurrentWorkDir } from '@gaunt-sloth/core/utils/systemUtils.js';
|
|
11
|
+
import { checkHardline } from '#src/tools/shell/hardline.js';
|
|
12
|
+
import { buildScrubbedEnv } from '#src/tools/shell/env.js';
|
|
13
|
+
import { OutputBuffer } from '#src/tools/shell/outputBuffer.js';
|
|
14
|
+
// Grace period (ms) between SIGTERM and the escalation to SIGKILL when a command
|
|
15
|
+
// exceeds its timeout. Mirrors opencode's `forceKillAfter` (3s).
|
|
16
|
+
const KILL_GRACE_MS = 3_000;
|
|
17
|
+
/**
|
|
18
|
+
* EXT-20: a run_* command that did NOT exit cleanly (non-zero exit code, or was killed for
|
|
19
|
+
* exceeding the timeout). Carries the FULL model-facing body text ({@link output}) so the
|
|
20
|
+
* softening middleware ({@link GthDeepShellExitSoftening}) can hand the model the exact same
|
|
21
|
+
* observation it saw before — the only change is the tool result's status flips to `'error'`,
|
|
22
|
+
* which drives the ✗ (`isError`) glyph.
|
|
23
|
+
*
|
|
24
|
+
* `executeCommand` previously `resolve()`d on a non-zero exit, so the LangChain `ToolMessage`
|
|
25
|
+
* stayed `status: 'success'` and every failure rendered a ✓. Throwing this typed error instead
|
|
26
|
+
* lets the deep-agent middleware convert it into an error `ToolMessage`. A clean exit (`code === 0`)
|
|
27
|
+
* still `resolve()`s; a spawn-level `child.on('error')` still rejects with a plain `Error`.
|
|
28
|
+
*/
|
|
29
|
+
export class ShellCommandFailedError extends Error {
|
|
30
|
+
/** The full model-facing body (command echo + `<COMMAND_OUTPUT>` + the failure/timeout tail). */
|
|
31
|
+
output;
|
|
32
|
+
/** The process exit code; `null` when the command was killed (timeout) and never exited cleanly. */
|
|
33
|
+
exitCode;
|
|
34
|
+
/** The exact command string that was executed. */
|
|
35
|
+
command;
|
|
36
|
+
/** The run_* tool name that invoked the command (e.g. `run_tests`, `run_shell_command`). */
|
|
37
|
+
toolName;
|
|
38
|
+
constructor(params) {
|
|
39
|
+
// Use the full body as the Error message so any generic logger/handler still surfaces the
|
|
40
|
+
// real command output rather than an opaque wrapper string.
|
|
41
|
+
super(params.output);
|
|
42
|
+
this.name = 'ShellCommandFailedError';
|
|
43
|
+
this.output = params.output;
|
|
44
|
+
this.exitCode = params.exitCode;
|
|
45
|
+
this.command = params.command;
|
|
46
|
+
this.toolName = params.toolName;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Kill the child AND its descendants on timeout.
|
|
51
|
+
*
|
|
52
|
+
* POSIX: the child is spawned `detached`, so it leads its own process group;
|
|
53
|
+
* signalling the NEGATIVE pid (`-pid`) delivers to the whole group — otherwise a
|
|
54
|
+
* shell's children (e.g. a spawned server) would be orphaned and keep running.
|
|
55
|
+
*
|
|
56
|
+
* Windows (EXT-15): there are no POSIX process groups — `process.kill(-pid)`
|
|
57
|
+
* throws `EINVAL`, and `child.kill()` only terminates the `cmd.exe` wrapper while
|
|
58
|
+
* grandchildren keep the piped stdio handles open, so `'close'` never fires and
|
|
59
|
+
* the tool Promise hangs forever (silently cancelling Windows CI). Use `taskkill
|
|
60
|
+
* /T` to kill the whole tree by pid; `/F` (force) mirrors POSIX SIGKILL, while a
|
|
61
|
+
* graceful taskkill mirrors SIGTERM. Swallows the races where it has already exited.
|
|
62
|
+
*
|
|
63
|
+
* Exported for unit testing the platform branch without a Windows host.
|
|
64
|
+
*/
|
|
65
|
+
export function killProcessGroup(child, signal) {
|
|
66
|
+
if (typeof child.pid !== 'number')
|
|
67
|
+
return;
|
|
68
|
+
if (process.platform === 'win32') {
|
|
69
|
+
// No process groups on Windows; taskkill /T walks the whole tree by pid.
|
|
70
|
+
const args = ['/PID', String(child.pid), '/T'];
|
|
71
|
+
if (signal === 'SIGKILL')
|
|
72
|
+
args.push('/F');
|
|
73
|
+
// IMPORTANT: spawnSync does NOT throw when it fails to spawn (e.g. ENOENT if taskkill is
|
|
74
|
+
// missing from PATH) — unlike execSync, it returns an object with an `error` property. So a
|
|
75
|
+
// try/catch would never reach the fallback. Inspect `res.error` explicitly and fall back to
|
|
76
|
+
// the direct child kill (best effort). A non-zero exit (process already gone) is NOT a spawn
|
|
77
|
+
// failure, so it correctly does not trigger the fallback. (`res?.` tolerates test mocks.)
|
|
78
|
+
const res = spawnSync('taskkill', args, { stdio: 'ignore', windowsHide: true });
|
|
79
|
+
if (res?.error) {
|
|
80
|
+
try {
|
|
81
|
+
child.kill(signal);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Already exited — nothing to do.
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
// Negative pid → signal the entire process group.
|
|
91
|
+
process.kill(-child.pid, signal);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
const code = e?.code;
|
|
96
|
+
// ESRCH: already gone. EPERM: group-kill not permitted — fall through to the
|
|
97
|
+
// direct child kill below. Anything else: also fall back rather than throw.
|
|
98
|
+
if (code === 'ESRCH')
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
// Fallback: kill just the child (best effort).
|
|
102
|
+
try {
|
|
103
|
+
child.kill(signal);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Already exited — nothing to do.
|
|
107
|
+
}
|
|
108
|
+
}
|
|
10
109
|
// Helper function to create a tool with dev type
|
|
11
110
|
function createGthTool(fn, config, gthDevType) {
|
|
12
111
|
const toolInstance = tool(fn, config);
|
|
@@ -21,13 +120,23 @@ const RunBuildArgsSchema = z.object({});
|
|
|
21
120
|
const RunSingleTestArgsSchema = z.object({
|
|
22
121
|
testPath: z.string().describe('Relative path to the test file to run'),
|
|
23
122
|
});
|
|
123
|
+
const RunShellCommandArgsSchema = z.object({
|
|
124
|
+
command: z.string().describe('The shell command to run'),
|
|
125
|
+
});
|
|
24
126
|
const TEST_PATH_PLACEHOLDER = '${testPath}';
|
|
25
127
|
export default class GthDevToolkit extends BaseToolkit {
|
|
26
128
|
tools;
|
|
27
129
|
commands;
|
|
28
|
-
|
|
130
|
+
/**
|
|
131
|
+
* The active command, threaded through so the EXT-12 absent-config default for the shell
|
|
132
|
+
* tool (ON in `code`, OFF elsewhere) is resolved consistently with the deep agent's
|
|
133
|
+
* interrupt wiring. Omitted → historical OFF-by-default behaviour.
|
|
134
|
+
*/
|
|
135
|
+
command;
|
|
136
|
+
constructor(commands = {}, command) {
|
|
29
137
|
super();
|
|
30
138
|
this.commands = commands;
|
|
139
|
+
this.command = command;
|
|
31
140
|
this.tools = this.createTools();
|
|
32
141
|
}
|
|
33
142
|
/**
|
|
@@ -93,45 +202,132 @@ export default class GthDevToolkit extends BaseToolkit {
|
|
|
93
202
|
throw new Error('No test command configured');
|
|
94
203
|
}
|
|
95
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* Execute a shell command with the EXT-9 Tier-1 hardening applied:
|
|
207
|
+
* 1. stdin closed + timeout + process-group kill (no hang on interactive
|
|
208
|
+
* commands; runaway commands are killed group-wide on timeout),
|
|
209
|
+
* 2. output capped with a head/tail window + temp-file spillover,
|
|
210
|
+
* 3. provider/LLM credentials scrubbed from the child env,
|
|
211
|
+
* 4. an unbypassable hardline blocklist (refuses catastrophic commands BEFORE
|
|
212
|
+
* spawn — fires even when confirmation is bypassed by yolo).
|
|
213
|
+
*
|
|
214
|
+
* Resolves with a model-facing string on a CLEAN exit (`code === 0`). EXT-20: a non-zero exit
|
|
215
|
+
* and a timeout-kill instead REJECT with a {@link ShellCommandFailedError} that carries the FULL
|
|
216
|
+
* model-facing body — the deep-agent {@link GthDeepShellExitSoftening} middleware converts that
|
|
217
|
+
* throw into an error `ToolMessage` (status:'error' → ✗) while preserving the output, so the
|
|
218
|
+
* model still sees the killed-after-N / exit-code message and can continue. Spawn-level failures
|
|
219
|
+
* (`child.on('error')`) still reject with a plain `Error`.
|
|
220
|
+
*/
|
|
96
221
|
async executeCommand(command, toolName) {
|
|
97
222
|
displayInfo(`\n🔧 Executing ${toolName}: ${command}`);
|
|
223
|
+
// (4) Hardline blocklist — checked here so it fires regardless of yolo,
|
|
224
|
+
// allow-lists, or any confirmation path. Refuse WITHOUT executing.
|
|
225
|
+
const hardline = checkHardline(command);
|
|
226
|
+
if (hardline) {
|
|
227
|
+
const refusal = `Refusing to execute '${command}': blocked by hardline safety policy ` +
|
|
228
|
+
`(${hardline.description}). This is a catastrophic, non-recoverable command ` +
|
|
229
|
+
`and is blocked even when command confirmation is disabled.`;
|
|
230
|
+
displayWarning(`\n⛔ ${refusal}`);
|
|
231
|
+
return refusal;
|
|
232
|
+
}
|
|
233
|
+
const timeoutMs = getShellTimeoutMs(this.commands);
|
|
234
|
+
const maxOutputBytes = getShellMaxOutputBytes(this.commands);
|
|
98
235
|
return new Promise((resolve, reject) => {
|
|
99
236
|
const child = spawn(command, {
|
|
100
237
|
shell: true,
|
|
238
|
+
// EXT-22 (S4): spawn in the SAME directory the deepagents FilesystemBackend is rooted at,
|
|
239
|
+
// so the shell tool and the fs tools (ls/read_file/write_file/edit_file/glob/grep) operate
|
|
240
|
+
// on one path namespace instead of diverging. That backend is constructed with
|
|
241
|
+
// `rootDir: getCurrentWorkDir()` (GthDeepAgent.ts init), so getCurrentWorkDir() IS the
|
|
242
|
+
// fs-backend root on the local code/chat runner. getCurrentWorkDir() =
|
|
243
|
+
// `process.env.INIT_CWD ?? process.cwd()` (core systemUtils); it only diverges from bare
|
|
244
|
+
// process.cwd() when INIT_CWD is set (npm-bin / IDE-spawned launches) — exactly the
|
|
245
|
+
// POSIX-latent divergence S4 closes. Evaluated at call time.
|
|
246
|
+
cwd: getCurrentWorkDir(),
|
|
247
|
+
// (1) Never let the child block on stdin (e.g. git commit opening $EDITOR).
|
|
248
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
249
|
+
// (1) POSIX: own process group so we can kill the whole tree on timeout
|
|
250
|
+
// (see killProcessGroup). No-op/harmful on Windows, which uses taskkill /T.
|
|
251
|
+
detached: process.platform !== 'win32',
|
|
252
|
+
// (3) Child env with provider/LLM credentials removed.
|
|
253
|
+
env: buildScrubbedEnv(),
|
|
101
254
|
});
|
|
102
|
-
|
|
103
|
-
|
|
255
|
+
// (2) Bounded capture for the returned message; live streaming is uncapped.
|
|
256
|
+
const buffer = new OutputBuffer(maxOutputBytes);
|
|
257
|
+
let timedOut = false;
|
|
258
|
+
let settled = false;
|
|
259
|
+
let killTimer;
|
|
260
|
+
const timeoutTimer = setTimeout(() => {
|
|
261
|
+
timedOut = true;
|
|
262
|
+
killProcessGroup(child, 'SIGTERM');
|
|
263
|
+
// Escalate to SIGKILL after a short grace if it didn't die.
|
|
264
|
+
killTimer = setTimeout(() => killProcessGroup(child, 'SIGKILL'), KILL_GRACE_MS);
|
|
265
|
+
// killTimer must not keep the event loop alive on its own.
|
|
266
|
+
killTimer.unref?.();
|
|
267
|
+
}, timeoutMs);
|
|
268
|
+
timeoutTimer.unref?.();
|
|
269
|
+
const clearTimers = () => {
|
|
270
|
+
clearTimeout(timeoutTimer);
|
|
271
|
+
if (killTimer)
|
|
272
|
+
clearTimeout(killTimer);
|
|
273
|
+
};
|
|
104
274
|
if (child.stdout) {
|
|
105
275
|
child.stdout.on('data', (data) => {
|
|
106
276
|
const chunk = data.toString();
|
|
107
277
|
stdout.write(chunk);
|
|
108
|
-
|
|
278
|
+
buffer.append(chunk);
|
|
109
279
|
});
|
|
110
280
|
}
|
|
111
281
|
if (child.stderr) {
|
|
112
282
|
child.stderr.on('data', (data) => {
|
|
113
283
|
const chunk = data.toString();
|
|
114
284
|
stdout.write(chunk);
|
|
115
|
-
|
|
285
|
+
buffer.append(chunk);
|
|
116
286
|
});
|
|
117
287
|
}
|
|
118
288
|
child.on('close', (code) => {
|
|
289
|
+
if (settled)
|
|
290
|
+
return;
|
|
291
|
+
settled = true;
|
|
292
|
+
clearTimers();
|
|
293
|
+
const captured = buffer.finalize();
|
|
294
|
+
const body = `Executing '${command}'...\n\n` +
|
|
295
|
+
`<COMMAND_OUTPUT>\n` +
|
|
296
|
+
captured.text +
|
|
297
|
+
`</COMMAND_OUTPUT>\n`;
|
|
298
|
+
if (timedOut) {
|
|
299
|
+
// EXT-20: a timeout-kill is a failure — reject so the deep-agent middleware flips the
|
|
300
|
+
// tool result to status:'error' (✗). The FULL body is preserved on the error so the
|
|
301
|
+
// model's observation is unchanged except for the status.
|
|
302
|
+
reject(new ShellCommandFailedError({
|
|
303
|
+
output: body +
|
|
304
|
+
`\n\nCommand '${command}' was killed after exceeding the ${Math.round(timeoutMs / 1000)}s timeout. ` +
|
|
305
|
+
`If it legitimately needs longer, increase the shell timeout in config.`,
|
|
306
|
+
exitCode: null,
|
|
307
|
+
command,
|
|
308
|
+
toolName,
|
|
309
|
+
}));
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
119
312
|
if (code === 0) {
|
|
120
|
-
resolve(
|
|
121
|
-
`<COMMAND_OUTPUT>\n` +
|
|
122
|
-
output +
|
|
123
|
-
`</COMMAND_OUTPUT>\n` +
|
|
124
|
-
`\n\nCommand '${command}' completed successfully`);
|
|
313
|
+
resolve(body + `\n\nCommand '${command}' completed successfully`);
|
|
125
314
|
}
|
|
126
315
|
else {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
316
|
+
// EXT-20: a non-zero exit is a failure — reject (was resolve) so the softening
|
|
317
|
+
// middleware surfaces the ✗ (isError) signal while preserving the full output body.
|
|
318
|
+
reject(new ShellCommandFailedError({
|
|
319
|
+
output: body + `\n\nCommand '${command}' exited with code ${code}`,
|
|
320
|
+
exitCode: code,
|
|
321
|
+
command,
|
|
322
|
+
toolName,
|
|
323
|
+
}));
|
|
132
324
|
}
|
|
133
325
|
});
|
|
134
326
|
child.on('error', (error) => {
|
|
327
|
+
if (settled)
|
|
328
|
+
return;
|
|
329
|
+
settled = true;
|
|
330
|
+
clearTimers();
|
|
135
331
|
const errorMsg = `Failed to execute command '${command}': ${error.message}`;
|
|
136
332
|
displayError(errorMsg);
|
|
137
333
|
reject(new Error(errorMsg));
|
|
@@ -183,6 +379,22 @@ export default class GthDevToolkit extends BaseToolkit {
|
|
|
183
379
|
schema: RunBuildArgsSchema,
|
|
184
380
|
}, 'execute'));
|
|
185
381
|
}
|
|
382
|
+
// Opt-in general-purpose shell tool. Unlike the fixed run_* commands, the model supplies
|
|
383
|
+
// the command, so the guardrail is the per-command confirmation dialog wired by the deep
|
|
384
|
+
// agent (createDeepAgent `interruptOn`), not a parameter sanitizer — a real shell command
|
|
385
|
+
// legitimately contains pipes / `$` / `;`, so validateParameterValue must NOT be applied.
|
|
386
|
+
if (isShellToolEnabled(this.commands, this.command)) {
|
|
387
|
+
tools.push(createGthTool(async (args) => {
|
|
388
|
+
return await this.executeCommand(args.command, 'run_shell_command');
|
|
389
|
+
}, {
|
|
390
|
+
name: 'run_shell_command',
|
|
391
|
+
description: 'Run an arbitrary shell command in the project working directory and return its ' +
|
|
392
|
+
'combined stdout/stderr and exit status. Use for any task the fixed run_* tools do ' +
|
|
393
|
+
'not cover (e.g. git, package managers, file inspection). Each call is subject to ' +
|
|
394
|
+
'human approval before it runs unless approval has been disabled.',
|
|
395
|
+
schema: RunShellCommandArgsSchema,
|
|
396
|
+
}, 'execute'));
|
|
397
|
+
}
|
|
186
398
|
return tools;
|
|
187
399
|
}
|
|
188
400
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GthDevToolkit.js","sourceRoot":"","sources":["../../src/tools/GthDevToolkit.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GthDevToolkit.js","sourceRoot":"","sources":["../../src/tools/GthDevToolkit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module tools/shell/allowlist
|
|
3
|
+
*
|
|
4
|
+
* Re-export of the EXT-9 Tier-2 allow-list engine. The implementation lives in
|
|
5
|
+
* `@gaunt-sloth/core` (`core/shell/allowlist`) because the core {@link GthAgentRunner}
|
|
6
|
+
* owns the per-instance session store and the loaded persisted store and consults
|
|
7
|
+
* `matchesApproval` before prompting (core cannot import from `@gaunt-sloth/agent`).
|
|
8
|
+
*
|
|
9
|
+
* See the core module for the exact safe-bin / anti-widening matching rule.
|
|
10
|
+
*/
|
|
11
|
+
export { matchesApproval, hasWideningFlag, AllowlistStore, PersistedAllowlist, type ApprovalScope, type ApprovalStores, } from '@gaunt-sloth/core/core/shell/allowlist.js';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module tools/shell/allowlist
|
|
3
|
+
*
|
|
4
|
+
* Re-export of the EXT-9 Tier-2 allow-list engine. The implementation lives in
|
|
5
|
+
* `@gaunt-sloth/core` (`core/shell/allowlist`) because the core {@link GthAgentRunner}
|
|
6
|
+
* owns the per-instance session store and the loaded persisted store and consults
|
|
7
|
+
* `matchesApproval` before prompting (core cannot import from `@gaunt-sloth/agent`).
|
|
8
|
+
*
|
|
9
|
+
* See the core module for the exact safe-bin / anti-widening matching rule.
|
|
10
|
+
*/
|
|
11
|
+
export { matchesApproval, hasWideningFlag, AllowlistStore, PersistedAllowlist, } from '@gaunt-sloth/core/core/shell/allowlist.js';
|
|
12
|
+
//# sourceMappingURL=allowlist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allowlist.js","sourceRoot":"","sources":["../../../src/tools/shell/allowlist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,eAAe,EACf,eAAe,EACf,cAAc,EACd,kBAAkB,GAGnB,MAAM,2CAA2C,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module tools/shell/arity
|
|
3
|
+
*
|
|
4
|
+
* Re-export of the EXT-9 Tier-2 command classifier. The implementation lives in
|
|
5
|
+
* `@gaunt-sloth/core` (`core/shell/arity`) because the core {@link GthAgentRunner}
|
|
6
|
+
* must consult it BEFORE prompting (and core cannot import from `@gaunt-sloth/agent`).
|
|
7
|
+
* This stable agent-side path is kept for tests and any agent-layer consumers.
|
|
8
|
+
*
|
|
9
|
+
* See the core module for the arity table scope and the anti-injection fail-closed rule.
|
|
10
|
+
*/
|
|
11
|
+
export { classifyCommand, tokenize, meaningfulPrefixTokens, type CommandClassification, } from '@gaunt-sloth/core/core/shell/arity.js';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module tools/shell/arity
|
|
3
|
+
*
|
|
4
|
+
* Re-export of the EXT-9 Tier-2 command classifier. The implementation lives in
|
|
5
|
+
* `@gaunt-sloth/core` (`core/shell/arity`) because the core {@link GthAgentRunner}
|
|
6
|
+
* must consult it BEFORE prompting (and core cannot import from `@gaunt-sloth/agent`).
|
|
7
|
+
* This stable agent-side path is kept for tests and any agent-layer consumers.
|
|
8
|
+
*
|
|
9
|
+
* See the core module for the arity table scope and the anti-injection fail-closed rule.
|
|
10
|
+
*/
|
|
11
|
+
export { classifyCommand, tokenize, meaningfulPrefixTokens, } from '@gaunt-sloth/core/core/shell/arity.js';
|
|
12
|
+
//# sourceMappingURL=arity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arity.js","sourceRoot":"","sources":["../../../src/tools/shell/arity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,eAAe,EACf,QAAQ,EACR,sBAAsB,GAEvB,MAAM,uCAAuC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Explicit blocklist of LLM-provider and cloud credentials. Covers the providers
|
|
3
|
+
* gaunt-sloth (and its consumers) can be configured against, plus the standard
|
|
4
|
+
* cloud secret-bearing vars. Matched case-insensitively.
|
|
5
|
+
*/
|
|
6
|
+
export declare const CREDENTIAL_BLOCKLIST: ReadonlyArray<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Allow-list of credential-shaped names that must survive the wildcard sweep
|
|
9
|
+
* because gaunt-sloth legitimately depends on them. Matched case-insensitively.
|
|
10
|
+
*/
|
|
11
|
+
export declare const CREDENTIAL_ALLOWLIST: ReadonlyArray<string>;
|
|
12
|
+
/**
|
|
13
|
+
* True when an env var name should be scrubbed from the child environment.
|
|
14
|
+
* Exported for testing.
|
|
15
|
+
*/
|
|
16
|
+
export declare function shouldScrubEnvVar(name: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Build the child environment for a spawned shell command: a copy of the parent
|
|
19
|
+
* env with LLM/cloud credentials removed. Defaults to the live `process.env`
|
|
20
|
+
* (via systemUtils); a source can be injected for testing.
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildScrubbedEnv(source?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module tools/shell/env
|
|
3
|
+
*
|
|
4
|
+
* Credential scrubbing for the shell tool's child environment. By default a
|
|
5
|
+
* spawned child inherits `process.env` verbatim, so an approved (or yolo'd)
|
|
6
|
+
* command can `echo $ANTHROPIC_API_KEY` and exfiltrate the operator's LLM/cloud
|
|
7
|
+
* credentials. {@link buildScrubbedEnv} returns a copy of the parent env with
|
|
8
|
+
* those credentials removed before spawn.
|
|
9
|
+
*
|
|
10
|
+
* Policy (deliberately scoped):
|
|
11
|
+
* - Strip LLM provider keys and cloud-provider secrets (the explicit blocklist +
|
|
12
|
+
* a wildcard sweep for `*_API_KEY` / `*_TOKEN` / `*_SECRET` / `*SECRET_KEY`).
|
|
13
|
+
* - LEAVE generic dev env intact (PATH, HOME, SHELL, LANG, npm/pnpm config, …)
|
|
14
|
+
* so normal commands still work.
|
|
15
|
+
* - LEAVE `GITHUB_TOKEN` / `GH_TOKEN` intact: gaunt-sloth's content/requirement
|
|
16
|
+
* providers shell out to `gh` (`gh pr diff`, `gh issue view`), so stripping
|
|
17
|
+
* these would break first-class workflows. They are explicitly allow-listed
|
|
18
|
+
* against the wildcard `*_TOKEN` sweep.
|
|
19
|
+
*
|
|
20
|
+
* Patterned after hermes-agent `_HERMES_PROVIDER_ENV_BLOCKLIST` (tools/environments/local.py)
|
|
21
|
+
* — but narrower: we only own the provider/cloud-secret floor.
|
|
22
|
+
*/
|
|
23
|
+
import { env as processEnv } from '@gaunt-sloth/core/utils/systemUtils.js';
|
|
24
|
+
/**
|
|
25
|
+
* Explicit blocklist of LLM-provider and cloud credentials. Covers the providers
|
|
26
|
+
* gaunt-sloth (and its consumers) can be configured against, plus the standard
|
|
27
|
+
* cloud secret-bearing vars. Matched case-insensitively.
|
|
28
|
+
*/
|
|
29
|
+
export const CREDENTIAL_BLOCKLIST = [
|
|
30
|
+
// LLM providers
|
|
31
|
+
'ANTHROPIC_API_KEY',
|
|
32
|
+
'ANTHROPIC_AUTH_TOKEN',
|
|
33
|
+
'CLAUDE_CODE_OAUTH_TOKEN',
|
|
34
|
+
'OPENAI_API_KEY',
|
|
35
|
+
'GOOGLE_API_KEY',
|
|
36
|
+
'GEMINI_API_KEY',
|
|
37
|
+
'GOOGLE_APPLICATION_CREDENTIALS',
|
|
38
|
+
'GROQ_API_KEY',
|
|
39
|
+
'XAI_API_KEY',
|
|
40
|
+
'DEEPSEEK_API_KEY',
|
|
41
|
+
'MISTRAL_API_KEY',
|
|
42
|
+
'OPENROUTER_API_KEY',
|
|
43
|
+
'COHERE_API_KEY',
|
|
44
|
+
'TOGETHER_API_KEY',
|
|
45
|
+
'PERPLEXITY_API_KEY',
|
|
46
|
+
'FIREWORKS_API_KEY',
|
|
47
|
+
// Azure OpenAI
|
|
48
|
+
'AZURE_OPENAI_API_KEY',
|
|
49
|
+
'AZURE_API_KEY',
|
|
50
|
+
// Cloud provider secrets (AWS / GCP)
|
|
51
|
+
'AWS_SECRET_ACCESS_KEY',
|
|
52
|
+
'AWS_SESSION_TOKEN',
|
|
53
|
+
'AWS_ACCESS_KEY_ID',
|
|
54
|
+
];
|
|
55
|
+
/**
|
|
56
|
+
* Allow-list of credential-shaped names that must survive the wildcard sweep
|
|
57
|
+
* because gaunt-sloth legitimately depends on them. Matched case-insensitively.
|
|
58
|
+
*/
|
|
59
|
+
export const CREDENTIAL_ALLOWLIST = [
|
|
60
|
+
// `gh` CLI auth — used by the github content/requirement providers.
|
|
61
|
+
'GITHUB_TOKEN',
|
|
62
|
+
'GH_TOKEN',
|
|
63
|
+
];
|
|
64
|
+
// Wildcard sweep: any var whose name ends in one of these suffixes is treated as
|
|
65
|
+
// a secret and stripped (unless allow-listed). Catches provider keys we didn't
|
|
66
|
+
// enumerate (e.g. a new `FOO_API_KEY`).
|
|
67
|
+
const SECRET_SUFFIXES = [
|
|
68
|
+
/_API_KEY$/i,
|
|
69
|
+
/_SECRET_ACCESS_KEY$/i,
|
|
70
|
+
/_SECRET_KEY$/i,
|
|
71
|
+
/_SECRET$/i,
|
|
72
|
+
/_TOKEN$/i,
|
|
73
|
+
];
|
|
74
|
+
function isAllowlisted(name) {
|
|
75
|
+
return CREDENTIAL_ALLOWLIST.some((a) => a.toUpperCase() === name.toUpperCase());
|
|
76
|
+
}
|
|
77
|
+
function isBlocklisted(name) {
|
|
78
|
+
return CREDENTIAL_BLOCKLIST.some((b) => b.toUpperCase() === name.toUpperCase());
|
|
79
|
+
}
|
|
80
|
+
function matchesSecretSuffix(name) {
|
|
81
|
+
return SECRET_SUFFIXES.some((re) => re.test(name));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* True when an env var name should be scrubbed from the child environment.
|
|
85
|
+
* Exported for testing.
|
|
86
|
+
*/
|
|
87
|
+
export function shouldScrubEnvVar(name) {
|
|
88
|
+
if (isAllowlisted(name))
|
|
89
|
+
return false;
|
|
90
|
+
if (isBlocklisted(name))
|
|
91
|
+
return true;
|
|
92
|
+
return matchesSecretSuffix(name);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Build the child environment for a spawned shell command: a copy of the parent
|
|
96
|
+
* env with LLM/cloud credentials removed. Defaults to the live `process.env`
|
|
97
|
+
* (via systemUtils); a source can be injected for testing.
|
|
98
|
+
*/
|
|
99
|
+
export function buildScrubbedEnv(source = processEnv) {
|
|
100
|
+
const scrubbed = {};
|
|
101
|
+
for (const [key, value] of Object.entries(source)) {
|
|
102
|
+
if (value === undefined)
|
|
103
|
+
continue;
|
|
104
|
+
if (shouldScrubEnvVar(key))
|
|
105
|
+
continue;
|
|
106
|
+
scrubbed[key] = value;
|
|
107
|
+
}
|
|
108
|
+
return scrubbed;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/tools/shell/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,GAAG,IAAI,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAE3E;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA0B;IACzD,gBAAgB;IAChB,mBAAmB;IACnB,sBAAsB;IACtB,yBAAyB;IACzB,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,gCAAgC;IAChC,cAAc;IACd,aAAa;IACb,kBAAkB;IAClB,iBAAiB;IACjB,oBAAoB;IACpB,gBAAgB;IAChB,kBAAkB;IAClB,oBAAoB;IACpB,mBAAmB;IACnB,eAAe;IACf,sBAAsB;IACtB,eAAe;IACf,qCAAqC;IACrC,uBAAuB;IACvB,mBAAmB;IACnB,mBAAmB;CACpB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA0B;IACzD,oEAAoE;IACpE,cAAc;IACd,UAAU;CACX,CAAC;AAEF,iFAAiF;AACjF,+EAA+E;AAC/E,wCAAwC;AACxC,MAAM,eAAe,GAAG;IACtB,YAAY;IACZ,sBAAsB;IACtB,eAAe;IACf,WAAW;IACX,UAAU;CACX,CAAC;AAEF,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY;IACvC,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,aAAa,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,aAAa,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAA4B,UAAU;IACrE,MAAM,QAAQ,GAAsB,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,IAAI,iBAAiB,CAAC,GAAG,CAAC;YAAE,SAAS;QACrC,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACxB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hardline patterns: [regex, human description]. Matched case-insensitively
|
|
3
|
+
* against the normalized command.
|
|
4
|
+
*/
|
|
5
|
+
export declare const HARDLINE_PATTERNS: ReadonlyArray<readonly [RegExp, string]>;
|
|
6
|
+
export interface HardlineMatch {
|
|
7
|
+
/** Human-readable reason the command was refused. */
|
|
8
|
+
description: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Check a raw command against the hardline blocklist. Normalizes first so
|
|
12
|
+
* obfuscated variants are caught. Returns the match (with a description) when the
|
|
13
|
+
* command is catastrophic, or `null` when it is allowed to proceed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function checkHardline(command: string): HardlineMatch | null;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module tools/shell/hardline
|
|
3
|
+
*
|
|
4
|
+
* Unbypassable hardline blocklist for the shell tool. These are catastrophic,
|
|
5
|
+
* non-recoverable commands (wipe the root filesystem, format a disk, overwrite a
|
|
6
|
+
* raw block device, fork-bomb, take the host down). They are refused inside
|
|
7
|
+
* `executeCommand` itself — BEFORE spawn — so the refusal fires regardless of
|
|
8
|
+
* yolo (`shellYolo`), any allow-list, or the confirmation path. yolo deliberately
|
|
9
|
+
* bypasses the *confirmation*; it does NOT bypass this floor.
|
|
10
|
+
*
|
|
11
|
+
* Recoverable-but-costly operations (e.g. `git reset --hard`, `rm -rf ./build`,
|
|
12
|
+
* `chmod -R 777 ./dir`, `curl | sh`) are intentionally NOT here — those are what
|
|
13
|
+
* the confirmation dialog / yolo are for.
|
|
14
|
+
*
|
|
15
|
+
* Patterns match the NORMALIZED command ({@link ./normalize.js}) so obfuscation
|
|
16
|
+
* (ANSI/fullwidth/backslash splits/whitespace padding) cannot bypass them.
|
|
17
|
+
*
|
|
18
|
+
* Patterned after hermes-agent `tools/approval.py` HARDLINE_PATTERNS.
|
|
19
|
+
*/
|
|
20
|
+
import { normalizeCommand } from '#src/tools/shell/normalize.js';
|
|
21
|
+
// Matches a position where the shell would begin parsing a NEW command: start of
|
|
22
|
+
// string, after a separator (; & | newline), after `$(` or backtick, optionally
|
|
23
|
+
// consuming leading wrappers (sudo/env VAR=VAL/exec/nohup/setsid/time). Used by
|
|
24
|
+
// the shutdown-family patterns so they don't false-positive on `echo reboot`.
|
|
25
|
+
const CMD_POS = '(?:^|[;&|\\n`]|\\$\\()' +
|
|
26
|
+
'\\s*' +
|
|
27
|
+
'(?:sudo\\s+(?:-[^\\s]+\\s+)*)?' +
|
|
28
|
+
'(?:env\\s+(?:\\w+=\\S*\\s+)*)?' +
|
|
29
|
+
'(?:(?:exec|nohup|setsid|time)\\s+)*' +
|
|
30
|
+
'\\s*';
|
|
31
|
+
/**
|
|
32
|
+
* Hardline patterns: [regex, human description]. Matched case-insensitively
|
|
33
|
+
* against the normalized command.
|
|
34
|
+
*/
|
|
35
|
+
export const HARDLINE_PATTERNS = [
|
|
36
|
+
// rm -rf targeting the root filesystem (`/`, `/*`).
|
|
37
|
+
[/\brm\s+(?:-[^\s]*\s+)*\/\s*\*?\s*(?:$|[;&|])/, 'recursive delete of root filesystem'],
|
|
38
|
+
// rm -rf targeting protected system directories (with optional /* suffix).
|
|
39
|
+
[
|
|
40
|
+
/\brm\s+(?:-[^\s]*\s+)*(?:\/(?:home|root|etc|usr|var|bin|sbin|boot|lib|lib64|opt|sys|proc))(?:\/\*)?\s*(?:$|[;&|])/,
|
|
41
|
+
'recursive delete of system directory',
|
|
42
|
+
],
|
|
43
|
+
// rm -rf targeting the home directory (~ or $HOME).
|
|
44
|
+
// Note: patterns match the LOWERCASED normalized command, so $HOME → $home.
|
|
45
|
+
[
|
|
46
|
+
/\brm\s+(?:-[^\s]*\s+)*(?:~|\$home)(?:\/\*)?\s*(?:$|[;&|])/,
|
|
47
|
+
'recursive delete of home directory',
|
|
48
|
+
],
|
|
49
|
+
// Filesystem format.
|
|
50
|
+
[/\bmkfs(?:\.[a-z0-9]+)?\b/, 'format filesystem (mkfs)'],
|
|
51
|
+
// dd writing to a raw block device.
|
|
52
|
+
[/\bdd\b[^\n]*\bof=\/dev\/(?:sd|nvme|hd|mmcblk|vd|xvd)[a-z0-9]*/, 'dd to raw block device'],
|
|
53
|
+
// Shell redirection to a raw block device (`> /dev/sda`).
|
|
54
|
+
[/>\s*\/dev\/(?:sd|nvme|hd|mmcblk|vd|xvd)[a-z0-9]*\b/, 'redirect to raw block device'],
|
|
55
|
+
// Classic fork bomb `:(){ :|:& };:`.
|
|
56
|
+
[/:\s*\(\s*\)\s*\{\s*:\s*\|\s*:\s*&\s*\}\s*;\s*:/, 'fork bomb'],
|
|
57
|
+
// chmod -R 777 / (recursive world-writable on root).
|
|
58
|
+
[
|
|
59
|
+
/\bchmod\s+(?:-[^\s]*\s+)*(?:-r|--recursive)\s+(?:-[^\s]*\s+)*777\s+\//,
|
|
60
|
+
'recursive chmod 777 of root',
|
|
61
|
+
],
|
|
62
|
+
// Kill every process on the system (`kill -1`, `kill -9 -1`).
|
|
63
|
+
[/\bkill\s+(?:-[^\s]+\s+)*-1\b/, 'kill all processes'],
|
|
64
|
+
// System shutdown / reboot — anchored to a command position so `echo reboot`
|
|
65
|
+
// and `grep shutdown log` don't trip it.
|
|
66
|
+
[new RegExp(CMD_POS + '(?:shutdown|reboot|halt|poweroff)\\b'), 'system shutdown/reboot'],
|
|
67
|
+
[new RegExp(CMD_POS + 'init\\s+[06]\\b'), 'init 0/6 (shutdown/reboot)'],
|
|
68
|
+
[
|
|
69
|
+
new RegExp(CMD_POS + 'systemctl\\s+(?:poweroff|reboot|halt|kexec)\\b'),
|
|
70
|
+
'systemctl poweroff/reboot',
|
|
71
|
+
],
|
|
72
|
+
[new RegExp(CMD_POS + 'telinit\\s+[06]\\b'), 'telinit 0/6 (shutdown/reboot)'],
|
|
73
|
+
];
|
|
74
|
+
/**
|
|
75
|
+
* Check a raw command against the hardline blocklist. Normalizes first so
|
|
76
|
+
* obfuscated variants are caught. Returns the match (with a description) when the
|
|
77
|
+
* command is catastrophic, or `null` when it is allowed to proceed.
|
|
78
|
+
*/
|
|
79
|
+
export function checkHardline(command) {
|
|
80
|
+
const normalized = normalizeCommand(command).toLowerCase();
|
|
81
|
+
for (const [pattern, description] of HARDLINE_PATTERNS) {
|
|
82
|
+
if (pattern.test(normalized)) {
|
|
83
|
+
return { description };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=hardline.js.map
|