@mycadet/cli 0.12.7 → 0.12.8

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 (165) 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-platform-login.ts → show-cloud-login.ts} +3 -5
  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 +1 -1
  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 +1 -1
  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 +1 -1
  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} +5 -5
  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__/guardian-token.test.ts +149 -56
  72. package/src/__tests__/hatch-provider-secrets.test.ts +2 -2
  73. package/src/__tests__/helpers/guardian-token.ts +22 -0
  74. package/src/__tests__/helpers/http.ts +10 -0
  75. package/src/__tests__/nginx-ingress.test.ts +18 -18
  76. package/src/__tests__/orphan-detection.test.ts +1 -1
  77. package/src/__tests__/pair.test.ts +1 -8
  78. package/src/__tests__/{ps-platform-status.test.ts → ps-cloud-status.test.ts} +79 -26
  79. package/src/__tests__/{recover.test.ts → restore.test.ts} +29 -28
  80. package/src/__tests__/retire.test.ts +58 -199
  81. package/src/__tests__/root-process-lockfile.test.ts +99 -0
  82. package/src/__tests__/sleep.test.ts +19 -19
  83. package/src/__tests__/statefulset.test.ts +8 -8
  84. package/src/__tests__/{tailscale-tunnel.test.ts → tailscale.test.ts} +1 -1
  85. package/src/__tests__/teleport-backup.test.ts +3 -3
  86. package/src/__tests__/teleport.test.ts +180 -196
  87. package/src/__tests__/tunnel.test.ts +255 -227
  88. package/src/__tests__/uninstall.test.ts +13 -4
  89. package/src/__tests__/upgrade-local.test.ts +3 -3
  90. package/src/__tests__/upgrade-replay-env.test.ts +12 -12
  91. package/src/__tests__/wake.test.ts +258 -41
  92. package/src/__tests__/workos-pkce.test.ts +2 -2
  93. package/src/commands/backup.ts +22 -22
  94. package/src/commands/client.ts +76 -76
  95. package/src/commands/debug.ts +20 -20
  96. package/src/commands/exec.ts +5 -5
  97. package/src/commands/hatch.ts +22 -22
  98. package/src/commands/login.ts +22 -22
  99. package/src/commands/logs.ts +1 -1
  100. package/src/commands/ps.ts +188 -79
  101. package/src/commands/restart.ts +30 -0
  102. package/src/commands/restore.ts +138 -20
  103. package/src/commands/retire.ts +46 -148
  104. package/src/commands/rollback.ts +18 -24
  105. package/src/commands/setup.ts +2 -2
  106. package/src/commands/teleport.ts +93 -93
  107. package/src/commands/terminal.ts +157 -17
  108. package/src/commands/tunnel.ts +80 -122
  109. package/src/commands/uninstall.ts +55 -7
  110. package/src/commands/unpair.ts +3 -3
  111. package/src/commands/upgrade.ts +22 -46
  112. package/src/commands/wake.ts +162 -46
  113. package/src/index.ts +3 -9
  114. package/src/lib/__tests__/{platform-client-signed-url.test.ts → cloud-client-signed-url.test.ts} +16 -16
  115. package/src/lib/__tests__/job-polling.test.ts +1 -1
  116. package/src/lib/__tests__/local-runtime-client.test.ts +4 -4
  117. package/src/lib/__tests__/runtime-url.test.ts +1 -1
  118. package/src/lib/assistant-api-key-resolution.ts +5 -5
  119. package/src/lib/assistant-client.ts +8 -8
  120. package/src/lib/assistant-config.ts +58 -12
  121. package/src/lib/{platform-client.ts → cloud-client.ts} +107 -98
  122. package/src/lib/cloud-login.ts +24 -24
  123. package/src/lib/{platform-releases.ts → cloud-releases.ts} +5 -5
  124. package/src/lib/cloud-values.ts +3 -0
  125. package/src/lib/config-utils.ts +1 -1
  126. package/src/lib/detached-process.ts +1 -1
  127. package/src/lib/docker.ts +111 -10
  128. package/src/lib/environments/__tests__/paths.test.ts +2 -2
  129. package/src/lib/environments/__tests__/resolve.test.ts +26 -26
  130. package/src/lib/environments/resolve.ts +8 -8
  131. package/src/lib/guardian-token.ts +36 -4
  132. package/src/lib/hatch-local.ts +19 -23
  133. package/src/lib/health-check.ts +6 -6
  134. package/src/lib/ingress-config.ts +8 -35
  135. package/src/lib/job-polling.ts +1 -1
  136. package/src/lib/live-voice/connection.ts +12 -12
  137. package/src/lib/live-voice/tunnel.test.ts +11 -11
  138. package/src/lib/live-voice/tunnel.ts +15 -15
  139. package/src/lib/local-runtime-client.ts +20 -20
  140. package/src/lib/local.ts +9 -30
  141. package/src/lib/nginx-ingress.ts +41 -14
  142. package/src/lib/process.ts +1 -1
  143. package/src/lib/provider-secrets.ts +3 -3
  144. package/src/lib/retire-apple-container.ts +1 -1
  145. package/src/lib/runtime-url.ts +8 -8
  146. package/src/lib/statefulset.ts +2 -2
  147. package/src/lib/sync-cloud-assistants.ts +18 -18
  148. package/src/lib/teleport-backup.ts +4 -4
  149. package/src/lib/terminal-client.ts +17 -17
  150. package/src/lib/terminal-session.ts +24 -24
  151. package/src/lib/{tunnel-edge.ts → tunnel.ts} +199 -11
  152. package/src/lib/tunnels/cadet.ts +29 -0
  153. package/src/lib/{cloudflare-tunnel.ts → tunnels/cloudflare.ts} +15 -4
  154. package/src/lib/tunnels/gateway-notify.ts +61 -0
  155. package/src/lib/{ngrok.ts → tunnels/ngrok.ts} +201 -30
  156. package/src/lib/{tailscale-tunnel.ts → tunnels/tailscale.ts} +19 -5
  157. package/src/lib/upgrade-lifecycle.ts +3 -17
  158. package/src/lib/upgrade-preflight.ts +2 -2
  159. package/src/lib/workos-pkce.ts +5 -5
  160. package/node_modules/@mycadet/assistant-api/events/platform-disconnected.ts +0 -21
  161. package/src/commands/recover.ts +0 -131
  162. package/src/commands/roadmap.ts +0 -459
  163. package/src/commands/ssh.ts +0 -144
  164. package/src/commands/workflows.ts +0 -305
  165. package/src/lib/managed-cloud.ts +0 -3
@@ -1,7 +1,7 @@
1
1
  import {
2
- type PlatformCredentialVerificationStatus,
2
+ type CloudCredentialVerificationStatus,
3
3
  PlatformVerifyCredentialResponseSchema,
4
- } from "@mycadet/service-contracts/platform-credential";
4
+ } from "@mycadet/service-contracts/cloud-credential";
5
5
  import {
6
6
  chmodSync,
7
7
  readFileSync,
@@ -18,7 +18,7 @@ import { getCurrentEnvironment } from "./environments/resolve.js";
18
18
  import { loopbackSafeFetch } from "./loopback-fetch.js";
19
19
  import { z } from "zod";
20
20
 
21
- const PlatformErrorDetailSchema = z.object({
21
+ const CloudErrorDetailSchema = z.object({
22
22
  detail: z.string().optional(),
23
23
  });
24
24
 
@@ -26,13 +26,18 @@ const InProgressResponseSchema = z.object({
26
26
  in_progress: z.boolean().optional(),
27
27
  });
28
28
 
29
- function getPlatformTokenPath(): string {
29
+ function getCloudTokenPath(): string {
30
+ return join(getConfigDir(getCurrentEnvironment()), "cloud-token");
31
+ }
32
+
33
+ /** The pre-rename token filename, read as a fallback for existing installs. */
34
+ function getLegacyCloudTokenPath(): string {
30
35
  return join(getConfigDir(getCurrentEnvironment()), "platform-token");
31
36
  }
32
37
 
33
38
  /**
34
- * Resolve the platform API base URL. Resolution order:
35
- * 1. `platformBaseUrl` persisted on the lockfile by
39
+ * Resolve the cloud API base URL. Resolution order:
40
+ * 1. `cloudBaseUrl` persisted on the lockfile by
36
41
  * {@link syncConfigToLockfile} when the active assistant was last
37
42
  * hatched/waked. This is the source of truth for "what URL does the
38
43
  * currently-active assistant target" — reading the workspace
@@ -40,17 +45,17 @@ function getPlatformTokenPath(): string {
40
45
  * non-production XDG layouts because the CLI process has no way to
41
46
  * know which instance to read from without first consulting the
42
47
  * lockfile anyway.
43
- * 2. `CADET_PLATFORM_URL` env var (explicit override, e.g. in CI).
48
+ * 2. `CADET_CLOUD_URL` env var (explicit override, e.g. in CI).
44
49
  * 3. The current environment's seed URL (e.g. `https://dev-cloud.mycadet.ai`
45
50
  * for `CADET_ENVIRONMENT=dev`, `https://cloud.mycadet.ai` for prod).
46
51
  * This makes the CLI environment-aware when no lockfile entry exists yet.
47
52
  */
48
- export function getPlatformUrl(): string {
53
+ export function getCloudUrl(): string {
49
54
  const lockfileUrl = getLockfilePlatformBaseUrl();
50
55
  return (
51
56
  lockfileUrl ||
52
- process.env.CADET_PLATFORM_URL?.trim() ||
53
- getCurrentEnvironment().platformUrl
57
+ process.env.CADET_CLOUD_URL?.trim() ||
58
+ getCurrentEnvironment().cloudUrl
54
59
  );
55
60
  }
56
61
 
@@ -67,19 +72,21 @@ export function getWebUrl(): string {
67
72
  return process.env.CADET_WEB_URL?.trim() || getCurrentEnvironment().webUrl;
68
73
  }
69
74
 
70
- export function readPlatformToken(): string | null {
75
+ export function readCloudToken(): string | null {
71
76
  for (const dir of getConfigDirs(getCurrentEnvironment())) {
72
- try {
73
- return readFileSync(join(dir, "platform-token"), "utf-8").trim();
74
- } catch {
75
- // Try the next compatible location.
77
+ for (const name of ["cloud-token", "platform-token"]) {
78
+ try {
79
+ return readFileSync(join(dir, name), "utf-8").trim();
80
+ } catch {
81
+ // Try the next compatible location, then the legacy name.
82
+ }
76
83
  }
77
84
  }
78
85
  return null;
79
86
  }
80
87
 
81
- export function savePlatformToken(token: string): void {
82
- const tokenPath = getPlatformTokenPath();
88
+ export function saveCloudToken(token: string): void {
89
+ const tokenPath = getCloudTokenPath();
83
90
  const dir = dirname(tokenPath);
84
91
  if (!existsSync(dir)) {
85
92
  mkdirSync(dir, { recursive: true, mode: 0o700 });
@@ -88,11 +95,13 @@ export function savePlatformToken(token: string): void {
88
95
  chmodSync(tokenPath, 0o600);
89
96
  }
90
97
 
91
- export function clearPlatformToken(): void {
92
- try {
93
- unlinkSync(getPlatformTokenPath());
94
- } catch {
95
- // already doesn't exist
98
+ export function clearCloudToken(): void {
99
+ for (const path of [getCloudTokenPath(), getLegacyCloudTokenPath()]) {
100
+ try {
101
+ unlinkSync(path);
102
+ } catch {
103
+ // already doesn't exist
104
+ }
96
105
  }
97
106
  }
98
107
 
@@ -131,20 +140,20 @@ const orgIdCache = new Map<string, { orgId: string; expiresAt: number }>();
131
140
  const ORG_ID_CACHE_TTL_MS = 60_000; // 60 seconds
132
141
 
133
142
  /**
134
- * Drop the cached org ID for a given (token, platformUrl) pair. Used by the
143
+ * Drop the cached org ID for a given (token, cloudUrl) pair. Used by the
135
144
  * one-shot 401-retry path: a 401 on a session-token request frequently means
136
145
  * the cached `Cadet-Organization-Id` header is stale (e.g. user switched
137
146
  * orgs in another tab). Clearing the entry forces the next `authHeaders`
138
- * call to refetch the org ID from the platform.
147
+ * call to refetch the org ID from the cloud.
139
148
  *
140
149
  * Exported so other modules (e.g. local-runtime-client) can implement the
141
150
  * same retry pattern without needing direct access to the cache map.
142
151
  */
143
152
  export function invalidateOrgIdCache(
144
153
  token: string,
145
- platformUrl?: string,
154
+ cloudUrl?: string,
146
155
  ): void {
147
- orgIdCache.delete(`${token}::${platformUrl ?? ""}`);
156
+ orgIdCache.delete(`${token}::${cloudUrl ?? ""}`);
148
157
  }
149
158
 
150
159
  /**
@@ -154,10 +163,10 @@ export function invalidateOrgIdCache(
154
163
  * - `Content-Type: application/json`
155
164
  * - The appropriate auth header (`Authorization: Bearer` for `vak_`
156
165
  * API keys, `X-Session-Token` for session tokens).
157
- * - `Cadet-Organization-Id` – fetched from the platform. Only
166
+ * - `Cadet-Organization-Id` – fetched from the cloud. Only
158
167
  * included for session-token callers; API keys are already org-scoped.
159
168
  *
160
- * The org ID is cached per (token, platformUrl) for 60 seconds to avoid
169
+ * The org ID is cached per (token, cloudUrl) for 60 seconds to avoid
161
170
  * redundant HTTP requests in tight polling loops.
162
171
  *
163
172
  * Auth errors (401 / 403) from the org-ID fetch are wrapped in a
@@ -169,7 +178,7 @@ export function invalidateOrgIdCache(
169
178
  */
170
179
  export async function authHeaders(
171
180
  token: string,
172
- platformUrl?: string,
181
+ cloudUrl?: string,
173
182
  ): Promise<Record<string, string>> {
174
183
  const base: Record<string, string> = {
175
184
  "Content-Type": "application/json",
@@ -181,14 +190,14 @@ export async function authHeaders(
181
190
  return base;
182
191
  }
183
192
 
184
- const cacheKey = `${token}::${platformUrl ?? ""}`;
193
+ const cacheKey = `${token}::${cloudUrl ?? ""}`;
185
194
  const cached = orgIdCache.get(cacheKey);
186
195
  if (cached && Date.now() < cached.expiresAt) {
187
196
  return { ...base, "Cadet-Organization-Id": cached.orgId };
188
197
  }
189
198
 
190
199
  try {
191
- const orgId = await fetchOrganizationId(token, platformUrl);
200
+ const orgId = await fetchOrganizationId(token, cloudUrl);
192
201
  orgIdCache.set(cacheKey, {
193
202
  orgId,
194
203
  expiresAt: Date.now() + ORG_ID_CACHE_TTL_MS,
@@ -300,7 +309,7 @@ const RawUnifiedJobStatusSchema = z.object({
300
309
 
301
310
  export interface HatchAssistantResult {
302
311
  assistant: HatchedAssistant;
303
- /** true when the platform returned an existing assistant (HTTP 200) */
312
+ /** true when the cloud returned an existing assistant (HTTP 200) */
304
313
  reusedExisting: boolean;
305
314
  }
306
315
 
@@ -320,7 +329,7 @@ export interface EnsureRegistrationResponse {
320
329
  }
321
330
 
322
331
  /**
323
- * Register (or re-confirm) a self-hosted local assistant with the platform.
332
+ * Register (or re-confirm) a self-hosted local assistant with the cloud.
324
333
  *
325
334
  * Calls `POST /v1/assistants/self-hosted-local/ensure-registration/`.
326
335
  * The endpoint is idempotent: the first call provisions an API key;
@@ -333,10 +342,10 @@ export async function ensureSelfHostedLocalRegistration(
333
342
  runtimeAssistantId: string,
334
343
  clientPlatform: string,
335
344
  assistantVersion?: string,
336
- platformUrl?: string,
345
+ cloudUrl?: string,
337
346
  publicBaseUrl?: string,
338
347
  ): Promise<EnsureRegistrationResponse> {
339
- const resolvedUrl = platformUrl || getPlatformUrl();
348
+ const resolvedUrl = cloudUrl || getCloudUrl();
340
349
  const body: Record<string, string> = {
341
350
  client_installation_id: clientInstallationId,
342
351
  runtime_assistant_id: runtimeAssistantId,
@@ -391,7 +400,7 @@ export interface ReprovisionApiKeyResponse {
391
400
  * Reprovision (rotate) the API key for a self-hosted local assistant.
392
401
  *
393
402
  * Calls `POST /v1/assistants/self-hosted-local/reprovision-api-key/`.
394
- * Returns a fresh API key. The platform keeps the previous key valid for a
403
+ * Returns a fresh API key. The cloud keeps the previous key valid for a
395
404
  * grace period rather than revoking it on the spot, so a rotation whose
396
405
  * replacement never gets stored leaves the assistant on a key that still
397
406
  * works until that window closes.
@@ -403,9 +412,9 @@ export async function reprovisionAssistantApiKey(
403
412
  runtimeAssistantId: string,
404
413
  clientPlatform: string,
405
414
  assistantVersion?: string,
406
- platformUrl?: string,
415
+ cloudUrl?: string,
407
416
  ): Promise<ReprovisionApiKeyResponse> {
408
- const resolvedUrl = platformUrl || getPlatformUrl();
417
+ const resolvedUrl = cloudUrl || getCloudUrl();
409
418
  const body: Record<string, string> = {
410
419
  client_installation_id: clientInstallationId,
411
420
  runtime_assistant_id: runtimeAssistantId,
@@ -455,20 +464,20 @@ export interface GatewayCredentialResult {
455
464
  }
456
465
 
457
466
  /**
458
- * Ask a running assistant to check its stored managed credential against the
467
+ * Ask a running assistant to check its stored cloud credential against the
459
468
  * platform, via the gateway-proxied `POST /v1/platform/verify-credential`.
460
469
  *
461
- * Returns `"rejected"` only when the platform settled that answer. Every other
470
+ * Returns `"rejected"` only when the cloud settled that answer. Every other
462
471
  * case, including a daemon too old to serve the route and any failure to reach
463
472
  * one, returns null: the answer decides whether a key is rotated, so an absent
464
473
  * answer must never read as a rejection.
465
474
  *
466
475
  * Never throws.
467
476
  */
468
- export async function verifyGatewayManagedCredential(
477
+ export async function verifyGatewayCloudCredential(
469
478
  gatewayUrl: string,
470
479
  bearerToken?: string,
471
- ): Promise<PlatformCredentialVerificationStatus | null> {
480
+ ): Promise<CloudCredentialVerificationStatus | null> {
472
481
  try {
473
482
  const headers: Record<string, string> = { Accept: "application/json" };
474
483
  if (bearerToken) {
@@ -506,7 +515,7 @@ export async function verifyGatewayManagedCredential(
506
515
  * Returns a result distinguishing "key not found" (`value: null,
507
516
  * unreachable: false`) from "gateway unreachable" (`value: null,
508
517
  * unreachable: true`). Callers should only reprovision when the gateway
509
- * is reachable: the platform keeps the outgoing key valid for a grace
518
+ * is reachable: the cloud keeps the outgoing key valid for a grace
510
519
  * period, so reprovisioning while the gateway is down does not break the
511
520
  * assistant immediately, but it starts a clock on a key the caller cannot
512
521
  * yet replace.
@@ -594,8 +603,8 @@ export interface CredentialInjectionParams {
594
603
  gatewayUrl: string;
595
604
  bearerToken?: string;
596
605
  assistantApiKey?: string | null;
597
- platformAssistantId: string;
598
- platformBaseUrl: string;
606
+ cloudAssistantId: string;
607
+ cloudBaseUrl: string;
599
608
  organizationId: string;
600
609
  userId?: string;
601
610
  webhookSecret?: string | null;
@@ -622,7 +631,7 @@ export async function injectCredentialsIntoAssistant(
622
631
  promises.push(inject("cadet:assistant_api_key", params.assistantApiKey));
623
632
  }
624
633
 
625
- promises.push(inject("cadet:platform_base_url", params.platformBaseUrl));
634
+ promises.push(inject("cadet:platform_base_url", params.cloudBaseUrl));
626
635
 
627
636
  if (params.webhookSecret) {
628
637
  promises.push(inject("cadet:webhook_secret", params.webhookSecret));
@@ -634,14 +643,14 @@ export async function injectCredentialsIntoAssistant(
634
643
 
635
644
  export async function hatchAssistant(
636
645
  token: string,
637
- platformUrl?: string,
646
+ cloudUrl?: string,
638
647
  ): Promise<HatchAssistantResult> {
639
- const resolvedUrl = platformUrl || getPlatformUrl();
648
+ const resolvedUrl = cloudUrl || getCloudUrl();
640
649
  const url = `${resolvedUrl}/v1/assistants/hatch/`;
641
650
 
642
651
  const response = await loopbackSafeFetch(url, {
643
652
  method: "POST",
644
- headers: await authHeaders(token, platformUrl),
653
+ headers: await authHeaders(token, cloudUrl),
645
654
  body: JSON.stringify({}),
646
655
  signal: AbortSignal.timeout(300_000),
647
656
  });
@@ -652,7 +661,7 @@ export async function hatchAssistant(
652
661
  }
653
662
 
654
663
  if (response.status === 401 || response.status === 403) {
655
- const detail = PlatformErrorDetailSchema
664
+ const detail = CloudErrorDetailSchema
656
665
  .catch({})
657
666
  .parse(await response.json().catch(() => ({})));
658
667
  throw new Error(
@@ -665,7 +674,7 @@ export async function hatchAssistant(
665
674
  throw new Error("Insufficient balance to hatch a new assistant.");
666
675
  }
667
676
 
668
- const errorBody = PlatformErrorDetailSchema
677
+ const errorBody = CloudErrorDetailSchema
669
678
  .catch({})
670
679
  .parse(await response.json().catch(() => ({})));
671
680
  throw new Error(
@@ -677,18 +686,18 @@ export async function hatchAssistant(
677
686
  const PLATFORM_FETCH_TIMEOUT_MS = 10_000;
678
687
 
679
688
  /**
680
- * Lightweight pre-check: returns the first active managed assistant for the
689
+ * Lightweight pre-check: returns the first active cloud assistant for the
681
690
  * authenticated user, or `null` if none exists. Calls `GET /v1/assistants/`
682
691
  * and looks for any assistant with status "active".
683
692
  *
684
693
  * Used by the teleport flow to block BEFORE the expensive GCS upload when
685
- * the user already has a platform assistant.
694
+ * the user already has a cloud assistant.
686
695
  */
687
- export async function checkExistingPlatformAssistant(
696
+ export async function checkExistingCloudAssistant(
688
697
  token: string,
689
- platformUrl?: string,
698
+ cloudUrl?: string,
690
699
  ): Promise<HatchedAssistant | null> {
691
- const resolvedUrl = platformUrl || getPlatformUrl();
700
+ const resolvedUrl = cloudUrl || getCloudUrl();
692
701
  const url = `${resolvedUrl}/v1/assistants/`;
693
702
 
694
703
  const controller = new AbortController();
@@ -700,7 +709,7 @@ export async function checkExistingPlatformAssistant(
700
709
  try {
701
710
  const response = await loopbackSafeFetch(url, {
702
711
  signal: controller.signal,
703
- headers: await authHeaders(token, platformUrl),
712
+ headers: await authHeaders(token, cloudUrl),
704
713
  });
705
714
 
706
715
  if (!response.ok) {
@@ -717,14 +726,14 @@ export async function checkExistingPlatformAssistant(
717
726
  }
718
727
 
719
728
  /**
720
- * Fetch all active assistants for the authenticated user from the platform.
729
+ * Fetch all active assistants for the authenticated user from the cloud.
721
730
  * Returns an empty array on failure (non-fatal).
722
731
  */
723
- export async function fetchPlatformAssistants(
732
+ export async function fetchCloudAssistants(
724
733
  token: string,
725
- platformUrl?: string,
734
+ cloudUrl?: string,
726
735
  ): Promise<HatchedAssistant[]> {
727
- const resolvedUrl = platformUrl || getPlatformUrl();
736
+ const resolvedUrl = cloudUrl || getCloudUrl();
728
737
  const url = `${resolvedUrl}/v1/assistants/`;
729
738
 
730
739
  const controller = new AbortController();
@@ -736,7 +745,7 @@ export async function fetchPlatformAssistants(
736
745
  try {
737
746
  const response = await loopbackSafeFetch(url, {
738
747
  signal: controller.signal,
739
- headers: await authHeaders(token, platformUrl),
748
+ headers: await authHeaders(token, cloudUrl),
740
749
  });
741
750
 
742
751
  if (!response.ok) return [];
@@ -750,7 +759,7 @@ export async function fetchPlatformAssistants(
750
759
  }
751
760
  }
752
761
 
753
- export interface PlatformAssistantDetail {
762
+ export interface CloudAssistantDetail {
754
763
  currentReleaseVersion: string | null;
755
764
  releaseChannel: "stable" | "preview";
756
765
  }
@@ -763,15 +772,15 @@ export interface PlatformAssistantDetail {
763
772
  export async function fetchAssistantDetail(
764
773
  token: string,
765
774
  assistantId: string,
766
- platformUrl?: string,
767
- ): Promise<PlatformAssistantDetail | null> {
768
- const resolvedUrl = platformUrl || getPlatformUrl();
775
+ cloudUrl?: string,
776
+ ): Promise<CloudAssistantDetail | null> {
777
+ const resolvedUrl = cloudUrl || getCloudUrl();
769
778
  const url = `${resolvedUrl}/v1/assistants/${encodeURIComponent(assistantId)}/`;
770
779
 
771
780
  try {
772
781
  const response = await loopbackSafeFetch(url, {
773
782
  signal: AbortSignal.timeout(PLATFORM_FETCH_TIMEOUT_MS),
774
- headers: await authHeaders(token, platformUrl),
783
+ headers: await authHeaders(token, cloudUrl),
775
784
  });
776
785
 
777
786
  if (!response.ok) return null;
@@ -790,7 +799,7 @@ export async function fetchAssistantDetail(
790
799
  }
791
800
 
792
801
  /**
793
- * Check whether the platform reports an upgrade in progress for the
802
+ * Check whether the cloud reports an upgrade in progress for the
794
803
  * assistant via `GET /v1/assistants/{id}/upgrade-status/`. Returns null
795
804
  * when the endpoint is unavailable (404 on older platforms, network
796
805
  * error) so callers can skip the check. Never throws.
@@ -798,15 +807,15 @@ export async function fetchAssistantDetail(
798
807
  export async function fetchUpgradeInProgress(
799
808
  token: string,
800
809
  assistantId: string,
801
- platformUrl?: string,
810
+ cloudUrl?: string,
802
811
  ): Promise<boolean | null> {
803
- const resolvedUrl = platformUrl || getPlatformUrl();
812
+ const resolvedUrl = cloudUrl || getCloudUrl();
804
813
  const url = `${resolvedUrl}/v1/assistants/${encodeURIComponent(assistantId)}/upgrade-status/`;
805
814
 
806
815
  try {
807
816
  const response = await loopbackSafeFetch(url, {
808
817
  signal: AbortSignal.timeout(PLATFORM_FETCH_TIMEOUT_MS),
809
- headers: await authHeaders(token, platformUrl),
818
+ headers: await authHeaders(token, cloudUrl),
810
819
  });
811
820
 
812
821
  if (!response.ok) return null;
@@ -828,9 +837,9 @@ export interface PlatformUser {
828
837
 
829
838
  export async function fetchOrganizationId(
830
839
  token: string,
831
- platformUrl?: string,
840
+ cloudUrl?: string,
832
841
  ): Promise<string> {
833
- const resolvedUrl = platformUrl || getPlatformUrl();
842
+ const resolvedUrl = cloudUrl || getCloudUrl();
834
843
  const url = `${resolvedUrl}/v1/organizations/`;
835
844
 
836
845
  const controller = new AbortController();
@@ -866,9 +875,9 @@ export async function fetchOrganizationId(
866
875
 
867
876
  export async function fetchCurrentUser(
868
877
  token: string,
869
- platformUrl?: string,
878
+ cloudUrl?: string,
870
879
  ): Promise<PlatformUser> {
871
- const resolvedUrl = platformUrl || getPlatformUrl();
880
+ const resolvedUrl = cloudUrl || getCloudUrl();
872
881
  const url = `${resolvedUrl}/_allauth/app/v1/auth/session`;
873
882
 
874
883
  const controller = new AbortController();
@@ -907,18 +916,18 @@ export async function fetchCurrentUser(
907
916
  // Rollback
908
917
  // ---------------------------------------------------------------------------
909
918
 
910
- export async function rollbackPlatformAssistant(
919
+ export async function rollbackCloudAssistant(
911
920
  token: string,
912
921
  assistantId: string,
913
922
  version?: string,
914
- platformUrl?: string,
923
+ cloudUrl?: string,
915
924
  ): Promise<{ detail: string; version: string | null }> {
916
- const resolvedUrl = platformUrl || getPlatformUrl();
925
+ const resolvedUrl = cloudUrl || getCloudUrl();
917
926
  const response = await loopbackSafeFetch(
918
927
  `${resolvedUrl}/v1/assistants/${encodeURIComponent(assistantId)}/rollback/`,
919
928
  {
920
929
  method: "POST",
921
- headers: await authHeaders(token, platformUrl),
930
+ headers: await authHeaders(token, cloudUrl),
922
931
  body: JSON.stringify(version ? { version } : {}),
923
932
  },
924
933
  );
@@ -973,14 +982,14 @@ export async function platformUploadToSignedUrl(
973
982
  export async function platformImportPreflightFromGcs(
974
983
  bundleKey: string,
975
984
  token: string,
976
- platformUrl?: string,
985
+ cloudUrl?: string,
977
986
  ): Promise<{ statusCode: number; body: Record<string, unknown> }> {
978
- const resolvedUrl = platformUrl || getPlatformUrl();
987
+ const resolvedUrl = cloudUrl || getCloudUrl();
979
988
  const response = await loopbackSafeFetch(
980
989
  `${resolvedUrl}/v1/migrations/import-preflight-from-gcs/`,
981
990
  {
982
991
  method: "POST",
983
- headers: await authHeaders(token, platformUrl),
992
+ headers: await authHeaders(token, cloudUrl),
984
993
  signal: AbortSignal.timeout(120_000),
985
994
  body: JSON.stringify({ bundle_key: bundleKey }),
986
995
  },
@@ -995,14 +1004,14 @@ export async function platformImportPreflightFromGcs(
995
1004
  export async function platformImportBundleFromGcs(
996
1005
  bundleKey: string,
997
1006
  token: string,
998
- platformUrl?: string,
1007
+ cloudUrl?: string,
999
1008
  ): Promise<{ statusCode: number; body: Record<string, unknown> }> {
1000
- const resolvedUrl = platformUrl || getPlatformUrl();
1009
+ const resolvedUrl = cloudUrl || getCloudUrl();
1001
1010
  const response = await loopbackSafeFetch(
1002
1011
  `${resolvedUrl}/v1/migrations/import-from-gcs/`,
1003
1012
  {
1004
1013
  method: "POST",
1005
- headers: await authHeaders(token, platformUrl),
1014
+ headers: await authHeaders(token, cloudUrl),
1006
1015
  body: JSON.stringify({ bundle_key: bundleKey }),
1007
1016
  signal: AbortSignal.timeout(60_000),
1008
1017
  },
@@ -1024,7 +1033,7 @@ export async function platformImportBundleFromGcs(
1024
1033
 
1025
1034
  /**
1026
1035
  * Discriminated union representing the unified migration job status shape
1027
- * returned by `GET /v1/migrations/jobs/{job_id}/` on both the platform and
1036
+ * returned by `GET /v1/migrations/jobs/{job_id}/` on both the cloud and
1028
1037
  * the local runtime.
1029
1038
  */
1030
1039
  export type UnifiedJobStatus =
@@ -1090,7 +1099,7 @@ export interface BundleCompatibility {
1090
1099
  }
1091
1100
 
1092
1101
  /**
1093
- * Thrown by platformRequestSignedUrl when the platform rejects a download
1102
+ * Thrown by cloudRequestSignedUrl when the cloud rejects a download
1094
1103
  * signed-URL request because the target runtime version is outside the
1095
1104
  * ExportJob's [min_runtime_version, max_runtime_version] band. Terminal
1096
1105
  * — callers must NOT retry; surface to the user and abort the
@@ -1124,7 +1133,7 @@ export class VersionMismatchError extends Error {
1124
1133
  }
1125
1134
 
1126
1135
  /**
1127
- * Request a signed URL from the platform for either uploading a new bundle
1136
+ * Request a signed URL from the cloud for either uploading a new bundle
1128
1137
  * or downloading an existing one. Calls `POST /v1/migrations/signed-url/`.
1129
1138
  *
1130
1139
  * - `operation: "upload"` (optionally with `contentType` / `contentLength`)
@@ -1138,7 +1147,7 @@ export class VersionMismatchError extends Error {
1138
1147
  * Throws {@link VersionMismatchError} on a 422 `version_mismatch` response,
1139
1148
  * which is terminal — callers must NOT retry.
1140
1149
  */
1141
- export async function platformRequestSignedUrl(
1150
+ export async function cloudRequestSignedUrl(
1142
1151
  params: {
1143
1152
  operation: "upload" | "download";
1144
1153
  bundleKey?: string;
@@ -1150,21 +1159,21 @@ export async function platformRequestSignedUrl(
1150
1159
  // Target-side, download only: runtime version that will import.
1151
1160
  targetRuntimeVersion?: string;
1152
1161
  // Upload only: who will PUT to the URL. "runtime" signs against the
1153
- // runtime-reachable storage endpoint so a managed assistant pod can
1162
+ // runtime-reachable storage endpoint so a cloud assistant pod can
1154
1163
  // upload its export bundle (platform→local teleport); defaults to
1155
1164
  // "client" server-side. No effect in production, where both endpoints
1156
1165
  // are the same.
1157
1166
  consumer?: "client" | "runtime";
1158
1167
  },
1159
1168
  token: string,
1160
- platformUrl?: string,
1169
+ cloudUrl?: string,
1161
1170
  ): Promise<{
1162
1171
  url: string;
1163
1172
  bundleKey: string;
1164
1173
  expiresAt: string;
1165
1174
  maxContentLength?: number;
1166
1175
  }> {
1167
- const resolvedUrl = platformUrl || getPlatformUrl();
1176
+ const resolvedUrl = cloudUrl || getCloudUrl();
1168
1177
  const body: Record<string, unknown> = { operation: params.operation };
1169
1178
  if (params.bundleKey !== undefined) body.bundle_key = params.bundleKey;
1170
1179
  if (params.contentType !== undefined) body.content_type = params.contentType;
@@ -1189,7 +1198,7 @@ export async function platformRequestSignedUrl(
1189
1198
  const doRequest = async (): Promise<Response> =>
1190
1199
  loopbackSafeFetch(`${resolvedUrl}/v1/migrations/signed-url/`, {
1191
1200
  method: "POST",
1192
- headers: await authHeaders(token, platformUrl),
1201
+ headers: await authHeaders(token, cloudUrl),
1193
1202
  body: JSON.stringify(body),
1194
1203
  });
1195
1204
 
@@ -1200,7 +1209,7 @@ export async function platformRequestSignedUrl(
1200
1209
  // lookup. For session-token callers, a 401 frequently means the
1201
1210
  // cached org ID is stale — calling doRequest() again without clearing
1202
1211
  // the cache would just send the same stale header and fail again.
1203
- invalidateOrgIdCache(token, platformUrl);
1212
+ invalidateOrgIdCache(token, cloudUrl);
1204
1213
  response = await doRequest();
1205
1214
  }
1206
1215
 
@@ -1240,19 +1249,19 @@ export async function platformRequestSignedUrl(
1240
1249
  }
1241
1250
 
1242
1251
  /**
1243
- * Poll the unified job-status endpoint on the platform. Calls
1252
+ * Poll the unified job-status endpoint on the cloud. Calls
1244
1253
  * `GET /v1/migrations/jobs/{jobId}/` and parses into {@link UnifiedJobStatus}.
1245
1254
  */
1246
1255
  export async function platformPollJobStatus(
1247
1256
  jobId: string,
1248
1257
  token: string,
1249
- platformUrl?: string,
1258
+ cloudUrl?: string,
1250
1259
  ): Promise<UnifiedJobStatus> {
1251
- const resolvedUrl = platformUrl || getPlatformUrl();
1260
+ const resolvedUrl = cloudUrl || getCloudUrl();
1252
1261
  const response = await loopbackSafeFetch(
1253
1262
  `${resolvedUrl}/v1/migrations/jobs/${jobId}/`,
1254
1263
  {
1255
- headers: await authHeaders(token, platformUrl),
1264
+ headers: await authHeaders(token, cloudUrl),
1256
1265
  },
1257
1266
  );
1258
1267