@mycadet/cli 0.12.7 → 0.12.9-dev.202610131452.9acab64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/knip.json +1 -1
- package/node_modules/@mycadet/assistant-api/events/cloud-disconnected.ts +21 -0
- package/node_modules/@mycadet/assistant-api/events/host-bash.ts +1 -1
- package/node_modules/@mycadet/assistant-api/events/host-cu.ts +1 -1
- package/node_modules/@mycadet/assistant-api/events/host-file.ts +1 -1
- package/node_modules/@mycadet/assistant-api/events/notification-intent.ts +1 -1
- package/node_modules/@mycadet/assistant-api/events/show-cloud-login.ts +18 -0
- package/node_modules/@mycadet/assistant-api/index.ts +11 -11
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/package.json +2 -2
- package/node_modules/@mycadet/{service-contracts/src/platform-credential.ts → assistant-api/node_modules/@mycadet/service-contracts/src/cloud-credential.ts} +9 -9
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
- package/node_modules/@mycadet/assistant-api/responses/home.ts +1 -1
- package/node_modules/@mycadet/assistant-api/surfaces.ts +4 -4
- package/node_modules/@mycadet/avatar-manifest/src/__tests__/notification-avatar.test.ts +1 -1
- package/node_modules/@mycadet/avatar-manifest/src/notification-avatar.ts +2 -2
- package/node_modules/@mycadet/environments/src/seeds.ts +6 -6
- package/node_modules/@mycadet/environments/src/shell.test.ts +1 -1
- package/node_modules/@mycadet/environments/src/types.ts +6 -6
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/avatar-manifest/src/__tests__/notification-avatar.test.ts +1 -1
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/avatar-manifest/src/notification-avatar.ts +2 -2
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/environments/src/seeds.ts +6 -6
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/environments/src/shell.test.ts +1 -1
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/environments/src/types.ts +6 -6
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/package.json +2 -2
- 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
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
- package/node_modules/@mycadet/local-mode/src/__tests__/pair.test.ts +5 -5
- package/node_modules/@mycadet/local-mode/src/__tests__/retire.test.ts +1 -1
- package/node_modules/@mycadet/local-mode/src/config.ts +2 -2
- package/node_modules/@mycadet/local-mode/src/index.ts +1 -1
- package/node_modules/@mycadet/local-mode/src/lockfile-contract.test.ts +3 -3
- package/node_modules/@mycadet/local-mode/src/lockfile-contract.ts +10 -5
- package/node_modules/@mycadet/local-mode/src/lockfile.test.ts +15 -15
- package/node_modules/@mycadet/local-mode/src/lockfile.ts +9 -9
- package/node_modules/@mycadet/local-mode/src/pair.ts +2 -2
- package/node_modules/@mycadet/local-mode/src/retire.ts +3 -3
- package/node_modules/@mycadet/local-mode/src/teleport-backup-policy.ts +2 -2
- package/node_modules/@mycadet/local-mode/src/unpair.ts +2 -2
- package/node_modules/@mycadet/service-contracts/package.json +2 -2
- package/node_modules/@mycadet/{local-mode/node_modules/@mycadet/service-contracts/src/platform-credential.ts → service-contracts/src/cloud-credential.ts} +9 -9
- package/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
- package/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
- package/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
- package/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
- package/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
- package/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
- package/package.json +6 -4
- package/src/__tests__/assistant-api-key-resolution.test.ts +6 -6
- package/src/__tests__/{assistant-client-platform-auth.test.ts → assistant-client-cloud-auth.test.ts} +10 -10
- package/src/__tests__/assistant-client-refresh.test.ts +2 -2
- package/src/__tests__/backup.test.ts +86 -91
- package/src/__tests__/client-token.test.ts +1 -1
- package/src/__tests__/client-tui-refresh.test.ts +1 -1
- package/src/__tests__/client-web-config.test.ts +1 -2
- package/src/__tests__/{platform-client.test.ts → cloud-client.test.ts} +59 -59
- package/src/__tests__/{platform-releases.test.ts → cloud-releases.test.ts} +28 -18
- package/src/__tests__/{cloudflare-tunnel.test.ts → cloudflare.test.ts} +1 -1
- package/src/__tests__/connect-import.test.ts +55 -39
- package/src/__tests__/debug.test.ts +38 -38
- package/src/__tests__/ensure-binary.test.ts +182 -0
- package/src/__tests__/guardian-token.test.ts +149 -56
- package/src/__tests__/hatch-provider-secrets.test.ts +2 -2
- package/src/__tests__/helpers/guardian-token.ts +22 -0
- package/src/__tests__/helpers/http.ts +10 -0
- package/src/__tests__/nginx-ingress.test.ts +15 -20
- package/src/__tests__/ngrok-spawn.test.ts +49 -0
- package/src/__tests__/orphan-detection.test.ts +1 -1
- package/src/__tests__/pair.test.ts +149 -85
- package/src/__tests__/{ps-platform-status.test.ts → ps-cloud-status.test.ts} +80 -26
- package/src/__tests__/ps-table.test.ts +79 -0
- package/src/__tests__/{recover.test.ts → restore.test.ts} +29 -28
- package/src/__tests__/retire.test.ts +58 -199
- package/src/__tests__/root-process-lockfile.test.ts +99 -0
- package/src/__tests__/sleep.test.ts +19 -19
- package/src/__tests__/statefulset.test.ts +8 -8
- package/src/__tests__/{tailscale-tunnel.test.ts → tailscale.test.ts} +2 -2
- package/src/__tests__/teleport-backup.test.ts +3 -3
- package/src/__tests__/teleport.test.ts +180 -211
- package/src/__tests__/tunnel.test.ts +490 -270
- package/src/__tests__/uninstall.test.ts +150 -9
- package/src/__tests__/upgrade-local.test.ts +3 -3
- package/src/__tests__/upgrade-replay-env.test.ts +12 -12
- package/src/__tests__/wake.test.ts +260 -43
- package/src/__tests__/workos-pkce.test.ts +2 -2
- package/src/commands/backup.ts +24 -24
- package/src/commands/client.ts +76 -78
- package/src/commands/completions.test.ts +104 -0
- package/src/commands/completions.ts +87 -0
- package/src/commands/debug.ts +20 -20
- package/src/commands/exec.ts +12 -12
- package/src/commands/flags.ts +2 -2
- package/src/commands/hatch.ts +27 -24
- package/src/commands/login.ts +22 -22
- package/src/commands/logs.ts +8 -8
- package/src/commands/pair.ts +140 -37
- package/src/commands/ps.ts +232 -86
- package/src/commands/restart.ts +30 -0
- package/src/commands/restore.ts +140 -22
- package/src/commands/retire.ts +48 -150
- package/src/commands/rollback.ts +20 -26
- package/src/commands/setup.ts +2 -2
- package/src/commands/sleep.ts +2 -2
- package/src/commands/teleport.ts +110 -129
- package/src/commands/terminal.ts +158 -18
- package/src/commands/tunnel.ts +156 -175
- package/src/commands/uninstall.ts +137 -54
- package/src/commands/unpair.ts +3 -3
- package/src/commands/upgrade.ts +30 -54
- package/src/commands/use.ts +1 -1
- package/src/commands/wake.ts +166 -50
- package/src/index.ts +18 -9
- package/src/lib/__tests__/{platform-client-signed-url.test.ts → cloud-client-signed-url.test.ts} +16 -16
- package/src/lib/__tests__/docker.test.ts +168 -20
- package/src/lib/__tests__/job-polling.test.ts +2 -2
- package/src/lib/__tests__/local-gateway-cli.test.ts +42 -0
- package/src/lib/__tests__/local-runtime-client.test.ts +4 -4
- package/src/lib/__tests__/runtime-url.test.ts +1 -1
- package/src/lib/assistant-api-key-resolution.ts +5 -5
- package/src/lib/assistant-client.ts +8 -8
- package/src/lib/assistant-config.ts +58 -12
- package/src/lib/{platform-client.ts → cloud-client.ts} +105 -99
- package/src/lib/cloud-login.ts +23 -24
- package/src/lib/{platform-releases.ts → cloud-releases.ts} +11 -9
- package/src/lib/cloud-values.ts +3 -0
- package/src/lib/color.ts +4 -0
- package/src/lib/config-utils.ts +1 -1
- package/src/lib/detached-process.ts +1 -1
- package/src/lib/docker.ts +300 -111
- package/src/lib/ensure-binary.ts +171 -0
- package/src/lib/environments/__tests__/paths.test.ts +29 -3
- package/src/lib/environments/__tests__/resolve.test.ts +26 -26
- package/src/lib/environments/paths.ts +16 -8
- package/src/lib/environments/resolve.ts +10 -12
- package/src/lib/flag-args.test.ts +1 -1
- package/src/lib/flag-args.ts +1 -1
- package/src/lib/guardian-token.ts +37 -5
- package/src/lib/hatch-local.ts +32 -29
- package/src/lib/hatch-next-steps.ts +5 -9
- package/src/lib/health-check.ts +6 -6
- package/src/lib/ingress-config.ts +8 -35
- package/src/lib/job-polling.ts +2 -2
- package/src/lib/live-voice/connection.ts +12 -12
- package/src/lib/live-voice/tunnel.test.ts +11 -11
- package/src/lib/live-voice/tunnel.ts +15 -15
- package/src/lib/local-runtime-client.ts +20 -20
- package/src/lib/local.ts +46 -34
- package/src/lib/nginx-ingress.ts +40 -15
- package/src/lib/pair.ts +1 -1
- package/src/lib/process.ts +1 -1
- package/src/lib/provider-secrets.ts +3 -3
- package/src/lib/retire-apple-container.ts +1 -1
- package/src/lib/runtime-url.ts +8 -8
- package/src/lib/statefulset.ts +2 -2
- package/src/lib/step-runner.ts +6 -1
- package/src/lib/sync-cloud-assistants.ts +19 -19
- package/src/lib/teleport-backup.ts +4 -4
- package/src/lib/terminal-client.ts +17 -17
- package/src/lib/terminal-session.ts +24 -24
- package/src/lib/{tunnel-edge.ts → tunnel.ts} +199 -11
- package/src/lib/tunnels/cadet.ts +29 -0
- package/src/lib/{cloudflare-tunnel.ts → tunnels/cloudflare.ts} +36 -15
- package/src/lib/tunnels/gateway-notify.ts +61 -0
- package/src/lib/{ngrok.ts → tunnels/ngrok.ts} +350 -89
- package/src/lib/{tailscale-tunnel.ts → tunnels/tailscale.ts} +53 -9
- package/src/lib/upgrade-lifecycle.ts +8 -21
- package/src/lib/upgrade-preflight.ts +2 -2
- package/src/lib/workos-pkce.ts +5 -5
- package/node_modules/@mycadet/assistant-api/events/platform-disconnected.ts +0 -21
- package/node_modules/@mycadet/assistant-api/events/show-platform-login.ts +0 -20
- package/src/commands/recover.ts +0 -131
- package/src/commands/roadmap.ts +0 -459
- package/src/commands/ssh.ts +0 -144
- package/src/commands/workflows.ts +0 -305
- package/src/lib/managed-cloud.ts +0 -3
package/src/commands/teleport.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isCloudHome } from "../lib/cloud-values.js";
|
|
2
2
|
import { resolveAssistantApiKeyForInjection } from "../lib/assistant-api-key-resolution";
|
|
3
3
|
import {
|
|
4
4
|
findAssistantByName,
|
|
@@ -15,20 +15,20 @@ import {
|
|
|
15
15
|
computeDeviceId,
|
|
16
16
|
} from "../lib/guardian-token.js";
|
|
17
17
|
import {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
readCloudToken,
|
|
19
|
+
getCloudUrl,
|
|
20
20
|
hatchAssistant,
|
|
21
|
-
|
|
21
|
+
checkExistingCloudAssistant,
|
|
22
22
|
platformPollJobStatus,
|
|
23
23
|
platformImportBundleFromGcs,
|
|
24
24
|
platformImportPreflightFromGcs,
|
|
25
|
-
|
|
25
|
+
cloudRequestSignedUrl,
|
|
26
26
|
VersionMismatchError,
|
|
27
27
|
ensureSelfHostedLocalRegistration,
|
|
28
28
|
injectCredentialsIntoAssistant,
|
|
29
29
|
fetchCurrentUser,
|
|
30
30
|
fetchOrganizationId,
|
|
31
|
-
} from "../lib/
|
|
31
|
+
} from "../lib/cloud-client.js";
|
|
32
32
|
import {
|
|
33
33
|
localRuntimeExportToGcs,
|
|
34
34
|
localRuntimeIdentity,
|
|
@@ -100,7 +100,7 @@ function printHelp(): void {
|
|
|
100
100
|
console.log(
|
|
101
101
|
"The source and target must be different environments. Same-environment",
|
|
102
102
|
);
|
|
103
|
-
console.log("transfers
|
|
103
|
+
console.log("transfers such as local to local are not supported.");
|
|
104
104
|
console.log("");
|
|
105
105
|
console.log(
|
|
106
106
|
"Before exporting, the source assistant is backed up. Platform sources",
|
|
@@ -159,7 +159,7 @@ function printHelp(): void {
|
|
|
159
159
|
" Import data from my-local into existing docker assistant my-docker",
|
|
160
160
|
);
|
|
161
161
|
console.log(
|
|
162
|
-
"
|
|
162
|
+
" or hatch a new docker assistant named my-docker if it doesn't exist",
|
|
163
163
|
);
|
|
164
164
|
console.log("");
|
|
165
165
|
console.log(" cadet teleport --from my-local --platform");
|
|
@@ -185,7 +185,6 @@ function printHelp(): void {
|
|
|
185
185
|
|
|
186
186
|
export function parseArgs(argv: string[]): {
|
|
187
187
|
from: string | undefined;
|
|
188
|
-
to: string | undefined;
|
|
189
188
|
targetEnv: "local" | "docker" | "platform" | undefined;
|
|
190
189
|
targetName: string | undefined;
|
|
191
190
|
keepSource: boolean;
|
|
@@ -193,7 +192,6 @@ export function parseArgs(argv: string[]): {
|
|
|
193
192
|
help: boolean;
|
|
194
193
|
} {
|
|
195
194
|
let from: string | undefined;
|
|
196
|
-
let to: string | undefined;
|
|
197
195
|
let targetEnv: "local" | "docker" | "platform" | undefined;
|
|
198
196
|
let targetName: string | undefined;
|
|
199
197
|
let keepSource = false;
|
|
@@ -209,11 +207,6 @@ export function parseArgs(argv: string[]): {
|
|
|
209
207
|
continue;
|
|
210
208
|
}
|
|
211
209
|
from = argv[++i];
|
|
212
|
-
} else if (arg === "--to" && i + 1 < argv.length) {
|
|
213
|
-
if (argv[i + 1].startsWith("--")) {
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
to = argv[++i];
|
|
217
210
|
} else if (
|
|
218
211
|
arg === "--local" ||
|
|
219
212
|
arg === "--docker" ||
|
|
@@ -242,7 +235,7 @@ export function parseArgs(argv: string[]): {
|
|
|
242
235
|
process.exit(1);
|
|
243
236
|
}
|
|
244
237
|
|
|
245
|
-
return { from,
|
|
238
|
+
return { from, targetEnv, targetName, keepSource, dryRun, help };
|
|
246
239
|
}
|
|
247
240
|
|
|
248
241
|
// ---------------------------------------------------------------------------
|
|
@@ -387,7 +380,7 @@ interface ImportResponse {
|
|
|
387
380
|
succeeded: number;
|
|
388
381
|
failed: number;
|
|
389
382
|
failedAccounts: string[];
|
|
390
|
-
|
|
383
|
+
skippedCloud?: number;
|
|
391
384
|
};
|
|
392
385
|
}
|
|
393
386
|
|
|
@@ -415,20 +408,20 @@ async function backupSourceBeforeTeleport(
|
|
|
415
408
|
cloud: string,
|
|
416
409
|
displayName: string,
|
|
417
410
|
): Promise<void> {
|
|
418
|
-
console.log(`Backing up ${displayName}
|
|
411
|
+
console.log(`Backing up ${displayName} on ${cloud}...`);
|
|
419
412
|
try {
|
|
420
|
-
if (
|
|
421
|
-
const
|
|
422
|
-
if (!
|
|
413
|
+
if (isCloudHome(cloud)) {
|
|
414
|
+
const cloudToken = readCloudToken();
|
|
415
|
+
if (!cloudToken) {
|
|
423
416
|
console.error("Not logged in. Run 'cadet login' first.");
|
|
424
417
|
process.exit(1);
|
|
425
418
|
}
|
|
426
|
-
const createdAts = await listPlatformBackups(entry,
|
|
419
|
+
const createdAts = await listPlatformBackups(entry, cloudToken);
|
|
427
420
|
if (hasRecentBackup(createdAts)) {
|
|
428
421
|
console.log("Recent backup found, reusing it.");
|
|
429
422
|
return;
|
|
430
423
|
}
|
|
431
|
-
await createPlatformBackup(entry,
|
|
424
|
+
await createPlatformBackup(entry, cloudToken);
|
|
432
425
|
console.log("Backup complete.");
|
|
433
426
|
return;
|
|
434
427
|
}
|
|
@@ -443,7 +436,7 @@ async function backupSourceBeforeTeleport(
|
|
|
443
436
|
timeoutMs: LOCAL_SOURCE_BACKUP_TIMEOUT_MS,
|
|
444
437
|
});
|
|
445
438
|
if (!backupPath) {
|
|
446
|
-
throw new Error("backup export failed
|
|
439
|
+
throw new Error("backup export failed — see the warning above");
|
|
447
440
|
}
|
|
448
441
|
pruneOldBackups(entry.assistantId, 3, "pre-teleport");
|
|
449
442
|
console.log(`Backup saved: ${backupPath}`);
|
|
@@ -465,12 +458,12 @@ async function backupSourceBeforeTeleport(
|
|
|
465
458
|
async function exportFromAssistant(
|
|
466
459
|
entry: AssistantEntry,
|
|
467
460
|
cloud: string,
|
|
468
|
-
|
|
461
|
+
bundleCloudUrl?: string,
|
|
469
462
|
): Promise<{ bundleKey: string }> {
|
|
470
|
-
const
|
|
471
|
-
if (!
|
|
463
|
+
const cloudToken = readCloudToken();
|
|
464
|
+
if (!cloudToken) {
|
|
472
465
|
console.error(
|
|
473
|
-
"Not logged in. Run 'cadet login' first
|
|
466
|
+
"Not logged in. Run 'cadet login' first.",
|
|
474
467
|
);
|
|
475
468
|
process.exit(1);
|
|
476
469
|
}
|
|
@@ -497,7 +490,7 @@ async function exportFromAssistant(
|
|
|
497
490
|
process.exit(1);
|
|
498
491
|
}
|
|
499
492
|
|
|
500
|
-
// Request a signed upload URL from the
|
|
493
|
+
// Request a signed upload URL from the cloud instance that will
|
|
501
494
|
// eventually own the bundle (i.e. the one the importer will read from).
|
|
502
495
|
// Passing the target's runtime URL here keeps upload and download on
|
|
503
496
|
// the same platform — otherwise a non-default/stale platform URL would
|
|
@@ -508,15 +501,15 @@ async function exportFromAssistant(
|
|
|
508
501
|
// is reachable; a docker daemon runs inside a container and reaches the
|
|
509
502
|
// host the same way managed pods do, so its URL must be signed for the
|
|
510
503
|
// runtime-reachable storage endpoint.
|
|
511
|
-
const { url: uploadUrl, bundleKey } = await
|
|
504
|
+
const { url: uploadUrl, bundleKey } = await cloudRequestSignedUrl(
|
|
512
505
|
{
|
|
513
506
|
operation: "upload",
|
|
514
507
|
minRuntimeVersion: sourceRuntimeVersion,
|
|
515
508
|
maxRuntimeVersion: null,
|
|
516
509
|
...(cloud === "docker" ? { consumer: "runtime" as const } : {}),
|
|
517
510
|
},
|
|
518
|
-
|
|
519
|
-
|
|
511
|
+
cloudToken,
|
|
512
|
+
bundleCloudUrl,
|
|
520
513
|
);
|
|
521
514
|
|
|
522
515
|
// Wrap the kickoff in a one-shot refresh-and-retry helper so a stale-but-
|
|
@@ -579,16 +572,16 @@ async function exportFromAssistant(
|
|
|
579
572
|
return { bundleKey };
|
|
580
573
|
}
|
|
581
574
|
|
|
582
|
-
if (
|
|
583
|
-
// Ask the
|
|
575
|
+
if (isCloudHome(cloud)) {
|
|
576
|
+
// Ask the cloud runtime which version it's running so the signed-URL
|
|
584
577
|
// request records the bundle's actual `min_runtime_version`. The
|
|
585
|
-
//
|
|
578
|
+
// cloud-managed runtime is the exporter; the CLI version is
|
|
586
579
|
// unrelated. Routed via the wildcard proxy with platform-token auth
|
|
587
580
|
// (resolveRuntimeUrl + migrationRequestHeaders inside
|
|
588
581
|
// localRuntimeIdentity).
|
|
589
582
|
let sourceRuntimeVersion: string;
|
|
590
583
|
try {
|
|
591
|
-
const identity = await localRuntimeIdentity(entry,
|
|
584
|
+
const identity = await localRuntimeIdentity(entry, cloudToken);
|
|
592
585
|
sourceRuntimeVersion = identity.version;
|
|
593
586
|
} catch (err) {
|
|
594
587
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -601,26 +594,26 @@ async function exportFromAssistant(
|
|
|
601
594
|
// Platform source — request a signed upload URL on the same platform
|
|
602
595
|
// instance the bundle will eventually be imported from, then ask the
|
|
603
596
|
// managed runtime to export directly to GCS. The runtime endpoint is
|
|
604
|
-
// reached via the
|
|
597
|
+
// reached via the cloud's wildcard runtime proxy at
|
|
605
598
|
// `/v1/assistants/<id>/migrations/export-to-gcs` — the
|
|
606
599
|
// `localRuntimeExportToGcs` helper uses `resolveRuntimeMigrationUrl` to
|
|
607
|
-
// pick that shape for `
|
|
600
|
+
// pick that shape for `isCloudHome(cloud)` and `migrationRequestHeaders`
|
|
608
601
|
// to send platform-token auth (no guardian-token bootstrap).
|
|
609
|
-
const { url: uploadUrl, bundleKey } = await
|
|
602
|
+
const { url: uploadUrl, bundleKey } = await cloudRequestSignedUrl(
|
|
610
603
|
{
|
|
611
604
|
operation: "upload",
|
|
612
605
|
minRuntimeVersion: sourceRuntimeVersion,
|
|
613
606
|
maxRuntimeVersion: null,
|
|
614
|
-
// The
|
|
607
|
+
// The cloud pod PUTs the bundle, not this CLI — the URL must be
|
|
615
608
|
// signed against the runtime-reachable storage endpoint.
|
|
616
609
|
consumer: "runtime",
|
|
617
610
|
},
|
|
618
|
-
|
|
619
|
-
|
|
611
|
+
cloudToken,
|
|
612
|
+
bundleCloudUrl,
|
|
620
613
|
);
|
|
621
614
|
|
|
622
615
|
let jobId: string;
|
|
623
|
-
let exportPlatformToken =
|
|
616
|
+
let exportPlatformToken = cloudToken;
|
|
624
617
|
try {
|
|
625
618
|
({ jobId } = await localRuntimeExportToGcs(entry, exportPlatformToken, {
|
|
626
619
|
uploadUrl,
|
|
@@ -639,18 +632,18 @@ async function exportFromAssistant(
|
|
|
639
632
|
console.log(`Export started (job ${jobId})...`);
|
|
640
633
|
|
|
641
634
|
// Polling also goes through the wildcard proxy — `localRuntimePollJobStatus`
|
|
642
|
-
// builds `/v1/assistants/<id>/migrations/jobs/<jobId>` for `
|
|
635
|
+
// builds `/v1/assistants/<id>/migrations/jobs/<jobId>` for `isCloudHome(cloud)`
|
|
643
636
|
// (the dedicated `/v1/migrations/jobs/{id}/` endpoint queries platform-side
|
|
644
637
|
// ImportJob records and 404s on runtime-created job IDs).
|
|
645
638
|
const terminal = await pollJobUntilDone({
|
|
646
639
|
label: "platform export",
|
|
647
640
|
poll: () => localRuntimePollJobStatus(entry, exportPlatformToken, jobId),
|
|
648
|
-
// The
|
|
641
|
+
// The cloud token is normally static per-process, but re-reading the
|
|
649
642
|
// on-disk credential covers the case where the user ran `cadet login`
|
|
650
643
|
// in another terminal during a long migration. A persistent 401 after
|
|
651
644
|
// a re-read surfaces to the caller with a clear next step.
|
|
652
645
|
refreshOn401: async () => {
|
|
653
|
-
const refreshed =
|
|
646
|
+
const refreshed = readCloudToken();
|
|
654
647
|
if (!refreshed) {
|
|
655
648
|
throw new Error(
|
|
656
649
|
"Platform auth expired during export and no credential was found on disk. Run 'cadet login' and retry.",
|
|
@@ -683,17 +676,17 @@ async function importToAssistant(
|
|
|
683
676
|
cloud: string,
|
|
684
677
|
bundleKey: string,
|
|
685
678
|
dryRun: boolean,
|
|
686
|
-
|
|
679
|
+
bundleCloudUrl?: string,
|
|
687
680
|
): Promise<void> {
|
|
688
|
-
const
|
|
689
|
-
if (!
|
|
681
|
+
const cloudToken = readCloudToken();
|
|
682
|
+
if (!cloudToken) {
|
|
690
683
|
console.error(
|
|
691
|
-
"Not logged in. Run 'cadet login' first
|
|
684
|
+
"Not logged in. Run 'cadet login' first.",
|
|
692
685
|
);
|
|
693
686
|
process.exit(1);
|
|
694
687
|
}
|
|
695
688
|
|
|
696
|
-
if (
|
|
689
|
+
if (isCloudHome(cloud)) {
|
|
697
690
|
// Platform target — the bundle is already in GCS; kick off preflight or
|
|
698
691
|
// async import via the unified job-status endpoint.
|
|
699
692
|
if (dryRun) {
|
|
@@ -701,7 +694,7 @@ async function importToAssistant(
|
|
|
701
694
|
|
|
702
695
|
const preflight = await platformImportPreflightFromGcs(
|
|
703
696
|
bundleKey,
|
|
704
|
-
|
|
697
|
+
cloudToken,
|
|
705
698
|
entry.runtimeUrl,
|
|
706
699
|
);
|
|
707
700
|
|
|
@@ -742,7 +735,7 @@ async function importToAssistant(
|
|
|
742
735
|
|
|
743
736
|
const importResult = await platformImportBundleFromGcs(
|
|
744
737
|
bundleKey,
|
|
745
|
-
|
|
738
|
+
cloudToken,
|
|
746
739
|
entry.runtimeUrl,
|
|
747
740
|
);
|
|
748
741
|
|
|
@@ -781,13 +774,13 @@ async function importToAssistant(
|
|
|
781
774
|
process.exit(1);
|
|
782
775
|
}
|
|
783
776
|
|
|
784
|
-
let importPlatformToken =
|
|
777
|
+
let importPlatformToken = cloudToken;
|
|
785
778
|
const terminal = await pollJobUntilDone({
|
|
786
779
|
label: "platform import",
|
|
787
780
|
poll: () =>
|
|
788
781
|
platformPollJobStatus(jobId, importPlatformToken, entry.runtimeUrl),
|
|
789
782
|
refreshOn401: async () => {
|
|
790
|
-
const refreshed =
|
|
783
|
+
const refreshed = readCloudToken();
|
|
791
784
|
if (!refreshed) {
|
|
792
785
|
throw new Error(
|
|
793
786
|
"Platform auth expired during import and no credential was found on disk. Run 'cadet login' and retry.",
|
|
@@ -815,7 +808,7 @@ async function importToAssistant(
|
|
|
815
808
|
console.log("Running preflight analysis...\n");
|
|
816
809
|
|
|
817
810
|
// Query the target runtime's version before requesting a signed
|
|
818
|
-
// download URL — the
|
|
811
|
+
// download URL — the cloud uses it for the bundle compatibility check.
|
|
819
812
|
let targetRuntimeVersion: string;
|
|
820
813
|
try {
|
|
821
814
|
const identity = await callRuntimeWithAuthRetry(entry, (token) =>
|
|
@@ -833,10 +826,10 @@ async function importToAssistant(
|
|
|
833
826
|
|
|
834
827
|
let bundleUrl: string;
|
|
835
828
|
try {
|
|
836
|
-
const result = await
|
|
829
|
+
const result = await cloudRequestSignedUrl(
|
|
837
830
|
{ operation: "download", bundleKey, targetRuntimeVersion },
|
|
838
|
-
|
|
839
|
-
|
|
831
|
+
cloudToken,
|
|
832
|
+
bundleCloudUrl,
|
|
840
833
|
);
|
|
841
834
|
bundleUrl = result.url;
|
|
842
835
|
} catch (err) {
|
|
@@ -854,13 +847,13 @@ async function importToAssistant(
|
|
|
854
847
|
return;
|
|
855
848
|
}
|
|
856
849
|
|
|
857
|
-
// Ask the
|
|
850
|
+
// Ask the cloud for a signed download URL and hand it to the local
|
|
858
851
|
// runtime. The runtime streams the bundle straight out of GCS — the CLI
|
|
859
852
|
// never touches the bytes. The URL must target the same platform the
|
|
860
853
|
// bundle was uploaded to; otherwise the object won't exist on this
|
|
861
854
|
// platform's GCS bucket.
|
|
862
855
|
//
|
|
863
|
-
// The
|
|
856
|
+
// The cloud's vbundle version gate compares the **target runtime's**
|
|
864
857
|
// version against the bundle's compatibility range. The CLI and the
|
|
865
858
|
// target assistant's daemon can diverge (assistants upgrade
|
|
866
859
|
// independently), so we MUST query the target runtime's `/v1/identity`
|
|
@@ -887,14 +880,14 @@ async function importToAssistant(
|
|
|
887
880
|
|
|
888
881
|
let bundleUrl: string;
|
|
889
882
|
try {
|
|
890
|
-
const result = await
|
|
883
|
+
const result = await cloudRequestSignedUrl(
|
|
891
884
|
{
|
|
892
885
|
operation: "download",
|
|
893
886
|
bundleKey,
|
|
894
887
|
targetRuntimeVersion,
|
|
895
888
|
},
|
|
896
|
-
|
|
897
|
-
|
|
889
|
+
cloudToken,
|
|
890
|
+
bundleCloudUrl,
|
|
898
891
|
);
|
|
899
892
|
bundleUrl = result.url;
|
|
900
893
|
} catch (err) {
|
|
@@ -990,7 +983,7 @@ export async function resolveOrHatchTarget(
|
|
|
990
983
|
);
|
|
991
984
|
process.exit(1);
|
|
992
985
|
}
|
|
993
|
-
console.log(`Target: ${targetName}
|
|
986
|
+
console.log(`Target: ${targetName} — ${targetEnv}`);
|
|
994
987
|
return existing;
|
|
995
988
|
}
|
|
996
989
|
|
|
@@ -1053,7 +1046,7 @@ export async function resolveOrHatchTarget(
|
|
|
1053
1046
|
}
|
|
1054
1047
|
|
|
1055
1048
|
if (targetEnv === "platform") {
|
|
1056
|
-
const token =
|
|
1049
|
+
const token = readCloudToken();
|
|
1057
1050
|
if (!token) {
|
|
1058
1051
|
console.error("Not logged in. Run 'cadet login' first.");
|
|
1059
1052
|
process.exit(1);
|
|
@@ -1067,13 +1060,13 @@ export async function resolveOrHatchTarget(
|
|
|
1067
1060
|
if (reusedExisting) {
|
|
1068
1061
|
const entry: AssistantEntry = {
|
|
1069
1062
|
assistantId: result.id,
|
|
1070
|
-
runtimeUrl:
|
|
1063
|
+
runtimeUrl: getCloudUrl(),
|
|
1071
1064
|
cloud: "cloud",
|
|
1072
1065
|
hatchedAt: new Date().toISOString(),
|
|
1073
1066
|
};
|
|
1074
1067
|
saveAssistantEntry(entry);
|
|
1075
1068
|
console.error(
|
|
1076
|
-
`Error: You already have a
|
|
1069
|
+
`Error: You already have a cloud assistant '${result.id}'.`,
|
|
1077
1070
|
);
|
|
1078
1071
|
console.error(
|
|
1079
1072
|
`Retire it first with 'cadet retire ${result.id}', then retry the teleport.`,
|
|
@@ -1083,7 +1076,7 @@ export async function resolveOrHatchTarget(
|
|
|
1083
1076
|
|
|
1084
1077
|
const entry: AssistantEntry = {
|
|
1085
1078
|
assistantId: result.id,
|
|
1086
|
-
runtimeUrl:
|
|
1079
|
+
runtimeUrl: getCloudUrl(),
|
|
1087
1080
|
cloud: "cloud",
|
|
1088
1081
|
hatchedAt: new Date().toISOString(),
|
|
1089
1082
|
};
|
|
@@ -1173,8 +1166,8 @@ function printImportSummary(result: ImportResponse): void {
|
|
|
1173
1166
|
const creds = result.credentialsImported;
|
|
1174
1167
|
if (creds) {
|
|
1175
1168
|
console.log(` Credentials imported: ${creds.succeeded}/${creds.total}`);
|
|
1176
|
-
if (creds.
|
|
1177
|
-
console.log(` Cadet Cloud credentials skipped: ${creds.
|
|
1169
|
+
if (creds.skippedCloud) {
|
|
1170
|
+
console.log(` Cadet Cloud credentials skipped: ${creds.skippedCloud}`);
|
|
1178
1171
|
}
|
|
1179
1172
|
if (creds.failed > 0) {
|
|
1180
1173
|
console.log(` Credentials failed: ${creds.failed}`);
|
|
@@ -1196,15 +1189,15 @@ function printImportSummary(result: ImportResponse): void {
|
|
|
1196
1189
|
|
|
1197
1190
|
/**
|
|
1198
1191
|
* After teleporting to a local/docker target, register the assistant with
|
|
1199
|
-
* the
|
|
1192
|
+
* the cloud and inject fresh cloud credentials — mirroring the
|
|
1200
1193
|
* login flow. Non-fatal: failures are logged as warnings.
|
|
1201
1194
|
*/
|
|
1202
|
-
async function
|
|
1195
|
+
async function tryInjectCloudCredentials(
|
|
1203
1196
|
entry: AssistantEntry,
|
|
1204
1197
|
): Promise<void> {
|
|
1205
|
-
const token =
|
|
1198
|
+
const token = readCloudToken();
|
|
1206
1199
|
if (!token) {
|
|
1207
|
-
console.log(" Skipped cloud credential injection
|
|
1200
|
+
console.log(" Skipped cloud credential injection — not logged in.");
|
|
1208
1201
|
return;
|
|
1209
1202
|
}
|
|
1210
1203
|
|
|
@@ -1216,7 +1209,7 @@ async function tryInjectPlatformCredentials(
|
|
|
1216
1209
|
fetchCurrentVersion(entry.runtimeUrl),
|
|
1217
1210
|
fetchAssistantIngressUrl(entry.runtimeUrl, entry.bearerToken),
|
|
1218
1211
|
]);
|
|
1219
|
-
const
|
|
1212
|
+
const cloudUrl = getCloudUrl();
|
|
1220
1213
|
const registration = await ensureSelfHostedLocalRegistration(
|
|
1221
1214
|
token,
|
|
1222
1215
|
orgId,
|
|
@@ -1224,14 +1217,14 @@ async function tryInjectPlatformCredentials(
|
|
|
1224
1217
|
entry.assistantId,
|
|
1225
1218
|
"cli",
|
|
1226
1219
|
assistantVersion,
|
|
1227
|
-
|
|
1220
|
+
cloudUrl,
|
|
1228
1221
|
ingressUrl,
|
|
1229
1222
|
);
|
|
1230
1223
|
saveAssistantEntry({
|
|
1231
1224
|
...entry,
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1225
|
+
cloudAssistantId: registration.assistant.id,
|
|
1226
|
+
cloudBaseUrl: cloudUrl,
|
|
1227
|
+
cloudOrganizationId: orgId,
|
|
1235
1228
|
});
|
|
1236
1229
|
|
|
1237
1230
|
// Which key to hand the assistant, and why. Shared with login so the two
|
|
@@ -1252,8 +1245,7 @@ async function tryInjectPlatformCredentials(
|
|
|
1252
1245
|
gatewayUrl: entry.runtimeUrl,
|
|
1253
1246
|
bearerToken: entry.bearerToken,
|
|
1254
1247
|
assistantApiKey,
|
|
1255
|
-
|
|
1256
|
-
platformBaseUrl: platformUrl,
|
|
1248
|
+
cloudAssistantId: registration.assistant.id,
|
|
1257
1249
|
organizationId: orgId,
|
|
1258
1250
|
userId: user.id,
|
|
1259
1251
|
webhookSecret: registration.webhook_secret,
|
|
@@ -1277,7 +1269,7 @@ async function tryInjectPlatformCredentials(
|
|
|
1277
1269
|
export const teleport = Object.assign(
|
|
1278
1270
|
async function teleport(): Promise<void> {
|
|
1279
1271
|
const args = process.argv.slice(3);
|
|
1280
|
-
const { from,
|
|
1272
|
+
const { from, targetEnv, targetName, keepSource, dryRun, help } =
|
|
1281
1273
|
parseArgs(args);
|
|
1282
1274
|
|
|
1283
1275
|
if (help) {
|
|
@@ -1285,17 +1277,6 @@ export const teleport = Object.assign(
|
|
|
1285
1277
|
process.exit(0);
|
|
1286
1278
|
}
|
|
1287
1279
|
|
|
1288
|
-
// Legacy --to flag deprecation
|
|
1289
|
-
if (to) {
|
|
1290
|
-
console.error("Error: --to is deprecated. Use environment flags instead:");
|
|
1291
|
-
console.error(
|
|
1292
|
-
" cadet teleport --from <source> --local|--docker|--platform [name]",
|
|
1293
|
-
);
|
|
1294
|
-
console.error("");
|
|
1295
|
-
console.error("Run 'cadet teleport --help' for details.");
|
|
1296
|
-
process.exit(1);
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
1280
|
if (!from) {
|
|
1300
1281
|
printHelp();
|
|
1301
1282
|
process.exit(1);
|
|
@@ -1360,7 +1341,7 @@ export const teleport = Object.assign(
|
|
|
1360
1341
|
// Nothing to reject — preflight-from-gcs is now implemented for all
|
|
1361
1342
|
// target topologies including local and docker.
|
|
1362
1343
|
|
|
1363
|
-
// Version guard: block platform→non-
|
|
1344
|
+
// Version guard: block platform→non-cloud when target is behind
|
|
1364
1345
|
if (fromCloud === "cadet" && toCloud !== "cadet") {
|
|
1365
1346
|
const [sourceVersion, targetVersion] = await Promise.all([
|
|
1366
1347
|
fetchCurrentVersion(fromEntry.runtimeUrl),
|
|
@@ -1373,7 +1354,7 @@ export const teleport = Object.assign(
|
|
|
1373
1354
|
if (cmp !== null && cmp < 0) {
|
|
1374
1355
|
console.error(
|
|
1375
1356
|
`Error: Target assistant '${existingTarget.assistantId}' is running ${targetVersion}, ` +
|
|
1376
|
-
`but the
|
|
1357
|
+
`but the cloud source is on ${sourceVersion}.`,
|
|
1377
1358
|
);
|
|
1378
1359
|
console.error(
|
|
1379
1360
|
`Upgrade your ${toCloud} assistant first: cadet upgrade ${existingTarget.assistantId}`,
|
|
@@ -1386,31 +1367,31 @@ export const teleport = Object.assign(
|
|
|
1386
1367
|
// platform targets the bundle is owned by the target platform; for
|
|
1387
1368
|
// platform sources it's owned by the source platform. Only one of
|
|
1388
1369
|
// these branches applies at a time (same-env was rejected earlier).
|
|
1389
|
-
const
|
|
1370
|
+
const bundleCloudUrl =
|
|
1390
1371
|
toCloud === "cadet"
|
|
1391
1372
|
? existingTarget.runtimeUrl
|
|
1392
1373
|
: fromCloud === "cadet"
|
|
1393
1374
|
? fromEntry.runtimeUrl
|
|
1394
1375
|
: undefined;
|
|
1395
1376
|
|
|
1396
|
-
console.log(`Exporting from ${from}
|
|
1377
|
+
console.log(`Exporting from ${from} on ${fromCloud}...`);
|
|
1397
1378
|
const { bundleKey } = await exportFromAssistant(
|
|
1398
1379
|
fromEntry,
|
|
1399
1380
|
fromCloud,
|
|
1400
|
-
|
|
1381
|
+
bundleCloudUrl,
|
|
1401
1382
|
);
|
|
1402
|
-
console.log(`Importing to ${existingTarget.assistantId}
|
|
1383
|
+
console.log(`Importing to ${existingTarget.assistantId} on ${toCloud}...`);
|
|
1403
1384
|
await importToAssistant(
|
|
1404
1385
|
existingTarget,
|
|
1405
1386
|
toCloud,
|
|
1406
1387
|
bundleKey,
|
|
1407
1388
|
true,
|
|
1408
|
-
|
|
1389
|
+
bundleCloudUrl,
|
|
1409
1390
|
);
|
|
1410
1391
|
} else {
|
|
1411
1392
|
// No existing target — just describe what would happen
|
|
1412
1393
|
console.log("Dry run summary:");
|
|
1413
|
-
console.log(` Would export data from: ${from}
|
|
1394
|
+
console.log(` Would export data from: ${from} on ${fromCloud}`);
|
|
1414
1395
|
console.log(` Would upload bundle via signed URL`);
|
|
1415
1396
|
console.log(
|
|
1416
1397
|
` Would hatch a new ${targetEnv} assistant${targetName ? ` named '${targetName}'` : ""}`,
|
|
@@ -1423,9 +1404,9 @@ export const teleport = Object.assign(
|
|
|
1423
1404
|
}
|
|
1424
1405
|
|
|
1425
1406
|
// Platform target: reordered flow — upload to GCS before hatching so that
|
|
1426
|
-
// if export/upload fails, no empty assistant is left dangling on the
|
|
1407
|
+
// if export/upload fails, no empty assistant is left dangling on the cloud.
|
|
1427
1408
|
if (targetEnv === "platform") {
|
|
1428
|
-
const token =
|
|
1409
|
+
const token = readCloudToken();
|
|
1429
1410
|
if (!token) {
|
|
1430
1411
|
console.error("Not logged in. Run 'cadet login' first.");
|
|
1431
1412
|
process.exit(1);
|
|
@@ -1447,24 +1428,24 @@ export const teleport = Object.assign(
|
|
|
1447
1428
|
|
|
1448
1429
|
// Use the existing target's runtimeUrl for all platform calls so the
|
|
1449
1430
|
// export, upload, and import all hit the same instance.
|
|
1450
|
-
const
|
|
1431
|
+
const targetCloudUrl = existingTarget?.runtimeUrl;
|
|
1451
1432
|
|
|
1452
|
-
// Pre-check: block if the user already has a
|
|
1433
|
+
// Pre-check: block if the user already has a cloud assistant. This
|
|
1453
1434
|
// runs BEFORE the expensive export so we don't waste the upload.
|
|
1454
1435
|
if (!existingTarget) {
|
|
1455
|
-
const existing = await
|
|
1436
|
+
const existing = await checkExistingCloudAssistant(
|
|
1456
1437
|
token,
|
|
1457
|
-
|
|
1438
|
+
targetCloudUrl,
|
|
1458
1439
|
);
|
|
1459
1440
|
if (existing) {
|
|
1460
1441
|
saveAssistantEntry({
|
|
1461
1442
|
assistantId: existing.id,
|
|
1462
|
-
runtimeUrl:
|
|
1443
|
+
runtimeUrl: getCloudUrl(),
|
|
1463
1444
|
cloud: "cloud",
|
|
1464
1445
|
hatchedAt: new Date().toISOString(),
|
|
1465
1446
|
});
|
|
1466
1447
|
console.error(
|
|
1467
|
-
`Error: You already have a
|
|
1448
|
+
`Error: You already have a cloud assistant '${existing.id}'.`,
|
|
1468
1449
|
);
|
|
1469
1450
|
console.error(
|
|
1470
1451
|
`Retire it first with 'cadet retire ${existing.id}', then retry the teleport.`,
|
|
@@ -1474,20 +1455,20 @@ export const teleport = Object.assign(
|
|
|
1474
1455
|
}
|
|
1475
1456
|
|
|
1476
1457
|
// Export — for local/docker sources this uploads straight into GCS via
|
|
1477
|
-
// the
|
|
1458
|
+
// the cloud's signed URL; for platform sources this runs a server-side
|
|
1478
1459
|
// export and we read the resulting bundle_key.
|
|
1479
1460
|
// The signed upload URL must be requested from the same platform instance
|
|
1480
1461
|
// where the import will run. For existing targets that's the lockfile's
|
|
1481
|
-
// runtimeUrl; for fresh hatches it's
|
|
1462
|
+
// runtimeUrl; for fresh hatches it's getCloudUrl() (which is what
|
|
1482
1463
|
// resolveOrHatchTarget writes to the new entry).
|
|
1483
1464
|
await backupSourceBeforeTeleport(fromEntry, fromCloud, from);
|
|
1484
1465
|
|
|
1485
|
-
console.log(`Exporting from ${from}
|
|
1486
|
-
const
|
|
1466
|
+
console.log(`Exporting from ${from} on ${fromCloud}...`);
|
|
1467
|
+
const bundleCloudUrl = targetCloudUrl ?? getCloudUrl();
|
|
1487
1468
|
const { bundleKey } = await exportFromAssistant(
|
|
1488
1469
|
fromEntry,
|
|
1489
1470
|
fromCloud,
|
|
1490
|
-
|
|
1471
|
+
bundleCloudUrl,
|
|
1491
1472
|
);
|
|
1492
1473
|
|
|
1493
1474
|
// Hatch (export succeeded — safe to create the target)
|
|
@@ -1495,20 +1476,20 @@ export const teleport = Object.assign(
|
|
|
1495
1476
|
const toCloud = toEntry.cloud;
|
|
1496
1477
|
|
|
1497
1478
|
// Import from GCS
|
|
1498
|
-
console.log(`Importing to ${toEntry.assistantId}
|
|
1479
|
+
console.log(`Importing to ${toEntry.assistantId} on ${toCloud}...`);
|
|
1499
1480
|
await importToAssistant(
|
|
1500
1481
|
toEntry,
|
|
1501
1482
|
toCloud,
|
|
1502
1483
|
bundleKey,
|
|
1503
1484
|
false,
|
|
1504
|
-
|
|
1485
|
+
bundleCloudUrl,
|
|
1505
1486
|
);
|
|
1506
1487
|
|
|
1507
1488
|
console.log(`Teleport complete: ${from} → ${toEntry.assistantId}`);
|
|
1508
1489
|
return;
|
|
1509
1490
|
}
|
|
1510
1491
|
|
|
1511
|
-
// Non-
|
|
1492
|
+
// Non-cloud targets (local/docker)
|
|
1512
1493
|
// For local<->docker transfers, stop (sleep) the source to free up ports
|
|
1513
1494
|
// before hatching the target. We do NOT retire yet — if hatch or import
|
|
1514
1495
|
// fails, the user can recover by running `cadet wake <source>`.
|
|
@@ -1532,7 +1513,7 @@ export const teleport = Object.assign(
|
|
|
1532
1513
|
if (cmp !== null && cmp < 0) {
|
|
1533
1514
|
console.error(
|
|
1534
1515
|
`Error: Target assistant '${existingTarget.assistantId}' is running ${existingVersion}, ` +
|
|
1535
|
-
`but the
|
|
1516
|
+
`but the cloud source is on ${sourceVersion}.`,
|
|
1536
1517
|
);
|
|
1537
1518
|
console.error(
|
|
1538
1519
|
`Upgrade your ${targetEnv} assistant first: cadet upgrade ${existingTarget.assistantId}`,
|
|
@@ -1547,19 +1528,19 @@ export const teleport = Object.assign(
|
|
|
1547
1528
|
// Pin the bundle's platform instance so upload and download land on the
|
|
1548
1529
|
// same GCS bucket. For platform sources the bundle is owned by the source
|
|
1549
1530
|
// platform. For local/docker→local/docker the bundle lives on whatever
|
|
1550
|
-
// platform
|
|
1531
|
+
// platform getCloudUrl() currently resolves to — we resolve it once
|
|
1551
1532
|
// here so a lockfile change mid-teleport can't split export and import.
|
|
1552
|
-
const
|
|
1553
|
-
fromCloud === "cadet" ? fromEntry.runtimeUrl :
|
|
1533
|
+
const bundleCloudUrl =
|
|
1534
|
+
fromCloud === "cadet" ? fromEntry.runtimeUrl : getCloudUrl();
|
|
1554
1535
|
|
|
1555
1536
|
await backupSourceBeforeTeleport(fromEntry, fromCloud, from);
|
|
1556
1537
|
|
|
1557
1538
|
// Export from source (bundle lives in GCS after this returns).
|
|
1558
|
-
console.log(`Exporting from ${from}
|
|
1539
|
+
console.log(`Exporting from ${from} on ${fromCloud}...`);
|
|
1559
1540
|
const { bundleKey } = await exportFromAssistant(
|
|
1560
1541
|
fromEntry,
|
|
1561
1542
|
fromCloud,
|
|
1562
|
-
|
|
1543
|
+
bundleCloudUrl,
|
|
1563
1544
|
);
|
|
1564
1545
|
|
|
1565
1546
|
if (sourceIsLocalOrDocker && targetIsLocalOrDocker && !keepSource) {
|
|
@@ -1622,7 +1603,7 @@ export const teleport = Object.assign(
|
|
|
1622
1603
|
removeAssistantEntry(toEntry.assistantId);
|
|
1623
1604
|
console.error(
|
|
1624
1605
|
`Error: Target assistant '${toEntry.assistantId}' was running ${targetVersion}, ` +
|
|
1625
|
-
`but the
|
|
1606
|
+
`but the cloud source is on ${sourceVersion}.`,
|
|
1626
1607
|
);
|
|
1627
1608
|
console.error(
|
|
1628
1609
|
`Upgrade your ${toCloud} environment first, then retry the teleport.`,
|
|
@@ -1632,20 +1613,20 @@ export const teleport = Object.assign(
|
|
|
1632
1613
|
}
|
|
1633
1614
|
|
|
1634
1615
|
// Import to target (also GCS-driven)
|
|
1635
|
-
console.log(`Importing to ${toEntry.assistantId}
|
|
1616
|
+
console.log(`Importing to ${toEntry.assistantId} on ${toCloud}...`);
|
|
1636
1617
|
await importToAssistant(
|
|
1637
1618
|
toEntry,
|
|
1638
1619
|
toCloud,
|
|
1639
1620
|
bundleKey,
|
|
1640
1621
|
false,
|
|
1641
|
-
|
|
1622
|
+
bundleCloudUrl,
|
|
1642
1623
|
);
|
|
1643
1624
|
|
|
1644
1625
|
// After successful import, inject fresh cloud credentials if the
|
|
1645
1626
|
// user is logged in — replaces the source's stale cadet:* credentials
|
|
1646
1627
|
// that were filtered during import.
|
|
1647
1628
|
if (fromCloud === "cadet") {
|
|
1648
|
-
await
|
|
1629
|
+
await tryInjectCloudCredentials(toEntry);
|
|
1649
1630
|
}
|
|
1650
1631
|
|
|
1651
1632
|
// Retire source after successful import
|
|
@@ -1660,7 +1641,7 @@ export const teleport = Object.assign(
|
|
|
1660
1641
|
removeAssistantEntry(fromEntry.assistantId);
|
|
1661
1642
|
console.log(`Source assistant '${from}' retired.`);
|
|
1662
1643
|
} else {
|
|
1663
|
-
console.log(`Source assistant '${from}' kept
|
|
1644
|
+
console.log(`Source assistant '${from}' kept via --keep-source.`);
|
|
1664
1645
|
}
|
|
1665
1646
|
}
|
|
1666
1647
|
|