deepspace 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/cli.ts","../src/cli/commands/login.ts","../src/cli/env.ts","../src/cli/session.ts","../src/cli/commands/logout.ts","../src/cli/commands/dev.ts","../src/cli/auth.ts","../src/cli/commands/test.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/add.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 { execSync } from 'node:child_process'\nimport login from './commands/login'\nimport logout from './commands/logout'\nimport dev from './commands/dev'\nimport test from './commands/test'\nimport testAccounts from './commands/test-accounts'\nimport deploy from './commands/deploy'\nimport undeploy from './commands/undeploy'\nimport whoami from './commands/whoami'\nimport add from './commands/add'\n\nconst create = defineCommand({\n meta: {\n name: 'create',\n description: 'Create a new DeepSpace app',\n },\n args: {\n name: {\n type: 'positional',\n description: 'App name',\n required: false,\n },\n },\n run({ args }) {\n const name = args.name ? ` ${args.name}` : ''\n console.log(`Running: npm create deepspace${name}\\n`)\n execSync(`npm create deepspace@latest${name}`, { stdio: 'inherit' })\n },\n})\n\nconst main = defineCommand({\n meta: {\n name: 'deepspace',\n version: '0.1.0',\n description: 'DeepSpace SDK CLI',\n },\n subCommands: {\n create,\n login,\n logout,\n whoami,\n dev,\n test,\n 'test-accounts': testAccounts,\n add,\n deploy,\n undeploy,\n },\n run() {\n console.log('deepspace CLI — run `npx deepspace --help` for usage')\n },\n})\n\nrunMain(main)\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 (CI/agents)\n */\n\nimport { defineCommand } from 'citty'\nimport { writeFileSync, mkdirSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport { exec } from 'node:child_process'\nimport { platform } from 'node:os'\nimport * as p from '@clack/prompts'\n\nimport { ENVS } from '../env'\nimport { exchangeSession, SESSION_COOKIE } from '../session'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? ENVS.prod.auth\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)',\n required: false,\n },\n password: {\n type: 'string',\n description: 'Password (non-interactive mode)',\n required: false,\n },\n },\n async run({ args }) {\n // Non-interactive mode for CI/agents with email+password\n if (args.email && args.password) {\n console.log(`Signing in as ${args.email}...`)\n await doEmailLogin(args.email, args.password)\n console.log('Logged in')\n return\n }\n\n // Browser-based OAuth flow\n p.intro('DeepSpace Login')\n\n const s = p.spinner()\n s.start('Creating login session...')\n\n // 1. Create a CLI session\n const sessionRes = await fetch(`${AUTH_URL}/api/auth/cli/session`, { method: 'POST' })\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 { sessionId?: string; loginUrl?: string }\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 { sessionId: string; loginUrl: string }\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)\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\n storeCredentials(result.sessionToken, result.jwt)\n\n s.stop('Authenticated')\n p.outro(`Logged in as ${result.name ?? result.email}`)\n },\n})\n\ninterface LoginResult {\n sessionToken: string\n jwt: string\n email: string\n name: string | null\n}\n\nasync function pollForCompletion(sessionId: string): 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\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 })\n writeFileSync(join(dir, 'session'), sessionToken, { mode: 0o600 })\n writeFileSync(join(dir, 'token'), jwt, { mode: 0o600 })\n}\n\nfunction openBrowser(url: string) {\n const cmd =\n platform() === 'darwin'\n ? `open \"${url}\"`\n : platform() === 'win32'\n ? `start \"\" \"${url}\"`\n : `xdg-open \"${url}\"`\n\n exec(cmd, () => {\n // Ignore errors — we already showed the URL\n })\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\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}\n","/**\n * DeepSpace environment configuration.\n *\n * Shared between `dev`, `test`, and `deploy` commands.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { parse as parseToml } from 'smol-toml'\n\nexport const ENVS = {\n dev: {\n auth: 'https://deepspace-auth.eudaimonicincorporated.workers.dev',\n api: 'https://deepspace-api.eudaimonicincorporated.workers.dev',\n platform: 'https://deepspace-platform-worker.eudaimonicincorporated.workers.dev',\n deploy: 'https://deepspace-deploy.eudaimonicincorporated.workers.dev',\n },\n prod: {\n auth: 'https://deepspace-auth.eudaimonicincorporated.workers.dev',\n api: 'https://deepspace-api.eudaimonicincorporated.workers.dev',\n platform: 'https://deepspace-platform-worker.eudaimonicincorporated.workers.dev',\n deploy: 'https://deepspace-deploy.eudaimonicincorporated.workers.dev',\n },\n} as const\n\nexport type EnvName = keyof typeof ENVS\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.\n * `deepspace dev` runs in an app directory; the name is required.\n */\nfunction readAppName(appDir: string): string {\n const wranglerPath = join(appDir, 'wrangler.toml')\n if (!existsSync(wranglerPath)) {\n throw new Error('No wrangler.toml found. Are you in a DeepSpace app directory?')\n }\n const parsed = parseToml(readFileSync(wranglerPath, 'utf-8')) as { name?: string }\n if (!parsed.name) {\n throw new Error('wrangler.toml has no `name` field')\n }\n return parsed.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({ 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 * Write .dev.vars for an app, pointing to the specified environment's workers.\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 env: EnvName,\n ownerId: string,\n callerJwt: string,\n): Promise<void> {\n const urls = ENVS[env]\n const publicKey = await fetchPublicKey(urls.auth)\n const appName = readAppName(appDir)\n const appOwnerJwt = await mintAppOwnerJwt(urls.auth, callerJwt, appName)\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 devVars = [\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 `INTERNAL_STORAGE_HMAC_SECRET=dev-${Date.now()}`,\n // Open /api/debug/* (proxied to RecordRoom) for dev + tests only.\n // Production secrets never set this, so deployed apps 404 the route.\n `ALLOW_DEBUG_ROUTES=true`,\n ].join('\\n')\n\n writeFileSync(join(appDir, '.dev.vars'), devVars + '\\n')\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 * 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 { ENVS } from '../env'\nimport { SESSION_COOKIE } from '../session'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? ENVS.prod.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 [--prod] [--port N]\n *\n * Starts local development:\n * 1. Ensures you're logged in\n * 2. Writes .dev.vars pointing to dev or prod workers\n * 3. Starts vite dev (Cloudflare Vite plugin runs the worker in-process)\n *\n * deepspace dev # uses dev workers, port 5173 (strict)\n * deepspace dev --prod # uses production workers\n * deepspace dev --port 5180 # bind to a different port (multi-app dev)\n *\n * Port is `--port` > $DEEPSPACE_PORT > 5173. We always pass --strictPort to\n * vite so a busy port fails loudly instead of silently jumping to 5174 (which\n * would diverge from anything Playwright/test config is expecting).\n */\n\nimport { defineCommand } from 'citty'\nimport { existsSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport { spawn } from 'node:child_process'\nimport { ensureToken } from '../auth'\nimport { writeDevVars } from '../env'\n\nconst DEFAULT_PORT = 5173\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 prod: {\n type: 'boolean',\n description: 'Use production workers (real auth, real API calls)',\n default: 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 const appDir = resolve(args.dir ?? '.')\n const env = args.prod ? 'prod' : 'dev'\n const port = resolvePort(args.port)\n\n if (!existsSync(join(appDir, 'wrangler.toml'))) {\n console.error('No wrangler.toml found. Are you in a DeepSpace app directory?')\n process.exit(1)\n }\n\n let token: string\n try {\n token = await ensureToken()\n } catch (err: any) {\n console.error(err.message)\n process.exit(1)\n }\n\n let payload: { sub: string; name?: string; email?: string }\n try {\n payload = JSON.parse(atob(token.split('.')[1]))\n } catch {\n console.error('Malformed session token. Run `npx deepspace login`.')\n process.exit(1)\n }\n console.log(`Logged in as ${payload.name ?? payload.email}`)\n console.log(`Environment: ${env}`)\n console.log(`Port: ${port}`)\n\n await writeDevVars(appDir, env, payload.sub, token)\n console.log('Starting dev server...\\n')\n\n const vite = spawn(\n 'npx',\n ['vite', '--port', String(port), '--strictPort'],\n {\n cwd: appDir,\n stdio: 'inherit',\n shell: process.platform === 'win32',\n env: { ...process.env, DEEPSPACE_PORT: String(port) },\n },\n )\n process.on('SIGINT', () => vite.kill())\n process.on('SIGTERM', () => vite.kill())\n vite.on('close', (code) => process.exit(code ?? 0))\n },\n})\n\nfunction 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 * 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 { ENVS } from './env'\nimport { exchangeSession } from './session'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? ENVS.prod.auth\n\nconst DIR = join(homedir(), '.deepspace')\nexport const SESSION_PATH = join(DIR, 'session')\nconst 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 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 // 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 // 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 })\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 = JSON.parse(atob(jwt.split('.')[1]))\n return payload.exp * 1000 > Date.now() + 30_000\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. The chosen port is exported as\n * DEEPSPACE_PORT to the Playwright child so the config + webServer both bind\n * to the same address. Pass a different port per app to run multiple apps\n * (and test suites) in parallel.\n */\n\nimport { defineCommand } from 'citty'\nimport { existsSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport { execSync, spawnSync } from 'node:child_process'\nimport { ensureToken } from '../auth'\nimport { writeDevVars } from '../env'\n\nconst DEFAULT_PORT = 5173\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 },\n async run({ args }) {\n const appDir = resolve('.')\n const suite = args.suite ?? 'default'\n const port = resolvePort(args.port)\n\n if (!existsSync(join(appDir, 'wrangler.toml'))) {\n console.error('No wrangler.toml found. Are you in a DeepSpace app directory?')\n process.exit(1)\n }\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 = JSON.parse(atob(token.split('.')[1]))\n ownerId = payload.sub\n } catch (err) {\n console.error('`deepspace test` requires you to be logged in. Run `deepspace login` first.')\n process.exit(1)\n }\n\n await writeDevVars(appDir, 'dev', ownerId, token)\n\n if (suite !== 'unit') {\n ensurePlaywright(appDir)\n }\n\n let exitCode = 0\n\n switch (suite) {\n case 'smoke':\n exitCode = runPlaywright(appDir, ['tests/smoke.spec.ts'], port)\n break\n case 'api':\n exitCode = runPlaywright(appDir, ['tests/api.spec.ts'], port)\n break\n case 'e2e':\n exitCode = runPlaywright(appDir, [], port)\n break\n case 'unit':\n exitCode = runVitest(appDir)\n break\n case 'all':\n exitCode = runVitest(appDir)\n if (exitCode === 0) exitCode = runPlaywright(appDir, [], port)\n break\n case 'default':\n exitCode = runPlaywright(appDir, ['tests/smoke.spec.ts', 'tests/api.spec.ts'], port)\n break\n default:\n if (suite.endsWith('.spec.ts')) {\n exitCode = runPlaywright(appDir, [suite], port)\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(appDir: string, testFiles: string[], port: number): number {\n const result = spawnSync('npx', [\n 'playwright', 'test',\n '--config', 'tests/playwright.config.ts',\n ...testFiles,\n ], {\n cwd: appDir,\n stdio: 'inherit',\n shell: process.platform === 'win32',\n env: { ...process.env, DEEPSPACE_PORT: String(port) },\n })\n return result.status ?? 1\n}\n\nfunction runVitest(appDir: string): number {\n const result = spawnSync('npx', ['vitest', 'run', '--passWithNoTests'], {\n cwd: appDir, stdio: 'inherit', shell: process.platform === 'win32',\n })\n return result.status ?? 1\n}\n\nfunction ensurePlaywright(appDir: string) {\n try {\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 try {\n execSync('npx playwright install --dry-run chromium', { cwd: appDir, stdio: 'pipe' })\n } catch {\n console.log('Installing Chromium for Playwright...')\n execSync('npx playwright install chromium', { cwd: appDir, stdio: 'inherit' })\n }\n}\n\nfunction 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 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 { ENVS } from '../env'\n\nconst SESSION_COOKIE = '__Secure-better-auth.session_token'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? ENVS.prod.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 { id: string; email: string; userId: string; label: string | null; createdAt: number }\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('No test accounts. Create one with: deepspace test-accounts create --email <email> --password <password>')\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 let 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\n ? remote.filter((a) => a.label === args.label)\n : 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 { readFileSync, readdirSync, existsSync } from 'node:fs'\nimport { parse as parseToml } from 'smol-toml'\nimport { join, resolve, dirname } from 'node:path'\nimport * as p from '@clack/prompts'\nimport { ensureToken } from '../auth'\nimport { ENVS } from '../env'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? ENVS.prod.deploy\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 },\n async run({ args }) {\n const appDir = resolve(args.dir ?? '.')\n p.intro('Deploying DeepSpace app')\n\n // ── Read app name from wrangler.toml ──────────────────────\n const wranglerPath = join(appDir, 'wrangler.toml')\n if (!existsSync(wranglerPath)) {\n p.cancel('No wrangler.toml found. Are you in a DeepSpace app directory?')\n process.exit(1)\n }\n\n const wranglerConfig = parseToml(readFileSync(wranglerPath, 'utf-8')) as { name?: string }\n const appName = wranglerConfig.name\n if (!appName) {\n p.cancel('Could not find app name in wrangler.toml')\n process.exit(1)\n }\n p.log.info(`App: ${appName}`)\n\n // ── Ensure valid JWT ───────────────────────────────────────\n let token: string\n try {\n token = await ensureToken()\n } catch (err: any) {\n p.cancel(err.message)\n process.exit(1)\n }\n\n // ── Build with Vite (Cloudflare plugin bundles client + worker) ──\n const s = p.spinner()\n s.start('Building...')\n try {\n execSync('npx vite build', { cwd: appDir, stdio: 'pipe' })\n } catch (err: any) {\n s.stop('Build failed')\n console.error(err.stderr?.toString() ?? err.message)\n process.exit(1)\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 { configPath: string }\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 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 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 Array<{ name: string; class_name: string }> | undefined\n const sqliteClasses = new Set(\n (outputConfig.migrations as Array<{ new_sqlite_classes?: string[] }> | undefined)\n ?.flatMap(m => m.new_sqlite_classes ?? []) ?? []\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 // ── Upload to deploy worker ───────────────────────────────\n s.start(`Deploying to ${appName}.app.space...`)\n\n const form = new FormData()\n form.append('worker', new Blob([workerJs], { type: 'application/javascript' }), 'worker.js')\n form.append('assets', JSON.stringify(assets))\n if (doManifest) {\n form.append('doManifest', JSON.stringify(doManifest))\n }\n\n const res = await fetch(`${DEPLOY_URL}/api/deploy/${appName}`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${token}` },\n body: form,\n })\n\n const body = (await res.json().catch(() => ({}))) as {\n success?: boolean\n url?: string\n error?: string\n }\n\n if (!res.ok || !body.success) {\n s.stop('Deploy failed')\n p.cancel(body.error ?? `Deployment error (${res.status})`)\n process.exit(1)\n }\n\n s.stop('Deployed!')\n p.log.success(`Live at: ${body.url}`)\n p.outro('Done')\n },\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 { readFileSync, existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { parse as parseToml } from 'smol-toml'\nimport * as p from '@clack/prompts'\nimport { ensureToken } from '../auth'\n\nimport { ENVS } from '../env'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? ENVS.prod.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 name to undeploy (reads from wrangler.toml if omitted)',\n required: false,\n },\n },\n async run({ args }) {\n let appName = args.name\n\n // If no name given, try to read from wrangler.toml in cwd\n if (!appName) {\n const wranglerPath = join(process.cwd(), 'wrangler.toml')\n if (existsSync(wranglerPath)) {\n const config = parseToml(readFileSync(wranglerPath, 'utf-8')) as { name?: string }\n if (config.name) appName = config.name\n }\n }\n\n if (!appName) {\n p.cancel('Provide an app name or run from a DeepSpace app directory.')\n process.exit(1)\n }\n\n let token: string\n try {\n token = await ensureToken()\n } catch (err: any) {\n p.cancel(err.message)\n process.exit(1)\n }\n\n p.intro(`Undeploying ${appName}`)\n const s = p.spinner()\n s.start('Removing...')\n\n const res = await fetch(`${DEPLOY_URL}/api/deploy/${appName}`, {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${token}` },\n })\n\n const body = (await res.json().catch(() => ({}))) as { success?: boolean; error?: string }\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 p.outro(`${appName}.app.space has been taken down`)\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'\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 let jwt: string\n try {\n jwt = await ensureToken()\n } catch (err: any) {\n console.error(err.message ?? 'Not signed in. Run `deepspace login`.')\n process.exit(1)\n }\n\n let payload: JwtPayload\n try {\n payload = JSON.parse(atob(jwt.split('.')[1]))\n } catch {\n console.error('Malformed session token. Run `deepspace login` again.')\n process.exit(1)\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 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 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 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 } from 'node:fs'\nimport { resolve, join } from 'node:path'\nimport { execSync } from 'node:child_process'\n\nfunction findScript(from: string): string | null {\n const candidate = join(from, '.deepspace', 'scripts', 'add-feature.cjs')\n if (existsSync(candidate)) return candidate\n return null\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 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 const script = findScript(appDir)\n\n if (!script) {\n console.error('No .deepspace/scripts/add-feature.cjs found.')\n console.error('Are you in a DeepSpace app directory?')\n process.exit(1)\n }\n\n const passArgs: string[] = []\n\n if (args.list) {\n passArgs.push('--list')\n } else if (args.info) {\n passArgs.push('--info', args.info)\n } else if (args.feature) {\n passArgs.push(args.feature, appDir)\n } else {\n passArgs.push('--help')\n }\n\n execSync(`node ${JSON.stringify(script)} ${passArgs.map(a => JSON.stringify(a)).join(' ')}`, {\n stdio: 'inherit',\n cwd: appDir,\n })\n },\n})\n"],"mappings":"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","names":["defineCommand","execSync","writeFileSync","join","join","writeFileSync","resolve","defineCommand","existsSync","readFileSync","join","homedir","AUTH_URL","join","homedir","defineCommand","existsSync","readFileSync","defineCommand","existsSync","join","readFileSync","writeFileSync","existsSync","mkdirSync","join","homedir","AUTH_URL","DIR","join","homedir","SESSION_PATH","TOKEN_PATH","existsSync","readFileSync","mkdirSync","writeFileSync","defineCommand","existsSync","join","defineCommand","existsSync","join","resolve","DEFAULT_PORT","defineCommand","resolve","resolvePort","existsSync","join","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","existsSync","parseToml","join","resolve","p","defineCommand","resolve","join","existsSync","parseToml","readFileSync","execSync","defineCommand","readFileSync","existsSync","join","parseToml","p","DEPLOY_URL","defineCommand","join","existsSync","parseToml","readFileSync","defineCommand","defineCommand","defineCommand","existsSync","resolve","join","execSync","create","defineCommand","execSync"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/cli.ts","../src/cli/commands/login.ts","../src/cli/env.ts","../src/cli/session.ts","../src/cli/commands/logout.ts","../src/cli/commands/dev.ts","../src/cli/auth.ts","../src/cli/commands/test.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/add.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 { execSync } from 'node:child_process'\nimport login from './commands/login'\nimport logout from './commands/logout'\nimport dev from './commands/dev'\nimport test from './commands/test'\nimport testAccounts from './commands/test-accounts'\nimport deploy from './commands/deploy'\nimport undeploy from './commands/undeploy'\nimport whoami from './commands/whoami'\nimport add from './commands/add'\n\nconst create = defineCommand({\n meta: {\n name: 'create',\n description: 'Create a new DeepSpace app',\n },\n args: {\n name: {\n type: 'positional',\n description: 'App name',\n required: false,\n },\n },\n run({ args }) {\n const name = args.name ? ` ${args.name}` : ''\n console.log(`Running: npm create deepspace${name}\\n`)\n execSync(`npm create deepspace@latest${name}`, { stdio: 'inherit' })\n },\n})\n\nconst main = defineCommand({\n meta: {\n name: 'deepspace',\n version: '0.2.1',\n description: 'DeepSpace SDK CLI',\n },\n subCommands: {\n create,\n login,\n logout,\n whoami,\n dev,\n test,\n 'test-accounts': testAccounts,\n add,\n deploy,\n undeploy,\n },\n run() {\n console.log('deepspace CLI — run `npx deepspace --help` for usage')\n },\n})\n\nrunMain(main)\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 (CI/agents)\n */\n\nimport { defineCommand } from 'citty'\nimport { writeFileSync, mkdirSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport { exec } from 'node:child_process'\nimport { platform } from 'node:os'\nimport * as p from '@clack/prompts'\n\nimport { ENVS } from '../env'\nimport { exchangeSession, SESSION_COOKIE } from '../session'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? ENVS.prod.auth\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)',\n required: false,\n },\n password: {\n type: 'string',\n description: 'Password (non-interactive mode)',\n required: false,\n },\n },\n async run({ args }) {\n // Non-interactive mode for CI/agents with email+password\n if (args.email && args.password) {\n console.log(`Signing in as ${args.email}...`)\n await doEmailLogin(args.email, args.password)\n console.log('Logged in')\n return\n }\n\n // Browser-based OAuth flow\n p.intro('DeepSpace Login')\n\n const s = p.spinner()\n s.start('Creating login session...')\n\n // 1. Create a CLI session\n const sessionRes = await fetch(`${AUTH_URL}/api/auth/cli/session`, { method: 'POST' })\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 { sessionId?: string; loginUrl?: string }\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 { sessionId: string; loginUrl: string }\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)\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\n storeCredentials(result.sessionToken, result.jwt)\n\n s.stop('Authenticated')\n p.outro(`Logged in as ${result.name ?? result.email}`)\n },\n})\n\ninterface LoginResult {\n sessionToken: string\n jwt: string\n email: string\n name: string | null\n}\n\nasync function pollForCompletion(sessionId: string): 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\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 })\n writeFileSync(join(dir, 'session'), sessionToken, { mode: 0o600 })\n writeFileSync(join(dir, 'token'), jwt, { mode: 0o600 })\n}\n\nfunction openBrowser(url: string) {\n const cmd =\n platform() === 'darwin'\n ? `open \"${url}\"`\n : platform() === 'win32'\n ? `start \"\" \"${url}\"`\n : `xdg-open \"${url}\"`\n\n exec(cmd, () => {\n // Ignore errors — we already showed the URL\n })\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\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}\n","/**\n * DeepSpace environment configuration.\n *\n * Shared between `dev`, `test`, and `deploy` commands.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { parse as parseToml } from 'smol-toml'\n\nexport const ENVS = {\n dev: {\n auth: 'https://deepspace-auth.eudaimonicincorporated.workers.dev',\n api: 'https://deepspace-api.eudaimonicincorporated.workers.dev',\n platform: 'https://deepspace-platform-worker.eudaimonicincorporated.workers.dev',\n deploy: 'https://deepspace-deploy.eudaimonicincorporated.workers.dev',\n },\n prod: {\n auth: 'https://deepspace-auth.eudaimonicincorporated.workers.dev',\n api: 'https://deepspace-api.eudaimonicincorporated.workers.dev',\n platform: 'https://deepspace-platform-worker.eudaimonicincorporated.workers.dev',\n deploy: 'https://deepspace-deploy.eudaimonicincorporated.workers.dev',\n },\n} as const\n\nexport type EnvName = keyof typeof ENVS\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.\n * `deepspace dev` runs in an app directory; the name is required.\n */\nfunction readAppName(appDir: string): string {\n const wranglerPath = join(appDir, 'wrangler.toml')\n if (!existsSync(wranglerPath)) {\n throw new Error('No wrangler.toml found. Are you in a DeepSpace app directory?')\n }\n const parsed = parseToml(readFileSync(wranglerPath, 'utf-8')) as { name?: string }\n if (!parsed.name) {\n throw new Error('wrangler.toml has no `name` field')\n }\n return parsed.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({ 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 * Write .dev.vars for an app, pointing to the specified environment's workers.\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 env: EnvName,\n ownerId: string,\n callerJwt: string,\n): Promise<void> {\n const urls = ENVS[env]\n const publicKey = await fetchPublicKey(urls.auth)\n const appName = readAppName(appDir)\n const appOwnerJwt = await mintAppOwnerJwt(urls.auth, callerJwt, appName)\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 devVars = [\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 `INTERNAL_STORAGE_HMAC_SECRET=dev-${Date.now()}`,\n // Open /api/debug/* (proxied to RecordRoom) for dev + tests only.\n // Production secrets never set this, so deployed apps 404 the route.\n `ALLOW_DEBUG_ROUTES=true`,\n ].join('\\n')\n\n writeFileSync(join(appDir, '.dev.vars'), devVars + '\\n')\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 * 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 { ENVS } from '../env'\nimport { SESSION_COOKIE } from '../session'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? ENVS.prod.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 [--prod] [--port N]\n *\n * Starts local development:\n * 1. Ensures you're logged in\n * 2. Writes .dev.vars pointing to dev or prod workers\n * 3. Starts vite dev (Cloudflare Vite plugin runs the worker in-process)\n *\n * deepspace dev # uses dev workers, port 5173 (strict)\n * deepspace dev --prod # uses production workers\n * deepspace dev --port 5180 # bind to a different port (multi-app dev)\n *\n * Port is `--port` > $DEEPSPACE_PORT > 5173. We always pass --strictPort to\n * vite so a busy port fails loudly instead of silently jumping to 5174 (which\n * would diverge from anything Playwright/test config is expecting).\n */\n\nimport { defineCommand } from 'citty'\nimport { existsSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport { spawn } from 'node:child_process'\nimport { ensureToken } from '../auth'\nimport { writeDevVars } from '../env'\n\nconst DEFAULT_PORT = 5173\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 prod: {\n type: 'boolean',\n description: 'Use production workers (real auth, real API calls)',\n default: 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 const appDir = resolve(args.dir ?? '.')\n const env = args.prod ? 'prod' : 'dev'\n const port = resolvePort(args.port)\n\n if (!existsSync(join(appDir, 'wrangler.toml'))) {\n console.error('No wrangler.toml found. Are you in a DeepSpace app directory?')\n process.exit(1)\n }\n\n let token: string\n try {\n token = await ensureToken()\n } catch (err: any) {\n console.error(err.message)\n process.exit(1)\n }\n\n let payload: { sub: string; name?: string; email?: string }\n try {\n payload = JSON.parse(atob(token.split('.')[1]))\n } catch {\n console.error('Malformed session token. Run `npx deepspace login`.')\n process.exit(1)\n }\n console.log(`Logged in as ${payload.name ?? payload.email}`)\n console.log(`Environment: ${env}`)\n console.log(`Port: ${port}`)\n\n await writeDevVars(appDir, env, payload.sub, token)\n console.log('Starting dev server...\\n')\n\n const vite = spawn(\n 'npx',\n ['vite', '--port', String(port), '--strictPort'],\n {\n cwd: appDir,\n stdio: 'inherit',\n shell: process.platform === 'win32',\n env: { ...process.env, DEEPSPACE_PORT: String(port) },\n },\n )\n process.on('SIGINT', () => vite.kill())\n process.on('SIGTERM', () => vite.kill())\n vite.on('close', (code) => process.exit(code ?? 0))\n },\n})\n\nfunction 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 * 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 { ENVS } from './env'\nimport { exchangeSession } from './session'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? ENVS.prod.auth\n\nconst DIR = join(homedir(), '.deepspace')\nexport const SESSION_PATH = join(DIR, 'session')\nconst 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 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 // 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 // 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 })\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 = JSON.parse(atob(jwt.split('.')[1]))\n return payload.exp * 1000 > Date.now() + 30_000\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. The chosen port is exported as\n * DEEPSPACE_PORT to the Playwright child so the config + webServer both bind\n * to the same address. Pass a different port per app to run multiple apps\n * (and test suites) in parallel.\n */\n\nimport { defineCommand } from 'citty'\nimport { existsSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\nimport { execSync, spawnSync } from 'node:child_process'\nimport { ensureToken } from '../auth'\nimport { writeDevVars } from '../env'\n\nconst DEFAULT_PORT = 5173\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 },\n async run({ args }) {\n const appDir = resolve('.')\n const suite = args.suite ?? 'default'\n const port = resolvePort(args.port)\n\n if (!existsSync(join(appDir, 'wrangler.toml'))) {\n console.error('No wrangler.toml found. Are you in a DeepSpace app directory?')\n process.exit(1)\n }\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 = JSON.parse(atob(token.split('.')[1]))\n ownerId = payload.sub\n } catch (err) {\n console.error('`deepspace test` requires you to be logged in. Run `deepspace login` first.')\n process.exit(1)\n }\n\n await writeDevVars(appDir, 'dev', ownerId, token)\n\n if (suite !== 'unit') {\n ensurePlaywright(appDir)\n }\n\n let exitCode = 0\n\n switch (suite) {\n case 'smoke':\n exitCode = runPlaywright(appDir, ['tests/smoke.spec.ts'], port)\n break\n case 'api':\n exitCode = runPlaywright(appDir, ['tests/api.spec.ts'], port)\n break\n case 'e2e':\n exitCode = runPlaywright(appDir, [], port)\n break\n case 'unit':\n exitCode = runVitest(appDir)\n break\n case 'all':\n exitCode = runVitest(appDir)\n if (exitCode === 0) exitCode = runPlaywright(appDir, [], port)\n break\n case 'default':\n exitCode = runPlaywright(appDir, ['tests/smoke.spec.ts', 'tests/api.spec.ts'], port)\n break\n default:\n if (suite.endsWith('.spec.ts')) {\n exitCode = runPlaywright(appDir, [suite], port)\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(appDir: string, testFiles: string[], port: number): number {\n const result = spawnSync('npx', [\n 'playwright', 'test',\n '--config', 'tests/playwright.config.ts',\n ...testFiles,\n ], {\n cwd: appDir,\n stdio: 'inherit',\n shell: process.platform === 'win32',\n env: { ...process.env, DEEPSPACE_PORT: String(port) },\n })\n return result.status ?? 1\n}\n\nfunction runVitest(appDir: string): number {\n const result = spawnSync('npx', ['vitest', 'run', '--passWithNoTests'], {\n cwd: appDir, stdio: 'inherit', shell: process.platform === 'win32',\n })\n return result.status ?? 1\n}\n\nfunction ensurePlaywright(appDir: string) {\n try {\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 try {\n execSync('npx playwright install --dry-run chromium', { cwd: appDir, stdio: 'pipe' })\n } catch {\n console.log('Installing Chromium for Playwright...')\n execSync('npx playwright install chromium', { cwd: appDir, stdio: 'inherit' })\n }\n}\n\nfunction 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 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 { ENVS } from '../env'\n\nconst SESSION_COOKIE = '__Secure-better-auth.session_token'\n\nconst AUTH_URL = process.env.DEEPSPACE_AUTH_URL ?? ENVS.prod.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 { id: string; email: string; userId: string; label: string | null; createdAt: number }\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('No test accounts. Create one with: deepspace test-accounts create --email <email> --password <password>')\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 let 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\n ? remote.filter((a) => a.label === args.label)\n : 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 { readFileSync, readdirSync, existsSync } from 'node:fs'\nimport { parse as parseToml } from 'smol-toml'\nimport { join, resolve, dirname } from 'node:path'\nimport * as p from '@clack/prompts'\nimport { ensureToken } from '../auth'\nimport { ENVS } from '../env'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? ENVS.prod.deploy\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 },\n async run({ args }) {\n const appDir = resolve(args.dir ?? '.')\n p.intro('Deploying DeepSpace app')\n\n // ── Read app name from wrangler.toml ──────────────────────\n const wranglerPath = join(appDir, 'wrangler.toml')\n if (!existsSync(wranglerPath)) {\n p.cancel('No wrangler.toml found. Are you in a DeepSpace app directory?')\n process.exit(1)\n }\n\n const wranglerConfig = parseToml(readFileSync(wranglerPath, 'utf-8')) as { name?: string }\n const appName = wranglerConfig.name\n if (!appName) {\n p.cancel('Could not find app name in wrangler.toml')\n process.exit(1)\n }\n p.log.info(`App: ${appName}`)\n\n // ── Ensure valid JWT ───────────────────────────────────────\n let token: string\n try {\n token = await ensureToken()\n } catch (err: any) {\n p.cancel(err.message)\n process.exit(1)\n }\n\n // ── Build with Vite (Cloudflare plugin bundles client + worker) ──\n const s = p.spinner()\n s.start('Building...')\n try {\n execSync('npx vite build', { cwd: appDir, stdio: 'pipe' })\n } catch (err: any) {\n s.stop('Build failed')\n console.error(err.stderr?.toString() ?? err.message)\n process.exit(1)\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 { configPath: string }\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 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 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 Array<{ name: string; class_name: string }> | undefined\n const sqliteClasses = new Set(\n (outputConfig.migrations as Array<{ new_sqlite_classes?: string[] }> | undefined)\n ?.flatMap(m => m.new_sqlite_classes ?? []) ?? []\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 // ── Upload to deploy worker ───────────────────────────────\n s.start(`Deploying to ${appName}.app.space...`)\n\n const form = new FormData()\n form.append('worker', new Blob([workerJs], { type: 'application/javascript' }), 'worker.js')\n form.append('assets', JSON.stringify(assets))\n if (doManifest) {\n form.append('doManifest', JSON.stringify(doManifest))\n }\n\n const res = await fetch(`${DEPLOY_URL}/api/deploy/${appName}`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${token}` },\n body: form,\n })\n\n const body = (await res.json().catch(() => ({}))) as {\n success?: boolean\n url?: string\n error?: string\n }\n\n if (!res.ok || !body.success) {\n s.stop('Deploy failed')\n p.cancel(body.error ?? `Deployment error (${res.status})`)\n process.exit(1)\n }\n\n s.stop('Deployed!')\n p.log.success(`Live at: ${body.url}`)\n p.outro('Done')\n },\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 { readFileSync, existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { parse as parseToml } from 'smol-toml'\nimport * as p from '@clack/prompts'\nimport { ensureToken } from '../auth'\n\nimport { ENVS } from '../env'\n\nconst DEPLOY_URL = process.env.DEEPSPACE_DEPLOY_URL ?? ENVS.prod.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 name to undeploy (reads from wrangler.toml if omitted)',\n required: false,\n },\n },\n async run({ args }) {\n let appName = args.name\n\n // If no name given, try to read from wrangler.toml in cwd\n if (!appName) {\n const wranglerPath = join(process.cwd(), 'wrangler.toml')\n if (existsSync(wranglerPath)) {\n const config = parseToml(readFileSync(wranglerPath, 'utf-8')) as { name?: string }\n if (config.name) appName = config.name\n }\n }\n\n if (!appName) {\n p.cancel('Provide an app name or run from a DeepSpace app directory.')\n process.exit(1)\n }\n\n let token: string\n try {\n token = await ensureToken()\n } catch (err: any) {\n p.cancel(err.message)\n process.exit(1)\n }\n\n p.intro(`Undeploying ${appName}`)\n const s = p.spinner()\n s.start('Removing...')\n\n const res = await fetch(`${DEPLOY_URL}/api/deploy/${appName}`, {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${token}` },\n })\n\n const body = (await res.json().catch(() => ({}))) as { success?: boolean; error?: string }\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 p.outro(`${appName}.app.space has been taken down`)\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'\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 let jwt: string\n try {\n jwt = await ensureToken()\n } catch (err: any) {\n console.error(err.message ?? 'Not signed in. Run `deepspace login`.')\n process.exit(1)\n }\n\n let payload: JwtPayload\n try {\n payload = JSON.parse(atob(jwt.split('.')[1]))\n } catch {\n console.error('Malformed session token. Run `deepspace login` again.')\n process.exit(1)\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 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 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 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 } from 'node:fs'\nimport { resolve, join } from 'node:path'\nimport { execSync } from 'node:child_process'\n\nfunction findScript(from: string): string | null {\n const candidate = join(from, '.deepspace', 'scripts', 'add-feature.cjs')\n if (existsSync(candidate)) return candidate\n return null\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 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 const script = findScript(appDir)\n\n if (!script) {\n console.error('No .deepspace/scripts/add-feature.cjs found.')\n console.error('Are you in a DeepSpace app directory?')\n process.exit(1)\n }\n\n const passArgs: string[] = []\n\n if (args.list) {\n passArgs.push('--list')\n } else if (args.info) {\n passArgs.push('--info', args.info)\n } else if (args.feature) {\n passArgs.push(args.feature, appDir)\n } else {\n passArgs.push('--help')\n }\n\n execSync(`node ${JSON.stringify(script)} ${passArgs.map(a => JSON.stringify(a)).join(' ')}`, {\n stdio: 'inherit',\n cwd: appDir,\n })\n },\n})\n"],"mappings":"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","names":["defineCommand","execSync","writeFileSync","join","join","writeFileSync","resolve","defineCommand","existsSync","readFileSync","join","homedir","AUTH_URL","join","homedir","defineCommand","existsSync","readFileSync","defineCommand","existsSync","join","readFileSync","writeFileSync","existsSync","mkdirSync","join","homedir","AUTH_URL","DIR","join","homedir","SESSION_PATH","TOKEN_PATH","existsSync","readFileSync","mkdirSync","writeFileSync","defineCommand","existsSync","join","defineCommand","existsSync","join","resolve","DEFAULT_PORT","defineCommand","resolve","resolvePort","existsSync","join","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","existsSync","parseToml","join","resolve","p","defineCommand","resolve","join","existsSync","parseToml","readFileSync","execSync","defineCommand","readFileSync","existsSync","join","parseToml","p","DEPLOY_URL","defineCommand","join","existsSync","parseToml","readFileSync","defineCommand","defineCommand","defineCommand","existsSync","resolve","join","execSync","create","defineCommand","execSync"]}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepspace",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "DeepSpace SDK — build real-time collaborative apps on Cloudflare Workers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"bin": {
|
|
9
|
-
"deepspace": "
|
|
9
|
+
"deepspace": "dist/cli.js"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|