@madarco/agentbox 0.14.0 → 0.16.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 (66) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/dist/{_cloud-attach-GUBB5RH2.js → _cloud-attach-5KJWOASL.js} +4 -4
  3. package/dist/{chunk-RSKG7AFU.js → chunk-3WCEB6RE.js} +2 -2
  4. package/dist/{chunk-XKH7NTT7.js → chunk-DBBUDKKB.js} +248 -5
  5. package/dist/chunk-DBBUDKKB.js.map +1 -0
  6. package/dist/{chunk-TCS5HXJX.js → chunk-GXJNJUEV.js} +1090 -527
  7. package/dist/chunk-GXJNJUEV.js.map +1 -0
  8. package/dist/{chunk-LDMYHWUS.js → chunk-NW2UZQV6.js} +10 -6
  9. package/dist/chunk-NW2UZQV6.js.map +1 -0
  10. package/dist/{chunk-TBSIJVSN.js → chunk-PIK47622.js} +37 -17
  11. package/dist/chunk-PIK47622.js.map +1 -0
  12. package/dist/{chunk-BKU34KYY.js → chunk-QXFNLKJJ.js} +9 -3
  13. package/dist/{chunk-BKU34KYY.js.map → chunk-QXFNLKJJ.js.map} +1 -1
  14. package/dist/{chunk-BYCLD6D6.js → chunk-SB4QTF2T.js} +98 -54
  15. package/dist/chunk-SB4QTF2T.js.map +1 -0
  16. package/dist/{chunk-VATTS2MR.js → chunk-SENASAU4.js} +10 -6
  17. package/dist/{chunk-VATTS2MR.js.map → chunk-SENASAU4.js.map} +1 -1
  18. package/dist/{dist-34RKQ74M.js → dist-4IQFJJQI.js} +5 -5
  19. package/dist/{dist-4DPOL5A7.js → dist-7YB7BMNG.js} +5 -5
  20. package/dist/{dist-3IMQNTTV.js → dist-SL2QSMBE.js} +5 -5
  21. package/dist/{dist-J2IHD5T7.js → dist-VHI5QOSQ.js} +6 -6
  22. package/dist/{dist-57M6ZA7H.js → dist-XC47DSCR.js} +5 -5
  23. package/dist/index.js +1043 -333
  24. package/dist/index.js.map +1 -1
  25. package/dist/{prepared-state-MQHD3M5F-Q27AZU53.js → prepared-state-MQHD3M5F-2LANTRL7.js} +2 -2
  26. package/package.json +6 -5
  27. package/runtime/docker/Dockerfile.box +21 -2
  28. package/runtime/docker/apps/cli/share/agentbox-setup/SKILL.md +112 -29
  29. package/runtime/docker/packages/ctl/dist/bin.cjs +10353 -8575
  30. package/runtime/docker/packages/sandbox-docker/scripts/agentbox-checkpoint-cleanup +5 -2
  31. package/runtime/docker/packages/sandbox-docker/scripts/linear-shim +181 -0
  32. package/runtime/docker/packages/sandbox-docker/scripts/ntn-shim +95 -0
  33. package/runtime/e2b/agentbox-checkpoint-cleanup +5 -2
  34. package/runtime/e2b/agentbox-setup-skill.md +112 -29
  35. package/runtime/e2b/ctl.cjs +10353 -8575
  36. package/runtime/e2b/linear-shim +181 -0
  37. package/runtime/e2b/ntn-shim +95 -0
  38. package/runtime/e2b/scripts/build-template.sh +13 -7
  39. package/runtime/hetzner/agentbox-checkpoint-cleanup +5 -2
  40. package/runtime/hetzner/agentbox-setup-skill.md +112 -29
  41. package/runtime/hetzner/ctl.cjs +10353 -8575
  42. package/runtime/hetzner/linear-shim +181 -0
  43. package/runtime/hetzner/ntn-shim +95 -0
  44. package/runtime/hetzner/scripts/install-box.sh +19 -9
  45. package/runtime/relay/bin.cjs +3707 -2828
  46. package/runtime/vercel/agentbox-checkpoint-cleanup +5 -2
  47. package/runtime/vercel/agentbox-setup-skill.md +112 -29
  48. package/runtime/vercel/ctl.cjs +10353 -8575
  49. package/runtime/vercel/linear-shim +181 -0
  50. package/runtime/vercel/ntn-shim +95 -0
  51. package/runtime/vercel/scripts/provision.sh +13 -7
  52. package/share/agentbox-setup/SKILL.md +112 -29
  53. package/share/host-skills/agentbox-info/SKILL.md +22 -2
  54. package/dist/chunk-BYCLD6D6.js.map +0 -1
  55. package/dist/chunk-LDMYHWUS.js.map +0 -1
  56. package/dist/chunk-TBSIJVSN.js.map +0 -1
  57. package/dist/chunk-TCS5HXJX.js.map +0 -1
  58. package/dist/chunk-XKH7NTT7.js.map +0 -1
  59. /package/dist/{_cloud-attach-GUBB5RH2.js.map → _cloud-attach-5KJWOASL.js.map} +0 -0
  60. /package/dist/{chunk-RSKG7AFU.js.map → chunk-3WCEB6RE.js.map} +0 -0
  61. /package/dist/{dist-34RKQ74M.js.map → dist-4IQFJJQI.js.map} +0 -0
  62. /package/dist/{dist-4DPOL5A7.js.map → dist-7YB7BMNG.js.map} +0 -0
  63. /package/dist/{dist-3IMQNTTV.js.map → dist-SL2QSMBE.js.map} +0 -0
  64. /package/dist/{dist-J2IHD5T7.js.map → dist-VHI5QOSQ.js.map} +0 -0
  65. /package/dist/{dist-57M6ZA7H.js.map → dist-XC47DSCR.js.map} +0 -0
  66. /package/dist/{prepared-state-MQHD3M5F-Q27AZU53.js.map → prepared-state-MQHD3M5F-2LANTRL7.js.map} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  DEFAULT_RELAY_PORT,
4
4
  loadEffectiveConfig,
5
5
  readBoxStatus
6
- } from "./chunk-TCS5HXJX.js";
6
+ } from "./chunk-GXJNJUEV.js";
7
7
 
8
8
  // src/commands/_cloud-attach.ts
9
9
  import { spawn as spawn4 } from "child_process";
@@ -20,26 +20,26 @@ function isKnownProvider(name) {
20
20
  async function getProvider(name) {
21
21
  switch (name) {
22
22
  case "docker": {
23
- const mod = await import("./dist-4DPOL5A7.js");
23
+ const mod = await import("./dist-7YB7BMNG.js");
24
24
  return mod.dockerProvider;
25
25
  }
26
26
  case "daytona": {
27
- const mod = await import("./dist-3IMQNTTV.js");
27
+ const mod = await import("./dist-SL2QSMBE.js");
28
28
  await mod.ensureDaytonaCredentials();
29
29
  return mod.daytonaProvider;
30
30
  }
31
31
  case "hetzner": {
32
- const mod = await import("./dist-J2IHD5T7.js");
32
+ const mod = await import("./dist-VHI5QOSQ.js");
33
33
  await mod.ensureHetznerCredentials();
34
34
  return mod.hetznerProvider;
35
35
  }
36
36
  case "vercel": {
37
- const mod = await import("./dist-57M6ZA7H.js");
37
+ const mod = await import("./dist-XC47DSCR.js");
38
38
  await mod.ensureVercelCredentials();
39
39
  return mod.vercelProvider;
40
40
  }
41
41
  case "e2b": {
42
- const mod = await import("./dist-34RKQ74M.js");
42
+ const mod = await import("./dist-4IQFJJQI.js");
43
43
  await mod.ensureE2bCredentials();
44
44
  return mod.e2bProvider;
45
45
  }
@@ -64,6 +64,24 @@ async function providerForCreate(choice) {
64
64
  // src/wrapped-pty/run.ts
65
65
  import { spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
66
66
 
67
+ // src/wrapped-pty/service-status.ts
68
+ function serviceStatusLabel(status) {
69
+ if (!status) return null;
70
+ const services = status.services ?? [];
71
+ const tasks = status.tasks ?? [];
72
+ if (services.length === 0 && tasks.length === 0) return null;
73
+ const errored = services.some((s) => s.state === "crashed" || s.state === "unhealthy" || s.state === "backoff") || tasks.some((t) => t.state === "failed");
74
+ if (errored) return "service error";
75
+ const isUp = (s) => s.state === "ready" || s.state === "running" && !s.probed;
76
+ const counted = services.filter((s) => s.state !== "stopped");
77
+ const total = counted.length;
78
+ const up = counted.filter(isUp).length;
79
+ const settling = services.some((s) => s.state === "pending" || s.state === "waiting" || s.state === "starting") || services.some((s) => s.state === "running" && Boolean(s.probed)) || tasks.some((t) => t.state === "pending" || t.state === "waiting" || t.state === "running");
80
+ if (total === 0) return settling ? "starting\u2026" : null;
81
+ if (settling || up < total) return `starting ${String(up)}/${String(total)}\u2026`;
82
+ return "ready";
83
+ }
84
+
67
85
  // src/pty/pty-backend.ts
68
86
  async function loadPtyBackend() {
69
87
  try {
@@ -115,16 +133,17 @@ async function spawnInNewTerminal(args) {
115
133
  }
116
134
  async function spawnInTmux(args) {
117
135
  const cmdStr = shellJoin(args.argv);
136
+ const target = args.tmuxTarget ? ["-t", args.tmuxTarget] : [];
118
137
  let tmuxArgv;
119
138
  let noteKind;
120
139
  if (args.mode === "split") {
121
- tmuxArgv = ["split-window", "-h", "-c", args.cwd, "--", cmdStr];
140
+ tmuxArgv = ["split-window", "-h", ...target, "-c", args.cwd, "--", cmdStr];
122
141
  noteKind = "tmux split";
123
142
  } else {
124
- tmuxArgv = ["new-window", "-n", args.title, "-c", args.cwd, "--", cmdStr];
143
+ tmuxArgv = ["new-window", ...target, "-n", args.title, "-c", args.cwd, "--", cmdStr];
125
144
  noteKind = "tmux window";
126
145
  }
127
- const r = await runQuiet("tmux", tmuxArgv);
146
+ const r = await runQuiet("tmux", tmuxArgv, args.env);
128
147
  if (r.code !== 0) {
129
148
  return {
130
149
  launched: false,
@@ -138,9 +157,54 @@ async function spawnInTmux(args) {
138
157
  };
139
158
  }
140
159
  async function spawnInCmux(args) {
141
- const bin = cmuxBinary();
142
- if (args.mode === "window") {
143
- const r = await runQuiet(bin, [
160
+ const bin = cmuxBinary(args.env);
161
+ if (args.mode === "window") return newCmuxWorkspace(bin, args);
162
+ const base = args.mode === "split" ? ["new-split", "right"] : ["new-surface"];
163
+ const noteKind = args.mode === "split" ? "cmux split" : "cmux tab";
164
+ const attempts = [];
165
+ if (args.mode === "split" && args.cmuxTargetSurface) {
166
+ attempts.push([...base, "--surface", args.cmuxTargetSurface, "--focus", "true"]);
167
+ }
168
+ if (args.cmuxTargetWorkspace) {
169
+ attempts.push([...base, "--workspace", args.cmuxTargetWorkspace, "--focus", "true"]);
170
+ }
171
+ if (!args.cmuxWorkspaceFallback) {
172
+ attempts.push([...base, "--focus", "true"]);
173
+ }
174
+ const cmdLine = `cd ${shellQuote(args.cwd)} && exec ${shellJoin(args.argv)}`;
175
+ let lastError = "";
176
+ for (const createArgv of attempts) {
177
+ const created = await runQuiet(bin, createArgv, args.env);
178
+ if (created.code !== 0) {
179
+ lastError = `cmux ${createArgv.join(" ")} exited ${String(created.code)}: ${created.stderr.trim()}`;
180
+ continue;
181
+ }
182
+ const surfaceRef = parseCmuxRef(created.stdout);
183
+ if (!surfaceRef) {
184
+ return {
185
+ launched: false,
186
+ note: "",
187
+ error: `cmux ${createArgv[0]} gave no surface ref: ${created.stdout.trim()}`
188
+ };
189
+ }
190
+ const sent = await runQuiet(bin, ["send", "--surface", surfaceRef, `${cmdLine}
191
+ `], args.env);
192
+ if (sent.code !== 0) {
193
+ return {
194
+ launched: false,
195
+ note: "",
196
+ error: `cmux send exited ${String(sent.code)}: ${sent.stderr.trim()}`
197
+ };
198
+ }
199
+ return { launched: true, note: `Attached in new ${noteKind}.` };
200
+ }
201
+ if (args.cmuxWorkspaceFallback) return newCmuxWorkspace(bin, args);
202
+ return { launched: false, note: "", error: lastError };
203
+ }
204
+ async function newCmuxWorkspace(bin, args) {
205
+ const r = await runQuiet(
206
+ bin,
207
+ [
144
208
  "new-workspace",
145
209
  "--name",
146
210
  args.title,
@@ -150,45 +214,17 @@ async function spawnInCmux(args) {
150
214
  shellJoin(args.argv),
151
215
  "--focus",
152
216
  "true"
153
- ]);
154
- if (r.code !== 0) {
155
- return {
156
- launched: false,
157
- note: "",
158
- error: `cmux new-workspace exited ${String(r.code)}: ${r.stderr.trim()}`
159
- };
160
- }
161
- return { launched: true, note: "Attached in new cmux workspace." };
162
- }
163
- const createArgv = args.mode === "split" ? ["new-split", "right", "--focus", "true"] : ["new-surface", "--focus", "true"];
164
- const noteKind = args.mode === "split" ? "cmux split" : "cmux tab";
165
- const created = await runQuiet(bin, createArgv);
166
- if (created.code !== 0) {
167
- return {
168
- launched: false,
169
- note: "",
170
- error: `cmux ${createArgv[0]} exited ${String(created.code)}: ${created.stderr.trim()}`
171
- };
172
- }
173
- const surfaceRef = parseCmuxRef(created.stdout);
174
- if (!surfaceRef) {
175
- return {
176
- launched: false,
177
- note: "",
178
- error: `cmux ${createArgv[0]} gave no surface ref: ${created.stdout.trim()}`
179
- };
180
- }
181
- const cmdLine = `cd ${shellQuote(args.cwd)} && exec ${shellJoin(args.argv)}`;
182
- const sent = await runQuiet(bin, ["send", "--surface", surfaceRef, `${cmdLine}
183
- `]);
184
- if (sent.code !== 0) {
217
+ ],
218
+ args.env
219
+ );
220
+ if (r.code !== 0) {
185
221
  return {
186
222
  launched: false,
187
223
  note: "",
188
- error: `cmux send exited ${String(sent.code)}: ${sent.stderr.trim()}`
224
+ error: `cmux new-workspace exited ${String(r.code)}: ${r.stderr.trim()}`
189
225
  };
190
226
  }
191
- return { launched: true, note: `Attached in new ${noteKind}.` };
227
+ return { launched: true, note: "Attached in new cmux workspace." };
192
228
  }
193
229
  function parseCmuxRef(stdout) {
194
230
  const m = stdout.match(/\b(?:surface|pane):\d+\b/);
@@ -242,9 +278,9 @@ async function spawnInITerm2(args) {
242
278
  note: `Attached in new ${noteKind}.`
243
279
  };
244
280
  }
245
- function runQuiet(cmd, argv) {
281
+ function runQuiet(cmd, argv, env) {
246
282
  return new Promise((resolve) => {
247
- const child = spawn(cmd, argv, { stdio: ["ignore", "pipe", "pipe"] });
283
+ const child = spawn(cmd, argv, { stdio: ["ignore", "pipe", "pipe"], env });
248
284
  let stdout = "";
249
285
  let stderr = "";
250
286
  child.stdout?.on("data", (chunk) => {
@@ -961,7 +997,8 @@ function renderFooter(state, cols) {
961
997
  };
962
998
  const isClaude = state.mode === "claude";
963
999
  const detachable = state.detachable ?? isClaude;
964
- const stateLabel = isClaude ? void 0 : state.mode === "shell" ? "shell" : state.mode;
1000
+ const modeLabel = isClaude ? void 0 : state.mode === "shell" ? "shell" : state.mode;
1001
+ const stateLabel = state.boxServiceStatus ?? modeLabel;
965
1002
  if (state.leaderActive) {
966
1003
  const leaderHints = detachable ? DETACHABLE_LEADER_HINTS : PLAIN_LEADER_HINTS;
967
1004
  return statusLine(sidebarBox, cols, stateLabel, leaderHints);
@@ -1323,11 +1360,12 @@ async function runWrappedAttach(opts) {
1323
1360
  setTerminalTitle(lastEmittedTitle);
1324
1361
  const detachable = opts.detachable ?? opts.mode === "claude";
1325
1362
  let leaderActive = false;
1326
- const buildIdle = (sessionTitle, claudeActivity) => ({
1363
+ const buildIdle = (sessionTitle, claudeActivity, boxServiceStatus) => ({
1327
1364
  kind: "idle",
1328
1365
  boxName: opts.boxName,
1329
1366
  sessionTitle,
1330
1367
  claudeActivity,
1368
+ boxServiceStatus,
1331
1369
  mode: opts.mode,
1332
1370
  detachable,
1333
1371
  leaderActive
@@ -1335,6 +1373,7 @@ async function runWrappedAttach(opts) {
1335
1373
  let footerState = buildIdle();
1336
1374
  let lastSessionTitle;
1337
1375
  let lastActivity;
1376
+ let lastServiceStatus;
1338
1377
  let capturingPrompt = null;
1339
1378
  let activeNotice = null;
1340
1379
  let reconnectBanner = null;
@@ -1382,7 +1421,7 @@ async function runWrappedAttach(opts) {
1382
1421
  } else if (flashMessage) {
1383
1422
  footerState = { kind: "flash", message: flashMessage };
1384
1423
  } else {
1385
- footerState = buildIdle(lastSessionTitle, lastActivity);
1424
+ footerState = buildIdle(lastSessionTitle, lastActivity, lastServiceStatus);
1386
1425
  }
1387
1426
  };
1388
1427
  const recomputeBand = () => {
@@ -1650,6 +1689,7 @@ async function runWrappedAttach(opts) {
1650
1689
  const body = opts.mode === "codex" ? status?.codex : opts.mode === "opencode" ? status?.opencode : opts.mode === "shell" ? void 0 : status?.claude;
1651
1690
  const nextTitle = body?.sessionTitle?.trim() || void 0;
1652
1691
  const nextActivity = body?.state || void 0;
1692
+ const nextServiceStatus = serviceStatusLabel(status) ?? void 0;
1653
1693
  if (cmuxOn && nextActivity !== lastActivity) {
1654
1694
  applyCmuxAgentState(opts.mode, nextActivity);
1655
1695
  if (isAttentionState(nextActivity) && !isAttentionState(lastActivity)) {
@@ -1667,9 +1707,11 @@ async function runWrappedAttach(opts) {
1667
1707
  questionPayload = nextQuestion;
1668
1708
  applyBandChange();
1669
1709
  }
1670
- if (nextTitle === lastSessionTitle && nextActivity === lastActivity) return;
1710
+ if (nextTitle === lastSessionTitle && nextActivity === lastActivity && nextServiceStatus === lastServiceStatus)
1711
+ return;
1671
1712
  lastSessionTitle = nextTitle;
1672
1713
  lastActivity = nextActivity;
1714
+ lastServiceStatus = nextServiceStatus;
1673
1715
  if (footerState.kind === "idle") {
1674
1716
  recomputeFooter();
1675
1717
  redrawChrome();
@@ -2103,8 +2145,10 @@ export {
2103
2145
  getProvider,
2104
2146
  providerForBox,
2105
2147
  providerForCreate,
2106
- loadPtyBackend,
2107
2148
  detectHostTerminal,
2149
+ cmuxBinary,
2150
+ spawnInNewTerminal,
2151
+ loadPtyBackend,
2108
2152
  setTerminalTitle,
2109
2153
  pushTerminalTitle,
2110
2154
  popTerminalTitle,
@@ -2129,4 +2173,4 @@ export {
2129
2173
  cloudAgentAttach,
2130
2174
  cloudAgentStartDetached
2131
2175
  };
2132
- //# sourceMappingURL=chunk-BYCLD6D6.js.map
2176
+ //# sourceMappingURL=chunk-SB4QTF2T.js.map