@mycadet/cli 0.12.11 → 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.
Files changed (86) hide show
  1. package/README.md +13 -0
  2. package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/__tests__/ingress.test.ts +2 -2
  3. package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/ingress.ts +2 -2
  4. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/__tests__/ingress.test.ts +2 -2
  5. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/ingress.ts +2 -2
  6. package/node_modules/@mycadet/service-contracts/src/__tests__/ingress.test.ts +2 -2
  7. package/node_modules/@mycadet/service-contracts/src/ingress.ts +2 -2
  8. package/package.json +3 -2
  9. package/src/__tests__/assistant-client-cloud-auth.test.ts +2 -2
  10. package/src/__tests__/backup-ops-matching.test.ts +15 -13
  11. package/src/__tests__/backup-ops.test.ts +105 -0
  12. package/src/__tests__/backup.test.ts +114 -673
  13. package/src/__tests__/cloud-releases.test.ts +82 -0
  14. package/src/__tests__/commands-mock.ts +101 -0
  15. package/src/__tests__/debug.test.ts +17 -91
  16. package/src/__tests__/devices.test.ts +2 -2
  17. package/src/__tests__/gateway-token.test.ts +267 -0
  18. package/src/__tests__/host-teleport-docker.test.ts +371 -0
  19. package/src/__tests__/host-teleport.test.ts +405 -0
  20. package/src/__tests__/nginx-ingress.test.ts +182 -23
  21. package/src/__tests__/orphan-detection.test.ts +1 -1
  22. package/src/__tests__/paired-lifecycle.test.ts +2 -2
  23. package/src/__tests__/ps-cloud-status.test.ts +6 -6
  24. package/src/__tests__/root-backup-docker.test.ts +294 -0
  25. package/src/__tests__/root-backup.test.ts +527 -0
  26. package/src/__tests__/root-restore-command.test.ts +147 -0
  27. package/src/__tests__/root-signing-key.test.ts +50 -0
  28. package/src/__tests__/setup.test.ts +3 -3
  29. package/src/__tests__/sleep.test.ts +11 -0
  30. package/src/__tests__/teleport.test.ts +68 -2996
  31. package/src/__tests__/tunnel.test.ts +1 -1
  32. package/src/__tests__/upgrade-local.test.ts +21 -11
  33. package/src/__tests__/upgrade-replay-env.test.ts +2 -2
  34. package/src/__tests__/upgrade-root-recovery.test.ts +185 -0
  35. package/src/__tests__/windows-lifecycle.test.ts +25 -0
  36. package/src/commands/backup.ts +44 -399
  37. package/src/commands/client.ts +3 -3
  38. package/src/commands/completions.ts +0 -2
  39. package/src/commands/debug.ts +75 -131
  40. package/src/commands/devices.ts +51 -17
  41. package/src/commands/gateway/token.ts +77 -23
  42. package/src/commands/pair.ts +2 -2
  43. package/src/commands/restore.ts +77 -444
  44. package/src/commands/retire.ts +2 -3
  45. package/src/commands/sleep.ts +15 -2
  46. package/src/commands/teleport.ts +47 -1559
  47. package/src/commands/upgrade.ts +78 -156
  48. package/src/commands/wake.ts +1 -1
  49. package/src/index.ts +0 -4
  50. package/src/lib/__tests__/http-client-version.test.ts +29 -0
  51. package/src/lib/__tests__/runtime-url.test.ts +3 -75
  52. package/src/lib/__tests__/web-dist.test.ts +27 -1
  53. package/src/lib/assistant-client.ts +1 -1
  54. package/src/lib/assistant-config.ts +0 -18
  55. package/src/lib/backup-ops.ts +37 -251
  56. package/src/lib/cloud-client.ts +10 -13
  57. package/src/lib/cloud-login.ts +2 -1
  58. package/src/lib/cloud-releases.ts +54 -10
  59. package/src/lib/cloud-values.ts +1 -1
  60. package/src/lib/confirm-action.ts +2 -2
  61. package/src/lib/docker.ts +59 -22
  62. package/src/lib/github-repository.ts +2 -0
  63. package/src/lib/guardian-token.ts +1 -23
  64. package/src/lib/hatch-local.ts +17 -1
  65. package/src/lib/host-teleport.ts +506 -0
  66. package/src/lib/http-client.ts +25 -0
  67. package/src/lib/live-voice/tunnel.test.ts +1 -1
  68. package/src/lib/live-voice/tunnel.ts +1 -1
  69. package/src/lib/local.ts +4 -2
  70. package/src/lib/nginx-ingress.ts +134 -18
  71. package/src/lib/process.ts +13 -0
  72. package/src/lib/root-backup.ts +917 -0
  73. package/src/lib/root-signing-key.ts +31 -0
  74. package/src/lib/runtime-url.ts +0 -29
  75. package/src/lib/teleport-backup.ts +3 -16
  76. package/src/lib/upgrade-lifecycle.ts +63 -141
  77. package/src/lib/web-dist.ts +23 -1
  78. package/src/__tests__/bundle-staging.test.ts +0 -268
  79. package/src/__tests__/unpair.test.ts +0 -160
  80. package/src/commands/rollback.ts +0 -479
  81. package/src/commands/unpair.ts +0 -122
  82. package/src/lib/__tests__/job-polling.test.ts +0 -278
  83. package/src/lib/__tests__/local-runtime-client.test.ts +0 -666
  84. package/src/lib/bundle-staging.ts +0 -220
  85. package/src/lib/job-polling.ts +0 -195
  86. package/src/lib/local-runtime-client.ts +0 -374
@@ -0,0 +1,50 @@
1
+ import { afterEach, expect, test } from "bun:test";
2
+ import {
3
+ mkdtempSync,
4
+ readFileSync,
5
+ rmSync,
6
+ statSync,
7
+ symlinkSync,
8
+ writeFileSync,
9
+ } from "node:fs";
10
+ import { tmpdir } from "node:os";
11
+ import { join } from "node:path";
12
+ import { persistRootSigningKey } from "../lib/root-signing-key.js";
13
+ const directories: string[] = [];
14
+ function fixture() {
15
+ const root = mkdtempSync(join(tmpdir(), "root-signing-key-"));
16
+ directories.push(root);
17
+ return root;
18
+ }
19
+ afterEach(() => {
20
+ for (const root of directories.splice(0)) {
21
+ rmSync(root, { recursive: true, force: true });
22
+ }
23
+ });
24
+ test("persists the raw key privately so offline capture retains installation identity", () => {
25
+ const root = fixture();
26
+ persistRootSigningKey(root, "07".repeat(32));
27
+ const file = join(root, "gateway-security", "actor-token-signing-key");
28
+ expect(readFileSync(file)).toEqual(Buffer.alloc(32, 7));
29
+ if (process.platform !== "win32") {
30
+ expect(statSync(file).mode & 0o777).toBe(0o600);
31
+ }
32
+ });
33
+ test("replaces a key file link without changing its target", () => {
34
+ const root = fixture();
35
+ persistRootSigningKey(root, "07".repeat(32));
36
+ const target = join(root, "other");
37
+ writeFileSync(target, "unchanged");
38
+ const file = join(root, "gateway-security", "actor-token-signing-key");
39
+ rmSync(file);
40
+ symlinkSync(target, file);
41
+ persistRootSigningKey(root, "09".repeat(32));
42
+ expect(readFileSync(target, "utf8")).toBe("unchanged");
43
+ expect(readFileSync(file)).toEqual(Buffer.alloc(32, 9));
44
+ });
45
+ test("rejects invalid key data before writing service state", () => {
46
+ const root = fixture();
47
+ expect(() => persistRootSigningKey(root, "bad")).toThrow(
48
+ "Invalid gateway signing key",
49
+ );
50
+ });
@@ -291,7 +291,7 @@ describe("setup command", () => {
291
291
  assistantId: "assistant-123",
292
292
  runtimeUrl: "https://assistant.example",
293
293
  bearerToken: "entry-token",
294
- cloud: "cadet",
294
+ cloud: "cloud",
295
295
  });
296
296
 
297
297
  await setup();
@@ -310,7 +310,7 @@ describe("setup command", () => {
310
310
  assistantId: "assistant-123",
311
311
  runtimeUrl: "https://assistant.example",
312
312
  bearerToken: "entry-token",
313
- cloud: "cadet",
313
+ cloud: "cloud",
314
314
  });
315
315
  saveGuardianToken(
316
316
  "assistant-123",
@@ -339,7 +339,7 @@ describe("setup command", () => {
339
339
  assistantId: "assistant-123",
340
340
  runtimeUrl: "https://assistant.example",
341
341
  bearerToken: "entry-token",
342
- cloud: "cadet",
342
+ cloud: "cloud",
343
343
  });
344
344
  saveGuardianToken(
345
345
  "assistant-123",
@@ -216,6 +216,12 @@ describe("sleep command", () => {
216
216
  expect(stopProcessByPidFileMock).toHaveBeenCalledTimes(3);
217
217
  });
218
218
 
219
+ test("default sleep passes the non-escalating service stopper", async () => {
220
+ process.argv = ["bun", "cadet", "sleep", "sleep-test"];
221
+ await sleep();
222
+ expect(stopProcessByPidFileMock).toHaveBeenNthCalledWith(1, join(assistantRootDir, "workspace", "cadet.pid"), "assistant", undefined, 45_000, realProcess.stopProcessGracefully);
223
+ });
224
+
219
225
  test("force stops the assistant even when an active call lease exists", async () => {
220
226
  writeLeaseFile(["call-active-1"]);
221
227
  process.argv = ["bun", "cadet", "sleep", "sleep-test", "--force"];
@@ -238,6 +244,7 @@ describe("sleep command", () => {
238
244
  "assistant",
239
245
  undefined,
240
246
  45_000,
247
+ expect.any(Function),
241
248
  );
242
249
  expect(stopProcessByPidFileMock).toHaveBeenNthCalledWith(
243
250
  2,
@@ -245,12 +252,16 @@ describe("sleep command", () => {
245
252
  "gateway",
246
253
  undefined,
247
254
  7000,
255
+ expect.any(Function),
248
256
  );
249
257
  // The CES sibling is stopped by its PID file; a no-op when absent.
250
258
  expect(stopProcessByPidFileMock).toHaveBeenNthCalledWith(
251
259
  3,
252
260
  join(assistantRootDir, "ces.pid"),
253
261
  "credential-executor",
262
+ undefined,
263
+ 45_000,
264
+ expect.any(Function),
254
265
  );
255
266
  });
256
267