@aidotnet/astra-gate 0.0.0-stage → 0.2.0
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/dist/index.js +2360 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -4
- package/README.md +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/lib/http.ts","../src/ui.ts","../src/lib/platform.ts","../src/commands/manage.ts","../../packages/update-core/src/manifest.ts","../../packages/update-core/src/version.ts","../../packages/update-core/src/state.ts","../../packages/update-core/src/paths.ts","../../packages/update-core/src/npm-runner.ts","../../packages/update-core/src/install-info.ts","../../packages/update-core/src/staging.ts","../../packages/update-core/src/swap.ts","../../packages/update-core/src/apply.ts","../../packages/update-core/src/check.ts","../../packages/update-core/src/desktop-install.ts","../src/lib/paths.ts","../src/lib/browser.ts","../src/lib/logs.ts","../src/lib/server-lifecycle.ts","../src/lib/json-file.ts","../src/lib/config-file.ts","../src/lib/runtime.ts","../src/lib/binary.ts","../package.json","../src/version.ts","../src/lib/process-utils.ts","../src/lib/install-json.ts","../src/commands/autostart.ts","../src/lib/autostart.ts","../src/commands/desktop.ts","../src/lib/desktop.ts","../src/lib/desktop-server.ts","../src/lib/prompt.ts","../src/commands/uninstall.ts","../src/commands/admin.ts","../src/commands/config.ts","../src/commands/restore-all.ts"],"sourcesContent":["import process from 'node:process';\nimport { Argument, Command } from 'commander';\nimport { ApiError } from './lib/http.js';\nimport { AstraError } from './errors.js';\nimport { fail } from './ui.js';\nimport { CLIENT_KINDS } from './lib/platform.js';\nimport { runStart, runStop, runRestart, runStatus, runLogs, runOpen } from './commands/manage.js';\nimport { runAutostart } from './commands/autostart.js';\nimport { runInstall, runUninstallClient, runUpdate } from './commands/desktop.js';\nimport { runUninstall } from './commands/uninstall.js';\nimport {\n runClientDisable,\n runClientEnable,\n runClientList,\n runClientStatus,\n runProviderAdd,\n runProviderList,\n runProviderRemove,\n} from './commands/admin.js';\nimport { runSetPassword } from './commands/config.js';\nimport { runRestoreAll } from './commands/restore-all.js';\nimport { VERSION } from './version.js';\n\nfunction addStartOptions(cmd: Command): Command {\n return cmd\n .option('--port <port>', 'TCP port to listen on (default 17321)')\n .option('--host <host>', 'Address to bind (default 127.0.0.1)')\n .option('--foreground', 'Run the server in the foreground instead of detached')\n .option('--open', 'Open the web UI in the default browser');\n}\n\nconst program = new Command();\n\nprogram\n .name('astra')\n .description('Astra — a local AI gateway. Manage the astra-server from the terminal.')\n .version(VERSION, '-v, --version', 'Print the CLI version');\n\n// `astra` with no subcommand behaves like `astra start`\naddStartOptions(program).action((opts) => runStart(opts));\n\naddStartOptions(\n program.command('start').description('Start the Astra server (background by default)'),\n).action((opts) => runStart(opts));\n\nprogram\n .command('stop')\n .description('Stop the running Astra server')\n .action(() => runStop());\n\naddStartOptions(program.command('restart').description('Restart the Astra server')).action(\n (opts) => runRestart(opts),\n);\n\nprogram\n .command('status')\n .description('Show whether the server is running and its details')\n .action(() => runStatus());\n\nprogram\n .command('logs')\n .description('Show recent server logs')\n .option('-f, --follow', 'Keep printing new log output')\n .action((opts: { follow?: boolean }) => runLogs(opts));\n\nprogram\n .command('open')\n .description('Open the Astra web UI in the default browser')\n .action(() => runOpen());\n\nconst autostart = program.command('autostart').description('Manage starting Astra at login');\nautostart\n .command('enable')\n .description('Enable autostart (LaunchAgent / systemd --user / schtasks)')\n .action(() => runAutostart('enable'));\nautostart\n .command('disable')\n .description('Disable autostart')\n .action(() => runAutostart('disable'));\nautostart\n .command('status')\n .description('Show whether autostart is enabled')\n .action(() => runAutostart('status'));\n\nprogram\n .command('install')\n .description('Install optional Astra components')\n .option('--desktop', 'Install the Astra desktop app for this platform')\n .option('--client', 'Alias of --desktop')\n .action((opts: { desktop?: boolean; client?: boolean }) =>\n runInstall({ client: opts.desktop || opts.client }),\n );\n\nprogram\n .command('uninstall')\n .description('Uninstall Astra (restore client configs, stop the server)')\n .option('--desktop', 'Only uninstall the desktop app')\n .option('--client', 'Alias of --desktop')\n .option('--purge', 'Also delete the Astra data directory (~/.astra)')\n .action((opts: { desktop?: boolean; client?: boolean; purge?: boolean }) => {\n if (opts.desktop || opts.client) return runUninstallClient();\n return runUninstall({ purge: opts.purge });\n });\n\nprogram\n .command('update')\n .description('Update astra (and the desktop app when installed), then restart the server')\n .option('--desktop', 'Only update the desktop app')\n .option('--client', 'Alias of --desktop')\n .option('--check', 'Only check for updates, do not install')\n .option('--retry', 'Retry even after repeated update failures')\n .action((opts: { desktop?: boolean; client?: boolean; check?: boolean; retry?: boolean }) =>\n runUpdate({ client: opts.desktop || opts.client, check: opts.check, retry: opts.retry }),\n );\n\nconst client = program.command('client').description('Manage AI clients (Codex, Claude Code, …)');\nclient\n .command('list')\n .description('List clients and their status')\n .action(() => runClientList());\nclient\n .command('status')\n .description('Show one client in detail')\n .addArgument(new Argument('<kind>', 'Client kind').choices([...CLIENT_KINDS]))\n .action((kind: (typeof CLIENT_KINDS)[number]) => runClientStatus(kind));\nclient\n .command('enable')\n .description('Enable a client and point it at Astra')\n .addArgument(new Argument('<kind>', 'Client kind').choices([...CLIENT_KINDS]))\n .requiredOption('--provider <id-or-name>', 'Provider id or name to bind')\n .option('--model <model>', 'Model to write into the client configuration')\n .action((kind: (typeof CLIENT_KINDS)[number], opts: { provider: string; model?: string }) =>\n runClientEnable(kind, opts),\n );\nclient\n .command('disable')\n .description('Disable a client and restore its original configuration')\n .addArgument(new Argument('<kind>', 'Client kind').choices([...CLIENT_KINDS]))\n .action((kind: (typeof CLIENT_KINDS)[number]) => runClientDisable(kind));\n\nconst provider = program.command('provider').description('Manage providers (upstream AI accounts)');\nprovider\n .command('list')\n .description('List providers')\n .action(() => runProviderList());\nprovider\n .command('add')\n .description('Add a provider from a template')\n .requiredOption('--template <id>', 'Provider template id (see `astra provider templates`)')\n .option('--variant <id>', 'Template variant, when the template has variants')\n .requiredOption('--key <apiKey>', 'API key for the provider')\n .option('--name <name>', 'Display name for the provider')\n .action((opts: { template: string; variant?: string; key: string; name?: string }) =>\n runProviderAdd(opts),\n );\nprovider\n .command('remove')\n .description('Remove a provider')\n .argument('<id>', 'Provider id')\n .action((id: string) => runProviderRemove(id));\n\nprogram\n .command('config')\n .description('Manage Astra configuration')\n .command('set-password')\n .description('Set the admin password (required before binding to a non-loopback address)')\n .action(() => runSetPassword());\n\nprogram\n .command('restore-all')\n .description('Restore every managed client configuration offline (no server needed)')\n .option('--purge', 'Also remove Astra entries from client configs entirely')\n .action((opts: { purge?: boolean }) => runRestoreAll(opts));\n\nprogram\n .parseAsync(process.argv)\n .then(() => {\n /* success — exit code already set by commands when needed */\n })\n .catch((err: unknown) => {\n if (err instanceof ApiError) {\n fail(`error: ${err.message} (HTTP ${err.status})`);\n process.exitCode = 1;\n return;\n }\n if (err instanceof AstraError) {\n fail(`error: ${err.message}`);\n if (err.hint) console.error(` ${err.hint}`);\n process.exitCode = 1;\n return;\n }\n fail(`error: ${err instanceof Error ? err.message : String(err)}`);\n if (process.env.ASTRA_DEBUG) console.error(err);\n else console.error('Run with ASTRA_DEBUG=1 for a stack trace.');\n process.exitCode = 1;\n });\n","/** An expected failure with a friendly message and an optional hint line. */\nexport class AstraError extends Error {\n readonly hint?: string;\n\n constructor(message: string, hint?: string) {\n super(message);\n this.name = 'AstraError';\n this.hint = hint;\n }\n}\n","import { AstraError } from '../errors.js';\n\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;\n\nexport class ApiError extends Error {\n readonly status: number;\n\n constructor(message: string, status: number) {\n super(message);\n this.name = 'ApiError';\n this.status = status;\n }\n}\n\n/** Build the HTTP base URL, mapping wildcard hosts to loopback. */\nexport function baseUrlFor(host: string, port: number): string {\n let h = host.trim();\n if (!h || h === '0.0.0.0' || h === '*' || h === '::') h = '127.0.0.1';\n if (h.startsWith('[') && h.endsWith(']')) h = h.slice(1, -1);\n return `http://${h.includes(':') ? `[${h}]` : h}:${port}`;\n}\n\n/**\n * Headers for Astra management API calls.\n * Every mutating /api/* request must carry X-Astra-Admin: 1;\n * privileged calls (shutdown) additionally carry the runtime token.\n */\nexport function adminHeaders(mutating: boolean, runtimeToken?: string): Record<string, string> {\n const headers: Record<string, string> = { Accept: 'application/json' };\n if (mutating) headers['X-Astra-Admin'] = '1';\n if (runtimeToken) headers['X-Astra-Runtime-Token'] = runtimeToken;\n return headers;\n}\n\nexport interface ApiRequestOptions {\n base: string;\n path: string;\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE';\n body?: unknown;\n runtimeToken?: string;\n timeoutMs?: number;\n fetchImpl?: FetchLike;\n}\n\nexport async function apiRequest<T>(options: ApiRequestOptions): Promise<T> {\n const { base, path, method = 'GET', body, runtimeToken, timeoutMs = 10_000 } = options;\n const doFetch = options.fetchImpl ?? globalThis.fetch;\n if (!doFetch) {\n throw new AstraError('fetch is unavailable. The Astra CLI requires Node.js 18+.');\n }\n const mutating = method !== 'GET';\n const headers = adminHeaders(mutating, runtimeToken);\n if (body !== undefined) headers['Content-Type'] = 'application/json';\n\n let response: Response;\n try {\n response = await doFetch(base + path, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (err) {\n throw new AstraError(\n `Cannot reach the Astra server at ${base} (${describeFetchError(err)}).`,\n 'Start it with `astra start`.',\n );\n }\n\n const text = await response.text();\n let payload: unknown;\n if (text.trim()) {\n try {\n payload = JSON.parse(text);\n } catch {\n payload = undefined;\n }\n }\n if (!response.ok) {\n const serverMessage = readErrorMessage(payload);\n throw new ApiError(\n serverMessage ?? `${response.status} ${response.statusText || 'request failed'}`,\n response.status,\n );\n }\n return payload as T;\n}\n\nfunction readErrorMessage(payload: unknown): string | undefined {\n if (payload && typeof payload === 'object' && 'error' in payload) {\n const e = (payload as { error: unknown }).error;\n if (typeof e === 'string' && e) return e;\n }\n return undefined;\n}\n\nfunction describeFetchError(err: unknown): string {\n if (err instanceof Error) {\n if (err.name === 'TimeoutError' || err.name === 'AbortError') return 'timed out';\n return err.message;\n }\n return String(err);\n}\n\nexport async function checkHealth(\n base: string,\n fetchImpl?: FetchLike,\n timeoutMs = 2_500,\n): Promise<boolean> {\n const doFetch = fetchImpl ?? globalThis.fetch;\n if (!doFetch) return false;\n try {\n const res = await doFetch(`${base}/api/health`, { signal: AbortSignal.timeout(timeoutMs) });\n if (!res.ok) return false;\n const payload = (await res.json()) as { status?: unknown };\n return payload.status === 'ok';\n } catch {\n return false;\n }\n}\n\nexport async function shutdownRequest(\n base: string,\n runtimeToken: string,\n fetchImpl?: FetchLike,\n): Promise<void> {\n await apiRequest<void>({\n base,\n path: '/api/admin/shutdown',\n method: 'POST',\n runtimeToken,\n timeoutMs: 5_000,\n fetchImpl,\n });\n}\n","import process from 'node:process';\n\nconst useColor =\n process.stdout.isTTY === true && process.env.NO_COLOR !== '1' && process.env.TERM !== 'dumb';\n\nfunction wrap(open: string): (text: string) => string {\n return (text: string): string => (useColor ? `\\u001b[${open}m${text}\\u001b[0m` : text);\n}\n\nexport const style = {\n bold: wrap('1'),\n dim: wrap('2'),\n green: wrap('32'),\n yellow: wrap('33'),\n red: wrap('31'),\n cyan: wrap('36'),\n};\n\nexport function info(message: string): void {\n console.log(message);\n}\n\nexport function success(message: string): void {\n console.log(style.green(message));\n}\n\nexport function warn(message: string): void {\n console.log(style.yellow(message));\n}\n\nexport function fail(message: string): void {\n console.error(style.red(message));\n}\n\n/** Print aligned columns. All cells are treated as plain strings. */\nexport function printTable(rows: readonly (readonly string[])[], headers?: readonly string[]): void {\n const all: readonly (readonly string[])[] = headers ? [headers, ...rows] : rows;\n if (all.length === 0) return;\n const widths: number[] = [];\n for (const row of all) {\n row.forEach((cell, i) => {\n widths[i] = Math.max(widths[i] ?? 0, cell.length);\n });\n }\n const line = (row: readonly string[]): string =>\n row.map((cell, i) => cell + ' '.repeat((widths[i] ?? 0) - cell.length)).join(' ');\n if (headers) console.log(style.bold(line(headers)));\n for (const row of rows) console.log(line(row));\n}\n","import { AstraError } from '../errors.js';\n\nexport type SupportedPlatform = 'darwin' | 'linux' | 'win32';\n\nexport interface PlatformInfo {\n platform: SupportedPlatform;\n arch: string;\n /** .NET-style runtime identifier, e.g. osx-arm64 */\n rid: string;\n serverPackage: string;\n desktopPackage: string;\n /** directory name under npm/ */\n serverDir: string;\n desktopDir: string;\n /** file name of the server binary */\n binaryName: string;\n}\n\nconst RID_PREFIX: Record<SupportedPlatform, string> = { darwin: 'osx', linux: 'linux', win32: 'win' };\nconst SUPPORTED_ARCHES = ['x64', 'arm64'];\n\nexport function platformInfo(\n platform: string = process.platform,\n arch: string = process.arch,\n): PlatformInfo {\n const ridPrefix = (RID_PREFIX as Record<string, string | undefined>)[platform];\n if (!ridPrefix || !SUPPORTED_ARCHES.includes(arch)) {\n throw new AstraError(\n `Astra does not ship binaries for ${platform}/${arch}.`,\n 'Supported platforms: macOS (x64, arm64), Linux (x64, arm64), Windows (x64, arm64).',\n );\n }\n const p = platform as SupportedPlatform;\n const dir = `${p}-${arch}`;\n return {\n platform: p,\n arch,\n rid: `${ridPrefix}-${arch}`,\n serverPackage: `@aidotnet/server-${dir}`,\n desktopPackage: `@aidotnet/desktop-${dir}`,\n serverDir: `server-${dir}`,\n desktopDir: `desktop-${dir}`,\n binaryName: p === 'win32' ? 'astra-server.exe' : 'astra-server',\n };\n}\n\nexport const CLIENT_KINDS = [\n 'codex',\n 'claude-code',\n 'gemini-cli',\n 'opencode',\n 'claude-desktop',\n 'grok-build',\n] as const;\n\nexport type ClientKind = (typeof CLIENT_KINDS)[number];\n","import process from 'node:process';\nimport { checkForServerUpdate } from '@aidotnet/update-core';\nimport { fail, info, style, success } from '../ui.js';\nimport { astraHome } from '../lib/paths.js';\nimport { openInBrowser } from '../lib/browser.js';\nimport { findNewestLog, followFile, tailLines } from '../lib/logs.js';\nimport { serverStatus, startServer, stopServer } from '../lib/server-lifecycle.js';\nimport { VERSION } from '../version.js';\n\nexport interface StartArgs {\n port?: string;\n host?: string;\n foreground?: boolean;\n open?: boolean;\n}\n\nexport async function runStart(opts: StartArgs): Promise<void> {\n console.log('Starting Astra…');\n const result = await startServer(opts);\n if (result.alreadyRunning) {\n success(`Astra is already running at ${style.cyan(result.base)} (pid ${result.pid ?? '?'}).`);\n info(style.dim('Use `astra restart` to reload it.'));\n if (opts.open) openInBrowser(result.base);\n return;\n }\n console.log(` Binary ${result.command.serverPath} ${style.dim(`(${result.command.source})`)}`);\n console.log(` Address ${style.cyan(result.base)}`);\n console.log(` Log ${style.dim(result.logFile)}`);\n if (opts.foreground) return; // foreground start returns when the server exits\n success(`Astra is running at ${style.cyan(result.base)}`);\n if (opts.open) openInBrowser(result.base);\n}\n\nexport async function runStop(): Promise<void> {\n const result = await stopServer();\n if (!result.stopped) {\n console.log('Astra is not running.');\n return;\n }\n success(`Astra stopped (pid ${result.pid ?? '?'}).`);\n}\n\nexport async function runRestart(opts: StartArgs): Promise<void> {\n const status = await serverStatus();\n if (status.running || status.runtime) {\n console.log('Stopping Astra…');\n await stopServer();\n }\n await runStart(opts);\n}\n\nexport async function runStatus(): Promise<void> {\n const status = await serverStatus();\n if (!status.running) {\n if (status.staleRuntime) {\n console.log(style.dim('Removed a stale runtime.json (its process is gone).'));\n }\n console.log(`Astra is not running. Start it with ${style.cyan('astra start')}.`);\n process.exitCode = 1;\n return;\n }\n const rt = status.runtime;\n if (!rt) return; // unreachable: running implies runtime\n console.log('Astra is running');\n console.log(` URL ${style.cyan(status.base ?? '')}`);\n console.log(` PID ${rt.pid}`);\n const versionLine = [rt.version, rt.apiVersion ? `API ${rt.apiVersion}` : undefined]\n .filter(Boolean)\n .join(' · ');\n if (versionLine) console.log(` Version ${versionLine}`);\n if (rt.startedBy) {\n console.log(` Started by ${rt.startedBy}${rt.startedAt ? ` at ${rt.startedAt}` : ''}`);\n }\n // Update hint: prefer the server's cached feed status; any failure stays silent.\n if (status.base) {\n try {\n const r = await checkForServerUpdate({ currentVersion: VERSION, baseUrl: status.base, timeoutMs: 2000 });\n if (r.availableVersion) {\n console.log(` Update ${style.cyan(r.availableVersion)} available — run ${style.cyan('astra update')}`);\n }\n } catch {\n /* offline or feed not configured — not a status failure */\n }\n }\n}\n\nexport async function runLogs(opts: { follow?: boolean }): Promise<void> {\n const home = astraHome();\n const logFile = findNewestLog(home);\n console.error(style.dim(`# ${logFile}`));\n process.stdout.write(`${tailLines(logFile, 100)}\\n`);\n if (opts.follow) {\n console.error(style.dim('--- following (Ctrl+C to stop) ---'));\n const stop = followFile(logFile, (chunk) => process.stdout.write(chunk));\n process.on('SIGINT', () => {\n stop();\n process.exit(0);\n });\n await new Promise(() => {\n /* follow forever */\n });\n }\n}\n\nexport async function runOpen(): Promise<void> {\n const status = await serverStatus();\n if (!status.running || !status.base) {\n fail('Astra is not running.');\n info(`Start it with ${style.cyan('astra start --open')}.`);\n process.exitCode = 1;\n return;\n }\n openInBrowser(status.base);\n console.log(`Opened ${status.base}`);\n}\n","/**\n * The update feed manifest (latest.json). Same contract the Astra server\n * consumes in UpdateCheckService — camelCase JSON at\n * `<feedUrl>/<channel>/latest.json`.\n */\nexport interface UpdatePlatformInfo {\n /** npm package carrying the self-contained server binary for this platform. */\n server?: string;\n /** npm package carrying the desktop app (npm-track installs) for this platform. */\n desktop?: string;\n /** sha256 of the server binary inside the server package (hex). */\n serverSha256?: string;\n serverSize?: number;\n}\n\nexport interface UpdateManifest {\n version: string;\n apiVersion?: string;\n releasedAt?: string;\n notes?: string | null;\n minUpdateable?: string;\n platforms?: Record<string, UpdatePlatformInfo>;\n}\n\n/** Built-in feed location; overridable via the server's updateFeedUrl setting. */\nexport const DEFAULT_FEED_URL = 'https://astra-gate.si/api/client-releases';\n\nexport const DEFAULT_CHANNEL = 'stable';\n\nexport interface FetchManifestOptions {\n feedUrl?: string;\n channel?: string;\n /** Identifies the caller without leaking anything else, e.g. \"Astra/0.2.0\". */\n userAgent?: string;\n timeoutMs?: number;\n fetchImpl?: typeof fetch;\n}\n\nexport class UpdateFeedError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'UpdateFeedError';\n }\n}\n\nexport async function fetchManifest(o: FetchManifestOptions = {}): Promise<UpdateManifest> {\n const feed = (o.feedUrl ?? DEFAULT_FEED_URL).trim();\n const channel = (o.channel ?? DEFAULT_CHANNEL).trim() || DEFAULT_CHANNEL;\n const url = `${feed.replace(/\\/+$/, '')}/${channel}/latest.json`;\n const doFetch = o.fetchImpl ?? globalThis.fetch;\n if (!doFetch) throw new UpdateFeedError('fetch is unavailable (Node.js 18+ required).');\n let response: Response;\n try {\n response = await doFetch(url, {\n headers: {\n Accept: 'application/json',\n ...(o.userAgent ? { 'User-Agent': o.userAgent } : {}),\n },\n signal: AbortSignal.timeout(o.timeoutMs ?? 15_000),\n });\n } catch (err) {\n const reason = err instanceof Error ? (err.name === 'TimeoutError' || err.name === 'AbortError' ? 'timed out' : err.message) : String(err);\n throw new UpdateFeedError(`Cannot reach the update feed at ${url} (${reason}).`);\n }\n if (!response.ok) {\n throw new UpdateFeedError(`Update feed responded ${response.status} ${response.statusText} for ${url}.`);\n }\n let manifest: UpdateManifest;\n try {\n manifest = (await response.json()) as UpdateManifest;\n } catch (err) {\n throw new UpdateFeedError(`Update feed returned invalid JSON (${err instanceof Error ? err.message : String(err)}).`);\n }\n if (!manifest || typeof manifest.version !== 'string' || manifest.version.trim() === '') {\n throw new UpdateFeedError('Update manifest has no version.');\n }\n return manifest;\n}\n","/**\n * Version comparison helpers shared by the CLI and the desktop app.\n * Semver-shaped (major.minor.patch), tolerant of -prerelease and +build suffixes\n * which are ignored for ordering, mirroring the server's UpdateCheckService.IsNewer.\n */\nexport function parseVersion(v: string | null | undefined): [number, number, number] | null {\n if (!v) return null;\n const core = v\n .trim()\n .split('-', 1)[0]!\n .split('+', 1)[0]!\n .replace(/^v/, '');\n const m = /^(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?$/.exec(core);\n if (!m) return null;\n return [Number(m[1]), Number(m[2] ?? 0), Number(m[3] ?? 0)];\n}\n\n/** True when candidate is strictly newer than current; unparsable inputs never count as newer. */\nexport function isNewerVersion(candidate: string | null | undefined, current: string): boolean {\n const c = parseVersion(candidate);\n const cur = parseVersion(current);\n if (!c || !cur) return false;\n for (let i = 0; i < 3; i++) {\n const a = c[i]!;\n const b = cur[i]!;\n if (a !== b) return a > b;\n }\n return false;\n}\n\n/** Returns the MAJOR part of a version-ish string like \"1.4\" or \"2\", or null. */\nexport function majorOf(v: string | null | undefined): number | null {\n const m = /^\\s*(\\d+)(?:\\.|$)/.exec(v ?? '');\n const group = m?.[1];\n return group ? Number.parseInt(group, 10) : null;\n}\n\n/**\n * The desktop/CLI expect the server's apiVersion to stay within the same major.\n * A different major means the two builds are out of sync and only a manual,\n * confirmed update is allowed.\n */\nexport function isApiVersionCompatible(\n serverApiVersion: string | null | undefined,\n expectedMajor: number,\n): boolean {\n const major = majorOf(serverApiVersion);\n return major !== null && major === expectedMajor;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\n/** Executor phases; persisted verbatim so the CLI, desktop app and UI can render progress. */\nexport type UpdatePhase =\n | 'idle'\n | 'checking'\n | 'downloading'\n | 'swapping'\n | 'restarting'\n | 'rolling-back'\n | 'failed';\n\nexport interface UpdateState {\n phase: UpdatePhase;\n /** Version we are moving to (absent on idle). */\n targetVersion?: string;\n /** Version we started from. */\n previousVersion?: string;\n /** Human-readable detail for the UI (\"verifying checksum…\"). */\n step?: string;\n /** Last failure message; null/absent on success. */\n error?: string | null;\n /** Consecutive failed runs; reaching the cap locks out further automatic attempts. */\n failedCount: number;\n updatedAt: string;\n}\n\n/** After this many consecutive failed runs, `astra update` requires --retry to try again. */\nexport const MAX_CONSECUTIVE_FAILURES = 2;\n\nconst KNOWN_PHASES: readonly UpdatePhase[] = [\n 'idle',\n 'checking',\n 'downloading',\n 'swapping',\n 'restarting',\n 'rolling-back',\n 'failed',\n];\n\nexport function initialState(now: () => Date = () => new Date()): UpdateState {\n return { phase: 'idle', failedCount: 0, updatedAt: now().toISOString() };\n}\n\n/** Tolerant read: a missing, empty or corrupt state file is treated as \"no state\". */\nexport function readUpdateState(file: string): UpdateState | null {\n let text: string;\n try {\n text = fs.readFileSync(file, 'utf8');\n } catch {\n return null;\n }\n if (!text.trim()) return null;\n try {\n const raw = JSON.parse(text) as Partial<UpdateState> | null;\n if (!raw || typeof raw !== 'object' || !KNOWN_PHASES.includes(raw.phase as UpdatePhase)) return null;\n return {\n phase: raw.phase as UpdatePhase,\n ...(raw.targetVersion !== undefined ? { targetVersion: raw.targetVersion } : {}),\n ...(raw.previousVersion !== undefined ? { previousVersion: raw.previousVersion } : {}),\n ...(raw.step !== undefined ? { step: raw.step } : {}),\n ...(raw.error !== undefined ? { error: raw.error } : {}),\n failedCount: typeof raw.failedCount === 'number' ? raw.failedCount : 0,\n updatedAt: typeof raw.updatedAt === 'string' ? raw.updatedAt : new Date().toISOString(),\n };\n } catch {\n return null;\n }\n}\n\n/** Write via tmp + rename so a crash mid-write never leaves a half file behind. */\nexport function writeUpdateState(file: string, state: UpdateState, now: () => Date = () => new Date()): void {\n const payload: UpdateState = { ...state, updatedAt: now().toISOString() };\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const tmp = `${file}.tmp`;\n fs.writeFileSync(tmp, `${JSON.stringify(payload, null, 2)}\\n`);\n fs.renameSync(tmp, file);\n}\n","import path from 'node:path';\n\n/**\n * Filesystem layout of everything the updater owns, all under the Astra home\n * (ASTRA_HOME or ~/.astra). The update state file lives here too because the\n * executor may run while the server is stopped — it can never live in the DB.\n */\nexport interface UpdatePaths {\n /** Staging area for npm installs that are not yet trusted. */\n stagingDir: string;\n /** Rolling binary backups (server/ and desktop/ subdirectories). */\n backupsDir: string;\n /** Managed server binaries: ~/.astra/server/astra-server-<version>[.exe]. */\n serverDir: string;\n /** Persistent executor state: ~/.astra/update-state.json. */\n stateFile: string;\n}\n\nexport function updatePaths(home: string): UpdatePaths {\n return {\n stagingDir: path.join(home, 'updates', 'staging'),\n backupsDir: path.join(home, 'backups'),\n serverDir: path.join(home, 'server'),\n stateFile: path.join(home, 'update-state.json'),\n };\n}\n\n/** The authoritative server binary lives in serverDir, never inside node_modules. */\nexport function managedServerBinaryPath(serverDir: string, version: string, platform: string): string {\n return path.join(serverDir, `astra-server-${version}${platform === 'win32' ? '.exe' : ''}`);\n}\n","import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\n/**\n * Locates and drives the system npm. Shared by the CLI and the desktop app;\n * from Electron the main process executable is NOT node, so prefix-based\n * discovery is skipped and PATH (plus well-known prefixes) is used instead.\n */\nexport interface NpmCommand {\n command: string;\n args: string[];\n}\n\nexport interface LocateNpmOptions {\n env?: NodeJS.ProcessEnv;\n platform?: string;\n execPath?: string;\n /** Resolve through the user's login shell when PATH lookups fail (GUI processes). */\n allowShellResolve?: boolean;\n}\n\nexport function locateNpm(o: LocateNpmOptions = {}): NpmCommand {\n const env = o.env ?? process.env;\n const platform = o.platform ?? process.platform;\n const execPath = o.execPath ?? process.execPath;\n const isNode = /^node(\\.exe)?$/i.test(path.basename(execPath));\n\n if (isNode) {\n const found = npmBesideNode(execPath, platform);\n if (found) return found;\n }\n\n // Well-known absolute locations cover GUI processes whose PATH is minimal.\n const home = env.HOME ?? '';\n const candidates =\n platform === 'win32'\n ? [path.join(process.env.APPDATA ?? path.join(home, 'AppData', 'Roaming'), 'npm', 'npm.cmd')]\n : ['/opt/homebrew/bin/npm', '/usr/local/bin/npm', '/usr/bin/npm'];\n for (const candidate of candidates) {\n if (candidate && fs.existsSync(candidate)) return { command: candidate, args: [] };\n }\n\n return { command: platform === 'win32' ? 'npm.cmd' : 'npm', args: [] };\n}\n\nfunction npmBesideNode(execPath: string, platform: string): NpmCommand | null {\n const execDir = path.dirname(execPath);\n const prefix = platform === 'win32' ? execDir : path.basename(execDir) === 'bin' ? path.dirname(execDir) : execDir;\n const cli = path.join(prefix, 'lib', 'node_modules', 'npm', 'bin', 'npm-cli.js');\n if (fs.existsSync(cli)) return { command: execPath, args: [cli] };\n return null;\n}\n\nfunction usesShell(command: string, platform: string): boolean {\n return platform === 'win32' && command.endsWith('.cmd');\n}\n\nexport interface RunCaptureOptions {\n timeoutMs?: number;\n env?: NodeJS.ProcessEnv;\n}\n\ninterface RunResult {\n code: number | null;\n stdout: string;\n stderr: string;\n}\n\nfunction runCapture(command: string, args: readonly string[], o: RunCaptureOptions & { platform?: string } = {}): Promise<RunResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, [...args], {\n env: o.env,\n windowsHide: true,\n shell: usesShell(command, o.platform ?? process.platform),\n });\n let stdout = '';\n let stderr = '';\n let settled = false;\n const timer = o.timeoutMs\n ? setTimeout(() => {\n settled = true;\n try {\n child.kill('SIGKILL');\n } catch {\n /* ignore */\n }\n reject(new Error(`Command timed out after ${o.timeoutMs}ms: ${command} ${args.join(' ')}`));\n }, o.timeoutMs)\n : null;\n child.stdout?.on('data', (d: Buffer) => {\n stdout += d.toString();\n });\n child.stderr?.on('data', (d: Buffer) => {\n stderr += d.toString();\n });\n child.on('error', (err) => {\n if (timer) clearTimeout(timer);\n if (!settled) reject(err);\n });\n child.on('close', (code) => {\n if (timer) clearTimeout(timer);\n if (!settled) resolve({ code, stdout, stderr });\n });\n });\n}\n\nexport interface NpmRunnerOptions {\n env?: NodeJS.ProcessEnv;\n platform?: string;\n execPath?: string;\n npm?: NpmCommand;\n /** Default 10 minutes — platform packages are 80-120 MB. */\n installTimeoutMs?: number;\n}\n\nfunction npmCommand(o: NpmRunnerOptions): NpmCommand {\n return o.npm ?? locateNpm(o);\n}\n\n/** `npm install --prefix <prefix> <spec>` — the primitive behind staging and desktop installs. */\nexport async function npmInstallIntoPrefix(prefix: string, spec: string, o: NpmRunnerOptions = {}): Promise<void> {\n const npm = npmCommand(o);\n const r = await runCapture(\n npm.command,\n [...npm.args, 'install', '--prefix', prefix, '--no-audit', '--no-fund', '--loglevel', 'error', spec],\n { env: o.env, platform: o.platform, timeoutMs: o.installTimeoutMs ?? 600_000 },\n );\n if (r.code !== 0) {\n throw new Error(`Failed to install ${spec}: ${r.stderr.trim() || `npm exited with code ${r.code}`}`);\n }\n}\n\n/** Best-effort `npm view <pkg> <field>`; throws on failure. */\nexport async function npmView(pkg: string, field: string, o: NpmRunnerOptions = {}): Promise<string> {\n const npm = npmCommand(o);\n const r = await runCapture(npm.command, [...npm.args, 'view', pkg, field, '--loglevel', 'error'], {\n env: o.env,\n platform: o.platform,\n timeoutMs: 60_000,\n });\n if (r.code !== 0) throw new Error(r.stderr.trim() || 'npm view failed');\n return r.stdout.trim();\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\n/**\n * install.json (~/.astra/install.json) is the cross-process anchor: the CLI\n * writes it, the desktop app reads it, and after an update it is what makes\n * both resolvers pick the new managed binary. Shape matches the CLI's\n * InstallJson exactly.\n */\nexport interface InstallInfo {\n serverPath?: string;\n serverVersion?: string;\n desktopPath?: string;\n desktopVersion?: string;\n updatedAt?: string;\n}\n\nexport function readInstallInfo(home: string): InstallInfo | null {\n let text: string;\n try {\n text = fs.readFileSync(path.join(home, 'install.json'), 'utf8');\n } catch {\n return null;\n }\n if (!text.trim()) return null;\n try {\n const raw = JSON.parse(text) as Record<string, unknown> | null;\n if (!raw || typeof raw !== 'object') return null;\n const info: InstallInfo = {};\n for (const key of ['serverPath', 'serverVersion', 'desktopPath', 'desktopVersion', 'updatedAt'] as const) {\n const v = raw[key];\n if (typeof v === 'string' && v.length > 0) info[key] = v;\n }\n return info;\n } catch {\n return null;\n }\n}\n\nexport function writeInstallInfo(home: string, info: InstallInfo): void {\n const file = path.join(home, 'install.json');\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(file, `${JSON.stringify(info, null, 2)}\\n`);\n}\n\nexport function applyServerInfo(existing: InstallInfo | null, server: { serverPath: string; serverVersion?: string }): InstallInfo {\n return {\n ...(existing ?? {}),\n serverPath: server.serverPath,\n ...(server.serverVersion ? { serverVersion: server.serverVersion } : {}),\n updatedAt: new Date().toISOString(),\n };\n}\n","import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { npmInstallIntoPrefix, type NpmRunnerOptions } from './npm-runner.js';\n\n/** sha256 of a file, hex-encoded (streamed — binaries are ~90 MB). */\nexport function sha256File(file: string): string {\n const hash = createHash('sha256');\n hash.update(fs.readFileSync(file));\n return hash.digest('hex');\n}\n\nexport interface StagedServerBinary {\n path: string;\n version: string;\n}\n\nexport interface StageServerBinaryOptions {\n home: string;\n stagingDir: string;\n serverPackage: string;\n version: string;\n /** Expected sha256 (hex) from the manifest; null skips verification. */\n sha256?: string | null;\n platform: string;\n npm?: NpmRunnerOptions;\n /** Test seam — defaults to the real npm runner. */\n installIntoPrefix?: (prefix: string, spec: string) => Promise<void>;\n log?: (line: string) => void;\n}\n\n/**\n * Downloads the server platform package into the staging prefix and verifies\n * the binary checksum BEFORE anything on the running installation is touched.\n * Staging is wiped on every run, so a failed run never leaves stale artifacts.\n */\nexport async function stageServerBinary(o: StageServerBinaryOptions): Promise<StagedServerBinary> {\n const install = o.installIntoPrefix ?? npmInstallIntoPrefix;\n fs.rmSync(o.stagingDir, { recursive: true, force: true });\n fs.mkdirSync(o.stagingDir, { recursive: true });\n o.log?.(`Downloading ${o.serverPackage}@${o.version}…`);\n await install(o.stagingDir, `${o.serverPackage}@${o.version}`);\n\n const binaryName = o.platform === 'win32' ? 'astra-server.exe' : 'astra-server';\n const staged = path.join(o.stagingDir, 'node_modules', ...o.serverPackage.split('/'), 'bin', binaryName);\n if (!fs.existsSync(staged)) {\n fs.rmSync(o.stagingDir, { recursive: true, force: true });\n throw new Error(`The staged package does not contain a server binary (${staged}).`);\n }\n if (o.sha256) {\n o.log?.('Verifying checksum…');\n const actual = sha256File(staged);\n if (actual.toLowerCase() !== o.sha256.toLowerCase()) {\n fs.rmSync(o.stagingDir, { recursive: true, force: true });\n throw new Error(`Checksum mismatch for the staged server binary (expected ${o.sha256}, got ${actual}).`);\n }\n }\n return { path: staged, version: o.version };\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { managedServerBinaryPath } from './paths.js';\n\n/** Rolling backups: keep this many per subject (server / desktop). */\nexport const MAX_BACKUPS = 3;\n\n/**\n * Copies the currently installed binary into backupsDir before anything is\n * replaced. Returns the backup path, or null when there is nothing to back up.\n * The copy is the last-resort rollback anchor — the primary rollback mechanism\n * is repointing install.json at the previous path, which is never deleted.\n */\nexport function backupCurrentBinary(o: {\n currentPath: string | null;\n backupsDir: string;\n currentVersion?: string | null;\n kind?: 'server' | 'desktop';\n platform?: string;\n maxBackups?: number;\n}): string | null {\n if (!o.currentPath || !fs.existsSync(o.currentPath)) return null;\n const kind = o.kind ?? 'server';\n const dir = path.join(o.backupsDir, kind);\n fs.mkdirSync(dir, { recursive: true });\n const ext = o.platform === 'win32' ? '.exe' : '';\n const stamp = o.currentVersion ? `-${o.currentVersion}` : `-${new Date().toISOString().replace(/[:.]/g, '-')}`;\n const backupPath = path.join(dir, `astra-server${stamp}${ext}`);\n fs.copyFileSync(o.currentPath, backupPath);\n pruneBackups(dir, o.maxBackups ?? MAX_BACKUPS);\n return backupPath;\n}\n\n/** Removes the oldest entries beyond `keep` (by filename sort — version names sort correctly). */\nexport function pruneBackups(dir: string, keep: number = MAX_BACKUPS): void {\n let entries: string[] = [];\n try {\n entries = fs.readdirSync(dir).sort();\n } catch {\n return;\n }\n const excess = entries.length - keep;\n for (let i = 0; i < excess; i++) {\n try {\n fs.rmSync(path.join(dir, entries[i]!), { force: true });\n } catch {\n /* best effort */\n }\n }\n}\n\nexport interface InstallManagedBinaryOptions {\n stagedPath: string;\n serverDir: string;\n version: string;\n platform: string;\n}\n\n/**\n * Copies the verified staged binary to its managed, version-suffixed home\n * (~/.astra/server/astra-server-<version>). A fresh file per version means\n * Windows file locks on a running binary are never an issue, and install.json\n * is what makes both resolvers pick this one after the restart.\n */\nexport function installManagedBinary(o: InstallManagedBinaryOptions): string {\n const target = managedServerBinaryPath(o.serverDir, o.version, o.platform);\n fs.mkdirSync(o.serverDir, { recursive: true });\n const tmp = `${target}.tmp`;\n fs.copyFileSync(o.stagedPath, tmp);\n fs.renameSync(tmp, target);\n if (o.platform !== 'win32') fs.chmodSync(target, 0o755);\n return target;\n}\n\n/**\n * Removes managed binaries older than `keep` versions. Never removes the\n * current target; failures are ignored (a leftover old binary is harmless).\n */\nexport function pruneManagedBinaries(serverDir: string, currentTarget: string, keep: number = 2): void {\n let entries: string[] = [];\n try {\n entries = fs.readdirSync(serverDir).filter((f) => /^astra-server-\\d/.test(f));\n } catch {\n return;\n }\n const excess = entries.filter((f) => path.join(serverDir, f) !== currentTarget).length - keep;\n for (let i = 0; i < Math.max(0, excess); i++) {\n try {\n fs.rmSync(path.join(serverDir, entries[i]!), { force: true });\n } catch {\n /* best effort */\n }\n }\n}\n\n/**\n * The server serves the web UI from `wwwroot` beside its own executable\n * (AstraApp: AppContext.BaseDirectory), so a managed binary in serverDir needs\n * serverDir/wwwroot. Replaces it with the copy shipped next to `binaryPath`\n * (bin/wwwroot in the platform package); the previous copy is kept as\n * wwwroot.prev until commitManagedWebRoot / restoreManagedWebRoot. Returns\n * false, touching nothing, when the package ships no wwwroot.\n */\nexport function installManagedWebRoot(binaryPath: string, serverDir: string): boolean {\n const src = path.join(path.dirname(binaryPath), 'wwwroot');\n if (!fs.existsSync(src)) return false;\n const dest = path.join(serverDir, 'wwwroot');\n const tmp = `${dest}.tmp`;\n const prev = `${dest}.prev`;\n fs.mkdirSync(serverDir, { recursive: true });\n fs.rmSync(tmp, { recursive: true, force: true });\n fs.cpSync(src, tmp, { recursive: true });\n fs.rmSync(prev, { recursive: true, force: true });\n if (fs.existsSync(dest)) fs.renameSync(dest, prev);\n fs.renameSync(tmp, dest);\n return true;\n}\n\n/** Drops the wwwroot.prev kept by installManagedWebRoot once the update stuck. */\nexport function commitManagedWebRoot(serverDir: string): void {\n fs.rmSync(path.join(serverDir, 'wwwroot.prev'), { recursive: true, force: true });\n}\n\n/** Undoes installManagedWebRoot: puts wwwroot.prev back (no-op without one). */\nexport function restoreManagedWebRoot(serverDir: string): void {\n const dest = path.join(serverDir, 'wwwroot');\n const prev = `${dest}.prev`;\n if (!fs.existsSync(prev)) return;\n fs.rmSync(dest, { recursive: true, force: true });\n fs.renameSync(prev, dest);\n}\n","import {\n applyServerInfo,\n readInstallInfo,\n writeInstallInfo,\n type InstallInfo,\n} from './install-info.js';\nimport fs from 'node:fs';\nimport type { UpdateManifest } from './manifest.js';\nimport { updatePaths } from './paths.js';\nimport type { NpmRunnerOptions } from './npm-runner.js';\nimport {\n MAX_CONSECUTIVE_FAILURES,\n initialState,\n readUpdateState,\n writeUpdateState,\n type UpdateState,\n} from './state.js';\nimport { stageServerBinary } from './staging.js';\nimport {\n backupCurrentBinary,\n commitManagedWebRoot,\n installManagedBinary,\n installManagedWebRoot,\n pruneManagedBinaries,\n restoreManagedWebRoot,\n} from './swap.js';\nimport { isApiVersionCompatible, isNewerVersion } from './version.js';\n\nexport class UpdateError extends Error {\n constructor(\n message: string,\n readonly hint?: string,\n ) {\n super(message);\n this.name = 'UpdateError';\n }\n}\n\n/** Process controls the orchestrator needs — implemented over the existing lifecycle helpers. */\nexport interface ServerControl {\n isRunning(): Promise<boolean>;\n stop(): Promise<void>;\n start(): Promise<void>;\n /** Version the server reports after (re)start; null counts as a failed restart. */\n probeVersion(): Promise<string | null>;\n}\n\nexport interface ApplyServerUpdateOptions {\n home: string;\n manifest: UpdateManifest;\n /** Key into manifest.platforms, e.g. \"darwin-arm64\". */\n platformKey: string;\n /** Used when the manifest does not name a server package for this platform. */\n serverPackage: string;\n /** process.platform-style value, decides the .exe suffix. */\n platform: string;\n currentServerPath: string | null;\n currentVersion: string;\n expectedApiMajor: number;\n control: ServerControl;\n npm?: NpmRunnerOptions;\n /** Test seam — replaces the npm runner inside the staging step. */\n installIntoPrefix?: (prefix: string, spec: string) => Promise<void>;\n /** Retry despite the consecutive-failure lock. */\n force?: boolean;\n log?: (line: string) => void;\n now?: () => Date;\n}\n\nexport interface ApplyServerUpdateResult {\n from: string;\n to: string;\n serverPath: string;\n}\n\n/**\n * The staged-swap state machine (plan §P2):\n * downloading → swapping → restarting → idle\n * with a rollback leg that repoints install.json at the previous binary and\n * restarts. Every phase transition is persisted to ~/.astra/update-state.json\n * so the UI/tray can render progress across process boundaries.\n *\n * Safety rails:\n * - refuses when the manifest is not newer, or its apiVersion major differs\n * from the running client's expectation (a half-updated pair is worse than\n * an old pair);\n * - refuses after MAX_CONSECUTIVE_FAILURES failed runs unless `force`;\n * - the new binary lands on a fresh version-suffixed path, so nothing running\n * is ever replaced in place (Windows file locks stay irrelevant).\n */\nexport async function applyServerUpdate(o: ApplyServerUpdateOptions): Promise<ApplyServerUpdateResult> {\n const paths = updatePaths(o.home);\n const log = o.log ?? (() => {});\n const now = o.now ?? (() => new Date());\n\n const state: UpdateState = readUpdateState(paths.stateFile) ?? initialState(now);\n if (!o.force && state.failedCount >= MAX_CONSECUTIVE_FAILURES) {\n throw new UpdateError(\n `The last ${state.failedCount} update attempts failed. Fix the problem and run the update with --retry.`,\n state.error ?? undefined,\n );\n }\n if (!isNewerVersion(o.manifest.version, o.currentVersion)) {\n throw new UpdateError(`Already on version ${o.currentVersion} (${o.manifest.version} is not newer).`);\n }\n if (o.manifest.apiVersion && !isApiVersionCompatible(o.manifest.apiVersion, o.expectedApiMajor)) {\n throw new UpdateError(\n `The update targets API major ${o.manifest.apiVersion} but this client expects ${o.expectedApiMajor}. ` +\n 'Update the whole Astra install manually (npm install -g astragate).',\n );\n }\n\n const setState = (phase: UpdateState['phase'], step?: string, error?: string | null): void => {\n writeUpdateState(\n paths.stateFile,\n {\n ...state,\n phase,\n targetVersion: o.manifest.version,\n previousVersion: o.currentVersion,\n ...(step !== undefined ? { step } : {}),\n ...(error !== undefined ? { error } : { error: null }),\n failedCount: state.failedCount,\n },\n now,\n );\n };\n\n const previousInstall = readInstallInfo(o.home);\n let swapped = false;\n let webRootSwapped = false;\n let backupPath: string | null = null;\n\n try {\n setState('downloading', 'downloading');\n const platformInfo = o.manifest.platforms?.[o.platformKey];\n const staged = await stageServerBinary({\n home: o.home,\n stagingDir: paths.stagingDir,\n serverPackage: platformInfo?.server ?? o.serverPackage,\n version: o.manifest.version,\n sha256: platformInfo?.serverSha256 ?? null,\n platform: o.platform,\n npm: o.npm,\n installIntoPrefix: o.installIntoPrefix,\n log,\n });\n\n setState('swapping', 'swapping');\n const wasRunning = await o.control.isRunning();\n backupPath = backupCurrentBinary({\n currentPath: o.currentServerPath,\n backupsDir: paths.backupsDir,\n currentVersion: o.currentVersion,\n platform: o.platform,\n });\n if (backupPath) log(`Backed up the current binary to ${backupPath}`);\n const serverPath = installManagedBinary({\n stagedPath: staged.path,\n serverDir: paths.serverDir,\n version: o.manifest.version,\n platform: o.platform,\n });\n writeInstallInfo(o.home, applyServerInfo(previousInstall, { serverPath, serverVersion: o.manifest.version }));\n pruneManagedBinaries(paths.serverDir, serverPath);\n swapped = true;\n\n setState('restarting', 'restarting');\n if (wasRunning) {\n log('Restarting the Astra server…');\n await o.control.stop();\n }\n // The web UI is read from wwwroot beside the binary; swap it while the\n // server is down (no open handles on Windows). Best effort: a failure\n // leaves the previous UI in place rather than failing the update.\n try {\n webRootSwapped = installManagedWebRoot(staged.path, paths.serverDir);\n } catch (err) {\n log(`Could not update the web UI files: ${err instanceof Error ? err.message : String(err)}`);\n }\n await o.control.start();\n const reported = await o.control.probeVersion();\n if (reported !== o.manifest.version) {\n throw new UpdateError(\n `The server reports ${reported ?? 'no version'} after the restart; expected ${o.manifest.version}.`,\n );\n }\n\n // Success: free the ~90 MB staging prefix immediately (it is wiped on the next run anyway).\n fs.rmSync(paths.stagingDir, { recursive: true, force: true });\n if (webRootSwapped) commitManagedWebRoot(paths.serverDir);\n writeUpdateState(paths.stateFile, { ...initialState(now), phase: 'idle' }, now);\n log(`Astra updated to ${o.manifest.version}.`);\n return { from: o.currentVersion, to: o.manifest.version, serverPath };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n setState('rolling-back', 'rolling-back', message);\n if (swapped) await rollback(o, previousInstall, backupPath, webRootSwapped, setState, log);\n const failed: UpdateState = {\n phase: 'failed',\n targetVersion: o.manifest.version,\n previousVersion: o.currentVersion,\n error: message,\n failedCount: state.failedCount + 1,\n updatedAt: now().toISOString(),\n };\n writeUpdateState(paths.stateFile, failed, now);\n throw err instanceof UpdateError ? err : new UpdateError(message);\n }\n}\n\nasync function rollback(\n o: ApplyServerUpdateOptions,\n previousInstall: InstallInfo | null,\n backupPath: string | null,\n webRootSwapped: boolean,\n setState: (phase: UpdateState['phase'], step?: string, error?: string | null) => void,\n log: (line: string) => void,\n): Promise<void> {\n const restorePath = previousInstall?.serverPath ?? backupPath;\n try {\n if (restorePath) {\n log(`Rolling back to ${restorePath}`);\n writeInstallInfo(o.home, applyServerInfo(previousInstall, { serverPath: restorePath }));\n }\n if (await o.control.isRunning()) await o.control.stop();\n if (webRootSwapped) restoreManagedWebRoot(updatePaths(o.home).serverDir);\n await o.control.start();\n } catch (rollbackErr) {\n setState('failed', undefined, `Rollback failed: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);\n log('Rollback failed — see the server log. `astra restore-all` still works offline.');\n }\n}\n","import { DEFAULT_CHANNEL, DEFAULT_FEED_URL, fetchManifest, type UpdateManifest } from './manifest.js';\nimport { isNewerVersion } from './version.js';\n\nexport interface ServerUpdateStatus {\n current?: string;\n available?: string | null;\n lastCheckAt?: string | null;\n notes?: string | null;\n error?: string | null;\n channel?: string;\n autoCheck?: boolean;\n feedConfigured?: boolean;\n}\n\n/**\n * Checks for a server update. Prefers the running server's /api/update/status\n * (it caches feed results and works even when the feed is unreachable from the\n * client machine); falls back to fetching the manifest directly.\n */\nexport async function checkForServerUpdate(o: {\n currentVersion: string;\n /** Base URL of the running server, e.g. http://127.0.0.1:17321. */\n baseUrl?: string;\n feedUrl?: string;\n channel?: string;\n timeoutMs?: number;\n fetchImpl?: typeof fetch;\n userAgent?: string;\n}): Promise<{ availableVersion: string | null; notes: string | null; source: 'server' | 'feed'; manifest?: UpdateManifest }> {\n const doFetch = o.fetchImpl ?? globalThis.fetch;\n if (o.baseUrl && doFetch) {\n try {\n const res = await doFetch(`${o.baseUrl.replace(/\\/+$/, '')}/api/update/status`, {\n signal: AbortSignal.timeout(o.timeoutMs ?? 3_000),\n });\n if (res.ok) {\n const status = (await res.json()) as ServerUpdateStatus;\n return {\n availableVersion: status.available ?? null,\n notes: status.notes ?? null,\n source: 'server',\n };\n }\n } catch {\n /* fall through to the feed */\n }\n }\n\n const manifest = await fetchManifest({\n feedUrl: o.feedUrl ?? DEFAULT_FEED_URL,\n channel: o.channel ?? DEFAULT_CHANNEL,\n timeoutMs: o.timeoutMs,\n fetchImpl: o.fetchImpl,\n userAgent: o.userAgent,\n });\n return {\n availableVersion: isNewerVersion(manifest.version, o.currentVersion) ? manifest.version : null,\n notes: manifest.notes ?? null,\n source: 'feed',\n manifest,\n };\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { npmInstallIntoPrefix, type NpmRunnerOptions } from './npm-runner.js';\n\n/**\n * Desktop-app installs for the npm track (Windows, Linux, and macOS installs\n * managed by `astra install --desktop`): an npm prefix under ~/.astra/desktop\n * holds @aidotnet/desktop-<platform>, and a per-OS launcher points at it.\n * Ported from the CLI's lib/desktop.ts so the desktop app can run the very\n * same flow when it drives updates itself.\n */\nexport type SupportedPlatform = 'darwin' | 'linux' | 'win32';\n\nexport interface DesktopEntry {\n path: string;\n isBundle: boolean;\n}\n\nfunction walkFiles(dir: string, depth: number): string[] {\n if (depth < 0) return [];\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return [];\n }\n const out: string[] = [];\n for (const e of entries) {\n const full = path.join(dir, e.name);\n if (e.isDirectory()) out.push(...walkFiles(full, depth - 1));\n else if (e.isFile()) out.push(full);\n }\n return out;\n}\n\nfunction walkDirs(dir: string, depth: number): string[] {\n if (depth < 0) return [];\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return [];\n }\n const out: string[] = [];\n for (const e of entries) {\n if (e.isDirectory()) {\n const full = path.join(dir, e.name);\n out.push(full, ...walkDirs(full, depth - 1));\n }\n }\n return out;\n}\n\n/** Locate the launchable inside <desktopPrefix>/node_modules/<pkg>/app. */\nexport function findDesktopEntry(appDir: string, platform: SupportedPlatform): DesktopEntry {\n if (!fs.existsSync(appDir)) {\n throw new Error(`The desktop package does not contain an app directory (${appDir}).`);\n }\n if (platform === 'darwin') {\n const bundles = walkDirs(appDir, 4)\n .filter((d) => d.endsWith('.app'))\n .sort((a, b) => a.length - b.length);\n const first = bundles[0];\n if (first) return { path: first, isBundle: true };\n throw new Error('Could not find the .app bundle inside the desktop package.');\n }\n const exes = walkFiles(appDir, 3)\n .filter((f) => (platform === 'win32' ? /\\.exe$/i.test(f) : !/\\.(so|png|json|sh|txt|desktop)$/i.test(f)))\n .filter((f) => {\n if (platform === 'win32') return !/(crashpad|installer|unins|squirrel)/i.test(f);\n try {\n fs.accessSync(f, fs.constants.X_OK);\n return true;\n } catch {\n return false;\n }\n })\n .sort((a, b) => a.split(path.sep).length - b.split(path.sep).length || a.length - b.length);\n const first = exes[0];\n if (first) return { path: first, isBundle: false };\n throw new Error('Could not find the desktop executable inside the desktop package.');\n}\n\nexport function macLauncherTarget(home: string = ''): string {\n return path.join(home, 'Applications', 'Astra.app');\n}\n\nexport function winLauncherTarget(home: string, env: NodeJS.ProcessEnv = process.env): string {\n const base = env.APPDATA || path.join(home, 'AppData', 'Roaming');\n return path.join(base, 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Astra.lnk');\n}\n\nexport function linuxLauncherTarget(home: string): string {\n return path.join(home, '.local', 'share', 'applications', 'astra.desktop');\n}\n\nexport function renderLinuxDesktopFile(exePath: string): string {\n return `[Desktop Entry]\nType=Application\nName=Astra\nComment=Local AI gateway\nExec=${exePath}\nTerminal=false\nCategories=Development;Network;\n`;\n}\n\nfunction runCapture(command: string, args: readonly string[], timeoutMs: number): Promise<{ code: number | null; stderr: string }> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, [...args], { stdio: 'ignore', windowsHide: true, shell: command.endsWith('.cmd') });\n let settled = false;\n const timer = setTimeout(() => {\n settled = true;\n reject(new Error(`${command} timed out`));\n }, timeoutMs);\n child.on('error', (err) => {\n clearTimeout(timer);\n if (!settled) reject(err);\n });\n child.on('close', (code) => {\n clearTimeout(timer);\n if (!settled) resolve({ code, stderr: '' });\n });\n });\n}\n\n/** Symlink (macOS) / shortcut (Windows) / .desktop file (Linux) pointing at the installed app. */\nexport async function createLauncher(\n entry: DesktopEntry,\n platform: SupportedPlatform,\n home: string,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<string> {\n if (platform === 'darwin') {\n const target = macLauncherTarget(home);\n fs.mkdirSync(path.dirname(target), { recursive: true });\n fs.rmSync(target, { force: true, recursive: true });\n fs.symlinkSync(entry.path, target, 'dir');\n return target;\n }\n if (platform === 'win32') {\n const target = winLauncherTarget(home, env);\n fs.mkdirSync(path.dirname(target), { recursive: true });\n const esc = (s: string): string => s.replace(/'/g, \"''\");\n const ps =\n `$s=(New-Object -ComObject WScript.Shell).CreateShortcut('${esc(target)}');` +\n `$s.TargetPath='${esc(entry.path)}';$s.Save()`;\n const r = await runCapture('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', ps], 60_000);\n if (r.code !== 0) throw new Error('Failed to create the Start Menu shortcut.');\n return target;\n }\n const target = linuxLauncherTarget(home);\n fs.mkdirSync(path.dirname(target), { recursive: true });\n fs.writeFileSync(target, renderLinuxDesktopFile(entry.path));\n return target;\n}\n\nexport function removeLauncher(platform: SupportedPlatform, home: string, env: NodeJS.ProcessEnv = process.env): void {\n if (platform === 'darwin') {\n const target = macLauncherTarget(home);\n try {\n const st = fs.lstatSync(target);\n if (st.isSymbolicLink()) fs.rmSync(target);\n } catch {\n /* absent */\n }\n return;\n }\n const target = platform === 'win32' ? winLauncherTarget(home, env) : linuxLauncherTarget(home);\n fs.rmSync(target, { force: true });\n}\n\nexport interface InstalledDesktop {\n path: string;\n version: string;\n launcher: string;\n}\n\nexport interface InstallDesktopClientOptions {\n home: string;\n version: string;\n desktopPackage: string;\n platform: SupportedPlatform;\n npm?: NpmRunnerOptions;\n log?: (line: string) => void;\n}\n\n/** Installs (or replaces) the desktop app under the npm prefix and refreshes the launcher. */\nexport async function installDesktopClient(o: InstallDesktopClientOptions): Promise<InstalledDesktop> {\n const prefix = path.join(o.home, 'desktop');\n const spec = `${o.desktopPackage}@${o.version}`;\n o.log?.(`Installing ${spec} (this may take a minute)…`);\n await npmInstallIntoPrefix(prefix, spec, o.npm);\n const pkgDir = path.join(prefix, 'node_modules', ...o.desktopPackage.split('/'));\n const entry = findDesktopEntry(path.join(pkgDir, 'app'), o.platform);\n const launcher = await createLauncher(entry, o.platform, o.home, o.npm?.env);\n let version = o.version;\n try {\n const pkg = JSON.parse(fs.readFileSync(path.join(pkgDir, 'package.json'), 'utf8')) as { version?: string };\n version = pkg.version ?? version;\n } catch {\n /* keep the requested version */\n }\n return { path: entry.path, version, launcher };\n}\n","import os from 'node:os';\nimport path from 'node:path';\n\nexport interface HomePaths {\n home: string;\n configFile: string;\n runtimeFile: string;\n installFile: string;\n logsDir: string;\n serverStdoutLog: string;\n dbFile: string;\n keysDir: string;\n desktopPrefix: string;\n}\n\n/** Data directory: ASTRA_HOME if set, else ~/.astra */\nexport function astraHome(env: NodeJS.ProcessEnv = process.env): string {\n const override = env.ASTRA_HOME?.trim();\n return override ? override : path.join(os.homedir(), '.astra');\n}\n\nexport function homePaths(home: string): HomePaths {\n return {\n home,\n configFile: path.join(home, 'config.json'),\n runtimeFile: path.join(home, 'runtime.json'),\n installFile: path.join(home, 'install.json'),\n logsDir: path.join(home, 'logs'),\n serverStdoutLog: path.join(home, 'logs', 'server-stdout.log'),\n dbFile: path.join(home, 'astra.db'),\n keysDir: path.join(home, 'keys'),\n desktopPrefix: path.join(home, 'desktop'),\n };\n}\n","import { spawn } from 'node:child_process';\n\nexport function openInBrowser(url: string, platform: string = process.platform): void {\n try {\n if (platform === 'darwin') {\n spawn('open', [url], { detached: true, stdio: 'ignore' }).unref();\n return;\n }\n if (platform === 'win32') {\n spawn('rundll32', ['url.dll,FileProtocolHandler', url], {\n detached: true,\n stdio: 'ignore',\n windowsHide: true,\n }).unref();\n return;\n }\n spawn('xdg-open', [url], { detached: true, stdio: 'ignore' }).unref();\n } catch {\n // Nothing worked — the URL is printed anyway by the caller.\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { AstraError } from '../errors.js';\nimport { homePaths } from './paths.js';\n\n/** Newest logs/astra-YYYYMMDD.log, falling back to logs/server-stdout.log. */\nexport function findNewestLog(home: string): string {\n const { logsDir, serverStdoutLog } = homePaths(home);\n let candidates: string[] = [];\n try {\n candidates = fs\n .readdirSync(logsDir)\n .filter((f) => /^astra-\\d{8}\\.log$/.test(f))\n .map((f) => path.join(logsDir, f));\n } catch {\n /* no logs dir */\n }\n candidates.sort((a, b) => mtimeOf(b) - mtimeOf(a));\n const newest = candidates[0];\n if (newest) return newest;\n if (fs.existsSync(serverStdoutLog)) return serverStdoutLog;\n throw new AstraError('No log files found.', 'Start the server first: `astra start`.');\n}\n\nfunction mtimeOf(p: string): number {\n try {\n return fs.statSync(p).mtimeMs;\n } catch {\n return 0;\n }\n}\n\nexport function tailLines(filePath: string, lineCount: number): string {\n const text = fs.readFileSync(filePath, 'utf8');\n const lines = text.split(/\\r?\\n/);\n while (lines.length > 0 && lines[lines.length - 1] === '') lines.pop();\n return lines.slice(-lineCount).join('\\n');\n}\n\n/** Poll a file for growth and stream appended content. Returns a stop function. */\nexport function followFile(filePath: string, write: (chunk: string) => void): () => void {\n let pos = fs.existsSync(filePath) ? fs.statSync(filePath).size : 0;\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = (): void => {\n if (stopped) return;\n try {\n const st = fs.existsSync(filePath) ? fs.statSync(filePath) : null;\n if (!st) {\n pos = 0;\n } else if (st.size < pos) {\n pos = 0; // rotated or truncated\n } else if (st.size > pos) {\n const fd = fs.openSync(filePath, 'r');\n try {\n const buf = Buffer.alloc(st.size - pos);\n const bytesRead = fs.readSync(fd, buf, 0, buf.length, pos);\n pos += bytesRead;\n write(buf.toString('utf8'));\n } finally {\n fs.closeSync(fd);\n }\n }\n } catch {\n /* keep polling */\n }\n timer = setTimeout(tick, 1_000);\n };\n tick();\n return () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n };\n}\n","import fs from 'node:fs';\nimport type { ChildProcess } from 'node:child_process';\nimport { spawn } from 'node:child_process';\nimport { AstraError } from '../errors.js';\nimport { homePaths, astraHome } from './paths.js';\nimport {\n readConfig,\n writeConfig,\n normalizePort,\n normalizeHost,\n} from './config-file.js';\nimport { readRuntimeInfo, type RuntimeInfo } from './runtime.js';\nimport { resolveServerBinary, type ServerCommand } from './binary.js';\nimport { baseUrlFor, checkHealth, shutdownRequest, type FetchLike } from './http.js';\nimport {\n delay,\n exitCodeOf,\n isPidAlive as pidAliveFn,\n killPid,\n runCapture,\n spawnDetached,\n terminatePid,\n waitForPidExit,\n} from './process-utils.js';\nimport { applyServerInfo, readInstallJson, writeInstallJson } from './install-json.js';\n\nexport interface StartOptions {\n port?: number | string;\n host?: string;\n foreground?: boolean;\n open?: boolean;\n}\n\nexport interface StartResult {\n base: string;\n host: string;\n port: number;\n alreadyRunning: boolean;\n pid?: number;\n command: ServerCommand;\n logFile: string;\n}\n\nexport function currentRuntime(home: string): RuntimeInfo | null {\n return readRuntimeInfo(homePaths(home).runtimeFile);\n}\n\nfunction clearRuntimeFile(home: string): void {\n try {\n fs.rmSync(homePaths(home).runtimeFile, { force: true });\n } catch {\n /* ignore */\n }\n}\n\n/** The server is running when runtime.json exists, its pid is alive, and /api/health says ok. */\nexport async function probeRunning(\n home: string,\n fetchImpl?: FetchLike,\n): Promise<{ runtime: RuntimeInfo; base: string } | null> {\n const rt = currentRuntime(home);\n if (!rt) return null;\n if (!pidAliveFn(rt.pid)) return null;\n const base = baseUrlFor(rt.host, rt.port);\n if (await checkHealth(base, fetchImpl)) return { runtime: rt, base };\n return null;\n}\n\n/** Best-effort `astra-server version` probe. */\nexport async function getServerVersion(command: ServerCommand): Promise<string | undefined> {\n try {\n const r = await runCapture(command.command, [...command.args, 'version'], { timeoutMs: 15_000 });\n if (r.code !== 0) return undefined;\n const parsed = JSON.parse(r.stdout.trim()) as { version?: unknown };\n return typeof parsed.version === 'string' ? parsed.version : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport async function waitForHealthy(\n base: string,\n timeoutMs: number,\n aborted?: () => boolean,\n fetchImpl?: FetchLike,\n): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (aborted?.()) return false;\n if (await checkHealth(base, fetchImpl)) return true;\n await delay(400);\n }\n return false;\n}\n\nexport interface StartedServerProbe {\n /** Address we asked for; used when the server has not written runtime.json (older servers). */\n fallbackBase: string;\n timeoutMs: number;\n aborted?: () => boolean;\n readRuntime: () => RuntimeInfo | null;\n isAlive?: (pid: number) => boolean;\n fetchImpl?: FetchLike;\n pollMs?: number;\n}\n\n/**\n * Waits for a freshly spawned server. The server moves to the next free port when the configured one is taken\n * (plan §2), so its real address comes from runtime.json, not from the port we passed.\n */\nexport async function waitForStartedServer(o: StartedServerProbe): Promise<{ base: string; runtime: RuntimeInfo | null } | null> {\n const isAlive = o.isAlive ?? pidAliveFn;\n const deadline = Date.now() + o.timeoutMs;\n while (Date.now() < deadline) {\n if (o.aborted?.()) return null;\n const rt = o.readRuntime();\n if (rt && isAlive(rt.pid)) {\n const base = baseUrlFor(rt.host, rt.port);\n if (await checkHealth(base, o.fetchImpl)) return { base, runtime: rt };\n } else if (!rt && (await checkHealth(o.fallbackBase, o.fetchImpl))) {\n return { base: o.fallbackBase, runtime: null };\n }\n await delay(o.pollMs ?? 400);\n }\n return null;\n}\n\nfunction openLogFds(home: string): { out: number; err: number; logFile: string } {\n const p = homePaths(home);\n fs.mkdirSync(p.logsDir, { recursive: true });\n const fd = fs.openSync(p.serverStdoutLog, 'a');\n return { out: fd, err: fd, logFile: p.serverStdoutLog };\n}\n\nexport async function startServer(options: StartOptions = {}): Promise<StartResult> {\n const home = astraHome();\n const p = homePaths(home);\n const cfg = readConfig(home);\n const port = normalizePort(options.port ?? cfg.port);\n const host = normalizeHost(options.host ?? cfg.host);\n // Persist the effective port/host so autostart entries and the desktop app agree.\n if (\n options.port !== undefined ||\n options.host !== undefined ||\n cfg.port === undefined ||\n cfg.host === undefined\n ) {\n writeConfig(home, { port, host });\n }\n\n const existing = await probeRunning(home);\n if (existing) {\n return {\n base: existing.base,\n host: existing.runtime.host,\n port: existing.runtime.port,\n alreadyRunning: true,\n pid: existing.runtime.pid,\n command: resolveServerBinary({ installServerPath: readInstallJson(home)?.serverPath ?? null }),\n logFile: p.serverStdoutLog,\n };\n }\n // runtime.json exists but the process is gone — clean up before starting.\n if (currentRuntime(home)) clearRuntimeFile(home);\n\n const command = resolveServerBinary({ installServerPath: readInstallJson(home)?.serverPath ?? null });\n const version = await getServerVersion(command);\n writeInstallJson(\n home,\n applyServerInfo(readInstallJson(home), {\n serverPath: command.serverPath,\n serverVersion: version,\n }),\n );\n\n const args = [...command.args, 'serve', '--port', String(port), '--host', host, '--started-by', 'cli'];\n const base = baseUrlFor(host, port);\n\n if (options.foreground) {\n const child = spawn(command.command, args, { stdio: 'inherit', windowsHide: true });\n void (async () => {\n if (await waitForHealthy(base, 20_000, () => child.exitCode !== null)) {\n // Health polling side effect only; the command layer opens the browser.\n }\n })();\n const code = await exitCodeOf(child);\n if (code !== 0) {\n throw new AstraError(\n `The server exited with code ${code}.`,\n `Check the logs in ${p.logsDir}`,\n );\n }\n return { base, host, port, alreadyRunning: false, command, logFile: p.serverStdoutLog };\n }\n\n const fds = openLogFds(home);\n let child: ChildProcess;\n try {\n child = spawnDetached(command.command, args, ['ignore', fds.out, fds.err]);\n } catch (err) {\n throw new AstraError(\n `Failed to start the server binary: ${(err as Error).message}`,\n `Binary: ${command.command}`,\n );\n } finally {\n try {\n fs.closeSync(fds.out);\n } catch {\n /* ignore */\n }\n }\n\n const started = await waitForStartedServer({\n fallbackBase: base,\n timeoutMs: 20_000,\n aborted: () => child.exitCode !== null,\n readRuntime: () => currentRuntime(home),\n });\n if (!started) {\n if (child.exitCode !== null && child.exitCode !== 0) {\n throw new AstraError(\n `The server exited with code ${child.exitCode} before becoming healthy.`,\n `Check the log: ${p.serverStdoutLog}`,\n );\n }\n throw new AstraError(\n `The server did not become healthy at ${base} within 20 seconds.`,\n `Check the log: ${p.serverStdoutLog}`,\n );\n }\n const rt = started.runtime;\n return {\n base: started.base,\n host: rt?.host ?? host,\n port: rt?.port ?? port,\n alreadyRunning: false,\n pid: rt?.pid ?? child.pid,\n command,\n logFile: p.serverStdoutLog,\n };\n}\n\nexport interface StopResult {\n stopped: boolean;\n pid?: number;\n}\n\nexport async function stopServer(): Promise<StopResult> {\n const home = astraHome();\n const rt = currentRuntime(home);\n if (!rt) return { stopped: false };\n if (!pidAliveFn(rt.pid)) {\n clearRuntimeFile(home);\n return { stopped: false };\n }\n const base = baseUrlFor(rt.host, rt.port);\n if (rt.runtimeToken) {\n try {\n await shutdownRequest(base, rt.runtimeToken);\n } catch {\n /* fall through to signals */\n }\n }\n if (!(await waitForPidExit(rt.pid, 8_000))) {\n await terminatePid(rt.pid);\n if (!(await waitForPidExit(rt.pid, 3_000))) {\n await killPid(rt.pid);\n await waitForPidExit(rt.pid, 2_000);\n }\n }\n clearRuntimeFile(home);\n return { stopped: true, pid: rt.pid };\n}\n\nexport interface ServerStatus {\n running: boolean;\n base?: string;\n runtime?: RuntimeInfo;\n staleRuntime: boolean;\n configPort: number;\n configHost: string;\n}\n\nexport async function serverStatus(fetchImpl?: FetchLike): Promise<ServerStatus> {\n const home = astraHome();\n const cfg = readConfig(home);\n const configPort = normalizePort(cfg.port);\n const configHost = normalizeHost(cfg.host);\n const rt = currentRuntime(home);\n if (!rt) return { running: false, staleRuntime: false, configPort, configHost };\n if (!pidAliveFn(rt.pid)) {\n clearRuntimeFile(home);\n return { running: false, staleRuntime: true, configPort, configHost };\n }\n const base = baseUrlFor(rt.host, rt.port);\n const healthy = await checkHealth(base, fetchImpl);\n return { running: healthy, base, runtime: rt, staleRuntime: false, configPort, configHost };\n}\n\nexport interface EnsuredServer {\n base: string;\n runtime?: RuntimeInfo;\n started: boolean;\n}\n\n/** For admin subcommands: use the running server or start one in the background. */\nexport async function ensureServerRunning(): Promise<EnsuredServer> {\n const home = astraHome();\n const existing = await probeRunning(home);\n if (existing) return { base: existing.base, runtime: existing.runtime, started: false };\n const result = await startServer({});\n return { base: result.base, runtime: currentRuntime(home) ?? undefined, started: true };\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nexport function readTextOrNull(filePath: string): string | null {\n try {\n return fs.readFileSync(filePath, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT' || code === 'EISDIR') return null;\n throw err;\n }\n}\n\n/** Read a JSON file; missing or corrupt files are treated as absent (null). */\nexport function readJsonFile<T>(filePath: string): T | null {\n const text = readTextOrNull(filePath);\n if (text === null || text.trim() === '') return null;\n try {\n return JSON.parse(text) as T;\n } catch {\n return null;\n }\n}\n\nexport function writeJsonFile(filePath: string, data: unknown, mode: number = 0o644): void {\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n fs.writeFileSync(filePath, `${JSON.stringify(data, null, 2)}\\n`, { mode });\n}\n","import { AstraError } from '../errors.js';\nimport { readJsonFile, writeJsonFile } from './json-file.js';\nimport { homePaths } from './paths.js';\n\nexport interface AstraConfig {\n port?: number;\n host?: string;\n logLevel?: string;\n [key: string]: unknown;\n}\n\nexport const DEFAULT_PORT = 17321;\nexport const DEFAULT_HOST = '127.0.0.1';\n\nexport function readConfig(home: string): AstraConfig {\n return readJsonFile<AstraConfig>(homePaths(home).configFile) ?? {};\n}\n\nexport function writeConfig(home: string, patch: AstraConfig): AstraConfig {\n const next = { ...readConfig(home), ...patch };\n writeJsonFile(homePaths(home).configFile, next);\n return next;\n}\n\nexport function normalizePort(value: unknown, fallback: number = DEFAULT_PORT): number {\n if (value === undefined || value === null || value === '') return fallback;\n const n = typeof value === 'number' ? value : Number(value);\n if (!Number.isInteger(n) || n < 1 || n > 65535) {\n throw new AstraError(`Invalid port: ${String(value)}. Use a number between 1 and 65535.`);\n }\n return n;\n}\n\nexport function normalizeHost(value: unknown, fallback: string = DEFAULT_HOST): string {\n if (value === undefined || value === null || value === '') return fallback;\n if (typeof value !== 'string') throw new AstraError(`Invalid host: ${String(value)}`);\n return value;\n}\n","import { readTextOrNull } from './json-file.js';\n\nexport const STARTED_BY_VALUES = ['cli', 'desktop', 'autostart'] as const;\nexport type StartedBy = (typeof STARTED_BY_VALUES)[number];\n\n/** Shape of runtime.json, written by the server when it starts listening. */\nexport interface RuntimeInfo {\n pid: number;\n port: number;\n host: string;\n version?: string;\n apiVersion?: string;\n startedBy?: StartedBy;\n startedAt?: string;\n runtimeToken?: string;\n}\n\nexport function parseRuntimeJson(text: string): RuntimeInfo | null {\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch {\n return null;\n }\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\n const obj = raw as Record<string, unknown>;\n const { pid, port, host } = obj;\n if (typeof pid !== 'number' || !Number.isInteger(pid) || pid <= 0) return null;\n if (typeof port !== 'number' || !Number.isInteger(port) || port <= 0 || port > 65535) return null;\n if (typeof host !== 'string' || host.trim() === '') return null;\n\n const info: RuntimeInfo = { pid, port, host };\n if (typeof obj.version === 'string') info.version = obj.version;\n if (typeof obj.apiVersion === 'string') info.apiVersion = obj.apiVersion;\n if (\n typeof obj.startedBy === 'string' &&\n (STARTED_BY_VALUES as readonly string[]).includes(obj.startedBy)\n ) {\n info.startedBy = obj.startedBy as StartedBy;\n }\n if (typeof obj.startedAt === 'string') info.startedAt = obj.startedAt;\n if (typeof obj.runtimeToken === 'string') info.runtimeToken = obj.runtimeToken;\n return info;\n}\n\nexport function readRuntimeInfo(runtimeFile: string): RuntimeInfo | null {\n const text = readTextOrNull(runtimeFile);\n return text === null ? null : parseRuntimeJson(text);\n}\n\nexport function isRuntimeCurrent(\n info: RuntimeInfo,\n isAlive: (pid: number) => boolean,\n): boolean {\n return isAlive(info.pid);\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\nimport { AstraError } from '../errors.js';\nimport { PACKAGE_NAME } from '../version.js';\nimport { platformInfo } from './platform.js';\n\nexport interface ServerCommand {\n /** executable to run */\n command: string;\n /** arguments before the subcommand (non-empty in `dotnet <dll>` dev mode) */\n args: string[];\n /** path recorded in install.json */\n serverPath: string;\n source: 'env' | 'install' | 'repo' | 'package';\n}\n\nexport interface ResolveServerBinaryOptions {\n env?: NodeJS.ProcessEnv;\n cwd?: string;\n /** serverPath from ~/.astra/install.json — written by the updater and previous starts */\n installServerPath?: string | null;\n /** directory used to resolve @aidotnet/server-* (defaults to this module's directory) */\n baseDir?: string;\n platform?: string;\n arch?: string;\n existsSync?: (p: string) => boolean;\n readFileSync?: (p: string, encoding: 'utf8') => string;\n resolveFrom?: (baseDir: string, request: string) => string;\n}\n\n/**\n * Find the repository root by looking for src/Astra.Server, walking up\n * from startDir. Returns null when not inside the repo.\n */\nexport function findRepoRoot(startDir: string, exists: (p: string) => boolean): string | null {\n let dir = path.resolve(startDir);\n for (;;) {\n if (exists(path.join(dir, 'src', 'Astra.Server'))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\nfunction defaultResolveFrom(baseDir: string, request: string): string {\n const require2 = createRequire(path.join(baseDir, 'index.js'));\n return require2.resolve(request);\n}\n\n/**\n * Resolution order (mirrors the desktop app's resolver):\n * 1. ASTRA_SERVER_BIN env var\n * 2. install.json serverPath — the updater's managed binary (~/.astra/server/…)\n * 3. repo dev build: src/Astra.Server/bin/Debug/net10.0/astra-server[.exe],\n * or `dotnet astra-server.dll` when only the dll exists\n * 4. the installed platform package @aidotnet/server-<platform>\n */\nexport function resolveServerBinary(options: ResolveServerBinaryOptions = {}): ServerCommand {\n const env = options.env ?? process.env;\n const exists = options.existsSync ?? ((p: string) => fs.existsSync(p));\n const cwd = options.cwd ?? process.cwd();\n const plat = platformInfo(options.platform ?? process.platform, options.arch ?? process.arch);\n\n // 1. explicit override\n const envBin = env.ASTRA_SERVER_BIN?.trim();\n if (envBin) {\n if (!exists(envBin)) {\n throw new AstraError(`ASTRA_SERVER_BIN points to a missing file: ${envBin}`);\n }\n return { command: envBin, args: [], serverPath: envBin, source: 'env' };\n }\n\n // 2. the updater's managed binary recorded in install.json\n const installPath = options.installServerPath?.trim();\n if (installPath && exists(installPath)) {\n return { command: installPath, args: [], serverPath: installPath, source: 'install' };\n }\n\n // 3. in-repo dev build\n const repoRoot = findRepoRoot(cwd, exists);\n if (repoRoot) {\n const binDir = path.join(repoRoot, 'src', 'Astra.Server', 'bin', 'Debug', 'net10.0');\n const native = path.join(binDir, plat.binaryName);\n if (exists(native)) return { command: native, args: [], serverPath: native, source: 'repo' };\n const dll = path.join(binDir, 'astra-server.dll');\n if (exists(dll)) return { command: 'dotnet', args: [dll], serverPath: dll, source: 'repo' };\n }\n\n // 4. installed platform package\n const packaged = findPackagedServerBinary(options);\n if ('path' in packaged) {\n return { command: packaged.path, args: [], serverPath: packaged.path, source: 'package' };\n }\n\n throw new AstraError(\n `Could not find the Astra server binary. ${packaged.error}`,\n `Reinstall the CLI (\\`npm install -g ${PACKAGE_NAME}\\`), or point ASTRA_SERVER_BIN at the server binary.`,\n );\n}\n\n/**\n * Step 4 of resolveServerBinary on its own: the binary shipped in the\n * installed @aidotnet/server-<platform> package next to this CLI.\n */\nexport function findPackagedServerBinary(\n options: ResolveServerBinaryOptions = {},\n): { path: string } | { error: string } {\n const exists = options.existsSync ?? ((p: string) => fs.existsSync(p));\n const readText =\n options.readFileSync ?? ((p: string, _enc: 'utf8') => fs.readFileSync(p, 'utf8'));\n const baseDir = options.baseDir ?? path.dirname(fileURLToPath(import.meta.url));\n const plat = platformInfo(options.platform ?? process.platform, options.arch ?? process.arch);\n const resolveFrom = options.resolveFrom ?? defaultResolveFrom;\n try {\n const pkgJsonPath = resolveFrom(baseDir, `${plat.serverPackage}/package.json`);\n const pkg = JSON.parse(readText(pkgJsonPath, 'utf8')) as { bin?: Record<string, string> };\n const binRel = pkg.bin?.['astra-server'];\n if (!binRel) return { error: `${plat.serverPackage} has no 'astra-server' bin entry.` };\n const binPath = path.resolve(path.dirname(pkgJsonPath), binRel);\n if (exists(binPath)) return { path: binPath };\n return { error: `${plat.serverPackage} is installed but its binary is missing (${binPath}).` };\n } catch {\n return { error: `${plat.serverPackage} is not installed.` };\n }\n}\n","{\n \"name\": \"@aidotnet/astra-gate\",\n \"version\": \"0.2.0\",\n \"description\": \"Astra — a local AI gateway. Install, start, stop and manage the astra-server from the terminal.\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"bin\": {\n \"astra\": \"dist/index.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"engines\": {\n \"node\": \">=18\"\n },\n \"keywords\": [\n \"astra\",\n \"ai\",\n \"gateway\",\n \"llm\",\n \"proxy\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"watch\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint .\"\n },\n \"dependencies\": {\n \"commander\": \"^12.1.0\"\n },\n \"optionalDependencies\": {\n \"@aidotnet/server-darwin-arm64\": \"0.2.0\",\n \"@aidotnet/server-darwin-x64\": \"0.2.0\",\n \"@aidotnet/server-linux-arm64\": \"0.2.0\",\n \"@aidotnet/server-linux-x64\": \"0.2.0\",\n \"@aidotnet/server-win32-arm64\": \"0.2.0\",\n \"@aidotnet/server-win32-x64\": \"0.2.0\"\n },\n \"devDependencies\": {\n \"@aidotnet/update-core\": \"workspace:*\",\n \"@types/node\": \"^24.0.0\",\n \"eslint\": \"^9.17.0\",\n \"prettier\": \"^3.4.2\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^5.7.2\",\n \"typescript-eslint\": \"^8.18.1\",\n \"vitest\": \"^3.0.0\"\n },\n \"packageManager\": \"pnpm@9.15.0\"\n}\n","import pkg from '../package.json';\n\nexport const VERSION: string = pkg.version;\n\n/**\n * npm name this build is published under: `astragate`, or `@aidotnet/astra-gate`\n * (release.yml rebuilds the same CLI under the scoped name). Self-update and\n * reinstall hints use it so they target the package the user actually installed.\n */\nexport const PACKAGE_NAME: string = pkg.name;\n","import { spawn, type ChildProcess } from 'node:child_process';\n\nexport interface RunResult {\n code: number | null;\n stdout: string;\n stderr: string;\n}\n\nexport interface RunCaptureOptions {\n timeoutMs?: number;\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n input?: string;\n shell?: boolean;\n}\n\nexport function runCapture(\n command: string,\n args: readonly string[],\n options: RunCaptureOptions = {},\n): Promise<RunResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, [...args], {\n cwd: options.cwd,\n env: options.env,\n windowsHide: true,\n shell: options.shell ?? false,\n });\n let stdout = '';\n let stderr = '';\n let settled = false;\n const timer = options.timeoutMs\n ? setTimeout(() => {\n settled = true;\n try {\n child.kill('SIGKILL');\n } catch {\n /* ignore */\n }\n reject(new Error(`Command timed out after ${options.timeoutMs}ms: ${command} ${args.join(' ')}`));\n }, options.timeoutMs)\n : null;\n\n child.stdout?.on('data', (d: Buffer) => {\n stdout += d.toString();\n });\n child.stderr?.on('data', (d: Buffer) => {\n stderr += d.toString();\n });\n if (options.input !== undefined) {\n child.stdin?.write(options.input);\n }\n child.stdin?.end();\n child.on('error', (err) => {\n if (timer) clearTimeout(timer);\n if (!settled) reject(err);\n });\n child.on('close', (code) => {\n if (timer) clearTimeout(timer);\n if (!settled) resolve({ code, stdout, stderr });\n });\n });\n}\n\nexport function spawnDetached(\n command: string,\n args: readonly string[],\n stdio: ('ignore' | number)[],\n): ChildProcess {\n const child = spawn(command, [...args], { detached: true, stdio, windowsHide: true });\n child.unref();\n return child;\n}\n\nexport function exitCodeOf(child: ChildProcess): Promise<number | null> {\n return new Promise((resolve, reject) => {\n child.on('error', reject);\n child.on('close', (code) => resolve(code));\n });\n}\n\nexport function isPidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === 'EPERM';\n }\n}\n\n/** Ask a process to terminate: SIGTERM on POSIX, taskkill on Windows. */\nexport async function terminatePid(pid: number, platform: string = process.platform): Promise<void> {\n if (platform === 'win32') {\n try {\n await runCapture('taskkill', ['/PID', String(pid), '/T', '/F'], { timeoutMs: 10_000 });\n } catch {\n /* ignore */\n }\n return;\n }\n try {\n process.kill(pid, 'SIGTERM');\n } catch {\n /* already dead */\n }\n}\n\n/** Force-kill a process: SIGKILL on POSIX, taskkill /F on Windows. */\nexport async function killPid(pid: number, platform: string = process.platform): Promise<void> {\n if (platform === 'win32') {\n await terminatePid(pid, platform);\n return;\n }\n try {\n process.kill(pid, 'SIGKILL');\n } catch {\n /* already dead */\n }\n}\n\nexport async function waitForPidExit(\n pid: number,\n timeoutMs: number,\n isAlive: (pid: number) => boolean = isPidAlive,\n): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (!isAlive(pid)) return true;\n await delay(300);\n }\n return !isAlive(pid);\n}\n\nexport function delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { readJsonFile, writeJsonFile } from './json-file.js';\nimport { homePaths } from './paths.js';\n\n/** Shape of install.json, written by the CLI and read by the Electron app. */\nexport interface InstallJson {\n serverPath?: string;\n serverVersion?: string;\n desktopPath?: string;\n desktopVersion?: string;\n updatedAt?: string;\n}\n\nexport function readInstallJson(home: string): InstallJson | null {\n return readJsonFile<InstallJson>(homePaths(home).installFile);\n}\n\nexport function writeInstallJson(home: string, data: InstallJson): void {\n writeJsonFile(homePaths(home).installFile, data);\n}\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nexport function applyServerInfo(\n existing: InstallJson | null,\n server: { serverPath: string; serverVersion?: string },\n): InstallJson {\n return {\n ...(existing ?? {}),\n serverPath: server.serverPath,\n ...(server.serverVersion ? { serverVersion: server.serverVersion } : {}),\n updatedAt: nowIso(),\n };\n}\n\nexport function applyDesktopInfo(\n existing: InstallJson | null,\n desktop: { desktopPath: string; desktopVersion?: string },\n): InstallJson {\n return {\n ...(existing ?? {}),\n desktopPath: desktop.desktopPath,\n ...(desktop.desktopVersion ? { desktopVersion: desktop.desktopVersion } : {}),\n updatedAt: nowIso(),\n };\n}\n\nexport function clearDesktopInfo(existing: InstallJson | null): InstallJson {\n const { desktopPath: _dp, desktopVersion: _dv, ...rest } = existing ?? {};\n return { ...rest, updatedAt: nowIso() };\n}\n","import os from 'node:os';\nimport process from 'node:process';\nimport { AstraError } from '../errors.js';\nimport { style, success } from '../ui.js';\nimport { astraHome } from '../lib/paths.js';\nimport { resolveServerBinary } from '../lib/binary.js';\nimport {\n autostartArgv,\n autostartStatusLinux,\n autostartStatusMac,\n autostartStatusWindows,\n disableAutostartLinux,\n disableAutostartMac,\n disableAutostartWindows,\n enableAutostartLinux,\n enableAutostartMac,\n enableAutostartWindows,\n} from '../lib/autostart.js';\n\nexport type AutostartAction = 'enable' | 'disable' | 'status';\n\nasync function dispatch<T>(mac: () => Promise<T>, linux: () => Promise<T>, win: () => Promise<T>): Promise<T> {\n switch (process.platform) {\n case 'darwin':\n return mac();\n case 'win32':\n return win();\n case 'linux':\n return linux();\n default:\n throw new AstraError(`Autostart is not supported on ${process.platform}.`);\n }\n}\n\nexport async function runAutostart(action: AutostartAction): Promise<void> {\n const home = astraHome();\n if (action === 'status') {\n const s = await dispatch(\n () => autostartStatusMac(os.homedir()),\n () => autostartStatusLinux(os.homedir()),\n () => autostartStatusWindows(),\n );\n console.log(`Autostart is ${s === 'enabled' ? style.green('enabled') : 'disabled'}.`);\n return;\n }\n if (action === 'enable') {\n const command = resolveServerBinary();\n const argv = autostartArgv(command);\n await dispatch(\n () => enableAutostartMac(argv, os.homedir(), home),\n () => enableAutostartLinux(argv, os.homedir()),\n () => enableAutostartWindows(argv),\n );\n success('Astra will start automatically at login.');\n } else {\n await dispatch(\n () => disableAutostartMac(os.homedir()),\n () => disableAutostartLinux(os.homedir()),\n () => disableAutostartWindows(),\n );\n success('Autostart disabled.');\n }\n}\n","import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { AstraError } from '../errors.js';\nimport { homePaths } from './paths.js';\nimport { runCapture } from './process-utils.js';\n\nexport const LAUNCHD_LABEL = 'io.astra.server';\nexport const SYSTEMD_UNIT_NAME = 'astra.service';\nexport const SCHTASKS_TASK_NAME = 'Astra Server';\n\nfunction xmlEscape(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nexport function launchdPlistPath(home: string = os.homedir()): string {\n return path.join(home, 'Library', 'LaunchAgents', `${LAUNCHD_LABEL}.plist`);\n}\n\nexport function renderLaunchdPlist(argv: readonly string[], logFile: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${xmlEscape(LAUNCHD_LABEL)}</string>\n <key>ProgramArguments</key>\n <array>\n${argv.map((a) => ` <string>${xmlEscape(a)}</string>`).join('\\n')}\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <false/>\n <key>ProcessType</key>\n <string>Background</string>\n <key>StandardOutPath</key>\n <string>${xmlEscape(logFile)}</string>\n <key>StandardErrorPath</key>\n <string>${xmlEscape(logFile)}</string>\n</dict>\n</plist>\n`;\n}\n\nexport function systemdUnitPath(home: string = os.homedir()): string {\n return path.join(home, '.config', 'systemd', 'user', SYSTEMD_UNIT_NAME);\n}\n\nfunction systemdQuote(part: string): string {\n return /[\\s\"]/.test(part) ? `\"${part.replace(/\"/g, '\\\\\"')}\"` : part;\n}\n\nexport function renderSystemdUnit(argv: readonly string[]): string {\n const exec = argv.map(systemdQuote).join(' ');\n return `[Unit]\nDescription=Astra local AI gateway server\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=${exec}\nRestart=on-failure\nRestartSec=3\n\n[Install]\nWantedBy=default.target\n`;\n}\n\nfunction quoteForTr(argv: readonly string[]): string {\n // Canonical schtasks /TR form: outer quotes, inner quotes backslash-escaped:\n // \"\\\"C:\\Program Files\\app.exe\\\" serve --flag\"\n const inner = argv\n .map((a) => (/[\\s\"]/.test(a) ? `\"${a}\"` : a))\n .join(' ')\n .replace(/\"/g, '\\\\\"');\n return `\"${inner}\"`;\n}\n\nexport function schtasksCreateArgs(argv: readonly string[]): string[] {\n return ['/Create', '/F', '/SC', 'ONLOGON', '/TN', SCHTASKS_TASK_NAME, '/TR', quoteForTr(argv)];\n}\n\nexport function schtasksDeleteArgs(): string[] {\n return ['/Delete', '/F', '/TN', SCHTASKS_TASK_NAME];\n}\n\nexport function schtasksQueryArgs(): string[] {\n return ['/Query', '/TN', SCHTASKS_TASK_NAME];\n}\n\n/** Full argv for the autostart entry: [<command> ...args] serve --started-by autostart */\nexport function autostartArgv(command: { command: string; args: readonly string[] }): string[] {\n return [command.command, ...command.args, 'serve', '--started-by', 'autostart'];\n}\n\nasync function exec(\n args: readonly string[],\n): Promise<{ code: number | null; stdout: string; stderr: string }> {\n const [cmd, ...rest] = args;\n if (!cmd) throw new AstraError('Missing command.');\n return runCapture(cmd, rest, { timeoutMs: 30_000 });\n}\n\nfunction logFileFor(lgHome: string): string {\n return path.join(homePaths(lgHome).logsDir, 'server-stdout.log');\n}\n\n// ---------- macOS (launchd) ----------\n\nexport async function enableAutostartMac(\n argv: readonly string[],\n home: string = os.homedir(),\n lgHome: string = homePaths(home).home,\n): Promise<void> {\n const plist = launchdPlistPath(home);\n fs.mkdirSync(path.dirname(plist), { recursive: true });\n fs.writeFileSync(plist, renderLaunchdPlist(argv, logFileFor(lgHome)));\n await exec(['launchctl', 'unload', plist]).catch(() => undefined);\n const r = await exec(['launchctl', 'load', plist]);\n if (r.code !== 0) {\n throw new AstraError('launchctl load failed.', r.stderr.trim() || r.stdout.trim() || undefined);\n }\n}\n\nexport async function disableAutostartMac(home: string = os.homedir()): Promise<void> {\n const plist = launchdPlistPath(home);\n await exec(['launchctl', 'unload', plist]).catch(() => undefined);\n fs.rmSync(plist, { force: true });\n}\n\nexport async function autostartStatusMac(home: string = os.homedir()): Promise<'enabled' | 'disabled'> {\n return fs.existsSync(launchdPlistPath(home)) ? 'enabled' : 'disabled';\n}\n\n// ---------- Linux (systemd --user) ----------\n\nexport async function enableAutostartLinux(\n argv: readonly string[],\n home: string = os.homedir(),\n): Promise<void> {\n const unit = systemdUnitPath(home);\n fs.mkdirSync(path.dirname(unit), { recursive: true });\n fs.writeFileSync(unit, renderSystemdUnit(argv));\n const reload = await exec(['systemctl', '--user', 'daemon-reload']);\n if (reload.code !== 0) {\n throw new AstraError(\n 'systemctl --user daemon-reload failed. Is systemd available (a WSL setup without systemd is not supported)?',\n reload.stderr.trim() || undefined,\n );\n }\n const enable = await exec(['systemctl', '--user', 'enable', '--now', SYSTEMD_UNIT_NAME]);\n if (enable.code !== 0) {\n throw new AstraError(\n `systemctl --user enable --now ${SYSTEMD_UNIT_NAME} failed.`,\n enable.stderr.trim() || undefined,\n );\n }\n}\n\nexport async function disableAutostartLinux(home: string = os.homedir()): Promise<void> {\n await exec(['systemctl', '--user', 'disable', '--now', SYSTEMD_UNIT_NAME]).catch(() => undefined);\n fs.rmSync(systemdUnitPath(home), { force: true });\n await exec(['systemctl', '--user', 'daemon-reload']).catch(() => undefined);\n}\n\nexport async function autostartStatusLinux(\n home: string = os.homedir(),\n): Promise<'enabled' | 'disabled'> {\n if (!fs.existsSync(systemdUnitPath(home))) return 'disabled';\n const r = await exec(['systemctl', '--user', 'is-enabled', SYSTEMD_UNIT_NAME]).catch(() => null);\n return r !== null && r.code === 0 && r.stdout.trim() === 'enabled' ? 'enabled' : 'disabled';\n}\n\n// ---------- Windows (schtasks) ----------\n\nexport async function enableAutostartWindows(argv: readonly string[]): Promise<void> {\n const r = await exec(['schtasks', ...schtasksCreateArgs(argv)]);\n if (r.code !== 0) {\n throw new AstraError('schtasks /Create failed.', r.stderr.trim() || undefined);\n }\n}\n\nexport async function disableAutostartWindows(): Promise<void> {\n const r = await exec(['schtasks', ...schtasksDeleteArgs()]);\n if (r.code !== 0 && !/does not exist|no existe/i.test(r.stderr + r.stdout)) {\n throw new AstraError('schtasks /Delete failed.', r.stderr.trim() || undefined);\n }\n}\n\nexport async function autostartStatusWindows(): Promise<'enabled' | 'disabled'> {\n const r = await exec(['schtasks', ...schtasksQueryArgs()]);\n return r.code === 0 ? 'enabled' : 'disabled';\n}\n","import fs from 'node:fs';\nimport {\n applyServerUpdate,\n checkForServerUpdate,\n fetchManifest,\n installDesktopClient,\n isNewerVersion,\n majorOf,\n removeLauncher,\n type ServerControl,\n type UpdateManifest,\n} from '@aidotnet/update-core';\nimport { info, style, success, warn } from '../ui.js';\nimport { astraHome, homePaths } from '../lib/paths.js';\nimport { npmInstallGlobal } from '../lib/desktop.js';\nimport { ensureDesktopServer } from '../lib/desktop-server.js';\nimport { platformInfo } from '../lib/platform.js';\nimport { apiRequest, baseUrlFor } from '../lib/http.js';\nimport { confirmPrompt } from '../lib/prompt.js';\nimport {\n applyDesktopInfo,\n clearDesktopInfo,\n readInstallJson,\n writeInstallJson,\n} from '../lib/install-json.js';\nimport { currentRuntime, probeRunning, serverStatus, startServer, stopServer } from '../lib/server-lifecycle.js';\nimport { PACKAGE_NAME, VERSION } from '../version.js';\n\nexport async function runInstall(opts: { client?: boolean }): Promise<void> {\n if (!opts.client) {\n console.log('The Astra server is installed automatically with the npm package.');\n console.log(`To install the desktop app, run ${style.cyan('astra install --desktop')}.`);\n return;\n }\n const home = astraHome();\n await installDesktopAt(home, VERSION);\n // The desktop app needs a durable serverPath in install.json (it has no\n // platform-package fallback) — essential when running via npx.\n const server = ensureDesktopServer({ home, version: VERSION, platform: platformInfo().platform });\n if (server.action === 'missing') {\n warn(\n `The desktop app cannot find an Astra server: ${server.reason} ` +\n `Install the CLI (\\`npm i -g ${PACKAGE_NAME}\\`) and run \\`astra start\\` once, or set ASTRA_SERVER_BIN.`,\n );\n } else if (server.action === 'copied') {\n success(`Astra server ${VERSION} installed to ${server.serverPath}.`);\n }\n info('Launch it from your applications, or run `astra open` for the web UI.');\n}\n\nexport async function runUninstallClient(): Promise<void> {\n const home = astraHome();\n const install = readInstallJson(home);\n if (!install?.desktopPath && !fs.existsSync(homePaths(home).desktopPrefix)) {\n console.log('The desktop app is not installed.');\n return;\n }\n removeLauncher(platformInfo().platform, home);\n fs.rmSync(homePaths(home).desktopPrefix, { recursive: true, force: true });\n writeInstallJson(home, clearDesktopInfo(readInstallJson(home)));\n success('Astra desktop app uninstalled.');\n}\n\nexport interface UpdateArgs {\n client?: boolean;\n check?: boolean;\n retry?: boolean;\n}\n\nexport async function runUpdate(opts: UpdateArgs): Promise<void> {\n const home = astraHome();\n\n if (opts.check) {\n await reportCheck();\n return;\n }\n\n // The feed manifest drives every target version; --client falls back to the\n // running CLI version when the feed is unreachable (offline reinstall).\n let manifest: UpdateManifest;\n try {\n manifest = await fetchManifest({ userAgent: `Astra-CLI/${VERSION}` });\n } catch (err) {\n if (!opts.client) throw err;\n manifest = { version: VERSION };\n }\n\n if (!opts.client) {\n await updateServer(home, manifest, opts.retry ?? false);\n\n // CLI self-update: the staged/verified flow above covers the server\n // binary; the npm global package carries the CLI code itself.\n if (isNewerVersion(manifest.version, VERSION)) {\n console.log(`Updating the Astra CLI (npm install -g ${PACKAGE_NAME}@latest)…`);\n const r = await npmInstallGlobal();\n if (r.code !== 0) {\n info(`npm install -g ${PACKAGE_NAME}@latest failed — the server is updated; run \\`npm i -g ${PACKAGE_NAME}\\` for the CLI.`);\n } else {\n success('The new CLI version is used the next time you run `astra`.');\n }\n }\n }\n\n const install = readInstallJson(home);\n const wantsDesktop = opts.client || !!install?.desktopPath || fs.existsSync(homePaths(home).desktopPrefix);\n if (wantsDesktop) {\n const target = isNewerVersion(manifest.version, VERSION) ? manifest.version : VERSION;\n await installDesktopAt(home, target);\n }\n}\n\nasync function reportCheck(): Promise<void> {\n const status = await serverStatus();\n const r = await checkForServerUpdate({\n currentVersion: VERSION,\n baseUrl: status.running ? (status.base ?? undefined) : undefined,\n });\n if (r.availableVersion) {\n console.log(`Update available: ${style.cyan(r.availableVersion)} (current ${VERSION}).`);\n if (r.notes) console.log(style.dim(r.notes));\n console.log(`Run ${style.cyan('astra update')} to install.`);\n process.exitCode = 1;\n } else {\n success(`Astra is up to date (${VERSION}).`);\n }\n}\n\n/** Installs (or refreshes) the desktop app and records it in install.json. */\nasync function installDesktopAt(home: string, version: string): Promise<void> {\n const plat = platformInfo();\n console.log(`Installing the Astra desktop app ${version} (this may take a minute)…`);\n const entry = await installDesktopClient({\n home,\n version,\n desktopPackage: plat.desktopPackage,\n platform: plat.platform,\n });\n writeInstallJson(\n home,\n applyDesktopInfo(readInstallJson(home), {\n desktopPath: entry.path,\n desktopVersion: entry.version,\n }),\n );\n success(`Astra desktop app installed (${entry.version}).`);\n}\n\n/**\n * Server track: staged download → sha256 verify → swap → restart, with\n * automatic rollback (plan §P2). The new binary lands on a fresh versioned\n * path and install.json repoints at it, so nothing running is replaced.\n */\nasync function updateServer(home: string, manifest: UpdateManifest, force: boolean): Promise<void> {\n if (!isNewerVersion(manifest.version, VERSION)) {\n console.log(`Astra server is up to date (${VERSION}).`);\n return;\n }\n\n const plat = platformInfo();\n const status = await serverStatus();\n const ok = await confirmPrompt(\n `Update the Astra server ${VERSION} → ${manifest.version}? The gateway restarts and in-flight requests are interrupted. [y/N] `,\n );\n if (!ok) {\n console.log('Update cancelled.');\n return;\n }\n\n const control: ServerControl = {\n isRunning: async () => (await probeRunning(home)) !== null,\n stop: async () => {\n await stopServer();\n },\n start: async () => {\n await startServer({});\n },\n probeVersion: async () => {\n const rt = currentRuntime(home);\n if (!rt) return null;\n try {\n const v = await apiRequest<{ version?: string }>({\n base: baseUrlFor(rt.host, rt.port),\n path: '/api/version',\n });\n return v.version ?? null;\n } catch {\n return null;\n }\n },\n };\n\n await applyServerUpdate({\n home,\n manifest,\n platformKey: `${plat.platform}-${plat.arch}`,\n serverPackage: plat.serverPackage,\n platform: plat.platform,\n currentServerPath: readInstallJson(home)?.serverPath ?? null,\n currentVersion: VERSION,\n // The running server's API major is the compatibility anchor (fallback 1).\n expectedApiMajor: majorOf(status.runtime?.apiVersion) ?? 1,\n control,\n force,\n log: (line) => console.log(` ${line}`),\n });\n success(`Astra server updated to ${manifest.version}.`);\n}\n","import { spawn } from 'node:child_process';\nimport { locateNpm } from '@aidotnet/update-core';\nimport { PACKAGE_NAME } from '../version.js';\n\n// Desktop-app install/launch helpers now live in the shared update engine\n// (@aidotnet/update-core) so the desktop app can drive the exact same flow.\n// The CLI keeps only the npm-global self-update, which is CLI-specific.\nexport {\n createLauncher,\n findDesktopEntry,\n installDesktopClient,\n removeLauncher,\n renderLinuxDesktopFile,\n} from '@aidotnet/update-core';\n\nfunction usesShell(command: string): boolean {\n return process.platform === 'win32' && command.endsWith('.cmd');\n}\n\nexport async function npmInstallGlobal(): Promise<{ code: number | null; stderr: string }> {\n const npm = locateNpm();\n const full = [...npm.args, 'install', '-g', `${PACKAGE_NAME}@latest`, '--no-audit', '--no-fund', '--loglevel', 'error'];\n return new Promise((resolve, reject) => {\n const child = spawn(npm.command, full, {\n stdio: 'inherit',\n windowsHide: true,\n shell: usesShell(npm.command),\n });\n child.on('error', reject);\n child.on('close', (code) => resolve({ code, stderr: '' }));\n });\n}\n","import fs from 'node:fs';\nimport {\n commitManagedWebRoot,\n installManagedBinary,\n installManagedWebRoot,\n isNewerVersion,\n pruneManagedBinaries,\n updatePaths,\n} from '@aidotnet/update-core';\nimport { findPackagedServerBinary } from './binary.js';\nimport {\n applyServerInfo,\n readInstallJson,\n writeInstallJson,\n type InstallJson,\n} from './install-json.js';\n\n/**\n * npx / pnpm dlx run packages from a throwaway cache (~/.npm/_npx/<hash>/…,\n * …/pnpm/dlx/…) that may be pruned at any time — never a durable server path.\n */\nexport function isEphemeralPackagePath(p: string): boolean {\n return /[\\\\/](_npx|dlx)[\\\\/]/.test(p);\n}\n\n/** Whether install.json already points at a server the desktop app can keep using. */\nexport function hasUsableServer(\n install: InstallJson | null,\n cliVersion: string,\n exists: (p: string) => boolean = (p) => fs.existsSync(p),\n): boolean {\n const current = install?.serverPath?.trim();\n if (!current || !exists(current) || isEphemeralPackagePath(current)) return false;\n // A recorded server older than the one shipped with this CLI gets replaced.\n return !(install?.serverVersion && isNewerVersion(cliVersion, install.serverVersion));\n}\n\nexport type DesktopServerResult =\n | { action: 'kept' | 'recorded' | 'copied'; serverPath: string }\n | { action: 'missing'; reason: string };\n\nexport interface EnsureDesktopServerOptions {\n home: string;\n /** Version of this CLI — its platform package ships the same server version. */\n version: string;\n platform: string;\n /** Test seam — defaults to the platform package installed next to this CLI. */\n findPackaged?: () => { path: string } | { error: string };\n}\n\n/**\n * The desktop app finds the server only through install.json / ASTRA_SERVER_BIN\n * (no platform-package fallback), so `astra install --desktop` must leave a\n * durable serverPath behind. A globally installed package path is recorded\n * as-is (the same path `astra start` records). A binary inside an npx cache is\n * copied into the updater's managed dir (~/.astra/server/astra-server-<version>)\n * together with wwwroot, because the server serves the web UI from the\n * directory of its own executable.\n */\nexport function ensureDesktopServer(o: EnsureDesktopServerOptions): DesktopServerResult {\n const install = readInstallJson(o.home);\n const current = install?.serverPath;\n if (current && hasUsableServer(install, o.version)) return { action: 'kept', serverPath: current };\n\n const packaged = (o.findPackaged ?? (() => findPackagedServerBinary()))();\n if (!('path' in packaged)) return { action: 'missing', reason: packaged.error };\n\n let serverPath = packaged.path;\n let action: 'recorded' | 'copied' = 'recorded';\n if (isEphemeralPackagePath(packaged.path)) {\n const { serverDir } = updatePaths(o.home);\n serverPath = installManagedBinary({\n stagedPath: packaged.path,\n serverDir,\n version: o.version,\n platform: o.platform,\n });\n if (installManagedWebRoot(packaged.path, serverDir)) commitManagedWebRoot(serverDir);\n pruneManagedBinaries(serverDir, serverPath);\n action = 'copied';\n }\n writeInstallJson(\n o.home,\n applyServerInfo(readInstallJson(o.home), { serverPath, serverVersion: o.version }),\n );\n return { action, serverPath };\n}\n","import readline from 'node:readline';\nimport { Writable } from 'node:stream';\n\n/** Read a line without echoing it (falls back to plain stdin when piped). */\nexport function promptHidden(question: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const stdin = process.stdin;\n if (!stdin.isTTY) {\n let data = '';\n stdin.setEncoding('utf8');\n stdin.on('data', (chunk: string) => {\n data += chunk;\n });\n stdin.on('end', () => resolve(data.replace(/\\r?\\n$/, '')));\n stdin.on('error', reject);\n return;\n }\n process.stdout.write(question);\n const muted = new Writable({\n write(_chunk, _encoding, callback) {\n callback();\n },\n });\n const rl = readline.createInterface({ input: stdin, output: muted, terminal: true });\n rl.question('', (answer) => {\n rl.close();\n process.stdout.write('\\n');\n resolve(answer);\n });\n });\n}\n\nexport function confirmPrompt(question: string): Promise<boolean> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n rl.question(question, (answer) => {\n rl.close();\n resolve(/^\\s*(y|yes)/i.test(answer.trim()));\n });\n });\n}\n","import fs from 'node:fs';\nimport { spawn } from 'node:child_process';\nimport { AstraError } from '../errors.js';\nimport { info, success, warn } from '../ui.js';\nimport { astraHome } from '../lib/paths.js';\nimport { resolveServerBinary } from '../lib/binary.js';\nimport { confirmPrompt } from '../lib/prompt.js';\nimport { exitCodeOf } from '../lib/process-utils.js';\nimport { stopServer } from '../lib/server-lifecycle.js';\nimport { runAutostart } from './autostart.js';\nimport { runUninstallClient } from './desktop.js';\nimport { PACKAGE_NAME } from '../version.js';\n\nasync function restoreAllOffline(purge: boolean): Promise<void> {\n const command = resolveServerBinary();\n const child = spawn(\n command.command,\n [...command.args, 'restore-all', ...(purge ? ['--purge'] : [])],\n { stdio: 'inherit', windowsHide: true },\n );\n const code = await exitCodeOf(child);\n if (code !== 0) throw new AstraError(`restore-all exited with code ${code}.`);\n}\n\n/**\n * Full uninstall: restore client configs → disable autostart → remove the\n * desktop app → stop the server → optionally delete ~/.astra.\n */\nexport async function runUninstall(opts: { purge?: boolean }): Promise<void> {\n const home = astraHome();\n info('Uninstalling Astra…');\n\n info('• Restoring client configurations…');\n try {\n await restoreAllOffline(opts.purge === true);\n } catch (err) {\n warn(`restore-all failed: ${(err as Error).message}`);\n }\n\n info('• Disabling autostart…');\n try {\n await runAutostart('disable');\n } catch (err) {\n warn(`Could not disable autostart: ${(err as Error).message}`);\n }\n\n info('• Removing the desktop app…');\n try {\n await runUninstallClient();\n } catch (err) {\n warn(`Could not remove the desktop app: ${(err as Error).message}`);\n }\n\n info('• Stopping the server…');\n try {\n await stopServer();\n } catch (err) {\n warn(`Could not stop the server: ${(err as Error).message}`);\n }\n\n if (opts.purge) {\n if (process.stdin.isTTY) {\n const ok = await confirmPrompt(`Delete all Astra data in ${home}? [y/N] `);\n if (!ok) {\n console.log('Skipped data deletion. Run `astra uninstall --purge` again to delete it.');\n return;\n }\n }\n fs.rmSync(home, { recursive: true, force: true });\n success(`Deleted ${home}.`);\n }\n\n success(`Astra uninstalled. Remove the npm package with \\`npm uninstall -g ${PACKAGE_NAME}\\`.`);\n}\n","import { AstraError } from '../errors.js';\nimport { printTable, success } from '../ui.js';\nimport { apiRequest, ApiError } from '../lib/http.js';\nimport { ensureServerRunning } from '../lib/server-lifecycle.js';\nimport { CLIENT_KINDS, type ClientKind } from '../lib/platform.js';\n\ninterface ClientRow {\n kind: string;\n name?: string;\n enabled?: boolean;\n status?: string;\n providerId?: string;\n selectedModel?: string;\n availability?: string;\n}\n\ninterface ProviderRow {\n id: string;\n name?: string;\n templateId?: string;\n enabled?: boolean;\n modelCount?: number;\n}\n\ninterface TemplateRow {\n id: string;\n name?: string;\n variants?: { id: string; name?: string }[];\n}\n\ninterface ApiCallOptions {\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE';\n body?: unknown;\n}\n\nasync function api<T>(path: string, options: ApiCallOptions = {}): Promise<T> {\n const { base, runtime, started } = await ensureServerRunning();\n if (started) console.log('Server was not running — started it in the background.');\n return apiRequest<T>({\n base,\n path,\n method: options.method ?? 'GET',\n body: options.body,\n runtimeToken: runtime?.runtimeToken,\n });\n}\n\nfunction fmtBool(v: boolean | undefined): string {\n if (v === undefined) return '';\n return v ? 'yes' : 'no';\n}\n\nfunction findProvider(providers: ProviderRow[], idOrName: string): ProviderRow | undefined {\n const needle = idOrName.toLowerCase();\n const byId = providers.find((p) => p.id.toLowerCase() === needle);\n if (byId) return byId;\n const byName = providers.filter((p) => p.name?.toLowerCase() === needle);\n if (byName.length === 1) return byName[0];\n if (byName.length > 1) {\n throw new AstraError(\n `Provider name \"${idOrName}\" is ambiguous.`,\n `Matching ids: ${byName.map((p) => p.id).join(', ')} — use an id instead.`,\n );\n }\n return undefined;\n}\n\n// ---------- client ----------\n\nexport async function runClientList(): Promise<void> {\n const rows = await api<ClientRow[]>('/api/clients');\n printTable(\n rows.map((r) => [\n r.kind,\n r.name ?? '',\n fmtBool(r.enabled),\n r.status ?? '',\n r.providerId ?? '',\n r.selectedModel ?? '',\n r.availability ?? '',\n ]),\n ['KIND', 'NAME', 'ENABLED', 'STATUS', 'PROVIDER', 'MODEL', 'AVAILABILITY'],\n );\n}\n\nexport async function runClientStatus(kind: ClientKind): Promise<void> {\n const rows = await api<ClientRow[]>('/api/clients');\n const row = rows.find((r) => r.kind === kind);\n if (!row) throw new AstraError(`Unknown client kind: ${kind}.`);\n console.log(`Client: ${row.name ?? row.kind} (${row.kind})`);\n console.log(` Enabled ${fmtBool(row.enabled)}`);\n if (row.status) console.log(` Status ${row.status}`);\n if (row.availability) console.log(` Availability ${row.availability}`);\n if (row.providerId) console.log(` Provider ${row.providerId}`);\n if (row.selectedModel) console.log(` Model ${row.selectedModel}`);\n}\n\nexport async function runClientEnable(\n kind: ClientKind,\n opts: { provider: string; model?: string },\n): Promise<void> {\n const providers = await api<ProviderRow[]>('/api/providers');\n const provider = findProvider(providers, opts.provider);\n if (!provider) {\n throw new AstraError(\n `No provider matches \"${opts.provider}\".`,\n 'Run `astra provider list` to see available providers.',\n );\n }\n await api(`/api/clients/${kind}/enable`, {\n method: 'POST',\n body: { providerId: provider.id, ...(opts.model ? { model: opts.model } : {}) },\n });\n success(\n `Client \"${kind}\" enabled with provider \"${provider.name ?? provider.id}\"` +\n `${opts.model ? ` (model: ${opts.model})` : ''}.`,\n );\n console.log('Restart the client (Codex, Claude Desktop, …) if it does not pick up the change.');\n}\n\nexport async function runClientDisable(kind: ClientKind): Promise<void> {\n await api(`/api/clients/${kind}/disable`, { method: 'POST', body: {} });\n success(`Client \"${kind}\" disabled. Its original configuration was restored.`);\n}\n\n// ---------- provider ----------\n\nexport async function runProviderList(): Promise<void> {\n const rows = await api<ProviderRow[]>('/api/providers');\n printTable(\n rows.map((r) => [\n r.id,\n r.name ?? '',\n r.templateId ?? '',\n fmtBool(r.enabled),\n r.modelCount === undefined ? '' : String(r.modelCount),\n ]),\n ['ID', 'NAME', 'TEMPLATE', 'ENABLED', 'MODELS'],\n );\n}\n\nexport async function runProviderAdd(opts: {\n template: string;\n variant?: string;\n key: string;\n name?: string;\n}): Promise<void> {\n const templates = await api<TemplateRow[]>('/api/provider-templates');\n const needle = opts.template.toLowerCase();\n const template = templates.find(\n (t) => t.id.toLowerCase() === needle || t.name?.toLowerCase() === needle,\n );\n if (!template) {\n throw new AstraError(\n `Unknown provider template \"${opts.template}\".`,\n `Available templates: ${templates.map((t) => t.id).join(', ') || '(none reported)'}`,\n );\n }\n const variants = template.variants ?? [];\n let variantId: string | undefined = opts.variant;\n if (variants.length > 0 && !variantId) {\n throw new AstraError(\n `Template \"${template.id}\" has variants — pass --variant.`,\n `Variants: ${variants.map((v) => v.id).join(', ')}`,\n );\n }\n if (variantId && variants.length > 0 && !variants.some((v) => v.id === variantId)) {\n throw new AstraError(\n `Unknown variant \"${variantId}\" for template \"${template.id}\".`,\n `Variants: ${variants.map((v) => v.id).join(', ')}`,\n );\n }\n if (variants.length === 0) variantId = undefined;\n const created = await api<ProviderRow>('/api/providers', {\n method: 'POST',\n body: {\n templateId: template.id,\n ...(variantId ? { variantId } : {}),\n ...(opts.name ? { name: opts.name } : {}),\n apiKey: opts.key,\n },\n });\n success(`Provider added: ${created.name ?? created.id} (id: ${created.id}).`);\n}\n\nexport async function runProviderRemove(id: string): Promise<void> {\n try {\n await api(`/api/providers/${encodeURIComponent(id)}`, { method: 'DELETE' });\n } catch (err) {\n if (err instanceof ApiError && err.status === 409) {\n throw new AstraError(\n `Provider \"${id}\" is still bound to one or more clients.`,\n 'Disable the client or bind it to another provider first (`astra client disable <kind>`).',\n );\n }\n throw err;\n }\n success(`Provider \"${id}\" removed.`);\n}\n\nexport const KNOWN_CLIENT_KINDS: readonly string[] = CLIENT_KINDS;\n","import { spawn } from 'node:child_process';\nimport { AstraError } from '../errors.js';\nimport { info, success } from '../ui.js';\nimport { resolveServerBinary } from '../lib/binary.js';\nimport { promptHidden } from '../lib/prompt.js';\nimport { exitCodeOf } from '../lib/process-utils.js';\nimport { serverStatus } from '../lib/server-lifecycle.js';\n\nexport async function runSetPassword(): Promise<void> {\n const password = await promptHidden('Enter new admin password: ');\n if (!password) throw new AstraError('Password must not be empty.');\n const confirm = await promptHidden('Repeat password: ');\n if (confirm !== password) throw new AstraError('Passwords do not match.');\n\n const command = resolveServerBinary();\n const child = spawn(command.command, [...command.args, 'set-password'], {\n stdio: ['pipe', 'inherit', 'inherit'],\n windowsHide: true,\n });\n child.stdin?.write(`${password}\\n`);\n child.stdin?.end();\n const code = await exitCodeOf(child);\n if (code !== 0) {\n throw new AstraError(`set-password failed with exit code ${code}.`);\n }\n success('Admin password updated.');\n const status = await serverStatus();\n if (status.running) {\n info('Restart the server for the new password to take effect: `astra restart`.');\n }\n}\n","import { AstraError } from '../errors.js';\nimport { success } from '../ui.js';\nimport { resolveServerBinary } from '../lib/binary.js';\nimport { exitCodeOf } from '../lib/process-utils.js';\nimport { spawn } from 'node:child_process';\n\n/** Run the server binary's offline `restore-all` subcommand (no HTTP needed). */\nexport async function runRestoreAll(opts: { purge?: boolean }): Promise<void> {\n const command = resolveServerBinary();\n const args = [...command.args, 'restore-all', ...(opts.purge ? ['--purge'] : [])];\n const child = spawn(command.command, args, { stdio: 'inherit', windowsHide: true });\n const code = await exitCodeOf(child);\n if (code !== 0) {\n throw new AstraError(`restore-all failed with exit code ${code}.`);\n }\n success(\n opts.purge\n ? 'All client configurations were restored and Astra entries were removed from them.'\n : 'All client configurations were restored.',\n );\n}\n"],"mappings":"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","names":["process","path","process","process","path","fs","path","fs","path","info","fs","path","fs","path","fs","path","fs","path","fs","platformInfo","fs","fs","path","spawn","fs","path","first","runCapture","spawn","target","path","spawn","fs","path","fs","path","fs","spawn","fs","path","info","fs","path","path","fs","spawn","runCapture","applyServerInfo","fs","runCapture","applyServerInfo","child","spawn","process","os","process","fs","os","path","os","path","exec","runCapture","fs","process","os","fs","spawn","usesShell","spawn","fs","fs","applyServerInfo","fs","fs","spawn","spawn","fs","path","provider","spawn","spawn","spawn","process"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,52 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aidotnet/astra-gate",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Astra — a local AI gateway. Install, start, stop and manage the astra-server from the terminal.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"astra": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"astra",
|
|
18
|
+
"ai",
|
|
19
|
+
"gateway",
|
|
20
|
+
"llm",
|
|
21
|
+
"proxy"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"watch": "tsup --watch",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"lint": "eslint ."
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"commander": "^12.1.0"
|
|
32
|
+
},
|
|
33
|
+
"optionalDependencies": {
|
|
34
|
+
"@aidotnet/server-darwin-arm64": "0.2.0",
|
|
35
|
+
"@aidotnet/server-darwin-x64": "0.2.0",
|
|
36
|
+
"@aidotnet/server-linux-arm64": "0.2.0",
|
|
37
|
+
"@aidotnet/server-linux-x64": "0.2.0",
|
|
38
|
+
"@aidotnet/server-win32-arm64": "0.2.0",
|
|
39
|
+
"@aidotnet/server-win32-x64": "0.2.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@aidotnet/update-core": "workspace:*",
|
|
43
|
+
"@types/node": "^24.0.0",
|
|
44
|
+
"eslint": "^9.17.0",
|
|
45
|
+
"prettier": "^3.4.2",
|
|
46
|
+
"tsup": "^8.3.5",
|
|
47
|
+
"typescript": "^5.7.2",
|
|
48
|
+
"typescript-eslint": "^8.18.1",
|
|
49
|
+
"vitest": "^3.0.0"
|
|
50
|
+
},
|
|
51
|
+
"packageManager": "pnpm@9.15.0"
|
|
52
|
+
}
|
package/README.md
DELETED