@zqagent/core 0.2.20 → 0.3.6
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 +1 -1
- package/README.oss.en.md +3 -3
- package/README.oss.md +8 -3
- package/README.oss.zh-TW.md +3 -3
- package/dist/McpClient-CEQBUPuC.d.cts +145 -0
- package/dist/McpClient-CEQBUPuC.d.ts +145 -0
- package/dist/{ToolRegistry-C3pTFiaJ.d.cts → ToolRegistry-Cy0fQxrb.d.ts} +2 -111
- package/dist/{ToolRegistry-C3pTFiaJ.d.ts → ToolRegistry-DouDvn9E.d.cts} +2 -111
- package/dist/{explore-RtZtb-V6.d.ts → TurnEngine-BPKhWuSI.d.cts} +108 -73
- package/dist/{explore-BgRhj6SP.d.cts → TurnEngine-DtGEuVLT.d.ts} +108 -73
- package/dist/conflictGuard-BBOOIxxK.d.cts +42 -0
- package/dist/conflictGuard-BBOOIxxK.d.ts +42 -0
- package/dist/index.cjs +5418 -1096
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +577 -195
- package/dist/index.d.ts +577 -195
- package/dist/index.js +5299 -1011
- package/dist/index.js.map +1 -1
- package/dist/internal/crypto/secrets.cjs +25 -0
- package/dist/internal/crypto/secrets.cjs.map +1 -0
- package/dist/internal/crypto/secrets.d.cts +2 -0
- package/dist/internal/crypto/secrets.d.ts +2 -0
- package/dist/internal/crypto/secrets.js +3 -0
- package/dist/internal/crypto/secrets.js.map +1 -0
- package/dist/internal/engine/FileLogHook.cjs +179 -0
- package/dist/internal/engine/FileLogHook.cjs.map +1 -0
- package/dist/internal/engine/FileLogHook.d.cts +67 -0
- package/dist/internal/engine/FileLogHook.d.ts +67 -0
- package/dist/internal/engine/FileLogHook.js +144 -0
- package/dist/internal/engine/FileLogHook.js.map +1 -0
- package/dist/internal/engine/approvalView.cjs +25 -0
- package/dist/internal/engine/approvalView.cjs.map +1 -0
- package/dist/internal/engine/approvalView.d.cts +1 -0
- package/dist/internal/engine/approvalView.d.ts +1 -0
- package/dist/internal/engine/approvalView.js +3 -0
- package/dist/internal/engine/approvalView.js.map +1 -0
- package/dist/internal/engine/limits.cjs +59 -0
- package/dist/internal/engine/limits.cjs.map +1 -0
- package/dist/internal/engine/limits.d.cts +32 -0
- package/dist/internal/engine/limits.d.ts +32 -0
- package/dist/internal/engine/limits.js +31 -0
- package/dist/internal/engine/limits.js.map +1 -0
- package/dist/internal/engine/sessionNaming.cjs +47 -0
- package/dist/internal/engine/sessionNaming.cjs.map +1 -0
- package/dist/internal/engine/sessionNaming.d.cts +25 -0
- package/dist/internal/engine/sessionNaming.d.ts +25 -0
- package/dist/internal/engine/sessionNaming.js +20 -0
- package/dist/internal/engine/sessionNaming.js.map +1 -0
- package/dist/internal/llmConfig.cjs +561 -0
- package/dist/internal/llmConfig.cjs.map +1 -0
- package/dist/internal/llmConfig.d.cts +75 -0
- package/dist/internal/llmConfig.d.ts +75 -0
- package/dist/internal/llmConfig.js +535 -0
- package/dist/internal/llmConfig.js.map +1 -0
- package/dist/internal/mcp/builtin/index.cjs +685 -0
- package/dist/internal/mcp/builtin/index.cjs.map +1 -0
- package/dist/internal/mcp/builtin/index.d.cts +21 -0
- package/dist/internal/mcp/builtin/index.d.ts +21 -0
- package/dist/internal/mcp/builtin/index.js +652 -0
- package/dist/internal/mcp/builtin/index.js.map +1 -0
- package/dist/internal/mcp/config.cjs +278 -0
- package/dist/internal/mcp/config.cjs.map +1 -0
- package/dist/internal/mcp/config.d.cts +61 -0
- package/dist/internal/mcp/config.d.ts +61 -0
- package/dist/internal/mcp/config.js +235 -0
- package/dist/internal/mcp/config.js.map +1 -0
- package/dist/internal/mcp/presets.cjs +184 -0
- package/dist/internal/mcp/presets.cjs.map +1 -0
- package/dist/internal/mcp/presets.d.cts +39 -0
- package/dist/internal/mcp/presets.d.ts +39 -0
- package/dist/internal/mcp/presets.js +158 -0
- package/dist/internal/mcp/presets.js.map +1 -0
- package/dist/internal/node-name.cjs +45 -0
- package/dist/internal/node-name.cjs.map +1 -0
- package/dist/internal/node-name.d.cts +3 -0
- package/dist/internal/node-name.d.ts +3 -0
- package/dist/internal/node-name.js +10 -0
- package/dist/internal/node-name.js.map +1 -0
- package/dist/internal/paths.cjs +63 -0
- package/dist/internal/paths.cjs.map +1 -0
- package/dist/internal/paths.d.cts +17 -0
- package/dist/internal/paths.d.ts +17 -0
- package/dist/internal/paths.js +25 -0
- package/dist/internal/paths.js.map +1 -0
- package/dist/internal/providers/diagnostics.cjs +288 -0
- package/dist/internal/providers/diagnostics.cjs.map +1 -0
- package/dist/internal/providers/diagnostics.d.cts +103 -0
- package/dist/internal/providers/diagnostics.d.ts +103 -0
- package/dist/internal/providers/diagnostics.js +250 -0
- package/dist/internal/providers/diagnostics.js.map +1 -0
- package/dist/internal/providers/models.cjs +699 -0
- package/dist/internal/providers/models.cjs.map +1 -0
- package/dist/internal/providers/models.d.cts +136 -0
- package/dist/internal/providers/models.d.ts +136 -0
- package/dist/internal/providers/models.js +654 -0
- package/dist/internal/providers/models.js.map +1 -0
- package/dist/internal/terminal.cjs +161 -0
- package/dist/internal/terminal.cjs.map +1 -0
- package/dist/internal/terminal.d.cts +58 -0
- package/dist/internal/terminal.d.ts +58 -0
- package/dist/internal/terminal.js +128 -0
- package/dist/internal/terminal.js.map +1 -0
- package/dist/internal/tools/execAsync.cjs +187 -0
- package/dist/internal/tools/execAsync.cjs.map +1 -0
- package/dist/internal/tools/execAsync.d.cts +30 -0
- package/dist/internal/tools/execAsync.d.ts +30 -0
- package/dist/internal/tools/execAsync.js +162 -0
- package/dist/internal/tools/execAsync.js.map +1 -0
- package/dist/internal/tools/git.cjs +935 -0
- package/dist/internal/tools/git.cjs.map +1 -0
- package/dist/internal/tools/git.d.cts +206 -0
- package/dist/internal/tools/git.d.ts +206 -0
- package/dist/internal/tools/git.js +883 -0
- package/dist/internal/tools/git.js.map +1 -0
- package/dist/internal/tools/pathSafety.cjs +99 -0
- package/dist/internal/tools/pathSafety.cjs.map +1 -0
- package/dist/internal/tools/pathSafety.d.cts +44 -0
- package/dist/internal/tools/pathSafety.d.ts +44 -0
- package/dist/internal/tools/pathSafety.js +61 -0
- package/dist/internal/tools/pathSafety.js.map +1 -0
- package/dist/internal/tools/plan.cjs +146 -0
- package/dist/internal/tools/plan.cjs.map +1 -0
- package/dist/internal/tools/plan.d.cts +48 -0
- package/dist/internal/tools/plan.d.ts +48 -0
- package/dist/internal/tools/plan.js +117 -0
- package/dist/internal/tools/plan.js.map +1 -0
- package/dist/internal/tools/ripgrep.cjs +118 -0
- package/dist/internal/tools/ripgrep.cjs.map +1 -0
- package/dist/internal/tools/ripgrep.d.cts +6 -0
- package/dist/internal/tools/ripgrep.d.ts +6 -0
- package/dist/internal/tools/ripgrep.js +89 -0
- package/dist/internal/tools/ripgrep.js.map +1 -0
- package/dist/internal/tools/sandbox.cjs +253 -0
- package/dist/internal/tools/sandbox.cjs.map +1 -0
- package/dist/internal/tools/sandbox.d.cts +67 -0
- package/dist/internal/tools/sandbox.d.ts +67 -0
- package/dist/internal/tools/sandbox.js +213 -0
- package/dist/internal/tools/sandbox.js.map +1 -0
- package/dist/internal/tools/shell.cjs +771 -0
- package/dist/internal/tools/shell.cjs.map +1 -0
- package/dist/internal/tools/shell.d.cts +47 -0
- package/dist/internal/tools/shell.d.ts +47 -0
- package/dist/internal/tools/shell.js +731 -0
- package/dist/internal/tools/shell.js.map +1 -0
- package/dist/internal/tools/shellRuntime.cjs +220 -0
- package/dist/internal/tools/shellRuntime.cjs.map +1 -0
- package/dist/internal/tools/shellRuntime.d.cts +67 -0
- package/dist/internal/tools/shellRuntime.d.ts +67 -0
- package/dist/internal/tools/shellRuntime.js +181 -0
- package/dist/internal/tools/shellRuntime.js.map +1 -0
- package/dist/internal/update/controller.cjs +1035 -0
- package/dist/internal/update/controller.cjs.map +1 -0
- package/dist/internal/update/controller.d.cts +150 -0
- package/dist/internal/update/controller.d.ts +150 -0
- package/dist/internal/update/controller.js +991 -0
- package/dist/internal/update/controller.js.map +1 -0
- package/dist/internal/update/platform.cjs +234 -0
- package/dist/internal/update/platform.cjs.map +1 -0
- package/dist/internal/update/platform.d.cts +77 -0
- package/dist/internal/update/platform.d.ts +77 -0
- package/dist/internal/update/platform.js +184 -0
- package/dist/internal/update/platform.js.map +1 -0
- package/dist/tools/ask.d.cts +3 -1
- package/dist/tools/ask.d.ts +3 -1
- package/dist/tools/diff.cjs +17 -6
- package/dist/tools/diff.cjs.map +1 -1
- package/dist/tools/diff.d.cts +5 -2
- package/dist/tools/diff.d.ts +5 -2
- package/dist/tools/diff.js +17 -6
- package/dist/tools/diff.js.map +1 -1
- package/dist/tools/directories.d.cts +3 -1
- package/dist/tools/directories.d.ts +3 -1
- package/dist/tools/explore.cjs +1778 -204
- package/dist/tools/explore.cjs.map +1 -1
- package/dist/tools/explore.d.cts +82 -2
- package/dist/tools/explore.d.ts +82 -2
- package/dist/tools/explore.js +1780 -204
- package/dist/tools/explore.js.map +1 -1
- package/dist/tools/files.cjs +56 -21
- package/dist/tools/files.cjs.map +1 -1
- package/dist/tools/files.d.cts +6 -3
- package/dist/tools/files.d.ts +6 -3
- package/dist/tools/files.js +56 -21
- package/dist/tools/files.js.map +1 -1
- package/dist/tools/git.cjs +34 -25
- package/dist/tools/git.cjs.map +1 -1
- package/dist/tools/git.d.cts +4 -204
- package/dist/tools/git.d.ts +4 -204
- package/dist/tools/git.js +34 -25
- package/dist/tools/git.js.map +1 -1
- package/dist/tools/media.cjs +280 -3
- package/dist/tools/media.cjs.map +1 -1
- package/dist/tools/media.d.cts +3 -1
- package/dist/tools/media.d.ts +3 -1
- package/dist/tools/media.js +278 -1
- package/dist/tools/media.js.map +1 -1
- package/dist/tools/plan.cjs +62 -0
- package/dist/tools/plan.cjs.map +1 -1
- package/dist/tools/plan.d.cts +4 -17
- package/dist/tools/plan.d.ts +4 -17
- package/dist/tools/plan.js +59 -0
- package/dist/tools/plan.js.map +1 -1
- package/dist/tools/search.cjs +3 -0
- package/dist/tools/search.cjs.map +1 -1
- package/dist/tools/search.d.cts +3 -1
- package/dist/tools/search.d.ts +3 -1
- package/dist/tools/search.js +3 -0
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/shell.cjs +76 -11
- package/dist/tools/shell.cjs.map +1 -1
- package/dist/tools/shell.d.cts +5 -39
- package/dist/tools/shell.d.ts +5 -39
- package/dist/tools/shell.js +75 -11
- package/dist/tools/shell.js.map +1 -1
- package/dist/tools/todo.d.cts +3 -1
- package/dist/tools/todo.d.ts +3 -1
- package/dist/tools/web.cjs +279 -5
- package/dist/tools/web.cjs.map +1 -1
- package/dist/tools/web.d.cts +3 -1
- package/dist/tools/web.d.ts +3 -1
- package/dist/tools/web.js +275 -3
- package/dist/tools/web.js.map +1 -1
- package/dist/types-BYyXWWPW.d.cts +237 -0
- package/dist/types-BYyXWWPW.d.ts +237 -0
- package/package.json +26 -37
- package/bin/zqagent +0 -2
- package/dist/cli/index.cjs +0 -25218
- package/dist/cli/index.cjs.map +0 -1
- package/dist/cli/index.d.cts +0 -2
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.js +0 -25201
- package/dist/cli/index.js.map +0 -1
- package/dist/server/index.cjs +0 -20510
- package/dist/server/index.cjs.map +0 -1
- package/dist/server/index.d.cts +0 -2
- package/dist/server/index.d.ts +0 -2
- package/dist/server/index.js +0 -20493
- package/dist/server/index.js.map +0 -1
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
// src/tools/sandbox.ts
|
|
2
|
+
import { spawnSync } from "child_process";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import * as os from "os";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
function expandHome(p, env) {
|
|
7
|
+
if (p === "~") return env.HOME ?? p;
|
|
8
|
+
if (p.startsWith("~/") || p.startsWith("~\\")) {
|
|
9
|
+
return path.join(env.HOME ?? "~", p.slice(2));
|
|
10
|
+
}
|
|
11
|
+
return p;
|
|
12
|
+
}
|
|
13
|
+
function toolchainWritable(platform, env) {
|
|
14
|
+
const home = env.HOME ?? os.homedir();
|
|
15
|
+
const rel = platform === "darwin" ? ["Library/pnpm", "Library/Caches", ".npm", ".cache"] : [".npm", ".cache", ".local/share/pnpm", ".local/state/pnpm", ".pnpm-store"];
|
|
16
|
+
return rel.map((r) => path.join(home, r));
|
|
17
|
+
}
|
|
18
|
+
function addToolchainWritable(platform, env, add, exists) {
|
|
19
|
+
for (const dir of toolchainWritable(platform, env)) {
|
|
20
|
+
if (exists(dir)) add(dir);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function collectWritable(opts) {
|
|
24
|
+
const out = /* @__PURE__ */ new Set();
|
|
25
|
+
const add = (p) => {
|
|
26
|
+
if (!p) return;
|
|
27
|
+
const abs = path.resolve(p);
|
|
28
|
+
out.add(abs);
|
|
29
|
+
try {
|
|
30
|
+
out.add(fs.realpathSync(abs));
|
|
31
|
+
} catch {
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
add(opts.workspace);
|
|
35
|
+
if (opts.platform === "darwin") {
|
|
36
|
+
const tmp = os.tmpdir();
|
|
37
|
+
add(tmp);
|
|
38
|
+
add("/tmp");
|
|
39
|
+
add("/private/tmp");
|
|
40
|
+
add("/dev");
|
|
41
|
+
addToolchainWritable(opts.platform, opts.env, add, opts.exists);
|
|
42
|
+
} else if (opts.platform !== "win32") {
|
|
43
|
+
add("/tmp");
|
|
44
|
+
add("/dev");
|
|
45
|
+
addToolchainWritable(opts.platform, opts.env, add, opts.exists);
|
|
46
|
+
}
|
|
47
|
+
for (const raw of opts.extraWritable) {
|
|
48
|
+
const expanded = expandHome(String(raw ?? "").trim(), opts.env);
|
|
49
|
+
if (!expanded) continue;
|
|
50
|
+
add(path.resolve(opts.workspace, expanded));
|
|
51
|
+
}
|
|
52
|
+
return [...out];
|
|
53
|
+
}
|
|
54
|
+
function defaultProbe(backend, bin) {
|
|
55
|
+
const args = backend === "sandbox-exec" ? ["-p", "(version 1)(allow default)", "/bin/sh", "-c", "true"] : ["--ro-bind", "/", "/", "--dev-bind", "/dev", "/dev", "--", "/bin/true"];
|
|
56
|
+
try {
|
|
57
|
+
const r = spawnSync(bin, args, { timeout: 3e3, stdio: "ignore" });
|
|
58
|
+
return r.status === 0;
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function normalizeMode(raw) {
|
|
64
|
+
const v = String(raw ?? "").trim().toLowerCase();
|
|
65
|
+
if (v === "off" || v === "none" || v === "false") return "off";
|
|
66
|
+
if (v === "required" || v === "on" || v === "true") return "required";
|
|
67
|
+
return "auto";
|
|
68
|
+
}
|
|
69
|
+
var planCache = /* @__PURE__ */ new Map();
|
|
70
|
+
function resolveSandbox(opts = {}) {
|
|
71
|
+
const platform = opts.platform ?? process.platform;
|
|
72
|
+
const env = opts.env ?? process.env;
|
|
73
|
+
const workspace = path.resolve(opts.workspace ?? process.cwd());
|
|
74
|
+
const mode = normalizeMode(opts.mode ?? env.ZQAGENT_SANDBOX);
|
|
75
|
+
const extraWritable = opts.extraWritable ?? [];
|
|
76
|
+
const pathExists = opts.fileExists ?? ((p) => {
|
|
77
|
+
try {
|
|
78
|
+
return fs.existsSync(p);
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
const writable = collectWritable({
|
|
84
|
+
workspace,
|
|
85
|
+
extraWritable,
|
|
86
|
+
platform,
|
|
87
|
+
env,
|
|
88
|
+
exists: pathExists
|
|
89
|
+
});
|
|
90
|
+
const cacheKey = [
|
|
91
|
+
platform,
|
|
92
|
+
mode,
|
|
93
|
+
workspace,
|
|
94
|
+
writable.join("\0"),
|
|
95
|
+
opts.probe ? "injected" : "default"
|
|
96
|
+
].join("|");
|
|
97
|
+
const cached = planCache.get(cacheKey);
|
|
98
|
+
if (cached && !opts.probe) return cached;
|
|
99
|
+
const finish = (plan) => {
|
|
100
|
+
if (!opts.probe) planCache.set(cacheKey, plan);
|
|
101
|
+
return plan;
|
|
102
|
+
};
|
|
103
|
+
if (mode === "off") {
|
|
104
|
+
return finish({
|
|
105
|
+
backend: "none",
|
|
106
|
+
enforced: false,
|
|
107
|
+
bin: null,
|
|
108
|
+
writable,
|
|
109
|
+
mode,
|
|
110
|
+
reason: "\u6C99\u7BB1\u5DF2\u6309\u914D\u7F6E\u5173\u95ED"
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
const fileExists = opts.fileExists ?? ((p) => {
|
|
114
|
+
try {
|
|
115
|
+
return fs.statSync(p).isFile();
|
|
116
|
+
} catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
const candidate = platform === "darwin" ? { backend: "sandbox-exec", bin: "/usr/bin/sandbox-exec" } : platform === "linux" ? { backend: "bwrap", bin: "/usr/bin/bwrap" } : null;
|
|
121
|
+
if (!candidate) {
|
|
122
|
+
return finish({
|
|
123
|
+
backend: "none",
|
|
124
|
+
enforced: false,
|
|
125
|
+
bin: null,
|
|
126
|
+
writable,
|
|
127
|
+
mode,
|
|
128
|
+
reason: platform === "win32" ? "Windows \u65E0\u96F6\u4F9D\u8D56\u7684\u8FDB\u7A0B\u7EA7\u6587\u4EF6\u7CFB\u7EDF\u6C99\u7BB1\uFF0C\u6539\u7528\u5DE5\u4F5C\u533A\u8DEF\u5F84\u5224\u5B9A" : `\u5E73\u53F0 ${platform} \u65E0\u53D7\u652F\u6301\u7684\u6C99\u7BB1\u540E\u7AEF`
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
if (!fileExists(candidate.bin)) {
|
|
132
|
+
return finish({
|
|
133
|
+
backend: "none",
|
|
134
|
+
enforced: false,
|
|
135
|
+
bin: null,
|
|
136
|
+
writable,
|
|
137
|
+
mode,
|
|
138
|
+
reason: `\u672A\u627E\u5230 ${candidate.bin}\uFF08${candidate.backend === "bwrap" ? "\u5B89\u88C5 bubblewrap \u540E\u53EF\u542F\u7528" : "\u7CFB\u7EDF\u7F3A\u5C11 sandbox-exec"}\uFF09\uFF0C\u6539\u7528\u5DE5\u4F5C\u533A\u8DEF\u5F84\u5224\u5B9A`
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const probe = opts.probe ?? defaultProbe;
|
|
142
|
+
if (!probe(candidate.backend, candidate.bin)) {
|
|
143
|
+
return finish({
|
|
144
|
+
backend: "none",
|
|
145
|
+
enforced: false,
|
|
146
|
+
bin: null,
|
|
147
|
+
writable,
|
|
148
|
+
mode,
|
|
149
|
+
reason: `${candidate.bin} \u63A2\u6D4B\u5931\u8D25\uFF08\u5BB9\u5668\u5185\u53EF\u80FD\u7981\u7528\u4E86 user namespace\uFF09\uFF0C\u6539\u7528\u5DE5\u4F5C\u533A\u8DEF\u5F84\u5224\u5B9A`
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return finish({
|
|
153
|
+
backend: candidate.backend,
|
|
154
|
+
enforced: true,
|
|
155
|
+
bin: candidate.bin,
|
|
156
|
+
writable,
|
|
157
|
+
mode,
|
|
158
|
+
reason: candidate.backend === "sandbox-exec" ? "macOS sandbox-exec\uFF1A\u53EA\u5141\u8BB8\u5199\u5165\u5DE5\u4F5C\u533A\u4E0E\u4E34\u65F6\u76EE\u5F55" : "Linux bubblewrap\uFF1A\u53EA\u5141\u8BB8\u5199\u5165\u5DE5\u4F5C\u533A\u4E0E\u4E34\u65F6\u76EE\u5F55"
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
function sbplString(value) {
|
|
162
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
163
|
+
}
|
|
164
|
+
function buildMacProfile(writable) {
|
|
165
|
+
const rules = writable.map((p) => ` (subpath ${sbplString(p)})`).join("\n");
|
|
166
|
+
return [
|
|
167
|
+
"(version 1)",
|
|
168
|
+
"(allow default)",
|
|
169
|
+
"(deny file-write*)",
|
|
170
|
+
"(allow file-write*",
|
|
171
|
+
rules,
|
|
172
|
+
")"
|
|
173
|
+
].join("\n");
|
|
174
|
+
}
|
|
175
|
+
function buildBwrapArgs(writable, cwd) {
|
|
176
|
+
const args = ["--ro-bind", "/", "/", "--dev-bind", "/dev", "/dev"];
|
|
177
|
+
if (!writable.includes("/tmp")) args.push("--tmpfs", "/tmp");
|
|
178
|
+
for (const dir of writable) {
|
|
179
|
+
if (dir === "/dev" || dir === "/proc") continue;
|
|
180
|
+
args.push("--bind", dir, dir);
|
|
181
|
+
}
|
|
182
|
+
args.push("--chdir", cwd, "--die-with-parent");
|
|
183
|
+
return args;
|
|
184
|
+
}
|
|
185
|
+
function wrapWithSandbox(plan, invocation, ctx) {
|
|
186
|
+
if (!plan || !plan.enforced || !plan.bin) return invocation;
|
|
187
|
+
if (plan.backend === "sandbox-exec") {
|
|
188
|
+
return {
|
|
189
|
+
file: plan.bin,
|
|
190
|
+
argv: ["-p", buildMacProfile(plan.writable), invocation.file, ...invocation.argv]
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
file: plan.bin,
|
|
195
|
+
argv: [...buildBwrapArgs(plan.writable, ctx.cwd), "--", invocation.file, ...invocation.argv]
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function describeSandbox(plan) {
|
|
199
|
+
if (!plan) return "\u672A\u914D\u7F6E";
|
|
200
|
+
return plan.enforced ? plan.reason : `\u672A\u542F\u7528\uFF08${plan.reason}\uFF09`;
|
|
201
|
+
}
|
|
202
|
+
function resetSandboxCache() {
|
|
203
|
+
planCache.clear();
|
|
204
|
+
}
|
|
205
|
+
export {
|
|
206
|
+
buildBwrapArgs,
|
|
207
|
+
buildMacProfile,
|
|
208
|
+
describeSandbox,
|
|
209
|
+
resetSandboxCache,
|
|
210
|
+
resolveSandbox,
|
|
211
|
+
wrapWithSandbox
|
|
212
|
+
};
|
|
213
|
+
//# sourceMappingURL=sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/tools/sandbox.ts"],"sourcesContent":["/**\n * Shell 沙箱(OS 级文件系统约束)\n *\n * 目标:让 `run_shell` 在工作区内可以免审批执行,而不是靠命令名白名单\n * 逐个放行——后者既挡不住 `python -c` 这类间接执行,也让日常开发寸步难行。\n *\n * 各平台取当前可用的最优方案:\n * - macOS:`/usr/bin/sandbox-exec`(SBPL profile)。系统自带,进程级,\n * 毫秒级开销;默认放行读与网络,只把 `file-write*` 收窄到工作区 + 临时目录。\n * - Linux:`bubblewrap`(bwrap)。用 `--ro-bind / /` 把整机只读挂载,\n * 再把工作区 `--bind` 成可写,二者叠加即为「只在工作区内可写」。\n * 需要发行版装了 bwrap 且允许非特权 user namespace(容器里通常需\n * `--security-opt seccomp=unconfined` 或 privileged)。\n * - Windows:没有进程级文件系统沙箱的等价物(AppContainer 需要额外的\n * 原生 helper 与 ACL 配置,不属于零依赖方案)。此处明确返回\n * `enforced: false`,由权限层退化为「工作区路径启发式」判定\n * (见 permissions/workspaceGuard.ts)——它是降低打扰的策略,不是安全边界。\n *\n * 探测结果做进程级缓存:CLI 在 /mode、/agent 等场景会重建引擎,\n * 但沙箱能力不会变,不必每次 spawn 探测进程。\n */\nimport { spawnSync } from \"node:child_process\";\nimport * as fs from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\n/** 沙箱后端 */\nexport type SandboxBackend = \"sandbox-exec\" | \"bwrap\" | \"none\";\n\n/** 配置取值:auto=探测到就用;off=禁用;required=探测不到时明确报错 */\nexport type SandboxMode = \"auto\" | \"off\" | \"required\";\n\nexport interface SandboxOptions {\n mode?: SandboxMode;\n /** 额外可写路径(绝对路径,支持 ~;相对路径按 workspace 解析) */\n extraWritable?: string[];\n /** 工作区根(解析相对路径的额外可写项) */\n workspace?: string;\n platform?: NodeJS.Platform;\n env?: NodeJS.ProcessEnv;\n fileExists?: (p: string) => boolean;\n /** 可用性探测(测试注入);提供时不走缓存 */\n probe?: (backend: Exclude<SandboxBackend, \"none\">, bin: string) => boolean;\n}\n\n/** 沙箱方案(可跨调用复用) */\nexport interface SandboxPlan {\n backend: SandboxBackend;\n /** OS 级文件系统约束是否生效 */\n enforced: boolean;\n /** 沙箱可执行文件;未生效时为 null */\n bin: string | null;\n /** 允许写入的路径(绝对路径,已去重) */\n writable: string[];\n mode: SandboxMode;\n /** 状态说明(日志 / 工具描述用) */\n reason: string;\n}\n\n/** 一次待执行的子进程调用(file + argv,不经 shell 解释) */\nexport interface SandboxInvocation {\n file: string;\n argv: string[];\n}\n\n/** 解析 ~ 与环境变量无关的常见写法 */\nfunction expandHome(p: string, env: NodeJS.ProcessEnv): string {\n if (p === \"~\") return env.HOME ?? p;\n if (p.startsWith(\"~/\") || p.startsWith(\"~\\\\\")) {\n return path.join(env.HOME ?? \"~\", p.slice(2));\n }\n return p;\n}\n\n/**\n * 工具链缓存目录:这些必须可写,否则 `pnpm install` / `npm ci` 会因\n * store / cache 落在工作区外而报 EPERM。只放行缓存与包仓库,\n * 不放行 `~/.ssh`、shell 配置等敏感位置。\n */\nfunction toolchainWritable(\n platform: NodeJS.Platform,\n env: NodeJS.ProcessEnv,\n): string[] {\n const home = env.HOME ?? os.homedir();\n const rel =\n platform === \"darwin\"\n ? [\"Library/pnpm\", \"Library/Caches\", \".npm\", \".cache\"]\n : [\".npm\", \".cache\", \".local/share/pnpm\", \".local/state/pnpm\", \".pnpm-store\"];\n return rel.map((r) => path.join(home, r));\n}\n\n/**\n * 加入工具链缓存目录。\n *\n * 只加**真实存在**的目录:bwrap 对不存在的 bind 源会直接报错并终止整个命令\n * (`Can't find source path ~/.pnpm-store`),一个没装过的缓存目录就能让沙箱\n * 里所有命令失败。缓存目录不存在本身也无所谓——第一次 `pnpm install` 会自己建。\n */\nfunction addToolchainWritable(\n platform: NodeJS.Platform,\n env: NodeJS.ProcessEnv,\n add: (p: string) => void,\n exists: (p: string) => boolean,\n): void {\n for (const dir of toolchainWritable(platform, env)) {\n if (exists(dir)) add(dir);\n }\n}\n\n/** 收集去重后的可写路径(工作区 + 临时目录 + 用户追加) */\nfunction collectWritable(opts: {\n workspace: string;\n extraWritable: string[];\n platform: NodeJS.Platform;\n env: NodeJS.ProcessEnv;\n /** 路径存在性判定(测试可注入) */\n exists: (p: string) => boolean;\n}): string[] {\n const out = new Set<string>();\n const add = (p: string): void => {\n if (!p) return;\n const abs = path.resolve(p);\n out.add(abs);\n // macOS 的 /tmp、/var 都是符号链接,SBPL 按真实路径匹配,两个都加上\n try {\n out.add(fs.realpathSync(abs));\n } catch {\n /* 路径尚不存在:只保留原始绝对路径 */\n }\n };\n\n add(opts.workspace);\n\n if (opts.platform === \"darwin\") {\n const tmp = os.tmpdir();\n add(tmp);\n add(\"/tmp\");\n add(\"/private/tmp\");\n add(\"/dev\");\n addToolchainWritable(opts.platform, opts.env, add, opts.exists);\n } else if (opts.platform !== \"win32\") {\n add(\"/tmp\");\n add(\"/dev\");\n addToolchainWritable(opts.platform, opts.env, add, opts.exists);\n }\n\n for (const raw of opts.extraWritable) {\n const expanded = expandHome(String(raw ?? \"\").trim(), opts.env);\n if (!expanded) continue;\n add(path.resolve(opts.workspace, expanded));\n }\n\n return [...out];\n}\n\n/** 默认探测:真正跑一次最小命令,确认后端在本机可用(含 user namespace 限制) */\nfunction defaultProbe(\n backend: Exclude<SandboxBackend, \"none\">,\n bin: string,\n): boolean {\n const args =\n backend === \"sandbox-exec\"\n ? [\"-p\", \"(version 1)(allow default)\", \"/bin/sh\", \"-c\", \"true\"]\n : [\"--ro-bind\", \"/\", \"/\", \"--dev-bind\", \"/dev\", \"/dev\", \"--\", \"/bin/true\"];\n try {\n const r = spawnSync(bin, args, { timeout: 3000, stdio: \"ignore\" });\n return r.status === 0;\n } catch {\n return false;\n }\n}\n\n/** 是否为正则化的模式取值 */\nfunction normalizeMode(raw: string | undefined): SandboxMode {\n const v = String(raw ?? \"\").trim().toLowerCase();\n if (v === \"off\" || v === \"none\" || v === \"false\") return \"off\";\n if (v === \"required\" || v === \"on\" || v === \"true\") return \"required\";\n return \"auto\";\n}\n\n/** 缓存键:同平台、同模式、同工作区、同追加路径只探测一次 */\nconst planCache = new Map<string, SandboxPlan>();\n\n/**\n * 解析当前平台可用的沙箱方案。\n *\n * `mode: \"off\"` 直接返回未生效;`required` 在探测失败时通过 `reason`\n * 说明原因(调用方可据此拒绝启动或提示用户安装 bwrap)。\n */\nexport function resolveSandbox(opts: SandboxOptions = {}): SandboxPlan {\n const platform = opts.platform ?? process.platform;\n const env = opts.env ?? process.env;\n const workspace = path.resolve(opts.workspace ?? process.cwd());\n const mode = normalizeMode(opts.mode ?? env.ZQAGENT_SANDBOX);\n const extraWritable = opts.extraWritable ?? [];\n // 目录(而非文件)的存在性:缓存目录不存在时不能写进 bind 列表,\n // 否则 bwrap 会因为「源路径不存在」让整条命令失败。\n // 复用 fileExists 注入点,测试可用它模拟「目录都存在」。\n const pathExists: (p: string) => boolean =\n opts.fileExists ??\n ((p: string) => {\n try {\n return fs.existsSync(p);\n } catch {\n return false;\n }\n });\n const writable = collectWritable({\n workspace,\n extraWritable,\n platform,\n env,\n exists: pathExists,\n });\n\n const cacheKey = [\n platform,\n mode,\n workspace,\n writable.join(\"\\u0000\"),\n opts.probe ? \"injected\" : \"default\",\n ].join(\"|\");\n const cached = planCache.get(cacheKey);\n if (cached && !opts.probe) return cached;\n\n const finish = (plan: SandboxPlan): SandboxPlan => {\n if (!opts.probe) planCache.set(cacheKey, plan);\n return plan;\n };\n\n if (mode === \"off\") {\n return finish({\n backend: \"none\",\n enforced: false,\n bin: null,\n writable,\n mode,\n reason: \"沙箱已按配置关闭\",\n });\n }\n\n const fileExists = opts.fileExists ?? ((p: string) => {\n try {\n return fs.statSync(p).isFile();\n } catch {\n return false;\n }\n });\n\n const candidate: { backend: Exclude<SandboxBackend, \"none\">; bin: string } | null =\n platform === \"darwin\"\n ? { backend: \"sandbox-exec\", bin: \"/usr/bin/sandbox-exec\" }\n : platform === \"linux\"\n ? { backend: \"bwrap\", bin: \"/usr/bin/bwrap\" }\n : null;\n\n if (!candidate) {\n return finish({\n backend: \"none\",\n enforced: false,\n bin: null,\n writable,\n mode,\n reason:\n platform === \"win32\"\n ? \"Windows 无零依赖的进程级文件系统沙箱,改用工作区路径判定\"\n : `平台 ${platform} 无受支持的沙箱后端`,\n });\n }\n\n if (!fileExists(candidate.bin)) {\n return finish({\n backend: \"none\",\n enforced: false,\n bin: null,\n writable,\n mode,\n reason: `未找到 ${candidate.bin}(${\n candidate.backend === \"bwrap\" ? \"安装 bubblewrap 后可启用\" : \"系统缺少 sandbox-exec\"\n }),改用工作区路径判定`,\n });\n }\n\n const probe = opts.probe ?? defaultProbe;\n if (!probe(candidate.backend, candidate.bin)) {\n return finish({\n backend: \"none\",\n enforced: false,\n bin: null,\n writable,\n mode,\n reason: `${candidate.bin} 探测失败(容器内可能禁用了 user namespace),改用工作区路径判定`,\n });\n }\n\n return finish({\n backend: candidate.backend,\n enforced: true,\n bin: candidate.bin,\n writable,\n mode,\n reason:\n candidate.backend === \"sandbox-exec\"\n ? \"macOS sandbox-exec:只允许写入工作区与临时目录\"\n : \"Linux bubblewrap:只允许写入工作区与临时目录\",\n });\n}\n\n/** SBPL 字符串字面量转义 */\nfunction sbplString(value: string): string {\n return `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n}\n\n/**\n * 生成 macOS sandbox profile。\n *\n * 采用「allow default + deny file-write* + 白名单放行」而不是\n * 「deny default」:后者要逐项放行进程、信号、sysctl、mach lookup 等,\n * 极易把 git / node / 包管理器弄挂,维护成本也高。这里只收窄写权限,\n * 读与网络保持默认——与 bwrap 方案的能力边界一致。\n */\nexport function buildMacProfile(writable: string[]): string {\n const rules = writable.map((p) => ` (subpath ${sbplString(p)})`).join(\"\\n\");\n return [\n \"(version 1)\",\n \"(allow default)\",\n \"(deny file-write*)\",\n \"(allow file-write*\",\n rules,\n \")\",\n ].join(\"\\n\");\n}\n\n/** 生成 bubblewrap 的参数前缀 */\nexport function buildBwrapArgs(writable: string[], cwd: string): string[] {\n const args: string[] = [\"--ro-bind\", \"/\", \"/\", \"--dev-bind\", \"/dev\", \"/dev\"];\n // /tmp 用独立 tmpfs:避免把宿主机 /tmp 暴露成可写(工作区内的 /tmp 除外)\n if (!writable.includes(\"/tmp\")) args.push(\"--tmpfs\", \"/tmp\");\n for (const dir of writable) {\n if (dir === \"/dev\" || dir === \"/proc\") continue;\n args.push(\"--bind\", dir, dir);\n }\n args.push(\"--chdir\", cwd, \"--die-with-parent\");\n return args;\n}\n\n/**\n * 把一次 shell 调用包进沙箱。\n *\n * 未生效时原样返回(调用方无需分支)。参数一律走 argv,不拼字符串,\n * 避免用户命令中的引号 / 空格影响外层命令。\n */\nexport function wrapWithSandbox(\n plan: SandboxPlan | null | undefined,\n invocation: SandboxInvocation,\n ctx: { cwd: string },\n): SandboxInvocation {\n if (!plan || !plan.enforced || !plan.bin) return invocation;\n\n if (plan.backend === \"sandbox-exec\") {\n return {\n file: plan.bin,\n argv: [\"-p\", buildMacProfile(plan.writable), invocation.file, ...invocation.argv],\n };\n }\n\n return {\n file: plan.bin,\n argv: [...buildBwrapArgs(plan.writable, ctx.cwd), \"--\", invocation.file, ...invocation.argv],\n };\n}\n\n/** 一行状态说明,用于日志与工具描述 */\nexport function describeSandbox(plan: SandboxPlan | null | undefined): string {\n if (!plan) return \"未配置\";\n return plan.enforced ? plan.reason : `未启用(${plan.reason})`;\n}\n\n/** 测试用:清空探测缓存 */\nexport function resetSandboxCache(): void {\n planCache.clear();\n}\n"],"mappings":"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","names":[]}
|