@deepwhale/coding-agent 1.0.10 → 1.0.12
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/LICENSE +21 -21
- package/package.json +1 -1
- package/dist/agent/agent-compaction.d.ts +0 -74
- package/dist/agent/agent-compaction.d.ts.map +0 -1
- package/dist/agent/agent-compaction.js +0 -145
- package/dist/agent/agent-compaction.js.map +0 -1
- package/dist/agent/index.d.ts +0 -16
- package/dist/agent/index.d.ts.map +0 -1
- package/dist/agent/index.js +0 -17
- package/dist/agent/index.js.map +0 -1
- package/dist/agent/session-adapter.d.ts +0 -177
- package/dist/agent/session-adapter.d.ts.map +0 -1
- package/dist/agent/session-adapter.js +0 -365
- package/dist/agent/session-adapter.js.map +0 -1
- package/dist/agent/tool-loop.d.ts +0 -123
- package/dist/agent/tool-loop.d.ts.map +0 -1
- package/dist/agent/tool-loop.js +0 -436
- package/dist/agent/tool-loop.js.map +0 -1
- package/dist/env/load-project-env.d.ts +0 -40
- package/dist/env/load-project-env.d.ts.map +0 -1
- package/dist/env/load-project-env.js +0 -80
- package/dist/env/load-project-env.js.map +0 -1
- package/dist/index.d.ts +0 -31
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -30
- package/dist/index.js.map +0 -1
- package/dist/llm-factory.d.ts +0 -50
- package/dist/llm-factory.d.ts.map +0 -1
- package/dist/llm-factory.js +0 -110
- package/dist/llm-factory.js.map +0 -1
- package/dist/modes/index.d.ts +0 -14
- package/dist/modes/index.d.ts.map +0 -1
- package/dist/modes/index.js +0 -14
- package/dist/modes/index.js.map +0 -1
- package/dist/modes/print.d.ts +0 -50
- package/dist/modes/print.d.ts.map +0 -1
- package/dist/modes/print.js +0 -236
- package/dist/modes/print.js.map +0 -1
- package/dist/modes/rpc.d.ts +0 -52
- package/dist/modes/rpc.d.ts.map +0 -1
- package/dist/modes/rpc.js +0 -316
- package/dist/modes/rpc.js.map +0 -1
- package/dist/modes/tui.d.ts +0 -112
- package/dist/modes/tui.d.ts.map +0 -1
- package/dist/modes/tui.js +0 -733
- package/dist/modes/tui.js.map +0 -1
- package/dist/policy/args-digest.d.ts +0 -13
- package/dist/policy/args-digest.d.ts.map +0 -1
- package/dist/policy/args-digest.js +0 -29
- package/dist/policy/args-digest.js.map +0 -1
- package/dist/policy/chain.d.ts +0 -19
- package/dist/policy/chain.d.ts.map +0 -1
- package/dist/policy/chain.js +0 -24
- package/dist/policy/chain.js.map +0 -1
- package/dist/policy/index.d.ts +0 -17
- package/dist/policy/index.d.ts.map +0 -1
- package/dist/policy/index.js +0 -16
- package/dist/policy/index.js.map +0 -1
- package/dist/policy/sanitize-reason.d.ts +0 -11
- package/dist/policy/sanitize-reason.d.ts.map +0 -1
- package/dist/policy/sanitize-reason.js +0 -24
- package/dist/policy/sanitize-reason.js.map +0 -1
- package/dist/policy/static-rules.d.ts +0 -32
- package/dist/policy/static-rules.d.ts.map +0 -1
- package/dist/policy/static-rules.js +0 -106
- package/dist/policy/static-rules.js.map +0 -1
- package/dist/policy/types.d.ts +0 -56
- package/dist/policy/types.d.ts.map +0 -1
- package/dist/policy/types.js +0 -13
- package/dist/policy/types.js.map +0 -1
- package/dist/repl/repl-confirm.d.ts +0 -49
- package/dist/repl/repl-confirm.d.ts.map +0 -1
- package/dist/repl/repl-confirm.js +0 -88
- package/dist/repl/repl-confirm.js.map +0 -1
- package/dist/repl.d.ts +0 -154
- package/dist/repl.d.ts.map +0 -1
- package/dist/repl.js +0 -780
- package/dist/repl.js.map +0 -1
- package/dist/sandbox/docker-runner.d.ts +0 -147
- package/dist/sandbox/docker-runner.d.ts.map +0 -1
- package/dist/sandbox/docker-runner.js +0 -426
- package/dist/sandbox/docker-runner.js.map +0 -1
- package/dist/sandbox/env-gate.d.ts +0 -28
- package/dist/sandbox/env-gate.d.ts.map +0 -1
- package/dist/sandbox/env-gate.js +0 -65
- package/dist/sandbox/env-gate.js.map +0 -1
- package/dist/sandbox/local-runner.d.ts +0 -29
- package/dist/sandbox/local-runner.d.ts.map +0 -1
- package/dist/sandbox/local-runner.js +0 -79
- package/dist/sandbox/local-runner.js.map +0 -1
- package/dist/sandbox/types.d.ts +0 -80
- package/dist/sandbox/types.d.ts.map +0 -1
- package/dist/sandbox/types.js +0 -25
- package/dist/sandbox/types.js.map +0 -1
- package/dist/tools/bash.d.ts +0 -35
- package/dist/tools/bash.d.ts.map +0 -1
- package/dist/tools/bash.js +0 -233
- package/dist/tools/bash.js.map +0 -1
- package/dist/tools/edit-file.d.ts +0 -22
- package/dist/tools/edit-file.d.ts.map +0 -1
- package/dist/tools/edit-file.js +0 -79
- package/dist/tools/edit-file.js.map +0 -1
- package/dist/tools/find.d.ts +0 -21
- package/dist/tools/find.d.ts.map +0 -1
- package/dist/tools/find.js +0 -168
- package/dist/tools/find.js.map +0 -1
- package/dist/tools/grep.d.ts +0 -19
- package/dist/tools/grep.d.ts.map +0 -1
- package/dist/tools/grep.js +0 -170
- package/dist/tools/grep.js.map +0 -1
- package/dist/tools/index.d.ts +0 -10
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -10
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/read-file.d.ts +0 -18
- package/dist/tools/read-file.d.ts.map +0 -1
- package/dist/tools/read-file.js +0 -52
- package/dist/tools/read-file.js.map +0 -1
- package/dist/tools/registry.d.ts +0 -39
- package/dist/tools/registry.d.ts.map +0 -1
- package/dist/tools/registry.js +0 -67
- package/dist/tools/registry.js.map +0 -1
- package/dist/tools/write-file.d.ts +0 -18
- package/dist/tools/write-file.d.ts.map +0 -1
- package/dist/tools/write-file.js +0 -47
- package/dist/tools/write-file.js.map +0 -1
- package/dist/tui-ink-bundle.js +0 -38587
- package/dist/types.d.ts +0 -89
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -5
- package/dist/types.js.map +0 -1
- package/dist/util/index.d.ts +0 -16
- package/dist/util/index.d.ts.map +0 -1
- package/dist/util/index.js +0 -16
- package/dist/util/index.js.map +0 -1
- package/dist/util/tui-history.d.ts +0 -37
- package/dist/util/tui-history.d.ts.map +0 -1
- package/dist/util/tui-history.js +0 -93
- package/dist/util/tui-history.js.map +0 -1
- package/dist/verify/format-report.d.ts +0 -57
- package/dist/verify/format-report.d.ts.map +0 -1
- package/dist/verify/format-report.js +0 -128
- package/dist/verify/format-report.js.map +0 -1
- package/dist/verify/index.d.ts +0 -8
- package/dist/verify/index.d.ts.map +0 -1
- package/dist/verify/index.js +0 -8
- package/dist/verify/index.js.map +0 -1
- package/dist/verify/verify-runner.d.ts +0 -186
- package/dist/verify/verify-runner.d.ts.map +0 -1
- package/dist/verify/verify-runner.js +0 -707
- package/dist/verify/verify-runner.js.map +0 -1
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* env gate helper — 从环境变量解析 sandbox 配置
|
|
3
|
-
*
|
|
4
|
-
* Sprint 1c-revive-3-D-12 (2026-06-05). MVP 入口, 跟 BashTool 解耦, 后续可换 config.toml.
|
|
5
|
-
*
|
|
6
|
-
* 支持的 env:
|
|
7
|
-
* - DEEPWHALE_SANDBOX=local|docker — 选 runner. 缺省 = local (BashTool 现状行为)
|
|
8
|
-
* - DEEPWHALE_DOCKER_IMAGE — 容器镜像. 缺省 = 'node:22-alpine'
|
|
9
|
-
* - DEEPWHALE_DOCKER_NETWORK=none|bridge — 容器网络. 缺省 = 'none' 禁网
|
|
10
|
-
*
|
|
11
|
-
* 安全: 不传 DEEPSEEK_API_KEY / ANTHROPIC_AUTH_TOKEN 等敏感 env 到 docker 容器
|
|
12
|
-
* (DockerSandboxRunner 默认只透 process.env, **不** 注入 .env / API key).
|
|
13
|
-
*/
|
|
14
|
-
import type { SandboxRunner } from './types.js';
|
|
15
|
-
export interface SandboxEnvConfig {
|
|
16
|
-
readonly sandboxRoot: string;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* 解析 env → 选 sandbox runner. 缺省 = LocalSandboxRunner (BashTool 现状).
|
|
20
|
-
* env DEEPWHALE_SANDBOX=docker 时返 DockerSandboxRunner, 镜像/网络用对应 env.
|
|
21
|
-
*
|
|
22
|
-
* Sprint 1c-revive-3-D-12 review P1 修复 (2026-06-05): 严格 enum, 未知值 throw.
|
|
23
|
-
* 之前 `mode !== 'docker'` 全部 fallback local, 拼错 `dokcer` 之类会静默本地执行
|
|
24
|
-
* — fail-open, 安全红线. 修法: 只接受 unset / `local` / `docker`, 其他值抛错.
|
|
25
|
-
* 入口 (CLI / REPL 启动) 应当把 throw 转到 stderr + exit 1, 不静默.
|
|
26
|
-
*/
|
|
27
|
-
export declare function resolveSandboxRunnerFromEnv(config: SandboxEnvConfig, env?: NodeJS.ProcessEnv): SandboxRunner;
|
|
28
|
-
//# sourceMappingURL=env-gate.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"env-gate.d.ts","sourceRoot":"","sources":["../../src/sandbox/env-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,gBAAgB,EACxB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,aAAa,CAyCf"}
|
package/dist/sandbox/env-gate.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* env gate helper — 从环境变量解析 sandbox 配置
|
|
3
|
-
*
|
|
4
|
-
* Sprint 1c-revive-3-D-12 (2026-06-05). MVP 入口, 跟 BashTool 解耦, 后续可换 config.toml.
|
|
5
|
-
*
|
|
6
|
-
* 支持的 env:
|
|
7
|
-
* - DEEPWHALE_SANDBOX=local|docker — 选 runner. 缺省 = local (BashTool 现状行为)
|
|
8
|
-
* - DEEPWHALE_DOCKER_IMAGE — 容器镜像. 缺省 = 'node:22-alpine'
|
|
9
|
-
* - DEEPWHALE_DOCKER_NETWORK=none|bridge — 容器网络. 缺省 = 'none' 禁网
|
|
10
|
-
*
|
|
11
|
-
* 安全: 不传 DEEPSEEK_API_KEY / ANTHROPIC_AUTH_TOKEN 等敏感 env 到 docker 容器
|
|
12
|
-
* (DockerSandboxRunner 默认只透 process.env, **不** 注入 .env / API key).
|
|
13
|
-
*/
|
|
14
|
-
import { LocalSandboxRunner } from './local-runner.js';
|
|
15
|
-
import { DockerSandboxRunner, DOCKER_DEFAULT_TIMEOUT_MS } from './docker-runner.js';
|
|
16
|
-
/**
|
|
17
|
-
* 解析 env → 选 sandbox runner. 缺省 = LocalSandboxRunner (BashTool 现状).
|
|
18
|
-
* env DEEPWHALE_SANDBOX=docker 时返 DockerSandboxRunner, 镜像/网络用对应 env.
|
|
19
|
-
*
|
|
20
|
-
* Sprint 1c-revive-3-D-12 review P1 修复 (2026-06-05): 严格 enum, 未知值 throw.
|
|
21
|
-
* 之前 `mode !== 'docker'` 全部 fallback local, 拼错 `dokcer` 之类会静默本地执行
|
|
22
|
-
* — fail-open, 安全红线. 修法: 只接受 unset / `local` / `docker`, 其他值抛错.
|
|
23
|
-
* 入口 (CLI / REPL 启动) 应当把 throw 转到 stderr + exit 1, 不静默.
|
|
24
|
-
*/
|
|
25
|
-
export function resolveSandboxRunnerFromEnv(config, env = process.env) {
|
|
26
|
-
const raw = env['DEEPWHALE_SANDBOX'];
|
|
27
|
-
// unset / 空字符串 = 默认 local (跟 README 一致)
|
|
28
|
-
if (raw === undefined || raw === '') {
|
|
29
|
-
return new LocalSandboxRunner();
|
|
30
|
-
}
|
|
31
|
-
if (raw === 'local') {
|
|
32
|
-
return new LocalSandboxRunner();
|
|
33
|
-
}
|
|
34
|
-
if (raw === 'docker') {
|
|
35
|
-
const image = env['DEEPWHALE_DOCKER_IMAGE'] ?? 'node:22-alpine';
|
|
36
|
-
// Sprint 1c-revive-4-D-20.1 (2026-06-05) review-fix: 跟 DEEPWHALE_SANDBOX 一致
|
|
37
|
-
// fail-closed, 不静默 fallback. 之前 raw !== 'bridge' 静默 → 'none', 拼错
|
|
38
|
-
// 'bridgee' 之类会"以防网跑" (跟用户本意"放行"相反, 安全红线).
|
|
39
|
-
const networkEnv = env['DEEPWHALE_DOCKER_NETWORK'];
|
|
40
|
-
if (networkEnv !== undefined && networkEnv !== '' && networkEnv !== 'none' && networkEnv !== 'bridge') {
|
|
41
|
-
throw new Error(`invalid DEEPWHALE_DOCKER_NETWORK=${JSON.stringify(networkEnv)}, expected unset|none|bridge`);
|
|
42
|
-
}
|
|
43
|
-
const network = networkEnv === 'bridge' ? 'bridge' : 'none';
|
|
44
|
-
// Sprint 1c-revive-4-D-20.1 P0-F (2026-06-05): 容器资源限制 (拍板: memory=512m /
|
|
45
|
-
// cpus=1.0 / pids-limit=256). 防止 Docker 容器 fork 炸弹 / OOM 把宿主打挂.
|
|
46
|
-
// env 解析走跟 NETWORK 同形态, 空字符串 = unset (走 DockerSandboxRunner 内部 default).
|
|
47
|
-
// 格式校验: docker CLI 接受 '512m'/'1g' 等字符串, 解析失败 docker 自己会 stderr
|
|
48
|
-
// 出来, 走 result.warning. 0 强校验降低复杂度, 接受"用户传错格式 → docker 报错"风险.
|
|
49
|
-
const memoryEnv = env['DEEPWHALE_DOCKER_MEMORY'];
|
|
50
|
-
const cpusEnv = env['DEEPWHALE_DOCKER_CPUS'];
|
|
51
|
-
const pidsLimitEnv = env['DEEPWHALE_DOCKER_PIDS_LIMIT'];
|
|
52
|
-
return new DockerSandboxRunner({
|
|
53
|
-
sandboxRoot: config.sandboxRoot,
|
|
54
|
-
image,
|
|
55
|
-
network,
|
|
56
|
-
defaultTimeoutMs: DOCKER_DEFAULT_TIMEOUT_MS,
|
|
57
|
-
...(memoryEnv !== undefined && memoryEnv !== '' ? { memory: memoryEnv } : {}),
|
|
58
|
-
...(cpusEnv !== undefined && cpusEnv !== '' ? { cpus: cpusEnv } : {}),
|
|
59
|
-
...(pidsLimitEnv !== undefined && pidsLimitEnv !== '' ? { pidsLimit: pidsLimitEnv } : {}),
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
// 未知值 — fail-closed. 抛出的 message 拼齐提示, 入口能直接 stderr 打印给用户.
|
|
63
|
-
throw new Error(`invalid DEEPWHALE_SANDBOX=${JSON.stringify(raw)}, expected unset|local|docker`);
|
|
64
|
-
}
|
|
65
|
-
//# sourceMappingURL=env-gate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"env-gate.js","sourceRoot":"","sources":["../../src/sandbox/env-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAMpF;;;;;;;;GAQG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAAwB,EACxB,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,GAAG,GAAG,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACrC,wCAAwC;IACxC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACpC,OAAO,IAAI,kBAAkB,EAAE,CAAC;IAClC,CAAC;IACD,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACpB,OAAO,IAAI,kBAAkB,EAAE,CAAC;IAClC,CAAC;IACD,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,GAAG,CAAC,wBAAwB,CAAC,IAAI,gBAAgB,CAAC;QAChE,4EAA4E;QAC5E,iEAAiE;QACjE,2CAA2C;QAC3C,MAAM,UAAU,GAAG,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACnD,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,EAAE,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;YACtG,MAAM,IAAI,KAAK,CACb,oCAAoC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,8BAA8B,CAC7F,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAsB,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/E,yEAAyE;QACzE,gEAAgE;QAChE,yEAAyE;QACzE,+DAA+D;QAC/D,8DAA8D;QAC9D,MAAM,SAAS,GAAG,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,GAAG,CAAC,uBAAuB,CAAC,CAAC;QAC7C,MAAM,YAAY,GAAG,GAAG,CAAC,6BAA6B,CAAC,CAAC;QACxD,OAAO,IAAI,mBAAmB,CAAC;YAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,KAAK;YACL,OAAO;YACP,gBAAgB,EAAE,yBAAyB;YAC3C,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,GAAG,CAAC,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1F,CAAC,CAAC;IACL,CAAC;IACD,2DAA2D;IAC3D,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;AACnG,CAAC"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* LocalSandboxRunner — 默认本地 exec, 把 BashTool 现有 execFile 调用包到 SandboxRunner 接口
|
|
3
|
-
*
|
|
4
|
-
* Sprint 1c-revive-3-D-12 (2026-06-05): 这是 BashTool 行为事实的拆解版. BashTool 1.0
|
|
5
|
-
* 的"本地执行" 走 execFile(command, args, { cwd, maxBuffer, timeout }) —— 本 runner
|
|
6
|
-
* 不改语义, 重新组织返回形状到 SandboxRunResult. 默认 stdout cap 4KB 替换原 10MB
|
|
7
|
-
* maxBuffer (10MB 对 LLM 太大, cap 末尾 4KB 跟 verify-runner 一致).
|
|
8
|
-
*
|
|
9
|
-
* 安全边界: 不在这里加 cwd 校验 / dangerous pattern / allowlist — caller (BashTool)
|
|
10
|
-
* 入口已经做完, 这里只跑过白名单的命令.
|
|
11
|
-
*
|
|
12
|
-
* 实现注意: 用 execFile callback 的 stdout/stderr 参数做 cap. Node 16+ 默认 encoding
|
|
13
|
-
* 是 'utf8' (返回 string), 早期 Node 是 Buffer. 兼容方式: 强 encoding: 'buffer' 拿
|
|
14
|
-
* Buffer. 这样 cap 跟 utf8 decode 顺序明确.
|
|
15
|
-
*/
|
|
16
|
-
import type { SandboxRunRequest, SandboxRunResult, SandboxRunner } from './types.js';
|
|
17
|
-
export declare class LocalSandboxRunner implements SandboxRunner {
|
|
18
|
-
readonly kind: "local";
|
|
19
|
-
/**
|
|
20
|
-
* 跑命令. 不抛异常 — 失败 / timeout 都在 result 里.
|
|
21
|
-
*
|
|
22
|
-
* 走 execFile 自身的 timeout 选项 (Node.js 内置): 到点 execFile 会 kill child +
|
|
23
|
-
* 触发 callback 的 err. err.killed / err.signal 拿来填 SandboxRunResult.signal.
|
|
24
|
-
*/
|
|
25
|
-
run(req: SandboxRunRequest): Promise<SandboxRunResult>;
|
|
26
|
-
/** Local mode 无外部资源, cleanup 是 noop. */
|
|
27
|
-
cleanup(): Promise<void>;
|
|
28
|
-
}
|
|
29
|
-
//# sourceMappingURL=local-runner.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-runner.d.ts","sourceRoot":"","sources":["../../src/sandbox/local-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACd,MAAM,YAAY,CAAC;AAUpB,qBAAa,kBAAmB,YAAW,aAAa;IACtD,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAU;IAEjC;;;;;OAKG;IACG,GAAG,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqD5D,wCAAwC;IAClC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B"}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* LocalSandboxRunner — 默认本地 exec, 把 BashTool 现有 execFile 调用包到 SandboxRunner 接口
|
|
3
|
-
*
|
|
4
|
-
* Sprint 1c-revive-3-D-12 (2026-06-05): 这是 BashTool 行为事实的拆解版. BashTool 1.0
|
|
5
|
-
* 的"本地执行" 走 execFile(command, args, { cwd, maxBuffer, timeout }) —— 本 runner
|
|
6
|
-
* 不改语义, 重新组织返回形状到 SandboxRunResult. 默认 stdout cap 4KB 替换原 10MB
|
|
7
|
-
* maxBuffer (10MB 对 LLM 太大, cap 末尾 4KB 跟 verify-runner 一致).
|
|
8
|
-
*
|
|
9
|
-
* 安全边界: 不在这里加 cwd 校验 / dangerous pattern / allowlist — caller (BashTool)
|
|
10
|
-
* 入口已经做完, 这里只跑过白名单的命令.
|
|
11
|
-
*
|
|
12
|
-
* 实现注意: 用 execFile callback 的 stdout/stderr 参数做 cap. Node 16+ 默认 encoding
|
|
13
|
-
* 是 'utf8' (返回 string), 早期 Node 是 Buffer. 兼容方式: 强 encoding: 'buffer' 拿
|
|
14
|
-
* Buffer. 这样 cap 跟 utf8 decode 顺序明确.
|
|
15
|
-
*/
|
|
16
|
-
import { execFile } from 'node:child_process';
|
|
17
|
-
/**
|
|
18
|
-
* 末尾 cap bytes — Buffer.concat 重建独立 Buffer (跟 verify-runner 同样的 ts 5.x 严格模式坑).
|
|
19
|
-
*/
|
|
20
|
-
function capTail(buf, cap) {
|
|
21
|
-
if (buf.length <= cap)
|
|
22
|
-
return buf;
|
|
23
|
-
return Buffer.from(buf.subarray(buf.length - cap));
|
|
24
|
-
}
|
|
25
|
-
export class LocalSandboxRunner {
|
|
26
|
-
kind = 'local';
|
|
27
|
-
/**
|
|
28
|
-
* 跑命令. 不抛异常 — 失败 / timeout 都在 result 里.
|
|
29
|
-
*
|
|
30
|
-
* 走 execFile 自身的 timeout 选项 (Node.js 内置): 到点 execFile 会 kill child +
|
|
31
|
-
* 触发 callback 的 err. err.killed / err.signal 拿来填 SandboxRunResult.signal.
|
|
32
|
-
*/
|
|
33
|
-
async run(req) {
|
|
34
|
-
const start = Date.now();
|
|
35
|
-
const cap = req.stdoutCapBytes;
|
|
36
|
-
return new Promise((resolve) => {
|
|
37
|
-
execFile(req.command, [...req.args], {
|
|
38
|
-
cwd: req.cwd,
|
|
39
|
-
env: req.env ? { ...process.env, ...req.env } : process.env,
|
|
40
|
-
maxBuffer: 10 * 1024 * 1024, // 10MB hard ceiling
|
|
41
|
-
timeout: req.timeoutMs,
|
|
42
|
-
killSignal: 'SIGTERM',
|
|
43
|
-
encoding: 'buffer', // 拿 Buffer 不用 deal with string/Buffer 歧义
|
|
44
|
-
}, (err, stdout, stderr) => {
|
|
45
|
-
const durationMs = Date.now() - start;
|
|
46
|
-
if (err) {
|
|
47
|
-
const e = err;
|
|
48
|
-
const isSignalKill = e.signal === 'SIGTERM' || e.signal === 'SIGKILL' || e.killed;
|
|
49
|
-
const exitCode = typeof e.code === 'number'
|
|
50
|
-
? e.code
|
|
51
|
-
: typeof e.code === 'string' && /^\d+$/.test(e.code)
|
|
52
|
-
? Number(e.code)
|
|
53
|
-
: null;
|
|
54
|
-
resolve({
|
|
55
|
-
ok: false,
|
|
56
|
-
exitCode,
|
|
57
|
-
stdoutTail: capTail(stdout, cap).toString('utf8'),
|
|
58
|
-
stderrTail: capTail(stderr, cap).toString('utf8'),
|
|
59
|
-
durationMs,
|
|
60
|
-
...(isSignalKill ? { signal: 'SIGTERM' } : {}),
|
|
61
|
-
});
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
resolve({
|
|
65
|
-
ok: true,
|
|
66
|
-
exitCode: 0,
|
|
67
|
-
stdoutTail: capTail(stdout, cap).toString('utf8'),
|
|
68
|
-
stderrTail: capTail(stderr, cap).toString('utf8'),
|
|
69
|
-
durationMs,
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
/** Local mode 无外部资源, cleanup 是 noop. */
|
|
75
|
-
async cleanup() {
|
|
76
|
-
// noop — local exec 跑完进程就退出, 没有需要清理的
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
//# sourceMappingURL=local-runner.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-runner.js","sourceRoot":"","sources":["../../src/sandbox/local-runner.ts"],"names":[],"mappings":"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"}
|
package/dist/sandbox/types.d.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SandboxRunner 抽象 — BashTool 跟执行环境 (local / docker) 解耦
|
|
3
|
-
*
|
|
4
|
-
* Sprint 1c-revive-3-D-12 (2026-06-05): 把 BashTool 里的 execFile 抽出来, 让 docker
|
|
5
|
-
* sandbox 可以替换而不动工具逻辑. interface 设计原则:
|
|
6
|
-
* - 命令/参数已过 allowlist + dangerous pattern (BashTool 入口做), sandbox 不重复
|
|
7
|
-
* - cwd 已过 SANDBOX_ROOT 校验, sandbox 不再防 cd 跳出
|
|
8
|
-
* - env 由 caller 过滤 (不传 DEEPSEEK_API_KEY / .env 之类)
|
|
9
|
-
* - timeoutMs 走调用方 clamp, 内部不再二次检查
|
|
10
|
-
* - 失败分两种: 命令跑挂 (ok=false, exitCode != 0) vs spawn 失败 (exitCode=null)
|
|
11
|
-
*
|
|
12
|
-
* MVP 边界: 这是执行环境抽象, **不是** 完整安全策略语言. 文档 .hermes/plans/d12/D12-PLAN.md
|
|
13
|
-
* 写了威胁模型 + 已知风险.
|
|
14
|
-
*/
|
|
15
|
-
/** 一个 sandbox 执行请求 — 已经过 BashTool 入口校验. */
|
|
16
|
-
export interface SandboxRunRequest {
|
|
17
|
-
/** 已被 allowlist 通过的命令名 (e.g. 'ls', 'node', 'pnpm'). 不再二次校验. */
|
|
18
|
-
readonly command: string;
|
|
19
|
-
/** 命令参数, 已是 string[]. 不再二次 dangerous pattern 检查. */
|
|
20
|
-
readonly args: readonly string[];
|
|
21
|
-
/** 工作目录, **绝对路径**, 已被 pathResolve + SANDBOX_ROOT 防跳出检查. */
|
|
22
|
-
readonly cwd: string;
|
|
23
|
-
/** 环境变量. MVP: 由 caller 过滤敏感 (DEEPSEEK_API_KEY / ANTHROPIC_AUTH_TOKEN 不传). */
|
|
24
|
-
readonly env?: Readonly<Record<string, string>>;
|
|
25
|
-
/** 超时毫秒. BashTool 默认 60_000, Docker mode clamp 到 10 分钟. */
|
|
26
|
-
readonly timeoutMs: number;
|
|
27
|
-
/** stdout 保留尾 N bytes. MVP 默认 4KB (跟 VerifyCheck 一致). */
|
|
28
|
-
readonly stdoutCapBytes: number;
|
|
29
|
-
}
|
|
30
|
-
/** 一个 sandbox 执行结果. */
|
|
31
|
-
export interface SandboxRunResult {
|
|
32
|
-
/** exitCode === 0 时为 true. 包含 timeout / signal / spawn 失败都 false. */
|
|
33
|
-
readonly ok: boolean;
|
|
34
|
-
/** 进程退出码. spawn 失败 / signal kill 时为 null. */
|
|
35
|
-
readonly exitCode: number | null;
|
|
36
|
-
/** 末尾 N bytes stdout (utf8 decode). */
|
|
37
|
-
readonly stdoutTail: string;
|
|
38
|
-
/** 末尾 N bytes stderr (utf8 decode). */
|
|
39
|
-
readonly stderrTail: string;
|
|
40
|
-
/** 实际耗时. */
|
|
41
|
-
readonly durationMs: number;
|
|
42
|
-
/** 超时 / 主动 kill 时记录信号名. */
|
|
43
|
-
readonly signal?: 'SIGTERM' | 'SIGKILL';
|
|
44
|
-
/** Cleanup 失败 / docker 不存在等非致命警告. 真实失败进 error 而非 warning. */
|
|
45
|
-
readonly warning?: string;
|
|
46
|
-
}
|
|
47
|
-
/** 沙箱执行器抽象. */
|
|
48
|
-
export interface SandboxRunner {
|
|
49
|
-
/** 区分实现 — 给 caller 用于 log / 调试 / 拒绝某个 kind. */
|
|
50
|
-
readonly kind: 'local' | 'docker';
|
|
51
|
-
/**
|
|
52
|
-
* 执行命令. 不抛异常 (除非参数类型根本不对, 那是 caller bug):
|
|
53
|
-
* - 命令跑挂 → result.ok=false
|
|
54
|
-
* - spawn 失败 → result.exitCode=null
|
|
55
|
-
* - 超时 → result.signal=SIGTERM/SIGKILL, result.ok=false
|
|
56
|
-
* - cleanup 失败 → result.warning 含 stderr tail
|
|
57
|
-
*/
|
|
58
|
-
run(req: SandboxRunRequest): Promise<SandboxRunResult>;
|
|
59
|
-
/**
|
|
60
|
-
* 主动清理资源 (docker container 等). **不抛异常**, 错误进 stderr warning.
|
|
61
|
-
* Local mode 是 noop. 多次调用幂等.
|
|
62
|
-
*/
|
|
63
|
-
cleanup?(): Promise<void>;
|
|
64
|
-
}
|
|
65
|
-
/** 默认 sandbox 选项 — BashTool 构造时没传 runner 用这套. */
|
|
66
|
-
export interface SandboxDefaults {
|
|
67
|
-
readonly defaultTimeoutMs: number;
|
|
68
|
-
readonly defaultStdoutCapBytes: number;
|
|
69
|
-
/**
|
|
70
|
-
* 沙箱根目录, BashTool 入口 cwd 校验用. Default = process.cwd() at construct time.
|
|
71
|
-
**必须**给 — 类型故意必填, 避免 process.cwd() 漂移. factory 拿不到时抛错给 caller.
|
|
72
|
-
*/
|
|
73
|
-
readonly sandboxRoot: string;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* 默认值常量. 故意只填 defaultTimeoutMs + defaultStdoutCapBytes. sandboxRoot 留空
|
|
77
|
-
* 字符串 — caller 必须传真值, 拿到空字符串时 BashTool ctor 会拒绝 (见构造实现).
|
|
78
|
-
*/
|
|
79
|
-
export declare const DEFAULT_SANDBOX_DEFAULTS: SandboxDefaults;
|
|
80
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,2CAA2C;AAC3C,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,uBAAuB;AACvB,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,uCAAuC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,YAAY;IACZ,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,2BAA2B;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IACxC,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,eAAe;AACf,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC;;;;;;OAMG;IACH,GAAG,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACvD;;;OAGG;IACH,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,eAKtC,CAAC"}
|
package/dist/sandbox/types.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SandboxRunner 抽象 — BashTool 跟执行环境 (local / docker) 解耦
|
|
3
|
-
*
|
|
4
|
-
* Sprint 1c-revive-3-D-12 (2026-06-05): 把 BashTool 里的 execFile 抽出来, 让 docker
|
|
5
|
-
* sandbox 可以替换而不动工具逻辑. interface 设计原则:
|
|
6
|
-
* - 命令/参数已过 allowlist + dangerous pattern (BashTool 入口做), sandbox 不重复
|
|
7
|
-
* - cwd 已过 SANDBOX_ROOT 校验, sandbox 不再防 cd 跳出
|
|
8
|
-
* - env 由 caller 过滤 (不传 DEEPSEEK_API_KEY / .env 之类)
|
|
9
|
-
* - timeoutMs 走调用方 clamp, 内部不再二次检查
|
|
10
|
-
* - 失败分两种: 命令跑挂 (ok=false, exitCode != 0) vs spawn 失败 (exitCode=null)
|
|
11
|
-
*
|
|
12
|
-
* MVP 边界: 这是执行环境抽象, **不是** 完整安全策略语言. 文档 .hermes/plans/d12/D12-PLAN.md
|
|
13
|
-
* 写了威胁模型 + 已知风险.
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
|
-
* 默认值常量. 故意只填 defaultTimeoutMs + defaultStdoutCapBytes. sandboxRoot 留空
|
|
17
|
-
* 字符串 — caller 必须传真值, 拿到空字符串时 BashTool ctor 会拒绝 (见构造实现).
|
|
18
|
-
*/
|
|
19
|
-
export const DEFAULT_SANDBOX_DEFAULTS = {
|
|
20
|
-
defaultTimeoutMs: 60_000,
|
|
21
|
-
defaultStdoutCapBytes: 4 * 1024,
|
|
22
|
-
// 占位, 实际 BashTool ctor 拿到 sandboxRoot 为空字符串时 throw
|
|
23
|
-
sandboxRoot: '',
|
|
24
|
-
};
|
|
25
|
-
//# sourceMappingURL=types.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAkEH;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAoB;IACvD,gBAAgB,EAAE,MAAM;IACxB,qBAAqB,EAAE,CAAC,GAAG,IAAI;IAC/B,mDAAmD;IACnD,WAAW,EAAE,EAAE;CAChB,CAAC"}
|
package/dist/tools/bash.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* bash 工具 — 在白名单内执行 shell 命令
|
|
3
|
-
*
|
|
4
|
-
* Sprint 0.2 范围:本地直接 exec(**沙箱挪 Sprint 2**)
|
|
5
|
-
* Sprint 0.2 简化版安全措施:
|
|
6
|
-
* - 命令白名单(v1.0 = ls/cat/grep/find/echo/pwd/cd/head/tail/wc/cp/mv/mkdir/rm)
|
|
7
|
-
* - 危险 token 黑名单(rm -rf /、sudo、curl、wget)
|
|
8
|
-
*
|
|
9
|
-
* Sprint 1+ 增强:Docker sandbox 统一(arch §2.3 ROADMAP 红线)
|
|
10
|
-
* Sprint 1c-revive-3-D-12 (2026-06-05): BashTool 接入 SandboxRunner 抽象.
|
|
11
|
-
* 默认 sandboxRunner = LocalSandboxRunner (现状行为). 可注入 DockerSandboxRunner
|
|
12
|
-
* 跑容器化命令. BashTool 入口的 allowlist + dangerous pattern + cwd 校验不变.
|
|
13
|
-
*/
|
|
14
|
-
import type { ToolName } from '@deepwhale/core';
|
|
15
|
-
import type { Tool, ToolInputSchema, ToolResult } from '../types.js';
|
|
16
|
-
import type { SandboxRunner } from '../sandbox/types.js';
|
|
17
|
-
export declare class BashTool implements Tool {
|
|
18
|
-
private readonly sandboxRunner;
|
|
19
|
-
private readonly sandboxDefaults;
|
|
20
|
-
readonly name: ToolName;
|
|
21
|
-
readonly description = "Execute a whitelisted shell command. v1.0 command allowlist; dangerous patterns (rm -rf /, sudo, curl|sh) are blocked.";
|
|
22
|
-
readonly risk: 'low' | 'medium' | 'high';
|
|
23
|
-
readonly schema: ToolInputSchema;
|
|
24
|
-
/**
|
|
25
|
-
* Sprint 1c-revive-3-D-12 (2026-06-05): sandbox runner 注入点. 默认 = LocalSandboxRunner
|
|
26
|
-
* (BashTool 现状行为). 测试 / 外部可传 DockerSandboxRunner. BashTool 入口的 allowlist
|
|
27
|
-
* + dangerous pattern + cwd 校验 **不** 依赖 runner — runner 只跑过白名单的命令.
|
|
28
|
-
*/
|
|
29
|
-
constructor(sandboxRunner?: SandboxRunner, sandboxDefaults?: {
|
|
30
|
-
defaultTimeoutMs: number;
|
|
31
|
-
defaultStdoutCapBytes: number;
|
|
32
|
-
});
|
|
33
|
-
execute(input: Record<string, unknown>): Promise<ToolResult>;
|
|
34
|
-
}
|
|
35
|
-
//# sourceMappingURL=bash.d.ts.map
|
package/dist/tools/bash.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,qBAAqB,CAAC;AAkF5E,qBAAa,QAAS,YAAW,IAAI;IA0BjC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IA1BlC,QAAQ,CAAC,IAAI,EAAa,QAAQ,CAAC;IACnC,QAAQ,CAAC,WAAW,4HACuG;IAC3H,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAU;IAElD,QAAQ,CAAC,MAAM,EAAE,eAAe,CAY9B;IAEF;;;;OAIG;gBAEgB,aAAa,GAAE,aAAwC,EACvD,eAAe,GAAE;QAChC,gBAAgB,EAAE,MAAM,CAAC;QACzB,qBAAqB,EAAE,MAAM,CAAC;KAI/B;IAGG,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;CAqHnE"}
|
package/dist/tools/bash.js
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* bash 工具 — 在白名单内执行 shell 命令
|
|
3
|
-
*
|
|
4
|
-
* Sprint 0.2 范围:本地直接 exec(**沙箱挪 Sprint 2**)
|
|
5
|
-
* Sprint 0.2 简化版安全措施:
|
|
6
|
-
* - 命令白名单(v1.0 = ls/cat/grep/find/echo/pwd/cd/head/tail/wc/cp/mv/mkdir/rm)
|
|
7
|
-
* - 危险 token 黑名单(rm -rf /、sudo、curl、wget)
|
|
8
|
-
*
|
|
9
|
-
* Sprint 1+ 增强:Docker sandbox 统一(arch §2.3 ROADMAP 红线)
|
|
10
|
-
* Sprint 1c-revive-3-D-12 (2026-06-05): BashTool 接入 SandboxRunner 抽象.
|
|
11
|
-
* 默认 sandboxRunner = LocalSandboxRunner (现状行为). 可注入 DockerSandboxRunner
|
|
12
|
-
* 跑容器化命令. BashTool 入口的 allowlist + dangerous pattern + cwd 校验不变.
|
|
13
|
-
*/
|
|
14
|
-
import { resolve as pathResolve, sep as pathSep } from 'node:path';
|
|
15
|
-
import process from 'node:process';
|
|
16
|
-
import { LocalSandboxRunner } from '../sandbox/local-runner.js';
|
|
17
|
-
const ALLOWED_COMMANDS = new Set([
|
|
18
|
-
'ls',
|
|
19
|
-
'cat',
|
|
20
|
-
'head',
|
|
21
|
-
'tail',
|
|
22
|
-
'wc',
|
|
23
|
-
'grep',
|
|
24
|
-
'find',
|
|
25
|
-
'echo',
|
|
26
|
-
'pwd',
|
|
27
|
-
'cp',
|
|
28
|
-
'mv',
|
|
29
|
-
'mkdir',
|
|
30
|
-
'rmdir',
|
|
31
|
-
'rm',
|
|
32
|
-
'touch',
|
|
33
|
-
'stat',
|
|
34
|
-
'file',
|
|
35
|
-
'tree',
|
|
36
|
-
'node',
|
|
37
|
-
'pnpm',
|
|
38
|
-
'npm',
|
|
39
|
-
'npx',
|
|
40
|
-
'tsc',
|
|
41
|
-
'tsx',
|
|
42
|
-
'git',
|
|
43
|
-
]);
|
|
44
|
-
/**
|
|
45
|
-
* 危险模式黑名单。Sprint 0.2 简化版只挡"立即破坏"模式。
|
|
46
|
-
* Sprint 1+ 会接 sandbox 红线(arch §2.3),这里只防"最常见误操作"。
|
|
47
|
-
*
|
|
48
|
-
* 设计原则:
|
|
49
|
-
* - 只对**字符串**匹配,不在 shell 上下文解释(避免误判/被绕过)
|
|
50
|
-
* - 同时检测 `command` 和 `args` 拼成的完整命令
|
|
51
|
-
* - 危险模式必须**能拒掉真实攻击**,否则不如不加
|
|
52
|
-
*/
|
|
53
|
-
const DANGEROUS_PATTERNS = [
|
|
54
|
-
// rm 任何 -r/-R/-f 组合 + 路径(不限 /),覆盖 `rm -rf .`、`rm -rf ~`、`rm -rf *`
|
|
55
|
-
{ re: /\brm\s+(-\w+\s+)*\S/, reason: 'rm with flags requires sandbox (Sprint 1)' },
|
|
56
|
-
// sudo / su 提权
|
|
57
|
-
{ re: /\bsudo\b/, reason: 'sudo blocked' },
|
|
58
|
-
{ re: /\bsu\s+-?\s*\S/, reason: 'su blocked' },
|
|
59
|
-
// 网络下载 + pipe 执行(curl|sh, wget|bash 等)
|
|
60
|
-
{ re: /\bcurl\b.*\|\s*(sh|bash|zsh|fish)\b/, reason: 'curl | shell blocked' },
|
|
61
|
-
{ re: /\bwget\b.*\|\s*(sh|bash|zsh|fish)\b/, reason: 'wget | shell blocked' },
|
|
62
|
-
// 反引号 / $() 命令替换
|
|
63
|
-
{ re: /`[^`]*`/, reason: 'command substitution backticks blocked' },
|
|
64
|
-
{ re: /\$\([^)]*\)/, reason: 'command substitution $() blocked' },
|
|
65
|
-
// SUID / 设备写 / 格式化
|
|
66
|
-
{ re: /\bchmod\s+\+s\b/, reason: 'SUID chmod blocked' },
|
|
67
|
-
{ re: /\bmkfs\b/, reason: 'mkfs blocked' },
|
|
68
|
-
{ re: /\bdd\s+if=/, reason: 'dd if= blocked' },
|
|
69
|
-
{ re: />\s*\/dev\/sd[a-z]/, reason: 'raw disk write blocked' },
|
|
70
|
-
// shell 链接
|
|
71
|
-
{ re: /\bexec\s+sh\b/, reason: 'exec sh blocked' },
|
|
72
|
-
// 删除 home / etc / 系统目录(额外保护)
|
|
73
|
-
{ re: /\brm\s+(-\w+\s+)*~(?:\s|$)/, reason: 'rm ~ blocked' },
|
|
74
|
-
{ re: /\brm\s+(-\w+\s+)*\/etc(?:\s|$)/, reason: 'rm /etc blocked' },
|
|
75
|
-
];
|
|
76
|
-
/** Sprint 0.2 sandbox 边界:cwd 必须落在此根目录之下。 */
|
|
77
|
-
const SANDBOX_ROOT = pathResolve(process.cwd());
|
|
78
|
-
/**
|
|
79
|
-
* 跨平台 builtin 兜底:返回 string 表示命中(stdout),null 表示走 sandbox。
|
|
80
|
-
*
|
|
81
|
-
* 触发原因:Windows 的 `echo` / `cd` / `dir` 等是 cmd builtin,没有独立 exe,
|
|
82
|
-
* `execFile` 会 spawn ENOENT。Sprint 0.2 简化版只实现 `echo`(最常用 + 测试覆盖)。
|
|
83
|
-
* Sprint 1c-revive-3-D-12: 仍由 BashTool 自身处理, 不进 sandbox (sandbox 是真 exec).
|
|
84
|
-
*/
|
|
85
|
-
function tryBuiltin(command, args) {
|
|
86
|
-
if (command === 'echo') {
|
|
87
|
-
// POSIX `echo` 行为:args 用单空格连接,末尾加 \n
|
|
88
|
-
return args.join(' ') + '\n';
|
|
89
|
-
}
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
export class BashTool {
|
|
93
|
-
sandboxRunner;
|
|
94
|
-
sandboxDefaults;
|
|
95
|
-
name = 'bash';
|
|
96
|
-
description = 'Execute a whitelisted shell command. v1.0 command allowlist; dangerous patterns (rm -rf /, sudo, curl|sh) are blocked.';
|
|
97
|
-
risk = 'high';
|
|
98
|
-
schema = {
|
|
99
|
-
type: 'object',
|
|
100
|
-
properties: {
|
|
101
|
-
command: { type: 'string', description: 'Command (must be in whitelist)' },
|
|
102
|
-
args: {
|
|
103
|
-
type: 'array',
|
|
104
|
-
description: 'Command arguments (array of strings)',
|
|
105
|
-
items: { type: 'string', description: 'arg' },
|
|
106
|
-
},
|
|
107
|
-
cwd: { type: 'string', description: 'Working directory (optional)' },
|
|
108
|
-
},
|
|
109
|
-
required: ['command'],
|
|
110
|
-
};
|
|
111
|
-
/**
|
|
112
|
-
* Sprint 1c-revive-3-D-12 (2026-06-05): sandbox runner 注入点. 默认 = LocalSandboxRunner
|
|
113
|
-
* (BashTool 现状行为). 测试 / 外部可传 DockerSandboxRunner. BashTool 入口的 allowlist
|
|
114
|
-
* + dangerous pattern + cwd 校验 **不** 依赖 runner — runner 只跑过白名单的命令.
|
|
115
|
-
*/
|
|
116
|
-
constructor(sandboxRunner = new LocalSandboxRunner(), sandboxDefaults = {
|
|
117
|
-
defaultTimeoutMs: 60_000,
|
|
118
|
-
defaultStdoutCapBytes: 4 * 1024,
|
|
119
|
-
}) {
|
|
120
|
-
this.sandboxRunner = sandboxRunner;
|
|
121
|
-
this.sandboxDefaults = sandboxDefaults;
|
|
122
|
-
}
|
|
123
|
-
async execute(input) {
|
|
124
|
-
const command = input['command'];
|
|
125
|
-
const args = input['args'];
|
|
126
|
-
const cwd = input['cwd'];
|
|
127
|
-
if (typeof command !== 'string' || command.length === 0) {
|
|
128
|
-
return { success: false, content: '', error: 'invalid-input: command is required' };
|
|
129
|
-
}
|
|
130
|
-
if (!ALLOWED_COMMANDS.has(command)) {
|
|
131
|
-
return {
|
|
132
|
-
success: false,
|
|
133
|
-
content: '',
|
|
134
|
-
error: `permission-denied: command '${command}' is not in allowlist. Allowed: ${Array.from(ALLOWED_COMMANDS).join(', ')}`,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
const argList = Array.isArray(args) ? args : [];
|
|
138
|
-
const fullCommand = `${command} ${argList.join(' ')}`;
|
|
139
|
-
for (const { re, reason } of DANGEROUS_PATTERNS) {
|
|
140
|
-
if (re.test(fullCommand)) {
|
|
141
|
-
return {
|
|
142
|
-
success: false,
|
|
143
|
-
content: '',
|
|
144
|
-
error: `permission-denied: dangerous pattern blocked (${reason}): ${re.source}`,
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
// cwd 必须在 SANDBOX_ROOT 下(防止 `cd ../../..` 跳出)。Sprint 0.2 简化:
|
|
149
|
-
// 不递归扫 argList(避免 shell 逃逸误判),只校验 `cwd` 字段本身。
|
|
150
|
-
const requestedCwd = typeof cwd === 'string' ? cwd : process.cwd();
|
|
151
|
-
const resolvedCwd = pathResolve(requestedCwd);
|
|
152
|
-
const rootWithSep = SANDBOX_ROOT.endsWith(pathSep) ? SANDBOX_ROOT : SANDBOX_ROOT + pathSep;
|
|
153
|
-
if (resolvedCwd !== SANDBOX_ROOT && !resolvedCwd.startsWith(rootWithSep)) {
|
|
154
|
-
return {
|
|
155
|
-
success: false,
|
|
156
|
-
content: '',
|
|
157
|
-
error: `permission-denied: cwd '${requestedCwd}' is outside sandbox root '${SANDBOX_ROOT}'`,
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
// Sprint 0.2 跨平台兜底:少数命令在 Windows 上是 shell builtin(无独立可执行文件),
|
|
161
|
-
// `execFile` 会 ENOENT。这些命令用 Node 内置等价实现,不走 spawn。
|
|
162
|
-
// 后续 Sprint 1+ 沙箱化时整套换掉(arch §2.3)。
|
|
163
|
-
// Sprint 1c-revive-3-D-12: 仍保留 builtin 兜底, 不进 sandbox.
|
|
164
|
-
// Sprint 1c-revive-3-D-12 review P2 修复 (2026-06-05): docker 模式下 builtin
|
|
165
|
-
// 会**绕过**容器 — 跟 sandbox 隔离语义冲突, 也让 integration 假绿 (`echo`
|
|
166
|
-
// 不进容器但仍返 stdout). 修法: docker runner 时跳过 builtin, 交给容器执行.
|
|
167
|
-
// 注意: 只有 `echo` 一个 builtin, 影响面窄; local 模式继续走 builtin 兜底.
|
|
168
|
-
const skipBuiltin = this.sandboxRunner.kind === 'docker';
|
|
169
|
-
if (!skipBuiltin) {
|
|
170
|
-
const builtinResult = tryBuiltin(command, argList);
|
|
171
|
-
if (builtinResult !== null) {
|
|
172
|
-
return {
|
|
173
|
-
success: true,
|
|
174
|
-
content: builtinResult,
|
|
175
|
-
meta: { command, args: argList, builtin: true },
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
// Sprint 1c-revive-3-D-12: 走 sandboxRunner 而不是直接 execFile.
|
|
180
|
-
// BashTool 入口已完成 allowlist / dangerous pattern / cwd 校验, 这里直接调.
|
|
181
|
-
const req = {
|
|
182
|
-
command,
|
|
183
|
-
args: argList,
|
|
184
|
-
cwd: resolvedCwd,
|
|
185
|
-
timeoutMs: this.sandboxDefaults.defaultTimeoutMs,
|
|
186
|
-
stdoutCapBytes: this.sandboxDefaults.defaultStdoutCapBytes,
|
|
187
|
-
};
|
|
188
|
-
try {
|
|
189
|
-
const result = await this.sandboxRunner.run(req);
|
|
190
|
-
if (result.ok) {
|
|
191
|
-
return {
|
|
192
|
-
success: true,
|
|
193
|
-
content: result.stdoutTail + (result.stderrTail ? `\n[stderr]\n${result.stderrTail}` : ''),
|
|
194
|
-
meta: {
|
|
195
|
-
command,
|
|
196
|
-
args: argList,
|
|
197
|
-
sandboxKind: this.sandboxRunner.kind,
|
|
198
|
-
stderr: !!result.stderrTail,
|
|
199
|
-
durationMs: result.durationMs,
|
|
200
|
-
},
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
// 失败 / timeout / spawn fail — 跟 BashTool 现状 execFile catch 行为对齐
|
|
204
|
-
const failureMsg = result.signal !== undefined
|
|
205
|
-
? `execution-failed: killed by ${result.signal} after ${result.durationMs}ms`
|
|
206
|
-
: `execution-failed: exit ${result.exitCode ?? 'unknown'}`;
|
|
207
|
-
return {
|
|
208
|
-
success: false,
|
|
209
|
-
content: result.stdoutTail,
|
|
210
|
-
error: failureMsg +
|
|
211
|
-
(result.stderrTail ? `\nstderr: ${result.stderrTail}` : '') +
|
|
212
|
-
(result.warning ? `\nwarning: ${result.warning}` : ''),
|
|
213
|
-
meta: {
|
|
214
|
-
command,
|
|
215
|
-
sandboxKind: this.sandboxRunner.kind,
|
|
216
|
-
exitCode: result.exitCode,
|
|
217
|
-
signal: result.signal,
|
|
218
|
-
durationMs: result.durationMs,
|
|
219
|
-
},
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
catch (err) {
|
|
223
|
-
// sandboxRunner 自身抛 (e.g. 构造错误) — 兜底 catch
|
|
224
|
-
return {
|
|
225
|
-
success: false,
|
|
226
|
-
content: '',
|
|
227
|
-
error: `execution-failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
228
|
-
meta: { command, sandboxKind: this.sandboxRunner.kind },
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
//# sourceMappingURL=bash.js.map
|
package/dist/tools/bash.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"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"}
|