@bike4mind/cli 0.2.29-feat-cli-sandbox.18842 → 0.2.29-feat-cli-sandbox.18843
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BubblewrapRuntime-EJM4QF7U.js → BubblewrapRuntime-HXTR3NQG.js} +6 -6
- package/dist/{SandboxOrchestrator-AEOHC2BL.js → SandboxOrchestrator-Z36SFJ7X.js} +11 -2
- package/dist/{SandboxRuntimeAdapter-SRX3IM2Q.js → SandboxRuntimeAdapter-5ZMU25Q3.js} +1 -1
- package/dist/{SeatbeltRuntime-DZMEIRPM.js → SeatbeltRuntime-SL7HVS3J.js} +17 -13
- package/dist/{chunk-PRJKJWD6.js → chunk-AVAD2PPK.js} +2 -2
- package/dist/{chunk-JJL2EFHA.js → chunk-JWEG53NG.js} +4 -1
- package/dist/{chunk-XPSG72HV.js → chunk-W4TCH4ZT.js} +1 -0
- package/dist/commands/mcpCommand.js +2 -2
- package/dist/index.js +60 -14
- package/dist/{types-2T7ALTCA.js → types-SMQKWHQK.js} +1 -1
- package/package.json +6 -6
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
expandPath,
|
|
4
4
|
isBinaryAvailable
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-AVAD2PPK.js";
|
|
6
6
|
|
|
7
7
|
// src/sandbox/runtime/BubblewrapRuntime.ts
|
|
8
8
|
import os from "os";
|
|
9
|
-
import { existsSync } from "fs";
|
|
10
9
|
var SYSTEM_RO_BINDS = ["/usr", "/bin", "/lib", "/lib64", "/sbin", "/etc"];
|
|
11
10
|
var SPECIAL_MOUNTS = {
|
|
12
11
|
dev: "/dev",
|
|
@@ -27,9 +26,7 @@ var BubblewrapRuntime = class {
|
|
|
27
26
|
const expandedAllowed = filesystemConfig.allowedReadPaths.map(expandPath);
|
|
28
27
|
const args = [];
|
|
29
28
|
for (const sysPath of SYSTEM_RO_BINDS) {
|
|
30
|
-
|
|
31
|
-
args.push("--ro-bind", sysPath, sysPath);
|
|
32
|
-
}
|
|
29
|
+
args.push("--ro-bind-try", sysPath, sysPath);
|
|
33
30
|
}
|
|
34
31
|
args.push("--dev", SPECIAL_MOUNTS.dev);
|
|
35
32
|
args.push("--proc", SPECIAL_MOUNTS.proc);
|
|
@@ -38,7 +35,7 @@ var BubblewrapRuntime = class {
|
|
|
38
35
|
const homeDir = os.homedir();
|
|
39
36
|
args.push("--ro-bind", homeDir, homeDir);
|
|
40
37
|
for (const allowedPath of expandedAllowed) {
|
|
41
|
-
if (!allowedPath.startsWith(homeDir)
|
|
38
|
+
if (!allowedPath.startsWith(homeDir)) {
|
|
42
39
|
args.push("--ro-bind-try", allowedPath, allowedPath);
|
|
43
40
|
}
|
|
44
41
|
}
|
|
@@ -48,6 +45,9 @@ var BubblewrapRuntime = class {
|
|
|
48
45
|
args.push("--unshare-all");
|
|
49
46
|
args.push("--share-net");
|
|
50
47
|
args.push("--die-with-parent");
|
|
48
|
+
if (options.seccompProfile) {
|
|
49
|
+
args.push("--seccomp", options.seccompProfile);
|
|
50
|
+
}
|
|
51
51
|
args.push("--chdir", cwd);
|
|
52
52
|
args.push("bash", "-c", command);
|
|
53
53
|
const commandString = ["bwrap", ...args.map(shellEscape)].join(" ");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DEFAULT_SANDBOX_CONFIG
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-W4TCH4ZT.js";
|
|
5
5
|
|
|
6
6
|
// src/sandbox/SandboxOrchestrator.ts
|
|
7
7
|
var SandboxOrchestrator = class {
|
|
@@ -24,6 +24,12 @@ var SandboxOrchestrator = class {
|
|
|
24
24
|
}
|
|
25
25
|
const baseCommand = this.getBaseCommand(command);
|
|
26
26
|
if (this.isExcludedCommand(baseCommand)) {
|
|
27
|
+
if (!this.config.allowUnsandboxedCommands) {
|
|
28
|
+
return {
|
|
29
|
+
type: "blocked",
|
|
30
|
+
reason: `Command '${baseCommand}' is excluded from sandboxing and unsandboxed commands are not allowed`
|
|
31
|
+
};
|
|
32
|
+
}
|
|
27
33
|
return {
|
|
28
34
|
type: "unsandboxed",
|
|
29
35
|
requiresPermission: true,
|
|
@@ -40,7 +46,10 @@ var SandboxOrchestrator = class {
|
|
|
40
46
|
const wrappedCommand = this.runtime.wrapCommand({
|
|
41
47
|
command,
|
|
42
48
|
cwd,
|
|
43
|
-
filesystemConfig: this.config.filesystem
|
|
49
|
+
filesystemConfig: this.config.filesystem,
|
|
50
|
+
...this.runtime.platform === "linux" && this.config.platform.linux.seccompProfile && {
|
|
51
|
+
seccompProfile: this.config.platform.linux.seccompProfile
|
|
52
|
+
}
|
|
44
53
|
});
|
|
45
54
|
return { type: "sandbox", wrappedCommand };
|
|
46
55
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
expandPath,
|
|
4
4
|
isBinaryAvailable
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-AVAD2PPK.js";
|
|
6
6
|
|
|
7
7
|
// src/sandbox/runtime/SeatbeltRuntime.ts
|
|
8
8
|
import { writeFileSync, mkdtempSync } from "fs";
|
|
@@ -70,18 +70,22 @@ var SeatbeltRuntime = class {
|
|
|
70
70
|
return lines.join("\n");
|
|
71
71
|
}
|
|
72
72
|
wrapCommand(options) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
73
|
+
try {
|
|
74
|
+
const profile = this.generateProfile(options);
|
|
75
|
+
const tmpDir = mkdtempSync(path.join(os.tmpdir(), "b4m-sandbox-"));
|
|
76
|
+
const profilePath = path.join(tmpDir, "sandbox.sb");
|
|
77
|
+
writeFileSync(profilePath, profile, "utf-8");
|
|
78
|
+
const args = ["-f", profilePath, "bash", "-c", options.command];
|
|
79
|
+
return {
|
|
80
|
+
executable: "sandbox-exec",
|
|
81
|
+
args,
|
|
82
|
+
env: options.env ?? {},
|
|
83
|
+
commandString: `sandbox-exec -f ${profilePath} bash -c ${shellEscape(options.command)}`,
|
|
84
|
+
cleanupPaths: [profilePath, tmpDir]
|
|
85
|
+
};
|
|
86
|
+
} catch (err) {
|
|
87
|
+
throw new Error(`Failed to create sandbox profile: ${err instanceof Error ? err.message : String(err)}`);
|
|
88
|
+
}
|
|
85
89
|
}
|
|
86
90
|
};
|
|
87
91
|
function shellEscape(str) {
|
|
@@ -24,12 +24,12 @@ async function createSandboxRuntime() {
|
|
|
24
24
|
const platform = detectPlatform();
|
|
25
25
|
if (!platform) return null;
|
|
26
26
|
if (platform === "darwin") {
|
|
27
|
-
const { SeatbeltRuntime } = await import("./SeatbeltRuntime-
|
|
27
|
+
const { SeatbeltRuntime } = await import("./SeatbeltRuntime-SL7HVS3J.js");
|
|
28
28
|
const runtime = new SeatbeltRuntime();
|
|
29
29
|
return runtime.isAvailable() ? runtime : null;
|
|
30
30
|
}
|
|
31
31
|
if (platform === "linux") {
|
|
32
|
-
const { BubblewrapRuntime } = await import("./BubblewrapRuntime-
|
|
32
|
+
const { BubblewrapRuntime } = await import("./BubblewrapRuntime-HXTR3NQG.js");
|
|
33
33
|
const runtime = new BubblewrapRuntime();
|
|
34
34
|
return runtime.isAvailable() ? runtime : null;
|
|
35
35
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DEFAULT_SANDBOX_CONFIG
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-W4TCH4ZT.js";
|
|
5
5
|
|
|
6
6
|
// src/utils/Logger.ts
|
|
7
7
|
import fs from "fs/promises";
|
|
@@ -285,6 +285,7 @@ var SandboxConfigSchema = z.object({
|
|
|
285
285
|
mode: z.enum(["disabled", "auto-allow", "permissions"]).default("disabled"),
|
|
286
286
|
filesystem: SandboxFilesystemSchema.default(DEFAULT_SANDBOX_CONFIG.filesystem),
|
|
287
287
|
excludedCommands: z.array(z.string()).default(DEFAULT_SANDBOX_CONFIG.excludedCommands),
|
|
288
|
+
allowUnsandboxedCommands: z.boolean().default(true),
|
|
288
289
|
platform: SandboxPlatformSchema.default(DEFAULT_SANDBOX_CONFIG.platform)
|
|
289
290
|
});
|
|
290
291
|
var PartialSandboxConfigSchema = z.object({
|
|
@@ -296,6 +297,7 @@ var PartialSandboxConfigSchema = z.object({
|
|
|
296
297
|
writeOnlyToWorkingDir: z.boolean().optional()
|
|
297
298
|
}).optional(),
|
|
298
299
|
excludedCommands: z.array(z.string()).optional(),
|
|
300
|
+
allowUnsandboxedCommands: z.boolean().optional(),
|
|
299
301
|
platform: SandboxPlatformSchema.optional()
|
|
300
302
|
}).optional();
|
|
301
303
|
var AuthTokensSchema = z.object({
|
|
@@ -546,6 +548,7 @@ function mergeSandboxConfig(base, override) {
|
|
|
546
548
|
...override.filesystem ?? {}
|
|
547
549
|
},
|
|
548
550
|
excludedCommands: override.excludedCommands ?? resolved.excludedCommands,
|
|
551
|
+
allowUnsandboxedCommands: override.allowUnsandboxedCommands ?? resolved.allowUnsandboxedCommands,
|
|
549
552
|
platform: override.platform ?? resolved.platform
|
|
550
553
|
};
|
|
551
554
|
}
|
|
@@ -10,6 +10,7 @@ var DEFAULT_SANDBOX_CONFIG = {
|
|
|
10
10
|
deniedPaths: ["$HOME/.ssh", "$HOME/.aws", "$HOME/.gnupg", "$HOME/.env", "/etc/shadow", "/etc/passwd"]
|
|
11
11
|
},
|
|
12
12
|
excludedCommands: ["docker", "watchman", "podman"],
|
|
13
|
+
allowUnsandboxedCommands: true,
|
|
13
14
|
platform: {
|
|
14
15
|
linux: {
|
|
15
16
|
runtime: "bubblewrap"
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ConfigStore
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-JWEG53NG.js";
|
|
5
|
+
import "../chunk-W4TCH4ZT.js";
|
|
6
6
|
|
|
7
7
|
// src/commands/mcpCommand.ts
|
|
8
8
|
async function handleMcpCommand(subcommand, argv) {
|
package/dist/index.js
CHANGED
|
@@ -10,12 +10,12 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
ConfigStore,
|
|
12
12
|
logger
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-JWEG53NG.js";
|
|
14
14
|
import {
|
|
15
15
|
selectActiveBackgroundAgents,
|
|
16
16
|
useCliStore
|
|
17
17
|
} from "./chunk-TVW4ZESU.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-W4TCH4ZT.js";
|
|
19
19
|
import "./chunk-PKKJ44C5.js";
|
|
20
20
|
import {
|
|
21
21
|
BFLImageService,
|
|
@@ -11759,15 +11759,33 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
11759
11759
|
}
|
|
11760
11760
|
const effectiveArgs = isSandboxed ? sandboxedArgs : args;
|
|
11761
11761
|
if (!permissionManager.needsPermission(toolName, { isSandboxed })) {
|
|
11762
|
-
|
|
11762
|
+
let result2 = await executeTool(toolName, effectiveArgs, apiClient, originalFn);
|
|
11763
11763
|
cleanupSandboxFiles(effectiveArgs?._sandboxCleanup);
|
|
11764
|
+
result2 = await retrySandboxFailure(
|
|
11765
|
+
isSandboxed,
|
|
11766
|
+
result2,
|
|
11767
|
+
toolName,
|
|
11768
|
+
args,
|
|
11769
|
+
apiClient,
|
|
11770
|
+
originalFn,
|
|
11771
|
+
showPermissionPrompt
|
|
11772
|
+
);
|
|
11764
11773
|
agentContext.observationQueue.push({ toolName, result: result2 });
|
|
11765
11774
|
return result2;
|
|
11766
11775
|
}
|
|
11767
11776
|
const { useCliStore: useCliStore2 } = await import("./store-FU6NDC2W.js");
|
|
11768
11777
|
if (useCliStore2.getState().autoAcceptEdits) {
|
|
11769
|
-
|
|
11778
|
+
let result2 = await executeTool(toolName, effectiveArgs, apiClient, originalFn);
|
|
11770
11779
|
cleanupSandboxFiles(effectiveArgs?._sandboxCleanup);
|
|
11780
|
+
result2 = await retrySandboxFailure(
|
|
11781
|
+
isSandboxed,
|
|
11782
|
+
result2,
|
|
11783
|
+
toolName,
|
|
11784
|
+
args,
|
|
11785
|
+
apiClient,
|
|
11786
|
+
originalFn,
|
|
11787
|
+
showPermissionPrompt
|
|
11788
|
+
);
|
|
11771
11789
|
agentContext.observationQueue.push({ toolName, result: result2 });
|
|
11772
11790
|
return result2;
|
|
11773
11791
|
}
|
|
@@ -11830,13 +11848,41 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
11830
11848
|
}
|
|
11831
11849
|
}
|
|
11832
11850
|
}
|
|
11833
|
-
|
|
11851
|
+
let result = await executeTool(toolName, effectiveArgs, apiClient, originalFn);
|
|
11834
11852
|
cleanupSandboxFiles(effectiveArgs?._sandboxCleanup);
|
|
11853
|
+
result = await retrySandboxFailure(
|
|
11854
|
+
isSandboxed,
|
|
11855
|
+
result,
|
|
11856
|
+
toolName,
|
|
11857
|
+
args,
|
|
11858
|
+
apiClient,
|
|
11859
|
+
originalFn,
|
|
11860
|
+
showPermissionPrompt
|
|
11861
|
+
);
|
|
11835
11862
|
agentContext.observationQueue.push({ toolName, result });
|
|
11836
11863
|
return result;
|
|
11837
11864
|
}
|
|
11838
11865
|
};
|
|
11839
11866
|
}
|
|
11867
|
+
function isSandboxFailure(isSandboxed, result) {
|
|
11868
|
+
if (!isSandboxed) return false;
|
|
11869
|
+
return result.includes("sandbox-exec:") || result.includes("bwrap:") || result.includes("Operation not permitted");
|
|
11870
|
+
}
|
|
11871
|
+
async function retrySandboxFailure(isSandboxed, result, toolName, originalArgs, apiClient, originalFn, showPermissionPrompt) {
|
|
11872
|
+
if (!isSandboxFailure(isSandboxed, result)) return result;
|
|
11873
|
+
const errorSnippet = result.slice(0, 200);
|
|
11874
|
+
const retryResponse = await showPermissionPrompt(
|
|
11875
|
+
toolName,
|
|
11876
|
+
originalArgs,
|
|
11877
|
+
`Sandbox execution failed. Retry without sandbox?
|
|
11878
|
+
|
|
11879
|
+
Error: ${errorSnippet}`
|
|
11880
|
+
);
|
|
11881
|
+
if (retryResponse.action !== "deny") {
|
|
11882
|
+
return executeTool(toolName, originalArgs, apiClient, originalFn);
|
|
11883
|
+
}
|
|
11884
|
+
return result;
|
|
11885
|
+
}
|
|
11840
11886
|
function cleanupSandboxFiles(paths) {
|
|
11841
11887
|
if (!paths || paths.length === 0) return;
|
|
11842
11888
|
for (const p of paths) {
|
|
@@ -13643,7 +13689,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
13643
13689
|
// package.json
|
|
13644
13690
|
var package_default = {
|
|
13645
13691
|
name: "@bike4mind/cli",
|
|
13646
|
-
version: "0.2.29-feat-cli-sandbox.
|
|
13692
|
+
version: "0.2.29-feat-cli-sandbox.18843+467f137bc",
|
|
13647
13693
|
type: "module",
|
|
13648
13694
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
13649
13695
|
license: "UNLICENSED",
|
|
@@ -13753,10 +13799,10 @@ var package_default = {
|
|
|
13753
13799
|
},
|
|
13754
13800
|
devDependencies: {
|
|
13755
13801
|
"@bike4mind/agents": "0.1.0",
|
|
13756
|
-
"@bike4mind/common": "2.50.1-feat-cli-sandbox.
|
|
13757
|
-
"@bike4mind/mcp": "1.29.1-feat-cli-sandbox.
|
|
13758
|
-
"@bike4mind/services": "2.48.1-feat-cli-sandbox.
|
|
13759
|
-
"@bike4mind/utils": "2.5.1-feat-cli-sandbox.
|
|
13802
|
+
"@bike4mind/common": "2.50.1-feat-cli-sandbox.18843+467f137bc",
|
|
13803
|
+
"@bike4mind/mcp": "1.29.1-feat-cli-sandbox.18843+467f137bc",
|
|
13804
|
+
"@bike4mind/services": "2.48.1-feat-cli-sandbox.18843+467f137bc",
|
|
13805
|
+
"@bike4mind/utils": "2.5.1-feat-cli-sandbox.18843+467f137bc",
|
|
13760
13806
|
"@types/better-sqlite3": "^7.6.13",
|
|
13761
13807
|
"@types/diff": "^5.0.9",
|
|
13762
13808
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -13773,7 +13819,7 @@ var package_default = {
|
|
|
13773
13819
|
optionalDependencies: {
|
|
13774
13820
|
"@vscode/ripgrep": "^1.17.0"
|
|
13775
13821
|
},
|
|
13776
|
-
gitHead: "
|
|
13822
|
+
gitHead: "467f137bcb738020d1665b78bc7d34de7d846df5"
|
|
13777
13823
|
};
|
|
13778
13824
|
|
|
13779
13825
|
// src/config/constants.ts
|
|
@@ -15779,9 +15825,9 @@ function CliApp() {
|
|
|
15779
15825
|
config.tools.disabled || []
|
|
15780
15826
|
// denied tools from project config
|
|
15781
15827
|
);
|
|
15782
|
-
const { createSandboxRuntime } = await import("./SandboxRuntimeAdapter-
|
|
15783
|
-
const { SandboxOrchestrator } = await import("./SandboxOrchestrator-
|
|
15784
|
-
const { DEFAULT_SANDBOX_CONFIG } = await import("./types-
|
|
15828
|
+
const { createSandboxRuntime } = await import("./SandboxRuntimeAdapter-5ZMU25Q3.js");
|
|
15829
|
+
const { SandboxOrchestrator } = await import("./SandboxOrchestrator-Z36SFJ7X.js");
|
|
15830
|
+
const { DEFAULT_SANDBOX_CONFIG } = await import("./types-SMQKWHQK.js");
|
|
15785
15831
|
const sandboxRuntime = await createSandboxRuntime();
|
|
15786
15832
|
const sandboxConfig = config.sandbox ?? DEFAULT_SANDBOX_CONFIG;
|
|
15787
15833
|
const sandboxOrchestrator = new SandboxOrchestrator(sandboxConfig, sandboxRuntime);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.2.29-feat-cli-sandbox.
|
|
3
|
+
"version": "0.2.29-feat-cli-sandbox.18843+467f137bc",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -110,10 +110,10 @@
|
|
|
110
110
|
},
|
|
111
111
|
"devDependencies": {
|
|
112
112
|
"@bike4mind/agents": "0.1.0",
|
|
113
|
-
"@bike4mind/common": "2.50.1-feat-cli-sandbox.
|
|
114
|
-
"@bike4mind/mcp": "1.29.1-feat-cli-sandbox.
|
|
115
|
-
"@bike4mind/services": "2.48.1-feat-cli-sandbox.
|
|
116
|
-
"@bike4mind/utils": "2.5.1-feat-cli-sandbox.
|
|
113
|
+
"@bike4mind/common": "2.50.1-feat-cli-sandbox.18843+467f137bc",
|
|
114
|
+
"@bike4mind/mcp": "1.29.1-feat-cli-sandbox.18843+467f137bc",
|
|
115
|
+
"@bike4mind/services": "2.48.1-feat-cli-sandbox.18843+467f137bc",
|
|
116
|
+
"@bike4mind/utils": "2.5.1-feat-cli-sandbox.18843+467f137bc",
|
|
117
117
|
"@types/better-sqlite3": "^7.6.13",
|
|
118
118
|
"@types/diff": "^5.0.9",
|
|
119
119
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -130,5 +130,5 @@
|
|
|
130
130
|
"optionalDependencies": {
|
|
131
131
|
"@vscode/ripgrep": "^1.17.0"
|
|
132
132
|
},
|
|
133
|
-
"gitHead": "
|
|
133
|
+
"gitHead": "467f137bcb738020d1665b78bc7d34de7d846df5"
|
|
134
134
|
}
|