@madarco/agentbox 0.11.3 → 0.13.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.
- package/CHANGELOG.md +90 -0
- package/README.md +11 -0
- package/dist/{_cloud-attach-XWCVLO5V.js → _cloud-attach-HJC672UR.js} +3 -3
- package/dist/{chunk-ZGVMN54V.js → chunk-2LF5YILI.js} +21 -3
- package/dist/chunk-2LF5YILI.js.map +1 -0
- package/dist/{chunk-MXXXKJYS.js → chunk-4NQXNQ53.js} +234 -83
- package/dist/chunk-4NQXNQ53.js.map +1 -0
- package/dist/{chunk-ZJXTIH6C.js → chunk-B4QG2MCW.js} +1352 -851
- package/dist/chunk-B4QG2MCW.js.map +1 -0
- package/dist/{chunk-GYJ62GFL.js → chunk-QYRK5H6Q.js} +297 -33
- package/dist/chunk-QYRK5H6Q.js.map +1 -0
- package/dist/{dist-WMQDMTWS.js → dist-7KVUIKJX.js} +8 -5
- package/dist/dist-7KVUIKJX.js.map +1 -0
- package/dist/{dist-RAZP76VX.js → dist-JAN5VABY.js} +3 -3
- package/dist/{dist-ASLPRUQR.js → dist-OG6NW6SM.js} +28 -2
- package/dist/{dist-PTJ6CEQY.js → dist-OPIBZ7XM.js} +4 -4
- package/dist/index.js +1720 -876
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/runtime/docker/packages/ctl/dist/bin.cjs +341 -5
- package/runtime/docker/packages/sandbox-docker/scripts/gh-shim +86 -5
- package/runtime/hetzner/ctl.cjs +341 -5
- package/runtime/hetzner/gh-shim +86 -5
- package/runtime/relay/bin.cjs +293 -4
- package/runtime/vercel/ctl.cjs +341 -5
- package/runtime/vercel/gh-shim +86 -5
- package/share/host-skills/agentbox/SKILL.md +16 -5
- package/share/host-skills/agentbox-info/SKILL.md +3 -1
- package/dist/chunk-GYJ62GFL.js.map +0 -1
- package/dist/chunk-MXXXKJYS.js.map +0 -1
- package/dist/chunk-ZGVMN54V.js.map +0 -1
- package/dist/chunk-ZJXTIH6C.js.map +0 -1
- package/dist/dist-WMQDMTWS.js.map +0 -1
- /package/dist/{_cloud-attach-XWCVLO5V.js.map → _cloud-attach-HJC672UR.js.map} +0 -0
- /package/dist/{dist-RAZP76VX.js.map → dist-JAN5VABY.js.map} +0 -0
- /package/dist/{dist-ASLPRUQR.js.map → dist-OG6NW6SM.js.map} +0 -0
- /package/dist/{dist-PTJ6CEQY.js.map → dist-OPIBZ7XM.js.map} +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DEFAULT_RELAY_PORT,
|
|
4
|
+
loadEffectiveConfig,
|
|
4
5
|
readBoxStatus
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-B4QG2MCW.js";
|
|
6
7
|
|
|
7
8
|
// src/commands/_cloud-attach.ts
|
|
8
|
-
import { spawn as
|
|
9
|
+
import { spawn as spawn4 } from "child_process";
|
|
9
10
|
import { appendFileSync } from "fs";
|
|
10
11
|
import { homedir } from "os";
|
|
11
12
|
import { join as join2 } from "path";
|
|
@@ -19,21 +20,21 @@ function isKnownProvider(name) {
|
|
|
19
20
|
async function getProvider(name) {
|
|
20
21
|
switch (name) {
|
|
21
22
|
case "docker": {
|
|
22
|
-
const mod = await import("./dist-
|
|
23
|
+
const mod = await import("./dist-OG6NW6SM.js");
|
|
23
24
|
return mod.dockerProvider;
|
|
24
25
|
}
|
|
25
26
|
case "daytona": {
|
|
26
|
-
const mod = await import("./dist-
|
|
27
|
+
const mod = await import("./dist-OPIBZ7XM.js");
|
|
27
28
|
await mod.ensureDaytonaCredentials();
|
|
28
29
|
return mod.daytonaProvider;
|
|
29
30
|
}
|
|
30
31
|
case "hetzner": {
|
|
31
|
-
const mod = await import("./dist-
|
|
32
|
+
const mod = await import("./dist-7KVUIKJX.js");
|
|
32
33
|
await mod.ensureHetznerCredentials();
|
|
33
34
|
return mod.hetznerProvider;
|
|
34
35
|
}
|
|
35
36
|
case "vercel": {
|
|
36
|
-
const mod = await import("./dist-
|
|
37
|
+
const mod = await import("./dist-JAN5VABY.js");
|
|
37
38
|
await mod.ensureVercelCredentials();
|
|
38
39
|
return mod.vercelProvider;
|
|
39
40
|
}
|
|
@@ -56,20 +57,20 @@ async function providerForCreate(choice) {
|
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
// src/wrapped-pty/run.ts
|
|
59
|
-
import { spawn as
|
|
60
|
+
import { spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
|
|
60
61
|
|
|
61
62
|
// src/pty/pty-backend.ts
|
|
62
63
|
async function loadPtyBackend() {
|
|
63
64
|
try {
|
|
64
65
|
const ptyMod = await import("@homebridge/node-pty-prebuilt-multiarch");
|
|
65
66
|
const xtermMod = await import("@xterm/headless");
|
|
66
|
-
const
|
|
67
|
+
const spawn5 = ptyMod["spawn"] ?? ptyMod["default"]?.["spawn"];
|
|
67
68
|
const Terminal = xtermMod["Terminal"] ?? xtermMod["default"]?.["Terminal"];
|
|
68
|
-
if (typeof
|
|
69
|
+
if (typeof spawn5 !== "function" || typeof Terminal !== "function") {
|
|
69
70
|
return null;
|
|
70
71
|
}
|
|
71
72
|
return {
|
|
72
|
-
ptySpawn:
|
|
73
|
+
ptySpawn: spawn5,
|
|
73
74
|
termCtor: Terminal
|
|
74
75
|
};
|
|
75
76
|
} catch {
|
|
@@ -82,10 +83,16 @@ import { spawn } from "child_process";
|
|
|
82
83
|
function detectHostTerminal(env = process.env) {
|
|
83
84
|
const tmux = env["TMUX"];
|
|
84
85
|
if (tmux && tmux.length > 0) return "tmux";
|
|
86
|
+
const cmuxSocket = env["CMUX_SOCKET_PATH"];
|
|
87
|
+
if (cmuxSocket && cmuxSocket.length > 0) return "cmux";
|
|
85
88
|
const termProgram = env["TERM_PROGRAM"];
|
|
86
89
|
if (termProgram === "iTerm.app") return "iterm2";
|
|
87
90
|
return "unknown";
|
|
88
91
|
}
|
|
92
|
+
function cmuxBinary(env = process.env) {
|
|
93
|
+
const bundled = env["CMUX_BUNDLED_CLI_PATH"];
|
|
94
|
+
return bundled && bundled.length > 0 ? bundled : "cmux";
|
|
95
|
+
}
|
|
89
96
|
function shellQuote(s) {
|
|
90
97
|
if (s.length === 0) return "''";
|
|
91
98
|
return "'" + s.replace(/'/g, "'\\''") + "'";
|
|
@@ -98,6 +105,7 @@ function shellJoin(argv) {
|
|
|
98
105
|
}
|
|
99
106
|
async function spawnInNewTerminal(args) {
|
|
100
107
|
if (args.host === "tmux") return spawnInTmux(args);
|
|
108
|
+
if (args.host === "cmux") return spawnInCmux(args);
|
|
101
109
|
return spawnInITerm2(args);
|
|
102
110
|
}
|
|
103
111
|
async function spawnInTmux(args) {
|
|
@@ -124,6 +132,63 @@ async function spawnInTmux(args) {
|
|
|
124
132
|
note: `Attached in new ${noteKind}.`
|
|
125
133
|
};
|
|
126
134
|
}
|
|
135
|
+
async function spawnInCmux(args) {
|
|
136
|
+
const bin = cmuxBinary();
|
|
137
|
+
if (args.mode === "window") {
|
|
138
|
+
const r = await runQuiet(bin, [
|
|
139
|
+
"new-workspace",
|
|
140
|
+
"--name",
|
|
141
|
+
args.title,
|
|
142
|
+
"--cwd",
|
|
143
|
+
args.cwd,
|
|
144
|
+
"--command",
|
|
145
|
+
shellJoin(args.argv),
|
|
146
|
+
"--focus",
|
|
147
|
+
"true"
|
|
148
|
+
]);
|
|
149
|
+
if (r.code !== 0) {
|
|
150
|
+
return {
|
|
151
|
+
launched: false,
|
|
152
|
+
note: "",
|
|
153
|
+
error: `cmux new-workspace exited ${String(r.code)}: ${r.stderr.trim()}`
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
return { launched: true, note: "Attached in new cmux workspace." };
|
|
157
|
+
}
|
|
158
|
+
const createArgv = args.mode === "split" ? ["new-split", "right", "--focus", "true"] : ["new-surface", "--focus", "true"];
|
|
159
|
+
const noteKind = args.mode === "split" ? "cmux split" : "cmux tab";
|
|
160
|
+
const created = await runQuiet(bin, createArgv);
|
|
161
|
+
if (created.code !== 0) {
|
|
162
|
+
return {
|
|
163
|
+
launched: false,
|
|
164
|
+
note: "",
|
|
165
|
+
error: `cmux ${createArgv[0]} exited ${String(created.code)}: ${created.stderr.trim()}`
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const surfaceRef = parseCmuxRef(created.stdout);
|
|
169
|
+
if (!surfaceRef) {
|
|
170
|
+
return {
|
|
171
|
+
launched: false,
|
|
172
|
+
note: "",
|
|
173
|
+
error: `cmux ${createArgv[0]} gave no surface ref: ${created.stdout.trim()}`
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
const cmdLine = `cd ${shellQuote(args.cwd)} && exec ${shellJoin(args.argv)}`;
|
|
177
|
+
const sent = await runQuiet(bin, ["send", "--surface", surfaceRef, `${cmdLine}
|
|
178
|
+
`]);
|
|
179
|
+
if (sent.code !== 0) {
|
|
180
|
+
return {
|
|
181
|
+
launched: false,
|
|
182
|
+
note: "",
|
|
183
|
+
error: `cmux send exited ${String(sent.code)}: ${sent.stderr.trim()}`
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
return { launched: true, note: `Attached in new ${noteKind}.` };
|
|
187
|
+
}
|
|
188
|
+
function parseCmuxRef(stdout) {
|
|
189
|
+
const m = stdout.match(/\b(?:surface|pane):\d+\b/);
|
|
190
|
+
return m ? m[0] : void 0;
|
|
191
|
+
}
|
|
127
192
|
async function spawnInITerm2(args) {
|
|
128
193
|
const inner = shellJoin(args.argv);
|
|
129
194
|
const cmdLine = `cd ${shellQuote(args.cwd)} && exec ${inner}`;
|
|
@@ -174,20 +239,139 @@ async function spawnInITerm2(args) {
|
|
|
174
239
|
}
|
|
175
240
|
function runQuiet(cmd, argv) {
|
|
176
241
|
return new Promise((resolve) => {
|
|
177
|
-
const child = spawn(cmd, argv, { stdio: ["ignore", "
|
|
242
|
+
const child = spawn(cmd, argv, { stdio: ["ignore", "pipe", "pipe"] });
|
|
243
|
+
let stdout = "";
|
|
178
244
|
let stderr = "";
|
|
245
|
+
child.stdout?.on("data", (chunk) => {
|
|
246
|
+
stdout += chunk.toString("utf8");
|
|
247
|
+
});
|
|
179
248
|
child.stderr?.on("data", (chunk) => {
|
|
180
249
|
stderr += chunk.toString("utf8");
|
|
181
250
|
});
|
|
182
251
|
child.on("error", (err) => {
|
|
183
|
-
resolve({ code: 127, stderr: err.message });
|
|
252
|
+
resolve({ code: 127, stdout, stderr: err.message });
|
|
184
253
|
});
|
|
185
254
|
child.on("exit", (code) => {
|
|
186
|
-
resolve({ code: typeof code === "number" ? code : 1, stderr });
|
|
255
|
+
resolve({ code: typeof code === "number" ? code : 1, stdout, stderr });
|
|
187
256
|
});
|
|
188
257
|
});
|
|
189
258
|
}
|
|
190
259
|
|
|
260
|
+
// src/terminal/cmux-status.ts
|
|
261
|
+
import { spawn as spawn2, spawnSync } from "child_process";
|
|
262
|
+
var AGENT_LABEL = {
|
|
263
|
+
claude: "claude",
|
|
264
|
+
codex: "codex",
|
|
265
|
+
opencode: "opencode"
|
|
266
|
+
};
|
|
267
|
+
function mapActivityToWorkspace(mode, activity) {
|
|
268
|
+
if (mode === "shell") return null;
|
|
269
|
+
const label = AGENT_LABEL[mode];
|
|
270
|
+
switch (activity) {
|
|
271
|
+
case "working":
|
|
272
|
+
case "compacting":
|
|
273
|
+
return { description: `${label} \xB7 working`, color: "Blue" };
|
|
274
|
+
case "question":
|
|
275
|
+
case "waiting":
|
|
276
|
+
return { description: `${label} \xB7 needs input`, color: "Amber" };
|
|
277
|
+
case "end-plan":
|
|
278
|
+
return { description: `${label} \xB7 plan ready`, color: "Amber" };
|
|
279
|
+
case "error":
|
|
280
|
+
return { description: `${label} \xB7 error`, color: "Red" };
|
|
281
|
+
case "idle":
|
|
282
|
+
return { description: `${label} \xB7 idle`, color: "" };
|
|
283
|
+
case "unknown":
|
|
284
|
+
case void 0:
|
|
285
|
+
default:
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function isAttentionState(activity) {
|
|
290
|
+
return activity === "question" || activity === "waiting" || activity === "end-plan" || activity === "error";
|
|
291
|
+
}
|
|
292
|
+
function attentionReason(activity) {
|
|
293
|
+
switch (activity) {
|
|
294
|
+
case "end-plan":
|
|
295
|
+
return "plan ready";
|
|
296
|
+
case "error":
|
|
297
|
+
return "error";
|
|
298
|
+
case "question":
|
|
299
|
+
case "waiting":
|
|
300
|
+
default:
|
|
301
|
+
return "needs input";
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function cmuxStatusActive(env = process.env) {
|
|
305
|
+
const sock = env["CMUX_SOCKET_PATH"];
|
|
306
|
+
return typeof sock === "string" && sock.length > 0;
|
|
307
|
+
}
|
|
308
|
+
async function cmuxStatusEnabled(env = process.env) {
|
|
309
|
+
if (!cmuxStatusActive(env)) return false;
|
|
310
|
+
try {
|
|
311
|
+
const cfg = await loadEffectiveConfig(process.cwd());
|
|
312
|
+
return cfg.effective.attach.cmuxStatus;
|
|
313
|
+
} catch {
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function runCmux(argv) {
|
|
318
|
+
try {
|
|
319
|
+
const child = spawn2(cmuxBinary(), argv, { stdio: "ignore" });
|
|
320
|
+
child.on("error", () => {
|
|
321
|
+
});
|
|
322
|
+
child.unref();
|
|
323
|
+
} catch {
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
function captureCmuxWorkspace(env = process.env) {
|
|
327
|
+
const wsId = env["CMUX_WORKSPACE_ID"];
|
|
328
|
+
if (!wsId) return null;
|
|
329
|
+
try {
|
|
330
|
+
const r = spawnSync(cmuxBinary(), ["list-workspaces", "--json", "--id-format", "both"], {
|
|
331
|
+
encoding: "utf8"
|
|
332
|
+
});
|
|
333
|
+
if (r.status !== 0 || !r.stdout) return null;
|
|
334
|
+
const data = JSON.parse(r.stdout);
|
|
335
|
+
for (const w of data.workspaces ?? []) {
|
|
336
|
+
if (!JSON.stringify(w).includes(wsId)) continue;
|
|
337
|
+
const description = typeof w["description"] === "string" ? w["description"] : "";
|
|
338
|
+
const color = typeof w["custom_color"] === "string" ? w["custom_color"] : "";
|
|
339
|
+
return { description, color };
|
|
340
|
+
}
|
|
341
|
+
} catch {
|
|
342
|
+
}
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
function applyCmuxAgentState(mode, activity) {
|
|
346
|
+
const view = mapActivityToWorkspace(mode, activity);
|
|
347
|
+
if (!view) return;
|
|
348
|
+
runCmux(["workspace-action", "--action", "set-description", "--description", view.description]);
|
|
349
|
+
if (view.color) {
|
|
350
|
+
runCmux(["workspace-action", "--action", "set-color", "--color", view.color]);
|
|
351
|
+
} else {
|
|
352
|
+
runCmux(["workspace-action", "--action", "clear-color"]);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function markCmuxTabAttention(mode, boxName, activity, env = process.env) {
|
|
356
|
+
const label = mode === "shell" ? "shell" : AGENT_LABEL[mode];
|
|
357
|
+
const argv = ["notify", "--title", boxName, "--body", `${label} \xB7 ${attentionReason(activity)}`];
|
|
358
|
+
const surface = env["CMUX_SURFACE_ID"];
|
|
359
|
+
if (surface && surface.length > 0) argv.push("--surface", surface);
|
|
360
|
+
runCmux(argv);
|
|
361
|
+
}
|
|
362
|
+
function restoreCmuxWorkspace(orig) {
|
|
363
|
+
if (orig && orig.description) {
|
|
364
|
+
runCmux(["workspace-action", "--action", "set-description", "--description", orig.description]);
|
|
365
|
+
} else {
|
|
366
|
+
runCmux(["workspace-action", "--action", "clear-description"]);
|
|
367
|
+
}
|
|
368
|
+
if (orig && orig.color) {
|
|
369
|
+
runCmux(["workspace-action", "--action", "set-color", "--color", orig.color]);
|
|
370
|
+
} else {
|
|
371
|
+
runCmux(["workspace-action", "--action", "clear-color"]);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
191
375
|
// src/terminal/title.ts
|
|
192
376
|
var ESC = "\x1B";
|
|
193
377
|
var BEL = "\x07";
|
|
@@ -665,7 +849,7 @@ var ADVANCED_HINT_GROUPS = [
|
|
|
665
849
|
["u", "url"],
|
|
666
850
|
["t", "stop"],
|
|
667
851
|
["p", "pause"],
|
|
668
|
-
["
|
|
852
|
+
["k", "destroy"],
|
|
669
853
|
["q", "quit"]
|
|
670
854
|
];
|
|
671
855
|
function statusLine(box, w, stateLabel, groups = HINT_GROUPS, fallbackGroups) {
|
|
@@ -728,12 +912,16 @@ var DETACHABLE_LEADER_HINTS = [
|
|
|
728
912
|
["c", "code"],
|
|
729
913
|
["s", "screen"],
|
|
730
914
|
["u", "url"],
|
|
915
|
+
["t", "shell"],
|
|
916
|
+
["k", "destroy"],
|
|
731
917
|
["d", "detach"]
|
|
732
918
|
];
|
|
733
919
|
var PLAIN_LEADER_HINTS = [
|
|
734
920
|
["c", "code"],
|
|
735
921
|
["s", "screen"],
|
|
736
|
-
["u", "url"]
|
|
922
|
+
["u", "url"],
|
|
923
|
+
["t", "shell"],
|
|
924
|
+
["k", "destroy"]
|
|
737
925
|
];
|
|
738
926
|
function padTo(visible, width) {
|
|
739
927
|
if (visible.length === width) return visible;
|
|
@@ -1062,7 +1250,8 @@ var CHECKPOINT_DROP_GRACE_MS = 4e3;
|
|
|
1062
1250
|
var ACTION_FLASH = {
|
|
1063
1251
|
screen: "Opening noVNC viewer\u2026",
|
|
1064
1252
|
code: "Launching VS Code / Cursor\u2026",
|
|
1065
|
-
url: "Opening box URL\u2026"
|
|
1253
|
+
url: "Opening box URL\u2026",
|
|
1254
|
+
shell: "Opening shell in box\u2026"
|
|
1066
1255
|
};
|
|
1067
1256
|
var ACTION_CMD = {
|
|
1068
1257
|
screen: { sub: "screen", flags: [] },
|
|
@@ -1154,6 +1343,7 @@ async function runWrappedAttach(opts) {
|
|
|
1154
1343
|
let reconnecting = false;
|
|
1155
1344
|
let reconnectAbort = null;
|
|
1156
1345
|
let userDetached = false;
|
|
1346
|
+
let userKilled = false;
|
|
1157
1347
|
let checkpointNoticeAt = 0;
|
|
1158
1348
|
let checkpointNoticeClearedAt = 0;
|
|
1159
1349
|
const reservedRows = () => FOOTER_ROWS + bandReservedRows;
|
|
@@ -1249,7 +1439,7 @@ async function runWrappedAttach(opts) {
|
|
|
1249
1439
|
});
|
|
1250
1440
|
};
|
|
1251
1441
|
wireOutput();
|
|
1252
|
-
const leaderChords = detachable ? { c: "code", s: "screen", u: "url", d: "detach" } : { c: "code", s: "screen", u: "url" };
|
|
1442
|
+
const leaderChords = detachable ? { c: "code", s: "screen", u: "url", t: "shell", k: "kill", d: "detach" } : { c: "code", s: "screen", u: "url", t: "shell", k: "kill" };
|
|
1253
1443
|
const runAction = (name) => {
|
|
1254
1444
|
if (name === "detach") {
|
|
1255
1445
|
if (!reconnecting) {
|
|
@@ -1258,20 +1448,76 @@ async function runWrappedAttach(opts) {
|
|
|
1258
1448
|
}
|
|
1259
1449
|
return;
|
|
1260
1450
|
}
|
|
1451
|
+
if (name === "kill") {
|
|
1452
|
+
if (capturingPrompt) return;
|
|
1453
|
+
const ev = {
|
|
1454
|
+
id: "local:kill",
|
|
1455
|
+
kind: "confirm",
|
|
1456
|
+
message: `Destroy ${opts.boxName}? This wipes the box and all its data.`,
|
|
1457
|
+
detail: "This cannot be undone.",
|
|
1458
|
+
defaultAnswer: "n",
|
|
1459
|
+
context: { command: "destroy box" }
|
|
1460
|
+
};
|
|
1461
|
+
capturingPrompt = ev;
|
|
1462
|
+
applyBandChange();
|
|
1463
|
+
void router.capture(ev).then((body) => {
|
|
1464
|
+
if (body.answer !== "y" || body.cancelled) return;
|
|
1465
|
+
userDetached = true;
|
|
1466
|
+
userKilled = true;
|
|
1467
|
+
flashMessage = `Destroying ${opts.boxName}\u2026`;
|
|
1468
|
+
recomputeFooter();
|
|
1469
|
+
redrawChrome();
|
|
1470
|
+
const cli = process.argv[1];
|
|
1471
|
+
if (typeof cli === "string" && cli.length > 0) {
|
|
1472
|
+
try {
|
|
1473
|
+
spawn3(process.execPath, [cli, "destroy", opts.boxId, "-y"], {
|
|
1474
|
+
detached: true,
|
|
1475
|
+
stdio: "ignore"
|
|
1476
|
+
}).unref();
|
|
1477
|
+
} catch (e) {
|
|
1478
|
+
logErr(`leader-action kill spawn failed: ${e.message}`);
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
}).catch((e) => {
|
|
1482
|
+
if (capturingPrompt === ev) {
|
|
1483
|
+
capturingPrompt = null;
|
|
1484
|
+
applyBandChange();
|
|
1485
|
+
}
|
|
1486
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
1487
|
+
if (msg !== "resolved-elsewhere") logErr(`kill confirm rejected: ${msg}`);
|
|
1488
|
+
});
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1261
1491
|
const cliEntry = process.argv[1];
|
|
1262
|
-
if (
|
|
1263
|
-
const
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1492
|
+
if (name === "shell") {
|
|
1493
|
+
const host = detectHostTerminal();
|
|
1494
|
+
if (typeof cliEntry === "string" && cliEntry.length > 0 && host !== "unknown") {
|
|
1495
|
+
void spawnInNewTerminal({
|
|
1496
|
+
host,
|
|
1497
|
+
mode: "tab",
|
|
1498
|
+
argv: [process.execPath, cliEntry, "shell", opts.boxId, "--new"],
|
|
1499
|
+
cwd: process.cwd(),
|
|
1500
|
+
title: `${opts.boxName} shell`
|
|
1501
|
+
}).then((r) => {
|
|
1502
|
+
if (!r.launched && r.error) logErr(`leader-action shell: ${r.error}`);
|
|
1503
|
+
}).catch((e) => logErr(`leader-action shell failed: ${e.message}`));
|
|
1504
|
+
}
|
|
1505
|
+
flashMessage = host === "unknown" ? `Run: agentbox shell ${opts.boxId} --new` : ACTION_FLASH.shell;
|
|
1506
|
+
} else {
|
|
1507
|
+
if (typeof cliEntry === "string" && cliEntry.length > 0) {
|
|
1508
|
+
const cmd = ACTION_CMD[name];
|
|
1509
|
+
try {
|
|
1510
|
+
spawn3(
|
|
1511
|
+
process.execPath,
|
|
1512
|
+
[cliEntry, cmd.sub, opts.boxId, ...cmd.flags],
|
|
1513
|
+
{ detached: true, stdio: "ignore" }
|
|
1514
|
+
).unref();
|
|
1515
|
+
} catch (e) {
|
|
1516
|
+
logErr(`leader-action spawn (${name}) failed: ${e.message}`);
|
|
1517
|
+
}
|
|
1272
1518
|
}
|
|
1519
|
+
flashMessage = ACTION_FLASH[name];
|
|
1273
1520
|
}
|
|
1274
|
-
flashMessage = ACTION_FLASH[name];
|
|
1275
1521
|
if (flashTimer) clearTimeout(flashTimer);
|
|
1276
1522
|
flashTimer = setTimeout(() => {
|
|
1277
1523
|
flashTimer = null;
|
|
@@ -1318,7 +1564,9 @@ async function runWrappedAttach(opts) {
|
|
|
1318
1564
|
pty.write(b.toString("utf8"));
|
|
1319
1565
|
},
|
|
1320
1566
|
onAnswer: (body) => {
|
|
1321
|
-
|
|
1567
|
+
if (!body.id.startsWith("local:")) {
|
|
1568
|
+
void postAnswer({ relayBaseUrl: opts.relayBaseUrl, body });
|
|
1569
|
+
}
|
|
1322
1570
|
capturingPrompt = null;
|
|
1323
1571
|
applyBandChange();
|
|
1324
1572
|
},
|
|
@@ -1385,6 +1633,8 @@ async function runWrappedAttach(opts) {
|
|
|
1385
1633
|
}
|
|
1386
1634
|
}
|
|
1387
1635
|
});
|
|
1636
|
+
let cmuxOn = false;
|
|
1637
|
+
let cmuxOrig = null;
|
|
1388
1638
|
const pollStatus = async () => {
|
|
1389
1639
|
try {
|
|
1390
1640
|
const status = await readBoxStatus({
|
|
@@ -1395,6 +1645,12 @@ async function runWrappedAttach(opts) {
|
|
|
1395
1645
|
const body = opts.mode === "codex" ? status?.codex : opts.mode === "opencode" ? status?.opencode : opts.mode === "shell" ? void 0 : status?.claude;
|
|
1396
1646
|
const nextTitle = body?.sessionTitle?.trim() || void 0;
|
|
1397
1647
|
const nextActivity = body?.state || void 0;
|
|
1648
|
+
if (cmuxOn && nextActivity !== lastActivity) {
|
|
1649
|
+
applyCmuxAgentState(opts.mode, nextActivity);
|
|
1650
|
+
if (isAttentionState(nextActivity) && !isAttentionState(lastActivity)) {
|
|
1651
|
+
markCmuxTabAttention(opts.mode, opts.boxName, nextActivity);
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1398
1654
|
const desiredTitle = nextTitle ?? opts.boxName;
|
|
1399
1655
|
if (desiredTitle !== lastEmittedTitle) {
|
|
1400
1656
|
lastEmittedTitle = desiredTitle;
|
|
@@ -1417,6 +1673,10 @@ async function runWrappedAttach(opts) {
|
|
|
1417
1673
|
logErr(`status poll failed: ${e.message}`);
|
|
1418
1674
|
}
|
|
1419
1675
|
};
|
|
1676
|
+
if (opts.mode !== "shell") {
|
|
1677
|
+
cmuxOn = await cmuxStatusEnabled();
|
|
1678
|
+
if (cmuxOn) cmuxOrig = captureCmuxWorkspace();
|
|
1679
|
+
}
|
|
1420
1680
|
void pollStatus();
|
|
1421
1681
|
const statusTimer = setInterval(() => {
|
|
1422
1682
|
void pollStatus();
|
|
@@ -1505,6 +1765,7 @@ async function runWrappedAttach(opts) {
|
|
|
1505
1765
|
process.stdin.off("data", onStdinData);
|
|
1506
1766
|
process.stdout.off("resize", onResize);
|
|
1507
1767
|
clearInterval(statusTimer);
|
|
1768
|
+
if (cmuxOn) restoreCmuxWorkspace(cmuxOrig);
|
|
1508
1769
|
stopSpinner();
|
|
1509
1770
|
if (flashTimer) clearTimeout(flashTimer);
|
|
1510
1771
|
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
@@ -1520,13 +1781,16 @@ async function runWrappedAttach(opts) {
|
|
|
1520
1781
|
teardownPaint += cursorMoveTo(rsFinal, csFinal);
|
|
1521
1782
|
process.stdout.write(teardownPaint);
|
|
1522
1783
|
popTerminalTitle();
|
|
1523
|
-
if (
|
|
1784
|
+
if (userKilled) {
|
|
1785
|
+
process.stdout.write(`\x1B[1A\x1B[2K\rbox ${opts.boxName} destroyed
|
|
1786
|
+
`);
|
|
1787
|
+
} else if (exitCode === 0 && opts.detachNotice) {
|
|
1524
1788
|
process.stdout.write("\x1B[1A\x1B[2K\r" + opts.detachNotice + "\n");
|
|
1525
1789
|
}
|
|
1526
1790
|
return exitCode;
|
|
1527
1791
|
}
|
|
1528
1792
|
function runFallback(command, argv, env) {
|
|
1529
|
-
const child =
|
|
1793
|
+
const child = spawnSync2(command, argv, {
|
|
1530
1794
|
stdio: "inherit",
|
|
1531
1795
|
env: env ? { ...process.env, ...env } : process.env
|
|
1532
1796
|
});
|
|
@@ -1817,7 +2081,7 @@ async function cloudAgentStartDetached(args) {
|
|
|
1817
2081
|
}
|
|
1818
2082
|
function runDetached(argv, env) {
|
|
1819
2083
|
return new Promise((resolve) => {
|
|
1820
|
-
const child =
|
|
2084
|
+
const child = spawn4(argv[0], argv.slice(1), {
|
|
1821
2085
|
stdio: "ignore",
|
|
1822
2086
|
env: env ? { ...process.env, ...env } : process.env
|
|
1823
2087
|
});
|
|
@@ -1857,4 +2121,4 @@ export {
|
|
|
1857
2121
|
cloudAgentAttach,
|
|
1858
2122
|
cloudAgentStartDetached
|
|
1859
2123
|
};
|
|
1860
|
-
//# sourceMappingURL=chunk-
|
|
2124
|
+
//# sourceMappingURL=chunk-QYRK5H6Q.js.map
|