@mycadet/cli 0.12.7 → 0.12.9

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 (179) hide show
  1. package/README.md +2 -2
  2. package/knip.json +1 -1
  3. package/node_modules/@mycadet/assistant-api/events/cloud-disconnected.ts +21 -0
  4. package/node_modules/@mycadet/assistant-api/events/host-bash.ts +1 -1
  5. package/node_modules/@mycadet/assistant-api/events/host-cu.ts +1 -1
  6. package/node_modules/@mycadet/assistant-api/events/host-file.ts +1 -1
  7. package/node_modules/@mycadet/assistant-api/events/notification-intent.ts +1 -1
  8. package/node_modules/@mycadet/assistant-api/events/show-cloud-login.ts +18 -0
  9. package/node_modules/@mycadet/assistant-api/index.ts +11 -11
  10. package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/package.json +2 -2
  11. package/node_modules/@mycadet/{service-contracts/src/platform-credential.ts → assistant-api/node_modules/@mycadet/service-contracts/src/cloud-credential.ts} +9 -9
  12. package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
  13. package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
  14. package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
  15. package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
  16. package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
  17. package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
  18. package/node_modules/@mycadet/assistant-api/responses/home.ts +1 -1
  19. package/node_modules/@mycadet/assistant-api/surfaces.ts +4 -4
  20. package/node_modules/@mycadet/avatar-manifest/src/__tests__/notification-avatar.test.ts +1 -1
  21. package/node_modules/@mycadet/avatar-manifest/src/notification-avatar.ts +2 -2
  22. package/node_modules/@mycadet/environments/src/seeds.ts +6 -6
  23. package/node_modules/@mycadet/environments/src/shell.test.ts +1 -1
  24. package/node_modules/@mycadet/environments/src/types.ts +6 -6
  25. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/avatar-manifest/src/__tests__/notification-avatar.test.ts +1 -1
  26. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/avatar-manifest/src/notification-avatar.ts +2 -2
  27. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/environments/src/seeds.ts +6 -6
  28. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/environments/src/shell.test.ts +1 -1
  29. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/environments/src/types.ts +6 -6
  30. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/package.json +2 -2
  31. package/node_modules/@mycadet/{assistant-api/node_modules/@mycadet/service-contracts/src/platform-credential.ts → local-mode/node_modules/@mycadet/service-contracts/src/cloud-credential.ts} +9 -9
  32. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
  33. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
  34. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
  35. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
  36. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
  37. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
  38. package/node_modules/@mycadet/local-mode/src/__tests__/pair.test.ts +5 -5
  39. package/node_modules/@mycadet/local-mode/src/__tests__/retire.test.ts +1 -1
  40. package/node_modules/@mycadet/local-mode/src/config.ts +2 -2
  41. package/node_modules/@mycadet/local-mode/src/index.ts +1 -1
  42. package/node_modules/@mycadet/local-mode/src/lockfile-contract.test.ts +3 -3
  43. package/node_modules/@mycadet/local-mode/src/lockfile-contract.ts +10 -5
  44. package/node_modules/@mycadet/local-mode/src/lockfile.test.ts +15 -15
  45. package/node_modules/@mycadet/local-mode/src/lockfile.ts +9 -9
  46. package/node_modules/@mycadet/local-mode/src/pair.ts +2 -2
  47. package/node_modules/@mycadet/local-mode/src/retire.ts +3 -3
  48. package/node_modules/@mycadet/local-mode/src/teleport-backup-policy.ts +2 -2
  49. package/node_modules/@mycadet/local-mode/src/unpair.ts +2 -2
  50. package/node_modules/@mycadet/service-contracts/package.json +2 -2
  51. package/node_modules/@mycadet/{local-mode/node_modules/@mycadet/service-contracts/src/platform-credential.ts → service-contracts/src/cloud-credential.ts} +9 -9
  52. package/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
  53. package/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
  54. package/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
  55. package/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
  56. package/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
  57. package/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
  58. package/package.json +3 -2
  59. package/src/__tests__/assistant-api-key-resolution.test.ts +6 -6
  60. package/src/__tests__/{assistant-client-platform-auth.test.ts → assistant-client-cloud-auth.test.ts} +10 -10
  61. package/src/__tests__/assistant-client-refresh.test.ts +2 -2
  62. package/src/__tests__/backup.test.ts +86 -91
  63. package/src/__tests__/client-token.test.ts +1 -1
  64. package/src/__tests__/client-tui-refresh.test.ts +1 -1
  65. package/src/__tests__/client-web-config.test.ts +2 -2
  66. package/src/__tests__/{platform-client.test.ts → cloud-client.test.ts} +59 -59
  67. package/src/__tests__/{platform-releases.test.ts → cloud-releases.test.ts} +28 -18
  68. package/src/__tests__/{cloudflare-tunnel.test.ts → cloudflare.test.ts} +1 -1
  69. package/src/__tests__/connect-import.test.ts +55 -39
  70. package/src/__tests__/debug.test.ts +38 -38
  71. package/src/__tests__/ensure-binary.test.ts +182 -0
  72. package/src/__tests__/guardian-token.test.ts +149 -56
  73. package/src/__tests__/hatch-provider-secrets.test.ts +2 -2
  74. package/src/__tests__/helpers/guardian-token.ts +22 -0
  75. package/src/__tests__/helpers/http.ts +10 -0
  76. package/src/__tests__/nginx-ingress.test.ts +21 -20
  77. package/src/__tests__/ngrok-spawn.test.ts +49 -0
  78. package/src/__tests__/orphan-detection.test.ts +1 -1
  79. package/src/__tests__/pair.test.ts +1 -8
  80. package/src/__tests__/{ps-platform-status.test.ts → ps-cloud-status.test.ts} +79 -26
  81. package/src/__tests__/ps-table.test.ts +79 -0
  82. package/src/__tests__/{recover.test.ts → restore.test.ts} +29 -28
  83. package/src/__tests__/retire.test.ts +58 -199
  84. package/src/__tests__/root-process-lockfile.test.ts +99 -0
  85. package/src/__tests__/sleep.test.ts +19 -19
  86. package/src/__tests__/statefulset.test.ts +8 -8
  87. package/src/__tests__/{tailscale-tunnel.test.ts → tailscale.test.ts} +2 -2
  88. package/src/__tests__/teleport-backup.test.ts +3 -3
  89. package/src/__tests__/teleport.test.ts +181 -197
  90. package/src/__tests__/tunnel.test.ts +257 -222
  91. package/src/__tests__/uninstall.test.ts +13 -4
  92. package/src/__tests__/upgrade-local.test.ts +3 -3
  93. package/src/__tests__/upgrade-replay-env.test.ts +12 -12
  94. package/src/__tests__/wake.test.ts +260 -43
  95. package/src/__tests__/workos-pkce.test.ts +2 -2
  96. package/src/commands/backup.ts +24 -24
  97. package/src/commands/client.ts +76 -76
  98. package/src/commands/completions.test.ts +104 -0
  99. package/src/commands/completions.ts +87 -0
  100. package/src/commands/debug.ts +20 -20
  101. package/src/commands/exec.ts +12 -12
  102. package/src/commands/flags.ts +2 -2
  103. package/src/commands/hatch.ts +23 -23
  104. package/src/commands/login.ts +22 -22
  105. package/src/commands/logs.ts +8 -8
  106. package/src/commands/ps.ts +244 -86
  107. package/src/commands/restart.ts +30 -0
  108. package/src/commands/restore.ts +140 -22
  109. package/src/commands/retire.ts +48 -150
  110. package/src/commands/rollback.ts +20 -26
  111. package/src/commands/setup.ts +2 -2
  112. package/src/commands/sleep.ts +2 -2
  113. package/src/commands/teleport.ts +109 -109
  114. package/src/commands/terminal.ts +158 -18
  115. package/src/commands/tunnel.ts +138 -157
  116. package/src/commands/uninstall.ts +57 -9
  117. package/src/commands/unpair.ts +3 -3
  118. package/src/commands/upgrade.ts +30 -54
  119. package/src/commands/use.ts +1 -1
  120. package/src/commands/wake.ts +166 -50
  121. package/src/index.ts +18 -9
  122. package/src/lib/__tests__/{platform-client-signed-url.test.ts → cloud-client-signed-url.test.ts} +16 -16
  123. package/src/lib/__tests__/docker.test.ts +168 -20
  124. package/src/lib/__tests__/job-polling.test.ts +2 -2
  125. package/src/lib/__tests__/local-runtime-client.test.ts +4 -4
  126. package/src/lib/__tests__/runtime-url.test.ts +1 -1
  127. package/src/lib/assistant-api-key-resolution.ts +5 -5
  128. package/src/lib/assistant-client.ts +8 -8
  129. package/src/lib/assistant-config.ts +58 -12
  130. package/src/lib/{platform-client.ts → cloud-client.ts} +107 -98
  131. package/src/lib/cloud-login.ts +24 -24
  132. package/src/lib/{platform-releases.ts → cloud-releases.ts} +11 -9
  133. package/src/lib/cloud-values.ts +3 -0
  134. package/src/lib/config-utils.ts +1 -1
  135. package/src/lib/detached-process.ts +1 -1
  136. package/src/lib/docker.ts +260 -53
  137. package/src/lib/ensure-binary.ts +171 -0
  138. package/src/lib/environments/__tests__/paths.test.ts +2 -2
  139. package/src/lib/environments/__tests__/resolve.test.ts +26 -26
  140. package/src/lib/environments/resolve.ts +8 -8
  141. package/src/lib/flag-args.test.ts +1 -1
  142. package/src/lib/flag-args.ts +1 -1
  143. package/src/lib/guardian-token.ts +37 -5
  144. package/src/lib/hatch-local.ts +19 -23
  145. package/src/lib/health-check.ts +6 -6
  146. package/src/lib/ingress-config.ts +8 -35
  147. package/src/lib/job-polling.ts +2 -2
  148. package/src/lib/live-voice/connection.ts +12 -12
  149. package/src/lib/live-voice/tunnel.test.ts +11 -11
  150. package/src/lib/live-voice/tunnel.ts +15 -15
  151. package/src/lib/local-runtime-client.ts +20 -20
  152. package/src/lib/local.ts +10 -31
  153. package/src/lib/nginx-ingress.ts +42 -15
  154. package/src/lib/pair.ts +1 -1
  155. package/src/lib/process.ts +1 -1
  156. package/src/lib/provider-secrets.ts +3 -3
  157. package/src/lib/retire-apple-container.ts +1 -1
  158. package/src/lib/runtime-url.ts +8 -8
  159. package/src/lib/statefulset.ts +2 -2
  160. package/src/lib/sync-cloud-assistants.ts +19 -19
  161. package/src/lib/teleport-backup.ts +4 -4
  162. package/src/lib/terminal-client.ts +17 -17
  163. package/src/lib/terminal-session.ts +24 -24
  164. package/src/lib/{tunnel-edge.ts → tunnel.ts} +199 -11
  165. package/src/lib/tunnels/cadet.ts +29 -0
  166. package/src/lib/{cloudflare-tunnel.ts → tunnels/cloudflare.ts} +36 -15
  167. package/src/lib/tunnels/gateway-notify.ts +61 -0
  168. package/src/lib/{ngrok.ts → tunnels/ngrok.ts} +350 -89
  169. package/src/lib/{tailscale-tunnel.ts → tunnels/tailscale.ts} +53 -9
  170. package/src/lib/upgrade-lifecycle.ts +8 -21
  171. package/src/lib/upgrade-preflight.ts +2 -2
  172. package/src/lib/workos-pkce.ts +5 -5
  173. package/node_modules/@mycadet/assistant-api/events/platform-disconnected.ts +0 -21
  174. package/node_modules/@mycadet/assistant-api/events/show-platform-login.ts +0 -20
  175. package/src/commands/recover.ts +0 -131
  176. package/src/commands/roadmap.ts +0 -459
  177. package/src/commands/ssh.ts +0 -144
  178. package/src/commands/workflows.ts +0 -305
  179. package/src/lib/managed-cloud.ts +0 -3
@@ -8,6 +8,7 @@ import {
8
8
  spyOn,
9
9
  test,
10
10
  } from "bun:test";
11
+ import type { Mock } from "bun:test";
11
12
  import { mkdtempSync, rmSync } from "node:fs";
12
13
  import { tmpdir } from "node:os";
13
14
  import { join } from "node:path";
@@ -37,7 +38,7 @@ process.env.CADET_LOCKFILE_DIR = testDir;
37
38
 
38
39
  import * as assistantConfig from "../lib/assistant-config.js";
39
40
  import * as guardianToken from "../lib/guardian-token.js";
40
- import * as platformClient from "../lib/platform-client.js";
41
+ import * as cloudClient from "../lib/cloud-client.js";
41
42
  import * as localRuntimeClient from "../lib/local-runtime-client.js";
42
43
  import * as backupOps from "../lib/backup-ops.js";
43
44
  import * as teleportBackup from "../lib/teleport-backup.js";
@@ -47,7 +48,8 @@ import * as teleportBackup from "../lib/teleport-backup.js";
47
48
  // how Bun's loader treats namespace bindings post-mock.
48
49
  const realAssistantConfig = { ...assistantConfig };
49
50
  const realGuardianToken = { ...guardianToken };
50
- const realPlatformClient = { ...platformClient };
51
+
52
+ const realCloudClient = { ...cloudClient };
51
53
  const realLocalRuntimeClient = { ...localRuntimeClient };
52
54
  const realBackupOps = { ...backupOps };
53
55
  const realTeleportBackup = { ...teleportBackup };
@@ -73,22 +75,19 @@ mock.module("../lib/assistant-config.js", () => ({
73
75
  removeAssistantEntry: removeAssistantEntryMock,
74
76
  }));
75
77
 
76
- const loadGuardianTokenMock = mock<typeof guardianToken.loadGuardianToken>(
77
- () =>
78
- ({
79
- accessToken: "local-token",
80
- accessTokenExpiresAt: new Date(Date.now() + 60_000).toISOString(),
81
- }) as unknown as ReturnType<typeof guardianToken.loadGuardianToken>,
78
+ const loadGuardianTokenMock = mock<typeof guardianToken.loadGuardianToken>(() =>
79
+ makeGuardianTokenData({
80
+ accessToken: "local-token",
81
+ accessTokenExpiresAt: new Date(Date.now() + 60_000).toISOString(),
82
+ }),
82
83
  );
83
84
 
84
85
  const leaseGuardianTokenMock = mock<typeof guardianToken.leaseGuardianToken>(
85
86
  async () =>
86
- ({
87
+ makeGuardianTokenData({
87
88
  accessToken: "leased-token",
88
89
  accessTokenExpiresAt: new Date(Date.now() + 60_000).toISOString(),
89
- }) as unknown as Awaited<
90
- ReturnType<typeof guardianToken.leaseGuardianToken>
91
- >,
90
+ }),
92
91
  );
93
92
 
94
93
  const computeDeviceIdMock = mock<typeof guardianToken.computeDeviceId>(
@@ -102,15 +101,15 @@ mock.module("../lib/guardian-token.js", () => ({
102
101
  computeDeviceId: computeDeviceIdMock,
103
102
  }));
104
103
 
105
- const readPlatformTokenMock = mock<typeof platformClient.readPlatformToken>(
104
+ const readCloudTokenMock = mock<typeof cloudClient.readCloudToken>(
106
105
  () => "platform-token",
107
106
  );
108
107
 
109
- const getPlatformUrlMock = mock<typeof platformClient.getPlatformUrl>(
108
+ const getCloudUrlMock = mock<typeof cloudClient.getCloudUrl>(
110
109
  () => "https://cloud.mycadet.ai",
111
110
  );
112
111
 
113
- const hatchAssistantMock = mock<typeof platformClient.hatchAssistant>(
112
+ const hatchAssistantMock = mock<typeof cloudClient.hatchAssistant>(
114
113
  async () => ({
115
114
  assistant: {
116
115
  id: "platform-new-id",
@@ -122,7 +121,7 @@ const hatchAssistantMock = mock<typeof platformClient.hatchAssistant>(
122
121
  );
123
122
 
124
123
  const platformPollJobStatusMock = mock<
125
- typeof platformClient.platformPollJobStatus
124
+ typeof cloudClient.platformPollJobStatus
126
125
  >(async () => ({
127
126
  jobId: "platform-job-1",
128
127
  type: "export",
@@ -130,8 +129,8 @@ const platformPollJobStatusMock = mock<
130
129
  bundleKey: "platform-bundle-key-abc",
131
130
  }));
132
131
 
133
- const platformRequestSignedUrlMock = mock<
134
- typeof platformClient.platformRequestSignedUrl
132
+ const cloudRequestSignedUrlMock = mock<
133
+ typeof cloudClient.cloudRequestSignedUrl
135
134
  >(async (params) => ({
136
135
  url:
137
136
  params.operation === "upload"
@@ -142,7 +141,7 @@ const platformRequestSignedUrlMock = mock<
142
141
  }));
143
142
 
144
143
  const platformImportBundleFromGcsMock = mock<
145
- typeof platformClient.platformImportBundleFromGcs
144
+ typeof cloudClient.platformImportBundleFromGcs
146
145
  >(async () => ({
147
146
  statusCode: 200,
148
147
  body: {
@@ -154,11 +153,11 @@ const platformImportBundleFromGcsMock = mock<
154
153
  files_skipped: 0,
155
154
  backups_created: 1,
156
155
  },
157
- } as Record<string, unknown>,
156
+ },
158
157
  }));
159
158
 
160
159
  const platformImportPreflightFromGcsMock = mock<
161
- typeof platformClient.platformImportPreflightFromGcs
160
+ typeof cloudClient.platformImportPreflightFromGcs
162
161
  >(async () => ({
163
162
  statusCode: 200,
164
163
  body: {
@@ -169,60 +168,52 @@ const platformImportPreflightFromGcsMock = mock<
169
168
  files_unchanged: 0,
170
169
  total_files: 3,
171
170
  },
172
- } as Record<string, unknown>,
171
+ },
173
172
  }));
174
173
 
175
- const checkExistingPlatformAssistantMock = mock<
176
- typeof platformClient.checkExistingPlatformAssistant
174
+ const checkExistingCloudAssistantMock = mock<
175
+ typeof cloudClient.checkExistingCloudAssistant
177
176
  >(async () => null);
178
177
 
179
178
  const ensureSelfHostedLocalRegistrationMock = mock<
180
- typeof platformClient.ensureSelfHostedLocalRegistration
181
- >(
182
- async () =>
183
- ({
184
- assistant: { id: "platform-assistant-1", name: "my-assistant" },
185
- registration: {
186
- client_installation_id: "device-id-123",
187
- runtime_assistant_id: "target-local",
188
- client_platform: "cli",
189
- },
190
- assistant_api_key: "api-key-123",
191
- webhook_secret: "webhook-secret-123",
192
- }) as unknown as Awaited<
193
- ReturnType<typeof platformClient.ensureSelfHostedLocalRegistration>
194
- >,
195
- );
179
+ typeof cloudClient.ensureSelfHostedLocalRegistration
180
+ >(async () => ({
181
+ assistant: { id: "platform-assistant-1", name: "my-assistant" },
182
+ registration: {
183
+ client_installation_id: "device-id-123",
184
+ runtime_assistant_id: "target-local",
185
+ client_platform: "cli",
186
+ },
187
+ assistant_api_key: "api-key-123",
188
+ webhook_secret: "webhook-secret-123",
189
+ }));
196
190
 
197
191
  const injectCredentialsIntoAssistantMock = mock<
198
- typeof platformClient.injectCredentialsIntoAssistant
192
+ typeof cloudClient.injectCredentialsIntoAssistant
199
193
  >(async () => true);
200
194
 
201
- const fetchCurrentUserMock = mock<typeof platformClient.fetchCurrentUser>(
202
- async () =>
203
- ({
204
- id: "user-1",
205
- email: "test@example.com",
206
- display: "Test",
207
- }) as unknown as Awaited<
208
- ReturnType<typeof platformClient.fetchCurrentUser>
209
- >,
195
+ const fetchCurrentUserMock = mock<typeof cloudClient.fetchCurrentUser>(
196
+ async () => ({
197
+ id: "user-1",
198
+ email: "test@example.com",
199
+ display: "Test",
200
+ }),
210
201
  );
211
202
 
212
- const fetchOrganizationIdMock = mock<typeof platformClient.fetchOrganizationId>(
203
+ const fetchOrganizationIdMock = mock<typeof cloudClient.fetchOrganizationId>(
213
204
  async () => "org-1",
214
205
  );
215
206
 
216
- mock.module("../lib/platform-client.js", () => ({
217
- ...realPlatformClient,
218
- readPlatformToken: readPlatformTokenMock,
219
- getPlatformUrl: getPlatformUrlMock,
207
+ mock.module("../lib/cloud-client.js", () => ({
208
+ ...realCloudClient,
209
+ readCloudToken: readCloudTokenMock,
210
+ getCloudUrl: getCloudUrlMock,
220
211
  hatchAssistant: hatchAssistantMock,
221
212
  platformPollJobStatus: platformPollJobStatusMock,
222
- platformRequestSignedUrl: platformRequestSignedUrlMock,
213
+ cloudRequestSignedUrl: cloudRequestSignedUrlMock,
223
214
  platformImportBundleFromGcs: platformImportBundleFromGcsMock,
224
215
  platformImportPreflightFromGcs: platformImportPreflightFromGcsMock,
225
- checkExistingPlatformAssistant: checkExistingPlatformAssistantMock,
216
+ checkExistingCloudAssistant: checkExistingCloudAssistantMock,
226
217
  ensureSelfHostedLocalRegistration: ensureSelfHostedLocalRegistrationMock,
227
218
  injectCredentialsIntoAssistant: injectCredentialsIntoAssistantMock,
228
219
  fetchCurrentUser: fetchCurrentUserMock,
@@ -383,6 +374,8 @@ import {
383
374
  resolveOrHatchTarget,
384
375
  } from "../commands/teleport.js";
385
376
  import type { AssistantEntry } from "../lib/assistant-config.js";
377
+ import { withPreconnect } from "./helpers/http.js";
378
+ import { makeGuardianTokenData } from "./helpers/guardian-token.js";
386
379
 
387
380
  // ---------------------------------------------------------------------------
388
381
  // Helpers
@@ -390,11 +383,11 @@ import type { AssistantEntry } from "../lib/assistant-config.js";
390
383
 
391
384
  afterAll(() => {
392
385
  // Restore the real module exports so the mocks do not leak into sibling
393
- // test files (e.g. guardian-token.test.ts, platform-client tests) that
386
+ // test files (e.g. guardian-token.test.ts, cloud-client tests) that
394
387
  // run in the same `bun test` invocation.
395
388
  mock.module("../lib/assistant-config.js", () => realAssistantConfig);
396
389
  mock.module("../lib/guardian-token.js", () => realGuardianToken);
397
- mock.module("../lib/platform-client.js", () => realPlatformClient);
390
+ mock.module("../lib/cloud-client.js", () => realCloudClient);
398
391
  mock.module("../lib/local-runtime-client.js", () => realLocalRuntimeClient);
399
392
  mock.module("../lib/backup-ops.js", () => realBackupOps);
400
393
  mock.module("../lib/teleport-backup.js", () => realTeleportBackup);
@@ -408,7 +401,7 @@ afterAll(() => {
408
401
  });
409
402
 
410
403
  let originalArgv: string[];
411
- let exitMock: ReturnType<typeof mock>;
404
+ let exitMock: Mock<(code?: number | string | undefined) => never>;
412
405
  let originalExit: typeof process.exit;
413
406
  let consoleLogSpy: ReturnType<typeof spyOn>;
414
407
  let consoleErrorSpy: ReturnType<typeof spyOn>;
@@ -455,16 +448,18 @@ beforeEach(() => {
455
448
  removeAssistantEntryMock.mockImplementation(() => {});
456
449
 
457
450
  loadGuardianTokenMock.mockReset();
458
- loadGuardianTokenMock.mockReturnValue({
459
- accessToken: "local-token",
460
- accessTokenExpiresAt: new Date(Date.now() + 60_000).toISOString(),
461
- } as unknown as ReturnType<typeof guardianToken.loadGuardianToken>);
451
+ loadGuardianTokenMock.mockReturnValue(
452
+ makeGuardianTokenData({
453
+ accessToken: "local-token",
454
+ accessTokenExpiresAt: new Date(Date.now() + 60_000).toISOString(),
455
+ }),
456
+ );
462
457
  leaseGuardianTokenMock.mockReset();
463
458
 
464
- readPlatformTokenMock.mockReset();
465
- readPlatformTokenMock.mockReturnValue("platform-token");
466
- getPlatformUrlMock.mockReset();
467
- getPlatformUrlMock.mockReturnValue("https://cloud.mycadet.ai");
459
+ readCloudTokenMock.mockReset();
460
+ readCloudTokenMock.mockReturnValue("platform-token");
461
+ getCloudUrlMock.mockReset();
462
+ getCloudUrlMock.mockReturnValue("https://cloud.mycadet.ai");
468
463
  hatchAssistantMock.mockReset();
469
464
  hatchAssistantMock.mockResolvedValue({
470
465
  assistant: {
@@ -481,8 +476,8 @@ beforeEach(() => {
481
476
  status: "complete",
482
477
  bundleKey: "platform-bundle-key-abc",
483
478
  });
484
- platformRequestSignedUrlMock.mockReset();
485
- platformRequestSignedUrlMock.mockImplementation(async (params) => ({
479
+ cloudRequestSignedUrlMock.mockReset();
480
+ cloudRequestSignedUrlMock.mockImplementation(async (params) => ({
486
481
  url:
487
482
  params.operation === "upload"
488
483
  ? "https://storage.googleapis.com/bucket/signed-upload"
@@ -517,8 +512,8 @@ beforeEach(() => {
517
512
  },
518
513
  },
519
514
  });
520
- checkExistingPlatformAssistantMock.mockReset();
521
- checkExistingPlatformAssistantMock.mockResolvedValue(null);
515
+ checkExistingCloudAssistantMock.mockReset();
516
+ checkExistingCloudAssistantMock.mockResolvedValue(null);
522
517
  ensureSelfHostedLocalRegistrationMock.mockReset();
523
518
  ensureSelfHostedLocalRegistrationMock.mockResolvedValue({
524
519
  assistant: { id: "platform-assistant-1", name: "my-assistant" },
@@ -597,11 +592,11 @@ beforeEach(() => {
597
592
  stopProcessByPidFileMock.mockResolvedValue(true);
598
593
 
599
594
  // Mock process.exit to throw so we can catch it
600
- exitMock = mock((code?: number) => {
595
+ exitMock = mock((code?: number | string | undefined): never => {
601
596
  throw new Error(`process.exit:${code}`);
602
597
  });
603
598
  originalExit = process.exit;
604
- process.exit = exitMock as unknown as typeof process.exit;
599
+ process.exit = exitMock;
605
600
 
606
601
  consoleLogSpy = spyOn(console, "log").mockImplementation(() => {});
607
602
  consoleErrorSpy = spyOn(console, "error").mockImplementation(() => {});
@@ -638,13 +633,13 @@ function makeEntry(
638
633
  */
639
634
  function installTrackingFetch(): () => void {
640
635
  const originalFetch = globalThis.fetch;
641
- globalThis.fetch = mock(
642
- async (url: string | URL | Request, init?: RequestInit) => {
643
- const urlStr = typeof url === "string" ? url : url.toString();
636
+ globalThis.fetch = withPreconnect(
637
+ async (input: RequestInfo | URL, init?: RequestInit) => {
638
+ const urlStr = String(input);
644
639
  fetchCalls.push({ url: urlStr, body: init?.body });
645
640
  return new Response("not found", { status: 404 });
646
641
  },
647
- ) as unknown as typeof globalThis.fetch;
642
+ );
648
643
  return () => {
649
644
  globalThis.fetch = originalFetch;
650
645
  };
@@ -890,17 +885,17 @@ describe("resolveOrHatchTarget", () => {
890
885
  });
891
886
 
892
887
  test("platform with existing ID -> returns existing without hatching", async () => {
893
- const platformEntry = makeEntry("uuid-123", {
888
+ const cloudEntry = makeEntry("uuid-123", {
894
889
  cloud: "cadet",
895
890
  runtimeUrl: "https://cloud.mycadet.ai",
896
891
  });
897
892
  findAssistantByNameMock.mockImplementation((name: string) => {
898
- if (name === "uuid-123") return platformEntry;
893
+ if (name === "uuid-123") return cloudEntry;
899
894
  return null;
900
895
  });
901
896
 
902
897
  const result = await resolveOrHatchTarget("platform", "uuid-123");
903
- expect(result).toBe(platformEntry);
898
+ expect(result).toBe(cloudEntry);
904
899
  expect(hatchAssistantMock).not.toHaveBeenCalled();
905
900
  });
906
901
 
@@ -927,7 +922,7 @@ describe("resolveOrHatchTarget", () => {
927
922
  "process.exit:1",
928
923
  );
929
924
  expect(consoleErrorSpy).toHaveBeenCalledWith(
930
- expect.stringContaining("already have a platform assistant"),
925
+ expect.stringContaining("already have a cloud assistant"),
931
926
  );
932
927
  });
933
928
 
@@ -976,9 +971,9 @@ describe("unified GCS flow — four directions", () => {
976
971
  try {
977
972
  await teleport();
978
973
 
979
- // Signed-URL request for upload — pinned to the platform target's URL
974
+ // Signed-URL request for upload — pinned to the cloud target's URL
980
975
  // so upload and download land on the same platform.
981
- expect(platformRequestSignedUrlMock).toHaveBeenCalledWith(
976
+ expect(cloudRequestSignedUrlMock).toHaveBeenCalledWith(
982
977
  expect.objectContaining({
983
978
  operation: "upload",
984
979
  minRuntimeVersion: "0.6.5",
@@ -1014,9 +1009,8 @@ describe("unified GCS flow — four directions", () => {
1014
1009
 
1015
1010
  // No download-URL request on the import side (platform target pulls
1016
1011
  // directly from GCS).
1017
- const downloadOps = platformRequestSignedUrlMock.mock.calls.filter(
1018
- (call: unknown[]) =>
1019
- (call[0] as { operation: string }).operation === "download",
1012
+ const downloadOps = cloudRequestSignedUrlMock.mock.calls.filter(
1013
+ (call) => call[0].operation === "download",
1020
1014
  );
1021
1015
  expect(downloadOps.length).toBe(0);
1022
1016
  } finally {
@@ -1027,7 +1021,7 @@ describe("unified GCS flow — four directions", () => {
1027
1021
  test("platform → local: drives platform export, reads bundle_key, requests download URL for runtime import", async () => {
1028
1022
  setArgv("--from", "my-platform", "--local", "my-local");
1029
1023
 
1030
- const platformEntry = makeEntry("my-platform", {
1024
+ const cloudEntry = makeEntry("my-platform", {
1031
1025
  cloud: "cadet",
1032
1026
  runtimeUrl: "https://cloud.mycadet.ai",
1033
1027
  });
@@ -1037,7 +1031,7 @@ describe("unified GCS flow — four directions", () => {
1037
1031
  });
1038
1032
 
1039
1033
  findAssistantByNameMock.mockImplementation((name: string) => {
1040
- if (name === "my-platform") return platformEntry;
1034
+ if (name === "my-platform") return cloudEntry;
1041
1035
  if (name === "my-local") return localEntry;
1042
1036
  return null;
1043
1037
  });
@@ -1053,7 +1047,7 @@ describe("unified GCS flow — four directions", () => {
1053
1047
  // The bundle key now flows from the upload signed-URL request rather than
1054
1048
  // the job-status payload — pin it so the download-URL assertion below
1055
1049
  // still uses the same expected key.
1056
- platformRequestSignedUrlMock.mockImplementation(async (params) => ({
1050
+ cloudRequestSignedUrlMock.mockImplementation(async (params) => ({
1057
1051
  url:
1058
1052
  params.operation === "upload"
1059
1053
  ? "https://storage.googleapis.com/bucket/signed-upload"
@@ -1069,7 +1063,7 @@ describe("unified GCS flow — four directions", () => {
1069
1063
 
1070
1064
  // Platform side: requested an upload URL, kicked off a runtime export to
1071
1065
  // GCS, and polled the unified job status.
1072
- expect(platformRequestSignedUrlMock).toHaveBeenCalledWith(
1066
+ expect(cloudRequestSignedUrlMock).toHaveBeenCalledWith(
1073
1067
  expect.objectContaining({
1074
1068
  operation: "upload",
1075
1069
  minRuntimeVersion: "0.6.5",
@@ -1078,7 +1072,7 @@ describe("unified GCS flow — four directions", () => {
1078
1072
  "platform-token",
1079
1073
  "https://cloud.mycadet.ai",
1080
1074
  );
1081
- // For platform sources, export-to-gcs is reached via the platform's
1075
+ // For platform sources, export-to-gcs is reached via the cloud's
1082
1076
  // wildcard runtime proxy. The helper builds the assistant-scoped URL
1083
1077
  // from the entry (`/v1/assistants/<id>/migrations/export-to-gcs`) and
1084
1078
  // sends platform-token auth — no guardian-token bootstrap.
@@ -1116,7 +1110,7 @@ describe("unified GCS flow — four directions", () => {
1116
1110
  // `/v1/identity` (mocked to "0.6.5"), NOT from the CLI's package
1117
1111
  // version. The local target's daemon can be on a different version
1118
1112
  // than the CLI orchestrating the teleport.
1119
- expect(platformRequestSignedUrlMock).toHaveBeenCalledWith(
1113
+ expect(cloudRequestSignedUrlMock).toHaveBeenCalledWith(
1120
1114
  expect.objectContaining({
1121
1115
  operation: "download",
1122
1116
  bundleKey: "platform-exports/org-1/bundle-abc.vbundle",
@@ -1177,8 +1171,8 @@ describe("unified GCS flow — four directions", () => {
1177
1171
 
1178
1172
  // Export and import must pin the same platform URL so the bundle
1179
1173
  // lives in one place end-to-end. For local→docker neither side is
1180
- // platform, so we default to getPlatformUrl() (resolved once).
1181
- expect(platformRequestSignedUrlMock).toHaveBeenCalledWith(
1174
+ // platform, so we default to getCloudUrl() (resolved once).
1175
+ expect(cloudRequestSignedUrlMock).toHaveBeenCalledWith(
1182
1176
  expect.objectContaining({
1183
1177
  operation: "upload",
1184
1178
  minRuntimeVersion: "0.6.5",
@@ -1192,7 +1186,7 @@ describe("unified GCS flow — four directions", () => {
1192
1186
  // Import: download-URL for the docker target, then runtime import.
1193
1187
  // targetRuntimeVersion comes from the docker target's runtime
1194
1188
  // identity (mocked to "0.6.5"), not from cliPkg.version.
1195
- expect(platformRequestSignedUrlMock).toHaveBeenCalledWith(
1189
+ expect(cloudRequestSignedUrlMock).toHaveBeenCalledWith(
1196
1190
  expect.objectContaining({
1197
1191
  operation: "download",
1198
1192
  bundleKey: "bundle-key-123",
@@ -1256,7 +1250,7 @@ describe("unified GCS flow — four directions", () => {
1256
1250
 
1257
1251
  // Export leg: upload-URL (pinned to the same platform as import),
1258
1252
  // then runtime export.
1259
- expect(platformRequestSignedUrlMock).toHaveBeenCalledWith(
1253
+ expect(cloudRequestSignedUrlMock).toHaveBeenCalledWith(
1260
1254
  expect.objectContaining({
1261
1255
  operation: "upload",
1262
1256
  minRuntimeVersion: "0.6.5",
@@ -1305,16 +1299,16 @@ describe("signed-URL request targets the bundle-owning platform", () => {
1305
1299
  setArgv("--from", "my-local", "--platform", "existing-platform");
1306
1300
 
1307
1301
  const localEntry = makeEntry("my-local", { cloud: "local" });
1308
- // Crucially, the target's runtimeUrl is NOT the default getPlatformUrl()
1302
+ // Crucially, the target's runtimeUrl is NOT the default getCloudUrl()
1309
1303
  // return value — this is the regression case Codex flagged.
1310
- const platformEntry = makeEntry("existing-platform", {
1304
+ const cloudEntry = makeEntry("existing-platform", {
1311
1305
  cloud: "cadet",
1312
1306
  runtimeUrl: "https://staging-cloud.mycadet.ai",
1313
1307
  });
1314
1308
 
1315
1309
  findAssistantByNameMock.mockImplementation((name: string) => {
1316
1310
  if (name === "my-local") return localEntry;
1317
- if (name === "existing-platform") return platformEntry;
1311
+ if (name === "existing-platform") return cloudEntry;
1318
1312
  return null;
1319
1313
  });
1320
1314
 
@@ -1324,7 +1318,7 @@ describe("signed-URL request targets the bundle-owning platform", () => {
1324
1318
 
1325
1319
  // The signed-URL request for upload MUST target the existing
1326
1320
  // platform assistant's runtimeUrl, not the default platform URL.
1327
- expect(platformRequestSignedUrlMock).toHaveBeenCalledWith(
1321
+ expect(cloudRequestSignedUrlMock).toHaveBeenCalledWith(
1328
1322
  expect.objectContaining({
1329
1323
  operation: "upload",
1330
1324
  minRuntimeVersion: "0.6.5",
@@ -1343,7 +1337,7 @@ describe("signed-URL request targets the bundle-owning platform", () => {
1343
1337
 
1344
1338
  // Assert none of the signed-URL calls used the default URL — if any
1345
1339
  // did, upload and download would hit different platforms.
1346
- for (const call of platformRequestSignedUrlMock.mock.calls) {
1340
+ for (const call of cloudRequestSignedUrlMock.mock.calls) {
1347
1341
  expect(call[2]).toBe("https://staging-cloud.mycadet.ai");
1348
1342
  }
1349
1343
  } finally {
@@ -1354,14 +1348,14 @@ describe("signed-URL request targets the bundle-owning platform", () => {
1354
1348
  test("platform → local with non-default source runtimeUrl: download URL pinned to source's runtimeUrl", async () => {
1355
1349
  setArgv("--from", "my-platform", "--local", "my-local");
1356
1350
 
1357
- const platformEntry = makeEntry("my-platform", {
1351
+ const cloudEntry = makeEntry("my-platform", {
1358
1352
  cloud: "cadet",
1359
1353
  runtimeUrl: "https://dev-cloud.mycadet.ai",
1360
1354
  });
1361
1355
  const localEntry = makeEntry("my-local", { cloud: "local" });
1362
1356
 
1363
1357
  findAssistantByNameMock.mockImplementation((name: string) => {
1364
- if (name === "my-platform") return platformEntry;
1358
+ if (name === "my-platform") return cloudEntry;
1365
1359
  if (name === "my-local") return localEntry;
1366
1360
  return null;
1367
1361
  });
@@ -1375,7 +1369,7 @@ describe("signed-URL request targets the bundle-owning platform", () => {
1375
1369
 
1376
1370
  // Bundle key flows from the upload signed-URL request now; pin it so the
1377
1371
  // download-URL assertion below uses the same key.
1378
- platformRequestSignedUrlMock.mockImplementation(async (params) => ({
1372
+ cloudRequestSignedUrlMock.mockImplementation(async (params) => ({
1379
1373
  url:
1380
1374
  params.operation === "upload"
1381
1375
  ? "https://storage.googleapis.com/bucket/signed-upload"
@@ -1392,7 +1386,7 @@ describe("signed-URL request targets the bundle-owning platform", () => {
1392
1386
  // the bundle was written by the runtime export), not the default.
1393
1387
  // targetRuntimeVersion comes from the local target's `/v1/identity`
1394
1388
  // (mocked to "0.6.5"), not from cliPkg.version.
1395
- expect(platformRequestSignedUrlMock).toHaveBeenCalledWith(
1389
+ expect(cloudRequestSignedUrlMock).toHaveBeenCalledWith(
1396
1390
  expect.objectContaining({
1397
1391
  operation: "download",
1398
1392
  bundleKey: "dev-bundle-key",
@@ -1447,14 +1441,14 @@ describe("CLI never buffers bundle bytes", () => {
1447
1441
  test("platform → local: no fetch call carries a bundle-sized body", async () => {
1448
1442
  setArgv("--from", "my-platform", "--local", "my-local");
1449
1443
 
1450
- const platformEntry = makeEntry("my-platform", {
1444
+ const cloudEntry = makeEntry("my-platform", {
1451
1445
  cloud: "cadet",
1452
1446
  runtimeUrl: "https://cloud.mycadet.ai",
1453
1447
  });
1454
1448
  const localEntry = makeEntry("my-local", { cloud: "local" });
1455
1449
 
1456
1450
  findAssistantByNameMock.mockImplementation((name: string) => {
1457
- if (name === "my-platform") return platformEntry;
1451
+ if (name === "my-platform") return cloudEntry;
1458
1452
  if (name === "my-local") return localEntry;
1459
1453
  return null;
1460
1454
  });
@@ -1550,14 +1544,14 @@ describe("polling", () => {
1550
1544
  test("local-runtime import failure → teleport exits 1", async () => {
1551
1545
  setArgv("--from", "my-platform", "--local", "my-local");
1552
1546
 
1553
- const platformEntry = makeEntry("my-platform", {
1547
+ const cloudEntry = makeEntry("my-platform", {
1554
1548
  cloud: "cadet",
1555
1549
  runtimeUrl: "https://cloud.mycadet.ai",
1556
1550
  });
1557
1551
  const localEntry = makeEntry("my-local", { cloud: "local" });
1558
1552
 
1559
1553
  findAssistantByNameMock.mockImplementation((name: string) => {
1560
- if (name === "my-platform") return platformEntry;
1554
+ if (name === "my-platform") return cloudEntry;
1561
1555
  if (name === "my-local") return localEntry;
1562
1556
  return null;
1563
1557
  });
@@ -1647,14 +1641,14 @@ describe("MigrationInProgressError handling", () => {
1647
1641
  test("local-runtime import already in flight → fail fast with existing job id", async () => {
1648
1642
  setArgv("--from", "my-platform", "--local", "my-local");
1649
1643
 
1650
- const platformEntry = makeEntry("my-platform", {
1644
+ const cloudEntry = makeEntry("my-platform", {
1651
1645
  cloud: "cadet",
1652
1646
  runtimeUrl: "https://cloud.mycadet.ai",
1653
1647
  });
1654
1648
  const localEntry = makeEntry("my-local", { cloud: "local" });
1655
1649
 
1656
1650
  findAssistantByNameMock.mockImplementation((name: string) => {
1657
- if (name === "my-platform") return platformEntry;
1651
+ if (name === "my-platform") return cloudEntry;
1658
1652
  if (name === "my-local") return localEntry;
1659
1653
  return null;
1660
1654
  });
@@ -1697,7 +1691,7 @@ describe("MigrationInProgressError handling", () => {
1697
1691
  });
1698
1692
 
1699
1693
  // ---------------------------------------------------------------------------
1700
- // VersionMismatchError handling — 422 from platformRequestSignedUrl on the
1694
+ // VersionMismatchError handling — 422 from cloudRequestSignedUrl on the
1701
1695
  // download leg is terminal: surface a friendly message + exit 1, no retry.
1702
1696
  // ---------------------------------------------------------------------------
1703
1697
 
@@ -1705,14 +1699,14 @@ describe("VersionMismatchError handling", () => {
1705
1699
  test("local target: 422 on download signed-URL exits 1 with friendly message", async () => {
1706
1700
  setArgv("--from", "my-platform", "--local", "my-local");
1707
1701
 
1708
- const platformEntry = makeEntry("my-platform", {
1702
+ const cloudEntry = makeEntry("my-platform", {
1709
1703
  cloud: "cadet",
1710
1704
  runtimeUrl: "https://cloud.mycadet.ai",
1711
1705
  });
1712
1706
  const localEntry = makeEntry("my-local", { cloud: "local" });
1713
1707
 
1714
1708
  findAssistantByNameMock.mockImplementation((name: string) => {
1715
- if (name === "my-platform") return platformEntry;
1709
+ if (name === "my-platform") return cloudEntry;
1716
1710
  if (name === "my-local") return localEntry;
1717
1711
  return null;
1718
1712
  });
@@ -1725,9 +1719,9 @@ describe("VersionMismatchError handling", () => {
1725
1719
  });
1726
1720
 
1727
1721
  // Upload signed-URL succeeds; download signed-URL throws version-mismatch.
1728
- platformRequestSignedUrlMock.mockImplementation(async (params) => {
1722
+ cloudRequestSignedUrlMock.mockImplementation(async (params) => {
1729
1723
  if (params.operation === "download") {
1730
- throw new platformClient.VersionMismatchError(
1724
+ throw new cloudClient.VersionMismatchError(
1731
1725
  { min_runtime_version: "99.0.0", max_runtime_version: null },
1732
1726
  "0.7.1",
1733
1727
  );
@@ -1749,8 +1743,8 @@ describe("VersionMismatchError handling", () => {
1749
1743
  );
1750
1744
 
1751
1745
  // Terminal: no retry of the download signed-URL request.
1752
- const downloadCalls = platformRequestSignedUrlMock.mock.calls.filter(
1753
- (c) => (c[0] as { operation: string }).operation === "download",
1746
+ const downloadCalls = cloudRequestSignedUrlMock.mock.calls.filter(
1747
+ (c) => c[0].operation === "download",
1754
1748
  );
1755
1749
  expect(downloadCalls).toHaveLength(1);
1756
1750
 
@@ -1781,9 +1775,9 @@ describe("VersionMismatchError handling", () => {
1781
1775
  return [localEntry];
1782
1776
  });
1783
1777
 
1784
- platformRequestSignedUrlMock.mockImplementation(async (params) => {
1778
+ cloudRequestSignedUrlMock.mockImplementation(async (params) => {
1785
1779
  if (params.operation === "download") {
1786
- throw new platformClient.VersionMismatchError(
1780
+ throw new cloudClient.VersionMismatchError(
1787
1781
  { min_runtime_version: "99.0.0", max_runtime_version: null },
1788
1782
  "0.7.1",
1789
1783
  );
@@ -1812,14 +1806,14 @@ describe("VersionMismatchError handling", () => {
1812
1806
  test("non-VersionMismatchError on download signed-URL re-raises", async () => {
1813
1807
  setArgv("--from", "my-platform", "--local", "my-local");
1814
1808
 
1815
- const platformEntry = makeEntry("my-platform", {
1809
+ const cloudEntry = makeEntry("my-platform", {
1816
1810
  cloud: "cadet",
1817
1811
  runtimeUrl: "https://cloud.mycadet.ai",
1818
1812
  });
1819
1813
  const localEntry = makeEntry("my-local", { cloud: "local" });
1820
1814
 
1821
1815
  findAssistantByNameMock.mockImplementation((name: string) => {
1822
- if (name === "my-platform") return platformEntry;
1816
+ if (name === "my-platform") return cloudEntry;
1823
1817
  if (name === "my-local") return localEntry;
1824
1818
  return null;
1825
1819
  });
@@ -1831,7 +1825,7 @@ describe("VersionMismatchError handling", () => {
1831
1825
  bundleKey: "platform-bundle-key-abc",
1832
1826
  });
1833
1827
 
1834
- platformRequestSignedUrlMock.mockImplementation(async (params) => {
1828
+ cloudRequestSignedUrlMock.mockImplementation(async (params) => {
1835
1829
  if (params.operation === "download") {
1836
1830
  throw new Error("network blew up");
1837
1831
  }
@@ -1861,14 +1855,14 @@ describe("target runtime version fetch", () => {
1861
1855
  test("local target: targetRuntimeVersion comes from /v1/identity, not cliPkg", async () => {
1862
1856
  setArgv("--from", "my-platform", "--local", "my-local");
1863
1857
 
1864
- const platformEntry = makeEntry("my-platform", {
1858
+ const cloudEntry = makeEntry("my-platform", {
1865
1859
  cloud: "cadet",
1866
1860
  runtimeUrl: "https://cloud.mycadet.ai",
1867
1861
  });
1868
1862
  const localEntry = makeEntry("my-local", { cloud: "local" });
1869
1863
 
1870
1864
  findAssistantByNameMock.mockImplementation((name: string) => {
1871
- if (name === "my-platform") return platformEntry;
1865
+ if (name === "my-platform") return cloudEntry;
1872
1866
  if (name === "my-local") return localEntry;
1873
1867
  return null;
1874
1868
  });
@@ -1888,8 +1882,8 @@ describe("target runtime version fetch", () => {
1888
1882
  try {
1889
1883
  await teleport();
1890
1884
 
1891
- const downloadCall = platformRequestSignedUrlMock.mock.calls.find(
1892
- (c) => (c[0] as { operation: string }).operation === "download",
1885
+ const downloadCall = cloudRequestSignedUrlMock.mock.calls.find(
1886
+ (c) => c[0].operation === "download",
1893
1887
  );
1894
1888
  expect(downloadCall).toBeDefined();
1895
1889
  expect(downloadCall![0]).toMatchObject({
@@ -1913,14 +1907,14 @@ describe("target runtime version fetch", () => {
1913
1907
  test("identity fetch failure aborts before requesting download URL", async () => {
1914
1908
  setArgv("--from", "my-platform", "--local", "my-local");
1915
1909
 
1916
- const platformEntry = makeEntry("my-platform", {
1910
+ const cloudEntry = makeEntry("my-platform", {
1917
1911
  cloud: "cadet",
1918
1912
  runtimeUrl: "https://cloud.mycadet.ai",
1919
1913
  });
1920
1914
  const localEntry = makeEntry("my-local", { cloud: "local" });
1921
1915
 
1922
1916
  findAssistantByNameMock.mockImplementation((name: string) => {
1923
- if (name === "my-platform") return platformEntry;
1917
+ if (name === "my-platform") return cloudEntry;
1924
1918
  if (name === "my-local") return localEntry;
1925
1919
  return null;
1926
1920
  });
@@ -1953,8 +1947,8 @@ describe("target runtime version fetch", () => {
1953
1947
  );
1954
1948
 
1955
1949
  // No download signed-URL request was made — we aborted before that.
1956
- const downloadCalls = platformRequestSignedUrlMock.mock.calls.filter(
1957
- (c) => (c[0] as { operation: string }).operation === "download",
1950
+ const downloadCalls = cloudRequestSignedUrlMock.mock.calls.filter(
1951
+ (c) => c[0].operation === "download",
1958
1952
  );
1959
1953
  expect(downloadCalls).toHaveLength(0);
1960
1954
  expect(localRuntimeImportFromGcsMock).not.toHaveBeenCalled();
@@ -1998,14 +1992,14 @@ describe("dry-run", () => {
1998
1992
  );
1999
1993
 
2000
1994
  const localEntry = makeEntry("my-local", { cloud: "local" });
2001
- const platformEntry = makeEntry("existing-platform", {
1995
+ const cloudEntry = makeEntry("existing-platform", {
2002
1996
  cloud: "cadet",
2003
1997
  runtimeUrl: "https://cloud.mycadet.ai",
2004
1998
  });
2005
1999
 
2006
2000
  findAssistantByNameMock.mockImplementation((name: string) => {
2007
2001
  if (name === "my-local") return localEntry;
2008
- if (name === "existing-platform") return platformEntry;
2002
+ if (name === "existing-platform") return cloudEntry;
2009
2003
  return null;
2010
2004
  });
2011
2005
 
@@ -2026,14 +2020,14 @@ describe("dry-run", () => {
2026
2020
  test("dry-run with existing local target calls preflight-from-gcs on runtime", async () => {
2027
2021
  setArgv("--from", "my-platform", "--local", "my-local", "--dry-run");
2028
2022
 
2029
- const platformEntry = makeEntry("my-platform", {
2023
+ const cloudEntry = makeEntry("my-platform", {
2030
2024
  cloud: "cadet",
2031
2025
  runtimeUrl: "https://cloud.mycadet.ai",
2032
2026
  });
2033
2027
  const localEntry = makeEntry("my-local", { cloud: "local" });
2034
2028
 
2035
2029
  findAssistantByNameMock.mockImplementation((name: string) => {
2036
- if (name === "my-platform") return platformEntry;
2030
+ if (name === "my-platform") return cloudEntry;
2037
2031
  if (name === "my-local") return localEntry;
2038
2032
  return null;
2039
2033
  });
@@ -2179,13 +2173,13 @@ describe("pre-export source backup", () => {
2179
2173
 
2180
2174
  test("platform source: takes a PVC snapshot through the source platform before exporting", async () => {
2181
2175
  setArgv("--from", "my-platform", "--local", "my-local");
2182
- const platformEntry = makeEntry("my-platform", {
2176
+ const cloudEntry = makeEntry("my-platform", {
2183
2177
  cloud: "cadet",
2184
2178
  runtimeUrl: "https://cloud.mycadet.ai",
2185
2179
  });
2186
2180
  const localEntry = makeEntry("my-local", { cloud: "local" });
2187
2181
  findAssistantByNameMock.mockImplementation((name: string) => {
2188
- if (name === "my-platform") return platformEntry;
2182
+ if (name === "my-platform") return cloudEntry;
2189
2183
  if (name === "my-local") return localEntry;
2190
2184
  return null;
2191
2185
  });
@@ -2223,13 +2217,13 @@ describe("pre-export source backup", () => {
2223
2217
 
2224
2218
  test("platform source with a recent ready snapshot: reuses it", async () => {
2225
2219
  setArgv("--from", "my-platform", "--local", "my-local");
2226
- const platformEntry = makeEntry("my-platform", {
2220
+ const cloudEntry = makeEntry("my-platform", {
2227
2221
  cloud: "cadet",
2228
2222
  runtimeUrl: "https://cloud.mycadet.ai",
2229
2223
  });
2230
2224
  const localEntry = makeEntry("my-local", { cloud: "local" });
2231
2225
  findAssistantByNameMock.mockImplementation((name: string) => {
2232
- if (name === "my-platform") return platformEntry;
2226
+ if (name === "my-platform") return cloudEntry;
2233
2227
  if (name === "my-local") return localEntry;
2234
2228
  return null;
2235
2229
  });
@@ -2273,13 +2267,13 @@ describe("pre-export source backup", () => {
2273
2267
 
2274
2268
  test("platform snapshot failure (never ready) aborts too", async () => {
2275
2269
  setArgv("--from", "my-platform", "--local", "my-local");
2276
- const platformEntry = makeEntry("my-platform", {
2270
+ const cloudEntry = makeEntry("my-platform", {
2277
2271
  cloud: "cadet",
2278
2272
  runtimeUrl: "https://cloud.mycadet.ai",
2279
2273
  });
2280
2274
  const localEntry = makeEntry("my-local", { cloud: "local" });
2281
2275
  findAssistantByNameMock.mockImplementation((name: string) => {
2282
- if (name === "my-platform") return platformEntry;
2276
+ if (name === "my-platform") return cloudEntry;
2283
2277
  if (name === "my-local") return localEntry;
2284
2278
  return null;
2285
2279
  });
@@ -2323,7 +2317,7 @@ describe("pre-check: existing platform assistant", () => {
2323
2317
  name === "my-local" ? localEntry : null,
2324
2318
  );
2325
2319
 
2326
- checkExistingPlatformAssistantMock.mockResolvedValue({
2320
+ checkExistingCloudAssistantMock.mockResolvedValue({
2327
2321
  id: "existing-platform-id",
2328
2322
  name: "existing-platform",
2329
2323
  status: "active",
@@ -2331,17 +2325,17 @@ describe("pre-check: existing platform assistant", () => {
2331
2325
 
2332
2326
  await expect(teleport()).rejects.toThrow("process.exit:1");
2333
2327
 
2334
- expect(checkExistingPlatformAssistantMock).toHaveBeenCalledWith(
2328
+ expect(checkExistingCloudAssistantMock).toHaveBeenCalledWith(
2335
2329
  "platform-token",
2336
2330
  undefined,
2337
2331
  );
2338
2332
  // No signed-URL or runtime calls
2339
- expect(platformRequestSignedUrlMock).not.toHaveBeenCalled();
2333
+ expect(cloudRequestSignedUrlMock).not.toHaveBeenCalled();
2340
2334
  expect(localRuntimeExportToGcsMock).not.toHaveBeenCalled();
2341
2335
  expect(hatchAssistantMock).not.toHaveBeenCalled();
2342
2336
 
2343
2337
  expect(consoleErrorSpy).toHaveBeenCalledWith(
2344
- expect.stringContaining("already have a platform assistant"),
2338
+ expect.stringContaining("already have a cloud assistant"),
2345
2339
  );
2346
2340
  });
2347
2341
  });
@@ -2354,14 +2348,14 @@ describe("version guard", () => {
2354
2348
  test("blocks platform→local when local version is behind", async () => {
2355
2349
  setArgv("--from", "my-platform", "--local", "my-local");
2356
2350
 
2357
- const platformEntry = makeEntry("my-platform", {
2351
+ const cloudEntry = makeEntry("my-platform", {
2358
2352
  cloud: "cadet",
2359
2353
  runtimeUrl: "https://cloud.mycadet.ai",
2360
2354
  });
2361
2355
  const localEntry = makeEntry("my-local", { cloud: "local" });
2362
2356
 
2363
2357
  findAssistantByNameMock.mockImplementation((name: string) => {
2364
- if (name === "my-platform") return platformEntry;
2358
+ if (name === "my-platform") return cloudEntry;
2365
2359
  if (name === "my-local") return localEntry;
2366
2360
  return null;
2367
2361
  });
@@ -2385,14 +2379,14 @@ describe("version guard", () => {
2385
2379
  test("allows equal versions", async () => {
2386
2380
  setArgv("--from", "my-platform", "--local", "my-local");
2387
2381
 
2388
- const platformEntry = makeEntry("my-platform", {
2382
+ const cloudEntry = makeEntry("my-platform", {
2389
2383
  cloud: "cadet",
2390
2384
  runtimeUrl: "https://cloud.mycadet.ai",
2391
2385
  });
2392
2386
  const localEntry = makeEntry("my-local", { cloud: "local" });
2393
2387
 
2394
2388
  findAssistantByNameMock.mockImplementation((name: string) => {
2395
- if (name === "my-platform") return platformEntry;
2389
+ if (name === "my-platform") return cloudEntry;
2396
2390
  if (name === "my-local") return localEntry;
2397
2391
  return null;
2398
2392
  });
@@ -2419,21 +2413,21 @@ describe("version guard", () => {
2419
2413
  test("newly hatched target is cleaned up when version check fails", async () => {
2420
2414
  setArgv("--from", "my-platform", "--local");
2421
2415
 
2422
- const platformEntry = makeEntry("my-platform", {
2416
+ const cloudEntry = makeEntry("my-platform", {
2423
2417
  cloud: "cadet",
2424
2418
  runtimeUrl: "https://cloud.mycadet.ai",
2425
2419
  });
2426
2420
  const newLocalEntry = makeEntry("new-local", { cloud: "local" });
2427
2421
 
2428
2422
  findAssistantByNameMock.mockImplementation((name: string) =>
2429
- name === "my-platform" ? platformEntry : null,
2423
+ name === "my-platform" ? cloudEntry : null,
2430
2424
  );
2431
2425
 
2432
2426
  loadAllAssistantsMock.mockImplementation(() => {
2433
2427
  if (hatchLocalMock.mock.calls.length > 0) {
2434
- return [platformEntry, newLocalEntry];
2428
+ return [cloudEntry, newLocalEntry];
2435
2429
  }
2436
- return [platformEntry];
2430
+ return [cloudEntry];
2437
2431
  });
2438
2432
 
2439
2433
  platformPollJobStatusMock.mockResolvedValue({
@@ -2533,7 +2527,7 @@ describe("platform credential injection", () => {
2533
2527
  test("platform→local teleport calls ensureSelfHostedLocalRegistration and injectCredentialsIntoAssistant", async () => {
2534
2528
  setArgv("--from", "my-platform", "--local", "my-local");
2535
2529
 
2536
- const platformEntry = makeEntry("my-platform", {
2530
+ const cloudEntry = makeEntry("my-platform", {
2537
2531
  cloud: "cadet",
2538
2532
  runtimeUrl: "https://cloud.mycadet.ai",
2539
2533
  });
@@ -2543,7 +2537,7 @@ describe("platform credential injection", () => {
2543
2537
  });
2544
2538
 
2545
2539
  findAssistantByNameMock.mockImplementation((name: string) => {
2546
- if (name === "my-platform") return platformEntry;
2540
+ if (name === "my-platform") return cloudEntry;
2547
2541
  if (name === "my-local") return localEntry;
2548
2542
  return null;
2549
2543
  });
@@ -2565,15 +2559,15 @@ describe("platform credential injection", () => {
2565
2559
  "my-local",
2566
2560
  "cli",
2567
2561
  undefined, // assistantVersion (gateway unreachable in test)
2568
- expect.any(String), // platformUrl from getPlatformUrl()
2562
+ expect.any(String), // cloudUrl from getCloudUrl()
2569
2563
  undefined, // ingressUrl (gateway unreachable in test)
2570
2564
  );
2571
2565
  expect(injectCredentialsIntoAssistantMock).toHaveBeenCalledWith({
2572
2566
  gatewayUrl: "http://localhost:7821",
2573
2567
  bearerToken: "local-bearer",
2574
2568
  assistantApiKey: "api-key-123",
2575
- platformAssistantId: "platform-assistant-1",
2576
- platformBaseUrl: "https://cloud.mycadet.ai",
2569
+ cloudAssistantId: "platform-assistant-1",
2570
+ cloudBaseUrl: "https://cloud.mycadet.ai",
2577
2571
  organizationId: "org-1",
2578
2572
  userId: "user-1",
2579
2573
  webhookSecret: "webhook-secret-123",
@@ -2581,9 +2575,9 @@ describe("platform credential injection", () => {
2581
2575
  expect(saveAssistantEntryMock).toHaveBeenCalledWith(
2582
2576
  expect.objectContaining({
2583
2577
  assistantId: "my-local",
2584
- platformAssistantId: "platform-assistant-1",
2585
- platformBaseUrl: "https://cloud.mycadet.ai",
2586
- platformOrganizationId: "org-1",
2578
+ cloudAssistantId: "platform-assistant-1",
2579
+ cloudBaseUrl: "https://cloud.mycadet.ai",
2580
+ cloudOrganizationId: "org-1",
2587
2581
  }),
2588
2582
  );
2589
2583
  } finally {
@@ -2639,12 +2633,9 @@ describe("auth + transient-error resilience", () => {
2639
2633
  }));
2640
2634
 
2641
2635
  // Ensure the refresh path returns a distinguishable token.
2642
- leaseGuardianTokenMock.mockResolvedValueOnce({
2643
- accessToken: "refreshed-token",
2644
- accessTokenExpiresAt: new Date(Date.now() + 60_000).toISOString(),
2645
- } as unknown as Awaited<
2646
- ReturnType<typeof guardianToken.leaseGuardianToken>
2647
- >);
2636
+ leaseGuardianTokenMock.mockResolvedValueOnce(
2637
+ makeGuardianTokenData({ accessToken: "refreshed-token" }),
2638
+ );
2648
2639
 
2649
2640
  const restoreFetch = installTrackingFetch();
2650
2641
  try {
@@ -2669,14 +2660,14 @@ describe("auth + transient-error resilience", () => {
2669
2660
  test("runtime 401 on import kickoff triggers token refresh and retry", async () => {
2670
2661
  setArgv("--from", "my-platform", "--local", "my-local");
2671
2662
 
2672
- const platformEntry = makeEntry("my-platform", {
2663
+ const cloudEntry = makeEntry("my-platform", {
2673
2664
  cloud: "cadet",
2674
2665
  runtimeUrl: "https://cloud.mycadet.ai",
2675
2666
  });
2676
2667
  const localEntry = makeEntry("my-local", { cloud: "local" });
2677
2668
 
2678
2669
  findAssistantByNameMock.mockImplementation((name: string) => {
2679
- if (name === "my-platform") return platformEntry;
2670
+ if (name === "my-platform") return cloudEntry;
2680
2671
  if (name === "my-local") return localEntry;
2681
2672
  return null;
2682
2673
  });
@@ -2697,12 +2688,9 @@ describe("auth + transient-error resilience", () => {
2697
2688
  jobId: "local-import-after-refresh",
2698
2689
  }));
2699
2690
 
2700
- leaseGuardianTokenMock.mockResolvedValueOnce({
2701
- accessToken: "refreshed-import-token",
2702
- accessTokenExpiresAt: new Date(Date.now() + 60_000).toISOString(),
2703
- } as unknown as Awaited<
2704
- ReturnType<typeof guardianToken.leaseGuardianToken>
2705
- >);
2691
+ leaseGuardianTokenMock.mockResolvedValueOnce(
2692
+ makeGuardianTokenData({ accessToken: "refreshed-import-token" }),
2693
+ );
2706
2694
 
2707
2695
  const restoreFetch = installTrackingFetch();
2708
2696
  try {
@@ -2770,12 +2758,9 @@ describe("auth + transient-error resilience", () => {
2770
2758
  },
2771
2759
  );
2772
2760
 
2773
- leaseGuardianTokenMock.mockResolvedValueOnce({
2774
- accessToken: "poll-refreshed-token",
2775
- accessTokenExpiresAt: new Date(Date.now() + 60_000).toISOString(),
2776
- } as unknown as Awaited<
2777
- ReturnType<typeof guardianToken.leaseGuardianToken>
2778
- >);
2761
+ leaseGuardianTokenMock.mockResolvedValueOnce(
2762
+ makeGuardianTokenData({ accessToken: "poll-refreshed-token" }),
2763
+ );
2779
2764
 
2780
2765
  const warnSpy = spyOn(console, "warn").mockImplementation(() => {});
2781
2766
  const restoreFetch = installTrackingFetch();
@@ -2836,7 +2821,7 @@ describe("auth + transient-error resilience", () => {
2836
2821
  await teleport();
2837
2822
  expect(pollCalls).toBeGreaterThanOrEqual(2);
2838
2823
  expect(warnSpy).toHaveBeenCalledWith(
2839
- expect.stringContaining("polling failed, retrying"),
2824
+ expect.stringContaining("polling failed:"),
2840
2825
  );
2841
2826
  } finally {
2842
2827
  restoreFetch();
@@ -2868,7 +2853,7 @@ describe("upload signed-URL records source runtime version (not CLI version)", (
2868
2853
  callOrder.push("identity");
2869
2854
  return { version: "0.5.9" };
2870
2855
  });
2871
- platformRequestSignedUrlMock.mockImplementationOnce(async (params) => {
2856
+ cloudRequestSignedUrlMock.mockImplementationOnce(async (params) => {
2872
2857
  callOrder.push("signed-url");
2873
2858
  return {
2874
2859
  url: "https://storage.googleapis.com/bucket/signed-upload",
@@ -2886,7 +2871,7 @@ describe("upload signed-URL records source runtime version (not CLI version)", (
2886
2871
 
2887
2872
  // Upload request stamps minRuntimeVersion with the daemon's version,
2888
2873
  // NOT cliPkg.version.
2889
- expect(platformRequestSignedUrlMock).toHaveBeenCalledWith(
2874
+ expect(cloudRequestSignedUrlMock).toHaveBeenCalledWith(
2890
2875
  expect.objectContaining({
2891
2876
  operation: "upload",
2892
2877
  minRuntimeVersion: "0.5.9",
@@ -2917,7 +2902,7 @@ describe("upload signed-URL records source runtime version (not CLI version)", (
2917
2902
  await expect(teleport()).rejects.toThrow("process.exit:1");
2918
2903
 
2919
2904
  // Must NOT have proceeded to signed URL or export.
2920
- expect(platformRequestSignedUrlMock).not.toHaveBeenCalled();
2905
+ expect(cloudRequestSignedUrlMock).not.toHaveBeenCalled();
2921
2906
  expect(localRuntimeExportToGcsMock).not.toHaveBeenCalled();
2922
2907
 
2923
2908
  expect(consoleErrorSpy).toHaveBeenCalledWith(
@@ -2931,14 +2916,14 @@ describe("upload signed-URL records source runtime version (not CLI version)", (
2931
2916
  test("platform source: managed runtime's identity is fetched and recorded", async () => {
2932
2917
  setArgv("--from", "my-platform", "--local", "my-local");
2933
2918
 
2934
- const platformEntry = makeEntry("my-platform", {
2919
+ const cloudEntry = makeEntry("my-platform", {
2935
2920
  cloud: "cadet",
2936
2921
  runtimeUrl: "https://cloud.mycadet.ai",
2937
2922
  });
2938
2923
  const localEntry = makeEntry("my-local", { cloud: "local" });
2939
2924
 
2940
2925
  findAssistantByNameMock.mockImplementation((name: string) => {
2941
- if (name === "my-platform") return platformEntry;
2926
+ if (name === "my-platform") return cloudEntry;
2942
2927
  if (name === "my-local") return localEntry;
2943
2928
  return null;
2944
2929
  });
@@ -2956,8 +2941,8 @@ describe("upload signed-URL records source runtime version (not CLI version)", (
2956
2941
  try {
2957
2942
  await teleport();
2958
2943
 
2959
- // Identity was fetched against the platform-managed runtime entry
2960
- // (cloud=cadet) with the platform token — not via guardian token.
2944
+ // Identity was fetched against the cloud-managed runtime entry
2945
+ // (cloud=cadet) with the cloud token — not via guardian token.
2961
2946
  expect(localRuntimeIdentityMock).toHaveBeenCalledWith(
2962
2947
  expect.objectContaining({
2963
2948
  cloud: "cadet",
@@ -2967,8 +2952,8 @@ describe("upload signed-URL records source runtime version (not CLI version)", (
2967
2952
  "platform-token",
2968
2953
  );
2969
2954
 
2970
- // The recorded version came from the platform runtime, not the CLI.
2971
- expect(platformRequestSignedUrlMock).toHaveBeenCalledWith(
2955
+ // The recorded version came from the cloud runtime, not the CLI.
2956
+ expect(cloudRequestSignedUrlMock).toHaveBeenCalledWith(
2972
2957
  expect.objectContaining({
2973
2958
  operation: "upload",
2974
2959
  minRuntimeVersion: "0.7.2",
@@ -2985,14 +2970,14 @@ describe("upload signed-URL records source runtime version (not CLI version)", (
2985
2970
  test("platform source: identity fetch failure aborts before signed-URL request", async () => {
2986
2971
  setArgv("--from", "my-platform", "--local", "my-local");
2987
2972
 
2988
- const platformEntry = makeEntry("my-platform", {
2973
+ const cloudEntry = makeEntry("my-platform", {
2989
2974
  cloud: "cadet",
2990
2975
  runtimeUrl: "https://cloud.mycadet.ai",
2991
2976
  });
2992
2977
  const localEntry = makeEntry("my-local", { cloud: "local" });
2993
2978
 
2994
2979
  findAssistantByNameMock.mockImplementation((name: string) => {
2995
- if (name === "my-platform") return platformEntry;
2980
+ if (name === "my-platform") return cloudEntry;
2996
2981
  if (name === "my-local") return localEntry;
2997
2982
  return null;
2998
2983
  });
@@ -3006,9 +2991,8 @@ describe("upload signed-URL records source runtime version (not CLI version)", (
3006
2991
  await expect(teleport()).rejects.toThrow("process.exit:1");
3007
2992
 
3008
2993
  // Signed-URL upload request must not have happened.
3009
- const uploadCalls = platformRequestSignedUrlMock.mock.calls.filter(
3010
- (call: unknown[]) =>
3011
- (call[0] as { operation: string }).operation === "upload",
2994
+ const uploadCalls = cloudRequestSignedUrlMock.mock.calls.filter(
2995
+ (call) => call[0].operation === "upload",
3012
2996
  );
3013
2997
  expect(uploadCalls.length).toBe(0);
3014
2998