@madarco/agentbox 0.13.0 → 0.15.0

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.
Files changed (74) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/README.md +11 -8
  3. package/dist/{_cloud-attach-HJC672UR.js → _cloud-attach-R6TRWG5L.js} +4 -4
  4. package/dist/{chunk-QYRK5H6Q.js → chunk-43Q5GWP6.js} +108 -56
  5. package/dist/chunk-43Q5GWP6.js.map +1 -0
  6. package/dist/{chunk-ECLLV5JH.js → chunk-72CJTXN6.js} +156 -5
  7. package/dist/chunk-72CJTXN6.js.map +1 -0
  8. package/dist/{chunk-R5XIDQFR.js → chunk-BKU34KYY.js} +170 -6
  9. package/dist/chunk-BKU34KYY.js.map +1 -0
  10. package/dist/{chunk-4NQXNQ53.js → chunk-E7CHS7ZR.js} +168 -58
  11. package/dist/chunk-E7CHS7ZR.js.map +1 -0
  12. package/dist/chunk-MCOU6CZS.js +346 -0
  13. package/dist/chunk-MCOU6CZS.js.map +1 -0
  14. package/dist/{chunk-B4QG2MCW.js → chunk-MLMFNN4T.js} +762 -483
  15. package/dist/chunk-MLMFNN4T.js.map +1 -0
  16. package/dist/{chunk-2LF5YILI.js → chunk-RSKG7AFU.js} +80 -6
  17. package/dist/chunk-RSKG7AFU.js.map +1 -0
  18. package/dist/{chunk-SNTHHWKY.js → chunk-XKH7NTT7.js} +80 -22
  19. package/dist/chunk-XKH7NTT7.js.map +1 -0
  20. package/dist/{dist-7KVUIKJX.js → dist-AGTIA7AD.js} +37 -226
  21. package/dist/dist-AGTIA7AD.js.map +1 -0
  22. package/dist/{dist-OPIBZ7XM.js → dist-FIFEFKJ7.js} +14 -69
  23. package/dist/dist-FIFEFKJ7.js.map +1 -0
  24. package/dist/dist-JZ3XO6EB.js +662 -0
  25. package/dist/dist-JZ3XO6EB.js.map +1 -0
  26. package/dist/{dist-OG6NW6SM.js → dist-OGJGZETZ.js} +5 -3
  27. package/dist/{dist-JAN5VABY.js → dist-S4XR4ACV.js} +25 -177
  28. package/dist/dist-S4XR4ACV.js.map +1 -0
  29. package/dist/index.js +2229 -1314
  30. package/dist/index.js.map +1 -1
  31. package/dist/{prepared-state-MQHD3M5F-KE4DT3GX.js → prepared-state-MQHD3M5F-Q27AZU53.js} +2 -2
  32. package/package.json +6 -4
  33. package/runtime/docker/Dockerfile.box +21 -26
  34. package/runtime/docker/apps/cli/share/agentbox-setup/SKILL.md +67 -1
  35. package/runtime/docker/packages/ctl/dist/bin.cjs +361 -43
  36. package/runtime/docker/packages/sandbox-docker/scripts/agentbox-vnc-start +17 -6
  37. package/runtime/docker/packages/sandbox-docker/scripts/chromium-resolver +57 -0
  38. package/runtime/docker/packages/sandbox-docker/scripts/claude-managed-settings.json +2 -1
  39. package/runtime/e2b/agentbox-checkpoint-cleanup +52 -0
  40. package/runtime/e2b/agentbox-codex-hooks.json +68 -0
  41. package/runtime/e2b/agentbox-open +28 -0
  42. package/runtime/e2b/agentbox-setup-skill.md +263 -0
  43. package/runtime/e2b/agentbox-vnc-start +102 -0
  44. package/runtime/e2b/attach-helper.cjs +167 -0
  45. package/runtime/e2b/claude-managed-settings.json +116 -0
  46. package/runtime/e2b/ctl.cjs +24158 -0
  47. package/runtime/e2b/custom-system-CLAUDE.md +46 -0
  48. package/runtime/e2b/gh-shim +344 -0
  49. package/runtime/e2b/git-shim +131 -0
  50. package/runtime/e2b/scripts/build-template.sh +295 -0
  51. package/runtime/hetzner/agentbox-setup-skill.md +67 -1
  52. package/runtime/hetzner/agentbox-vnc-start +17 -6
  53. package/runtime/hetzner/claude-managed-settings.json +2 -1
  54. package/runtime/hetzner/ctl.cjs +361 -43
  55. package/runtime/relay/bin.cjs +380 -233
  56. package/runtime/vercel/agentbox-setup-skill.md +67 -1
  57. package/runtime/vercel/agentbox-vnc-start +17 -6
  58. package/runtime/vercel/claude-managed-settings.json +2 -1
  59. package/runtime/vercel/ctl.cjs +361 -43
  60. package/share/agentbox-setup/SKILL.md +67 -1
  61. package/share/host-skills/agentbox-info/SKILL.md +47 -35
  62. package/dist/chunk-2LF5YILI.js.map +0 -1
  63. package/dist/chunk-4NQXNQ53.js.map +0 -1
  64. package/dist/chunk-B4QG2MCW.js.map +0 -1
  65. package/dist/chunk-ECLLV5JH.js.map +0 -1
  66. package/dist/chunk-QYRK5H6Q.js.map +0 -1
  67. package/dist/chunk-R5XIDQFR.js.map +0 -1
  68. package/dist/chunk-SNTHHWKY.js.map +0 -1
  69. package/dist/dist-7KVUIKJX.js.map +0 -1
  70. package/dist/dist-JAN5VABY.js.map +0 -1
  71. package/dist/dist-OPIBZ7XM.js.map +0 -1
  72. /package/dist/{_cloud-attach-HJC672UR.js.map → _cloud-attach-R6TRWG5L.js.map} +0 -0
  73. /package/dist/{dist-OG6NW6SM.js.map → dist-OGJGZETZ.js.map} +0 -0
  74. /package/dist/{prepared-state-MQHD3M5F-KE4DT3GX.js.map → prepared-state-MQHD3M5F-Q27AZU53.js.map} +0 -0
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+
3
+ // src/attach-helper.ts
4
+ var import_e2b = require("e2b");
5
+
6
+ // src/env-loader.ts
7
+ var import_node_fs = require("fs");
8
+ var import_node_os = require("os");
9
+ var import_node_path = require("path");
10
+ var E2B_KEYS = ["E2B_API_KEY", "E2B_DOMAIN"];
11
+ var loaded = false;
12
+ function ensureE2bEnvLoaded() {
13
+ if (loaded) return;
14
+ loaded = true;
15
+ importE2bFromFile((0, import_node_path.resolve)((0, import_node_os.homedir)(), ".agentbox", "secrets.env"), E2B_KEYS);
16
+ }
17
+ function importE2bFromFile(path, keys) {
18
+ if (!(0, import_node_fs.existsSync)(path)) return;
19
+ let body;
20
+ try {
21
+ body = (0, import_node_fs.readFileSync)(path, "utf8");
22
+ } catch {
23
+ return;
24
+ }
25
+ const parsed = parseEnvFile(body);
26
+ for (const key of keys) {
27
+ if (process.env[key] !== void 0) continue;
28
+ const value = parsed[key];
29
+ if (typeof value === "string") {
30
+ process.env[key] = value;
31
+ }
32
+ }
33
+ }
34
+ function parseEnvFile(body) {
35
+ const out = {};
36
+ for (const rawLine of body.split(/\r?\n/)) {
37
+ const line = rawLine.trim();
38
+ if (line.length === 0 || line.startsWith("#")) continue;
39
+ const stripped = line.startsWith("export ") ? line.slice("export ".length) : line;
40
+ const eq = stripped.indexOf("=");
41
+ if (eq <= 0) continue;
42
+ const key = stripped.slice(0, eq).trim();
43
+ let value = stripped.slice(eq + 1).trim();
44
+ if (value.length >= 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'"))) {
45
+ value = value.slice(1, -1);
46
+ }
47
+ out[key] = value;
48
+ }
49
+ return out;
50
+ }
51
+
52
+ // src/attach-helper.ts
53
+ function parseArgs(argv) {
54
+ let sandboxId;
55
+ let user = "vscode";
56
+ for (let i = 0; i < argv.length; i++) {
57
+ const a = argv[i];
58
+ if (a === "--sandbox-id") {
59
+ sandboxId = argv[i + 1];
60
+ i++;
61
+ } else if (a === "--user") {
62
+ user = argv[i + 1] ?? user;
63
+ i++;
64
+ }
65
+ }
66
+ if (!sandboxId) {
67
+ process.stderr.write("attach-helper: --sandbox-id is required\n");
68
+ process.exit(2);
69
+ }
70
+ return { sandboxId, user };
71
+ }
72
+ async function main() {
73
+ const { sandboxId, user } = parseArgs(process.argv.slice(2));
74
+ ensureE2bEnvLoaded();
75
+ const inner = process.env.AGENTBOX_E2B_INNER_CMD;
76
+ if (!inner) {
77
+ process.stderr.write("attach-helper: AGENTBOX_E2B_INNER_CMD env is required\n");
78
+ process.exit(2);
79
+ }
80
+ const apiKey = process.env.E2B_API_KEY;
81
+ if (!apiKey) {
82
+ process.stderr.write("attach-helper: E2B_API_KEY env is required\n");
83
+ process.exit(2);
84
+ }
85
+ let sb;
86
+ try {
87
+ sb = await import_e2b.Sandbox.connect(sandboxId, { apiKey, timeoutMs: 55 * 6e4 });
88
+ } catch (err) {
89
+ process.stderr.write(
90
+ `attach-helper: could not connect to sandbox ${sandboxId}: ${err instanceof Error ? err.message : String(err)}
91
+ `
92
+ );
93
+ process.exit(1);
94
+ }
95
+ const cols = process.stdout.columns && process.stdout.columns > 0 ? process.stdout.columns : 80;
96
+ const rows = process.stdout.rows && process.stdout.rows > 0 ? process.stdout.rows : 24;
97
+ if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
98
+ process.stdin.setRawMode(true);
99
+ }
100
+ process.stdin.resume();
101
+ const handle = await sb.pty.create({
102
+ cols,
103
+ rows,
104
+ user,
105
+ cwd: "/workspace",
106
+ envs: {
107
+ LANG: "C.UTF-8",
108
+ LC_ALL: "C.UTF-8",
109
+ TERM: "xterm-256color"
110
+ },
111
+ // Long-lived. We don't want the SDK reaping the PTY mid-session.
112
+ timeoutMs: 55 * 6e4,
113
+ onData: (data) => {
114
+ process.stdout.write(data);
115
+ }
116
+ });
117
+ const pid = handle.pid;
118
+ await sb.pty.sendInput(pid, new TextEncoder().encode(inner + "\n"));
119
+ process.stdin.on("data", (chunk) => {
120
+ sb.pty.sendInput(pid, new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength)).catch(() => {
121
+ });
122
+ });
123
+ const onResize = () => {
124
+ const c = process.stdout.columns ?? cols;
125
+ const r = process.stdout.rows ?? rows;
126
+ if (c > 0 && r > 0) {
127
+ sb.pty.resize(pid, { cols: c, rows: r }).catch(() => {
128
+ });
129
+ }
130
+ };
131
+ process.stdout.on("resize", onResize);
132
+ const cleanup = () => {
133
+ process.stdout.off("resize", onResize);
134
+ if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
135
+ try {
136
+ process.stdin.setRawMode(false);
137
+ } catch {
138
+ }
139
+ }
140
+ process.stdin.pause();
141
+ };
142
+ process.on("SIGINT", () => {
143
+ sb.pty.sendInput(pid, new Uint8Array([3])).catch(() => void 0);
144
+ });
145
+ let exitCode = 0;
146
+ try {
147
+ const result = await handle.wait();
148
+ exitCode = result.exitCode ?? 0;
149
+ } catch (err) {
150
+ process.stderr.write(
151
+ `attach-helper: PTY wait failed: ${err instanceof Error ? err.message : String(err)}
152
+ `
153
+ );
154
+ exitCode = 1;
155
+ } finally {
156
+ cleanup();
157
+ }
158
+ process.exit(exitCode);
159
+ }
160
+ main().catch((err) => {
161
+ process.stderr.write(
162
+ `attach-helper: unhandled error: ${err instanceof Error ? err.message : String(err)}
163
+ `
164
+ );
165
+ process.exit(1);
166
+ });
167
+ //# sourceMappingURL=attach-helper.cjs.map
@@ -0,0 +1,116 @@
1
+ {
2
+ "$comment": "AgentBox enterprise-managed Claude Code settings, baked into the box image at /etc/claude-code/managed-settings.json. Highest precedence and NOT synced from the host ~/.claude, so claude-hooks-filter.ts never touches it; per Claude Code, hook arrays MERGE across settings sources, so the user's own hooks still run. These hooks report Claude's activity to the box supervisor (agentbox-ctl claude-state -> ctl socket -> relay -> ~/.agentbox/boxes/<id>/status.json) so `agentbox status/list/inspect` can show it even when the box is paused. Each command is exit-0 fast and shell-backgrounded so a hook can never block or fail a Claude turn. The ExitPlanMode / AskUserQuestion entries run SYNCHRONOUSLY (no &) because they consume the hook's stdin payload; the catchall PreToolUse 'working' hook races with them, but the supervisor's sticky-state semantics swallow that race (a 'working' set while in end-plan/question is ignored unless --clear-pending is set, which only the matching PostToolUse hook passes). skipDangerousModePermissionPrompt pre-accepts the bypass-permissions disclaimer at policy precedence — AgentBox boxes are isolated, and `agentbox claude` defaults to --dangerously-skip-permissions, so the one-time accept gate would just trap every fresh box.",
3
+ "skipDangerousModePermissionPrompt": true,
4
+ "hooks": {
5
+ "UserPromptSubmit": [
6
+ {
7
+ "hooks": [
8
+ { "type": "command", "command": "agentbox-ctl claude-state working >/dev/null 2>&1 &", "timeout": 3 }
9
+ ]
10
+ }
11
+ ],
12
+ "PreToolUse": [
13
+ {
14
+ "hooks": [
15
+ { "type": "command", "command": "agentbox-ctl claude-state working >/dev/null 2>&1 &", "timeout": 3 }
16
+ ]
17
+ },
18
+ {
19
+ "matcher": "ExitPlanMode",
20
+ "hooks": [
21
+ { "type": "command", "command": "agentbox-ctl claude-state end-plan --payload-stdin >/dev/null 2>&1", "timeout": 3 }
22
+ ]
23
+ },
24
+ {
25
+ "matcher": "AskUserQuestion",
26
+ "hooks": [
27
+ { "type": "command", "command": "agentbox-ctl claude-state question --payload-stdin >/dev/null 2>&1", "timeout": 3 }
28
+ ]
29
+ }
30
+ ],
31
+ "PostToolUse": [
32
+ {
33
+ "matcher": "ExitPlanMode",
34
+ "hooks": [
35
+ { "type": "command", "command": "agentbox-ctl claude-state working --clear-pending >/dev/null 2>&1 &", "timeout": 3 }
36
+ ]
37
+ },
38
+ {
39
+ "matcher": "AskUserQuestion",
40
+ "hooks": [
41
+ { "type": "command", "command": "agentbox-ctl claude-state working --clear-pending >/dev/null 2>&1 &", "timeout": 3 }
42
+ ]
43
+ }
44
+ ],
45
+ "Stop": [
46
+ {
47
+ "hooks": [
48
+ { "type": "command", "command": "agentbox-ctl claude-state idle >/dev/null 2>&1 &", "timeout": 3 }
49
+ ]
50
+ }
51
+ ],
52
+ "StopFailure": [
53
+ {
54
+ "hooks": [
55
+ { "type": "command", "command": "agentbox-ctl claude-state error >/dev/null 2>&1 &", "timeout": 3 }
56
+ ]
57
+ }
58
+ ],
59
+ "PreCompact": [
60
+ {
61
+ "hooks": [
62
+ { "type": "command", "command": "agentbox-ctl claude-state compacting >/dev/null 2>&1 &", "timeout": 3 }
63
+ ]
64
+ }
65
+ ],
66
+ "PostCompact": [
67
+ {
68
+ "hooks": [
69
+ { "type": "command", "command": "agentbox-ctl claude-state working --clear-pending >/dev/null 2>&1 &", "timeout": 3 }
70
+ ]
71
+ }
72
+ ],
73
+ "SubagentStart": [
74
+ {
75
+ "hooks": [
76
+ { "type": "command", "command": "agentbox-ctl claude-state working >/dev/null 2>&1 &", "timeout": 3 }
77
+ ]
78
+ }
79
+ ],
80
+ "SubagentStop": [
81
+ {
82
+ "hooks": [
83
+ { "type": "command", "command": "agentbox-ctl claude-state working >/dev/null 2>&1 &", "timeout": 3 }
84
+ ]
85
+ }
86
+ ],
87
+ "Notification": [
88
+ {
89
+ "matcher": "permission_prompt",
90
+ "hooks": [
91
+ { "type": "command", "command": "agentbox-ctl claude-state waiting >/dev/null 2>&1 &", "timeout": 3 }
92
+ ]
93
+ },
94
+ {
95
+ "matcher": "idle_prompt",
96
+ "hooks": [
97
+ { "type": "command", "command": "agentbox-ctl claude-state idle >/dev/null 2>&1 &", "timeout": 3 }
98
+ ]
99
+ }
100
+ ],
101
+ "SessionStart": [
102
+ {
103
+ "hooks": [
104
+ { "type": "command", "command": "agentbox-ctl claude-state idle >/dev/null 2>&1 &", "timeout": 3 }
105
+ ]
106
+ }
107
+ ],
108
+ "SessionEnd": [
109
+ {
110
+ "hooks": [
111
+ { "type": "command", "command": "agentbox-ctl claude-state idle >/dev/null 2>&1 &", "timeout": 3 }
112
+ ]
113
+ }
114
+ ]
115
+ }
116
+ }