@gaunt-sloth/agent 2.0.0-alpha.2 → 2.0.0-alpha.3
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 +32 -0
- package/dist/core/GthDeepAgent.js +113 -9
- 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 +56 -2
- package/dist/modules/interactiveSessionModule.js.map +1 -1
- package/dist/tools/GthDevToolkit.d.ts +40 -1
- package/dist/tools/GthDevToolkit.js +169 -17
- 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 +5 -5
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hardline.js","sourceRoot":"","sources":["../../../src/tools/shell/hardline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,iFAAiF;AACjF,gFAAgF;AAChF,gFAAgF;AAChF,8EAA8E;AAC9E,MAAM,OAAO,GACX,wBAAwB;IACxB,MAAM;IACN,gCAAgC;IAChC,gCAAgC;IAChC,qCAAqC;IACrC,MAAM,CAAC;AAET;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA6C;IACzE,oDAAoD;IACpD,CAAC,8CAA8C,EAAE,qCAAqC,CAAC;IACvF,2EAA2E;IAC3E;QACE,mHAAmH;QACnH,sCAAsC;KACvC;IACD,oDAAoD;IACpD,4EAA4E;IAC5E;QACE,2DAA2D;QAC3D,oCAAoC;KACrC;IACD,qBAAqB;IACrB,CAAC,0BAA0B,EAAE,0BAA0B,CAAC;IACxD,oCAAoC;IACpC,CAAC,+DAA+D,EAAE,wBAAwB,CAAC;IAC3F,0DAA0D;IAC1D,CAAC,oDAAoD,EAAE,8BAA8B,CAAC;IACtF,qCAAqC;IACrC,CAAC,gDAAgD,EAAE,WAAW,CAAC;IAC/D,qDAAqD;IACrD;QACE,uEAAuE;QACvE,6BAA6B;KAC9B;IACD,8DAA8D;IAC9D,CAAC,8BAA8B,EAAE,oBAAoB,CAAC;IACtD,6EAA6E;IAC7E,yCAAyC;IACzC,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,sCAAsC,CAAC,EAAE,wBAAwB,CAAC;IACxF,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;IACvE;QACE,IAAI,MAAM,CAAC,OAAO,GAAG,gDAAgD,CAAC;QACtE,2BAA2B;KAC5B;IACD,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,oBAAoB,CAAC,EAAE,+BAA+B,CAAC;CAC9E,CAAC;AAOF;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3D,KAAK,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,iBAAiB,EAAE,CAAC;QACvD,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,WAAW,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module tools/shell/normalize
|
|
3
|
+
*
|
|
4
|
+
* Re-export of the canonical command normalizer, which now lives in
|
|
5
|
+
* `@gaunt-sloth/core` (`core/shell/normalize`) so the core runner's EXT-9 Tier-2
|
|
6
|
+
* allow-list classifier and the agent's Tier-1 hardline blocklist share ONE
|
|
7
|
+
* implementation. Kept as a stable import path for existing agent-side consumers
|
|
8
|
+
* (`tools/shell/hardline`, specs).
|
|
9
|
+
*/
|
|
10
|
+
export { normalizeCommand } from '@gaunt-sloth/core/core/shell/normalize.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module tools/shell/normalize
|
|
3
|
+
*
|
|
4
|
+
* Re-export of the canonical command normalizer, which now lives in
|
|
5
|
+
* `@gaunt-sloth/core` (`core/shell/normalize`) so the core runner's EXT-9 Tier-2
|
|
6
|
+
* allow-list classifier and the agent's Tier-1 hardline blocklist share ONE
|
|
7
|
+
* implementation. Kept as a stable import path for existing agent-side consumers
|
|
8
|
+
* (`tools/shell/hardline`, specs).
|
|
9
|
+
*/
|
|
10
|
+
export { normalizeCommand } from '@gaunt-sloth/core/core/shell/normalize.js';
|
|
11
|
+
//# sourceMappingURL=normalize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../src/tools/shell/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export interface CappedOutput {
|
|
2
|
+
/** The bounded text to surface to the model (head + tail with a gap note). */
|
|
3
|
+
text: string;
|
|
4
|
+
/** True when the output exceeded the budget and was truncated. */
|
|
5
|
+
truncated: boolean;
|
|
6
|
+
/** Total bytes captured (the full, untruncated size). */
|
|
7
|
+
totalBytes: number;
|
|
8
|
+
/** Absolute path to the spilled full output, or undefined when not truncated. */
|
|
9
|
+
spillPath?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Accumulates command output up to a byte budget using a head + tail window.
|
|
13
|
+
* The full output is retained in memory so it can be spilled to disk on demand;
|
|
14
|
+
* the in-memory full copy is itself bounded at a hard safety ceiling to avoid
|
|
15
|
+
* unbounded growth from a runaway command.
|
|
16
|
+
*/
|
|
17
|
+
export declare class OutputBuffer {
|
|
18
|
+
private head;
|
|
19
|
+
private headBytes;
|
|
20
|
+
private readonly tailChunks;
|
|
21
|
+
private tailBytes;
|
|
22
|
+
private totalBytesCount;
|
|
23
|
+
/** Full copy for spillover, bounded by a hard ceiling. */
|
|
24
|
+
private full;
|
|
25
|
+
private fullTruncated;
|
|
26
|
+
private readonly headBudget;
|
|
27
|
+
private readonly tailBudget;
|
|
28
|
+
private readonly fullCeiling;
|
|
29
|
+
/**
|
|
30
|
+
* @param maxOutputBytes total byte budget for the returned (head+tail) window.
|
|
31
|
+
* @param fullCeiling hard ceiling for the in-memory full copy kept for spillover.
|
|
32
|
+
* Defaults to a generous 16MB so the spill file holds the real output for
|
|
33
|
+
* typical noisy logs, while still bounding memory for a runaway command.
|
|
34
|
+
*/
|
|
35
|
+
constructor(maxOutputBytes: number, fullCeiling?: number);
|
|
36
|
+
/** Append a chunk of output. Byte accounting uses UTF-8 byte length. */
|
|
37
|
+
append(chunk: string): void;
|
|
38
|
+
/** Push into the tail ring-buffer, evicting oldest data beyond the budget. */
|
|
39
|
+
private pushTail;
|
|
40
|
+
get totalBytes(): number;
|
|
41
|
+
get isTruncated(): boolean;
|
|
42
|
+
/** The full captured output (bounded by the in-memory ceiling). */
|
|
43
|
+
getFull(): string;
|
|
44
|
+
/**
|
|
45
|
+
* Finalize the capture. When not truncated, returns the output verbatim. When
|
|
46
|
+
* truncated, spills the full output to a temp file and returns head + a gap
|
|
47
|
+
* note (with the file path) + tail.
|
|
48
|
+
*
|
|
49
|
+
* @param spill optional injected spill function (path-returning) for testing.
|
|
50
|
+
* Defaults to writing into `os.tmpdir()`.
|
|
51
|
+
*/
|
|
52
|
+
finalize(spill?: (content: string) => string): CappedOutput;
|
|
53
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module tools/shell/outputBuffer
|
|
3
|
+
*
|
|
4
|
+
* Bounded capture of a shell command's combined stdout/stderr for the value
|
|
5
|
+
* returned to the model. A noisy build/test log can be megabytes; dumping it
|
|
6
|
+
* verbatim into a ToolMessage blows the context window. This buffer keeps a
|
|
7
|
+
* HEAD window (the first N bytes) and a TAIL ring-buffer (the last N bytes) and
|
|
8
|
+
* drops the middle, while accumulating the FULL output separately so it can be
|
|
9
|
+
* spilled to a temp file the model can re-read with `read_file`.
|
|
10
|
+
*
|
|
11
|
+
* Live streaming to the terminal is unaffected — the toolkit still writes every
|
|
12
|
+
* chunk to stdout as it arrives; only the returned string is capped.
|
|
13
|
+
*
|
|
14
|
+
* Patterned after opencode `bash.ts` (per-stream cap + temp-file tail) and
|
|
15
|
+
* openclaw `bash-tools.shared.ts` `truncateMiddle`.
|
|
16
|
+
*/
|
|
17
|
+
import { writeFileSync } from 'node:fs';
|
|
18
|
+
import { tmpdir } from 'node:os';
|
|
19
|
+
import path from 'node:path';
|
|
20
|
+
/**
|
|
21
|
+
* Accumulates command output up to a byte budget using a head + tail window.
|
|
22
|
+
* The full output is retained in memory so it can be spilled to disk on demand;
|
|
23
|
+
* the in-memory full copy is itself bounded at a hard safety ceiling to avoid
|
|
24
|
+
* unbounded growth from a runaway command.
|
|
25
|
+
*/
|
|
26
|
+
export class OutputBuffer {
|
|
27
|
+
head = '';
|
|
28
|
+
headBytes = 0;
|
|
29
|
+
tailChunks = [];
|
|
30
|
+
tailBytes = 0;
|
|
31
|
+
totalBytesCount = 0;
|
|
32
|
+
/** Full copy for spillover, bounded by a hard ceiling. */
|
|
33
|
+
full = '';
|
|
34
|
+
fullTruncated = false;
|
|
35
|
+
headBudget;
|
|
36
|
+
tailBudget;
|
|
37
|
+
fullCeiling;
|
|
38
|
+
/**
|
|
39
|
+
* @param maxOutputBytes total byte budget for the returned (head+tail) window.
|
|
40
|
+
* @param fullCeiling hard ceiling for the in-memory full copy kept for spillover.
|
|
41
|
+
* Defaults to a generous 16MB so the spill file holds the real output for
|
|
42
|
+
* typical noisy logs, while still bounding memory for a runaway command.
|
|
43
|
+
*/
|
|
44
|
+
constructor(maxOutputBytes, fullCeiling = 16 * 1024 * 1024) {
|
|
45
|
+
// Split the budget evenly between head and tail.
|
|
46
|
+
this.headBudget = Math.max(1, Math.floor(maxOutputBytes / 2));
|
|
47
|
+
this.tailBudget = Math.max(1, maxOutputBytes - this.headBudget);
|
|
48
|
+
// The full copy must hold at least the preview window.
|
|
49
|
+
this.fullCeiling = Math.max(fullCeiling, maxOutputBytes);
|
|
50
|
+
}
|
|
51
|
+
/** Append a chunk of output. Byte accounting uses UTF-8 byte length. */
|
|
52
|
+
append(chunk) {
|
|
53
|
+
const bytes = Buffer.byteLength(chunk, 'utf8');
|
|
54
|
+
this.totalBytesCount += bytes;
|
|
55
|
+
// Maintain the full copy up to the ceiling (for spillover). Store as much of
|
|
56
|
+
// an oversized chunk as fits rather than dropping it wholesale.
|
|
57
|
+
if (!this.fullTruncated) {
|
|
58
|
+
const used = Buffer.byteLength(this.full, 'utf8');
|
|
59
|
+
const room = this.fullCeiling - used;
|
|
60
|
+
if (bytes <= room) {
|
|
61
|
+
this.full += chunk;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
if (room > 0) {
|
|
65
|
+
this.full += Buffer.from(chunk, 'utf8').subarray(0, room).toString('utf8');
|
|
66
|
+
}
|
|
67
|
+
this.fullTruncated = true;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Fill the head window first.
|
|
71
|
+
if (this.headBytes < this.headBudget) {
|
|
72
|
+
const room = this.headBudget - this.headBytes;
|
|
73
|
+
if (bytes <= room) {
|
|
74
|
+
this.head += chunk;
|
|
75
|
+
this.headBytes += bytes;
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Partial: take what fits into head, the rest flows to tail.
|
|
79
|
+
const take = Buffer.from(chunk, 'utf8').subarray(0, room).toString('utf8');
|
|
80
|
+
this.head += take;
|
|
81
|
+
this.headBytes += Buffer.byteLength(take, 'utf8');
|
|
82
|
+
const rest = chunk.slice(take.length);
|
|
83
|
+
this.pushTail(rest);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
this.pushTail(chunk);
|
|
87
|
+
}
|
|
88
|
+
/** Push into the tail ring-buffer, evicting oldest data beyond the budget. */
|
|
89
|
+
pushTail(chunk) {
|
|
90
|
+
if (chunk.length === 0)
|
|
91
|
+
return;
|
|
92
|
+
this.tailChunks.push(chunk);
|
|
93
|
+
this.tailBytes += Buffer.byteLength(chunk, 'utf8');
|
|
94
|
+
while (this.tailBytes > this.tailBudget && this.tailChunks.length > 1) {
|
|
95
|
+
const removed = this.tailChunks.shift();
|
|
96
|
+
this.tailBytes -= Buffer.byteLength(removed, 'utf8');
|
|
97
|
+
}
|
|
98
|
+
// If a single chunk alone exceeds the tail budget, trim it from the front.
|
|
99
|
+
if (this.tailBytes > this.tailBudget && this.tailChunks.length === 1) {
|
|
100
|
+
const only = this.tailChunks[0];
|
|
101
|
+
const overflow = this.tailBytes - this.tailBudget;
|
|
102
|
+
const buf = Buffer.from(only, 'utf8');
|
|
103
|
+
const trimmed = buf.subarray(overflow).toString('utf8');
|
|
104
|
+
this.tailChunks[0] = trimmed;
|
|
105
|
+
this.tailBytes = Buffer.byteLength(trimmed, 'utf8');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
get totalBytes() {
|
|
109
|
+
return this.totalBytesCount;
|
|
110
|
+
}
|
|
111
|
+
get isTruncated() {
|
|
112
|
+
return this.totalBytesCount > this.headBytes + this.tailBytes;
|
|
113
|
+
}
|
|
114
|
+
/** The full captured output (bounded by the in-memory ceiling). */
|
|
115
|
+
getFull() {
|
|
116
|
+
return this.full;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Finalize the capture. When not truncated, returns the output verbatim. When
|
|
120
|
+
* truncated, spills the full output to a temp file and returns head + a gap
|
|
121
|
+
* note (with the file path) + tail.
|
|
122
|
+
*
|
|
123
|
+
* @param spill optional injected spill function (path-returning) for testing.
|
|
124
|
+
* Defaults to writing into `os.tmpdir()`.
|
|
125
|
+
*/
|
|
126
|
+
finalize(spill = defaultSpill) {
|
|
127
|
+
const tail = this.tailChunks.join('');
|
|
128
|
+
if (!this.isTruncated) {
|
|
129
|
+
return {
|
|
130
|
+
text: this.head + tail,
|
|
131
|
+
truncated: false,
|
|
132
|
+
totalBytes: this.totalBytesCount,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const spillPath = spill(this.full);
|
|
136
|
+
const fullNote = this.fullTruncated
|
|
137
|
+
? `First ${Buffer.byteLength(this.full, 'utf8')} bytes`
|
|
138
|
+
: 'Full output';
|
|
139
|
+
const droppedNote = `\n\n... [output truncated: ${this.totalBytesCount} bytes total; ` +
|
|
140
|
+
`showing first ${this.headBytes} + last ${this.tailBytes} bytes. ` +
|
|
141
|
+
`${fullNote} written to ${spillPath} — use read_file to inspect.] ...\n\n`;
|
|
142
|
+
return {
|
|
143
|
+
text: this.head + droppedNote + tail,
|
|
144
|
+
truncated: true,
|
|
145
|
+
totalBytes: this.totalBytesCount,
|
|
146
|
+
spillPath,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/** Default spill: write to a uniquely-named file in the OS temp dir. */
|
|
151
|
+
function defaultSpill(content) {
|
|
152
|
+
const name = `gsloth-shell-${Date.now()}-${Math.random().toString(36).slice(2, 10)}.log`;
|
|
153
|
+
const filePath = path.join(tmpdir(), name);
|
|
154
|
+
writeFileSync(filePath, content, 'utf8');
|
|
155
|
+
return filePath;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=outputBuffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputBuffer.js","sourceRoot":"","sources":["../../../src/tools/shell/outputBuffer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gaunt-sloth/agent",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.3",
|
|
4
4
|
"description": "Deep agent runtime for Gaunt Sloth: tools, middleware, MCP/A2A clients and the AG-UI server",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Andrew Kondratev",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/
|
|
9
|
+
"url": "git+https://github.com/pukeko-robotics/gaunt-sloth.git",
|
|
10
10
|
"directory": "packages/agent"
|
|
11
11
|
},
|
|
12
12
|
"bugs": {
|
|
13
|
-
"url": "https://github.com/
|
|
13
|
+
"url": "https://github.com/pukeko-robotics/gaunt-sloth/issues"
|
|
14
14
|
},
|
|
15
|
-
"homepage": "https://github.com/
|
|
15
|
+
"homepage": "https://github.com/pukeko-robotics/gaunt-sloth/tree/main/packages/agent#readme",
|
|
16
16
|
"keywords": [
|
|
17
17
|
"ai",
|
|
18
18
|
"agent",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"langchain": "^1.5.0",
|
|
53
53
|
"uuid": ">=11.1.1",
|
|
54
54
|
"zod": "^3.25.0 || ^4.0.0",
|
|
55
|
-
"@gaunt-sloth/core": "2.0.0-alpha.
|
|
55
|
+
"@gaunt-sloth/core": "2.0.0-alpha.3"
|
|
56
56
|
},
|
|
57
57
|
"files": [
|
|
58
58
|
"./dist/*",
|