@madarco/agentbox 0.1.0 → 0.2.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/dist/{chunk-O5HS3QHW.js → chunk-3NIZKZPJ.js} +67 -16
- package/dist/chunk-3NIZKZPJ.js.map +1 -0
- package/dist/{chunk-RWJE6AER.js → chunk-3NU4PS5W.js} +3 -3
- package/dist/{chunk-OOOKFFR5.js → chunk-3OPLNXQ5.js} +3 -3
- package/dist/{create-LSSO7H4I-GWNALUMF.js → create-SE6H4B5U-ESNDTXAI.js} +3 -3
- package/dist/index.js +150 -10
- package/dist/index.js.map +1 -1
- package/dist/{lifecycle-P4FSKGR2-3466P54Y.js → lifecycle-A4QHFADW-4DREGGAE.js} +3 -3
- package/package.json +3 -3
- package/runtime/docker/apps/cli/share/agentbox-setup/SKILL.md +8 -4
- package/share/agentbox-setup/SKILL.md +8 -4
- package/dist/chunk-O5HS3QHW.js.map +0 -1
- /package/dist/{chunk-RWJE6AER.js.map → chunk-3NU4PS5W.js.map} +0 -0
- /package/dist/{chunk-OOOKFFR5.js.map → chunk-3OPLNXQ5.js.map} +0 -0
- /package/dist/{create-LSSO7H4I-GWNALUMF.js.map → create-SE6H4B5U-ESNDTXAI.js.map} +0 -0
- /package/dist/{lifecycle-P4FSKGR2-3466P54Y.js.map → lifecycle-A4QHFADW-4DREGGAE.js.map} +0 -0
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
snapshotPathFor,
|
|
28
28
|
verifyOverlay,
|
|
29
29
|
vscodeServerVolumeName
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-3NIZKZPJ.js";
|
|
31
31
|
import {
|
|
32
32
|
allocateProjectIndex,
|
|
33
33
|
readState,
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
runBox
|
|
52
52
|
} from "./chunk-SOMIKEN2.js";
|
|
53
53
|
|
|
54
|
-
// ../../packages/sandbox-docker/dist/chunk-
|
|
54
|
+
// ../../packages/sandbox-docker/dist/chunk-BC7AYNLK.js
|
|
55
55
|
import { randomBytes } from "crypto";
|
|
56
56
|
import { mkdir, stat } from "fs/promises";
|
|
57
57
|
import { homedir } from "os";
|
|
@@ -493,4 +493,4 @@ export {
|
|
|
493
493
|
defaultBoxName,
|
|
494
494
|
createBox
|
|
495
495
|
};
|
|
496
|
-
//# sourceMappingURL=chunk-
|
|
496
|
+
//# sourceMappingURL=chunk-3OPLNXQ5.js.map
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
createBox,
|
|
4
4
|
defaultBoxName,
|
|
5
5
|
sanitizeBasename
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-3OPLNXQ5.js";
|
|
7
|
+
import "./chunk-3NIZKZPJ.js";
|
|
8
8
|
import "./chunk-IDR4HVIC.js";
|
|
9
9
|
import "./chunk-SOMIKEN2.js";
|
|
10
10
|
export {
|
|
@@ -12,4 +12,4 @@ export {
|
|
|
12
12
|
defaultBoxName,
|
|
13
13
|
sanitizeBasename
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=create-
|
|
15
|
+
//# sourceMappingURL=create-SE6H4B5U-ESNDTXAI.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
createBox
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3OPLNXQ5.js";
|
|
5
5
|
import {
|
|
6
6
|
AmbiguousBoxError,
|
|
7
7
|
BoxNotFoundError,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
startBox,
|
|
16
16
|
stopBox,
|
|
17
17
|
unpauseBox
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-3NU4PS5W.js";
|
|
19
19
|
import {
|
|
20
20
|
ClaudeSessionError,
|
|
21
21
|
SHARED_CLAUDE_VOLUME,
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
resolveClaudeVolume,
|
|
38
38
|
startClaudeSession,
|
|
39
39
|
stopRelay
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-3NIZKZPJ.js";
|
|
41
41
|
import {
|
|
42
42
|
STATE_DIR,
|
|
43
43
|
readState,
|
|
@@ -1916,6 +1916,28 @@ function menuLines(boxName, w, h) {
|
|
|
1916
1916
|
for (let i = 0; i < h; i++) out.push(fit(body[i - top] ?? "", w));
|
|
1917
1917
|
return out;
|
|
1918
1918
|
}
|
|
1919
|
+
function lifecycleMenuLines(boxName, state, confirmDestroy, w, h) {
|
|
1920
|
+
const body = confirmDestroy ? [
|
|
1921
|
+
"",
|
|
1922
|
+
` Destroy ${boxName}?`,
|
|
1923
|
+
" This removes the container and its volumes.",
|
|
1924
|
+
"",
|
|
1925
|
+
" [y] Yes, destroy",
|
|
1926
|
+
" [any other key] Cancel"
|
|
1927
|
+
] : [
|
|
1928
|
+
"",
|
|
1929
|
+
` Box ${boxName} is ${state}.`,
|
|
1930
|
+
"",
|
|
1931
|
+
state === "paused" ? " [u] Unpause" : " [s] Start",
|
|
1932
|
+
" [d] Destroy",
|
|
1933
|
+
"",
|
|
1934
|
+
" Ctrl+Option+\u2191/\u2193 switch \xB7 Ctrl-a then q quit"
|
|
1935
|
+
];
|
|
1936
|
+
const top = Math.max(0, Math.floor((h - body.length) / 2));
|
|
1937
|
+
const out = [];
|
|
1938
|
+
for (let i = 0; i < h; i++) out.push(fit(body[i - top] ?? "", w));
|
|
1939
|
+
return out;
|
|
1940
|
+
}
|
|
1919
1941
|
function createMenuLines(where, w, h) {
|
|
1920
1942
|
const body = [
|
|
1921
1943
|
"",
|
|
@@ -1990,6 +2012,7 @@ var Compositor = class {
|
|
|
1990
2012
|
else if (e.type === "switch") this.switchBox(e.dir);
|
|
1991
2013
|
else if (e.type === "action") void this.doAction(e.name);
|
|
1992
2014
|
else if (this.createMenu) this.handleCreateMenuKey(e.bytes);
|
|
2015
|
+
else if (this.lifecycleMenu) this.handleLifecycleMenuKey(e.bytes);
|
|
1993
2016
|
else if (this.menu) this.handleMenuKey(e.bytes);
|
|
1994
2017
|
else this.session?.write(e.bytes);
|
|
1995
2018
|
},
|
|
@@ -2013,6 +2036,7 @@ var Compositor = class {
|
|
|
2013
2036
|
session = null;
|
|
2014
2037
|
placeholder = null;
|
|
2015
2038
|
menu = null;
|
|
2039
|
+
lifecycleMenu = null;
|
|
2016
2040
|
createMenu = null;
|
|
2017
2041
|
activeMode = "claude";
|
|
2018
2042
|
flashMsg = null;
|
|
@@ -2082,7 +2106,7 @@ var Compositor = class {
|
|
|
2082
2106
|
} else {
|
|
2083
2107
|
const box = this.selectedBox();
|
|
2084
2108
|
const running = box?.state === "running";
|
|
2085
|
-
const reresolve = this.session && !running || this.placeholder && running || this.menu && !running;
|
|
2109
|
+
const reresolve = this.session && !running || this.placeholder && running || this.menu && !running || this.lifecycleMenu != null && box?.state !== this.lifecycleMenu.state;
|
|
2086
2110
|
if (reresolve) await this.spawnActive();
|
|
2087
2111
|
}
|
|
2088
2112
|
if (JSON.stringify(this.boxes.map((b) => [b.id, b.state, b.claudeActivity])) !== before) {
|
|
@@ -2098,6 +2122,7 @@ var Compositor = class {
|
|
|
2098
2122
|
this.disposeSession();
|
|
2099
2123
|
this.placeholder = null;
|
|
2100
2124
|
this.menu = null;
|
|
2125
|
+
this.lifecycleMenu = null;
|
|
2101
2126
|
this.createMenu = null;
|
|
2102
2127
|
this.clearRightPane();
|
|
2103
2128
|
const id = this.selectedId;
|
|
@@ -2110,6 +2135,7 @@ var Compositor = class {
|
|
|
2110
2135
|
this.disposeSession();
|
|
2111
2136
|
this.placeholder = null;
|
|
2112
2137
|
this.menu = null;
|
|
2138
|
+
this.lifecycleMenu = null;
|
|
2113
2139
|
this.createMenu = null;
|
|
2114
2140
|
if (target.kind === "attach") {
|
|
2115
2141
|
this.activeMode = target.mode ?? "claude";
|
|
@@ -2124,6 +2150,12 @@ var Compositor = class {
|
|
|
2124
2150
|
);
|
|
2125
2151
|
} else if (target.kind === "menu") {
|
|
2126
2152
|
this.menu = { boxName: this.selectedBox()?.name ?? this.selectedId };
|
|
2153
|
+
} else if (target.kind === "lifecycle-menu") {
|
|
2154
|
+
this.lifecycleMenu = {
|
|
2155
|
+
boxName: this.selectedBox()?.name ?? this.selectedId,
|
|
2156
|
+
state: target.state,
|
|
2157
|
+
confirmDestroy: false
|
|
2158
|
+
};
|
|
2127
2159
|
} else if (target.kind === "create-menu") {
|
|
2128
2160
|
this.createMenu = { where: target.where };
|
|
2129
2161
|
} else {
|
|
@@ -2176,6 +2208,77 @@ var Compositor = class {
|
|
|
2176
2208
|
this.busy = false;
|
|
2177
2209
|
}
|
|
2178
2210
|
}
|
|
2211
|
+
handleLifecycleMenuKey(bytes) {
|
|
2212
|
+
const m = this.lifecycleMenu;
|
|
2213
|
+
if (!m) return;
|
|
2214
|
+
for (const b of bytes) {
|
|
2215
|
+
if (m.confirmDestroy) {
|
|
2216
|
+
if (b === 121 || b === 13 || b === 10) {
|
|
2217
|
+
void this.choosePaused("destroy");
|
|
2218
|
+
} else {
|
|
2219
|
+
m.confirmDestroy = false;
|
|
2220
|
+
this.drawChrome();
|
|
2221
|
+
this.scheduleRender();
|
|
2222
|
+
}
|
|
2223
|
+
return;
|
|
2224
|
+
}
|
|
2225
|
+
const resumeKey = m.state === "paused" ? 117 : 115;
|
|
2226
|
+
if (b === resumeKey) {
|
|
2227
|
+
void this.choosePaused("resume");
|
|
2228
|
+
return;
|
|
2229
|
+
}
|
|
2230
|
+
if (b === 100) {
|
|
2231
|
+
m.confirmDestroy = true;
|
|
2232
|
+
this.drawChrome();
|
|
2233
|
+
this.scheduleRender();
|
|
2234
|
+
return;
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
async choosePaused(which) {
|
|
2239
|
+
if (this.busy) return;
|
|
2240
|
+
const id = this.selectedId;
|
|
2241
|
+
const name = this.selectedBox()?.name ?? id;
|
|
2242
|
+
const resumeVerb = this.lifecycleMenu?.state === "stopped" ? "start" : "unpause";
|
|
2243
|
+
this.busy = true;
|
|
2244
|
+
this.menu = null;
|
|
2245
|
+
this.lifecycleMenu = null;
|
|
2246
|
+
this.createMenu = null;
|
|
2247
|
+
this.placeholder = ["", which === "resume" ? " Resuming\u2026" : " Destroying\u2026"];
|
|
2248
|
+
this.prevRows = null;
|
|
2249
|
+
this.drawChrome();
|
|
2250
|
+
this.scheduleRender();
|
|
2251
|
+
try {
|
|
2252
|
+
if (which === "resume") {
|
|
2253
|
+
await this.deps.resumeBox(id);
|
|
2254
|
+
if (this.selectedId !== id || this.tornDown) return;
|
|
2255
|
+
await this.refreshBoxes();
|
|
2256
|
+
await this.spawnActive();
|
|
2257
|
+
} else {
|
|
2258
|
+
await this.deps.destroyBox(id);
|
|
2259
|
+
if (this.tornDown) return;
|
|
2260
|
+
await this.refreshBoxes();
|
|
2261
|
+
if (this.boxes[0]) this.selectedId = this.boxes[0].id;
|
|
2262
|
+
await this.spawnActive();
|
|
2263
|
+
this.flash(`destroyed ${name}`);
|
|
2264
|
+
}
|
|
2265
|
+
} catch (err) {
|
|
2266
|
+
if (this.selectedId !== id || this.tornDown) return;
|
|
2267
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2268
|
+
const verb = which === "resume" ? resumeVerb : "destroy";
|
|
2269
|
+
this.placeholder = [
|
|
2270
|
+
"",
|
|
2271
|
+
` Failed to ${verb} ${name}:`,
|
|
2272
|
+
` ${msg}`,
|
|
2273
|
+
"",
|
|
2274
|
+
` Try from a shell: agentbox ${verb} ${name}`
|
|
2275
|
+
];
|
|
2276
|
+
this.prevRows = null;
|
|
2277
|
+
this.scheduleRender();
|
|
2278
|
+
} finally {
|
|
2279
|
+
this.busy = false;
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2179
2282
|
handleCreateMenuKey(bytes) {
|
|
2180
2283
|
for (const b of bytes) {
|
|
2181
2284
|
if (b === 99 || b === 13 || b === 10) {
|
|
@@ -2300,6 +2403,17 @@ var Compositor = class {
|
|
|
2300
2403
|
let s = SYNC_BEGIN + "\x1B[?25l";
|
|
2301
2404
|
for (let i = 0; i < r.h; i++) s += cursorTo2(r.x, r.y + i) + "\x1B[0m" + (lines[i] ?? "");
|
|
2302
2405
|
this.out.write(s + SYNC_END);
|
|
2406
|
+
} else if (this.lifecycleMenu) {
|
|
2407
|
+
const lines = lifecycleMenuLines(
|
|
2408
|
+
this.lifecycleMenu.boxName,
|
|
2409
|
+
this.lifecycleMenu.state,
|
|
2410
|
+
this.lifecycleMenu.confirmDestroy,
|
|
2411
|
+
r.w,
|
|
2412
|
+
r.h
|
|
2413
|
+
);
|
|
2414
|
+
let s = SYNC_BEGIN + "\x1B[?25l";
|
|
2415
|
+
for (let i = 0; i < r.h; i++) s += cursorTo2(r.x, r.y + i) + "\x1B[0m" + (lines[i] ?? "");
|
|
2416
|
+
this.out.write(s + SYNC_END);
|
|
2303
2417
|
} else if (this.createMenu) {
|
|
2304
2418
|
const lines = createMenuLines(this.createMenu.where, r.w, r.h);
|
|
2305
2419
|
let s = SYNC_BEGIN + "\x1B[?25l";
|
|
@@ -2437,6 +2551,9 @@ var dashboardCommand = new Command7("dashboard").description("Box list + the sel
|
|
|
2437
2551
|
if (boxId === NEW_BOX_ID) return { kind: "create-menu", where: project.root };
|
|
2438
2552
|
const box = (await listBoxes()).find((b) => b.id === boxId);
|
|
2439
2553
|
if (!box) return { kind: "placeholder", lines: ["", " box not found"] };
|
|
2554
|
+
if (box.state === "paused" || box.state === "stopped") {
|
|
2555
|
+
return { kind: "lifecycle-menu", state: box.state };
|
|
2556
|
+
}
|
|
2440
2557
|
if (box.state !== "running") {
|
|
2441
2558
|
return {
|
|
2442
2559
|
kind: "placeholder",
|
|
@@ -2552,6 +2669,15 @@ var dashboardCommand = new Command7("dashboard").description("Box list + the sel
|
|
|
2552
2669
|
detach(process.execPath, [process.argv[1], "code", box.name, "--no-wait"]);
|
|
2553
2670
|
return "Launching VS Code / Cursor\u2026";
|
|
2554
2671
|
};
|
|
2672
|
+
const resumeBox = async (boxId) => {
|
|
2673
|
+
const box = (await listBoxes()).find((b) => b.id === boxId);
|
|
2674
|
+
if (!box) throw new Error("box not found");
|
|
2675
|
+
if (box.state === "paused") await unpauseBox(box.id);
|
|
2676
|
+
else await startBox(box.id);
|
|
2677
|
+
};
|
|
2678
|
+
const destroyBoxAction = async (boxId) => {
|
|
2679
|
+
await destroyBox(boxId);
|
|
2680
|
+
};
|
|
2555
2681
|
const compositor = new Compositor(
|
|
2556
2682
|
{
|
|
2557
2683
|
ptySpawn,
|
|
@@ -2561,6 +2687,8 @@ var dashboardCommand = new Command7("dashboard").description("Box list + the sel
|
|
|
2561
2687
|
startClaude,
|
|
2562
2688
|
openShell,
|
|
2563
2689
|
createNewBox,
|
|
2690
|
+
resumeBox,
|
|
2691
|
+
destroyBox: destroyBoxAction,
|
|
2564
2692
|
openVnc,
|
|
2565
2693
|
openCode,
|
|
2566
2694
|
openWeb
|
|
@@ -2745,28 +2873,40 @@ function renderTable(boxes, stream) {
|
|
|
2745
2873
|
(row2) => row2.map((cell, i) => padCell(cell ?? plain(""), i)).join(" ").trimEnd()
|
|
2746
2874
|
).join("\n");
|
|
2747
2875
|
}
|
|
2748
|
-
async function
|
|
2876
|
+
async function scopedBoxes(all) {
|
|
2749
2877
|
const boxes = await listBoxes();
|
|
2750
|
-
if (
|
|
2878
|
+
if (all) return { boxes, projectRoot: "", scoped: false };
|
|
2879
|
+
const { root } = await findProjectRoot(process.cwd());
|
|
2880
|
+
return { boxes: boxes.filter((b) => b.projectRoot === root), projectRoot: root, scoped: true };
|
|
2881
|
+
}
|
|
2882
|
+
async function buildListText(all) {
|
|
2883
|
+
const { boxes, projectRoot, scoped: scoped2 } = await scopedBoxes(all);
|
|
2884
|
+
if (boxes.length === 0) {
|
|
2885
|
+
if (scoped2) {
|
|
2886
|
+
return `no boxes in this project (${projectRoot}) \u2014 run \`agentbox create\`, or \`agentbox list --all\` to see all`;
|
|
2887
|
+
}
|
|
2888
|
+
return "no boxes \u2014 run `agentbox create` to make one";
|
|
2889
|
+
}
|
|
2751
2890
|
return renderTable(boxes, process.stdout);
|
|
2752
2891
|
}
|
|
2753
2892
|
var listCommand2 = withWatchOptions(
|
|
2754
|
-
new Command9("list").alias("ls").description("List
|
|
2893
|
+
new Command9("list").alias("ls").description("List agent boxes in the current project (-a for all)").option("-j, --json", "machine-readable JSON output").option("-a, --all", "include boxes from all projects")
|
|
2755
2894
|
).action(async (opts) => {
|
|
2756
2895
|
if (opts.json && opts.watch) {
|
|
2757
2896
|
log11.error("cannot combine --json with --watch");
|
|
2758
2897
|
process.exit(2);
|
|
2759
2898
|
}
|
|
2899
|
+
const all = opts.all ?? false;
|
|
2760
2900
|
if (opts.watch) {
|
|
2761
|
-
await watchRender(buildListText, opts.interval);
|
|
2901
|
+
await watchRender(() => buildListText(all), opts.interval);
|
|
2762
2902
|
return;
|
|
2763
2903
|
}
|
|
2764
2904
|
if (opts.json) {
|
|
2765
|
-
const boxes = await
|
|
2905
|
+
const { boxes } = await scopedBoxes(all);
|
|
2766
2906
|
process.stdout.write(JSON.stringify(boxes, null, 2) + "\n");
|
|
2767
2907
|
return;
|
|
2768
2908
|
}
|
|
2769
|
-
process.stdout.write(await buildListText() + "\n");
|
|
2909
|
+
process.stdout.write(await buildListText(all) + "\n");
|
|
2770
2910
|
});
|
|
2771
2911
|
|
|
2772
2912
|
// src/commands/logs.ts
|