From 459ac73cdb54fbef66ea7108ccebf5d13ad955bc Mon Sep 17 00:00:00 2001 From: Delega Bot Date: Thu, 26 Mar 2026 21:36:33 -0500 Subject: [PATCH] fix: support cli login fallback on fresh linux hosts --- src/commands/init.ts | 18 +++++++++++------- src/commands/login.ts | 17 +++++++++++------ src/config.ts | 19 ++++++++++++++----- src/index.ts | 9 +++++++-- 4 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/commands/init.ts b/src/commands/init.ts index 642f503..b829040 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -276,22 +276,26 @@ function printKeyBox(apiKey: string, storageLocation: string): void { console.log(` └${"─".repeat(innerWidth + 2)}┘`); } -function saveApiConfig(rawApiUrl: string): void { +function saveApiConfig(rawApiUrl: string, apiKey?: string): void { try { const nextConfig = { ...loadConfig(), api_url: rawApiUrl }; - delete nextConfig.api_key; + if (apiKey) { + nextConfig.api_key = apiKey; + } else { + delete nextConfig.api_key; + } saveConfig(nextConfig); } catch (error) { throw new UserFacingError(`Unable to save config: ${extractMessage(error)}`); } } -function storeApiKey(apiKey: string): string { +function storeApiKey(apiKey: string): { location: string; secure: boolean } { try { return persistApiKey(apiKey); } catch (error) { throw new UserFacingError( - `Unable to store API key securely: ${extractMessage(error)}`, + `Unable to store API key: ${extractMessage(error)}`, ); } } @@ -456,10 +460,10 @@ async function finalizeSetup(rawApiUrl: string, apiKey: string, dashboardUrl: st // Validate API connectivity before persisting anything to disk. // If this fails, no config or key is saved — the user can retry cleanly. const task = await createDemoTask(apiBaseUrl, apiKey); - const storageLocation = storeApiKey(apiKey); - saveApiConfig(rawApiUrl); + const storage = storeApiKey(apiKey); + saveApiConfig(rawApiUrl, storage.secure ? undefined : apiKey); - return { apiKey, apiUrl: rawApiUrl, storageLocation, task, dashboardUrl }; + return { apiKey, apiUrl: rawApiUrl, storageLocation: storage.location, task, dashboardUrl }; } catch (error) { // The account/agent already exists server-side — print the key so it isn't lost. console.error(); diff --git a/src/commands/login.ts b/src/commands/login.ts index f2afd1a..b043c5d 100644 --- a/src/commands/login.ts +++ b/src/commands/login.ts @@ -155,16 +155,21 @@ Examples: let storageLocation: string; try { - storageLocation = persistApiKey(key); + const storage = persistApiKey(key); + storageLocation = storage.location; + + const nextConfig = { ...config }; + if (storage.secure) { + delete nextConfig.api_key; + } else { + nextConfig.api_key = key; + } + saveConfig(nextConfig); } catch (err) { const msg = err instanceof Error ? err.message : String(err); - console.error(`Unable to store API key securely: ${msg}`); + console.error(`Unable to store API key: ${msg}`); process.exit(1); } - - const nextConfig = { ...config }; - delete nextConfig.api_key; - saveConfig(nextConfig); if (validatedWithoutMetadata) { console.log(`\nLogged in. Key saved to ${storageLocation}`); console.log("Current server validated the key but does not expose /agent/me metadata."); diff --git a/src/config.ts b/src/config.ts index 6e9d249..13716a5 100644 --- a/src/config.ts +++ b/src/config.ts @@ -8,6 +8,11 @@ export interface DelegaConfig { api_url?: string; } +export interface ApiKeyStorageResult { + location: string; + secure: boolean; +} + const LOCAL_API_HOSTS = new Set(["localhost", "127.0.0.1", "::1"]); function normalizeHost(hostname: string): string { @@ -60,15 +65,19 @@ export function saveConfig(config: DelegaConfig): void { node_fs.chmodSync(getConfigPath(), 0o600); } -export function persistApiKey(apiKey: string): string { +export function persistApiKey(apiKey: string): ApiKeyStorageResult { const storeLabel = storeApiKey(apiKey); if (storeLabel) { - return storeLabel; + return { + location: storeLabel, + secure: true, + }; } - throw new Error( - "Secure credential storage is unavailable on this system. Set DELEGA_API_KEY manually instead.", - ); + return { + location: getConfigPath(), + secure: false, + }; } export function normalizeApiUrl(rawUrl: string): string { diff --git a/src/index.ts b/src/index.ts index df2834c..e903222 100644 --- a/src/index.ts +++ b/src/index.ts @@ -38,9 +38,14 @@ program.addCommand(statsCommand); program.addCommand(statusCommand); program.addCommand(resetCommand); -program.on("command:*", () => { +program.on("command:*", ([commandName]) => { printBanner(); - program.help(); + if (commandName) { + console.error(`Unknown command: ${commandName}`); + console.error(); + } + program.outputHelp(); + process.exit(1); }); if (process.argv.length <= 2) {