@tyvm/knowhow 0.0.143 → 0.0.144

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tyvm/knowhow",
3
- "version": "0.0.143",
3
+ "version": "0.0.144",
4
4
  "description": "ai cli with plugins and agents",
5
5
  "main": "ts_build/src/index.js",
6
6
  "bin": {
@@ -60,6 +60,7 @@ interface SandboxSnapshot {
60
60
  status: string;
61
61
  errorMsg?: string | null;
62
62
  statusMessage?: string | null;
63
+ regenerationSandboxId?: string | null;
63
64
  snapshotContent?: string;
64
65
  setupScript?: string | null;
65
66
  }
@@ -122,6 +123,51 @@ async function resolveSnapshot(
122
123
 
123
124
  // ─── Polling helpers ──────────────────────────────────────────────────────────
124
125
 
126
+ /**
127
+ * Poll a snapshot's status until regeneration is complete.
128
+ *
129
+ * The backend's POST /regenerate endpoint is fire-and-forget — it returns
130
+ * immediately with regenerationSandboxId set. We poll GET /snapshots/:id
131
+ * until one of:
132
+ * - regenerationSandboxId is null AND status === "ready" → success
133
+ * - status === "error" → failure
134
+ * - deadline exceeded → timeout
135
+ *
136
+ * statusMessage is printed whenever it changes so the user sees progress.
137
+ */
138
+ async function pollRegeneration(
139
+ sandboxId: string,
140
+ snapshotId: string,
141
+ timeoutMs: number
142
+ ): Promise<SandboxSnapshot> {
143
+ const deadline = Date.now() + timeoutMs;
144
+ let lastStatus = "";
145
+ let lastMessage = "";
146
+ while (Date.now() < deadline) {
147
+ const snap = await apiGet<SandboxSnapshot>(
148
+ `/sandboxes/${sandboxId}/snapshots/${snapshotId}`
149
+ );
150
+ if (snap.status !== lastStatus) {
151
+ console.log(` [snapshot] status: ${snap.status}`);
152
+ lastStatus = snap.status;
153
+ }
154
+ if (snap.statusMessage && snap.statusMessage !== lastMessage) {
155
+ console.log(` [snapshot] ${snap.statusMessage}`);
156
+ lastMessage = snap.statusMessage;
157
+ }
158
+ if (!snap.regenerationSandboxId && snap.status === "ready") return snap;
159
+ if (snap.status === "error") {
160
+ throw new Error(
161
+ `Snapshot regeneration failed: ${snap.errorMsg || snap.statusMessage || "(no details)"}`
162
+ );
163
+ }
164
+ await new Promise((r) => setTimeout(r, 5000));
165
+ }
166
+ throw new Error(
167
+ `Timeout waiting for snapshot regeneration to complete (${timeoutMs}ms). Last status: ${lastStatus}`
168
+ );
169
+ }
170
+
125
171
  async function pollSandboxStatus(
126
172
  sandboxId: string,
127
173
  targetStatuses: string[],
@@ -373,7 +419,7 @@ export function addSandboxCommand(program: Command): void {
373
419
  .option("--sandbox-name <name>", "Source sandbox name (alternative to --sandbox-id)")
374
420
  .option("--snapshot-id <id>", "Snapshot ID to regenerate")
375
421
  .option("--snapshot-name <name>", "Snapshot label to regenerate")
376
- .option("--no-wait", "Return immediately without waiting for snapshot to be ready")
422
+ .option("--no-wait", "Trigger regeneration and return immediately (do not poll for completion)")
377
423
  .option("--timeout-minutes <min>", "Max time for the full regen cycle", "60")
378
424
  .action(
379
425
  async (opts: {
@@ -381,20 +427,18 @@ export function addSandboxCommand(program: Command): void {
381
427
  sandboxName?: string;
382
428
  snapshotId?: string;
383
429
  snapshotName?: string;
384
- wait: boolean; // commander flips --no-wait → wait=false
430
+ wait: boolean;
385
431
  timeoutMinutes: string;
386
432
  }) => {
387
433
  const timeoutMs = Number(opts.timeoutMinutes) * 60 * 1000;
388
- const deadline = Date.now() + timeoutMs;
389
434
 
390
- // ── 1. Resolve sandbox ──────────────────────────────────────────────
435
+ // ── 1. Resolve sandbox & snapshot ──────────────────────────────────
391
436
  if (!opts.sandboxId && !opts.sandboxName) {
392
437
  throw new Error("Provide --sandbox-id or --sandbox-name");
393
438
  }
394
439
  const sandboxId =
395
440
  opts.sandboxId || (await resolveSandboxId(opts.sandboxName!));
396
441
 
397
- // ── 2. Resolve snapshot ─────────────────────────────────────────────
398
442
  if (!opts.snapshotId && !opts.snapshotName) {
399
443
  throw new Error("Provide --snapshot-id or --snapshot-name");
400
444
  }
@@ -410,132 +454,113 @@ export function addSandboxCommand(program: Command): void {
410
454
  );
411
455
  console.log(` Source sandbox: ${sandboxId}`);
412
456
 
413
- if (snapshot.status !== "ready") {
457
+ // ── 2. Validate preconditions ───────────────────────────────────────
458
+ if (snapshot.status !== "ready" && !snapshot.regenerationSandboxId) {
414
459
  throw new Error(
415
460
  `Snapshot must be in 'ready' status to regenerate (current: ${snapshot.status})`
416
461
  );
417
462
  }
418
- if (!snapshot.setupScript) {
419
- throw new Error(
420
- "Snapshot has no setupScript. Add one via the UI before regenerating."
421
- );
422
- }
423
463
 
424
- // ── 3. Fork ephemeral sandbox from the snapshot ─────────────────────
425
- console.log("\n📦 Step 1/4: Forking ephemeral sandbox from snapshot...");
426
- const ephemeralName = `regen-${snapshotId.slice(0, 8)}-${Date.now()}`;
427
- const forkResult = await apiPost<{ id?: string; sandboxId?: string }>(
428
- "/sandboxes/fork",
429
- { snapshotId, name: ephemeralName }
464
+ // ── 3. Kick off background regeneration via backend API ─────────────
465
+ // The backend POST /regenerate endpoint returns immediately with the
466
+ // updated snapshot (regenerationSandboxId set). It runs the full
467
+ // cycle (fork ephemeral → setupScript → snapshot) in the background.
468
+ console.log("\n📡 Triggering backend regeneration...");
469
+ const triggered = await apiPost<SandboxSnapshot>(
470
+ `/sandboxes/${sandboxId}/snapshots/${snapshotId}/regenerate`
430
471
  );
431
- const ephemeralId = forkResult.id || forkResult.sandboxId;
432
- if (!ephemeralId) {
433
- throw new Error(
434
- `Fork did not return a sandbox ID: ${JSON.stringify(forkResult)}`
472
+ console.log(` regenerationSandboxId: ${triggered.regenerationSandboxId || "(none)"}`);
473
+
474
+ if (!opts.wait) {
475
+ console.log(
476
+ `\n✅ Regeneration triggered. Monitor with:\n` +
477
+ ` knowhow sandbox snapshot-status --sandbox-id ${sandboxId} --snapshot-id ${snapshotId}`
435
478
  );
479
+ return;
436
480
  }
437
- console.log(` Ephemeral sandbox: ${ephemeralId} (${ephemeralName})`);
438
-
439
- // ── 4. Wait for ephemeral sandbox to be running ─────────────────────
440
- console.log("\n⏳ Step 2/4: Waiting for sandbox to start...");
441
- await pollSandboxStatus(
442
- ephemeralId,
443
- ["running"],
444
- Math.min(deadline - Date.now(), 10 * 60 * 1000),
445
- ephemeralName
481
+
482
+ // ── 4. Poll until complete ──────────────────────────────────────────
483
+ console.log("\n⏳ Waiting for regeneration to complete (Ctrl+C to stop polling)...");
484
+ const done = await pollRegeneration(sandboxId, snapshotId, timeoutMs);
485
+
486
+ console.log(
487
+ `\n✅ Snapshot regeneration complete!\n` +
488
+ ` Snapshot ID : ${done.id}\n` +
489
+ ` Label : ${done.label || "(none)"}\n` +
490
+ ` Status : ${done.status}`
446
491
  );
447
- console.log(" ✓ Running");
448
-
449
- // ── 5. Execute the setupScript ──────────────────────────────────────
450
- console.log("\n🔧 Step 3/4: Executing setupScript...");
451
- console.log(` Script length: ${snapshot.setupScript.length} chars`);
452
- let execResult: { stdout?: string; stderr?: string; exitCode?: number };
453
- try {
454
- execResult = await apiPost<{
455
- stdout?: string;
456
- stderr?: string;
457
- exitCode?: number;
458
- }>(`/sandboxes/${ephemeralId}/exec`, {
459
- command: "/bin/bash",
460
- args: ["-c", snapshot.setupScript],
461
- timeoutMs: Math.min(deadline - Date.now(), 25 * 60 * 1000),
462
- });
463
- } catch (err: any) {
464
- console.error(`\n❌ setupScript exec failed: ${err.message}`);
465
- await safeDestroy(ephemeralId);
466
- throw err;
467
- }
492
+ }
493
+ );
468
494
 
469
- if (execResult.stdout) {
470
- console.log("--- stdout ---");
471
- process.stdout.write(execResult.stdout);
472
- }
473
- if (execResult.stderr) {
474
- console.error("--- stderr ---");
475
- process.stderr.write(execResult.stderr);
495
+ // ── sandbox snapshot-status ──────────────────────────────────────────────────
496
+ sandboxCmd
497
+ .command("snapshot-status")
498
+ .description(
499
+ "Check and optionally wait for a snapshot's regeneration to complete.\n" +
500
+ "Useful after triggering regeneration with --no-wait."
501
+ )
502
+ .option("--sandbox-id <id>", "Sandbox ID")
503
+ .option("--sandbox-name <name>", "Sandbox name")
504
+ .option("--snapshot-id <id>", "Snapshot ID")
505
+ .option("--snapshot-name <name>", "Snapshot label")
506
+ .option("--wait", "Poll until regeneration completes (or times out)")
507
+ .option("--timeout-minutes <min>", "Max poll time in minutes", "60")
508
+ .option("--json", "Output raw JSON")
509
+ .action(
510
+ async (opts: {
511
+ sandboxId?: string;
512
+ sandboxName?: string;
513
+ snapshotId?: string;
514
+ snapshotName?: string;
515
+ wait?: boolean;
516
+ timeoutMinutes: string;
517
+ json?: boolean;
518
+ }) => {
519
+ if (!opts.sandboxId && !opts.sandboxName) {
520
+ throw new Error("Provide --sandbox-id or --sandbox-name");
476
521
  }
477
- if (execResult.exitCode != null && execResult.exitCode !== 0) {
478
- await safeDestroy(ephemeralId);
479
- throw new Error(`setupScript exited with code ${execResult.exitCode}`);
522
+ const sandboxId =
523
+ opts.sandboxId || (await resolveSandboxId(opts.sandboxName!));
524
+
525
+ if (!opts.snapshotId && !opts.snapshotName) {
526
+ throw new Error("Provide --snapshot-id or --snapshot-name");
480
527
  }
481
- console.log(" ✓ setupScript completed");
482
-
483
- // ── 6. Capture new snapshot with the same label ─────────────────────
484
- console.log("\n📸 Step 4/4: Capturing new snapshot...");
485
- const newLabel = snapshot.label || `regen-${snapshotId.slice(0, 8)}`;
486
- let createResult: { snapshot?: SandboxSnapshot; id?: string };
487
- try {
488
- createResult = await apiPost<{ snapshot?: SandboxSnapshot; id?: string }>(
489
- `/sandboxes/${ephemeralId}/snapshots`,
490
- {
491
- label: newLabel,
492
- description: snapshot.description,
493
- snapshotContent: snapshot.snapshotContent || "full",
494
- snapshotType: "full",
495
- }
528
+ const snapshot = opts.snapshotId
529
+ ? await apiGet<SandboxSnapshot>(
530
+ `/sandboxes/${sandboxId}/snapshots/${opts.snapshotId}`
531
+ )
532
+ : await resolveSnapshot(sandboxId, opts.snapshotName!);
533
+
534
+ if (opts.wait && snapshot.regenerationSandboxId) {
535
+ console.log("⏳ Waiting for regeneration to complete...");
536
+ const done = await pollRegeneration(
537
+ sandboxId,
538
+ snapshot.id,
539
+ Number(opts.timeoutMinutes) * 60 * 1000
496
540
  );
497
- } catch (err: any) {
498
- console.error(`\n❌ Snapshot creation failed: ${err.message}`);
499
- await safeDestroy(ephemeralId);
500
- throw err;
541
+ if (opts.json) {
542
+ console.log(JSON.stringify(done, null, 2));
543
+ } else {
544
+ console.log(
545
+ `✅ Done — status: ${done.status} label: ${done.label || "(none)"}`
546
+ );
547
+ }
548
+ return;
501
549
  }
502
550
 
503
- const newSnapshot = createResult.snapshot || (createResult as SandboxSnapshot);
504
- const newSnapshotId = newSnapshot.id;
505
- console.log(` New snapshot ID: ${newSnapshotId}`);
506
-
507
- if (opts.wait) {
508
- console.log(" Waiting for snapshot upload...");
509
- await pollSnapshotStatus(
510
- ephemeralId,
511
- newSnapshotId,
512
- ["ready"],
513
- Math.min(deadline - Date.now(), 20 * 60 * 1000)
551
+ if (opts.json) {
552
+ console.log(JSON.stringify(snapshot, null, 2));
553
+ } else {
554
+ const regenInfo = snapshot.regenerationSandboxId
555
+ ? `🔄 regenerating (ephemeral: ${snapshot.regenerationSandboxId})`
556
+ : `✅ ${snapshot.status}`;
557
+ console.log(
558
+ `Snapshot ${snapshot.id} label=${snapshot.label || "(none)"} ${regenInfo}`
514
559
  );
515
- console.log(" ✓ Snapshot ready");
560
+ if (snapshot.statusMessage) {
561
+ console.log(` message: ${snapshot.statusMessage}`);
562
+ }
516
563
  }
517
-
518
- // ── 7. Destroy ephemeral sandbox ────────────────────────────────────
519
- console.log("\n🗑 Destroying ephemeral sandbox...");
520
- await safeDestroy(ephemeralId);
521
- console.log(" ✓ Destroyed");
522
-
523
- console.log(
524
- `\n✅ Snapshot regeneration complete!\n` +
525
- ` Old snapshot ID : ${snapshotId}\n` +
526
- ` New snapshot ID : ${newSnapshotId}\n` +
527
- ` Label : ${newLabel}\n\n` +
528
- `ℹ The old snapshot still exists. Clean it up with:\n` +
529
- ` knowhow sandbox delete-snapshot --sandbox-id ${sandboxId} --snapshot-id ${snapshotId}`
530
- );
531
564
  }
532
565
  );
533
566
  }
534
-
535
- async function safeDestroy(sandboxId: string): Promise<void> {
536
- try {
537
- await apiDelete(`/sandboxes/${sandboxId}`);
538
- } catch (err: any) {
539
- console.warn(`⚠ Could not destroy sandbox ${sandboxId}: ${err.message}`);
540
- }
541
- }
@@ -0,0 +1,350 @@
1
+ /**
2
+ * Unit tests for the sandbox CLI command.
3
+ *
4
+ * Focus: `regenerate-snapshot` and `snapshot-status` commands use the backend
5
+ * `/regenerate` endpoint (fire-and-forget) + polling rather than a single
6
+ * long synchronous exec request.
7
+ */
8
+
9
+ // ─── Mock http util ───────────────────────────────────────────────────────────
10
+ // jest.mock is hoisted so we must declare the fns inside the factory,
11
+ // then retrieve them via require after the fact.
12
+ jest.mock("../../../src/utils/http", () => {
13
+ const get = jest.fn();
14
+ const post = jest.fn();
15
+ const del = jest.fn();
16
+ const mock = { get, post, delete: del };
17
+ return { default: mock, __esModule: true };
18
+ });
19
+
20
+ // Pull the mock fns after the module is mocked
21
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
22
+ const httpMock = (require("../../../src/utils/http") as { default: { get: jest.Mock; post: jest.Mock; delete: jest.Mock } }).default;
23
+ const mockGet = httpMock.get;
24
+ const mockPost = httpMock.post;
25
+ const mockDelete = httpMock.delete;
26
+
27
+ // ─── Mock KnowhowClient ───────────────────────────────────────────────────────
28
+ jest.mock("../../../src/services/KnowhowClient", () => ({
29
+ KNOWHOW_API_URL: "https://api.example.com",
30
+ loadKnowhowJwt: jest.fn().mockReturnValue("test-jwt-token"),
31
+ }));
32
+
33
+ import { Command } from "commander";
34
+ import { addSandboxCommand } from "../../../src/commands/sandbox";
35
+
36
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
37
+
38
+ function makeProgram(): Command {
39
+ const program = new Command();
40
+ program.exitOverride();
41
+ addSandboxCommand(program);
42
+ return program;
43
+ }
44
+
45
+ function makeSnapshot(overrides: Record<string, unknown> = {}) {
46
+ return {
47
+ id: "snap123456789012",
48
+ sandboxId: "sb123456789012",
49
+ label: "tests-ready",
50
+ description: "CI snapshot",
51
+ status: "ready",
52
+ errorMsg: null,
53
+ statusMessage: null,
54
+ regenerationSandboxId: null,
55
+ snapshotContent: "disk_only",
56
+ setupScript: "npm install && npm run build",
57
+ ...overrides,
58
+ };
59
+ }
60
+
61
+ function makeSandbox(overrides: Record<string, unknown> = {}) {
62
+ return {
63
+ id: "sb123456789012",
64
+ name: "knowhow-web",
65
+ status: "running",
66
+ vmStatus: "running",
67
+ ...overrides,
68
+ };
69
+ }
70
+
71
+ // ─── Tests ────────────────────────────────────────────────────────────────────
72
+
73
+ describe("sandbox regenerate-snapshot", () => {
74
+ let program: Command;
75
+ let consoleSpy: jest.SpyInstance;
76
+ let consoleErrorSpy: jest.SpyInstance;
77
+
78
+ beforeEach(() => {
79
+ jest.clearAllMocks();
80
+ jest.useFakeTimers();
81
+ program = makeProgram();
82
+ consoleSpy = jest.spyOn(console, "log").mockImplementation(() => {});
83
+ consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {});
84
+ });
85
+
86
+ afterEach(() => {
87
+ jest.useRealTimers();
88
+ consoleSpy.mockRestore();
89
+ consoleErrorSpy.mockRestore();
90
+ });
91
+
92
+ it("calls POST /regenerate and returns immediately when --no-wait is set", async () => {
93
+ const snap = makeSnapshot();
94
+ // GET snapshot
95
+ mockGet.mockResolvedValueOnce({ data: snap });
96
+ // POST regenerate — returns immediately with regenerationSandboxId set
97
+ mockPost.mockResolvedValueOnce({
98
+ data: makeSnapshot({ regenerationSandboxId: "eph123456789012" }),
99
+ });
100
+
101
+ await program.parseAsync([
102
+ "node", "knowhow", "sandbox", "regenerate-snapshot",
103
+ "--sandbox-id", "sb123456789012",
104
+ "--snapshot-id", "snap123456789012",
105
+ "--no-wait",
106
+ ]);
107
+
108
+ expect(mockPost).toHaveBeenCalledTimes(1);
109
+ expect(mockPost).toHaveBeenCalledWith(
110
+ expect.stringContaining("/sandboxes/sb123456789012/snapshots/snap123456789012/regenerate"),
111
+ undefined,
112
+ expect.any(Object)
113
+ );
114
+ // Should NOT poll further (no additional GET calls after initial snapshot fetch)
115
+ expect(mockGet).toHaveBeenCalledTimes(1);
116
+ });
117
+
118
+ it("polls snapshot status until regenerationSandboxId clears and status is ready", async () => {
119
+ const snap = makeSnapshot();
120
+ // Initial GET for resolving snapshot
121
+ mockGet.mockResolvedValueOnce({ data: snap });
122
+ // POST /regenerate returns immediately
123
+ mockPost.mockResolvedValueOnce({
124
+ data: makeSnapshot({ regenerationSandboxId: "eph123456789012" }),
125
+ });
126
+ // First poll: still regenerating
127
+ mockGet.mockResolvedValueOnce({
128
+ data: makeSnapshot({
129
+ regenerationSandboxId: "eph123456789012",
130
+ statusMessage: "Running setupScript...",
131
+ }),
132
+ });
133
+ // Second poll: done
134
+ mockGet.mockResolvedValueOnce({
135
+ data: makeSnapshot({ regenerationSandboxId: null, status: "ready" }),
136
+ });
137
+
138
+ // Run the command but don't await yet — it will pause at the first setTimeout
139
+ const parsePromise = program.parseAsync([
140
+ "node", "knowhow", "sandbox", "regenerate-snapshot",
141
+ "--sandbox-id", "sb123456789012",
142
+ "--snapshot-id", "snap123456789012",
143
+ // --wait is the default (no --no-wait)
144
+ ]);
145
+
146
+ // Let pending promises resolve (GET + POST), then advance past each 5s poll delay
147
+ await Promise.resolve();
148
+ await Promise.resolve();
149
+ await Promise.resolve();
150
+ jest.runAllTimers();
151
+ await Promise.resolve();
152
+ await Promise.resolve();
153
+ jest.runAllTimers();
154
+ await Promise.resolve();
155
+ await Promise.resolve();
156
+ jest.runAllTimers();
157
+
158
+ await parsePromise;
159
+
160
+ // POST /regenerate called once
161
+ expect(mockPost).toHaveBeenCalledTimes(1);
162
+ // Initial GET + 2 polling GETs
163
+ expect(mockGet).toHaveBeenCalledTimes(3);
164
+
165
+ const logOutput = consoleSpy.mock.calls.map((c) => c.join(" ")).join("\n");
166
+ expect(logOutput).toContain("✅ Snapshot regeneration complete!");
167
+ });
168
+
169
+ it("does NOT fork a sandbox or exec a script directly (old behavior)", async () => {
170
+ const snap = makeSnapshot();
171
+ mockGet.mockResolvedValueOnce({ data: snap });
172
+ mockPost.mockResolvedValueOnce({
173
+ data: makeSnapshot({ regenerationSandboxId: "eph123456789012" }),
174
+ });
175
+ // done immediately
176
+ mockGet.mockResolvedValueOnce({
177
+ data: makeSnapshot({ regenerationSandboxId: null, status: "ready" }),
178
+ });
179
+
180
+ const parsePromise = program.parseAsync([
181
+ "node", "knowhow", "sandbox", "regenerate-snapshot",
182
+ "--sandbox-id", "sb123456789012",
183
+ "--snapshot-id", "snap123456789012",
184
+ ]);
185
+
186
+ await Promise.resolve();
187
+ await Promise.resolve();
188
+ await Promise.resolve();
189
+ jest.runAllTimers();
190
+ await Promise.resolve();
191
+ await Promise.resolve();
192
+
193
+ await parsePromise;
194
+
195
+ // Should only call POST /regenerate — not POST /fork or POST /exec
196
+ const postCalls = mockPost.mock.calls.map((c) => c[0] as string);
197
+ expect(postCalls.every((url) => url.includes("/regenerate"))).toBe(true);
198
+ expect(postCalls.some((url) => url.includes("/fork"))).toBe(false);
199
+ expect(postCalls.some((url) => url.includes("/exec"))).toBe(false);
200
+ });
201
+
202
+ it("shows statusMessage updates during polling", async () => {
203
+ const snap = makeSnapshot();
204
+ mockGet.mockResolvedValueOnce({ data: snap });
205
+ mockPost.mockResolvedValueOnce({
206
+ data: makeSnapshot({ regenerationSandboxId: "eph123456789012" }),
207
+ });
208
+ mockGet.mockResolvedValueOnce({
209
+ data: makeSnapshot({
210
+ regenerationSandboxId: "eph123456789012",
211
+ statusMessage: "Uploading 500 MB / 1.0 GB (50%)",
212
+ }),
213
+ });
214
+ mockGet.mockResolvedValueOnce({
215
+ data: makeSnapshot({ regenerationSandboxId: null, status: "ready" }),
216
+ });
217
+
218
+ const parsePromise = program.parseAsync([
219
+ "node", "knowhow", "sandbox", "regenerate-snapshot",
220
+ "--sandbox-id", "sb123456789012",
221
+ "--snapshot-id", "snap123456789012",
222
+ ]);
223
+
224
+ // Flush microtasks then advance timers repeatedly until done
225
+ for (let i = 0; i < 10; i++) {
226
+ await Promise.resolve();
227
+ jest.runAllTimers();
228
+ }
229
+
230
+ await parsePromise;
231
+
232
+ const logOutput = consoleSpy.mock.calls.map((c) => c.join(" ")).join("\n");
233
+ expect(logOutput).toContain("Uploading 500 MB / 1.0 GB (50%)");
234
+ }, 15000);
235
+
236
+ it("requires --sandbox-id or --sandbox-name", async () => {
237
+ await expect(
238
+ program.parseAsync([
239
+ "node", "knowhow", "sandbox", "regenerate-snapshot",
240
+ "--snapshot-id", "snap123456789012",
241
+ ])
242
+ ).rejects.toThrow(/sandbox-id|sandbox-name/i);
243
+ });
244
+
245
+ it("requires --snapshot-id or --snapshot-name", async () => {
246
+ // Use --sandbox-id directly (avoids name resolution GET) to keep test isolated
247
+ await expect(
248
+ program.parseAsync([
249
+ "node", "knowhow", "sandbox", "regenerate-snapshot",
250
+ "--sandbox-id", "sb123456789012",
251
+ ])
252
+ ).rejects.toThrow(/snapshot-id|snapshot-name/i);
253
+ });
254
+ });
255
+
256
+ describe("sandbox snapshot-status", () => {
257
+ let program: Command;
258
+ let consoleSpy: jest.SpyInstance;
259
+
260
+ beforeEach(() => {
261
+ jest.clearAllMocks();
262
+ jest.useFakeTimers();
263
+ program = makeProgram();
264
+ consoleSpy = jest.spyOn(console, "log").mockImplementation(() => {});
265
+ });
266
+
267
+ afterEach(() => {
268
+ jest.useRealTimers();
269
+ consoleSpy.mockRestore();
270
+ });
271
+
272
+ it("prints snapshot status without waiting when --wait not set", async () => {
273
+ const snap = makeSnapshot({ regenerationSandboxId: "eph123456789012", status: "ready" });
274
+ mockGet.mockResolvedValueOnce({ data: snap });
275
+
276
+ await program.parseAsync([
277
+ "node", "knowhow", "sandbox", "snapshot-status",
278
+ "--sandbox-id", "sb123456789012",
279
+ "--snapshot-id", "snap123456789012",
280
+ ]);
281
+
282
+ const logOutput = consoleSpy.mock.calls.map((c) => c.join(" ")).join("\n");
283
+ expect(logOutput).toContain("regenerating");
284
+ expect(logOutput).toContain("eph123456789012");
285
+ // Should not poll further
286
+ expect(mockGet).toHaveBeenCalledTimes(1);
287
+ });
288
+
289
+ it("shows ready status when not regenerating", async () => {
290
+ const snap = makeSnapshot({ id: "snap123456789012", status: "ready" });
291
+ mockGet.mockResolvedValueOnce({ data: snap });
292
+
293
+ await program.parseAsync([
294
+ "node", "knowhow", "sandbox", "snapshot-status",
295
+ "--sandbox-id", "sb123456789012",
296
+ "--snapshot-id", "snap123456789012",
297
+ ]);
298
+
299
+ const logOutput = consoleSpy.mock.calls.map((c) => c.join(" ")).join("\n");
300
+ expect(logOutput).toContain("ready");
301
+ });
302
+
303
+ it("polls when --wait is set and regeneration is in progress", async () => {
304
+ const snapInProgress = makeSnapshot({ regenerationSandboxId: "eph123456789012" });
305
+ const snapDone = makeSnapshot({ regenerationSandboxId: null, status: "ready" });
306
+
307
+ // First GET: initial fetch (for snapshot-status command)
308
+ mockGet.mockResolvedValueOnce({ data: snapInProgress });
309
+ // Second GET: first poll iteration - still in progress
310
+ mockGet.mockResolvedValueOnce({ data: snapInProgress });
311
+ // Third GET: done
312
+ mockGet.mockResolvedValueOnce({ data: snapDone });
313
+
314
+ const parsePromise = program.parseAsync([
315
+ "node", "knowhow", "sandbox", "snapshot-status",
316
+ "--sandbox-id", "sb123456789012",
317
+ "--snapshot-id", "snap123456789012",
318
+ "--wait",
319
+ ]);
320
+
321
+ // Flush microtasks then advance timers
322
+ for (let i = 0; i < 10; i++) {
323
+ await Promise.resolve();
324
+ jest.runAllTimers();
325
+ }
326
+
327
+ await parsePromise;
328
+
329
+ const logOutput = consoleSpy.mock.calls.map((c) => c.join(" ")).join("\n");
330
+ expect(logOutput).toContain("Done");
331
+ expect(mockGet).toHaveBeenCalledTimes(3);
332
+ }, 15000);
333
+
334
+ it("outputs raw JSON with --json flag", async () => {
335
+ const snap = makeSnapshot();
336
+ mockGet.mockResolvedValueOnce({ data: snap });
337
+
338
+ await program.parseAsync([
339
+ "node", "knowhow", "sandbox", "snapshot-status",
340
+ "--sandbox-id", "sb123456789012",
341
+ "--snapshot-id", "snap123456789012",
342
+ "--json",
343
+ ]);
344
+
345
+ const logOutput = consoleSpy.mock.calls.map((c) => c.join(" ")).join("\n");
346
+ const parsed = JSON.parse(logOutput);
347
+ expect(parsed.id).toBe("snap123456789012");
348
+ expect(parsed.status).toBe("ready");
349
+ });
350
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tyvm/knowhow",
3
- "version": "0.0.143",
3
+ "version": "0.0.144",
4
4
  "description": "ai cli with plugins and agents",
5
5
  "main": "ts_build/src/index.js",
6
6
  "bin": {
@@ -71,6 +71,29 @@ async function resolveSnapshot(sandboxId, nameOrId) {
71
71
  }
72
72
  return match;
73
73
  }
74
+ async function pollRegeneration(sandboxId, snapshotId, timeoutMs) {
75
+ const deadline = Date.now() + timeoutMs;
76
+ let lastStatus = "";
77
+ let lastMessage = "";
78
+ while (Date.now() < deadline) {
79
+ const snap = await apiGet(`/sandboxes/${sandboxId}/snapshots/${snapshotId}`);
80
+ if (snap.status !== lastStatus) {
81
+ console.log(` [snapshot] status: ${snap.status}`);
82
+ lastStatus = snap.status;
83
+ }
84
+ if (snap.statusMessage && snap.statusMessage !== lastMessage) {
85
+ console.log(` [snapshot] ${snap.statusMessage}`);
86
+ lastMessage = snap.statusMessage;
87
+ }
88
+ if (!snap.regenerationSandboxId && snap.status === "ready")
89
+ return snap;
90
+ if (snap.status === "error") {
91
+ throw new Error(`Snapshot regeneration failed: ${snap.errorMsg || snap.statusMessage || "(no details)"}`);
92
+ }
93
+ await new Promise((r) => setTimeout(r, 5000));
94
+ }
95
+ throw new Error(`Timeout waiting for snapshot regeneration to complete (${timeoutMs}ms). Last status: ${lastStatus}`);
96
+ }
74
97
  async function pollSandboxStatus(sandboxId, targetStatuses, timeoutMs, label = sandboxId) {
75
98
  const deadline = Date.now() + timeoutMs;
76
99
  let lastStatus = "";
@@ -245,11 +268,10 @@ function addSandboxCommand(program) {
245
268
  .option("--sandbox-name <name>", "Source sandbox name (alternative to --sandbox-id)")
246
269
  .option("--snapshot-id <id>", "Snapshot ID to regenerate")
247
270
  .option("--snapshot-name <name>", "Snapshot label to regenerate")
248
- .option("--no-wait", "Return immediately without waiting for snapshot to be ready")
271
+ .option("--no-wait", "Trigger regeneration and return immediately (do not poll for completion)")
249
272
  .option("--timeout-minutes <min>", "Max time for the full regen cycle", "60")
250
273
  .action(async (opts) => {
251
274
  const timeoutMs = Number(opts.timeoutMinutes) * 60 * 1000;
252
- const deadline = Date.now() + timeoutMs;
253
275
  if (!opts.sandboxId && !opts.sandboxName) {
254
276
  throw new Error("Provide --sandbox-id or --sandbox-name");
255
277
  }
@@ -263,92 +285,69 @@ function addSandboxCommand(program) {
263
285
  const snapshotId = snapshot.id;
264
286
  console.log(`\n🔄 Regenerating snapshot "${snapshot.label || snapshotId}" (${snapshotId})`);
265
287
  console.log(` Source sandbox: ${sandboxId}`);
266
- if (snapshot.status !== "ready") {
288
+ if (snapshot.status !== "ready" && !snapshot.regenerationSandboxId) {
267
289
  throw new Error(`Snapshot must be in 'ready' status to regenerate (current: ${snapshot.status})`);
268
290
  }
269
- if (!snapshot.setupScript) {
270
- throw new Error("Snapshot has no setupScript. Add one via the UI before regenerating.");
271
- }
272
- console.log("\n📦 Step 1/4: Forking ephemeral sandbox from snapshot...");
273
- const ephemeralName = `regen-${snapshotId.slice(0, 8)}-${Date.now()}`;
274
- const forkResult = await apiPost("/sandboxes/fork", { snapshotId, name: ephemeralName });
275
- const ephemeralId = forkResult.id || forkResult.sandboxId;
276
- if (!ephemeralId) {
277
- throw new Error(`Fork did not return a sandbox ID: ${JSON.stringify(forkResult)}`);
278
- }
279
- console.log(` Ephemeral sandbox: ${ephemeralId} (${ephemeralName})`);
280
- console.log("\n⏳ Step 2/4: Waiting for sandbox to start...");
281
- await pollSandboxStatus(ephemeralId, ["running"], Math.min(deadline - Date.now(), 10 * 60 * 1000), ephemeralName);
282
- console.log(" ✓ Running");
283
- console.log("\n🔧 Step 3/4: Executing setupScript...");
284
- console.log(` Script length: ${snapshot.setupScript.length} chars`);
285
- let execResult;
286
- try {
287
- execResult = await apiPost(`/sandboxes/${ephemeralId}/exec`, {
288
- command: "/bin/bash",
289
- args: ["-c", snapshot.setupScript],
290
- timeoutMs: Math.min(deadline - Date.now(), 25 * 60 * 1000),
291
- });
292
- }
293
- catch (err) {
294
- console.error(`\n❌ setupScript exec failed: ${err.message}`);
295
- await safeDestroy(ephemeralId);
296
- throw err;
291
+ console.log("\n📡 Triggering backend regeneration...");
292
+ const triggered = await apiPost(`/sandboxes/${sandboxId}/snapshots/${snapshotId}/regenerate`);
293
+ console.log(` regenerationSandboxId: ${triggered.regenerationSandboxId || "(none)"}`);
294
+ if (!opts.wait) {
295
+ console.log(`\n✅ Regeneration triggered. Monitor with:\n` +
296
+ ` knowhow sandbox snapshot-status --sandbox-id ${sandboxId} --snapshot-id ${snapshotId}`);
297
+ return;
297
298
  }
298
- if (execResult.stdout) {
299
- console.log("--- stdout ---");
300
- process.stdout.write(execResult.stdout);
301
- }
302
- if (execResult.stderr) {
303
- console.error("--- stderr ---");
304
- process.stderr.write(execResult.stderr);
299
+ console.log("\n⏳ Waiting for regeneration to complete (Ctrl+C to stop polling)...");
300
+ const done = await pollRegeneration(sandboxId, snapshotId, timeoutMs);
301
+ console.log(`\n✅ Snapshot regeneration complete!\n` +
302
+ ` Snapshot ID : ${done.id}\n` +
303
+ ` Label : ${done.label || "(none)"}\n` +
304
+ ` Status : ${done.status}`);
305
+ });
306
+ sandboxCmd
307
+ .command("snapshot-status")
308
+ .description("Check and optionally wait for a snapshot's regeneration to complete.\n" +
309
+ "Useful after triggering regeneration with --no-wait.")
310
+ .option("--sandbox-id <id>", "Sandbox ID")
311
+ .option("--sandbox-name <name>", "Sandbox name")
312
+ .option("--snapshot-id <id>", "Snapshot ID")
313
+ .option("--snapshot-name <name>", "Snapshot label")
314
+ .option("--wait", "Poll until regeneration completes (or times out)")
315
+ .option("--timeout-minutes <min>", "Max poll time in minutes", "60")
316
+ .option("--json", "Output raw JSON")
317
+ .action(async (opts) => {
318
+ if (!opts.sandboxId && !opts.sandboxName) {
319
+ throw new Error("Provide --sandbox-id or --sandbox-name");
305
320
  }
306
- if (execResult.exitCode != null && execResult.exitCode !== 0) {
307
- await safeDestroy(ephemeralId);
308
- throw new Error(`setupScript exited with code ${execResult.exitCode}`);
321
+ const sandboxId = opts.sandboxId || (await resolveSandboxId(opts.sandboxName));
322
+ if (!opts.snapshotId && !opts.snapshotName) {
323
+ throw new Error("Provide --snapshot-id or --snapshot-name");
309
324
  }
310
- console.log(" ✓ setupScript completed");
311
- console.log("\n📸 Step 4/4: Capturing new snapshot...");
312
- const newLabel = snapshot.label || `regen-${snapshotId.slice(0, 8)}`;
313
- let createResult;
314
- try {
315
- createResult = await apiPost(`/sandboxes/${ephemeralId}/snapshots`, {
316
- label: newLabel,
317
- description: snapshot.description,
318
- snapshotContent: snapshot.snapshotContent || "full",
319
- snapshotType: "full",
320
- });
325
+ const snapshot = opts.snapshotId
326
+ ? await apiGet(`/sandboxes/${sandboxId}/snapshots/${opts.snapshotId}`)
327
+ : await resolveSnapshot(sandboxId, opts.snapshotName);
328
+ if (opts.wait && snapshot.regenerationSandboxId) {
329
+ console.log("⏳ Waiting for regeneration to complete...");
330
+ const done = await pollRegeneration(sandboxId, snapshot.id, Number(opts.timeoutMinutes) * 60 * 1000);
331
+ if (opts.json) {
332
+ console.log(JSON.stringify(done, null, 2));
333
+ }
334
+ else {
335
+ console.log(`✅ Done — status: ${done.status} label: ${done.label || "(none)"}`);
336
+ }
337
+ return;
321
338
  }
322
- catch (err) {
323
- console.error(`\n❌ Snapshot creation failed: ${err.message}`);
324
- await safeDestroy(ephemeralId);
325
- throw err;
339
+ if (opts.json) {
340
+ console.log(JSON.stringify(snapshot, null, 2));
326
341
  }
327
- const newSnapshot = createResult.snapshot || createResult;
328
- const newSnapshotId = newSnapshot.id;
329
- console.log(` New snapshot ID: ${newSnapshotId}`);
330
- if (opts.wait) {
331
- console.log(" Waiting for snapshot upload...");
332
- await pollSnapshotStatus(ephemeralId, newSnapshotId, ["ready"], Math.min(deadline - Date.now(), 20 * 60 * 1000));
333
- console.log(" ✓ Snapshot ready");
342
+ else {
343
+ const regenInfo = snapshot.regenerationSandboxId
344
+ ? `🔄 regenerating (ephemeral: ${snapshot.regenerationSandboxId})`
345
+ : `✅ ${snapshot.status}`;
346
+ console.log(`Snapshot ${snapshot.id} label=${snapshot.label || "(none)"} ${regenInfo}`);
347
+ if (snapshot.statusMessage) {
348
+ console.log(` message: ${snapshot.statusMessage}`);
349
+ }
334
350
  }
335
- console.log("\n🗑 Destroying ephemeral sandbox...");
336
- await safeDestroy(ephemeralId);
337
- console.log(" ✓ Destroyed");
338
- console.log(`\n✅ Snapshot regeneration complete!\n` +
339
- ` Old snapshot ID : ${snapshotId}\n` +
340
- ` New snapshot ID : ${newSnapshotId}\n` +
341
- ` Label : ${newLabel}\n\n` +
342
- `ℹ The old snapshot still exists. Clean it up with:\n` +
343
- ` knowhow sandbox delete-snapshot --sandbox-id ${sandboxId} --snapshot-id ${snapshotId}`);
344
351
  });
345
352
  }
346
- async function safeDestroy(sandboxId) {
347
- try {
348
- await apiDelete(`/sandboxes/${sandboxId}`);
349
- }
350
- catch (err) {
351
- console.warn(`⚠ Could not destroy sandbox ${sandboxId}: ${err.message}`);
352
- }
353
- }
354
353
  //# sourceMappingURL=sandbox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../../src/commands/sandbox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../../src/commands/sandbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,258 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ jest.mock("../../../src/utils/http", () => {
4
+ const get = jest.fn();
5
+ const post = jest.fn();
6
+ const del = jest.fn();
7
+ const mock = { get, post, delete: del };
8
+ return { default: mock, __esModule: true };
9
+ });
10
+ const httpMock = require("../../../src/utils/http").default;
11
+ const mockGet = httpMock.get;
12
+ const mockPost = httpMock.post;
13
+ const mockDelete = httpMock.delete;
14
+ jest.mock("../../../src/services/KnowhowClient", () => ({
15
+ KNOWHOW_API_URL: "https://api.example.com",
16
+ loadKnowhowJwt: jest.fn().mockReturnValue("test-jwt-token"),
17
+ }));
18
+ const commander_1 = require("commander");
19
+ const sandbox_1 = require("../../../src/commands/sandbox");
20
+ function makeProgram() {
21
+ const program = new commander_1.Command();
22
+ program.exitOverride();
23
+ (0, sandbox_1.addSandboxCommand)(program);
24
+ return program;
25
+ }
26
+ function makeSnapshot(overrides = {}) {
27
+ return {
28
+ id: "snap123456789012",
29
+ sandboxId: "sb123456789012",
30
+ label: "tests-ready",
31
+ description: "CI snapshot",
32
+ status: "ready",
33
+ errorMsg: null,
34
+ statusMessage: null,
35
+ regenerationSandboxId: null,
36
+ snapshotContent: "disk_only",
37
+ setupScript: "npm install && npm run build",
38
+ ...overrides,
39
+ };
40
+ }
41
+ function makeSandbox(overrides = {}) {
42
+ return {
43
+ id: "sb123456789012",
44
+ name: "knowhow-web",
45
+ status: "running",
46
+ vmStatus: "running",
47
+ ...overrides,
48
+ };
49
+ }
50
+ describe("sandbox regenerate-snapshot", () => {
51
+ let program;
52
+ let consoleSpy;
53
+ let consoleErrorSpy;
54
+ beforeEach(() => {
55
+ jest.clearAllMocks();
56
+ jest.useFakeTimers();
57
+ program = makeProgram();
58
+ consoleSpy = jest.spyOn(console, "log").mockImplementation(() => { });
59
+ consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => { });
60
+ });
61
+ afterEach(() => {
62
+ jest.useRealTimers();
63
+ consoleSpy.mockRestore();
64
+ consoleErrorSpy.mockRestore();
65
+ });
66
+ it("calls POST /regenerate and returns immediately when --no-wait is set", async () => {
67
+ const snap = makeSnapshot();
68
+ mockGet.mockResolvedValueOnce({ data: snap });
69
+ mockPost.mockResolvedValueOnce({
70
+ data: makeSnapshot({ regenerationSandboxId: "eph123456789012" }),
71
+ });
72
+ await program.parseAsync([
73
+ "node", "knowhow", "sandbox", "regenerate-snapshot",
74
+ "--sandbox-id", "sb123456789012",
75
+ "--snapshot-id", "snap123456789012",
76
+ "--no-wait",
77
+ ]);
78
+ expect(mockPost).toHaveBeenCalledTimes(1);
79
+ expect(mockPost).toHaveBeenCalledWith(expect.stringContaining("/sandboxes/sb123456789012/snapshots/snap123456789012/regenerate"), undefined, expect.any(Object));
80
+ expect(mockGet).toHaveBeenCalledTimes(1);
81
+ });
82
+ it("polls snapshot status until regenerationSandboxId clears and status is ready", async () => {
83
+ const snap = makeSnapshot();
84
+ mockGet.mockResolvedValueOnce({ data: snap });
85
+ mockPost.mockResolvedValueOnce({
86
+ data: makeSnapshot({ regenerationSandboxId: "eph123456789012" }),
87
+ });
88
+ mockGet.mockResolvedValueOnce({
89
+ data: makeSnapshot({
90
+ regenerationSandboxId: "eph123456789012",
91
+ statusMessage: "Running setupScript...",
92
+ }),
93
+ });
94
+ mockGet.mockResolvedValueOnce({
95
+ data: makeSnapshot({ regenerationSandboxId: null, status: "ready" }),
96
+ });
97
+ const parsePromise = program.parseAsync([
98
+ "node", "knowhow", "sandbox", "regenerate-snapshot",
99
+ "--sandbox-id", "sb123456789012",
100
+ "--snapshot-id", "snap123456789012",
101
+ ]);
102
+ await Promise.resolve();
103
+ await Promise.resolve();
104
+ await Promise.resolve();
105
+ jest.runAllTimers();
106
+ await Promise.resolve();
107
+ await Promise.resolve();
108
+ jest.runAllTimers();
109
+ await Promise.resolve();
110
+ await Promise.resolve();
111
+ jest.runAllTimers();
112
+ await parsePromise;
113
+ expect(mockPost).toHaveBeenCalledTimes(1);
114
+ expect(mockGet).toHaveBeenCalledTimes(3);
115
+ const logOutput = consoleSpy.mock.calls.map((c) => c.join(" ")).join("\n");
116
+ expect(logOutput).toContain("✅ Snapshot regeneration complete!");
117
+ });
118
+ it("does NOT fork a sandbox or exec a script directly (old behavior)", async () => {
119
+ const snap = makeSnapshot();
120
+ mockGet.mockResolvedValueOnce({ data: snap });
121
+ mockPost.mockResolvedValueOnce({
122
+ data: makeSnapshot({ regenerationSandboxId: "eph123456789012" }),
123
+ });
124
+ mockGet.mockResolvedValueOnce({
125
+ data: makeSnapshot({ regenerationSandboxId: null, status: "ready" }),
126
+ });
127
+ const parsePromise = program.parseAsync([
128
+ "node", "knowhow", "sandbox", "regenerate-snapshot",
129
+ "--sandbox-id", "sb123456789012",
130
+ "--snapshot-id", "snap123456789012",
131
+ ]);
132
+ await Promise.resolve();
133
+ await Promise.resolve();
134
+ await Promise.resolve();
135
+ jest.runAllTimers();
136
+ await Promise.resolve();
137
+ await Promise.resolve();
138
+ await parsePromise;
139
+ const postCalls = mockPost.mock.calls.map((c) => c[0]);
140
+ expect(postCalls.every((url) => url.includes("/regenerate"))).toBe(true);
141
+ expect(postCalls.some((url) => url.includes("/fork"))).toBe(false);
142
+ expect(postCalls.some((url) => url.includes("/exec"))).toBe(false);
143
+ });
144
+ it("shows statusMessage updates during polling", async () => {
145
+ const snap = makeSnapshot();
146
+ mockGet.mockResolvedValueOnce({ data: snap });
147
+ mockPost.mockResolvedValueOnce({
148
+ data: makeSnapshot({ regenerationSandboxId: "eph123456789012" }),
149
+ });
150
+ mockGet.mockResolvedValueOnce({
151
+ data: makeSnapshot({
152
+ regenerationSandboxId: "eph123456789012",
153
+ statusMessage: "Uploading 500 MB / 1.0 GB (50%)",
154
+ }),
155
+ });
156
+ mockGet.mockResolvedValueOnce({
157
+ data: makeSnapshot({ regenerationSandboxId: null, status: "ready" }),
158
+ });
159
+ const parsePromise = program.parseAsync([
160
+ "node", "knowhow", "sandbox", "regenerate-snapshot",
161
+ "--sandbox-id", "sb123456789012",
162
+ "--snapshot-id", "snap123456789012",
163
+ ]);
164
+ for (let i = 0; i < 10; i++) {
165
+ await Promise.resolve();
166
+ jest.runAllTimers();
167
+ }
168
+ await parsePromise;
169
+ const logOutput = consoleSpy.mock.calls.map((c) => c.join(" ")).join("\n");
170
+ expect(logOutput).toContain("Uploading 500 MB / 1.0 GB (50%)");
171
+ }, 15000);
172
+ it("requires --sandbox-id or --sandbox-name", async () => {
173
+ await expect(program.parseAsync([
174
+ "node", "knowhow", "sandbox", "regenerate-snapshot",
175
+ "--snapshot-id", "snap123456789012",
176
+ ])).rejects.toThrow(/sandbox-id|sandbox-name/i);
177
+ });
178
+ it("requires --snapshot-id or --snapshot-name", async () => {
179
+ await expect(program.parseAsync([
180
+ "node", "knowhow", "sandbox", "regenerate-snapshot",
181
+ "--sandbox-id", "sb123456789012",
182
+ ])).rejects.toThrow(/snapshot-id|snapshot-name/i);
183
+ });
184
+ });
185
+ describe("sandbox snapshot-status", () => {
186
+ let program;
187
+ let consoleSpy;
188
+ beforeEach(() => {
189
+ jest.clearAllMocks();
190
+ jest.useFakeTimers();
191
+ program = makeProgram();
192
+ consoleSpy = jest.spyOn(console, "log").mockImplementation(() => { });
193
+ });
194
+ afterEach(() => {
195
+ jest.useRealTimers();
196
+ consoleSpy.mockRestore();
197
+ });
198
+ it("prints snapshot status without waiting when --wait not set", async () => {
199
+ const snap = makeSnapshot({ regenerationSandboxId: "eph123456789012", status: "ready" });
200
+ mockGet.mockResolvedValueOnce({ data: snap });
201
+ await program.parseAsync([
202
+ "node", "knowhow", "sandbox", "snapshot-status",
203
+ "--sandbox-id", "sb123456789012",
204
+ "--snapshot-id", "snap123456789012",
205
+ ]);
206
+ const logOutput = consoleSpy.mock.calls.map((c) => c.join(" ")).join("\n");
207
+ expect(logOutput).toContain("regenerating");
208
+ expect(logOutput).toContain("eph123456789012");
209
+ expect(mockGet).toHaveBeenCalledTimes(1);
210
+ });
211
+ it("shows ready status when not regenerating", async () => {
212
+ const snap = makeSnapshot({ id: "snap123456789012", status: "ready" });
213
+ mockGet.mockResolvedValueOnce({ data: snap });
214
+ await program.parseAsync([
215
+ "node", "knowhow", "sandbox", "snapshot-status",
216
+ "--sandbox-id", "sb123456789012",
217
+ "--snapshot-id", "snap123456789012",
218
+ ]);
219
+ const logOutput = consoleSpy.mock.calls.map((c) => c.join(" ")).join("\n");
220
+ expect(logOutput).toContain("ready");
221
+ });
222
+ it("polls when --wait is set and regeneration is in progress", async () => {
223
+ const snapInProgress = makeSnapshot({ regenerationSandboxId: "eph123456789012" });
224
+ const snapDone = makeSnapshot({ regenerationSandboxId: null, status: "ready" });
225
+ mockGet.mockResolvedValueOnce({ data: snapInProgress });
226
+ mockGet.mockResolvedValueOnce({ data: snapInProgress });
227
+ mockGet.mockResolvedValueOnce({ data: snapDone });
228
+ const parsePromise = program.parseAsync([
229
+ "node", "knowhow", "sandbox", "snapshot-status",
230
+ "--sandbox-id", "sb123456789012",
231
+ "--snapshot-id", "snap123456789012",
232
+ "--wait",
233
+ ]);
234
+ for (let i = 0; i < 10; i++) {
235
+ await Promise.resolve();
236
+ jest.runAllTimers();
237
+ }
238
+ await parsePromise;
239
+ const logOutput = consoleSpy.mock.calls.map((c) => c.join(" ")).join("\n");
240
+ expect(logOutput).toContain("Done");
241
+ expect(mockGet).toHaveBeenCalledTimes(3);
242
+ }, 15000);
243
+ it("outputs raw JSON with --json flag", async () => {
244
+ const snap = makeSnapshot();
245
+ mockGet.mockResolvedValueOnce({ data: snap });
246
+ await program.parseAsync([
247
+ "node", "knowhow", "sandbox", "snapshot-status",
248
+ "--sandbox-id", "sb123456789012",
249
+ "--snapshot-id", "snap123456789012",
250
+ "--json",
251
+ ]);
252
+ const logOutput = consoleSpy.mock.calls.map((c) => c.join(" ")).join("\n");
253
+ const parsed = JSON.parse(logOutput);
254
+ expect(parsed.id).toBe("snap123456789012");
255
+ expect(parsed.status).toBe("ready");
256
+ });
257
+ });
258
+ //# sourceMappingURL=sandbox.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.test.js","sourceRoot":"","sources":["../../../../tests/unit/commands/sandbox.test.ts"],"names":[],"mappings":"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"}