@dmrlzz/davecode 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +1 -0
  2. package/dist/{ChatApp-IF5D7XNH.js → ChatApp-RQZ2IZFQ.js} +6 -6
  3. package/dist/{account-KBXJ5KR7.js → account-FY6THFLW.js} +3 -3
  4. package/dist/{accounts-XUJNDCFH.js → accounts-ZV3KMLC5.js} +5 -5
  5. package/dist/{budget-PHV4NRUS.js → budget-OUOEMMOM.js} +4 -4
  6. package/dist/{chat-HGTX76DU.js → chat-OHVP4BS3.js} +8 -8
  7. package/dist/{chunk-AFCQURO5.js → chunk-2MM5WT5J.js} +3 -3
  8. package/dist/{chunk-EBV5A33R.js → chunk-2P5DJWIJ.js} +4 -4
  9. package/dist/{chunk-ING5HCIO.js → chunk-2XGDILCW.js} +1677 -133
  10. package/dist/chunk-2XGDILCW.js.map +1 -0
  11. package/dist/{chunk-FZJNOG2T.js → chunk-FFB2QA5I.js} +2 -2
  12. package/dist/{goal-ETZWLVKO.js → chunk-HL4RIXPM.js} +8 -8
  13. package/dist/chunk-HL4RIXPM.js.map +1 -0
  14. package/dist/{chunk-FPSLYBLU.js → chunk-L7NEDOA3.js} +2 -2
  15. package/dist/{chunk-DFQW3MRD.js → chunk-NKRI6SYR.js} +2 -2
  16. package/dist/{chunk-YSD6W27K.js → chunk-TP3ORSHY.js} +134 -4
  17. package/dist/chunk-TP3ORSHY.js.map +1 -0
  18. package/dist/{chunk-ZVNX7CSO.js → chunk-U5CI774J.js} +3 -3
  19. package/dist/{config-DG2E4VDW.js → config-ZLO3YOUX.js} +3 -3
  20. package/dist/dashboard/assets/Accounts-CIhOt9FH.js +1 -0
  21. package/dist/dashboard/assets/{Callout-1E8Wsl9W.js → Callout-CqdcH6dC.js} +1 -1
  22. package/dist/dashboard/assets/Goals-CITP2GqG.js +1 -0
  23. package/dist/dashboard/assets/{Library-DZxBVUo_.js → Library-DnCIb76j.js} +1 -1
  24. package/dist/dashboard/assets/{Panes-C-TJekjs.js → Panes-DBqKYuaE.js} +3 -3
  25. package/dist/dashboard/assets/RoutesPage-BNVmKhyU.js +4 -0
  26. package/dist/dashboard/assets/Runner-KR35ZWUE.js +1 -0
  27. package/dist/dashboard/assets/Settings-B5qE-a5O.js +1 -0
  28. package/dist/dashboard/assets/Tasks-bJLfNJmS.js +2 -0
  29. package/dist/dashboard/assets/Traffic-CGfilrRx.js +1 -0
  30. package/dist/dashboard/assets/Workspace-Dc3cvct_.js +1 -0
  31. package/dist/dashboard/assets/format-328qIBHX.js +111 -0
  32. package/dist/dashboard/assets/index-C-bwzlsl.js +50 -0
  33. package/dist/dashboard/assets/index-D9FCfPmM.css +2 -0
  34. package/dist/dashboard/assets/task-errors-DK4-900l.js +1 -0
  35. package/dist/dashboard/index.html +3 -3
  36. package/dist/{dist-IPMBGFJD.js → dist-56V3DLJ4.js} +16 -2
  37. package/dist/{doctor-5APOWJ5D.js → doctor-DUOKUSJL.js} +3 -3
  38. package/dist/goal-WG37XHUY.js +26 -0
  39. package/dist/index.js +64 -31
  40. package/dist/index.js.map +1 -1
  41. package/dist/{init-YDLNA3GD.js → init-WW4XPFMM.js} +3 -3
  42. package/dist/orchestrate-7YQDBS3E.js +382 -0
  43. package/dist/orchestrate-7YQDBS3E.js.map +1 -0
  44. package/dist/{run-I6N7TLHV.js → run-QB4SGPEC.js} +3 -3
  45. package/dist/runtime.js +6 -2
  46. package/dist/{start-ECLELJGJ.js → start-U4RL377T.js} +3 -3
  47. package/dist/{status-QQPP67I4.js → status-GHVMGZI5.js} +4 -4
  48. package/dist/status-GHVMGZI5.js.map +1 -0
  49. package/dist/{tasks-RNMC2XFN.js → tasks-VTBJ4B2G.js} +4 -4
  50. package/package.json +4 -4
  51. package/dist/chunk-ING5HCIO.js.map +0 -1
  52. package/dist/chunk-YSD6W27K.js.map +0 -1
  53. package/dist/dashboard/assets/Accounts-DXiGsutB.js +0 -1
  54. package/dist/dashboard/assets/Badge-DUGKlx3Z.js +0 -55
  55. package/dist/dashboard/assets/Goals-kL4VAxw3.js +0 -1
  56. package/dist/dashboard/assets/RoutesPage-DWYm9tW8.js +0 -4
  57. package/dist/dashboard/assets/Runner-CmHBjECR.js +0 -1
  58. package/dist/dashboard/assets/Settings-BANphxva.js +0 -1
  59. package/dist/dashboard/assets/Tasks-cSx1PKyQ.js +0 -2
  60. package/dist/dashboard/assets/Traffic-DEAuM6jq.js +0 -1
  61. package/dist/dashboard/assets/Workspace-BQFjc1jH.js +0 -1
  62. package/dist/dashboard/assets/index-B8kld9xo.js +0 -104
  63. package/dist/dashboard/assets/index-BEmBgsbP.css +0 -2
  64. package/dist/dashboard/assets/task-errors-r-WYZ_S3.js +0 -1
  65. package/dist/goal-ETZWLVKO.js.map +0 -1
  66. /package/dist/{ChatApp-IF5D7XNH.js.map → ChatApp-RQZ2IZFQ.js.map} +0 -0
  67. /package/dist/{account-KBXJ5KR7.js.map → account-FY6THFLW.js.map} +0 -0
  68. /package/dist/{accounts-XUJNDCFH.js.map → accounts-ZV3KMLC5.js.map} +0 -0
  69. /package/dist/{budget-PHV4NRUS.js.map → budget-OUOEMMOM.js.map} +0 -0
  70. /package/dist/{chat-HGTX76DU.js.map → chat-OHVP4BS3.js.map} +0 -0
  71. /package/dist/{chunk-AFCQURO5.js.map → chunk-2MM5WT5J.js.map} +0 -0
  72. /package/dist/{chunk-EBV5A33R.js.map → chunk-2P5DJWIJ.js.map} +0 -0
  73. /package/dist/{chunk-FZJNOG2T.js.map → chunk-FFB2QA5I.js.map} +0 -0
  74. /package/dist/{chunk-FPSLYBLU.js.map → chunk-L7NEDOA3.js.map} +0 -0
  75. /package/dist/{chunk-DFQW3MRD.js.map → chunk-NKRI6SYR.js.map} +0 -0
  76. /package/dist/{chunk-ZVNX7CSO.js.map → chunk-U5CI774J.js.map} +0 -0
  77. /package/dist/{config-DG2E4VDW.js.map → config-ZLO3YOUX.js.map} +0 -0
  78. /package/dist/{dist-IPMBGFJD.js.map → dist-56V3DLJ4.js.map} +0 -0
  79. /package/dist/{doctor-5APOWJ5D.js.map → doctor-DUOKUSJL.js.map} +0 -0
  80. /package/dist/{status-QQPP67I4.js.map → goal-WG37XHUY.js.map} +0 -0
  81. /package/dist/{init-YDLNA3GD.js.map → init-WW4XPFMM.js.map} +0 -0
  82. /package/dist/{run-I6N7TLHV.js.map → run-QB4SGPEC.js.map} +0 -0
  83. /package/dist/{start-ECLELJGJ.js.map → start-U4RL377T.js.map} +0 -0
  84. /package/dist/{tasks-RNMC2XFN.js.map → tasks-VTBJ4B2G.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime.ts","../../server/src/errors.ts","../../server/src/gateway.ts","../../server/src/routes/account.ts","../../server/src/routes/api.ts","../../server/src/schemas.ts","../../server/src/routes/goals.ts","../../server/src/routes/tasks.ts","../../server/src/routes/auth.ts","../../server/src/routes/events.ts","../../server/src/routes/orchestrator.ts","../../server/src/routes/v1.ts","../src/sse.ts","../src/client.ts","../src/lib/terminal.ts","../src/lib/proc.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { access } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport type { AddressInfo } from 'node:net';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n type Account,\n type AccountControl,\n type AutonomousRunner,\n createAccountControl,\n createCliAgentRunner,\n createEngine,\n createGitWorkspace,\n createGoalService,\n createOrchestratorService,\n createRunner,\n type DaveConfigInput,\n type Engine,\n type EventBus,\n type GoalService,\n type OrchestratorService,\n ProjectBrain,\n ProjectBrainSource,\n WorkspaceLock,\n} from '@davecode/core';\nimport { type GatewayOptions, type ProjectInfo, startGateway } from '@davecode/server';\nimport { connectHost } from './client';\nimport { openBrowser } from './lib/browser';\nimport { launchLoginTerminal } from './lib/terminal';\n\nexport { launchLoginTerminal } from './lib/terminal';\n\nconst LOOPBACK_HOSTS = new Set(['127.0.0.1', '::1', 'localhost']);\n\n/**\n * Process wiring shared by `davecode start`, `chat` (in-process gateway) and `run`:\n * engine + project brain + autonomous runner + gateway.\n */\n\n// ---------------------------------------------------------------------------\n// Project discovery\n// ---------------------------------------------------------------------------\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Walk up from `startDir` to the first directory with `.davecode/` or `.git`. Unlike\n * `findProjectRoot` from core, a `.davecode` directory that is the DaveCode home itself\n * (`~/.davecode`) never marks a project, so running in `~/code/foo` cannot adopt `~`.\n */\nexport async function detectProjectRoot(\n startDir: string,\n home: string,\n): Promise<string | undefined> {\n const homeDir = resolve(home);\n let dir = resolve(startDir);\n for (;;) {\n const brainDir = join(dir, '.davecode');\n if (await exists(join(dir, '.git'))) return dir;\n if (resolve(brainDir) !== homeDir && (await exists(brainDir))) return dir;\n const parent = dirname(dir);\n if (parent === dir) return undefined;\n dir = parent;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Project brain + runner\n// ---------------------------------------------------------------------------\n\nexport interface ProjectWiring {\n brain: ProjectBrain;\n /** Read-only view for `/api/tasks` and `/api/brain` (missing files read as empty). */\n source: ProjectBrainSource;\n /** The Phase 4 autonomous runner for this repository; satisfies `RunnerControl`. */\n runner: AutonomousRunner;\n /** Goal mode for this repository; satisfies `GoalControl`. */\n goals: GoalService;\n /** Held by the runner (`runner`) or goal mode (`goal`) while they touch the working tree. */\n lock: WorkspaceLock;\n}\n\n/**\n * Open the project brain of `root` on the engine's event bus and build its autonomous runner\n * and goal service, which share one workspace lock. The runner is created even before\n * `davecode init`: `start()`/`runOnce()` then reject with a `RunnerError` (`no_brain`,\n * `not_a_repo`...) that the CLI and the dashboard explain.\n */\nexport function wireProject(\n engine: Engine,\n root: string,\n options: { env?: NodeJS.ProcessEnv; name?: string } = {},\n): ProjectWiring {\n const brain = new ProjectBrain(root, { events: engine.events });\n const lock = new WorkspaceLock();\n const budgetContext = () => engine.budget.context();\n return {\n brain,\n source: new ProjectBrainSource(brain, options.name),\n runner: createRunner(engine, {\n brain,\n lock: { lock, owner: 'runner' },\n contextExtras: budgetContext,\n ...(options.env ? { env: options.env } : {}),\n }),\n goals: createGoalService(engine, { brain, lock, budgetContext }),\n lock,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Pane orchestrator\n// ---------------------------------------------------------------------------\n\n/**\n * Where the orchestrator keeps the task worktrees of `projectDir`: under the DaveCode home,\n * outside the repository, one folder per project (first 16 hex digits of its path's SHA-256).\n */\nexport function orchestratorWorktreesDir(home: string, projectDir: string): string {\n const key = createHash('sha256').update(resolve(projectDir)).digest('hex').slice(0, 16);\n return join(home, 'worktrees', key);\n}\n\n/**\n * The pane orchestrator for `projectDir`: headless vendor CLIs (with the user's own sign-in,\n * from `env`) working in git worktrees, reporting on `events`. Throws if it cannot be built.\n */\nexport function createProjectOrchestrator(options: {\n projectDir: string;\n home: string;\n env: NodeJS.ProcessEnv;\n events: EventBus;\n}): OrchestratorService {\n const projectDir = resolve(options.projectDir);\n return createOrchestratorService({\n projectDir,\n home: options.home,\n events: options.events,\n runner: createCliAgentRunner({ env: options.env }),\n workspace: createGitWorkspace({\n projectDir,\n worktreesDir: orchestratorWorktreesDir(options.home, projectDir),\n }),\n });\n}\n\n// ---------------------------------------------------------------------------\n// Dashboard\n// ---------------------------------------------------------------------------\n\nfunction isDashboard(dir: string | undefined): dir is string {\n return dir !== undefined && existsSync(join(dir, 'index.html'));\n}\n\n/**\n * Locate the built dashboard (`index.html` inside), in order: `DAVECODE_DASHBOARD_DIR`, a\n * `dashboard/` folder shipped next to this bundle, the monorepo layout (`packages/ui/dist`, which\n * resolves the same from `packages/cli/dist/*.js` and `packages/cli/src/runtime.ts`) and finally\n * an installed `@davecode/ui` package's `dist/` (`lookupPackage: false` skips that step).\n */\nexport function resolveDashboardDir(\n env: NodeJS.ProcessEnv = process.env,\n moduleUrl: string = import.meta.url,\n lookupPackage = true,\n): string | undefined {\n const candidates: Array<() => string | undefined> = [\n () => (env.DAVECODE_DASHBOARD_DIR ? resolve(env.DAVECODE_DASHBOARD_DIR) : undefined),\n () => fileURLToPath(new URL('./dashboard', moduleUrl)),\n () => fileURLToPath(new URL('../../ui/dist', moduleUrl)),\n () => {\n if (!lookupPackage) return undefined;\n try {\n const pkg = createRequire(moduleUrl).resolve('@davecode/ui/package.json');\n return join(dirname(pkg), 'dist');\n } catch {\n return undefined;\n }\n },\n ];\n for (const candidate of candidates) {\n const dir = candidate();\n if (isDashboard(dir)) return dir;\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime\n// ---------------------------------------------------------------------------\n\nexport interface RuntimeOptions {\n home: string;\n env: NodeJS.ProcessEnv;\n cwd: string;\n /** Repository to serve the project brain for (default: detected from `cwd`). */\n projectDir?: string;\n /** Skip project detection entirely (no brain, no runner). */\n noProject?: boolean;\n host?: string;\n /** `0` picks a free port. */\n port?: number;\n /** Serve the dashboard when it is built (default true, and `server.dashboard` must be on). */\n dashboard?: boolean;\n logger?: GatewayOptions['logger'];\n /** Desktop hosts can launch official sign-in using their bundled CLI and Node runtime. */\n loginLauncher?: GatewayOptions['loginLauncher'];\n /** Programmatic config overrides. */\n config?: DaveConfigInput;\n /** Inject a pre-built engine (tests). It is closed with the runtime. */\n engine?: Engine;\n /**\n * Pane orchestrator to serve (closed with the runtime), or false for none. By default one is\n * built for the project when the gateway binds to loopback.\n */\n orchestrator?: OrchestratorService | false;\n /** Non-fatal startup problems (default: only a `log` event on the engine's bus). */\n onWarning?: (message: string) => void;\n}\n\nexport interface Runtime {\n engine: Engine;\n brain: ProjectBrain | undefined;\n project: ProjectInfo | undefined;\n runner: AutonomousRunner | undefined;\n goals: GoalService | undefined;\n /** The pane orchestrator, when this runtime serves one. */\n orchestrator: OrchestratorService | undefined;\n /** Address to connect to, e.g. `http://127.0.0.1:4040`. */\n url: string;\n host: string;\n port: number;\n /** Absolute dashboard directory when it is being served. */\n dashboardDir: string | undefined;\n /** Stop the runner (safely parking any task), the gateway and the engine. */\n close(): Promise<void>;\n}\n\n/** Resolve the project root for `projectDir` (relative to `cwd`) or detect it from `cwd`. */\nexport async function resolveProjectRoot(\n options: Pick<RuntimeOptions, 'cwd' | 'home' | 'projectDir' | 'noProject'>,\n): Promise<string | undefined> {\n if (options.noProject) return undefined;\n return options.projectDir\n ? resolve(options.cwd, options.projectDir)\n : detectProjectRoot(options.cwd, options.home);\n}\n\n/** Create the engine, open the project brain and runner, and start the gateway. */\nexport async function startRuntime(options: RuntimeOptions): Promise<Runtime> {\n const projectRoot = await resolveProjectRoot(options);\n const engine =\n options.engine ??\n createEngine({\n home: options.home,\n env: options.env,\n ...(projectRoot ? { projectRoot } : {}),\n ...(options.config ? { config: options.config } : {}),\n });\n let account: AccountControl | undefined;\n let orchestrator: OrchestratorService | undefined;\n\n try {\n const project = projectRoot\n ? wireProject(engine, projectRoot, { env: options.env })\n : undefined;\n const wantDashboard = options.dashboard !== false && engine.config.server.dashboard;\n const dashboardDir = wantDashboard ? resolveDashboardDir(options.env) : undefined;\n const bindHost = options.host ?? engine.config.server.host;\n // Only a gateway on loopback shares a screen with its user; elsewhere a login window\n // would open on a machine nobody is looking at.\n const loginLauncher = LOOPBACK_HOSTS.has(bindHost)\n ? {\n launch: async (account: Account) => ({\n launched: await launchLoginTerminal(account.id, { env: options.env }),\n }),\n }\n : undefined;\n\n // Same rule for the DaveCode account: the browser must open where the user is sitting.\n account = LOOPBACK_HOSTS.has(bindHost)\n ? createAccountControl({\n home: options.home,\n env: options.env,\n open: (url) => openBrowser(url),\n })\n : undefined;\n\n // Same rule again: the orchestrator drives the CLIs signed in on this machine. A failure to\n // build it never takes the gateway down; the routes are simply absent.\n if (options.orchestrator !== undefined) {\n orchestrator = options.orchestrator || undefined;\n } else if (projectRoot && LOOPBACK_HOSTS.has(bindHost)) {\n try {\n orchestrator = createProjectOrchestrator({\n projectDir: projectRoot,\n home: options.home,\n env: options.env,\n events: engine.events,\n });\n } catch {\n // The error may carry paths or vendor output: report that it failed, not why.\n const message = 'The pane orchestrator could not start; continuing without it.';\n engine.events.emit({ type: 'log', level: 'warn', scope: 'orchestrator', message });\n options.onWarning?.(message);\n }\n }\n\n const app = await startGateway(engine, {\n logger: options.logger ?? false,\n ...(account ? { account } : {}),\n ...(orchestrator ? { orchestrator } : {}),\n ...((options.loginLauncher ?? loginLauncher)\n ? { loginLauncher: options.loginLauncher ?? loginLauncher }\n : {}),\n ...(dashboardDir ? { dashboardDir } : {}),\n ...(project ? { brain: project.source, runner: project.runner, goals: project.goals } : {}),\n ...(options.host !== undefined ? { host: options.host } : {}),\n ...(options.port !== undefined ? { port: options.port } : {}),\n });\n\n const address = app.server.address() as AddressInfo | null;\n const host = options.host ?? engine.config.server.host;\n const port = address?.port ?? options.port ?? engine.config.server.port;\n\n let closed = false;\n const runner = project?.runner;\n const goals = project?.goals;\n return {\n engine,\n brain: project?.brain,\n project: project?.source.project(),\n runner,\n goals,\n orchestrator,\n url: `http://${connectHost(host)}:${port}`,\n host,\n port,\n dashboardDir,\n async close() {\n if (closed) return;\n closed = true;\n try {\n const active = goals?.activeGoalId;\n if (active) await goals?.cancel(active);\n await runner?.stop();\n await orchestrator?.close().catch(() => undefined);\n await account?.close();\n await app.close();\n } finally {\n engine.close();\n }\n },\n };\n } catch (err) {\n await orchestrator?.close().catch(() => undefined);\n await account?.close();\n engine.close();\n throw err;\n }\n}\n","import { ProviderError, RouterError } from '@davecode/core';\nimport type { FastifyReply } from 'fastify';\n\n/** `/api/*` error envelope. */\nexport function sendApiError(\n reply: FastifyReply,\n status: number,\n code: string,\n message: string,\n extra: Record<string, unknown> = {},\n): FastifyReply {\n return reply.code(status).send({ error: { message, code, ...extra } });\n}\n\n/** OpenAI-compatible error body used on `/v1/*` (also inside SSE error frames). */\nexport interface OpenAIErrorBody {\n message: string;\n type: string;\n code: string | null;\n}\n\nexport function sendOpenAIError(\n reply: FastifyReply,\n status: number,\n body: OpenAIErrorBody,\n): FastifyReply {\n return reply.code(status).send({ error: body });\n}\n\nfunction openAIType(status: number): string {\n if (status === 401) return 'authentication_error';\n if (status === 404 || status === 400 || status === 422) return 'invalid_request_error';\n if (status === 429) return 'rate_limit_error';\n return 'api_error';\n}\n\n/** Map a routing failure to an HTTP status and OpenAI error body. */\nexport function describeRoutingError(err: unknown): { status: number; body: OpenAIErrorBody } {\n if (err instanceof RouterError) {\n return {\n status: err.status,\n body: { message: err.message, type: openAIType(err.status), code: err.code },\n };\n }\n if (err instanceof ProviderError) {\n let status: number;\n let code: string = err.kind;\n switch (err.kind) {\n case 'bad_request':\n status = 400;\n break;\n case 'context_length':\n status = 400;\n code = 'context_length_exceeded';\n break;\n case 'rate_limit':\n case 'quota_exhausted':\n status = 429;\n break;\n case 'auth':\n // The client's request is fine; DaveCode's upstream credentials are not.\n status = 502;\n code = 'upstream_auth_error';\n break;\n default:\n status = 502;\n }\n return { status, body: { message: err.message, type: openAIType(status), code } };\n }\n return {\n status: 500,\n body: { message: 'Internal gateway error', type: 'api_error', code: 'internal_error' },\n };\n}\n","import { timingSafeEqual } from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { type Engine, loginFromEnv } from '@davecode/core';\nimport cors from '@fastify/cors';\nimport fastifyStatic from '@fastify/static';\nimport Fastify, { type FastifyInstance, type FastifyRequest } from 'fastify';\nimport { sendApiError, sendOpenAIError } from './errors';\nimport type { GatewayOptions, StartGatewayOptions } from './options';\nimport { registerAccountRoutes } from './routes/account';\nimport { registerApiRoutes } from './routes/api';\nimport { authCookie, registerAuthRoutes } from './routes/auth';\nimport { registerEventRoutes } from './routes/events';\nimport { registerOrchestratorRoutes } from './routes/orchestrator';\nimport { registerV1Routes } from './routes/v1';\n\n/** Origins allowed to call the gateway from a browser (the Vite dev server). */\nexport const DEFAULT_CORS_ORIGINS = ['http://localhost:5173', 'http://127.0.0.1:5173'];\n\nconst EXPOSED_HEADERS = [\n 'x-davecode-request-id',\n 'x-davecode-account',\n 'x-davecode-provider',\n 'x-davecode-failovers',\n];\n\ntype Surface = 'v1' | 'api' | 'other';\n\nfunction pathOf(url: string): string {\n const q = url.indexOf('?');\n return q === -1 ? url : url.slice(0, q);\n}\n\n/** Lower-cased, percent-decoded path. Used to pick an error envelope, never to skip a check. */\nfunction normalisedPath(url: string): string {\n const path = pathOf(url);\n try {\n return decodeURIComponent(path).toLowerCase();\n } catch {\n return path.toLowerCase();\n }\n}\n\nfunction surfaceOf(url: string): Surface {\n const path = normalisedPath(url);\n if (path === '/v1' || path.startsWith('/v1/')) return 'v1';\n if (path === '/api' || path.startsWith('/api/')) return 'api';\n return 'other';\n}\n\n/** Routes that never need a token: the login-mode routes. Matched by route pattern, not by URL. */\nconst PUBLIC_ROUTES = new Set([\n '/api/auth/session',\n '/api/auth/logout',\n '/api/auth/google/start',\n '/api/auth/google/callback',\n '/api/auth/github/start',\n '/api/auth/github/callback',\n]);\n\n/** Patterns under which the dashboard's static files are served (read-only GET/HEAD). */\nconst STATIC_ROUTES = new Set(['/', '/*']);\n\nconst SAFE_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']);\n\nfunction splitHost(header: string): { name: string; port: string } | undefined {\n const match = /^(\\[[0-9a-f:.]+\\]|[^:/\\\\@\\s]+)(?::(\\d{1,5}))?$/i.exec(header.trim());\n if (!match?.[1]) return undefined;\n return { name: match[1].toLowerCase(), port: match[2] ?? '' };\n}\n\nfunction originOf(value: string): string | undefined {\n try {\n const url = new URL(value);\n return url.origin === 'null' ? undefined : url.origin;\n } catch {\n return undefined;\n }\n}\n\n/** Hide `?token=` values from logs. */\nexport function redactUrl(url: string): string {\n return url.replace(/([?&](?:token|code|state|error_description)=)[^&]*/gi, '$1[redacted]');\n}\n\nfunction safeEqual(a: string, b: string): boolean {\n const left = Buffer.from(a);\n const right = Buffer.from(b);\n return left.length === right.length && timingSafeEqual(left, right);\n}\n\nfunction bearer(request: FastifyRequest): string | undefined {\n const header = request.headers.authorization;\n if (!header) return undefined;\n const match = /^Bearer\\s+(.+)$/i.exec(header.trim());\n return match?.[1];\n}\n\nfunction loggerOption(logger: GatewayOptions['logger']) {\n if (!logger) return false;\n return {\n ...(typeof logger === 'object' ? logger : {}),\n serializers: {\n req(req: FastifyRequest) {\n return { method: req.method, url: redactUrl(req.url), remoteAddress: req.ip };\n },\n },\n };\n}\n\n/**\n * Build the DaveCode gateway (OpenAI-compatible `/v1`, dashboard `/api`, SSE events and the\n * optional dashboard). The instance is not listening; use `app.inject()` or `startGateway()`.\n */\nexport async function buildGateway(\n engine: Engine,\n options: GatewayOptions = {},\n): Promise<FastifyInstance> {\n const app = Fastify({ logger: loggerOption(options.logger), bodyLimit: 10 * 1024 * 1024 });\n const login = options.login === false ? undefined : (options.login ?? loginFromEnv(process.env));\n if (login) app.addHook('onClose', async () => login.clear());\n\n const bindHost = (options.host ?? engine.config.server.host).toLowerCase();\n const loopbackBind = LOOPBACK.has(bindHost);\n // Origins that may call state-changing /api routes besides the gateway's own origin.\n const extraOrigins = [\n ...(options.dev ? DEFAULT_CORS_ORIGINS : []),\n ...(options.corsOrigins ?? []),\n ...(login ? [login.options.origin] : []),\n ]\n .map(originOf)\n .filter((origin): origin is string => origin !== undefined);\n const allowedOrigins = new Set(extraOrigins);\n // Hosts that are also expected when the gateway sits behind a proxy on a loopback bind.\n const extraHosts = new Set(\n [...(options.corsOrigins ?? []), ...(login ? [login.options.origin] : [])]\n .map(originOf)\n .filter((origin): origin is string => origin !== undefined)\n .map((origin) => new URL(origin).host.toLowerCase()),\n );\n\n function hostAllowed(request: FastifyRequest): boolean {\n // A gateway bound to a network address is reached by whatever name it was configured with.\n if (!loopbackBind) return true;\n const header = request.headers.host;\n if (!header) return false;\n if (extraHosts.has(header.toLowerCase())) return true;\n const parsed = splitHost(header);\n if (!parsed || !['127.0.0.1', 'localhost', '[::1]'].includes(parsed.name)) return false;\n const actual = request.raw.socket?.localPort;\n return actual === undefined || Number(parsed.port || 80) === actual;\n }\n\n function originAllowed(request: FastifyRequest): boolean {\n const origin = request.headers.origin;\n if (origin === undefined) return true;\n const normalised = originOf(origin);\n if (!normalised) return false;\n if (allowedOrigins.has(normalised)) return true;\n const host = request.headers.host?.toLowerCase();\n return host !== undefined && new URL(normalised).host.toLowerCase() === host;\n }\n\n // Runs first, after routing: which Host may be used, which Origin may change state, and\n // that state-changing /api requests declare a JSON body (a cross-site page cannot send that\n // without a preflight).\n app.addHook('onRequest', async (request, reply) => {\n // The matched route decides; the URL only picks an error format for unmatched requests.\n const surface = surfaceOf(request.routeOptions.url ?? request.url);\n const reject = (status: number, code: string, message: string) =>\n surface === 'v1'\n ? sendOpenAIError(reply, status, { message, type: 'invalid_request_error', code })\n : sendApiError(reply, status, code, message);\n if (!hostAllowed(request)) return reject(403, 'invalid_host', 'Unexpected Host header.');\n if (surface !== 'api' || SAFE_METHODS.has(request.method)) return;\n if (!originAllowed(request)) {\n return reject(403, 'invalid_origin', 'Requests from this origin are not allowed.');\n }\n if (PUBLIC_ROUTES.has(request.routeOptions.url ?? '')) return;\n // PUT, PATCH and DELETE always need a preflight cross-site; a POST can be sent without one.\n if (request.method !== 'POST') return;\n if (!request.headers['content-type']?.toLowerCase().startsWith('application/json')) {\n return reject(415, 'json_required', 'Send Content-Type: application/json');\n }\n });\n\n await app.register(cors, {\n origin: [...(options.dev ? DEFAULT_CORS_ORIGINS : []), ...(options.corsOrigins ?? [])],\n methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],\n allowedHeaders: ['content-type', 'authorization'],\n exposedHeaders: EXPOSED_HEADERS,\n });\n\n const token = engine.config.server.authToken;\n if (token || login) {\n // Deny by default: only the explicit public routes and the dashboard's static files skip\n // the check. The decision uses the matched route, not the raw URL text.\n app.addHook('onRequest', async (request, reply) => {\n if (request.method === 'OPTIONS') return;\n const route = request.routeOptions.url;\n if (route !== undefined) {\n if (PUBLIC_ROUTES.has(route)) return;\n if (STATIC_ROUTES.has(route) && (request.method === 'GET' || request.method === 'HEAD'))\n return;\n }\n const surface = surfaceOf(request.url);\n const isV1 = route === '/v1' || route?.startsWith('/v1/') || surface === 'v1';\n let provided = bearer(request);\n if (!provided && route === '/api/events') {\n const query = request.query as Record<string, unknown> | undefined;\n if (typeof query?.token === 'string') provided = query.token;\n }\n if (provided && token && safeEqual(provided, token)) return;\n if (!isV1 && login?.user(authCookie(request, 'dc_session'))) {\n if (\n !['GET', 'HEAD'].includes(request.method) &&\n request.headers.origin !== login.options.origin\n ) {\n return sendApiError(\n reply,\n 403,\n 'invalid_origin',\n 'Open DaveCode from its configured origin.',\n );\n }\n return;\n }\n const message = 'Missing or invalid bearer token';\n if (isV1) {\n return sendOpenAIError(reply, 401, {\n message,\n type: 'authentication_error',\n code: 'invalid_api_key',\n });\n }\n return sendApiError(reply, 401, 'unauthorized', message);\n });\n }\n\n // Accept `Content-Type: application/json` with an empty body (clients that always send the\n // header, e.g. `POST /api/runner/start` or `DELETE`): the body is simply undefined.\n app.addContentTypeParser('application/json', { parseAs: 'string' }, (_request, body, done) => {\n const text = typeof body === 'string' ? body : body.toString('utf8');\n if (text.trim() === '') return done(null, undefined);\n try {\n done(null, JSON.parse(text));\n } catch (err) {\n const error = Object.assign(err instanceof Error ? err : new Error('Invalid JSON'), {\n statusCode: 400,\n });\n done(error, undefined);\n }\n });\n\n app.setErrorHandler((error, request, reply) => {\n const status =\n typeof (error as { statusCode?: unknown }).statusCode === 'number'\n ? (error as { statusCode: number }).statusCode\n : 500;\n const message =\n status >= 500 ? 'Internal gateway error' : error instanceof Error ? error.message : 'Error';\n if (status >= 500) request.log.error({ err: error }, 'request failed');\n if (surfaceOf(request.url) === 'v1') {\n return sendOpenAIError(reply, status, {\n message,\n type: status >= 500 ? 'api_error' : 'invalid_request_error',\n code: status >= 500 ? 'internal_error' : 'bad_request',\n });\n }\n return sendApiError(reply, status, status >= 500 ? 'internal_error' : 'bad_request', message);\n });\n\n const dashboardDir =\n engine.config.server.dashboard && options.dashboardDir && existsSync(options.dashboardDir)\n ? resolve(options.dashboardDir)\n : undefined;\n if (dashboardDir) {\n await app.register(fastifyStatic, { root: dashboardDir });\n }\n\n app.setNotFoundHandler((request, reply) => {\n const surface = surfaceOf(request.url);\n const message = `Unknown endpoint ${request.method} ${pathOf(request.url)}`;\n if (surface === 'v1') {\n return sendOpenAIError(reply, 404, {\n message,\n type: 'invalid_request_error',\n code: 'not_found',\n });\n }\n if (surface === 'api') return sendApiError(reply, 404, 'not_found', message);\n if (dashboardDir && (request.method === 'GET' || request.method === 'HEAD')) {\n // SPA fallback: client-side routes are served by index.html.\n return reply.type('text/html; charset=utf-8').sendFile('index.html');\n }\n return reply.code(404).send({ error: { message, code: 'not_found' } });\n });\n\n registerV1Routes(app, engine);\n registerAuthRoutes(app, login);\n registerAccountRoutes(app, options.account);\n registerOrchestratorRoutes(app, engine, options.orchestrator);\n registerApiRoutes(app, engine, options);\n registerEventRoutes(app, engine, options.heartbeatMs ?? 15_000);\n\n return app;\n}\n\nconst LOOPBACK = new Set(['127.0.0.1', '::1', 'localhost']);\n\n/** Build and listen on `server.host:server.port` (or the overrides). */\nexport async function startGateway(\n engine: Engine,\n options: StartGatewayOptions = {},\n): Promise<FastifyInstance> {\n const host = options.host ?? engine.config.server.host;\n const app = await buildGateway(engine, { ...options, host });\n const port = options.port ?? engine.config.server.port;\n if (!engine.config.server.authToken && !LOOPBACK.has(host)) {\n app.log.warn(\n `Listening on ${host} without server.authToken: anyone on the network can use your accounts.`,\n );\n }\n await app.listen({ host, port });\n return app;\n}\n","import type { AccountControl } from '@davecode/core';\nimport type { FastifyInstance } from 'fastify';\nimport { z } from 'zod';\nimport { sendApiError } from '../errors';\n\nconst loginSchema = z.object({ provider: z.enum(['google', 'github']).optional() });\n\n/** The machine's DaveCode account. Identity only: tokens never leave the core store. */\nexport function registerAccountRoutes(app: FastifyInstance, account?: AccountControl): void {\n if (!account) return;\n app.get('/api/account', async (_request, reply) => {\n reply.header('Cache-Control', 'no-store');\n return account.state();\n });\n app.post('/api/account/login', async (request, reply) => {\n const parsed = loginSchema.safeParse(request.body ?? {});\n if (!parsed.success)\n return sendApiError(reply, 400, 'invalid_body', 'Unknown sign-in provider.');\n try {\n return reply.code(202).send(await account.login(parsed.data.provider));\n } catch {\n return sendApiError(reply, 502, 'account_unavailable', 'Could not start the sign-in.');\n }\n });\n app.post('/api/account/cancel', async (_request, reply) => {\n await account.cancel();\n return reply.code(204).send();\n });\n app.post('/api/account/logout', async (_request, reply) => {\n await account.logout();\n return reply.code(204).send();\n });\n}\n","import {\n type Account,\n type AccountUpdateInput,\n apiConfigIssues,\n ConfigError,\n type ConnectResult,\n connectionMethod,\n type Engine,\n endpointRebindIssue,\n loginCommandFor,\n mergeApiConfig,\n type RunnerStatus,\n type TaskGraph,\n VERSION,\n} from '@davecode/core';\nimport type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';\nimport { z } from 'zod';\nimport { sendApiError } from '../errors';\nimport type { GatewayOptions, RunnerControl } from '../options';\nimport {\n accountCreateSchema,\n accountPatchSchema,\n limitQuerySchema,\n routesUpdateSchema,\n runnerStartSchema,\n timeseriesQuerySchema,\n} from '../schemas';\nimport { registerGoalRoutes } from './goals';\nimport { registerTaskRoutes } from './tasks';\n\nconst EMPTY_GRAPH: TaskGraph = { version: 1, tasks: [] };\nconst IDLE: RunnerStatus = { state: 'idle' };\n\nfunction invalid(reply: FastifyReply, error: z.ZodError): FastifyReply {\n return sendApiError(reply, 400, 'invalid_body', z.prettifyError(error));\n}\n\n/** Dashboard REST API (`/api/*`, except the SSE stream). */\nexport function registerApiRoutes(\n app: FastifyInstance,\n engine: Engine,\n options: GatewayOptions,\n): void {\n const { accounts, events, audit, quota, keyring } = engine;\n const now = () => quota.clock();\n\n const emitAccount = (account: Account) => events.emit({ type: 'account.updated', account });\n\n app.get('/api/health', async () => ({\n status: 'ok',\n version: VERSION,\n uptimeSec: Math.max(0, Math.floor((now() - engine.startedAt) / 1000)),\n experimental: { ...engine.config.experimental },\n }));\n\n // --- accounts --------------------------------------------------------------\n\n app.get('/api/accounts', async () => ({ accounts: accounts.list() }));\n\n app.post('/api/accounts', async (request, reply) => {\n const parsed = accountCreateSchema.safeParse(request.body);\n if (!parsed.success) return invalid(reply, parsed.error);\n const { secret, ...input } = parsed.data;\n // Only an allow-list of config keys is writable here; executable settings are local-only.\n const configIssues = input.config ? apiConfigIssues(input.provider, input.config) : [];\n if (configIssues.length > 0) {\n return sendApiError(reply, 400, 'invalid_body', configIssues.join('; '));\n }\n if (input.provider === 'gemini-web' && !engine.config.experimental.geminiWeb) {\n return sendApiError(\n reply,\n 400,\n 'experimental_disabled',\n 'gemini-web is experimental and may violate Google’s Terms of Service. Set experimental.geminiWeb to true to opt in.',\n );\n }\n const account = engine.db.transaction(() => {\n const created = accounts.create(input);\n if (secret !== undefined) keyring.set(created.id, secret);\n audit.record({\n actor: 'api',\n action: 'account.create',\n target: created.id,\n details: { provider: created.provider, label: created.label, hasSecret: !!secret },\n });\n // Re-read so the response reflects the stored secret (hasSecret).\n return accounts.get(created.id) ?? created;\n })();\n emitAccount(account);\n return reply.code(201).send({ account });\n });\n\n app.patch<{ Params: { id: string } }>('/api/accounts/:id', async (request, reply) => {\n const parsed = accountPatchSchema.safeParse(request.body);\n if (!parsed.success) return invalid(reply, parsed.error);\n const existing = accounts.get(request.params.id);\n if (!existing) return sendApiError(reply, 404, 'not_found', 'Account not found');\n\n const { secret, ...fields } = parsed.data;\n const patch: AccountUpdateInput = { ...fields };\n if (fields.config) {\n const configIssues = apiConfigIssues(existing.provider, fields.config, existing.config);\n if (configIssues.length > 0) {\n return sendApiError(reply, 400, 'invalid_body', configIssues.join('; '));\n }\n // Keys the API cannot write (e.g. a locally configured binary) survive a config update.\n patch.config = mergeApiConfig(existing.provider, existing.config, fields.config);\n const rebind = endpointRebindIssue(existing, patch.config, secret !== undefined);\n if (rebind) return sendApiError(reply, 400, 'secret_required', rebind);\n }\n const enabled = fields.enabled ?? existing.enabled;\n if (!enabled) {\n patch.status = 'disabled';\n } else if (fields.enabled === true || secret !== undefined) {\n // Re-enabling or rotating credentials is a manual reset of error/cooldown state.\n patch.status = 'active';\n patch.cooldownUntil = null;\n patch.lastError = null;\n engine.router.breaker.reset(existing.id);\n engine.reported.forget(existing.id);\n }\n const account = engine.db.transaction(() => {\n // Store the secret first so the re-read account reports hasSecret correctly.\n if (secret !== undefined) keyring.set(existing.id, secret);\n const updated = accounts.update(existing.id, patch)!;\n audit.record({\n actor: 'api',\n action: 'account.update',\n target: existing.id,\n details: { fields: Object.keys(fields), secretChanged: secret !== undefined },\n });\n return updated;\n })();\n emitAccount(account);\n return { account };\n });\n\n app.delete<{ Params: { id: string } }>('/api/accounts/:id', async (request, reply) => {\n const { id } = request.params;\n if (!accounts.delete(id)) return sendApiError(reply, 404, 'not_found', 'Account not found');\n for (const cleanup of [() => engine.sandboxes.remove(id), () => engine.chromium.remove(id)]) {\n try {\n cleanup();\n } catch (err) {\n request.log.warn({ err, accountId: id }, 'failed to remove account directory');\n }\n }\n quota.forget(id);\n engine.reported.forget(id);\n engine.router.breaker.reset(id);\n audit.record({ actor: 'api', action: 'account.delete', target: id });\n events.emit({ type: 'account.removed', accountId: id });\n return reply.code(204).send();\n });\n\n // --- connect (official vendor login) ---------------------------------------\n\n app.get<{ Params: { id: string } }>('/api/accounts/:id/connection', async (request, reply) => {\n const account = accounts.get(request.params.id);\n if (!account) return sendApiError(reply, 404, 'not_found', 'Account not found');\n return { connection: await engine.connections.check(account) };\n });\n\n app.post<{ Params: { id: string } }>('/api/accounts/:id/connect', async (request, reply) => {\n // The gateway's request guard already requires a JSON content type on state changes.\n const account = accounts.get(request.params.id);\n if (!account) return sendApiError(reply, 404, 'not_found', 'Account not found');\n if (connectionMethod(account.provider) !== 'cli-login') {\n return sendApiError(\n reply,\n 400,\n 'not_cli_login',\n account.provider === 'gemini-web'\n ? 'gemini-web signs in through its own browser profile, not a CLI login'\n : 'This account connects with an API key: set it in the account settings',\n );\n }\n const command = loginCommandFor(account.id);\n const { launched } = options.loginLauncher\n ? await options.loginLauncher.launch(account)\n : { launched: false };\n audit.record({\n actor: 'api',\n action: 'account.connect',\n target: account.id,\n details: { launched },\n });\n const result: ConnectResult = {\n connection: await engine.connections.check(account),\n launched,\n command,\n message: launched\n ? 'A terminal opened on the gateway machine with the official sign-in. Finish it there; this page updates when the login is detected.'\n : `Run this in a terminal on the machine running the gateway: ${command}`,\n };\n return { connect: result };\n });\n\n // --- usage -----------------------------------------------------------------\n\n app.get('/api/usage', async () => ({\n usage: accounts.list().map((account) => quota.usage(account)),\n }));\n\n app.get('/api/budget', async () => ({ budget: engine.budget.snapshot() }));\n\n app.get('/api/usage/timeseries', async (request, reply) => {\n const parsed = timeseriesQuerySchema.safeParse(request.query);\n if (!parsed.success) return invalid(reply, parsed.error);\n const { minutes, bucketSec } = parsed.data;\n const until = now() + 1;\n const buckets = engine.usage.timeseries({\n since: until - minutes * 60_000,\n until,\n bucketMs: bucketSec * 1000,\n });\n return { buckets };\n });\n\n app.get('/api/requests', async (request, reply) => {\n const parsed = limitQuerySchema(100).safeParse(request.query);\n if (!parsed.success) return invalid(reply, parsed.error);\n return { requests: engine.usage.recent(parsed.data.limit) };\n });\n\n app.get('/api/logs', async (request, reply) => {\n const parsed = limitQuerySchema(200).safeParse(request.query);\n if (!parsed.success) return invalid(reply, parsed.error);\n return { events: events.recent(parsed.data.limit) };\n });\n\n // --- routes ----------------------------------------------------------------\n\n app.get('/api/routes', async () => ({\n defaultRoute: engine.config.routing.defaultRoute,\n routes: engine.config.routing.routes,\n }));\n\n app.put('/api/routes', async (request, reply) => {\n const parsed = routesUpdateSchema.safeParse(request.body);\n if (!parsed.success) return invalid(reply, parsed.error);\n const { routes, defaultRoute } = parsed.data;\n for (const route of routes) {\n for (const target of route.targets) {\n if (target.accountId !== undefined && !accounts.get(target.accountId)) {\n return sendApiError(\n reply,\n 400,\n 'unknown_account',\n `route \"${route.name}\" pins unknown account \"${target.accountId}\"`,\n );\n }\n }\n }\n let result: Awaited<ReturnType<Engine['updateRouting']>>;\n try {\n result = await engine.updateRouting({\n routes,\n ...(defaultRoute !== undefined ? { defaultRoute } : {}),\n });\n } catch (error) {\n // The stored config.json is unreadable or invalid: it is never overwritten.\n if (error instanceof ConfigError) {\n return sendApiError(reply, 409, 'config_invalid', error.message);\n }\n throw error;\n }\n audit.record({\n actor: 'api',\n action: 'routes.update',\n details: {\n routes: routes.map((r) => r.name),\n defaultRoute: engine.config.routing.defaultRoute,\n },\n });\n return {\n defaultRoute: engine.config.routing.defaultRoute,\n routes: engine.config.routing.routes,\n shadowedByProject: result.shadowedByProject,\n };\n });\n\n // --- project brain (Phase 3) -------------------------------------------------\n\n app.get('/api/tasks', async () => {\n const { brain } = options;\n if (!brain) return { project: null, graph: EMPTY_GRAPH };\n return { project: brain.project(), graph: await brain.graph() };\n });\n\n registerTaskRoutes(app, engine, options);\n registerGoalRoutes(app, engine, options);\n\n app.get('/api/brain', async () => {\n const { brain } = options;\n if (!brain) return { state: '', architecture: '' };\n const [state, architecture] = await Promise.all([brain.state(), brain.architecture()]);\n return { state, architecture };\n });\n\n // --- runner (Phase 4) --------------------------------------------------------\n\n app.get('/api/runner', async () => ({ status: options.runner?.status() ?? IDLE }));\n\n const control = (action: keyof Omit<RunnerControl, 'status'>) =>\n async function handler(request: FastifyRequest, reply: FastifyReply) {\n const { runner } = options;\n if (!runner) {\n return sendApiError(\n reply,\n 501,\n 'runner_unavailable',\n 'The autonomous runner is not available',\n );\n }\n let taskId: string | undefined;\n if (action === 'start' && request.body !== undefined && request.body !== null) {\n const parsed = runnerStartSchema.safeParse(request.body);\n if (!parsed.success) return invalid(reply, parsed.error);\n taskId = parsed.data.taskId;\n }\n try {\n if (action === 'start') await runner.start(taskId === undefined ? {} : { taskId });\n else await runner[action]();\n } catch (error) {\n // Runner refusals (RunnerError: dirty_worktree, no_brain, busy…) carry an HTTP status\n // and a machine-readable code; forward both so clients don't have to parse messages.\n const { statusCode, code } = error as { statusCode?: unknown; code?: unknown };\n if (typeof statusCode === 'number' && statusCode < 500 && typeof code === 'string') {\n return sendApiError(reply, statusCode, code, (error as Error).message);\n }\n throw error;\n }\n audit.record({\n actor: 'api',\n action: `runner.${action}`,\n ...(taskId !== undefined ? { details: { taskId } } : {}),\n });\n return { status: runner.status() };\n };\n app.post('/api/runner/start', control('start'));\n app.post('/api/runner/pause', control('pause'));\n app.post('/api/runner/stop', control('stop'));\n}\n","import {\n PROVIDER_KINDS,\n type ProviderKind,\n routeSchema,\n TASK_STATUSES,\n taskIdSchema,\n} from '@davecode/core';\nimport { z } from 'zod';\n\nconst providerKind = z.enum(PROVIDER_KINDS as [ProviderKind, ...ProviderKind[]]);\n\nconst contentPart = z.discriminatedUnion('type', [\n z.object({ type: z.literal('text'), text: z.string() }),\n z.object({\n type: z.literal('image_url'),\n image_url: z.object({\n url: z.string(),\n detail: z.enum(['auto', 'low', 'high']).optional(),\n }),\n }),\n]);\n\nconst toolCall = z.object({\n id: z.string(),\n type: z.literal('function'),\n function: z.object({ name: z.string(), arguments: z.string() }),\n});\n\nconst chatMessage = z.object({\n role: z.enum(['system', 'user', 'assistant', 'tool']),\n content: z.union([z.string(), z.array(contentPart), z.null()]),\n name: z.string().optional(),\n tool_call_id: z.string().optional(),\n tool_calls: z.array(toolCall).optional(),\n});\n\n/** `POST /v1/chat/completions` body. Unknown OpenAI parameters are accepted and dropped. */\nexport const chatRequestSchema = z.object({\n model: z.string().min(1),\n messages: z.array(chatMessage).min(1),\n stream: z.boolean().optional(),\n temperature: z.number().min(0).max(2).optional(),\n top_p: z.number().min(0).max(1).optional(),\n max_tokens: z.number().int().positive().optional(),\n stop: z.union([z.string(), z.array(z.string())]).optional(),\n tools: z\n .array(\n z.object({\n type: z.literal('function'),\n function: z.object({\n name: z.string(),\n description: z.string().optional(),\n parameters: z.record(z.string(), z.unknown()).optional(),\n }),\n }),\n )\n .optional(),\n tool_choice: z\n .union([\n z.enum(['auto', 'none', 'required']),\n z.object({ type: z.literal('function'), function: z.object({ name: z.string() }) }),\n ])\n .optional(),\n user: z.string().optional(),\n});\n\nconst positiveInt = z.number().int().positive();\n\nconst quotaLimits = z\n .object({\n tpm: positiveInt.optional(),\n rpm: positiveInt.optional(),\n tokens5h: positiveInt.optional(),\n requests5h: positiveInt.optional(),\n tokensDaily: positiveInt.optional(),\n requestsDaily: positiveInt.optional(),\n })\n .strict();\n\n/** Keys that look like credentials must go in `secret`, never in plain `config`. */\nconst SECRET_KEY =\n /^(api[-_]?key|secret|client[-_]?secret|(access|refresh|session|auth|bearer)?[-_]?token|password|passwd|cookies?|authorization|credentials?)$/i;\n\nconst accountConfig = z\n .record(z.string(), z.unknown())\n .refine((config) => !Object.keys(config).some((key) => SECRET_KEY.test(key)), {\n message: 'config must not contain credentials; send them in \"secret\" instead',\n });\n\n/** `YYYY-MM-DD` or a full ISO 8601 timestamp. */\nconst subscriptionDate = z\n .string()\n .trim()\n .refine(\n (value) =>\n /^\\d{4}-\\d{2}-\\d{2}(T[\\d:.]+(Z|[+-]\\d{2}:?\\d{2})?)?$/.test(value) &&\n !Number.isNaN(Date.parse(value)),\n { message: 'expected a date (YYYY-MM-DD) or an ISO timestamp' },\n );\n\n/** Plan, payment and renewal details for an account (`SubscriptionInfo`). */\nexport const subscriptionSchema = z\n .object({\n plan: z.string().trim().min(1).max(120).optional(),\n paidAt: subscriptionDate.optional(),\n renewsAt: subscriptionDate.optional(),\n price: z\n .object({\n amount: z.number().min(0).max(1_000_000),\n currency: z\n .string()\n .trim()\n .regex(/^[A-Za-z]{3}$/, 'expected a 3-letter currency code')\n .transform((c) => c.toUpperCase()),\n period: z.enum(['month', 'year']),\n })\n .strict()\n .optional(),\n notes: z.string().trim().max(1000).optional(),\n })\n .strict();\n\nconst accountFields = {\n label: z.string().trim().min(1).max(200),\n enabled: z.boolean().optional(),\n priority: z.number().int().min(0).max(1_000_000).optional(),\n weight: z.number().min(0).max(1_000).optional(),\n limits: quotaLimits.optional(),\n config: accountConfig.optional(),\n /** API key / token. Encrypted at rest and never returned. */\n secret: z.string().min(1).max(100_000).optional(),\n};\n\n/** `POST /api/accounts` body (`AccountCreate`). */\nexport const accountCreateSchema = z\n .object({ provider: providerKind, ...accountFields, subscription: subscriptionSchema.optional() })\n .strict();\n\n/** `PATCH /api/accounts/:id` body (`AccountPatch`); `subscription: null` clears it. */\nexport const accountPatchSchema = z\n .object({\n ...accountFields,\n label: accountFields.label.optional(),\n subscription: subscriptionSchema.nullable().optional(),\n })\n .strict();\n\n/**\n * `PUT /api/routes` body: the complete route list (validated with the config schema's route\n * shape) and optionally the default route, which must be one of those routes.\n */\nexport const routesUpdateSchema = z\n .object({ routes: z.array(routeSchema).max(200), defaultRoute: z.string().min(1).optional() })\n .strict()\n .superRefine((body, ctx) => {\n const seen = new Set<string>();\n body.routes.forEach((route, index) => {\n if (seen.has(route.name)) {\n ctx.addIssue({\n code: 'custom',\n path: ['routes', index, 'name'],\n message: `duplicate route name \"${route.name}\"`,\n });\n }\n seen.add(route.name);\n });\n if (body.defaultRoute !== undefined && !seen.has(body.defaultRoute)) {\n ctx.addIssue({\n code: 'custom',\n path: ['defaultRoute'],\n message: `defaultRoute \"${body.defaultRoute}\" is not one of the routes`,\n });\n }\n });\n\nconst taskText = {\n title: z.string().trim().min(1).max(300),\n description: z.string().max(50_000),\n acceptance: z.array(z.string().trim().min(1).max(2_000)).max(100),\n notes: z.string().max(50_000),\n dependsOn: z.array(z.string().min(1)).max(500),\n priority: z.number().finite(),\n};\n\n/** `POST /api/tasks` body. The task always starts PENDING. */\nexport const taskCreateSchema = z\n .object({\n id: taskIdSchema,\n title: taskText.title,\n description: taskText.description.optional(),\n dependsOn: taskText.dependsOn.optional(),\n priority: taskText.priority.optional(),\n acceptance: taskText.acceptance.optional(),\n })\n .strict();\n\n/**\n * `PATCH /api/tasks/:id` body. `null` clears an optional field (`description`, `priority`,\n * `acceptance`, `notes`).\n */\nexport const taskPatchSchema = z\n .object({\n title: taskText.title.optional(),\n description: taskText.description.nullable().optional(),\n dependsOn: taskText.dependsOn.optional(),\n priority: taskText.priority.nullable().optional(),\n acceptance: taskText.acceptance.nullable().optional(),\n notes: taskText.notes.nullable().optional(),\n status: z.enum(TASK_STATUSES).optional(),\n })\n .strict()\n .refine((patch) => Object.values(patch).some((v) => v !== undefined), {\n message: 'send at least one field to change',\n });\n\n/** `POST /api/runner/start` body: optional, `{}` or empty means \"pick the next task\". */\nexport const runnerStartSchema = z.object({ taskId: z.string().min(1).optional() }).strict();\n\n/** `POST /api/goals` body. Limits are further clamped to the `goal.*` config. */\nexport const goalStartSchema = z\n .object({\n objective: z.string().trim().min(1).max(4_000),\n maxRounds: z.number().int().min(1).max(20).optional(),\n maxTasks: z.number().int().min(1).max(100).optional(),\n maxTokens: z.number().int().min(1_000).optional(),\n dryRun: z.boolean().optional(),\n })\n .strict();\n\nexport const timeseriesQuerySchema = z.object({\n minutes: z.coerce\n .number()\n .int()\n .min(1)\n .max(7 * 24 * 60)\n .default(60),\n bucketSec: z.coerce.number().int().min(1).max(86_400).default(60),\n});\n\nexport const limitQuerySchema = (fallback: number, max = 1000) =>\n z.object({ limit: z.coerce.number().int().min(1).max(max).default(fallback) });\n","import type { Engine } from '@davecode/core';\nimport type { FastifyInstance, FastifyReply } from 'fastify';\nimport { z } from 'zod';\nimport { sendApiError } from '../errors';\nimport type { GatewayOptions, GoalControl, GoalStartInput } from '../options';\nimport { goalStartSchema } from '../schemas';\n\n/** Goal mode: `GET/POST /api/goals`, `GET /api/goals/:id`, `POST /api/goals/:id/cancel`. */\nexport function registerGoalRoutes(\n app: FastifyInstance,\n engine: Engine,\n options: GatewayOptions,\n): void {\n const { audit } = engine;\n\n const unavailable = (reply: FastifyReply) =>\n sendApiError(\n reply,\n 501,\n 'goals_unavailable',\n 'Goal mode is not available; start the gateway inside a project (davecode init)',\n );\n\n /** Forwards refusals that carry an HTTP status and a code (GoalError: busy, not_found…). */\n const guarded = async <T>(reply: FastifyReply, run: () => Promise<T>) => {\n try {\n return { ok: true as const, value: await run() };\n } catch (error) {\n const { statusCode, code } = error as { statusCode?: unknown; code?: unknown };\n if (typeof statusCode === 'number' && statusCode < 500 && typeof code === 'string') {\n return {\n ok: false as const,\n reply: sendApiError(reply, statusCode, code, (error as Error).message),\n };\n }\n throw error;\n }\n };\n\n const control = (reply: FastifyReply): GoalControl | undefined => {\n if (!options.goals) unavailable(reply);\n return options.goals;\n };\n\n app.get('/api/goals', async (_request, reply) => {\n const goals = control(reply);\n if (!goals) return reply;\n return { goals: await goals.list() };\n });\n\n app.get<{ Params: { id: string } }>('/api/goals/:id', async (request, reply) => {\n const goals = control(reply);\n if (!goals) return reply;\n const goal = await goals.get(request.params.id);\n if (!goal) return sendApiError(reply, 404, 'not_found', `unknown goal \"${request.params.id}\"`);\n return { goal };\n });\n\n app.post('/api/goals', async (request, reply) => {\n const parsed = goalStartSchema.safeParse(request.body);\n if (!parsed.success) {\n return sendApiError(reply, 400, 'invalid_body', z.prettifyError(parsed.error));\n }\n const goals = control(reply);\n if (!goals) return reply;\n const input: GoalStartInput = parsed.data;\n const result = await guarded(reply, () => goals.start(input));\n if (!result.ok) return result.reply;\n audit.record({\n actor: 'api',\n action: 'goal.start',\n target: result.value.id,\n details: { dryRun: input.dryRun === true },\n });\n return reply.code(202).send({ goal: result.value });\n });\n\n app.post<{ Params: { id: string } }>('/api/goals/:id/execute', async (request, reply) => {\n const goals = control(reply);\n if (!goals) return reply;\n if (!goals.execute) return unavailable(reply);\n const execute = goals.execute.bind(goals);\n const result = await guarded(reply, () => execute(request.params.id));\n if (!result.ok) return result.reply;\n audit.record({ actor: 'api', action: 'goal.execute', target: request.params.id });\n return reply.code(202).send({ goal: result.value });\n });\n\n app.get<{ Params: { id: string; taskId: string } }>(\n '/api/goals/:id/artifacts/:taskId',\n async (request, reply) => {\n const goals = control(reply);\n if (!goals) return reply;\n if (!goals.readArtifact) return unavailable(reply);\n const readArtifact = goals.readArtifact.bind(goals);\n const result = await guarded(reply, () =>\n readArtifact(request.params.id, request.params.taskId),\n );\n if (!result.ok) return result.reply;\n return { artifact: result.value };\n },\n );\n\n app.post<{ Params: { id: string } }>('/api/goals/:id/cancel', async (request, reply) => {\n const goals = control(reply);\n if (!goals) return reply;\n const result = await guarded(reply, () => goals.cancel(request.params.id));\n if (!result.ok) return result.reply;\n audit.record({ actor: 'api', action: 'goal.cancel', target: request.params.id });\n return { goal: result.value };\n });\n}\n","import {\n type ClearableTaskField,\n type Engine,\n type NewTask,\n TaskGraphError,\n type TaskGraphIssue,\n type TaskPatch,\n} from '@davecode/core';\nimport type { FastifyInstance, FastifyReply } from 'fastify';\nimport { z } from 'zod';\nimport { sendApiError } from '../errors';\nimport type { BrainSource, GatewayOptions } from '../options';\nimport { taskCreateSchema, taskPatchSchema } from '../schemas';\n\n/** How a task graph issue is reported: HTTP status plus the extra envelope fields. */\nfunction describeIssue(issue: TaskGraphIssue): {\n status: number;\n code: string;\n extra: Record<string, unknown>;\n} {\n switch (issue.code) {\n case 'unknown_task':\n return { status: 404, code: 'not_found', extra: {} };\n case 'duplicate_id':\n case 'invalid_transition':\n case 'task_in_progress':\n return { status: 409, code: issue.code, extra: {} };\n case 'has_dependents':\n return { status: 409, code: 'has_dependents', extra: { dependents: issue.dependents ?? [] } };\n case 'cycle':\n return { status: 400, code: 'cycle', extra: { cycle: issue.cycle ?? [] } };\n case 'unknown_dependency':\n case 'self_dependency':\n return { status: 400, code: issue.code, extra: {} };\n default:\n // The stored TASK_GRAPH.json itself is unreadable or invalid.\n return { status: 409, code: 'invalid_graph', extra: {} };\n }\n}\n\nfunction sendGraphError(reply: FastifyReply, error: TaskGraphError): FastifyReply {\n // Report the most specific issue: a cycle beats generic dependency problems.\n const issue = error.issues.find((i) => i.code === 'cycle') ?? error.issues[0];\n if (!issue) return sendApiError(reply, 400, 'invalid_graph', error.message);\n const { status, code, extra } = describeIssue(issue);\n return sendApiError(reply, status, code, issue.message, extra);\n}\n\n/** Task graph writes: `POST /api/tasks`, `PATCH /api/tasks/:id`, `DELETE /api/tasks/:id`. */\nexport function registerTaskRoutes(\n app: FastifyInstance,\n engine: Engine,\n options: GatewayOptions,\n): void {\n const { audit } = engine;\n\n /** The brain, or the error reply to send (no project, or a read-only source). */\n const writable = (reply: FastifyReply): BrainSource | FastifyReply => {\n const { brain } = options;\n if (!brain) {\n return sendApiError(\n reply,\n 409,\n 'no_brain',\n 'No project brain is loaded; start the gateway inside a project (davecode init)',\n );\n }\n return brain;\n };\n\n const guarded = async <T>(\n reply: FastifyReply,\n run: () => Promise<T>,\n ): Promise<T | FastifyReply> => {\n try {\n return await run();\n } catch (error) {\n if (error instanceof TaskGraphError) return sendGraphError(reply, error);\n // Brain refusals such as MissingBrainError carry an HTTP status and a machine code.\n const { statusCode, code } = error as { statusCode?: unknown; code?: unknown };\n if (typeof statusCode === 'number' && statusCode < 500 && typeof code === 'string') {\n return sendApiError(reply, statusCode, code, (error as Error).message);\n }\n throw error;\n }\n };\n\n const readOnly = (reply: FastifyReply) =>\n sendApiError(reply, 501, 'brain_read_only', 'The project brain of this gateway is read-only');\n\n app.post('/api/tasks', async (request, reply) => {\n const parsed = taskCreateSchema.safeParse(request.body);\n if (!parsed.success) {\n return sendApiError(reply, 400, 'invalid_body', z.prettifyError(parsed.error));\n }\n const brain = writable(reply);\n if (isReply(brain)) return brain;\n if (!brain.createTask) return readOnly(reply);\n const input: NewTask = parsed.data;\n const create = brain.createTask.bind(brain);\n const result = await guarded(reply, () => create(input));\n if (isReply(result)) return result;\n audit.record({ actor: 'api', action: 'task.create', target: input.id });\n return reply.code(201).send({ task: result });\n });\n\n app.patch<{ Params: { id: string } }>('/api/tasks/:id', async (request, reply) => {\n const parsed = taskPatchSchema.safeParse(request.body);\n if (!parsed.success) {\n return sendApiError(reply, 400, 'invalid_body', z.prettifyError(parsed.error));\n }\n const brain = writable(reply);\n if (isReply(brain)) return brain;\n if (!brain.updateTask) return readOnly(reply);\n\n const { description, priority, acceptance, notes, ...rest } = parsed.data;\n const patch: TaskPatch = { ...rest };\n const clear: ClearableTaskField[] = [];\n const optional = { description, priority, acceptance, notes };\n for (const [key, value] of Object.entries(optional) as Array<[ClearableTaskField, unknown]>) {\n if (value === null) clear.push(key);\n else if (value !== undefined) (patch as Record<string, unknown>)[key] = value;\n }\n const { id } = request.params;\n const update = brain.updateTask.bind(brain);\n const result = await guarded(reply, () => update(id, patch, { clear }));\n if (isReply(result)) return result;\n audit.record({\n actor: 'api',\n action: 'task.update',\n target: id,\n details: { fields: Object.keys(parsed.data) },\n });\n return { task: result };\n });\n\n app.delete<{ Params: { id: string } }>('/api/tasks/:id', async (request, reply) => {\n const brain = writable(reply);\n if (isReply(brain)) return brain;\n if (!brain.removeTask) return readOnly(reply);\n const { id } = request.params;\n const remove = brain.removeTask.bind(brain);\n const result = await guarded(reply, () => remove(id));\n if (isReply(result)) return result;\n audit.record({ actor: 'api', action: 'task.delete', target: id });\n return reply.code(204).send();\n });\n}\n\nfunction isReply(value: unknown): value is FastifyReply {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'sent' in value &&\n typeof (value as { code?: unknown }).code === 'function'\n );\n}\n","import type { LoginProvider, LoginService } from '@davecode/core';\nimport type { FastifyInstance, FastifyRequest } from 'fastify';\nimport { z } from 'zod';\nimport { sendApiError } from '../errors';\n\nexport function authCookie(request: FastifyRequest, name: string): string | undefined {\n return request.headers.cookie\n ?.split(';')\n .map((part) => part.trim())\n .find((part) => part.startsWith(`${name}=`))\n ?.slice(name.length + 1);\n}\n\nfunction cookie(name: string, value: string, seconds: number, secure: boolean): string {\n return `${name}=${value}; Path=/; HttpOnly; SameSite=Lax; Max-Age=${seconds}${secure ? '; Secure' : ''}`;\n}\n\nexport function registerAuthRoutes(app: FastifyInstance, login?: LoginService): void {\n const secure = login?.options.origin.startsWith('https:') ?? false;\n app.get('/api/auth/session', async (request, reply) => {\n reply.header('Cache-Control', 'no-store');\n return (\n login?.status(authCookie(request, 'dc_session')) ?? {\n required: false,\n providers: [],\n user: null,\n }\n );\n });\n app.post('/api/auth/logout', async (request, reply) => {\n if (login && request.headers.origin !== login.options.origin)\n return sendApiError(\n reply,\n 403,\n 'invalid_origin',\n 'Open DaveCode from its configured origin.',\n );\n login?.logout(authCookie(request, 'dc_session'));\n return reply\n .header('Cache-Control', 'no-store')\n .header('Set-Cookie', cookie('dc_session', '', 0, secure))\n .code(204)\n .send();\n });\n for (const provider of ['google', 'github'] as const satisfies readonly LoginProvider[]) {\n app.get(`/api/auth/${provider}/start`, async (request, reply) => {\n if (!login?.options.providers[provider])\n return sendApiError(\n reply,\n 503,\n 'login_not_configured',\n 'This sign-in provider is not configured.',\n );\n try {\n const flow = login.begin(provider, request.ip);\n return reply\n .header('Cache-Control', 'no-store')\n .header('Referrer-Policy', 'no-referrer')\n .header('Set-Cookie', cookie('dc_login', flow.binding, 600, secure))\n .redirect(flow.url);\n } catch {\n return sendApiError(reply, 429, 'login_busy', 'Sign-in is busy. Try again shortly.');\n }\n });\n app.get(`/api/auth/${provider}/callback`, async (request, reply) => {\n reply.header('Cache-Control', 'no-store').header('Referrer-Policy', 'no-referrer');\n if (!login)\n return sendApiError(reply, 503, 'login_not_configured', 'Sign-in is not configured.');\n const parsed = z\n .object({ state: z.string().min(1).max(200), code: z.string().min(1).max(4096) })\n .safeParse(request.query);\n const binding = authCookie(request, 'dc_login');\n if (!parsed.success || !binding)\n return reply.redirect(`${login.options.origin}/#/login?error=signin_failed`);\n try {\n const session = await login.finish(provider, parsed.data.state, parsed.data.code, binding);\n login.logout(authCookie(request, 'dc_session'));\n return reply\n .header('Set-Cookie', [\n cookie('dc_session', session, 8 * 60 * 60, secure),\n cookie('dc_login', '', 0, secure),\n ])\n .redirect(`${login.options.origin}/`);\n } catch {\n return reply\n .header('Set-Cookie', cookie('dc_login', '', 0, secure))\n .redirect(`${login.options.origin}/#/login?error=signin_failed`);\n }\n });\n }\n}\n","import type { OutgoingHttpHeaders, ServerResponse } from 'node:http';\nimport type { DaveEvent, Engine } from '@davecode/core';\nimport type { FastifyInstance } from 'fastify';\n\nfunction frame(event: DaveEvent, seq: number): string {\n return `id: ${seq}\\nevent: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`;\n}\n\n/** Resume cursor from the `Last-Event-ID` header (sent by EventSource on reconnect) or query. */\nfunction resumeCursor(headers: Record<string, unknown>, query: unknown): number {\n const fromQuery =\n typeof query === 'object' && query !== null && 'lastEventId' in query\n ? (query as { lastEventId: unknown }).lastEventId\n : undefined;\n const raw = headers['last-event-id'] ?? fromQuery;\n const value = Number(Array.isArray(raw) ? raw[0] : raw);\n return Number.isSafeInteger(value) && value >= 0 ? value : 0;\n}\n\n/**\n * `GET /api/events`: replays the buffered events after the client's `Last-Event-ID` (all of\n * them on a first connect), then streams live events with an `id:` per event and a `: ping`\n * heartbeat. Subscriptions and timers are released when the client disconnects.\n */\nexport function registerEventRoutes(\n app: FastifyInstance,\n engine: Engine,\n heartbeatMs: number,\n): void {\n const clients = new Set<ServerResponse>();\n\n // End open streams before the server stops, otherwise close() would wait on them.\n app.addHook('preClose', async () => {\n for (const res of clients) res.end();\n clients.clear();\n });\n\n app.get('/api/events', (request, reply) => {\n const cursor = resumeCursor(request.headers, request.query);\n reply.hijack();\n const res = reply.raw;\n // Keep headers set by earlier hooks (CORS).\n const inherited: OutgoingHttpHeaders = {};\n for (const [name, value] of Object.entries(reply.getHeaders())) {\n if (value !== undefined) inherited[name] = value;\n }\n res.writeHead(200, {\n ...inherited,\n 'content-type': 'text/event-stream; charset=utf-8',\n 'cache-control': 'no-cache, no-transform',\n connection: 'keep-alive',\n 'x-accel-buffering': 'no',\n });\n res.write('retry: 3000\\n\\n');\n clients.add(res);\n\n for (const { seq, event } of engine.events.since(cursor)) res.write(frame(event, seq));\n const unsubscribe = engine.events.subscribe((event, seq) => {\n res.write(frame(event, seq));\n });\n const heartbeat = setInterval(() => res.write(': ping\\n\\n'), heartbeatMs);\n heartbeat.unref();\n\n let closed = false;\n const cleanup = () => {\n if (closed) return;\n closed = true;\n clearInterval(heartbeat);\n unsubscribe();\n clients.delete(res);\n };\n // Not request.raw 'close': Node emits that once the (empty) body is consumed.\n res.on('close', cleanup);\n res.on('error', cleanup);\n });\n}\n","import {\n type Engine,\n OrchestratorError,\n type OrchestratorErrorCode,\n type OrchestratorService,\n startRunSchema,\n} from '@davecode/core';\nimport type { FastifyInstance, FastifyReply } from 'fastify';\nimport { z } from 'zod';\nimport { sendApiError } from '../errors';\n\nconst STATUS: Record<OrchestratorErrorCode, number> = {\n not_found: 404,\n no_agents: 409,\n not_a_repository: 409,\n busy: 409,\n not_appliable: 409,\n};\n\n/** Also matches an `OrchestratorError` from another copy of core (bundled hosts). */\nfunction orchestratorError(error: unknown): OrchestratorError | undefined {\n if (error instanceof OrchestratorError) return error;\n if (!(error instanceof Error) || error.name !== 'OrchestratorError') return undefined;\n const { code } = error as { code?: unknown };\n return typeof code === 'string' && Object.hasOwn(STATUS, code)\n ? (error as OrchestratorError)\n : undefined;\n}\n\n/**\n * Pane orchestrator: `/api/orchestrator/*`. Registered only when the host gave the gateway an\n * `OrchestratorService`; every decision is the service's, these routes only translate HTTP.\n */\nexport function registerOrchestratorRoutes(\n app: FastifyInstance,\n engine: Engine,\n orchestrator?: OrchestratorService,\n): void {\n if (!orchestrator) return;\n const { audit } = engine;\n\n /** Maps `OrchestratorError` refusals to the `/api` error envelope; anything else is a 500. */\n const guarded = async <T>(\n reply: FastifyReply,\n work: () => Promise<T>,\n ): Promise<{ ok: true; value: T } | { ok: false; reply: FastifyReply }> => {\n try {\n return { ok: true, value: await work() };\n } catch (error) {\n const known = orchestratorError(error);\n if (!known) throw error;\n return {\n ok: false,\n reply: sendApiError(reply, STATUS[known.code], known.code, known.message),\n };\n }\n };\n\n const unknownRun = (reply: FastifyReply, id: string) =>\n sendApiError(reply, 404, 'not_found', `unknown run \"${id}\"`);\n\n app.get('/api/orchestrator/agents', async (_request, reply) => {\n reply.header('Cache-Control', 'no-store');\n return { agents: await orchestrator.agents() };\n });\n\n app.get('/api/orchestrator/runs', async (_request, reply) => {\n reply.header('Cache-Control', 'no-store');\n return { runs: orchestrator.list() };\n });\n\n app.post('/api/orchestrator/runs', async (request, reply) => {\n const parsed = startRunSchema.safeParse(request.body);\n if (!parsed.success) {\n return sendApiError(reply, 400, 'invalid_body', z.prettifyError(parsed.error));\n }\n const result = await guarded(reply, () => orchestrator.start(parsed.data));\n if (!result.ok) return result.reply;\n audit.record({\n actor: 'api',\n action: 'orchestrator.start',\n target: result.value.id,\n details: { agents: result.value.agents },\n });\n return reply.code(202).send(result.value);\n });\n\n app.get<{ Params: { id: string } }>('/api/orchestrator/runs/:id', async (request, reply) => {\n reply.header('Cache-Control', 'no-store');\n const run = orchestrator.get(request.params.id);\n if (!run) return unknownRun(reply, request.params.id);\n return run;\n });\n\n app.post<{ Params: { id: string } }>(\n '/api/orchestrator/runs/:id/cancel',\n async (request, reply) => {\n const { id } = request.params;\n if (orchestrator.cancel(id)) {\n audit.record({ actor: 'api', action: 'orchestrator.cancel', target: id });\n return reply.code(204).send();\n }\n const run = orchestrator.get(id);\n if (!run) return unknownRun(reply, id);\n return sendApiError(reply, 409, 'not_active', `run \"${id}\" is already ${run.status}`);\n },\n );\n\n app.post<{ Params: { id: string } }>(\n '/api/orchestrator/runs/:id/apply',\n async (request, reply) => {\n const { id } = request.params;\n const result = await guarded(reply, () => orchestrator.apply(id));\n if (!result.ok) return result.reply;\n audit.record({ actor: 'api', action: 'orchestrator.apply', target: id });\n return result.value;\n },\n );\n}\n","import { Readable } from 'node:stream';\nimport {\n type ChatCompletionChunk,\n type ChatRequest,\n type Engine,\n newId,\n type RoutingMeta,\n type StreamResult,\n} from '@davecode/core';\nimport type { FastifyInstance, FastifyReply } from 'fastify';\nimport { z } from 'zod';\nimport { describeRoutingError, sendOpenAIError } from '../errors';\nimport { chatRequestSchema } from '../schemas';\n\nfunction setRoutingHeaders(reply: FastifyReply, meta: RoutingMeta): void {\n reply\n .header('x-davecode-request-id', meta.requestId)\n .header('x-davecode-account', meta.accountId)\n .header('x-davecode-provider', meta.provider)\n .header('x-davecode-failovers', String(meta.failovers));\n}\n\nfunction sendRoutingError(reply: FastifyReply, err: unknown): FastifyReply {\n const { status, body } = describeRoutingError(err);\n if (status === 500) reply.log.error({ err }, 'chat completion failed');\n if (err instanceof Error && 'failovers' in err && typeof err.failovers === 'number') {\n reply.header('x-davecode-failovers', String(err.failovers));\n }\n return sendOpenAIError(reply, status, body);\n}\n\n/** Frame chunks as SSE, forwarding a mid-stream failure as a final error frame. */\nasync function* sseFrames(chunks: AsyncIterable<ChatCompletionChunk>): AsyncGenerator<string> {\n try {\n for await (const chunk of chunks) yield `data: ${JSON.stringify(chunk)}\\n\\n`;\n } catch (err) {\n yield `data: ${JSON.stringify({ error: describeRoutingError(err).body })}\\n\\n`;\n }\n yield 'data: [DONE]\\n\\n';\n}\n\n/** OpenAI-compatible surface: `GET /v1/models`, `POST /v1/chat/completions`. */\nexport function registerV1Routes(app: FastifyInstance, engine: Engine): void {\n app.get('/v1/models', async () => ({ object: 'list', data: await engine.router.listModels() }));\n\n app.post('/v1/chat/completions', async (request, reply) => {\n const parsed = chatRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return sendOpenAIError(reply, 400, {\n message: z.prettifyError(parsed.error),\n type: 'invalid_request_error',\n code: 'invalid_body',\n });\n }\n const body = parsed.data as ChatRequest;\n const requestId = newId('req');\n reply.header('x-davecode-request-id', requestId);\n\n // Abort upstream work if the client goes away before we finish.\n const abort = new AbortController();\n reply.raw.on('close', () => {\n if (!reply.raw.writableFinished) abort.abort();\n });\n const routeOptions = { requestId, signal: abort.signal };\n\n if (!body.stream) {\n try {\n const { completion, meta } = await engine.router.complete(body, routeOptions);\n setRoutingHeaders(reply, meta);\n return completion;\n } catch (err) {\n return sendRoutingError(reply, err);\n }\n }\n\n let result: StreamResult;\n try {\n // Resolves after the first upstream chunk, so failover never leaks partial output.\n result = await engine.router.stream(body, routeOptions);\n } catch (err) {\n return sendRoutingError(reply, err);\n }\n setRoutingHeaders(reply, result.meta);\n reply\n .header('content-type', 'text/event-stream; charset=utf-8')\n .header('cache-control', 'no-cache, no-transform')\n .header('x-accel-buffering', 'no');\n return reply.send(Readable.from(sseFrames(result.chunks)));\n });\n}\n","import type { ChatCompletionChunk, DaveEvent } from '@davecode/core';\n\n/**\n * Server-Sent Events client parsing per the WHATWG spec: `\\n`, `\\r\\n` and `\\r` line endings\n * (even when split across chunks), comments, multi-line `data`, `event`, `id` and `retry`.\n */\n\nexport interface SSEMessage {\n /** `message` when the server sent no `event:` field. */\n event: string;\n data: string;\n /** Last event id seen on the stream, if any. */\n id?: string;\n retry?: number;\n}\n\nexport class SSEParser {\n private buffer = '';\n private pendingCR = false;\n private data: string[] = [];\n private event = '';\n private lastId: string | undefined;\n private retry: number | undefined;\n\n /** Feed decoded text; returns the messages completed by it. */\n push(chunk: string): SSEMessage[] {\n const out: SSEMessage[] = [];\n let text = chunk;\n if (this.pendingCR && text.startsWith('\\n')) text = text.slice(1);\n this.pendingCR = false;\n this.buffer += text;\n\n let start = 0;\n for (let i = 0; i < this.buffer.length; i++) {\n const ch = this.buffer[i];\n if (ch !== '\\n' && ch !== '\\r') continue;\n const line = this.buffer.slice(start, i);\n if (ch === '\\r') {\n if (i + 1 < this.buffer.length) {\n if (this.buffer[i + 1] === '\\n') i++;\n } else {\n // A CR at the end of the chunk may be the first half of CRLF.\n this.pendingCR = true;\n }\n }\n this.processLine(line, out);\n start = i + 1;\n }\n this.buffer = this.buffer.slice(start);\n return out;\n }\n\n /** End of stream. An unterminated final event is discarded, as the spec requires. */\n end(): SSEMessage[] {\n this.buffer = '';\n this.data = [];\n this.event = '';\n return [];\n }\n\n private processLine(line: string, out: SSEMessage[]): void {\n if (line === '') {\n this.dispatch(out);\n return;\n }\n if (line.startsWith(':')) return;\n const colon = line.indexOf(':');\n const field = colon === -1 ? line : line.slice(0, colon);\n let value = colon === -1 ? '' : line.slice(colon + 1);\n if (value.startsWith(' ')) value = value.slice(1);\n switch (field) {\n case 'data':\n this.data.push(value);\n break;\n case 'event':\n this.event = value;\n break;\n case 'id':\n if (!value.includes('\\u0000')) this.lastId = value;\n break;\n case 'retry':\n if (/^\\d+$/.test(value)) this.retry = Number(value);\n break;\n default:\n break;\n }\n }\n\n private dispatch(out: SSEMessage[]): void {\n if (this.data.length === 0) {\n this.event = '';\n return;\n }\n const message: SSEMessage = { event: this.event || 'message', data: this.data.join('\\n') };\n if (this.lastId !== undefined) message.id = this.lastId;\n if (this.retry !== undefined) message.retry = this.retry;\n out.push(message);\n this.data = [];\n this.event = '';\n }\n}\n\n/** Decode a byte stream (e.g. `fetch().body`) into SSE messages. */\nexport async function* readSSE(\n body: AsyncIterable<Uint8Array | string>,\n): AsyncGenerator<SSEMessage> {\n const parser = new SSEParser();\n const decoder = new TextDecoder();\n for await (const chunk of body) {\n const text = typeof chunk === 'string' ? chunk : decoder.decode(chunk, { stream: true });\n yield* parser.push(text);\n }\n const tail = decoder.decode();\n if (tail) yield* parser.push(tail);\n yield* parser.end();\n}\n\n/** An error frame (`data: {\"error\": …}`) sent by the gateway after a stream started. */\nexport class ChatStreamError extends Error {\n readonly code: string | undefined;\n\n constructor(message: string, code?: string | null) {\n super(message);\n this.name = 'ChatStreamError';\n this.code = code ?? undefined;\n }\n}\n\n/** OpenAI-style completion chunks from SSE messages, until `data: [DONE]`. */\nexport async function* chatChunks(\n messages: AsyncIterable<SSEMessage>,\n): AsyncGenerator<ChatCompletionChunk> {\n for await (const message of messages) {\n if (message.data === '[DONE]') return;\n let parsed: unknown;\n try {\n parsed = JSON.parse(message.data);\n } catch {\n continue;\n }\n if (!parsed || typeof parsed !== 'object') continue;\n const record = parsed as {\n error?: { message?: string; code?: string | null };\n choices?: unknown;\n };\n if (record.error && !record.choices) {\n throw new ChatStreamError(record.error.message ?? 'Upstream error', record.error.code);\n }\n if (Array.isArray(record.choices)) yield parsed as ChatCompletionChunk;\n }\n}\n\n/** Typed DaveCode events from `/api/events`. Malformed frames are skipped. */\nexport async function* daveEvents(messages: AsyncIterable<SSEMessage>): AsyncGenerator<DaveEvent> {\n for await (const message of messages) {\n try {\n const event = JSON.parse(message.data) as DaveEvent;\n if (event && typeof event.type === 'string') yield event;\n } catch {\n // ignore\n }\n }\n}\n","import type { ChatCompletionChunk, ChatRequest, DaveConfig, DaveEvent } from '@davecode/core';\nimport { chatChunks, daveEvents, readSSE } from './sse';\n\n/**\n * Thin HTTP client for a running DaveCode gateway (`/api/*`, `/v1/*`). Used by `status`,\n * `accounts`, the chat TUI and the runner view. Never logs request bodies (they may carry\n * account secrets).\n */\n\nexport interface GatewayTarget {\n /** e.g. `http://127.0.0.1:4040` (no trailing slash). */\n baseUrl: string;\n token?: string;\n}\n\nexport interface HealthResponse {\n status: string;\n version: string;\n uptimeSec: number;\n experimental: { geminiWeb: boolean; multiAccountRotation: boolean };\n}\n\nexport type FetchLike = typeof fetch;\n\n/** An `/api` or `/v1` error response, or a transport failure (`status` 0). */\nexport class GatewayError extends Error {\n readonly status: number;\n readonly code: string;\n\n constructor(status: number, code: string, message: string) {\n super(message);\n this.name = 'GatewayError';\n this.status = status;\n this.code = code;\n }\n}\n\nconst WILDCARD_HOSTS = new Set(['0.0.0.0', '::', '[::]', '']);\n\n/** Host to connect to for a configured bind address (wildcards resolve to loopback). */\nexport function connectHost(host: string): string {\n if (WILDCARD_HOSTS.has(host)) return '127.0.0.1';\n if (host.includes(':') && !host.startsWith('[')) return `[${host}]`;\n return host;\n}\n\nexport function targetFor(config: DaveConfig, port = config.server.port): GatewayTarget {\n const target: GatewayTarget = { baseUrl: `http://${connectHost(config.server.host)}:${port}` };\n if (config.server.authToken) target.token = config.server.authToken;\n return target;\n}\n\nasync function errorFrom(res: Response): Promise<GatewayError> {\n let code = `http_${res.status}`;\n let message = `${res.status} ${res.statusText}`.trim();\n try {\n const body = (await res.json()) as { error?: { message?: string; code?: string | null } };\n if (body.error?.message) message = body.error.message;\n if (body.error?.code) code = body.error.code;\n } catch {\n // Not JSON; keep the status line.\n }\n return new GatewayError(res.status, code, message);\n}\n\nexport interface RequestOptions {\n signal?: AbortSignal;\n timeoutMs?: number;\n}\n\nexport class GatewayClient {\n readonly baseUrl: string;\n private readonly token: string | undefined;\n private readonly fetchImpl: FetchLike;\n\n constructor(target: GatewayTarget, fetchImpl: FetchLike = fetch) {\n this.baseUrl = target.baseUrl.replace(/\\/+$/, '');\n this.token = target.token;\n this.fetchImpl = fetchImpl;\n }\n\n headers(extra: Record<string, string> = {}): Record<string, string> {\n return this.token ? { authorization: `Bearer ${this.token}`, ...extra } : extra;\n }\n\n /** Low-level fetch with auth, an optional timeout and transport errors as `GatewayError`. */\n async fetch(path: string, init: RequestInit = {}, options: RequestOptions = {}) {\n const signals: AbortSignal[] = [];\n if (options.signal) signals.push(options.signal);\n if (options.timeoutMs !== undefined) signals.push(AbortSignal.timeout(options.timeoutMs));\n const signal = signals.length > 1 ? AbortSignal.any(signals) : signals[0];\n try {\n return await this.fetchImpl(`${this.baseUrl}${path}`, {\n ...init,\n headers: this.headers((init.headers as Record<string, string> | undefined) ?? {}),\n ...(signal ? { signal } : {}),\n });\n } catch (err) {\n if (options.signal?.aborted) throw err;\n const reason = err instanceof Error ? err.message : String(err);\n throw new GatewayError(\n 0,\n 'unreachable',\n `Cannot reach the gateway at ${this.baseUrl} (${reason})`,\n );\n }\n }\n\n async request<T>(\n method: string,\n path: string,\n body?: unknown,\n options: RequestOptions = {},\n ): Promise<T> {\n const init: RequestInit = { method };\n // State-changing requests always declare JSON, even without a body (the gateway requires it).\n if (body !== undefined) init.body = JSON.stringify(body);\n if (body !== undefined || method !== 'GET')\n init.headers = { 'content-type': 'application/json' };\n const res = await this.fetch(path, init, { timeoutMs: 10_000, ...options });\n if (!res.ok) throw await errorFrom(res);\n if (res.status === 204) return undefined as T;\n return (await res.json()) as T;\n }\n\n get<T>(path: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('GET', path, undefined, options);\n }\n\n post<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T> {\n return this.request<T>('POST', path, body, options);\n }\n\n patch<T>(path: string, body: unknown, options?: RequestOptions): Promise<T> {\n return this.request<T>('PATCH', path, body, options);\n }\n\n delete(path: string, options?: RequestOptions): Promise<void> {\n return this.request<void>('DELETE', path, undefined, options);\n }\n\n /**\n * `GET /api/health`, or `undefined` when nothing (or something that is not DaveCode) answers.\n * Throws `GatewayError` 401 when a gateway is running but rejects our bearer token.\n */\n async health(timeoutMs = 800): Promise<HealthResponse | undefined> {\n let res: Response;\n try {\n res = await this.fetch('/api/health', {}, { timeoutMs });\n } catch {\n return undefined;\n }\n if (res.status === 401) {\n throw new GatewayError(\n 401,\n 'unauthorized',\n `The gateway at ${this.baseUrl} requires a bearer token`,\n );\n }\n if (!res.ok) return undefined;\n try {\n const body = (await res.json()) as Partial<HealthResponse>;\n return body.status === 'ok' && typeof body.version === 'string'\n ? (body as HealthResponse)\n : undefined;\n } catch {\n return undefined;\n }\n }\n /**\n * `POST /v1/chat/completions` with `stream: true`. Resolves once the gateway answered (after\n * routing and any failover), so `meta` already names the serving account.\n */\n async chatStream(\n request: ChatRequest,\n signal?: AbortSignal,\n ): Promise<{ meta: StreamMeta; chunks: AsyncIterable<ChatCompletionChunk> }> {\n const res = await this.fetch(\n '/v1/chat/completions',\n {\n method: 'POST',\n headers: { 'content-type': 'application/json', accept: 'text/event-stream' },\n body: JSON.stringify({ ...request, stream: true }),\n },\n signal ? { signal } : {},\n );\n if (!res.ok) throw await errorFrom(res);\n return { meta: streamMeta(res.headers), chunks: chatChunks(readSSE(bodyOf(res))) };\n }\n\n /** Live `/api/events` (the server replays its recent buffer first). */\n async *events(signal?: AbortSignal): AsyncGenerator<DaveEvent> {\n const res = await this.fetch(\n '/api/events',\n { headers: { accept: 'text/event-stream' } },\n signal ? { signal } : {},\n );\n if (!res.ok) throw await errorFrom(res);\n yield* daveEvents(readSSE(bodyOf(res)));\n }\n}\n\n/** Routing details the gateway reports in `x-davecode-*` response headers. */\nexport interface StreamMeta {\n requestId?: string;\n accountId?: string;\n provider?: string;\n failovers: number;\n}\n\nexport function streamMeta(headers: Headers): StreamMeta {\n const meta: StreamMeta = { failovers: Number(headers.get('x-davecode-failovers') ?? 0) || 0 };\n const requestId = headers.get('x-davecode-request-id');\n const accountId = headers.get('x-davecode-account');\n const provider = headers.get('x-davecode-provider');\n if (requestId) meta.requestId = requestId;\n if (accountId) meta.accountId = accountId;\n if (provider) meta.provider = provider;\n return meta;\n}\n\nfunction bodyOf(res: Response): AsyncIterable<Uint8Array> {\n if (!res.body) throw new GatewayError(res.status, 'empty_body', 'The gateway sent no body');\n return res.body as unknown as AsyncIterable<Uint8Array>;\n}\n\n/** A client for the configured gateway if one is answering `/api/health`, else `undefined`. */\nexport async function findGateway(\n config: DaveConfig,\n options: { port?: number; fetch?: FetchLike; timeoutMs?: number } = {},\n): Promise<{ client: GatewayClient; health: HealthResponse } | undefined> {\n const client = new GatewayClient(targetFor(config, options.port), options.fetch);\n const health = await client.health(options.timeoutMs);\n return health ? { client, health } : undefined;\n}\n","import { spawn as nodeSpawn, type SpawnOptions } from 'node:child_process';\nimport { which } from './proc';\n\nexport type DetachedSpawn = (\n command: string,\n args: readonly string[],\n options: SpawnOptions,\n) => {\n once(event: 'spawn', listener: () => void): unknown;\n once(event: 'error', listener: (err: Error) => void): unknown;\n unref(): void;\n};\n\nexport interface TerminalOptions {\n /** Override the CLI entry point when hosted by a bundled desktop runtime. */\n argv?: readonly string[];\n platform?: NodeJS.Platform;\n env?: NodeJS.ProcessEnv;\n spawn?: DetachedSpawn;\n}\n\n/** A program and its arguments, run in a new terminal window. */\nexport interface TerminalCommand {\n command: string;\n args: string[];\n}\n\nconst SAFE_ACCOUNT_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;\n\n/** `davecode accounts login <id> --hold`, using this same Node binary and CLI entry point. */\nexport function loginInvocation(\n accountId: string,\n argv: readonly string[] = process.argv,\n): string[] {\n if (!SAFE_ACCOUNT_ID.test(accountId)) throw new Error('Invalid account id');\n const entry = argv[1];\n if (!entry) throw new Error('Cannot locate the davecode entry point');\n return [process.execPath, entry, 'accounts', 'login', accountId, '--hold'];\n}\n\nfunction posixQuote(arg: string): string {\n return `'${arg.replace(/'/g, `'\\\\''`)}'`;\n}\n\n/** Linux terminal emulators and how each takes a command to run. */\nconst LINUX_TERMINALS: Array<{ bin: string; flag: string[] }> = [\n { bin: 'x-terminal-emulator', flag: ['-e'] },\n { bin: 'gnome-terminal', flag: ['--'] },\n { bin: 'konsole', flag: ['-e'] },\n { bin: 'xfce4-terminal', flag: ['-x'] },\n { bin: 'xterm', flag: ['-e'] },\n];\n\n/**\n * How to open `argv` in a new terminal window on this platform, or `undefined` when no\n * terminal can be opened (headless Linux, unsafe characters for cmd.exe).\n */\nexport function terminalCommand(\n argv: readonly string[],\n options: Pick<TerminalOptions, 'platform' | 'env'> = {},\n): TerminalCommand | undefined {\n const platform = options.platform ?? process.platform;\n const env = options.env ?? process.env;\n if (platform === 'win32') {\n // cmd.exe expands %VAR% even inside quotes and quotes cannot be escaped, so refuse both.\n if (argv.some((a) => /[\"%\\r\\n]/.test(a))) return undefined;\n const line = argv.map((a) => `\"${a}\"`).join(' ');\n return {\n command: env.ComSpec ?? env.COMSPEC ?? 'cmd.exe',\n args: ['/d', '/c', `start \"DaveCode login\" ${line}`],\n };\n }\n if (platform === 'darwin') {\n const script = argv.map(posixQuote).join(' ').replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n return {\n command: 'osascript',\n args: [\n '-e',\n `tell application \"Terminal\" to do script \"${script}\"`,\n '-e',\n 'tell application \"Terminal\" to activate',\n ],\n };\n }\n if (!env.DISPLAY && !env.WAYLAND_DISPLAY) return undefined;\n for (const terminal of LINUX_TERMINALS) {\n if (which(terminal.bin, env, platform)) {\n return { command: terminal.bin, args: [...terminal.flag, ...argv] };\n }\n }\n return undefined;\n}\n\n/**\n * Open a terminal window on this machine running the official vendor login for an account\n * (via `davecode accounts login`). Resolves `false` when no window could be opened.\n */\nexport function launchLoginTerminal(\n accountId: string,\n options: TerminalOptions = {},\n): Promise<boolean> {\n const platform = options.platform ?? process.platform;\n const target = terminalCommand(loginInvocation(accountId, options.argv), options);\n if (!target) return Promise.resolve(false);\n const spawn = options.spawn ?? (nodeSpawn as unknown as DetachedSpawn);\n return new Promise((resolve) => {\n try {\n const child = spawn(target.command, target.args, {\n detached: true,\n stdio: 'ignore',\n env: options.env ?? process.env,\n ...(platform === 'win32' ? { windowsVerbatimArguments: true } : {}),\n });\n child.once('spawn', () => {\n child.unref();\n resolve(true);\n });\n child.once('error', () => resolve(false));\n } catch {\n resolve(false);\n }\n });\n}\n","import { spawn as nodeSpawn, type SpawnOptions } from 'node:child_process';\nimport { existsSync, statSync } from 'node:fs';\nimport path from 'node:path';\n\n/** Split PATH, keeping Windows drive-letter prefixes when the delimiter is `:`. */\nexport function splitPathEnv(pathEnv: string, delimiter: string): string[] {\n if (delimiter === ';') return pathEnv.split(';').filter(Boolean);\n const dirs: string[] = [];\n let pendingDrive: string | undefined;\n for (const piece of pathEnv.split(':')) {\n if (pendingDrive !== undefined) {\n dirs.push(`${pendingDrive}:${piece}`);\n pendingDrive = undefined;\n continue;\n }\n if (/^[A-Za-z]$/.test(piece)) {\n pendingDrive = piece;\n continue;\n }\n if (piece) dirs.push(piece);\n }\n if (pendingDrive !== undefined) dirs.push(pendingDrive);\n return dirs;\n}\n\n/**\n * Locate `command` on PATH (honouring PATHEXT on Windows, preferring `.exe` over `.cmd` shims).\n * Paths containing a separator are returned as-is when they exist.\n */\nexport function which(\n command: string,\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform = process.platform,\n): string | undefined {\n const isFile = (p: string) => {\n try {\n return existsSync(p) && statSync(p).isFile();\n } catch {\n return false;\n }\n };\n if (command.includes('/') || command.includes('\\\\') || path.isAbsolute(command)) {\n return isFile(command) ? command : undefined;\n }\n const win = platform === 'win32';\n const delimiter = win ? ';' : ':';\n // When tests simulate linux/darwin on a Windows host, PATH still has drive letters\n // (`C:\\tmp\\bin`). Splitting only on `:` would yield `C` + `\\tmp\\bin`.\n const dirs = splitPathEnv(env.PATH ?? env.Path ?? '', delimiter);\n const exts = win\n ? [\n '.exe',\n '.com',\n '',\n ...(env.PATHEXT ?? '.COM;.EXE;.BAT;.CMD')\n .split(';')\n .map((e) => e.toLowerCase())\n .filter((e) => e && e !== '.exe' && e !== '.com'),\n ]\n : [''];\n for (const dir of dirs) {\n for (const ext of exts) {\n const candidate = path.join(dir, command + ext);\n if (isFile(candidate)) return candidate;\n }\n }\n return undefined;\n}\n\n/** Characters cmd.exe never interprets, so such arguments need no escaping. */\nconst SHELL_SAFE = /^[\\w.:=@+\\-/\\\\[\\]]+$/;\n\nexport type SpawnFn = (\n command: string,\n args: readonly string[],\n options: SpawnOptions,\n) => {\n on(\n event: 'exit',\n listener: (code: number | null, signal: NodeJS.Signals | null) => void,\n ): unknown;\n on(event: 'error', listener: (err: Error) => void): unknown;\n};\n\nexport interface InteractiveOptions {\n env: NodeJS.ProcessEnv;\n cwd?: string;\n spawn?: SpawnFn;\n platform?: NodeJS.Platform;\n}\n\n/**\n * Run a command attached to this terminal (`stdio: 'inherit'`) and resolve with its exit code.\n * Windows `.cmd`/`.bat` shims (npm-installed CLIs) need a shell; their arguments must then be\n * shell-safe, which is checked rather than escaped.\n */\nexport function spawnInteractive(\n command: string,\n args: string[],\n options: InteractiveOptions,\n): Promise<number> {\n const spawn = options.spawn ?? (nodeSpawn as unknown as SpawnFn);\n const platform = options.platform ?? process.platform;\n const shim = platform === 'win32' && /\\.(cmd|bat)$/i.test(command);\n if (shim) {\n const unsafe = args.find((a) => !SHELL_SAFE.test(a));\n if (unsafe !== undefined) {\n return Promise.reject(\n new Error(`Argument ${JSON.stringify(unsafe)} cannot be passed safely to ${command}`),\n );\n }\n }\n return new Promise((resolve, reject) => {\n const child = shim\n ? spawn(`\"${command}\"`, args, {\n stdio: 'inherit',\n env: options.env,\n shell: true,\n ...(options.cwd ? { cwd: options.cwd } : {}),\n })\n : spawn(command, args, {\n stdio: 'inherit',\n env: options.env,\n ...(options.cwd ? { cwd: options.cwd } : {}),\n });\n child.on('error', reject);\n child.on('exit', (code, signal) => resolve(code ?? (signal ? 130 : 1)));\n });\n}\n"],"mappings":"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","names":["existsSync","resolve","z","z","z","z","z","path","path","nodeSpawn","existsSync","resolve","nodeSpawn","resolve","path","resolve","existsSync","account"]}
@@ -14,7 +14,7 @@ import {
14
14
  detectProjectRoot,
15
15
  findGateway,
16
16
  targetFor
17
- } from "./chunk-YSD6W27K.js";
17
+ } from "./chunk-TP3ORSHY.js";
18
18
  import {
19
19
  EXIT
20
20
  } from "./chunk-7XVXEO7U.js";
@@ -22,7 +22,7 @@ import {
22
22
  QUOTA_WINDOWS,
23
23
  createEngine,
24
24
  loadConfig
25
- } from "./chunk-ING5HCIO.js";
25
+ } from "./chunk-2XGDILCW.js";
26
26
 
27
27
  // src/commands/status.ts
28
28
  function emptyUsage(accountId) {
@@ -210,4 +210,4 @@ export {
210
210
  renderStatus,
211
211
  statusCommand
212
212
  };
213
- //# sourceMappingURL=chunk-ZVNX7CSO.js.map
213
+ //# sourceMappingURL=chunk-U5CI774J.js.map
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-QA3O6RA2.js";
7
7
  import {
8
8
  detectProjectRoot
9
- } from "./chunk-YSD6W27K.js";
9
+ } from "./chunk-TP3ORSHY.js";
10
10
  import {
11
11
  CliError,
12
12
  EXIT
@@ -16,7 +16,7 @@ import {
16
16
  globalPaths,
17
17
  loadConfig,
18
18
  projectPaths
19
- } from "./chunk-ING5HCIO.js";
19
+ } from "./chunk-2XGDILCW.js";
20
20
  import "./chunk-MC7RIPL7.js";
21
21
 
22
22
  // src/commands/config.ts
@@ -156,4 +156,4 @@ export {
156
156
  configPath,
157
157
  configShow
158
158
  };
159
- //# sourceMappingURL=config-DG2E4VDW.js.map
159
+ //# sourceMappingURL=config-ZLO3YOUX.js.map
@@ -0,0 +1 @@
1
+ import{i as e,n as t,o as n,r,t as i}from"./cn-BwE4cei0.js";import{Dt as a,E as o,Et as s,Mt as c,Nt as l,R as u,V as d,_ as f,c as p,d as m,l as h,m as g,v as _,x as v,y}from"./format-328qIBHX.js";import{n as b,t as x}from"./Switch-DPYlLseH.js";import{a as S,c as C,i as w,l as ee,n as te,o as ne,r as T,s as re,t as ie}from"./forms-DVIUAxAc.js";import{t as E}from"./Callout-CqdcH6dC.js";import{t as D}from"./trash-BTuDcSaQ.js";import{A as O,B as ae,E as k,N as A,R as j,T as M,V as N,X as P,_ as F,a as I,d as L,f as R,g as z,i as B,j as V,m as H,n as U,o as W,p as G,r as K,s as q,t as oe,u as J,x as Y}from"./index-C-bwzlsl.js";import{n as X,t as Z}from"./Field-Cmpgg_1z.js";var se={name:`log-in`,size:24,node:[[`path`,{d:`m10 17 5-5-5-5`,key:`1bsop3`}],[`path`,{d:`M15 12H3`,key:`6jk70r`}],[`path`,{d:`M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4`,key:`u53s6r`}]]};se.node;var ce=t(se),le={name:`shield-alert`,size:24,node:[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`M12 8v4`,key:`1got3b`}],[`path`,{d:`M12 16h.01`,key:`1drbdi`}]]};le.node;var ue=t(le),Q=n(e(),1),$=r(),de=3e5,fe={connected:{tone:`ok`,label:`Connected`},not_connected:{tone:`warn`,label:`Not connected`},unknown:{tone:`neutral`,label:`Unknown`}};function pe({status:e}){let{tone:t,label:n}=fe[e];return(0,$.jsx)(Y,{tone:t,dot:!0,children:n})}function me({account:e}){let[t,n]=(0,Q.useState)(null),r=_(e.id,t!==null),i=f(),a=r.data,o=a?.status===`connected`;return(0,Q.useEffect)(()=>{if(!t)return;if(o){n(null),M({tone:`ok`,title:`Subscription connected`,description:e.label});return}let r=window.setTimeout(()=>n(null),de);return()=>window.clearTimeout(r)},[t,o,e.label]),(0,$.jsxs)(`section`,{"aria-label":`Connection`,className:`flex flex-col gap-2.5 rounded-md border border-line bg-raised p-3`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(`p`,{className:`text-[12px] font-medium text-fg-2`,children:`Connection`}),a?(0,$.jsx)(pe,{status:a.status}):r.isError?(0,$.jsx)(Y,{tone:`err`,children:`Check failed`}):(0,$.jsx)(Y,{children:`Checking…`}),(0,$.jsx)(k,{variant:`ghost`,size:`sm`,icon:ae,iconOnly:!0,"aria-label":`Check again`,className:`ml-auto`,loading:r.isFetching&&!t,onClick:()=>r.refetch()})]}),a?.detail&&(0,$.jsx)(`p`,{className:`text-2xs leading-5 text-muted`,children:a.detail}),r.isError&&(0,$.jsx)(`p`,{className:`text-2xs leading-5 text-err`,children:c(r.error)}),a?.method===`cli-login`&&(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,$.jsx)(k,{variant:o?`secondary`:`primary`,size:`sm`,icon:ce,loading:i.isPending,onClick:async()=>{try{n(await i.mutateAsync(e.id))}catch(e){M({tone:`err`,title:`Could not start the sign-in`,description:c(e)})}},children:o?`Sign in again`:`Connect subscription`}),(0,$.jsx)(`span`,{className:`text-2xs text-muted`,children:`Opens the vendor’s official sign-in. DaveCode never sees your password.`})]}),t&&(0,$.jsxs)(E,{tone:`info`,title:t.launched?`Waiting for the sign-in…`:`Run the sign-in on the gateway machine`,children:[(0,$.jsx)(`p`,{children:t.message}),!t.launched&&(0,$.jsx)(G,{command:t.command,className:`mt-2`})]}),!t&&!o&&a.loginCommand&&(0,$.jsx)(G,{command:a.loginCommand})]})]})}function he({account:e,usage:t,onClose:n}){return(0,$.jsx)(R,{open:!!e,onClose:n,title:e?.label??`Account`,description:e&&(0,$.jsx)(`span`,{className:`font-mono`,children:e.id}),width:`w-[min(560px,100vw)]`,children:e&&(0,$.jsx)(ge,{account:e,usage:t,onDone:n},e.id)})}function ge({account:e,usage:t,onDone:n}){let r=u(),i=v(),o=a(e.provider),s=Array.isArray(e.config.models)?e.config.models.join(`, `):``,[l,d]=(0,Q.useState)(e.label),[f,p]=(0,Q.useState)(String(e.priority)),[m,g]=(0,Q.useState)(String(e.weight)),[_,y]=(0,Q.useState)(S(e.limits)),[b,x]=(0,Q.useState)(ee(e.subscription)),[O,ae]=(0,Q.useState)({}),[A,j]=(0,Q.useState)(typeof e.config.baseUrl==`string`?e.config.baseUrl:``),[N,P]=(0,Q.useState)(s),[R,B]=(0,Q.useState)(``),[V,H]=(0,Q.useState)({}),[U,G]=(0,Q.useState)({}),[K,q]=(0,Q.useState)(null),[oe,J]=(0,Q.useState)(!1);return(0,$.jsxs)(`form`,{onSubmit:async t=>{t.preventDefault(),q(null);let i={};l.trim()||(i.label=`Label cannot be empty.`);let a=Number(f);(!Number.isInteger(a)||a<0)&&(i.priority=`Whole number, 0 or more.`);let o=Number(m);(!Number.isFinite(o)||o<=0)&&(i.weight=`Number above 0.`),e.provider===`openai-compatible`&&!w(A.trim())&&(i.baseUrl=`Enter an http(s) URL.`),e.provider===`openai-compatible`&&e.hasSecret&&!R.trim()&&A.trim().replace(/\/+$/,``)!==(typeof e.config.baseUrl==`string`?e.config.baseUrl:``).replace(/\/+$/,``)&&(i.secret=`Enter the API key again to point this account at a different URL.`);let s=ne(_),u=C(b);if(H(i),G(s.errors),ae(u.errors),Object.values(i).some(Boolean)||Object.keys(s.errors).length||Object.keys(u.errors).length)return;let d={};if(l.trim()!==e.label&&(d.label=l.trim()),a!==e.priority&&(d.priority=a),o!==e.weight&&(d.weight=o),JSON.stringify(s.limits)!==JSON.stringify(e.limits)&&(d.limits=s.limits),JSON.stringify(u.subscription??null)!==JSON.stringify(e.subscription??null)&&(d.subscription=u.subscription??null),e.provider===`openai-compatible`){let t=re(N),n={...e.config,baseUrl:A.trim(),models:t.length?t:void 0};JSON.stringify(n)!==JSON.stringify(e.config)&&(d.config=n)}if(R.trim()&&(d.secret=R.trim()),Object.keys(d).length===0)n();else try{await r.mutateAsync({id:e.id,patch:d}),B(``),M({tone:`ok`,title:`Account updated`,description:e.label}),n()}catch(e){B(``),q(c(e))}},noValidate:!0,className:`flex flex-col gap-5`,children:[(0,$.jsxs)(`section`,{"aria-label":`Summary`,className:`flex flex-col gap-3 rounded-md border border-line bg-raised p-3`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2.5`,children:[(0,$.jsx)(F,{provider:e.provider,size:`lg`}),(0,$.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,$.jsx)(`p`,{className:`text-[13px] font-medium text-fg`,children:o.label}),(0,$.jsxs)(`p`,{className:`font-mono text-2xs text-muted`,children:[e.provider,` · updated `,h(Date.parse(e.updatedAt))]})]}),(0,$.jsx)(z,{account:e})]}),e.lastError&&e.status!==`active`&&(0,$.jsx)(`p`,{className:`rounded border border-line bg-panel px-2 py-1.5 font-mono text-2xs text-fg-2`,children:e.lastError}),(0,$.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,$.jsx)(W,{label:`1m`,usage:t?.windows[`1m`]}),(0,$.jsx)(W,{label:`5h`,usage:t?.windows[`5h`]}),(0,$.jsx)(W,{label:`24h`,usage:t?.windows[`24h`]}),(0,$.jsx)(I,{className:`pl-9`})]})]}),(0,$.jsx)(me,{account:e}),(0,$.jsx)(Z,{label:`Label`,required:!0,error:V.label,children:({id:e,describedBy:t,invalid:n})=>(0,$.jsx)(X,{id:e,value:l,onChange:e=>d(e.target.value),"aria-describedby":t,"aria-invalid":n||void 0})}),(0,$.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,$.jsx)(Z,{label:`Priority`,error:V.priority,hint:`Lower is tried first.`,children:({id:e,describedBy:t,invalid:n})=>(0,$.jsx)(X,{id:e,inputMode:`numeric`,value:f,onChange:e=>p(e.target.value),"aria-describedby":t,"aria-invalid":n||void 0,className:`tnum font-mono`})}),(0,$.jsx)(Z,{label:`Weight`,error:V.weight,hint:`Share among equal priorities.`,children:({id:e,describedBy:t,invalid:n})=>(0,$.jsx)(X,{id:e,inputMode:`decimal`,value:m,onChange:e=>g(e.target.value),"aria-describedby":t,"aria-invalid":n||void 0,className:`tnum font-mono`})})]}),e.provider===`openai-compatible`&&(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(Z,{label:`Base URL`,required:!0,error:V.baseUrl,children:({id:e,describedBy:t,invalid:n})=>(0,$.jsx)(X,{id:e,type:`url`,value:A,onChange:e=>j(e.target.value),"aria-describedby":t,"aria-invalid":n||void 0,className:`font-mono`})}),(0,$.jsx)(Z,{label:`Models`,hint:`Comma-separated allow-list.`,children:({id:e,describedBy:t})=>(0,$.jsx)(X,{id:e,value:N,onChange:e=>P(e.target.value),"aria-describedby":t,className:`font-mono`})})]}),(o.auth===`api-key`||o.auth===`optional-key`)&&(0,$.jsx)(Z,{label:`Replace ${(o.secretLabel??`secret`).replace(` (optional)`,``)}`,error:V.secret,hint:e.hasSecret===!1?`No secret stored yet. Write-only: it is encrypted at rest and never displayed.`:`A secret is stored. Write-only: leave empty to keep it; it is never displayed.`,children:({id:e,describedBy:t})=>(0,$.jsx)(te,{id:e,value:R,onChange:B,placeholder:`••••••••••••`,describedBy:t})}),(0,$.jsxs)(`fieldset`,{className:`flex flex-col gap-2`,children:[(0,$.jsx)(`legend`,{className:`mb-2 text-[12px] font-medium text-fg-2`,children:`Quota limits`}),(0,$.jsx)(ie,{value:_,onChange:y,errors:U})]}),(0,$.jsxs)(`fieldset`,{className:`flex flex-col gap-2`,children:[(0,$.jsx)(`legend`,{className:`mb-1 text-[12px] font-medium text-fg-2`,children:`Subscription`}),(0,$.jsx)(`p`,{className:`mb-1 text-2xs text-muted`,children:`What you pay for this account. Entered by hand; DaveCode never reads billing pages. Agents see the plan, renewal and remaining budget, never secrets.`}),(0,$.jsx)(T,{value:b,onChange:x,errors:O})]}),Object.keys(e.config).length>0&&e.provider!==`openai-compatible`&&(0,$.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,$.jsx)(`p`,{className:`text-[12px] font-medium text-fg-2`,children:`Provider config`}),(0,$.jsx)(`pre`,{className:`overflow-x-auto rounded-md border border-line bg-raised p-2.5 font-mono text-2xs leading-5 text-fg-2`,children:JSON.stringify(e.config,null,2)})]}),K&&(0,$.jsx)(E,{tone:`err`,title:`Request failed`,children:K}),(0,$.jsxs)(`div`,{className:`sticky -bottom-4 -mx-5 -mb-4 flex items-center gap-2 border-t border-line bg-panel px-5 py-3`,children:[(0,$.jsx)(k,{variant:`danger`,icon:D,onClick:()=>J(!0),children:`Delete`}),(0,$.jsxs)(`div`,{className:`ml-auto flex gap-2`,children:[(0,$.jsx)(k,{variant:`ghost`,onClick:n,children:`Cancel`}),(0,$.jsx)(k,{type:`submit`,variant:`primary`,loading:r.isPending,children:`Save changes`})]})]}),(0,$.jsx)(L,{open:oe,onClose:()=>J(!1),title:`Delete ${e.label}?`,description:`The account and its encrypted secret are removed from the gateway. Requests already served stay in the usage history.`,footer:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(k,{variant:`ghost`,onClick:()=>J(!1),children:`Keep account`}),(0,$.jsx)(k,{variant:`danger`,icon:D,loading:i.isPending,onClick:async()=>{try{await i.mutateAsync(e.id),M({tone:`ok`,title:`Account removed`,description:e.label}),J(!1),n()}catch(e){J(!1),q(c(e))}},children:`Delete account`})]}),children:(0,$.jsx)(`p`,{className:`font-mono text-[12px] text-muted`,children:e.id})})]})}var _e={"claude-cli":{binary:`claude`,env:`CLAUDE_CONFIG_DIR`},"codex-cli":{binary:`codex`,env:`CODEX_HOME`},"gemini-cli":{binary:`gemini`,env:`GEMINI_CLI_HOME`}};function ve({open:e,onClose:t}){return(0,$.jsx)(R,{open:e,onClose:t,title:`Add account`,description:`Secrets are encrypted at rest with AES-256-GCM and are never shown again after saving.`,width:`w-[min(560px,100vw)]`,children:e&&(0,$.jsx)(ye,{onDone:t})})}function ye({onDone:e}){let t=o(),n=m(),r=y(),u=t.data?.experimental.geminiWeb??!1,d=t.data?.experimental.multiAccountRotation??!1,[f,p]=(0,Q.useState)(`anthropic`),[h,g]=(0,Q.useState)(``),[_,v]=(0,Q.useState)(``),[b,x]=(0,Q.useState)(``),[C,ee]=(0,Q.useState)(``),[T,D]=(0,Q.useState)(`100`),[O,ae]=(0,Q.useState)(`1`),[A,j]=(0,Q.useState)(S()),[N,P]=(0,Q.useState)(!1),[I,L]=(0,Q.useState)({}),[R,z]=(0,Q.useState)(null),B=a(f),V=(n.data??[]).filter(e=>e.provider===f),H=B.subscription&&V.length>0&&!d,U=f===`gemini-web`&&!u;return(0,$.jsxs)(`form`,{onSubmit:async t=>{t.preventDefault(),z(null);let n={};h.trim()||(n.label=`Give the account a name you will recognise in logs.`),B.auth===`api-key`&&!_.trim()&&(n.secret=`${B.secretLabel??`Secret`} is required.`),f===`openai-compatible`&&!w(b.trim())&&(n.baseUrl=`Enter an http(s) URL ending in the /v1 base, e.g. http://127.0.0.1:11434/v1`);let i=Number(T);(!Number.isInteger(i)||i<0)&&(n.priority=`Whole number, 0 or more.`);let a=Number(O);(!Number.isFinite(a)||a<=0)&&(n.weight=`Number above 0.`),f===`gemini-web`&&!N&&(n.ack=`Confirm that you accept the risk.`);let o=ne(A);if(Object.keys(o.errors).length&&(n.limits=o.errors),L(n),Object.keys(n).length||U)return;let s={};if(f===`openai-compatible`){s.baseUrl=b.trim();let e=re(C);e.length&&(s.models=e)}let u={provider:f,label:h.trim(),priority:i,weight:a,...Object.keys(o.limits).length&&{limits:o.limits},...Object.keys(s).length&&{config:s},..._.trim()&&{secret:_.trim()}};try{let t=await r.mutateAsync(u);v(``),M({tone:`ok`,title:`Account added`,description:`${t.label} (${t.id})`}),e()}catch(e){v(``),z(l(e)&&e.code===`experimental_disabled`?`The gateway refused this provider: experimental.geminiWeb is off in config.json.`:c(e))}},noValidate:!0,className:`flex flex-col gap-5`,children:[(0,$.jsxs)(`fieldset`,{children:[(0,$.jsx)(`legend`,{className:`mb-2 text-[12px] font-medium text-fg-2`,children:`Provider`}),(0,$.jsx)(`div`,{className:`grid grid-cols-2 gap-2`,children:s.map(e=>{let t=a(e),n=e===`gemini-web`&&!u,r=f===e;return(0,$.jsxs)(`label`,{className:i(`relative flex cursor-pointer items-start gap-2.5 rounded-md border p-2.5 transition-colors duration-150`,`has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-accent`,r?`border-accent/60 bg-accent-soft`:`border-line hover:border-line-strong hover:bg-hover`,n&&!r&&`opacity-60`),children:[(0,$.jsx)(`input`,{type:`radio`,name:`provider`,value:e,checked:r,onChange:()=>{p(e),L({}),z(null)},className:`sr-only`}),(0,$.jsx)(F,{provider:e}),(0,$.jsxs)(`span`,{className:`min-w-0`,children:[(0,$.jsxs)(`span`,{className:`flex items-center gap-1.5 text-[13px] font-medium text-fg`,children:[t.label,t.experimental&&(0,$.jsx)(`span`,{className:`rounded border border-warn/30 px-1 text-2xs font-medium text-warn`,children:n?`off`:`experimental`})]}),(0,$.jsx)(`span`,{className:`block font-mono text-2xs text-muted`,children:e})]})]},e)})}),(0,$.jsx)(`p`,{className:`mt-2 text-[12px] text-muted`,children:B.blurb})]}),f===`gemini-web`&&(0,$.jsxs)(E,{tone:`warn`,title:`Terms of Service risk`,children:[(0,$.jsx)(`p`,{children:`This provider automates a consumer Gemini web session through Chromium. That likely violates Google's Terms of Service and the account can be rate-limited or suspended.`}),u?(0,$.jsxs)(`label`,{className:`mt-2 flex items-start gap-2 text-fg`,children:[(0,$.jsx)(`input`,{type:`checkbox`,checked:N,onChange:e=>P(e.target.checked),className:`mt-0.5 accent-accent`,"aria-describedby":I.ack?`ack-error`:void 0}),`I understand the risk and want to add this account anyway.`]}):(0,$.jsxs)(`p`,{className:`mt-1.5`,children:[`It is disabled on this gateway. To opt in, set`,` `,(0,$.jsxs)(`code`,{className:`font-mono text-fg`,children:[`"experimental": `,`{ "geminiWeb": true }`]}),` `,`in `,(0,$.jsx)(`code`,{className:`font-mono text-fg`,children:`~/.davecode/config.json`}),` and restart.`]}),I.ack&&(0,$.jsx)(`p`,{id:`ack-error`,role:`alert`,className:`mt-1 text-err`,children:I.ack})]}),H&&(0,$.jsxs)(E,{tone:`info`,title:`Multi-account rotation is off`,children:[`You already have a `,B.label,` account. Without`,` `,(0,$.jsx)(`code`,{className:`font-mono text-fg`,children:`experimental.multiAccountRotation`}),` the router uses only one subscription login per provider; the others act as manual fallbacks.`]}),!U&&(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(Z,{label:`Label`,required:!0,error:I.label,hint:`Shown in the dashboard, logs and events.`,children:({id:e,describedBy:t,invalid:n})=>(0,$.jsx)(X,{id:e,value:h,placeholder:f===`openai-compatible`?`OpenRouter`:`${B.label} — work`,onChange:e=>g(e.target.value),"aria-describedby":t,"aria-invalid":n||void 0,"aria-required":!0})}),f===`openai-compatible`&&(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(Z,{label:`Base URL`,required:!0,error:I.baseUrl,hint:`The OpenAI-compatible root, including /v1.`,children:({id:e,describedBy:t,invalid:n})=>(0,$.jsx)(X,{id:e,type:`url`,value:b,placeholder:`http://127.0.0.1:11434/v1`,onChange:e=>x(e.target.value),"aria-describedby":t,"aria-invalid":n||void 0,className:`font-mono`})}),(0,$.jsx)(Z,{label:`Models`,hint:`Comma-separated allow-list. Leave empty to discover via /v1/models.`,children:({id:e,describedBy:t})=>(0,$.jsx)(X,{id:e,value:C,placeholder:`Provider model IDs`,onChange:e=>ee(e.target.value),"aria-describedby":t,className:`font-mono`})})]}),B.auth===`cli`?(0,$.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,$.jsxs)(`p`,{className:`text-[12px] text-muted`,children:[`DaveCode runs the`,` `,(0,$.jsx)(`span`,{className:`font-mono text-fg`,children:_e[f]?.binary}),` found on your PATH. To use another binary, add the account from a terminal with`,` `,(0,$.jsx)(`span`,{className:`font-mono text-fg`,children:`--binary-path`}),`. No secret is needed here. After adding, open the account and press`,` `,(0,$.jsx)(`span`,{className:`text-fg-2`,children:`Connect subscription`}),`: it runs the vendor’s official sign-in inside the account’s own sandbox (`,_e[f]?.env,`). DaveCode never sees your password. From a terminal:`]}),(0,$.jsx)(G,{command:`davecode add-account --provider ${f}`})]}):B.auth===`browser`?null:(0,$.jsx)(Z,{label:B.secretLabel??`Secret`,required:B.auth===`api-key`,error:I.secret,hint:`Write-only. Encrypted at rest; no endpoint ever returns it.`,children:({id:e,describedBy:t,invalid:n})=>(0,$.jsx)(te,{id:e,value:_,onChange:v,placeholder:B.secretPlaceholder,describedBy:t,invalid:n})}),(0,$.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,$.jsx)(Z,{label:`Priority`,error:I.priority,hint:`Lower is tried first.`,children:({id:e,describedBy:t,invalid:n})=>(0,$.jsx)(X,{id:e,inputMode:`numeric`,value:T,onChange:e=>D(e.target.value),"aria-describedby":t,"aria-invalid":n||void 0,className:`tnum font-mono`})}),(0,$.jsx)(Z,{label:`Weight`,error:I.weight,hint:`Share among equal priorities.`,children:({id:e,describedBy:t,invalid:n})=>(0,$.jsx)(X,{id:e,inputMode:`decimal`,value:O,onChange:e=>ae(e.target.value),"aria-describedby":t,"aria-invalid":n||void 0,className:`tnum font-mono`})})]}),(0,$.jsxs)(`details`,{className:`group rounded-md border border-line`,children:[(0,$.jsxs)(`summary`,{className:`flex items-center justify-between px-3 py-2 text-[12px] font-medium text-fg-2 select-none hover:text-fg`,children:[`Quota limits`,(0,$.jsx)(`span`,{className:`text-2xs font-normal text-muted group-open:hidden`,children:`optional · unlimited by default`})]}),(0,$.jsx)(`div`,{className:`border-t border-line p-3`,children:(0,$.jsx)(ie,{value:A,onChange:j,errors:I.limits??{}})})]})]}),R&&(0,$.jsx)(E,{tone:`err`,title:`Could not add the account`,children:R}),(0,$.jsxs)(`div`,{className:`sticky -bottom-4 -mx-5 -mb-4 flex items-center justify-end gap-2 border-t border-line bg-panel px-5 py-3`,children:[(0,$.jsx)(k,{variant:`ghost`,onClick:e,children:`Cancel`}),(0,$.jsx)(k,{type:`submit`,variant:`primary`,loading:r.isPending,disabled:U,icon:U?ue:void 0,children:U?`Disabled by config`:`Add account`})]})]})}function be(e){if(!e)return;let t=e.price?`${e.price.amount} ${e.price.currency}/${e.price.period===`month`?`mo`:`yr`}`:void 0;return[e.plan,t].filter(Boolean).join(` · `)||void 0}function xe({days:e}){return e===void 0?(0,$.jsx)(`span`,{className:`text-faint`,children:`—`}):e<0?(0,$.jsxs)(Y,{tone:`err`,children:[`overdue `,-e,`d`]}):(0,$.jsx)(Y,{tone:e<=3?`warn`:`neutral`,mono:!0,children:e===0?`today`:`in ${e}d`})}function Se({budget:e}){if(e.remaining===null)return(0,$.jsx)(`span`,{className:`text-2xs text-faint`,children:`no limit known`});let t=e.remaining,n=t<=.1?`bg-err`:t<=.15?`bg-warn`:`bg-meter`;return(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,$.jsx)(`div`,{role:`meter`,"aria-label":`${e.label} remaining budget`,"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":Math.round(t*100),className:`relative h-1.5 min-w-16 flex-1 rounded-full bg-track`,children:(0,$.jsx)(`div`,{className:i(`absolute inset-y-0 left-0 rounded-full transition-[width] duration-500 ease-snappy`,n),style:{width:`${Math.min(100,t*100)}%`}})}),(0,$.jsx)(`span`,{className:`tnum w-9 shrink-0 text-right font-mono text-2xs text-fg-2`,children:p(t)}),(0,$.jsx)(`span`,{className:`w-14 shrink-0 font-mono text-2xs text-muted`,children:e.tightestWindow??`provider`})]})}function Ce(){let e=g(),[t,n]=(0,Q.useState)(!1),r=e.data?.accounts??[],a=r.filter(e=>e.enabled),o=a.filter(e=>e.available).length;return(0,$.jsxs)(K,{"aria-labelledby":`budget-title`,children:[(0,$.jsx)(B,{id:`budget-title`,title:`Budget`,meta:e.data?`${o} of ${a.length} enabled accounts available · plans are entered by hand`:void 0,actions:(0,$.jsx)(k,{size:`sm`,variant:`ghost`,icon:P,"aria-expanded":t,onClick:()=>n(e=>!e),children:`What agents see`})}),e.isPending?(0,$.jsx)(J,{rows:3}):e.isError?(0,$.jsx)(`p`,{className:`px-3.5 py-3 text-[12px] text-err`,children:c(e.error)}):(0,$.jsxs)($.Fragment,{children:[t&&(0,$.jsxs)(`div`,{className:`relative border-b border-line bg-raised px-3.5 py-3`,children:[(0,$.jsx)(H,{value:e.data.context,label:`Copy agent budget context`,className:`absolute top-2 right-2`}),(0,$.jsx)(`pre`,{className:`overflow-x-auto pr-8 font-mono text-2xs leading-5 whitespace-pre-wrap text-fg-2`,children:e.data.context||`No enabled accounts: agents get no budget context.`})]}),(0,$.jsx)(`ul`,{className:`divide-y divide-line`,children:r.map(e=>(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,onClick:()=>O(`account`,e.accountId),className:i(`grid w-full grid-cols-[minmax(0,1.4fr)_minmax(0,1fr)_auto] items-center gap-x-4 gap-y-1.5 px-3.5 py-2.5 text-left transition-colors duration-150 hover:bg-hover/60 md:grid-cols-[minmax(0,1.3fr)_minmax(0,1fr)_5.5rem_minmax(0,1.2fr)_minmax(0,1fr)]`,!e.enabled&&`text-muted`),children:[(0,$.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2`,children:[(0,$.jsx)(F,{provider:e.provider}),(0,$.jsx)(`span`,{className:`truncate text-[13px] font-medium`,children:e.label})]}),(0,$.jsx)(`span`,{className:`truncate text-[12px] text-fg-2`,children:be(e.subscription)??(0,$.jsx)(`span`,{className:`text-faint`,children:`no plan`})}),(0,$.jsx)(`span`,{className:`justify-self-end md:justify-self-start`,children:(0,$.jsx)(xe,{days:e.renewsInDays})}),(0,$.jsx)(`span`,{className:`col-span-2 md:col-span-1`,children:(0,$.jsx)(Se,{budget:e})}),(0,$.jsx)(`span`,{className:`truncate text-[12px] md:text-right`,children:e.available?(0,$.jsx)(Y,{tone:`ok`,dot:!0,children:`available`}):(0,$.jsx)(`span`,{className:`text-warn`,title:e.unavailableReason,children:e.unavailableReason??`unavailable`})})]})},e.accountId))})]})]})}function we(){let e=m(),t=d(),n=u(),{params:r}=V(),[o,s]=(0,Q.useState)(``),[l,f]=(0,Q.useState)(`all`),p=r.get(`account`),h=r.get(`new`)===`1`,g=(0,Q.useMemo)(()=>new Map((t.data??[]).map(e=>[e.accountId,e])),[t.data]),_=(0,Q.useMemo)(()=>[...e.data??[]].sort((e,t)=>e.priority-t.priority||e.label.localeCompare(t.label)),[e.data]),v=(0,Q.useMemo)(()=>{let e={all:_.length,active:0,cooldown:0,disabled:0,error:0};for(let t of _)e[t.status]+=1;return e},[_]),y=o.trim().toLowerCase(),S=_.filter(e=>(l===`all`||e.status===l)&&(!y||e.label.toLowerCase().includes(y)||e.id.toLowerCase().includes(y)||e.provider.includes(y))),C=_.find(e=>e.id===p),w=(e,t)=>{n.mutate({id:e.id,patch:{enabled:t}},{onError:n=>M({tone:`err`,title:`Could not ${t?`enable`:`disable`} ${e.label}`,description:c(n)})})};return(0,$.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,$.jsx)(U,{title:`Accounts`,description:`Provider accounts the router balances across. Lower priority numbers are tried first.`,actions:(0,$.jsx)(k,{variant:`primary`,icon:N,onClick:()=>O(`new`,`1`),children:`Add account`})}),(0,$.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,$.jsxs)(`div`,{className:`relative w-full sm:w-64`,children:[(0,$.jsx)(j,{"aria-hidden":!0,className:`pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2 text-muted`,strokeWidth:1.75}),(0,$.jsx)(X,{type:`search`,"aria-label":`Filter accounts`,placeholder:`Filter by label, id or provider`,value:o,onChange:e=>s(e.target.value),className:`pl-8`,"data-filter-input":!0})]}),(0,$.jsx)(oe,{label:`Status`,value:l,onChange:f,options:[{value:`all`,label:`All`,count:v.all},{value:`active`,label:`Active`,count:v.active},{value:`cooldown`,label:`Cooldown`,count:v.cooldown},{value:`disabled`,label:`Disabled`,count:v.disabled},{value:`error`,label:`Error`,count:v.error}]}),(0,$.jsx)(I,{className:`ml-auto hidden lg:flex`})]}),e.isError&&(0,$.jsx)(E,{tone:`err`,title:`Could not load accounts`,children:c(e.error)}),(0,$.jsx)(K,{children:e.isPending?(0,$.jsx)(J,{rows:5}):_.length===0?(0,$.jsx)(q,{icon:A,title:`No accounts yet`,description:`Add an API key, a local OpenAI-compatible server or a CLI login. The router starts using it immediately.`,command:`davecode add-account`,action:(0,$.jsx)(k,{variant:`primary`,icon:N,onClick:()=>O(`new`,`1`),children:`Add account`})}):S.length===0?(0,$.jsx)(q,{icon:j,title:`No matching accounts`,description:`Try a different filter.`}):(0,$.jsx)(`div`,{className:`overflow-x-auto`,children:(0,$.jsxs)(`table`,{className:`w-full min-w-[880px] text-[13px]`,children:[(0,$.jsx)(`caption`,{className:`sr-only`,children:`Accounts`}),(0,$.jsx)(`thead`,{children:(0,$.jsxs)(`tr`,{className:`border-b border-line text-left text-[12px] text-muted`,children:[(0,$.jsx)(`th`,{scope:`col`,className:`w-[32%] px-3.5 py-2 font-medium`,children:`Account`}),(0,$.jsx)(`th`,{scope:`col`,className:`px-3 py-2 font-medium`,children:`Status`}),(0,$.jsx)(`th`,{scope:`col`,className:`w-20 px-3 py-2 text-right font-medium`,children:`Priority`}),(0,$.jsx)(`th`,{scope:`col`,className:`w-20 px-3 py-2 text-right font-medium`,children:`Weight`}),(0,$.jsx)(`th`,{scope:`col`,className:`w-[30%] px-3 py-2 font-medium`,children:`Quota`}),(0,$.jsx)(`th`,{scope:`col`,className:`w-20 px-3 py-2 font-medium`,children:`Enabled`}),(0,$.jsx)(`th`,{scope:`col`,className:`w-10 px-2 py-2`,children:(0,$.jsx)(`span`,{className:`sr-only`,children:`Details`})})]})}),(0,$.jsx)(`tbody`,{children:S.map(e=>{let t=g.get(e.id),n=a(e.provider);return(0,$.jsxs)(`tr`,{onClick:()=>O(`account`,e.id),className:i(`group cursor-pointer border-b border-line transition-colors duration-150 last:border-b-0 hover:bg-hover/60`,p===e.id&&`bg-hover/60`,!e.enabled&&`text-muted`),children:[(0,$.jsx)(`td`,{className:`max-w-0 px-3.5 py-2.5`,children:(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2.5`,children:[(0,$.jsx)(F,{provider:e.provider}),(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsx)(`button`,{type:`button`,onClick:t=>{t.stopPropagation(),O(`account`,e.id)},className:`block max-w-full truncate text-left font-medium text-fg hover:underline focus-visible:underline`,children:e.label}),(0,$.jsxs)(`p`,{className:`truncate font-mono text-2xs text-muted`,children:[e.id,` · `,n.label,n.experimental&&(0,$.jsx)(`span`,{className:`text-warn`,children:` · experimental`})]})]})]})}),(0,$.jsx)(`td`,{className:`px-3 py-2.5`,children:(0,$.jsx)(z,{account:e})}),(0,$.jsx)(`td`,{className:`tnum px-3 py-2.5 text-right font-mono`,children:e.priority}),(0,$.jsx)(`td`,{className:`tnum px-3 py-2.5 text-right font-mono`,children:e.weight}),(0,$.jsx)(`td`,{className:`px-3 py-2`,children:(0,$.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,$.jsx)(W,{label:`1m`,usage:t?.windows[`1m`]}),(0,$.jsx)(W,{label:`5h`,usage:t?.windows[`5h`]}),(0,$.jsx)(W,{label:`24h`,usage:t?.windows[`24h`]})]})}),(0,$.jsx)(`td`,{className:`px-3 py-2.5`,children:(0,$.jsx)(x,{checked:e.enabled,onChange:t=>w(e,t),label:`${e.enabled?`Disable`:`Enable`} ${e.label}`})}),(0,$.jsx)(`td`,{className:`px-2 py-2.5 text-muted`,children:(0,$.jsx)(b,{"aria-hidden":!0,className:`size-4 transition-transform duration-150 group-hover:translate-x-0.5`,strokeWidth:1.75})})]},e.id)})})]})})}),_.length>0&&(0,$.jsx)(Ce,{}),(0,$.jsx)(ve,{open:h,onClose:()=>O(`new`,null)}),(0,$.jsx)(he,{account:C,usage:C?g.get(C.id):void 0,onClose:()=>O(`account`,null)})]})}export{we as Accounts};
@@ -1 +1 @@
1
- import{n as e,r as t,t as n}from"./cn-BwE4cei0.js";import{M as r,W as i}from"./index-B8kld9xo.js";var a={name:`octagon-alert`,size:24,node:[[`path`,{d:`M12 16h.01`,key:`1drbdi`}],[`path`,{d:`M12 8v4`,key:`1got3b`}],[`path`,{d:`M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z`,key:`1fd625`}]],aliases:[`alert-octagon`]};a.node;var o=e(a),s=t(),c={info:{box:`border-info/25 bg-info-soft [&_svg]:text-info`,icon:i},warn:{box:`border-warn/30 bg-warn-soft [&_svg]:text-warn`,icon:r},err:{box:`border-err/30 bg-err-soft [&_svg]:text-err`,icon:o}};function l({tone:e=`info`,title:t,children:r,action:i,className:a}){let{box:o,icon:l}=c[e];return(0,s.jsxs)(`div`,{role:e===`info`?`note`:`alert`,className:n(`flex gap-2.5 rounded-md border px-3 py-2.5 text-[12px] leading-5`,o,a),children:[(0,s.jsx)(l,{"aria-hidden":!0,className:`mt-0.5 size-3.5 shrink-0`,strokeWidth:1.75}),(0,s.jsxs)(`div`,{className:`min-w-0 flex-1 text-fg-2`,children:[t&&(0,s.jsx)(`p`,{className:`font-medium text-fg`,children:t}),r]}),i&&(0,s.jsx)(`div`,{className:`shrink-0 self-center`,children:i})]})}export{l as t};
1
+ import{n as e,r as t,t as n}from"./cn-BwE4cei0.js";import{K as r,P as i}from"./index-C-bwzlsl.js";var a={name:`octagon-alert`,size:24,node:[[`path`,{d:`M12 16h.01`,key:`1drbdi`}],[`path`,{d:`M12 8v4`,key:`1got3b`}],[`path`,{d:`M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z`,key:`1fd625`}]],aliases:[`alert-octagon`]};a.node;var o=e(a),s=t(),c={info:{box:`border-info/25 bg-info-soft [&_svg]:text-info`,icon:r},warn:{box:`border-warn/30 bg-warn-soft [&_svg]:text-warn`,icon:i},err:{box:`border-err/30 bg-err-soft [&_svg]:text-err`,icon:o}};function l({tone:e=`info`,title:t,children:r,action:i,className:a}){let{box:o,icon:l}=c[e];return(0,s.jsxs)(`div`,{role:e===`info`?`note`:`alert`,className:n(`flex gap-2.5 rounded-md border px-3 py-2.5 text-[12px] leading-5`,o,a),children:[(0,s.jsx)(l,{"aria-hidden":!0,className:`mt-0.5 size-3.5 shrink-0`,strokeWidth:1.75}),(0,s.jsxs)(`div`,{className:`min-w-0 flex-1 text-fg-2`,children:[t&&(0,s.jsx)(`p`,{className:`font-medium text-fg`,children:t}),r]}),i&&(0,s.jsx)(`div`,{className:`shrink-0 self-center`,children:i})]})}export{l as t};
@@ -0,0 +1 @@
1
+ import{i as e,n as t,o as n,r,t as i}from"./cn-BwE4cei0.js";import{C as a,Mt as o,Nt as s,P as c,T as l,W as u,h as d,l as f,n as p,t as m,w as h}from"./format-328qIBHX.js";import{n as g,t as _}from"./Switch-DPYlLseH.js";import{n as v,t as y}from"./Markdown-CGgIydUh.js";import{t as b}from"./Callout-CqdcH6dC.js";import{E as x,F as S,H as C,L as w,T,d as E,i as D,m as O,n as k,p as A,r as j,s as M,u as N,x as P,y as F}from"./index-C-bwzlsl.js";import{i as I,n as L,t as R}from"./Field-Cmpgg_1z.js";var z={name:`chevron-down`,size:24,node:[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]};z.node;var B=t(z),V={name:`shield-check`,size:24,node:[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]};V.node;var H=t(V),U=n(e(),1),W=r(),G={planning:`info`,running:`info`,reviewing:`info`,planned:`accent`,succeeded:`ok`,failed:`err`,cancelled:`neutral`,budget_exhausted:`warn`},K={planning:`planning`,running:`running`,reviewing:`reviewing`,planned:`planned (dry run)`,succeeded:`succeeded`,failed:`failed`,cancelled:`cancelled`,budget_exhausted:`out of budget`},q=new Set([`planning`,`running`,`reviewing`]);function J(e){return q.has(e.status)}function Y(e){let t=Number(e);return e.trim()&&Number.isInteger(t)&&t>0?t:void 0}function X(){let e=l(),[t,n]=(0,U.useState)(),r=s(e.error)&&e.error.status===501,a=e.data??[],c=a.find(e=>e.id===t)??a[0],u=a.find(J);return(0,W.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,W.jsx)(k,{title:`Goals`,description:`Give the agent team an objective: a planner splits it into tasks, role agents execute them, a reviewer re-plans until it is done or the budget runs out.`}),r?(0,W.jsxs)(b,{tone:`warn`,title:`Goal mode unavailable`,children:[(0,W.jsxs)(`p`,{children:[`This gateway answered `,(0,W.jsx)(`code`,{className:`font-mono text-fg`,children:`501 goals_unavailable`}),`: it was started outside a project. Start it inside a repository with a project brain, or run a goal from the terminal:`]}),(0,W.jsx)(A,{command:`davecode goal "<objective>"`,className:`mt-2 max-w-sm`})]}):(0,W.jsx)(Z,{busy:u?.id,onStarted:e=>n(e.id)}),e.isError&&!r&&(0,W.jsx)(b,{tone:`err`,title:`Could not load goals`,children:o(e.error)}),!r&&(0,W.jsxs)(`div`,{className:`grid grid-cols-1 gap-4 xl:grid-cols-[320px_minmax(0,1fr)]`,children:[(0,W.jsxs)(j,{"aria-labelledby":`goal-list-title`,className:`xl:self-start`,children:[(0,W.jsx)(D,{id:`goal-list-title`,title:`History`,meta:a.length?`${a.length} goal${a.length===1?``:`s`}`:void 0}),e.isPending?(0,W.jsx)(N,{rows:4,className:`p-3`}):a.length===0?(0,W.jsx)(M,{icon:S,title:`No goals yet`,description:`Describe an objective above, or try a dry run to see the plan first.`}):(0,W.jsx)(`ul`,{className:`flex flex-col p-1.5`,"aria-label":`Goals`,children:a.map(e=>{let t=e.tasks.filter(e=>e.status===`SUCCESS`).length,r=e.id===c?.id;return(0,W.jsx)(`li`,{children:(0,W.jsxs)(`button`,{type:`button`,"aria-current":r?`true`:void 0,onClick:()=>n(e.id),className:i(`flex w-full flex-col gap-1 rounded-md px-2.5 py-2 text-left transition-colors duration-150`,r?`bg-hover`:`hover:bg-hover/60`),children:[(0,W.jsx)(`span`,{className:`line-clamp-2 text-[13px] leading-5 text-fg`,children:e.objective}),(0,W.jsxs)(`span`,{className:`flex items-center gap-2 text-2xs text-muted`,children:[(0,W.jsx)(P,{tone:G[e.status],dot:!0,pulse:J(e),children:K[e.status]}),(0,W.jsxs)(`span`,{className:`tnum`,children:[t,`/`,e.tasks.length,` tasks`]}),(0,W.jsx)(`span`,{className:`ml-auto`,children:f(Date.parse(e.createdAt))})]})]})},e.id)})})]}),c?(0,W.jsx)($,{goal:c}):null]})]})}function Z({busy:e,onStarted:t}){let n=c(),[r,i]=(0,U.useState)(``),[a,l]=(0,U.useState)(``),[u,d]=(0,U.useState)(``),[f,p]=(0,U.useState)(``),[m,h]=(0,U.useState)(!1),[g,v]=(0,U.useState)(null);return(0,W.jsxs)(j,{"aria-labelledby":`new-goal-title`,children:[(0,W.jsx)(D,{id:`new-goal-title`,title:`New goal`,meta:(0,W.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,W.jsx)(H,{"aria-hidden":!0,className:`size-3.5 text-ok`,strokeWidth:1.75}),`Never emails, posts, pays or signs up: those become drafts`]})}),(0,W.jsxs)(`form`,{onSubmit:e=>{if(e.preventDefault(),!r.trim()){v(`Describe what the team should achieve.`);return}v(null);let c={objective:r.trim()},l=Y(a),d=Y(u),p=Y(f);l&&(c.maxRounds=l),d&&(c.maxTasks=d),p&&(c.maxTokens=p),m&&(c.dryRun=!0),n.mutate(c,{onSuccess:e=>{T({tone:`info`,title:m?`Planning (dry run)`:`Goal started`,description:e.objective}),i(``),t(e)},onError:e=>T({tone:`err`,title:`Could not start the goal`,description:s(e)&&e.code===`busy`?`${e.message}. Goals and the runner take turns on the working tree.`:o(e)})})},className:`flex flex-col gap-3 p-4`,children:[(0,W.jsx)(R,{label:`Objective`,required:!0,error:g,children:({id:e,describedBy:t,invalid:n})=>(0,W.jsx)(I,{id:e,"aria-describedby":t,"aria-invalid":n,rows:2,maxLength:4e3,placeholder:`e.g. Write positioning and landing-page copy for this project, then add a /pricing page`,value:r,onChange:e=>i(e.target.value)})}),(0,W.jsxs)(`div`,{className:`flex flex-wrap items-end gap-3`,children:[(0,W.jsx)(R,{label:`Max rounds`,className:`w-28`,children:({id:e})=>(0,W.jsx)(L,{id:e,inputMode:`numeric`,placeholder:`4`,value:a,onChange:e=>l(e.target.value)})}),(0,W.jsx)(R,{label:`Max tasks`,className:`w-28`,children:({id:e})=>(0,W.jsx)(L,{id:e,inputMode:`numeric`,placeholder:`12`,value:u,onChange:e=>d(e.target.value)})}),(0,W.jsx)(R,{label:`Token budget`,className:`w-36`,children:({id:e})=>(0,W.jsx)(L,{id:e,inputMode:`numeric`,placeholder:`1000000`,value:f,onChange:e=>p(e.target.value)})}),(0,W.jsxs)(`span`,{className:`flex h-8 items-center gap-2 text-[12px] text-fg-2`,children:[(0,W.jsx)(_,{checked:m,onChange:h,label:`Dry run`}),`Dry run (plan only)`]}),(0,W.jsx)(x,{type:`submit`,variant:`primary`,icon:C,className:`ml-auto`,loading:n.isPending,disabled:n.isPending||!!e&&!m,title:e&&!m?`Goal ${e} is still running`:void 0,children:m?`Plan`:`Start goal`})]})]})]})}function Q({label:e,value:t,max:n,format:r=String}){let a=n>0?Math.min(100,t/n*100):0;return(0,W.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-1.5`,children:[(0,W.jsxs)(`div`,{className:`flex items-baseline justify-between gap-2 text-[12px]`,children:[(0,W.jsx)(`span`,{className:`text-muted`,children:e}),(0,W.jsxs)(`span`,{className:`tnum font-mono text-fg`,children:[r(t),(0,W.jsxs)(`span`,{className:`text-muted`,children:[` / `,r(n)]})]})]}),(0,W.jsx)(`div`,{className:`h-1.5 overflow-hidden rounded-full bg-track`,"aria-hidden":!0,children:(0,W.jsx)(`div`,{className:i(`h-full rounded-full transition-[width] duration-500 ease-snappy`,a>=90?`bg-warn`:`bg-accent`),style:{width:`${a}%`}})})]})}function $({goal:e}){let t=d(),n=a(),r=u(),[s,c]=(0,U.useState)(!1),[l,f]=(0,U.useState)(),h=J(e),_=e.tasks.filter(e=>e.status===`SUCCESS`).length,b=r.events.filter(t=>t.type===`goal.log`&&t.goalId===e.id),S=()=>t.mutate(e.id,{onSuccess:e=>T({tone:`info`,title:`Goal ${e.status}`,description:e.objective}),onError:e=>T({tone:`err`,title:`Could not cancel`,description:o(e)})});return(0,W.jsxs)(j,{"aria-labelledby":`goal-detail-title`,className:`min-w-0`,children:[(0,W.jsx)(D,{id:`goal-detail-title`,title:(0,W.jsx)(`span`,{className:`font-mono text-2xs text-muted`,children:e.id}),meta:(0,W.jsx)(P,{tone:G[e.status],dot:!0,pulse:h,children:K[e.status]}),actions:(0,W.jsxs)(W.Fragment,{children:[e.status===`planned`&&(0,W.jsx)(x,{size:`sm`,variant:`primary`,icon:C,loading:n.isPending,onClick:()=>n.mutate(e.id,{onSuccess:e=>T({tone:`info`,title:`Executing planned goal`,description:e.objective}),onError:e=>T({tone:`err`,title:`Could not execute plan`,description:o(e)})}),children:`Execute plan`}),h&&(0,W.jsx)(x,{size:`sm`,variant:`danger`,icon:w,loading:t.isPending,onClick:()=>c(!0),children:`Cancel`})]})}),(0,W.jsxs)(`div`,{className:`flex flex-col gap-4 p-4`,children:[(0,W.jsx)(`p`,{className:`text-[15px] leading-6 font-medium text-fg`,children:e.objective}),(0,W.jsxs)(`div`,{className:`flex flex-wrap gap-x-6 gap-y-3`,children:[(0,W.jsx)(Q,{label:`Rounds`,value:e.round,max:e.limits.maxRounds}),(0,W.jsx)(Q,{label:`Tasks done`,value:_,max:Math.max(e.tasks.length,1)}),(0,W.jsx)(Q,{label:`Tokens`,value:e.limits.tokensUsed,max:e.limits.maxTokens,format:p})]}),e.lastError&&(0,W.jsx)(`p`,{className:`rounded-md border border-err/30 bg-err-soft p-2 font-mono text-2xs text-err`,children:e.lastError}),(0,W.jsx)(`section`,{"aria-label":`Tasks`,className:`flex flex-col`,children:e.tasks.length===0?(0,W.jsx)(`p`,{className:`text-[12px] text-muted`,children:h?`The planner is drafting the task graph…`:`No tasks were planned.`}):(0,W.jsx)(`ol`,{className:`flex flex-col divide-y divide-line rounded-md border border-line`,children:e.tasks.map(t=>(0,W.jsxs)(`li`,{className:i(`flex flex-col gap-1.5 px-3 py-2.5`,t.id===e.activeTaskId&&`bg-accent-soft/40`),children:[(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,W.jsx)(F,{status:t.status}),(0,W.jsx)(`span`,{className:`font-mono text-2xs text-muted`,children:t.id}),(0,W.jsx)(`span`,{className:`min-w-0 flex-1 text-[13px] text-fg`,children:t.title}),(0,W.jsx)(P,{mono:!0,children:t.role}),(0,W.jsx)(P,{tone:t.kind===`code`?`accent`:`neutral`,mono:!0,children:t.kind}),t.round>1&&(0,W.jsxs)(P,{mono:!0,children:[`round `,t.round]})]}),t.dependsOn.length>0&&(0,W.jsxs)(`p`,{className:`text-2xs text-muted`,children:[`after `,t.dependsOn.join(`, `)]}),t.artifact&&(0,W.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-1.5 font-mono text-2xs text-fg-2`,children:[(0,W.jsxs)(`button`,{type:`button`,onClick:()=>f(e=>e===t.id?void 0:t.id),"aria-expanded":l===t.id,className:`inline-flex items-center gap-1 rounded px-1 py-0.5 text-fg-2 transition-colors hover:bg-hover hover:text-fg`,children:[l===t.id?(0,W.jsx)(B,{"aria-hidden":!0,className:`size-3.5 text-muted`}):(0,W.jsx)(g,{"aria-hidden":!0,className:`size-3.5 text-muted`}),(0,W.jsx)(v,{"aria-hidden":!0,className:`size-3.5 text-muted`,strokeWidth:1.75}),(0,W.jsx)(`span`,{className:`truncate`,children:t.artifact})]}),(0,W.jsx)(O,{value:t.artifact,label:`Copy path`})]}),l===t.id&&(0,W.jsx)(ee,{goalId:e.id,taskId:t.id})]}),t.status===`FAILED`&&t.notes&&(0,W.jsx)(`p`,{className:`line-clamp-3 font-mono text-2xs text-err`,children:t.notes})]},t.id))})}),e.summary&&(0,W.jsx)(`section`,{"aria-label":`Summary`,className:`rounded-md border border-line bg-raised/40 p-3`,children:(0,W.jsx)(y,{source:e.summary,className:`text-[13px]`})}),(0,W.jsx)(`section`,{"aria-label":`Goal log`,className:`term max-h-64 overflow-auto rounded-md border border-line bg-term py-2 font-mono text-[12px] leading-[1.6]`,children:b.length===0?(0,W.jsx)(`p`,{className:`px-3 text-muted`,children:h?`Waiting for agent output…`:`No live log for this goal in this session.`}):b.map(e=>(0,W.jsxs)(`div`,{className:`flex gap-3 px-3`,children:[(0,W.jsx)(`span`,{className:`tnum shrink-0 text-faint select-none`,children:m(e.ts)}),(0,W.jsx)(`span`,{className:`w-20 shrink-0 truncate text-info`,children:e.role??`goal`}),(0,W.jsx)(`span`,{className:i(`min-w-0 break-words`,e.level===`error`?`text-err`:e.level===`warn`?`text-warn`:`text-fg-2`),children:e.message})]},`${e.ts}-${e.message}`))})]}),(0,W.jsx)(E,{open:s,onClose:()=>c(!1),title:`Cancel this goal?`,description:`The agent in flight is stopped. Finished artifacts and merged code stay; an interrupted code task keeps its partial work on its branch.`,footer:(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(x,{variant:`ghost`,onClick:()=>c(!1),children:`Keep going`}),(0,W.jsx)(x,{variant:`danger`,icon:w,onClick:()=>{c(!1),S()},children:`Cancel goal`})]}),children:(0,W.jsx)(`p`,{className:`text-[12px] text-muted`,children:e.objective})})]})}function ee({goalId:e,taskId:t}){let n=h(e,t);return n.isPending?(0,W.jsx)(N,{rows:3,className:`p-2`}):n.isError?(0,W.jsx)(`p`,{className:`rounded-md border border-err/30 bg-err-soft p-2 font-mono text-2xs text-err`,children:o(n.error)}):(0,W.jsxs)(`div`,{className:`rounded-md border border-line bg-raised/50 p-3`,children:[(0,W.jsxs)(`div`,{className:`mb-2 flex items-center justify-between gap-2 border-b border-line pb-1.5`,children:[(0,W.jsx)(`span`,{className:`font-mono text-2xs text-muted`,children:n.data.path}),(0,W.jsx)(O,{value:n.data.content,label:`Copy markdown`})]}),(0,W.jsx)(y,{source:n.data.content,className:`text-[13px]`})]})}export{$ as GoalDetail,X as Goals,J as isActiveGoal,B as t};
@@ -1 +1 @@
1
- import{i as e,o as t,r as n}from"./cn-BwE4cei0.js";import{D as r,I as i,X as a,Y as o,n as s,w as c}from"./index-B8kld9xo.js";import{n as l}from"./Field-Cmpgg_1z.js";var u=t(e(),1),d=[{id:`ponytail`,name:`Ponytail`,kind:`Guidance`,url:`https://github.com/DietrichGebert/ponytail`,description:`Reuse what exists and keep implementations small. Useful for avoiding unnecessary code; it does not supply an art direction.`,access:`Repository; review license before reuse`},{id:`anti-slop`,name:`Anti Slop`,kind:`Guidance`,url:`https://github.com/miqdadbadjuber/anti-slop`,description:`Review recurring generic patterns in interface design, copy and generated code.`,access:`Repository; review license before reuse`},{id:`impeccable`,name:`Impeccable`,kind:`Guidance`,url:`https://github.com/pbakaus/impeccable`,description:`Design guidance for defining a product direction and refining the finished interface.`,access:`Repository; review license before reuse`},{id:`anti-ui-slop`,name:`Anti UI Slop`,kind:`Guidance`,url:`https://github.com/tuanphung2005/anti-ui-slop`,description:`A separate UI-focused ruleset. Compare its constraints with your brief rather than combining conflicting rules.`,access:`Repository; review license before reuse`},{id:`shadcn`,name:`shadcn/ui`,kind:`Components`,url:`https://github.com/shadcn-ui/ui`,description:`Own and adapt the component source. Start from accessible building blocks and make them fit your identity.`,access:`MIT component library`},{id:`radix`,name:`Radix Primitives`,kind:`Components`,url:`https://github.com/radix-ui/primitives`,description:`Accessible interaction primitives for dialogs, menus and other complex interface behaviors.`,access:`MIT component library`},{id:`motion`,name:`Motion`,kind:`Components`,url:`https://github.com/motiondivision/motion`,description:`Animation for React and JavaScript. Use motion to explain a change, with a reduced-motion alternative.`,access:`MIT library; optional paid products are separate`},{id:`r3f`,name:`React Three Fiber`,kind:`Components`,url:`https://github.com/pmndrs/react-three-fiber`,description:`A React renderer for Three.js. Consider it when a real 3D experience serves the idea.`,access:`MIT library; assets have their own licenses`},{id:`awwwards`,name:`Awwwards`,kind:`Inspiration`,url:`https://www.awwwards.com/`,description:`Explore expressive websites and the studios behind them. Study composition and interaction, then create your own interpretation.`,access:`Reference gallery; artwork is not licensed for copying`},{id:`siteinspire`,name:`Siteinspire`,kind:`Inspiration`,url:`https://www.siteinspire.com/`,description:`Find references by style, type and subject instead of starting from the same SaaS template.`,access:`Reference gallery; artwork is not licensed for copying`},{id:`freight`,name:`Studio Freight`,kind:`Inspiration`,url:`https://studiofreight.com/`,description:`A studio reference for thoughtful digital identity and web experiences.`,access:`Studio portfolio; reference only`},{id:`hf`,name:`Hugging Face Spaces`,kind:`AI tools`,url:`https://huggingface.co/spaces`,description:`Discover interactive AI demos. Check each Space, model license and compute requirements before using it in your project.`,access:`Availability, model licenses and costs vary`}];function f(e){return`Help me create a distinctive interface for this project. Use ${e.name} (${e.url}) as a reference if you can access it. Its purpose: ${e.description}\n\nFirst identify the audience, intended outcome and existing design system. Propose a specific visual direction and a short design brief: typography, palette, composition, imagery, interaction and mobile behavior. Preserve the project stack, cover loading/empty/error states, and verify the rendered result. Use references as inspiration and respect their licenses. Do not claim to have read, installed or connected a resource without checking. Explain any external dependency before adding it.`}var p=n(),m=[`All`,`Guidance`,`Components`,`Inspiration`,`AI tools`];function h(){let[e,t]=(0,u.useState)(`All`),[n,h]=(0,u.useState)(``),g=d.filter(t=>(e===`All`||t.kind===e)&&`${t.name} ${t.description}`.toLowerCase().includes(n.toLowerCase()));return(0,p.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,p.jsx)(s,{title:`Creative library`,description:`Find a direction before you build. A curated starting point for people with ideas, with guidance, components and real design references.`}),(0,p.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,p.jsx)(`fieldset`,{className:`flex flex-wrap gap-1`,"aria-label":`Resource category`,children:m.map(n=>(0,p.jsx)(c,{variant:n===e?`primary`:`ghost`,onClick:()=>t(n),"aria-pressed":n===e,children:n},n))}),(0,p.jsxs)(`label`,{htmlFor:`creative-search`,className:`relative ml-auto w-full max-w-xs`,children:[(0,p.jsx)(`span`,{className:`sr-only`,children:`Find a creative resource`}),(0,p.jsx)(i,{"aria-hidden":!0,className:`absolute top-2.5 left-2.5 size-3.5 text-muted`}),(0,p.jsx)(l,{id:`creative-search`,value:n,onChange:e=>h(e.target.value),placeholder:`Find a resource…`,className:`pl-8`})]})]}),(0,p.jsx)(`div`,{className:`grid gap-x-8 md:grid-cols-2 xl:grid-cols-3`,children:g.map(e=>(0,p.jsxs)(`article`,{className:`flex flex-col items-start border-t border-line py-6`,children:[(0,p.jsx)(`p`,{className:`text-[12px] text-accent-text`,children:e.kind}),(0,p.jsx)(`h2`,{className:`mt-3 text-[21px] font-medium tracking-tight text-fg`,children:e.name}),(0,p.jsx)(`p`,{className:`mt-3 max-w-sm flex-1 text-[13px] leading-6 text-muted`,children:e.description}),(0,p.jsx)(`p`,{className:`mt-4 text-[11px] leading-5 text-muted`,children:e.access}),(0,p.jsxs)(`div`,{className:`mt-4 flex flex-wrap items-center gap-4`,children:[(0,p.jsx)(c,{size:`sm`,onClick:()=>r(`/?brief=${encodeURIComponent(f(e))}`),children:`Use in a goal`}),(0,p.jsxs)(`a`,{href:e.url,target:`_blank`,rel:`noreferrer`,className:`inline-flex items-center gap-1 text-[12px] text-fg-2 hover:text-fg`,children:[`Visit source`,(0,p.jsx)(a,{"aria-hidden":!0,className:`size-3`})]})]})]},e.id))}),g.length===0&&(0,p.jsx)(`p`,{role:`status`,className:`py-8 text-[13px] text-muted`,children:`No resources match. Try another name or category.`}),(0,p.jsxs)(`div`,{className:`flex gap-3 border-t border-line pt-5 text-[12px] leading-6 text-muted`,children:[(0,p.jsx)(o,{"aria-hidden":!0,className:`mt-1 size-4 shrink-0`}),(0,p.jsx)(`p`,{children:`These are curated references, not installed plugins. “Use in a goal” prepares a brief for your agent; it does not run code, fetch a site or connect an account. DaveCode includes its own design-quality guidance by default. Third-party resources keep their own licenses and access requirements.`})]})]})}export{h as Library};
1
+ import{i as e,o as t,r as n}from"./cn-BwE4cei0.js";import{E as r,Q as i,R as a,Z as o,k as s,n as c}from"./index-C-bwzlsl.js";import{n as l}from"./Field-Cmpgg_1z.js";var u=t(e(),1),d=[{id:`ponytail`,name:`Ponytail`,kind:`Guidance`,url:`https://github.com/DietrichGebert/ponytail`,description:`Reuse what exists and keep implementations small. Useful for avoiding unnecessary code; it does not supply an art direction.`,access:`Repository; review license before reuse`},{id:`anti-slop`,name:`Anti Slop`,kind:`Guidance`,url:`https://github.com/miqdadbadjuber/anti-slop`,description:`Review recurring generic patterns in interface design, copy and generated code.`,access:`Repository; review license before reuse`},{id:`impeccable`,name:`Impeccable`,kind:`Guidance`,url:`https://github.com/pbakaus/impeccable`,description:`Design guidance for defining a product direction and refining the finished interface.`,access:`Repository; review license before reuse`},{id:`anti-ui-slop`,name:`Anti UI Slop`,kind:`Guidance`,url:`https://github.com/tuanphung2005/anti-ui-slop`,description:`A separate UI-focused ruleset. Compare its constraints with your brief rather than combining conflicting rules.`,access:`Repository; review license before reuse`},{id:`shadcn`,name:`shadcn/ui`,kind:`Components`,url:`https://github.com/shadcn-ui/ui`,description:`Own and adapt the component source. Start from accessible building blocks and make them fit your identity.`,access:`MIT component library`},{id:`radix`,name:`Radix Primitives`,kind:`Components`,url:`https://github.com/radix-ui/primitives`,description:`Accessible interaction primitives for dialogs, menus and other complex interface behaviors.`,access:`MIT component library`},{id:`motion`,name:`Motion`,kind:`Components`,url:`https://github.com/motiondivision/motion`,description:`Animation for React and JavaScript. Use motion to explain a change, with a reduced-motion alternative.`,access:`MIT library; optional paid products are separate`},{id:`r3f`,name:`React Three Fiber`,kind:`Components`,url:`https://github.com/pmndrs/react-three-fiber`,description:`A React renderer for Three.js. Consider it when a real 3D experience serves the idea.`,access:`MIT library; assets have their own licenses`},{id:`awwwards`,name:`Awwwards`,kind:`Inspiration`,url:`https://www.awwwards.com/`,description:`Explore expressive websites and the studios behind them. Study composition and interaction, then create your own interpretation.`,access:`Reference gallery; artwork is not licensed for copying`},{id:`siteinspire`,name:`Siteinspire`,kind:`Inspiration`,url:`https://www.siteinspire.com/`,description:`Find references by style, type and subject instead of starting from the same SaaS template.`,access:`Reference gallery; artwork is not licensed for copying`},{id:`freight`,name:`Studio Freight`,kind:`Inspiration`,url:`https://studiofreight.com/`,description:`A studio reference for thoughtful digital identity and web experiences.`,access:`Studio portfolio; reference only`},{id:`hf`,name:`Hugging Face Spaces`,kind:`AI tools`,url:`https://huggingface.co/spaces`,description:`Discover interactive AI demos. Check each Space, model license and compute requirements before using it in your project.`,access:`Availability, model licenses and costs vary`}];function f(e){return`Help me create a distinctive interface for this project. Use ${e.name} (${e.url}) as a reference if you can access it. Its purpose: ${e.description}\n\nFirst identify the audience, intended outcome and existing design system. Propose a specific visual direction and a short design brief: typography, palette, composition, imagery, interaction and mobile behavior. Preserve the project stack, cover loading/empty/error states, and verify the rendered result. Use references as inspiration and respect their licenses. Do not claim to have read, installed or connected a resource without checking. Explain any external dependency before adding it.`}var p=n(),m=[`All`,`Guidance`,`Components`,`Inspiration`,`AI tools`];function h(){let[e,t]=(0,u.useState)(`All`),[n,h]=(0,u.useState)(``),g=d.filter(t=>(e===`All`||t.kind===e)&&`${t.name} ${t.description}`.toLowerCase().includes(n.toLowerCase()));return(0,p.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,p.jsx)(c,{title:`Creative library`,description:`Find a direction before you build. A curated starting point for people with ideas, with guidance, components and real design references.`}),(0,p.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,p.jsx)(`fieldset`,{className:`flex flex-wrap gap-1`,"aria-label":`Resource category`,children:m.map(n=>(0,p.jsx)(r,{variant:n===e?`primary`:`ghost`,onClick:()=>t(n),"aria-pressed":n===e,children:n},n))}),(0,p.jsxs)(`label`,{htmlFor:`creative-search`,className:`relative ml-auto w-full max-w-xs`,children:[(0,p.jsx)(`span`,{className:`sr-only`,children:`Find a creative resource`}),(0,p.jsx)(a,{"aria-hidden":!0,className:`absolute top-2.5 left-2.5 size-3.5 text-muted`}),(0,p.jsx)(l,{id:`creative-search`,value:n,onChange:e=>h(e.target.value),placeholder:`Find a resource…`,className:`pl-8`})]})]}),(0,p.jsx)(`div`,{className:`grid gap-x-8 md:grid-cols-2 xl:grid-cols-3`,children:g.map(e=>(0,p.jsxs)(`article`,{className:`flex flex-col items-start border-t border-line py-6`,children:[(0,p.jsx)(`p`,{className:`text-[12px] text-accent-text`,children:e.kind}),(0,p.jsx)(`h2`,{className:`mt-3 text-[21px] font-medium tracking-tight text-fg`,children:e.name}),(0,p.jsx)(`p`,{className:`mt-3 max-w-sm flex-1 text-[13px] leading-6 text-muted`,children:e.description}),(0,p.jsx)(`p`,{className:`mt-4 text-[11px] leading-5 text-muted`,children:e.access}),(0,p.jsxs)(`div`,{className:`mt-4 flex flex-wrap items-center gap-4`,children:[(0,p.jsx)(r,{size:`sm`,onClick:()=>s(`/?brief=${encodeURIComponent(f(e))}`),children:`Use in a goal`}),(0,p.jsxs)(`a`,{href:e.url,target:`_blank`,rel:`noreferrer`,className:`inline-flex items-center gap-1 text-[12px] text-fg-2 hover:text-fg`,children:[`Visit source`,(0,p.jsx)(i,{"aria-hidden":!0,className:`size-3`})]})]})]},e.id))}),g.length===0&&(0,p.jsx)(`p`,{role:`status`,className:`py-8 text-[13px] text-muted`,children:`No resources match. Try another name or category.`}),(0,p.jsxs)(`div`,{className:`flex gap-3 border-t border-line pt-5 text-[12px] leading-6 text-muted`,children:[(0,p.jsx)(o,{"aria-hidden":!0,className:`mt-1 size-4 shrink-0`}),(0,p.jsx)(`p`,{children:`These are curated references, not installed plugins. “Use in a goal” prepares a brief for your agent; it does not run code, fetch a site or connect an account. DaveCode includes its own design-quality guidance by default. Third-party resources keep their own licenses and access requirements.`})]})]})}export{h as Library};