@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.
- 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 +3 -2
- 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 +2 -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 +21 -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 +1 -8
- package/src/__tests__/{ps-platform-status.test.ts → ps-cloud-status.test.ts} +79 -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 +181 -197
- package/src/__tests__/tunnel.test.ts +257 -222
- package/src/__tests__/uninstall.test.ts +13 -4
- 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 -76
- 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 +23 -23
- package/src/commands/login.ts +22 -22
- package/src/commands/logs.ts +8 -8
- package/src/commands/ps.ts +244 -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 +109 -109
- package/src/commands/terminal.ts +158 -18
- package/src/commands/tunnel.ts +138 -157
- package/src/commands/uninstall.ts +57 -9
- 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-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} +107 -98
- package/src/lib/cloud-login.ts +24 -24
- package/src/lib/{platform-releases.ts → cloud-releases.ts} +11 -9
- package/src/lib/cloud-values.ts +3 -0
- package/src/lib/config-utils.ts +1 -1
- package/src/lib/detached-process.ts +1 -1
- package/src/lib/docker.ts +260 -53
- package/src/lib/ensure-binary.ts +171 -0
- package/src/lib/environments/__tests__/paths.test.ts +2 -2
- package/src/lib/environments/__tests__/resolve.test.ts +26 -26
- package/src/lib/environments/resolve.ts +8 -8
- 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 +19 -23
- 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 +10 -31
- package/src/lib/nginx-ingress.ts +42 -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/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/lib/cloud-login.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { randomBytes } from "crypto";
|
|
|
10
10
|
import { createServer } from "http";
|
|
11
11
|
import type { AddressInfo } from "net";
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import { isCloudHome } from "./cloud-values.js";
|
|
14
14
|
import {
|
|
15
15
|
resolveAssistant,
|
|
16
16
|
saveAssistantEntry,
|
|
@@ -22,11 +22,11 @@ import {
|
|
|
22
22
|
fetchCurrentUser,
|
|
23
23
|
fetchOrganizationId,
|
|
24
24
|
ensureSelfHostedLocalRegistration,
|
|
25
|
-
|
|
25
|
+
getCloudUrl,
|
|
26
26
|
injectCredentialsIntoAssistant,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
} from "./
|
|
27
|
+
readCloudToken,
|
|
28
|
+
saveCloudToken,
|
|
29
|
+
} from "./cloud-client.js";
|
|
30
30
|
import { fetchAssistantIngressUrl, fetchCurrentVersion } from "./upgrade-lifecycle.js";
|
|
31
31
|
import {
|
|
32
32
|
CALLBACK_PATH,
|
|
@@ -257,8 +257,8 @@ export function startLoopbackListener(
|
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
/** App-held WorkOS PKCE login */
|
|
260
|
-
export async function workosPkceLogin(
|
|
261
|
-
const clientId = await fetchWorkosClientId(
|
|
260
|
+
export async function workosPkceLogin(cloudUrl: string): Promise<string> {
|
|
261
|
+
const clientId = await fetchWorkosClientId(cloudUrl);
|
|
262
262
|
const { verifier, challenge } = generatePkcePair();
|
|
263
263
|
const state = randomBytes(32).toString("hex");
|
|
264
264
|
|
|
@@ -286,7 +286,7 @@ export async function workosPkceLogin(platformUrl: string): Promise<string> {
|
|
|
286
286
|
verifier,
|
|
287
287
|
});
|
|
288
288
|
return await exchangeAccessTokenForSession(
|
|
289
|
-
|
|
289
|
+
cloudUrl,
|
|
290
290
|
clientId,
|
|
291
291
|
accessToken,
|
|
292
292
|
);
|
|
@@ -307,7 +307,7 @@ export interface CloudLoginSession {
|
|
|
307
307
|
* validates the resulting token, and persists it.
|
|
308
308
|
*/
|
|
309
309
|
export async function ensureCloudLoginInteractive(): Promise<CloudLoginSession> {
|
|
310
|
-
const existingToken =
|
|
310
|
+
const existingToken = readCloudToken();
|
|
311
311
|
if (existingToken) {
|
|
312
312
|
try {
|
|
313
313
|
const user = await fetchCurrentUser(existingToken);
|
|
@@ -317,16 +317,16 @@ export async function ensureCloudLoginInteractive(): Promise<CloudLoginSession>
|
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
-
const token = await workosPkceLogin(
|
|
320
|
+
const token = await workosPkceLogin(getCloudUrl());
|
|
321
321
|
const user = await fetchCurrentUser(token);
|
|
322
|
-
|
|
322
|
+
saveCloudToken(token);
|
|
323
323
|
return { token, user };
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
/**
|
|
327
327
|
* TLS failures surface as opaque messages like "unknown certificate
|
|
328
328
|
* verification error" from Bun's fetch. Translate the recognizable ones into
|
|
329
|
-
* something actionable — most commonly the
|
|
329
|
+
* something actionable — most commonly the cloud host's managed
|
|
330
330
|
* certificate is still provisioning.
|
|
331
331
|
*/
|
|
332
332
|
export function describeLoginError(error: unknown): string {
|
|
@@ -335,13 +335,13 @@ export function describeLoginError(error: unknown): string {
|
|
|
335
335
|
if (!tlsish) return raw;
|
|
336
336
|
return (
|
|
337
337
|
`Cadet Cloud is unreachable (${raw}). This usually means ` +
|
|
338
|
-
`${
|
|
339
|
-
"Retry in a few minutes, or point
|
|
338
|
+
`${getCloudUrl()}'s TLS certificate is missing or still provisioning. ` +
|
|
339
|
+
"Retry in a few minutes, or point CADET_CLOUD_URL at a reachable host."
|
|
340
340
|
);
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
/**
|
|
344
|
-
* Register the active self-hosted assistant with the
|
|
344
|
+
* Register the active self-hosted assistant with the cloud and inject
|
|
345
345
|
* cloud credentials into its runtime — the post-login half of the desktop
|
|
346
346
|
* app's LocalAssistantBootstrapService flow. Extracted so `cadet hatch` can
|
|
347
347
|
* complete the same flow right after an interactive login on the Cadet Cloud
|
|
@@ -355,8 +355,8 @@ export async function registerLocalAssistantWithPlatform(
|
|
|
355
355
|
const log = options.log ?? console.log;
|
|
356
356
|
const entry = resolveAssistant();
|
|
357
357
|
|
|
358
|
-
// Skip managed ("cadet") assistants — they are handled by the
|
|
359
|
-
if (!entry ||
|
|
358
|
+
// Skip managed ("cadet") assistants — they are handled by the cloud.
|
|
359
|
+
if (!entry || isCloudHome(entry.cloud)) return;
|
|
360
360
|
|
|
361
361
|
const orgId = await fetchOrganizationId(token);
|
|
362
362
|
const clientInstallationId = computeDeviceId();
|
|
@@ -364,7 +364,7 @@ export async function registerLocalAssistantWithPlatform(
|
|
|
364
364
|
fetchCurrentVersion(entry.runtimeUrl),
|
|
365
365
|
fetchAssistantIngressUrl(entry.runtimeUrl, options.bearerToken ?? entry.bearerToken),
|
|
366
366
|
]);
|
|
367
|
-
const
|
|
367
|
+
const cloudUrl = getCloudUrl();
|
|
368
368
|
const registration = await ensureSelfHostedLocalRegistration(
|
|
369
369
|
token,
|
|
370
370
|
orgId,
|
|
@@ -372,14 +372,14 @@ export async function registerLocalAssistantWithPlatform(
|
|
|
372
372
|
entry.assistantId,
|
|
373
373
|
"cli",
|
|
374
374
|
assistantVersion,
|
|
375
|
-
|
|
375
|
+
cloudUrl,
|
|
376
376
|
ingressUrl,
|
|
377
377
|
);
|
|
378
378
|
saveAssistantEntry({
|
|
379
379
|
...entry,
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
380
|
+
cloudAssistantId: registration.assistant.id,
|
|
381
|
+
cloudBaseUrl: cloudUrl,
|
|
382
|
+
cloudOrganizationId: orgId,
|
|
383
383
|
});
|
|
384
384
|
log(
|
|
385
385
|
`Registered assistant: ${registration.assistant.name} (${registration.assistant.id})`,
|
|
@@ -408,8 +408,8 @@ export async function registerLocalAssistantWithPlatform(
|
|
|
408
408
|
gatewayUrl: entry.runtimeUrl,
|
|
409
409
|
bearerToken: options.bearerToken ?? entry.bearerToken,
|
|
410
410
|
assistantApiKey,
|
|
411
|
-
|
|
412
|
-
|
|
411
|
+
cloudAssistantId: registration.assistant.id,
|
|
412
|
+
cloudBaseUrl: cloudUrl,
|
|
413
413
|
organizationId: orgId,
|
|
414
414
|
userId: user.id,
|
|
415
415
|
webhookSecret: registration.webhook_secret,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getCloudUrl } from "./cloud-client.js";
|
|
2
2
|
import { dockerhubImages } from "./docker.js";
|
|
3
3
|
import type { ServiceName } from "./docker.js";
|
|
4
4
|
import { loopbackSafeFetch } from "./loopback-fetch.js";
|
|
@@ -40,20 +40,20 @@ const RELEASES_FETCH_LIMIT = 100;
|
|
|
40
40
|
/**
|
|
41
41
|
* Fetch the releases list from Cadet Cloud, optionally filtered by channel
|
|
42
42
|
* (the `channel` param takes precedence over `stable` server-side).
|
|
43
|
-
* `
|
|
43
|
+
* `cloudUrl` overrides the lockfile/env-resolved default — pass the
|
|
44
44
|
* target assistant's platform URL when it may differ from the active one.
|
|
45
45
|
* Returns `null` when Cadet Cloud is unreachable or responds non-OK —
|
|
46
46
|
* distinct from `[]` (it answered, no releases).
|
|
47
47
|
*/
|
|
48
48
|
export async function fetchReleases(opts?: {
|
|
49
49
|
channel?: "stable" | "preview";
|
|
50
|
-
|
|
50
|
+
cloudUrl?: string;
|
|
51
51
|
}): Promise<ReleaseListItem[] | null> {
|
|
52
52
|
try {
|
|
53
|
-
const
|
|
53
|
+
const cloudUrl = opts?.cloudUrl || getCloudUrl();
|
|
54
54
|
const filter = opts?.channel ? `channel=${opts.channel}` : "stable=true";
|
|
55
55
|
const response = await loopbackSafeFetch(
|
|
56
|
-
`${
|
|
56
|
+
`${cloudUrl}/v1/releases/?${filter}&limit=${RELEASES_FETCH_LIMIT}`,
|
|
57
57
|
{ signal: AbortSignal.timeout(10_000) },
|
|
58
58
|
);
|
|
59
59
|
if (!response.ok) return null;
|
|
@@ -85,7 +85,9 @@ export async function fetchLatestStableVersion(): Promise<string | null> {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
|
-
* Image refs for a target version: the tag is the target version
|
|
88
|
+
* Image refs for a target version: the tag is the target version exactly as
|
|
89
|
+
* the release workflows push it — bare ("0.12.8", "0.12.8-dev…"); a
|
|
90
|
+
* git-tag-style "v" prefix on the input is tolerated and stripped. The repo
|
|
89
91
|
* follows the CLI's own version shape (dev CLI → `-dev` repos).
|
|
90
92
|
*/
|
|
91
93
|
export function resolveImageRefs(
|
|
@@ -93,8 +95,8 @@ export function resolveImageRefs(
|
|
|
93
95
|
cliVersion: string,
|
|
94
96
|
): Record<ServiceName, string> {
|
|
95
97
|
const versionTag = targetVersion.startsWith("v")
|
|
96
|
-
? targetVersion
|
|
97
|
-
:
|
|
98
|
+
? targetVersion.slice(1)
|
|
99
|
+
: targetVersion;
|
|
98
100
|
const images = dockerhubImages(cliVersion);
|
|
99
101
|
return {
|
|
100
102
|
assistant: `${images.assistant}:${versionTag}`,
|
|
@@ -107,5 +109,5 @@ export function resolveImageRefs(
|
|
|
107
109
|
export function resolveOwnImageRefs(
|
|
108
110
|
cliVersion: string,
|
|
109
111
|
): Record<ServiceName, string> {
|
|
110
|
-
return resolveImageRefs(cliVersion
|
|
112
|
+
return resolveImageRefs(cliVersion || "latest", cliVersion);
|
|
111
113
|
}
|
package/src/lib/config-utils.ts
CHANGED
|
@@ -34,7 +34,7 @@ export function buildNestedConfig(
|
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Ensure hatch always provides enough initial LLM config for the assistant to
|
|
37
|
-
* detect a fresh off-
|
|
37
|
+
* detect a fresh off-cloud hatch and seed BYOK profiles.
|
|
38
38
|
*
|
|
39
39
|
* @deprecated Part of the workspace-config overlay path — a CLI→Assistant
|
|
40
40
|
* side channel that bypasses the Assistant's public APIs and has no
|
|
@@ -6,7 +6,7 @@ import { isCompiledCli } from "./local.js";
|
|
|
6
6
|
import { getLogDir, openLogFile, resetLogFile } from "./xdg-log.js";
|
|
7
7
|
|
|
8
8
|
export interface RelaunchDetachedOptions {
|
|
9
|
-
/** argv for the re-invoked CLI command, e.g. ["tunnel", "--provider", "
|
|
9
|
+
/** argv for the re-invoked CLI command, e.g. ["tunnel", "--provider", "cloudflare"]. */
|
|
10
10
|
args: string[];
|
|
11
11
|
/** Log file basename under the XDG log dir; truncated before spawn. */
|
|
12
12
|
logFile: string;
|
package/src/lib/docker.ts
CHANGED
|
@@ -37,9 +37,10 @@ import {
|
|
|
37
37
|
isLocalBuildRef,
|
|
38
38
|
loadImageViaHost,
|
|
39
39
|
} from "./host-image-loader.js";
|
|
40
|
-
import { resolveOwnImageRefs } from "./
|
|
40
|
+
import { resolveOwnImageRefs } from "./cloud-releases.js";
|
|
41
41
|
import { isDevVersion } from "./version-compat.js";
|
|
42
42
|
import {
|
|
43
|
+
collectProviderApiKey,
|
|
43
44
|
configureHatchProviderApiKey,
|
|
44
45
|
formatProviderName,
|
|
45
46
|
promptProviderChoice,
|
|
@@ -340,14 +341,96 @@ export function resolveDockerProviderCredentialSetupAction(options: {
|
|
|
340
341
|
provider: string | null | undefined;
|
|
341
342
|
guardianAccessToken?: string;
|
|
342
343
|
detached: boolean;
|
|
344
|
+
/**
|
|
345
|
+
* Key — or an explicit skip ("") — collected from the user right after
|
|
346
|
+
* they picked the provider. When present (even empty), the user already
|
|
347
|
+
* answered at the prompt, so detached hatches configure (or report the
|
|
348
|
+
* missing key) instead of deferring to a second `cadet setup` run.
|
|
349
|
+
*/
|
|
350
|
+
precollectedKey?: string;
|
|
343
351
|
}): DockerProviderCredentialSetupAction {
|
|
344
352
|
if (options.provider === undefined) return "skip";
|
|
345
353
|
if (options.provider === null) return options.detached ? "skip" : "configure";
|
|
346
|
-
if (options.detached)
|
|
354
|
+
if (options.detached) {
|
|
355
|
+
if (options.precollectedKey !== undefined) {
|
|
356
|
+
return options.guardianAccessToken ? "configure" : "missing-token";
|
|
357
|
+
}
|
|
358
|
+
return "defer";
|
|
359
|
+
}
|
|
347
360
|
if (!options.guardianAccessToken) return "missing-token";
|
|
348
361
|
return "configure";
|
|
349
362
|
}
|
|
350
363
|
|
|
364
|
+
/** Time to wait for the Docker daemon to answer `docker info` after a Colima start. */
|
|
365
|
+
const COLIMA_SETTLE_TIMEOUT_MS = 15_000;
|
|
366
|
+
|
|
367
|
+
/** Poll `docker info` until the daemon answers or the timeout elapses. */
|
|
368
|
+
async function waitForDockerDaemon(
|
|
369
|
+
execFn: typeof exec,
|
|
370
|
+
timeoutMs: number,
|
|
371
|
+
): Promise<boolean> {
|
|
372
|
+
const deadline = Date.now() + timeoutMs;
|
|
373
|
+
for (;;) {
|
|
374
|
+
try {
|
|
375
|
+
await execFn("docker", ["info"]);
|
|
376
|
+
return true;
|
|
377
|
+
} catch {
|
|
378
|
+
if (Date.now() >= deadline) return false;
|
|
379
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Start Colima and wait for the Docker daemon to actually answer.
|
|
386
|
+
*
|
|
387
|
+
* `colima start` exiting 0 only means Colima's own state file says the VM is
|
|
388
|
+
* up — that state can be stale (zombie VM after a host sleep or crash), in
|
|
389
|
+
* which case start is a no-op ("already running, ignoring") while the daemon
|
|
390
|
+
* inside stays dead. So success is decided by re-probing `docker info`, and a
|
|
391
|
+
* failed probe triggers the manual-fix cycle: force-stop and start fresh.
|
|
392
|
+
* Never `colima delete` — the VM disk holds every container image and volume.
|
|
393
|
+
* `startArgs` carries extra flags (e.g. `--memory`) for a first start; the
|
|
394
|
+
* wake path starts an existing instance bare.
|
|
395
|
+
*/
|
|
396
|
+
async function startColimaAndAwaitDaemon(
|
|
397
|
+
execFn: typeof exec,
|
|
398
|
+
log: (msg: string) => void,
|
|
399
|
+
opts: { startArgs?: string[]; settleTimeoutMs?: number } = {},
|
|
400
|
+
): Promise<void> {
|
|
401
|
+
const startArgs = opts.startArgs ?? [];
|
|
402
|
+
const settleTimeoutMs = opts.settleTimeoutMs ?? COLIMA_SETTLE_TIMEOUT_MS;
|
|
403
|
+
|
|
404
|
+
try {
|
|
405
|
+
await execFn("colima", ["start", ...startArgs]);
|
|
406
|
+
} catch (err) {
|
|
407
|
+
// exec captures the child's output and only surfaces it in the error —
|
|
408
|
+
// print it so a failed start is never silent.
|
|
409
|
+
log(`⚠️ colima start failed: ${err instanceof Error ? err.message : err}`);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (await waitForDockerDaemon(execFn, settleTimeoutMs)) return;
|
|
413
|
+
|
|
414
|
+
log(
|
|
415
|
+
"🔄 Colima state looks stale — restarting the VM (colima stop --force, then start)...",
|
|
416
|
+
);
|
|
417
|
+
await execFn("colima", ["stop", "--force"]).catch(() => {});
|
|
418
|
+
try {
|
|
419
|
+
await execFn("colima", ["start", ...startArgs]);
|
|
420
|
+
} catch (err) {
|
|
421
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
422
|
+
throw new Error(
|
|
423
|
+
`Failed to restart Colima. Please run 'colima stop --force && colima start' manually.\n${message}`,
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
if (!(await waitForDockerDaemon(execFn, settleTimeoutMs))) {
|
|
427
|
+
throw new Error(
|
|
428
|
+
"Docker daemon is still not reachable after restarting Colima. " +
|
|
429
|
+
"Check `colima status` and `docker info`, then try again.",
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
351
434
|
/**
|
|
352
435
|
* Checks whether the `docker` CLI and daemon are available on the system.
|
|
353
436
|
* Installs Colima and Docker via direct binary download if missing (no sudo
|
|
@@ -418,41 +501,9 @@ async function ensureDockerInstalled(): Promise<void> {
|
|
|
418
501
|
}
|
|
419
502
|
|
|
420
503
|
console.log("🚀 Docker daemon not running. Starting Colima...");
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
"--memory",
|
|
425
|
-
String(COLIMA_DEFAULT_MEMORY_GIB),
|
|
426
|
-
]);
|
|
427
|
-
} catch {
|
|
428
|
-
// Colima may fail if a previous VM instance is in a corrupt state.
|
|
429
|
-
// Attempt to delete the stale instance and retry once.
|
|
430
|
-
console.log(
|
|
431
|
-
"⚠️ Colima start failed — attempting to reset stale VM state...",
|
|
432
|
-
);
|
|
433
|
-
try {
|
|
434
|
-
await exec("colima", ["stop", "--force"]).catch(() => {});
|
|
435
|
-
await exec("colima", ["delete", "--force"]);
|
|
436
|
-
} catch {
|
|
437
|
-
// If delete also fails, fall through to the retry which will
|
|
438
|
-
// produce a clear error message.
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
try {
|
|
442
|
-
console.log("🔄 Retrying colima start...");
|
|
443
|
-
await exec("colima", [
|
|
444
|
-
"start",
|
|
445
|
-
"--memory",
|
|
446
|
-
String(COLIMA_DEFAULT_MEMORY_GIB),
|
|
447
|
-
]);
|
|
448
|
-
} catch (retryErr) {
|
|
449
|
-
const message =
|
|
450
|
-
retryErr instanceof Error ? retryErr.message : String(retryErr);
|
|
451
|
-
throw new Error(
|
|
452
|
-
`Failed to start Colima after resetting stale VM state. Please run 'colima start' manually.\n${message}`,
|
|
453
|
-
);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
504
|
+
await startColimaAndAwaitDaemon(exec, console.log, {
|
|
505
|
+
startArgs: ["--memory", String(COLIMA_DEFAULT_MEMORY_GIB)],
|
|
506
|
+
});
|
|
456
507
|
}
|
|
457
508
|
}
|
|
458
509
|
|
|
@@ -486,6 +537,56 @@ export async function removeContainer(containerName: string): Promise<void> {
|
|
|
486
537
|
}
|
|
487
538
|
}
|
|
488
539
|
|
|
540
|
+
/**
|
|
541
|
+
* Error signatures Docker Hub returns when the host has STALE Docker Hub
|
|
542
|
+
* credentials: an expired personal access token saved by a past
|
|
543
|
+
* `docker login` gets attached to the pull, and Hub rejects the request
|
|
544
|
+
* instead of falling back to anonymous access for a public image.
|
|
545
|
+
*/
|
|
546
|
+
export function isExpiredDockerHubCredentialError(err: unknown): boolean {
|
|
547
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
548
|
+
return /personal access token is expired|authentication required|unauthorized/i.test(
|
|
549
|
+
message,
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Pull an image, retrying once without stale credentials when Docker Hub
|
|
555
|
+
* rejects the pull with an expired-token/auth error — public pulls need no
|
|
556
|
+
* login, so `docker logout` (clears the stored Docker Hub credentials the
|
|
557
|
+
* docker CLI attaches to pulls) costs nothing. Other failures propagate raw;
|
|
558
|
+
* a still-failing auth retry is rethrown with actionable copy.
|
|
559
|
+
*/
|
|
560
|
+
export async function pullImage(
|
|
561
|
+
ref: string,
|
|
562
|
+
log: (msg: string) => void = console.log,
|
|
563
|
+
execFn: typeof exec = exec,
|
|
564
|
+
): Promise<void> {
|
|
565
|
+
try {
|
|
566
|
+
await execFn("docker", ["pull", ref]);
|
|
567
|
+
return;
|
|
568
|
+
} catch (err) {
|
|
569
|
+
if (!isExpiredDockerHubCredentialError(err)) throw err;
|
|
570
|
+
log(
|
|
571
|
+
`⚠️ Docker Hub rejected the pull of ${ref} with an expired-credential ` +
|
|
572
|
+
`error — clearing stale Docker Hub login and retrying (public images ` +
|
|
573
|
+
`need no credentials)...`,
|
|
574
|
+
);
|
|
575
|
+
await execFn("docker", ["logout"]).catch(() => {});
|
|
576
|
+
}
|
|
577
|
+
try {
|
|
578
|
+
await execFn("docker", ["pull", ref]);
|
|
579
|
+
} catch (err) {
|
|
580
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
581
|
+
throw new Error(
|
|
582
|
+
`Failed to pull ${ref}.\n${message}\n` +
|
|
583
|
+
`If the Docker daemon is not running, start it, e.g. 'colima start' on macOS. ` +
|
|
584
|
+
`If the error mentions authentication, run 'docker logout' and check your ` +
|
|
585
|
+
`Docker Hub credentials — public image pulls need none.`,
|
|
586
|
+
);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
489
590
|
export async function retireDocker(name: string): Promise<void> {
|
|
490
591
|
console.log(`\u{1F5D1}\ufe0f Stopping Docker containers for '${name}'...\n`);
|
|
491
592
|
|
|
@@ -785,6 +886,113 @@ export async function wakeContainers(
|
|
|
785
886
|
}
|
|
786
887
|
}
|
|
787
888
|
|
|
889
|
+
/** The `docker start` failure for a container that was never created. */
|
|
890
|
+
export function isNoSuchContainerError(err: unknown): boolean {
|
|
891
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
892
|
+
return msg.includes("No such container");
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* Recreate a docker instance's service group from its lockfile entry — the
|
|
897
|
+
* wake path for containers that don't exist yet. A migrated install has its
|
|
898
|
+
* data in the volumes but no containers: nothing ever ran `docker run` for
|
|
899
|
+
* it (v0.0.10 run feedback: `wake --all` died on "No such container:
|
|
900
|
+
* <name>-assistant").
|
|
901
|
+
*
|
|
902
|
+
* Network and volume creates are idempotent; the three service containers
|
|
903
|
+
* come up from the entry's recorded images (the migrator points those at
|
|
904
|
+
* the installed cadet's release). The guardian bootstrap secret rides
|
|
905
|
+
* through from the entry; the signing key and CES token are deliberately
|
|
906
|
+
* NOT invented — with no env value the gateway and assistant load the
|
|
907
|
+
* persisted trust material from their security volumes (a migrated install
|
|
908
|
+
* keeps its own), matching the gateway's resolution order (env → file →
|
|
909
|
+
* generate). Empty volumes just get fresh state on first boot.
|
|
910
|
+
*/
|
|
911
|
+
export async function recreateDockerContainers(entry: AssistantEntry): Promise<void> {
|
|
912
|
+
const info = entry.containerInfo;
|
|
913
|
+
if (!info?.assistantImage || !info.gatewayImage || !info.cesImage) {
|
|
914
|
+
throw new Error(
|
|
915
|
+
`no container images recorded for '${entry.assistantId}' — re-hatch or run \`cadet upgrade\` to set them`,
|
|
916
|
+
);
|
|
917
|
+
}
|
|
918
|
+
const res = dockerResourceNames(entry.assistantId);
|
|
919
|
+
const log = (msg: string): void => console.log(msg);
|
|
920
|
+
|
|
921
|
+
// Clean slate for the create: an existing container (even a stopped one)
|
|
922
|
+
// would collide with `docker run --name` (the upgrade path does the same).
|
|
923
|
+
await stopContainers(res);
|
|
924
|
+
|
|
925
|
+
try {
|
|
926
|
+
await exec("docker", ["network", "inspect", res.network]);
|
|
927
|
+
} catch {
|
|
928
|
+
await exec("docker", ["network", "create", res.network]);
|
|
929
|
+
}
|
|
930
|
+
for (const vol of [
|
|
931
|
+
res.socketVolume,
|
|
932
|
+
res.assistantIpcVolume,
|
|
933
|
+
res.gatewayIpcVolume,
|
|
934
|
+
res.workspaceVolume,
|
|
935
|
+
res.gatewaySecurityVolume,
|
|
936
|
+
res.cesSecurityVolume,
|
|
937
|
+
]) {
|
|
938
|
+
try {
|
|
939
|
+
await exec("docker", ["volume", "inspect", vol]);
|
|
940
|
+
} catch {
|
|
941
|
+
await exec("docker", ["volume", "create", vol]);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// The recorded images may not be on the machine yet (a migrated install
|
|
946
|
+
// gets its refs written before anything pulled them) — a pull of an
|
|
947
|
+
// already-present image is a cheap no-op.
|
|
948
|
+
for (const image of [info.assistantImage, info.gatewayImage, info.cesImage]) {
|
|
949
|
+
log(`📦 Pulling ${image}...`);
|
|
950
|
+
await pullImage(image, log);
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
const gatewayPort = parseGatewayPort(entry.runtimeUrl) ??
|
|
954
|
+
getDefaultPorts(getCurrentEnvironment()).gateway;
|
|
955
|
+
const assistantPort = info.assistantPort ?? ASSISTANT_INTERNAL_PORT;
|
|
956
|
+
const device = getOrCreateHostDeviceId();
|
|
957
|
+
await startContainers(
|
|
958
|
+
{
|
|
959
|
+
bootstrapSecret: entry.guardianBootstrapSecret,
|
|
960
|
+
extraAssistantEnv: { CADET_DEVICE_ID: device },
|
|
961
|
+
extraGatewayEnv: { CADET_DEVICE_ID: device },
|
|
962
|
+
gatewayPort,
|
|
963
|
+
assistantPort,
|
|
964
|
+
imageTags: {
|
|
965
|
+
assistant: info.assistantImage,
|
|
966
|
+
gateway: info.gatewayImage,
|
|
967
|
+
"credential-executor": info.cesImage,
|
|
968
|
+
},
|
|
969
|
+
instanceName: entry.assistantId,
|
|
970
|
+
res,
|
|
971
|
+
},
|
|
972
|
+
log,
|
|
973
|
+
);
|
|
974
|
+
|
|
975
|
+
// Persist what the recreation decided (the gateway port in the runtime
|
|
976
|
+
// url, the assistant port when it defaulted) so plain `docker start`
|
|
977
|
+
// wakes work and clients reach the right endpoints.
|
|
978
|
+
saveAssistantEntry({
|
|
979
|
+
...entry,
|
|
980
|
+
runtimeUrl: `http://localhost:${gatewayPort}`,
|
|
981
|
+
containerInfo: { ...info, assistantPort },
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
/** The port of the CLI's own runtime url form (`http://localhost:7830`). */
|
|
986
|
+
function parseGatewayPort(runtimeUrl: string): number | null {
|
|
987
|
+
try {
|
|
988
|
+
const port = new URL(runtimeUrl).port;
|
|
989
|
+
const parsed = parseInt(port, 10);
|
|
990
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
991
|
+
} catch {
|
|
992
|
+
return null;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
|
|
788
996
|
/**
|
|
789
997
|
* Ensure a Docker daemon is reachable before waking an instance's containers
|
|
790
998
|
* (macOS only — on Linux the daemon runs natively).
|
|
@@ -805,6 +1013,7 @@ export async function wakeContainers(
|
|
|
805
1013
|
*/
|
|
806
1014
|
export async function ensureDockerDaemonRunning(
|
|
807
1015
|
execFn: typeof exec = exec,
|
|
1016
|
+
opts: { settleTimeoutMs?: number } = {},
|
|
808
1017
|
): Promise<void> {
|
|
809
1018
|
ensureLocalBinOnPath();
|
|
810
1019
|
|
|
@@ -817,12 +1026,10 @@ export async function ensureDockerDaemonRunning(
|
|
|
817
1026
|
// No daemon reachable — fall through to the Colima fallback below.
|
|
818
1027
|
}
|
|
819
1028
|
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
await execFn("colima", ["start"]);
|
|
825
|
-
}
|
|
1029
|
+
// Deliberately no `colima status` probe: it trusts Colima's own state file,
|
|
1030
|
+
// which can be stale (zombie VM) — daemon reachability is the oracle.
|
|
1031
|
+
console.log("🚀 Docker daemon not running. Starting Colima...");
|
|
1032
|
+
await startColimaAndAwaitDaemon(execFn, console.log, opts);
|
|
826
1033
|
}
|
|
827
1034
|
|
|
828
1035
|
/**
|
|
@@ -1127,6 +1334,7 @@ export async function hatchDocker(params: HatchDockerParams): Promise<void> {
|
|
|
1127
1334
|
let provider = setupProviderCredentials
|
|
1128
1335
|
? resolveHatchProvider(configValues)
|
|
1129
1336
|
: undefined;
|
|
1337
|
+
let precollectedApiKey: string | undefined;
|
|
1130
1338
|
|
|
1131
1339
|
if (
|
|
1132
1340
|
shouldPromptForHatchProvider({
|
|
@@ -1139,6 +1347,9 @@ export async function hatchDocker(params: HatchDockerParams): Promise<void> {
|
|
|
1139
1347
|
const picked = await promptProviderChoice();
|
|
1140
1348
|
if (picked) {
|
|
1141
1349
|
provider = picked;
|
|
1350
|
+
// Collect the key immediately, while the choice is fresh — the
|
|
1351
|
+
// startup logs are quiet now, so nothing separates the two prompts.
|
|
1352
|
+
precollectedApiKey = await collectProviderApiKey(picked);
|
|
1142
1353
|
}
|
|
1143
1354
|
}
|
|
1144
1355
|
|
|
@@ -1320,7 +1531,7 @@ export async function hatchDocker(params: HatchDockerParams): Promise<void> {
|
|
|
1320
1531
|
const MAX_PULL_RETRIES = 3;
|
|
1321
1532
|
for (let attempt = 1; attempt <= MAX_PULL_RETRIES; attempt++) {
|
|
1322
1533
|
try {
|
|
1323
|
-
await
|
|
1534
|
+
await pullImage(ref, log);
|
|
1324
1535
|
break;
|
|
1325
1536
|
} catch (err) {
|
|
1326
1537
|
if (attempt === MAX_PULL_RETRIES) throw err;
|
|
@@ -1434,9 +1645,9 @@ export async function hatchDocker(params: HatchDockerParams): Promise<void> {
|
|
|
1434
1645
|
: ownSecret;
|
|
1435
1646
|
|
|
1436
1647
|
emitProgress(4, 6, "Starting containers...");
|
|
1437
|
-
if (flagEnvVars.
|
|
1438
|
-
extraAssistantEnv.
|
|
1439
|
-
flagEnvVars.
|
|
1648
|
+
if (flagEnvVars.CADET_DISABLE_CLOUD) {
|
|
1649
|
+
extraAssistantEnv.CADET_DISABLE_CLOUD =
|
|
1650
|
+
flagEnvVars.CADET_DISABLE_CLOUD;
|
|
1440
1651
|
}
|
|
1441
1652
|
const hostDeviceId = getOrCreateHostDeviceId();
|
|
1442
1653
|
extraAssistantEnv.CADET_DEVICE_ID = hostDeviceId;
|
|
@@ -1478,8 +1689,6 @@ export async function hatchDocker(params: HatchDockerParams): Promise<void> {
|
|
|
1478
1689
|
);
|
|
1479
1690
|
const containersUpAt = Date.now();
|
|
1480
1691
|
|
|
1481
|
-
const imageDigests = await captureImageRefs(res);
|
|
1482
|
-
|
|
1483
1692
|
const runtimeUrl = `http://localhost:${gatewayPort}`;
|
|
1484
1693
|
const dockerEntry: AssistantEntry = {
|
|
1485
1694
|
assistantId: instanceName,
|
|
@@ -1491,10 +1700,6 @@ export async function hatchDocker(params: HatchDockerParams): Promise<void> {
|
|
|
1491
1700
|
assistantImage: imageTags.assistant,
|
|
1492
1701
|
gatewayImage: imageTags.gateway,
|
|
1493
1702
|
cesImage: imageTags["credential-executor"],
|
|
1494
|
-
assistantDigest: imageDigests?.assistant,
|
|
1495
|
-
gatewayDigest: imageDigests?.gateway,
|
|
1496
|
-
cesDigest: imageDigests?.["credential-executor"],
|
|
1497
|
-
networkName: res.network,
|
|
1498
1703
|
assistantPort,
|
|
1499
1704
|
},
|
|
1500
1705
|
};
|
|
@@ -1530,6 +1735,7 @@ export async function hatchDocker(params: HatchDockerParams): Promise<void> {
|
|
|
1530
1735
|
provider,
|
|
1531
1736
|
guardianAccessToken,
|
|
1532
1737
|
detached: waitDetached,
|
|
1738
|
+
precollectedKey: precollectedApiKey,
|
|
1533
1739
|
});
|
|
1534
1740
|
|
|
1535
1741
|
if (providerSetupAction === "defer" && provider !== null) {
|
|
@@ -1556,6 +1762,7 @@ export async function hatchDocker(params: HatchDockerParams): Promise<void> {
|
|
|
1556
1762
|
provider,
|
|
1557
1763
|
bearerToken: guardianAccessToken,
|
|
1558
1764
|
env: process.env,
|
|
1765
|
+
precollectedKey: precollectedApiKey,
|
|
1559
1766
|
log,
|
|
1560
1767
|
});
|
|
1561
1768
|
}
|