deepspace 0.5.6 → 0.6.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/CHANGELOG.md +17 -0
- package/LICENSE +202 -0
- package/README.md +4 -0
- package/dist/cli.js +117 -30
- package/dist/cli.js.map +1 -1
- package/dist/testing.d.ts +115 -0
- package/package.json +13 -3
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/cli.ts","../src/cli/lib/cli-errors.ts","../src/cli/commands/login.ts","../src/cli/lib/spinner.ts","../src/cli/env.ts","../src/server/rooms/binding-manifest.ts","../src/cli/lib/secrets.ts","../src/cli/lib/app-identity.ts","../src/cli/lib/secure-file.ts","../src/cli/lib/wrangler-env.ts","../src/server/rooms/app-name.ts","../src/cli/session.ts","../src/cli/lib/open-browser.ts","../src/cli/commands/logout.ts","../src/cli/commands/dev.ts","../src/cli/auth.ts","../src/cli/jwt.ts","../src/cli/lib/app-context.ts","../src/cli/lib/api.ts","../src/cli/lib/install-status.ts","../src/cli/lib/preflight.ts","../src/cli/lib/macos-junk.ts","../src/cli/lib/port.ts","../src/cli/commands/kill.ts","../src/cli/commands/test.ts","../src/cli/lib/playwright.ts","../src/cli/commands/screenshot.ts","../src/cli/commands/test-accounts.ts","../src/cli/commands/deploy.ts","../src/cli/commands/undeploy.ts","../src/cli/commands/whoami.ts","../src/cli/commands/apps.ts","../src/cli/commands/add.ts","../src/cli/commands/domain.ts","../src/cli/commands/collaborators.ts","../src/server/auth/testAccounts.ts","../src/cli/commands/transfer.ts","../src/cli/commands/integrations.ts","../src/cli/commands/_invoke-impl.ts","../src/cli/commands/invoke.ts","../src/cli/commands/library.ts","../src/cli/commands/feedback.ts","../src/cli/commands/secrets.ts","../src/cli/lib/citty-args.ts","../src/cli/commands/init.ts"],"sourcesContent":["/**\n * DeepSpace CLI\n *\n * Commands:\n * login — authenticate with your DeepSpace account\n * deploy — build and deploy your app to *.app.space\n * undeploy — remove a deployed app\n * create — redirects to `npm create deepspace`\n */\n\nimport { defineCommand, runMain } from 'citty'\nimport { spawnSync } from 'node:child_process'\nimport { readFileSync, existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { wrapCommandErrors } from './lib/cli-errors'\nimport login from './commands/login'\nimport logout from './commands/logout'\nimport dev from './commands/dev'\nimport kill from './commands/kill'\nimport test from './commands/test'\nimport screenshot from './commands/screenshot'\nimport testAccounts from './commands/test-accounts'\nimport deploy from './commands/deploy'\nimport undeploy from './commands/undeploy'\nimport whoami from './commands/whoami'\nimport apps from './commands/apps'\nimport add from './commands/add'\nimport domain from './commands/domain'\nimport collaborators from './commands/collaborators'\nimport transfer from './commands/transfer'\nimport integrations from './commands/integrations'\nimport invoke from './commands/invoke'\nimport library from './commands/library'\nimport feedback from './commands/feedback'\nimport secrets from './commands/secrets'\nimport init from './commands/init'\n\n// Read own version from package.json so the CLI banner stays in sync with publishes.\n// __dirname of the bundled output is <pkg>/dist; package.json sits one level up.\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'))\n\n// workerd doesn't auto-discover system CAs in containers — outbound HTTPS to the\n// auth/api workers fails with \"TLS peer's certificate is not trusted\" until we\n// point it at the standard Debian/Ubuntu cert bundle. Harmless on macOS (path\n// doesn't exist, env var not set).\nif (\n process.platform === 'linux' &&\n !process.env.SSL_CERT_FILE &&\n existsSync('/etc/ssl/certs/ca-certificates.crt')\n) {\n process.env.SSL_CERT_FILE = '/etc/ssl/certs/ca-certificates.crt'\n}\n\nconst create = defineCommand({\n meta: {\n name: 'create',\n description: 'Create a new DeepSpace app (runs create-deepspace; all flags are forwarded)',\n },\n args: {\n name: {\n type: 'positional',\n description: 'App name',\n required: false,\n },\n interactive: {\n type: 'boolean',\n description: 'Prompt for options instead of using defaults',\n },\n local: {\n type: 'string',\n description: 'Use a local SDK monorepo checkout instead of the published package',\n },\n },\n run({ rawArgs }) {\n // Forward EVERY argument verbatim and pin the scaffolder to this CLI's own\n // version — `npm create deepspace@latest` used to drop all flags and could\n // fetch a create-deepspace newer than the running CLI.\n const scaffolder = `create-deepspace@${pkg.version}`\n console.log(`Running: npx ${scaffolder} ${rawArgs.join(' ')}`.trimEnd() + '\\n')\n const res = spawnSync('npx', ['-y', scaffolder, ...rawArgs], { stdio: 'inherit' })\n process.exit(res.status ?? 1)\n },\n})\n\nconst main = defineCommand({\n meta: {\n name: 'deepspace',\n version: pkg.version,\n description: 'DeepSpace SDK CLI',\n },\n subCommands: {\n init,\n create,\n login,\n logout,\n whoami,\n apps,\n dev,\n kill,\n test,\n screenshot,\n 'test-accounts': testAccounts,\n add,\n integrations,\n invoke,\n deploy,\n undeploy,\n domain,\n collaborators,\n transfer,\n library,\n feedback,\n secrets,\n },\n // No `run()` here — citty cascades parent run() AFTER subcommand finishes,\n // which corrupts agent-friendly output (`--json`) and prints noise on every\n // command. Citty's default behavior when no subcommand matches is to print\n // help, which is what we want for `deepspace` with no args.\n})\n\n// Escaped errors (API failures, network hiccups) render as one clean line\n// instead of citty's default Error-object dump with a stack trace.\nrunMain(wrapCommandErrors(main))\n","/**\n * Friendly rendering for errors that escape a command's run().\n *\n * citty's runMain catches escaped errors and console.errors the full Error\n * object — stack trace and all. For expected operational failures (an API\n * 403, a network hiccup) that reads like a crash. wrapCommandErrors()\n * recursively wraps every command's run() so escaped errors render as a\n * single clean message (with known API error slugs translated), while\n * citty's own help/version/usage handling stays untouched. Set DEBUG=1 to\n * get the full stack back.\n */\n\nimport type { CommandDef } from 'citty'\n\n/**\n * API error slugs that genuinely confuse people → what to tell them. Slugs\n * whose meaning is obvious from the name (invalid_email, ...) stay unmapped\n * and render as-is; don't grow this into a mirror of the server's errors.\n */\nconst API_ERROR_HINTS: Record<string, string> = {\n not_app_owner: 'Only the app owner can do this.',\n app_not_found:\n 'App not found. Check the app id — the DEEPSPACE_APP_ID value in wrangler.toml, usually ' +\n '`app_…` (a legacy app\\'s id is its name). List your apps with `deepspace apps`. ' +\n '(`domain` commands take the deployed app *name* instead.)',\n not_app_owner_or_collaborator: 'You must be the app owner or a collaborator to do this.',\n test_account_cannot_be_collaborator:\n 'Test accounts cannot be added as collaborators. Use a real DeepSpace account.',\n user_not_found:\n 'No DeepSpace user with that email. They need to log in to DeepSpace at least once ' +\n '(`deepspace login`, or sign in to any app) before they can be referenced by email.',\n}\n\n/** Exported for tests. One clean message for an escaped error. */\nexport function formatCliError(err: unknown): string {\n const message = err instanceof Error ? err.message : String(err)\n // Preferred: the platform returns { error: <sentence>, code: <slug> } and\n // apiFetch throws a typed ApiError carrying the code. Fallback: legacy\n // helpers throw `API <path> (<status>): <slug>` with the slug in the text.\n const code = (err as { code?: unknown })?.code\n const slug =\n typeof code === 'string' ? code : /^API \\S+ \\(\\d+\\): ([a-z0-9_]+)$/.exec(message)?.[1]\n const hint = slug ? API_ERROR_HINTS[slug] : undefined\n // The server sentence and the hint can say the same thing — don't stutter.\n return hint && !message.includes(hint) ? `${message}\\n${hint}` : message\n}\n\nfunction renderCliError(err: unknown): never {\n console.error(formatCliError(err))\n if (process.env.DEBUG) {\n // ApiError/secretsApi keep the internal REST path off the message; show it here.\n const { apiPath, status } = err as { apiPath?: string; status?: number }\n if (apiPath) console.error(`\\nAPI ${apiPath}${status ? ` (${status})` : ''}`)\n if (err instanceof Error && err.stack) console.error('\\n' + err.stack)\n }\n process.exit(1)\n}\n\ntype RunFn = NonNullable<CommandDef['run']>\n\n/**\n * Recursively wrap a concrete command tree's run() handlers. Only plain\n * object subcommands are wrapped — every command in this CLI is one; lazy\n * (function/promise) subcommand definitions would pass through unwrapped.\n */\nexport function wrapCommandErrors<T extends CommandDef>(cmd: T): T {\n const run = cmd.run\n if (run) {\n cmd.run = (async (ctx: Parameters<RunFn>[0]) => {\n try {\n await run(ctx)\n } catch (err) {\n renderCliError(err)\n }\n }) as RunFn\n }\n if (cmd.subCommands && typeof cmd.subCommands === 'object') {\n for (const sub of Object.values(cmd.subCommands)) {\n if (sub && typeof sub === 'object') wrapCommandErrors(sub as CommandDef)\n }\n }\n return cmd\n}\n","/**\n * deepspace login\n *\n * Opens the browser to sign in with GitHub or Google.\n * CLI polls the auth worker until login is complete.\n *\n * deepspace login # browser-based OAuth\n * deepspace login --email x --password y # non-interactive (discouraged: argv leaks)\n * echo \"$PW\" | deepspace login --email x --password-stdin # password via stdin\n * DEEPSPACE_EMAIL=x DEEPSPACE_PASSWORD=y deepspace login # via env\n */\n\nimport { defineCommand } from 'citty'\nimport { writeFileSync, mkdirSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport { randomBytes, createHash } from 'node:crypto'\nimport * as p from '@clack/prompts'\n\nimport { createSpinner } from '../lib/spinner'\nimport { DASHBOARD_URL, PLATFORM_URLS } from '../env'\nimport { exchangeSession, SESSION_COOKIE } from '../session'\nimport { openBrowser } from '../lib/open-browser'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? PLATFORM_URLS.auth\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\n\nexport default defineCommand({\n meta: {\n name: 'login',\n description: 'Log in to your DeepSpace account',\n },\n args: {\n email: {\n type: 'string',\n description: 'Email address (non-interactive mode; or $DEEPSPACE_EMAIL)',\n required: false,\n },\n password: {\n type: 'string',\n description: 'Password (discouraged — visible in ps/history; prefer --password-stdin or $DEEPSPACE_PASSWORD)',\n required: false,\n },\n 'password-stdin': {\n type: 'boolean',\n description: 'Read the password from stdin instead of --password',\n default: false,\n },\n },\n async run({ args }) {\n // Non-interactive mode for CI/agents. Password from --password-stdin\n // (safest), $DEEPSPACE_PASSWORD, or --password (discouraged — visible in\n // `ps`/shell history); email from --email or $DEEPSPACE_EMAIL. The env vars\n // are consulted ONLY when stdin is non-interactive, so ambient\n // DEEPSPACE_* in a dev shell can't hijack an interactive `deepspace login`\n // into a password login as a different identity.\n const interactive = Boolean(process.stdin.isTTY)\n const { email, password } = resolveLoginCredentials({\n emailArg: args.email,\n passwordArg: args.password,\n envEmail: interactive ? undefined : process.env.DEEPSPACE_EMAIL,\n envPassword: interactive ? undefined : process.env.DEEPSPACE_PASSWORD,\n passwordStdin: args['password-stdin'] ? readPasswordFromStdin() : undefined,\n })\n const passwordIntent =\n Boolean(args['password-stdin']) || args.password !== undefined || password !== undefined\n\n const decision = loginModeDecision({ email, password, passwordIntent })\n if (decision.mode === 'error') {\n console.error(decision.message)\n process.exit(1)\n }\n if (decision.mode === 'password') {\n console.log(`Signing in as ${email}...`)\n await doEmailLogin(email as string, password as string)\n console.log('Logged in')\n return\n }\n // decision.mode === 'oauth' → fall through to the browser flow below.\n\n // Browser-based OAuth flow\n p.intro('DeepSpace Login')\n\n const s = createSpinner()\n s.start('Creating login session...')\n\n // PKCE: generate a random verifier and send only its SHA-256 hash to the\n // server. The verifier never leaves this process, so the loginUrl alone\n // can't be used to drain credentials at /status — only this CLI can.\n const codeVerifier = base64url(randomBytes(32))\n const codeChallenge = base64url(createHash('sha256').update(codeVerifier).digest())\n\n // 1. Create a CLI session\n const sessionRes = await fetch(`${AUTH_URL}/api/auth/cli/session`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ code_challenge: codeChallenge }),\n })\n if (!sessionRes.ok) {\n s.stop('Failed')\n p.cancel('Could not create login session')\n process.exit(1)\n }\n const sessionData = (await sessionRes.json()) as {\n sessionId?: string\n loginUrl?: string\n }\n if (!sessionData.sessionId || !sessionData.loginUrl) {\n s.stop('Failed')\n p.cancel('Could not create login session')\n process.exit(1)\n }\n\n const { sessionId, loginUrl } = sessionData as {\n sessionId: string\n loginUrl: string\n }\n\n s.stop('Opening browser...')\n p.log.info(`If the browser doesn't open, visit:\\n ${loginUrl}`)\n\n // 2. Open browser\n openBrowser(loginUrl)\n\n // 3. Poll for completion\n s.start('Waiting for authentication...')\n const result = await pollForCompletion(sessionId, codeVerifier)\n\n if (!result) {\n s.stop('Timed out')\n p.cancel('Login timed out. Run `deepspace login` to try again.')\n process.exit(1)\n }\n\n // 4. Store credentials + provision the billing profile (see provisionProfile)\n storeCredentials(result.sessionToken, result.jwt)\n await provisionProfile(result.jwt)\n\n s.stop('Authenticated')\n p.log.success(`Logged in as ${result.name ?? result.email}`)\n p.note(\n `Manage your account, deployed apps, billing, and subscription\\nplans on the web dashboard:\\n\\n ${DASHBOARD_URL}`,\n 'Dashboard',\n )\n p.outro('Done')\n },\n})\n\n/**\n * Resolve non-interactive login credentials with a clear precedence (ONB-4):\n * email = --email > $DEEPSPACE_EMAIL; password = --password-stdin (when the flag\n * is set, its already-read value wins) > --password > $DEEPSPACE_PASSWORD.\n * Pure for testing.\n */\nexport function resolveLoginCredentials(opts: {\n emailArg?: string\n passwordArg?: string\n envEmail?: string\n envPassword?: string\n passwordStdin?: string\n}): { email?: string; password?: string } {\n const email = opts.emailArg || opts.envEmail || undefined\n const password =\n opts.passwordStdin !== undefined\n ? opts.passwordStdin\n : opts.passwordArg || opts.envPassword || undefined\n return { email, password }\n}\n\n/**\n * Decide how `login` should proceed given the resolved credentials (ONB-4).\n * `passwordIntent` is true when the user asked for a password login (a\n * credential flag/stdin or a resolved password). Crucially, a supplied-but-\n * incomplete credential set (missing email, or an EMPTY password — e.g. an\n * empty `--password-stdin` in CI) becomes an `error`, not a silent fall-through\n * to the browser OAuth flow (which would hang ~10 min in a headless pipeline).\n * Pure for testing.\n */\nexport function loginModeDecision(opts: {\n email?: string\n password?: string\n passwordIntent: boolean\n}): { mode: 'password' } | { mode: 'oauth' } | { mode: 'error'; message: string } {\n if (opts.email && opts.password) return { mode: 'password' }\n if (!opts.passwordIntent) return { mode: 'oauth' }\n if (!opts.email) {\n return {\n mode: 'error',\n message: 'Non-interactive login needs an email: --email <you@example.com> (or $DEEPSPACE_EMAIL).',\n }\n }\n return {\n mode: 'error',\n message:\n 'Non-interactive login needs a non-empty password: --password-stdin, $DEEPSPACE_PASSWORD, or --password.',\n }\n}\n\n/**\n * Read a password piped on stdin (one trailing newline stripped). Errors on a\n * TTY, where reading stdin would block forever waiting for EOF.\n */\nfunction readPasswordFromStdin(): string {\n if (process.stdin.isTTY) {\n console.error(\n '--password-stdin expects the password piped on stdin, e.g. `printf %s \"$PW\" | deepspace login --email you@x.com --password-stdin`.',\n )\n process.exit(1)\n }\n return readFileSync(0, 'utf-8').replace(/\\r?\\n$/, '')\n}\n\ninterface LoginResult {\n sessionToken: string\n jwt: string\n email: string\n name: string | null\n}\n\nasync function pollForCompletion(\n sessionId: string,\n codeVerifier: string,\n): Promise<LoginResult | null> {\n const maxAttempts = 120 // 10 minutes at 5s intervals\n const interval = 5000\n\n for (let i = 0; i < maxAttempts; i++) {\n await sleep(interval)\n\n try {\n const res = await fetch(`${AUTH_URL}/api/auth/cli/status/${sessionId}`, {\n headers: { 'x-code-verifier': codeVerifier },\n })\n\n if (res.status === 410 || res.status === 404) return null // expired / not found\n if (!res.ok) continue\n\n const data = (await res.json()) as {\n state?: string\n sessionToken?: string\n jwt?: string\n email?: string\n name?: string\n }\n\n if (data.state === 'complete' && data.sessionToken && data.jwt) {\n return {\n sessionToken: data.sessionToken,\n jwt: data.jwt,\n email: data.email ?? '',\n name: data.name ?? null,\n }\n }\n } catch {\n // Network error, keep polling\n }\n }\n\n return null\n}\n\nfunction storeCredentials(sessionToken: string, jwt: string) {\n const dir = join(homedir(), '.deepspace')\n mkdirSync(dir, { recursive: true, mode: 0o700 })\n writeFileSync(join(dir, 'session'), sessionToken, { mode: 0o600 })\n writeFileSync(join(dir, 'token'), jwt, { mode: 0o600 })\n}\n\n/**\n * Provision the user's billing profile so they can be referenced by email\n * immediately after logging in — e.g. added as a collaborator on someone\n * else's app. The api-worker's auth middleware upserts the `userProfiles`\n * row on any authenticated call, but login/whoami only ever touch the auth\n * worker, so a fresh CLI-only account otherwise has no profile and\n * `collaborators add <their-email>` 404s until their first deploy. One GET\n * to /api/users/me creates it. Best-effort: the same upsert happens on any\n * later api-worker call, so a transient failure here must not fail login.\n */\nasync function provisionProfile(jwt: string): Promise<void> {\n try {\n await fetch(`${API_URL}/api/users/me`, { headers: { Authorization: `Bearer ${jwt}` } })\n } catch {\n // non-fatal — the profile is upserted on the next api-worker request\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nfunction base64url(bytes: Buffer): string {\n return bytes.toString('base64').replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\n// ── Email/password login (for test accounts and CI) ────────────────\n\nasync function doEmailLogin(email: string, password: string): Promise<void> {\n const res = await fetch(`${AUTH_URL}/api/auth/sign-in/email`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Origin: AUTH_URL },\n body: JSON.stringify({ email, password }),\n redirect: 'manual',\n })\n\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as { message?: string }\n throw new Error(body.message ?? `Authentication failed (${res.status})`)\n }\n\n const setCookie = res.headers.get('set-cookie') ?? ''\n const cookieMatch = setCookie.match(new RegExp(`${SESSION_COOKIE}=([^;]+)`))\n if (!cookieMatch) {\n throw new Error('No session cookie returned')\n }\n const sessionToken = decodeURIComponent(cookieMatch[1])\n\n const jwt = await exchangeSession(AUTH_URL, sessionToken)\n if (!jwt) {\n throw new Error('JWT issuance failed')\n }\n\n storeCredentials(sessionToken, jwt)\n await provisionProfile(jwt)\n}\n","import * as p from '@clack/prompts'\n\n// In a real terminal, @clack/prompts repaints the spinner by writing `\\r`\n// to overwrite the previous frame. In non-TTY contexts (agents, CI logs,\n// pipes, `tee`-ed output) `\\r` does nothing and every frame becomes a new\n// line — a single long phase floods the log with thousands of repeats.\n// When stdout is not a TTY we fall back to one static line per phase.\nexport function createSpinner(): {\n start: (msg?: string) => void\n stop: (msg?: string) => void\n message: (msg?: string) => void\n} {\n if (process.stdout.isTTY) return p.spinner()\n return {\n start: (msg?: string) => { if (msg) console.log(msg) },\n stop: (msg?: string) => { if (msg) console.log(msg) },\n message: (msg?: string) => { if (msg) console.log(msg) },\n }\n}\n","/**\n * DeepSpace environment configuration.\n *\n * Shared between `dev`, `test`, and `deploy` commands.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { stripGeneratedSecretsCache } from './lib/secrets'\nexport { stripGeneratedSecretsCache } // re-export: env.test + callers treat env as the .dev.vars surface\nimport { readAppId } from './lib/app-identity'\nimport { writeSecretFileSync } from './lib/secure-file'\nimport {\n devVarsPathFor,\n resolveAppNameForEnv,\n readWranglerConfig,\n hasWranglerConfig,\n} from './lib/wrangler-env'\n\n/**\n * Production DeepSpace platform URLs. The CLI always targets production\n * workers — there is no separate dev stack. Individual worker URLs can be\n * overridden per-command via the `DEEPSPACE_*_URL` env vars.\n */\nexport const PLATFORM_URLS = {\n auth: 'https://auth.deep.space',\n api: 'https://api-worker.deep.space',\n platform: 'https://platform-worker.deep.space',\n deploy: 'https://deploy-worker.deep.space',\n} as const\n\n/**\n * Web dashboard for managing deployed apps, billing, subscription plans,\n * earnings, etc. Linked from `login` and `whoami` so developers\n * discover it (the CLI alone gives no hint that it exists).\n */\nexport const DASHBOARD_URL = 'https://dashboard.deep.space'\n\n/**\n * Fetch the JWT public key from an auth worker's /api/auth/jwks endpoint.\n */\nexport async function fetchPublicKey(authUrl: string): Promise<string> {\n const res = await fetch(`${authUrl}/api/auth/jwks`)\n if (!res.ok) {\n throw new Error(`Failed to fetch JWT public key (${res.status})`)\n }\n const data = (await res.json()) as { publicKey?: string }\n if (!data.publicKey) {\n throw new Error('JWKS response missing publicKey')\n }\n return data.publicKey\n}\n\n/**\n * Read the app name from the app's wrangler.toml. A non-canonical `name`\n * (e.g. `My_App` vs. `my-app`) is rejected with a clear error so wrangler.toml\n * stays the single source of truth — otherwise the canonical form would land\n * on deployed bindings and the registry while the raw form persisted in\n * `[vars].APP_NAME` and the client `SCOPE_ID`, splitting identity across\n * surfaces.\n *\n * `deepspace dev` runs in an app directory; the name is required.\n */\nfunction requireAppIdFor(appDir: string, wranglerEnv?: string): string {\n const id = readAppId(appDir, wranglerEnv)\n if (id) return id\n throw new Error(\n 'wrangler.toml has no DEEPSPACE_APP_ID' +\n (wranglerEnv ? ` for [env.${wranglerEnv}]` : '') +\n '. Run `deepspace init` (or `deepspace init --env <name>`) and retry.',\n )\n}\n\nfunction readAppName(appDir: string, wranglerEnv?: string): string {\n if (!hasWranglerConfig(appDir)) {\n throw new Error('No wrangler.toml found. Are you in a DeepSpace app directory?')\n }\n const config = readWranglerConfig(appDir)\n // Single source of truth — every command (deploy, dev, undeploy)\n // resolves through `resolveAppNameForEnv` so the validation rules\n // (missing block, empty name, collision with the top-level name,\n // canonical form) can never drift between them.\n const resolved = resolveAppNameForEnv(config, wranglerEnv)\n if (!resolved.ok) throw new Error(resolved.reason)\n\n // Refuse to proceed when the declared name doesn't already match the\n // canonical form. Otherwise the canonical name lands on deployed bindings\n // and the registry, while the raw name persists in `[vars].APP_NAME` and\n // client-side `SCOPE_ID = app:${APP_NAME}` — splitting the identity across\n // surfaces. Failing here forces the dev to fix wrangler.toml once, after\n // which every surface reads from the same source of truth.\n const rawName = wranglerEnv ? config.env?.[wranglerEnv]?.name : config.name\n if (rawName !== resolved.name) {\n const where = wranglerEnv ? `[env.${wranglerEnv}].name` : '`name`'\n throw new Error(\n `wrangler.toml: ${where} \"${rawName}\" is not in canonical form. ` +\n `Update it to \"${resolved.name}\" and re-run.`,\n )\n }\n return resolved.name\n}\n\n/**\n * Mint a long-lived app-owner JWT from the auth worker.\n *\n * The caller passes their own short-lived user JWT (obtained via\n * `ensureToken()` from auth.ts) and the target env's auth URL. The auth\n * worker verifies the caller, signs a 10-year owner-scoped token bound to\n * `appName`, and returns it. This same token is used in dev (written into\n * `.dev.vars`) and in production (injected as a secret at deploy time).\n */\nexport async function mintAppOwnerJwt(\n authUrl: string,\n callerJwt: string,\n appName: string,\n): Promise<string> {\n const res = await fetch(`${authUrl}/api/auth/mint-app-token`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${callerJwt}`,\n },\n body: JSON.stringify({ appId: appName }),\n })\n if (!res.ok) {\n const err = await res.text().catch(() => '')\n throw new Error(`Failed to mint APP_OWNER_JWT (${res.status}): ${err}`)\n }\n const body = (await res.json()) as { token?: string; error?: string }\n if (!body.token) {\n throw new Error(`Auth worker returned no token: ${body.error ?? 'unknown error'}`)\n }\n return body.token\n}\n\n/**\n * Fetch the per-app HMAC identity token from the deploy worker. The starter's\n * /_deepspace/* proxy attaches this token on every call to the API worker so\n * the platform can verify the request originated from a known app. In\n * production this is minted at deploy time and injected as a Worker binding;\n * in local dev we fetch it via this endpoint, which is gated by app ownership.\n */\nexport async function fetchAppIdentityToken(\n deployUrl: string,\n callerJwt: string,\n appName: string,\n): Promise<string | null> {\n const res = await fetch(`${deployUrl}/api/apps/${encodeURIComponent(appName)}/identity-token`, { // appName carries the appId\n method: 'POST',\n headers: { Authorization: `Bearer ${callerJwt}` },\n })\n if (res.status === 404) {\n // App hasn't been deployed yet — pre-deploy dev workflow. The proxy will\n // 401 calls under /_deepspace/* until first deploy registers the app.\n return null\n }\n if (!res.ok) {\n const err = await res.text().catch(() => '')\n throw new Error(`Failed to fetch APP_IDENTITY_TOKEN (${res.status}): ${err}`)\n }\n const body = (await res.json()) as { token?: string; error?: string }\n if (!body.token) {\n throw new Error(`Deploy worker returned no token: ${body.error ?? 'unknown error'}`)\n }\n return body.token\n}\n\n/**\n * Keys the SDK manages in the top section of .dev.vars. They're rewritten\n * on every `deepspace dev`/`test`/`deploy` run from the platform's truth\n * (auth URL, owner JWT, identity token, etc.). Keys that match this set\n * are stripped from the top section on read so they don't double-write.\n *\n * Critically: this set is only consulted above the legacy/custom divider.\n * Once we cross that divider, content is preserved so older workspaces and\n * local-only non-secret vars are not clobbered. New app secrets should flow\n * through `npx deepspace secrets`, which renders a generated cache section.\n */\nconst SDK_MANAGED_KEYS = new Set([\n 'AUTH_JWT_PUBLIC_KEY',\n 'AUTH_JWT_ISSUER',\n 'AUTH_WORKER_URL',\n 'API_WORKER_URL',\n 'PLATFORM_WORKER_URL',\n 'OWNER_USER_ID',\n 'APP_OWNER_JWT',\n 'APP_IDENTITY_TOKEN',\n 'ALLOW_DEBUG_ROUTES',\n])\n\n// Marker the SDK writes between its own keys and user-managed content. We\n// recognize and strip this line on read so it doesn't accumulate across runs.\nexport const DEV_VARS_DIVIDER = '# --- not managed by the SDK; preserved across dev/test runs ---'\n\n\ninterface WriteDevVarsOptions {\n /** The app's immutable id when the caller already resolved it; read from\n * wrangler.toml otherwise. */\n appId?: string\n /**\n * Remote app secrets rendered as a generated dotenv cache. When present,\n * this replaces the legacy preserved section so the remote store stays the\n * source of truth.\n */\n generatedSecretsCache?: string\n /**\n * Linked secrets configs use a shared `.dev.vars` cache across Wrangler envs.\n * Unlinked apps keep Wrangler's legacy `.dev.vars.<env>` convention.\n */\n sharedDevVarsCache?: boolean\n}\n\n/**\n * Strip SDK-managed lines from an existing .dev.vars file, preserving all\n * other content (comments, blank lines, custom KEY=value pairs, multi-line\n * quoted values). Also strips the SDK divider marker so it doesn't double\n * up across runs.\n *\n * Exported for testing.\n */\nexport function extractCustomDevVars(content: string): string {\n const lines = content.split('\\n')\n const out: string[] = []\n // SDK-managed keys are only stripped above the divider. Once we cross\n // into the legacy/custom section, every line is preserved verbatim so\n // older workspaces and local-only non-secret vars survive rewrites.\n let belowDivider = false\n let i = 0\n while (i < lines.length) {\n const line = lines[i]\n if (line.trim() === DEV_VARS_DIVIDER.trim()) {\n // Drop our own divider — writeDevVars will re-add a single one.\n belowDivider = true\n i++\n continue\n }\n const eq = line.indexOf('=')\n const keyMatch = eq >= 0 ? line.slice(0, eq).match(/^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*$/) : null\n if (!keyMatch) {\n // Comment, blank, or non-key line — preserve verbatim.\n out.push(line)\n i++\n continue\n }\n const key = keyMatch[1]\n const valStart = line.slice(eq + 1)\n const block: string[] = [line]\n // Multi-line quoted value: opens with `\"` and the rest of the line has no\n // closing quote. Keep accumulating until a closing `\"` lands.\n if (valStart.startsWith('\"') && !hasUnescapedQuote(valStart.slice(1))) {\n i++\n while (i < lines.length) {\n block.push(lines[i])\n const closed = hasUnescapedQuote(lines[i])\n i++\n if (closed) break\n }\n } else {\n i++\n }\n if (belowDivider || !SDK_MANAGED_KEYS.has(key)) {\n out.push(...block)\n }\n }\n // Trim trailing blanks so we don't accumulate them across runs.\n while (out.length && out[out.length - 1].trim() === '') out.pop()\n return out.join('\\n')\n}\n\nfunction hasUnescapedQuote(s: string): boolean {\n let escaped = false\n for (const ch of s) {\n if (escaped) {\n escaped = false\n continue\n }\n if (ch === '\\\\') {\n escaped = true\n continue\n }\n if (ch === '\"') return true\n }\n return false\n}\n\n/**\n * Parse a `.dev.vars` (dotenv) string into a key→value map.\n *\n * Handles:\n * - bare KEY=value\n * - KEY=\"quoted value\"\n * - multi-line KEY=\"-----BEGIN ...\\n-----END ...\"\n * - escaped quotes/backslashes inside (`KEY=\"he said \\\"hi\\\"\"` / `KEY=\"C:\\\\tmp\"`)\n * - comments and blank lines (skipped)\n *\n * Used for two things:\n * 1. parsing generated or legacy `.dev.vars` content so the CLI can ship\n * app-defined secrets as `secret_text` bindings at deploy time\n * 2. round-tripping for tests\n *\n * Exported.\n */\nexport function parseDevVars(content: string): Record<string, string> {\n const result: Record<string, string> = {}\n const lines = content.split('\\n')\n let i = 0\n while (i < lines.length) {\n const line = lines[i]\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith('#')) {\n i++\n continue\n }\n const eq = line.indexOf('=')\n if (eq < 0) {\n i++\n continue\n }\n const keyMatch = line.slice(0, eq).match(/^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*$/)\n if (!keyMatch) {\n i++\n continue\n }\n const key = keyMatch[1]\n let value = line.slice(eq + 1)\n\n // Multi-line quoted value: opens with `\"` and the rest of the line has\n // no closing quote. Keep accumulating until a closing `\"` lands.\n let closed = !value.startsWith('\"') || hasUnescapedQuote(value.slice(1))\n if (!closed) {\n i++\n while (i < lines.length) {\n value += '\\n' + lines[i]\n if (hasUnescapedQuote(lines[i])) {\n closed = true\n i++\n break\n }\n i++\n }\n } else {\n i++\n }\n\n // Reject unterminated quoted values rather than silently corrupting the\n // secret. Without this guard, a `KEY=\"value with no closing quote` line\n // would round-trip through deploy as a literal leading `\"` in the value\n // — a near-impossible bug to debug in production.\n if (value.startsWith('\"') && !closed) {\n throw new Error(\n `parseDevVars: unterminated quoted value for key \"${key}\" — check your .dev.vars file for a missing closing quote.`,\n )\n }\n\n // Strip surrounding quotes and decode the same two escapes emitted by\n // generated secrets cache rendering. Other backslash sequences are left\n // untouched for compatibility with manually-authored dotenv files.\n if (value.startsWith('\"') && value.endsWith('\"') && value.length >= 2) {\n value = unescapeQuotedDevVar(value.slice(1, -1))\n }\n\n result[key] = value\n }\n return result\n}\n\nfunction unescapeQuotedDevVar(value: string): string {\n let out = ''\n for (let i = 0; i < value.length; i++) {\n const ch = value[i]\n if (ch !== '\\\\' || i === value.length - 1) {\n out += ch\n continue\n }\n const next = value[i + 1]\n if (next === '\\\\' || next === '\"') {\n out += next\n i++\n continue\n }\n out += ch\n }\n return out\n}\n\n/**\n * Write .dev.vars for an app, pointing to the specified environment's workers.\n *\n * Only the SDK-managed keys (see `SDK_MANAGED_KEYS`) are rewritten on each\n * call. Existing non-generated lines are preserved for compatibility, but app\n * secrets should be managed with `npx deepspace secrets`, not direct edits.\n *\n * Includes a freshly-minted `APP_OWNER_JWT` so server-side code in the app\n * (DO alarms, cron handlers, autonomous agents) can call the API worker\n * proxy without any further auth plumbing. Uses the same flow as production:\n * the auth-worker mints the token, we store it as an env var.\n */\nexport async function writeDevVars(\n appDir: string,\n ownerId: string,\n callerJwt: string,\n /** Wrangler [env.<name>] block to target. When set, mints\n * APP_OWNER_JWT for that env's app (each env carries its own id). */\n wranglerEnv?: string,\n opts: WriteDevVarsOptions = {},\n): Promise<void> {\n const urls = PLATFORM_URLS\n const publicKey = await fetchPublicKey(urls.auth)\n // Tokens key to the immutable app id (docs/proposals/app-identity-registry.md);\n // renames never rotate identity. `deepspace init` mints the id for repos\n // that predate it.\n const appId = opts.appId ?? requireAppIdFor(appDir, wranglerEnv)\n const appOwnerJwt = await mintAppOwnerJwt(urls.auth, callerJwt, appId)\n // Pre-first-deploy this returns null (the app isn't in the registry yet)\n // — that's expected. The /_deepspace/* proxy will start working after the\n // first `deepspace deploy` registers the app and a follow-up\n // `deepspace dev` re-runs this writer.\n const appIdentityToken = await fetchAppIdentityToken(urls.deploy, callerJwt, appId)\n\n // Wrangler's .dev.vars parser is dotenv-style: bare multi-line values are\n // truncated to the first line. The PEM public key spans multiple lines, so\n // it MUST be wrapped in double quotes (dotenv multi-line value syntax).\n // Without this, AUTH_JWT_PUBLIC_KEY ends up as just \"-----BEGIN PUBLIC KEY-----\"\n // and `importSPKI` throws `DataError: Invalid SPKI input`, which silently\n // breaks JWT verification on every WS connection (anonymous fallback).\n const sdkVars = [\n `AUTH_JWT_PUBLIC_KEY=\"${publicKey}\"`,\n `AUTH_JWT_ISSUER=${urls.auth}/api/auth`,\n `AUTH_WORKER_URL=${urls.auth}`,\n `API_WORKER_URL=${urls.api}`,\n `PLATFORM_WORKER_URL=${urls.platform}`,\n `OWNER_USER_ID=${ownerId}`,\n `APP_OWNER_JWT=${appOwnerJwt}`,\n ...(appIdentityToken ? [`APP_IDENTITY_TOKEN=${appIdentityToken}`] : []),\n // Open /api/debug/* (proxied to RecordRoom) locally. This is the SDK's\n // dev-only auto-value; the deploy ships the remote store, not this\n // `.dev.vars` section, so it never reaches prod. To enable it on a deployed\n // env, `deepspace secrets set ALLOW_DEBUG_ROUTES=true`.\n `ALLOW_DEBUG_ROUTES=true`,\n ].join('\\n')\n\n const useSharedDevVarsCache = opts.sharedDevVarsCache ?? opts.generatedSecretsCache !== undefined\n const devVarsPath = devVarsPathFor(appDir, wranglerEnv, {\n sharedDevVarsCache: useSharedDevVarsCache,\n })\n const existing = existsSync(devVarsPath) ? readFileSync(devVarsPath, 'utf-8') : ''\n const custom =\n opts.generatedSecretsCache ?? extractCustomDevVars(stripGeneratedSecretsCache(existing).trimEnd())\n let body: string\n if (!custom) {\n body = `${sdkVars}\\n`\n } else if (opts.generatedSecretsCache) {\n // The cache section carries its own divider header.\n body = `${sdkVars}\\n\\n${custom}\\n`\n } else {\n body = `${sdkVars}\\n\\n${DEV_VARS_DIVIDER}\\n${custom}\\n`\n }\n\n writeSecretFileSync(devVarsPath, body)\n}\n","/**\n * Binding Manifest — non-DO bindings declared by an app's wrangler.toml that\n * the deploy-worker should pass through to Cloudflare's WfP upload API.\n *\n * Apps don't export a `__BINDING_MANIFEST__`; the CLI extracts these from the\n * normalized vite/wrangler output config at deploy time. This file just owns\n * the types + validation so both sides (CLI client and deploy-worker server)\n * agree on the shape.\n */\n/// <reference types=\"@cloudflare/workers-types\" />\n\n/**\n * A single non-DO binding the app declares. Mirrors CF's WfP binding API.\n *\n * Provisionable resources (d1, kv_namespace, vectorize, r2_bucket, queue) accept\n * the literal string `\"auto\"` in their ID field to request platform-side\n * provisioning at deploy time. When `\"auto\"` is used, the deploy-worker creates\n * the resource on the platform CF account, persists the resulting CF ID in the\n * app registry, and substitutes the real ID before forwarding to WfP. The\n * sentinel sticks around in this type because:\n * 1. `wrangler` parsing requires a non-empty string in the id field\n * 2. The CLI passes the unresolved manifest through to the deploy-worker\n * 3. The deploy-worker is the only side with CF API credentials\n *\n * Companion fields (`database_name`, `title`, `dimensions`, `metric`) are only\n * used when `\"auto\"` is set — they tell the provisioner how to create the\n * resource. After provisioning these fields are still present on the wire but\n * ignored by WfP.\n */\nexport type CustomBinding =\n | {\n type: 'vectorize'\n name: string\n /** Either a pre-existing index name or the literal `\"auto\"`. */\n index_name: string\n /** Required when `index_name === \"auto\"`. */\n dimensions?: number\n /** Required when `index_name === \"auto\"`. */\n metric?: 'cosine' | 'euclidean' | 'dot-product'\n }\n | { type: 'ai'; name: string }\n | {\n type: 'r2_bucket'\n name: string\n /** Either a pre-existing bucket name or the literal `\"auto\"`. */\n bucket_name: string\n }\n | {\n type: 'kv_namespace'\n name: string\n /** Either a pre-existing KV namespace ID or the literal `\"auto\"`. */\n namespace_id: string\n /** Required when `namespace_id === \"auto\"`. Human-readable namespace title. */\n title?: string\n }\n | {\n type: 'd1'\n name: string\n /** Either a pre-existing D1 database UUID or the literal `\"auto\"`. */\n id: string\n /** Required when `id === \"auto\"`. Human-readable database name. */\n database_name?: string\n }\n | {\n type: 'queue'\n name: string\n /** Either a pre-existing queue name or the literal `\"auto\"`. */\n queue_name: string\n }\n | { type: 'browser_rendering'; name: string }\n | { type: 'analytics_engine'; name: string; dataset?: string }\n | { type: 'hyperdrive'; name: string; id: string }\n\nexport type CustomBindingManifest = CustomBinding[]\n\n/** Sentinel string in an ID field that requests platform-side provisioning. */\nexport const AUTO_PROVISION_SENTINEL = 'auto'\n\n/** Binding types whose ID field accepts the `\"auto\"` sentinel for provisioning. */\nexport const AUTO_PROVISIONABLE_TYPES = new Set([\n 'd1',\n 'kv_namespace',\n 'vectorize',\n 'r2_bucket',\n 'queue',\n])\n\n/** Vectorize metric values accepted by CF when creating an index. */\nconst VECTORIZE_METRICS = new Set(['cosine', 'euclidean', 'dot-product'])\n\n/**\n * True if a binding has the `\"auto\"` sentinel in its primary ID field. Used by\n * the deploy-worker to decide which entries need provisioning and by the\n * validator to enforce companion-field requirements.\n */\nexport function isAutoProvision(b: CustomBinding): boolean {\n switch (b.type) {\n case 'd1':\n return b.id === AUTO_PROVISION_SENTINEL\n case 'kv_namespace':\n return b.namespace_id === AUTO_PROVISION_SENTINEL\n case 'vectorize':\n return b.index_name === AUTO_PROVISION_SENTINEL\n case 'r2_bucket':\n return b.bucket_name === AUTO_PROVISION_SENTINEL\n case 'queue':\n return b.queue_name === AUTO_PROVISION_SENTINEL\n default:\n return false\n }\n}\n\n/** Binding `type` values an app is allowed to declare. */\nexport const ALLOWED_BINDING_TYPES = new Set([\n 'vectorize',\n 'ai',\n 'r2_bucket',\n 'kv_namespace',\n 'd1',\n 'queue',\n 'browser_rendering',\n 'analytics_engine',\n 'hyperdrive',\n])\n\n/**\n * Binding NAMES the SDK reserves on every app — apps may not redeclare them.\n *\n * Includes:\n * - Static-asset + service bindings the platform sets up automatically.\n * - SDK-managed env (auth, identity, owner JWT).\n * - The auto-attached cost-tracking AE dataset (`USAGE_EVENTS`).\n *\n * DO binding names (RECORD_ROOMS, YJS_ROOMS, etc.) are NOT in this set\n * because they live in a separate manifest (`__DO_MANIFEST__`).\n */\nexport const RESERVED_BINDING_NAMES = new Set([\n 'ASSETS',\n 'PLATFORM_WORKER',\n 'API_WORKER',\n 'APP_NAME',\n 'OWNER_USER_ID',\n 'AUTH_JWT_PUBLIC_KEY',\n 'AUTH_JWT_ISSUER',\n 'AUTH_WORKER_URL',\n 'APP_IDENTITY_TOKEN',\n 'APP_OWNER_JWT',\n 'USAGE_EVENTS',\n])\n\n/**\n * Per-binding validation error. `binding` is undefined for top-level\n * shape failures (e.g. manifest is not an array).\n */\nexport interface ValidationError {\n binding?: CustomBinding\n reason: string\n}\n\n/**\n * Validate a binding manifest. Returns errors; an empty array means valid.\n *\n * Used both client-side (CLI) for friendly fail-fast and server-side\n * (deploy-worker) as a security boundary — apps can't sneak in reserved\n * binding names by editing the wire format.\n */\nexport function validateBindingManifest(\n manifest: unknown,\n): { valid: true; bindings: CustomBindingManifest } | { valid: false; errors: ValidationError[] } {\n if (!Array.isArray(manifest)) {\n return { valid: false, errors: [{ reason: 'Manifest must be an array' }] }\n }\n const errors: ValidationError[] = []\n const seenNames = new Set<string>()\n for (const entry of manifest) {\n if (!entry || typeof entry !== 'object') {\n errors.push({ reason: `Entry must be an object (got ${entry === null ? 'null' : typeof entry})` })\n continue\n }\n const e = entry as Record<string, unknown>\n const type = e.type\n const name = e.name\n if (typeof type !== 'string' || !ALLOWED_BINDING_TYPES.has(type)) {\n errors.push({\n reason: `Disallowed binding type: ${typeof type === 'string' ? type : `(${typeof type})`}. Allowed: ${[...ALLOWED_BINDING_TYPES].sort().join(', ')}`,\n })\n continue\n }\n if (typeof name !== 'string' || !name) {\n errors.push({ reason: `Binding of type \"${type}\" missing 'name' (string)` })\n continue\n }\n if (RESERVED_BINDING_NAMES.has(name)) {\n errors.push({ reason: `Binding name \"${name}\" is reserved by the SDK` })\n continue\n }\n if (seenNames.has(name)) {\n errors.push({ reason: `Duplicate binding name \"${name}\"` })\n continue\n }\n seenNames.add(name)\n // Now safely typed: type is in ALLOWED_BINDING_TYPES + name is a string.\n const binding = entry as CustomBinding\n const fieldErr = requiredFieldError(binding)\n if (fieldErr) errors.push({ binding, reason: fieldErr })\n }\n if (errors.length) return { valid: false, errors }\n return { valid: true, bindings: manifest as CustomBindingManifest }\n}\n\nfunction requiredFieldError(b: CustomBinding): string | null {\n switch (b.type) {\n case 'vectorize': {\n if (!b.index_name) return `vectorize binding \"${b.name}\" missing index_name (or \"auto\")`\n if (b.index_name === AUTO_PROVISION_SENTINEL) {\n // Auto-provisioning needs the index shape upfront — CF requires both\n // dimensions and metric at index-create time.\n if (typeof b.dimensions !== 'number' || b.dimensions <= 0) {\n return `vectorize binding \"${b.name}\" with index_name=\"auto\" requires \"dimensions\" (positive number)`\n }\n if (!b.metric || !VECTORIZE_METRICS.has(b.metric)) {\n return `vectorize binding \"${b.name}\" with index_name=\"auto\" requires \"metric\" (one of: ${[...VECTORIZE_METRICS].join(', ')})`\n }\n }\n return null\n }\n case 'r2_bucket':\n return b.bucket_name ? null : `r2_bucket binding \"${b.name}\" missing bucket_name (or \"auto\")`\n case 'kv_namespace': {\n if (!b.namespace_id) return `kv_namespace binding \"${b.name}\" missing namespace_id (or \"auto\")`\n if (b.namespace_id === AUTO_PROVISION_SENTINEL && !b.title) {\n return `kv_namespace binding \"${b.name}\" with namespace_id=\"auto\" requires \"title\"`\n }\n return null\n }\n case 'd1': {\n if (!b.id) return `d1 binding \"${b.name}\" missing id (or \"auto\")`\n if (b.id === AUTO_PROVISION_SENTINEL && !b.database_name) {\n return `d1 binding \"${b.name}\" with id=\"auto\" requires \"database_name\"`\n }\n return null\n }\n case 'queue':\n return b.queue_name ? null : `queue binding \"${b.name}\" missing queue_name (or \"auto\")`\n case 'hyperdrive':\n // Hyperdrive auto-provisioning is out of scope for v1 (needs upstream\n // connection-string management). Only pre-existing IDs accepted.\n if (!b.id) return `hyperdrive binding \"${b.name}\" missing id`\n if (b.id === AUTO_PROVISION_SENTINEL) {\n return `hyperdrive binding \"${b.name}\": auto-provisioning not yet supported (provide a real id)`\n }\n return null\n case 'ai':\n case 'browser_rendering':\n case 'analytics_engine':\n return null // no required fields beyond `name`\n default: {\n // Exhaustiveness guard — adding a new variant without a case fails here.\n const _exhaustive: never = b\n void _exhaustive\n return null\n }\n }\n}\n\n/**\n * Convert vite/wrangler's normalized config (from `.wrangler/deploy/config.json`)\n * into a CustomBindingManifest.\n *\n * Vite normalizes wrangler.toml into object/array structures with shapes like\n * `{ ai: { binding: 'AI' } }`, `{ vectorize: [{ binding, index_name }] }`,\n * etc. We extract each known shape with explicit field plucks (no broad\n * `as` casts) and return a flat array.\n */\nexport function bindingManifestFromOutputConfig(\n outputConfig: Record<string, unknown>,\n): CustomBindingManifest {\n const out: CustomBindingManifest = []\n\n // ai: single object\n const aiBinding = pluckString(outputConfig.ai, 'binding')\n if (aiBinding) out.push({ type: 'ai', name: aiBinding })\n\n // vectorize: array of { binding, index_name, dimensions?, metric? }\n // `dimensions` and `metric` are only required when index_name === \"auto\"\n // (auto-provisioning); the validator enforces that, so we just pluck both\n // here and let it decide.\n for (const v of asObjectArray(outputConfig.vectorize)) {\n const name = pluckString(v, 'binding')\n const index_name = pluckString(v, 'index_name')\n if (!name || !index_name) continue\n const dimensions = pluckNumber(v, 'dimensions')\n const metric = pluckString(v, 'metric')\n out.push({\n type: 'vectorize',\n name,\n index_name,\n ...(dimensions != null && { dimensions }),\n ...(metric && (metric === 'cosine' || metric === 'euclidean' || metric === 'dot-product') && { metric }),\n })\n }\n\n // r2_buckets: array of { binding, bucket_name }\n for (const r of asObjectArray(outputConfig.r2_buckets)) {\n const name = pluckString(r, 'binding')\n const bucket_name = pluckString(r, 'bucket_name')\n if (name && bucket_name) out.push({ type: 'r2_bucket', name, bucket_name })\n }\n\n // kv_namespaces: array of { binding, id, title? }\n // `title` is only required when id === \"auto\"; pluck both here and let\n // the validator enforce the dependency.\n for (const k of asObjectArray(outputConfig.kv_namespaces)) {\n const name = pluckString(k, 'binding')\n const namespace_id = pluckString(k, 'id')\n if (!name || !namespace_id) continue\n const title = pluckString(k, 'title')\n out.push({\n type: 'kv_namespace',\n name,\n namespace_id,\n ...(title && { title }),\n })\n }\n\n // d1_databases: array of { binding, database_id, database_name? }\n // `database_name` is only required when database_id === \"auto\"; pluck both\n // and let the validator enforce.\n for (const d of asObjectArray(outputConfig.d1_databases)) {\n const name = pluckString(d, 'binding')\n const id = pluckString(d, 'database_id')\n if (!name || !id) continue\n const database_name = pluckString(d, 'database_name')\n out.push({\n type: 'd1',\n name,\n id,\n ...(database_name && { database_name }),\n })\n }\n\n // queues.producers: array of { binding, queue }\n const queues = isObject(outputConfig.queues) ? outputConfig.queues : null\n for (const q of asObjectArray(queues?.producers)) {\n const name = pluckString(q, 'binding')\n const queue_name = pluckString(q, 'queue')\n if (name && queue_name) out.push({ type: 'queue', name, queue_name })\n }\n\n // browser: { binding } (Cloudflare names this `browser` not `browser_rendering`)\n const browserBinding = pluckString(outputConfig.browser, 'binding')\n if (browserBinding) out.push({ type: 'browser_rendering', name: browserBinding })\n\n // analytics_engine_datasets: array of { binding, dataset? }\n for (const a of asObjectArray(outputConfig.analytics_engine_datasets)) {\n const name = pluckString(a, 'binding')\n const dataset = pluckString(a, 'dataset')\n if (name) out.push({ type: 'analytics_engine', name, dataset: dataset ?? undefined })\n }\n\n // hyperdrive: array of { binding, id }\n for (const h of asObjectArray(outputConfig.hyperdrive)) {\n const name = pluckString(h, 'binding')\n const id = pluckString(h, 'id')\n if (name && id) out.push({ type: 'hyperdrive', name, id })\n }\n\n return out\n}\n\n// ---- internal helpers (no broad `as` casts) ----\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v)\n}\n\nfunction pluckString(v: unknown, key: string): string | null {\n if (!isObject(v)) return null\n const val = v[key]\n return typeof val === 'string' && val.length > 0 ? val : null\n}\n\nfunction pluckNumber(v: unknown, key: string): number | null {\n if (!isObject(v)) return null\n const val = v[key]\n return typeof val === 'number' && Number.isFinite(val) ? val : null\n}\n\nfunction asObjectArray(v: unknown): Record<string, unknown>[] {\n if (!Array.isArray(v)) return []\n return v.filter(isObject)\n}\n","/**\n * App secrets — client helpers for the app-anchored store\n * (docs/proposals/app-identity-registry.md §4.3).\n *\n * Every app has exactly one store, addressed by its immutable id:\n * `/api/secrets/:appId/configs/:config/...` on the deploy worker. Configs\n * follow the wrangler-env convention: the top-level config is `prd`, an\n * `--env staging` deploy ships the `staging` config. There are no per-user\n * projects and no app↔project links — those concepts are gone.\n */\n\nimport { RESERVED_BINDING_NAMES } from '../../server/rooms/binding-manifest'\n\nexport const GENERATED_SECRETS_DIVIDER =\n '# --- DeepSpace secrets cache: generated by `npx deepspace secrets`; do not edit manually ---'\n\n/**\n * Names a user may not set as an app secret. `RESERVED_BINDING_NAMES` covers\n * runtime bindings the platform injects; `API_WORKER_URL`/`PLATFORM_WORKER_URL`\n * are SDK-managed env that isn't a binding (so absent from that set) but is\n * still platform-owned. `ALLOW_DEBUG_ROUTES` is deliberately NOT here — it's a\n * normal, user-settable flag. Rejecting these client-side gives a clear message\n * instead of a raw server `(400)` that leaks the API path.\n */\nconst RESERVED_SECRET_NAMES = new Set([\n ...RESERVED_BINDING_NAMES,\n 'API_WORKER_URL',\n 'PLATFORM_WORKER_URL',\n])\n\nexport const SECRET_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/\nexport const CONFIG_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/\nconst MAX_SECRET_VALUE_BYTES = 32 * 1024\n\nexport interface SecretListItem {\n key: string\n version: number\n updatedAt: string\n updatedBy: string\n}\n\nexport interface SecretsConfigInfo {\n name: string\n createdAt: string\n updatedAt: string\n secretCount?: number\n}\n\nexport interface PulledSecretsCache {\n appId: string\n configName: string\n values: Record<string, string>\n}\n\nexport type SecretsDownloadFormat = 'dotenv' | 'json' | 'shell'\n\nexport function validateConfigName(configName: string): string {\n if (!CONFIG_NAME_RE.test(configName)) {\n throw new Error(\n `Invalid config \"${configName}\". Use letters, numbers, underscores, or hyphens; start with a letter or number.`,\n )\n }\n return configName\n}\n\nexport function validateSecretName(name: string): string {\n if (!SECRET_NAME_RE.test(name)) {\n throw new Error(\n `Invalid secret name \"${name}\". Use letters, numbers, and underscores; start with a letter or underscore.`,\n )\n }\n if (RESERVED_SECRET_NAMES.has(name)) {\n throw new Error(\n `\"${name}\" is managed by the DeepSpace SDK and can't be set as an app secret — ` +\n 'the platform injects it at deploy time.',\n )\n }\n return name\n}\n\nexport function validateSecretValue(key: string, value: string): void {\n if (new TextEncoder().encode(value).byteLength > MAX_SECRET_VALUE_BYTES) {\n throw new Error(`Secret \"${key}\" exceeds ${MAX_SECRET_VALUE_BYTES} bytes`)\n }\n}\n\n/** Config convention: top-level deploys/dev use `prd`; a wrangler env uses\n * its own name. */\nexport function defaultConfigNameForEnv(wranglerEnv?: string): string {\n return wranglerEnv ?? 'prd'\n}\n\n// ── HTTP plumbing ────────────────────────────────────────────────────────────\n\nexport async function secretsApi<T>(\n deployUrl: string,\n token: string,\n path: string,\n init: RequestInit = {},\n): Promise<T> {\n const res = await fetch(`${deployUrl}/api/secrets${path}`, {\n ...init,\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n ...(init.headers ?? {}),\n },\n })\n const body = (await res.json().catch(() => ({}))) as T & { error?: string }\n if (!res.ok) {\n // Surface the server's sentence, not the internal `/api/secrets/app_…/…`\n // slug — that path is an implementation detail and reads like a bug to\n // users. `status` carries the code for programmatic branches; set DEBUG=1\n // (via cli-errors) for the full error. `apiPath` is kept for debugging.\n const err = new Error(body.error ?? `Secrets request failed (${res.status})`) as Error & {\n status?: number\n apiPath?: string\n }\n err.status = res.status\n err.apiPath = path\n throw err\n }\n return body\n}\n\nexport function listSecrets(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n): Promise<{ secrets: SecretListItem[] }> {\n return secretsApi(deployUrl, token, `/${appId}/configs/${encodeURIComponent(configName)}`)\n}\n\nexport function fetchSecretsValues(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n): Promise<{ secrets: Record<string, string> }> {\n return secretsApi(deployUrl, token, `/${appId}/configs/${encodeURIComponent(configName)}/values`)\n}\n\nexport function getSecretPlain(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n key: string,\n): Promise<{ key: string; value: string }> {\n return secretsApi(\n deployUrl,\n token,\n `/${appId}/configs/${encodeURIComponent(configName)}/secrets/${encodeURIComponent(key)}?plain=true`,\n )\n}\n\nexport function setSecret(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n key: string,\n value: string,\n): Promise<{ ok: boolean }> {\n return secretsApi(\n deployUrl,\n token,\n `/${appId}/configs/${encodeURIComponent(configName)}/secrets/${encodeURIComponent(key)}`,\n { method: 'PUT', body: JSON.stringify({ value }) },\n )\n}\n\nexport function deleteSecret(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n key: string,\n): Promise<{ ok: boolean }> {\n return secretsApi(\n deployUrl,\n token,\n `/${appId}/configs/${encodeURIComponent(configName)}/secrets/${encodeURIComponent(key)}`,\n { method: 'DELETE' },\n )\n}\n\nexport function uploadSecrets(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n secrets: Record<string, string>,\n replace: boolean,\n): Promise<{ ok: boolean }> {\n return secretsApi(\n deployUrl,\n token,\n `/${appId}/configs/${encodeURIComponent(configName)}/secrets`,\n { method: 'PUT', body: JSON.stringify({ secrets, replace }) },\n )\n}\n\nexport function listConfigs(\n deployUrl: string,\n token: string,\n appId: string,\n): Promise<{ configs: SecretsConfigInfo[] }> {\n return secretsApi(deployUrl, token, `/${appId}/configs`)\n}\n\nexport function createConfig(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n copyFrom?: string,\n): Promise<{ ok: boolean }> {\n return secretsApi(deployUrl, token, `/${appId}/configs`, {\n method: 'POST',\n body: JSON.stringify({ name: configName, ...(copyFrom ? { copyFrom } : {}) }),\n })\n}\n\nexport function deleteConfig(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n): Promise<{ ok: boolean }> {\n return secretsApi(deployUrl, token, `/${appId}/configs/${encodeURIComponent(configName)}`, {\n method: 'DELETE',\n })\n}\n\n/**\n * Pull the app's config values for dev/test/deploy caches. Missing store or\n * config is NOT an error — a fresh app simply has no secrets yet.\n */\nexport async function pullAppSecretsCache(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n): Promise<PulledSecretsCache | null> {\n try {\n const { secrets } = await fetchSecretsValues(deployUrl, token, appId, configName)\n return { appId, configName, values: secrets }\n } catch (err) {\n // 404: no store yet, or no such config. Both mean \"nothing to ship\". Match\n // on the status field, not the message (which no longer carries the code).\n if ((err as { status?: number })?.status === 404) return null\n throw err\n }\n}\n\n// ── Cache rendering / parsing ────────────────────────────────────────────────\n\nexport function quoteDotenvValue(value: string): string {\n if (/^[A-Za-z0-9_./:@+-]*$/.test(value) && value !== '') return value\n // Newlines must be escaped or the value's tail parses as extra env vars;\n // dotenv expands \\n / \\r inside double-quoted values.\n const escaped = value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n return `\"${escaped}\"`\n}\n\n/** Render pulled values as the generated `.dev.vars` cache section. */\nexport function renderSecretsCache(\n secrets: Record<string, string>,\n source: { appId: string; configName: string },\n): string {\n const keys = Object.keys(secrets).sort()\n const lines = [\n GENERATED_SECRETS_DIVIDER,\n `# app ${source.appId} · config ${source.configName}`,\n '# Use `npx deepspace secrets` to change these values.',\n ]\n for (const key of keys) {\n validateSecretValue(key, secrets[key])\n lines.push(`${key}=${quoteDotenvValue(secrets[key])}`)\n }\n return lines.join('\\n')\n}\n\n/** Strip a previously generated cache section from a `.dev.vars` body. */\nexport function stripGeneratedSecretsCache(content: string): string {\n const idx = content.indexOf(GENERATED_SECRETS_DIVIDER)\n if (idx === -1) return content\n return content.slice(0, idx).trimEnd() + '\\n'\n}\n\n// ── Upload/download formats (Doppler-compatible) ─────────────────────────────\n\nexport function parseSecretsUpload(content: string): Record<string, string> {\n const trimmed = content.trim()\n if (!trimmed) return {}\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n const parsed = JSON.parse(trimmed) as unknown\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('JSON upload must be an object of KEY=value strings.')\n }\n const out: Record<string, string> = {}\n for (const [key, value] of Object.entries(parsed)) {\n validateSecretName(key)\n if (typeof value !== 'string') throw new Error(`Secret \"${key}\" must be a string`)\n validateSecretValue(key, value)\n out[key] = value\n }\n return out\n }\n // dotenv — supports multiline quoted values (dotenv ≥15 semantics): a value\n // whose opening quote isn't closed on its own line continues, verbatim,\n // until a line ending with the closing quote. Without this, uploading a\n // .env holding a real PEM silently stored one byte and minted phantom keys\n // from the base64 continuation lines.\n const out: Record<string, string> = {}\n const lines = trimmed.split(/\\r?\\n/)\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim()\n if (!line || line.startsWith('#')) continue\n const eq = line.indexOf('=')\n if (eq <= 0) continue // junk line — tolerated, like comments\n const key = line.slice(0, eq).trim()\n if (!SECRET_NAME_RE.test(key)) continue\n validateSecretName(key) // reject reserved/SDK-managed names with a clear message, same as `set`\n const raw = line.slice(eq + 1).trim()\n const quote = raw[0] === '\"' || raw[0] === \"'\" ? raw[0] : null\n let value: string\n if (!quote) {\n value = raw\n } else if (endsWithUnescapedQuote(raw.slice(1), quote)) {\n const inner = raw.slice(1, -1)\n value = quote === '\"' ? unescapeDotenv(inner) : inner\n } else {\n // Multiline: consume raw (untrimmed) lines until one closes the quote.\n const startLine = i + 1\n const parts = [raw.slice(1)]\n let closed = false\n while (++i < lines.length) {\n const cont = lines[i].trimEnd()\n if (endsWithUnescapedQuote(cont, quote)) {\n parts.push(cont.slice(0, -1))\n closed = true\n break\n }\n parts.push(lines[i])\n }\n if (!closed) {\n throw new Error(\n `Unterminated quoted value for \"${key}\" (opens on line ${startLine}). ` +\n `Close the ${quote === '\"' ? 'double' : 'single'} quote, or escape newlines as \\\\n on one line.`,\n )\n }\n value = parts.join('\\n')\n if (quote === '\"') value = unescapeDotenv(value)\n }\n validateSecretValue(key, value)\n out[key] = value\n }\n return out\n}\n\n/** True when `s` is non-empty and ends with `q` not preceded by an odd run of\n * backslashes (only `\"` values support escapes; `'` closes unconditionally). */\nfunction endsWithUnescapedQuote(s: string, q: string): boolean {\n if (!s.endsWith(q)) return false\n if (q === \"'\") return true\n let backslashes = 0\n for (let j = s.length - 2; j >= 0 && s[j] === '\\\\'; j--) backslashes++\n return backslashes % 2 === 0\n}\n\n/** Left-to-right so `\\\\n` (escaped backslash + n) isn't confused with `\\n`. */\nfunction unescapeDotenv(v: string): string {\n let out = ''\n for (let i = 0; i < v.length; i++) {\n if (v[i] === '\\\\' && i + 1 < v.length) {\n const c = v[++i]\n out += c === 'n' ? '\\n' : c === 'r' ? '\\r' : c\n } else {\n out += v[i]\n }\n }\n return out\n}\n\n/**\n * POSIX single-quote: wrap in `'…'`, closing/reopening around any embedded\n * single quote (`'\\''`). Unlike dotenv double-quoting, this preserves real\n * newlines literally, so `eval \"$(… download --format shell)\"` restores a\n * multiline value (e.g. a PEM key) byte-for-byte instead of a one-line `\\n`.\n */\nexport function shellSingleQuote(value: string): string {\n return `'${value.replace(/'/g, \"'\\\\''\")}'`\n}\n\nexport function formatSecretsDownload(\n secrets: Record<string, string>,\n format: SecretsDownloadFormat,\n): string {\n const entries = Object.entries(secrets).sort(([a], [b]) => a.localeCompare(b))\n if (format === 'json') {\n return JSON.stringify(Object.fromEntries(entries), null, 2) + '\\n'\n }\n if (format === 'shell') {\n return entries.map(([k, v]) => `export ${k}=${shellSingleQuote(v)}`).join('\\n') + '\\n'\n }\n return entries.map(([k, v]) => `${k}=${quoteDotenvValue(v)}`).join('\\n') + '\\n'\n}\n\n/**\n * The pull-and-render step every command shares (deploy/dev/test): fetch the\n * app's config values and render the generated `.dev.vars` cache section.\n * Returns null when the store/config doesn't exist yet (\"nothing to ship\").\n * Real failures (auth, 5xx) throw — callers cancel loudly.\n */\nexport async function refreshSecretsCache(\n deployUrl: string,\n token: string,\n appId: string,\n wranglerEnv: string | undefined,\n): Promise<{ pulled: PulledSecretsCache; rendered: string; summary: string } | null> {\n const configName = defaultConfigNameForEnv(wranglerEnv)\n const pulled = await pullAppSecretsCache(deployUrl, token, appId, configName)\n if (!pulled) return null\n const count = Object.keys(pulled.values).length\n return {\n pulled,\n rendered: renderSecretsCache(pulled.values, pulled),\n summary: `Secrets: ${pulled.configName} (${count} secret${count === 1 ? '' : 's'})`,\n }\n}\n","/**\n * App identity (docs/proposals/app-identity-registry.md).\n *\n * Every app carries an immutable id in wrangler.toml:\n *\n * [vars]\n * DEEPSPACE_APP_ID = \"app_01JG8QK…\" # minted at scaffold/init\n *\n * [env.staging.vars]\n * DEEPSPACE_APP_ID = \"app_01JG8QM…\" # each env is its own app\n *\n * The wrangler `name` field is just the subdomain label the next deploy\n * claims; identity is the id. Minting is local (a ULID — 80 random bits\n * need no server round-trip to be unique); registration happens at first\n * deploy.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport { parse as parseToml } from 'smol-toml'\n\nexport const APP_ID_RE = /^(app_[0-9A-HJKMNP-TV-Z]{26}|[a-z0-9][a-z0-9_-]{0,63})$/\n\nconst CROCKFORD = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'\n\n/** Mint a fresh app id: `app_` + 26-char ULID (48-bit ms timestamp + 80\n * random bits, Crockford base32). */\nexport function mintAppId(now = Date.now()): string {\n let ts = ''\n let t = now\n for (let i = 0; i < 10; i++) {\n ts = CROCKFORD[t % 32] + ts\n t = Math.floor(t / 32)\n }\n const rand = new Uint8Array(10)\n crypto.getRandomValues(rand)\n let rs = ''\n let acc = 0\n let bits = 0\n for (const byte of rand) {\n acc = (acc << 8) | byte\n bits += 8\n while (bits >= 5) {\n bits -= 5\n rs += CROCKFORD[(acc >> bits) & 31]\n }\n }\n return `app_${ts}${rs}`.slice(0, 30)\n}\n\n/**\n * Adopt the caller's existing app id for this subdomain, if they already own an\n * app there. A repo with no `DEEPSPACE_APP_ID` must NOT blindly mint a fresh id:\n * an app the platform already registered — e.g. one backfilled during the\n * app-identity cutover — owns its route, so a fresh id would collide\n * (\"name … is taken by another app\"). Look up the caller's apps and reuse the\n * id for a matching subdomain; return null (→ mint a new one) only when they\n * own nothing here. Best-effort: any failure returns null so the deploy still\n * proceeds and mints, exactly as before.\n */\nexport async function resolveOwnedAppId(\n deployUrl: string,\n token: string,\n appName: string,\n): Promise<string | null> {\n try {\n const res = await fetch(`${deployUrl}/api/apps`, {\n headers: { Authorization: `Bearer ${token}` },\n })\n if (!res.ok) return null\n const body = (await res.json()) as {\n apps?: Array<{ appId?: string; name?: string | null }>\n }\n const match = body.apps?.find((a) => a.name === appName)\n return match?.appId ?? null\n } catch {\n return null\n }\n}\n\ninterface WranglerVars {\n vars?: Record<string, unknown>\n env?: Record<string, { vars?: Record<string, unknown> }>\n}\n\n/** Read DEEPSPACE_APP_ID for the given wrangler env (top-level when omitted).\n * Env blocks do NOT inherit the top-level id — each env is its own app. */\nexport function readAppId(cwd: string = process.cwd(), wranglerEnv?: string): string | null {\n const wranglerPath = join(resolve(cwd), 'wrangler.toml')\n if (!existsSync(wranglerPath)) return null\n let cfg: WranglerVars\n try {\n cfg = parseToml(readFileSync(wranglerPath, 'utf-8')) as WranglerVars\n } catch (err) {\n // A corrupt wrangler.toml must NOT read as \"no id yet\" — callers would\n // tell the user to run `deepspace init` (a lie) or mint a SECOND id\n // into the broken file. Surface the real problem.\n throw new Error(\n `Could not parse ${wranglerPath}: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n const vars = wranglerEnv ? cfg.env?.[wranglerEnv]?.vars : cfg.vars\n const id = vars?.DEEPSPACE_APP_ID\n return typeof id === 'string' && APP_ID_RE.test(id) ? id : null\n}\n\n/**\n * Write DEEPSPACE_APP_ID into wrangler.toml, text-preserving: appended to the\n * existing `[vars]` / `[env.<name>.vars]` block, or the block is created.\n * Refuses to overwrite an existing id unless `force` — identity is immutable;\n * a new id means a new app (`deepspace init --new-id`).\n */\nexport function writeAppId(\n cwd: string,\n appId: string,\n opts: { wranglerEnv?: string; force?: boolean } = {},\n): void {\n const wranglerPath = join(resolve(cwd), 'wrangler.toml')\n if (!existsSync(wranglerPath)) {\n throw new Error(`No wrangler.toml in ${resolve(cwd)}`)\n }\n const existing = readAppId(cwd, opts.wranglerEnv)\n if (existing && !opts.force) {\n if (existing === appId) return\n throw new Error(\n `wrangler.toml already carries ${existing}. The app id is immutable — use --new-id only to fork this repo as a separate app.`,\n )\n }\n\n let src = readFileSync(wranglerPath, 'utf-8')\n const header = opts.wranglerEnv ? `[env.${opts.wranglerEnv}.vars]` : '[vars]'\n const line = `DEEPSPACE_APP_ID = \"${appId}\"`\n const headerRe = new RegExp(`^\\\\${header.replace(/\\./g, '\\\\.')}[ \\\\t]*$`, 'm')\n const idLineRe = /^DEEPSPACE_APP_ID\\s*=.*$/m\n\n const match = headerRe.exec(src)\n if (match) {\n // Insert (or replace) inside the existing block: from the header to the\n // next section header or EOF.\n const blockStart = match.index + match[0].length\n const rest = src.slice(blockStart)\n const nextSection = rest.search(/^\\s*\\[/m)\n const blockEnd = nextSection === -1 ? src.length : blockStart + nextSection\n const block = src.slice(blockStart, blockEnd)\n const newBlock = idLineRe.test(block)\n ? block.replace(idLineRe, line)\n : `\\n${line}${block}`\n src = src.slice(0, blockStart) + newBlock + src.slice(blockEnd)\n } else {\n src = src.trimEnd() + `\\n\\n${header}\\n${line}\\n`\n }\n writeFileSync(wranglerPath, src)\n}\n\n/** Read the app id or fail with the actionable next step. */\nexport function requireAppId(cwd: string = process.cwd(), wranglerEnv?: string): string {\n const id = readAppId(cwd, wranglerEnv)\n if (id) return id\n const where = wranglerEnv ? `[env.${wranglerEnv}.vars]` : '[vars]'\n throw new Error(\n `wrangler.toml has no DEEPSPACE_APP_ID in ${where}. Run \\`deepspace init\\` to mint one (existing deployed apps get theirs from the migration backfill — see the app-identity runbook).`,\n )\n}\n","import { chmodSync, writeFileSync } from 'node:fs'\n\n/**\n * Write a file that holds plaintext secret values (`.dev.vars` caches,\n * `secrets download` output) readable by the owner only. `writeFileSync`'s\n * `mode` applies only when the file is created, so chmod separately to\n * tighten files that already exist with a wider mode.\n */\nexport function writeSecretFileSync(path: string, content: string): void {\n writeFileSync(path, content, { mode: 0o600 })\n try {\n chmodSync(path, 0o600)\n } catch {\n // POSIX modes are best-effort on Windows; the write itself succeeded.\n }\n}\n","/**\n * Wrangler env resolution for DeepSpace's multi-environment deploys.\n *\n * Lets a single repo deploy to `<app>.app.space` and `<app>-staging.app.space`\n * (or any other named environment) from one `wrangler.toml`:\n *\n * name = \"hopkins\"\n * [vars]\n * APP_NAME = \"hopkins\"\n *\n * [env.staging]\n * name = \"hopkins-staging\"\n * [env.staging.vars]\n * APP_NAME = \"hopkins-staging\"\n *\n * Then `npx deepspace deploy --env staging` reads the override and ships to\n * `hopkins-staging.app.space`. The platform treats it as a fully separate\n * app — its own DO state, OAuth tokens, Stripe products, cron schedule.\n * No platform-side change needed beyond letting the CLI register a second\n * app under the same owner.\n *\n * When an app links a remote secrets project, DeepSpace keeps generated\n * dev/test/deploy credentials in a single `.dev.vars` cache so named\n * environments do not leave extra local files. In that linked-secrets mode,\n * `--env` flattens the selected Wrangler env into a generated config for the\n * Cloudflare Vite plugin instead of passing `CLOUDFLARE_ENV`; otherwise\n * Wrangler would prefer legacy `.dev.vars.<env>` files over the shared cache.\n * Unlinked apps keep Wrangler's legacy env-file behavior.\n */\n\nimport { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { parse as parseToml, stringify as stringifyToml } from 'smol-toml'\nimport { resolveAppName } from '../../server/rooms/app-name'\n\n/** Shape of the bits of wrangler.toml that DeepSpace CLI commands read.\n * Add an optional field here whenever a new command starts consulting\n * the config — avoids one-off `WranglerConfig & { … }` casts at\n * call sites and keeps the canonical type in one place. */\nexport interface WranglerConfig {\n name?: string\n env?: Record<\n string,\n ({ name?: string; vars?: Record<string, unknown> } & Record<string, unknown>) | undefined\n >\n /** `[assets]` block (`directory`, `binding`, `not_found_handling`,\n * `run_worker_first`). Consumed by deploy.ts to merge extra\n * worker-first routes into the deployed metadata. */\n assets?: {\n directory?: string\n binding?: string\n not_found_handling?: string\n run_worker_first?: unknown\n }\n /** `[vars]` block — string-valued environment variables baked into\n * the worker at deploy time. */\n vars?: Record<string, unknown>\n}\n\nexport interface PreparedWranglerEnvConfig {\n configPath?: string\n wranglerEnv?: string\n cleanup(): void\n}\n\nexport interface WranglerEnvModeOptions {\n sharedDevVarsCache?: boolean\n}\n\ntype TomlRecord = Record<string, unknown>\n\nconst NON_INHERITABLE_ENV_KEYS = new Set([\n 'define',\n 'vars',\n 'durable_objects',\n 'kv_namespaces',\n 'r2_buckets',\n 'ai_search_namespaces',\n 'ai_search',\n 'vectorize',\n 'services',\n 'queues',\n 'workflows',\n 'tail_consumers',\n 'secrets',\n 'secrets_store_secrets',\n])\n\nlet generatedConfigSeq = 0\n\n/**\n * Resolve the appName that this CLI invocation should target.\n *\n * Without `envName`: returns the top-level `name`.\n * With `envName`: returns `[env.<envName>].name` and requires that the\n * env block exists and declares a name. We refuse to\n * fall back to the top-level name because that would\n * silently deploy staging code to production.\n *\n * Returns a discriminated union so callers can surface a precise error\n * (matches the existing `resolveAppName` contract).\n */\nexport function resolveAppNameForEnv(\n config: WranglerConfig,\n envName: string | undefined,\n): { ok: true; name: string; warning?: string } | { ok: false; reason: string } {\n if (!envName) {\n return resolveAppName(config.name)\n }\n const envBlock = config.env?.[envName]\n if (!envBlock) {\n return {\n ok: false,\n reason:\n `wrangler.toml: no [env.${envName}] block found. ` +\n `Add one with a distinct \\`name\\` to deploy this environment.`,\n }\n }\n if (typeof envBlock.name !== 'string' || envBlock.name.trim() === '') {\n return {\n ok: false,\n reason:\n `wrangler.toml: [env.${envName}].name is missing. ` +\n `Set a distinct app name (e.g. \"${typeof config.name === 'string' ? config.name : 'myapp'}-${envName}\") so this environment doesn't overwrite the default.`,\n }\n }\n if (envBlock.name === config.name) {\n return {\n ok: false,\n reason:\n `wrangler.toml: [env.${envName}].name \"${envBlock.name}\" is the same as the top-level name. ` +\n `Pick a distinct name (e.g. \"${config.name}-${envName}\") so deploys don't collide.`,\n }\n }\n return resolveAppName(envBlock.name)\n}\n\n/** The .dev.vars path for the selected mode. Linked secrets use a shared cache. */\nexport function devVarsPathFor(\n appDir: string,\n envName: string | undefined,\n opts: WranglerEnvModeOptions = {},\n): string {\n if (opts.sharedDevVarsCache || !envName) return join(appDir, '.dev.vars')\n return join(appDir, `.dev.vars.${envName}`)\n}\n\nexport function legacyEnvDevVarsPathFor(\n appDir: string,\n envName: string | undefined,\n): string | undefined {\n return envName ? join(appDir, `.dev.vars.${envName}`) : undefined\n}\n\nexport function warnIfLegacyEnvDevVarsExists(\n appDir: string,\n envName: string | undefined,\n warn: (message: string) => void = console.warn,\n): void {\n const legacyPath = legacyEnvDevVarsPathFor(appDir, envName)\n if (!legacyPath || !existsSync(legacyPath)) return\n warn(\n `Warning: ${legacyPath} exists, but DeepSpace now uses ${devVarsPathFor(appDir, envName, { sharedDevVarsCache: true })} ` +\n `for every environment. This run will ignore ${legacyPath}; move any secrets you still ` +\n `need into .dev.vars, then remove the env-specific file when you're ready.`,\n )\n}\n\nexport function prepareWranglerEnvConfig(\n appDir: string,\n envName: string | undefined,\n opts: { warn?: (message: string) => void } & WranglerEnvModeOptions = {},\n): PreparedWranglerEnvConfig {\n if (!envName) return { cleanup() {} }\n if (!opts.sharedDevVarsCache) return { wranglerEnv: envName, cleanup() {} }\n\n warnIfLegacyEnvDevVarsExists(appDir, envName, opts.warn)\n\n const config = readWranglerConfig(appDir)\n const resolved = resolveAppNameForEnv(config, envName)\n if (!resolved.ok) throw new Error(resolved.reason)\n const flattened = flattenWranglerEnvConfig(config as TomlRecord, envName)\n const configPath = join(\n appDir,\n `.wrangler.deepspace.${safeGeneratedConfigSegment(envName)}.${process.pid}.${++generatedConfigSeq}.toml`,\n )\n writeFileSync(\n configPath,\n [\n '# Generated by DeepSpace for this CLI run.',\n '# Do not edit; wrangler.toml remains the source of truth.',\n stringifyToml(flattened),\n ]\n .join('\\n')\n .replace(/\\s*$/u, '\\n'),\n )\n return {\n configPath,\n cleanup() {\n rmSync(configPath, { force: true })\n },\n }\n}\n\nexport function wranglerViteEnv(\n baseEnv: NodeJS.ProcessEnv,\n prepared: PreparedWranglerEnvConfig,\n extraEnv: NodeJS.ProcessEnv = {},\n): NodeJS.ProcessEnv {\n const env = { ...baseEnv, ...extraEnv }\n if (prepared.configPath) {\n delete env.CLOUDFLARE_ENV\n env.CLOUDFLARE_VITE_WRANGLER_CONFIG_PATH = prepared.configPath\n } else if (prepared.wranglerEnv) {\n env.CLOUDFLARE_ENV = prepared.wranglerEnv\n }\n return env\n}\n\nfunction flattenWranglerEnvConfig(config: TomlRecord, envName: string): TomlRecord {\n const envRoot = asTomlRecord(config.env)\n const envBlock = asTomlRecord(envRoot?.[envName])\n if (!envBlock) {\n throw new Error(`wrangler.toml: no [env.${envName}] block found.`)\n }\n\n const flattened: TomlRecord = {}\n for (const [key, value] of Object.entries(config)) {\n if (key === 'env' || NON_INHERITABLE_ENV_KEYS.has(key)) continue\n flattened[key] = value\n }\n for (const [key, value] of Object.entries(envBlock)) {\n flattened[key] = value\n }\n return flattened\n}\n\nfunction asTomlRecord(value: unknown): TomlRecord | undefined {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as TomlRecord)\n : undefined\n}\n\nfunction safeGeneratedConfigSegment(value: string): string {\n return value.replace(/[^A-Za-z0-9._-]/gu, '_')\n}\n\n/**\n * Read + parse wrangler.toml. Caller checks existence first via\n * `hasWranglerConfig`. Throws a `WranglerConfigError` with the absolute\n * path embedded on a malformed file — saves the user from staring at\n * a raw smol-toml parser stack trace when they have one stray\n * unquoted character in their config.\n */\nexport class WranglerConfigError extends Error {\n constructor(\n public readonly path: string,\n public readonly cause: unknown,\n ) {\n const detail = cause instanceof Error ? cause.message : String(cause)\n super(`wrangler.toml: malformed TOML at ${path}: ${detail}`)\n this.name = 'WranglerConfigError'\n }\n}\n\nexport function readWranglerConfig(appDir: string): WranglerConfig {\n const path = join(appDir, 'wrangler.toml')\n const raw = readFileSync(path, 'utf-8')\n try {\n return parseToml(raw) as WranglerConfig\n } catch (err) {\n throw new WranglerConfigError(path, err)\n }\n}\n\n/** Convenience: true when wrangler.toml exists at the standard path. */\nexport function hasWranglerConfig(appDir: string): boolean {\n return existsSync(join(appDir, 'wrangler.toml'))\n}\n","/**\n * App-name validation + sanitization helpers.\n *\n * Strategy: validate strictly so we have a precise definition of \"valid\",\n * but DON'T reject non-conforming names — sanitize them, warn the user, and\n * proceed. Hard rejection would break apps whose `wrangler.toml name` was\n * something like `My_App` (previously deployed as `my-app` via silent\n * server-side sanitization). The new behavior preserves \"still deploys,\"\n * but the CLI now surfaces a warning so the user can fix the name when\n * convenient instead of being silently surprised by their hostname.\n *\n * Rules track Cloudflare's WfP script-name constraints (RFC 1035 host label,\n * no consecutive dashes) plus our 2-char minimum so subdomains read sensibly.\n */\n\nexport const APP_NAME_RULES = {\n /** ^[a-z0-9](-?[a-z0-9])+$ — RFC 1035 host label, no consecutive dashes. */\n pattern: /^[a-z0-9](?:-?[a-z0-9])+$/,\n minLength: 2,\n maxLength: 63,\n} as const\n\nexport type AppNameValidation =\n | { valid: true; name: string }\n | { valid: false; reason: string }\n\n/**\n * Strict validation: returns valid only if the name already conforms.\n * Useful as a precondition test or for CI lints.\n */\nexport function validateAppName(raw: unknown): AppNameValidation {\n if (typeof raw !== 'string') {\n return { valid: false, reason: 'App name must be a string' }\n }\n const name = raw.trim()\n if (!name) {\n return { valid: false, reason: 'App name is required' }\n }\n if (name.length < APP_NAME_RULES.minLength) {\n return { valid: false, reason: `App name \"${name}\" is too short (min ${APP_NAME_RULES.minLength} chars)` }\n }\n if (name.length > APP_NAME_RULES.maxLength) {\n return { valid: false, reason: `App name \"${name}\" is too long (max ${APP_NAME_RULES.maxLength} chars)` }\n }\n if (!APP_NAME_RULES.pattern.test(name)) {\n return {\n valid: false,\n reason:\n `App name \"${name}\" is invalid. Use lowercase letters, digits, and single hyphens only ` +\n `(must start + end with alphanumeric). Examples: my-app, search-v2, unison-search.`,\n }\n }\n return { valid: true, name }\n}\n\nexport type AppNameResolution =\n | { ok: true; name: string; warning?: string }\n | { ok: false; reason: string }\n\n/**\n * Resolve an app name for deploy: prefer the input as-is if valid, otherwise\n * sanitize and warn. Hard-fail only if even sanitization can't produce a\n * valid name (empty, all-non-alphanumeric, too short, too long).\n *\n * The intent is \"what previously worked still works, with a friendly warning\n * about non-conforming names.\"\n */\nexport function resolveAppName(raw: unknown): AppNameResolution {\n const strict = validateAppName(raw)\n if (strict.valid) return { ok: true, name: strict.name }\n\n if (typeof raw !== 'string') return { ok: false, reason: strict.reason }\n const trimmed = raw.trim()\n if (!trimmed) return { ok: false, reason: 'App name is required' }\n\n const sanitized = sanitizeAppName(trimmed)\n const sanitizedStrict = validateAppName(sanitized)\n if (!sanitizedStrict.valid) {\n return {\n ok: false,\n reason: `App name \"${trimmed}\" can't be sanitized into a valid name (${sanitizedStrict.reason}). Pick something matching: lowercase letters, digits, single hyphens, ${APP_NAME_RULES.minLength}-${APP_NAME_RULES.maxLength} chars.`,\n }\n }\n return {\n ok: true,\n name: sanitized,\n warning:\n `App name \"${trimmed}\" doesn't conform to deploy rules — using \"${sanitized}\" instead. ` +\n `Update wrangler.toml's \\`name\\` to silence this warning.`,\n }\n}\n\n/**\n * Lossy normalization that mirrors what the deploy-worker historically did\n * server-side. Keep only [a-z0-9-], collapse consecutive dashes, trim leading\n * and trailing dashes.\n */\nfunction sanitizeAppName(raw: string): string {\n return raw\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-{2,}/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n","/**\n * CLI session helpers — exchange a Better Auth session cookie for a short-lived\n * JWT against the auth worker. Shared by `auth.ts` (token refresh for all\n * authenticated commands) and `login.ts` (email/password flow).\n */\n\nexport const SESSION_COOKIE = '__Secure-better-auth.session_token'\n\n/**\n * Exchange a Better Auth session token for a fresh JWT.\n * Returns null if the session is invalid or expired.\n */\nexport async function exchangeSession(\n authUrl: string,\n sessionToken: string,\n): Promise<string | null> {\n const res = await fetch(`${authUrl}/api/auth/token`, {\n method: 'POST',\n headers: {\n Cookie: `${SESSION_COOKIE}=${encodeURIComponent(sessionToken)}`,\n Origin: authUrl,\n },\n })\n if (!res.ok) return null\n const data = (await res.json()) as { token?: string | null }\n return data.token ?? null\n}\n","/**\n * Best-effort \"open this URL in the default browser\".\n *\n * Non-blocking and never throws: every caller has already printed the URL, so\n * a failure to launch the browser is harmless — the user opens it manually.\n * `JSON.stringify` quotes the URL so query strings / special chars can't break\n * out of the shell command.\n */\nimport { exec } from 'node:child_process'\n\nexport function openBrowser(url: string): void {\n const quoted = JSON.stringify(url)\n const cmd =\n process.platform === 'darwin'\n ? `open ${quoted}`\n : process.platform === 'win32'\n ? `start \"\" ${quoted}`\n : `xdg-open ${quoted}`\n\n // Swallow errors — the URL was already shown, so launching is optional.\n exec(cmd, () => {})\n}\n","/**\n * deepspace logout\n *\n * Revokes the session on the auth worker, then removes the cached session\n * token and JWT from ~/.deepspace/. Test accounts (managed by `deepspace\n * test-accounts`) are not touched.\n */\n\nimport { defineCommand } from 'citty'\nimport { existsSync, readFileSync, rmSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\n\nimport { PLATFORM_URLS } from '../env'\nimport { SESSION_COOKIE } from '../session'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? PLATFORM_URLS.auth\n\nconst DIR = join(homedir(), '.deepspace')\nconst SESSION_PATH = join(DIR, 'session')\nconst TOKEN_PATH = join(DIR, 'token')\n\nexport default defineCommand({\n meta: {\n name: 'logout',\n description: 'Sign out and remove cached credentials',\n },\n async run() {\n // Read the session token before deleting it so we can revoke server-side.\n const sessionToken = existsSync(SESSION_PATH)\n ? readFileSync(SESSION_PATH, 'utf-8').trim()\n : null\n\n if (sessionToken) {\n try {\n await fetch(`${AUTH_URL}/api/auth/sign-out`, {\n method: 'POST',\n headers: {\n Cookie: `${SESSION_COOKIE}=${encodeURIComponent(sessionToken)}`,\n Origin: AUTH_URL,\n },\n })\n } catch {\n // Network failure — still wipe local credentials so the user can\n // re-authenticate. Server-side session will expire on its own.\n }\n }\n\n let removed = 0\n for (const path of [SESSION_PATH, TOKEN_PATH]) {\n if (existsSync(path)) {\n rmSync(path)\n removed++\n }\n }\n\n if (removed === 0) {\n console.log('Already logged out.')\n return\n }\n console.log('Logged out.')\n },\n})\n","/**\n * deepspace dev [--port N]\n *\n * Starts local development:\n * 1. Ensures you're logged in\n * 2. Writes .dev.vars pointing to the production platform workers\n * 3. Starts vite dev (Cloudflare Vite plugin runs the worker in-process)\n *\n * deepspace dev # port 5173 (strict)\n * deepspace dev --port 5180 # bind to a different port (multi-app dev)\n *\n * Port is `--port` > $DEEPSPACE_PORT > 5173 — except inside a Claude Code\n * worktree, where (unless --port was passed) a stable per-worktree port in\n * 5180–5199 is derived instead, so the preview server never collides with a\n * main-repo dev server. We always pass --strictPort to vite so a busy port\n * fails loudly instead of silently jumping to 5174 (which would diverge from\n * anything Playwright/test config is expecting).\n */\n\nimport { defineCommand } from 'citty'\nimport { readAppId } from '../lib/app-identity'\nimport { resolve, basename, join } from 'node:path'\nimport spawn from 'cross-spawn'\nimport { ensureToken } from '../auth'\nimport {\n detectAppName,\n detectClaudeWorktree,\n deriveWorktreePort,\n findAppDir,\n findChildApps,\n upsertWorktreeLaunchConfig,\n writeLaunchConfigIfMissing,\n} from '../lib/app-context'\nimport { PLATFORM_URLS, writeDevVars } from '../env'\nimport { decodeJwtPayload } from '../jwt'\nimport { ensureInstallReady } from '../lib/install-status'\nimport { preflightNodeVersion, preflightWindowsWorkerd } from '../lib/preflight'\nimport { removeMacosJunk } from '../lib/macos-junk'\nimport { refreshSecretsCache } from '../lib/secrets'\nimport { DEFAULT_PORT, resolvePort, checkPortAvailable } from '../lib/port'\nimport {\n prepareWranglerEnvConfig,\n wranglerViteEnv,\n type PreparedWranglerEnvConfig,\n} from '../lib/wrangler-env'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\nexport default defineCommand({\n meta: {\n name: 'dev',\n description: 'Start local development server',\n },\n args: {\n dir: {\n type: 'positional',\n description: 'App directory (default: current directory)',\n required: false,\n },\n env: {\n type: 'string',\n alias: 'e',\n description:\n 'wrangler.toml [env.<name>] block to run (e.g. --env staging). ' +\n \"Applies the env's overrides at build time.\",\n required: false,\n },\n port: {\n type: 'string',\n description: `Port to bind (default ${DEFAULT_PORT}, or $DEEPSPACE_PORT)`,\n required: false,\n },\n },\n async run({ args }) {\n preflightNodeVersion('dev')\n const wranglerEnv =\n typeof args.env === 'string' && args.env.trim() ? args.env.trim() : undefined\n\n // Resolve the app root by walking up from the requested dir (default cwd),\n // so running from a subdirectory still works instead of hard-failing.\n const start = resolve(args.dir ?? '.')\n const appDir = findAppDir(start)\n if (!appDir) {\n console.error(`No wrangler.toml found at or above ${start}.`)\n const children = findChildApps(start)\n if (children.length > 0) {\n console.error('Did you mean to run inside one of these app directories?')\n for (const c of children) console.error(` cd ${c}`)\n } else {\n console.error('Run from a DeepSpace app directory (one containing wrangler.toml).')\n }\n process.exit(1)\n }\n\n const junk = removeMacosJunk(appDir)\n if (junk > 0) console.log(`Removed ${junk} macOS metadata file(s) (._*, .DS_Store)`)\n\n // Inside a Claude Code worktree the desktop preview tool reads only the\n // MAIN repo's launch.json and would serve the main repo's stale code\n // (anthropics/claude-code#56688) — so upsert a cwd-pinned entry there.\n // Only a literal --port counts as explicit and is honored verbatim: an\n // ambient $DEEPSPACE_PORT (e.g. exported in a shell profile) must not pin\n // the worktree to the main repo's port — the port is resolved AFTER\n // worktree detection so a malformed ambient value can't kill dev either.\n // Otherwise a stable per-worktree port (bumped past other entries' ports)\n // avoids colliding with a main-repo server. This run binds the same port\n // the entry advertises, so the preview tool can attach to an\n // already-running worktree server instead of spawning a duplicate.\n const worktree = detectClaudeWorktree(appDir)\n const explicitPort = Boolean(args.port)\n let port =\n worktree && !explicitPort ? deriveWorktreePort(worktree.worktreeName) : resolvePort(args.port)\n if (worktree) {\n const upserted = upsertWorktreeLaunchConfig(\n worktree.mainRepoRoot,\n worktree.worktreeName,\n appDir,\n {\n port,\n probePort: !explicitPort,\n extraArgs: [...(wranglerEnv ? ['--env', wranglerEnv] : [])],\n },\n )\n if (upserted) {\n port = upserted.port\n console.log(\n `Claude worktree detected — preview tool: use preview_start with name \"${upserted.entryName}\" (port ${upserted.port})`,\n )\n } else {\n console.warn(\n `Warning: could not update ${join(worktree.mainRepoRoot, '.claude', 'launch.json')} ` +\n `(malformed or unwritable) — the Claude preview tool may serve the main repo's code ` +\n `instead of this worktree.`,\n )\n }\n if (!explicitPort && process.env.DEEPSPACE_PORT) {\n console.log(\n `Ignoring DEEPSPACE_PORT=${process.env.DEEPSPACE_PORT} inside a worktree — ` +\n `using per-worktree port ${port}. Pass --port to override.`,\n )\n }\n }\n\n // Seed an app-local .claude/launch.json (only if absent) so the Claude Code\n // preview tool launches this app on the resolved port, instead of walking\n // up and latching onto an ancestor repo's config. With an explicit --port,\n // also update the existing entry so `kill` and the preview tool track the\n // port we actually bind (DEV-3).\n writeLaunchConfigIfMissing(appDir, detectAppName(appDir) ?? basename(appDir), port, {\n updatePort: explicitPort,\n })\n\n ensureInstallReady(appDir)\n\n let token: string\n try {\n token = await ensureToken()\n } catch (err: unknown) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n\n let payload: { sub: string; name?: string; email?: string }\n try {\n payload = decodeJwtPayload<{ sub: string; name?: string; email?: string }>(token)\n } catch {\n console.error('Malformed session token. Run `npx deepspace login`.')\n process.exit(1)\n }\n // `--env` selects which `[env.<name>]` block of wrangler.toml we apply\n // (renames the app, swaps vars, etc.). Surface it in the startup log so\n // it's obvious which app slot a session is hitting when it's set.\n console.log(`Logged in as ${payload.name ?? payload.email}`)\n if (wranglerEnv) console.log(`Wrangler env: ${wranglerEnv}`)\n console.log(`Port: ${port}`)\n\n // Refresh the app-store secrets cache (config = wrangler env, or 'prd').\n // A repo without a DEEPSPACE_APP_ID hasn't been initialized — writeDevVars\n // below throws with the `deepspace init` pointer, so skip the pull.\n let generatedSecretsCache: string | undefined\n const appIdForSecrets = readAppId(appDir, wranglerEnv)\n if (appIdForSecrets) {\n try {\n const refreshed = await refreshSecretsCache(DEPLOY_URL, token, appIdForSecrets, wranglerEnv)\n if (refreshed) {\n generatedSecretsCache = refreshed.rendered\n console.log(refreshed.summary)\n }\n } catch (err: unknown) {\n console.error(\n `Failed to refresh app secrets: ${err instanceof Error ? err.message : String(err)}`,\n )\n process.exit(1)\n }\n }\n\n const sharedDevVarsCache = generatedSecretsCache !== undefined\n await writeDevVars(appDir, payload.sub, token, wranglerEnv, {\n generatedSecretsCache,\n sharedDevVarsCache,\n })\n let wranglerConfig: PreparedWranglerEnvConfig\n try {\n wranglerConfig = prepareWranglerEnvConfig(appDir, wranglerEnv, { sharedDevVarsCache })\n } catch (err: unknown) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n preflightWindowsWorkerd(appDir)\n\n // Pre-probe the port so a collision gets a friendly remedy instead of\n // vite's raw --strictPort EADDRINUSE stack trace (DEV-5).\n if (!(await checkPortAvailable(port))) {\n console.error(`Port ${port} is already in use.`)\n const killCmd = port === DEFAULT_PORT ? 'deepspace kill' : `deepspace kill --port ${port}`\n console.error(`Free it with \\`${killCmd}\\`, or start on another port: \\`deepspace dev --port <other>\\`.`)\n process.exit(1)\n }\n\n console.log('Starting dev server...\\n')\n\n const vite = spawn('npx', ['vite', '--port', String(port), '--strictPort', '--host'], {\n cwd: appDir,\n stdio: 'inherit',\n env: wranglerViteEnv(process.env, wranglerConfig, { DEEPSPACE_PORT: String(port) }),\n })\n const stop = () => {\n wranglerConfig.cleanup()\n vite.kill()\n }\n process.on('SIGINT', stop)\n process.on('SIGTERM', stop)\n vite.on('close', (code) => {\n wranglerConfig.cleanup()\n process.exit(code ?? 0)\n })\n },\n})\n","/**\n * CLI auth utilities — shared across all commands.\n *\n * Reads the session token from ~/.deepspace/session and ensures\n * a fresh JWT is available at ~/.deepspace/token.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\n\nimport { PLATFORM_URLS } from './env'\nimport { decodeJwtPayload } from './jwt'\nimport { exchangeSession } from './session'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? PLATFORM_URLS.auth\n\nconst DIR = join(homedir(), '.deepspace')\nexport const SESSION_PATH = join(DIR, 'session')\nexport const TOKEN_PATH = join(DIR, 'token')\n\n/**\n * Ensure a valid JWT exists. Refreshes from the session token if expired.\n * Returns the JWT string or throws if not logged in / session expired.\n */\nexport async function ensureToken(): Promise<string> {\n // Try existing token first — if it's still valid, skip the refresh\n if (existsSync(TOKEN_PATH)) {\n const existing = readFileSync(TOKEN_PATH, 'utf-8').trim()\n if (isTokenValid(existing)) {\n return existing\n }\n }\n\n if (!existsSync(SESSION_PATH)) {\n throw new Error('Not logged in. Run `deepspace login` first.')\n }\n\n const sessionToken = readFileSync(SESSION_PATH, 'utf-8').trim()\n\n // Refresh from session\n const token = await exchangeSession(AUTH_URL, sessionToken)\n if (!token) {\n throw new Error('Session expired. Run `deepspace login` to re-authenticate.')\n }\n\n mkdirSync(DIR, { recursive: true, mode: 0o700 })\n writeFileSync(TOKEN_PATH, token, { mode: 0o600 })\n\n return token\n}\n\n/** Check if a JWT has at least 30 seconds of validity remaining. */\nfunction isTokenValid(jwt: string): boolean {\n try {\n const payload = decodeJwtPayload<{ exp?: number }>(jwt)\n return typeof payload.exp === 'number' && payload.exp * 1000 > Date.now() + 30_000\n } catch {\n return false\n }\n}\n","export function decodeJwtPayload<T = Record<string, unknown>>(token: string): T {\n const payloadSegment = token.split('.')[1]\n if (!payloadSegment) {\n throw new Error('JWT payload is missing')\n }\n return JSON.parse(Buffer.from(payloadSegment, 'base64url').toString('utf8')) as T\n}\n","/**\n * Shared helper: read the current project's app name from `./wrangler.toml`.\n *\n * Used by commands that operate on \"the current app\" — `deploy`, `domain buy`,\n * `domain attach`, etc. Lets agents and scripts run from inside a project\n * directory without redundantly passing `--app <name>`.\n */\n\nimport {\n existsSync,\n readFileSync,\n readdirSync,\n writeFileSync,\n mkdirSync,\n renameSync,\n unlinkSync,\n} from 'node:fs'\nimport { join, resolve, dirname, basename, isAbsolute, sep } from 'node:path'\nimport { parse as parseToml } from 'smol-toml'\nimport { APP_ID_RE, readAppId } from './app-identity'\nimport { apiFetch } from './api'\n\n/** Strict app-id shape (excludes the legacy name-as-id branch of APP_ID_RE). */\nconst STRICT_APP_ID_RE = /^app_[0-9A-HJKMNP-TV-Z]{26}$/\n\n/**\n * Read the app name from `wrangler.toml` in the given directory (default cwd).\n * Returns null if no wrangler.toml exists or the file lacks a `name` field.\n */\nexport function detectAppName(cwd: string = process.cwd()): string | null {\n const wranglerPath = join(resolve(cwd), 'wrangler.toml')\n if (!existsSync(wranglerPath)) return null\n try {\n const cfg = parseToml(readFileSync(wranglerPath, 'utf-8')) as { name?: string }\n return typeof cfg.name === 'string' && cfg.name.length > 0 ? cfg.name : null\n } catch (err) {\n // Malformed is NOT absent — treating it as \"no app here\" sends callers\n // down create-new-app paths against a directory that has one.\n throw new Error(\n `Could not parse ${wranglerPath}: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n\n/**\n * Resolve the app name from explicit arg or wrangler.toml.\n * Throws with a clear message if neither is available.\n */\nexport function requireAppName(explicit: string | undefined, cwd?: string): string {\n if (explicit) return explicit\n const detected = detectAppName(cwd)\n if (detected) return detected\n throw new Error(\n 'No app specified. Pass --app <name>, or run from an app directory with a wrangler.toml.',\n )\n}\n\n/**\n * Walk upward from `start` (default cwd) to the nearest directory containing a\n * `wrangler.toml`, returning that directory — or null if none is found before\n * the filesystem root.\n *\n * This makes the dev-loop commands robust to being run from a *subdirectory*\n * of an app instead of hard-failing the moment cwd isn't exactly the app root.\n * (It does NOT recover the inverse case — cwd sitting at the app's *parent*;\n * for that, `findChildApps` powers a \"did you mean cd <app>\" hint.)\n */\nexport function findAppDir(start: string = process.cwd()): string | null {\n let dir = resolve(start)\n for (;;) {\n if (existsSync(join(dir, 'wrangler.toml'))) return dir\n const parent = dirname(dir)\n if (parent === dir) return null // reached filesystem root\n dir = parent\n }\n}\n\n/**\n * Immediate subdirectories of `dir` that look like an app (contain a\n * `wrangler.toml`). Used to turn a bare \"no wrangler.toml here\" failure into an\n * actionable hint when the caller is sitting one level above the app — the\n * exact situation a harness creates when it resets cwd to the parent.\n */\nexport function findChildApps(dir: string): string[] {\n try {\n return readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && existsSync(join(dir, e.name, 'wrangler.toml')))\n .map((e) => e.name)\n .sort()\n } catch {\n return []\n }\n}\n\n/**\n * Atomic launch.json write: temp file + rename, so an interrupted write can\n * never leave torn (permanently unparseable) JSON behind.\n */\nfunction writeLaunchFile(launchPath: string, config: unknown): void {\n mkdirSync(dirname(launchPath), { recursive: true })\n const tmpPath = `${launchPath}.${process.pid}.tmp`\n writeFileSync(tmpPath, JSON.stringify(config, null, 2) + '\\n')\n try {\n renameSync(tmpPath, launchPath)\n } catch (err) {\n // Don't leave an orphan tmp file behind (e.g. Windows EPERM while the\n // preview tool holds launch.json open).\n try {\n unlinkSync(tmpPath)\n } catch {\n // best-effort cleanup\n }\n throw err\n }\n}\n\n/**\n * Read + validate a launch.json. Returns the parsed config, an empty skeleton\n * when the file is absent or empty (interrupted write, `touch` — nothing to\n * preserve), or null when it exists but is malformed / wrong-shaped (leave it\n * alone rather than clobber a hand-edited file). Trimmed before parsing so a\n * UTF-8 BOM from Windows editors doesn't read as \"malformed\".\n */\nfunction readLaunchFile(\n launchPath: string,\n): { version?: string; configurations: Array<Record<string, unknown>> } | null {\n const empty = { version: '0.0.1', configurations: [] }\n if (!existsSync(launchPath)) return empty\n const raw = readFileSync(launchPath, 'utf-8').trim()\n if (!raw) return empty\n const parsed = JSON.parse(raw)\n if (!parsed || typeof parsed !== 'object' || !Array.isArray(parsed.configurations)) return null\n return parsed\n}\n\n/**\n * Seed the app's own entry in `<appDir>/.claude/launch.json` so the Claude\n * Code preview tool launches THIS app. Without an app-local launch.json the\n * tool walks up the directory tree and can latch onto an ancestor repo's\n * config — pointing at a different app and port — which is a real failure\n * when a DeepSpace app lives inside another repo.\n *\n * Entry-level, not file-level: if the file already has an entry named\n * `appName` (possibly user-customized) it is left untouched by default, but a\n * file that exists without it — e.g. created by a worktree run's upsert before\n * the main app ever ran `dev` — still gets the app's entry appended.\n *\n * `opts.updatePort` (DEV-3): when the user passed an explicit `--port`, update\n * the existing entry's `port` and the `--port` value inside its `runtimeArgs`\n * (other args like `--env` are preserved) so `kill` and the preview tool track\n * the port `dev` actually bound. Without it, a scaffold pinned to 5173 would\n * stay stale after `dev --port 5180`. Best-effort: a failure must never block\n * `dev` from starting.\n */\nexport function writeLaunchConfigIfMissing(\n appDir: string,\n appName: string,\n port: number,\n opts: { updatePort?: boolean } = {},\n): void {\n const launchPath = join(appDir, '.claude', 'launch.json')\n try {\n const config = readLaunchFile(launchPath)\n if (!config) return\n const existing = config.configurations.find((c) => c?.name === appName)\n if (existing) {\n if (!opts.updatePort) return\n // Resync BOTH the `port` field and the `--port` value in runtimeArgs — a\n // stale runtimeArgs (even when the port field matches) makes the preview\n // tool launch on the wrong port. Only write when something actually changed.\n let changed = false\n if (Number(existing.port) !== port) {\n existing.port = port\n changed = true\n }\n if (Array.isArray(existing.runtimeArgs)) {\n const ra = existing.runtimeArgs.map(String)\n const pi = ra.indexOf('--port')\n if (pi >= 0 && pi + 1 < ra.length) {\n if (ra[pi + 1] !== String(port)) {\n ra[pi + 1] = String(port)\n changed = true\n }\n } else {\n ra.push('--port', String(port))\n changed = true\n }\n if (changed) existing.runtimeArgs = ra\n }\n if (changed) writeLaunchFile(launchPath, config)\n return\n }\n config.configurations.push({\n name: appName,\n runtimeExecutable: 'npx',\n runtimeArgs: ['deepspace', 'dev', '--port', String(port)],\n port,\n })\n writeLaunchFile(launchPath, config)\n } catch {\n // best-effort only\n }\n}\n\n/**\n * The port `kill` should target for the app at `appDir` when no `--port` was\n * given and we're not in a worktree (DEV-2): the port recorded in the app's own\n * `.claude/launch.json` entry, which `dev --port` keeps in sync (see above).\n * Falls back to null (caller uses the default) when there's no launch.json,\n * no matching entry, or a malformed file.\n */\nexport function resolveAppLaunchPort(appDir: string): number | null {\n try {\n const config = readLaunchFile(join(appDir, '.claude', 'launch.json'))\n if (!config) return null\n const appName = detectAppName(appDir) ?? basename(appDir)\n const entry =\n config.configurations.find((c) => c?.name === appName) ??\n (config.configurations.length === 1 ? config.configurations[0] : undefined)\n const port = Number(entry?.port)\n return Number.isInteger(port) && port > 0 ? port : null\n } catch {\n return null\n }\n}\n\n/**\n * Detect whether `appDir` lives inside a Claude Code worktree\n * (`<root>/.claude/worktrees/<name>/...`). Returns the main repo root (the\n * directory containing `.claude`) and the worktree name, or null.\n *\n * The Claude desktop preview tool starts dev servers from the session's\n * primary working directory and reads only the MAIN repo's\n * `.claude/launch.json` — a worktree's own launch.json is never read\n * (anthropics/claude-code#56688). Detecting this lets `dev` seed a\n * `cwd`-pinned entry where the tool will actually look.\n */\nexport function detectClaudeWorktree(\n appDir: string,\n): { mainRepoRoot: string; worktreeName: string } | null {\n const segments = resolve(appDir).split(sep)\n // Innermost match wins: worktrees are created under the *session root's*\n // .claude/worktrees, so a nested worktree implies the session is rooted at\n // the outer worktree — that outer root's launch.json is the one the\n // session's preview tool reads.\n for (let i = segments.length - 3; i >= 1; i--) {\n if (segments[i] === '.claude' && segments[i + 1] === 'worktrees' && segments[i + 2]) {\n return {\n mainRepoRoot: segments.slice(0, i).join(sep) || sep,\n worktreeName: segments[i + 2],\n }\n }\n }\n return null\n}\n\nconst WORKTREE_ENTRY_PREFIX = 'wt-'\nconst WORKTREE_PORT_MIN = 5180\nconst WORKTREE_PORT_RANGE = 20\n\n/**\n * Deterministic per-worktree preview port in the worktree band\n * (5180–5199), distinct from the default 5173 so a preview server for the\n * worktree never collides with a main-repo dev server. Stable across runs\n * for the same worktree name. Hash collisions between worktree names are\n * resolved at write time by `upsertWorktreeLaunchConfig`, which probes past\n * ports already claimed by other launch.json entries.\n */\nexport function deriveWorktreePort(worktreeName: string): number {\n let hash = 0\n for (const ch of worktreeName) hash = (hash * 31 + ch.charCodeAt(0)) >>> 0\n return WORKTREE_PORT_MIN + (hash % WORKTREE_PORT_RANGE)\n}\n\nexport interface WorktreeLaunchOptions {\n /** Desired port for the entry (and for the current dev run). */\n port: number\n /**\n * When true, bump the port past any port already claimed by another\n * launch.json entry (wrapping within 5180–5199). Off for an explicit\n * --port, which is honored verbatim.\n */\n probePort?: boolean\n /** Extra `deepspace dev` args to preserve in the entry (e.g. --prod, --env). */\n extraArgs?: string[]\n}\n\n/**\n * Upsert a `cwd`-pinned entry named `wt-<worktreeName>` into the MAIN repo's\n * `.claude/launch.json`, so the Claude desktop preview tool (which only reads\n * that file) starts the dev server inside the worktree instead of serving the\n * main repo's stale code. Also prunes `wt-*` entries whose absolute `cwd` no\n * longer exists (deleted worktrees) — relative `cwd`s are left alone, since\n * `existsSync` would resolve them against this process's cwd, not the\n * preview tool's. All other entries are preserved verbatim.\n *\n * Returns the entry name and the (possibly probed) port on success, or null\n * if the file was malformed or unwritable — best-effort: must never block\n * `dev` from starting, but the caller should warn, since a missing entry\n * means the preview tool will serve the main repo's code.\n */\nexport function upsertWorktreeLaunchConfig(\n mainRepoRoot: string,\n worktreeName: string,\n appDir: string,\n opts: WorktreeLaunchOptions,\n): { entryName: string; port: number } | null {\n const launchPath = join(mainRepoRoot, '.claude', 'launch.json')\n const entryName = WORKTREE_ENTRY_PREFIX + worktreeName\n try {\n const config = readLaunchFile(launchPath)\n if (!config) return null\n // Ownership check for pruning: only entries whose cwd lives under this\n // repo's .claude/worktrees/ could have been written by us. A hand-authored\n // wt-* entry pointing elsewhere (or at an unmounted volume) is never ours\n // to delete.\n const worktreesRoot = join(mainRepoRoot, '.claude', 'worktrees') + sep\n config.configurations = config.configurations.filter((c) => {\n if (c?.name === entryName) return false // replaced below\n const isStaleWorktreeEntry =\n typeof c?.name === 'string' &&\n c.name.startsWith(WORKTREE_ENTRY_PREFIX) &&\n typeof c.cwd === 'string' &&\n isAbsolute(c.cwd) &&\n c.cwd.startsWith(worktreesRoot) &&\n !existsSync(c.cwd)\n return !isStaleWorktreeEntry\n })\n\n let port = opts.port\n if (opts.probePort) {\n // Number() coercion so a hand-edited string port (\"5186\") still counts\n // as claimed.\n const taken = new Set(\n config.configurations.map((c) => Number(c?.port)).filter((p) => Number.isInteger(p) && p > 0),\n )\n for (let i = 0; i < WORKTREE_PORT_RANGE && taken.has(port); i++) {\n port = WORKTREE_PORT_MIN + ((port - WORKTREE_PORT_MIN + 1) % WORKTREE_PORT_RANGE)\n }\n }\n\n config.configurations.push({\n name: entryName,\n runtimeExecutable: 'npx',\n runtimeArgs: ['deepspace', 'dev', '--port', String(port), ...(opts.extraArgs ?? [])],\n port,\n // `cwd` is honored verbatim by the desktop preview tool (documented in\n // the Claude Code desktop launch.json reference alongside `port`) and\n // verified end-to-end: with it set, the preview server builds from the\n // worktree instead of the session's main repo.\n cwd: resolve(appDir),\n })\n writeLaunchFile(launchPath, config)\n return { entryName, port }\n } catch {\n return null\n }\n}\n\n/**\n * The port dev/test/kill should default to inside a Claude Code worktree, so\n * all three commands target the same server (`test` against a different port\n * silently exercises the main repo's code via Playwright's\n * reuseExistingServer). The `wt-<name>` entry in the main repo's launch.json\n * is the source of truth — it includes any probing `dev` applied; fall back\n * to the derived port when it doesn't exist yet. Returns null outside a\n * worktree.\n */\nexport function resolveWorktreePort(appDir: string): number | null {\n const worktree = detectClaudeWorktree(appDir)\n if (!worktree) return null\n try {\n const config = readLaunchFile(join(worktree.mainRepoRoot, '.claude', 'launch.json'))\n const entry = config?.configurations.find(\n (c) => c?.name === WORKTREE_ENTRY_PREFIX + worktree.worktreeName,\n )\n const port = Number(entry?.port)\n if (Number.isInteger(port) && port > 0) return port\n } catch {\n // malformed launch.json — fall through to the derived port\n }\n return deriveWorktreePort(worktree.worktreeName)\n}\n\n/**\n * Resolve the app id a command targets: an explicit `--app app_…` wins,\n * otherwise the surrounding app directory's DEEPSPACE_APP_ID. Shared by\n * `collaborators`, `transfer`, and other id-scoped commands.\n */\nexport function requireAppIdArg(explicit: string | undefined): string {\n if (explicit) {\n if (!APP_ID_RE.test(explicit)) {\n throw new Error(`\"${explicit}\" is not an app id (app_…). Pass --app <appId>.`)\n }\n return explicit\n }\n const appDir = findAppDir()\n const id = appDir ? readAppId(appDir) : null\n if (!id) {\n throw new Error(\n 'No app id. Run from an app directory whose wrangler.toml carries DEEPSPACE_APP_ID, or pass --app <appId>.',\n )\n }\n return id\n}\n\ninterface AppListEntry {\n appId: string\n name: string | null\n}\n\n/** Find an app id or subdomain name in the caller's registry list. Exported for tests. */\nexport function matchAppSelector(apps: AppListEntry[], selector: string): string | null {\n const byId = apps.find((a) => a.appId === selector)\n if (byId) return byId.appId\n const byName = apps.find((a) => a.name === selector)\n if (byName) return byName.appId\n // Not among the caller's apps. A well-formed app_… id is trusted as-is (e.g.\n // an app the list didn't surface); anything else is an unknown name.\n return STRICT_APP_ID_RE.test(selector) ? selector : null\n}\n\n/**\n * Resolve an app selector — an app id (`app_…` or a legacy name-as-id) OR a live\n * subdomain name — to the canonical app id, via the deploy worker's `/api/apps`\n * registry. Unifies the \"id vs name\" split (DEP-4/DEP-5): id-scoped commands now\n * accept either. Throws a `deepspace apps` pointer when nothing matches.\n */\nexport async function resolveAppSelector(\n deployUrl: string,\n token: string,\n selector: string,\n): Promise<string> {\n // A canonical app_… id needs no registry lookup — trust it and let the target\n // worker authorize it. This skips an extra round-trip and, for the API-worker\n // commands (collaborators/transfer), a needless dependency on the deploy\n // worker's /api/apps. Legacy name-as-id and subdomain names still need it.\n if (STRICT_APP_ID_RE.test(selector)) return selector\n const { apps } = await apiFetch<{ apps: AppListEntry[] }>(deployUrl, token, '/api/apps')\n const id = matchAppSelector(apps, selector)\n if (!id) {\n throw new Error(`No app \"${selector}\" in your account. Run \\`deepspace apps\\` to list your apps.`)\n }\n return id\n}\n\n/**\n * The app id a command targets: an explicit `--app` selector (id or name,\n * resolved via resolveAppSelector) wins; otherwise the surrounding app\n * directory's DEEPSPACE_APP_ID. The async, name-accepting counterpart of\n * requireAppIdArg (DEP-4).\n */\nexport async function resolveAppTarget(\n deployUrl: string,\n token: string,\n explicit: string | undefined,\n): Promise<string> {\n if (explicit) return resolveAppSelector(deployUrl, token, explicit)\n const appDir = findAppDir()\n const id = appDir ? readAppId(appDir) : null\n if (!id) {\n throw new Error(\n 'No app id. Run from an app directory whose wrangler.toml carries DEEPSPACE_APP_ID, or pass --app <id or name>.',\n )\n }\n return id\n}\n","/**\n * Authenticated JSON fetch against a platform worker.\n *\n * Shared by the CLI commands that call the platform as the logged-in user\n * (`domain`, `feedback`, `collaborators`, `transfer`, …). Sends a Bearer\n * token, parses the JSON body, and on a non-2xx response throws an ApiError\n * carrying the worker's `{ error, code }` — message for display, code for\n * branching — so callers never string-sniff error text.\n */\nexport class ApiError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly code?: string,\n /** Internal REST path — kept off the message (DEBUG-only rendering). */\n readonly apiPath?: string,\n ) {\n super(message)\n }\n}\n\nexport async function apiFetch<T>(\n baseUrl: string,\n token: string,\n path: string,\n init?: RequestInit,\n): Promise<T> {\n const res = await fetch(`${baseUrl}${path}`, {\n ...init,\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n ...(init?.headers ?? {}),\n },\n })\n const text = await res.text()\n if (!res.ok) {\n let msg = text\n let code: string | undefined\n try {\n const body = JSON.parse(text) as { error?: string; code?: string }\n msg = body.error ?? text\n code = body.code\n } catch {\n // not JSON\n }\n // Message = the server's sentence only. The internal REST path and raw\n // status read like a stack trace to users (same treatment as secretsApi);\n // they stay on the error's fields for DEBUG rendering and branching.\n throw new ApiError(msg || `Request failed (${res.status})`, res.status, code, path)\n }\n return (text ? JSON.parse(text) : {}) as T\n}\n","/**\n * Verifies the app's dependencies are installed before running a command that\n * needs them (dev, test, deploy, add).\n *\n * `create-deepspace` runs `npm install` (and the agent-skill installer) in a\n * detached background process so the user gets their prompt back immediately.\n * The background worker writes three sentinels under `<appDir>/.deepspace/`:\n *\n * install.started — created before the worker is spawned\n * install.pid — the worker's pid (liveness check for a killed install)\n * install.done — written on successful completion\n * install.err — written on failure (contains the error message)\n * install.log — combined stdout/stderr of the install\n *\n * The presence of `node_modules/deepspace/package.json` is the ground truth\n * for \"ready\"; the sentinels only shape the error message.\n */\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\n\nexport function ensureInstallReady(appDir: string): void {\n if (existsSync(join(appDir, 'node_modules', 'deepspace', 'package.json'))) return\n\n const sentinelDir = join(appDir, '.deepspace')\n const errPath = join(sentinelDir, 'install.err')\n const startedPath = join(sentinelDir, 'install.started')\n const donePath = join(sentinelDir, 'install.done')\n const logPath = join(sentinelDir, 'install.log')\n\n if (existsSync(errPath)) {\n console.error('Background install failed:')\n console.error(readFileSync(errPath, 'utf-8').trimEnd())\n if (existsSync(logPath)) console.error(`\\nFull log: ${logPath}`)\n console.error('\\nRun `npm install` (or `bun install`) manually, then retry.')\n process.exit(1)\n }\n\n if (existsSync(startedPath) && !existsSync(donePath)) {\n // A worker that died without writing done/err (OOM, docker stop, laptop\n // shutdown) must not read as \"still installing\" forever. install.pid is\n // written by create-deepspace ≥0.5.6; without it, assume in-progress.\n if (!installWorkerAlive(sentinelDir)) {\n console.error('The background install is no longer running and never finished.')\n if (existsSync(logPath)) console.error(`See what happened: ${logPath}`)\n console.error('Run `npm install` (or `bun install`) manually, then retry.')\n process.exit(1)\n }\n console.error('Dependencies are still installing in the background.')\n if (existsSync(logPath)) console.error(`Tail progress: tail -f ${logPath}`)\n console.error('Retry once it finishes.')\n process.exit(1)\n }\n\n console.error('Dependencies not installed. Run `npm install` (or `bun install`) first.')\n process.exit(1)\n}\n\n/**\n * Is the detached install worker still running? True when install.pid is\n * missing (pre-0.5.6 scaffolds — assume in-progress rather than cry wolf) or\n * the pid answers signal 0. EPERM means \"alive, not ours\".\n */\nfunction installWorkerAlive(sentinelDir: string): boolean {\n const pidPath = join(sentinelDir, 'install.pid')\n if (!existsSync(pidPath)) return true\n const pid = Number.parseInt(readFileSync(pidPath, 'utf-8').trim(), 10)\n if (!Number.isFinite(pid) || pid <= 0) return true\n try {\n process.kill(pid, 0)\n return true\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === 'EPERM'\n }\n}\n","import { execFileSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\n// Namespace import on purpose: a named `import { registerHooks }` would itself\n// crash at load time on the very Nodes this preflight exists to catch.\nimport * as nodeModule from 'node:module'\nimport { resolve } from 'node:path'\n\n/**\n * The Cloudflare Vite plugin uses `module.registerHooks` (Node 22.15+ /\n * 23.5+). On older Nodes, `vite build` and the dev server die with a cryptic\n * ESM error from deep inside the plugin:\n *\n * SyntaxError: The requested module 'node:module' does not provide an\n * export named 'registerHooks'\n *\n * Catch it before spawning Vite and print the actual fix instead. Feature-\n * detected rather than version-pinned so the check can't go stale; the\n * `hasRegisterHooks` parameter exists only for tests.\n */\nexport function preflightNodeVersion(\n command: string,\n hasRegisterHooks: boolean = typeof (nodeModule as { registerHooks?: unknown }).registerHooks ===\n 'function',\n): void {\n if (hasRegisterHooks) return\n console.error(\n `deepspace ${command} requires Node 22.15 or newer (found v${process.versions.node}).`,\n )\n console.error('Install the current LTS from https://nodejs.org and re-run.')\n process.exit(1)\n}\n\n// 0xC0000135 = STATUS_DLL_NOT_FOUND on Windows. Node reports it as a signed int.\nconst DLL_NOT_FOUND = -1073741515\n\n/**\n * On Windows, the Cloudflare Workers runtime (`workerd.exe`) is built with\n * MSVC and links against `vcruntime140.dll`. A bare Windows install (Server\n * 2022, Server Core, minimal Windows 11) does not ship those DLLs, so workerd\n * exits immediately with STATUS_DLL_NOT_FOUND. Miniflare then surfaces this as\n * \"Error: write EOF\" because workerd closed the stdin pipe before reading its\n * config — an error with no JS stack trace and no hint at the cause.\n *\n * This preflight catches the case and prints the actual fix (install VC++\n * Redistributable). Skip silently if workerd isn't installed yet or runs fine.\n */\nexport function preflightWindowsWorkerd(appDir: string): void {\n if (process.platform !== 'win32') return\n\n const workerdExe = resolve(\n appDir,\n 'node_modules',\n '@cloudflare',\n 'workerd-windows-64',\n 'bin',\n 'workerd.exe',\n )\n if (!existsSync(workerdExe)) return\n\n try {\n execFileSync(workerdExe, ['--help'], { stdio: 'pipe', timeout: 10_000 })\n return\n } catch (err: unknown) {\n const status = (err as { status?: number }).status\n if (status !== DLL_NOT_FOUND) return\n\n console.error('')\n console.error(' workerd (Cloudflare Workers runtime) cannot start on this system.')\n console.error(' It needs the Microsoft Visual C++ Redistributable, which is not installed.')\n console.error('')\n console.error(' Install it with any of:')\n console.error(' winget install Microsoft.VCRedist.2015+.x64')\n console.error(' choco install -y vcredist140')\n console.error(' https://aka.ms/vs/17/release/vc_redist.x64.exe')\n console.error('')\n console.error(' Then restart this terminal and re-run the command.')\n console.error('')\n process.exit(1)\n }\n}\n","import { readdirSync, rmSync } from 'node:fs'\nimport { join } from 'node:path'\n\nconst SKIP_DIRS = new Set(['node_modules', '.git', 'dist', '.wrangler', '.vite'])\n\n/**\n * Delete macOS metadata files (AppleDouble `._*` and `.DS_Store`) under an\n * app directory. They appear when a project is copied from macOS through\n * tar/zip/SMB onto another system, and they poison the toolchain: ESLint\n * hard-fails on their binary content (\"Parsing error: Invalid character\",\n * failing the deploy lint), and generouted can pick up `._index.tsx` in\n * src/pages as a phantom route. Returns the number of files removed.\n */\nexport function removeMacosJunk(dir: string): number {\n let removed = 0\n // Best-effort throughout: an unreadable subdir or undeletable file must\n // never abort a build that would otherwise have worked.\n let entries\n try {\n entries = readdirSync(dir, { withFileTypes: true })\n } catch {\n return removed\n }\n for (const entry of entries) {\n const path = join(dir, entry.name)\n if (entry.isDirectory()) {\n if (!SKIP_DIRS.has(entry.name)) removed += removeMacosJunk(path)\n continue\n }\n if (entry.name === '.DS_Store' || entry.name.startsWith('._')) {\n try {\n rmSync(path, { force: true })\n removed++\n } catch {\n // Leave it — the lint may still trip on it, but we didn't make\n // anything worse.\n }\n }\n }\n return removed\n}\n","/**\n * Shared dev-server port resolution for `dev`, `test`, and `kill`.\n *\n * Precedence: explicit `--port` arg > $DEEPSPACE_PORT > DEFAULT_PORT. An\n * out-of-range value is a hard error (exit 1) rather than a silent fallback,\n * so a typo doesn't quietly bind the wrong port.\n */\n\nimport { createServer } from 'node:net'\n\nexport const DEFAULT_PORT = 5173\n\n/**\n * Whether `port` is free to bind on `host`. Used by `dev` to pre-probe before\n * spawning vite (which binds with `--host`, i.e. 0.0.0.0), so a busy port gets\n * a friendly `deepspace kill` / `--port` remedy instead of vite's raw\n * EADDRINUSE stack (DEV-5). Best-effort: a bind race after the probe still\n * surfaces vite's own error, but the common \"server already running\" case is\n * caught cleanly.\n */\nexport function checkPortAvailable(port: number, host = '0.0.0.0'): Promise<boolean> {\n return new Promise((resolve) => {\n const srv = createServer()\n srv.once('error', () => resolve(false))\n srv.once('listening', () => srv.close(() => resolve(true)))\n srv.listen(port, host)\n })\n}\n\nexport function resolvePort(arg?: string): number {\n const raw = arg ?? process.env.DEEPSPACE_PORT\n if (!raw) return DEFAULT_PORT\n const n = Number(raw)\n if (!Number.isInteger(n) || n < 1 || n > 65535) {\n console.error(`Invalid port: ${raw}. Must be an integer between 1 and 65535.`)\n process.exit(1)\n }\n return n\n}\n","/**\n * deepspace kill [--port N] [--all]\n *\n * Stops a local dev server bound to the given port, plus the workerd\n * child processes that wrangler/Vite would normally clean up but\n * sometimes leak when the parent dies ungracefully (Ctrl-C in a\n * detached terminal, IDE close, sandbox deny on signal, etc).\n *\n * deepspace kill # kill listener on 5173 + its workerd children\n * deepspace kill --port 5180 # kill listener on a different port\n * deepspace kill --all # also sweep ALL stray workerd/wrangler procs on the machine\n *\n * Cross-platform: uses lsof/pgrep on macOS and Linux, and PowerShell\n * (Get-NetTCPConnection / Get-CimInstance) on Windows. PowerShell ships\n * with every supported Windows version since 7; no extra install required.\n *\n * Always sends SIGTERM first, waits briefly, then SIGKILL anything\n * still alive — same shape as `vite`'s own shutdown handler so we\n * don't trample DO state mid-write. (On Windows, SIGTERM is best-effort:\n * Win32 has no real signals, so node maps both to TerminateProcess. We\n * still issue them in the same order for consistent log output.)\n */\n\nimport { defineCommand } from 'citty'\nimport { spawnSync } from 'node:child_process'\nimport { readFileSync, readdirSync, readlinkSync } from 'node:fs'\nimport { setTimeout as wait } from 'node:timers/promises'\nimport { findAppDir, resolveWorktreePort, resolveAppLaunchPort } from '../lib/app-context'\nimport { DEFAULT_PORT, resolvePort } from '../lib/port'\n\nconst SIGTERM_GRACE_MS = 1500\nconst IS_WIN = process.platform === 'win32'\n\n/**\n * Pick the port `kill` targets, mirroring `dev`'s binding precedence so the two\n * always agree (DEV-2). Pure for testing.\n * 1. explicit --port\n * 2. worktree port (dev ignores $DEEPSPACE_PORT inside a worktree, so we do too)\n * 3. $DEEPSPACE_PORT (dev binds it outside a worktree, over a launch.json that\n * dev only rewrites for an explicit --port)\n * 4. the app's launch.json port (kept in sync by `dev --port`)\n * 5. the default\n */\nexport function pickKillPort(opts: {\n explicit: number | null\n worktree: number | null\n env: number | null\n appLaunch: number | null\n}): number {\n if (opts.explicit != null) return opts.explicit\n if (opts.worktree != null) return opts.worktree\n if (opts.env != null) return opts.env\n return opts.appLaunch ?? DEFAULT_PORT\n}\n\nexport default defineCommand({\n meta: {\n name: 'kill',\n description: 'Kill the local dev server and any orphaned workerd processes',\n },\n args: {\n port: {\n type: 'string',\n description: `Port the dev server is bound to (default ${DEFAULT_PORT}, or $DEEPSPACE_PORT)`,\n required: false,\n },\n all: {\n type: 'boolean',\n description: 'Also kill stray workerd/wrangler processes across all ports',\n default: false,\n },\n },\n async run({ args }) {\n // Resolve which port to target, mirroring `dev`'s own precedence so `kill`\n // always targets the server `dev` bound (DEV-2). Without this, no-arg `kill`\n // hit :5173 even when `dev --port 8790` was running elsewhere.\n const cwd = process.cwd()\n const port = pickKillPort({\n explicit: args.port ? resolvePort(args.port) : null,\n worktree: resolveWorktreePort(cwd),\n // resolvePort() reads + validates $DEEPSPACE_PORT; only consult it when set.\n env: process.env.DEEPSPACE_PORT ? resolvePort() : null,\n appLaunch: resolveAppLaunchPort(findAppDir(cwd) ?? cwd),\n })\n const targets = new Set<number>()\n\n // 1. Anything LISTENing on the dev port (vite + the workerd child it\n // publishes through, occasionally a stray inspector). `enumerated`\n // tells us whether we could actually inspect the port at all.\n const listeners = enumerateListeners(port)\n for (const pid of listeners.pids) targets.add(pid)\n\n // 2. Children of those listeners — wrangler/vite tend to spawn workerd\n // as a sibling, but in some shells it ends up as a child instead.\n for (const pid of [...targets]) {\n for (const child of childPids(pid)) targets.add(child)\n }\n\n // 3. With --all, sweep workerd / wrangler / vite anywhere on the box.\n // Useful when port 5173 is \"free\" but a leftover workerd from a\n // previous run is still holding D1 / DO state in .wrangler/.\n let swept = false\n if (args.all) {\n const sweep = sweepByName(['workerd', 'wrangler', 'vite'])\n swept = sweep.swept\n for (const pid of sweep.pids) targets.add(pid)\n }\n\n if (targets.size === 0) {\n // DEV-1: distinguish \"inspected, found nothing\" from \"couldn't inspect\".\n // The latter must NOT report the port free (exit 0) while a leaked\n // workerd keeps holding DO/D1 state — that was the original silent no-op.\n const outcome = noTargetsMessage({\n enumerated: listeners.enumerated,\n swept,\n all: args.all,\n port,\n })\n if (!outcome.ok) {\n console.error(outcome.message)\n process.exit(1)\n }\n console.log(outcome.message)\n return\n }\n\n // SIGTERM pass.\n for (const pid of targets) {\n if (sendSignal(pid, 'SIGTERM')) {\n console.log(`SIGTERM → pid ${pid}`)\n }\n }\n await wait(SIGTERM_GRACE_MS)\n\n const stillAlive: number[] = []\n for (const pid of targets) {\n if (isAlive(pid)) stillAlive.push(pid)\n }\n\n // SIGKILL holdouts.\n for (const pid of stillAlive) {\n if (sendSignal(pid, 'SIGKILL')) {\n console.log(`SIGKILL → pid ${pid} (did not exit on SIGTERM)`)\n }\n }\n\n // Re-verify the port is free.\n await wait(200)\n const remaining = listenerPids(port)\n if (remaining.length > 0) {\n console.error(\n `Port ${port} is still held by pid(s) ${remaining.join(', ')} — try \\`deepspace kill --port ${port}\\` again, or kill manually.`,\n )\n process.exit(1)\n }\n\n // Report what actually happened. Under --all we may have swept processes on\n // ports other than `port` (matched by name), so a bare \"Port 5173 is free\"\n // would misrepresent the sweep (DEV-6).\n if (args.all) {\n console.log(`Killed ${targets.size} process(es) (workerd/wrangler/vite sweep). :${port} is free.`)\n } else {\n console.log(`Port ${port} is free.`)\n }\n },\n})\n\n// ── Platform-specific helpers ─────────────────────────────────────────────\n\n/**\n * Decide what to print when no kill targets were found. Pure so the DEV-1\n * rule — never claim the port is free when we couldn't actually inspect it —\n * is unit-testable. `ok:false` means we lacked any way to observe the system\n * (no lsof/pgrep AND no /proc) and must exit non-zero rather than lie.\n */\nexport function noTargetsMessage(opts: {\n enumerated: boolean\n swept: boolean\n all: boolean\n port: number\n}): { ok: boolean; message: string } {\n const { enumerated, swept, all, port } = opts\n const couldObserve = enumerated || (all && swept)\n if (!couldObserve) {\n return {\n ok: false,\n message:\n `Couldn't determine what's running on :${port}: no lsof/pgrep and /proc ` +\n `is unavailable, so nothing was inspected or killed. Install lsof (or ` +\n `procps for pgrep), or find and kill the process manually.`,\n }\n }\n return {\n ok: true,\n message: all\n ? `Nothing listening on :${port} and no stray workerd/wrangler/vite processes found.`\n : `Nothing listening on :${port}. (Pass --all to sweep stray workerd/wrangler.)`,\n }\n}\n\n/**\n * PIDs listening on `port`, plus whether we could inspect the port at all.\n * `enumerated:false` means every available method (lsof / PowerShell / /proc)\n * was missing — a genuine \"don't know\", not \"nothing there\".\n */\nfunction enumerateListeners(port: number): { pids: number[]; enumerated: boolean } {\n if (IS_WIN) {\n // Get-NetTCPConnection is the modern replacement for netstat -ano.\n // -ErrorAction SilentlyContinue swallows \"No matching connection\" so\n // the command exits 0 with empty stdout instead of a noisy red error.\n const r = runPowershellChecked(\n `Get-NetTCPConnection -LocalPort ${port} -State Listen -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess`,\n )\n return { pids: r.pids, enumerated: r.ran }\n }\n // lsof is authoritative when present. It exits 1 (not an error, for us) when\n // nothing matches, so \"ran but empty\" is a real \"nothing listening\".\n const lsof = runLsof(port)\n if (lsof.ran) return { pids: lsof.pids, enumerated: true }\n // lsof is absent on many container/CI images — `node:22-bookworm` ships none\n // of lsof/ss/fuser/netstat. /proc needs no external binary and covers Linux;\n // if it's also unavailable we truly can't tell (enumerated:false).\n const proc = listenerPidsViaProc(port)\n return { pids: proc.pids, enumerated: proc.available }\n}\n\n/** Thin wrapper for the post-kill re-verify, where capability is irrelevant. */\nfunction listenerPids(port: number): number[] {\n return enumerateListeners(port).pids\n}\n\n/** Run lsof for a port. `ran` distinguishes \"lsof absent\" from \"found nothing\". */\nfunction runLsof(port: number): { pids: number[]; ran: boolean } {\n try {\n // -t prints PIDs only, one per line; -nP avoids DNS / service lookups.\n const r = spawnSync('lsof', ['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-t'], {\n encoding: 'utf-8',\n })\n if (r.error) return { pids: [], ran: false } // ENOENT: lsof not installed\n // 0 = matches printed; 1 = no matches. Both mean lsof ran successfully.\n return { pids: r.status === 0 ? parsePidLines(r.stdout) : [], ran: true }\n } catch {\n return { pids: [], ran: false }\n }\n}\n\n/** Port → listening PIDs via /proc alone (no lsof/ss). Finds the LISTEN\n * socket's inode in /proc/net/tcp{,6}, then the process holding that fd.\n * `available` is false when /proc itself couldn't be read. */\nfunction listenerPidsViaProc(port: number): { pids: number[]; available: boolean } {\n let available = false\n try {\n const hexPort = port.toString(16).toUpperCase().padStart(4, '0')\n const inodes = new Set<string>()\n for (const f of ['/proc/net/tcp', '/proc/net/tcp6']) {\n let data: string\n try {\n data = readFileSync(f, 'utf-8')\n } catch {\n continue\n }\n available = true\n for (const line of data.split('\\n').slice(1)) {\n const cols = line.trim().split(/\\s+/)\n // sl local_address(1) rem_address(2) st(3) … inode(9); st 0A = LISTEN.\n if (cols[3] !== '0A') continue\n if (cols[1]?.split(':')[1] === hexPort && cols[9]) inodes.add(cols[9])\n }\n }\n if (!available) return { pids: [], available: false }\n if (!inodes.size) return { pids: [], available: true }\n const pids = new Set<number>()\n for (const pidDir of readdirSync('/proc')) {\n if (!/^\\d+$/.test(pidDir)) continue\n let fds: string[]\n try {\n fds = readdirSync(`/proc/${pidDir}/fd`)\n } catch {\n continue // not ours / gone\n }\n for (const fd of fds) {\n let link: string\n try {\n link = readlinkSync(`/proc/${pidDir}/fd/${fd}`)\n } catch {\n continue\n }\n const m = link.match(/^socket:\\[(\\d+)\\]$/)\n if (m && inodes.has(m[1])) {\n pids.add(Number(pidDir))\n break\n }\n }\n }\n return { pids: [...pids], available: true }\n } catch {\n return { pids: [], available }\n }\n}\n\nfunction childPids(parentPid: number): number[] {\n if (IS_WIN) {\n return runPowershell(\n `Get-CimInstance Win32_Process -Filter \"ParentProcessId=${parentPid}\" | Select-Object -ExpandProperty ProcessId`,\n )\n }\n return run(['pgrep', '-P', String(parentPid)])\n}\n\n/**\n * Sweep processes by name/commandline. `swept` reports whether the enumerator\n * (pgrep / PowerShell) actually ran — so `--all` doesn't falsely claim \"no\n * stray processes\" when it never got to look.\n */\nfunction sweepByName(names: string[]): { pids: number[]; swept: boolean } {\n const all = new Set<number>()\n if (IS_WIN) {\n // Match against process Name (e.g. \"workerd\") AND CommandLine (catches\n // npx-launched scripts like \"vite\" that show up as node.exe with vite\n // in the args).\n const orClauses = names\n .map((n) => `($_.Name -like '*${n}*') -or ($_.CommandLine -like '*${n}*')`)\n .join(' -or ')\n const script = `Get-CimInstance Win32_Process | Where-Object { ${orClauses} } | Select-Object -ExpandProperty ProcessId`\n const r = runPowershellChecked(script)\n for (const pid of r.pids) if (pid !== process.pid) all.add(pid)\n return { pids: [...all], swept: r.ran }\n }\n let swept = false\n for (const name of names) {\n const r = runPgrep(['-f', name])\n if (r.ran) swept = true\n for (const pid of r.pids) if (pid !== process.pid) all.add(pid)\n }\n return { pids: [...all], swept }\n}\n\n/** Run pgrep. `ran` distinguishes \"pgrep absent\" from \"matched nothing\" (exit 1). */\nfunction runPgrep(pgrepArgs: string[]): { pids: number[]; ran: boolean } {\n try {\n const r = spawnSync('pgrep', pgrepArgs, { encoding: 'utf-8' })\n if (r.error) return { pids: [], ran: false } // ENOENT: pgrep not installed\n // 0 = matches; 1 = no matches. Both mean pgrep ran.\n return { pids: r.status === 0 ? parsePidLines(r.stdout) : [], ran: r.status === 0 || r.status === 1 }\n } catch {\n return { pids: [], ran: false }\n }\n}\n\n// ── Process primitives ────────────────────────────────────────────────────\n\n/** Run a command and return whitespace-separated PIDs (empty array on failure). */\nfunction run(cmd: string[]): number[] {\n try {\n const r = spawnSync(cmd[0], cmd.slice(1), { encoding: 'utf-8' })\n if (r.status !== 0) return []\n return parsePidLines(r.stdout)\n } catch {\n return []\n }\n}\n\n/**\n * Run a PowerShell snippet. Prefers `pwsh` (PowerShell 7+) when available\n * and falls back to `powershell.exe` (Windows PowerShell 5.1, ships with\n * every Windows version we care about).\n */\nfunction runPowershell(script: string): number[] {\n return runPowershellChecked(script).pids\n}\n\n/** Like runPowershell but reports whether PowerShell actually ran (`ran`),\n * so callers can tell \"no matches\" (exit 0, empty) from \"PowerShell absent\". */\nfunction runPowershellChecked(script: string): { pids: number[]; ran: boolean } {\n const exe = pwshOrPowershell()\n try {\n const r = spawnSync(exe, ['-NoProfile', '-NonInteractive', '-Command', script], {\n encoding: 'utf-8',\n })\n if (r.error) return { pids: [], ran: false }\n // With -ErrorAction SilentlyContinue the query exits 0 even with no matches.\n return { pids: r.status === 0 ? parsePidLines(r.stdout) : [], ran: r.status === 0 }\n } catch {\n return { pids: [], ran: false }\n }\n}\n\nfunction pwshOrPowershell(): string {\n // `pwsh` is the modern cross-platform binary; `powershell.exe` is the\n // legacy Windows-only one. Try modern first, fall back if missing.\n const probe = spawnSync('pwsh', ['-NoProfile', '-Command', '$PSVersionTable.PSVersion.Major'], {\n encoding: 'utf-8',\n })\n if (probe.status === 0) return 'pwsh'\n return 'powershell.exe'\n}\n\nfunction parsePidLines(stdout: string): number[] {\n return stdout\n .split(/\\s+/)\n .map((s) => Number.parseInt(s, 10))\n .filter((n) => Number.isFinite(n) && n > 0)\n}\n\nfunction sendSignal(pid: number, signal: NodeJS.Signals): boolean {\n try {\n process.kill(pid, signal)\n return true\n } catch {\n return false\n }\n}\n\nfunction isAlive(pid: number): boolean {\n try {\n // signal 0 = \"do nothing, just check\"\n process.kill(pid, 0)\n return true\n } catch {\n return false\n }\n}\n","/**\n * deepspace test [suite] [--port N]\n *\n * Runs tests for a DeepSpace app. Always uses dev workers.\n *\n * deepspace test # smoke + api (quick check)\n * deepspace test smoke # smoke tests only\n * deepspace test api # API tests only\n * deepspace test e2e # all Playwright tests\n * deepspace test unit # vitest unit tests\n * deepspace test all # everything\n * deepspace test <file> # run specific test file\n *\n * Port is `--port` > $DEEPSPACE_PORT > 5173 — except inside a Claude Code\n * worktree, where (unless --port was passed) the worktree's own port is used\n * so tests hit the worktree's server, not the main repo's. The chosen port is\n * exported as DEEPSPACE_PORT to the Playwright child so the config +\n * webServer both bind to the same address. Pass a different port per app to\n * run multiple apps\n * (and test suites) in parallel.\n */\n\nimport { defineCommand } from 'citty'\nimport { readAppId } from '../lib/app-identity'\nimport { resolve } from 'node:path'\nimport { sync as spawnSync } from 'cross-spawn'\nimport { ensureToken } from '../auth'\nimport { findAppDir, findChildApps, resolveWorktreePort } from '../lib/app-context'\nimport { PLATFORM_URLS, writeDevVars } from '../env'\nimport { decodeJwtPayload } from '../jwt'\nimport { ensureInstallReady } from '../lib/install-status'\nimport { ensurePlaywright } from '../lib/playwright'\nimport { preflightNodeVersion, preflightWindowsWorkerd } from '../lib/preflight'\nimport { refreshSecretsCache } from '../lib/secrets'\nimport { DEFAULT_PORT, resolvePort } from '../lib/port'\nimport {\n prepareWranglerEnvConfig,\n wranglerViteEnv,\n type PreparedWranglerEnvConfig,\n} from '../lib/wrangler-env'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\nexport default defineCommand({\n meta: {\n name: 'test',\n description: 'Run tests for your DeepSpace app',\n },\n args: {\n suite: {\n type: 'positional',\n description: 'Test suite: smoke, api, e2e, unit, all (default: smoke+api)',\n required: false,\n },\n port: {\n type: 'string',\n description: `Port for vite/webServer (default ${DEFAULT_PORT}, or $DEEPSPACE_PORT)`,\n required: false,\n },\n env: {\n type: 'string',\n alias: 'e',\n description:\n 'wrangler.toml [env.<name>] block to test (uses secrets config <name> by default).',\n required: false,\n },\n },\n async run({ args }) {\n preflightNodeVersion('test')\n const suite = args.suite ?? 'default'\n const wranglerEnv =\n typeof args.env === 'string' && args.env.trim() ? args.env.trim() : undefined\n\n // Resolve the app root by walking up from cwd, matching `deepspace dev`.\n const start = resolve('.')\n const appDir = findAppDir(start)\n if (!appDir) {\n console.error(`No wrangler.toml found at or above ${start}.`)\n const children = findChildApps(start)\n if (children.length > 0) {\n console.error('Did you mean to run inside one of these app directories?')\n for (const c of children) console.error(` cd ${c}`)\n } else {\n console.error('Run from a DeepSpace app directory (one containing wrangler.toml).')\n }\n process.exit(1)\n }\n\n // Inside a Claude Code worktree the default port must match the\n // worktree's dev server (not 5173): Playwright's reuseExistingServer\n // would otherwise attach to the MAIN repo's server and silently test\n // stale code. Explicit --port still wins.\n const worktreePort = args.port ? null : resolveWorktreePort(appDir)\n const port = worktreePort ?? resolvePort(args.port)\n if (worktreePort && process.env.DEEPSPACE_PORT) {\n console.log(\n `Ignoring DEEPSPACE_PORT=${process.env.DEEPSPACE_PORT} inside a worktree — ` +\n `targeting per-worktree port ${port}. Pass --port to override.`,\n )\n }\n\n ensureInstallReady(appDir)\n\n // Always write .dev.vars pointing to dev workers. A logged-in user is\n // required so writeDevVars can mint APP_OWNER_JWT via the auth-worker.\n let token: string\n let ownerId: string\n try {\n token = await ensureToken()\n const payload = decodeJwtPayload<{ sub: string }>(token)\n ownerId = payload.sub\n } catch (err) {\n // Surface ensureToken's canonical message (\"Not logged in. Run `deepspace\n // login` first.\" / \"Session expired…\") instead of a bespoke one (ONB-5).\n console.error(err instanceof Error ? err.message : 'Not logged in. Run `deepspace login` first.')\n process.exit(1)\n }\n\n // Refresh the app-store secrets cache (config = wrangler env, or 'prd').\n // A repo without a DEEPSPACE_APP_ID hasn't been initialized — writeDevVars\n // below throws with the `deepspace init` pointer, so skip the pull.\n let generatedSecretsCache: string | undefined\n const appIdForSecrets = readAppId(appDir, wranglerEnv)\n if (appIdForSecrets) {\n try {\n const refreshed = await refreshSecretsCache(DEPLOY_URL, token, appIdForSecrets, wranglerEnv)\n if (refreshed) {\n generatedSecretsCache = refreshed.rendered\n console.log(refreshed.summary)\n }\n } catch (err: unknown) {\n console.error(\n `Failed to refresh app secrets: ${err instanceof Error ? err.message : String(err)}`,\n )\n process.exit(1)\n }\n }\n\n const sharedDevVarsCache = generatedSecretsCache !== undefined\n await writeDevVars(appDir, ownerId, token, wranglerEnv, {\n generatedSecretsCache,\n sharedDevVarsCache,\n })\n\n if (suite !== 'unit') {\n preflightWindowsWorkerd(appDir)\n ensurePlaywright(appDir)\n }\n\n let exitCode = 0\n\n switch (suite) {\n case 'smoke':\n exitCode = runPlaywright(\n appDir,\n ['tests/smoke.spec.ts'],\n port,\n wranglerEnv,\n sharedDevVarsCache,\n )\n break\n case 'api':\n exitCode = runPlaywright(\n appDir,\n ['tests/api.spec.ts'],\n port,\n wranglerEnv,\n sharedDevVarsCache,\n )\n break\n case 'e2e':\n exitCode = runPlaywright(appDir, [], port, wranglerEnv, sharedDevVarsCache)\n break\n case 'unit':\n exitCode = runVitest(appDir)\n break\n case 'all':\n exitCode = runVitest(appDir)\n if (exitCode === 0)\n exitCode = runPlaywright(appDir, [], port, wranglerEnv, sharedDevVarsCache)\n break\n case 'default':\n exitCode = runPlaywright(\n appDir,\n ['tests/smoke.spec.ts', 'tests/api.spec.ts'],\n port,\n wranglerEnv,\n sharedDevVarsCache,\n )\n break\n default:\n if (suite.endsWith('.spec.ts')) {\n exitCode = runPlaywright(appDir, [suite], port, wranglerEnv, sharedDevVarsCache)\n } else {\n console.error(`Unknown test suite: ${suite}`)\n console.error('Available: smoke, api, e2e, unit, all')\n process.exit(1)\n }\n }\n\n process.exit(exitCode)\n },\n})\n\nfunction runPlaywright(\n appDir: string,\n testFiles: string[],\n port: number,\n wranglerEnv?: string,\n sharedDevVarsCache = false,\n): number {\n let wranglerConfig: PreparedWranglerEnvConfig\n try {\n wranglerConfig = prepareWranglerEnvConfig(appDir, wranglerEnv, { sharedDevVarsCache })\n } catch (err: unknown) {\n console.error(err instanceof Error ? err.message : String(err))\n return 1\n }\n try {\n const result = spawnSync(\n 'npx',\n ['playwright', 'test', '--config', 'tests/playwright.config.ts', ...testFiles],\n {\n cwd: appDir,\n stdio: 'inherit',\n env: wranglerViteEnv(process.env, wranglerConfig, { DEEPSPACE_PORT: String(port) }),\n },\n )\n return result.status ?? 1\n } finally {\n wranglerConfig.cleanup()\n }\n}\n\nfunction runVitest(appDir: string): number {\n const result = spawnSync('npx', ['vitest', 'run', '--passWithNoTests'], {\n cwd: appDir,\n stdio: 'inherit',\n })\n return result.status ?? 1\n}\n","import { execSync } from 'node:child_process'\nimport { sync as spawnSync } from 'cross-spawn'\n\nexport function ensurePlaywright(appDir: string) {\n try {\n // execSync interprets the command via shell, so it handles npx/npx.cmd\n // resolution on its own. Only spawn()/spawnSync() need cross-spawn.\n execSync('npx playwright --version', { cwd: appDir, stdio: 'pipe' })\n } catch {\n console.log('Installing Playwright...')\n execSync('npm install -D @playwright/test', { cwd: appDir, stdio: 'pipe' })\n }\n\n // `playwright install` is idempotent: a fast no-op when Chromium already\n // exists, and the first real browser download only when a browser command\n // actually needs it.\n const isLinux = process.platform === 'linux'\n const isRoot = isLinux && typeof process.getuid === 'function' && process.getuid() === 0\n const args = isRoot ? ['install', '--with-deps', 'chromium'] : ['install', 'chromium']\n const result = spawnSync('npx', ['playwright', ...args], {\n cwd: appDir,\n stdio: 'inherit',\n })\n\n if (result.status !== 0) {\n console.error('\\nPlaywright install failed. On Linux, system libs may be missing. Try:')\n console.error(' sudo npx playwright install --with-deps chromium')\n process.exit(1)\n }\n}\n","/**\n * deepspace screenshot <url> <output> [--full-page] [--wait-for-timeout ms]\n *\n * Takes a Playwright Chromium screenshot, installing the browser on demand.\n */\n\nimport { defineCommand } from 'citty'\nimport { sync as spawnSync } from 'cross-spawn'\nimport { resolve } from 'node:path'\nimport { ensurePlaywright } from '../lib/playwright'\n\nexport default defineCommand({\n meta: {\n name: 'screenshot',\n description: 'Take a Playwright screenshot, installing Chromium on demand',\n },\n args: {\n url: {\n type: 'positional',\n description: 'URL to capture, for example http://localhost:5173/',\n required: true,\n },\n output: {\n type: 'positional',\n description: 'Output image path, for example screenshot.png',\n required: true,\n },\n 'full-page': {\n type: 'boolean',\n description: 'Capture the full scrollable page',\n required: false,\n },\n 'wait-for-timeout': {\n type: 'string',\n description: 'Milliseconds to wait before capture',\n required: false,\n },\n },\n run({ args }) {\n const appDir = resolve('.')\n ensurePlaywright(appDir)\n\n const playwrightArgs = ['playwright', 'screenshot', args.url, args.output]\n if (args['full-page']) playwrightArgs.push('--full-page')\n if (args['wait-for-timeout']) {\n playwrightArgs.push('--wait-for-timeout', String(args['wait-for-timeout']))\n }\n\n const result = spawnSync('npx', playwrightArgs, {\n cwd: appDir,\n stdio: 'inherit',\n })\n\n process.exit(result.status ?? 1)\n },\n})\n","/**\n * deepspace test-accounts\n *\n * Manage test accounts for local development and CI.\n * Test accounts use @deepspace.test emails and are clearly\n * demarcated in the database. Max 10 per developer.\n *\n * Credentials are saved to ~/.deepspace/test-accounts.json (0600)\n * so they persist across projects and sessions.\n *\n * deepspace test-accounts create --email bot@deepspace.test --password Pass123!\n * deepspace test-accounts list\n * deepspace test-accounts delete --email bot@deepspace.test\n * deepspace test-accounts delete --id <id>\n * deepspace test-accounts clear # delete all (with confirm)\n * deepspace test-accounts clear --label e2e # delete only label=e2e\n * deepspace test-accounts clear --yes # skip confirm (CI)\n */\n\nimport { defineCommand } from 'citty'\nimport * as p from '@clack/prompts'\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport { ensureToken, SESSION_PATH } from '../auth'\nimport { PLATFORM_URLS } from '../env'\n\nconst SESSION_COOKIE = '__Secure-better-auth.session_token'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? PLATFORM_URLS.auth\nconst DIR = join(homedir(), '.deepspace')\nconst ACCOUNTS_PATH = join(DIR, 'test-accounts.json')\n\n// ── Local credential store ─────────────────────────────────────────\n\ninterface StoredAccount {\n id: string\n email: string\n password: string\n userId: string\n name?: string\n label?: string | null\n createdAt: number\n}\n\nfunction loadAccounts(): StoredAccount[] {\n if (!existsSync(ACCOUNTS_PATH)) return []\n try {\n return JSON.parse(readFileSync(ACCOUNTS_PATH, 'utf-8'))\n } catch {\n return []\n }\n}\n\nfunction saveAccounts(accounts: StoredAccount[]) {\n mkdirSync(DIR, { recursive: true })\n writeFileSync(ACCOUNTS_PATH, JSON.stringify(accounts, null, 2), { mode: 0o600 })\n}\n\n// ── Helpers ────────────────────────────────────────────────────────\n\nfunction sessionCookie(): string {\n const token = readFileSync(SESSION_PATH, 'utf-8').trim()\n return `${SESSION_COOKIE}=${encodeURIComponent(token)}`\n}\n\ninterface RemoteAccount {\n id: string\n email: string\n userId: string\n label: string | null\n createdAt: number\n}\n\nasync function fetchRemoteAccounts(): Promise<RemoteAccount[]> {\n const res = await fetch(`${AUTH_URL}/api/auth/test-accounts`, {\n headers: { Cookie: sessionCookie(), Origin: AUTH_URL },\n })\n const data = (await res.json().catch(() => ({}))) as {\n accounts?: RemoteAccount[]\n error?: string\n }\n if (!res.ok || !data.accounts) {\n throw new Error(data.error ?? 'Failed to list test accounts')\n }\n return data.accounts\n}\n\nasync function deleteRemote(id: string): Promise<void> {\n const res = await fetch(`${AUTH_URL}/api/auth/test-accounts/${id}`, {\n method: 'DELETE',\n headers: { Cookie: sessionCookie(), Origin: AUTH_URL },\n })\n if (!res.ok) {\n const data = (await res.json().catch(() => ({}))) as { error?: string }\n throw new Error(data.error ?? `DELETE returned ${res.status}`)\n }\n}\n\n// ── Subcommands ────────────────────────────────────────────────────\n\nconst create = defineCommand({\n meta: {\n name: 'create',\n description: 'Create a test account',\n },\n args: {\n email: {\n type: 'string',\n description: 'Email (must end with @deepspace.test)',\n required: true,\n },\n password: {\n type: 'string',\n description: 'Password (min 8 characters)',\n required: true,\n },\n name: {\n type: 'string',\n description: 'Display name',\n required: false,\n },\n label: {\n type: 'string',\n description: 'Label for this test account',\n required: false,\n },\n },\n async run({ args }) {\n await ensureToken()\n\n const res = await fetch(`${AUTH_URL}/api/auth/test-accounts`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Cookie: sessionCookie(),\n Origin: AUTH_URL,\n },\n body: JSON.stringify({\n email: args.email,\n password: args.password,\n name: args.name,\n label: args.label,\n }),\n })\n\n const data = (await res.json().catch(() => ({}))) as {\n id?: string\n email?: string\n userId?: string\n label?: string | null\n createdAt?: number\n error?: string\n }\n\n if (!res.ok || !data.id) {\n console.error(`Failed: ${data.error ?? 'Unknown error'}`)\n process.exit(1)\n }\n\n const account = data as {\n id: string\n email: string\n userId: string\n label: string | null\n createdAt: number\n }\n\n // Save credentials locally\n const accounts = loadAccounts()\n accounts.push({\n id: account.id,\n email: args.email,\n password: args.password,\n userId: account.userId,\n name: args.name,\n label: account.label,\n createdAt: account.createdAt,\n })\n saveAccounts(accounts)\n\n console.log(`Created test account:`)\n console.log(` ID: ${account.id}`)\n console.log(` Email: ${account.email}`)\n console.log(` Password: ${args.password}`)\n console.log(` UserID: ${account.userId}`)\n if (account.label) console.log(` Label: ${account.label}`)\n console.log(`\\nSaved to ${ACCOUNTS_PATH}`)\n },\n})\n\nconst list = defineCommand({\n meta: {\n name: 'list',\n description: 'List your test accounts',\n },\n async run() {\n await ensureToken()\n\n let remote: RemoteAccount[]\n try {\n remote = await fetchRemoteAccounts()\n } catch (err) {\n console.error(`Failed: ${(err as Error).message}`)\n process.exit(1)\n }\n\n if (remote.length === 0) {\n console.log(\n 'No test accounts. Create one with: deepspace test-accounts create --email <email> --password <password>',\n )\n return\n }\n\n // Merge with local credentials (passwords are only stored locally)\n const local = loadAccounts()\n const localByEmail = new Map(local.map((a) => [a.email, a]))\n\n console.log(`Test accounts (${remote.length}/10):\\n`)\n for (const a of remote) {\n const stored = localByEmail.get(a.email)\n const date = new Date(a.createdAt).toLocaleDateString()\n console.log(` ${a.email}${a.label ? ` (${a.label})` : ''}`)\n console.log(` ID: ${a.id} UserID: ${a.userId} Created: ${date}`)\n if (stored?.password) {\n console.log(` Password: ${stored.password}`)\n } else {\n console.log(` Password: (not saved locally)`)\n }\n }\n },\n})\n\nconst del = defineCommand({\n meta: {\n name: 'delete',\n description: 'Delete a test account by --email or --id',\n },\n args: {\n email: {\n type: 'string',\n description: 'Email of the test account to delete',\n required: false,\n },\n id: {\n type: 'string',\n description: 'ID of the test account to delete',\n required: false,\n },\n },\n async run({ args }) {\n if (!args.email && !args.id) {\n console.error('Provide --email <email> or --id <id>.')\n process.exit(1)\n }\n if (args.email && args.id) {\n console.error('Provide either --email or --id, not both.')\n process.exit(1)\n }\n\n await ensureToken()\n\n let targetId = args.id as string | undefined\n const targetEmail = args.email as string | undefined\n\n if (targetEmail && !targetId) {\n let remote: RemoteAccount[]\n try {\n remote = await fetchRemoteAccounts()\n } catch (err) {\n console.error(`Failed: ${(err as Error).message}`)\n process.exit(1)\n }\n const match = remote.find((a) => a.email === targetEmail)\n if (!match) {\n console.error(`No test account with email ${targetEmail}.`)\n process.exit(1)\n }\n targetId = match.id\n }\n\n try {\n await deleteRemote(targetId!)\n } catch (err) {\n console.error(`Failed: ${(err as Error).message}`)\n process.exit(1)\n }\n\n // Remove from local store\n const accounts = loadAccounts().filter(\n (a) => a.id !== targetId && (!targetEmail || a.email !== targetEmail),\n )\n saveAccounts(accounts)\n\n console.log(`Test account deleted${targetEmail ? `: ${targetEmail}` : `: ${targetId}`}`)\n },\n})\n\nconst clear = defineCommand({\n meta: {\n name: 'clear',\n description: 'Delete all your test accounts (or those matching --label)',\n },\n args: {\n label: {\n type: 'string',\n description: 'Only delete accounts with this label (e.g. e2e, slack-clone)',\n required: false,\n },\n yes: {\n type: 'boolean',\n description: 'Skip confirmation prompt (for CI scripts)',\n default: false,\n },\n },\n async run({ args }) {\n await ensureToken()\n\n let remote: RemoteAccount[]\n try {\n remote = await fetchRemoteAccounts()\n } catch (err) {\n console.error(`Failed: ${(err as Error).message}`)\n process.exit(1)\n }\n\n const targets = args.label ? remote.filter((a) => a.label === args.label) : remote\n\n if (targets.length === 0) {\n const suffix = args.label ? ` with label '${args.label}'` : ''\n console.log(`No test accounts${suffix} to delete.`)\n return\n }\n\n if (!args.yes) {\n const subject = args.label\n ? `${targets.length} test account(s) labeled '${args.label}'`\n : `all ${targets.length} test account(s)`\n const confirmed = await p.confirm({\n message: `Delete ${subject}? This is not reversible.`,\n initialValue: false,\n })\n if (p.isCancel(confirmed) || !confirmed) {\n console.log('Cancelled.')\n return\n }\n }\n\n let ok = 0\n const failures: Array<{ email: string; error: string }> = []\n for (const a of targets) {\n try {\n await deleteRemote(a.id)\n ok++\n } catch (err) {\n failures.push({ email: a.email, error: (err as Error).message })\n }\n }\n\n // Sync local store with what's actually deleted.\n const deletedIds = new Set(\n targets.filter((t) => !failures.find((f) => f.email === t.email)).map((t) => t.id),\n )\n saveAccounts(loadAccounts().filter((a) => !deletedIds.has(a.id)))\n\n console.log(`Deleted ${ok}/${targets.length} test account(s).`)\n if (failures.length > 0) {\n console.error(`\\nFailed:`)\n for (const f of failures) console.error(` ${f.email}: ${f.error}`)\n process.exit(1)\n }\n },\n})\n\nexport default defineCommand({\n meta: {\n name: 'test-accounts',\n description: 'Manage test accounts for development',\n },\n subCommands: {\n create,\n list,\n delete: del,\n clear,\n },\n})\n","/**\n * deepspace deploy\n *\n * Builds the app with Vite (Cloudflare plugin bundles both client + worker),\n * then uploads to the deploy worker which handles Cloudflare WfP deployment.\n *\n * Uses the same build pipeline as dev for full fidelity. Reads the output\n * wrangler.json (via .wrangler/deploy/config.json) to find the built assets\n * and worker bundle — the same contract that `wrangler deploy` uses.\n */\n\nimport { defineCommand } from 'citty'\nimport { execSync } from 'node:child_process'\nimport { randomUUID } from 'node:crypto'\nimport { readFileSync, readdirSync, existsSync } from 'node:fs'\nimport { join, resolve, dirname } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport * as p from '@clack/prompts'\nimport { createSpinner } from '../lib/spinner'\nimport { ensureInstallReady } from '../lib/install-status'\nimport { preflightNodeVersion } from '../lib/preflight'\nimport { removeMacosJunk } from '../lib/macos-junk'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS, extractCustomDevVars, parseDevVars, writeDevVars } from '../env'\nimport { decodeJwtPayload } from '../jwt'\nimport {\n type PulledSecretsCache,\n refreshSecretsCache,\n stripGeneratedSecretsCache,\n} from '../lib/secrets'\nimport { mintAppId, readAppId, resolveOwnedAppId, writeAppId } from '../lib/app-identity'\nimport {\n bindingManifestFromOutputConfig,\n validateBindingManifest,\n RESERVED_BINDING_NAMES,\n} from '../../server/rooms/binding-manifest'\nimport {\n resolveAppNameForEnv,\n devVarsPathFor,\n readWranglerConfig,\n hasWranglerConfig,\n prepareWranglerEnvConfig,\n wranglerViteEnv,\n type PreparedWranglerEnvConfig,\n type WranglerConfig,\n} from '../lib/wrangler-env'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\n\nconst CLOUDFLARE_DEPLOY_ERROR_HINT =\n \"Deployment reached the DeepSpace deploy worker, but Cloudflare's deployment \" +\n 'control-plane API failed. This is often caused by a Cloudflare Dashboard/API ' +\n 'incident or Workers for Platforms entitlement outage. Already deployed apps ' +\n 'should keep serving; wait for Cloudflare to recover and retry.'\n\n/**\n * SDK-reserved `run_worker_first` prefixes. Apps can't override or\n * shadow these; only declare additional patterns. The CLI strips the\n * reserved ones before forwarding so the platform never sees them\n * twice — keeps the deploy-side merge a clean set-union.\n */\nconst RESERVED_RUN_WORKER_FIRST = new Set([\n '/api/*',\n '/ws/*',\n '/internal/*',\n '/v1/*',\n '/_deepspace/*',\n])\n\nfunction extractRunWorkerFirst(cfg: { assets?: { run_worker_first?: unknown } }): string[] {\n const raw = cfg.assets?.run_worker_first\n if (!Array.isArray(raw)) return []\n const out: string[] = []\n const seen = new Set<string>()\n for (const entry of raw) {\n if (typeof entry !== 'string') continue\n const trimmed = entry.trim()\n if (!trimmed.startsWith('/')) continue\n if (RESERVED_RUN_WORKER_FIRST.has(trimmed)) continue\n if (seen.has(trimmed)) continue\n seen.add(trimmed)\n out.push(trimmed)\n }\n return out\n}\n\n/** Extract a human-readable message from an unknown thrown value. */\nfunction errMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n\nfunction isLikelyCloudflareDeployFailure(status: number, error: string | undefined): boolean {\n if (status >= 500) return true\n if (!error) return false\n return [\n 'Upload session failed',\n 'Asset upload failed',\n 'Worker deploy failed',\n 'entitlements.not_available',\n 'Internal Server Error',\n ].some((needle) => error.includes(needle))\n}\n\nfunction formatDeployWorkerError(status: number, error: string | undefined): string {\n const detail = error ?? `Deployment error (${status})`\n if (!isLikelyCloudflareDeployFailure(status, error)) return detail\n return `${CLOUDFLARE_DEPLOY_ERROR_HINT}\\n\\nUnderlying error: ${detail}`\n}\n\n/**\n * Must stay <= the deploy worker's MAX_UPLOAD_GROUP_BYTES, otherwise the worker\n * rejects a group with a 413 that postWithRetry won't retry (it's a 4xx),\n * dead-ending the deploy. The DEEPSPACE_DEPLOY_GROUP_BYTES override is clamped\n * to this.\n */\nconst MAX_GROUP_BYTES = 40 * 1024 * 1024\n\n/**\n * Soft cap on the serialized size of one asset *group*. We pack whole asset\n * entries into groups under this size and POST each group on its own, so no\n * single request carries the entire payload (a ~40MB+ body stalls and gets\n * reset mid-upload on a marginal uplink: `write EPIPE`). A single asset larger\n * than this is sent alone in its own group — we never split an individual\n * asset. Overridable via DEEPSPACE_DEPLOY_GROUP_BYTES, clamped to MAX_GROUP_BYTES.\n */\nconst GROUP_BYTES = (() => {\n const raw = Number(process.env.DEEPSPACE_DEPLOY_GROUP_BYTES)\n const v = Number.isInteger(raw) && raw > 0 ? raw : 3 * 1024 * 1024\n return Math.min(v, MAX_GROUP_BYTES)\n})()\n\n/**\n * Decide how deploy should react to hand-edited `.dev.vars` secrets relative to\n * the store, which is the single source of truth for what a deploy ships.\n *\n * The dangerous case (see the secrets-source-of-truth work): the store ships\n * NOTHING but `.dev.vars` holds hand-edited secrets. Deploying then ships the\n * app with an empty secret set, replacing any secrets a previous deploy set —\n * silently dropping them from production. We block that (overridable with\n * `--allow-missing-secrets`) rather than only warning after the fact. When the\n * store already ships some secrets, extra local-only `.dev.vars` entries are a\n * benign warning (they're a local dev cache, not deploy config).\n *\n * Pure + exported for tests.\n */\nexport function classifyDevVarsSecrets(opts: {\n storeSecretNames: string[]\n handEditedDevVarKeys: string[]\n allowMissing: boolean\n}): { kind: 'ok' } | { kind: 'warn'; strayKeys: string[] } | { kind: 'block'; strayKeys: string[] } {\n const store = new Set(opts.storeSecretNames)\n const strayKeys = opts.handEditedDevVarKeys.filter((k) => !store.has(k))\n if (strayKeys.length === 0) return { kind: 'ok' }\n if (opts.storeSecretNames.length === 0 && !opts.allowMissing) return { kind: 'block', strayKeys }\n return { kind: 'warn', strayKeys }\n}\n\n/**\n * Pack whole asset entries into groups whose serialized JSON stays under\n * `maxBytes`. We never split an individual asset across groups, so a single\n * asset larger than `maxBytes` becomes its own (oversized) group.\n */\nexport function packAssetGroups<T>(assets: T[], maxBytes: number): T[][] {\n const groups: T[][] = []\n let current: T[] = []\n let currentBytes = 2 // \"[]\"\n for (const a of assets) {\n const entryBytes = Buffer.byteLength(JSON.stringify(a), 'utf-8') + 1 // +1 ≈ comma\n if (current.length > 0 && currentBytes + entryBytes > maxBytes) {\n groups.push(current)\n current = []\n currentBytes = 2\n }\n current.push(a)\n currentBytes += entryBytes\n }\n if (current.length > 0) groups.push(current)\n return groups\n}\n\n/**\n * POST with retry + backoff. Chunked upload exists to survive a flaky uplink,\n * so we always retry on network errors (fetch throws — e.g. `write EPIPE` when\n * the edge resets a stalled upload). Transient server statuses (408/429/5xx)\n * are only retried when `retryServerErrors` is set; client 4xx are always\n * returned as-is (caller surfaces the message). `makeInit` is called per\n * attempt so the request body is rebuilt fresh each time.\n *\n * The group-staging endpoint is an idempotent PUT, so retrying its 5xx is safe.\n * The commit endpoint runs a real (non-idempotent) deploy, so it passes\n * `retryServerErrors: false` — a 5xx means the server already received and\n * possibly acted on the request, and re-sending could double-deploy. Only a\n * thrown fetch (connection reset before/without a response) is retried there.\n */\nexport async function postWithRetry(\n url: string,\n makeInit: () => RequestInit,\n {\n attempts = 4,\n retryServerErrors = true,\n }: { attempts?: number; retryServerErrors?: boolean } = {},\n): Promise<Response> {\n let lastRes: Response | undefined\n let lastErr: unknown\n for (let attempt = 1; attempt <= attempts; attempt++) {\n try {\n const res = await fetch(url, makeInit())\n const isTransient =\n retryServerErrors && (res.status >= 500 || res.status === 408 || res.status === 429)\n if (!isTransient) {\n return res\n }\n lastRes = res\n } catch (err) {\n lastErr = err\n }\n if (attempt < attempts) {\n await new Promise((r) => setTimeout(r, Math.min(8_000, 500 * 2 ** (attempt - 1))))\n }\n }\n if (lastRes) return lastRes\n throw lastErr instanceof Error ? lastErr : new Error(String(lastErr))\n}\n\n/**\n * Best-effort cleanup of an upload's staged groups after a deploy gives up.\n * Fire-and-forget: a failed deploy must surface its real error, not a cleanup\n * error, so this never throws. It's not the only safety net either — the\n * deploy worker's R2 staging prefix carries a lifecycle rule that reaps\n * anything this misses (e.g. the CLI process is killed before it can abort).\n */\nasync function abortStagedUpload(\n appId: string,\n uploadId: string,\n totalGroups: number,\n token: string,\n): Promise<void> {\n try {\n await fetch(\n `${DEPLOY_URL}/api/deploy/${appId}/assets` +\n `?uploadId=${uploadId}&totalGroups=${totalGroups}`,\n { method: 'DELETE', headers: { Authorization: `Bearer ${token}` } },\n )\n } catch {\n // best-effort — orphaned groups are reaped by the staging lifecycle rule\n }\n}\n\nexport default defineCommand({\n meta: {\n name: 'deploy',\n description: 'Build and deploy your DeepSpace app',\n },\n args: {\n dir: {\n type: 'positional',\n description: 'App directory (default: current directory)',\n required: false,\n },\n env: {\n type: 'string',\n alias: 'e',\n description:\n 'wrangler.toml [env.<name>] block to deploy (e.g. --env staging). ' +\n 'Omit to deploy the top-level config.',\n required: false,\n },\n rename: {\n type: 'boolean',\n description:\n 'Confirm that a changed wrangler `name` renames this app (its URL moves; data, secrets, and collaborators travel). Without this flag an interactive prompt asks.',\n default: false,\n },\n 'allow-missing-secrets': {\n type: 'boolean',\n description:\n 'Deploy even though hand-edited .dev.vars secrets are absent from the store (they will NOT be deployed, and any a previous deploy set are dropped).',\n default: false,\n },\n },\n async run({ args }) {\n preflightNodeVersion('deploy')\n const appDir = resolve(args.dir ?? '.')\n const envName = typeof args.env === 'string' && args.env.trim() ? args.env.trim() : undefined\n\n // ── Read app name from wrangler.toml ──────────────────────\n if (!hasWranglerConfig(appDir)) {\n console.error('No wrangler.toml found. Are you in a DeepSpace app directory?')\n process.exit(1)\n }\n\n ensureInstallReady(appDir)\n\n p.intro('Deploying DeepSpace app')\n\n const wranglerConfig: WranglerConfig = readWranglerConfig(appDir)\n const nameRes = resolveAppNameForEnv(wranglerConfig, envName)\n if (!nameRes.ok) {\n p.cancel(nameRes.reason)\n process.exit(1)\n }\n // Refuse noncanonical names the same way `deepspace dev` does. Without\n // this, deploy would canonicalize server bindings while client constants\n // (`SCOPE_ID = app:${APP_NAME}`) and `[vars].APP_NAME` continued to use\n // the raw name — splitting identity across surfaces. Fail-fast so the\n // dev fixes wrangler.toml once and every surface reads from the same\n // source of truth.\n const declaredName = envName ? wranglerConfig.env?.[envName]?.name : wranglerConfig.name\n if (declaredName !== nameRes.name) {\n const where = envName ? `[env.${envName}].name` : '`name`'\n p.cancel(\n `wrangler.toml: ${where} \"${declaredName}\" is not in canonical form. ` +\n `Update it to \"${nameRes.name}\" and re-run.`,\n )\n process.exit(1)\n }\n const appName = nameRes.name\n\n // ── App identity ───────────────────────────────────────────\n // The immutable id is the deploy target; `name` is just the subdomain\n // label this deploy claims. A repo with no id yet gets one minted here\n // (first deploy registers it) — commit the wrangler.toml change.\n let appId = readAppId(appDir, envName)\n p.log.info(envName ? `App: ${appName} (env: ${envName})` : `App: ${appName}`)\n\n // ── Ensure valid JWT ───────────────────────────────────────\n let token: string\n let ownerId: string\n try {\n token = await ensureToken()\n ownerId = decodeJwtPayload<{ sub: string }>(token).sub\n } catch (err: unknown) {\n p.cancel(errMessage(err))\n process.exit(1)\n }\n\n // A repo with no id yet ADOPTS the caller's existing app for this subdomain\n // (e.g. a legacy app the platform registered during the app-identity\n // cutover) instead of minting a fresh id that would collide with the\n // existing route registration (\"name … is taken by another app\"). Only\n // mints when the caller owns nothing at this name. Needs the token, so it\n // runs after auth.\n if (!appId) {\n const adopted = await resolveOwnedAppId(DEPLOY_URL, token, appName)\n appId = adopted ?? mintAppId()\n writeAppId(appDir, appId, { wranglerEnv: envName })\n p.log.info(\n adopted\n ? `Adopted existing app id ${appId} for ${appName} — commit wrangler.toml.`\n : `Minted app id ${appId} — commit wrangler.toml.`,\n )\n }\n p.log.info(`Id: ${appId}`)\n\n // ── App secrets ────────────────────────────────────────────\n // Every app has one store (/api/secrets/:appId); the config shipped is\n // the wrangler env name, or 'prd' for the top-level config. No store or\n // config yet → deploy proceeds with no user secrets.\n // Reads only the hand-edited \"custom\" section of a .dev.vars file. We strip\n // the generated store cache first (extractCustomDevVars only drops SDK-managed\n // keys, not the GENERATED_SECRETS_DIVIDER block), mirroring writeDevVars — else\n // a stale cache entry (a just-deleted secret, or another config's secrets in\n // the shared .dev.vars) would masquerade as a hand-edited local-only var.\n const readCustomDevVarsAt = (path: string): Record<string, string> => {\n if (!existsSync(path)) return {}\n const section = extractCustomDevVars(stripGeneratedSecretsCache(readFileSync(path, 'utf-8')))\n if (!section) return {}\n try {\n return parseDevVars(section)\n } catch (err: unknown) {\n p.cancel(`.dev.vars: ${errMessage(err)}`)\n process.exit(1)\n }\n }\n\n let linkedSecrets: PulledSecretsCache | null = null\n // Hand-edited .dev.vars vars, snapshotted BEFORE the store refresh regenerates\n // the file — the refresh's writeDevVars overwrites the custom section with the\n // store's rendered cache, so reading afterwards would always come back empty.\n let localOnlyDevVars: Record<string, string> = {}\n try {\n const refreshed = await refreshSecretsCache(DEPLOY_URL, token, appId, envName)\n if (refreshed) {\n linkedSecrets = refreshed.pulled\n localOnlyDevVars = readCustomDevVarsAt(\n devVarsPathFor(appDir, envName, { sharedDevVarsCache: true }),\n )\n await writeDevVars(appDir, ownerId, token, envName, {\n appId,\n generatedSecretsCache: refreshed.rendered,\n sharedDevVarsCache: true,\n })\n p.log.info(refreshed.summary)\n }\n } catch (err: unknown) {\n // A 403 here means the caller isn't the owner/collaborator/admin — the\n // same gate deploy enforces. The secrets refresh just hits it first, so\n // present a clean authorization message (e.g. a revoked collaborator).\n const msg = errMessage(err)\n if ((err as { status?: number })?.status === 403) {\n p.cancel(\n \"You're not authorized to deploy this app — you must be its owner or a current \" +\n 'collaborator. If you were a collaborator, your access may have been revoked.',\n )\n } else {\n p.cancel(`Failed to refresh app secrets before deploy: ${msg}`)\n }\n process.exit(1)\n }\n\n // ── Build with Vite (Cloudflare plugin bundles client + worker) ──\n // When --env is set, pass Vite a generated config with that env already\n // flattened. This keeps Cloudflare from preferring stale `.dev.vars.<env>`\n // files over DeepSpace's shared `.dev.vars` cache.\n const junk = removeMacosJunk(appDir)\n if (junk > 0) p.log.info(`Removed ${junk} macOS metadata file(s) (._*, .DS_Store)`)\n\n const s = createSpinner()\n s.start('Building...')\n let preparedWranglerConfig: PreparedWranglerEnvConfig | undefined\n try {\n preparedWranglerConfig = prepareWranglerEnvConfig(appDir, envName, {\n sharedDevVarsCache: linkedSecrets !== null,\n })\n execSync('npx vite build', {\n cwd: appDir,\n stdio: 'pipe',\n env: wranglerViteEnv(process.env, preparedWranglerConfig),\n })\n } catch (err: unknown) {\n s.stop('Build failed')\n // Show both streams. Vite writes build errors to stderr, but the Rules of\n // Hooks checker (vite-plugin-checker) prints its diagnostics to stdout —\n // showing only stderr would collapse a hooks violation into a bare\n // \"Command failed\" and hide the exact fix the developer needs.\n const execErr = err as { stdout?: { toString(): string }; stderr?: { toString(): string } }\n const detail = [execErr.stdout?.toString(), execErr.stderr?.toString()]\n .filter(Boolean)\n .join('\\n')\n .trim()\n console.error(detail || errMessage(err))\n process.exit(1)\n } finally {\n preparedWranglerConfig?.cleanup()\n }\n s.stop('Built')\n\n // ── Locate build output via .wrangler/deploy/config.json ──\n // This is the same contract that `wrangler deploy` uses after `vite build`.\n const deployConfigPath = join(appDir, '.wrangler', 'deploy', 'config.json')\n if (!existsSync(deployConfigPath)) {\n p.cancel('Build output config not found at .wrangler/deploy/config.json')\n process.exit(1)\n }\n\n const deployConfig = JSON.parse(readFileSync(deployConfigPath, 'utf-8')) as {\n configPath: string\n }\n const outputWranglerPath = resolve(dirname(deployConfigPath), deployConfig.configPath)\n\n if (!existsSync(outputWranglerPath)) {\n p.cancel(`Output wrangler.json not found at ${outputWranglerPath}`)\n process.exit(1)\n }\n\n const outputConfig = JSON.parse(readFileSync(outputWranglerPath, 'utf-8')) as {\n name?: string\n main: string\n assets?: { directory: string }\n durable_objects?: { bindings: Array<{ name: string; class_name: string }> }\n migrations?: Array<{ new_sqlite_classes?: string[] }>\n }\n\n // Defense in depth: the deploy CLI sends `appName` as the registry\n // slot and Cloudflare Vite plugin bakes a `name` field into the\n // built wrangler.json. They MUST agree — if the generated env config\n // ever fails to apply, we'd otherwise ship one configuration's worker\n // bundle under another configuration's name.\n // Fail loudly before the upload starts.\n if (outputConfig.name && outputConfig.name !== appName) {\n const envHint = envName ? ` (--env ${envName})` : ''\n p.cancel(\n `Build output mismatch: expected name \"${appName}\"${envHint}, ` +\n `but the built wrangler.json declares \"${outputConfig.name}\". ` +\n `This usually means the Cloudflare Vite plugin didn't apply ` +\n `DeepSpace's generated env config. Check the plugin version and re-run.`,\n )\n process.exit(1)\n }\n\n const workerDir = dirname(outputWranglerPath)\n const workerBundlePath = join(workerDir, outputConfig.main)\n const clientDir = outputConfig.assets?.directory\n ? resolve(workerDir, outputConfig.assets.directory)\n : null\n\n if (!existsSync(workerBundlePath)) {\n p.cancel(`Worker bundle not found at ${workerBundlePath}`)\n process.exit(1)\n }\n if (!clientDir || !existsSync(clientDir)) {\n p.cancel(`Client assets not found at ${clientDir}`)\n process.exit(1)\n }\n\n // ── Collect assets ────────────────────────────────────────\n s.start('Collecting assets...')\n const assets = collectAssets(clientDir)\n s.stop(`Collected ${assets.length} assets`)\n\n const workerJs = readFileSync(workerBundlePath, 'utf-8')\n\n // ── Extract DO manifest from build output config ───────────\n const doBindings = outputConfig.durable_objects?.bindings as\n | Array<{ name: string; class_name: string }>\n | undefined\n const sqliteClasses = new Set(\n (outputConfig.migrations as Array<{ new_sqlite_classes?: string[] }> | undefined)?.flatMap(\n (m) => m.new_sqlite_classes ?? [],\n ) ?? [],\n )\n const doManifest = doBindings?.map((b) => ({\n binding: b.name,\n className: b.class_name,\n sqlite: sqliteClasses.has(b.class_name),\n }))\n if (doManifest?.length) {\n p.log.info(`DO manifest: ${doManifest.length} binding(s)`)\n }\n\n // ── Extract custom (non-DO) bindings: Vectorize, AI, R2, KV, D1, etc.\n const customBindings = bindingManifestFromOutputConfig(outputConfig)\n const validation = validateBindingManifest(customBindings)\n if (!validation.valid) {\n p.cancel(\n `Invalid binding(s) in wrangler.toml:\\n` +\n validation.errors.map((e) => ` • ${e.reason}`).join('\\n'),\n )\n process.exit(1)\n }\n if (customBindings.length) {\n p.log.info(\n `Custom bindings: ${customBindings.map((b) => `${b.name} (${b.type})`).join(', ')}`,\n )\n }\n\n // ── App secrets ─────────────────────────────────────────────────────\n const devVarsPath = devVarsPathFor(appDir, envName, {\n sharedDevVarsCache: linkedSecrets !== null,\n })\n // The remote secrets STORE is the single source of truth for what a deployed\n // app's env contains (docs/proposals/secrets-source-of-truth.md). `.dev.vars`\n // is a generated local dev cache — it is NEVER read to decide what ships.\n // Whether or not a store exists, deploy ships exactly the store's values; the\n // only thing we do with `.dev.vars` here is WARN when it holds secrets that\n // aren't in the store (so an edit-and-deploy doesn't silently do nothing).\n const userSecrets: Record<string, string> = linkedSecrets ? { ...linkedSecrets.values } : {}\n // Hand-edited `.dev.vars` secrets, for the warning only. When a store exists,\n // the refresh above already regenerated `.dev.vars` (wiping its custom\n // section), so use the snapshot taken before that write; with no store the\n // file was never regenerated this run, so read it fresh.\n const handEditedDevVars = linkedSecrets ? localOnlyDevVars : readCustomDevVarsAt(devVarsPath)\n const secretsDecision = classifyDevVarsSecrets({\n storeSecretNames: Object.keys(userSecrets),\n handEditedDevVarKeys: Object.keys(handEditedDevVars),\n allowMissing: Boolean(args['allow-missing-secrets']),\n })\n if (secretsDecision.kind === 'block') {\n // Store ships nothing but `.dev.vars` has hand-edited secrets: deploying\n // now would drop any secrets a previous deploy set. Stop, don't just warn.\n // `-e <env>` (not `-c`) so the upload targets the SAME env-specific app id\n // and config this deploy uses — `readAppId(appDir, envName)`. `-c` alone\n // would resolve the top-level app and upload to the wrong store.\n const uploadCmd = envName\n ? `deepspace secrets upload .dev.vars -e ${envName}`\n : 'deepspace secrets upload .dev.vars'\n const keys = secretsDecision.strayKeys.join(', ')\n p.cancel(\n `Refusing to deploy: the app store has no secrets, but .dev.vars has ${keys}.\\n` +\n 'Deploying now would ship the app with no secrets — replacing any a previous ' +\n 'deploy set (they would be dropped from production).\\n' +\n `Upload them to the store first:\\n ${uploadCmd}\\n` +\n 'then redeploy. (Pass --allow-missing-secrets to deploy without them.)',\n )\n process.exit(1)\n }\n if (secretsDecision.kind === 'warn') {\n const stray = secretsDecision.strayKeys\n p.log.warn(\n `.dev.vars has ${stray.join(', ')} not in the app store — ${stray.length === 1 ? 'it is' : 'they are'} NOT deployed. ` +\n '`.dev.vars` is a local dev cache, not deploy config. Move ' +\n `${stray.length === 1 ? 'it' : 'them'} into the store with ` +\n '`deepspace secrets set KEY=value` (or `deepspace secrets upload .dev.vars`), then redeploy.',\n )\n }\n const userSecretNames = Object.keys(userSecrets)\n\n // Pre-flight: fail clearly rather than letting the deploy-worker reject\n // mid-deploy. Reserved names are platform-owned (ASSETS, USAGE_EVENTS, …) —\n // `deepspace secrets` rejects them at write time, so this only trips on a\n // legacy store — and a secret colliding with a declared binding would\n // otherwise produce duplicate-name metadata that CF rejects opaquely.\n const declaredBindingNames = new Set([\n ...customBindings.map((b) => b.name),\n ...(doManifest ?? []).map((d) => d.binding),\n ])\n for (const name of userSecretNames) {\n if (RESERVED_BINDING_NAMES.has(name)) {\n p.cancel(\n `App secret \"${name}\" is a reserved binding name — remove it with \\`deepspace secrets delete ${name}\\`.`,\n )\n process.exit(1)\n }\n if (declaredBindingNames.has(name)) {\n p.cancel(\n `App secret \"${name}\" collides with a binding declared in wrangler.toml — rename one or the other.`,\n )\n process.exit(1)\n }\n }\n if (userSecretNames.length) {\n p.log.info(`App secrets: ${userSecretNames.join(', ')}`)\n }\n\n // ── Upload to deploy worker ───────────────────────────────\n s.start(`Deploying to ${appName}.app.space...`)\n\n // ── Forward custom worker-first asset routes ───────────────\n // CF Workers `[assets]` config supports a `run_worker_first` array\n // that wins over the SPA 404 fallback for matching paths. We always\n // reserve the SDK baseline (/api/*, /ws/*, /internal/*, /v1/*,\n // /_deepspace/*) on the platform side, but apps can declare extra\n // dynamic routes (e.g. /preview/*, /oauth/*, /.well-known/*) in\n // their wrangler.toml under `[assets] run_worker_first`. Pass those\n // through so the platform merges them into the deployed metadata.\n const extraRoutes = extractRunWorkerFirst(wranglerConfig)\n if (extraRoutes.length) {\n p.log.info(`Custom worker-first routes: ${extraRoutes.join(', ')}`)\n }\n\n // ── Choose transport: inline vs grouped ────────────────────\n // The assets array (base64-inlined file bytes) is the bulk of the upload.\n // Sending it all in one request stalls and gets reset mid-body on a\n // marginal uplink (`write EPIPE`). When it doesn't fit in a single group we\n // pack whole asset entries into groups under GROUP_BYTES, POST each group\n // on its own (retry-able) into the deploy worker's R2 staging, and\n // reference them by `uploadId` in the small commit request below. Small\n // deploys keep the original single-request inline transport.\n const assetGroups = packAssetGroups(assets, GROUP_BYTES)\n let inlineAssets: string | null = null\n let uploadId: string | null = null\n let totalGroups = 0\n if (assetGroups.length <= 1) {\n inlineAssets = JSON.stringify(assets)\n } else {\n uploadId = randomUUID()\n totalGroups = assetGroups.length\n try {\n for (let i = 0; i < totalGroups; i++) {\n const groupJson = JSON.stringify(assetGroups[i])\n s.message(`Uploading assets — group ${i + 1}/${totalGroups}...`)\n const groupRes = await postWithRetry(\n `${DEPLOY_URL}/api/deploy/${appId}/assets` +\n `?uploadId=${uploadId}&groupIndex=${i}&totalGroups=${totalGroups}`,\n () => ({\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: groupJson,\n }),\n )\n if (!groupRes.ok) {\n const errBody = (await groupRes.json().catch(() => ({}))) as { error?: string }\n // Reap the groups already staged for this upload before bailing —\n // a fresh deploy mints a new uploadId, so these would otherwise\n // never be reused.\n await abortStagedUpload(appId, uploadId, totalGroups, token)\n s.stop('Deploy failed')\n p.cancel(\n `Asset upload failed on group ${i + 1}/${totalGroups}: ` +\n `${errBody.error ?? `HTTP ${groupRes.status}`}`,\n )\n process.exit(1)\n }\n }\n } catch (err: unknown) {\n // postWithRetry exhausted its network-error retries and threw.\n await abortStagedUpload(appId, uploadId, totalGroups, token)\n s.stop('Deploy failed')\n p.cancel(`Asset upload failed (network): ${errMessage(err)}`)\n process.exit(1)\n }\n s.message(`Deploying to ${appName}.app.space...`)\n }\n\n const commitUrl = `${DEPLOY_URL}/api/deploy/${appId}`\n // Declared BEFORE makeForm — the closure reads it (TDZ trap otherwise).\n let confirmRename = args.rename === true\n\n // Every bail path must reap the staged groups (a re-run mints a new\n // uploadId, so the worker never reuses them) — one place owns that.\n const bailDeploy = async (message: string, stopLabel: string | null = 'Deploy failed'): Promise<never> => {\n if (uploadId) await abortStagedUpload(appId, uploadId, totalGroups, token)\n if (stopLabel !== null) s.stop(stopLabel)\n p.cancel(message)\n process.exit(1)\n }\n\n // Rebuilt per attempt so retried requests get a fresh body.\n const makeForm = (): FormData => {\n const form = new FormData()\n form.append('worker', new Blob([workerJs], { type: 'application/javascript' }), 'worker.js')\n if (inlineAssets !== null) {\n form.append('assets', inlineAssets)\n } else {\n form.append('uploadId', uploadId as string)\n form.append('totalGroups', String(totalGroups))\n }\n if (doManifest) {\n form.append('doManifest', JSON.stringify(doManifest))\n }\n if (customBindings.length) {\n form.append('bindingManifest', JSON.stringify(customBindings))\n }\n if (userSecretNames.length) {\n form.append('userSecrets', JSON.stringify(userSecrets))\n }\n // This CLI always ships the store's exact secret set (the refresh above\n // exits on failure), so tell the worker to delete live secrets we didn't\n // ship. Legacy CLIs never send this, keeping their deploys non-destructive.\n form.append('secretsAuthoritative', 'true')\n if (extraRoutes.length) {\n form.append('extraRunWorkerFirst', JSON.stringify(extraRoutes))\n }\n form.append('name', appName)\n if (confirmRename) form.append('confirmRename', 'true')\n return form\n }\n\n const postCommit = async (): Promise<Response> =>\n postWithRetry(\n commitUrl,\n () => ({\n method: 'POST',\n headers: { Authorization: `Bearer ${token}` },\n body: makeForm(),\n }),\n // Commit runs a real deploy — don't retry its 5xx (could double-deploy);\n // only a thrown fetch (dropped connection) is retried, and the staged\n // groups survive on the worker until this request succeeds.\n { retryServerErrors: false },\n )\n\n let res: Response\n try {\n res = await postCommit()\n } catch (err: unknown) {\n // The commit never got a response after its retries (dropped connection).\n await bailDeploy(`Deploy request failed: ${errMessage(err)}`)\n throw err // unreachable — bailDeploy exits\n }\n\n let body = (await res.json().catch(() => ({}))) as {\n success?: boolean\n url?: string\n error?: string\n code?: string\n fromHost?: string\n toHost?: string\n onBehalfOfOwner?: string\n }\n\n // A changed wrangler `name` is a RENAME of this app — never a silent\n // second app. Confirm interactively (or via --rename) and retry once.\n if (res.status === 409 && body.code === 'rename_required' && !confirmRename) {\n s.stop('Rename confirmation needed')\n // Piped/CI stdin: clack's confirm never resolves — the process would\n // drain its event loop and exit 0 having deployed nothing. Fail loudly\n // with the flag remedy instead.\n if (!process.stdin.isTTY) {\n await bailDeploy(\n `This deploy renames the app: ${body.fromHost} → ${body.toHost}. ` +\n 'Confirmation needs an interactive terminal — re-run with --rename to approve the ' +\n 'rename, or `deepspace init --new-id` if you meant a separate app.',\n null,\n )\n }\n const yes = await p.confirm({\n message:\n `This deploy renames the app: ${body.fromHost} → ${body.toHost}. ` +\n `The URL changes and the old one stops serving right away; data, secrets, and collaborators travel with it. ` +\n '(Meant a separate app? Run `deepspace init --new-id` instead.) Rename?',\n })\n if (p.isCancel(yes) || !yes) {\n await bailDeploy('Deploy cancelled.', null)\n }\n confirmRename = true\n s.start(`Deploying to ${appName}.app.space...`)\n res = await postCommit()\n body = (await res.json().catch(() => ({}))) as typeof body\n }\n\n if (!res.ok || !body.success) {\n await bailDeploy(formatDeployWorkerError(res.status, body.error))\n }\n\n // Deployed on behalf of another user: you're an admin or a collaborator on\n // their app. Say whose app it was; ownership is unchanged.\n if (body.onBehalfOfOwner) {\n p.log.warn(`Deployed on behalf of owner ${body.onBehalfOfOwner}`)\n }\n\n // ── Wait for assets propagation ───────────────────────────\n // Cloudflare's deploy API returns \"success\" once the script + bindings are\n // accepted, but the assets binding can still be indexing for ~10–60s.\n // During that window any request hits CF's transitional \"Assets have not\n // yet deployed\" page (HTML), even on `/api/*` routes that should run the\n // worker first. Block here until we see the worker actually serving so\n // CI / smoke checks that fire immediately don't hit the flake.\n if (body.url) {\n s.message('Waiting for edge propagation...')\n const ok = await waitForAssetsReady(body.url, 90_000)\n if (!ok) {\n s.stop('Deployed (edge propagation still in progress after 90s)')\n p.log.warn(\n 'First requests may briefly hit the assets transitional page; retry in a minute.',\n )\n p.log.success(`Live at: ${body.url}`)\n await syncSubscriptionPlans(appDir, appId, token)\n await syncOneTimeProducts(appDir, appId, token)\n p.outro('Done')\n return\n }\n }\n\n s.stop('Deployed!')\n p.log.success(`Live at: ${body.url}`)\n\n // ── Reconcile subscription plans + one-time products (optional files) ──\n // Each surfaces its own result inline but never fails the deploy — a\n // developer who hasn't finished Stripe Connect onboarding still gets a\n // working deploy; they just see a warning telling them to connect first.\n await syncSubscriptionPlans(appDir, appId, token)\n await syncOneTimeProducts(appDir, appId, token)\n\n p.outro('Done')\n },\n})\n\n/**\n * Bundle the app's `src/subscriptions.ts` with esbuild, dynamic-import the\n * resulting ESM, and POST the declarations to /api/subscriptions/sync.\n * No-op when the file is absent.\n */\nasync function syncSubscriptionPlans(\n appDir: string,\n appName: string,\n token: string,\n): Promise<void> {\n const subsPath = join(appDir, 'src', 'subscriptions.ts')\n if (!existsSync(subsPath)) return\n\n let plans: unknown\n try {\n const esbuild = await import('esbuild')\n const outDir = join(appDir, '.wrangler', 'deploy')\n const outFile = join(outDir, 'subscriptions.bundle.mjs')\n await esbuild.build({\n entryPoints: [subsPath],\n bundle: true,\n format: 'esm',\n platform: 'node',\n target: 'node18',\n outfile: outFile,\n logLevel: 'silent',\n write: true,\n })\n // Cache-bust the import so repeat deploys in the same Node process don't\n // reuse a stale module from the loader cache.\n const mod = (await import(`${pathToFileURL(outFile).href}?t=${Date.now()}`)) as {\n subscriptionPlans?: unknown\n }\n plans = mod.subscriptionPlans\n } catch (err: unknown) {\n p.log.warn(`Could not load src/subscriptions.ts: ${errMessage(err)}`)\n return\n }\n\n if (!Array.isArray(plans)) {\n p.log.warn('src/subscriptions.ts must `export const subscriptionPlans = [...] as const`')\n return\n }\n\n // The platform rejects an empty plan set (no_plans_declared), and an app with\n // no subscriptions has nothing to sync, so skip the request and stay quiet.\n // The moment a plan is declared the normal sync line and Connect warning\n // resume. Plans are removed by dropping them from a still-non-empty list; you\n // cannot reconcile down to zero plans.\n if (plans.length === 0) return\n\n const s = createSpinner()\n s.start('Syncing subscription plans...')\n\n // The deploy has already succeeded by the time we get here, so a network blip\n // or malformed response on /sync must not throw; anything unexpected becomes a\n // warning rather than a stack trace after the app is already live.\n let res: Response\n try {\n res = await fetch(`${API_URL}/api/subscriptions/sync`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ appId: appName, plans }),\n })\n } catch (err: unknown) {\n s.stop('Plan sync skipped')\n p.log.warn(`Plan sync request failed (network): ${errMessage(err)}`)\n return\n }\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean\n error?: string\n hint?: string\n onboardingUrl?: string\n planChanges?: PlanChange[]\n connectMissing?: boolean\n }\n\n if (res.ok && body.ok) {\n s.stop(`Synced ${plans.length} plan${plans.length === 1 ? '' : 's'} to Stripe`)\n // Connect-not-yet-set-up is no longer a sync-blocking error. Plans land\n // in Stripe normally; the warning tells the developer their earnings\n // will queue in the platform balance until they finish Stripe Connect\n // onboarding. Once they connect, the first payout sweeps everything.\n if (body.connectMissing) {\n p.log.warn(\n 'Stripe Connect not yet set up. Customers can subscribe and earnings ' +\n 'will queue in your platform balance until you finish onboarding at ' +\n '/earnings on the dashboard. The first payout after you connect ' +\n 'will sweep everything that accumulated in the meantime.',\n )\n }\n // Any plan change that stranded existing subscribers — whether the plan\n // was removed entirely or just had its price swapped — flows through one\n // prompt. The platform has no way to know whether the developer wants\n // those subscribers cancelled or grandfathered; this is the moment they\n // get to decide. Skipping is fine (silent grandfathering is the safe\n // default); they can always cancel later via the SDK helper.\n const changes = (body.planChanges ?? []).filter((c) => c.affectedSubscribers > 0)\n if (changes.length > 0) {\n await promptAndCancelChangedPlans(appName, token, changes)\n }\n return\n }\n\n s?.stop('Plan sync skipped')\n p.log.warn(\n `Plan sync failed: ${body.error ?? `HTTP ${res.status}`}${body.hint ? ` — ${body.hint}` : ''}`,\n )\n}\n\n// Plan-change events the deploy CLI surfaces to the developer. Mirrors the\n// /sync response shape on the platform side; kept inline here so the helper\n// is self-contained.\ninterface PlanChange {\n slug: string\n reason: 'removed' | 'repriced'\n affectedSubscribers: number\n intervals?: Array<{ interval: 'month' | 'year'; oldCents: number; newCents: number }>\n}\n\nfunction formatCents(c: number): string {\n return c === 0 ? 'free' : `$${(c / 100).toFixed(2)}`\n}\n\nfunction summaryLine(c: PlanChange): string {\n const n = c.affectedSubscribers\n const suffix = `${n} subscriber${n === 1 ? '' : 's'}`\n if (c.reason === 'removed') {\n return ` • ${c.slug} — removed (${suffix} still on it)`\n }\n // repriced: include the interval diffs for context.\n const diffs = (c.intervals ?? [])\n .map((i) => `${i.interval}: ${formatCents(i.oldCents)} → ${formatCents(i.newCents)}`)\n .join('; ')\n return ` • ${c.slug} — repriced (${diffs}; ${suffix} grandfathered on old price)`\n}\n\n/**\n * After /sync reports plans that stranded existing subscribers (removed\n * outright OR repriced with grandfathered customers), ask the developer\n * whether to cancel those subscriptions at the end of their current billing\n * period. Skipping is fine — they can run their own cleanup later via the\n * SDK's `cancelSubscription` helper.\n *\n * One yes/no prompt covers every affected plan. Granular per-plan control\n * is intentionally not surfaced; if a developer wants to cancel for plan A\n * but keep plan B, they can re-declare A in their next deploy.\n *\n * Errors here are warnings, never deploy failures: the deploy itself\n * succeeded; cleanup is the polite-but-optional tail.\n */\nasync function promptAndCancelChangedPlans(\n appName: string,\n token: string,\n changes: PlanChange[],\n): Promise<void> {\n const summary = changes.map(summaryLine).join('\\n')\n p.log.warn(\n `Plan change${changes.length === 1 ? '' : 's'} from this deploy left subscribers stranded:\\n${summary}\\n\\n` +\n 'Stripe will keep charging them until you cancel. Cancel at the end of their\\n' +\n 'current billing period? (Skip to leave them grandfathered.)',\n )\n const choice = await p.confirm({\n message: `Cancel ${changes.length === 1 ? 'these subscribers' : 'all of them'} at period end?`,\n initialValue: false,\n })\n if (p.isCancel(choice) || !choice) {\n p.log.info('Skipped — existing subscribers stay on their current plan/price.')\n return\n }\n\n // The admin-cancel endpoint batches at 50 and returns `hasMore` when there\n // are more rows to process. Loop until done so a plan with hundreds of\n // stranded subscribers gets fully cleaned up — without this, the deploy\n // prompt's confirmation (\"cancel these subscribers\") would silently leave\n // the tail being charged. The cap on iterations is a safety net for the\n // unlikely \"nothing makes progress\" path; a fresh deploy can resume.\n const MAX_ITERATIONS = 100 // 50/batch × 100 = 5000 subs/plan max per deploy\n for (const c of changes) {\n const s = createSpinner()\n s.start(\n `Canceling ${c.affectedSubscribers} subscriber${c.affectedSubscribers === 1 ? '' : 's'} on ${c.slug}...`,\n )\n let totalCanceled = 0\n let totalFailed = 0\n let iteration = 0\n let lastError: string | null = null\n let stopped = false\n try {\n while (iteration < MAX_ITERATIONS) {\n const res = await fetch(`${API_URL}/api/subscriptions/admin-cancel`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n appName,\n planSlug: c.slug,\n atPeriodEnd: true,\n reason: `plan ${c.reason} via deploy`,\n }),\n })\n const body = (await res.json().catch(() => ({}))) as {\n success?: boolean\n canceled?: number\n failures?: Array<{ stripeSubscriptionId: string; error: string }>\n hasMore?: boolean\n error?: string\n }\n if (!res.ok || !body.success) {\n // Genuine failure (auth, 5xx, etc.) — surface and stop. The empty-\n // match case returns 200 with hasMore=false, not an error, so this\n // branch only fires for real problems.\n lastError = body.error ?? `HTTP ${res.status}`\n s.stop(`Cancel failed for ${c.slug}: ${lastError}`)\n stopped = true\n break\n }\n const batchCanceled = body.canceled ?? 0\n totalCanceled += batchCanceled\n totalFailed += body.failures?.length ?? 0\n if (!body.hasMore) break\n // Progress guard: if a batch returned hasMore=true but canceled=0\n // (every row failed), we'd loop forever. Stop and report.\n if (batchCanceled === 0) {\n lastError = 'no progress (all rows failed this batch)'\n break\n }\n iteration++\n }\n if (!stopped) {\n const tail = totalFailed > 0 ? `; ${totalFailed} failed (see Stripe)` : ''\n const cap =\n iteration >= MAX_ITERATIONS\n ? ` (batch cap reached — re-run deploy to finish remaining)`\n : ''\n const errSuffix = lastError ? ` — ${lastError}` : ''\n s.stop(`Canceled ${totalCanceled} on ${c.slug}${tail}${cap}${errSuffix}`)\n }\n } catch (err: unknown) {\n s.stop(`Cancel failed for ${c.slug}: ${errMessage(err)}`)\n }\n }\n}\n\n/**\n * Bundle the app's `src/products.ts` with esbuild, dynamic-import the\n * resulting ESM, and POST the declarations to /api/charges/products/sync.\n * No-op when the file is absent. Mirrors syncSubscriptionPlans — products are\n * the one-time-charge equivalent of subscription plans, and the platform\n * resolves amount/name from this catalog at checkout time so the browser\n * can't pick (productId, amount) together.\n */\nasync function syncOneTimeProducts(appDir: string, appName: string, token: string): Promise<void> {\n const productsPath = join(appDir, 'src', 'products.ts')\n if (!existsSync(productsPath)) return\n\n let products: unknown\n try {\n const esbuild = await import('esbuild')\n const outDir = join(appDir, '.wrangler', 'deploy')\n const outFile = join(outDir, 'products.bundle.mjs')\n await esbuild.build({\n entryPoints: [productsPath],\n bundle: true,\n format: 'esm',\n platform: 'node',\n target: 'node18',\n outfile: outFile,\n logLevel: 'silent',\n write: true,\n })\n const mod = (await import(`${pathToFileURL(outFile).href}?t=${Date.now()}`)) as {\n oneTimeProducts?: unknown\n }\n products = mod.oneTimeProducts\n } catch (err: unknown) {\n p.log.warn(`Could not load src/products.ts: ${errMessage(err)}`)\n return\n }\n\n if (!Array.isArray(products)) {\n p.log.warn('src/products.ts must `export const oneTimeProducts = [...] as const`')\n return\n }\n\n // An empty catalog is the default for apps that don't sell one-time products.\n // Still reconcile it so emptying a previously-populated file deactivates the\n // dropped products, but skip the spinner and the \"Synced 0\" line so a\n // payment-free app isn't narrated on every deploy. Real failures still warn.\n const empty = products.length === 0\n const s = empty ? null : createSpinner()\n s?.start('Syncing one-time products...')\n\n // The deploy is already live by the time we get here, so network/parse\n // failures degrade to warnings rather than failing the deploy.\n let res: Response\n try {\n res = await fetch(`${API_URL}/api/charges/products/sync`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ appId: appName, products }),\n })\n } catch (err: unknown) {\n s?.stop('Product sync skipped')\n p.log.warn(`Product sync request failed (network): ${errMessage(err)}`)\n return\n }\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean\n count?: number\n error?: string\n details?: unknown\n }\n\n if (res.ok && body.ok) {\n if (s) {\n const n = body.count ?? products.length\n s.stop(`Synced ${n} one-time product${n === 1 ? '' : 's'}`)\n }\n return\n }\n\n s?.stop('Product sync skipped')\n p.log.warn(\n `Product sync failed: ${body.error ?? `HTTP ${res.status}`}${\n body.details ? ` — ${JSON.stringify(body.details)}` : ''\n }`,\n )\n}\n\n/**\n * Poll the deployed URL until it stops returning Cloudflare's\n * \"Assets have not yet deployed\" transitional page. Returns true when the\n * worker is actually serving, false on timeout.\n */\nasync function waitForAssetsReady(url: string, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs\n let attempt = 0\n while (Date.now() < deadline) {\n attempt++\n try {\n const res = await fetch(url, { redirect: 'manual' })\n const body = await res.text()\n // The transitional page is HTML with the literal phrase below. Any\n // other body — worker JSON, the app's index.html, even a 404 from the\n // worker's catch-all — means the deploy is live.\n if (!body.includes('Assets have not yet deployed')) {\n return true\n }\n } catch {\n // network blip — try again\n }\n // Exponential backoff capped at 8s: 1s → 2s → 4s → 8s → 8s …\n const wait = Math.min(8_000, 1_000 * 2 ** (attempt - 1))\n await new Promise((r) => setTimeout(r, wait))\n }\n return false\n}\n\nfunction collectAssets(dir: string): Array<{ path: string; contentBase64: string }> {\n const assets: Array<{ path: string; contentBase64: string }> = []\n function walk(d: string, prefix: string) {\n for (const entry of readdirSync(d, { withFileTypes: true })) {\n if (entry.name === '.assetsignore') continue\n const full = join(d, entry.name)\n const rel = prefix ? `${prefix}/${entry.name}` : entry.name\n if (entry.isDirectory()) {\n walk(full, rel)\n } else {\n assets.push({\n path: '/' + rel,\n contentBase64: readFileSync(full).toString('base64'),\n })\n }\n }\n }\n walk(dir, '')\n return assets\n}\n","/**\n * deepspace undeploy\n *\n * Removes a deployed app from *.app.space via the deploy worker.\n */\n\nimport { defineCommand } from 'citty'\nimport { readAppId } from '../lib/app-identity'\nimport * as p from '@clack/prompts'\nimport { createSpinner } from '../lib/spinner'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS } from '../env'\nimport { resolveAppSelector } from '../lib/app-context'\nimport { hasWranglerConfig } from '../lib/wrangler-env'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\nexport default defineCommand({\n meta: {\n name: 'undeploy',\n description: 'Remove a deployed DeepSpace app',\n },\n args: {\n name: {\n type: 'positional',\n description: 'App id or subdomain name to undeploy (reads DEEPSPACE_APP_ID from wrangler.toml if omitted)',\n required: false,\n },\n env: {\n type: 'string',\n description:\n 'wrangler.toml [env.<name>] block whose deployed app to remove ' +\n '(e.g. --env staging). Ignored if a positional name is given.',\n required: false,\n },\n },\n async run({ args }) {\n const envName = typeof args.env === 'string' && args.env.trim() ? args.env.trim() : undefined\n\n // Token first — resolving a subdomain name to its id needs the registry.\n let token: string\n try {\n token = await ensureToken()\n } catch (err: unknown) {\n p.cancel(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n\n // Target: an explicit positional — app id OR live subdomain name, resolved\n // via the registry (DEP-5) — else DEEPSPACE_APP_ID from wrangler.toml.\n let appId: string | undefined\n const positional =\n typeof args.name === 'string' && args.name.trim() ? args.name.trim() : undefined\n if (positional) {\n try {\n appId = await resolveAppSelector(DEPLOY_URL, token, positional)\n } catch (err: unknown) {\n p.cancel(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n } else if (hasWranglerConfig(process.cwd())) {\n appId = readAppId(process.cwd(), envName) ?? undefined\n }\n if (!appId) {\n p.cancel('Provide an app id or subdomain name, or run from a DeepSpace app directory with a DEEPSPACE_APP_ID.')\n process.exit(1)\n }\n\n p.intro(`Undeploying ${appId}`)\n const s = createSpinner()\n s.start('Removing...')\n\n const res = await fetch(`${DEPLOY_URL}/api/deploy/${appId}`, {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${token}` },\n })\n\n const body = (await res.json().catch(() => ({}))) as {\n success?: boolean\n error?: string\n releasedHosts?: string[]\n }\n\n if (!res.ok || !body.success) {\n s.stop('Failed')\n p.cancel(body.error ?? `Undeploy error (${res.status})`)\n process.exit(1)\n }\n\n s.stop('Removed')\n const hosts = body.releasedHosts ?? []\n p.outro(\n hosts.length\n ? `${hosts.join(', ')} taken down. The app keeps its id — redeploy to bring it back.`\n : `App ${appId} taken down.`,\n )\n },\n})\n","/**\n * deepspace whoami\n *\n * Shows the currently logged-in user. Auto-refreshes the JWT if expired.\n *\n * Prints all the identity fields a developer cares about (email, name,\n * userId, issuer) so you don't have to peek into ~/.deepspace/token.\n * Also flags whether the session is for a test account (`@deepspace.test`\n * email), since that's a meaningful distinction for who can do what — see\n * docs/auth/dev-vs-test-accounts.md.\n *\n * `--json` emits a parseable single-line JSON object for scripts.\n */\n\nimport { defineCommand } from 'citty'\nimport { ensureToken } from '../auth'\nimport { DASHBOARD_URL } from '../env'\nimport { decodeJwtPayload } from '../jwt'\n\ninterface JwtPayload {\n sub?: string\n name?: string\n email?: string\n image?: string | null\n iss?: string\n iat?: number\n exp?: number\n}\n\nexport default defineCommand({\n meta: {\n name: 'whoami',\n description: 'Show the currently logged-in user',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Emit a single-line JSON object instead of human output',\n default: false,\n },\n },\n async run({ args }) {\n // A logged-out / malformed-session exit must honor --json so a consumer\n // parsing stdout gets a JSON error object, not a bare sentence, and both\n // paths exit non-zero (ONB-6).\n const failLoggedOut = (msg: string): never => {\n if (args.json) console.log(JSON.stringify({ loggedIn: false, error: msg }))\n else console.error(msg)\n process.exit(1)\n }\n\n // Definite-assignment: failLoggedOut() exits, so jwt is always set here.\n let jwt!: string\n try {\n jwt = await ensureToken()\n } catch (err: unknown) {\n failLoggedOut(err instanceof Error ? err.message : 'Not logged in. Run `deepspace login` first.')\n }\n\n // Definite-assignment: failLoggedOut() exits, so payload is always set here.\n let payload!: JwtPayload\n try {\n payload = decodeJwtPayload<JwtPayload>(jwt)\n } catch {\n failLoggedOut('Malformed session token. Run `deepspace login` again.')\n }\n\n const isTestAccount = !!payload.email?.endsWith('@deepspace.test')\n const accountType: 'developer' | 'test-account' | 'unknown' = isTestAccount\n ? 'test-account'\n : payload.email\n ? 'developer'\n : 'unknown'\n\n if (args.json) {\n console.log(JSON.stringify({\n loggedIn: true,\n name: payload.name ?? null,\n email: payload.email ?? null,\n userId: payload.sub ?? null,\n accountType,\n issuer: payload.iss ?? null,\n expiresAt: payload.exp ? new Date(payload.exp * 1000).toISOString() : null,\n }))\n return\n }\n\n console.log(`Name: ${payload.name ?? '(none)'}`)\n console.log(`Email: ${payload.email ?? '(none)'}`)\n console.log(`UserID: ${payload.sub ?? '(none)'}`)\n console.log(`Type: ${accountType}`)\n if (payload.iss) console.log(`Issuer: ${payload.iss}`)\n console.log(`Dashboard: ${DASHBOARD_URL}`)\n if (isTestAccount) {\n console.log('')\n console.log('Note: this is a test account, not a real OAuth developer.')\n console.log('See docs/auth/dev-vs-test-accounts.md.')\n }\n },\n})\n","/**\n * deepspace apps\n *\n * Lists every app registered to the logged-in user — deployed or not — with\n * its id, live URL, and deploy state. This is the answer to \"which app do I\n * undeploy?\" when the deploy quota message names an id you've lost track of,\n * and the discovery surface for a second checkout / lost app dir.\n *\n * `--json` emits the raw entries for scripts.\n */\n\nimport { defineCommand } from 'citty'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS } from '../env'\nimport { apiFetch } from '../lib/api'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\ninterface AppEntry {\n appId: string\n status: string\n createdAt: string\n deployedAt: string | null\n /** Current subdomain lease; null when undeployed. */\n name: string | null\n url: string | null\n}\n\nexport default defineCommand({\n meta: {\n name: 'apps',\n description: 'List your apps (deployed and registered)',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Emit JSON instead of human output',\n default: false,\n },\n },\n async run({ args }) {\n const token = await ensureToken()\n const { apps } = await apiFetch<{ apps: AppEntry[] }>(DEPLOY_URL, token, '/api/apps')\n\n if (args.json) {\n process.stdout.write(JSON.stringify(apps, null, 2) + '\\n')\n return\n }\n if (!apps.length) {\n console.log('No apps yet. Create one with `npx create-deepspace <name>` and `deepspace deploy`.')\n return\n }\n\n const nameWidth = Math.max(4, ...apps.map((a) => (a.name ?? '—').length))\n const idWidth = Math.max(6, ...apps.map((a) => a.appId.length))\n console.log(`${'NAME'.padEnd(nameWidth)} ${'APP ID'.padEnd(idWidth)} URL`)\n for (const a of apps) {\n const url = a.url ?? '(not deployed)'\n console.log(`${(a.name ?? '—').padEnd(nameWidth)} ${a.appId.padEnd(idWidth)} ${url}`)\n }\n },\n})\n","/**\n * deepspace add <feature> [dir]\n *\n * Installs a DeepSpace feature into the current app.\n *\n * deepspace add --list # list available features\n * deepspace add messaging # install into current dir\n * deepspace add messaging ./my-app # install into specific dir\n * deepspace add --info messaging # show feature details\n */\n\nimport { defineCommand } from 'citty'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { resolve, join, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { spawnSync } from 'node:child_process'\nimport { ensureInstallReady } from '../lib/install-status'\n\nfunction findScript(from: string): string | null {\n // Preferred: ships inside the deepspace npm package at\n // node_modules/deepspace/scripts/add-feature.cjs, so the script and its\n // sibling features/ dir are delivered by `npm install`.\n const inNodeModules = join(from, 'node_modules', 'deepspace', 'scripts', 'add-feature.cjs')\n if (existsSync(inNodeModules)) return inNodeModules\n // Fallback for apps scaffolded before features moved into the SDK; their\n // .deepspace/ folder still works with newer deepspace versions.\n const inDotDeepspace = join(from, '.deepspace', 'scripts', 'add-feature.cjs')\n if (existsSync(inDotDeepspace)) return inDotDeepspace\n return null\n}\n\n/**\n * The installer + its sibling features/ dir that ship inside THIS running\n * deepspace package (the bin is dist/cli.js, so `..` is the package root and\n * scripts/ + features/ are its siblings via package.json \"files\"). Used for\n * catalog queries (--list / --info / help) so they work before the target app\n * has run `npm install`.\n */\nfunction runningScript(): string | null {\n const here = dirname(fileURLToPath(import.meta.url)) // <pkg>/dist\n const script = join(here, '..', 'scripts', 'add-feature.cjs')\n return existsSync(script) ? script : null\n}\n\n/**\n * A DeepSpace app has a wrangler.toml (workers config) or declares `deepspace`\n * as a dependency. A bare/unrelated directory has neither — installing a\n * feature there would just scatter files, so we redirect to `deepspace create`.\n */\nexport function isDeepSpaceApp(dir: string): boolean {\n if (existsSync(join(dir, 'wrangler.toml'))) return true\n const pkgPath = join(dir, 'package.json')\n if (!existsSync(pkgPath)) return false\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n return Boolean(pkg.dependencies?.deepspace || pkg.devDependencies?.deepspace)\n } catch {\n return false\n }\n}\n\n/** Run the .cjs installer with inherited stdio and exit with its status. */\nfunction runInstaller(script: string, passArgs: string[], cwd: string): never {\n const res = spawnSync(process.execPath, [script, ...passArgs], { stdio: 'inherit', cwd })\n if (res.error) {\n console.error(`Could not run the feature installer: ${res.error.message}`)\n process.exit(1)\n }\n process.exit(res.status ?? 1)\n}\n\nexport default defineCommand({\n meta: {\n name: 'add',\n description: 'Add a feature to your DeepSpace app',\n },\n args: {\n list: {\n type: 'boolean',\n alias: 'l',\n description: 'List available features',\n required: false,\n },\n info: {\n type: 'string',\n description: 'Show details about a feature',\n required: false,\n },\n install: {\n type: 'boolean',\n description: 'Run your package manager after adding dependencies',\n required: false,\n },\n feature: {\n type: 'positional',\n description: 'Feature to install',\n required: false,\n },\n dir: {\n type: 'positional',\n description: 'App directory (default: current directory)',\n required: false,\n },\n },\n run({ args }) {\n const appDir = resolve(args.dir ?? '.')\n\n // Catalog queries (--list / --info) and bare help never touch the target\n // app, so resolve the installer from THIS running deepspace package. This\n // lets `deepspace add --list` work before the app has run `npm install`.\n if (args.list || args.info || !args.feature) {\n const script = runningScript()\n if (!script) {\n console.error('Could not find the deepspace feature catalog.')\n console.error('Reinstall deepspace (`npm i -g deepspace`) or run inside a DeepSpace app.')\n process.exit(1)\n }\n const passArgs = args.list\n ? ['--list']\n : args.info\n ? ['--info', String(args.info)]\n : ['--help']\n runInstaller(script, passArgs, process.cwd())\n }\n\n // Install path: the feature is copied into the target app, so it must be a\n // real DeepSpace app with dependencies installed. Check both BEFORE\n // ensureInstallReady, whose \"Dependencies not installed\" message would\n // otherwise shadow the more useful \"not an app / no such dir\" guidance.\n if (!existsSync(appDir)) {\n console.error(`Target directory not found: ${appDir}`)\n console.error('Create a new app first: deepspace create <name>')\n process.exit(1)\n }\n if (!isDeepSpaceApp(appDir)) {\n console.error(`Not a DeepSpace app: ${appDir}`)\n console.error('(no wrangler.toml and no \"deepspace\" dependency found)')\n console.error('Create one with: deepspace create <name>')\n process.exit(1)\n }\n\n ensureInstallReady(appDir)\n const script = findScript(appDir)\n if (!script) {\n console.error('Could not find the deepspace feature installer.')\n console.error('Looked in:')\n console.error(` ${join(appDir, 'node_modules', 'deepspace', 'scripts', 'add-feature.cjs')}`)\n console.error(` ${join(appDir, '.deepspace', 'scripts', 'add-feature.cjs')}`)\n console.error('Are you in a DeepSpace app directory? Try `npm install` first.')\n process.exit(1)\n }\n\n const passArgs = [args.feature, appDir]\n if (args.install) passArgs.push('--install')\n runInstaller(script, passArgs, appDir)\n },\n})\n","/**\n * deepspace domain — purchase and manage custom domains for your apps.\n *\n * Designed to be both human-friendly and agent/script-friendly:\n * - All destructive commands accept `--yes` to skip prompts.\n * - All read commands accept `--json` for structured stdout.\n * - `--app` defaults to the cwd's wrangler.toml name (matches `deepspace deploy`).\n * - `domain buy` opens Stripe Checkout in a browser and polls until live;\n * pass `--no-open` to print the URL only, `--no-wait` to skip polling.\n *\n * Subcommands:\n * search <query> — find available domains and prices\n * buy <domain> — buy a domain via Stripe Checkout (browser)\n * list — list domains you own\n * status <domain> — detail view for one domain\n * attach <domain> — re-point a domain at a different app\n * detach <domain> — stop routing the domain (keeps registration)\n * renew <domain> --auto X — toggle auto-renew on/off at the registrar\n */\n\nimport { defineCommand } from 'citty'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS } from '../env'\nimport { apiFetch } from '../lib/api'\nimport { openBrowser } from '../lib/open-browser'\nimport { requireAppName, detectAppName } from '../lib/app-context'\n\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\n\ninterface SearchResult {\n name: string\n registrable: boolean\n registrar?: 'cloudflare' | 'namesilo'\n pricing?: { currency: string; registrationCost: string; renewalCost: string }\n registrationCost?: number\n renewalCost?: number\n chargedCents?: number | null\n costCents?: number | null\n reason?: string\n premium?: boolean\n}\n\ninterface DomainPurchase {\n id: string\n domain: string\n appName: string\n status: string\n statusError?: string | null\n registeredAt?: string | null\n expiresAt?: string | null\n chargedCents: number\n autoRenew: boolean\n registrar: string\n}\n\nconst api = <T>(token: string, path: string, init?: RequestInit): Promise<T> =>\n apiFetch<T>(API_URL, token, path, init)\n\n/**\n * Strip internal-only pricing fields from any value before emitting it to\n * stdout. The api-worker exposes both the user-facing `chargedCents` and the\n * platform's at-cost `costCents`; only the former should reach the CLI user.\n */\nfunction scrubInternal<T>(value: T): T {\n if (Array.isArray(value)) return value.map(scrubInternal) as unknown as T\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (k === 'costCents') continue\n out[k] = scrubInternal(v)\n }\n return out as T\n }\n return value\n}\n\nfunction fmtCents(cents: number | null | undefined): string {\n if (cents === null || cents === undefined) return '—'\n return `$${(cents / 100).toFixed(2)}`\n}\n\nfunction fmtDate(iso: string | null | undefined): string {\n if (!iso) return '—'\n return iso.slice(0, 10)\n}\n\n/**\n * Plain stdin Y/N prompt — no clack, agent can pipe `yes` or pass --yes.\n */\nasync function confirm(message: string): Promise<boolean> {\n if (!process.stdin.isTTY) {\n // Non-interactive (piped, agent) — refuse rather than hang\n throw new Error(`${message} — pass --yes to confirm non-interactively`)\n }\n process.stdout.write(`${message} [y/N] `)\n return new Promise((resolve) => {\n process.stdin.setEncoding('utf-8')\n process.stdin.once('data', (data) => {\n const answer = data.toString().trim().toLowerCase()\n resolve(answer === 'y' || answer === 'yes')\n })\n })\n}\n\n// ============================================================================\n// search\n// ============================================================================\n\nconst search = defineCommand({\n meta: { name: 'search', description: 'Search for available domains' },\n args: {\n query: { type: 'positional', description: 'Domain or keyword', required: true },\n limit: { type: 'string', description: 'Max results (default 10)', default: '10' },\n json: { type: 'boolean', description: 'Emit JSON instead of a table' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const limit = parseInt(args.limit ?? '10', 10) || 10\n const result = await api<{ domains: SearchResult[] }>(\n token,\n `/api/domains/search?q=${encodeURIComponent(args.query)}&limit=${limit}`,\n )\n if (args.json) {\n process.stdout.write(JSON.stringify(scrubInternal(result), null, 2) + '\\n')\n return\n }\n if (result.domains.length === 0) {\n console.log('No matches.')\n return\n }\n for (const d of result.domains) {\n const tag = d.registrable ? '✓' : '✗'\n const price = d.registrable ? `${fmtCents(d.chargedCents)}/yr` : (d.reason ?? '—')\n // Annotate slow-path TLDs so users have realistic expectations.\n const slowFlag =\n d.registrar && d.registrar !== 'cloudflare' ? ' (15-60 min provisioning)' : ''\n console.log(`${tag} ${d.name.padEnd(40)} ${price}${slowFlag}`)\n }\n },\n})\n\n// ============================================================================\n// buy\n// ============================================================================\n\nconst buy = defineCommand({\n meta: { name: 'buy', description: 'Buy a domain and attach it to an app' },\n args: {\n domain: { type: 'positional', description: 'Domain to buy', required: true },\n app: { type: 'string', description: 'App to attach (defaults to ./wrangler.toml)' },\n yes: { type: 'boolean', description: 'Skip the confirmation prompt', default: false },\n open: {\n type: 'boolean',\n description: 'Open browser at Stripe URL (use --no-open to print URL only)',\n default: true,\n },\n wait: {\n type: 'boolean',\n description:\n 'Poll until provisioning completes (use --no-wait to exit after session creation)',\n default: true,\n },\n json: { type: 'boolean', description: 'Emit JSON to stdout', default: false },\n },\n async run({ args }) {\n const token = await ensureToken()\n const appName = requireAppName(args.app)\n\n // Re-check pricing\n const priceCheck = await api<{ domains: SearchResult[] }>(token, '/api/domains/check', {\n method: 'POST',\n body: JSON.stringify({ domains: [args.domain] }),\n })\n const result = priceCheck.domains[0]\n if (!result || !result.registrable) {\n console.error(`Not available: ${result?.reason ?? 'unknown'}`)\n process.exit(1)\n }\n\n const price = fmtCents(result.chargedCents)\n // Provisioning time depends on registrar:\n // CF Registrar (.com/.dev/.app/.xyz/etc): ~60-90s — registry publishes\n // CF nameservers atomically with registration.\n // Porkbun fallback (.ai/.io/.me/.co/etc + ccTLDs): 15-60 min — depends\n // on the destination registry (Verisign/.me, NIC.AI, etc) batch-\n // publishing our NS records to public DNS. The platform side is\n // done in <30s; the wait is registry-side.\n const expectedTime =\n result.registrar === 'cloudflare'\n ? '~60-90 seconds'\n : '15-60 minutes (registry NS propagation)'\n\n if (!args.yes) {\n const ok = await confirm(\n `Buy ${args.domain} for ${price}/yr (auto-renews; non-refundable), attach to ${appName}? Provisioning takes ${expectedTime}.`,\n )\n if (!ok) {\n console.log('Cancelled.')\n return\n }\n }\n\n const checkout = await api<{\n purchaseId: string\n sessionId: string\n url: string\n chargedCents: number\n }>(token, '/api/domains/checkout', {\n method: 'POST',\n body: JSON.stringify({ domain: args.domain, appId: appName }),\n })\n\n if (args.json) {\n process.stdout.write(\n JSON.stringify(\n scrubInternal({ ...checkout, expectedTime, registrar: result.registrar }),\n null,\n 2,\n ) + '\\n',\n )\n } else {\n console.log(`Stripe Checkout: ${checkout.url}`)\n }\n\n if (args.open && process.stdin.isTTY) {\n openBrowser(checkout.url)\n }\n\n if (!args.wait) return\n\n // Poll until active or failed.\n // Timeout depends on registrar — CF can take 5 min worst case, Porkbun\n // up to 60 min for slow registries. User can Ctrl-C and resume polling\n // later via `deepspace domain status <domain>` — provisioning runs\n // server-side regardless.\n const timeoutMs = result.registrar === 'cloudflare' ? 5 * 60 * 1000 : 60 * 60 * 1000\n if (!args.json) {\n console.log(\n `Waiting for payment & provisioning (up to ${expectedTime}). Press Ctrl-C anytime —`,\n )\n console.log(\n `provisioning continues server-side; check later with \\`deepspace domain status ${args.domain}\\`.`,\n )\n }\n const deadline = Date.now() + timeoutMs\n let lastStatus = ''\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, 5000))\n try {\n const detail = await api<{ domain: DomainPurchase }>(\n token,\n `/api/domains/${checkout.purchaseId}`,\n )\n if (detail.domain.status !== lastStatus) {\n lastStatus = detail.domain.status\n if (!args.json) console.log(` → ${lastStatus}`)\n }\n if (detail.domain.status === 'active') {\n if (args.json) {\n process.stdout.write(\n JSON.stringify(\n scrubInternal({ ...checkout, status: 'active', domain: args.domain }),\n null,\n 2,\n ) + '\\n',\n )\n } else {\n console.log(`✓ ${args.domain} is live and pointing at ${appName}`)\n }\n return\n }\n if (detail.domain.status.startsWith('failed:')) {\n console.error(`Provisioning failed: ${detail.domain.statusError ?? detail.domain.status}`)\n process.exit(1)\n }\n } catch (err) {\n // Transient — keep polling\n if (!args.json)\n console.error(`(poll error: ${err instanceof Error ? err.message : String(err)})`)\n }\n }\n console.error(`Polling timed out. Provisioning may still be in progress; check with:`)\n console.error(` deepspace domain status ${args.domain}`)\n process.exit(1)\n },\n})\n\n// ============================================================================\n// list\n// ============================================================================\n\nconst list = defineCommand({\n meta: { name: 'list', description: 'List your domains' },\n args: {\n json: { type: 'boolean', description: 'Emit JSON' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const result = await api<{ domains: DomainPurchase[] }>(token, '/api/domains')\n if (args.json) {\n process.stdout.write(JSON.stringify(scrubInternal(result), null, 2) + '\\n')\n return\n }\n if (result.domains.length === 0) {\n console.log('No domains. Try `deepspace domain search <name>`.')\n return\n }\n console.log(\n `DOMAIN APP STATUS EXPIRES AUTO-RENEW`,\n )\n for (const d of result.domains) {\n console.log(\n `${d.domain.padEnd(35)} ${d.appName.padEnd(20)} ${d.status.padEnd(20)} ${fmtDate(d.expiresAt).padEnd(12)} ${d.autoRenew ? 'on' : 'off'}`,\n )\n }\n },\n})\n\n// ============================================================================\n// status\n// ============================================================================\n\nconst status = defineCommand({\n meta: { name: 'status', description: 'Show details for one domain' },\n args: {\n domain: { type: 'positional', description: 'Domain', required: true },\n json: { type: 'boolean' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const all = await api<{ domains: DomainPurchase[] }>(token, '/api/domains')\n const found = all.domains.find((d) => d.domain === args.domain)\n if (!found) {\n console.error(`No domain ${args.domain} in your account`)\n process.exit(1)\n }\n if (args.json) {\n process.stdout.write(JSON.stringify(scrubInternal(found), null, 2) + '\\n')\n return\n }\n console.log(`Domain: ${found.domain}`)\n console.log(\n `Status: ${found.status}${found.statusError ? ` (${found.statusError})` : ''}`,\n )\n console.log(`Attached app: ${found.appName}`)\n console.log(`Registrar: ${found.registrar}`)\n console.log(`Registered: ${fmtDate(found.registeredAt)}`)\n console.log(`Expires: ${fmtDate(found.expiresAt)}`)\n console.log(`Auto-renew: ${found.autoRenew ? 'on' : 'off'}`)\n console.log(`Charged: ${fmtCents(found.chargedCents)}/yr`)\n },\n})\n\n// ============================================================================\n// attach\n// ============================================================================\n\nconst attach = defineCommand({\n meta: { name: 'attach', description: 'Re-point a domain at a different app' },\n args: {\n domain: { type: 'positional', description: 'Domain to re-point', required: true },\n app: { type: 'string', description: 'Target app (defaults to ./wrangler.toml)' },\n json: { type: 'boolean' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const targetApp = requireAppName(args.app)\n const all = await api<{ domains: DomainPurchase[] }>(token, '/api/domains')\n const found = all.domains.find((d) => d.domain === args.domain)\n if (!found) {\n console.error(`No domain ${args.domain} in your account`)\n process.exit(1)\n }\n const result = await api<{ success: boolean; appName: string }>(\n token,\n `/api/domains/${found.id}/reattach`,\n {\n method: 'POST',\n body: JSON.stringify({ appId: targetApp }),\n },\n )\n if (args.json) {\n process.stdout.write(JSON.stringify(result, null, 2) + '\\n')\n return\n }\n console.log(`✓ ${args.domain} now points at ${targetApp}`)\n },\n})\n\n// ============================================================================\n// detach\n// ============================================================================\n\nconst detach = defineCommand({\n meta: {\n name: 'detach',\n description: 'Stop routing the domain (keeps the registration; auto-renew unchanged)',\n },\n args: {\n domain: { type: 'positional', description: 'Domain to detach', required: true },\n yes: { type: 'boolean', description: 'Skip the confirmation prompt' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const all = await api<{ domains: DomainPurchase[] }>(token, '/api/domains')\n const found = all.domains.find((d) => d.domain === args.domain)\n if (!found) {\n console.error(`No domain ${args.domain} in your account`)\n process.exit(1)\n }\n if (!args.yes) {\n const ok = await confirm(\n `Detach ${args.domain}? Routing will stop; the domain stays registered (auto-renew is unchanged).`,\n )\n if (!ok) {\n console.log('Cancelled.')\n return\n }\n }\n await api(token, `/api/domains/${found.id}`, { method: 'DELETE' })\n console.log(\n `✓ ${args.domain} detached. Use \\`deepspace domain attach\\` to re-route, or \\`renew --auto off\\` to stop auto-renewal.`,\n )\n },\n})\n\n// ============================================================================\n// renew\n// ============================================================================\n\nconst renew = defineCommand({\n meta: { name: 'renew', description: 'Toggle auto-renewal at the registrar' },\n args: {\n domain: { type: 'positional', description: 'Domain', required: true },\n auto: { type: 'string', description: '\"on\" or \"off\"', required: true },\n },\n async run({ args }) {\n if (args.auto !== 'on' && args.auto !== 'off') {\n console.error('--auto must be \"on\" or \"off\"')\n process.exit(1)\n }\n const token = await ensureToken()\n const all = await api<{ domains: DomainPurchase[] }>(token, '/api/domains')\n const found = all.domains.find((d) => d.domain === args.domain)\n if (!found) {\n console.error(`No domain ${args.domain} in your account`)\n process.exit(1)\n }\n const enabled = args.auto === 'on'\n await api(token, `/api/domains/${found.id}/auto-renew`, {\n method: 'POST',\n body: JSON.stringify({ autoRenew: enabled }),\n })\n console.log(`✓ ${args.domain} auto-renew ${enabled ? 'enabled' : 'disabled'}`)\n },\n})\n\n// ============================================================================\n// Top-level\n// ============================================================================\n\n// Note: no `run()` on the parent — citty otherwise calls it after every\n// subcommand finishes, which prints spurious help text.\n//\n// `detectAppName` is imported for type-checking the `--app` defaulting in\n// each subcommand; not used here directly.\nvoid detectAppName\n\nexport default defineCommand({\n meta: { name: 'domain', description: 'Buy and manage custom domains' },\n subCommands: { search, buy, list, status, attach, detach, renew },\n})\n","/**\n * Manage app collaborators: users you authorize to deploy your app on your\n * behalf. A collaborator just runs `deepspace deploy`; the deploy keeps your\n * identity and billing. Collaborators have owner-equivalent deploy access, so\n * only add people you trust.\n */\n\nimport { defineCommand } from 'citty'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS } from '../env'\nimport { resolveAppTarget } from '../lib/app-context'\nimport { apiFetch } from '../lib/api'\nimport { isTestAccountEmail } from '../../server/auth/testAccounts'\n\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\ninterface Collaborator {\n userId: string\n emailDisplay: string\n createdAt: string | number\n}\n\nfunction api<T>(token: string, path: string, init?: RequestInit): Promise<T> {\n return apiFetch<T>(API_URL, token, path, init)\n}\n\nconst list = defineCommand({\n meta: { name: 'list', description: 'List collaborators on your app' },\n args: {\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n json: { type: 'boolean', description: 'Emit JSON' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n const { collaborators } = await api<{ collaborators: Collaborator[] }>(\n token,\n `/api/app-collaborators/${encodeURIComponent(app)}`,\n )\n if (args.json) {\n process.stdout.write(JSON.stringify(collaborators, null, 2) + '\\n')\n return\n }\n if (!collaborators.length) {\n console.log(`No collaborators on ${app}. Add one with \\`deepspace collaborators add <email>\\`.`)\n return\n }\n // COL-4: print a header and the resolved email (emailDisplay). The raw\n // userId is dropped from the human view — it's still in --json, a human\n // reads the email, and `collaborators remove <email>` matches on it.\n console.log(`COLLABORATORS ON ${app}`)\n for (const c of collaborators) {\n console.log(` ${c.emailDisplay}`)\n }\n },\n})\n\nconst add = defineCommand({\n meta: { name: 'add', description: 'Authorize a DeepSpace user to deploy your app' },\n args: {\n email: {\n type: 'positional',\n description: 'Collaborator email (must already be a DeepSpace user)',\n required: true,\n },\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n json: { type: 'boolean', description: 'Emit JSON' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n if (isTestAccountEmail(args.email)) {\n console.error(\n 'Test accounts (@deepspace.test) cannot be added as collaborators. Use a real DeepSpace account.',\n )\n process.exit(1)\n }\n // Failure slugs (user_not_found, test_account_cannot_be_collaborator, ...)\n // are translated centrally by wrapCommandErrors — just let them escape.\n const { collaborator } = await api<{ collaborator: Collaborator }>(\n token,\n `/api/app-collaborators/${encodeURIComponent(app)}`,\n { method: 'POST', body: JSON.stringify({ email: args.email }) },\n )\n if (args.json) {\n process.stdout.write(JSON.stringify(collaborator, null, 2) + '\\n')\n return\n }\n console.log(`✓ ${collaborator.emailDisplay} can now deploy ${app}`)\n },\n})\n\nconst remove = defineCommand({\n meta: { name: 'remove', description: 'Remove a collaborator from your app' },\n args: {\n email: { type: 'positional', description: 'Collaborator email', required: true },\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n json: { type: 'boolean', description: 'Emit JSON' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n const { collaborators } = await api<{ collaborators: Collaborator[] }>(\n token,\n `/api/app-collaborators/${encodeURIComponent(app)}`,\n )\n const target = args.email.trim().toLowerCase()\n const found = collaborators.find((c) => c.emailDisplay.toLowerCase() === target)\n if (!found) {\n console.error(`${args.email} is not a collaborator on ${app}`)\n process.exit(1)\n }\n await api(\n token,\n `/api/app-collaborators/${encodeURIComponent(app)}/${encodeURIComponent(found.userId)}`,\n { method: 'DELETE' },\n )\n if (args.json) {\n process.stdout.write(JSON.stringify({ removed: found }, null, 2) + '\\n')\n return\n }\n console.log(`✓ ${found.emailDisplay} can no longer deploy ${app}`)\n },\n})\n\n// No `run()` on the parent: citty otherwise cascades it after each subcommand,\n// printing spurious help text.\nexport default defineCommand({\n meta: { name: 'collaborators', description: 'Manage who can deploy your app' },\n subCommands: { list, add, remove },\n})\n","/**\n * Test-account identification, shared by every platform worker.\n *\n * Test accounts (created via `deepspace test-accounts`) are real Better Auth\n * users demarcated three ways, and a caller may present as any of them\n * depending on where the check runs:\n * - their email always ends with @deepspace.test (enforced at creation)\n * - their JWTs carry `isTestAccount: true` (minted by the auth-worker,\n * the source of truth)\n * - their billing profile's subscription tier is 'test' (mirrored by the\n * api-worker on every authenticated request)\n *\n * Gate anything a test account must not do with these helpers rather than\n * hand-rolled string comparisons, so the policy stays in one place. Prefer\n * checking the claim when a verified JWT is at hand, and the tier as the\n * fallback for persisted state that may outlive a claim (e.g. rows written\n * before a guard existed).\n */\n\nimport type { JwtClaims } from './types'\n\nexport const TEST_ACCOUNT_EMAIL_SUFFIX = '@deepspace.test'\n\n/** True when the email belongs to a test account (case-insensitive). */\nexport function isTestAccountEmail(email: string | null | undefined): boolean {\n return !!email && email.trim().toLowerCase().endsWith(TEST_ACCOUNT_EMAIL_SUFFIX)\n}\n\n/** True when verified JWT claims identify the caller as a test account. */\nexport function isTestAccountClaims(\n claims: JwtClaims | Record<string, unknown> | null | undefined,\n): boolean {\n return claims?.isTestAccount === true\n}\n\n/** True when a billing subscription tier marks a test account. */\nexport function isTestAccountTier(tier: string | null | undefined): boolean {\n return tier === 'test'\n}\n","/**\n * Transfer app ownership — the GitHub-style offer/accept handshake.\n *\n * `deepspace transfer offer <email>` creates (or replaces) a 7-day offer;\n * the recipient runs `deepspace transfer accept --app <appId>` to commit.\n * Acceptance flips the registry owner and re-tags the deployed script for\n * billing in the same call. Either party can `cancel`. Data, secrets, and\n * routes travel with the app — only the owner (and billing) changes.\n */\n\nimport { defineCommand } from 'citty'\nimport * as p from '@clack/prompts'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS } from '../env'\nimport { requireAppIdArg, resolveAppTarget } from '../lib/app-context'\nimport { apiFetch as api } from '../lib/api'\n\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\nconst offer = defineCommand({\n meta: { name: 'offer', description: 'Offer this app to another DeepSpace user' },\n args: {\n email: { type: 'positional', description: 'Recipient email', required: true },\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n replace: {\n type: 'boolean',\n description: 'Replace a pending offer to someone else without asking',\n },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n\n // The server replaces a pending offer wholesale — a stray second `offer`\n // used to silently revoke the first with no signal to anyone, and the\n // original recipient's `accept` then failed with a mystery 404. Surface\n // the pending offer and make replacing it a deliberate choice.\n const pending = await api<{ transfer: { toEmailDisplay: string } | null }>(\n API_URL,\n token,\n `/api/app-transfers/${encodeURIComponent(app)}`,\n )\n const pendingTo = pending.transfer?.toEmailDisplay\n if (\n pendingTo &&\n pendingTo.toLowerCase() !== args.email.trim().toLowerCase() &&\n !args.replace\n ) {\n if (!process.stdin.isTTY) {\n console.error(\n `A pending offer to ${pendingTo} already exists for ${app}. ` +\n 'Re-run with --replace to replace it, or `deepspace transfer cancel` first.',\n )\n process.exit(1)\n }\n const yes = await p.confirm({\n message: `A pending offer to ${pendingTo} exists — replace it with ${args.email}?`,\n })\n if (p.isCancel(yes) || !yes) {\n console.log(`Kept the pending offer to ${pendingTo}.`)\n process.exit(1)\n }\n }\n\n const { expiresAt } = await api<{ toUserId: string; expiresAt: string }>(\n API_URL,\n token,\n `/api/app-transfers/${encodeURIComponent(app)}`,\n { method: 'POST', body: JSON.stringify({ email: args.email }) },\n )\n if (pendingTo && pendingTo.toLowerCase() !== args.email.trim().toLowerCase()) {\n console.log(`▲ Replaced the pending offer to ${pendingTo}.`)\n }\n console.log(\n `✓ Offered ${app} to ${args.email} (expires ${expiresAt}).\\n` +\n ` They accept with: deepspace transfer accept --app ${app}`,\n )\n },\n})\n\nconst status = defineCommand({\n meta: { name: 'status', description: 'Show the pending transfer offer, if any' },\n args: {\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n const { transfer } = await api<{\n transfer: { toEmailDisplay: string; expiresAt: string } | null\n }>(API_URL, token, `/api/app-transfers/${encodeURIComponent(app)}`)\n if (!transfer) {\n console.log(`No pending transfer for ${app}.`)\n return\n }\n console.log(`Pending: ${app} → ${transfer.toEmailDisplay} (expires ${transfer.expiresAt}).`)\n },\n})\n\nconst accept = defineCommand({\n meta: { name: 'accept', description: 'Accept a transfer offered to you' },\n args: {\n app: { type: 'string', alias: 'a', description: 'App id of the offered app', required: true },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = requireAppIdArg(args.app)\n await api(DEPLOY_URL, token, `/api/apps/${encodeURIComponent(app)}/transfer/accept`, {\n method: 'POST',\n })\n console.log(\n `✓ You now own ${app}. Run \\`deepspace init\\` in a fresh clone (or set ` +\n `DEEPSPACE_APP_ID = \"${app}\" in wrangler.toml) and deploy.`,\n )\n },\n})\n\nconst cancel = defineCommand({\n meta: { name: 'cancel', description: 'Cancel/decline the pending offer (either party)' },\n args: {\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n await api(API_URL, token, `/api/app-transfers/${encodeURIComponent(app)}`, { method: 'DELETE' })\n console.log(`✓ Transfer offer for ${app} cancelled.`)\n },\n})\n\n// No `run()` on the parent: citty otherwise cascades it after each subcommand.\nexport default defineCommand({\n meta: { name: 'transfer', description: 'Transfer app ownership to another user' },\n subCommands: { offer, status, accept, cancel },\n})\n","/**\n * deepspace integrations <subcommand>\n *\n * Namespace for working with platform integrations from the command line.\n *\n * deepspace integrations # prints help\n * deepspace integrations list # list all\n * deepspace integrations info openai/chat-completion # schema + example\n * deepspace integrations invoke openai/chat-completion --body '{...}'\n *\n * `deepspace invoke ...` is a top-level alias for `integrations invoke ...`.\n * `deepspace invoke --list` is a shortcut for `integrations list`.\n *\n * All calls are made as the currently logged-in user (`deepspace whoami`).\n * That user is billed.\n *\n * No `run()` is defined on the parent — that matches the convention used\n * by `test-accounts` and prevents citty from firing both the parent and\n * a matched subcommand. Bare `deepspace integrations` (no subcommand)\n * prints citty's auto-generated help.\n */\n\nimport { defineCommand } from 'citty'\nimport { runInvoke, runInfo, runList } from './_invoke-impl'\n\nconst list = defineCommand({\n meta: {\n name: 'list',\n description: 'List all available integrations',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Print raw JSON (machine-readable)',\n default: false,\n },\n },\n async run({ args }) {\n try {\n await runList({ json: args.json })\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n },\n})\n\nconst info = defineCommand({\n meta: {\n name: 'info',\n description: 'Print schema + example body for an integration endpoint',\n },\n args: {\n target: {\n type: 'positional',\n description: \"<integration>/<endpoint> (e.g. 'openai/chat-completion')\",\n required: true,\n },\n json: {\n type: 'boolean',\n description: 'Print raw JSON (machine-readable)',\n default: false,\n },\n },\n async run({ args }) {\n try {\n await runInfo({ target: args.target as string, json: args.json })\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n },\n})\n\nconst invoke = defineCommand({\n meta: {\n name: 'invoke',\n description: 'Invoke a platform integration as the logged-in user',\n },\n args: {\n target: {\n type: 'positional',\n description: \"<integration>/<endpoint> (e.g. 'openai/chat-completion')\",\n required: true,\n },\n body: {\n type: 'string',\n alias: 'd',\n description: 'Inline JSON body',\n required: false,\n },\n 'body-file': {\n type: 'string',\n alias: 'f',\n description: 'Read JSON body from file (use - for stdin)',\n required: false,\n },\n json: {\n type: 'boolean',\n description: 'Print only the response JSON (machine-readable)',\n default: false,\n },\n timeout: {\n type: 'string',\n description: 'Request timeout in milliseconds (default: 120000)',\n required: false,\n },\n yes: {\n type: 'boolean',\n alias: 'y',\n description: 'Skip the paid-call cost confirmation',\n default: false,\n },\n },\n async run({ args }) {\n try {\n const timeout = args.timeout != null ? Number(args.timeout) : undefined\n if (timeout != null && (!Number.isFinite(timeout) || timeout <= 0)) {\n throw new Error(`Invalid --timeout '${args.timeout}'. Must be a positive number of milliseconds.`)\n }\n await runInvoke({\n target: args.target as string,\n body: args.body,\n bodyFile: args['body-file'],\n json: args.json,\n timeout,\n yes: args.yes,\n })\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n },\n})\n\nexport default defineCommand({\n meta: {\n name: 'integrations',\n description: 'List, inspect, and invoke platform integrations',\n },\n subCommands: {\n list,\n info,\n invoke,\n },\n})\n","/**\n * Shared implementation for `deepspace invoke` and `deepspace integrations *`.\n *\n * The CLI invokes platform integrations as the currently logged-in user\n * (the same identity shown by `deepspace whoami`). That user is billed.\n *\n * This module is the single source of truth for:\n * - listing the integration catalog\n * - showing per-endpoint info (schema + example body)\n * - making the actual POST call\n *\n * Both `commands/invoke.ts` (top-level alias) and `commands/integrations.ts`\n * (namespaced subcommands) delegate here so the behavior never drifts.\n *\n * Why `flushAndExit` is used (only on the --json paths):\n * Large JSON outputs (the full catalog is ~78KB) exceed the OS pipe buffer,\n * and libuv flushes piped writes asynchronously — a plain `process.exit()`\n * would truncate stdout for any downstream consumer that JSON.parses it\n * (jq, file redirects, agent scripts, the e2e tests). So on the --json\n * paths we wait for stdout to drain before exiting. See flushAndExit().\n *\n * Human-mode paths don't need this: they return / process.exit() normally.\n */\n\nimport { readFileSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS } from '../env'\n\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\nconst DEFAULT_TIMEOUT_MS = 120_000\n\ninterface EndpointInfo {\n endpoint: string\n billing: { model: string; baseCost: number; currency: string }\n inputSchema: Record<string, unknown> | null\n example: Record<string, unknown> | null\n}\n\ninterface Catalog {\n integrations: Record<string, EndpointInfo[]>\n}\n\nexport interface InvokeArgs {\n target: string\n body?: string\n bodyFile?: string\n json?: boolean\n timeout?: number\n yes?: boolean\n}\n\nexport interface InfoArgs {\n target: string\n json?: boolean\n}\n\nexport interface ListArgs {\n json?: boolean\n}\n\n/**\n * Parse \"<integration>/<endpoint>\" into its two segments.\n * Throws on malformed input.\n */\nfunction parseTarget(target: string): { integration: string; endpoint: string } {\n if (!target || typeof target !== 'string') {\n throw new Error(\n \"Missing target. Expected '<integration>/<endpoint>' (e.g. 'openai/chat-completion').\",\n )\n }\n const parts = target.split('/')\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new Error(\n `Bad target '${target}'. Expected '<integration>/<endpoint>' (e.g. 'openai/chat-completion').`,\n )\n }\n return { integration: parts[0], endpoint: parts[1] }\n}\n\n/**\n * Resolve the request body from --body, --body-file, or default to '{}'.\n * Errors if both --body and --body-file are provided, or the body isn't\n * valid JSON.\n */\nfunction resolveBody(opts: { body?: string; bodyFile?: string }): string {\n if (opts.body != null && opts.bodyFile != null) {\n throw new Error('Pass either --body or --body-file, not both.')\n }\n\n let raw: string\n if (opts.body != null) {\n raw = opts.body\n } else if (opts.bodyFile != null) {\n raw = opts.bodyFile === '-' ? readFileSync(0, 'utf-8') : readFileSync(opts.bodyFile, 'utf-8')\n } else {\n return '{}'\n }\n\n // Validate it parses as JSON so we fail fast with a clear message.\n try {\n JSON.parse(raw)\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'invalid JSON'\n throw new Error(`Body is not valid JSON: ${msg}`)\n }\n return raw\n}\n\n/**\n * Exit the process after stdout has drained.\n *\n * Used only on --json paths. Plain `process.exit()` truncates piped stdout\n * for outputs larger than the pipe buffer (~64KB on macOS) —\n * `integrations --json | jq` would lose data because libuv flushes\n * asynchronously.\n *\n * The pattern: schedule a zero-byte write so its callback fires only\n * after all prior writes have been flushed, then exit from the callback.\n * Returns a Promise that never resolves so the caller can `await` it.\n */\nfunction flushAndExit(code: number): Promise<never> {\n return new Promise<never>(() => {\n process.stdout.write('', () => process.exit(code))\n })\n}\n\nasync function fetchCatalog(opts: { summary?: boolean } = {}): Promise<Catalog> {\n // `list` uses the summary view (names + billing); the full catalog with every\n // endpoint's schema is large enough to be truncated in an agent's terminal.\n // `info` omits the flag so it still gets the schema + example.\n const url = opts.summary ? `${API_URL}/api/integrations?summary=1` : `${API_URL}/api/integrations`\n const res = await fetch(url)\n if (!res.ok) {\n throw new Error(`Failed to fetch integration catalog (${res.status})`)\n }\n return (await res.json()) as Catalog\n}\n\nfunction findEndpoint(\n catalog: Catalog,\n integration: string,\n endpoint: string,\n): EndpointInfo | null {\n const endpoints = catalog.integrations[integration]\n if (!endpoints) return null\n return endpoints.find((e) => e.endpoint === endpoint) ?? null\n}\n\nfunction formatCurrency(value: number, currency: string): string {\n if (currency === 'USD') return `$${value}`\n return `${value} ${currency}`\n}\n\n/**\n * Human-readable billing unit for a pricing model. `per_token` → \"per token\",\n * `per_call` → \"per call\". Unknown/future models render their raw `per_*` shape\n * (\"per foo\") or pass through, so we never mislabel one mode as another (INT-1).\n */\nexport function billingUnit(model: string): string {\n if (model === 'per_token') return 'per token'\n if (model === 'per_call') return 'per call'\n return model.startsWith('per_') ? model.replace(/^per_/, 'per ').replace(/_/g, ' ') : model\n}\n\n/**\n * Interactive only when BOTH streams are TTYs: p.confirm reads stdin and draws\n * to stdout, so a piped stdin (`echo {} | invoke … --body-file -`) must never\n * reach the prompt — it would hang waiting for input that can't arrive. Pure so\n * the both-streams rule is testable.\n */\nexport function isInteractive(\n stdin: { isTTY?: boolean },\n stdout: { isTTY?: boolean },\n): boolean {\n return Boolean(stdin.isTTY && stdout.isTTY)\n}\n\n/**\n * Whether to confirm a paid invoke before firing it (FEAT-13). Only on an\n * interactive terminal, for a non-free endpoint, when the caller hasn't asked\n * for machine output (--json) or pre-approved (--yes). Pure for testing.\n */\nexport function shouldConfirmCost(opts: {\n json: boolean\n yes: boolean\n isTTY: boolean\n baseCost: number\n}): boolean {\n return !opts.json && !opts.yes && opts.isTTY && opts.baseCost > 0\n}\n\n/**\n * `deepspace integrations` (default action) / `--list`\n * Prints the catalog grouped by integration.\n */\nexport async function runList(args: ListArgs): Promise<void> {\n const catalog = await fetchCatalog({ summary: true })\n\n if (args.json) {\n process.stdout.write(JSON.stringify(catalog) + '\\n')\n await flushAndExit(0)\n }\n\n const names = Object.keys(catalog.integrations).sort()\n if (names.length === 0) {\n console.log('No integrations available.')\n return\n }\n\n for (const name of names) {\n console.log(name)\n const endpoints = [...catalog.integrations[name]].sort((a, b) =>\n a.endpoint.localeCompare(b.endpoint),\n )\n const widest = Math.max(...endpoints.map((e) => e.endpoint.length))\n for (const ep of endpoints) {\n const pad = ep.endpoint.padEnd(widest)\n const cost = formatCurrency(ep.billing.baseCost, ep.billing.currency)\n console.log(` ${pad} ${ep.billing.model.padEnd(12)} ${cost}`)\n }\n console.log()\n }\n\n console.log(\"Run 'deepspace integrations info <integration>/<endpoint>' for the request schema.\")\n}\n\n/**\n * `deepspace integrations info <target>` / `--info`\n * Prints the schema + example body for a single endpoint.\n */\nexport async function runInfo(args: InfoArgs): Promise<void> {\n const { integration, endpoint } = parseTarget(args.target)\n const catalog = await fetchCatalog()\n const info = findEndpoint(catalog, integration, endpoint)\n\n if (!info) {\n const available = catalog.integrations[integration]\n if (!available) {\n const names = Object.keys(catalog.integrations).sort().join(', ')\n throw new Error(`Unknown integration '${integration}'. Available: ${names}`)\n }\n const endpoints = available.map((e) => e.endpoint).join(', ')\n throw new Error(`Unknown endpoint '${endpoint}' for '${integration}'. Available: ${endpoints}`)\n }\n\n if (args.json) {\n process.stdout.write(JSON.stringify(info) + '\\n')\n await flushAndExit(0)\n }\n\n console.log(`${integration}/${endpoint}`)\n console.log(\n ` billing: ${formatCurrency(info.billing.baseCost, info.billing.currency)} ${billingUnit(info.billing.model)}`,\n )\n console.log()\n console.log('Input schema:')\n console.log(\n info.inputSchema ? JSON.stringify(info.inputSchema, null, 2) : ' (no schema registered)',\n )\n console.log()\n console.log('Example body:')\n console.log(info.example ? JSON.stringify(info.example, null, 2) : ' (no example available)')\n}\n\n/**\n * `deepspace invoke <target>` / `deepspace integrations invoke <target>`\n * Performs the actual integration call.\n */\nexport async function runInvoke(args: InvokeArgs): Promise<void> {\n const { integration, endpoint } = parseTarget(args.target)\n const body = resolveBody({ body: args.body, bodyFile: args.bodyFile })\n const timeoutMs = args.timeout ?? DEFAULT_TIMEOUT_MS\n\n // FEAT-13: this fires a PAID call billed to the logged-in user. On a fully\n // interactive terminal, confirm the cost first (unless --yes or --json).\n // Gate on BOTH streams: p.confirm reads stdin and draws to stdout, so a piped\n // stdin (e.g. `echo {} | deepspace invoke … --body-file -`) must never reach\n // the prompt — it would hang waiting for input that can't come.\n const interactive = isInteractive(process.stdin, process.stdout)\n if (!args.json && !args.yes && interactive) {\n let info: EndpointInfo | null = null\n try {\n info = findEndpoint(await fetchCatalog({ summary: true }), integration, endpoint)\n } catch {\n // Couldn't fetch billing — don't block the call, but say so, so a paid\n // call never fires completely silently. The POST still enforces\n // auth/existence and reports its own errors.\n console.error('Note: could not verify the call cost; proceeding. Pass --yes to skip this check.')\n info = null\n }\n if (\n info &&\n shouldConfirmCost({\n json: !!args.json,\n yes: !!args.yes,\n isTTY: interactive,\n baseCost: info.billing.baseCost,\n })\n ) {\n const cost = formatCurrency(info.billing.baseCost, info.billing.currency)\n const ok = await p.confirm({\n message: `${integration}/${endpoint} costs ${cost} ${billingUnit(info.billing.model)}, billed to your account. Continue?`,\n })\n if (p.isCancel(ok) || !ok) {\n p.cancel('Cancelled — no call made.')\n process.exit(0)\n }\n }\n }\n\n let jwt: string\n try {\n jwt = await ensureToken()\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n throw new Error(msg)\n }\n\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n const startedAt = Date.now()\n\n let res: Response\n try {\n res = await fetch(`${API_URL}/api/integrations/${integration}/${endpoint}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${jwt}`,\n },\n body,\n signal: controller.signal,\n })\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n throw new Error(`Request timed out after ${timeoutMs}ms`)\n }\n throw new Error(err instanceof Error ? err.message : 'Request failed')\n } finally {\n clearTimeout(timer)\n }\n\n const elapsed = Date.now() - startedAt\n let payload: Record<string, unknown>\n try {\n payload = (await res.json()) as Record<string, unknown>\n } catch {\n throw new Error(`Request failed (${res.status}) with non-JSON response`)\n }\n\n if (args.json) {\n process.stdout.write(JSON.stringify(payload) + '\\n')\n await flushAndExit(payload?.success === false || !res.ok ? 1 : 0)\n }\n\n const ok = payload?.success !== false && res.ok\n if (ok) {\n const data = 'data' in payload ? payload.data : payload\n console.log(JSON.stringify(data, null, 2))\n console.error(`\\n✓ ${integration}/${endpoint} (${elapsed}ms)`)\n return\n }\n\n // Error path\n const errMsg = (payload.error as string) ?? `Request failed (${res.status})`\n console.error(`✗ ${integration}/${endpoint} (${res.status}, ${elapsed}ms): ${errMsg}`)\n if (Array.isArray(payload.issues)) {\n for (const issue of payload.issues as Array<{ path?: string[]; message: string }>) {\n const path = issue.path?.length ? issue.path.join('.') : '(root)'\n console.error(` - ${path}: ${issue.message}`)\n }\n }\n if (res.status === 401) {\n console.error(\"\\nHint: run 'deepspace login' to authenticate.\")\n }\n process.exit(1)\n}\n","/**\n * deepspace invoke <integration>/<endpoint> [options]\n *\n * Top-level alias for `deepspace integrations invoke ...`. Calls a platform\n * integration as the currently logged-in user — the same identity shown by\n * `deepspace whoami`. That user is billed.\n *\n * deepspace invoke openai/chat-completion --body '{\"messages\":[...]}'\n * deepspace invoke openai/chat-completion --body-file req.json\n * cat req.json | deepspace invoke openai/chat-completion --body-file -\n * deepspace invoke openai/chat-completion --info\n * deepspace invoke --list\n */\n\nimport { defineCommand } from 'citty'\nimport { runInvoke, runInfo, runList } from './_invoke-impl'\n\nexport default defineCommand({\n meta: {\n name: 'invoke',\n description: 'Invoke a platform integration as the logged-in user',\n },\n args: {\n target: {\n type: 'positional',\n description: \"<integration>/<endpoint> (e.g. 'openai/chat-completion')\",\n required: false,\n },\n body: {\n type: 'string',\n alias: 'd',\n description: 'Inline JSON body',\n required: false,\n },\n 'body-file': {\n type: 'string',\n alias: 'f',\n description: 'Read JSON body from file (use - for stdin)',\n required: false,\n },\n json: {\n type: 'boolean',\n description: 'Print only the response JSON (machine-readable)',\n default: false,\n },\n info: {\n type: 'boolean',\n description: 'Print schema + example body for the endpoint, then exit',\n default: false,\n },\n list: {\n type: 'boolean',\n description: 'Print all available integrations, then exit',\n default: false,\n },\n timeout: {\n type: 'string',\n description: 'Request timeout in milliseconds (default: 120000)',\n required: false,\n },\n yes: {\n type: 'boolean',\n alias: 'y',\n description: 'Skip the paid-call cost confirmation',\n default: false,\n },\n },\n async run({ args }) {\n try {\n if (args.list) {\n await runList({ json: args.json })\n return\n }\n if (args.info) {\n await runInfo({ target: args.target as string, json: args.json })\n return\n }\n const timeout = args.timeout != null ? Number(args.timeout) : undefined\n if (timeout != null && (!Number.isFinite(timeout) || timeout <= 0)) {\n throw new Error(`Invalid --timeout '${args.timeout}'. Must be a positive number of milliseconds.`)\n }\n await runInvoke({\n target: args.target as string,\n body: args.body,\n bodyFile: args['body-file'],\n json: args.json,\n timeout,\n yes: args.yes,\n })\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n },\n})\n","/**\n * deepspace library [publish|unpublish] [options]\n *\n * Manage entries in the DeepSpace community library (lives at\n * deepdotspace-site.app.space by default; override with --library-app\n * or DEEPSPACE_LIBRARY_HOST). Subcommands POST to that app's\n * `library.publish` / `library.unpublish` actions as the currently\n * logged-in user.\n *\n * The publish action verifies the caller owns the deployed app (by\n * checking the deploy worker's `/api/apps` registry) before writing\n * the row, so publishing another user's app is rejected server-side.\n *\n * Usage:\n * deepspace library publish (uses wrangler.toml)\n * deepspace library publish --app my-cool-app --name \"My Cool App\"\n * deepspace library publish --description \"...\" --category Productivity\n * deepspace library publish --tags utility,ai --visibility unlisted\n * deepspace library unpublish <handle>\n */\n\nimport { defineCommand } from 'citty'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport { parse as parseToml } from 'smol-toml'\nimport * as p from '@clack/prompts'\n\nimport { ensureToken } from '../auth'\nimport { resolveAppName } from '../../server/rooms/app-name'\n\nconst DEFAULT_LIBRARY_APP = 'deepdotspace-site'\n\nconst publish = defineCommand({\n meta: {\n name: 'publish',\n description: 'Publish the current app to the DeepSpace library',\n },\n args: {\n dir: {\n type: 'string',\n description: 'App directory (default: current directory)',\n required: false,\n },\n app: {\n type: 'string',\n description: 'App name (default: read from wrangler.toml)',\n required: false,\n },\n name: {\n type: 'string',\n description: 'Display name (default: app name)',\n required: false,\n },\n description: {\n type: 'string',\n description: 'Short description',\n required: false,\n },\n category: {\n type: 'string',\n description: 'Category (e.g. Productivity, Finance, AI). Default: General',\n required: false,\n },\n tags: {\n type: 'string',\n description: 'Comma-separated tags',\n required: false,\n },\n visibility: {\n type: 'string',\n description: \"'public' (default), 'unlisted', or 'private'\",\n required: false,\n },\n screenshot: {\n type: 'string',\n description: 'Override the auto-captured preview with a public PNG URL',\n required: false,\n },\n 'library-app': {\n type: 'string',\n description: `Target library app subdomain (default: ${DEFAULT_LIBRARY_APP})`,\n required: false,\n },\n json: {\n type: 'boolean',\n description: 'Print only the JSON response (machine-readable)',\n default: false,\n },\n },\n async run({ args }) {\n const json = !!args.json\n const intro = (s: string) => { if (!json) p.intro(s) }\n const info = (s: string) => { if (!json) p.log.info(s) }\n const die = (msg: string) => {\n if (json) console.error(JSON.stringify({ ok: false, error: msg }))\n else p.cancel(msg)\n process.exit(1)\n }\n\n intro('Publishing to the DeepSpace library')\n\n let appName = typeof args.app === 'string' && args.app.trim() ? args.app.trim() : undefined\n if (!appName) {\n const appDir = resolve(typeof args.dir === 'string' && args.dir ? args.dir : '.')\n const wranglerPath = join(appDir, 'wrangler.toml')\n if (!existsSync(wranglerPath)) {\n return die(\"No --app provided and no wrangler.toml found. Either pass --app <name> or run from your app's directory.\")\n }\n const cfg = parseToml(readFileSync(wranglerPath, 'utf-8')) as { name?: string }\n const nameRes = resolveAppName(cfg.name)\n if (!nameRes.ok) return die(`wrangler.toml: ${nameRes.reason}`)\n appName = nameRes.name\n }\n info(`App: ${appName}`)\n\n const visibility = (args.visibility ?? 'public') as string\n if (!['public', 'private', 'unlisted'].includes(visibility)) {\n return die(\"--visibility must be 'public', 'unlisted', or 'private'.\")\n }\n\n const tags = typeof args.tags === 'string' && args.tags\n ? args.tags.split(',').map((t) => t.trim()).filter(Boolean)\n : undefined\n\n const libraryApp = typeof args['library-app'] === 'string' && args['library-app']\n ? args['library-app']\n : DEFAULT_LIBRARY_APP\n const libraryHost = process.env.DEEPSPACE_LIBRARY_HOST ?? `https://${libraryApp}.app.space`\n\n let token: string\n try {\n token = await ensureToken()\n } catch (err) {\n return die(err instanceof Error ? err.message : String(err))\n }\n\n const payload: Record<string, unknown> = {\n appName,\n ...(args.name ? { name: args.name } : {}),\n ...(args.description ? { description: args.description } : {}),\n ...(args.category ? { category: args.category } : {}),\n ...(tags ? { tags } : {}),\n visibility,\n ...(args.screenshot ? { screenshotUrl: args.screenshot } : {}),\n }\n\n const url = `${libraryHost}/api/actions/library.publish`\n let res: Response\n try {\n res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(payload),\n })\n } catch (err) {\n return die(`Network error reaching ${url}: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n const body = await res.text()\n let parsed: { success?: boolean; data?: { templateHandle?: string; url?: string; version?: number }; error?: string }\n try {\n parsed = JSON.parse(body)\n } catch {\n return die(`Server returned non-JSON (${res.status}): ${body.slice(0, 400)}`)\n }\n\n if (json) {\n console.log(JSON.stringify(parsed))\n process.exit(parsed.success ? 0 : 1)\n }\n\n if (!parsed.success) {\n return die(parsed.error ?? `Publish failed (HTTP ${res.status}).`)\n }\n\n p.log.success(`Published ${appName} as ${parsed.data?.templateHandle} (v${parsed.data?.version})`)\n if (parsed.data?.url) p.log.message(parsed.data.url)\n p.outro('Done')\n },\n})\n\nconst unpublish = defineCommand({\n meta: {\n name: 'unpublish',\n description: 'Remove a library entry (owner or admin only)',\n },\n args: {\n handle: {\n type: 'positional',\n description: 'templateHandle to remove (usually your app name)',\n required: true,\n },\n 'library-app': {\n type: 'string',\n description: `Target library app subdomain (default: ${DEFAULT_LIBRARY_APP})`,\n required: false,\n },\n json: {\n type: 'boolean',\n description: 'Print only the JSON response',\n default: false,\n },\n },\n async run({ args }) {\n const json = !!args.json\n const die = (msg: string) => {\n if (json) console.error(JSON.stringify({ ok: false, error: msg }))\n else p.cancel(msg)\n process.exit(1)\n }\n if (!json) p.intro('Unpublishing library entry')\n\n let token: string\n try { token = await ensureToken() } catch (err) {\n return die(err instanceof Error ? err.message : String(err))\n }\n\n const libraryApp = typeof args['library-app'] === 'string' && args['library-app']\n ? args['library-app']\n : DEFAULT_LIBRARY_APP\n const libraryHost = process.env.DEEPSPACE_LIBRARY_HOST ?? `https://${libraryApp}.app.space`\n\n const res = await fetch(`${libraryHost}/api/actions/library.unpublish`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n body: JSON.stringify({ templateHandle: String(args.handle) }),\n })\n const body = await res.text()\n let parsed: { success?: boolean; error?: string; data?: { templateHandle?: string } }\n try { parsed = JSON.parse(body) } catch {\n return die(`Server returned non-JSON (${res.status}): ${body.slice(0, 400)}`)\n }\n if (json) { console.log(JSON.stringify(parsed)); process.exit(parsed.success ? 0 : 1) }\n if (!parsed.success) return die(parsed.error ?? `HTTP ${res.status}`)\n p.log.success(`Unpublished ${parsed.data?.templateHandle}`)\n p.outro('Done')\n },\n})\n\nexport default defineCommand({\n meta: {\n name: 'library',\n description: 'Manage your DeepSpace library entries',\n },\n subCommands: {\n publish,\n unpublish,\n },\n})\n","/**\n * deepspace feedback\n *\n * Submit a bug report, feature request, or general feedback to the DeepSpace\n * team. The report is authenticated as the logged-in user and POSTed to the\n * api-worker, where it lands in the admin triage queue (dashboard ·\n * Admin · Feedback).\n *\n * Interactive when run in a TTY (prompts for type/title/details); flag-driven\n * for agents and CI. The title is a positional argument; the details go in\n * --message (-m). Both are required for non-interactive use.\n *\n * deepspace feedback # full interactive prompt\n * deepspace feedback \"Crash on deploy\" -m \"It explodes when…\" # quick, non-interactive\n * deepspace feedback -t feature \"Add dark mode\" -m \"…\" --yes --json\n *\n * Best-effort environment context (CLI version, Node version, OS, and the\n * current app name if run inside a scaffolded app) is attached automatically\n * so the team can reproduce issues without a round-trip.\n */\n\nimport { defineCommand } from 'citty'\nimport * as p from '@clack/prompts'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { release } from 'node:os'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS, DASHBOARD_URL } from '../env'\nimport { apiFetch } from '../lib/api'\nimport { hasWranglerConfig, readWranglerConfig } from '../lib/wrangler-env'\n\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\n\nconst TYPES = ['bug', 'feature', 'other'] as const\ntype FeedbackType = (typeof TYPES)[number]\n\nconst TYPE_LABELS: Record<FeedbackType, string> = {\n bug: 'Bug report',\n feature: 'Feature request',\n other: 'Other feedback',\n}\n\n// Mirror the api-worker's limits so over-length input fails fast with a clear\n// field-specific message instead of a generic 400 after the round-trip.\nconst MAX_TITLE_LEN = 200\nconst MAX_BODY_LEN = 10_000\nconst MAX_CONTEXT_LEN = 200\n\ninterface FeedbackContext {\n cliVersion: string\n nodeVersion: string\n platform: string\n appName?: string\n}\n\ninterface FeedbackPayload extends FeedbackContext {\n type: FeedbackType\n title: string\n body: string\n}\n\ninterface FeedbackReport {\n id: string\n type: FeedbackType\n title: string\n status: string\n createdAt: string\n}\n\nconst api = <T>(token: string, path: string, init?: RequestInit): Promise<T> =>\n apiFetch<T>(API_URL, token, path, init)\n\n/** Normalize/validate a `--type` value. Throws on an unknown type. */\nexport function normalizeType(raw: string | undefined): FeedbackType {\n const value = (raw ?? 'bug').toLowerCase()\n if ((TYPES as readonly string[]).includes(value)) return value as FeedbackType\n throw new Error(`Invalid --type \"${raw}\". Use one of: ${TYPES.join(', ')}.`)\n}\n\n/** Read the deepspace CLI version from its own package.json. */\nfunction readCliVersion(): string {\n try {\n const here = dirname(fileURLToPath(import.meta.url))\n // Bundled output lives in <pkg>/dist (package.json one level up); the\n // source tree has it three levels up from src/cli/commands.\n const candidates = [\n join(here, '..', 'package.json'),\n join(here, '..', '..', '..', 'package.json'),\n ]\n for (const path of candidates) {\n if (!existsSync(path)) continue\n const pkg = JSON.parse(readFileSync(path, 'utf-8')) as {\n name?: string\n version?: string\n }\n if (pkg.name === 'deepspace' && pkg.version) return pkg.version\n }\n } catch {\n // fall through\n }\n return 'unknown'\n}\n\n/** Best-effort app name from the current dir's wrangler.toml, if any. */\nfunction detectAppName(): string | undefined {\n try {\n const cwd = process.cwd()\n if (!hasWranglerConfig(cwd)) return undefined\n const config = readWranglerConfig(cwd)\n return typeof config.name === 'string' ? config.name : undefined\n } catch {\n return undefined\n }\n}\n\n/** Clamp a best-effort context value so it can never block submission. */\nfunction clampContext(value: string): string {\n return value.length > MAX_CONTEXT_LEN ? value.slice(0, MAX_CONTEXT_LEN) : value\n}\n\n/** Collect the environment context attached to every report. */\nexport function collectContext(): FeedbackContext {\n const appName = detectAppName()\n return {\n cliVersion: clampContext(readCliVersion()),\n nodeVersion: clampContext(process.version),\n platform: clampContext(`${process.platform} ${release()}`),\n ...(appName ? { appName: clampContext(appName) } : {}),\n }\n}\n\n/** Assemble the request body. Trims and validates title/body are non-empty. */\nexport function buildFeedbackPayload(input: {\n type: string | undefined\n title: string\n body: string\n context: FeedbackContext\n}): FeedbackPayload {\n const title = input.title.trim()\n const body = input.body.trim()\n if (!title) throw new Error('A title is required.')\n if (!body) throw new Error('A message/description is required.')\n if (title.length > MAX_TITLE_LEN) {\n throw new Error(`Title must be ${MAX_TITLE_LEN} characters or fewer (got ${title.length}).`)\n }\n if (body.length > MAX_BODY_LEN) {\n throw new Error(`Description must be ${MAX_BODY_LEN} characters or fewer (got ${body.length}).`)\n }\n return {\n type: normalizeType(input.type),\n title,\n body,\n ...input.context,\n }\n}\n\nexport default defineCommand({\n meta: {\n name: 'feedback',\n description: 'Submit a bug report, feature request, or feedback to DeepSpace',\n },\n args: {\n title: {\n type: 'positional',\n description: 'Short summary (prompted if omitted in a terminal)',\n required: false,\n },\n type: {\n type: 'string',\n alias: 't',\n description: `Report type: ${TYPES.join(' | ')} (default: bug)`,\n required: false,\n },\n message: {\n type: 'string',\n alias: 'm',\n description: 'Details / description (prompted if omitted in a terminal)',\n required: false,\n },\n yes: {\n type: 'boolean',\n description: 'Skip the confirmation prompt',\n default: false,\n },\n json: {\n type: 'boolean',\n description: 'Emit JSON instead of human output',\n default: false,\n },\n },\n async run({ args }) {\n const interactive = process.stdin.isTTY && !args.json\n\n // Fail consistently: under --json, emit the same { ok, error } shape on\n // stdout that the success/network paths use, so an agent can always parse\n // the outcome. Otherwise print to stderr. Either way exit non-zero.\n const fail = (message: string): never => {\n if (args.json) {\n process.stdout.write(JSON.stringify({ ok: false, error: message }) + '\\n')\n } else {\n console.error(message)\n }\n process.exit(1)\n }\n\n let type: FeedbackType\n try {\n type = normalizeType(args.type ? String(args.type) : undefined)\n } catch (err) {\n return fail((err as Error).message)\n }\n\n let title = args.title ? String(args.title) : ''\n let body = args.message ? String(args.message) : ''\n\n // Non-interactive callers (agents/CI) must supply both fields up front.\n if ((!title || !body) && !interactive) {\n return fail(\n 'Provide a title and --message to submit non-interactively, ' +\n 'e.g. `deepspace feedback \"Title\" --message \"Details\"`.',\n )\n }\n\n // Prompt for whatever is still missing — including the type, so an\n // interactive user who passed --title/--message but no --type is still\n // asked rather than having it silently default to \"bug\".\n if (interactive && (!args.type || !title || !body)) {\n p.intro('DeepSpace Feedback')\n\n if (!args.type) {\n const picked = await p.select({\n message: 'What kind of feedback is this?',\n options: TYPES.map((t) => ({ value: t, label: TYPE_LABELS[t] })),\n initialValue: type,\n })\n if (p.isCancel(picked)) {\n p.cancel('Cancelled.')\n process.exit(0)\n }\n type = picked as FeedbackType\n }\n\n if (!title) {\n const t = await p.text({\n message: 'Title',\n placeholder: 'Short summary of the issue',\n validate: (v) => {\n if (!v?.trim()) return 'Title is required'\n if (v.length > MAX_TITLE_LEN)\n return `Title must be ${MAX_TITLE_LEN} characters or fewer`\n return undefined\n },\n })\n if (p.isCancel(t)) {\n p.cancel('Cancelled.')\n process.exit(0)\n }\n title = String(t)\n }\n\n if (!body) {\n const m = await p.text({\n message: 'Details',\n placeholder: 'What happened? Steps to reproduce, what you expected…',\n validate: (v) => {\n if (!v?.trim()) return 'A description is required'\n if (v.length > MAX_BODY_LEN)\n return `Description must be ${MAX_BODY_LEN} characters or fewer`\n return undefined\n },\n })\n if (p.isCancel(m)) {\n p.cancel('Cancelled.')\n process.exit(0)\n }\n body = String(m)\n }\n }\n\n let payload: FeedbackPayload\n try {\n payload = buildFeedbackPayload({\n type,\n title,\n body,\n context: collectContext(),\n })\n } catch (err) {\n return fail((err as Error).message)\n }\n\n // Confirmation — only when interactive and not explicitly skipped.\n if (interactive && !args.yes) {\n p.note(\n `${TYPE_LABELS[payload.type]}\\n${payload.title}\\n\\n${payload.body}` +\n `\\n\\nContext: deepspace ${payload.cliVersion} · ${payload.nodeVersion} · ${payload.platform}` +\n (payload.appName ? ` · app ${payload.appName}` : ''),\n 'Review',\n )\n const ok = await p.confirm({ message: 'Send this to the DeepSpace team?' })\n if (p.isCancel(ok) || !ok) {\n p.cancel('Not sent.')\n process.exit(0)\n }\n }\n\n let token: string\n try {\n token = await ensureToken()\n } catch (err) {\n return fail((err as Error).message ?? 'Not signed in. Run `deepspace login`.')\n }\n\n let result: { report: FeedbackReport }\n try {\n result = await api<{ report: FeedbackReport }>(token, '/api/feedback', {\n method: 'POST',\n body: JSON.stringify(payload),\n })\n } catch (err) {\n return fail((err as Error).message)\n }\n\n if (args.json) {\n process.stdout.write(JSON.stringify({ ok: true, report: result.report }) + '\\n')\n return\n }\n\n if (interactive) {\n p.outro(`Thanks! Submitted as ${result.report.id}.`)\n } else {\n console.log(`Submitted feedback ${result.report.id} (${result.report.type}).`)\n }\n console.log(`Track triage status at ${DASHBOARD_URL}.`)\n },\n})\n","/**\n * `deepspace secrets` — manage the app's secrets store.\n *\n * Every app has exactly one store, addressed by its immutable id (the\n * DEEPSPACE_APP_ID in wrangler.toml); configs follow the wrangler-env\n * convention (top-level → `prd`, `--env staging` → `staging`). There is no\n * project/link setup step: run the commands from the app directory (or pass\n * --app <appId>) and they just work — for the owner, collaborators, and\n * admin accounts alike.\n *\n * deepspace secrets list [-c prd]\n * deepspace secrets set KEY=value [KEY2=value2 …]\n * deepspace secrets get KEY [--plain]\n * deepspace secrets delete KEY [KEY2 …]\n * deepspace secrets upload <file> (dotenv or JSON; --replace)\n * deepspace secrets download [--format dotenv|json|shell]\n * deepspace secrets pull (refresh the .dev.vars cache)\n * deepspace secrets configs list|create|delete\n */\n\nimport { defineCommand } from 'citty'\nimport { readFileSync } from 'node:fs'\nimport { ensureToken } from '../auth'\nimport { decodeJwtPayload } from '../jwt'\nimport { PLATFORM_URLS, writeDevVars } from '../env'\nimport { findAppDir } from '../lib/app-context'\nimport { readAppId, APP_ID_RE } from '../lib/app-identity'\nimport { dedupePositionals } from '../lib/citty-args'\nimport {\n createConfig,\n defaultConfigNameForEnv,\n deleteConfig,\n deleteSecret,\n fetchSecretsValues,\n formatSecretsDownload,\n getSecretPlain,\n listConfigs,\n listSecrets,\n parseSecretsUpload,\n pullAppSecretsCache,\n renderSecretsCache,\n setSecret,\n uploadSecrets,\n validateConfigName,\n validateSecretName,\n validateSecretValue,\n type SecretsDownloadFormat,\n} from '../lib/secrets'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\nconst COMMON_ARGS = {\n app: {\n type: 'string' as const,\n alias: 'a',\n description: 'App id (default: DEEPSPACE_APP_ID from the nearest wrangler.toml)',\n required: false,\n },\n config: {\n type: 'string' as const,\n alias: 'c',\n description: 'Config name (default: the --env name, or \"prd\")',\n required: false,\n },\n env: {\n type: 'string' as const,\n alias: 'e',\n description: 'wrangler.toml [env.<name>] slot — selects that env’s app id and config',\n required: false,\n },\n}\n\ninterface Target {\n appId: string\n configName: string\n token: string\n}\n\nasync function resolveTarget(args: {\n app?: string\n config?: string\n env?: string\n}): Promise<Target> {\n const wranglerEnv = args.env?.trim() || undefined\n let appId = args.app?.trim()\n if (appId && !APP_ID_RE.test(appId)) {\n throw new Error(`Invalid app id \"${appId}\" — expected app_<26 chars>.`)\n }\n if (!appId) {\n const appDir = findAppDir()\n appId = (appDir && readAppId(appDir, wranglerEnv)) || undefined\n if (!appId) {\n // `--env <name>` selects a wrangler [env.<name>] slot with its OWN app id.\n // If the slot is missing but a top-level app id exists, the user almost\n // certainly wanted to pick a *config*, not an env — point them at `-c`.\n if (wranglerEnv && appDir && readAppId(appDir, undefined)) {\n throw new Error(\n `No app id for env \"${wranglerEnv}\" — wrangler.toml has no [env.${wranglerEnv}] block with its own DEEPSPACE_APP_ID. ` +\n `To target the \"${wranglerEnv}\" config on this app, use \\`-c ${wranglerEnv}\\` instead of \\`--env ${wranglerEnv}\\`.`,\n )\n }\n throw new Error(\n 'No app id. Run from an app directory whose wrangler.toml carries DEEPSPACE_APP_ID (`deepspace init` mints one), or pass --app <appId>.',\n )\n }\n }\n const configName = validateConfigName(args.config?.trim() || defaultConfigNameForEnv(wranglerEnv))\n const token = await ensureToken()\n return { appId, configName, token }\n}\n\nfunction fail(err: unknown): never {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n}\n\n/**\n * Warn (once) when a write turns on the unauthenticated debug API. Applies to\n * every write path that can carry it — `set` and `upload` alike. Returns true\n * when it warned, so callers can skip the generic \"run deploy\" line (this\n * message already tells the user to redeploy).\n */\nfunction warnIfDebugRoutesEnabled(secrets: Record<string, string>): boolean {\n if (secrets.ALLOW_DEBUG_ROUTES !== 'true') return false\n console.warn(\n '\\n⚠ ALLOW_DEBUG_ROUTES=true exposes an UNAUTHENTICATED debug API on the deployed app —\\n' +\n ' anyone who can reach /api/debug/* can read and mutate any record. Redeploy to apply;\\n' +\n ' `deepspace secrets delete ALLOW_DEBUG_ROUTES` (then redeploy) turns it back off.',\n )\n return true\n}\n\nconst APPLY_HINT = 'Run `deepspace deploy` to apply — secrets take effect at deploy time.'\n// `deepspace dev` regenerates .dev.vars from the store only at startup, so a\n// secret changed mid-session isn't picked up until dev restarts (DEV-4).\nconst LOCAL_DEV_HINT = 'Running `deepspace dev`? Restart it to load the change locally.'\n\nconst list = defineCommand({\n meta: { name: 'list', description: 'List masked secrets in a config' },\n args: {\n ...COMMON_ARGS,\n 'only-names': {\n type: 'boolean',\n description: 'Only print secret names; omit values and metadata',\n default: false,\n },\n json: { type: 'boolean', description: 'Machine-readable output', default: false },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const { secrets } = await listSecrets(DEPLOY_URL, t.token, t.appId, t.configName)\n if (args.json) {\n console.log(JSON.stringify({ appId: t.appId, config: t.configName, secrets }, null, 2))\n return\n }\n if (secrets.length === 0) {\n console.log(`No secrets in ${t.configName}.`)\n return\n }\n for (const s of secrets) {\n console.log(args['only-names'] ? s.key : `${s.key} (v${s.version}, ${s.updatedAt})`)\n }\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst set = defineCommand({\n meta: { name: 'set', description: 'Set secrets from KEY=value pairs' },\n args: {\n ...COMMON_ARGS,\n secret: { type: 'positional', description: 'KEY=value (repeatable)', required: true },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const pairs = dedupePositionals(args.secret, args._)\n const secrets: Record<string, string> = {}\n const dupes: string[] = []\n for (const pair of pairs) {\n const eq = pair.indexOf('=')\n if (eq <= 0) throw new Error(`Expected KEY=value, got \"${pair}\"`)\n const key = validateSecretName(pair.slice(0, eq))\n const value = pair.slice(eq + 1)\n validateSecretValue(key, value)\n // The same KEY given twice (with different values) silently keeps the\n // last — surface it instead of dropping a value without a word.\n if (key in secrets && !dupes.includes(key)) dupes.push(key)\n secrets[key] = value\n }\n if (dupes.length) {\n console.warn(\n `Warning: ${dupes.join(', ')} given more than once — kept the last value for each.`,\n )\n }\n if (Object.keys(secrets).length === 1) {\n const [[k, v]] = Object.entries(secrets)\n await setSecret(DEPLOY_URL, t.token, t.appId, t.configName, k, v)\n } else {\n await uploadSecrets(DEPLOY_URL, t.token, t.appId, t.configName, secrets, false)\n }\n console.log(`Set ${Object.keys(secrets).length} secret${Object.keys(secrets).length === 1 ? '' : 's'} in ${t.configName}.`)\n if (!warnIfDebugRoutesEnabled(secrets)) {\n console.log(APPLY_HINT)\n console.log(LOCAL_DEV_HINT)\n }\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst get = defineCommand({\n meta: { name: 'get', description: 'Get a secret; pass --plain to print the value' },\n args: {\n ...COMMON_ARGS,\n key: { type: 'positional', description: 'Secret name', required: true },\n plain: { type: 'boolean', description: 'Print the plaintext value', default: false },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const key = validateSecretName(args.key)\n if (args.plain) {\n const { value } = await getSecretPlain(DEPLOY_URL, t.token, t.appId, t.configName, key)\n // Byte-exact when piped/redirected (`… get --plain KEY > key.pem`); add a\n // trailing newline only for a human reading it in a terminal.\n process.stdout.write(process.stdout.isTTY ? value + '\\n' : value)\n return\n }\n const { secrets } = await listSecrets(DEPLOY_URL, t.token, t.appId, t.configName)\n const item = secrets.find((s) => s.key === key)\n if (!item) fail(new Error(`Secret \"${key}\" not found in ${t.configName}`))\n console.log(`${item.key} (v${item.version}, ${item.updatedAt})`)\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst del = defineCommand({\n meta: { name: 'delete', description: 'Delete one or more secrets' },\n args: {\n ...COMMON_ARGS,\n key: { type: 'positional', description: 'Secret name (repeatable)', required: true },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const keys = dedupePositionals(args.key, args._)\n let deleted = 0\n let absent = 0\n for (const key of keys) {\n const name = validateSecretName(key)\n try {\n await deleteSecret(DEPLOY_URL, t.token, t.appId, t.configName, name)\n deleted++\n } catch (err) {\n // An already-absent key is a completed delete, not a failure: don't\n // let one missing key abort the rest, and keep retries idempotent.\n if ((err as { status?: number })?.status === 404) absent++\n else throw err\n }\n }\n const note = absent > 0 ? ` (${absent} already absent)` : ''\n console.log(`Deleted ${deleted} secret${deleted === 1 ? '' : 's'} from ${t.configName}.${note}`)\n if (deleted > 0) console.log(APPLY_HINT)\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst upload = defineCommand({\n meta: { name: 'upload', description: 'Upload secrets from a dotenv or JSON file' },\n args: {\n ...COMMON_ARGS,\n file: { type: 'positional', description: 'Path to a dotenv or JSON file (- for stdin)', required: true },\n replace: {\n type: 'boolean',\n description: 'Replace the whole config (delete keys missing from the file)',\n default: false,\n },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const content =\n args.file === '-' ? readFileSync(0, 'utf-8') : readFileSync(args.file, 'utf-8')\n const secrets = parseSecretsUpload(content)\n if (Object.keys(secrets).length === 0) fail(new Error('No secrets found in the input.'))\n await uploadSecrets(DEPLOY_URL, t.token, t.appId, t.configName, secrets, args.replace)\n console.log(`Uploaded ${Object.keys(secrets).length} secrets to ${t.configName}.`)\n // A file can turn on the debug API just like `set` can — warn either way.\n if (!warnIfDebugRoutesEnabled(secrets)) console.log(APPLY_HINT)\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst download = defineCommand({\n meta: { name: 'download', description: 'Download a config’s secrets (dotenv/json/shell)' },\n args: {\n ...COMMON_ARGS,\n format: {\n type: 'string',\n description: 'dotenv (default) | json | shell',\n default: 'dotenv',\n },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const format = args.format as SecretsDownloadFormat\n if (!['dotenv', 'json', 'shell'].includes(format)) {\n fail(new Error(`Unknown format \"${args.format}\" — use dotenv, json, or shell.`))\n }\n const { secrets } = await fetchSecretsValues(DEPLOY_URL, t.token, t.appId, t.configName)\n process.stdout.write(formatSecretsDownload(secrets, format))\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst pull = defineCommand({\n meta: { name: 'pull', description: 'Refresh the .dev.vars cache from the app store' },\n args: { ...COMMON_ARGS },\n async run({ args }) {\n try {\n const wranglerEnv = args.env?.trim() || undefined\n const appDir = findAppDir()\n if (!appDir) fail(new Error('Run from a DeepSpace app directory (one containing wrangler.toml).'))\n const t = await resolveTarget(args)\n const ownerId = decodeJwtPayload<{ sub: string }>(t.token).sub\n const pulled = await pullAppSecretsCache(DEPLOY_URL, t.token, t.appId, t.configName)\n if (!pulled) {\n console.log(`No secrets in ${t.configName} yet — nothing to pull.`)\n return\n }\n await writeDevVars(appDir, ownerId, t.token, wranglerEnv, {\n appId: t.appId,\n generatedSecretsCache: renderSecretsCache(pulled.values, pulled),\n sharedDevVarsCache: true,\n })\n console.log(\n `Pulled ${Object.keys(pulled.values).length} secrets (${t.configName}) into .dev.vars.`,\n )\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst configsList = defineCommand({\n meta: { name: 'list', description: 'List the app’s configs' },\n args: { ...COMMON_ARGS },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const { configs } = await listConfigs(DEPLOY_URL, t.token, t.appId)\n if (configs.length === 0) {\n console.log('No configs yet — the first `secrets set` creates one.')\n return\n }\n for (const cfg of configs) {\n console.log(`${cfg.name} (${cfg.secretCount ?? 0} secrets, updated ${cfg.updatedAt})`)\n }\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst configsCreate = defineCommand({\n meta: { name: 'create', description: 'Create a config (optionally copying another)' },\n args: {\n ...COMMON_ARGS,\n name: { type: 'positional', description: 'Config name', required: true },\n 'copy-from': { type: 'string', description: 'Copy secrets from this config', required: false },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const name = validateConfigName(args.name)\n const copyFrom = args['copy-from'] || undefined\n // Create is idempotent server-side, so a plain create of an existing\n // config used to print a false \"Created\". Distinguish the cases up front:\n // a bare re-create is a no-op (\"Already exists.\"); a --copy-from into an\n // existing config would clobber it, so refuse rather than silently create.\n const { configs } = await listConfigs(DEPLOY_URL, t.token, t.appId)\n if (configs.some((c) => c.name === name)) {\n if (copyFrom) {\n fail(\n new Error(\n `Config \"${name}\" already exists — refusing to copy \"${copyFrom}\" over it. Delete it first, or pick a new name.`,\n ),\n )\n }\n console.log(`Config ${name} already exists.`)\n return\n }\n await createConfig(DEPLOY_URL, t.token, t.appId, name, copyFrom)\n console.log(`Created ${name}.`)\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst configsDelete = defineCommand({\n meta: { name: 'delete', description: 'Delete a config and all of its secrets' },\n args: {\n ...COMMON_ARGS,\n name: { type: 'positional', description: 'Config name', required: true },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const name = validateConfigName(args.name)\n await deleteConfig(DEPLOY_URL, t.token, t.appId, name)\n console.log(`Deleted ${name}.`)\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst configs = defineCommand({\n meta: { name: 'configs', description: 'Manage the app’s secrets configs' },\n subCommands: { list: configsList, create: configsCreate, delete: configsDelete },\n})\n\nexport default defineCommand({\n meta: { name: 'secrets', description: 'Manage the app’s secrets store' },\n subCommands: {\n list,\n set,\n get,\n delete: del,\n upload,\n download,\n pull,\n configs,\n },\n})\n","/**\n * Helpers for citty argument quirks.\n */\n\n/**\n * citty binds the first positional to its named arg AND *also* leaves the full\n * positional list in `args._`. A handler that naively unions `[named, ...args._]`\n * therefore processes the first positional twice — which silently broke\n * `secrets delete`: it deleted a key, re-attempted the same key, got a 404, and\n * aborted the rest (`delete A B` kept B; a single `delete A` exited 1 on success).\n *\n * Union + dedupe (dropping empties / non-strings) yields the caller's distinct\n * positionals exactly once, in first-seen order. Use this anywhere a command\n * accepts a repeatable positional.\n */\nexport function dedupePositionals(bound: unknown, rest: unknown): string[] {\n const restArr = Array.isArray(rest) ? rest : []\n return [...new Set([bound, ...restArr])].filter(\n (v): v is string => typeof v === 'string' && v.length > 0,\n )\n}\n","/**\n * `deepspace init` — ensure this app carries its immutable identity.\n *\n * Mints DEEPSPACE_APP_ID into wrangler.toml (per wrangler env with --env).\n * Registration happens at the first deploy. `--new-id` replaces an existing\n * id, which FORKS the repo into a separate app: fresh registration, fresh\n * Durable Object data, fresh secrets store — the original app is untouched.\n */\n\nimport { defineCommand } from 'citty'\nimport { findAppDir } from '../lib/app-context'\nimport { mintAppId, readAppId, writeAppId } from '../lib/app-identity'\n\nexport default defineCommand({\n meta: {\n name: 'init',\n description: 'Mint this app’s immutable DEEPSPACE_APP_ID into wrangler.toml',\n },\n args: {\n 'new-id': {\n type: 'boolean',\n description:\n 'Replace the existing id — forks this repo as a SEPARATE app (new data, new secrets, new registration). The original app keeps running.',\n default: false,\n },\n env: {\n type: 'string',\n alias: 'e',\n description: 'wrangler.toml [env.<name>] block to stamp (each env is its own app)',\n required: false,\n },\n },\n async run({ args }) {\n const appDir = findAppDir()\n if (!appDir) {\n console.error(\n 'No wrangler.toml here — `deepspace init` stamps an app id into an existing ' +\n 'DeepSpace app. To create a new app, run `deepspace create <name>` (or ' +\n '`npm create deepspace@latest <name>`), then run this from inside it.',\n )\n process.exit(1)\n }\n const envName = args.env || undefined\n const existing = readAppId(appDir, envName)\n if (existing && !args['new-id']) {\n console.log(`Already initialized: ${existing}${envName ? ` (env: ${envName})` : ''}`)\n return\n }\n const appId = mintAppId()\n writeAppId(appDir, appId, { wranglerEnv: envName, force: args['new-id'] })\n if (existing) {\n console.log(`Forked: ${existing} → ${appId}${envName ? ` (env: ${envName})` : ''}`)\n console.log('The next deploy registers this as a NEW app; the original is untouched.')\n } else {\n console.log(`Minted ${appId}${envName ? ` (env: ${envName})` : ''} — commit wrangler.toml.`)\n console.log('The first deploy registers it and claims the `name` subdomain.')\n }\n },\n})\n"],"mappings":"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","names":["defineCommand","spawnSync","readFileSync","existsSync","dirname","join","fileURLToPath","status","run","writeFileSync","readFileSync","join","p","existsSync","readFileSync","out","writeFileSync","existsSync","readFileSync","writeFileSync","join","parseToml","join","existsSync","writeFileSync","readFileSync","parseToml","existsSync","readFileSync","readFileSync","join","writeFileSync","resolve","defineCommand","existsSync","readFileSync","rmSync","join","homedir","AUTH_URL","join","homedir","defineCommand","existsSync","readFileSync","rmSync","defineCommand","resolve","basename","join","readFileSync","writeFileSync","existsSync","mkdirSync","join","homedir","AUTH_URL","DIR","join","homedir","SESSION_PATH","TOKEN_PATH","existsSync","readFileSync","mkdirSync","writeFileSync","existsSync","readFileSync","writeFileSync","mkdirSync","join","resolve","parseToml","status","text","join","resolve","existsSync","parseToml","readFileSync","mkdirSync","writeFileSync","p","existsSync","readFileSync","join","existsSync","resolve","status","readdirSync","rmSync","join","resolve","defineCommand","resolve","join","basename","defineCommand","readFileSync","readdirSync","defineCommand","readFileSync","readdirSync","defineCommand","resolve","spawnSync","spawnSync","DEPLOY_URL","defineCommand","resolve","spawnSync","defineCommand","spawnSync","resolve","defineCommand","resolve","spawnSync","defineCommand","p","readFileSync","writeFileSync","existsSync","mkdirSync","join","homedir","SESSION_COOKIE","AUTH_URL","DIR","join","homedir","existsSync","readFileSync","mkdirSync","writeFileSync","SESSION_PATH","defineCommand","defineCommand","execSync","readFileSync","readdirSync","existsSync","join","resolve","dirname","p","DEPLOY_URL","API_URL","status","defineCommand","resolve","existsSync","readFileSync","execSync","join","dirname","wait","readdirSync","defineCommand","p","DEPLOY_URL","defineCommand","defineCommand","defineCommand","defineCommand","DEPLOY_URL","defineCommand","defineCommand","existsSync","readFileSync","resolve","join","dirname","spawnSync","join","existsSync","dirname","pkg","readFileSync","spawnSync","defineCommand","resolve","script","passArgs","defineCommand","API_URL","confirm","resolve","defineCommand","list","defineCommand","list","defineCommand","API_URL","DEPLOY_URL","api","list","defineCommand","defineCommand","p","API_URL","DEPLOY_URL","defineCommand","status","cancel","defineCommand","readFileSync","p","API_URL","readFileSync","info","ok","list","defineCommand","defineCommand","defineCommand","defineCommand","existsSync","readFileSync","join","resolve","parseToml","p","defineCommand","intro","info","resolve","join","existsSync","parseToml","readFileSync","defineCommand","p","existsSync","readFileSync","dirname","join","fileURLToPath","API_URL","api","dirname","fileURLToPath","join","existsSync","pkg","readFileSync","detectAppName","defineCommand","fail","defineCommand","readFileSync","DEPLOY_URL","list","defineCommand","del","note","readFileSync","configs","defineCommand","defineCommand","dirname","fileURLToPath","readFileSync","join","existsSync","create","defineCommand","spawnSync"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/cli.ts","../src/cli/lib/cli-errors.ts","../src/cli/commands/login.ts","../src/cli/lib/spinner.ts","../src/cli/env.ts","../src/server/rooms/binding-manifest.ts","../src/cli/lib/secrets.ts","../src/cli/lib/app-identity.ts","../src/cli/lib/secure-file.ts","../src/cli/lib/wrangler-env.ts","../src/server/rooms/app-name.ts","../src/cli/session.ts","../src/cli/lib/open-browser.ts","../src/cli/commands/logout.ts","../src/cli/commands/dev.ts","../src/cli/auth.ts","../src/cli/jwt.ts","../src/cli/lib/app-context.ts","../src/cli/lib/api.ts","../src/cli/lib/install-status.ts","../src/cli/lib/preflight.ts","../src/cli/lib/macos-junk.ts","../src/cli/lib/port.ts","../src/cli/commands/kill.ts","../src/cli/commands/test.ts","../src/cli/lib/playwright.ts","../src/cli/commands/screenshot.ts","../src/cli/commands/test-accounts.ts","../src/cli/commands/deploy.ts","../src/cli/commands/undeploy.ts","../src/cli/commands/whoami.ts","../src/cli/commands/apps.ts","../src/cli/commands/add.ts","../src/cli/commands/domain.ts","../src/cli/commands/collaborators.ts","../src/server/auth/testAccounts.ts","../src/cli/commands/transfer.ts","../src/cli/commands/integrations.ts","../src/cli/commands/_invoke-impl.ts","../src/cli/commands/invoke.ts","../src/cli/commands/library.ts","../src/cli/commands/feedback.ts","../src/cli/commands/secrets.ts","../src/cli/lib/citty-args.ts","../src/cli/commands/init.ts"],"sourcesContent":["/**\n * DeepSpace CLI\n *\n * Commands:\n * login — authenticate with your DeepSpace account\n * deploy — build and deploy your app to *.app.space\n * undeploy — remove a deployed app\n * create — redirects to `npm create deepspace`\n */\n\nimport { defineCommand, runMain } from 'citty'\nimport { spawnSync } from 'node:child_process'\nimport { readFileSync, existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { wrapCommandErrors } from './lib/cli-errors'\nimport login from './commands/login'\nimport logout from './commands/logout'\nimport dev from './commands/dev'\nimport kill from './commands/kill'\nimport test from './commands/test'\nimport screenshot from './commands/screenshot'\nimport testAccounts from './commands/test-accounts'\nimport deploy from './commands/deploy'\nimport undeploy from './commands/undeploy'\nimport whoami from './commands/whoami'\nimport apps from './commands/apps'\nimport add from './commands/add'\nimport domain from './commands/domain'\nimport collaborators from './commands/collaborators'\nimport transfer from './commands/transfer'\nimport integrations from './commands/integrations'\nimport invoke from './commands/invoke'\nimport library from './commands/library'\nimport feedback from './commands/feedback'\nimport secrets from './commands/secrets'\nimport init from './commands/init'\n\n// Read own version from package.json so the CLI banner stays in sync with publishes.\n// __dirname of the bundled output is <pkg>/dist; package.json sits one level up.\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'))\n\n// workerd doesn't auto-discover system CAs in containers — outbound HTTPS to the\n// auth/api workers fails with \"TLS peer's certificate is not trusted\" until we\n// point it at the standard Debian/Ubuntu cert bundle. Harmless on macOS (path\n// doesn't exist, env var not set).\nif (\n process.platform === 'linux' &&\n !process.env.SSL_CERT_FILE &&\n existsSync('/etc/ssl/certs/ca-certificates.crt')\n) {\n process.env.SSL_CERT_FILE = '/etc/ssl/certs/ca-certificates.crt'\n}\n\nconst create = defineCommand({\n meta: {\n name: 'create',\n description: 'Create a new DeepSpace app (runs create-deepspace; all flags are forwarded)',\n },\n args: {\n name: {\n type: 'positional',\n description: 'App name',\n required: false,\n },\n interactive: {\n type: 'boolean',\n description: 'Prompt for options instead of using defaults',\n },\n local: {\n type: 'string',\n description: 'Use a local SDK monorepo checkout instead of the published package',\n },\n },\n run({ rawArgs }) {\n // Forward EVERY argument verbatim and pin the scaffolder to this CLI's own\n // version — `npm create deepspace@latest` used to drop all flags and could\n // fetch a create-deepspace newer than the running CLI.\n const scaffolder = `create-deepspace@${pkg.version}`\n console.log(`Running: npx ${scaffolder} ${rawArgs.join(' ')}`.trimEnd() + '\\n')\n const res = spawnSync('npx', ['-y', scaffolder, ...rawArgs], { stdio: 'inherit' })\n process.exit(res.status ?? 1)\n },\n})\n\nconst main = defineCommand({\n meta: {\n name: 'deepspace',\n version: pkg.version,\n description: 'DeepSpace SDK CLI',\n },\n subCommands: {\n init,\n create,\n login,\n logout,\n whoami,\n apps,\n dev,\n kill,\n test,\n screenshot,\n 'test-accounts': testAccounts,\n add,\n integrations,\n invoke,\n deploy,\n undeploy,\n domain,\n collaborators,\n transfer,\n library,\n feedback,\n secrets,\n },\n // No `run()` here — citty cascades parent run() AFTER subcommand finishes,\n // which corrupts agent-friendly output (`--json`) and prints noise on every\n // command. Citty's default behavior when no subcommand matches is to print\n // help, which is what we want for `deepspace` with no args.\n})\n\n// Escaped errors (API failures, network hiccups) render as one clean line\n// instead of citty's default Error-object dump with a stack trace.\nrunMain(wrapCommandErrors(main))\n","/**\n * Friendly rendering for errors that escape a command's run().\n *\n * citty's runMain catches escaped errors and console.errors the full Error\n * object — stack trace and all. For expected operational failures (an API\n * 403, a network hiccup) that reads like a crash. wrapCommandErrors()\n * recursively wraps every command's run() so escaped errors render as a\n * single clean message (with known API error slugs translated), while\n * citty's own help/version/usage handling stays untouched. Set DEBUG=1 to\n * get the full stack back.\n */\n\nimport type { CommandDef } from 'citty'\n\n/**\n * API error slugs that genuinely confuse people → what to tell them. Slugs\n * whose meaning is obvious from the name (invalid_email, ...) stay unmapped\n * and render as-is; don't grow this into a mirror of the server's errors.\n */\nconst API_ERROR_HINTS: Record<string, string> = {\n not_app_owner: 'Only the app owner can do this.',\n app_not_found:\n 'App not found. Check the app id — the DEEPSPACE_APP_ID value in wrangler.toml, usually ' +\n '`app_…` (a legacy app\\'s id is its name). List your apps with `deepspace apps`. ' +\n '(`domain` commands take the deployed app *name* instead.)',\n not_app_owner_or_collaborator: 'You must be the app owner or a collaborator to do this.',\n test_account_cannot_be_collaborator:\n 'Test accounts cannot be added as collaborators. Use a real DeepSpace account.',\n user_not_found:\n 'No DeepSpace user with that email. They need to log in to DeepSpace at least once ' +\n '(`deepspace login`, or sign in to any app) before they can be referenced by email.',\n insufficient_credits:\n 'Out of credits. Inviting a new collaborator by email sends them a transactional ' +\n 'email billed to your account — top up your credits and try again.',\n invite_email_failed:\n 'The invite email could not be sent. You were not charged — please try again in a moment.',\n}\n\n/** Exported for tests. One clean message for an escaped error. */\nexport function formatCliError(err: unknown): string {\n const message = err instanceof Error ? err.message : String(err)\n // Preferred: the platform returns { error: <sentence>, code: <slug> } and\n // apiFetch throws a typed ApiError carrying the code. Fallback: legacy\n // helpers throw `API <path> (<status>): <slug>` with the slug in the text.\n const code = (err as { code?: unknown })?.code\n const slug =\n typeof code === 'string' ? code : /^API \\S+ \\(\\d+\\): ([a-z0-9_]+)$/.exec(message)?.[1]\n const hint = slug ? API_ERROR_HINTS[slug] : undefined\n // The server sentence and the hint can say the same thing — don't stutter.\n return hint && !message.includes(hint) ? `${message}\\n${hint}` : message\n}\n\nfunction renderCliError(err: unknown): never {\n console.error(formatCliError(err))\n if (process.env.DEBUG) {\n // ApiError/secretsApi keep the internal REST path off the message; show it here.\n const { apiPath, status } = err as { apiPath?: string; status?: number }\n if (apiPath) console.error(`\\nAPI ${apiPath}${status ? ` (${status})` : ''}`)\n if (err instanceof Error && err.stack) console.error('\\n' + err.stack)\n }\n process.exit(1)\n}\n\ntype RunFn = NonNullable<CommandDef['run']>\n\n/**\n * Recursively wrap a concrete command tree's run() handlers. Only plain\n * object subcommands are wrapped — every command in this CLI is one; lazy\n * (function/promise) subcommand definitions would pass through unwrapped.\n */\nexport function wrapCommandErrors<T extends CommandDef>(cmd: T): T {\n const run = cmd.run\n if (run) {\n cmd.run = (async (ctx: Parameters<RunFn>[0]) => {\n try {\n await run(ctx)\n } catch (err) {\n renderCliError(err)\n }\n }) as RunFn\n }\n if (cmd.subCommands && typeof cmd.subCommands === 'object') {\n for (const sub of Object.values(cmd.subCommands)) {\n if (sub && typeof sub === 'object') wrapCommandErrors(sub as CommandDef)\n }\n }\n return cmd\n}\n","/**\n * deepspace login\n *\n * Opens the browser to sign in with GitHub or Google.\n * CLI polls the auth worker until login is complete.\n *\n * deepspace login # browser-based OAuth\n * deepspace login --email x --password y # non-interactive (discouraged: argv leaks)\n * echo \"$PW\" | deepspace login --email x --password-stdin # password via stdin\n * DEEPSPACE_EMAIL=x DEEPSPACE_PASSWORD=y deepspace login # via env\n */\n\nimport { defineCommand } from 'citty'\nimport { writeFileSync, mkdirSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport { randomBytes, createHash } from 'node:crypto'\nimport * as p from '@clack/prompts'\n\nimport { createSpinner } from '../lib/spinner'\nimport { DASHBOARD_URL, PLATFORM_URLS } from '../env'\nimport { exchangeSession, SESSION_COOKIE } from '../session'\nimport { openBrowser } from '../lib/open-browser'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? PLATFORM_URLS.auth\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\n\nexport default defineCommand({\n meta: {\n name: 'login',\n description: 'Log in to your DeepSpace account',\n },\n args: {\n email: {\n type: 'string',\n description: 'Email address (non-interactive mode; or $DEEPSPACE_EMAIL)',\n required: false,\n },\n password: {\n type: 'string',\n description: 'Password (discouraged — visible in ps/history; prefer --password-stdin or $DEEPSPACE_PASSWORD)',\n required: false,\n },\n 'password-stdin': {\n type: 'boolean',\n description: 'Read the password from stdin instead of --password',\n default: false,\n },\n },\n async run({ args }) {\n // Non-interactive mode for CI/agents. Password from --password-stdin\n // (safest), $DEEPSPACE_PASSWORD, or --password (discouraged — visible in\n // `ps`/shell history); email from --email or $DEEPSPACE_EMAIL. The env vars\n // are consulted ONLY when stdin is non-interactive, so ambient\n // DEEPSPACE_* in a dev shell can't hijack an interactive `deepspace login`\n // into a password login as a different identity.\n const interactive = Boolean(process.stdin.isTTY)\n const { email, password } = resolveLoginCredentials({\n emailArg: args.email,\n passwordArg: args.password,\n envEmail: interactive ? undefined : process.env.DEEPSPACE_EMAIL,\n envPassword: interactive ? undefined : process.env.DEEPSPACE_PASSWORD,\n passwordStdin: args['password-stdin'] ? readPasswordFromStdin() : undefined,\n })\n const passwordIntent =\n Boolean(args['password-stdin']) || args.password !== undefined || password !== undefined\n\n const decision = loginModeDecision({ email, password, passwordIntent })\n if (decision.mode === 'error') {\n console.error(decision.message)\n process.exit(1)\n }\n if (decision.mode === 'password') {\n console.log(`Signing in as ${email}...`)\n await doEmailLogin(email as string, password as string)\n console.log('Logged in')\n return\n }\n // decision.mode === 'oauth' → fall through to the browser flow below.\n\n // Browser-based OAuth flow\n p.intro('DeepSpace Login')\n\n const s = createSpinner()\n s.start('Creating login session...')\n\n // PKCE: generate a random verifier and send only its SHA-256 hash to the\n // server. The verifier never leaves this process, so the loginUrl alone\n // can't be used to drain credentials at /status — only this CLI can.\n const codeVerifier = base64url(randomBytes(32))\n const codeChallenge = base64url(createHash('sha256').update(codeVerifier).digest())\n\n // 1. Create a CLI session\n const sessionRes = await fetch(`${AUTH_URL}/api/auth/cli/session`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ code_challenge: codeChallenge }),\n })\n if (!sessionRes.ok) {\n s.stop('Failed')\n p.cancel('Could not create login session')\n process.exit(1)\n }\n const sessionData = (await sessionRes.json()) as {\n sessionId?: string\n loginUrl?: string\n }\n if (!sessionData.sessionId || !sessionData.loginUrl) {\n s.stop('Failed')\n p.cancel('Could not create login session')\n process.exit(1)\n }\n\n const { sessionId, loginUrl } = sessionData as {\n sessionId: string\n loginUrl: string\n }\n\n s.stop('Opening browser...')\n p.log.info(`If the browser doesn't open, visit:\\n ${loginUrl}`)\n\n // 2. Open browser\n openBrowser(loginUrl)\n\n // 3. Poll for completion\n s.start('Waiting for authentication...')\n const result = await pollForCompletion(sessionId, codeVerifier)\n\n if (!result) {\n s.stop('Timed out')\n p.cancel('Login timed out. Run `deepspace login` to try again.')\n process.exit(1)\n }\n\n // 4. Store credentials + provision the billing profile (see provisionProfile)\n storeCredentials(result.sessionToken, result.jwt)\n await provisionProfile(result.jwt)\n\n s.stop('Authenticated')\n p.log.success(`Logged in as ${result.name ?? result.email}`)\n p.note(\n `Manage your account, deployed apps, billing, and subscription\\nplans on the web dashboard:\\n\\n ${DASHBOARD_URL}`,\n 'Dashboard',\n )\n p.outro('Done')\n },\n})\n\n/**\n * Resolve non-interactive login credentials with a clear precedence (ONB-4):\n * email = --email > $DEEPSPACE_EMAIL; password = --password-stdin (when the flag\n * is set, its already-read value wins) > --password > $DEEPSPACE_PASSWORD.\n * Pure for testing.\n */\nexport function resolveLoginCredentials(opts: {\n emailArg?: string\n passwordArg?: string\n envEmail?: string\n envPassword?: string\n passwordStdin?: string\n}): { email?: string; password?: string } {\n const email = opts.emailArg || opts.envEmail || undefined\n const password =\n opts.passwordStdin !== undefined\n ? opts.passwordStdin\n : opts.passwordArg || opts.envPassword || undefined\n return { email, password }\n}\n\n/**\n * Decide how `login` should proceed given the resolved credentials (ONB-4).\n * `passwordIntent` is true when the user asked for a password login (a\n * credential flag/stdin or a resolved password). Crucially, a supplied-but-\n * incomplete credential set (missing email, or an EMPTY password — e.g. an\n * empty `--password-stdin` in CI) becomes an `error`, not a silent fall-through\n * to the browser OAuth flow (which would hang ~10 min in a headless pipeline).\n * Pure for testing.\n */\nexport function loginModeDecision(opts: {\n email?: string\n password?: string\n passwordIntent: boolean\n}): { mode: 'password' } | { mode: 'oauth' } | { mode: 'error'; message: string } {\n if (opts.email && opts.password) return { mode: 'password' }\n if (!opts.passwordIntent) return { mode: 'oauth' }\n if (!opts.email) {\n return {\n mode: 'error',\n message: 'Non-interactive login needs an email: --email <you@example.com> (or $DEEPSPACE_EMAIL).',\n }\n }\n return {\n mode: 'error',\n message:\n 'Non-interactive login needs a non-empty password: --password-stdin, $DEEPSPACE_PASSWORD, or --password.',\n }\n}\n\n/**\n * Read a password piped on stdin (one trailing newline stripped). Errors on a\n * TTY, where reading stdin would block forever waiting for EOF.\n */\nfunction readPasswordFromStdin(): string {\n if (process.stdin.isTTY) {\n console.error(\n '--password-stdin expects the password piped on stdin, e.g. `printf %s \"$PW\" | deepspace login --email you@x.com --password-stdin`.',\n )\n process.exit(1)\n }\n return readFileSync(0, 'utf-8').replace(/\\r?\\n$/, '')\n}\n\ninterface LoginResult {\n sessionToken: string\n jwt: string\n email: string\n name: string | null\n}\n\nasync function pollForCompletion(\n sessionId: string,\n codeVerifier: string,\n): Promise<LoginResult | null> {\n const maxAttempts = 120 // 10 minutes at 5s intervals\n const interval = 5000\n\n for (let i = 0; i < maxAttempts; i++) {\n await sleep(interval)\n\n try {\n const res = await fetch(`${AUTH_URL}/api/auth/cli/status/${sessionId}`, {\n headers: { 'x-code-verifier': codeVerifier },\n })\n\n if (res.status === 410 || res.status === 404) return null // expired / not found\n if (!res.ok) continue\n\n const data = (await res.json()) as {\n state?: string\n sessionToken?: string\n jwt?: string\n email?: string\n name?: string\n }\n\n if (data.state === 'complete' && data.sessionToken && data.jwt) {\n return {\n sessionToken: data.sessionToken,\n jwt: data.jwt,\n email: data.email ?? '',\n name: data.name ?? null,\n }\n }\n } catch {\n // Network error, keep polling\n }\n }\n\n return null\n}\n\nfunction storeCredentials(sessionToken: string, jwt: string) {\n const dir = join(homedir(), '.deepspace')\n mkdirSync(dir, { recursive: true, mode: 0o700 })\n writeFileSync(join(dir, 'session'), sessionToken, { mode: 0o600 })\n writeFileSync(join(dir, 'token'), jwt, { mode: 0o600 })\n}\n\n/**\n * Provision the user's billing profile so they can be referenced by email\n * immediately after logging in — e.g. added as a collaborator on someone\n * else's app. The api-worker's auth middleware upserts the `userProfiles`\n * row on any authenticated call, but login/whoami only ever touch the auth\n * worker, so a fresh CLI-only account otherwise has no profile and\n * `collaborators add <their-email>` 404s until their first deploy. One GET\n * to /api/users/me creates it. Best-effort: the same upsert happens on any\n * later api-worker call, so a transient failure here must not fail login.\n */\nasync function provisionProfile(jwt: string): Promise<void> {\n try {\n await fetch(`${API_URL}/api/users/me`, { headers: { Authorization: `Bearer ${jwt}` } })\n } catch {\n // non-fatal — the profile is upserted on the next api-worker request\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nfunction base64url(bytes: Buffer): string {\n return bytes.toString('base64').replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\n// ── Email/password login (for test accounts and CI) ────────────────\n\nasync function doEmailLogin(email: string, password: string): Promise<void> {\n const res = await fetch(`${AUTH_URL}/api/auth/sign-in/email`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Origin: AUTH_URL },\n body: JSON.stringify({ email, password }),\n redirect: 'manual',\n })\n\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as { message?: string }\n throw new Error(body.message ?? `Authentication failed (${res.status})`)\n }\n\n const setCookie = res.headers.get('set-cookie') ?? ''\n const cookieMatch = setCookie.match(new RegExp(`${SESSION_COOKIE}=([^;]+)`))\n if (!cookieMatch) {\n throw new Error('No session cookie returned')\n }\n const sessionToken = decodeURIComponent(cookieMatch[1])\n\n const jwt = await exchangeSession(AUTH_URL, sessionToken)\n if (!jwt) {\n throw new Error('JWT issuance failed')\n }\n\n storeCredentials(sessionToken, jwt)\n await provisionProfile(jwt)\n}\n","import * as p from '@clack/prompts'\n\n// In a real terminal, @clack/prompts repaints the spinner by writing `\\r`\n// to overwrite the previous frame. In non-TTY contexts (agents, CI logs,\n// pipes, `tee`-ed output) `\\r` does nothing and every frame becomes a new\n// line — a single long phase floods the log with thousands of repeats.\n// When stdout is not a TTY we fall back to one static line per phase.\nexport function createSpinner(): {\n start: (msg?: string) => void\n stop: (msg?: string) => void\n message: (msg?: string) => void\n} {\n if (process.stdout.isTTY) return p.spinner()\n return {\n start: (msg?: string) => { if (msg) console.log(msg) },\n stop: (msg?: string) => { if (msg) console.log(msg) },\n message: (msg?: string) => { if (msg) console.log(msg) },\n }\n}\n","/**\n * DeepSpace environment configuration.\n *\n * Shared between `dev`, `test`, and `deploy` commands.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { stripGeneratedSecretsCache } from './lib/secrets'\nexport { stripGeneratedSecretsCache } // re-export: env.test + callers treat env as the .dev.vars surface\nimport { readAppId } from './lib/app-identity'\nimport { writeSecretFileSync } from './lib/secure-file'\nimport {\n devVarsPathFor,\n resolveAppNameForEnv,\n readWranglerConfig,\n hasWranglerConfig,\n} from './lib/wrangler-env'\n\n/**\n * Production DeepSpace platform URLs. The CLI always targets production\n * workers — there is no separate dev stack. Individual worker URLs can be\n * overridden per-command via the `DEEPSPACE_*_URL` env vars.\n */\nexport const PLATFORM_URLS = {\n auth: 'https://auth.deep.space',\n api: 'https://api-worker.deep.space',\n platform: 'https://platform-worker.deep.space',\n deploy: 'https://deploy-worker.deep.space',\n} as const\n\n/**\n * Web dashboard for managing deployed apps, billing, subscription plans,\n * earnings, etc. Linked from `login` and `whoami` so developers\n * discover it (the CLI alone gives no hint that it exists).\n */\nexport const DASHBOARD_URL = 'https://dashboard.deep.space'\n\n/**\n * Fetch the JWT public key from an auth worker's /api/auth/jwks endpoint.\n */\nexport async function fetchPublicKey(authUrl: string): Promise<string> {\n const res = await fetch(`${authUrl}/api/auth/jwks`)\n if (!res.ok) {\n throw new Error(`Failed to fetch JWT public key (${res.status})`)\n }\n const data = (await res.json()) as { publicKey?: string }\n if (!data.publicKey) {\n throw new Error('JWKS response missing publicKey')\n }\n return data.publicKey\n}\n\n/**\n * Read the app name from the app's wrangler.toml. A non-canonical `name`\n * (e.g. `My_App` vs. `my-app`) is rejected with a clear error so wrangler.toml\n * stays the single source of truth — otherwise the canonical form would land\n * on deployed bindings and the registry while the raw form persisted in\n * `[vars].APP_NAME` and the client `SCOPE_ID`, splitting identity across\n * surfaces.\n *\n * `deepspace dev` runs in an app directory; the name is required.\n */\nfunction requireAppIdFor(appDir: string, wranglerEnv?: string): string {\n const id = readAppId(appDir, wranglerEnv)\n if (id) return id\n throw new Error(\n 'wrangler.toml has no DEEPSPACE_APP_ID' +\n (wranglerEnv ? ` for [env.${wranglerEnv}]` : '') +\n '. Run `deepspace init` (or `deepspace init --env <name>`) and retry.',\n )\n}\n\nfunction readAppName(appDir: string, wranglerEnv?: string): string {\n if (!hasWranglerConfig(appDir)) {\n throw new Error('No wrangler.toml found. Are you in a DeepSpace app directory?')\n }\n const config = readWranglerConfig(appDir)\n // Single source of truth — every command (deploy, dev, undeploy)\n // resolves through `resolveAppNameForEnv` so the validation rules\n // (missing block, empty name, collision with the top-level name,\n // canonical form) can never drift between them.\n const resolved = resolveAppNameForEnv(config, wranglerEnv)\n if (!resolved.ok) throw new Error(resolved.reason)\n\n // Refuse to proceed when the declared name doesn't already match the\n // canonical form. Otherwise the canonical name lands on deployed bindings\n // and the registry, while the raw name persists in `[vars].APP_NAME` and\n // client-side `SCOPE_ID = app:${APP_NAME}` — splitting the identity across\n // surfaces. Failing here forces the dev to fix wrangler.toml once, after\n // which every surface reads from the same source of truth.\n const rawName = wranglerEnv ? config.env?.[wranglerEnv]?.name : config.name\n if (rawName !== resolved.name) {\n const where = wranglerEnv ? `[env.${wranglerEnv}].name` : '`name`'\n throw new Error(\n `wrangler.toml: ${where} \"${rawName}\" is not in canonical form. ` +\n `Update it to \"${resolved.name}\" and re-run.`,\n )\n }\n return resolved.name\n}\n\n/**\n * Mint a long-lived app-owner JWT from the auth worker.\n *\n * The caller passes their own short-lived user JWT (obtained via\n * `ensureToken()` from auth.ts) and the target env's auth URL. The auth\n * worker verifies the caller, signs a 10-year owner-scoped token bound to\n * `appName`, and returns it. This same token is used in dev (written into\n * `.dev.vars`) and in production (injected as a secret at deploy time).\n */\nexport async function mintAppOwnerJwt(\n authUrl: string,\n callerJwt: string,\n appName: string,\n): Promise<string> {\n const res = await fetch(`${authUrl}/api/auth/mint-app-token`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${callerJwt}`,\n },\n body: JSON.stringify({ appId: appName }),\n })\n if (!res.ok) {\n const err = await res.text().catch(() => '')\n throw new Error(`Failed to mint APP_OWNER_JWT (${res.status}): ${err}`)\n }\n const body = (await res.json()) as { token?: string; error?: string }\n if (!body.token) {\n throw new Error(`Auth worker returned no token: ${body.error ?? 'unknown error'}`)\n }\n return body.token\n}\n\n/**\n * Fetch the per-app HMAC identity token from the deploy worker. The starter's\n * /_deepspace/* proxy attaches this token on every call to the API worker so\n * the platform can verify the request originated from a known app. In\n * production this is minted at deploy time and injected as a Worker binding;\n * in local dev we fetch it via this endpoint, which is gated by app ownership.\n */\nexport async function fetchAppIdentityToken(\n deployUrl: string,\n callerJwt: string,\n appName: string,\n): Promise<string | null> {\n const res = await fetch(`${deployUrl}/api/apps/${encodeURIComponent(appName)}/identity-token`, { // appName carries the appId\n method: 'POST',\n headers: { Authorization: `Bearer ${callerJwt}` },\n })\n if (res.status === 404) {\n // App hasn't been deployed yet — pre-deploy dev workflow. The proxy will\n // 401 calls under /_deepspace/* until first deploy registers the app.\n return null\n }\n if (!res.ok) {\n const err = await res.text().catch(() => '')\n throw new Error(`Failed to fetch APP_IDENTITY_TOKEN (${res.status}): ${err}`)\n }\n const body = (await res.json()) as { token?: string; error?: string }\n if (!body.token) {\n throw new Error(`Deploy worker returned no token: ${body.error ?? 'unknown error'}`)\n }\n return body.token\n}\n\n/**\n * Keys the SDK manages in the top section of .dev.vars. They're rewritten\n * on every `deepspace dev`/`test`/`deploy` run from the platform's truth\n * (auth URL, owner JWT, identity token, etc.). Keys that match this set\n * are stripped from the top section on read so they don't double-write.\n *\n * Critically: this set is only consulted above the legacy/custom divider.\n * Once we cross that divider, content is preserved so older workspaces and\n * local-only non-secret vars are not clobbered. New app secrets should flow\n * through `npx deepspace secrets`, which renders a generated cache section.\n */\nconst SDK_MANAGED_KEYS = new Set([\n 'AUTH_JWT_PUBLIC_KEY',\n 'AUTH_JWT_ISSUER',\n 'AUTH_WORKER_URL',\n 'API_WORKER_URL',\n 'PLATFORM_WORKER_URL',\n 'OWNER_USER_ID',\n 'APP_OWNER_JWT',\n 'APP_IDENTITY_TOKEN',\n 'ALLOW_DEBUG_ROUTES',\n])\n\n// Marker the SDK writes between its own keys and user-managed content. We\n// recognize and strip this line on read so it doesn't accumulate across runs.\nexport const DEV_VARS_DIVIDER = '# --- not managed by the SDK; preserved across dev/test runs ---'\n\n\ninterface WriteDevVarsOptions {\n /** The app's immutable id when the caller already resolved it; read from\n * wrangler.toml otherwise. */\n appId?: string\n /**\n * Remote app secrets rendered as a generated dotenv cache. When present,\n * this replaces the legacy preserved section so the remote store stays the\n * source of truth.\n */\n generatedSecretsCache?: string\n /**\n * Linked secrets configs use a shared `.dev.vars` cache across Wrangler envs.\n * Unlinked apps keep Wrangler's legacy `.dev.vars.<env>` convention.\n */\n sharedDevVarsCache?: boolean\n}\n\n/**\n * Strip SDK-managed lines from an existing .dev.vars file, preserving all\n * other content (comments, blank lines, custom KEY=value pairs, multi-line\n * quoted values). Also strips the SDK divider marker so it doesn't double\n * up across runs.\n *\n * Exported for testing.\n */\nexport function extractCustomDevVars(content: string): string {\n const lines = content.split('\\n')\n const out: string[] = []\n // SDK-managed keys are only stripped above the divider. Once we cross\n // into the legacy/custom section, every line is preserved verbatim so\n // older workspaces and local-only non-secret vars survive rewrites.\n let belowDivider = false\n let i = 0\n while (i < lines.length) {\n const line = lines[i]\n if (line.trim() === DEV_VARS_DIVIDER.trim()) {\n // Drop our own divider — writeDevVars will re-add a single one.\n belowDivider = true\n i++\n continue\n }\n const eq = line.indexOf('=')\n const keyMatch = eq >= 0 ? line.slice(0, eq).match(/^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*$/) : null\n if (!keyMatch) {\n // Comment, blank, or non-key line — preserve verbatim.\n out.push(line)\n i++\n continue\n }\n const key = keyMatch[1]\n const valStart = line.slice(eq + 1)\n const block: string[] = [line]\n // Multi-line quoted value: opens with `\"` and the rest of the line has no\n // closing quote. Keep accumulating until a closing `\"` lands.\n if (valStart.startsWith('\"') && !hasUnescapedQuote(valStart.slice(1))) {\n i++\n while (i < lines.length) {\n block.push(lines[i])\n const closed = hasUnescapedQuote(lines[i])\n i++\n if (closed) break\n }\n } else {\n i++\n }\n if (belowDivider || !SDK_MANAGED_KEYS.has(key)) {\n out.push(...block)\n }\n }\n // Trim trailing blanks so we don't accumulate them across runs.\n while (out.length && out[out.length - 1].trim() === '') out.pop()\n return out.join('\\n')\n}\n\nfunction hasUnescapedQuote(s: string): boolean {\n let escaped = false\n for (const ch of s) {\n if (escaped) {\n escaped = false\n continue\n }\n if (ch === '\\\\') {\n escaped = true\n continue\n }\n if (ch === '\"') return true\n }\n return false\n}\n\n/**\n * Parse a `.dev.vars` (dotenv) string into a key→value map.\n *\n * Handles:\n * - bare KEY=value\n * - KEY=\"quoted value\"\n * - multi-line KEY=\"-----BEGIN ...\\n-----END ...\"\n * - escaped quotes/backslashes inside (`KEY=\"he said \\\"hi\\\"\"` / `KEY=\"C:\\\\tmp\"`)\n * - comments and blank lines (skipped)\n *\n * Used for two things:\n * 1. parsing generated or legacy `.dev.vars` content so the CLI can ship\n * app-defined secrets as `secret_text` bindings at deploy time\n * 2. round-tripping for tests\n *\n * Exported.\n */\nexport function parseDevVars(content: string): Record<string, string> {\n const result: Record<string, string> = {}\n const lines = content.split('\\n')\n let i = 0\n while (i < lines.length) {\n const line = lines[i]\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith('#')) {\n i++\n continue\n }\n const eq = line.indexOf('=')\n if (eq < 0) {\n i++\n continue\n }\n const keyMatch = line.slice(0, eq).match(/^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*$/)\n if (!keyMatch) {\n i++\n continue\n }\n const key = keyMatch[1]\n let value = line.slice(eq + 1)\n\n // Multi-line quoted value: opens with `\"` and the rest of the line has\n // no closing quote. Keep accumulating until a closing `\"` lands.\n let closed = !value.startsWith('\"') || hasUnescapedQuote(value.slice(1))\n if (!closed) {\n i++\n while (i < lines.length) {\n value += '\\n' + lines[i]\n if (hasUnescapedQuote(lines[i])) {\n closed = true\n i++\n break\n }\n i++\n }\n } else {\n i++\n }\n\n // Reject unterminated quoted values rather than silently corrupting the\n // secret. Without this guard, a `KEY=\"value with no closing quote` line\n // would round-trip through deploy as a literal leading `\"` in the value\n // — a near-impossible bug to debug in production.\n if (value.startsWith('\"') && !closed) {\n throw new Error(\n `parseDevVars: unterminated quoted value for key \"${key}\" — check your .dev.vars file for a missing closing quote.`,\n )\n }\n\n // Strip surrounding quotes and decode the same two escapes emitted by\n // generated secrets cache rendering. Other backslash sequences are left\n // untouched for compatibility with manually-authored dotenv files.\n if (value.startsWith('\"') && value.endsWith('\"') && value.length >= 2) {\n value = unescapeQuotedDevVar(value.slice(1, -1))\n }\n\n result[key] = value\n }\n return result\n}\n\nfunction unescapeQuotedDevVar(value: string): string {\n let out = ''\n for (let i = 0; i < value.length; i++) {\n const ch = value[i]\n if (ch !== '\\\\' || i === value.length - 1) {\n out += ch\n continue\n }\n const next = value[i + 1]\n if (next === '\\\\' || next === '\"') {\n out += next\n i++\n continue\n }\n out += ch\n }\n return out\n}\n\n/**\n * Write .dev.vars for an app, pointing to the specified environment's workers.\n *\n * Only the SDK-managed keys (see `SDK_MANAGED_KEYS`) are rewritten on each\n * call. Existing non-generated lines are preserved for compatibility, but app\n * secrets should be managed with `npx deepspace secrets`, not direct edits.\n *\n * Includes a freshly-minted `APP_OWNER_JWT` so server-side code in the app\n * (DO alarms, cron handlers, autonomous agents) can call the API worker\n * proxy without any further auth plumbing. Uses the same flow as production:\n * the auth-worker mints the token, we store it as an env var.\n */\nexport async function writeDevVars(\n appDir: string,\n ownerId: string,\n callerJwt: string,\n /** Wrangler [env.<name>] block to target. When set, mints\n * APP_OWNER_JWT for that env's app (each env carries its own id). */\n wranglerEnv?: string,\n opts: WriteDevVarsOptions = {},\n): Promise<void> {\n const urls = PLATFORM_URLS\n const publicKey = await fetchPublicKey(urls.auth)\n // Tokens key to the immutable app id (docs/proposals/app-identity-registry.md);\n // renames never rotate identity. `deepspace init` mints the id for repos\n // that predate it.\n const appId = opts.appId ?? requireAppIdFor(appDir, wranglerEnv)\n const appOwnerJwt = await mintAppOwnerJwt(urls.auth, callerJwt, appId)\n // Pre-first-deploy this returns null (the app isn't in the registry yet)\n // — that's expected. The /_deepspace/* proxy will start working after the\n // first `deepspace deploy` registers the app and a follow-up\n // `deepspace dev` re-runs this writer.\n const appIdentityToken = await fetchAppIdentityToken(urls.deploy, callerJwt, appId)\n\n // Wrangler's .dev.vars parser is dotenv-style: bare multi-line values are\n // truncated to the first line. The PEM public key spans multiple lines, so\n // it MUST be wrapped in double quotes (dotenv multi-line value syntax).\n // Without this, AUTH_JWT_PUBLIC_KEY ends up as just \"-----BEGIN PUBLIC KEY-----\"\n // and `importSPKI` throws `DataError: Invalid SPKI input`, which silently\n // breaks JWT verification on every WS connection (anonymous fallback).\n const sdkVars = [\n `AUTH_JWT_PUBLIC_KEY=\"${publicKey}\"`,\n `AUTH_JWT_ISSUER=${urls.auth}/api/auth`,\n `AUTH_WORKER_URL=${urls.auth}`,\n `API_WORKER_URL=${urls.api}`,\n `PLATFORM_WORKER_URL=${urls.platform}`,\n `OWNER_USER_ID=${ownerId}`,\n `APP_OWNER_JWT=${appOwnerJwt}`,\n ...(appIdentityToken ? [`APP_IDENTITY_TOKEN=${appIdentityToken}`] : []),\n // Open /api/debug/* (proxied to RecordRoom) locally. This is the SDK's\n // dev-only auto-value; the deploy ships the remote store, not this\n // `.dev.vars` section, so it never reaches prod. To enable it on a deployed\n // env, `deepspace secrets set ALLOW_DEBUG_ROUTES=true`.\n `ALLOW_DEBUG_ROUTES=true`,\n ].join('\\n')\n\n const useSharedDevVarsCache = opts.sharedDevVarsCache ?? opts.generatedSecretsCache !== undefined\n const devVarsPath = devVarsPathFor(appDir, wranglerEnv, {\n sharedDevVarsCache: useSharedDevVarsCache,\n })\n const existing = existsSync(devVarsPath) ? readFileSync(devVarsPath, 'utf-8') : ''\n const custom =\n opts.generatedSecretsCache ?? extractCustomDevVars(stripGeneratedSecretsCache(existing).trimEnd())\n let body: string\n if (!custom) {\n body = `${sdkVars}\\n`\n } else if (opts.generatedSecretsCache) {\n // The cache section carries its own divider header.\n body = `${sdkVars}\\n\\n${custom}\\n`\n } else {\n body = `${sdkVars}\\n\\n${DEV_VARS_DIVIDER}\\n${custom}\\n`\n }\n\n writeSecretFileSync(devVarsPath, body)\n}\n","/**\n * Binding Manifest — non-DO bindings declared by an app's wrangler.toml that\n * the deploy-worker should pass through to Cloudflare's WfP upload API.\n *\n * Apps don't export a `__BINDING_MANIFEST__`; the CLI extracts these from the\n * normalized vite/wrangler output config at deploy time. This file just owns\n * the types + validation so both sides (CLI client and deploy-worker server)\n * agree on the shape.\n */\n/// <reference types=\"@cloudflare/workers-types\" />\n\n/**\n * A single non-DO binding the app declares. Mirrors CF's WfP binding API.\n *\n * Provisionable resources (d1, kv_namespace, vectorize, r2_bucket, queue) accept\n * the literal string `\"auto\"` in their ID field to request platform-side\n * provisioning at deploy time. When `\"auto\"` is used, the deploy-worker creates\n * the resource on the platform CF account, persists the resulting CF ID in the\n * app registry, and substitutes the real ID before forwarding to WfP. The\n * sentinel sticks around in this type because:\n * 1. `wrangler` parsing requires a non-empty string in the id field\n * 2. The CLI passes the unresolved manifest through to the deploy-worker\n * 3. The deploy-worker is the only side with CF API credentials\n *\n * Companion fields (`database_name`, `title`, `dimensions`, `metric`) are only\n * used when `\"auto\"` is set — they tell the provisioner how to create the\n * resource. After provisioning these fields are still present on the wire but\n * ignored by WfP.\n */\nexport type CustomBinding =\n | {\n type: 'vectorize'\n name: string\n /** Either a pre-existing index name or the literal `\"auto\"`. */\n index_name: string\n /** Required when `index_name === \"auto\"`. */\n dimensions?: number\n /** Required when `index_name === \"auto\"`. */\n metric?: 'cosine' | 'euclidean' | 'dot-product'\n }\n | { type: 'ai'; name: string }\n | {\n type: 'r2_bucket'\n name: string\n /** Either a pre-existing bucket name or the literal `\"auto\"`. */\n bucket_name: string\n }\n | {\n type: 'kv_namespace'\n name: string\n /** Either a pre-existing KV namespace ID or the literal `\"auto\"`. */\n namespace_id: string\n /** Required when `namespace_id === \"auto\"`. Human-readable namespace title. */\n title?: string\n }\n | {\n type: 'd1'\n name: string\n /** Either a pre-existing D1 database UUID or the literal `\"auto\"`. */\n id: string\n /** Required when `id === \"auto\"`. Human-readable database name. */\n database_name?: string\n }\n | {\n type: 'queue'\n name: string\n /** Either a pre-existing queue name or the literal `\"auto\"`. */\n queue_name: string\n }\n | { type: 'browser_rendering'; name: string }\n | { type: 'analytics_engine'; name: string; dataset?: string }\n | { type: 'hyperdrive'; name: string; id: string }\n\nexport type CustomBindingManifest = CustomBinding[]\n\n/** Sentinel string in an ID field that requests platform-side provisioning. */\nexport const AUTO_PROVISION_SENTINEL = 'auto'\n\n/** Binding types whose ID field accepts the `\"auto\"` sentinel for provisioning. */\nexport const AUTO_PROVISIONABLE_TYPES = new Set([\n 'd1',\n 'kv_namespace',\n 'vectorize',\n 'r2_bucket',\n 'queue',\n])\n\n/** Vectorize metric values accepted by CF when creating an index. */\nconst VECTORIZE_METRICS = new Set(['cosine', 'euclidean', 'dot-product'])\n\n/**\n * True if a binding has the `\"auto\"` sentinel in its primary ID field. Used by\n * the deploy-worker to decide which entries need provisioning and by the\n * validator to enforce companion-field requirements.\n */\nexport function isAutoProvision(b: CustomBinding): boolean {\n switch (b.type) {\n case 'd1':\n return b.id === AUTO_PROVISION_SENTINEL\n case 'kv_namespace':\n return b.namespace_id === AUTO_PROVISION_SENTINEL\n case 'vectorize':\n return b.index_name === AUTO_PROVISION_SENTINEL\n case 'r2_bucket':\n return b.bucket_name === AUTO_PROVISION_SENTINEL\n case 'queue':\n return b.queue_name === AUTO_PROVISION_SENTINEL\n default:\n return false\n }\n}\n\n/** Binding `type` values an app is allowed to declare. */\nexport const ALLOWED_BINDING_TYPES = new Set([\n 'vectorize',\n 'ai',\n 'r2_bucket',\n 'kv_namespace',\n 'd1',\n 'queue',\n 'browser_rendering',\n 'analytics_engine',\n 'hyperdrive',\n])\n\n/**\n * Binding NAMES the SDK reserves on every app — apps may not redeclare them.\n *\n * Includes:\n * - Static-asset + service bindings the platform sets up automatically.\n * - SDK-managed env (auth, identity, owner JWT).\n * - The auto-attached cost-tracking AE dataset (`USAGE_EVENTS`).\n *\n * DO binding names (RECORD_ROOMS, YJS_ROOMS, etc.) are NOT in this set\n * because they live in a separate manifest (`__DO_MANIFEST__`).\n */\nexport const RESERVED_BINDING_NAMES = new Set([\n 'ASSETS',\n 'PLATFORM_WORKER',\n 'API_WORKER',\n 'APP_NAME',\n 'OWNER_USER_ID',\n 'AUTH_JWT_PUBLIC_KEY',\n 'AUTH_JWT_ISSUER',\n 'AUTH_WORKER_URL',\n 'APP_IDENTITY_TOKEN',\n 'APP_OWNER_JWT',\n 'USAGE_EVENTS',\n])\n\n/**\n * Per-binding validation error. `binding` is undefined for top-level\n * shape failures (e.g. manifest is not an array).\n */\nexport interface ValidationError {\n binding?: CustomBinding\n reason: string\n}\n\n/**\n * Validate a binding manifest. Returns errors; an empty array means valid.\n *\n * Used both client-side (CLI) for friendly fail-fast and server-side\n * (deploy-worker) as a security boundary — apps can't sneak in reserved\n * binding names by editing the wire format.\n */\nexport function validateBindingManifest(\n manifest: unknown,\n): { valid: true; bindings: CustomBindingManifest } | { valid: false; errors: ValidationError[] } {\n if (!Array.isArray(manifest)) {\n return { valid: false, errors: [{ reason: 'Manifest must be an array' }] }\n }\n const errors: ValidationError[] = []\n const seenNames = new Set<string>()\n for (const entry of manifest) {\n if (!entry || typeof entry !== 'object') {\n errors.push({ reason: `Entry must be an object (got ${entry === null ? 'null' : typeof entry})` })\n continue\n }\n const e = entry as Record<string, unknown>\n const type = e.type\n const name = e.name\n if (typeof type !== 'string' || !ALLOWED_BINDING_TYPES.has(type)) {\n errors.push({\n reason: `Disallowed binding type: ${typeof type === 'string' ? type : `(${typeof type})`}. Allowed: ${[...ALLOWED_BINDING_TYPES].sort().join(', ')}`,\n })\n continue\n }\n if (typeof name !== 'string' || !name) {\n errors.push({ reason: `Binding of type \"${type}\" missing 'name' (string)` })\n continue\n }\n if (RESERVED_BINDING_NAMES.has(name)) {\n errors.push({ reason: `Binding name \"${name}\" is reserved by the SDK` })\n continue\n }\n if (seenNames.has(name)) {\n errors.push({ reason: `Duplicate binding name \"${name}\"` })\n continue\n }\n seenNames.add(name)\n // Now safely typed: type is in ALLOWED_BINDING_TYPES + name is a string.\n const binding = entry as CustomBinding\n const fieldErr = requiredFieldError(binding)\n if (fieldErr) errors.push({ binding, reason: fieldErr })\n }\n if (errors.length) return { valid: false, errors }\n return { valid: true, bindings: manifest as CustomBindingManifest }\n}\n\nfunction requiredFieldError(b: CustomBinding): string | null {\n switch (b.type) {\n case 'vectorize': {\n if (!b.index_name) return `vectorize binding \"${b.name}\" missing index_name (or \"auto\")`\n if (b.index_name === AUTO_PROVISION_SENTINEL) {\n // Auto-provisioning needs the index shape upfront — CF requires both\n // dimensions and metric at index-create time.\n if (typeof b.dimensions !== 'number' || b.dimensions <= 0) {\n return `vectorize binding \"${b.name}\" with index_name=\"auto\" requires \"dimensions\" (positive number)`\n }\n if (!b.metric || !VECTORIZE_METRICS.has(b.metric)) {\n return `vectorize binding \"${b.name}\" with index_name=\"auto\" requires \"metric\" (one of: ${[...VECTORIZE_METRICS].join(', ')})`\n }\n }\n return null\n }\n case 'r2_bucket':\n return b.bucket_name ? null : `r2_bucket binding \"${b.name}\" missing bucket_name (or \"auto\")`\n case 'kv_namespace': {\n if (!b.namespace_id) return `kv_namespace binding \"${b.name}\" missing namespace_id (or \"auto\")`\n if (b.namespace_id === AUTO_PROVISION_SENTINEL && !b.title) {\n return `kv_namespace binding \"${b.name}\" with namespace_id=\"auto\" requires \"title\"`\n }\n return null\n }\n case 'd1': {\n if (!b.id) return `d1 binding \"${b.name}\" missing id (or \"auto\")`\n if (b.id === AUTO_PROVISION_SENTINEL && !b.database_name) {\n return `d1 binding \"${b.name}\" with id=\"auto\" requires \"database_name\"`\n }\n return null\n }\n case 'queue':\n return b.queue_name ? null : `queue binding \"${b.name}\" missing queue_name (or \"auto\")`\n case 'hyperdrive':\n // Hyperdrive auto-provisioning is out of scope for v1 (needs upstream\n // connection-string management). Only pre-existing IDs accepted.\n if (!b.id) return `hyperdrive binding \"${b.name}\" missing id`\n if (b.id === AUTO_PROVISION_SENTINEL) {\n return `hyperdrive binding \"${b.name}\": auto-provisioning not yet supported (provide a real id)`\n }\n return null\n case 'ai':\n case 'browser_rendering':\n case 'analytics_engine':\n return null // no required fields beyond `name`\n default: {\n // Exhaustiveness guard — adding a new variant without a case fails here.\n const _exhaustive: never = b\n void _exhaustive\n return null\n }\n }\n}\n\n/**\n * Convert vite/wrangler's normalized config (from `.wrangler/deploy/config.json`)\n * into a CustomBindingManifest.\n *\n * Vite normalizes wrangler.toml into object/array structures with shapes like\n * `{ ai: { binding: 'AI' } }`, `{ vectorize: [{ binding, index_name }] }`,\n * etc. We extract each known shape with explicit field plucks (no broad\n * `as` casts) and return a flat array.\n */\nexport function bindingManifestFromOutputConfig(\n outputConfig: Record<string, unknown>,\n): CustomBindingManifest {\n const out: CustomBindingManifest = []\n\n // ai: single object\n const aiBinding = pluckString(outputConfig.ai, 'binding')\n if (aiBinding) out.push({ type: 'ai', name: aiBinding })\n\n // vectorize: array of { binding, index_name, dimensions?, metric? }\n // `dimensions` and `metric` are only required when index_name === \"auto\"\n // (auto-provisioning); the validator enforces that, so we just pluck both\n // here and let it decide.\n for (const v of asObjectArray(outputConfig.vectorize)) {\n const name = pluckString(v, 'binding')\n const index_name = pluckString(v, 'index_name')\n if (!name || !index_name) continue\n const dimensions = pluckNumber(v, 'dimensions')\n const metric = pluckString(v, 'metric')\n out.push({\n type: 'vectorize',\n name,\n index_name,\n ...(dimensions != null && { dimensions }),\n ...(metric && (metric === 'cosine' || metric === 'euclidean' || metric === 'dot-product') && { metric }),\n })\n }\n\n // r2_buckets: array of { binding, bucket_name }\n for (const r of asObjectArray(outputConfig.r2_buckets)) {\n const name = pluckString(r, 'binding')\n const bucket_name = pluckString(r, 'bucket_name')\n if (name && bucket_name) out.push({ type: 'r2_bucket', name, bucket_name })\n }\n\n // kv_namespaces: array of { binding, id, title? }\n // `title` is only required when id === \"auto\"; pluck both here and let\n // the validator enforce the dependency.\n for (const k of asObjectArray(outputConfig.kv_namespaces)) {\n const name = pluckString(k, 'binding')\n const namespace_id = pluckString(k, 'id')\n if (!name || !namespace_id) continue\n const title = pluckString(k, 'title')\n out.push({\n type: 'kv_namespace',\n name,\n namespace_id,\n ...(title && { title }),\n })\n }\n\n // d1_databases: array of { binding, database_id, database_name? }\n // `database_name` is only required when database_id === \"auto\"; pluck both\n // and let the validator enforce.\n for (const d of asObjectArray(outputConfig.d1_databases)) {\n const name = pluckString(d, 'binding')\n const id = pluckString(d, 'database_id')\n if (!name || !id) continue\n const database_name = pluckString(d, 'database_name')\n out.push({\n type: 'd1',\n name,\n id,\n ...(database_name && { database_name }),\n })\n }\n\n // queues.producers: array of { binding, queue }\n const queues = isObject(outputConfig.queues) ? outputConfig.queues : null\n for (const q of asObjectArray(queues?.producers)) {\n const name = pluckString(q, 'binding')\n const queue_name = pluckString(q, 'queue')\n if (name && queue_name) out.push({ type: 'queue', name, queue_name })\n }\n\n // browser: { binding } (Cloudflare names this `browser` not `browser_rendering`)\n const browserBinding = pluckString(outputConfig.browser, 'binding')\n if (browserBinding) out.push({ type: 'browser_rendering', name: browserBinding })\n\n // analytics_engine_datasets: array of { binding, dataset? }\n for (const a of asObjectArray(outputConfig.analytics_engine_datasets)) {\n const name = pluckString(a, 'binding')\n const dataset = pluckString(a, 'dataset')\n if (name) out.push({ type: 'analytics_engine', name, dataset: dataset ?? undefined })\n }\n\n // hyperdrive: array of { binding, id }\n for (const h of asObjectArray(outputConfig.hyperdrive)) {\n const name = pluckString(h, 'binding')\n const id = pluckString(h, 'id')\n if (name && id) out.push({ type: 'hyperdrive', name, id })\n }\n\n return out\n}\n\n// ---- internal helpers (no broad `as` casts) ----\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v)\n}\n\nfunction pluckString(v: unknown, key: string): string | null {\n if (!isObject(v)) return null\n const val = v[key]\n return typeof val === 'string' && val.length > 0 ? val : null\n}\n\nfunction pluckNumber(v: unknown, key: string): number | null {\n if (!isObject(v)) return null\n const val = v[key]\n return typeof val === 'number' && Number.isFinite(val) ? val : null\n}\n\nfunction asObjectArray(v: unknown): Record<string, unknown>[] {\n if (!Array.isArray(v)) return []\n return v.filter(isObject)\n}\n","/**\n * App secrets — client helpers for the app-anchored store\n * (docs/proposals/app-identity-registry.md §4.3).\n *\n * Every app has exactly one store, addressed by its immutable id:\n * `/api/secrets/:appId/configs/:config/...` on the deploy worker. Configs\n * follow the wrangler-env convention: the top-level config is `prd`, an\n * `--env staging` deploy ships the `staging` config. There are no per-user\n * projects and no app↔project links — those concepts are gone.\n */\n\nimport { RESERVED_BINDING_NAMES } from '../../server/rooms/binding-manifest'\n\nexport const GENERATED_SECRETS_DIVIDER =\n '# --- DeepSpace secrets cache: generated by `npx deepspace secrets`; do not edit manually ---'\n\n/**\n * Names a user may not set as an app secret. `RESERVED_BINDING_NAMES` covers\n * runtime bindings the platform injects; `API_WORKER_URL`/`PLATFORM_WORKER_URL`\n * are SDK-managed env that isn't a binding (so absent from that set) but is\n * still platform-owned. `ALLOW_DEBUG_ROUTES` is deliberately NOT here — it's a\n * normal, user-settable flag. Rejecting these client-side gives a clear message\n * instead of a raw server `(400)` that leaks the API path.\n */\nconst RESERVED_SECRET_NAMES = new Set([\n ...RESERVED_BINDING_NAMES,\n 'API_WORKER_URL',\n 'PLATFORM_WORKER_URL',\n])\n\nexport const SECRET_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/\nexport const CONFIG_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/\nconst MAX_SECRET_VALUE_BYTES = 32 * 1024\n\nexport interface SecretListItem {\n key: string\n version: number\n updatedAt: string\n updatedBy: string\n}\n\nexport interface SecretsConfigInfo {\n name: string\n createdAt: string\n updatedAt: string\n secretCount?: number\n}\n\nexport interface PulledSecretsCache {\n appId: string\n configName: string\n values: Record<string, string>\n}\n\nexport type SecretsDownloadFormat = 'dotenv' | 'json' | 'shell'\n\nexport function validateConfigName(configName: string): string {\n if (!CONFIG_NAME_RE.test(configName)) {\n throw new Error(\n `Invalid config \"${configName}\". Use letters, numbers, underscores, or hyphens; start with a letter or number.`,\n )\n }\n return configName\n}\n\nexport function validateSecretName(name: string): string {\n if (!SECRET_NAME_RE.test(name)) {\n throw new Error(\n `Invalid secret name \"${name}\". Use letters, numbers, and underscores; start with a letter or underscore.`,\n )\n }\n if (RESERVED_SECRET_NAMES.has(name)) {\n throw new Error(\n `\"${name}\" is managed by the DeepSpace SDK and can't be set as an app secret — ` +\n 'the platform injects it at deploy time.',\n )\n }\n return name\n}\n\nexport function validateSecretValue(key: string, value: string): void {\n if (new TextEncoder().encode(value).byteLength > MAX_SECRET_VALUE_BYTES) {\n throw new Error(`Secret \"${key}\" exceeds ${MAX_SECRET_VALUE_BYTES} bytes`)\n }\n}\n\n/** Config convention: top-level deploys/dev use `prd`; a wrangler env uses\n * its own name. */\nexport function defaultConfigNameForEnv(wranglerEnv?: string): string {\n return wranglerEnv ?? 'prd'\n}\n\n// ── HTTP plumbing ────────────────────────────────────────────────────────────\n\nexport async function secretsApi<T>(\n deployUrl: string,\n token: string,\n path: string,\n init: RequestInit = {},\n): Promise<T> {\n const res = await fetch(`${deployUrl}/api/secrets${path}`, {\n ...init,\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n ...(init.headers ?? {}),\n },\n })\n const body = (await res.json().catch(() => ({}))) as T & { error?: string }\n if (!res.ok) {\n // Surface the server's sentence, not the internal `/api/secrets/app_…/…`\n // slug — that path is an implementation detail and reads like a bug to\n // users. `status` carries the code for programmatic branches; set DEBUG=1\n // (via cli-errors) for the full error. `apiPath` is kept for debugging.\n const err = new Error(body.error ?? `Secrets request failed (${res.status})`) as Error & {\n status?: number\n apiPath?: string\n }\n err.status = res.status\n err.apiPath = path\n throw err\n }\n return body\n}\n\nexport function listSecrets(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n): Promise<{ secrets: SecretListItem[] }> {\n return secretsApi(deployUrl, token, `/${appId}/configs/${encodeURIComponent(configName)}`)\n}\n\nexport function fetchSecretsValues(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n): Promise<{ secrets: Record<string, string> }> {\n return secretsApi(deployUrl, token, `/${appId}/configs/${encodeURIComponent(configName)}/values`)\n}\n\nexport function getSecretPlain(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n key: string,\n): Promise<{ key: string; value: string }> {\n return secretsApi(\n deployUrl,\n token,\n `/${appId}/configs/${encodeURIComponent(configName)}/secrets/${encodeURIComponent(key)}?plain=true`,\n )\n}\n\nexport function setSecret(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n key: string,\n value: string,\n): Promise<{ ok: boolean }> {\n return secretsApi(\n deployUrl,\n token,\n `/${appId}/configs/${encodeURIComponent(configName)}/secrets/${encodeURIComponent(key)}`,\n { method: 'PUT', body: JSON.stringify({ value }) },\n )\n}\n\nexport function deleteSecret(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n key: string,\n): Promise<{ ok: boolean }> {\n return secretsApi(\n deployUrl,\n token,\n `/${appId}/configs/${encodeURIComponent(configName)}/secrets/${encodeURIComponent(key)}`,\n { method: 'DELETE' },\n )\n}\n\nexport function uploadSecrets(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n secrets: Record<string, string>,\n replace: boolean,\n): Promise<{ ok: boolean }> {\n return secretsApi(\n deployUrl,\n token,\n `/${appId}/configs/${encodeURIComponent(configName)}/secrets`,\n { method: 'PUT', body: JSON.stringify({ secrets, replace }) },\n )\n}\n\nexport function listConfigs(\n deployUrl: string,\n token: string,\n appId: string,\n): Promise<{ configs: SecretsConfigInfo[] }> {\n return secretsApi(deployUrl, token, `/${appId}/configs`)\n}\n\nexport function createConfig(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n copyFrom?: string,\n): Promise<{ ok: boolean }> {\n return secretsApi(deployUrl, token, `/${appId}/configs`, {\n method: 'POST',\n body: JSON.stringify({ name: configName, ...(copyFrom ? { copyFrom } : {}) }),\n })\n}\n\nexport function deleteConfig(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n): Promise<{ ok: boolean }> {\n return secretsApi(deployUrl, token, `/${appId}/configs/${encodeURIComponent(configName)}`, {\n method: 'DELETE',\n })\n}\n\n/**\n * Pull the app's config values for dev/test/deploy caches. Missing store or\n * config is NOT an error — a fresh app simply has no secrets yet.\n */\nexport async function pullAppSecretsCache(\n deployUrl: string,\n token: string,\n appId: string,\n configName: string,\n): Promise<PulledSecretsCache | null> {\n try {\n const { secrets } = await fetchSecretsValues(deployUrl, token, appId, configName)\n return { appId, configName, values: secrets }\n } catch (err) {\n // 404: no store yet, or no such config. Both mean \"nothing to ship\". Match\n // on the status field, not the message (which no longer carries the code).\n if ((err as { status?: number })?.status === 404) return null\n throw err\n }\n}\n\n// ── Cache rendering / parsing ────────────────────────────────────────────────\n\nexport function quoteDotenvValue(value: string): string {\n if (/^[A-Za-z0-9_./:@+-]*$/.test(value) && value !== '') return value\n // Newlines must be escaped or the value's tail parses as extra env vars;\n // dotenv expands \\n / \\r inside double-quoted values.\n const escaped = value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n return `\"${escaped}\"`\n}\n\n/** Render pulled values as the generated `.dev.vars` cache section. */\nexport function renderSecretsCache(\n secrets: Record<string, string>,\n source: { appId: string; configName: string },\n): string {\n const keys = Object.keys(secrets).sort()\n const lines = [\n GENERATED_SECRETS_DIVIDER,\n `# app ${source.appId} · config ${source.configName}`,\n '# Use `npx deepspace secrets` to change these values.',\n ]\n for (const key of keys) {\n validateSecretValue(key, secrets[key])\n lines.push(`${key}=${quoteDotenvValue(secrets[key])}`)\n }\n return lines.join('\\n')\n}\n\n/** Strip a previously generated cache section from a `.dev.vars` body. */\nexport function stripGeneratedSecretsCache(content: string): string {\n const idx = content.indexOf(GENERATED_SECRETS_DIVIDER)\n if (idx === -1) return content\n return content.slice(0, idx).trimEnd() + '\\n'\n}\n\n// ── Upload/download formats (Doppler-compatible) ─────────────────────────────\n\nexport function parseSecretsUpload(content: string): Record<string, string> {\n const trimmed = content.trim()\n if (!trimmed) return {}\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n const parsed = JSON.parse(trimmed) as unknown\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('JSON upload must be an object of KEY=value strings.')\n }\n const out: Record<string, string> = {}\n for (const [key, value] of Object.entries(parsed)) {\n validateSecretName(key)\n if (typeof value !== 'string') throw new Error(`Secret \"${key}\" must be a string`)\n validateSecretValue(key, value)\n out[key] = value\n }\n return out\n }\n // dotenv — supports multiline quoted values (dotenv ≥15 semantics): a value\n // whose opening quote isn't closed on its own line continues, verbatim,\n // until a line ending with the closing quote. Without this, uploading a\n // .env holding a real PEM silently stored one byte and minted phantom keys\n // from the base64 continuation lines.\n const out: Record<string, string> = {}\n const lines = trimmed.split(/\\r?\\n/)\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim()\n if (!line || line.startsWith('#')) continue\n const eq = line.indexOf('=')\n if (eq <= 0) continue // junk line — tolerated, like comments\n const key = line.slice(0, eq).trim()\n if (!SECRET_NAME_RE.test(key)) continue\n validateSecretName(key) // reject reserved/SDK-managed names with a clear message, same as `set`\n const raw = line.slice(eq + 1).trim()\n const quote = raw[0] === '\"' || raw[0] === \"'\" ? raw[0] : null\n let value: string\n if (!quote) {\n value = raw\n } else if (endsWithUnescapedQuote(raw.slice(1), quote)) {\n const inner = raw.slice(1, -1)\n value = quote === '\"' ? unescapeDotenv(inner) : inner\n } else {\n // Multiline: consume raw (untrimmed) lines until one closes the quote.\n const startLine = i + 1\n const parts = [raw.slice(1)]\n let closed = false\n while (++i < lines.length) {\n const cont = lines[i].trimEnd()\n if (endsWithUnescapedQuote(cont, quote)) {\n parts.push(cont.slice(0, -1))\n closed = true\n break\n }\n parts.push(lines[i])\n }\n if (!closed) {\n throw new Error(\n `Unterminated quoted value for \"${key}\" (opens on line ${startLine}). ` +\n `Close the ${quote === '\"' ? 'double' : 'single'} quote, or escape newlines as \\\\n on one line.`,\n )\n }\n value = parts.join('\\n')\n if (quote === '\"') value = unescapeDotenv(value)\n }\n validateSecretValue(key, value)\n out[key] = value\n }\n return out\n}\n\n/** True when `s` is non-empty and ends with `q` not preceded by an odd run of\n * backslashes (only `\"` values support escapes; `'` closes unconditionally). */\nfunction endsWithUnescapedQuote(s: string, q: string): boolean {\n if (!s.endsWith(q)) return false\n if (q === \"'\") return true\n let backslashes = 0\n for (let j = s.length - 2; j >= 0 && s[j] === '\\\\'; j--) backslashes++\n return backslashes % 2 === 0\n}\n\n/** Left-to-right so `\\\\n` (escaped backslash + n) isn't confused with `\\n`. */\nfunction unescapeDotenv(v: string): string {\n let out = ''\n for (let i = 0; i < v.length; i++) {\n if (v[i] === '\\\\' && i + 1 < v.length) {\n const c = v[++i]\n out += c === 'n' ? '\\n' : c === 'r' ? '\\r' : c\n } else {\n out += v[i]\n }\n }\n return out\n}\n\n/**\n * POSIX single-quote: wrap in `'…'`, closing/reopening around any embedded\n * single quote (`'\\''`). Unlike dotenv double-quoting, this preserves real\n * newlines literally, so `eval \"$(… download --format shell)\"` restores a\n * multiline value (e.g. a PEM key) byte-for-byte instead of a one-line `\\n`.\n */\nexport function shellSingleQuote(value: string): string {\n return `'${value.replace(/'/g, \"'\\\\''\")}'`\n}\n\nexport function formatSecretsDownload(\n secrets: Record<string, string>,\n format: SecretsDownloadFormat,\n): string {\n const entries = Object.entries(secrets).sort(([a], [b]) => a.localeCompare(b))\n if (format === 'json') {\n return JSON.stringify(Object.fromEntries(entries), null, 2) + '\\n'\n }\n if (format === 'shell') {\n return entries.map(([k, v]) => `export ${k}=${shellSingleQuote(v)}`).join('\\n') + '\\n'\n }\n return entries.map(([k, v]) => `${k}=${quoteDotenvValue(v)}`).join('\\n') + '\\n'\n}\n\n/**\n * The pull-and-render step every command shares (deploy/dev/test): fetch the\n * app's config values and render the generated `.dev.vars` cache section.\n * Returns null when the store/config doesn't exist yet (\"nothing to ship\").\n * Real failures (auth, 5xx) throw — callers cancel loudly.\n */\nexport async function refreshSecretsCache(\n deployUrl: string,\n token: string,\n appId: string,\n wranglerEnv: string | undefined,\n): Promise<{ pulled: PulledSecretsCache; rendered: string; summary: string } | null> {\n const configName = defaultConfigNameForEnv(wranglerEnv)\n const pulled = await pullAppSecretsCache(deployUrl, token, appId, configName)\n if (!pulled) return null\n const count = Object.keys(pulled.values).length\n return {\n pulled,\n rendered: renderSecretsCache(pulled.values, pulled),\n summary: `Secrets: ${pulled.configName} (${count} secret${count === 1 ? '' : 's'})`,\n }\n}\n","/**\n * App identity (docs/proposals/app-identity-registry.md).\n *\n * Every app carries an immutable id in wrangler.toml:\n *\n * [vars]\n * DEEPSPACE_APP_ID = \"app_01JG8QK…\" # minted at scaffold/init\n *\n * [env.staging.vars]\n * DEEPSPACE_APP_ID = \"app_01JG8QM…\" # each env is its own app\n *\n * The wrangler `name` field is just the subdomain label the next deploy\n * claims; identity is the id. Minting is local (a ULID — 80 random bits\n * need no server round-trip to be unique); registration happens at first\n * deploy.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport { parse as parseToml } from 'smol-toml'\n\nexport const APP_ID_RE = /^(app_[0-9A-HJKMNP-TV-Z]{26}|[a-z0-9][a-z0-9_-]{0,63})$/\n\nconst CROCKFORD = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'\n\n/** Mint a fresh app id: `app_` + 26-char ULID (48-bit ms timestamp + 80\n * random bits, Crockford base32). */\nexport function mintAppId(now = Date.now()): string {\n let ts = ''\n let t = now\n for (let i = 0; i < 10; i++) {\n ts = CROCKFORD[t % 32] + ts\n t = Math.floor(t / 32)\n }\n const rand = new Uint8Array(10)\n crypto.getRandomValues(rand)\n let rs = ''\n let acc = 0\n let bits = 0\n for (const byte of rand) {\n acc = (acc << 8) | byte\n bits += 8\n while (bits >= 5) {\n bits -= 5\n rs += CROCKFORD[(acc >> bits) & 31]\n }\n }\n return `app_${ts}${rs}`.slice(0, 30)\n}\n\n/** Outcome of looking for an app already registered at this name. */\nexport type ExistingAppResolution =\n /** A registered app the caller can deploy — reuse its id. `owned` is false\n * when access comes from the on-behalf matrix (collaborator/admin) rather\n * than ownership; callers must confirm before deploying those. */\n | { kind: 'adopted'; appId: string; owned: boolean }\n /** A registered app the caller CANNOT deploy — abort before minting. */\n | { kind: 'taken' }\n /** Nothing registered here → mint a fresh id. */\n | { kind: 'none' }\n\n/**\n * Resolve the app already registered at this subdomain, if any. A repo with no\n * `DEEPSPACE_APP_ID` must NOT blindly mint a fresh id: an app the platform\n * already registered — e.g. one backfilled during the app-identity cutover —\n * owns its route, so a fresh id would collide (\"name … is taken by another\n * app\"). Two probes:\n *\n * 1. The caller's own apps (`/api/apps`), matched by subdomain — the owner\n * redeploying a legacy repo.\n * 2. The name itself as a legacy id: backfilled apps use their name as their\n * appId, so a gated per-app read (`/api/apps/:appId/analytics`, the same\n * owner / collaborator / admin matrix deploy grants) answers in one call\n * whether the app exists and whether the caller may deploy it. 200 → adopt\n * (deploy runs on-behalf when the caller isn't the owner); 403 → the name\n * belongs to an app the caller can't deploy, so minting would only defer\n * the failure to a confusing route-claim collision — report `taken` so\n * deploy can fail with the real reason; 404 → nothing there.\n *\n * Best-effort otherwise: network errors and unexpected responses resolve to\n * `none` so the deploy still proceeds and mints, exactly as before.\n */\nexport async function resolveExistingAppId(\n deployUrl: string,\n token: string,\n appName: string,\n): Promise<ExistingAppResolution> {\n const headers = { Authorization: `Bearer ${token}` }\n\n try {\n const res = await fetch(`${deployUrl}/api/apps`, { headers })\n if (res.ok) {\n const body = (await res.json()) as {\n apps?: Array<{ appId?: string; name?: string | null }>\n }\n const match = body.apps?.find((a) => a.name === appName)\n if (match?.appId) return { kind: 'adopted', appId: match.appId, owned: true }\n }\n } catch {\n // fall through to the legacy-id probe\n }\n\n try {\n const res = await fetch(\n `${deployUrl}/api/apps/${encodeURIComponent(appName)}/analytics?period=1h`,\n { headers },\n )\n // Not in the owned list but the gated read authorizes → on-behalf access\n // (collaborator or admin). NOT ownership: for an admin this is true of\n // EVERY registered app, so the caller must confirm before deploying.\n if (res.ok) return { kind: 'adopted', appId: appName, owned: false }\n if (res.status === 403) return { kind: 'taken' }\n } catch {\n // best-effort: fall through\n }\n\n return { kind: 'none' }\n}\n\ninterface WranglerVars {\n vars?: Record<string, unknown>\n env?: Record<string, { vars?: Record<string, unknown> }>\n}\n\n/** Read DEEPSPACE_APP_ID for the given wrangler env (top-level when omitted).\n * Env blocks do NOT inherit the top-level id — each env is its own app. */\nexport function readAppId(cwd: string = process.cwd(), wranglerEnv?: string): string | null {\n const wranglerPath = join(resolve(cwd), 'wrangler.toml')\n if (!existsSync(wranglerPath)) return null\n let cfg: WranglerVars\n try {\n cfg = parseToml(readFileSync(wranglerPath, 'utf-8')) as WranglerVars\n } catch (err) {\n // A corrupt wrangler.toml must NOT read as \"no id yet\" — callers would\n // tell the user to run `deepspace init` (a lie) or mint a SECOND id\n // into the broken file. Surface the real problem.\n throw new Error(\n `Could not parse ${wranglerPath}: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n const vars = wranglerEnv ? cfg.env?.[wranglerEnv]?.vars : cfg.vars\n const id = vars?.DEEPSPACE_APP_ID\n return typeof id === 'string' && APP_ID_RE.test(id) ? id : null\n}\n\n/**\n * Write DEEPSPACE_APP_ID into wrangler.toml, text-preserving: appended to the\n * existing `[vars]` / `[env.<name>.vars]` block, or the block is created.\n * Refuses to overwrite an existing id unless `force` — identity is immutable;\n * a new id means a new app (`deepspace init --new-id`).\n */\nexport function writeAppId(\n cwd: string,\n appId: string,\n opts: { wranglerEnv?: string; force?: boolean } = {},\n): void {\n const wranglerPath = join(resolve(cwd), 'wrangler.toml')\n if (!existsSync(wranglerPath)) {\n throw new Error(`No wrangler.toml in ${resolve(cwd)}`)\n }\n const existing = readAppId(cwd, opts.wranglerEnv)\n if (existing && !opts.force) {\n if (existing === appId) return\n throw new Error(\n `wrangler.toml already carries ${existing}. The app id is immutable — use --new-id only to fork this repo as a separate app.`,\n )\n }\n\n let src = readFileSync(wranglerPath, 'utf-8')\n const header = opts.wranglerEnv ? `[env.${opts.wranglerEnv}.vars]` : '[vars]'\n const line = `DEEPSPACE_APP_ID = \"${appId}\"`\n const headerRe = new RegExp(`^\\\\${header.replace(/\\./g, '\\\\.')}[ \\\\t]*$`, 'm')\n const idLineRe = /^DEEPSPACE_APP_ID\\s*=.*$/m\n\n const match = headerRe.exec(src)\n if (match) {\n // Insert (or replace) inside the existing block: from the header to the\n // next section header or EOF.\n const blockStart = match.index + match[0].length\n const rest = src.slice(blockStart)\n const nextSection = rest.search(/^\\s*\\[/m)\n const blockEnd = nextSection === -1 ? src.length : blockStart + nextSection\n const block = src.slice(blockStart, blockEnd)\n const newBlock = idLineRe.test(block)\n ? block.replace(idLineRe, line)\n : `\\n${line}${block}`\n src = src.slice(0, blockStart) + newBlock + src.slice(blockEnd)\n } else {\n src = src.trimEnd() + `\\n\\n${header}\\n${line}\\n`\n }\n writeFileSync(wranglerPath, src)\n}\n\n/** Read the app id or fail with the actionable next step. */\nexport function requireAppId(cwd: string = process.cwd(), wranglerEnv?: string): string {\n const id = readAppId(cwd, wranglerEnv)\n if (id) return id\n const where = wranglerEnv ? `[env.${wranglerEnv}.vars]` : '[vars]'\n throw new Error(\n `wrangler.toml has no DEEPSPACE_APP_ID in ${where}. Run \\`deepspace init\\` to mint one (existing deployed apps get theirs from the migration backfill — see the app-identity runbook).`,\n )\n}\n","import { chmodSync, writeFileSync } from 'node:fs'\n\n/**\n * Write a file that holds plaintext secret values (`.dev.vars` caches,\n * `secrets download` output) readable by the owner only. `writeFileSync`'s\n * `mode` applies only when the file is created, so chmod separately to\n * tighten files that already exist with a wider mode.\n */\nexport function writeSecretFileSync(path: string, content: string): void {\n writeFileSync(path, content, { mode: 0o600 })\n try {\n chmodSync(path, 0o600)\n } catch {\n // POSIX modes are best-effort on Windows; the write itself succeeded.\n }\n}\n","/**\n * Wrangler env resolution for DeepSpace's multi-environment deploys.\n *\n * Lets a single repo deploy to `<app>.app.space` and `<app>-staging.app.space`\n * (or any other named environment) from one `wrangler.toml`:\n *\n * name = \"hopkins\"\n * [vars]\n * APP_NAME = \"hopkins\"\n *\n * [env.staging]\n * name = \"hopkins-staging\"\n * [env.staging.vars]\n * APP_NAME = \"hopkins-staging\"\n *\n * Then `npx deepspace deploy --env staging` reads the override and ships to\n * `hopkins-staging.app.space`. The platform treats it as a fully separate\n * app — its own DO state, OAuth tokens, Stripe products, cron schedule.\n * No platform-side change needed beyond letting the CLI register a second\n * app under the same owner.\n *\n * When an app links a remote secrets project, DeepSpace keeps generated\n * dev/test/deploy credentials in a single `.dev.vars` cache so named\n * environments do not leave extra local files. In that linked-secrets mode,\n * `--env` flattens the selected Wrangler env into a generated config for the\n * Cloudflare Vite plugin instead of passing `CLOUDFLARE_ENV`; otherwise\n * Wrangler would prefer legacy `.dev.vars.<env>` files over the shared cache.\n * Unlinked apps keep Wrangler's legacy env-file behavior.\n */\n\nimport { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { parse as parseToml, stringify as stringifyToml } from 'smol-toml'\nimport { resolveAppName } from '../../server/rooms/app-name'\n\n/** Shape of the bits of wrangler.toml that DeepSpace CLI commands read.\n * Add an optional field here whenever a new command starts consulting\n * the config — avoids one-off `WranglerConfig & { … }` casts at\n * call sites and keeps the canonical type in one place. */\nexport interface WranglerConfig {\n name?: string\n env?: Record<\n string,\n ({ name?: string; vars?: Record<string, unknown> } & Record<string, unknown>) | undefined\n >\n /** `[assets]` block (`directory`, `binding`, `not_found_handling`,\n * `run_worker_first`). Consumed by deploy.ts to merge extra\n * worker-first routes into the deployed metadata. */\n assets?: {\n directory?: string\n binding?: string\n not_found_handling?: string\n run_worker_first?: unknown\n }\n /** `[vars]` block — string-valued environment variables baked into\n * the worker at deploy time. */\n vars?: Record<string, unknown>\n}\n\nexport interface PreparedWranglerEnvConfig {\n configPath?: string\n wranglerEnv?: string\n cleanup(): void\n}\n\nexport interface WranglerEnvModeOptions {\n sharedDevVarsCache?: boolean\n}\n\ntype TomlRecord = Record<string, unknown>\n\nconst NON_INHERITABLE_ENV_KEYS = new Set([\n 'define',\n 'vars',\n 'durable_objects',\n 'kv_namespaces',\n 'r2_buckets',\n 'ai_search_namespaces',\n 'ai_search',\n 'vectorize',\n 'services',\n 'queues',\n 'workflows',\n 'tail_consumers',\n 'secrets',\n 'secrets_store_secrets',\n])\n\nlet generatedConfigSeq = 0\n\n/**\n * Resolve the appName that this CLI invocation should target.\n *\n * Without `envName`: returns the top-level `name`.\n * With `envName`: returns `[env.<envName>].name` and requires that the\n * env block exists and declares a name. We refuse to\n * fall back to the top-level name because that would\n * silently deploy staging code to production.\n *\n * Returns a discriminated union so callers can surface a precise error\n * (matches the existing `resolveAppName` contract).\n */\nexport function resolveAppNameForEnv(\n config: WranglerConfig,\n envName: string | undefined,\n): { ok: true; name: string; warning?: string } | { ok: false; reason: string } {\n if (!envName) {\n return resolveAppName(config.name)\n }\n const envBlock = config.env?.[envName]\n if (!envBlock) {\n return {\n ok: false,\n reason:\n `wrangler.toml: no [env.${envName}] block found. ` +\n `Add one with a distinct \\`name\\` to deploy this environment.`,\n }\n }\n if (typeof envBlock.name !== 'string' || envBlock.name.trim() === '') {\n return {\n ok: false,\n reason:\n `wrangler.toml: [env.${envName}].name is missing. ` +\n `Set a distinct app name (e.g. \"${typeof config.name === 'string' ? config.name : 'myapp'}-${envName}\") so this environment doesn't overwrite the default.`,\n }\n }\n if (envBlock.name === config.name) {\n return {\n ok: false,\n reason:\n `wrangler.toml: [env.${envName}].name \"${envBlock.name}\" is the same as the top-level name. ` +\n `Pick a distinct name (e.g. \"${config.name}-${envName}\") so deploys don't collide.`,\n }\n }\n return resolveAppName(envBlock.name)\n}\n\n/** The .dev.vars path for the selected mode. Linked secrets use a shared cache. */\nexport function devVarsPathFor(\n appDir: string,\n envName: string | undefined,\n opts: WranglerEnvModeOptions = {},\n): string {\n if (opts.sharedDevVarsCache || !envName) return join(appDir, '.dev.vars')\n return join(appDir, `.dev.vars.${envName}`)\n}\n\nexport function legacyEnvDevVarsPathFor(\n appDir: string,\n envName: string | undefined,\n): string | undefined {\n return envName ? join(appDir, `.dev.vars.${envName}`) : undefined\n}\n\nexport function warnIfLegacyEnvDevVarsExists(\n appDir: string,\n envName: string | undefined,\n warn: (message: string) => void = console.warn,\n): void {\n const legacyPath = legacyEnvDevVarsPathFor(appDir, envName)\n if (!legacyPath || !existsSync(legacyPath)) return\n warn(\n `Warning: ${legacyPath} exists, but DeepSpace now uses ${devVarsPathFor(appDir, envName, { sharedDevVarsCache: true })} ` +\n `for every environment. This run will ignore ${legacyPath}; move any secrets you still ` +\n `need into .dev.vars, then remove the env-specific file when you're ready.`,\n )\n}\n\nexport function prepareWranglerEnvConfig(\n appDir: string,\n envName: string | undefined,\n opts: { warn?: (message: string) => void } & WranglerEnvModeOptions = {},\n): PreparedWranglerEnvConfig {\n if (!envName) return { cleanup() {} }\n if (!opts.sharedDevVarsCache) return { wranglerEnv: envName, cleanup() {} }\n\n warnIfLegacyEnvDevVarsExists(appDir, envName, opts.warn)\n\n const config = readWranglerConfig(appDir)\n const resolved = resolveAppNameForEnv(config, envName)\n if (!resolved.ok) throw new Error(resolved.reason)\n const flattened = flattenWranglerEnvConfig(config as TomlRecord, envName)\n const configPath = join(\n appDir,\n `.wrangler.deepspace.${safeGeneratedConfigSegment(envName)}.${process.pid}.${++generatedConfigSeq}.toml`,\n )\n writeFileSync(\n configPath,\n [\n '# Generated by DeepSpace for this CLI run.',\n '# Do not edit; wrangler.toml remains the source of truth.',\n stringifyToml(flattened),\n ]\n .join('\\n')\n .replace(/\\s*$/u, '\\n'),\n )\n return {\n configPath,\n cleanup() {\n rmSync(configPath, { force: true })\n },\n }\n}\n\nexport function wranglerViteEnv(\n baseEnv: NodeJS.ProcessEnv,\n prepared: PreparedWranglerEnvConfig,\n extraEnv: NodeJS.ProcessEnv = {},\n): NodeJS.ProcessEnv {\n const env = { ...baseEnv, ...extraEnv }\n if (prepared.configPath) {\n delete env.CLOUDFLARE_ENV\n env.CLOUDFLARE_VITE_WRANGLER_CONFIG_PATH = prepared.configPath\n } else if (prepared.wranglerEnv) {\n env.CLOUDFLARE_ENV = prepared.wranglerEnv\n }\n return env\n}\n\nfunction flattenWranglerEnvConfig(config: TomlRecord, envName: string): TomlRecord {\n const envRoot = asTomlRecord(config.env)\n const envBlock = asTomlRecord(envRoot?.[envName])\n if (!envBlock) {\n throw new Error(`wrangler.toml: no [env.${envName}] block found.`)\n }\n\n const flattened: TomlRecord = {}\n for (const [key, value] of Object.entries(config)) {\n if (key === 'env' || NON_INHERITABLE_ENV_KEYS.has(key)) continue\n flattened[key] = value\n }\n for (const [key, value] of Object.entries(envBlock)) {\n flattened[key] = value\n }\n return flattened\n}\n\nfunction asTomlRecord(value: unknown): TomlRecord | undefined {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as TomlRecord)\n : undefined\n}\n\nfunction safeGeneratedConfigSegment(value: string): string {\n return value.replace(/[^A-Za-z0-9._-]/gu, '_')\n}\n\n/**\n * Read + parse wrangler.toml. Caller checks existence first via\n * `hasWranglerConfig`. Throws a `WranglerConfigError` with the absolute\n * path embedded on a malformed file — saves the user from staring at\n * a raw smol-toml parser stack trace when they have one stray\n * unquoted character in their config.\n */\nexport class WranglerConfigError extends Error {\n constructor(\n public readonly path: string,\n public readonly cause: unknown,\n ) {\n const detail = cause instanceof Error ? cause.message : String(cause)\n super(`wrangler.toml: malformed TOML at ${path}: ${detail}`)\n this.name = 'WranglerConfigError'\n }\n}\n\nexport function readWranglerConfig(appDir: string): WranglerConfig {\n const path = join(appDir, 'wrangler.toml')\n const raw = readFileSync(path, 'utf-8')\n try {\n return parseToml(raw) as WranglerConfig\n } catch (err) {\n throw new WranglerConfigError(path, err)\n }\n}\n\n/** Convenience: true when wrangler.toml exists at the standard path. */\nexport function hasWranglerConfig(appDir: string): boolean {\n return existsSync(join(appDir, 'wrangler.toml'))\n}\n","/**\n * App-name validation + sanitization helpers.\n *\n * Strategy: validate strictly so we have a precise definition of \"valid\",\n * but DON'T reject non-conforming names — sanitize them, warn the user, and\n * proceed. Hard rejection would break apps whose `wrangler.toml name` was\n * something like `My_App` (previously deployed as `my-app` via silent\n * server-side sanitization). The new behavior preserves \"still deploys,\"\n * but the CLI now surfaces a warning so the user can fix the name when\n * convenient instead of being silently surprised by their hostname.\n *\n * Rules track Cloudflare's WfP script-name constraints (RFC 1035 host label,\n * no consecutive dashes) plus our 2-char minimum so subdomains read sensibly.\n */\n\nexport const APP_NAME_RULES = {\n /** ^[a-z0-9](-?[a-z0-9])+$ — RFC 1035 host label, no consecutive dashes. */\n pattern: /^[a-z0-9](?:-?[a-z0-9])+$/,\n minLength: 2,\n maxLength: 63,\n} as const\n\nexport type AppNameValidation =\n | { valid: true; name: string }\n | { valid: false; reason: string }\n\n/**\n * Strict validation: returns valid only if the name already conforms.\n * Useful as a precondition test or for CI lints.\n */\nexport function validateAppName(raw: unknown): AppNameValidation {\n if (typeof raw !== 'string') {\n return { valid: false, reason: 'App name must be a string' }\n }\n const name = raw.trim()\n if (!name) {\n return { valid: false, reason: 'App name is required' }\n }\n if (name.length < APP_NAME_RULES.minLength) {\n return { valid: false, reason: `App name \"${name}\" is too short (min ${APP_NAME_RULES.minLength} chars)` }\n }\n if (name.length > APP_NAME_RULES.maxLength) {\n return { valid: false, reason: `App name \"${name}\" is too long (max ${APP_NAME_RULES.maxLength} chars)` }\n }\n if (!APP_NAME_RULES.pattern.test(name)) {\n return {\n valid: false,\n reason:\n `App name \"${name}\" is invalid. Use lowercase letters, digits, and single hyphens only ` +\n `(must start + end with alphanumeric). Examples: my-app, search-v2, unison-search.`,\n }\n }\n return { valid: true, name }\n}\n\nexport type AppNameResolution =\n | { ok: true; name: string; warning?: string }\n | { ok: false; reason: string }\n\n/**\n * Resolve an app name for deploy: prefer the input as-is if valid, otherwise\n * sanitize and warn. Hard-fail only if even sanitization can't produce a\n * valid name (empty, all-non-alphanumeric, too short, too long).\n *\n * The intent is \"what previously worked still works, with a friendly warning\n * about non-conforming names.\"\n */\nexport function resolveAppName(raw: unknown): AppNameResolution {\n const strict = validateAppName(raw)\n if (strict.valid) return { ok: true, name: strict.name }\n\n if (typeof raw !== 'string') return { ok: false, reason: strict.reason }\n const trimmed = raw.trim()\n if (!trimmed) return { ok: false, reason: 'App name is required' }\n\n const sanitized = sanitizeAppName(trimmed)\n const sanitizedStrict = validateAppName(sanitized)\n if (!sanitizedStrict.valid) {\n return {\n ok: false,\n reason: `App name \"${trimmed}\" can't be sanitized into a valid name (${sanitizedStrict.reason}). Pick something matching: lowercase letters, digits, single hyphens, ${APP_NAME_RULES.minLength}-${APP_NAME_RULES.maxLength} chars.`,\n }\n }\n return {\n ok: true,\n name: sanitized,\n warning:\n `App name \"${trimmed}\" doesn't conform to deploy rules — using \"${sanitized}\" instead. ` +\n `Update wrangler.toml's \\`name\\` to silence this warning.`,\n }\n}\n\n/**\n * Lossy normalization that mirrors what the deploy-worker historically did\n * server-side. Keep only [a-z0-9-], collapse consecutive dashes, trim leading\n * and trailing dashes.\n */\nfunction sanitizeAppName(raw: string): string {\n return raw\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-{2,}/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n","/**\n * CLI session helpers — exchange a Better Auth session cookie for a short-lived\n * JWT against the auth worker. Shared by `auth.ts` (token refresh for all\n * authenticated commands) and `login.ts` (email/password flow).\n */\n\nexport const SESSION_COOKIE = '__Secure-better-auth.session_token'\n\n/**\n * Exchange a Better Auth session token for a fresh JWT.\n * Returns null if the session is invalid or expired.\n */\nexport async function exchangeSession(\n authUrl: string,\n sessionToken: string,\n): Promise<string | null> {\n const res = await fetch(`${authUrl}/api/auth/token`, {\n method: 'POST',\n headers: {\n Cookie: `${SESSION_COOKIE}=${encodeURIComponent(sessionToken)}`,\n Origin: authUrl,\n },\n })\n if (!res.ok) return null\n const data = (await res.json()) as { token?: string | null }\n return data.token ?? null\n}\n","/**\n * Best-effort \"open this URL in the default browser\".\n *\n * Non-blocking and never throws: every caller has already printed the URL, so\n * a failure to launch the browser is harmless — the user opens it manually.\n * `JSON.stringify` quotes the URL so query strings / special chars can't break\n * out of the shell command.\n */\nimport { exec } from 'node:child_process'\n\nexport function openBrowser(url: string): void {\n const quoted = JSON.stringify(url)\n const cmd =\n process.platform === 'darwin'\n ? `open ${quoted}`\n : process.platform === 'win32'\n ? `start \"\" ${quoted}`\n : `xdg-open ${quoted}`\n\n // Swallow errors — the URL was already shown, so launching is optional.\n exec(cmd, () => {})\n}\n","/**\n * deepspace logout\n *\n * Revokes the session on the auth worker, then removes the cached session\n * token and JWT from ~/.deepspace/. Test accounts (managed by `deepspace\n * test-accounts`) are not touched.\n */\n\nimport { defineCommand } from 'citty'\nimport { existsSync, readFileSync, rmSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\n\nimport { PLATFORM_URLS } from '../env'\nimport { SESSION_COOKIE } from '../session'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? PLATFORM_URLS.auth\n\nconst DIR = join(homedir(), '.deepspace')\nconst SESSION_PATH = join(DIR, 'session')\nconst TOKEN_PATH = join(DIR, 'token')\n\nexport default defineCommand({\n meta: {\n name: 'logout',\n description: 'Sign out and remove cached credentials',\n },\n async run() {\n // Read the session token before deleting it so we can revoke server-side.\n const sessionToken = existsSync(SESSION_PATH)\n ? readFileSync(SESSION_PATH, 'utf-8').trim()\n : null\n\n if (sessionToken) {\n try {\n await fetch(`${AUTH_URL}/api/auth/sign-out`, {\n method: 'POST',\n headers: {\n Cookie: `${SESSION_COOKIE}=${encodeURIComponent(sessionToken)}`,\n Origin: AUTH_URL,\n },\n })\n } catch {\n // Network failure — still wipe local credentials so the user can\n // re-authenticate. Server-side session will expire on its own.\n }\n }\n\n let removed = 0\n for (const path of [SESSION_PATH, TOKEN_PATH]) {\n if (existsSync(path)) {\n rmSync(path)\n removed++\n }\n }\n\n if (removed === 0) {\n console.log('Already logged out.')\n return\n }\n console.log('Logged out.')\n },\n})\n","/**\n * deepspace dev [--port N]\n *\n * Starts local development:\n * 1. Ensures you're logged in\n * 2. Writes .dev.vars pointing to the production platform workers\n * 3. Starts vite dev (Cloudflare Vite plugin runs the worker in-process)\n *\n * deepspace dev # port 5173 (strict)\n * deepspace dev --port 5180 # bind to a different port (multi-app dev)\n *\n * Port is `--port` > $DEEPSPACE_PORT > 5173 — except inside a Claude Code\n * worktree, where (unless --port was passed) a stable per-worktree port in\n * 5180–5199 is derived instead, so the preview server never collides with a\n * main-repo dev server. We always pass --strictPort to vite so a busy port\n * fails loudly instead of silently jumping to 5174 (which would diverge from\n * anything Playwright/test config is expecting).\n */\n\nimport { defineCommand } from 'citty'\nimport { readAppId } from '../lib/app-identity'\nimport { resolve, basename, join } from 'node:path'\nimport spawn from 'cross-spawn'\nimport { ensureToken } from '../auth'\nimport {\n detectAppName,\n detectClaudeWorktree,\n deriveWorktreePort,\n findAppDir,\n findChildApps,\n upsertWorktreeLaunchConfig,\n writeLaunchConfigIfMissing,\n} from '../lib/app-context'\nimport { PLATFORM_URLS, writeDevVars } from '../env'\nimport { decodeJwtPayload } from '../jwt'\nimport { ensureInstallReady } from '../lib/install-status'\nimport { preflightNodeVersion, preflightWindowsWorkerd } from '../lib/preflight'\nimport { removeMacosJunk } from '../lib/macos-junk'\nimport { refreshSecretsCache } from '../lib/secrets'\nimport { DEFAULT_PORT, resolvePort, checkPortAvailable } from '../lib/port'\nimport {\n prepareWranglerEnvConfig,\n wranglerViteEnv,\n type PreparedWranglerEnvConfig,\n} from '../lib/wrangler-env'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\nexport default defineCommand({\n meta: {\n name: 'dev',\n description: 'Start local development server',\n },\n args: {\n dir: {\n type: 'positional',\n description: 'App directory (default: current directory)',\n required: false,\n },\n env: {\n type: 'string',\n alias: 'e',\n description:\n 'wrangler.toml [env.<name>] block to run (e.g. --env staging). ' +\n \"Applies the env's overrides at build time.\",\n required: false,\n },\n port: {\n type: 'string',\n description: `Port to bind (default ${DEFAULT_PORT}, or $DEEPSPACE_PORT)`,\n required: false,\n },\n },\n async run({ args }) {\n preflightNodeVersion('dev')\n const wranglerEnv =\n typeof args.env === 'string' && args.env.trim() ? args.env.trim() : undefined\n\n // Resolve the app root by walking up from the requested dir (default cwd),\n // so running from a subdirectory still works instead of hard-failing.\n const start = resolve(args.dir ?? '.')\n const appDir = findAppDir(start)\n if (!appDir) {\n console.error(`No wrangler.toml found at or above ${start}.`)\n const children = findChildApps(start)\n if (children.length > 0) {\n console.error('Did you mean to run inside one of these app directories?')\n for (const c of children) console.error(` cd ${c}`)\n } else {\n console.error('Run from a DeepSpace app directory (one containing wrangler.toml).')\n }\n process.exit(1)\n }\n\n const junk = removeMacosJunk(appDir)\n if (junk > 0) console.log(`Removed ${junk} macOS metadata file(s) (._*, .DS_Store)`)\n\n // Inside a Claude Code worktree the desktop preview tool reads only the\n // MAIN repo's launch.json and would serve the main repo's stale code\n // (anthropics/claude-code#56688) — so upsert a cwd-pinned entry there.\n // Only a literal --port counts as explicit and is honored verbatim: an\n // ambient $DEEPSPACE_PORT (e.g. exported in a shell profile) must not pin\n // the worktree to the main repo's port — the port is resolved AFTER\n // worktree detection so a malformed ambient value can't kill dev either.\n // Otherwise a stable per-worktree port (bumped past other entries' ports)\n // avoids colliding with a main-repo server. This run binds the same port\n // the entry advertises, so the preview tool can attach to an\n // already-running worktree server instead of spawning a duplicate.\n const worktree = detectClaudeWorktree(appDir)\n const explicitPort = Boolean(args.port)\n let port =\n worktree && !explicitPort ? deriveWorktreePort(worktree.worktreeName) : resolvePort(args.port)\n if (worktree) {\n const upserted = upsertWorktreeLaunchConfig(\n worktree.mainRepoRoot,\n worktree.worktreeName,\n appDir,\n {\n port,\n probePort: !explicitPort,\n extraArgs: [...(wranglerEnv ? ['--env', wranglerEnv] : [])],\n },\n )\n if (upserted) {\n port = upserted.port\n console.log(\n `Claude worktree detected — preview tool: use preview_start with name \"${upserted.entryName}\" (port ${upserted.port})`,\n )\n } else {\n console.warn(\n `Warning: could not update ${join(worktree.mainRepoRoot, '.claude', 'launch.json')} ` +\n `(malformed or unwritable) — the Claude preview tool may serve the main repo's code ` +\n `instead of this worktree.`,\n )\n }\n if (!explicitPort && process.env.DEEPSPACE_PORT) {\n console.log(\n `Ignoring DEEPSPACE_PORT=${process.env.DEEPSPACE_PORT} inside a worktree — ` +\n `using per-worktree port ${port}. Pass --port to override.`,\n )\n }\n }\n\n // Seed an app-local .claude/launch.json (only if absent) so the Claude Code\n // preview tool launches this app on the resolved port, instead of walking\n // up and latching onto an ancestor repo's config. With an explicit --port,\n // also update the existing entry so `kill` and the preview tool track the\n // port we actually bind (DEV-3).\n writeLaunchConfigIfMissing(appDir, detectAppName(appDir) ?? basename(appDir), port, {\n updatePort: explicitPort,\n })\n\n ensureInstallReady(appDir)\n\n let token: string\n try {\n token = await ensureToken()\n } catch (err: unknown) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n\n let payload: { sub: string; name?: string; email?: string }\n try {\n payload = decodeJwtPayload<{ sub: string; name?: string; email?: string }>(token)\n } catch {\n console.error('Malformed session token. Run `npx deepspace login`.')\n process.exit(1)\n }\n // `--env` selects which `[env.<name>]` block of wrangler.toml we apply\n // (renames the app, swaps vars, etc.). Surface it in the startup log so\n // it's obvious which app slot a session is hitting when it's set.\n console.log(`Logged in as ${payload.name ?? payload.email}`)\n if (wranglerEnv) console.log(`Wrangler env: ${wranglerEnv}`)\n console.log(`Port: ${port}`)\n\n // Refresh the app-store secrets cache (config = wrangler env, or 'prd').\n // A repo without a DEEPSPACE_APP_ID hasn't been initialized — writeDevVars\n // below throws with the `deepspace init` pointer, so skip the pull.\n let generatedSecretsCache: string | undefined\n const appIdForSecrets = readAppId(appDir, wranglerEnv)\n if (appIdForSecrets) {\n try {\n const refreshed = await refreshSecretsCache(DEPLOY_URL, token, appIdForSecrets, wranglerEnv)\n if (refreshed) {\n generatedSecretsCache = refreshed.rendered\n console.log(refreshed.summary)\n }\n } catch (err: unknown) {\n console.error(\n `Failed to refresh app secrets: ${err instanceof Error ? err.message : String(err)}`,\n )\n process.exit(1)\n }\n }\n\n const sharedDevVarsCache = generatedSecretsCache !== undefined\n await writeDevVars(appDir, payload.sub, token, wranglerEnv, {\n generatedSecretsCache,\n sharedDevVarsCache,\n })\n let wranglerConfig: PreparedWranglerEnvConfig\n try {\n wranglerConfig = prepareWranglerEnvConfig(appDir, wranglerEnv, { sharedDevVarsCache })\n } catch (err: unknown) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n preflightWindowsWorkerd(appDir)\n\n // Pre-probe the port so a collision gets a friendly remedy instead of\n // vite's raw --strictPort EADDRINUSE stack trace (DEV-5).\n if (!(await checkPortAvailable(port))) {\n console.error(`Port ${port} is already in use.`)\n const killCmd = port === DEFAULT_PORT ? 'deepspace kill' : `deepspace kill --port ${port}`\n console.error(`Free it with \\`${killCmd}\\`, or start on another port: \\`deepspace dev --port <other>\\`.`)\n process.exit(1)\n }\n\n console.log('Starting dev server...\\n')\n\n const vite = spawn('npx', ['vite', '--port', String(port), '--strictPort', '--host'], {\n cwd: appDir,\n stdio: 'inherit',\n env: wranglerViteEnv(process.env, wranglerConfig, { DEEPSPACE_PORT: String(port) }),\n })\n const stop = () => {\n wranglerConfig.cleanup()\n vite.kill()\n }\n process.on('SIGINT', stop)\n process.on('SIGTERM', stop)\n vite.on('close', (code) => {\n wranglerConfig.cleanup()\n process.exit(code ?? 0)\n })\n },\n})\n","/**\n * CLI auth utilities — shared across all commands.\n *\n * Reads the session token from ~/.deepspace/session and ensures\n * a fresh JWT is available at ~/.deepspace/token.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\n\nimport { PLATFORM_URLS } from './env'\nimport { decodeJwtPayload } from './jwt'\nimport { exchangeSession } from './session'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? PLATFORM_URLS.auth\n\nconst DIR = join(homedir(), '.deepspace')\nexport const SESSION_PATH = join(DIR, 'session')\nexport const TOKEN_PATH = join(DIR, 'token')\n\n/**\n * Ensure a valid JWT exists. Refreshes from the session token if expired.\n * Returns the JWT string or throws if not logged in / session expired.\n */\nexport async function ensureToken(): Promise<string> {\n // Try existing token first — if it's still valid, skip the refresh\n if (existsSync(TOKEN_PATH)) {\n const existing = readFileSync(TOKEN_PATH, 'utf-8').trim()\n if (isTokenValid(existing)) {\n return existing\n }\n }\n\n if (!existsSync(SESSION_PATH)) {\n throw new Error('Not logged in. Run `deepspace login` first.')\n }\n\n const sessionToken = readFileSync(SESSION_PATH, 'utf-8').trim()\n\n // Refresh from session\n const token = await exchangeSession(AUTH_URL, sessionToken)\n if (!token) {\n throw new Error('Session expired. Run `deepspace login` to re-authenticate.')\n }\n\n mkdirSync(DIR, { recursive: true, mode: 0o700 })\n writeFileSync(TOKEN_PATH, token, { mode: 0o600 })\n\n return token\n}\n\n/** Check if a JWT has at least 30 seconds of validity remaining. */\nfunction isTokenValid(jwt: string): boolean {\n try {\n const payload = decodeJwtPayload<{ exp?: number }>(jwt)\n return typeof payload.exp === 'number' && payload.exp * 1000 > Date.now() + 30_000\n } catch {\n return false\n }\n}\n","export function decodeJwtPayload<T = Record<string, unknown>>(token: string): T {\n const payloadSegment = token.split('.')[1]\n if (!payloadSegment) {\n throw new Error('JWT payload is missing')\n }\n return JSON.parse(Buffer.from(payloadSegment, 'base64url').toString('utf8')) as T\n}\n","/**\n * Shared helper: read the current project's app name from `./wrangler.toml`.\n *\n * Used by commands that operate on \"the current app\" — `deploy`, `domain buy`,\n * `domain attach`, etc. Lets agents and scripts run from inside a project\n * directory without redundantly passing `--app <name>`.\n */\n\nimport {\n existsSync,\n readFileSync,\n readdirSync,\n writeFileSync,\n mkdirSync,\n renameSync,\n unlinkSync,\n} from 'node:fs'\nimport { join, resolve, dirname, basename, isAbsolute, sep } from 'node:path'\nimport { parse as parseToml } from 'smol-toml'\nimport { APP_ID_RE, readAppId } from './app-identity'\nimport { apiFetch } from './api'\n\n/** Strict app-id shape (excludes the legacy name-as-id branch of APP_ID_RE). */\nconst STRICT_APP_ID_RE = /^app_[0-9A-HJKMNP-TV-Z]{26}$/\n\n/**\n * Read the app name from `wrangler.toml` in the given directory (default cwd).\n * Returns null if no wrangler.toml exists or the file lacks a `name` field.\n */\nexport function detectAppName(cwd: string = process.cwd()): string | null {\n const wranglerPath = join(resolve(cwd), 'wrangler.toml')\n if (!existsSync(wranglerPath)) return null\n try {\n const cfg = parseToml(readFileSync(wranglerPath, 'utf-8')) as { name?: string }\n return typeof cfg.name === 'string' && cfg.name.length > 0 ? cfg.name : null\n } catch (err) {\n // Malformed is NOT absent — treating it as \"no app here\" sends callers\n // down create-new-app paths against a directory that has one.\n throw new Error(\n `Could not parse ${wranglerPath}: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n\n/**\n * Resolve the app name from explicit arg or wrangler.toml.\n * Throws with a clear message if neither is available.\n */\nexport function requireAppName(explicit: string | undefined, cwd?: string): string {\n if (explicit) return explicit\n const detected = detectAppName(cwd)\n if (detected) return detected\n throw new Error(\n 'No app specified. Pass --app <name>, or run from an app directory with a wrangler.toml.',\n )\n}\n\n/**\n * Walk upward from `start` (default cwd) to the nearest directory containing a\n * `wrangler.toml`, returning that directory — or null if none is found before\n * the filesystem root.\n *\n * This makes the dev-loop commands robust to being run from a *subdirectory*\n * of an app instead of hard-failing the moment cwd isn't exactly the app root.\n * (It does NOT recover the inverse case — cwd sitting at the app's *parent*;\n * for that, `findChildApps` powers a \"did you mean cd <app>\" hint.)\n */\nexport function findAppDir(start: string = process.cwd()): string | null {\n let dir = resolve(start)\n for (;;) {\n if (existsSync(join(dir, 'wrangler.toml'))) return dir\n const parent = dirname(dir)\n if (parent === dir) return null // reached filesystem root\n dir = parent\n }\n}\n\n/**\n * Immediate subdirectories of `dir` that look like an app (contain a\n * `wrangler.toml`). Used to turn a bare \"no wrangler.toml here\" failure into an\n * actionable hint when the caller is sitting one level above the app — the\n * exact situation a harness creates when it resets cwd to the parent.\n */\nexport function findChildApps(dir: string): string[] {\n try {\n return readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && existsSync(join(dir, e.name, 'wrangler.toml')))\n .map((e) => e.name)\n .sort()\n } catch {\n return []\n }\n}\n\n/**\n * Atomic launch.json write: temp file + rename, so an interrupted write can\n * never leave torn (permanently unparseable) JSON behind.\n */\nfunction writeLaunchFile(launchPath: string, config: unknown): void {\n mkdirSync(dirname(launchPath), { recursive: true })\n const tmpPath = `${launchPath}.${process.pid}.tmp`\n writeFileSync(tmpPath, JSON.stringify(config, null, 2) + '\\n')\n try {\n renameSync(tmpPath, launchPath)\n } catch (err) {\n // Don't leave an orphan tmp file behind (e.g. Windows EPERM while the\n // preview tool holds launch.json open).\n try {\n unlinkSync(tmpPath)\n } catch {\n // best-effort cleanup\n }\n throw err\n }\n}\n\n/**\n * Read + validate a launch.json. Returns the parsed config, an empty skeleton\n * when the file is absent or empty (interrupted write, `touch` — nothing to\n * preserve), or null when it exists but is malformed / wrong-shaped (leave it\n * alone rather than clobber a hand-edited file). Trimmed before parsing so a\n * UTF-8 BOM from Windows editors doesn't read as \"malformed\".\n */\nfunction readLaunchFile(\n launchPath: string,\n): { version?: string; configurations: Array<Record<string, unknown>> } | null {\n const empty = { version: '0.0.1', configurations: [] }\n if (!existsSync(launchPath)) return empty\n const raw = readFileSync(launchPath, 'utf-8').trim()\n if (!raw) return empty\n const parsed = JSON.parse(raw)\n if (!parsed || typeof parsed !== 'object' || !Array.isArray(parsed.configurations)) return null\n return parsed\n}\n\n/**\n * Seed the app's own entry in `<appDir>/.claude/launch.json` so the Claude\n * Code preview tool launches THIS app. Without an app-local launch.json the\n * tool walks up the directory tree and can latch onto an ancestor repo's\n * config — pointing at a different app and port — which is a real failure\n * when a DeepSpace app lives inside another repo.\n *\n * Entry-level, not file-level: if the file already has an entry named\n * `appName` (possibly user-customized) it is left untouched by default, but a\n * file that exists without it — e.g. created by a worktree run's upsert before\n * the main app ever ran `dev` — still gets the app's entry appended.\n *\n * `opts.updatePort` (DEV-3): when the user passed an explicit `--port`, update\n * the existing entry's `port` and the `--port` value inside its `runtimeArgs`\n * (other args like `--env` are preserved) so `kill` and the preview tool track\n * the port `dev` actually bound. Without it, a scaffold pinned to 5173 would\n * stay stale after `dev --port 5180`. Best-effort: a failure must never block\n * `dev` from starting.\n */\nexport function writeLaunchConfigIfMissing(\n appDir: string,\n appName: string,\n port: number,\n opts: { updatePort?: boolean } = {},\n): void {\n const launchPath = join(appDir, '.claude', 'launch.json')\n try {\n const config = readLaunchFile(launchPath)\n if (!config) return\n const existing = config.configurations.find((c) => c?.name === appName)\n if (existing) {\n if (!opts.updatePort) return\n // Resync BOTH the `port` field and the `--port` value in runtimeArgs — a\n // stale runtimeArgs (even when the port field matches) makes the preview\n // tool launch on the wrong port. Only write when something actually changed.\n let changed = false\n if (Number(existing.port) !== port) {\n existing.port = port\n changed = true\n }\n if (Array.isArray(existing.runtimeArgs)) {\n const ra = existing.runtimeArgs.map(String)\n const pi = ra.indexOf('--port')\n if (pi >= 0 && pi + 1 < ra.length) {\n if (ra[pi + 1] !== String(port)) {\n ra[pi + 1] = String(port)\n changed = true\n }\n } else {\n ra.push('--port', String(port))\n changed = true\n }\n if (changed) existing.runtimeArgs = ra\n }\n if (changed) writeLaunchFile(launchPath, config)\n return\n }\n config.configurations.push({\n name: appName,\n runtimeExecutable: 'npx',\n runtimeArgs: ['deepspace', 'dev', '--port', String(port)],\n port,\n })\n writeLaunchFile(launchPath, config)\n } catch {\n // best-effort only\n }\n}\n\n/**\n * The port `kill` should target for the app at `appDir` when no `--port` was\n * given and we're not in a worktree (DEV-2): the port recorded in the app's own\n * `.claude/launch.json` entry, which `dev --port` keeps in sync (see above).\n * Falls back to null (caller uses the default) when there's no launch.json,\n * no matching entry, or a malformed file.\n */\nexport function resolveAppLaunchPort(appDir: string): number | null {\n try {\n const config = readLaunchFile(join(appDir, '.claude', 'launch.json'))\n if (!config) return null\n const appName = detectAppName(appDir) ?? basename(appDir)\n const entry =\n config.configurations.find((c) => c?.name === appName) ??\n (config.configurations.length === 1 ? config.configurations[0] : undefined)\n const port = Number(entry?.port)\n return Number.isInteger(port) && port > 0 ? port : null\n } catch {\n return null\n }\n}\n\n/**\n * Detect whether `appDir` lives inside a Claude Code worktree\n * (`<root>/.claude/worktrees/<name>/...`). Returns the main repo root (the\n * directory containing `.claude`) and the worktree name, or null.\n *\n * The Claude desktop preview tool starts dev servers from the session's\n * primary working directory and reads only the MAIN repo's\n * `.claude/launch.json` — a worktree's own launch.json is never read\n * (anthropics/claude-code#56688). Detecting this lets `dev` seed a\n * `cwd`-pinned entry where the tool will actually look.\n */\nexport function detectClaudeWorktree(\n appDir: string,\n): { mainRepoRoot: string; worktreeName: string } | null {\n const segments = resolve(appDir).split(sep)\n // Innermost match wins: worktrees are created under the *session root's*\n // .claude/worktrees, so a nested worktree implies the session is rooted at\n // the outer worktree — that outer root's launch.json is the one the\n // session's preview tool reads.\n for (let i = segments.length - 3; i >= 1; i--) {\n if (segments[i] === '.claude' && segments[i + 1] === 'worktrees' && segments[i + 2]) {\n return {\n mainRepoRoot: segments.slice(0, i).join(sep) || sep,\n worktreeName: segments[i + 2],\n }\n }\n }\n return null\n}\n\nconst WORKTREE_ENTRY_PREFIX = 'wt-'\nconst WORKTREE_PORT_MIN = 5180\nconst WORKTREE_PORT_RANGE = 20\n\n/**\n * Deterministic per-worktree preview port in the worktree band\n * (5180–5199), distinct from the default 5173 so a preview server for the\n * worktree never collides with a main-repo dev server. Stable across runs\n * for the same worktree name. Hash collisions between worktree names are\n * resolved at write time by `upsertWorktreeLaunchConfig`, which probes past\n * ports already claimed by other launch.json entries.\n */\nexport function deriveWorktreePort(worktreeName: string): number {\n let hash = 0\n for (const ch of worktreeName) hash = (hash * 31 + ch.charCodeAt(0)) >>> 0\n return WORKTREE_PORT_MIN + (hash % WORKTREE_PORT_RANGE)\n}\n\nexport interface WorktreeLaunchOptions {\n /** Desired port for the entry (and for the current dev run). */\n port: number\n /**\n * When true, bump the port past any port already claimed by another\n * launch.json entry (wrapping within 5180–5199). Off for an explicit\n * --port, which is honored verbatim.\n */\n probePort?: boolean\n /** Extra `deepspace dev` args to preserve in the entry (e.g. --prod, --env). */\n extraArgs?: string[]\n}\n\n/**\n * Upsert a `cwd`-pinned entry named `wt-<worktreeName>` into the MAIN repo's\n * `.claude/launch.json`, so the Claude desktop preview tool (which only reads\n * that file) starts the dev server inside the worktree instead of serving the\n * main repo's stale code. Also prunes `wt-*` entries whose absolute `cwd` no\n * longer exists (deleted worktrees) — relative `cwd`s are left alone, since\n * `existsSync` would resolve them against this process's cwd, not the\n * preview tool's. All other entries are preserved verbatim.\n *\n * Returns the entry name and the (possibly probed) port on success, or null\n * if the file was malformed or unwritable — best-effort: must never block\n * `dev` from starting, but the caller should warn, since a missing entry\n * means the preview tool will serve the main repo's code.\n */\nexport function upsertWorktreeLaunchConfig(\n mainRepoRoot: string,\n worktreeName: string,\n appDir: string,\n opts: WorktreeLaunchOptions,\n): { entryName: string; port: number } | null {\n const launchPath = join(mainRepoRoot, '.claude', 'launch.json')\n const entryName = WORKTREE_ENTRY_PREFIX + worktreeName\n try {\n const config = readLaunchFile(launchPath)\n if (!config) return null\n // Ownership check for pruning: only entries whose cwd lives under this\n // repo's .claude/worktrees/ could have been written by us. A hand-authored\n // wt-* entry pointing elsewhere (or at an unmounted volume) is never ours\n // to delete.\n const worktreesRoot = join(mainRepoRoot, '.claude', 'worktrees') + sep\n config.configurations = config.configurations.filter((c) => {\n if (c?.name === entryName) return false // replaced below\n const isStaleWorktreeEntry =\n typeof c?.name === 'string' &&\n c.name.startsWith(WORKTREE_ENTRY_PREFIX) &&\n typeof c.cwd === 'string' &&\n isAbsolute(c.cwd) &&\n c.cwd.startsWith(worktreesRoot) &&\n !existsSync(c.cwd)\n return !isStaleWorktreeEntry\n })\n\n let port = opts.port\n if (opts.probePort) {\n // Number() coercion so a hand-edited string port (\"5186\") still counts\n // as claimed.\n const taken = new Set(\n config.configurations.map((c) => Number(c?.port)).filter((p) => Number.isInteger(p) && p > 0),\n )\n for (let i = 0; i < WORKTREE_PORT_RANGE && taken.has(port); i++) {\n port = WORKTREE_PORT_MIN + ((port - WORKTREE_PORT_MIN + 1) % WORKTREE_PORT_RANGE)\n }\n }\n\n config.configurations.push({\n name: entryName,\n runtimeExecutable: 'npx',\n runtimeArgs: ['deepspace', 'dev', '--port', String(port), ...(opts.extraArgs ?? [])],\n port,\n // `cwd` is honored verbatim by the desktop preview tool (documented in\n // the Claude Code desktop launch.json reference alongside `port`) and\n // verified end-to-end: with it set, the preview server builds from the\n // worktree instead of the session's main repo.\n cwd: resolve(appDir),\n })\n writeLaunchFile(launchPath, config)\n return { entryName, port }\n } catch {\n return null\n }\n}\n\n/**\n * The port dev/test/kill should default to inside a Claude Code worktree, so\n * all three commands target the same server (`test` against a different port\n * silently exercises the main repo's code via Playwright's\n * reuseExistingServer). The `wt-<name>` entry in the main repo's launch.json\n * is the source of truth — it includes any probing `dev` applied; fall back\n * to the derived port when it doesn't exist yet. Returns null outside a\n * worktree.\n */\nexport function resolveWorktreePort(appDir: string): number | null {\n const worktree = detectClaudeWorktree(appDir)\n if (!worktree) return null\n try {\n const config = readLaunchFile(join(worktree.mainRepoRoot, '.claude', 'launch.json'))\n const entry = config?.configurations.find(\n (c) => c?.name === WORKTREE_ENTRY_PREFIX + worktree.worktreeName,\n )\n const port = Number(entry?.port)\n if (Number.isInteger(port) && port > 0) return port\n } catch {\n // malformed launch.json — fall through to the derived port\n }\n return deriveWorktreePort(worktree.worktreeName)\n}\n\n/**\n * Resolve the app id a command targets: an explicit `--app app_…` wins,\n * otherwise the surrounding app directory's DEEPSPACE_APP_ID. Shared by\n * `collaborators`, `transfer`, and other id-scoped commands.\n */\nexport function requireAppIdArg(explicit: string | undefined): string {\n if (explicit) {\n if (!APP_ID_RE.test(explicit)) {\n throw new Error(`\"${explicit}\" is not an app id (app_…). Pass --app <appId>.`)\n }\n return explicit\n }\n const appDir = findAppDir()\n const id = appDir ? readAppId(appDir) : null\n if (!id) {\n throw new Error(\n 'No app id. Run from an app directory whose wrangler.toml carries DEEPSPACE_APP_ID, or pass --app <appId>.',\n )\n }\n return id\n}\n\ninterface AppListEntry {\n appId: string\n name: string | null\n}\n\n/** Find an app id or subdomain name in the caller's registry list. Exported for tests. */\nexport function matchAppSelector(apps: AppListEntry[], selector: string): string | null {\n const byId = apps.find((a) => a.appId === selector)\n if (byId) return byId.appId\n const byName = apps.find((a) => a.name === selector)\n if (byName) return byName.appId\n // Not among the caller's apps. A well-formed app_… id is trusted as-is (e.g.\n // an app the list didn't surface); anything else is an unknown name.\n return STRICT_APP_ID_RE.test(selector) ? selector : null\n}\n\n/**\n * Resolve an app selector — an app id (`app_…` or a legacy name-as-id) OR a live\n * subdomain name — to the canonical app id, via the deploy worker's `/api/apps`\n * registry. Unifies the \"id vs name\" split (DEP-4/DEP-5): id-scoped commands now\n * accept either. Throws a `deepspace apps` pointer when nothing matches.\n */\nexport async function resolveAppSelector(\n deployUrl: string,\n token: string,\n selector: string,\n): Promise<string> {\n // A canonical app_… id needs no registry lookup — trust it and let the target\n // worker authorize it. This skips an extra round-trip and, for the API-worker\n // commands (collaborators/transfer), a needless dependency on the deploy\n // worker's /api/apps. Legacy name-as-id and subdomain names still need it.\n if (STRICT_APP_ID_RE.test(selector)) return selector\n const { apps } = await apiFetch<{ apps: AppListEntry[] }>(deployUrl, token, '/api/apps')\n const id = matchAppSelector(apps, selector)\n if (!id) {\n throw new Error(`No app \"${selector}\" in your account. Run \\`deepspace apps\\` to list your apps.`)\n }\n return id\n}\n\n/**\n * The app id a command targets: an explicit `--app` selector (id or name,\n * resolved via resolveAppSelector) wins; otherwise the surrounding app\n * directory's DEEPSPACE_APP_ID. The async, name-accepting counterpart of\n * requireAppIdArg (DEP-4).\n */\nexport async function resolveAppTarget(\n deployUrl: string,\n token: string,\n explicit: string | undefined,\n): Promise<string> {\n if (explicit) return resolveAppSelector(deployUrl, token, explicit)\n const appDir = findAppDir()\n const id = appDir ? readAppId(appDir) : null\n if (!id) {\n throw new Error(\n 'No app id. Run from an app directory whose wrangler.toml carries DEEPSPACE_APP_ID, or pass --app <id or name>.',\n )\n }\n return id\n}\n","/**\n * Authenticated JSON fetch against a platform worker.\n *\n * Shared by the CLI commands that call the platform as the logged-in user\n * (`domain`, `feedback`, `collaborators`, `transfer`, …). Sends a Bearer\n * token, parses the JSON body, and on a non-2xx response throws an ApiError\n * carrying the worker's `{ error, code }` — message for display, code for\n * branching — so callers never string-sniff error text.\n */\nexport class ApiError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly code?: string,\n /** Internal REST path — kept off the message (DEBUG-only rendering). */\n readonly apiPath?: string,\n ) {\n super(message)\n }\n}\n\nexport async function apiFetch<T>(\n baseUrl: string,\n token: string,\n path: string,\n init?: RequestInit,\n): Promise<T> {\n const res = await fetch(`${baseUrl}${path}`, {\n ...init,\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n ...(init?.headers ?? {}),\n },\n })\n const text = await res.text()\n if (!res.ok) {\n let msg = text\n let code: string | undefined\n try {\n const body = JSON.parse(text) as { error?: string; code?: string }\n msg = body.error ?? text\n code = body.code\n } catch {\n // not JSON\n }\n // Message = the server's sentence only. The internal REST path and raw\n // status read like a stack trace to users (same treatment as secretsApi);\n // they stay on the error's fields for DEBUG rendering and branching.\n throw new ApiError(msg || `Request failed (${res.status})`, res.status, code, path)\n }\n return (text ? JSON.parse(text) : {}) as T\n}\n","/**\n * Verifies the app's dependencies are installed before running a command that\n * needs them (dev, test, deploy, add).\n *\n * `create-deepspace` runs `npm install` (and the agent-skill installer) in a\n * detached background process so the user gets their prompt back immediately.\n * The background worker writes three sentinels under `<appDir>/.deepspace/`:\n *\n * install.started — created before the worker is spawned\n * install.pid — the worker's pid (liveness check for a killed install)\n * install.done — written on successful completion\n * install.err — written on failure (contains the error message)\n * install.log — combined stdout/stderr of the install\n *\n * The presence of `node_modules/deepspace/package.json` is the ground truth\n * for \"ready\"; the sentinels only shape the error message.\n */\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\n\nexport function ensureInstallReady(appDir: string): void {\n if (existsSync(join(appDir, 'node_modules', 'deepspace', 'package.json'))) return\n\n const sentinelDir = join(appDir, '.deepspace')\n const errPath = join(sentinelDir, 'install.err')\n const startedPath = join(sentinelDir, 'install.started')\n const donePath = join(sentinelDir, 'install.done')\n const logPath = join(sentinelDir, 'install.log')\n\n if (existsSync(errPath)) {\n console.error('Background install failed:')\n console.error(readFileSync(errPath, 'utf-8').trimEnd())\n if (existsSync(logPath)) console.error(`\\nFull log: ${logPath}`)\n console.error('\\nRun `npm install` (or `bun install`) manually, then retry.')\n process.exit(1)\n }\n\n if (existsSync(startedPath) && !existsSync(donePath)) {\n // A worker that died without writing done/err (OOM, docker stop, laptop\n // shutdown) must not read as \"still installing\" forever. install.pid is\n // written by create-deepspace ≥0.5.6; without it, assume in-progress.\n if (!installWorkerAlive(sentinelDir)) {\n console.error('The background install is no longer running and never finished.')\n if (existsSync(logPath)) console.error(`See what happened: ${logPath}`)\n console.error('Run `npm install` (or `bun install`) manually, then retry.')\n process.exit(1)\n }\n console.error('Dependencies are still installing in the background.')\n if (existsSync(logPath)) console.error(`Tail progress: tail -f ${logPath}`)\n console.error('Retry once it finishes.')\n process.exit(1)\n }\n\n console.error('Dependencies not installed. Run `npm install` (or `bun install`) first.')\n process.exit(1)\n}\n\n/**\n * Is the detached install worker still running? True when install.pid is\n * missing (pre-0.5.6 scaffolds — assume in-progress rather than cry wolf) or\n * the pid answers signal 0. EPERM means \"alive, not ours\".\n */\nfunction installWorkerAlive(sentinelDir: string): boolean {\n const pidPath = join(sentinelDir, 'install.pid')\n if (!existsSync(pidPath)) return true\n const pid = Number.parseInt(readFileSync(pidPath, 'utf-8').trim(), 10)\n if (!Number.isFinite(pid) || pid <= 0) return true\n try {\n process.kill(pid, 0)\n return true\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === 'EPERM'\n }\n}\n","import { execFileSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\n// Namespace import on purpose: a named `import { registerHooks }` would itself\n// crash at load time on the very Nodes this preflight exists to catch.\nimport * as nodeModule from 'node:module'\nimport { resolve } from 'node:path'\n\n/**\n * The Cloudflare Vite plugin uses `module.registerHooks` (Node 22.15+ /\n * 23.5+). On older Nodes, `vite build` and the dev server die with a cryptic\n * ESM error from deep inside the plugin:\n *\n * SyntaxError: The requested module 'node:module' does not provide an\n * export named 'registerHooks'\n *\n * Catch it before spawning Vite and print the actual fix instead. Feature-\n * detected rather than version-pinned so the check can't go stale; the\n * `hasRegisterHooks` parameter exists only for tests.\n */\nexport function preflightNodeVersion(\n command: string,\n hasRegisterHooks: boolean = typeof (nodeModule as { registerHooks?: unknown }).registerHooks ===\n 'function',\n): void {\n if (hasRegisterHooks) return\n console.error(\n `deepspace ${command} requires Node 22.15 or newer (found v${process.versions.node}).`,\n )\n console.error('Install the current LTS from https://nodejs.org and re-run.')\n process.exit(1)\n}\n\n// 0xC0000135 = STATUS_DLL_NOT_FOUND on Windows. Node reports it as a signed int.\nconst DLL_NOT_FOUND = -1073741515\n\n/**\n * On Windows, the Cloudflare Workers runtime (`workerd.exe`) is built with\n * MSVC and links against `vcruntime140.dll`. A bare Windows install (Server\n * 2022, Server Core, minimal Windows 11) does not ship those DLLs, so workerd\n * exits immediately with STATUS_DLL_NOT_FOUND. Miniflare then surfaces this as\n * \"Error: write EOF\" because workerd closed the stdin pipe before reading its\n * config — an error with no JS stack trace and no hint at the cause.\n *\n * This preflight catches the case and prints the actual fix (install VC++\n * Redistributable). Skip silently if workerd isn't installed yet or runs fine.\n */\nexport function preflightWindowsWorkerd(appDir: string): void {\n if (process.platform !== 'win32') return\n\n const workerdExe = resolve(\n appDir,\n 'node_modules',\n '@cloudflare',\n 'workerd-windows-64',\n 'bin',\n 'workerd.exe',\n )\n if (!existsSync(workerdExe)) return\n\n try {\n execFileSync(workerdExe, ['--help'], { stdio: 'pipe', timeout: 10_000 })\n return\n } catch (err: unknown) {\n const status = (err as { status?: number }).status\n if (status !== DLL_NOT_FOUND) return\n\n console.error('')\n console.error(' workerd (Cloudflare Workers runtime) cannot start on this system.')\n console.error(' It needs the Microsoft Visual C++ Redistributable, which is not installed.')\n console.error('')\n console.error(' Install it with any of:')\n console.error(' winget install Microsoft.VCRedist.2015+.x64')\n console.error(' choco install -y vcredist140')\n console.error(' https://aka.ms/vs/17/release/vc_redist.x64.exe')\n console.error('')\n console.error(' Then restart this terminal and re-run the command.')\n console.error('')\n process.exit(1)\n }\n}\n","import { readdirSync, rmSync } from 'node:fs'\nimport { join } from 'node:path'\n\nconst SKIP_DIRS = new Set(['node_modules', '.git', 'dist', '.wrangler', '.vite'])\n\n/**\n * Delete macOS metadata files (AppleDouble `._*` and `.DS_Store`) under an\n * app directory. They appear when a project is copied from macOS through\n * tar/zip/SMB onto another system, and they poison the toolchain: ESLint\n * hard-fails on their binary content (\"Parsing error: Invalid character\",\n * failing the deploy lint), and generouted can pick up `._index.tsx` in\n * src/pages as a phantom route. Returns the number of files removed.\n */\nexport function removeMacosJunk(dir: string): number {\n let removed = 0\n // Best-effort throughout: an unreadable subdir or undeletable file must\n // never abort a build that would otherwise have worked.\n let entries\n try {\n entries = readdirSync(dir, { withFileTypes: true })\n } catch {\n return removed\n }\n for (const entry of entries) {\n const path = join(dir, entry.name)\n if (entry.isDirectory()) {\n if (!SKIP_DIRS.has(entry.name)) removed += removeMacosJunk(path)\n continue\n }\n if (entry.name === '.DS_Store' || entry.name.startsWith('._')) {\n try {\n rmSync(path, { force: true })\n removed++\n } catch {\n // Leave it — the lint may still trip on it, but we didn't make\n // anything worse.\n }\n }\n }\n return removed\n}\n","/**\n * Shared dev-server port resolution for `dev`, `test`, and `kill`.\n *\n * Precedence: explicit `--port` arg > $DEEPSPACE_PORT > DEFAULT_PORT. An\n * out-of-range value is a hard error (exit 1) rather than a silent fallback,\n * so a typo doesn't quietly bind the wrong port.\n */\n\nimport { createServer } from 'node:net'\n\nexport const DEFAULT_PORT = 5173\n\n/**\n * Whether `port` is free to bind on `host`. Used by `dev` to pre-probe before\n * spawning vite (which binds with `--host`, i.e. 0.0.0.0), so a busy port gets\n * a friendly `deepspace kill` / `--port` remedy instead of vite's raw\n * EADDRINUSE stack (DEV-5). Best-effort: a bind race after the probe still\n * surfaces vite's own error, but the common \"server already running\" case is\n * caught cleanly.\n */\nexport function checkPortAvailable(port: number, host = '0.0.0.0'): Promise<boolean> {\n return new Promise((resolve) => {\n const srv = createServer()\n srv.once('error', () => resolve(false))\n srv.once('listening', () => srv.close(() => resolve(true)))\n srv.listen(port, host)\n })\n}\n\nexport function resolvePort(arg?: string): number {\n const raw = arg ?? process.env.DEEPSPACE_PORT\n if (!raw) return DEFAULT_PORT\n const n = Number(raw)\n if (!Number.isInteger(n) || n < 1 || n > 65535) {\n console.error(`Invalid port: ${raw}. Must be an integer between 1 and 65535.`)\n process.exit(1)\n }\n return n\n}\n","/**\n * deepspace kill [--port N] [--all]\n *\n * Stops a local dev server bound to the given port, plus the workerd\n * child processes that wrangler/Vite would normally clean up but\n * sometimes leak when the parent dies ungracefully (Ctrl-C in a\n * detached terminal, IDE close, sandbox deny on signal, etc).\n *\n * deepspace kill # kill listener on 5173 + its workerd children\n * deepspace kill --port 5180 # kill listener on a different port\n * deepspace kill --all # also sweep ALL stray workerd/wrangler procs on the machine\n *\n * Cross-platform: uses lsof/pgrep on macOS and Linux, and PowerShell\n * (Get-NetTCPConnection / Get-CimInstance) on Windows. PowerShell ships\n * with every supported Windows version since 7; no extra install required.\n *\n * Always sends SIGTERM first, waits briefly, then SIGKILL anything\n * still alive — same shape as `vite`'s own shutdown handler so we\n * don't trample DO state mid-write. (On Windows, SIGTERM is best-effort:\n * Win32 has no real signals, so node maps both to TerminateProcess. We\n * still issue them in the same order for consistent log output.)\n */\n\nimport { defineCommand } from 'citty'\nimport { spawnSync } from 'node:child_process'\nimport { readFileSync, readdirSync, readlinkSync } from 'node:fs'\nimport { setTimeout as wait } from 'node:timers/promises'\nimport { findAppDir, resolveWorktreePort, resolveAppLaunchPort } from '../lib/app-context'\nimport { DEFAULT_PORT, resolvePort } from '../lib/port'\n\nconst SIGTERM_GRACE_MS = 1500\nconst IS_WIN = process.platform === 'win32'\n\n/**\n * Pick the port `kill` targets, mirroring `dev`'s binding precedence so the two\n * always agree (DEV-2). Pure for testing.\n * 1. explicit --port\n * 2. worktree port (dev ignores $DEEPSPACE_PORT inside a worktree, so we do too)\n * 3. $DEEPSPACE_PORT (dev binds it outside a worktree, over a launch.json that\n * dev only rewrites for an explicit --port)\n * 4. the app's launch.json port (kept in sync by `dev --port`)\n * 5. the default\n */\nexport function pickKillPort(opts: {\n explicit: number | null\n worktree: number | null\n env: number | null\n appLaunch: number | null\n}): number {\n if (opts.explicit != null) return opts.explicit\n if (opts.worktree != null) return opts.worktree\n if (opts.env != null) return opts.env\n return opts.appLaunch ?? DEFAULT_PORT\n}\n\nexport default defineCommand({\n meta: {\n name: 'kill',\n description: 'Kill the local dev server and any orphaned workerd processes',\n },\n args: {\n port: {\n type: 'string',\n description: `Port the dev server is bound to (default ${DEFAULT_PORT}, or $DEEPSPACE_PORT)`,\n required: false,\n },\n all: {\n type: 'boolean',\n description: 'Also kill stray workerd/wrangler processes across all ports',\n default: false,\n },\n },\n async run({ args }) {\n // Resolve which port to target, mirroring `dev`'s own precedence so `kill`\n // always targets the server `dev` bound (DEV-2). Without this, no-arg `kill`\n // hit :5173 even when `dev --port 8790` was running elsewhere.\n const cwd = process.cwd()\n const port = pickKillPort({\n explicit: args.port ? resolvePort(args.port) : null,\n worktree: resolveWorktreePort(cwd),\n // resolvePort() reads + validates $DEEPSPACE_PORT; only consult it when set.\n env: process.env.DEEPSPACE_PORT ? resolvePort() : null,\n appLaunch: resolveAppLaunchPort(findAppDir(cwd) ?? cwd),\n })\n const targets = new Set<number>()\n\n // 1. Anything LISTENing on the dev port (vite + the workerd child it\n // publishes through, occasionally a stray inspector). `enumerated`\n // tells us whether we could actually inspect the port at all.\n const listeners = enumerateListeners(port)\n for (const pid of listeners.pids) targets.add(pid)\n\n // 2. Children of those listeners — wrangler/vite tend to spawn workerd\n // as a sibling, but in some shells it ends up as a child instead.\n for (const pid of [...targets]) {\n for (const child of childPids(pid)) targets.add(child)\n }\n\n // 3. With --all, sweep workerd / wrangler / vite anywhere on the box.\n // Useful when port 5173 is \"free\" but a leftover workerd from a\n // previous run is still holding D1 / DO state in .wrangler/.\n let swept = false\n if (args.all) {\n const sweep = sweepByName(['workerd', 'wrangler', 'vite'])\n swept = sweep.swept\n for (const pid of sweep.pids) targets.add(pid)\n }\n\n if (targets.size === 0) {\n // DEV-1: distinguish \"inspected, found nothing\" from \"couldn't inspect\".\n // The latter must NOT report the port free (exit 0) while a leaked\n // workerd keeps holding DO/D1 state — that was the original silent no-op.\n const outcome = noTargetsMessage({\n enumerated: listeners.enumerated,\n swept,\n all: args.all,\n port,\n })\n if (!outcome.ok) {\n console.error(outcome.message)\n process.exit(1)\n }\n console.log(outcome.message)\n return\n }\n\n // SIGTERM pass.\n for (const pid of targets) {\n if (sendSignal(pid, 'SIGTERM')) {\n console.log(`SIGTERM → pid ${pid}`)\n }\n }\n await wait(SIGTERM_GRACE_MS)\n\n const stillAlive: number[] = []\n for (const pid of targets) {\n if (isAlive(pid)) stillAlive.push(pid)\n }\n\n // SIGKILL holdouts.\n for (const pid of stillAlive) {\n if (sendSignal(pid, 'SIGKILL')) {\n console.log(`SIGKILL → pid ${pid} (did not exit on SIGTERM)`)\n }\n }\n\n // Re-verify the port is free.\n await wait(200)\n const remaining = listenerPids(port)\n if (remaining.length > 0) {\n console.error(\n `Port ${port} is still held by pid(s) ${remaining.join(', ')} — try \\`deepspace kill --port ${port}\\` again, or kill manually.`,\n )\n process.exit(1)\n }\n\n // Report what actually happened. Under --all we may have swept processes on\n // ports other than `port` (matched by name), so a bare \"Port 5173 is free\"\n // would misrepresent the sweep (DEV-6).\n if (args.all) {\n console.log(`Killed ${targets.size} process(es) (workerd/wrangler/vite sweep). :${port} is free.`)\n } else {\n console.log(`Port ${port} is free.`)\n }\n },\n})\n\n// ── Platform-specific helpers ─────────────────────────────────────────────\n\n/**\n * Decide what to print when no kill targets were found. Pure so the DEV-1\n * rule — never claim the port is free when we couldn't actually inspect it —\n * is unit-testable. `ok:false` means we lacked any way to observe the system\n * (no lsof/pgrep AND no /proc) and must exit non-zero rather than lie.\n */\nexport function noTargetsMessage(opts: {\n enumerated: boolean\n swept: boolean\n all: boolean\n port: number\n}): { ok: boolean; message: string } {\n const { enumerated, swept, all, port } = opts\n const couldObserve = enumerated || (all && swept)\n if (!couldObserve) {\n return {\n ok: false,\n message:\n `Couldn't determine what's running on :${port}: no lsof/pgrep and /proc ` +\n `is unavailable, so nothing was inspected or killed. Install lsof (or ` +\n `procps for pgrep), or find and kill the process manually.`,\n }\n }\n return {\n ok: true,\n message: all\n ? `Nothing listening on :${port} and no stray workerd/wrangler/vite processes found.`\n : `Nothing listening on :${port}. (Pass --all to sweep stray workerd/wrangler.)`,\n }\n}\n\n/**\n * PIDs listening on `port`, plus whether we could inspect the port at all.\n * `enumerated:false` means every available method (lsof / PowerShell / /proc)\n * was missing — a genuine \"don't know\", not \"nothing there\".\n */\nfunction enumerateListeners(port: number): { pids: number[]; enumerated: boolean } {\n if (IS_WIN) {\n // Get-NetTCPConnection is the modern replacement for netstat -ano.\n // -ErrorAction SilentlyContinue swallows \"No matching connection\" so\n // the command exits 0 with empty stdout instead of a noisy red error.\n const r = runPowershellChecked(\n `Get-NetTCPConnection -LocalPort ${port} -State Listen -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess`,\n )\n return { pids: r.pids, enumerated: r.ran }\n }\n // lsof is authoritative when present. It exits 1 (not an error, for us) when\n // nothing matches, so \"ran but empty\" is a real \"nothing listening\".\n const lsof = runLsof(port)\n if (lsof.ran) return { pids: lsof.pids, enumerated: true }\n // lsof is absent on many container/CI images — `node:22-bookworm` ships none\n // of lsof/ss/fuser/netstat. /proc needs no external binary and covers Linux;\n // if it's also unavailable we truly can't tell (enumerated:false).\n const proc = listenerPidsViaProc(port)\n return { pids: proc.pids, enumerated: proc.available }\n}\n\n/** Thin wrapper for the post-kill re-verify, where capability is irrelevant. */\nfunction listenerPids(port: number): number[] {\n return enumerateListeners(port).pids\n}\n\n/** Run lsof for a port. `ran` distinguishes \"lsof absent\" from \"found nothing\". */\nfunction runLsof(port: number): { pids: number[]; ran: boolean } {\n try {\n // -t prints PIDs only, one per line; -nP avoids DNS / service lookups.\n const r = spawnSync('lsof', ['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-t'], {\n encoding: 'utf-8',\n })\n if (r.error) return { pids: [], ran: false } // ENOENT: lsof not installed\n // 0 = matches printed; 1 = no matches. Both mean lsof ran successfully.\n return { pids: r.status === 0 ? parsePidLines(r.stdout) : [], ran: true }\n } catch {\n return { pids: [], ran: false }\n }\n}\n\n/** Port → listening PIDs via /proc alone (no lsof/ss). Finds the LISTEN\n * socket's inode in /proc/net/tcp{,6}, then the process holding that fd.\n * `available` is false when /proc itself couldn't be read. */\nfunction listenerPidsViaProc(port: number): { pids: number[]; available: boolean } {\n let available = false\n try {\n const hexPort = port.toString(16).toUpperCase().padStart(4, '0')\n const inodes = new Set<string>()\n for (const f of ['/proc/net/tcp', '/proc/net/tcp6']) {\n let data: string\n try {\n data = readFileSync(f, 'utf-8')\n } catch {\n continue\n }\n available = true\n for (const line of data.split('\\n').slice(1)) {\n const cols = line.trim().split(/\\s+/)\n // sl local_address(1) rem_address(2) st(3) … inode(9); st 0A = LISTEN.\n if (cols[3] !== '0A') continue\n if (cols[1]?.split(':')[1] === hexPort && cols[9]) inodes.add(cols[9])\n }\n }\n if (!available) return { pids: [], available: false }\n if (!inodes.size) return { pids: [], available: true }\n const pids = new Set<number>()\n for (const pidDir of readdirSync('/proc')) {\n if (!/^\\d+$/.test(pidDir)) continue\n let fds: string[]\n try {\n fds = readdirSync(`/proc/${pidDir}/fd`)\n } catch {\n continue // not ours / gone\n }\n for (const fd of fds) {\n let link: string\n try {\n link = readlinkSync(`/proc/${pidDir}/fd/${fd}`)\n } catch {\n continue\n }\n const m = link.match(/^socket:\\[(\\d+)\\]$/)\n if (m && inodes.has(m[1])) {\n pids.add(Number(pidDir))\n break\n }\n }\n }\n return { pids: [...pids], available: true }\n } catch {\n return { pids: [], available }\n }\n}\n\nfunction childPids(parentPid: number): number[] {\n if (IS_WIN) {\n return runPowershell(\n `Get-CimInstance Win32_Process -Filter \"ParentProcessId=${parentPid}\" | Select-Object -ExpandProperty ProcessId`,\n )\n }\n return run(['pgrep', '-P', String(parentPid)])\n}\n\n/**\n * Sweep processes by name/commandline. `swept` reports whether the enumerator\n * (pgrep / PowerShell) actually ran — so `--all` doesn't falsely claim \"no\n * stray processes\" when it never got to look.\n */\nfunction sweepByName(names: string[]): { pids: number[]; swept: boolean } {\n const all = new Set<number>()\n if (IS_WIN) {\n // Match against process Name (e.g. \"workerd\") AND CommandLine (catches\n // npx-launched scripts like \"vite\" that show up as node.exe with vite\n // in the args).\n const orClauses = names\n .map((n) => `($_.Name -like '*${n}*') -or ($_.CommandLine -like '*${n}*')`)\n .join(' -or ')\n const script = `Get-CimInstance Win32_Process | Where-Object { ${orClauses} } | Select-Object -ExpandProperty ProcessId`\n const r = runPowershellChecked(script)\n for (const pid of r.pids) if (pid !== process.pid) all.add(pid)\n return { pids: [...all], swept: r.ran }\n }\n let swept = false\n for (const name of names) {\n const r = runPgrep(['-f', name])\n if (r.ran) swept = true\n for (const pid of r.pids) if (pid !== process.pid) all.add(pid)\n }\n return { pids: [...all], swept }\n}\n\n/** Run pgrep. `ran` distinguishes \"pgrep absent\" from \"matched nothing\" (exit 1). */\nfunction runPgrep(pgrepArgs: string[]): { pids: number[]; ran: boolean } {\n try {\n const r = spawnSync('pgrep', pgrepArgs, { encoding: 'utf-8' })\n if (r.error) return { pids: [], ran: false } // ENOENT: pgrep not installed\n // 0 = matches; 1 = no matches. Both mean pgrep ran.\n return { pids: r.status === 0 ? parsePidLines(r.stdout) : [], ran: r.status === 0 || r.status === 1 }\n } catch {\n return { pids: [], ran: false }\n }\n}\n\n// ── Process primitives ────────────────────────────────────────────────────\n\n/** Run a command and return whitespace-separated PIDs (empty array on failure). */\nfunction run(cmd: string[]): number[] {\n try {\n const r = spawnSync(cmd[0], cmd.slice(1), { encoding: 'utf-8' })\n if (r.status !== 0) return []\n return parsePidLines(r.stdout)\n } catch {\n return []\n }\n}\n\n/**\n * Run a PowerShell snippet. Prefers `pwsh` (PowerShell 7+) when available\n * and falls back to `powershell.exe` (Windows PowerShell 5.1, ships with\n * every Windows version we care about).\n */\nfunction runPowershell(script: string): number[] {\n return runPowershellChecked(script).pids\n}\n\n/** Like runPowershell but reports whether PowerShell actually ran (`ran`),\n * so callers can tell \"no matches\" (exit 0, empty) from \"PowerShell absent\". */\nfunction runPowershellChecked(script: string): { pids: number[]; ran: boolean } {\n const exe = pwshOrPowershell()\n try {\n const r = spawnSync(exe, ['-NoProfile', '-NonInteractive', '-Command', script], {\n encoding: 'utf-8',\n })\n if (r.error) return { pids: [], ran: false }\n // With -ErrorAction SilentlyContinue the query exits 0 even with no matches.\n return { pids: r.status === 0 ? parsePidLines(r.stdout) : [], ran: r.status === 0 }\n } catch {\n return { pids: [], ran: false }\n }\n}\n\nfunction pwshOrPowershell(): string {\n // `pwsh` is the modern cross-platform binary; `powershell.exe` is the\n // legacy Windows-only one. Try modern first, fall back if missing.\n const probe = spawnSync('pwsh', ['-NoProfile', '-Command', '$PSVersionTable.PSVersion.Major'], {\n encoding: 'utf-8',\n })\n if (probe.status === 0) return 'pwsh'\n return 'powershell.exe'\n}\n\nfunction parsePidLines(stdout: string): number[] {\n return stdout\n .split(/\\s+/)\n .map((s) => Number.parseInt(s, 10))\n .filter((n) => Number.isFinite(n) && n > 0)\n}\n\nfunction sendSignal(pid: number, signal: NodeJS.Signals): boolean {\n try {\n process.kill(pid, signal)\n return true\n } catch {\n return false\n }\n}\n\nfunction isAlive(pid: number): boolean {\n try {\n // signal 0 = \"do nothing, just check\"\n process.kill(pid, 0)\n return true\n } catch {\n return false\n }\n}\n","/**\n * deepspace test [suite] [--port N]\n *\n * Runs tests for a DeepSpace app. Always uses dev workers.\n *\n * deepspace test # smoke + api (quick check)\n * deepspace test smoke # smoke tests only\n * deepspace test api # API tests only\n * deepspace test e2e # all Playwright tests\n * deepspace test unit # vitest unit tests\n * deepspace test all # everything\n * deepspace test <file> # run specific test file\n *\n * Port is `--port` > $DEEPSPACE_PORT > 5173 — except inside a Claude Code\n * worktree, where (unless --port was passed) the worktree's own port is used\n * so tests hit the worktree's server, not the main repo's. The chosen port is\n * exported as DEEPSPACE_PORT to the Playwright child so the config +\n * webServer both bind to the same address. Pass a different port per app to\n * run multiple apps\n * (and test suites) in parallel.\n */\n\nimport { defineCommand } from 'citty'\nimport { readAppId } from '../lib/app-identity'\nimport { resolve } from 'node:path'\nimport { sync as spawnSync } from 'cross-spawn'\nimport { ensureToken } from '../auth'\nimport { findAppDir, findChildApps, resolveWorktreePort } from '../lib/app-context'\nimport { PLATFORM_URLS, writeDevVars } from '../env'\nimport { decodeJwtPayload } from '../jwt'\nimport { ensureInstallReady } from '../lib/install-status'\nimport { ensurePlaywright } from '../lib/playwright'\nimport { preflightNodeVersion, preflightWindowsWorkerd } from '../lib/preflight'\nimport { refreshSecretsCache } from '../lib/secrets'\nimport { DEFAULT_PORT, resolvePort } from '../lib/port'\nimport {\n prepareWranglerEnvConfig,\n wranglerViteEnv,\n type PreparedWranglerEnvConfig,\n} from '../lib/wrangler-env'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\nexport default defineCommand({\n meta: {\n name: 'test',\n description: 'Run tests for your DeepSpace app',\n },\n args: {\n suite: {\n type: 'positional',\n description: 'Test suite: smoke, api, e2e, unit, all (default: smoke+api)',\n required: false,\n },\n port: {\n type: 'string',\n description: `Port for vite/webServer (default ${DEFAULT_PORT}, or $DEEPSPACE_PORT)`,\n required: false,\n },\n env: {\n type: 'string',\n alias: 'e',\n description:\n 'wrangler.toml [env.<name>] block to test (uses secrets config <name> by default).',\n required: false,\n },\n },\n async run({ args }) {\n preflightNodeVersion('test')\n const suite = args.suite ?? 'default'\n const wranglerEnv =\n typeof args.env === 'string' && args.env.trim() ? args.env.trim() : undefined\n\n // Resolve the app root by walking up from cwd, matching `deepspace dev`.\n const start = resolve('.')\n const appDir = findAppDir(start)\n if (!appDir) {\n console.error(`No wrangler.toml found at or above ${start}.`)\n const children = findChildApps(start)\n if (children.length > 0) {\n console.error('Did you mean to run inside one of these app directories?')\n for (const c of children) console.error(` cd ${c}`)\n } else {\n console.error('Run from a DeepSpace app directory (one containing wrangler.toml).')\n }\n process.exit(1)\n }\n\n // Inside a Claude Code worktree the default port must match the\n // worktree's dev server (not 5173): Playwright's reuseExistingServer\n // would otherwise attach to the MAIN repo's server and silently test\n // stale code. Explicit --port still wins.\n const worktreePort = args.port ? null : resolveWorktreePort(appDir)\n const port = worktreePort ?? resolvePort(args.port)\n if (worktreePort && process.env.DEEPSPACE_PORT) {\n console.log(\n `Ignoring DEEPSPACE_PORT=${process.env.DEEPSPACE_PORT} inside a worktree — ` +\n `targeting per-worktree port ${port}. Pass --port to override.`,\n )\n }\n\n ensureInstallReady(appDir)\n\n // Always write .dev.vars pointing to dev workers. A logged-in user is\n // required so writeDevVars can mint APP_OWNER_JWT via the auth-worker.\n let token: string\n let ownerId: string\n try {\n token = await ensureToken()\n const payload = decodeJwtPayload<{ sub: string }>(token)\n ownerId = payload.sub\n } catch (err) {\n // Surface ensureToken's canonical message (\"Not logged in. Run `deepspace\n // login` first.\" / \"Session expired…\") instead of a bespoke one (ONB-5).\n console.error(err instanceof Error ? err.message : 'Not logged in. Run `deepspace login` first.')\n process.exit(1)\n }\n\n // Refresh the app-store secrets cache (config = wrangler env, or 'prd').\n // A repo without a DEEPSPACE_APP_ID hasn't been initialized — writeDevVars\n // below throws with the `deepspace init` pointer, so skip the pull.\n let generatedSecretsCache: string | undefined\n const appIdForSecrets = readAppId(appDir, wranglerEnv)\n if (appIdForSecrets) {\n try {\n const refreshed = await refreshSecretsCache(DEPLOY_URL, token, appIdForSecrets, wranglerEnv)\n if (refreshed) {\n generatedSecretsCache = refreshed.rendered\n console.log(refreshed.summary)\n }\n } catch (err: unknown) {\n console.error(\n `Failed to refresh app secrets: ${err instanceof Error ? err.message : String(err)}`,\n )\n process.exit(1)\n }\n }\n\n const sharedDevVarsCache = generatedSecretsCache !== undefined\n await writeDevVars(appDir, ownerId, token, wranglerEnv, {\n generatedSecretsCache,\n sharedDevVarsCache,\n })\n\n if (suite !== 'unit') {\n preflightWindowsWorkerd(appDir)\n ensurePlaywright(appDir)\n }\n\n let exitCode = 0\n\n switch (suite) {\n case 'smoke':\n exitCode = runPlaywright(\n appDir,\n ['tests/smoke.spec.ts'],\n port,\n wranglerEnv,\n sharedDevVarsCache,\n )\n break\n case 'api':\n exitCode = runPlaywright(\n appDir,\n ['tests/api.spec.ts'],\n port,\n wranglerEnv,\n sharedDevVarsCache,\n )\n break\n case 'e2e':\n exitCode = runPlaywright(appDir, [], port, wranglerEnv, sharedDevVarsCache)\n break\n case 'unit':\n exitCode = runVitest(appDir)\n break\n case 'all':\n exitCode = runVitest(appDir)\n if (exitCode === 0)\n exitCode = runPlaywright(appDir, [], port, wranglerEnv, sharedDevVarsCache)\n break\n case 'default':\n exitCode = runPlaywright(\n appDir,\n ['tests/smoke.spec.ts', 'tests/api.spec.ts'],\n port,\n wranglerEnv,\n sharedDevVarsCache,\n )\n break\n default:\n if (suite.endsWith('.spec.ts')) {\n exitCode = runPlaywright(appDir, [suite], port, wranglerEnv, sharedDevVarsCache)\n } else {\n console.error(`Unknown test suite: ${suite}`)\n console.error('Available: smoke, api, e2e, unit, all')\n process.exit(1)\n }\n }\n\n process.exit(exitCode)\n },\n})\n\nfunction runPlaywright(\n appDir: string,\n testFiles: string[],\n port: number,\n wranglerEnv?: string,\n sharedDevVarsCache = false,\n): number {\n let wranglerConfig: PreparedWranglerEnvConfig\n try {\n wranglerConfig = prepareWranglerEnvConfig(appDir, wranglerEnv, { sharedDevVarsCache })\n } catch (err: unknown) {\n console.error(err instanceof Error ? err.message : String(err))\n return 1\n }\n try {\n const result = spawnSync(\n 'npx',\n ['playwright', 'test', '--config', 'tests/playwright.config.ts', ...testFiles],\n {\n cwd: appDir,\n stdio: 'inherit',\n env: wranglerViteEnv(process.env, wranglerConfig, { DEEPSPACE_PORT: String(port) }),\n },\n )\n return result.status ?? 1\n } finally {\n wranglerConfig.cleanup()\n }\n}\n\nfunction runVitest(appDir: string): number {\n const result = spawnSync('npx', ['vitest', 'run', '--passWithNoTests'], {\n cwd: appDir,\n stdio: 'inherit',\n })\n return result.status ?? 1\n}\n","import { execSync } from 'node:child_process'\nimport { sync as spawnSync } from 'cross-spawn'\n\nexport function ensurePlaywright(appDir: string) {\n try {\n // execSync interprets the command via shell, so it handles npx/npx.cmd\n // resolution on its own. Only spawn()/spawnSync() need cross-spawn.\n execSync('npx playwright --version', { cwd: appDir, stdio: 'pipe' })\n } catch {\n console.log('Installing Playwright...')\n execSync('npm install -D @playwright/test', { cwd: appDir, stdio: 'pipe' })\n }\n\n // `playwright install` is idempotent: a fast no-op when Chromium already\n // exists, and the first real browser download only when a browser command\n // actually needs it.\n const isLinux = process.platform === 'linux'\n const isRoot = isLinux && typeof process.getuid === 'function' && process.getuid() === 0\n const args = isRoot ? ['install', '--with-deps', 'chromium'] : ['install', 'chromium']\n const result = spawnSync('npx', ['playwright', ...args], {\n cwd: appDir,\n stdio: 'inherit',\n })\n\n if (result.status !== 0) {\n console.error('\\nPlaywright install failed. On Linux, system libs may be missing. Try:')\n console.error(' sudo npx playwright install --with-deps chromium')\n process.exit(1)\n }\n}\n","/**\n * deepspace screenshot <url> <output> [--full-page] [--wait-for-timeout ms]\n *\n * Takes a Playwright Chromium screenshot, installing the browser on demand.\n */\n\nimport { defineCommand } from 'citty'\nimport { sync as spawnSync } from 'cross-spawn'\nimport { resolve } from 'node:path'\nimport { ensurePlaywright } from '../lib/playwright'\n\nexport default defineCommand({\n meta: {\n name: 'screenshot',\n description: 'Take a Playwright screenshot, installing Chromium on demand',\n },\n args: {\n url: {\n type: 'positional',\n description: 'URL to capture, for example http://localhost:5173/',\n required: true,\n },\n output: {\n type: 'positional',\n description: 'Output image path, for example screenshot.png',\n required: true,\n },\n 'full-page': {\n type: 'boolean',\n description: 'Capture the full scrollable page',\n required: false,\n },\n 'wait-for-timeout': {\n type: 'string',\n description: 'Milliseconds to wait before capture',\n required: false,\n },\n },\n run({ args }) {\n const appDir = resolve('.')\n ensurePlaywright(appDir)\n\n const playwrightArgs = ['playwright', 'screenshot', args.url, args.output]\n if (args['full-page']) playwrightArgs.push('--full-page')\n if (args['wait-for-timeout']) {\n playwrightArgs.push('--wait-for-timeout', String(args['wait-for-timeout']))\n }\n\n const result = spawnSync('npx', playwrightArgs, {\n cwd: appDir,\n stdio: 'inherit',\n })\n\n process.exit(result.status ?? 1)\n },\n})\n","/**\n * deepspace test-accounts\n *\n * Manage test accounts for local development and CI.\n * Test accounts use @deepspace.test emails and are clearly\n * demarcated in the database. Max 10 per developer.\n *\n * Credentials are saved to ~/.deepspace/test-accounts.json (0600)\n * so they persist across projects and sessions.\n *\n * deepspace test-accounts create --email bot@deepspace.test --password Pass123!\n * deepspace test-accounts list\n * deepspace test-accounts delete --email bot@deepspace.test\n * deepspace test-accounts delete --id <id>\n * deepspace test-accounts clear # delete all (with confirm)\n * deepspace test-accounts clear --label e2e # delete only label=e2e\n * deepspace test-accounts clear --yes # skip confirm (CI)\n */\n\nimport { defineCommand } from 'citty'\nimport * as p from '@clack/prompts'\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport { ensureToken, SESSION_PATH } from '../auth'\nimport { PLATFORM_URLS } from '../env'\n\nconst SESSION_COOKIE = '__Secure-better-auth.session_token'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? PLATFORM_URLS.auth\nconst DIR = join(homedir(), '.deepspace')\nconst ACCOUNTS_PATH = join(DIR, 'test-accounts.json')\n\n// ── Local credential store ─────────────────────────────────────────\n\ninterface StoredAccount {\n id: string\n email: string\n password: string\n userId: string\n name?: string\n label?: string | null\n createdAt: number\n}\n\nfunction loadAccounts(): StoredAccount[] {\n if (!existsSync(ACCOUNTS_PATH)) return []\n try {\n return JSON.parse(readFileSync(ACCOUNTS_PATH, 'utf-8'))\n } catch {\n return []\n }\n}\n\nfunction saveAccounts(accounts: StoredAccount[]) {\n mkdirSync(DIR, { recursive: true })\n writeFileSync(ACCOUNTS_PATH, JSON.stringify(accounts, null, 2), { mode: 0o600 })\n}\n\n// ── Helpers ────────────────────────────────────────────────────────\n\nfunction sessionCookie(): string {\n const token = readFileSync(SESSION_PATH, 'utf-8').trim()\n return `${SESSION_COOKIE}=${encodeURIComponent(token)}`\n}\n\ninterface RemoteAccount {\n id: string\n email: string\n userId: string\n label: string | null\n createdAt: number\n}\n\nasync function fetchRemoteAccounts(): Promise<RemoteAccount[]> {\n const res = await fetch(`${AUTH_URL}/api/auth/test-accounts`, {\n headers: { Cookie: sessionCookie(), Origin: AUTH_URL },\n })\n const data = (await res.json().catch(() => ({}))) as {\n accounts?: RemoteAccount[]\n error?: string\n }\n if (!res.ok || !data.accounts) {\n throw new Error(data.error ?? 'Failed to list test accounts')\n }\n return data.accounts\n}\n\nasync function deleteRemote(id: string): Promise<void> {\n const res = await fetch(`${AUTH_URL}/api/auth/test-accounts/${id}`, {\n method: 'DELETE',\n headers: { Cookie: sessionCookie(), Origin: AUTH_URL },\n })\n if (!res.ok) {\n const data = (await res.json().catch(() => ({}))) as { error?: string }\n throw new Error(data.error ?? `DELETE returned ${res.status}`)\n }\n}\n\n// ── Subcommands ────────────────────────────────────────────────────\n\nconst create = defineCommand({\n meta: {\n name: 'create',\n description: 'Create a test account',\n },\n args: {\n email: {\n type: 'string',\n description: 'Email (must end with @deepspace.test)',\n required: true,\n },\n password: {\n type: 'string',\n description: 'Password (min 8 characters)',\n required: true,\n },\n name: {\n type: 'string',\n description: 'Display name',\n required: false,\n },\n label: {\n type: 'string',\n description: 'Label for this test account',\n required: false,\n },\n },\n async run({ args }) {\n await ensureToken()\n\n const res = await fetch(`${AUTH_URL}/api/auth/test-accounts`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Cookie: sessionCookie(),\n Origin: AUTH_URL,\n },\n body: JSON.stringify({\n email: args.email,\n password: args.password,\n name: args.name,\n label: args.label,\n }),\n })\n\n const data = (await res.json().catch(() => ({}))) as {\n id?: string\n email?: string\n userId?: string\n label?: string | null\n createdAt?: number\n error?: string\n }\n\n if (!res.ok || !data.id) {\n console.error(`Failed: ${data.error ?? 'Unknown error'}`)\n process.exit(1)\n }\n\n const account = data as {\n id: string\n email: string\n userId: string\n label: string | null\n createdAt: number\n }\n\n // Save credentials locally\n const accounts = loadAccounts()\n accounts.push({\n id: account.id,\n email: args.email,\n password: args.password,\n userId: account.userId,\n name: args.name,\n label: account.label,\n createdAt: account.createdAt,\n })\n saveAccounts(accounts)\n\n console.log(`Created test account:`)\n console.log(` ID: ${account.id}`)\n console.log(` Email: ${account.email}`)\n console.log(` Password: ${args.password}`)\n console.log(` UserID: ${account.userId}`)\n if (account.label) console.log(` Label: ${account.label}`)\n console.log(`\\nSaved to ${ACCOUNTS_PATH}`)\n },\n})\n\nconst list = defineCommand({\n meta: {\n name: 'list',\n description: 'List your test accounts',\n },\n async run() {\n await ensureToken()\n\n let remote: RemoteAccount[]\n try {\n remote = await fetchRemoteAccounts()\n } catch (err) {\n console.error(`Failed: ${(err as Error).message}`)\n process.exit(1)\n }\n\n if (remote.length === 0) {\n console.log(\n 'No test accounts. Create one with: deepspace test-accounts create --email <email> --password <password>',\n )\n return\n }\n\n // Merge with local credentials (passwords are only stored locally)\n const local = loadAccounts()\n const localByEmail = new Map(local.map((a) => [a.email, a]))\n\n console.log(`Test accounts (${remote.length}/10):\\n`)\n for (const a of remote) {\n const stored = localByEmail.get(a.email)\n const date = new Date(a.createdAt).toLocaleDateString()\n console.log(` ${a.email}${a.label ? ` (${a.label})` : ''}`)\n console.log(` ID: ${a.id} UserID: ${a.userId} Created: ${date}`)\n if (stored?.password) {\n console.log(` Password: ${stored.password}`)\n } else {\n console.log(` Password: (not saved locally)`)\n }\n }\n },\n})\n\nconst del = defineCommand({\n meta: {\n name: 'delete',\n description: 'Delete a test account by --email or --id',\n },\n args: {\n email: {\n type: 'string',\n description: 'Email of the test account to delete',\n required: false,\n },\n id: {\n type: 'string',\n description: 'ID of the test account to delete',\n required: false,\n },\n },\n async run({ args }) {\n if (!args.email && !args.id) {\n console.error('Provide --email <email> or --id <id>.')\n process.exit(1)\n }\n if (args.email && args.id) {\n console.error('Provide either --email or --id, not both.')\n process.exit(1)\n }\n\n await ensureToken()\n\n let targetId = args.id as string | undefined\n const targetEmail = args.email as string | undefined\n\n if (targetEmail && !targetId) {\n let remote: RemoteAccount[]\n try {\n remote = await fetchRemoteAccounts()\n } catch (err) {\n console.error(`Failed: ${(err as Error).message}`)\n process.exit(1)\n }\n const match = remote.find((a) => a.email === targetEmail)\n if (!match) {\n console.error(`No test account with email ${targetEmail}.`)\n process.exit(1)\n }\n targetId = match.id\n }\n\n try {\n await deleteRemote(targetId!)\n } catch (err) {\n console.error(`Failed: ${(err as Error).message}`)\n process.exit(1)\n }\n\n // Remove from local store\n const accounts = loadAccounts().filter(\n (a) => a.id !== targetId && (!targetEmail || a.email !== targetEmail),\n )\n saveAccounts(accounts)\n\n console.log(`Test account deleted${targetEmail ? `: ${targetEmail}` : `: ${targetId}`}`)\n },\n})\n\nconst clear = defineCommand({\n meta: {\n name: 'clear',\n description: 'Delete all your test accounts (or those matching --label)',\n },\n args: {\n label: {\n type: 'string',\n description: 'Only delete accounts with this label (e.g. e2e, slack-clone)',\n required: false,\n },\n yes: {\n type: 'boolean',\n description: 'Skip confirmation prompt (for CI scripts)',\n default: false,\n },\n },\n async run({ args }) {\n await ensureToken()\n\n let remote: RemoteAccount[]\n try {\n remote = await fetchRemoteAccounts()\n } catch (err) {\n console.error(`Failed: ${(err as Error).message}`)\n process.exit(1)\n }\n\n const targets = args.label ? remote.filter((a) => a.label === args.label) : remote\n\n if (targets.length === 0) {\n const suffix = args.label ? ` with label '${args.label}'` : ''\n console.log(`No test accounts${suffix} to delete.`)\n return\n }\n\n if (!args.yes) {\n const subject = args.label\n ? `${targets.length} test account(s) labeled '${args.label}'`\n : `all ${targets.length} test account(s)`\n const confirmed = await p.confirm({\n message: `Delete ${subject}? This is not reversible.`,\n initialValue: false,\n })\n if (p.isCancel(confirmed) || !confirmed) {\n console.log('Cancelled.')\n return\n }\n }\n\n let ok = 0\n const failures: Array<{ email: string; error: string }> = []\n for (const a of targets) {\n try {\n await deleteRemote(a.id)\n ok++\n } catch (err) {\n failures.push({ email: a.email, error: (err as Error).message })\n }\n }\n\n // Sync local store with what's actually deleted.\n const deletedIds = new Set(\n targets.filter((t) => !failures.find((f) => f.email === t.email)).map((t) => t.id),\n )\n saveAccounts(loadAccounts().filter((a) => !deletedIds.has(a.id)))\n\n console.log(`Deleted ${ok}/${targets.length} test account(s).`)\n if (failures.length > 0) {\n console.error(`\\nFailed:`)\n for (const f of failures) console.error(` ${f.email}: ${f.error}`)\n process.exit(1)\n }\n },\n})\n\nexport default defineCommand({\n meta: {\n name: 'test-accounts',\n description: 'Manage test accounts for development',\n },\n subCommands: {\n create,\n list,\n delete: del,\n clear,\n },\n})\n","/**\n * deepspace deploy\n *\n * Builds the app with Vite (Cloudflare plugin bundles both client + worker),\n * then uploads to the deploy worker which handles Cloudflare WfP deployment.\n *\n * Uses the same build pipeline as dev for full fidelity. Reads the output\n * wrangler.json (via .wrangler/deploy/config.json) to find the built assets\n * and worker bundle — the same contract that `wrangler deploy` uses.\n */\n\nimport { defineCommand } from 'citty'\nimport { execSync } from 'node:child_process'\nimport { randomUUID } from 'node:crypto'\nimport { readFileSync, readdirSync, existsSync } from 'node:fs'\nimport { join, resolve, dirname } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport * as p from '@clack/prompts'\nimport { createSpinner } from '../lib/spinner'\nimport { ensureInstallReady } from '../lib/install-status'\nimport { preflightNodeVersion } from '../lib/preflight'\nimport { removeMacosJunk } from '../lib/macos-junk'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS, extractCustomDevVars, parseDevVars, writeDevVars } from '../env'\nimport { decodeJwtPayload } from '../jwt'\nimport {\n type PulledSecretsCache,\n refreshSecretsCache,\n stripGeneratedSecretsCache,\n} from '../lib/secrets'\nimport { mintAppId, readAppId, resolveExistingAppId, writeAppId } from '../lib/app-identity'\nimport {\n bindingManifestFromOutputConfig,\n validateBindingManifest,\n RESERVED_BINDING_NAMES,\n} from '../../server/rooms/binding-manifest'\nimport {\n resolveAppNameForEnv,\n devVarsPathFor,\n readWranglerConfig,\n hasWranglerConfig,\n prepareWranglerEnvConfig,\n wranglerViteEnv,\n type PreparedWranglerEnvConfig,\n type WranglerConfig,\n} from '../lib/wrangler-env'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\n\nconst CLOUDFLARE_DEPLOY_ERROR_HINT =\n \"Deployment reached the DeepSpace deploy worker, but Cloudflare's deployment \" +\n 'control-plane API failed. This is often caused by a Cloudflare Dashboard/API ' +\n 'incident or Workers for Platforms entitlement outage. Already deployed apps ' +\n 'should keep serving; wait for Cloudflare to recover and retry.'\n\n/**\n * SDK-reserved `run_worker_first` prefixes. Apps can't override or\n * shadow these; only declare additional patterns. The CLI strips the\n * reserved ones before forwarding so the platform never sees them\n * twice — keeps the deploy-side merge a clean set-union.\n */\nconst RESERVED_RUN_WORKER_FIRST = new Set([\n '/api/*',\n '/ws/*',\n '/internal/*',\n '/v1/*',\n '/_deepspace/*',\n])\n\nfunction extractRunWorkerFirst(cfg: { assets?: { run_worker_first?: unknown } }): string[] {\n const raw = cfg.assets?.run_worker_first\n if (!Array.isArray(raw)) return []\n const out: string[] = []\n const seen = new Set<string>()\n for (const entry of raw) {\n if (typeof entry !== 'string') continue\n const trimmed = entry.trim()\n if (!trimmed.startsWith('/')) continue\n if (RESERVED_RUN_WORKER_FIRST.has(trimmed)) continue\n if (seen.has(trimmed)) continue\n seen.add(trimmed)\n out.push(trimmed)\n }\n return out\n}\n\n/** Extract a human-readable message from an unknown thrown value. */\nfunction errMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n\nfunction isLikelyCloudflareDeployFailure(status: number, error: string | undefined): boolean {\n if (status >= 500) return true\n if (!error) return false\n return [\n 'Upload session failed',\n 'Asset upload failed',\n 'Worker deploy failed',\n 'entitlements.not_available',\n 'Internal Server Error',\n ].some((needle) => error.includes(needle))\n}\n\nfunction formatDeployWorkerError(status: number, error: string | undefined): string {\n const detail = error ?? `Deployment error (${status})`\n if (!isLikelyCloudflareDeployFailure(status, error)) return detail\n return `${CLOUDFLARE_DEPLOY_ERROR_HINT}\\n\\nUnderlying error: ${detail}`\n}\n\n/**\n * Must stay <= the deploy worker's MAX_UPLOAD_GROUP_BYTES, otherwise the worker\n * rejects a group with a 413 that postWithRetry won't retry (it's a 4xx),\n * dead-ending the deploy. The DEEPSPACE_DEPLOY_GROUP_BYTES override is clamped\n * to this.\n */\nconst MAX_GROUP_BYTES = 40 * 1024 * 1024\n\n/**\n * Soft cap on the serialized size of one asset *group*. We pack whole asset\n * entries into groups under this size and POST each group on its own, so no\n * single request carries the entire payload (a ~40MB+ body stalls and gets\n * reset mid-upload on a marginal uplink: `write EPIPE`). A single asset larger\n * than this is sent alone in its own group — we never split an individual\n * asset. Overridable via DEEPSPACE_DEPLOY_GROUP_BYTES, clamped to MAX_GROUP_BYTES.\n */\nconst GROUP_BYTES = (() => {\n const raw = Number(process.env.DEEPSPACE_DEPLOY_GROUP_BYTES)\n const v = Number.isInteger(raw) && raw > 0 ? raw : 3 * 1024 * 1024\n return Math.min(v, MAX_GROUP_BYTES)\n})()\n\n/**\n * Decide how deploy should react to hand-edited `.dev.vars` secrets relative to\n * the store, which is the single source of truth for what a deploy ships.\n *\n * The dangerous case (see the secrets-source-of-truth work): the store ships\n * NOTHING but `.dev.vars` holds hand-edited secrets. Deploying then ships the\n * app with an empty secret set, replacing any secrets a previous deploy set —\n * silently dropping them from production. We block that (overridable with\n * `--allow-missing-secrets`) rather than only warning after the fact. When the\n * store already ships some secrets, extra local-only `.dev.vars` entries are a\n * benign warning (they're a local dev cache, not deploy config).\n *\n * Pure + exported for tests.\n */\nexport function classifyDevVarsSecrets(opts: {\n storeSecretNames: string[]\n handEditedDevVarKeys: string[]\n allowMissing: boolean\n}): { kind: 'ok' } | { kind: 'warn'; strayKeys: string[] } | { kind: 'block'; strayKeys: string[] } {\n const store = new Set(opts.storeSecretNames)\n const strayKeys = opts.handEditedDevVarKeys.filter((k) => !store.has(k))\n if (strayKeys.length === 0) return { kind: 'ok' }\n if (opts.storeSecretNames.length === 0 && !opts.allowMissing) return { kind: 'block', strayKeys }\n return { kind: 'warn', strayKeys }\n}\n\n/**\n * Pack whole asset entries into groups whose serialized JSON stays under\n * `maxBytes`. We never split an individual asset across groups, so a single\n * asset larger than `maxBytes` becomes its own (oversized) group.\n */\nexport function packAssetGroups<T>(assets: T[], maxBytes: number): T[][] {\n const groups: T[][] = []\n let current: T[] = []\n let currentBytes = 2 // \"[]\"\n for (const a of assets) {\n const entryBytes = Buffer.byteLength(JSON.stringify(a), 'utf-8') + 1 // +1 ≈ comma\n if (current.length > 0 && currentBytes + entryBytes > maxBytes) {\n groups.push(current)\n current = []\n currentBytes = 2\n }\n current.push(a)\n currentBytes += entryBytes\n }\n if (current.length > 0) groups.push(current)\n return groups\n}\n\n/**\n * POST with retry + backoff. Chunked upload exists to survive a flaky uplink,\n * so we always retry on network errors (fetch throws — e.g. `write EPIPE` when\n * the edge resets a stalled upload). Transient server statuses (408/429/5xx)\n * are only retried when `retryServerErrors` is set; client 4xx are always\n * returned as-is (caller surfaces the message). `makeInit` is called per\n * attempt so the request body is rebuilt fresh each time.\n *\n * The group-staging endpoint is an idempotent PUT, so retrying its 5xx is safe.\n * The commit endpoint runs a real (non-idempotent) deploy, so it passes\n * `retryServerErrors: false` — a 5xx means the server already received and\n * possibly acted on the request, and re-sending could double-deploy. Only a\n * thrown fetch (connection reset before/without a response) is retried there.\n */\nexport async function postWithRetry(\n url: string,\n makeInit: () => RequestInit,\n {\n attempts = 4,\n retryServerErrors = true,\n }: { attempts?: number; retryServerErrors?: boolean } = {},\n): Promise<Response> {\n let lastRes: Response | undefined\n let lastErr: unknown\n for (let attempt = 1; attempt <= attempts; attempt++) {\n try {\n const res = await fetch(url, makeInit())\n const isTransient =\n retryServerErrors && (res.status >= 500 || res.status === 408 || res.status === 429)\n if (!isTransient) {\n return res\n }\n lastRes = res\n } catch (err) {\n lastErr = err\n }\n if (attempt < attempts) {\n await new Promise((r) => setTimeout(r, Math.min(8_000, 500 * 2 ** (attempt - 1))))\n }\n }\n if (lastRes) return lastRes\n throw lastErr instanceof Error ? lastErr : new Error(String(lastErr))\n}\n\n/**\n * Best-effort cleanup of an upload's staged groups after a deploy gives up.\n * Fire-and-forget: a failed deploy must surface its real error, not a cleanup\n * error, so this never throws. It's not the only safety net either — the\n * deploy worker's R2 staging prefix carries a lifecycle rule that reaps\n * anything this misses (e.g. the CLI process is killed before it can abort).\n */\nasync function abortStagedUpload(\n appId: string,\n uploadId: string,\n totalGroups: number,\n token: string,\n): Promise<void> {\n try {\n await fetch(\n `${DEPLOY_URL}/api/deploy/${appId}/assets` +\n `?uploadId=${uploadId}&totalGroups=${totalGroups}`,\n { method: 'DELETE', headers: { Authorization: `Bearer ${token}` } },\n )\n } catch {\n // best-effort — orphaned groups are reaped by the staging lifecycle rule\n }\n}\n\nexport default defineCommand({\n meta: {\n name: 'deploy',\n description: 'Build and deploy your DeepSpace app',\n },\n args: {\n dir: {\n type: 'positional',\n description: 'App directory (default: current directory)',\n required: false,\n },\n env: {\n type: 'string',\n alias: 'e',\n description:\n 'wrangler.toml [env.<name>] block to deploy (e.g. --env staging). ' +\n 'Omit to deploy the top-level config.',\n required: false,\n },\n rename: {\n type: 'boolean',\n description:\n 'Confirm that a changed wrangler `name` renames this app (its URL moves; data, secrets, and collaborators travel). Without this flag an interactive prompt asks.',\n default: false,\n },\n 'allow-missing-secrets': {\n type: 'boolean',\n description:\n 'Deploy even though hand-edited .dev.vars secrets are absent from the store (they will NOT be deployed, and any a previous deploy set are dropped).',\n default: false,\n },\n adopt: {\n type: 'boolean',\n description:\n 'Confirm adopting an existing app you can deploy but do not own (collaborator/admin ' +\n 'on-behalf) when wrangler.toml has no DEEPSPACE_APP_ID. Without this flag an ' +\n 'interactive prompt asks.',\n default: false,\n },\n },\n async run({ args }) {\n preflightNodeVersion('deploy')\n const appDir = resolve(args.dir ?? '.')\n const envName = typeof args.env === 'string' && args.env.trim() ? args.env.trim() : undefined\n\n // ── Read app name from wrangler.toml ──────────────────────\n if (!hasWranglerConfig(appDir)) {\n console.error('No wrangler.toml found. Are you in a DeepSpace app directory?')\n process.exit(1)\n }\n\n ensureInstallReady(appDir)\n\n p.intro('Deploying DeepSpace app')\n\n const wranglerConfig: WranglerConfig = readWranglerConfig(appDir)\n const nameRes = resolveAppNameForEnv(wranglerConfig, envName)\n if (!nameRes.ok) {\n p.cancel(nameRes.reason)\n process.exit(1)\n }\n // Refuse noncanonical names the same way `deepspace dev` does. Without\n // this, deploy would canonicalize server bindings while client constants\n // (`SCOPE_ID = app:${APP_NAME}`) and `[vars].APP_NAME` continued to use\n // the raw name — splitting identity across surfaces. Fail-fast so the\n // dev fixes wrangler.toml once and every surface reads from the same\n // source of truth.\n const declaredName = envName ? wranglerConfig.env?.[envName]?.name : wranglerConfig.name\n if (declaredName !== nameRes.name) {\n const where = envName ? `[env.${envName}].name` : '`name`'\n p.cancel(\n `wrangler.toml: ${where} \"${declaredName}\" is not in canonical form. ` +\n `Update it to \"${nameRes.name}\" and re-run.`,\n )\n process.exit(1)\n }\n const appName = nameRes.name\n\n // ── App identity ───────────────────────────────────────────\n // The immutable id is the deploy target; `name` is just the subdomain\n // label this deploy claims. A repo with no id yet gets one minted here\n // (first deploy registers it) — commit the wrangler.toml change.\n let appId = readAppId(appDir, envName)\n p.log.info(envName ? `App: ${appName} (env: ${envName})` : `App: ${appName}`)\n\n // ── Ensure valid JWT ───────────────────────────────────────\n let token: string\n let ownerId: string\n try {\n token = await ensureToken()\n ownerId = decodeJwtPayload<{ sub: string }>(token).sub\n } catch (err: unknown) {\n p.cancel(errMessage(err))\n process.exit(1)\n }\n\n // A repo with no id yet ADOPTS the app already registered at this\n // subdomain (e.g. a legacy app the platform registered during the\n // app-identity cutover) instead of minting a fresh id that would collide\n // with the existing route registration (\"name … is taken by another\n // app\"). Adoption covers on-behalf deployers too — a collaborator or\n // admin deploying a legacy repo they don't own. Mints only when nothing\n // is registered here; fails up front when the name belongs to an app the\n // caller can't deploy. Needs the token, so it runs after auth.\n if (!appId) {\n const existing = await resolveExistingAppId(DEPLOY_URL, token, appName)\n if (existing.kind === 'taken') {\n p.cancel(\n `\"${appName}\" is taken by an app you don't have deploy access to. ` +\n 'Ask the owner to add you as a collaborator (`deepspace collaborators add`), ' +\n 'or pick a different `name` in wrangler.toml.',\n )\n process.exit(1)\n }\n // Adopting an app the caller does NOT own must be explicit: for an\n // admin-tier account the access check passes for EVERY registered app,\n // so a fresh project whose name collides with someone's legacy app\n // would otherwise silently deploy over it on-behalf.\n if (existing.kind === 'adopted' && !existing.owned && !args.adopt) {\n if (!process.stdin.isTTY) {\n // Piped/CI stdin: clack's confirm never resolves — fail loudly\n // with the flag remedy instead (same idiom as --rename).\n p.cancel(\n `\"${appName}\" is an existing app owned by another account that you can deploy ` +\n 'on-behalf (collaborator/admin). Confirmation needs an interactive terminal — ' +\n 're-run with --adopt to deploy it, or pick a different `name` in wrangler.toml ' +\n 'if you meant a new app.',\n )\n process.exit(1)\n }\n const yes = await p.confirm({\n message:\n `\"${appName}\" is an existing app owned by another account that you can deploy ` +\n 'on-behalf (you are a collaborator or admin). Deploy it? ' +\n '(Meant a new app? Pick a different `name` in wrangler.toml.)',\n })\n if (p.isCancel(yes) || !yes) {\n p.cancel('Deploy cancelled.')\n process.exit(1)\n }\n }\n appId = existing.kind === 'adopted' ? existing.appId : mintAppId()\n writeAppId(appDir, appId, { wranglerEnv: envName })\n p.log.info(\n existing.kind === 'adopted'\n ? `Adopted existing app id ${appId} for ${appName} — commit wrangler.toml.`\n : `Minted app id ${appId} — commit wrangler.toml.`,\n )\n }\n p.log.info(`Id: ${appId}`)\n\n // ── App secrets ────────────────────────────────────────────\n // Every app has one store (/api/secrets/:appId); the config shipped is\n // the wrangler env name, or 'prd' for the top-level config. No store or\n // config yet → deploy proceeds with no user secrets.\n // Reads only the hand-edited \"custom\" section of a .dev.vars file. We strip\n // the generated store cache first (extractCustomDevVars only drops SDK-managed\n // keys, not the GENERATED_SECRETS_DIVIDER block), mirroring writeDevVars — else\n // a stale cache entry (a just-deleted secret, or another config's secrets in\n // the shared .dev.vars) would masquerade as a hand-edited local-only var.\n const readCustomDevVarsAt = (path: string): Record<string, string> => {\n if (!existsSync(path)) return {}\n const section = extractCustomDevVars(stripGeneratedSecretsCache(readFileSync(path, 'utf-8')))\n if (!section) return {}\n try {\n return parseDevVars(section)\n } catch (err: unknown) {\n p.cancel(`.dev.vars: ${errMessage(err)}`)\n process.exit(1)\n }\n }\n\n let linkedSecrets: PulledSecretsCache | null = null\n // Hand-edited .dev.vars vars, snapshotted BEFORE the store refresh regenerates\n // the file — the refresh's writeDevVars overwrites the custom section with the\n // store's rendered cache, so reading afterwards would always come back empty.\n let localOnlyDevVars: Record<string, string> = {}\n try {\n const refreshed = await refreshSecretsCache(DEPLOY_URL, token, appId, envName)\n if (refreshed) {\n linkedSecrets = refreshed.pulled\n localOnlyDevVars = readCustomDevVarsAt(\n devVarsPathFor(appDir, envName, { sharedDevVarsCache: true }),\n )\n await writeDevVars(appDir, ownerId, token, envName, {\n appId,\n generatedSecretsCache: refreshed.rendered,\n sharedDevVarsCache: true,\n })\n p.log.info(refreshed.summary)\n }\n } catch (err: unknown) {\n // A 403 here means the caller isn't the owner/collaborator/admin — the\n // same gate deploy enforces. The secrets refresh just hits it first, so\n // present a clean authorization message (e.g. a revoked collaborator).\n const msg = errMessage(err)\n if ((err as { status?: number })?.status === 403) {\n p.cancel(\n \"You're not authorized to deploy this app — you must be its owner or a current \" +\n 'collaborator. If you were a collaborator, your access may have been revoked.',\n )\n } else {\n p.cancel(`Failed to refresh app secrets before deploy: ${msg}`)\n }\n process.exit(1)\n }\n\n // ── Build with Vite (Cloudflare plugin bundles client + worker) ──\n // When --env is set, pass Vite a generated config with that env already\n // flattened. This keeps Cloudflare from preferring stale `.dev.vars.<env>`\n // files over DeepSpace's shared `.dev.vars` cache.\n const junk = removeMacosJunk(appDir)\n if (junk > 0) p.log.info(`Removed ${junk} macOS metadata file(s) (._*, .DS_Store)`)\n\n const s = createSpinner()\n s.start('Building...')\n let preparedWranglerConfig: PreparedWranglerEnvConfig | undefined\n try {\n preparedWranglerConfig = prepareWranglerEnvConfig(appDir, envName, {\n sharedDevVarsCache: linkedSecrets !== null,\n })\n execSync('npx vite build', {\n cwd: appDir,\n stdio: 'pipe',\n env: wranglerViteEnv(process.env, preparedWranglerConfig),\n })\n } catch (err: unknown) {\n s.stop('Build failed')\n // Show both streams. Vite writes build errors to stderr, but the Rules of\n // Hooks checker (vite-plugin-checker) prints its diagnostics to stdout —\n // showing only stderr would collapse a hooks violation into a bare\n // \"Command failed\" and hide the exact fix the developer needs.\n const execErr = err as { stdout?: { toString(): string }; stderr?: { toString(): string } }\n const detail = [execErr.stdout?.toString(), execErr.stderr?.toString()]\n .filter(Boolean)\n .join('\\n')\n .trim()\n console.error(detail || errMessage(err))\n process.exit(1)\n } finally {\n preparedWranglerConfig?.cleanup()\n }\n s.stop('Built')\n\n // ── Locate build output via .wrangler/deploy/config.json ──\n // This is the same contract that `wrangler deploy` uses after `vite build`.\n const deployConfigPath = join(appDir, '.wrangler', 'deploy', 'config.json')\n if (!existsSync(deployConfigPath)) {\n p.cancel('Build output config not found at .wrangler/deploy/config.json')\n process.exit(1)\n }\n\n const deployConfig = JSON.parse(readFileSync(deployConfigPath, 'utf-8')) as {\n configPath: string\n }\n const outputWranglerPath = resolve(dirname(deployConfigPath), deployConfig.configPath)\n\n if (!existsSync(outputWranglerPath)) {\n p.cancel(`Output wrangler.json not found at ${outputWranglerPath}`)\n process.exit(1)\n }\n\n const outputConfig = JSON.parse(readFileSync(outputWranglerPath, 'utf-8')) as {\n name?: string\n main: string\n assets?: { directory: string }\n durable_objects?: { bindings: Array<{ name: string; class_name: string }> }\n migrations?: Array<{ new_sqlite_classes?: string[] }>\n }\n\n // Defense in depth: the deploy CLI sends `appName` as the registry\n // slot and Cloudflare Vite plugin bakes a `name` field into the\n // built wrangler.json. They MUST agree — if the generated env config\n // ever fails to apply, we'd otherwise ship one configuration's worker\n // bundle under another configuration's name.\n // Fail loudly before the upload starts.\n if (outputConfig.name && outputConfig.name !== appName) {\n const envHint = envName ? ` (--env ${envName})` : ''\n p.cancel(\n `Build output mismatch: expected name \"${appName}\"${envHint}, ` +\n `but the built wrangler.json declares \"${outputConfig.name}\". ` +\n `This usually means the Cloudflare Vite plugin didn't apply ` +\n `DeepSpace's generated env config. Check the plugin version and re-run.`,\n )\n process.exit(1)\n }\n\n const workerDir = dirname(outputWranglerPath)\n const workerBundlePath = join(workerDir, outputConfig.main)\n const clientDir = outputConfig.assets?.directory\n ? resolve(workerDir, outputConfig.assets.directory)\n : null\n\n if (!existsSync(workerBundlePath)) {\n p.cancel(`Worker bundle not found at ${workerBundlePath}`)\n process.exit(1)\n }\n if (!clientDir || !existsSync(clientDir)) {\n p.cancel(`Client assets not found at ${clientDir}`)\n process.exit(1)\n }\n\n // ── Collect assets ────────────────────────────────────────\n s.start('Collecting assets...')\n const assets = collectAssets(clientDir)\n s.stop(`Collected ${assets.length} assets`)\n\n const workerJs = readFileSync(workerBundlePath, 'utf-8')\n\n // ── Extract DO manifest from build output config ───────────\n const doBindings = outputConfig.durable_objects?.bindings as\n | Array<{ name: string; class_name: string }>\n | undefined\n const sqliteClasses = new Set(\n (outputConfig.migrations as Array<{ new_sqlite_classes?: string[] }> | undefined)?.flatMap(\n (m) => m.new_sqlite_classes ?? [],\n ) ?? [],\n )\n const doManifest = doBindings?.map((b) => ({\n binding: b.name,\n className: b.class_name,\n sqlite: sqliteClasses.has(b.class_name),\n }))\n if (doManifest?.length) {\n p.log.info(`DO manifest: ${doManifest.length} binding(s)`)\n }\n\n // ── Extract custom (non-DO) bindings: Vectorize, AI, R2, KV, D1, etc.\n const customBindings = bindingManifestFromOutputConfig(outputConfig)\n const validation = validateBindingManifest(customBindings)\n if (!validation.valid) {\n p.cancel(\n `Invalid binding(s) in wrangler.toml:\\n` +\n validation.errors.map((e) => ` • ${e.reason}`).join('\\n'),\n )\n process.exit(1)\n }\n if (customBindings.length) {\n p.log.info(\n `Custom bindings: ${customBindings.map((b) => `${b.name} (${b.type})`).join(', ')}`,\n )\n }\n\n // ── App secrets ─────────────────────────────────────────────────────\n const devVarsPath = devVarsPathFor(appDir, envName, {\n sharedDevVarsCache: linkedSecrets !== null,\n })\n // The remote secrets STORE is the single source of truth for what a deployed\n // app's env contains (docs/proposals/secrets-source-of-truth.md). `.dev.vars`\n // is a generated local dev cache — it is NEVER read to decide what ships.\n // Whether or not a store exists, deploy ships exactly the store's values; the\n // only thing we do with `.dev.vars` here is WARN when it holds secrets that\n // aren't in the store (so an edit-and-deploy doesn't silently do nothing).\n const userSecrets: Record<string, string> = linkedSecrets ? { ...linkedSecrets.values } : {}\n // Hand-edited `.dev.vars` secrets, for the warning only. When a store exists,\n // the refresh above already regenerated `.dev.vars` (wiping its custom\n // section), so use the snapshot taken before that write; with no store the\n // file was never regenerated this run, so read it fresh.\n const handEditedDevVars = linkedSecrets ? localOnlyDevVars : readCustomDevVarsAt(devVarsPath)\n const secretsDecision = classifyDevVarsSecrets({\n storeSecretNames: Object.keys(userSecrets),\n handEditedDevVarKeys: Object.keys(handEditedDevVars),\n allowMissing: Boolean(args['allow-missing-secrets']),\n })\n if (secretsDecision.kind === 'block') {\n // Store ships nothing but `.dev.vars` has hand-edited secrets: deploying\n // now would drop any secrets a previous deploy set. Stop, don't just warn.\n // `-e <env>` (not `-c`) so the upload targets the SAME env-specific app id\n // and config this deploy uses — `readAppId(appDir, envName)`. `-c` alone\n // would resolve the top-level app and upload to the wrong store.\n const uploadCmd = envName\n ? `deepspace secrets upload .dev.vars -e ${envName}`\n : 'deepspace secrets upload .dev.vars'\n const keys = secretsDecision.strayKeys.join(', ')\n p.cancel(\n `Refusing to deploy: the app store has no secrets, but .dev.vars has ${keys}.\\n` +\n 'Deploying now would ship the app with no secrets — replacing any a previous ' +\n 'deploy set (they would be dropped from production).\\n' +\n `Upload them to the store first:\\n ${uploadCmd}\\n` +\n 'then redeploy. (Pass --allow-missing-secrets to deploy without them.)',\n )\n process.exit(1)\n }\n if (secretsDecision.kind === 'warn') {\n const stray = secretsDecision.strayKeys\n p.log.warn(\n `.dev.vars has ${stray.join(', ')} not in the app store — ${stray.length === 1 ? 'it is' : 'they are'} NOT deployed. ` +\n '`.dev.vars` is a local dev cache, not deploy config. Move ' +\n `${stray.length === 1 ? 'it' : 'them'} into the store with ` +\n '`deepspace secrets set KEY=value` (or `deepspace secrets upload .dev.vars`), then redeploy.',\n )\n }\n const userSecretNames = Object.keys(userSecrets)\n\n // Pre-flight: fail clearly rather than letting the deploy-worker reject\n // mid-deploy. Reserved names are platform-owned (ASSETS, USAGE_EVENTS, …) —\n // `deepspace secrets` rejects them at write time, so this only trips on a\n // legacy store — and a secret colliding with a declared binding would\n // otherwise produce duplicate-name metadata that CF rejects opaquely.\n const declaredBindingNames = new Set([\n ...customBindings.map((b) => b.name),\n ...(doManifest ?? []).map((d) => d.binding),\n ])\n for (const name of userSecretNames) {\n if (RESERVED_BINDING_NAMES.has(name)) {\n p.cancel(\n `App secret \"${name}\" is a reserved binding name — remove it with \\`deepspace secrets delete ${name}\\`.`,\n )\n process.exit(1)\n }\n if (declaredBindingNames.has(name)) {\n p.cancel(\n `App secret \"${name}\" collides with a binding declared in wrangler.toml — rename one or the other.`,\n )\n process.exit(1)\n }\n }\n if (userSecretNames.length) {\n p.log.info(`App secrets: ${userSecretNames.join(', ')}`)\n }\n\n // ── Upload to deploy worker ───────────────────────────────\n s.start(`Deploying to ${appName}.app.space...`)\n\n // ── Forward custom worker-first asset routes ───────────────\n // CF Workers `[assets]` config supports a `run_worker_first` array\n // that wins over the SPA 404 fallback for matching paths. We always\n // reserve the SDK baseline (/api/*, /ws/*, /internal/*, /v1/*,\n // /_deepspace/*) on the platform side, but apps can declare extra\n // dynamic routes (e.g. /preview/*, /oauth/*, /.well-known/*) in\n // their wrangler.toml under `[assets] run_worker_first`. Pass those\n // through so the platform merges them into the deployed metadata.\n const extraRoutes = extractRunWorkerFirst(wranglerConfig)\n if (extraRoutes.length) {\n p.log.info(`Custom worker-first routes: ${extraRoutes.join(', ')}`)\n }\n\n // ── Choose transport: inline vs grouped ────────────────────\n // The assets array (base64-inlined file bytes) is the bulk of the upload.\n // Sending it all in one request stalls and gets reset mid-body on a\n // marginal uplink (`write EPIPE`). When it doesn't fit in a single group we\n // pack whole asset entries into groups under GROUP_BYTES, POST each group\n // on its own (retry-able) into the deploy worker's R2 staging, and\n // reference them by `uploadId` in the small commit request below. Small\n // deploys keep the original single-request inline transport.\n const assetGroups = packAssetGroups(assets, GROUP_BYTES)\n let inlineAssets: string | null = null\n let uploadId: string | null = null\n let totalGroups = 0\n if (assetGroups.length <= 1) {\n inlineAssets = JSON.stringify(assets)\n } else {\n uploadId = randomUUID()\n totalGroups = assetGroups.length\n try {\n for (let i = 0; i < totalGroups; i++) {\n const groupJson = JSON.stringify(assetGroups[i])\n s.message(`Uploading assets — group ${i + 1}/${totalGroups}...`)\n const groupRes = await postWithRetry(\n `${DEPLOY_URL}/api/deploy/${appId}/assets` +\n `?uploadId=${uploadId}&groupIndex=${i}&totalGroups=${totalGroups}`,\n () => ({\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: groupJson,\n }),\n )\n if (!groupRes.ok) {\n const errBody = (await groupRes.json().catch(() => ({}))) as { error?: string }\n // Reap the groups already staged for this upload before bailing —\n // a fresh deploy mints a new uploadId, so these would otherwise\n // never be reused.\n await abortStagedUpload(appId, uploadId, totalGroups, token)\n s.stop('Deploy failed')\n p.cancel(\n `Asset upload failed on group ${i + 1}/${totalGroups}: ` +\n `${errBody.error ?? `HTTP ${groupRes.status}`}`,\n )\n process.exit(1)\n }\n }\n } catch (err: unknown) {\n // postWithRetry exhausted its network-error retries and threw.\n await abortStagedUpload(appId, uploadId, totalGroups, token)\n s.stop('Deploy failed')\n p.cancel(`Asset upload failed (network): ${errMessage(err)}`)\n process.exit(1)\n }\n s.message(`Deploying to ${appName}.app.space...`)\n }\n\n const commitUrl = `${DEPLOY_URL}/api/deploy/${appId}`\n // Declared BEFORE makeForm — the closure reads it (TDZ trap otherwise).\n let confirmRename = args.rename === true\n\n // Every bail path must reap the staged groups (a re-run mints a new\n // uploadId, so the worker never reuses them) — one place owns that.\n const bailDeploy = async (message: string, stopLabel: string | null = 'Deploy failed'): Promise<never> => {\n if (uploadId) await abortStagedUpload(appId, uploadId, totalGroups, token)\n if (stopLabel !== null) s.stop(stopLabel)\n p.cancel(message)\n process.exit(1)\n }\n\n // Rebuilt per attempt so retried requests get a fresh body.\n const makeForm = (): FormData => {\n const form = new FormData()\n form.append('worker', new Blob([workerJs], { type: 'application/javascript' }), 'worker.js')\n if (inlineAssets !== null) {\n form.append('assets', inlineAssets)\n } else {\n form.append('uploadId', uploadId as string)\n form.append('totalGroups', String(totalGroups))\n }\n if (doManifest) {\n form.append('doManifest', JSON.stringify(doManifest))\n }\n if (customBindings.length) {\n form.append('bindingManifest', JSON.stringify(customBindings))\n }\n if (userSecretNames.length) {\n form.append('userSecrets', JSON.stringify(userSecrets))\n }\n // This CLI always ships the store's exact secret set (the refresh above\n // exits on failure), so tell the worker to delete live secrets we didn't\n // ship. Legacy CLIs never send this, keeping their deploys non-destructive.\n form.append('secretsAuthoritative', 'true')\n if (extraRoutes.length) {\n form.append('extraRunWorkerFirst', JSON.stringify(extraRoutes))\n }\n form.append('name', appName)\n if (confirmRename) form.append('confirmRename', 'true')\n return form\n }\n\n const postCommit = async (): Promise<Response> =>\n postWithRetry(\n commitUrl,\n () => ({\n method: 'POST',\n headers: { Authorization: `Bearer ${token}` },\n body: makeForm(),\n }),\n // Commit runs a real deploy — don't retry its 5xx (could double-deploy);\n // only a thrown fetch (dropped connection) is retried, and the staged\n // groups survive on the worker until this request succeeds.\n { retryServerErrors: false },\n )\n\n let res: Response\n try {\n res = await postCommit()\n } catch (err: unknown) {\n // The commit never got a response after its retries (dropped connection).\n await bailDeploy(`Deploy request failed: ${errMessage(err)}`)\n throw err // unreachable — bailDeploy exits\n }\n\n let body = (await res.json().catch(() => ({}))) as {\n success?: boolean\n url?: string\n error?: string\n code?: string\n fromHost?: string\n toHost?: string\n onBehalfOfOwner?: string\n }\n\n // A changed wrangler `name` is a RENAME of this app — never a silent\n // second app. Confirm interactively (or via --rename) and retry once.\n if (res.status === 409 && body.code === 'rename_required' && !confirmRename) {\n s.stop('Rename confirmation needed')\n // Piped/CI stdin: clack's confirm never resolves — the process would\n // drain its event loop and exit 0 having deployed nothing. Fail loudly\n // with the flag remedy instead.\n if (!process.stdin.isTTY) {\n await bailDeploy(\n `This deploy renames the app: ${body.fromHost} → ${body.toHost}. ` +\n 'Confirmation needs an interactive terminal — re-run with --rename to approve the ' +\n 'rename, or `deepspace init --new-id` if you meant a separate app.',\n null,\n )\n }\n const yes = await p.confirm({\n message:\n `This deploy renames the app: ${body.fromHost} → ${body.toHost}. ` +\n `The URL changes and the old one stops serving right away; data, secrets, and collaborators travel with it. ` +\n '(Meant a separate app? Run `deepspace init --new-id` instead.) Rename?',\n })\n if (p.isCancel(yes) || !yes) {\n await bailDeploy('Deploy cancelled.', null)\n }\n confirmRename = true\n s.start(`Deploying to ${appName}.app.space...`)\n res = await postCommit()\n body = (await res.json().catch(() => ({}))) as typeof body\n }\n\n if (!res.ok || !body.success) {\n await bailDeploy(formatDeployWorkerError(res.status, body.error))\n }\n\n // Deployed on behalf of another user: you're an admin or a collaborator on\n // their app. Say whose app it was; ownership is unchanged.\n if (body.onBehalfOfOwner) {\n p.log.warn(`Deployed on behalf of owner ${body.onBehalfOfOwner}`)\n }\n\n // ── Wait for assets propagation ───────────────────────────\n // Cloudflare's deploy API returns \"success\" once the script + bindings are\n // accepted, but the assets binding can still be indexing for ~10–60s.\n // During that window any request hits CF's transitional \"Assets have not\n // yet deployed\" page (HTML), even on `/api/*` routes that should run the\n // worker first. Block here until we see the worker actually serving so\n // CI / smoke checks that fire immediately don't hit the flake.\n if (body.url) {\n s.message('Waiting for edge propagation...')\n const ok = await waitForAssetsReady(body.url, 90_000)\n if (!ok) {\n s.stop('Deployed (edge propagation still in progress after 90s)')\n p.log.warn(\n 'First requests may briefly hit the assets transitional page; retry in a minute.',\n )\n p.log.success(`Live at: ${body.url}`)\n await syncSubscriptionPlans(appDir, appId, token)\n await syncOneTimeProducts(appDir, appId, token)\n p.outro('Done')\n return\n }\n }\n\n s.stop('Deployed!')\n p.log.success(`Live at: ${body.url}`)\n\n // ── Reconcile subscription plans + one-time products (optional files) ──\n // Each surfaces its own result inline but never fails the deploy — a\n // developer who hasn't finished Stripe Connect onboarding still gets a\n // working deploy; they just see a warning telling them to connect first.\n await syncSubscriptionPlans(appDir, appId, token)\n await syncOneTimeProducts(appDir, appId, token)\n\n p.outro('Done')\n },\n})\n\n/**\n * Bundle the app's `src/subscriptions.ts` with esbuild, dynamic-import the\n * resulting ESM, and POST the declarations to /api/subscriptions/sync.\n * No-op when the file is absent.\n */\nasync function syncSubscriptionPlans(\n appDir: string,\n appName: string,\n token: string,\n): Promise<void> {\n const subsPath = join(appDir, 'src', 'subscriptions.ts')\n if (!existsSync(subsPath)) return\n\n let plans: unknown\n try {\n const esbuild = await import('esbuild')\n const outDir = join(appDir, '.wrangler', 'deploy')\n const outFile = join(outDir, 'subscriptions.bundle.mjs')\n await esbuild.build({\n entryPoints: [subsPath],\n bundle: true,\n format: 'esm',\n platform: 'node',\n target: 'node18',\n outfile: outFile,\n logLevel: 'silent',\n write: true,\n })\n // Cache-bust the import so repeat deploys in the same Node process don't\n // reuse a stale module from the loader cache.\n const mod = (await import(`${pathToFileURL(outFile).href}?t=${Date.now()}`)) as {\n subscriptionPlans?: unknown\n }\n plans = mod.subscriptionPlans\n } catch (err: unknown) {\n p.log.warn(`Could not load src/subscriptions.ts: ${errMessage(err)}`)\n return\n }\n\n if (!Array.isArray(plans)) {\n p.log.warn('src/subscriptions.ts must `export const subscriptionPlans = [...] as const`')\n return\n }\n\n // The platform rejects an empty plan set (no_plans_declared), and an app with\n // no subscriptions has nothing to sync, so skip the request and stay quiet.\n // The moment a plan is declared the normal sync line and Connect warning\n // resume. Plans are removed by dropping them from a still-non-empty list; you\n // cannot reconcile down to zero plans.\n if (plans.length === 0) return\n\n const s = createSpinner()\n s.start('Syncing subscription plans...')\n\n // The deploy has already succeeded by the time we get here, so a network blip\n // or malformed response on /sync must not throw; anything unexpected becomes a\n // warning rather than a stack trace after the app is already live.\n let res: Response\n try {\n res = await fetch(`${API_URL}/api/subscriptions/sync`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ appId: appName, plans }),\n })\n } catch (err: unknown) {\n s.stop('Plan sync skipped')\n p.log.warn(`Plan sync request failed (network): ${errMessage(err)}`)\n return\n }\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean\n error?: string\n hint?: string\n onboardingUrl?: string\n planChanges?: PlanChange[]\n connectMissing?: boolean\n }\n\n if (res.ok && body.ok) {\n s.stop(`Synced ${plans.length} plan${plans.length === 1 ? '' : 's'} to Stripe`)\n // Connect-not-yet-set-up is no longer a sync-blocking error. Plans land\n // in Stripe normally; the warning tells the developer their earnings\n // will queue in the platform balance until they finish Stripe Connect\n // onboarding. Once they connect, the first payout sweeps everything.\n if (body.connectMissing) {\n p.log.warn(\n 'Stripe Connect not yet set up. Customers can subscribe and earnings ' +\n 'will queue in your platform balance until you finish onboarding at ' +\n '/earnings on the dashboard. The first payout after you connect ' +\n 'will sweep everything that accumulated in the meantime.',\n )\n }\n // Any plan change that stranded existing subscribers — whether the plan\n // was removed entirely or just had its price swapped — flows through one\n // prompt. The platform has no way to know whether the developer wants\n // those subscribers cancelled or grandfathered; this is the moment they\n // get to decide. Skipping is fine (silent grandfathering is the safe\n // default); they can always cancel later via the SDK helper.\n const changes = (body.planChanges ?? []).filter((c) => c.affectedSubscribers > 0)\n if (changes.length > 0) {\n await promptAndCancelChangedPlans(appName, token, changes)\n }\n return\n }\n\n s?.stop('Plan sync skipped')\n p.log.warn(\n `Plan sync failed: ${body.error ?? `HTTP ${res.status}`}${body.hint ? ` — ${body.hint}` : ''}`,\n )\n}\n\n// Plan-change events the deploy CLI surfaces to the developer. Mirrors the\n// /sync response shape on the platform side; kept inline here so the helper\n// is self-contained.\ninterface PlanChange {\n slug: string\n reason: 'removed' | 'repriced'\n affectedSubscribers: number\n intervals?: Array<{ interval: 'month' | 'year'; oldCents: number; newCents: number }>\n}\n\nfunction formatCents(c: number): string {\n return c === 0 ? 'free' : `$${(c / 100).toFixed(2)}`\n}\n\nfunction summaryLine(c: PlanChange): string {\n const n = c.affectedSubscribers\n const suffix = `${n} subscriber${n === 1 ? '' : 's'}`\n if (c.reason === 'removed') {\n return ` • ${c.slug} — removed (${suffix} still on it)`\n }\n // repriced: include the interval diffs for context.\n const diffs = (c.intervals ?? [])\n .map((i) => `${i.interval}: ${formatCents(i.oldCents)} → ${formatCents(i.newCents)}`)\n .join('; ')\n return ` • ${c.slug} — repriced (${diffs}; ${suffix} grandfathered on old price)`\n}\n\n/**\n * After /sync reports plans that stranded existing subscribers (removed\n * outright OR repriced with grandfathered customers), ask the developer\n * whether to cancel those subscriptions at the end of their current billing\n * period. Skipping is fine — they can run their own cleanup later via the\n * SDK's `cancelSubscription` helper.\n *\n * One yes/no prompt covers every affected plan. Granular per-plan control\n * is intentionally not surfaced; if a developer wants to cancel for plan A\n * but keep plan B, they can re-declare A in their next deploy.\n *\n * Errors here are warnings, never deploy failures: the deploy itself\n * succeeded; cleanup is the polite-but-optional tail.\n */\nasync function promptAndCancelChangedPlans(\n appName: string,\n token: string,\n changes: PlanChange[],\n): Promise<void> {\n const summary = changes.map(summaryLine).join('\\n')\n p.log.warn(\n `Plan change${changes.length === 1 ? '' : 's'} from this deploy left subscribers stranded:\\n${summary}\\n\\n` +\n 'Stripe will keep charging them until you cancel. Cancel at the end of their\\n' +\n 'current billing period? (Skip to leave them grandfathered.)',\n )\n const choice = await p.confirm({\n message: `Cancel ${changes.length === 1 ? 'these subscribers' : 'all of them'} at period end?`,\n initialValue: false,\n })\n if (p.isCancel(choice) || !choice) {\n p.log.info('Skipped — existing subscribers stay on their current plan/price.')\n return\n }\n\n // The admin-cancel endpoint batches at 50 and returns `hasMore` when there\n // are more rows to process. Loop until done so a plan with hundreds of\n // stranded subscribers gets fully cleaned up — without this, the deploy\n // prompt's confirmation (\"cancel these subscribers\") would silently leave\n // the tail being charged. The cap on iterations is a safety net for the\n // unlikely \"nothing makes progress\" path; a fresh deploy can resume.\n const MAX_ITERATIONS = 100 // 50/batch × 100 = 5000 subs/plan max per deploy\n for (const c of changes) {\n const s = createSpinner()\n s.start(\n `Canceling ${c.affectedSubscribers} subscriber${c.affectedSubscribers === 1 ? '' : 's'} on ${c.slug}...`,\n )\n let totalCanceled = 0\n let totalFailed = 0\n let iteration = 0\n let lastError: string | null = null\n let stopped = false\n try {\n while (iteration < MAX_ITERATIONS) {\n const res = await fetch(`${API_URL}/api/subscriptions/admin-cancel`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n appName,\n planSlug: c.slug,\n atPeriodEnd: true,\n reason: `plan ${c.reason} via deploy`,\n }),\n })\n const body = (await res.json().catch(() => ({}))) as {\n success?: boolean\n canceled?: number\n failures?: Array<{ stripeSubscriptionId: string; error: string }>\n hasMore?: boolean\n error?: string\n }\n if (!res.ok || !body.success) {\n // Genuine failure (auth, 5xx, etc.) — surface and stop. The empty-\n // match case returns 200 with hasMore=false, not an error, so this\n // branch only fires for real problems.\n lastError = body.error ?? `HTTP ${res.status}`\n s.stop(`Cancel failed for ${c.slug}: ${lastError}`)\n stopped = true\n break\n }\n const batchCanceled = body.canceled ?? 0\n totalCanceled += batchCanceled\n totalFailed += body.failures?.length ?? 0\n if (!body.hasMore) break\n // Progress guard: if a batch returned hasMore=true but canceled=0\n // (every row failed), we'd loop forever. Stop and report.\n if (batchCanceled === 0) {\n lastError = 'no progress (all rows failed this batch)'\n break\n }\n iteration++\n }\n if (!stopped) {\n const tail = totalFailed > 0 ? `; ${totalFailed} failed (see Stripe)` : ''\n const cap =\n iteration >= MAX_ITERATIONS\n ? ` (batch cap reached — re-run deploy to finish remaining)`\n : ''\n const errSuffix = lastError ? ` — ${lastError}` : ''\n s.stop(`Canceled ${totalCanceled} on ${c.slug}${tail}${cap}${errSuffix}`)\n }\n } catch (err: unknown) {\n s.stop(`Cancel failed for ${c.slug}: ${errMessage(err)}`)\n }\n }\n}\n\n/**\n * Bundle the app's `src/products.ts` with esbuild, dynamic-import the\n * resulting ESM, and POST the declarations to /api/charges/products/sync.\n * No-op when the file is absent. Mirrors syncSubscriptionPlans — products are\n * the one-time-charge equivalent of subscription plans, and the platform\n * resolves amount/name from this catalog at checkout time so the browser\n * can't pick (productId, amount) together.\n */\nasync function syncOneTimeProducts(appDir: string, appName: string, token: string): Promise<void> {\n const productsPath = join(appDir, 'src', 'products.ts')\n if (!existsSync(productsPath)) return\n\n let products: unknown\n try {\n const esbuild = await import('esbuild')\n const outDir = join(appDir, '.wrangler', 'deploy')\n const outFile = join(outDir, 'products.bundle.mjs')\n await esbuild.build({\n entryPoints: [productsPath],\n bundle: true,\n format: 'esm',\n platform: 'node',\n target: 'node18',\n outfile: outFile,\n logLevel: 'silent',\n write: true,\n })\n const mod = (await import(`${pathToFileURL(outFile).href}?t=${Date.now()}`)) as {\n oneTimeProducts?: unknown\n }\n products = mod.oneTimeProducts\n } catch (err: unknown) {\n p.log.warn(`Could not load src/products.ts: ${errMessage(err)}`)\n return\n }\n\n if (!Array.isArray(products)) {\n p.log.warn('src/products.ts must `export const oneTimeProducts = [...] as const`')\n return\n }\n\n // An empty catalog is the default for apps that don't sell one-time products.\n // Still reconcile it so emptying a previously-populated file deactivates the\n // dropped products, but skip the spinner and the \"Synced 0\" line so a\n // payment-free app isn't narrated on every deploy. Real failures still warn.\n const empty = products.length === 0\n const s = empty ? null : createSpinner()\n s?.start('Syncing one-time products...')\n\n // The deploy is already live by the time we get here, so network/parse\n // failures degrade to warnings rather than failing the deploy.\n let res: Response\n try {\n res = await fetch(`${API_URL}/api/charges/products/sync`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ appId: appName, products }),\n })\n } catch (err: unknown) {\n s?.stop('Product sync skipped')\n p.log.warn(`Product sync request failed (network): ${errMessage(err)}`)\n return\n }\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean\n count?: number\n error?: string\n details?: unknown\n }\n\n if (res.ok && body.ok) {\n if (s) {\n const n = body.count ?? products.length\n s.stop(`Synced ${n} one-time product${n === 1 ? '' : 's'}`)\n }\n return\n }\n\n s?.stop('Product sync skipped')\n p.log.warn(\n `Product sync failed: ${body.error ?? `HTTP ${res.status}`}${\n body.details ? ` — ${JSON.stringify(body.details)}` : ''\n }`,\n )\n}\n\n/**\n * Poll the deployed URL until it stops returning Cloudflare's\n * \"Assets have not yet deployed\" transitional page. Returns true when the\n * worker is actually serving, false on timeout.\n */\nasync function waitForAssetsReady(url: string, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs\n let attempt = 0\n while (Date.now() < deadline) {\n attempt++\n try {\n const res = await fetch(url, { redirect: 'manual' })\n const body = await res.text()\n // The transitional page is HTML with the literal phrase below. Any\n // other body — worker JSON, the app's index.html, even a 404 from the\n // worker's catch-all — means the deploy is live.\n if (!body.includes('Assets have not yet deployed')) {\n return true\n }\n } catch {\n // network blip — try again\n }\n // Exponential backoff capped at 8s: 1s → 2s → 4s → 8s → 8s …\n const wait = Math.min(8_000, 1_000 * 2 ** (attempt - 1))\n await new Promise((r) => setTimeout(r, wait))\n }\n return false\n}\n\nfunction collectAssets(dir: string): Array<{ path: string; contentBase64: string }> {\n const assets: Array<{ path: string; contentBase64: string }> = []\n function walk(d: string, prefix: string) {\n for (const entry of readdirSync(d, { withFileTypes: true })) {\n if (entry.name === '.assetsignore') continue\n const full = join(d, entry.name)\n const rel = prefix ? `${prefix}/${entry.name}` : entry.name\n if (entry.isDirectory()) {\n walk(full, rel)\n } else {\n assets.push({\n path: '/' + rel,\n contentBase64: readFileSync(full).toString('base64'),\n })\n }\n }\n }\n walk(dir, '')\n return assets\n}\n","/**\n * deepspace undeploy\n *\n * Removes a deployed app from *.app.space via the deploy worker.\n */\n\nimport { defineCommand } from 'citty'\nimport { readAppId } from '../lib/app-identity'\nimport * as p from '@clack/prompts'\nimport { createSpinner } from '../lib/spinner'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS } from '../env'\nimport { resolveAppSelector } from '../lib/app-context'\nimport { hasWranglerConfig } from '../lib/wrangler-env'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\nexport default defineCommand({\n meta: {\n name: 'undeploy',\n description: 'Remove a deployed DeepSpace app',\n },\n args: {\n name: {\n type: 'positional',\n description: 'App id or subdomain name to undeploy (reads DEEPSPACE_APP_ID from wrangler.toml if omitted)',\n required: false,\n },\n env: {\n type: 'string',\n description:\n 'wrangler.toml [env.<name>] block whose deployed app to remove ' +\n '(e.g. --env staging). Ignored if a positional name is given.',\n required: false,\n },\n },\n async run({ args }) {\n const envName = typeof args.env === 'string' && args.env.trim() ? args.env.trim() : undefined\n\n // Token first — resolving a subdomain name to its id needs the registry.\n let token: string\n try {\n token = await ensureToken()\n } catch (err: unknown) {\n p.cancel(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n\n // Target: an explicit positional — app id OR live subdomain name, resolved\n // via the registry (DEP-5) — else DEEPSPACE_APP_ID from wrangler.toml.\n let appId: string | undefined\n const positional =\n typeof args.name === 'string' && args.name.trim() ? args.name.trim() : undefined\n if (positional) {\n try {\n appId = await resolveAppSelector(DEPLOY_URL, token, positional)\n } catch (err: unknown) {\n p.cancel(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n } else if (hasWranglerConfig(process.cwd())) {\n appId = readAppId(process.cwd(), envName) ?? undefined\n }\n if (!appId) {\n p.cancel('Provide an app id or subdomain name, or run from a DeepSpace app directory with a DEEPSPACE_APP_ID.')\n process.exit(1)\n }\n\n p.intro(`Undeploying ${appId}`)\n const s = createSpinner()\n s.start('Removing...')\n\n const res = await fetch(`${DEPLOY_URL}/api/deploy/${appId}`, {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${token}` },\n })\n\n const body = (await res.json().catch(() => ({}))) as {\n success?: boolean\n error?: string\n releasedHosts?: string[]\n }\n\n if (!res.ok || !body.success) {\n s.stop('Failed')\n p.cancel(body.error ?? `Undeploy error (${res.status})`)\n process.exit(1)\n }\n\n s.stop('Removed')\n const hosts = body.releasedHosts ?? []\n p.outro(\n hosts.length\n ? `${hosts.join(', ')} taken down. The app keeps its id — redeploy to bring it back.`\n : `App ${appId} taken down.`,\n )\n },\n})\n","/**\n * deepspace whoami\n *\n * Shows the currently logged-in user. Auto-refreshes the JWT if expired.\n *\n * Prints all the identity fields a developer cares about (email, name,\n * userId, issuer) so you don't have to peek into ~/.deepspace/token.\n * Also flags whether the session is for a test account (`@deepspace.test`\n * email), since that's a meaningful distinction for who can do what — see\n * docs/auth/dev-vs-test-accounts.md.\n *\n * `--json` emits a parseable single-line JSON object for scripts.\n */\n\nimport { defineCommand } from 'citty'\nimport { ensureToken } from '../auth'\nimport { DASHBOARD_URL } from '../env'\nimport { decodeJwtPayload } from '../jwt'\n\ninterface JwtPayload {\n sub?: string\n name?: string\n email?: string\n image?: string | null\n iss?: string\n iat?: number\n exp?: number\n}\n\nexport default defineCommand({\n meta: {\n name: 'whoami',\n description: 'Show the currently logged-in user',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Emit a single-line JSON object instead of human output',\n default: false,\n },\n },\n async run({ args }) {\n // A logged-out / malformed-session exit must honor --json so a consumer\n // parsing stdout gets a JSON error object, not a bare sentence, and both\n // paths exit non-zero (ONB-6).\n const failLoggedOut = (msg: string): never => {\n if (args.json) console.log(JSON.stringify({ loggedIn: false, error: msg }))\n else console.error(msg)\n process.exit(1)\n }\n\n // Definite-assignment: failLoggedOut() exits, so jwt is always set here.\n let jwt!: string\n try {\n jwt = await ensureToken()\n } catch (err: unknown) {\n failLoggedOut(err instanceof Error ? err.message : 'Not logged in. Run `deepspace login` first.')\n }\n\n // Definite-assignment: failLoggedOut() exits, so payload is always set here.\n let payload!: JwtPayload\n try {\n payload = decodeJwtPayload<JwtPayload>(jwt)\n } catch {\n failLoggedOut('Malformed session token. Run `deepspace login` again.')\n }\n\n const isTestAccount = !!payload.email?.endsWith('@deepspace.test')\n const accountType: 'developer' | 'test-account' | 'unknown' = isTestAccount\n ? 'test-account'\n : payload.email\n ? 'developer'\n : 'unknown'\n\n if (args.json) {\n console.log(JSON.stringify({\n loggedIn: true,\n name: payload.name ?? null,\n email: payload.email ?? null,\n userId: payload.sub ?? null,\n accountType,\n issuer: payload.iss ?? null,\n expiresAt: payload.exp ? new Date(payload.exp * 1000).toISOString() : null,\n }))\n return\n }\n\n console.log(`Name: ${payload.name ?? '(none)'}`)\n console.log(`Email: ${payload.email ?? '(none)'}`)\n console.log(`UserID: ${payload.sub ?? '(none)'}`)\n console.log(`Type: ${accountType}`)\n if (payload.iss) console.log(`Issuer: ${payload.iss}`)\n console.log(`Dashboard: ${DASHBOARD_URL}`)\n if (isTestAccount) {\n console.log('')\n console.log('Note: this is a test account, not a real OAuth developer.')\n console.log('See docs/auth/dev-vs-test-accounts.md.')\n }\n },\n})\n","/**\n * deepspace apps\n *\n * Lists every app registered to the logged-in user — deployed or not — with\n * its id, live URL, and deploy state. This is the answer to \"which app do I\n * undeploy?\" when the deploy quota message names an id you've lost track of,\n * and the discovery surface for a second checkout / lost app dir.\n *\n * `--json` emits the raw entries for scripts.\n */\n\nimport { defineCommand } from 'citty'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS } from '../env'\nimport { apiFetch } from '../lib/api'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\ninterface AppEntry {\n appId: string\n status: string\n createdAt: string\n deployedAt: string | null\n /** Current subdomain lease; null when undeployed. */\n name: string | null\n url: string | null\n}\n\nexport default defineCommand({\n meta: {\n name: 'apps',\n description: 'List your apps (deployed and registered)',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Emit JSON instead of human output',\n default: false,\n },\n },\n async run({ args }) {\n const token = await ensureToken()\n const { apps } = await apiFetch<{ apps: AppEntry[] }>(DEPLOY_URL, token, '/api/apps')\n\n if (args.json) {\n process.stdout.write(JSON.stringify(apps, null, 2) + '\\n')\n return\n }\n if (!apps.length) {\n console.log('No apps yet. Create one with `npx create-deepspace <name>` and `deepspace deploy`.')\n return\n }\n\n const nameWidth = Math.max(4, ...apps.map((a) => (a.name ?? '—').length))\n const idWidth = Math.max(6, ...apps.map((a) => a.appId.length))\n console.log(`${'NAME'.padEnd(nameWidth)} ${'APP ID'.padEnd(idWidth)} URL`)\n for (const a of apps) {\n const url = a.url ?? '(not deployed)'\n console.log(`${(a.name ?? '—').padEnd(nameWidth)} ${a.appId.padEnd(idWidth)} ${url}`)\n }\n },\n})\n","/**\n * deepspace add <feature> [dir]\n *\n * Installs a DeepSpace feature into the current app.\n *\n * deepspace add --list # list available features\n * deepspace add messaging # install into current dir\n * deepspace add messaging ./my-app # install into specific dir\n * deepspace add --info messaging # show feature details\n */\n\nimport { defineCommand } from 'citty'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { resolve, join, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { spawnSync } from 'node:child_process'\nimport { ensureInstallReady } from '../lib/install-status'\n\nfunction findScript(from: string): string | null {\n // Preferred: ships inside the deepspace npm package at\n // node_modules/deepspace/scripts/add-feature.cjs, so the script and its\n // sibling features/ dir are delivered by `npm install`.\n const inNodeModules = join(from, 'node_modules', 'deepspace', 'scripts', 'add-feature.cjs')\n if (existsSync(inNodeModules)) return inNodeModules\n // Fallback for apps scaffolded before features moved into the SDK; their\n // .deepspace/ folder still works with newer deepspace versions.\n const inDotDeepspace = join(from, '.deepspace', 'scripts', 'add-feature.cjs')\n if (existsSync(inDotDeepspace)) return inDotDeepspace\n return null\n}\n\n/**\n * The installer + its sibling features/ dir that ship inside THIS running\n * deepspace package (the bin is dist/cli.js, so `..` is the package root and\n * scripts/ + features/ are its siblings via package.json \"files\"). Used for\n * catalog queries (--list / --info / help) so they work before the target app\n * has run `npm install`.\n */\nfunction runningScript(): string | null {\n const here = dirname(fileURLToPath(import.meta.url)) // <pkg>/dist\n const script = join(here, '..', 'scripts', 'add-feature.cjs')\n return existsSync(script) ? script : null\n}\n\n/**\n * A DeepSpace app has a wrangler.toml (workers config) or declares `deepspace`\n * as a dependency. A bare/unrelated directory has neither — installing a\n * feature there would just scatter files, so we redirect to `deepspace create`.\n */\nexport function isDeepSpaceApp(dir: string): boolean {\n if (existsSync(join(dir, 'wrangler.toml'))) return true\n const pkgPath = join(dir, 'package.json')\n if (!existsSync(pkgPath)) return false\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n return Boolean(pkg.dependencies?.deepspace || pkg.devDependencies?.deepspace)\n } catch {\n return false\n }\n}\n\n/** Run the .cjs installer with inherited stdio and exit with its status. */\nfunction runInstaller(script: string, passArgs: string[], cwd: string): never {\n const res = spawnSync(process.execPath, [script, ...passArgs], { stdio: 'inherit', cwd })\n if (res.error) {\n console.error(`Could not run the feature installer: ${res.error.message}`)\n process.exit(1)\n }\n process.exit(res.status ?? 1)\n}\n\nexport default defineCommand({\n meta: {\n name: 'add',\n description: 'Add a feature to your DeepSpace app',\n },\n args: {\n list: {\n type: 'boolean',\n alias: 'l',\n description: 'List available features',\n required: false,\n },\n info: {\n type: 'string',\n description: 'Show details about a feature',\n required: false,\n },\n install: {\n type: 'boolean',\n description: 'Run your package manager after adding dependencies',\n required: false,\n },\n feature: {\n type: 'positional',\n description: 'Feature to install',\n required: false,\n },\n dir: {\n type: 'positional',\n description: 'App directory (default: current directory)',\n required: false,\n },\n },\n run({ args }) {\n const appDir = resolve(args.dir ?? '.')\n\n // Catalog queries (--list / --info) and bare help never touch the target\n // app, so resolve the installer from THIS running deepspace package. This\n // lets `deepspace add --list` work before the app has run `npm install`.\n if (args.list || args.info || !args.feature) {\n const script = runningScript()\n if (!script) {\n console.error('Could not find the deepspace feature catalog.')\n console.error('Reinstall deepspace (`npm i -g deepspace`) or run inside a DeepSpace app.')\n process.exit(1)\n }\n const passArgs = args.list\n ? ['--list']\n : args.info\n ? ['--info', String(args.info)]\n : ['--help']\n runInstaller(script, passArgs, process.cwd())\n }\n\n // Install path: the feature is copied into the target app, so it must be a\n // real DeepSpace app with dependencies installed. Check both BEFORE\n // ensureInstallReady, whose \"Dependencies not installed\" message would\n // otherwise shadow the more useful \"not an app / no such dir\" guidance.\n if (!existsSync(appDir)) {\n console.error(`Target directory not found: ${appDir}`)\n console.error('Create a new app first: deepspace create <name>')\n process.exit(1)\n }\n if (!isDeepSpaceApp(appDir)) {\n console.error(`Not a DeepSpace app: ${appDir}`)\n console.error('(no wrangler.toml and no \"deepspace\" dependency found)')\n console.error('Create one with: deepspace create <name>')\n process.exit(1)\n }\n\n ensureInstallReady(appDir)\n const script = findScript(appDir)\n if (!script) {\n console.error('Could not find the deepspace feature installer.')\n console.error('Looked in:')\n console.error(` ${join(appDir, 'node_modules', 'deepspace', 'scripts', 'add-feature.cjs')}`)\n console.error(` ${join(appDir, '.deepspace', 'scripts', 'add-feature.cjs')}`)\n console.error('Are you in a DeepSpace app directory? Try `npm install` first.')\n process.exit(1)\n }\n\n const passArgs = [args.feature, appDir]\n if (args.install) passArgs.push('--install')\n runInstaller(script, passArgs, appDir)\n },\n})\n","/**\n * deepspace domain — purchase and manage custom domains for your apps.\n *\n * Designed to be both human-friendly and agent/script-friendly:\n * - All destructive commands accept `--yes` to skip prompts.\n * - All read commands accept `--json` for structured stdout.\n * - `--app` defaults to the cwd's wrangler.toml name (matches `deepspace deploy`).\n * - `domain buy` opens Stripe Checkout in a browser and polls until live;\n * pass `--no-open` to print the URL only, `--no-wait` to skip polling.\n *\n * Subcommands:\n * search <query> — find available domains and prices\n * buy <domain> — buy a domain via Stripe Checkout (browser)\n * list — list domains you own\n * status <domain> — detail view for one domain\n * attach <domain> — re-point a domain at a different app\n * detach <domain> — stop routing the domain (keeps registration)\n * renew <domain> --auto X — toggle auto-renew on/off at the registrar\n */\n\nimport { defineCommand } from 'citty'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS } from '../env'\nimport { apiFetch } from '../lib/api'\nimport { openBrowser } from '../lib/open-browser'\nimport { requireAppName, detectAppName } from '../lib/app-context'\n\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\n\ninterface SearchResult {\n name: string\n registrable: boolean\n registrar?: 'cloudflare' | 'namesilo'\n pricing?: { currency: string; registrationCost: string; renewalCost: string }\n registrationCost?: number\n renewalCost?: number\n chargedCents?: number | null\n costCents?: number | null\n reason?: string\n premium?: boolean\n}\n\ninterface DomainPurchase {\n id: string\n domain: string\n appName: string\n status: string\n statusError?: string | null\n registeredAt?: string | null\n expiresAt?: string | null\n chargedCents: number\n autoRenew: boolean\n registrar: string\n}\n\nconst api = <T>(token: string, path: string, init?: RequestInit): Promise<T> =>\n apiFetch<T>(API_URL, token, path, init)\n\n/**\n * Strip internal-only pricing fields from any value before emitting it to\n * stdout. The api-worker exposes both the user-facing `chargedCents` and the\n * platform's at-cost `costCents`; only the former should reach the CLI user.\n */\nfunction scrubInternal<T>(value: T): T {\n if (Array.isArray(value)) return value.map(scrubInternal) as unknown as T\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (k === 'costCents') continue\n out[k] = scrubInternal(v)\n }\n return out as T\n }\n return value\n}\n\nfunction fmtCents(cents: number | null | undefined): string {\n if (cents === null || cents === undefined) return '—'\n return `$${(cents / 100).toFixed(2)}`\n}\n\nfunction fmtDate(iso: string | null | undefined): string {\n if (!iso) return '—'\n return iso.slice(0, 10)\n}\n\n/**\n * Plain stdin Y/N prompt — no clack, agent can pipe `yes` or pass --yes.\n */\nasync function confirm(message: string): Promise<boolean> {\n if (!process.stdin.isTTY) {\n // Non-interactive (piped, agent) — refuse rather than hang\n throw new Error(`${message} — pass --yes to confirm non-interactively`)\n }\n process.stdout.write(`${message} [y/N] `)\n return new Promise((resolve) => {\n process.stdin.setEncoding('utf-8')\n process.stdin.once('data', (data) => {\n const answer = data.toString().trim().toLowerCase()\n resolve(answer === 'y' || answer === 'yes')\n })\n })\n}\n\n// ============================================================================\n// search\n// ============================================================================\n\nconst search = defineCommand({\n meta: { name: 'search', description: 'Search for available domains' },\n args: {\n query: { type: 'positional', description: 'Domain or keyword', required: true },\n limit: { type: 'string', description: 'Max results (default 10)', default: '10' },\n json: { type: 'boolean', description: 'Emit JSON instead of a table' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const limit = parseInt(args.limit ?? '10', 10) || 10\n const result = await api<{ domains: SearchResult[] }>(\n token,\n `/api/domains/search?q=${encodeURIComponent(args.query)}&limit=${limit}`,\n )\n if (args.json) {\n process.stdout.write(JSON.stringify(scrubInternal(result), null, 2) + '\\n')\n return\n }\n if (result.domains.length === 0) {\n console.log('No matches.')\n return\n }\n for (const d of result.domains) {\n const tag = d.registrable ? '✓' : '✗'\n const price = d.registrable ? `${fmtCents(d.chargedCents)}/yr` : (d.reason ?? '—')\n // Annotate slow-path TLDs so users have realistic expectations.\n const slowFlag =\n d.registrar && d.registrar !== 'cloudflare' ? ' (15-60 min provisioning)' : ''\n console.log(`${tag} ${d.name.padEnd(40)} ${price}${slowFlag}`)\n }\n },\n})\n\n// ============================================================================\n// buy\n// ============================================================================\n\nconst buy = defineCommand({\n meta: { name: 'buy', description: 'Buy a domain and attach it to an app' },\n args: {\n domain: { type: 'positional', description: 'Domain to buy', required: true },\n app: { type: 'string', description: 'App to attach (defaults to ./wrangler.toml)' },\n yes: { type: 'boolean', description: 'Skip the confirmation prompt', default: false },\n open: {\n type: 'boolean',\n description: 'Open browser at Stripe URL (use --no-open to print URL only)',\n default: true,\n },\n wait: {\n type: 'boolean',\n description:\n 'Poll until provisioning completes (use --no-wait to exit after session creation)',\n default: true,\n },\n json: { type: 'boolean', description: 'Emit JSON to stdout', default: false },\n },\n async run({ args }) {\n const token = await ensureToken()\n const appName = requireAppName(args.app)\n\n // Re-check pricing\n const priceCheck = await api<{ domains: SearchResult[] }>(token, '/api/domains/check', {\n method: 'POST',\n body: JSON.stringify({ domains: [args.domain] }),\n })\n const result = priceCheck.domains[0]\n if (!result || !result.registrable) {\n console.error(`Not available: ${result?.reason ?? 'unknown'}`)\n process.exit(1)\n }\n\n const price = fmtCents(result.chargedCents)\n // Provisioning time depends on registrar:\n // CF Registrar (.com/.dev/.app/.xyz/etc): ~60-90s — registry publishes\n // CF nameservers atomically with registration.\n // Porkbun fallback (.ai/.io/.me/.co/etc + ccTLDs): 15-60 min — depends\n // on the destination registry (Verisign/.me, NIC.AI, etc) batch-\n // publishing our NS records to public DNS. The platform side is\n // done in <30s; the wait is registry-side.\n const expectedTime =\n result.registrar === 'cloudflare'\n ? '~60-90 seconds'\n : '15-60 minutes (registry NS propagation)'\n\n if (!args.yes) {\n const ok = await confirm(\n `Buy ${args.domain} for ${price}/yr (auto-renews; non-refundable), attach to ${appName}? Provisioning takes ${expectedTime}.`,\n )\n if (!ok) {\n console.log('Cancelled.')\n return\n }\n }\n\n const checkout = await api<{\n purchaseId: string\n sessionId: string\n url: string\n chargedCents: number\n }>(token, '/api/domains/checkout', {\n method: 'POST',\n body: JSON.stringify({ domain: args.domain, appId: appName }),\n })\n\n if (args.json) {\n process.stdout.write(\n JSON.stringify(\n scrubInternal({ ...checkout, expectedTime, registrar: result.registrar }),\n null,\n 2,\n ) + '\\n',\n )\n } else {\n console.log(`Stripe Checkout: ${checkout.url}`)\n }\n\n if (args.open && process.stdin.isTTY) {\n openBrowser(checkout.url)\n }\n\n if (!args.wait) return\n\n // Poll until active or failed.\n // Timeout depends on registrar — CF can take 5 min worst case, Porkbun\n // up to 60 min for slow registries. User can Ctrl-C and resume polling\n // later via `deepspace domain status <domain>` — provisioning runs\n // server-side regardless.\n const timeoutMs = result.registrar === 'cloudflare' ? 5 * 60 * 1000 : 60 * 60 * 1000\n if (!args.json) {\n console.log(\n `Waiting for payment & provisioning (up to ${expectedTime}). Press Ctrl-C anytime —`,\n )\n console.log(\n `provisioning continues server-side; check later with \\`deepspace domain status ${args.domain}\\`.`,\n )\n }\n const deadline = Date.now() + timeoutMs\n let lastStatus = ''\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, 5000))\n try {\n const detail = await api<{ domain: DomainPurchase }>(\n token,\n `/api/domains/${checkout.purchaseId}`,\n )\n if (detail.domain.status !== lastStatus) {\n lastStatus = detail.domain.status\n if (!args.json) console.log(` → ${lastStatus}`)\n }\n if (detail.domain.status === 'active') {\n if (args.json) {\n process.stdout.write(\n JSON.stringify(\n scrubInternal({ ...checkout, status: 'active', domain: args.domain }),\n null,\n 2,\n ) + '\\n',\n )\n } else {\n console.log(`✓ ${args.domain} is live and pointing at ${appName}`)\n }\n return\n }\n if (detail.domain.status.startsWith('failed:')) {\n console.error(`Provisioning failed: ${detail.domain.statusError ?? detail.domain.status}`)\n process.exit(1)\n }\n } catch (err) {\n // Transient — keep polling\n if (!args.json)\n console.error(`(poll error: ${err instanceof Error ? err.message : String(err)})`)\n }\n }\n console.error(`Polling timed out. Provisioning may still be in progress; check with:`)\n console.error(` deepspace domain status ${args.domain}`)\n process.exit(1)\n },\n})\n\n// ============================================================================\n// list\n// ============================================================================\n\nconst list = defineCommand({\n meta: { name: 'list', description: 'List your domains' },\n args: {\n json: { type: 'boolean', description: 'Emit JSON' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const result = await api<{ domains: DomainPurchase[] }>(token, '/api/domains')\n if (args.json) {\n process.stdout.write(JSON.stringify(scrubInternal(result), null, 2) + '\\n')\n return\n }\n if (result.domains.length === 0) {\n console.log('No domains. Try `deepspace domain search <name>`.')\n return\n }\n console.log(\n `DOMAIN APP STATUS EXPIRES AUTO-RENEW`,\n )\n for (const d of result.domains) {\n console.log(\n `${d.domain.padEnd(35)} ${d.appName.padEnd(20)} ${d.status.padEnd(20)} ${fmtDate(d.expiresAt).padEnd(12)} ${d.autoRenew ? 'on' : 'off'}`,\n )\n }\n },\n})\n\n// ============================================================================\n// status\n// ============================================================================\n\nconst status = defineCommand({\n meta: { name: 'status', description: 'Show details for one domain' },\n args: {\n domain: { type: 'positional', description: 'Domain', required: true },\n json: { type: 'boolean' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const all = await api<{ domains: DomainPurchase[] }>(token, '/api/domains')\n const found = all.domains.find((d) => d.domain === args.domain)\n if (!found) {\n console.error(`No domain ${args.domain} in your account`)\n process.exit(1)\n }\n if (args.json) {\n process.stdout.write(JSON.stringify(scrubInternal(found), null, 2) + '\\n')\n return\n }\n console.log(`Domain: ${found.domain}`)\n console.log(\n `Status: ${found.status}${found.statusError ? ` (${found.statusError})` : ''}`,\n )\n console.log(`Attached app: ${found.appName}`)\n console.log(`Registrar: ${found.registrar}`)\n console.log(`Registered: ${fmtDate(found.registeredAt)}`)\n console.log(`Expires: ${fmtDate(found.expiresAt)}`)\n console.log(`Auto-renew: ${found.autoRenew ? 'on' : 'off'}`)\n console.log(`Charged: ${fmtCents(found.chargedCents)}/yr`)\n },\n})\n\n// ============================================================================\n// attach\n// ============================================================================\n\nconst attach = defineCommand({\n meta: { name: 'attach', description: 'Re-point a domain at a different app' },\n args: {\n domain: { type: 'positional', description: 'Domain to re-point', required: true },\n app: { type: 'string', description: 'Target app (defaults to ./wrangler.toml)' },\n json: { type: 'boolean' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const targetApp = requireAppName(args.app)\n const all = await api<{ domains: DomainPurchase[] }>(token, '/api/domains')\n const found = all.domains.find((d) => d.domain === args.domain)\n if (!found) {\n console.error(`No domain ${args.domain} in your account`)\n process.exit(1)\n }\n const result = await api<{ success: boolean; appName: string }>(\n token,\n `/api/domains/${found.id}/reattach`,\n {\n method: 'POST',\n body: JSON.stringify({ appId: targetApp }),\n },\n )\n if (args.json) {\n process.stdout.write(JSON.stringify(result, null, 2) + '\\n')\n return\n }\n console.log(`✓ ${args.domain} now points at ${targetApp}`)\n },\n})\n\n// ============================================================================\n// detach\n// ============================================================================\n\nconst detach = defineCommand({\n meta: {\n name: 'detach',\n description: 'Stop routing the domain (keeps the registration; auto-renew unchanged)',\n },\n args: {\n domain: { type: 'positional', description: 'Domain to detach', required: true },\n yes: { type: 'boolean', description: 'Skip the confirmation prompt' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const all = await api<{ domains: DomainPurchase[] }>(token, '/api/domains')\n const found = all.domains.find((d) => d.domain === args.domain)\n if (!found) {\n console.error(`No domain ${args.domain} in your account`)\n process.exit(1)\n }\n if (!args.yes) {\n const ok = await confirm(\n `Detach ${args.domain}? Routing will stop; the domain stays registered (auto-renew is unchanged).`,\n )\n if (!ok) {\n console.log('Cancelled.')\n return\n }\n }\n await api(token, `/api/domains/${found.id}`, { method: 'DELETE' })\n console.log(\n `✓ ${args.domain} detached. Use \\`deepspace domain attach\\` to re-route, or \\`renew --auto off\\` to stop auto-renewal.`,\n )\n },\n})\n\n// ============================================================================\n// renew\n// ============================================================================\n\nconst renew = defineCommand({\n meta: { name: 'renew', description: 'Toggle auto-renewal at the registrar' },\n args: {\n domain: { type: 'positional', description: 'Domain', required: true },\n auto: { type: 'string', description: '\"on\" or \"off\"', required: true },\n },\n async run({ args }) {\n if (args.auto !== 'on' && args.auto !== 'off') {\n console.error('--auto must be \"on\" or \"off\"')\n process.exit(1)\n }\n const token = await ensureToken()\n const all = await api<{ domains: DomainPurchase[] }>(token, '/api/domains')\n const found = all.domains.find((d) => d.domain === args.domain)\n if (!found) {\n console.error(`No domain ${args.domain} in your account`)\n process.exit(1)\n }\n const enabled = args.auto === 'on'\n await api(token, `/api/domains/${found.id}/auto-renew`, {\n method: 'POST',\n body: JSON.stringify({ autoRenew: enabled }),\n })\n console.log(`✓ ${args.domain} auto-renew ${enabled ? 'enabled' : 'disabled'}`)\n },\n})\n\n// ============================================================================\n// Top-level\n// ============================================================================\n\n// Note: no `run()` on the parent — citty otherwise calls it after every\n// subcommand finishes, which prints spurious help text.\n//\n// `detectAppName` is imported for type-checking the `--app` defaulting in\n// each subcommand; not used here directly.\nvoid detectAppName\n\nexport default defineCommand({\n meta: { name: 'domain', description: 'Buy and manage custom domains' },\n subCommands: { search, buy, list, status, attach, detach, renew },\n})\n","/**\n * Manage app collaborators: users you authorize to deploy your app on your\n * behalf. A collaborator just runs `deepspace deploy`; the deploy keeps your\n * identity and billing. Collaborators have owner-equivalent deploy access, so\n * only add people you trust.\n */\n\nimport { defineCommand } from 'citty'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS } from '../env'\nimport { resolveAppTarget } from '../lib/app-context'\nimport { apiFetch } from '../lib/api'\nimport { isTestAccountEmail } from '../../server/auth/testAccounts'\n\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\ninterface Collaborator {\n userId: string\n emailDisplay: string\n createdAt: string | number\n}\n\ninterface PendingInvite {\n email: string\n /** Epoch milliseconds. */\n expiresAt: number\n invitedAt: number\n}\n\ntype AddResponse =\n | { status: 'added'; collaborator: Collaborator }\n | { status: 'invited'; email: string; token: string; expiresAt: number }\n // A live invite already existed → the server did NOT re-charge or re-send.\n | { status: 'already_invited'; email: string; token: string; expiresAt: number }\n\nfunction api<T>(token: string, path: string, init?: RequestInit): Promise<T> {\n return apiFetch<T>(API_URL, token, path, init)\n}\n\nconst list = defineCommand({\n meta: { name: 'list', description: 'List collaborators on your app' },\n args: {\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n json: { type: 'boolean', description: 'Emit JSON' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n const { collaborators, pending = [] } = await api<{\n collaborators: Collaborator[]\n pending?: PendingInvite[]\n }>(token, `/api/app-collaborators/${encodeURIComponent(app)}`)\n if (args.json) {\n process.stdout.write(JSON.stringify({ collaborators, pending }, null, 2) + '\\n')\n return\n }\n if (!collaborators.length && !pending.length) {\n console.log(`No collaborators on ${app}. Add one with \\`deepspace collaborators add <email>\\`.`)\n return\n }\n // COL-4: print a header and the resolved email (emailDisplay). The raw\n // userId is dropped from the human view — it's still in --json, a human\n // reads the email, and `collaborators remove <email>` matches on it.\n if (collaborators.length) {\n console.log(`COLLABORATORS ON ${app}`)\n for (const c of collaborators) {\n console.log(` ${c.emailDisplay}`)\n }\n }\n if (pending.length) {\n console.log(`PENDING INVITES ON ${app}`)\n for (const p of pending) {\n console.log(` ${p.email} (expires ${new Date(p.expiresAt).toLocaleDateString()})`)\n }\n }\n },\n})\n\nconst add = defineCommand({\n meta: { name: 'add', description: 'Authorize someone to deploy your app' },\n args: {\n email: {\n type: 'positional',\n description: 'Collaborator email',\n required: true,\n },\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n json: { type: 'boolean', description: 'Emit JSON' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n if (isTestAccountEmail(args.email)) {\n console.error(\n 'Test accounts (@deepspace.test) cannot be added as collaborators. Use a real DeepSpace account.',\n )\n process.exit(1)\n }\n // Failure slugs (insufficient_credits, test_account_cannot_be_collaborator,\n // ...) are translated centrally by wrapCommandErrors — just let them escape.\n // An email with no DeepSpace user is no longer an error: the server creates\n // a pending invite ({status:'invited'}) and emails the person.\n const res = await api<AddResponse>(\n token,\n `/api/app-collaborators/${encodeURIComponent(app)}`,\n { method: 'POST', body: JSON.stringify({ email: args.email }) },\n )\n if (args.json) {\n process.stdout.write(JSON.stringify(res, null, 2) + '\\n')\n return\n }\n if (res.status === 'invited' || res.status === 'already_invited') {\n const expires = new Date(res.expiresAt).toLocaleDateString()\n if (res.status === 'already_invited') {\n console.log(\n `• ${res.email} already has a pending invite (expires ${expires}). ` +\n `No new email was sent. Cancel it with \\`deepspace collaborators cancel ${res.email}\\` to reset.`,\n )\n return\n }\n console.log(\n `✓ Invite sent to ${res.email} (expires ${expires}). ` +\n `They become a collaborator when they sign in.`,\n )\n return\n }\n console.log(`✓ ${res.collaborator.emailDisplay} can now deploy ${app}`)\n },\n})\n\nconst remove = defineCommand({\n meta: { name: 'remove', description: 'Remove a collaborator from your app' },\n args: {\n email: { type: 'positional', description: 'Collaborator email', required: true },\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n json: { type: 'boolean', description: 'Emit JSON' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n const { collaborators } = await api<{ collaborators: Collaborator[] }>(\n token,\n `/api/app-collaborators/${encodeURIComponent(app)}`,\n )\n const target = args.email.trim().toLowerCase()\n const found = collaborators.find((c) => c.emailDisplay.toLowerCase() === target)\n if (!found) {\n console.error(`${args.email} is not a collaborator on ${app}`)\n process.exit(1)\n }\n await api(\n token,\n `/api/app-collaborators/${encodeURIComponent(app)}/${encodeURIComponent(found.userId)}`,\n { method: 'DELETE' },\n )\n if (args.json) {\n process.stdout.write(JSON.stringify({ removed: found }, null, 2) + '\\n')\n return\n }\n console.log(`✓ ${found.emailDisplay} can no longer deploy ${app}`)\n },\n})\n\nconst cancel = defineCommand({\n meta: { name: 'cancel', description: 'Cancel a pending (un-accepted) email invite' },\n args: {\n email: { type: 'positional', description: 'Invited email', required: true },\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n json: { type: 'boolean', description: 'Emit JSON' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n // Match against the pending list (mirrors `remove`) so we can tell the user\n // when there's nothing to cancel rather than silently no-op'ing the DELETE.\n const { pending = [] } = await api<{ pending?: PendingInvite[] }>(\n token,\n `/api/app-collaborators/${encodeURIComponent(app)}`,\n )\n const target = args.email.trim().toLowerCase()\n const found = pending.find((p) => p.email.toLowerCase() === target)\n if (!found) {\n console.error(`${args.email} has no pending invite on ${app}`)\n process.exit(1)\n }\n await api(\n token,\n `/api/app-collaborators/${encodeURIComponent(app)}/pending/${encodeURIComponent(found.email)}`,\n { method: 'DELETE' },\n )\n if (args.json) {\n process.stdout.write(JSON.stringify({ cancelled: found }, null, 2) + '\\n')\n return\n }\n console.log(`✓ Cancelled the pending invite to ${found.email} on ${app}`)\n },\n})\n\n// No `run()` on the parent: citty otherwise cascades it after each subcommand,\n// printing spurious help text.\nexport default defineCommand({\n meta: { name: 'collaborators', description: 'Manage who can deploy your app' },\n subCommands: { list, add, remove, cancel },\n})\n","/**\n * Test-account identification, shared by every platform worker.\n *\n * Test accounts (created via `deepspace test-accounts`) are real Better Auth\n * users demarcated three ways, and a caller may present as any of them\n * depending on where the check runs:\n * - their email always ends with @deepspace.test (enforced at creation)\n * - their JWTs carry `isTestAccount: true` (minted by the auth-worker,\n * the source of truth)\n * - their billing profile's subscription tier is 'test' (mirrored by the\n * api-worker on every authenticated request)\n *\n * Gate anything a test account must not do with these helpers rather than\n * hand-rolled string comparisons, so the policy stays in one place. Prefer\n * checking the claim when a verified JWT is at hand, and the tier as the\n * fallback for persisted state that may outlive a claim (e.g. rows written\n * before a guard existed).\n */\n\nimport type { JwtClaims } from './types'\n\nexport const TEST_ACCOUNT_EMAIL_SUFFIX = '@deepspace.test'\n\n/** True when the email belongs to a test account (case-insensitive). */\nexport function isTestAccountEmail(email: string | null | undefined): boolean {\n return !!email && email.trim().toLowerCase().endsWith(TEST_ACCOUNT_EMAIL_SUFFIX)\n}\n\n/** True when verified JWT claims identify the caller as a test account. */\nexport function isTestAccountClaims(\n claims: JwtClaims | Record<string, unknown> | null | undefined,\n): boolean {\n return claims?.isTestAccount === true\n}\n\n/** True when a billing subscription tier marks a test account. */\nexport function isTestAccountTier(tier: string | null | undefined): boolean {\n return tier === 'test'\n}\n","/**\n * Transfer app ownership — the GitHub-style offer/accept handshake.\n *\n * `deepspace transfer offer <email>` creates (or replaces) a 7-day offer;\n * the recipient runs `deepspace transfer accept --app <appId>` to commit.\n * Acceptance flips the registry owner and re-tags the deployed script for\n * billing in the same call. Either party can `cancel`. Data, secrets, and\n * routes travel with the app — only the owner (and billing) changes.\n */\n\nimport { defineCommand } from 'citty'\nimport * as p from '@clack/prompts'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS } from '../env'\nimport { requireAppIdArg, resolveAppTarget } from '../lib/app-context'\nimport { apiFetch as api } from '../lib/api'\n\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\nconst offer = defineCommand({\n meta: { name: 'offer', description: 'Offer this app to another DeepSpace user' },\n args: {\n email: { type: 'positional', description: 'Recipient email', required: true },\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n replace: {\n type: 'boolean',\n description: 'Replace a pending offer to someone else without asking',\n },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n\n // The server replaces a pending offer wholesale — a stray second `offer`\n // used to silently revoke the first with no signal to anyone, and the\n // original recipient's `accept` then failed with a mystery 404. Surface\n // the pending offer and make replacing it a deliberate choice.\n const pending = await api<{ transfer: { toEmailDisplay: string } | null }>(\n API_URL,\n token,\n `/api/app-transfers/${encodeURIComponent(app)}`,\n )\n const pendingTo = pending.transfer?.toEmailDisplay\n if (\n pendingTo &&\n pendingTo.toLowerCase() !== args.email.trim().toLowerCase() &&\n !args.replace\n ) {\n if (!process.stdin.isTTY) {\n console.error(\n `A pending offer to ${pendingTo} already exists for ${app}. ` +\n 'Re-run with --replace to replace it, or `deepspace transfer cancel` first.',\n )\n process.exit(1)\n }\n const yes = await p.confirm({\n message: `A pending offer to ${pendingTo} exists — replace it with ${args.email}?`,\n })\n if (p.isCancel(yes) || !yes) {\n console.log(`Kept the pending offer to ${pendingTo}.`)\n process.exit(1)\n }\n }\n\n const { expiresAt } = await api<{ toUserId: string; expiresAt: string }>(\n API_URL,\n token,\n `/api/app-transfers/${encodeURIComponent(app)}`,\n { method: 'POST', body: JSON.stringify({ email: args.email }) },\n )\n if (pendingTo && pendingTo.toLowerCase() !== args.email.trim().toLowerCase()) {\n console.log(`▲ Replaced the pending offer to ${pendingTo}.`)\n }\n console.log(\n `✓ Offered ${app} to ${args.email} (expires ${expiresAt}).\\n` +\n ` They accept with: deepspace transfer accept --app ${app}`,\n )\n },\n})\n\nconst status = defineCommand({\n meta: { name: 'status', description: 'Show the pending transfer offer, if any' },\n args: {\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n const { transfer } = await api<{\n transfer: { toEmailDisplay: string; expiresAt: string } | null\n }>(API_URL, token, `/api/app-transfers/${encodeURIComponent(app)}`)\n if (!transfer) {\n console.log(`No pending transfer for ${app}.`)\n return\n }\n console.log(`Pending: ${app} → ${transfer.toEmailDisplay} (expires ${transfer.expiresAt}).`)\n },\n})\n\nconst accept = defineCommand({\n meta: { name: 'accept', description: 'Accept a transfer offered to you' },\n args: {\n app: { type: 'string', alias: 'a', description: 'App id of the offered app', required: true },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = requireAppIdArg(args.app)\n await api(DEPLOY_URL, token, `/api/apps/${encodeURIComponent(app)}/transfer/accept`, {\n method: 'POST',\n })\n console.log(\n `✓ You now own ${app}. Run \\`deepspace init\\` in a fresh clone (or set ` +\n `DEEPSPACE_APP_ID = \"${app}\" in wrangler.toml) and deploy.`,\n )\n },\n})\n\nconst cancel = defineCommand({\n meta: { name: 'cancel', description: 'Cancel/decline the pending offer (either party)' },\n args: {\n app: { type: 'string', alias: 'a', description: 'App id or name (defaults to ./wrangler.toml)' },\n },\n async run({ args }) {\n const token = await ensureToken()\n const app = await resolveAppTarget(DEPLOY_URL, token, args.app)\n await api(API_URL, token, `/api/app-transfers/${encodeURIComponent(app)}`, { method: 'DELETE' })\n console.log(`✓ Transfer offer for ${app} cancelled.`)\n },\n})\n\n// No `run()` on the parent: citty otherwise cascades it after each subcommand.\nexport default defineCommand({\n meta: { name: 'transfer', description: 'Transfer app ownership to another user' },\n subCommands: { offer, status, accept, cancel },\n})\n","/**\n * deepspace integrations <subcommand>\n *\n * Namespace for working with platform integrations from the command line.\n *\n * deepspace integrations # prints help\n * deepspace integrations list # list all\n * deepspace integrations info openai/chat-completion # schema + example\n * deepspace integrations invoke openai/chat-completion --body '{...}'\n *\n * `deepspace invoke ...` is a top-level alias for `integrations invoke ...`.\n * `deepspace invoke --list` is a shortcut for `integrations list`.\n *\n * All calls are made as the currently logged-in user (`deepspace whoami`).\n * That user is billed.\n *\n * No `run()` is defined on the parent — that matches the convention used\n * by `test-accounts` and prevents citty from firing both the parent and\n * a matched subcommand. Bare `deepspace integrations` (no subcommand)\n * prints citty's auto-generated help.\n */\n\nimport { defineCommand } from 'citty'\nimport { runInvoke, runInfo, runList } from './_invoke-impl'\n\nconst list = defineCommand({\n meta: {\n name: 'list',\n description: 'List all available integrations',\n },\n args: {\n json: {\n type: 'boolean',\n description: 'Print raw JSON (machine-readable)',\n default: false,\n },\n },\n async run({ args }) {\n try {\n await runList({ json: args.json })\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n },\n})\n\nconst info = defineCommand({\n meta: {\n name: 'info',\n description: 'Print schema + example body for an integration endpoint',\n },\n args: {\n target: {\n type: 'positional',\n description: \"<integration>/<endpoint> (e.g. 'openai/chat-completion')\",\n required: true,\n },\n json: {\n type: 'boolean',\n description: 'Print raw JSON (machine-readable)',\n default: false,\n },\n },\n async run({ args }) {\n try {\n await runInfo({ target: args.target as string, json: args.json })\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n },\n})\n\nconst invoke = defineCommand({\n meta: {\n name: 'invoke',\n description: 'Invoke a platform integration as the logged-in user',\n },\n args: {\n target: {\n type: 'positional',\n description: \"<integration>/<endpoint> (e.g. 'openai/chat-completion')\",\n required: true,\n },\n body: {\n type: 'string',\n alias: 'd',\n description: 'Inline JSON body',\n required: false,\n },\n 'body-file': {\n type: 'string',\n alias: 'f',\n description: 'Read JSON body from file (use - for stdin)',\n required: false,\n },\n json: {\n type: 'boolean',\n description: 'Print only the response JSON (machine-readable)',\n default: false,\n },\n timeout: {\n type: 'string',\n description: 'Request timeout in milliseconds (default: 120000)',\n required: false,\n },\n yes: {\n type: 'boolean',\n alias: 'y',\n description: 'Skip the paid-call cost confirmation',\n default: false,\n },\n },\n async run({ args }) {\n try {\n const timeout = args.timeout != null ? Number(args.timeout) : undefined\n if (timeout != null && (!Number.isFinite(timeout) || timeout <= 0)) {\n throw new Error(`Invalid --timeout '${args.timeout}'. Must be a positive number of milliseconds.`)\n }\n await runInvoke({\n target: args.target as string,\n body: args.body,\n bodyFile: args['body-file'],\n json: args.json,\n timeout,\n yes: args.yes,\n })\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n },\n})\n\nexport default defineCommand({\n meta: {\n name: 'integrations',\n description: 'List, inspect, and invoke platform integrations',\n },\n subCommands: {\n list,\n info,\n invoke,\n },\n})\n","/**\n * Shared implementation for `deepspace invoke` and `deepspace integrations *`.\n *\n * The CLI invokes platform integrations as the currently logged-in user\n * (the same identity shown by `deepspace whoami`). That user is billed.\n *\n * This module is the single source of truth for:\n * - listing the integration catalog\n * - showing per-endpoint info (schema + example body)\n * - making the actual POST call\n *\n * Both `commands/invoke.ts` (top-level alias) and `commands/integrations.ts`\n * (namespaced subcommands) delegate here so the behavior never drifts.\n *\n * Why `flushAndExit` is used (only on the --json paths):\n * Large JSON outputs (the full catalog is ~78KB) exceed the OS pipe buffer,\n * and libuv flushes piped writes asynchronously — a plain `process.exit()`\n * would truncate stdout for any downstream consumer that JSON.parses it\n * (jq, file redirects, agent scripts, the e2e tests). So on the --json\n * paths we wait for stdout to drain before exiting. See flushAndExit().\n *\n * Human-mode paths don't need this: they return / process.exit() normally.\n */\n\nimport { readFileSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS } from '../env'\n\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\nconst DEFAULT_TIMEOUT_MS = 120_000\n\ninterface EndpointInfo {\n endpoint: string\n billing: { model: string; baseCost: number; currency: string }\n inputSchema: Record<string, unknown> | null\n example: Record<string, unknown> | null\n}\n\ninterface Catalog {\n integrations: Record<string, EndpointInfo[]>\n}\n\nexport interface InvokeArgs {\n target: string\n body?: string\n bodyFile?: string\n json?: boolean\n timeout?: number\n yes?: boolean\n}\n\nexport interface InfoArgs {\n target: string\n json?: boolean\n}\n\nexport interface ListArgs {\n json?: boolean\n}\n\n/**\n * Parse \"<integration>/<endpoint>\" into its two segments.\n * Throws on malformed input.\n */\nfunction parseTarget(target: string): { integration: string; endpoint: string } {\n if (!target || typeof target !== 'string') {\n throw new Error(\n \"Missing target. Expected '<integration>/<endpoint>' (e.g. 'openai/chat-completion').\",\n )\n }\n const parts = target.split('/')\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new Error(\n `Bad target '${target}'. Expected '<integration>/<endpoint>' (e.g. 'openai/chat-completion').`,\n )\n }\n return { integration: parts[0], endpoint: parts[1] }\n}\n\n/**\n * Resolve the request body from --body, --body-file, or default to '{}'.\n * Errors if both --body and --body-file are provided, or the body isn't\n * valid JSON.\n */\nfunction resolveBody(opts: { body?: string; bodyFile?: string }): string {\n if (opts.body != null && opts.bodyFile != null) {\n throw new Error('Pass either --body or --body-file, not both.')\n }\n\n let raw: string\n if (opts.body != null) {\n raw = opts.body\n } else if (opts.bodyFile != null) {\n raw = opts.bodyFile === '-' ? readFileSync(0, 'utf-8') : readFileSync(opts.bodyFile, 'utf-8')\n } else {\n return '{}'\n }\n\n // Validate it parses as JSON so we fail fast with a clear message.\n try {\n JSON.parse(raw)\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'invalid JSON'\n throw new Error(`Body is not valid JSON: ${msg}`)\n }\n return raw\n}\n\n/**\n * Exit the process after stdout has drained.\n *\n * Used only on --json paths. Plain `process.exit()` truncates piped stdout\n * for outputs larger than the pipe buffer (~64KB on macOS) —\n * `integrations --json | jq` would lose data because libuv flushes\n * asynchronously.\n *\n * The pattern: schedule a zero-byte write so its callback fires only\n * after all prior writes have been flushed, then exit from the callback.\n * Returns a Promise that never resolves so the caller can `await` it.\n */\nfunction flushAndExit(code: number): Promise<never> {\n return new Promise<never>(() => {\n process.stdout.write('', () => process.exit(code))\n })\n}\n\nasync function fetchCatalog(opts: { summary?: boolean } = {}): Promise<Catalog> {\n // `list` uses the summary view (names + billing); the full catalog with every\n // endpoint's schema is large enough to be truncated in an agent's terminal.\n // `info` omits the flag so it still gets the schema + example.\n const url = opts.summary ? `${API_URL}/api/integrations?summary=1` : `${API_URL}/api/integrations`\n const res = await fetch(url)\n if (!res.ok) {\n throw new Error(`Failed to fetch integration catalog (${res.status})`)\n }\n return (await res.json()) as Catalog\n}\n\nfunction findEndpoint(\n catalog: Catalog,\n integration: string,\n endpoint: string,\n): EndpointInfo | null {\n const endpoints = catalog.integrations[integration]\n if (!endpoints) return null\n return endpoints.find((e) => e.endpoint === endpoint) ?? null\n}\n\nfunction formatCurrency(value: number, currency: string): string {\n if (currency === 'USD') return `$${value}`\n return `${value} ${currency}`\n}\n\n/**\n * Human-readable billing unit for a pricing model. `per_token` → \"per token\",\n * `per_call` → \"per call\". Unknown/future models render their raw `per_*` shape\n * (\"per foo\") or pass through, so we never mislabel one mode as another (INT-1).\n */\nexport function billingUnit(model: string): string {\n if (model === 'per_token') return 'per token'\n if (model === 'per_call') return 'per call'\n return model.startsWith('per_') ? model.replace(/^per_/, 'per ').replace(/_/g, ' ') : model\n}\n\n/**\n * Interactive only when BOTH streams are TTYs: p.confirm reads stdin and draws\n * to stdout, so a piped stdin (`echo {} | invoke … --body-file -`) must never\n * reach the prompt — it would hang waiting for input that can't arrive. Pure so\n * the both-streams rule is testable.\n */\nexport function isInteractive(\n stdin: { isTTY?: boolean },\n stdout: { isTTY?: boolean },\n): boolean {\n return Boolean(stdin.isTTY && stdout.isTTY)\n}\n\n/**\n * Whether to confirm a paid invoke before firing it (FEAT-13). Only on an\n * interactive terminal, for a non-free endpoint, when the caller hasn't asked\n * for machine output (--json) or pre-approved (--yes). Pure for testing.\n */\nexport function shouldConfirmCost(opts: {\n json: boolean\n yes: boolean\n isTTY: boolean\n baseCost: number\n}): boolean {\n return !opts.json && !opts.yes && opts.isTTY && opts.baseCost > 0\n}\n\n/**\n * `deepspace integrations` (default action) / `--list`\n * Prints the catalog grouped by integration.\n */\nexport async function runList(args: ListArgs): Promise<void> {\n const catalog = await fetchCatalog({ summary: true })\n\n if (args.json) {\n process.stdout.write(JSON.stringify(catalog) + '\\n')\n await flushAndExit(0)\n }\n\n const names = Object.keys(catalog.integrations).sort()\n if (names.length === 0) {\n console.log('No integrations available.')\n return\n }\n\n for (const name of names) {\n console.log(name)\n const endpoints = [...catalog.integrations[name]].sort((a, b) =>\n a.endpoint.localeCompare(b.endpoint),\n )\n const widest = Math.max(...endpoints.map((e) => e.endpoint.length))\n for (const ep of endpoints) {\n const pad = ep.endpoint.padEnd(widest)\n const cost = formatCurrency(ep.billing.baseCost, ep.billing.currency)\n console.log(` ${pad} ${ep.billing.model.padEnd(12)} ${cost}`)\n }\n console.log()\n }\n\n console.log(\"Run 'deepspace integrations info <integration>/<endpoint>' for the request schema.\")\n}\n\n/**\n * `deepspace integrations info <target>` / `--info`\n * Prints the schema + example body for a single endpoint.\n */\nexport async function runInfo(args: InfoArgs): Promise<void> {\n const { integration, endpoint } = parseTarget(args.target)\n const catalog = await fetchCatalog()\n const info = findEndpoint(catalog, integration, endpoint)\n\n if (!info) {\n const available = catalog.integrations[integration]\n if (!available) {\n const names = Object.keys(catalog.integrations).sort().join(', ')\n throw new Error(`Unknown integration '${integration}'. Available: ${names}`)\n }\n const endpoints = available.map((e) => e.endpoint).join(', ')\n throw new Error(`Unknown endpoint '${endpoint}' for '${integration}'. Available: ${endpoints}`)\n }\n\n if (args.json) {\n process.stdout.write(JSON.stringify(info) + '\\n')\n await flushAndExit(0)\n }\n\n console.log(`${integration}/${endpoint}`)\n console.log(\n ` billing: ${formatCurrency(info.billing.baseCost, info.billing.currency)} ${billingUnit(info.billing.model)}`,\n )\n console.log()\n console.log('Input schema:')\n console.log(\n info.inputSchema ? JSON.stringify(info.inputSchema, null, 2) : ' (no schema registered)',\n )\n console.log()\n console.log('Example body:')\n console.log(info.example ? JSON.stringify(info.example, null, 2) : ' (no example available)')\n}\n\n/**\n * `deepspace invoke <target>` / `deepspace integrations invoke <target>`\n * Performs the actual integration call.\n */\nexport async function runInvoke(args: InvokeArgs): Promise<void> {\n const { integration, endpoint } = parseTarget(args.target)\n const body = resolveBody({ body: args.body, bodyFile: args.bodyFile })\n const timeoutMs = args.timeout ?? DEFAULT_TIMEOUT_MS\n\n // FEAT-13: this fires a PAID call billed to the logged-in user. On a fully\n // interactive terminal, confirm the cost first (unless --yes or --json).\n // Gate on BOTH streams: p.confirm reads stdin and draws to stdout, so a piped\n // stdin (e.g. `echo {} | deepspace invoke … --body-file -`) must never reach\n // the prompt — it would hang waiting for input that can't come.\n const interactive = isInteractive(process.stdin, process.stdout)\n if (!args.json && !args.yes && interactive) {\n let info: EndpointInfo | null = null\n try {\n info = findEndpoint(await fetchCatalog({ summary: true }), integration, endpoint)\n } catch {\n // Couldn't fetch billing — don't block the call, but say so, so a paid\n // call never fires completely silently. The POST still enforces\n // auth/existence and reports its own errors.\n console.error('Note: could not verify the call cost; proceeding. Pass --yes to skip this check.')\n info = null\n }\n if (\n info &&\n shouldConfirmCost({\n json: !!args.json,\n yes: !!args.yes,\n isTTY: interactive,\n baseCost: info.billing.baseCost,\n })\n ) {\n const cost = formatCurrency(info.billing.baseCost, info.billing.currency)\n const ok = await p.confirm({\n message: `${integration}/${endpoint} costs ${cost} ${billingUnit(info.billing.model)}, billed to your account. Continue?`,\n })\n if (p.isCancel(ok) || !ok) {\n p.cancel('Cancelled — no call made.')\n process.exit(0)\n }\n }\n }\n\n let jwt: string\n try {\n jwt = await ensureToken()\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n throw new Error(msg)\n }\n\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n const startedAt = Date.now()\n\n let res: Response\n try {\n res = await fetch(`${API_URL}/api/integrations/${integration}/${endpoint}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${jwt}`,\n },\n body,\n signal: controller.signal,\n })\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n throw new Error(`Request timed out after ${timeoutMs}ms`)\n }\n throw new Error(err instanceof Error ? err.message : 'Request failed')\n } finally {\n clearTimeout(timer)\n }\n\n const elapsed = Date.now() - startedAt\n let payload: Record<string, unknown>\n try {\n payload = (await res.json()) as Record<string, unknown>\n } catch {\n throw new Error(`Request failed (${res.status}) with non-JSON response`)\n }\n\n if (args.json) {\n process.stdout.write(JSON.stringify(payload) + '\\n')\n await flushAndExit(payload?.success === false || !res.ok ? 1 : 0)\n }\n\n const ok = payload?.success !== false && res.ok\n if (ok) {\n const data = 'data' in payload ? payload.data : payload\n console.log(JSON.stringify(data, null, 2))\n console.error(`\\n✓ ${integration}/${endpoint} (${elapsed}ms)`)\n return\n }\n\n // Error path\n const errMsg = (payload.error as string) ?? `Request failed (${res.status})`\n console.error(`✗ ${integration}/${endpoint} (${res.status}, ${elapsed}ms): ${errMsg}`)\n if (Array.isArray(payload.issues)) {\n for (const issue of payload.issues as Array<{ path?: string[]; message: string }>) {\n const path = issue.path?.length ? issue.path.join('.') : '(root)'\n console.error(` - ${path}: ${issue.message}`)\n }\n }\n if (res.status === 401) {\n console.error(\"\\nHint: run 'deepspace login' to authenticate.\")\n }\n process.exit(1)\n}\n","/**\n * deepspace invoke <integration>/<endpoint> [options]\n *\n * Top-level alias for `deepspace integrations invoke ...`. Calls a platform\n * integration as the currently logged-in user — the same identity shown by\n * `deepspace whoami`. That user is billed.\n *\n * deepspace invoke openai/chat-completion --body '{\"messages\":[...]}'\n * deepspace invoke openai/chat-completion --body-file req.json\n * cat req.json | deepspace invoke openai/chat-completion --body-file -\n * deepspace invoke openai/chat-completion --info\n * deepspace invoke --list\n */\n\nimport { defineCommand } from 'citty'\nimport { runInvoke, runInfo, runList } from './_invoke-impl'\n\nexport default defineCommand({\n meta: {\n name: 'invoke',\n description: 'Invoke a platform integration as the logged-in user',\n },\n args: {\n target: {\n type: 'positional',\n description: \"<integration>/<endpoint> (e.g. 'openai/chat-completion')\",\n required: false,\n },\n body: {\n type: 'string',\n alias: 'd',\n description: 'Inline JSON body',\n required: false,\n },\n 'body-file': {\n type: 'string',\n alias: 'f',\n description: 'Read JSON body from file (use - for stdin)',\n required: false,\n },\n json: {\n type: 'boolean',\n description: 'Print only the response JSON (machine-readable)',\n default: false,\n },\n info: {\n type: 'boolean',\n description: 'Print schema + example body for the endpoint, then exit',\n default: false,\n },\n list: {\n type: 'boolean',\n description: 'Print all available integrations, then exit',\n default: false,\n },\n timeout: {\n type: 'string',\n description: 'Request timeout in milliseconds (default: 120000)',\n required: false,\n },\n yes: {\n type: 'boolean',\n alias: 'y',\n description: 'Skip the paid-call cost confirmation',\n default: false,\n },\n },\n async run({ args }) {\n try {\n if (args.list) {\n await runList({ json: args.json })\n return\n }\n if (args.info) {\n await runInfo({ target: args.target as string, json: args.json })\n return\n }\n const timeout = args.timeout != null ? Number(args.timeout) : undefined\n if (timeout != null && (!Number.isFinite(timeout) || timeout <= 0)) {\n throw new Error(`Invalid --timeout '${args.timeout}'. Must be a positive number of milliseconds.`)\n }\n await runInvoke({\n target: args.target as string,\n body: args.body,\n bodyFile: args['body-file'],\n json: args.json,\n timeout,\n yes: args.yes,\n })\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n },\n})\n","/**\n * deepspace library [publish|unpublish] [options]\n *\n * Manage entries in the DeepSpace community library (lives at\n * deepdotspace-site.app.space by default; override with --library-app\n * or DEEPSPACE_LIBRARY_HOST). Subcommands POST to that app's\n * `library.publish` / `library.unpublish` actions as the currently\n * logged-in user.\n *\n * The publish action verifies the caller owns the deployed app (by\n * checking the deploy worker's `/api/apps` registry) before writing\n * the row, so publishing another user's app is rejected server-side.\n *\n * Usage:\n * deepspace library publish (uses wrangler.toml)\n * deepspace library publish --app my-cool-app --name \"My Cool App\"\n * deepspace library publish --description \"...\" --category Productivity\n * deepspace library publish --tags utility,ai --visibility unlisted\n * deepspace library unpublish <handle>\n */\n\nimport { defineCommand } from 'citty'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport { parse as parseToml } from 'smol-toml'\nimport * as p from '@clack/prompts'\n\nimport { ensureToken } from '../auth'\nimport { resolveAppName } from '../../server/rooms/app-name'\n\nconst DEFAULT_LIBRARY_APP = 'deepdotspace-site'\n\nconst publish = defineCommand({\n meta: {\n name: 'publish',\n description: 'Publish the current app to the DeepSpace library',\n },\n args: {\n dir: {\n type: 'string',\n description: 'App directory (default: current directory)',\n required: false,\n },\n app: {\n type: 'string',\n description: 'App name (default: read from wrangler.toml)',\n required: false,\n },\n name: {\n type: 'string',\n description: 'Display name (default: app name)',\n required: false,\n },\n description: {\n type: 'string',\n description: 'Short description',\n required: false,\n },\n category: {\n type: 'string',\n description: 'Category (e.g. Productivity, Finance, AI). Default: General',\n required: false,\n },\n tags: {\n type: 'string',\n description: 'Comma-separated tags',\n required: false,\n },\n visibility: {\n type: 'string',\n description: \"'public' (default), 'unlisted', or 'private'\",\n required: false,\n },\n screenshot: {\n type: 'string',\n description: 'Override the auto-captured preview with a public PNG URL',\n required: false,\n },\n 'library-app': {\n type: 'string',\n description: `Target library app subdomain (default: ${DEFAULT_LIBRARY_APP})`,\n required: false,\n },\n json: {\n type: 'boolean',\n description: 'Print only the JSON response (machine-readable)',\n default: false,\n },\n },\n async run({ args }) {\n const json = !!args.json\n const intro = (s: string) => { if (!json) p.intro(s) }\n const info = (s: string) => { if (!json) p.log.info(s) }\n const die = (msg: string) => {\n if (json) console.error(JSON.stringify({ ok: false, error: msg }))\n else p.cancel(msg)\n process.exit(1)\n }\n\n intro('Publishing to the DeepSpace library')\n\n let appName = typeof args.app === 'string' && args.app.trim() ? args.app.trim() : undefined\n if (!appName) {\n const appDir = resolve(typeof args.dir === 'string' && args.dir ? args.dir : '.')\n const wranglerPath = join(appDir, 'wrangler.toml')\n if (!existsSync(wranglerPath)) {\n return die(\"No --app provided and no wrangler.toml found. Either pass --app <name> or run from your app's directory.\")\n }\n const cfg = parseToml(readFileSync(wranglerPath, 'utf-8')) as { name?: string }\n const nameRes = resolveAppName(cfg.name)\n if (!nameRes.ok) return die(`wrangler.toml: ${nameRes.reason}`)\n appName = nameRes.name\n }\n info(`App: ${appName}`)\n\n const visibility = (args.visibility ?? 'public') as string\n if (!['public', 'private', 'unlisted'].includes(visibility)) {\n return die(\"--visibility must be 'public', 'unlisted', or 'private'.\")\n }\n\n const tags = typeof args.tags === 'string' && args.tags\n ? args.tags.split(',').map((t) => t.trim()).filter(Boolean)\n : undefined\n\n const libraryApp = typeof args['library-app'] === 'string' && args['library-app']\n ? args['library-app']\n : DEFAULT_LIBRARY_APP\n const libraryHost = process.env.DEEPSPACE_LIBRARY_HOST ?? `https://${libraryApp}.app.space`\n\n let token: string\n try {\n token = await ensureToken()\n } catch (err) {\n return die(err instanceof Error ? err.message : String(err))\n }\n\n const payload: Record<string, unknown> = {\n appName,\n ...(args.name ? { name: args.name } : {}),\n ...(args.description ? { description: args.description } : {}),\n ...(args.category ? { category: args.category } : {}),\n ...(tags ? { tags } : {}),\n visibility,\n ...(args.screenshot ? { screenshotUrl: args.screenshot } : {}),\n }\n\n const url = `${libraryHost}/api/actions/library.publish`\n let res: Response\n try {\n res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(payload),\n })\n } catch (err) {\n return die(`Network error reaching ${url}: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n const body = await res.text()\n let parsed: { success?: boolean; data?: { templateHandle?: string; url?: string; version?: number }; error?: string }\n try {\n parsed = JSON.parse(body)\n } catch {\n return die(`Server returned non-JSON (${res.status}): ${body.slice(0, 400)}`)\n }\n\n if (json) {\n console.log(JSON.stringify(parsed))\n process.exit(parsed.success ? 0 : 1)\n }\n\n if (!parsed.success) {\n return die(parsed.error ?? `Publish failed (HTTP ${res.status}).`)\n }\n\n p.log.success(`Published ${appName} as ${parsed.data?.templateHandle} (v${parsed.data?.version})`)\n if (parsed.data?.url) p.log.message(parsed.data.url)\n p.outro('Done')\n },\n})\n\nconst unpublish = defineCommand({\n meta: {\n name: 'unpublish',\n description: 'Remove a library entry (owner or admin only)',\n },\n args: {\n handle: {\n type: 'positional',\n description: 'templateHandle to remove (usually your app name)',\n required: true,\n },\n 'library-app': {\n type: 'string',\n description: `Target library app subdomain (default: ${DEFAULT_LIBRARY_APP})`,\n required: false,\n },\n json: {\n type: 'boolean',\n description: 'Print only the JSON response',\n default: false,\n },\n },\n async run({ args }) {\n const json = !!args.json\n const die = (msg: string) => {\n if (json) console.error(JSON.stringify({ ok: false, error: msg }))\n else p.cancel(msg)\n process.exit(1)\n }\n if (!json) p.intro('Unpublishing library entry')\n\n let token: string\n try { token = await ensureToken() } catch (err) {\n return die(err instanceof Error ? err.message : String(err))\n }\n\n const libraryApp = typeof args['library-app'] === 'string' && args['library-app']\n ? args['library-app']\n : DEFAULT_LIBRARY_APP\n const libraryHost = process.env.DEEPSPACE_LIBRARY_HOST ?? `https://${libraryApp}.app.space`\n\n const res = await fetch(`${libraryHost}/api/actions/library.unpublish`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n body: JSON.stringify({ templateHandle: String(args.handle) }),\n })\n const body = await res.text()\n let parsed: { success?: boolean; error?: string; data?: { templateHandle?: string } }\n try { parsed = JSON.parse(body) } catch {\n return die(`Server returned non-JSON (${res.status}): ${body.slice(0, 400)}`)\n }\n if (json) { console.log(JSON.stringify(parsed)); process.exit(parsed.success ? 0 : 1) }\n if (!parsed.success) return die(parsed.error ?? `HTTP ${res.status}`)\n p.log.success(`Unpublished ${parsed.data?.templateHandle}`)\n p.outro('Done')\n },\n})\n\nexport default defineCommand({\n meta: {\n name: 'library',\n description: 'Manage your DeepSpace library entries',\n },\n subCommands: {\n publish,\n unpublish,\n },\n})\n","/**\n * deepspace feedback\n *\n * Submit a bug report, feature request, or general feedback to the DeepSpace\n * team. The report is authenticated as the logged-in user and POSTed to the\n * api-worker, where it lands in the admin triage queue (dashboard ·\n * Admin · Feedback).\n *\n * Interactive when run in a TTY (prompts for type/title/details); flag-driven\n * for agents and CI. The title is a positional argument; the details go in\n * --message (-m). Both are required for non-interactive use.\n *\n * deepspace feedback # full interactive prompt\n * deepspace feedback \"Crash on deploy\" -m \"It explodes when…\" # quick, non-interactive\n * deepspace feedback -t feature \"Add dark mode\" -m \"…\" --yes --json\n *\n * Best-effort environment context (CLI version, Node version, OS, and the\n * current app name if run inside a scaffolded app) is attached automatically\n * so the team can reproduce issues without a round-trip.\n */\n\nimport { defineCommand } from 'citty'\nimport * as p from '@clack/prompts'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { release } from 'node:os'\nimport { ensureToken } from '../auth'\nimport { PLATFORM_URLS, DASHBOARD_URL } from '../env'\nimport { apiFetch } from '../lib/api'\nimport { hasWranglerConfig, readWranglerConfig } from '../lib/wrangler-env'\n\nconst API_URL = process.env.DEEPSPACE_API_URL ?? PLATFORM_URLS.api\n\nconst TYPES = ['bug', 'feature', 'other'] as const\ntype FeedbackType = (typeof TYPES)[number]\n\nconst TYPE_LABELS: Record<FeedbackType, string> = {\n bug: 'Bug report',\n feature: 'Feature request',\n other: 'Other feedback',\n}\n\n// Mirror the api-worker's limits so over-length input fails fast with a clear\n// field-specific message instead of a generic 400 after the round-trip.\nconst MAX_TITLE_LEN = 200\nconst MAX_BODY_LEN = 10_000\nconst MAX_CONTEXT_LEN = 200\n\ninterface FeedbackContext {\n cliVersion: string\n nodeVersion: string\n platform: string\n appName?: string\n}\n\ninterface FeedbackPayload extends FeedbackContext {\n type: FeedbackType\n title: string\n body: string\n}\n\ninterface FeedbackReport {\n id: string\n type: FeedbackType\n title: string\n status: string\n createdAt: string\n}\n\nconst api = <T>(token: string, path: string, init?: RequestInit): Promise<T> =>\n apiFetch<T>(API_URL, token, path, init)\n\n/** Normalize/validate a `--type` value. Throws on an unknown type. */\nexport function normalizeType(raw: string | undefined): FeedbackType {\n const value = (raw ?? 'bug').toLowerCase()\n if ((TYPES as readonly string[]).includes(value)) return value as FeedbackType\n throw new Error(`Invalid --type \"${raw}\". Use one of: ${TYPES.join(', ')}.`)\n}\n\n/** Read the deepspace CLI version from its own package.json. */\nfunction readCliVersion(): string {\n try {\n const here = dirname(fileURLToPath(import.meta.url))\n // Bundled output lives in <pkg>/dist (package.json one level up); the\n // source tree has it three levels up from src/cli/commands.\n const candidates = [\n join(here, '..', 'package.json'),\n join(here, '..', '..', '..', 'package.json'),\n ]\n for (const path of candidates) {\n if (!existsSync(path)) continue\n const pkg = JSON.parse(readFileSync(path, 'utf-8')) as {\n name?: string\n version?: string\n }\n if (pkg.name === 'deepspace' && pkg.version) return pkg.version\n }\n } catch {\n // fall through\n }\n return 'unknown'\n}\n\n/** Best-effort app name from the current dir's wrangler.toml, if any. */\nfunction detectAppName(): string | undefined {\n try {\n const cwd = process.cwd()\n if (!hasWranglerConfig(cwd)) return undefined\n const config = readWranglerConfig(cwd)\n return typeof config.name === 'string' ? config.name : undefined\n } catch {\n return undefined\n }\n}\n\n/** Clamp a best-effort context value so it can never block submission. */\nfunction clampContext(value: string): string {\n return value.length > MAX_CONTEXT_LEN ? value.slice(0, MAX_CONTEXT_LEN) : value\n}\n\n/** Collect the environment context attached to every report. */\nexport function collectContext(): FeedbackContext {\n const appName = detectAppName()\n return {\n cliVersion: clampContext(readCliVersion()),\n nodeVersion: clampContext(process.version),\n platform: clampContext(`${process.platform} ${release()}`),\n ...(appName ? { appName: clampContext(appName) } : {}),\n }\n}\n\n/** Assemble the request body. Trims and validates title/body are non-empty. */\nexport function buildFeedbackPayload(input: {\n type: string | undefined\n title: string\n body: string\n context: FeedbackContext\n}): FeedbackPayload {\n const title = input.title.trim()\n const body = input.body.trim()\n if (!title) throw new Error('A title is required.')\n if (!body) throw new Error('A message/description is required.')\n if (title.length > MAX_TITLE_LEN) {\n throw new Error(`Title must be ${MAX_TITLE_LEN} characters or fewer (got ${title.length}).`)\n }\n if (body.length > MAX_BODY_LEN) {\n throw new Error(`Description must be ${MAX_BODY_LEN} characters or fewer (got ${body.length}).`)\n }\n return {\n type: normalizeType(input.type),\n title,\n body,\n ...input.context,\n }\n}\n\nexport default defineCommand({\n meta: {\n name: 'feedback',\n description: 'Submit a bug report, feature request, or feedback to DeepSpace',\n },\n args: {\n title: {\n type: 'positional',\n description: 'Short summary (prompted if omitted in a terminal)',\n required: false,\n },\n type: {\n type: 'string',\n alias: 't',\n description: `Report type: ${TYPES.join(' | ')} (default: bug)`,\n required: false,\n },\n message: {\n type: 'string',\n alias: 'm',\n description: 'Details / description (prompted if omitted in a terminal)',\n required: false,\n },\n yes: {\n type: 'boolean',\n description: 'Skip the confirmation prompt',\n default: false,\n },\n json: {\n type: 'boolean',\n description: 'Emit JSON instead of human output',\n default: false,\n },\n },\n async run({ args }) {\n const interactive = process.stdin.isTTY && !args.json\n\n // Fail consistently: under --json, emit the same { ok, error } shape on\n // stdout that the success/network paths use, so an agent can always parse\n // the outcome. Otherwise print to stderr. Either way exit non-zero.\n const fail = (message: string): never => {\n if (args.json) {\n process.stdout.write(JSON.stringify({ ok: false, error: message }) + '\\n')\n } else {\n console.error(message)\n }\n process.exit(1)\n }\n\n let type: FeedbackType\n try {\n type = normalizeType(args.type ? String(args.type) : undefined)\n } catch (err) {\n return fail((err as Error).message)\n }\n\n let title = args.title ? String(args.title) : ''\n let body = args.message ? String(args.message) : ''\n\n // Non-interactive callers (agents/CI) must supply both fields up front.\n if ((!title || !body) && !interactive) {\n return fail(\n 'Provide a title and --message to submit non-interactively, ' +\n 'e.g. `deepspace feedback \"Title\" --message \"Details\"`.',\n )\n }\n\n // Prompt for whatever is still missing — including the type, so an\n // interactive user who passed --title/--message but no --type is still\n // asked rather than having it silently default to \"bug\".\n if (interactive && (!args.type || !title || !body)) {\n p.intro('DeepSpace Feedback')\n\n if (!args.type) {\n const picked = await p.select({\n message: 'What kind of feedback is this?',\n options: TYPES.map((t) => ({ value: t, label: TYPE_LABELS[t] })),\n initialValue: type,\n })\n if (p.isCancel(picked)) {\n p.cancel('Cancelled.')\n process.exit(0)\n }\n type = picked as FeedbackType\n }\n\n if (!title) {\n const t = await p.text({\n message: 'Title',\n placeholder: 'Short summary of the issue',\n validate: (v) => {\n if (!v?.trim()) return 'Title is required'\n if (v.length > MAX_TITLE_LEN)\n return `Title must be ${MAX_TITLE_LEN} characters or fewer`\n return undefined\n },\n })\n if (p.isCancel(t)) {\n p.cancel('Cancelled.')\n process.exit(0)\n }\n title = String(t)\n }\n\n if (!body) {\n const m = await p.text({\n message: 'Details',\n placeholder: 'What happened? Steps to reproduce, what you expected…',\n validate: (v) => {\n if (!v?.trim()) return 'A description is required'\n if (v.length > MAX_BODY_LEN)\n return `Description must be ${MAX_BODY_LEN} characters or fewer`\n return undefined\n },\n })\n if (p.isCancel(m)) {\n p.cancel('Cancelled.')\n process.exit(0)\n }\n body = String(m)\n }\n }\n\n let payload: FeedbackPayload\n try {\n payload = buildFeedbackPayload({\n type,\n title,\n body,\n context: collectContext(),\n })\n } catch (err) {\n return fail((err as Error).message)\n }\n\n // Confirmation — only when interactive and not explicitly skipped.\n if (interactive && !args.yes) {\n p.note(\n `${TYPE_LABELS[payload.type]}\\n${payload.title}\\n\\n${payload.body}` +\n `\\n\\nContext: deepspace ${payload.cliVersion} · ${payload.nodeVersion} · ${payload.platform}` +\n (payload.appName ? ` · app ${payload.appName}` : ''),\n 'Review',\n )\n const ok = await p.confirm({ message: 'Send this to the DeepSpace team?' })\n if (p.isCancel(ok) || !ok) {\n p.cancel('Not sent.')\n process.exit(0)\n }\n }\n\n let token: string\n try {\n token = await ensureToken()\n } catch (err) {\n return fail((err as Error).message ?? 'Not signed in. Run `deepspace login`.')\n }\n\n let result: { report: FeedbackReport }\n try {\n result = await api<{ report: FeedbackReport }>(token, '/api/feedback', {\n method: 'POST',\n body: JSON.stringify(payload),\n })\n } catch (err) {\n return fail((err as Error).message)\n }\n\n if (args.json) {\n process.stdout.write(JSON.stringify({ ok: true, report: result.report }) + '\\n')\n return\n }\n\n if (interactive) {\n p.outro(`Thanks! Submitted as ${result.report.id}.`)\n } else {\n console.log(`Submitted feedback ${result.report.id} (${result.report.type}).`)\n }\n console.log(`Track triage status at ${DASHBOARD_URL}.`)\n },\n})\n","/**\n * `deepspace secrets` — manage the app's secrets store.\n *\n * Every app has exactly one store, addressed by its immutable id (the\n * DEEPSPACE_APP_ID in wrangler.toml); configs follow the wrangler-env\n * convention (top-level → `prd`, `--env staging` → `staging`). There is no\n * project/link setup step: run the commands from the app directory (or pass\n * --app <appId>) and they just work — for the owner, collaborators, and\n * admin accounts alike.\n *\n * deepspace secrets list [-c prd]\n * deepspace secrets set KEY=value [KEY2=value2 …]\n * deepspace secrets get KEY [--plain]\n * deepspace secrets delete KEY [KEY2 …]\n * deepspace secrets upload <file> (dotenv or JSON; --replace)\n * deepspace secrets download [--format dotenv|json|shell]\n * deepspace secrets pull (refresh the .dev.vars cache)\n * deepspace secrets configs list|create|delete\n */\n\nimport { defineCommand } from 'citty'\nimport { readFileSync } from 'node:fs'\nimport { ensureToken } from '../auth'\nimport { decodeJwtPayload } from '../jwt'\nimport { PLATFORM_URLS, writeDevVars } from '../env'\nimport { findAppDir } from '../lib/app-context'\nimport { readAppId, APP_ID_RE } from '../lib/app-identity'\nimport { dedupePositionals } from '../lib/citty-args'\nimport {\n createConfig,\n defaultConfigNameForEnv,\n deleteConfig,\n deleteSecret,\n fetchSecretsValues,\n formatSecretsDownload,\n getSecretPlain,\n listConfigs,\n listSecrets,\n parseSecretsUpload,\n pullAppSecretsCache,\n renderSecretsCache,\n setSecret,\n uploadSecrets,\n validateConfigName,\n validateSecretName,\n validateSecretValue,\n type SecretsDownloadFormat,\n} from '../lib/secrets'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? PLATFORM_URLS.deploy\n\nconst COMMON_ARGS = {\n app: {\n type: 'string' as const,\n alias: 'a',\n description: 'App id (default: DEEPSPACE_APP_ID from the nearest wrangler.toml)',\n required: false,\n },\n config: {\n type: 'string' as const,\n alias: 'c',\n description: 'Config name (default: the --env name, or \"prd\")',\n required: false,\n },\n env: {\n type: 'string' as const,\n alias: 'e',\n description: 'wrangler.toml [env.<name>] slot — selects that env’s app id and config',\n required: false,\n },\n}\n\ninterface Target {\n appId: string\n configName: string\n token: string\n}\n\nasync function resolveTarget(args: {\n app?: string\n config?: string\n env?: string\n}): Promise<Target> {\n const wranglerEnv = args.env?.trim() || undefined\n let appId = args.app?.trim()\n if (appId && !APP_ID_RE.test(appId)) {\n throw new Error(`Invalid app id \"${appId}\" — expected app_<26 chars>.`)\n }\n if (!appId) {\n const appDir = findAppDir()\n appId = (appDir && readAppId(appDir, wranglerEnv)) || undefined\n if (!appId) {\n // `--env <name>` selects a wrangler [env.<name>] slot with its OWN app id.\n // If the slot is missing but a top-level app id exists, the user almost\n // certainly wanted to pick a *config*, not an env — point them at `-c`.\n if (wranglerEnv && appDir && readAppId(appDir, undefined)) {\n throw new Error(\n `No app id for env \"${wranglerEnv}\" — wrangler.toml has no [env.${wranglerEnv}] block with its own DEEPSPACE_APP_ID. ` +\n `To target the \"${wranglerEnv}\" config on this app, use \\`-c ${wranglerEnv}\\` instead of \\`--env ${wranglerEnv}\\`.`,\n )\n }\n throw new Error(\n 'No app id. Run from an app directory whose wrangler.toml carries DEEPSPACE_APP_ID (`deepspace init` mints one), or pass --app <appId>.',\n )\n }\n }\n const configName = validateConfigName(args.config?.trim() || defaultConfigNameForEnv(wranglerEnv))\n const token = await ensureToken()\n return { appId, configName, token }\n}\n\nfunction fail(err: unknown): never {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n}\n\n/**\n * Warn (once) when a write turns on the unauthenticated debug API. Applies to\n * every write path that can carry it — `set` and `upload` alike. Returns true\n * when it warned, so callers can skip the generic \"run deploy\" line (this\n * message already tells the user to redeploy).\n */\nfunction warnIfDebugRoutesEnabled(secrets: Record<string, string>): boolean {\n if (secrets.ALLOW_DEBUG_ROUTES !== 'true') return false\n console.warn(\n '\\n⚠ ALLOW_DEBUG_ROUTES=true exposes an UNAUTHENTICATED debug API on the deployed app —\\n' +\n ' anyone who can reach /api/debug/* can read and mutate any record. Redeploy to apply;\\n' +\n ' `deepspace secrets delete ALLOW_DEBUG_ROUTES` (then redeploy) turns it back off.',\n )\n return true\n}\n\nconst APPLY_HINT = 'Run `deepspace deploy` to apply — secrets take effect at deploy time.'\n// `deepspace dev` regenerates .dev.vars from the store only at startup, so a\n// secret changed mid-session isn't picked up until dev restarts (DEV-4).\nconst LOCAL_DEV_HINT = 'Running `deepspace dev`? Restart it to load the change locally.'\n\nconst list = defineCommand({\n meta: { name: 'list', description: 'List masked secrets in a config' },\n args: {\n ...COMMON_ARGS,\n 'only-names': {\n type: 'boolean',\n description: 'Only print secret names; omit values and metadata',\n default: false,\n },\n json: { type: 'boolean', description: 'Machine-readable output', default: false },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const { secrets } = await listSecrets(DEPLOY_URL, t.token, t.appId, t.configName)\n if (args.json) {\n console.log(JSON.stringify({ appId: t.appId, config: t.configName, secrets }, null, 2))\n return\n }\n if (secrets.length === 0) {\n console.log(`No secrets in ${t.configName}.`)\n return\n }\n for (const s of secrets) {\n console.log(args['only-names'] ? s.key : `${s.key} (v${s.version}, ${s.updatedAt})`)\n }\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst set = defineCommand({\n meta: { name: 'set', description: 'Set secrets from KEY=value pairs' },\n args: {\n ...COMMON_ARGS,\n secret: { type: 'positional', description: 'KEY=value (repeatable)', required: true },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const pairs = dedupePositionals(args.secret, args._)\n const secrets: Record<string, string> = {}\n const dupes: string[] = []\n for (const pair of pairs) {\n const eq = pair.indexOf('=')\n if (eq <= 0) throw new Error(`Expected KEY=value, got \"${pair}\"`)\n const key = validateSecretName(pair.slice(0, eq))\n const value = pair.slice(eq + 1)\n validateSecretValue(key, value)\n // The same KEY given twice (with different values) silently keeps the\n // last — surface it instead of dropping a value without a word.\n if (key in secrets && !dupes.includes(key)) dupes.push(key)\n secrets[key] = value\n }\n if (dupes.length) {\n console.warn(\n `Warning: ${dupes.join(', ')} given more than once — kept the last value for each.`,\n )\n }\n if (Object.keys(secrets).length === 1) {\n const [[k, v]] = Object.entries(secrets)\n await setSecret(DEPLOY_URL, t.token, t.appId, t.configName, k, v)\n } else {\n await uploadSecrets(DEPLOY_URL, t.token, t.appId, t.configName, secrets, false)\n }\n console.log(`Set ${Object.keys(secrets).length} secret${Object.keys(secrets).length === 1 ? '' : 's'} in ${t.configName}.`)\n if (!warnIfDebugRoutesEnabled(secrets)) {\n console.log(APPLY_HINT)\n console.log(LOCAL_DEV_HINT)\n }\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst get = defineCommand({\n meta: { name: 'get', description: 'Get a secret; pass --plain to print the value' },\n args: {\n ...COMMON_ARGS,\n key: { type: 'positional', description: 'Secret name', required: true },\n plain: { type: 'boolean', description: 'Print the plaintext value', default: false },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const key = validateSecretName(args.key)\n if (args.plain) {\n const { value } = await getSecretPlain(DEPLOY_URL, t.token, t.appId, t.configName, key)\n // Byte-exact when piped/redirected (`… get --plain KEY > key.pem`); add a\n // trailing newline only for a human reading it in a terminal.\n process.stdout.write(process.stdout.isTTY ? value + '\\n' : value)\n return\n }\n const { secrets } = await listSecrets(DEPLOY_URL, t.token, t.appId, t.configName)\n const item = secrets.find((s) => s.key === key)\n if (!item) fail(new Error(`Secret \"${key}\" not found in ${t.configName}`))\n console.log(`${item.key} (v${item.version}, ${item.updatedAt})`)\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst del = defineCommand({\n meta: { name: 'delete', description: 'Delete one or more secrets' },\n args: {\n ...COMMON_ARGS,\n key: { type: 'positional', description: 'Secret name (repeatable)', required: true },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const keys = dedupePositionals(args.key, args._)\n let deleted = 0\n let absent = 0\n for (const key of keys) {\n const name = validateSecretName(key)\n try {\n await deleteSecret(DEPLOY_URL, t.token, t.appId, t.configName, name)\n deleted++\n } catch (err) {\n // An already-absent key is a completed delete, not a failure: don't\n // let one missing key abort the rest, and keep retries idempotent.\n if ((err as { status?: number })?.status === 404) absent++\n else throw err\n }\n }\n const note = absent > 0 ? ` (${absent} already absent)` : ''\n console.log(`Deleted ${deleted} secret${deleted === 1 ? '' : 's'} from ${t.configName}.${note}`)\n if (deleted > 0) console.log(APPLY_HINT)\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst upload = defineCommand({\n meta: { name: 'upload', description: 'Upload secrets from a dotenv or JSON file' },\n args: {\n ...COMMON_ARGS,\n file: { type: 'positional', description: 'Path to a dotenv or JSON file (- for stdin)', required: true },\n replace: {\n type: 'boolean',\n description: 'Replace the whole config (delete keys missing from the file)',\n default: false,\n },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const content =\n args.file === '-' ? readFileSync(0, 'utf-8') : readFileSync(args.file, 'utf-8')\n const secrets = parseSecretsUpload(content)\n if (Object.keys(secrets).length === 0) fail(new Error('No secrets found in the input.'))\n await uploadSecrets(DEPLOY_URL, t.token, t.appId, t.configName, secrets, args.replace)\n console.log(`Uploaded ${Object.keys(secrets).length} secrets to ${t.configName}.`)\n // A file can turn on the debug API just like `set` can — warn either way.\n if (!warnIfDebugRoutesEnabled(secrets)) console.log(APPLY_HINT)\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst download = defineCommand({\n meta: { name: 'download', description: 'Download a config’s secrets (dotenv/json/shell)' },\n args: {\n ...COMMON_ARGS,\n format: {\n type: 'string',\n description: 'dotenv (default) | json | shell',\n default: 'dotenv',\n },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const format = args.format as SecretsDownloadFormat\n if (!['dotenv', 'json', 'shell'].includes(format)) {\n fail(new Error(`Unknown format \"${args.format}\" — use dotenv, json, or shell.`))\n }\n const { secrets } = await fetchSecretsValues(DEPLOY_URL, t.token, t.appId, t.configName)\n process.stdout.write(formatSecretsDownload(secrets, format))\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst pull = defineCommand({\n meta: { name: 'pull', description: 'Refresh the .dev.vars cache from the app store' },\n args: { ...COMMON_ARGS },\n async run({ args }) {\n try {\n const wranglerEnv = args.env?.trim() || undefined\n const appDir = findAppDir()\n if (!appDir) fail(new Error('Run from a DeepSpace app directory (one containing wrangler.toml).'))\n const t = await resolveTarget(args)\n const ownerId = decodeJwtPayload<{ sub: string }>(t.token).sub\n const pulled = await pullAppSecretsCache(DEPLOY_URL, t.token, t.appId, t.configName)\n if (!pulled) {\n console.log(`No secrets in ${t.configName} yet — nothing to pull.`)\n return\n }\n await writeDevVars(appDir, ownerId, t.token, wranglerEnv, {\n appId: t.appId,\n generatedSecretsCache: renderSecretsCache(pulled.values, pulled),\n sharedDevVarsCache: true,\n })\n console.log(\n `Pulled ${Object.keys(pulled.values).length} secrets (${t.configName}) into .dev.vars.`,\n )\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst configsList = defineCommand({\n meta: { name: 'list', description: 'List the app’s configs' },\n args: { ...COMMON_ARGS },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const { configs } = await listConfigs(DEPLOY_URL, t.token, t.appId)\n if (configs.length === 0) {\n console.log('No configs yet — the first `secrets set` creates one.')\n return\n }\n for (const cfg of configs) {\n console.log(`${cfg.name} (${cfg.secretCount ?? 0} secrets, updated ${cfg.updatedAt})`)\n }\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst configsCreate = defineCommand({\n meta: { name: 'create', description: 'Create a config (optionally copying another)' },\n args: {\n ...COMMON_ARGS,\n name: { type: 'positional', description: 'Config name', required: true },\n 'copy-from': { type: 'string', description: 'Copy secrets from this config', required: false },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const name = validateConfigName(args.name)\n const copyFrom = args['copy-from'] || undefined\n // Create is idempotent server-side, so a plain create of an existing\n // config used to print a false \"Created\". Distinguish the cases up front:\n // a bare re-create is a no-op (\"Already exists.\"); a --copy-from into an\n // existing config would clobber it, so refuse rather than silently create.\n const { configs } = await listConfigs(DEPLOY_URL, t.token, t.appId)\n if (configs.some((c) => c.name === name)) {\n if (copyFrom) {\n fail(\n new Error(\n `Config \"${name}\" already exists — refusing to copy \"${copyFrom}\" over it. Delete it first, or pick a new name.`,\n ),\n )\n }\n console.log(`Config ${name} already exists.`)\n return\n }\n await createConfig(DEPLOY_URL, t.token, t.appId, name, copyFrom)\n console.log(`Created ${name}.`)\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst configsDelete = defineCommand({\n meta: { name: 'delete', description: 'Delete a config and all of its secrets' },\n args: {\n ...COMMON_ARGS,\n name: { type: 'positional', description: 'Config name', required: true },\n },\n async run({ args }) {\n try {\n const t = await resolveTarget(args)\n const name = validateConfigName(args.name)\n await deleteConfig(DEPLOY_URL, t.token, t.appId, name)\n console.log(`Deleted ${name}.`)\n } catch (err) {\n fail(err)\n }\n },\n})\n\nconst configs = defineCommand({\n meta: { name: 'configs', description: 'Manage the app’s secrets configs' },\n subCommands: { list: configsList, create: configsCreate, delete: configsDelete },\n})\n\nexport default defineCommand({\n meta: { name: 'secrets', description: 'Manage the app’s secrets store' },\n subCommands: {\n list,\n set,\n get,\n delete: del,\n upload,\n download,\n pull,\n configs,\n },\n})\n","/**\n * Helpers for citty argument quirks.\n */\n\n/**\n * citty binds the first positional to its named arg AND *also* leaves the full\n * positional list in `args._`. A handler that naively unions `[named, ...args._]`\n * therefore processes the first positional twice — which silently broke\n * `secrets delete`: it deleted a key, re-attempted the same key, got a 404, and\n * aborted the rest (`delete A B` kept B; a single `delete A` exited 1 on success).\n *\n * Union + dedupe (dropping empties / non-strings) yields the caller's distinct\n * positionals exactly once, in first-seen order. Use this anywhere a command\n * accepts a repeatable positional.\n */\nexport function dedupePositionals(bound: unknown, rest: unknown): string[] {\n const restArr = Array.isArray(rest) ? rest : []\n return [...new Set([bound, ...restArr])].filter(\n (v): v is string => typeof v === 'string' && v.length > 0,\n )\n}\n","/**\n * `deepspace init` — ensure this app carries its immutable identity.\n *\n * Mints DEEPSPACE_APP_ID into wrangler.toml (per wrangler env with --env).\n * Registration happens at the first deploy. `--new-id` replaces an existing\n * id, which FORKS the repo into a separate app: fresh registration, fresh\n * Durable Object data, fresh secrets store — the original app is untouched.\n */\n\nimport { defineCommand } from 'citty'\nimport { findAppDir } from '../lib/app-context'\nimport { mintAppId, readAppId, writeAppId } from '../lib/app-identity'\n\nexport default defineCommand({\n meta: {\n name: 'init',\n description: 'Mint this app’s immutable DEEPSPACE_APP_ID into wrangler.toml',\n },\n args: {\n 'new-id': {\n type: 'boolean',\n description:\n 'Replace the existing id — forks this repo as a SEPARATE app (new data, new secrets, new registration). The original app keeps running.',\n default: false,\n },\n env: {\n type: 'string',\n alias: 'e',\n description: 'wrangler.toml [env.<name>] block to stamp (each env is its own app)',\n required: false,\n },\n },\n async run({ args }) {\n const appDir = findAppDir()\n if (!appDir) {\n console.error(\n 'No wrangler.toml here — `deepspace init` stamps an app id into an existing ' +\n 'DeepSpace app. To create a new app, run `deepspace create <name>` (or ' +\n '`npm create deepspace@latest <name>`), then run this from inside it.',\n )\n process.exit(1)\n }\n const envName = args.env || undefined\n const existing = readAppId(appDir, envName)\n if (existing && !args['new-id']) {\n console.log(`Already initialized: ${existing}${envName ? ` (env: ${envName})` : ''}`)\n return\n }\n const appId = mintAppId()\n writeAppId(appDir, appId, { wranglerEnv: envName, force: args['new-id'] })\n if (existing) {\n console.log(`Forked: ${existing} → ${appId}${envName ? ` (env: ${envName})` : ''}`)\n console.log('The next deploy registers this as a NEW app; the original is untouched.')\n } else {\n console.log(`Minted ${appId}${envName ? ` (env: ${envName})` : ''} — commit wrangler.toml.`)\n console.log('The first deploy registers it and claims the `name` subdomain.')\n }\n },\n})\n"],"mappings":"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","names":["defineCommand","spawnSync","readFileSync","existsSync","dirname","join","fileURLToPath","status","run","writeFileSync","readFileSync","join","p","existsSync","readFileSync","out","writeFileSync","existsSync","readFileSync","writeFileSync","join","parseToml","join","existsSync","writeFileSync","readFileSync","parseToml","existsSync","readFileSync","readFileSync","join","writeFileSync","resolve","defineCommand","existsSync","readFileSync","rmSync","join","homedir","AUTH_URL","join","homedir","defineCommand","existsSync","readFileSync","rmSync","defineCommand","resolve","basename","join","readFileSync","writeFileSync","existsSync","mkdirSync","join","homedir","AUTH_URL","DIR","join","homedir","SESSION_PATH","TOKEN_PATH","existsSync","readFileSync","mkdirSync","writeFileSync","existsSync","readFileSync","writeFileSync","mkdirSync","join","resolve","parseToml","status","text","join","resolve","existsSync","parseToml","readFileSync","mkdirSync","writeFileSync","p","existsSync","readFileSync","join","existsSync","resolve","status","readdirSync","rmSync","join","resolve","defineCommand","resolve","join","basename","defineCommand","readFileSync","readdirSync","defineCommand","readFileSync","readdirSync","defineCommand","resolve","spawnSync","spawnSync","DEPLOY_URL","defineCommand","resolve","spawnSync","defineCommand","spawnSync","resolve","defineCommand","resolve","spawnSync","defineCommand","p","readFileSync","writeFileSync","existsSync","mkdirSync","join","homedir","SESSION_COOKIE","AUTH_URL","DIR","join","homedir","existsSync","readFileSync","mkdirSync","writeFileSync","SESSION_PATH","defineCommand","defineCommand","execSync","readFileSync","readdirSync","existsSync","join","resolve","dirname","p","DEPLOY_URL","API_URL","status","defineCommand","resolve","existsSync","readFileSync","execSync","join","dirname","wait","readdirSync","defineCommand","p","DEPLOY_URL","defineCommand","defineCommand","defineCommand","defineCommand","DEPLOY_URL","defineCommand","defineCommand","existsSync","readFileSync","resolve","join","dirname","spawnSync","join","existsSync","dirname","pkg","readFileSync","spawnSync","defineCommand","resolve","script","passArgs","defineCommand","API_URL","confirm","resolve","defineCommand","list","defineCommand","list","defineCommand","API_URL","DEPLOY_URL","api","list","defineCommand","p","cancel","defineCommand","p","API_URL","DEPLOY_URL","defineCommand","status","cancel","defineCommand","readFileSync","p","API_URL","readFileSync","info","ok","list","defineCommand","defineCommand","defineCommand","defineCommand","existsSync","readFileSync","join","resolve","parseToml","p","defineCommand","intro","info","resolve","join","existsSync","parseToml","readFileSync","defineCommand","p","existsSync","readFileSync","dirname","join","fileURLToPath","API_URL","api","dirname","fileURLToPath","join","existsSync","pkg","readFileSync","detectAppName","defineCommand","fail","defineCommand","readFileSync","DEPLOY_URL","list","defineCommand","del","note","readFileSync","configs","defineCommand","defineCommand","dirname","fileURLToPath","readFileSync","join","existsSync","create","defineCommand","spawnSync"]}
|