@dmrlzz/davecode 0.5.3 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/{ChatApp-IF5D7XNH.js → ChatApp-C23NVTME.js} +6 -6
- package/dist/{account-KBXJ5KR7.js → account-GG7UFSNY.js} +3 -3
- package/dist/{accounts-XUJNDCFH.js → accounts-IPOGUMHF.js} +5 -5
- package/dist/{budget-PHV4NRUS.js → budget-7QJGPYPF.js} +4 -4
- package/dist/{chat-HGTX76DU.js → chat-3K2KXS3E.js} +8 -8
- package/dist/{chunk-FZJNOG2T.js → chunk-3BTE76UD.js} +2 -2
- package/dist/{chunk-FPSLYBLU.js → chunk-4FE2YV5U.js} +2 -2
- package/dist/{chunk-YSD6W27K.js → chunk-FKGZERYB.js} +283 -5
- package/dist/chunk-FKGZERYB.js.map +1 -0
- package/dist/{chunk-AFCQURO5.js → chunk-JBX6J74G.js} +3 -3
- package/dist/{chunk-EBV5A33R.js → chunk-KEURMO75.js} +4 -4
- package/dist/{chunk-DFQW3MRD.js → chunk-LK2K73DC.js} +2 -2
- package/dist/{chunk-ING5HCIO.js → chunk-NBQIMB43.js} +3430 -1063
- package/dist/chunk-NBQIMB43.js.map +1 -0
- package/dist/{goal-ETZWLVKO.js → chunk-PGZPSJS7.js} +8 -8
- package/dist/chunk-PGZPSJS7.js.map +1 -0
- package/dist/{chunk-ZVNX7CSO.js → chunk-U42YONUN.js} +3 -3
- package/dist/{config-DG2E4VDW.js → config-BFEQFGAR.js} +3 -3
- package/dist/dashboard/assets/Accounts-CUMFzGls.js +1 -0
- package/dist/dashboard/assets/{Callout-1E8Wsl9W.js → Callout-DDtTG_BA.js} +1 -1
- package/dist/dashboard/assets/Goals-CBGiTkcP.js +1 -0
- package/dist/dashboard/assets/{Library-DZxBVUo_.js → Library-CKWa3h0E.js} +1 -1
- package/dist/dashboard/assets/{Panes-C-TJekjs.js → Panes-ziAz-CZa.js} +4 -4
- package/dist/dashboard/assets/RoutesPage-D2iW-KhM.js +4 -0
- package/dist/dashboard/assets/Runner-4e79FB1J.js +1 -0
- package/dist/dashboard/assets/Settings-CSae84S0.js +1 -0
- package/dist/dashboard/assets/Tasks-CnbZ5PvX.js +2 -0
- package/dist/dashboard/assets/Traffic-B12xKOUm.js +1 -0
- package/dist/dashboard/assets/Workspace-CMPHlw4f.js +1 -0
- package/dist/dashboard/assets/chevron-down-DT349Fth.js +1 -0
- package/dist/dashboard/assets/external-link-DCIUScea.js +1 -0
- package/dist/dashboard/assets/format-C7Q-B9fI.js +112 -0
- package/dist/dashboard/assets/index-4RIBvhr9.css +2 -0
- package/dist/dashboard/assets/index-z8TlFwRe.js +50 -0
- package/dist/dashboard/assets/task-errors-3F3vbQ7k.js +1 -0
- package/dist/dashboard/assets/x-UBQsC1rW.js +1 -0
- package/dist/dashboard/index.html +4 -3
- package/dist/{dist-IPMBGFJD.js → dist-VTC5E7Z5.js} +48 -2
- package/dist/{doctor-5APOWJ5D.js → doctor-JLFYQ3EP.js} +3 -3
- package/dist/goal-JM7QYTL2.js +26 -0
- package/dist/index.js +64 -31
- package/dist/index.js.map +1 -1
- package/dist/{init-YDLNA3GD.js → init-6K4EGMTV.js} +3 -3
- package/dist/orchestrate-QC5P6IUZ.js +382 -0
- package/dist/orchestrate-QC5P6IUZ.js.map +1 -0
- package/dist/{run-I6N7TLHV.js → run-ABQNQ722.js} +3 -3
- package/dist/runtime.js +6 -2
- package/dist/{start-ECLELJGJ.js → start-MSO7TGBX.js} +3 -3
- package/dist/{status-QQPP67I4.js → status-U6C4LUCM.js} +4 -4
- package/dist/status-U6C4LUCM.js.map +1 -0
- package/dist/{tasks-RNMC2XFN.js → tasks-HEVT67YM.js} +4 -4
- package/package.json +4 -4
- package/dist/chunk-ING5HCIO.js.map +0 -1
- package/dist/chunk-YSD6W27K.js.map +0 -1
- package/dist/dashboard/assets/Accounts-DXiGsutB.js +0 -1
- package/dist/dashboard/assets/Badge-DUGKlx3Z.js +0 -55
- package/dist/dashboard/assets/Goals-kL4VAxw3.js +0 -1
- package/dist/dashboard/assets/RoutesPage-DWYm9tW8.js +0 -4
- package/dist/dashboard/assets/Runner-CmHBjECR.js +0 -1
- package/dist/dashboard/assets/Settings-BANphxva.js +0 -1
- package/dist/dashboard/assets/Tasks-cSx1PKyQ.js +0 -2
- package/dist/dashboard/assets/Traffic-DEAuM6jq.js +0 -1
- package/dist/dashboard/assets/Workspace-BQFjc1jH.js +0 -1
- package/dist/dashboard/assets/index-B8kld9xo.js +0 -104
- package/dist/dashboard/assets/index-BEmBgsbP.css +0 -2
- package/dist/dashboard/assets/task-errors-r-WYZ_S3.js +0 -1
- package/dist/goal-ETZWLVKO.js.map +0 -1
- /package/dist/{ChatApp-IF5D7XNH.js.map → ChatApp-C23NVTME.js.map} +0 -0
- /package/dist/{account-KBXJ5KR7.js.map → account-GG7UFSNY.js.map} +0 -0
- /package/dist/{accounts-XUJNDCFH.js.map → accounts-IPOGUMHF.js.map} +0 -0
- /package/dist/{budget-PHV4NRUS.js.map → budget-7QJGPYPF.js.map} +0 -0
- /package/dist/{chat-HGTX76DU.js.map → chat-3K2KXS3E.js.map} +0 -0
- /package/dist/{chunk-FZJNOG2T.js.map → chunk-3BTE76UD.js.map} +0 -0
- /package/dist/{chunk-FPSLYBLU.js.map → chunk-4FE2YV5U.js.map} +0 -0
- /package/dist/{chunk-AFCQURO5.js.map → chunk-JBX6J74G.js.map} +0 -0
- /package/dist/{chunk-EBV5A33R.js.map → chunk-KEURMO75.js.map} +0 -0
- /package/dist/{chunk-DFQW3MRD.js.map → chunk-LK2K73DC.js.map} +0 -0
- /package/dist/{chunk-ZVNX7CSO.js.map → chunk-U42YONUN.js.map} +0 -0
- /package/dist/{config-DG2E4VDW.js.map → config-BFEQFGAR.js.map} +0 -0
- /package/dist/{dist-IPMBGFJD.js.map → dist-VTC5E7Z5.js.map} +0 -0
- /package/dist/{doctor-5APOWJ5D.js.map → doctor-JLFYQ3EP.js.map} +0 -0
- /package/dist/{status-QQPP67I4.js.map → goal-JM7QYTL2.js.map} +0 -0
- /package/dist/{init-YDLNA3GD.js.map → init-6K4EGMTV.js.map} +0 -0
- /package/dist/{run-I6N7TLHV.js.map → run-ABQNQ722.js.map} +0 -0
- /package/dist/{start-ECLELJGJ.js.map → start-MSO7TGBX.js.map} +0 -0
- /package/dist/{tasks-RNMC2XFN.js.map → tasks-HEVT67YM.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../core/src/errors.ts","../../core/src/auth/login.ts","../../core/src/brain/markdown.ts","../../core/src/brain/system-prompt.ts","../../core/src/brain/context.ts","../../core/src/brain/global.ts","../../core/src/paths.ts","../../core/src/brain/fs-util.ts","../../core/src/brain/graph.ts","../../core/src/brain/lock.ts","../../core/src/brain/project.ts","../../core/src/config/schema.ts","../../core/src/config/writer.ts","../../core/src/config/loader.ts","../../core/src/events.ts","../../core/src/providers/shared/util.ts","../../core/src/providers/shared/errors.ts","../../core/src/rate-limiter/reported.ts","../../core/src/providers/shared/lines.ts","../../core/src/providers/shared/http.ts","../../core/src/providers/anthropic.ts","../../core/src/providers/antigravity-cli.ts","../../core/src/providers/shared/cli.ts","../../core/src/providers/shared/collect.ts","../../core/src/providers/claude-cli.ts","../../core/src/providers/codex-cli.ts","../../core/src/providers/gemini.ts","../../core/src/providers/gemini-cli.ts","../../core/src/identity/sandbox.ts","../../core/src/providers/gemini-web.ts","../../core/src/providers/openai.ts","../../core/src/providers/openai-compatible.ts","../../core/src/providers/registry.ts","../../core/src/providers/account-config.ts","../../core/src/types.ts","../../core/src/version.ts","../../core/src/rate-limiter/window.ts","../../core/src/budget/service.ts","../../core/src/engine.ts","../../core/src/identity/chromium.ts","../../core/src/identity/connect.ts","../../core/src/identity/keyring.ts","../../core/src/rate-limiter/tracker.ts","../../core/src/rate-limiter/tokens.ts","../../core/src/storage/ids.ts","../../core/src/router/candidates.ts","../../core/src/router/circuit-breaker.ts","../../core/src/router/errors.ts","../../core/src/router/router.ts","../../core/src/storage/accounts.ts","../../core/src/storage/audit.ts","../../core/src/storage/database.ts","../../core/src/storage/usage.ts","../../core/src/autonomous/process.ts","../../core/src/autonomous/tools.ts","../../core/src/autonomous/executor.ts","../../core/src/autonomous/claude-cli-executor.ts","../../core/src/autonomous/git.ts","../../core/src/autonomous/judge.ts","../../core/src/autonomous/validator.ts","../../core/src/autonomous/runner.ts","../../core/src/autonomous/create.ts","../../core/src/autonomous/workspace-lock.ts","../../core/src/brain/source.ts","../../core/src/account/client.ts","../../core/src/account/login-server.ts","../../core/src/account/store.ts","../../core/src/account/control.ts","../../core/src/brand.ts","../../core/src/changes/contract.ts","../../core/src/changes/service.ts","../../core/src/orchestrator/runners.ts","../../core/src/orchestrator/contract.ts","../../core/src/changes/parse.ts","../../core/src/changes/suggest.ts","../../core/src/goal/plan.ts","../../core/src/goal/code-tasks.ts","../../core/src/goal/orchestrator.ts","../../core/src/goal/service.ts","../../core/src/goal/store.ts","../../core/src/goal/create.ts","../../core/src/orchestrator/service.ts","../../core/src/orchestrator/plan.ts","../../core/src/orchestrator/store.ts","../../core/src/orchestrator/workspace.ts"],"sourcesContent":["import type { ProviderErrorKind, ProviderKind } from './types';\n\n/** Error kinds that should make the router try the next account/provider. */\nconst FAILOVER_KINDS: ReadonlySet<ProviderErrorKind> = new Set([\n 'rate_limit',\n 'quota_exhausted',\n 'unavailable',\n 'context_length',\n 'timeout',\n 'network',\n]);\n\nexport interface ProviderErrorOptions {\n kind: ProviderErrorKind;\n status?: number;\n provider?: ProviderKind;\n accountId?: string;\n /** Upstream hint (Retry-After) in milliseconds. */\n retryAfterMs?: number;\n cause?: unknown;\n}\n\nexport class ProviderError extends Error {\n readonly kind: ProviderErrorKind;\n readonly status?: number;\n readonly provider?: ProviderKind;\n readonly accountId?: string;\n readonly retryAfterMs?: number;\n\n constructor(message: string, opts: ProviderErrorOptions) {\n super(message, { cause: opts.cause });\n this.name = 'ProviderError';\n this.kind = opts.kind;\n this.status = opts.status;\n this.provider = opts.provider;\n this.accountId = opts.accountId;\n this.retryAfterMs = opts.retryAfterMs;\n }\n\n /** True when the request may succeed on a different account or provider. */\n get failover(): boolean {\n return FAILOVER_KINDS.has(this.kind);\n }\n\n toJSON() {\n return {\n name: this.name,\n kind: this.kind,\n message: this.message,\n status: this.status,\n provider: this.provider,\n accountId: this.accountId,\n retryAfterMs: this.retryAfterMs,\n };\n }\n}\n\n/** Map an HTTP status code from an upstream provider to an error kind. */\nexport function errorKindFromStatus(status: number): ProviderErrorKind {\n if (status === 429) return 'rate_limit';\n if (status === 401 || status === 403) return 'auth';\n if (status === 408 || status === 504) return 'timeout';\n if (status === 413) return 'context_length';\n if (status === 400 || status === 404 || status === 422) return 'bad_request';\n // 529 is Anthropic's \"overloaded\".\n if (status === 500 || status === 502 || status === 503 || status === 529) return 'unavailable';\n return 'unknown';\n}\n\n/** Parse a Retry-After header (seconds or HTTP date) into milliseconds. */\nexport function parseRetryAfter(\n value: string | null | undefined,\n now = Date.now(),\n): number | undefined {\n if (!value) return undefined;\n const seconds = Number(value);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n const date = Date.parse(value);\n return Number.isNaN(date) ? undefined : Math.max(0, date - now);\n}\n\nexport function isFailoverEligible(err: unknown): boolean {\n return err instanceof ProviderError && err.failover;\n}\n","import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';\nimport { z } from 'zod';\nimport type { LoginProvider, LoginStatus, LoginUser } from '../types';\n\nconst credentials = z.object({ clientId: z.string().min(1), clientSecret: z.string().min(1) });\nconst optionsSchema = z.object({\n origin: z\n .string()\n .url()\n .refine((value) => {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n return false;\n }\n return (\n url.origin === value &&\n (url.protocol === 'https:' ||\n (url.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname)))\n );\n }, 'Use an HTTPS origin, or HTTP on loopback, without a path or trailing slash'),\n providers: z\n .object({ google: credentials.optional(), github: credentials.optional() })\n .refine(\n (value) => Boolean(value.google || value.github),\n 'Configure at least one login provider',\n ),\n allowedUsers: z.array(z.string().regex(/^(google|github):[^\\s:]+$/)).min(1),\n});\n\nexport type LoginOptions = z.infer<typeof optionsSchema>;\n\nconst ENDPOINTS = {\n google: {\n authorize: 'https://accounts.google.com/o/oauth2/v2/auth',\n token: 'https://oauth2.googleapis.com/token',\n user: 'https://openidconnect.googleapis.com/v1/userinfo',\n scope: 'openid profile',\n },\n github: {\n authorize: 'https://github.com/login/oauth/authorize',\n token: 'https://github.com/login/oauth/access_token',\n user: 'https://api.github.com/user',\n scope: 'read:user',\n },\n} as const;\n\nconst PENDING_MS = 10 * 60_000;\nconst PENDING_MAX = 1000;\nconst PENDING_PER_PEER = 20;\nconst SESSION_MS = 8 * 60 * 60_000;\nconst random = () => randomBytes(32).toString('base64url');\nconst digest = (value: string) => createHash('sha256').update(value).digest('base64url');\nfunction equal(left: string, right: string): boolean {\n const a = Buffer.from(left);\n const b = Buffer.from(right);\n return a.length === b.length && timingSafeEqual(a, b);\n}\n\nexport class LoginError extends Error {\n constructor() {\n super('Sign-in could not be completed. Try again or contact the workspace owner.');\n }\n}\n\n/** In-memory, single-owner gateway login. Provider tokens are discarded after user lookup. */\nexport class LoginService {\n readonly options: LoginOptions;\n private readonly pending = new Map<\n string,\n { provider: LoginProvider; binding: string; verifier: string; peer: string; expires: number }\n >();\n private readonly sessions = new Map<string, { user: LoginUser; expires: number }>();\n\n constructor(\n options: LoginOptions,\n private readonly fetcher: typeof fetch = fetch,\n private readonly now: () => number = Date.now,\n ) {\n const parsed = optionsSchema.safeParse(options);\n if (!parsed.success)\n throw new Error(\n 'Invalid login configuration: set a canonical origin, provider credentials and an allowed user list.',\n );\n this.options = parsed.data;\n }\n\n status(session?: string): LoginStatus {\n return {\n required: true,\n providers: (['google', 'github'] as const).filter(\n (provider) => this.options.providers[provider],\n ),\n user: this.user(session),\n };\n }\n\n user(session?: string): LoginUser | null {\n this.prune();\n return session ? (this.sessions.get(digest(session))?.user ?? null) : null;\n }\n\n logout(session?: string): void {\n if (session) this.sessions.delete(digest(session));\n }\n\n /**\n * Start a sign-in. `peer` is the connection's address as the HTTP server sees it (never a\n * forwarded header unless the server was configured to trust its proxy). Unfinished sign-ins\n * never block a new one: each peer keeps a few, and when the table is full the oldest goes.\n */\n begin(provider: LoginProvider, peer = 'unknown'): { url: string; binding: string } {\n this.prune();\n const client = this.options.providers[provider];\n if (!client) throw new LoginError();\n // Map order is insertion order, so the first entries are the oldest.\n let mine = 0;\n for (const value of this.pending.values()) if (value.peer === peer) mine++;\n for (const [key, value] of this.pending) {\n if (mine < PENDING_PER_PEER) break;\n if (value.peer === peer) {\n this.pending.delete(key);\n mine--;\n }\n }\n while (this.pending.size >= PENDING_MAX) {\n const oldest = this.pending.keys().next().value;\n if (oldest === undefined) break;\n this.pending.delete(oldest);\n }\n const state = random();\n const binding = random();\n const verifier = random();\n this.pending.set(digest(state), {\n provider,\n binding: digest(binding),\n verifier,\n peer,\n expires: this.now() + PENDING_MS,\n });\n const url = new URL(ENDPOINTS[provider].authorize);\n url.search = new URLSearchParams({\n client_id: client.clientId,\n redirect_uri: this.callback(provider),\n response_type: 'code',\n scope: ENDPOINTS[provider].scope,\n state,\n code_challenge: digest(verifier),\n code_challenge_method: 'S256',\n }).toString();\n return { url: url.toString(), binding };\n }\n\n async finish(\n provider: LoginProvider,\n state: string,\n code: string,\n binding: string,\n ): Promise<string> {\n this.prune();\n const flow = this.pending.get(digest(state));\n if (!flow || flow.provider !== provider || !equal(flow.binding, digest(binding)))\n throw new LoginError();\n this.pending.delete(digest(state));\n const client = this.options.providers[provider];\n if (!client) throw new LoginError();\n try {\n const response = await this.fetcher(ENDPOINTS[provider].token, {\n method: 'POST',\n redirect: 'error',\n signal: AbortSignal.timeout(15_000),\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n client_id: client.clientId,\n client_secret: client.clientSecret,\n code,\n code_verifier: flow.verifier,\n grant_type: 'authorization_code',\n redirect_uri: this.callback(provider),\n }),\n });\n if (!response.ok) throw new LoginError();\n const token = z\n .object({ access_token: z.string().min(1), token_type: z.string().regex(/^bearer$/i) })\n .parse(await response.json());\n const profile = await this.fetcher(ENDPOINTS[provider].user, {\n headers: {\n Accept: 'application/json',\n Authorization: `Bearer ${token.access_token}`,\n 'User-Agent': 'DaveCode',\n },\n redirect: 'error',\n signal: AbortSignal.timeout(15_000),\n });\n if (!profile.ok) throw new LoginError();\n const data: unknown = await profile.json();\n let user: LoginUser;\n if (provider === 'google') {\n const parsed = z\n .object({ sub: z.string().min(1), name: z.string().max(200).optional() })\n .parse(data);\n user = { id: parsed.sub, provider, name: parsed.name ?? 'Google user' };\n } else {\n const parsed = z\n .object({\n id: z.number().int().positive(),\n login: z.string().min(1).max(200),\n name: z.string().max(200).nullable().optional(),\n })\n .parse(data);\n user = { id: String(parsed.id), provider, name: parsed.name || parsed.login };\n }\n if (\n !this.options.allowedUsers.includes(`${provider}:${user.id}`) ||\n this.sessions.size >= 1000\n )\n throw new LoginError();\n const session = random();\n this.sessions.set(digest(session), { user, expires: this.now() + SESSION_MS });\n return session;\n } catch {\n // Upstream bodies, credentials and authorization codes never reach logs or clients.\n throw new LoginError();\n }\n }\n\n clear(): void {\n this.pending.clear();\n this.sessions.clear();\n }\n\n private callback(provider: LoginProvider): string {\n return `${this.options.origin}/api/auth/${provider}/callback`;\n }\n\n private prune(): void {\n const now = this.now();\n for (const [key, value] of this.pending) if (value.expires <= now) this.pending.delete(key);\n for (const [key, value] of this.sessions) if (value.expires <= now) this.sessions.delete(key);\n }\n}\n\n/** Read only dedicated auth variables. No credentials are exposed in validation errors. */\nexport function loginFromEnv(env: NodeJS.ProcessEnv): LoginService | undefined {\n if (env.DAVECODE_LOGIN_ENABLED !== '1') return undefined;\n const providers: LoginOptions['providers'] = {};\n for (const [provider, prefix] of [\n ['google', 'GOOGLE'],\n ['github', 'GITHUB'],\n ] as const) {\n const clientId = env[`DAVECODE_${prefix}_CLIENT_ID`];\n const clientSecret = env[`DAVECODE_${prefix}_CLIENT_SECRET`];\n if (clientId || clientSecret)\n providers[provider] = { clientId: clientId ?? '', clientSecret: clientSecret ?? '' };\n }\n return new LoginService({\n origin: env.DAVECODE_PUBLIC_ORIGIN ?? '',\n providers,\n allowedUsers: (env.DAVECODE_LOGIN_ALLOWED_USERS ?? '')\n .split(',')\n .map((value) => value.trim())\n .filter(Boolean),\n });\n}\n","/**\n * A deliberately small markdown section parser. It only understands level-2 headings\n * (`## Title`) outside fenced code blocks, which is all STATE.md needs. Everything else is\n * treated as opaque text and preserved byte-for-byte.\n */\n\nexport interface MarkdownSection {\n heading: string;\n /** Index of the `## ` line. */\n start: number;\n /** Exclusive end index (start of the next section, or number of lines). */\n end: number;\n}\n\nconst FENCE = /^ {0,3}(`{3,}|~{3,})/;\nconst H2 = /^##[ \\t]+(\\S.*?)[ \\t]*$/;\n\nfunction stripCr(line: string): string {\n return line.endsWith('\\r') ? line.slice(0, -1) : line;\n}\n\nfunction listSections(lines: string[]): MarkdownSection[] {\n const sections: MarkdownSection[] = [];\n let fence: string | undefined;\n lines.forEach((raw, index) => {\n const line = stripCr(raw);\n const fenceMatch = FENCE.exec(line);\n if (fenceMatch) {\n const marker = (fenceMatch[1] as string)[0] as string;\n if (fence === undefined) fence = marker;\n else if (fence === marker) fence = undefined;\n return;\n }\n if (fence !== undefined) return;\n const match = H2.exec(line);\n if (match) {\n const prev = sections[sections.length - 1];\n if (prev) prev.end = index;\n sections.push({\n heading: (match[1] as string).replace(/\\s+#+$/, ''),\n start: index,\n end: lines.length,\n });\n }\n });\n return sections;\n}\n\nconst sameHeading = (a: string, b: string) => a.trim().toLowerCase() === b.trim().toLowerCase();\n\n/** Level-2 sections in document order. */\nexport function parseSections(markdown: string): MarkdownSection[] {\n return listSections(markdown.split('\\n'));\n}\n\n/** Body text of a `## heading` section (without the heading line), trimmed; undefined if absent. */\nexport function getSection(markdown: string, heading: string): string | undefined {\n const lines = markdown.split('\\n');\n const section = listSections(lines).find((s) => sameHeading(s.heading, heading));\n if (!section) return undefined;\n return lines\n .slice(section.start + 1, section.end)\n .map(stripCr)\n .join('\\n')\n .trim();\n}\n\n/**\n * Replaces the body of `## heading` (matched case-insensitively), or appends a new section at the\n * end when it does not exist. All other content is left untouched.\n */\nexport function upsertSection(markdown: string, heading: string, body: string): string {\n const crlf = markdown.includes('\\r\\n');\n const cr = crlf ? '\\r' : '';\n const block = [`## ${heading.trim()}`, '', ...body.trim().split(/\\r?\\n/)].map((l) => l + cr);\n\n const lines = markdown.split('\\n');\n const section = listSections(lines).find((s) => sameHeading(s.heading, heading));\n\n if (!section) {\n const base = markdown.replace(/\\s+$/, '');\n if (base === '') return `${block.join('\\n')}\\n`;\n return `${base}${crlf ? '\\r\\n\\r\\n' : '\\n\\n'}${block.join('\\n')}\\n`;\n }\n\n const after = lines.slice(section.end);\n // A following section needs a blank separator line; the last section just ends with a newline.\n const replacement = after.length > 0 ? [...block, cr] : [...block, ''];\n return [...lines.slice(0, section.start), ...replacement, ...after].join('\\n');\n}\n\nconst LAST_UPDATED = /^_Last updated: \\d{4}-\\d{2}-\\d{2}_[ \\t]*(\\r?)$/m;\n\n/** Rewrites the `_Last updated: YYYY-MM-DD_` line when present; otherwise returns the input. */\nexport function touchLastUpdated(markdown: string, date: Date): string {\n const day = date.toISOString().slice(0, 10);\n return markdown.replace(LAST_UPDATED, (_m, cr: string) => `_Last updated: ${day}_${cr}`);\n}\n","/**\n * The DaveCode master system prompt (docs/SPEC.md section 6). `system-prompt.test.ts` verifies\n * that this constant stays identical to the fenced block in the specification.\n */\nexport const DAVECODE_SYSTEM_PROMPT = `SYSTEM PROMPT: DAVECODE_AUTONOMOUS_ENGINE_V1\n\nYou are operating as DaveCode, an elite, fully autonomous multi-account AI software engineering\nengine and protocol orchestrator. You are responsible for local context management, task\nexecution, dynamic failover orchestration, and rigorous quality assurance.\n\n### CORE OPERATIONAL DIRECTIVES\n\n1. STRICT ISOLATION & ACCOUNT INTEGRITY\n - Never write runtime session artifacts to global environments.\n - Respect isolated directory boundaries. Ensure all sub-process calls specify their\n designated \\`CLAUDE_CONFIG_DIR\\` or profile directory.\n - Do not leak authorization headers or state cookies across accounts.\n\n2. DUAL-BRAIN CONTEXT MAINTENANCE\n - Before executing any modification, inspect \\`.davecode/STATE.md\\` and\n \\`.davecode/ARCHITECTURE.md\\`.\n - Update \\`.davecode/STATE.md\\` immediately upon changing execution status.\n - Mark task statuses in \\`.davecode/TASK_GRAPH.json\\` using explicit states: \\`PENDING\\`,\n \\`IN_PROGRESS\\`, \\`SUCCESS\\`, \\`FAILED\\`.\n\n3. DETERMINISTIC TEST-DRIVEN QUALITY GATES\n - Code changes are NOT complete until linters and tests pass clean (exit code 0).\n - If a test or linter fails:\n a. Capture exact stderr and stdout logs.\n b. Diagnose root cause in context.\n c. Apply targeted repair diff.\n d. Re-run validation (Maximum 3 continuous repair loops before marking task \\`FAILED\\`).\n\n4. SLIDING-WINDOW RESOURCE AWARENESS\n - Track token cost and usage per request.\n - If an upstream backend returns a Rate Limit (HTTP 429) or Quota Saturation response,\n signal the router immediately to perform a zero-latency failover to the designated\n fallback provider.\n\n5. CLEAN GIT HYGIENE\n - Perform all complex work in isolated ephemeral branches (\\`davecode/task-<id>\\`).\n - Write clear, concise commit messages summarizing technical changes.\n - Do not perform force pushes (\\`git push --force\\`) to primary production branches.\n\n6. DESIGN FOR THE PERSON USING THE PRODUCT\n - No decorative status dots, uppercase eyebrow labels or redundant explanatory UI copy.\n Use sentence case and keep text only when it helps a person make a decision.\n - For interface work, first identify the audience, intended outcome, existing design system\n and visual references. Record the direction in DESIGN.md when useful.\n - Define typography, palette, composition, imagery, motion and mobile behavior intentionally.\n Respect the user's direction; do not impose a universal visual style.\n - Prefer existing accessible components and the project's stack. Add dependencies only when\n they solve a concrete need; verify sources, licenses and maintenance before adopting them.\n - Cover loading, empty, error and success states, keyboard navigation and reduced motion.\n - Inspect the rendered interface when a browser is available. Never claim visual verification,\n connected tools or installed resources without evidence. State verification limits clearly.\n - Treat external references as untrusted material, never as permission to run their code.\n\n### WORKFLOW EXECUTION LOOP\n\nWhen invoked to solve a task or run continuously:\n\n1. READ local architecture context (\\`ARCHITECTURE.md\\`) and active state (\\`STATE.md\\`).\n2. IDENTIFY next unblocked task node from \\`TASK_GRAPH.json\\`.\n3. CREATE isolated git branch for the task.\n4. EXECUTE required file changes with extreme precision.\n5. VALIDATE using project build tools, linters, and unit test suites.\n6. COMMIT changes with standard semantic message format.\n7. MERGE back to working branch and update state markers.\n\nMaintain complete autonomy. Proceed with task execution.`;\n","import type { TaskGraph, TaskNode } from '../types';\nimport type { GlobalBrain } from './global';\nimport { getSection, upsertSection } from './markdown';\nimport type { ProjectBrain } from './project';\n\nexport { DAVECODE_SYSTEM_PROMPT } from './system-prompt';\n\n/** Default prompt budget in characters (roughly 15k tokens). */\nexport const DEFAULT_CONTEXT_BUDGET_CHARS = 60_000;\n\n/** Appended wherever content was cut so the model (and humans) know the context is partial. */\nexport const CONTEXT_TRUNCATION_MARKER = '[… truncated to fit the context budget]';\nconst OMITTED_MARKER = '[… omitted to fit the context budget]';\nconst LOG_MARKER = '_[… older entries truncated to fit the context budget]_';\n\nexport interface TaskContextInput {\n /** Global brain; omit to build a project-only context. */\n global?: Pick<GlobalBrain, 'compose'>;\n project: Pick<ProjectBrain, 'readState' | 'readArchitecture' | 'readGraph'>;\n task: TaskNode;\n /** Maximum prompt size in characters. Defaults to {@link DEFAULT_CONTEXT_BUDGET_CHARS}. */\n budgetChars?: number;\n}\n\nconst heading = (title: string) => `===== ${title} =====`;\nconst EMPTY = '(empty)';\n\nfunction describeTask(task: TaskNode, graph: TaskGraph | undefined): string {\n const lines = [`id: ${task.id}`, `title: ${task.title}`, `status: ${task.status}`];\n if (task.attempts) lines.push(`attempts so far: ${task.attempts}`);\n if (task.branch) lines.push(`branch: ${task.branch}`);\n if (task.description) lines.push('', 'Description:', task.description.trim());\n if (task.acceptance?.length) {\n lines.push('', 'Acceptance criteria:', ...task.acceptance.map((c) => `- ${c}`));\n }\n if (task.notes) lines.push('', 'Notes from previous attempts:', task.notes.trim());\n if (task.dependsOn.length > 0) {\n lines.push('', 'Dependencies:');\n const byId = new Map(graph?.tasks.map((t) => [t.id, t]));\n for (const id of task.dependsOn) {\n const dep = byId.get(id);\n if (!dep) {\n lines.push(`- ${id}: (not found in the task graph)`);\n continue;\n }\n const note = dep.notes?.trim().split('\\n')[0]?.slice(0, 200);\n lines.push(`- ${dep.id}: ${dep.title} [${dep.status}]${note ? ` (${note})` : ''}`);\n }\n }\n return lines.join('\\n');\n}\n\n/** Cuts `text` by at least `excess` characters from the end, leaving a marker. */\nfunction cutEnd(text: string, excess: number, omittedLabel = OMITTED_MARKER): string {\n const keep = text.length - excess - CONTEXT_TRUNCATION_MARKER.length - 1;\n if (keep <= 0) return omittedLabel;\n return `${text.slice(0, keep).trimEnd()}\\n${CONTEXT_TRUNCATION_MARKER}`;\n}\n\n/** Drops the oldest Activity log bullets of STATE.md (at least `excess` characters). */\nfunction trimActivityLog(state: string, excess: number): string {\n const body = getSection(state, 'Activity log');\n if (body === undefined) return state;\n const lines = body.split('\\n').filter((l) => l !== LOG_MARKER);\n let removed = 0;\n let drop = 0;\n const needed = excess + LOG_MARKER.length + 1;\n while (drop < lines.length && removed < needed) {\n removed += (lines[drop] as string).length + 1;\n drop++;\n }\n const kept = lines.slice(drop);\n return upsertSection(state, 'Activity log', [LOG_MARKER, ...kept].join('\\n'));\n}\n\n/**\n * Builds the single prompt injected into an autonomous task: GLOBAL BRAIN, ARCHITECTURE.md,\n * STATE.md and the task itself, in that order, each under a `===== TITLE =====` delimiter.\n *\n * When the result exceeds `budgetChars`, the least important material goes first: global notes,\n * then the STATE.md activity log (oldest entries first), then the rest of STATE.md, and only as a\n * last resort ARCHITECTURE.md. Every cut leaves an explicit truncation marker. The task section is\n * never truncated, so a budget smaller than the task itself yields an over-budget result.\n */\nexport async function buildTaskContext(input: TaskContextInput): Promise<string> {\n const budget = input.budgetChars ?? DEFAULT_CONTEXT_BUDGET_CHARS;\n const [globalNotes, architectureRaw, stateRaw, graph] = await Promise.all([\n input.global?.compose() ?? Promise.resolve(''),\n input.project.readArchitecture(),\n input.project.readState(),\n input.project.readGraph(),\n ]);\n\n let global = globalNotes.trim();\n let architecture = architectureRaw.trim();\n let state = stateRaw.trim();\n const taskText = describeTask(input.task, graph);\n\n const render = () =>\n [\n heading('GLOBAL BRAIN (user preferences and coding patterns)'),\n global || EMPTY,\n '',\n heading('PROJECT ARCHITECTURE (.davecode/ARCHITECTURE.md)'),\n architecture || EMPTY,\n '',\n heading('PROJECT STATE (.davecode/STATE.md)'),\n state || EMPTY,\n '',\n heading('CURRENT TASK'),\n taskText,\n ].join('\\n');\n\n const excess = () => render().length - budget;\n\n if (global && excess() > 0) global = cutEnd(global, excess());\n if (state && excess() > 0) state = trimActivityLog(state, excess());\n if (state && excess() > 0) state = cutEnd(state, excess());\n if (architecture && excess() > 0) architecture = cutEnd(architecture, excess());\n\n return render();\n}\n","import { readdir, rm, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { globalPaths } from '../paths';\nimport { atomicWriteFile, isNodeError, readFileIfExists } from './fs-util';\n\nexport class InvalidNoteNameError extends Error {\n constructor(\n readonly noteName: string,\n reason: string,\n ) {\n super(`Invalid brain note name ${JSON.stringify(noteName)}: ${reason}`);\n this.name = 'InvalidNoteNameError';\n }\n}\n\nexport interface NoteInfo {\n /** Note name without the `.md` extension. */\n name: string;\n bytes: number;\n /** ISO timestamp of the last modification. */\n updatedAt: string;\n}\n\nconst MAX_NAME_LENGTH = 100;\nconst SAFE_NAME = /^[A-Za-z0-9][A-Za-z0-9._ -]*$/;\nconst WINDOWS_RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;\n\n/**\n * Validates a note name and returns its canonical form (no `.md` suffix). Notes are flat files:\n * separators, `..`, leading dots, control characters and reserved device names are rejected.\n */\nexport function sanitizeNoteName(raw: string): string {\n const name = raw.trim().replace(/\\.md$/i, '');\n if (name === '') throw new InvalidNoteNameError(raw, 'name is empty');\n if (name.length > MAX_NAME_LENGTH) throw new InvalidNoteNameError(raw, 'name is too long');\n if (/[\\\\/]/.test(name)) throw new InvalidNoteNameError(raw, 'path separators are not allowed');\n if (name.includes('..')) throw new InvalidNoteNameError(raw, '\"..\" is not allowed');\n if (!SAFE_NAME.test(name)) {\n throw new InvalidNoteNameError(\n raw,\n 'use letters, digits, spaces, \"-\", \"_\" and \".\" (not at the start)',\n );\n }\n if (/[. ]$/.test(name)) throw new InvalidNoteNameError(raw, 'must not end with \".\" or a space');\n if (WINDOWS_RESERVED.test(name.split('.')[0] ?? '')) {\n throw new InvalidNoteNameError(raw, 'reserved device name');\n }\n return name;\n}\n\n/** The user's global brain: markdown notes in `~/.davecode/brain/` (preferences, patterns). */\nexport class GlobalBrain {\n constructor(readonly dir: string = globalPaths().brain) {}\n\n private fileFor(name: string): string {\n return join(this.dir, `${sanitizeNoteName(name)}.md`);\n }\n\n /** All notes, sorted by name. Returns an empty list when the directory does not exist. */\n async list(): Promise<NoteInfo[]> {\n let entries: string[];\n try {\n entries = await readdir(this.dir);\n } catch (err) {\n if (isNodeError(err, 'ENOENT')) return [];\n throw err;\n }\n const notes: NoteInfo[] = [];\n for (const entry of entries) {\n if (!entry.toLowerCase().endsWith('.md')) continue;\n let name: string;\n try {\n name = sanitizeNoteName(entry);\n } catch {\n continue; // foreign file with a name we would never write; ignore it\n }\n const info = await stat(join(this.dir, entry));\n if (!info.isFile()) continue;\n notes.push({ name, bytes: info.size, updatedAt: info.mtime.toISOString() });\n }\n return notes.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n }\n\n /** Note content, or `undefined` when it does not exist. */\n async read(name: string): Promise<string | undefined> {\n return readFileIfExists(this.fileFor(name));\n }\n\n async write(name: string, content: string): Promise<void> {\n await atomicWriteFile(this.fileFor(name), content);\n }\n\n /** Deletes a note. Returns false when it did not exist. */\n async delete(name: string): Promise<boolean> {\n const file = this.fileFor(name);\n try {\n await stat(file);\n } catch (err) {\n if (isNodeError(err, 'ENOENT')) return false;\n throw err;\n }\n await rm(file, { force: true });\n return true;\n }\n\n /** Every non-empty note concatenated under a `## <name>` heading, sorted by name. */\n async compose(): Promise<string> {\n const parts: string[] = [];\n for (const { name } of await this.list()) {\n const content = (await this.read(name))?.trim();\n if (content) parts.push(`## ${name}\\n\\n${content}`);\n }\n return parts.join('\\n\\n');\n }\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/** Root of the global user brain and runtime state. Override with DAVECODE_HOME. */\nexport function davecodeHome(env: NodeJS.ProcessEnv = process.env): string {\n return env.DAVECODE_HOME ?? join(homedir(), '.davecode');\n}\n\nexport interface GlobalPaths {\n home: string;\n config: string;\n database: string;\n /** Encryption master key for the keyring (created with 0600 permissions). */\n masterKey: string;\n brain: string;\n sandboxes: string;\n profiles: string;\n logs: string;\n}\n\nexport function globalPaths(home = davecodeHome()): GlobalPaths {\n return {\n home,\n config: join(home, 'config.json'),\n database: join(home, 'state.db'),\n masterKey: join(home, 'master.key'),\n brain: join(home, 'brain'),\n sandboxes: join(home, 'sandboxes'),\n profiles: join(home, 'profiles'),\n logs: join(home, 'logs'),\n };\n}\n\nexport interface ProjectPaths {\n root: string;\n dir: string;\n config: string;\n state: string;\n architecture: string;\n taskGraph: string;\n}\n\n/** Local project brain inside a repository (`<repo>/.davecode`). */\nexport function projectPaths(root: string): ProjectPaths {\n const dir = join(root, '.davecode');\n return {\n root,\n dir,\n config: join(dir, 'config.json'),\n state: join(dir, 'STATE.md'),\n architecture: join(dir, 'ARCHITECTURE.md'),\n taskGraph: join(dir, 'TASK_GRAPH.json'),\n };\n}\n","import { randomBytes } from 'node:crypto';\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\n\nconst sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n\n/** Windows can briefly refuse to rename over a file another process is reading. */\nconst RETRYABLE_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES']);\n\n/**\n * Writes `content` to `path` atomically: the data goes to a sibling temp file first and is then\n * renamed over the target, so readers see either the old or the new content, never a torn write.\n */\nexport async function atomicWriteFile(path: string, content: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const tmp = `${path}.${process.pid}.${randomBytes(4).toString('hex')}.tmp`;\n try {\n await writeFile(tmp, content, 'utf8');\n for (let attempt = 0; ; attempt++) {\n try {\n await rename(tmp, path);\n return;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (attempt >= 8 || !code || !RETRYABLE_RENAME_CODES.has(code)) throw err;\n await sleep(10 * (attempt + 1));\n }\n }\n } catch (err) {\n await rm(tmp, { force: true }).catch(() => undefined);\n throw err;\n }\n}\n\n/** Reads a UTF-8 file, returning `undefined` when it does not exist. */\nexport async function readFileIfExists(path: string): Promise<string | undefined> {\n try {\n return await readFile(path, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return undefined;\n throw err;\n }\n}\n\nexport function isNodeError(err: unknown, code: string): boolean {\n return (err as NodeJS.ErrnoException | undefined)?.code === code;\n}\n","import { z } from 'zod';\nimport type { TaskGraph, TaskNode, TaskStatus } from '../types';\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\nexport type TaskGraphIssueCode =\n | 'invalid_json'\n | 'schema'\n | 'duplicate_id'\n | 'unknown_dependency'\n | 'self_dependency'\n | 'cycle'\n | 'unknown_task'\n | 'invalid_transition'\n /** Deleting a task that other tasks still depend on. */\n | 'has_dependents'\n /** Deleting a task the runner is working on. */\n | 'task_in_progress';\n\nexport interface TaskGraphIssue {\n code: TaskGraphIssueCode;\n message: string;\n taskId?: string;\n /** For `cycle`: the ids along the cycle, first id repeated at the end. */\n cycle?: string[];\n /** For `has_dependents`: ids of the tasks that depend on `taskId`. */\n dependents?: string[];\n}\n\n/** Thrown when a task graph is malformed or an update is not allowed. */\nexport class TaskGraphError extends Error {\n readonly issues: TaskGraphIssue[];\n\n constructor(issues: TaskGraphIssue[]) {\n super(\n issues.length === 1\n ? `Invalid task graph: ${issues[0]?.message}`\n : `Invalid task graph (${issues.length} issues):\\n${issues\n .map((i) => ` - ${i.message}`)\n .join('\\n')}`,\n );\n this.name = 'TaskGraphError';\n this.issues = issues;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Schema\n// ---------------------------------------------------------------------------\n\nexport const TASK_STATUSES = ['PENDING', 'IN_PROGRESS', 'SUCCESS', 'FAILED'] as const;\n\n/** kebab-case or snake_case segments, dots allowed inside (e.g. `release-0.1.0`). */\nconst TASK_ID_PATTERN = /^[a-z0-9]+(?:[-_.][a-z0-9]+)*$/;\n\nexport const taskIdSchema = z\n .string()\n .regex(TASK_ID_PATTERN, 'must be lowercase kebab-case or snake_case (letters, digits, - _ .)');\n\nexport const taskStatusSchema = z.enum(TASK_STATUSES);\n\nexport const taskNodeSchema = z.object({\n id: taskIdSchema,\n title: z.string().min(1),\n description: z.string().optional(),\n status: taskStatusSchema,\n dependsOn: z.array(z.string().min(1)).default([]),\n priority: z.number().finite().optional(),\n acceptance: z.array(z.string()).optional(),\n attempts: z.number().int().nonnegative().optional(),\n branch: z.string().optional(),\n notes: z.string().optional(),\n createdAt: z.string().optional(),\n updatedAt: z.string().optional(),\n});\n\nexport const taskGraphSchema = z.object({\n version: z.literal(1),\n tasks: z.array(taskNodeSchema),\n});\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\n/** Follows `dependsOn` edges; returns each distinct cycle as `[a, b, c, a]`. Ignores self-loops. */\nexport function findCycles(graph: TaskGraph): string[][] {\n const byId = new Map<string, TaskNode>();\n for (const task of graph.tasks) if (!byId.has(task.id)) byId.set(task.id, task);\n\n const cycles: string[][] = [];\n const seen = new Set<string>();\n const done = new Set<string>();\n const onStack = new Set<string>();\n const stack: string[] = [];\n\n const visit = (id: string): void => {\n onStack.add(id);\n stack.push(id);\n for (const dep of byId.get(id)?.dependsOn ?? []) {\n if (dep === id || !byId.has(dep)) continue;\n if (onStack.has(dep)) {\n const cycle = [...stack.slice(stack.indexOf(dep)), dep];\n const key = canonicalCycleKey(cycle);\n if (!seen.has(key)) {\n seen.add(key);\n cycles.push(cycle);\n }\n } else if (!done.has(dep)) {\n visit(dep);\n }\n }\n stack.pop();\n onStack.delete(id);\n done.add(id);\n };\n\n for (const id of byId.keys()) if (!done.has(id)) visit(id);\n return cycles;\n}\n\nfunction canonicalCycleKey(cycle: string[]): string {\n const ring = cycle.slice(0, -1);\n let start = 0;\n for (let i = 1; i < ring.length; i++) {\n if ((ring[i] as string) < (ring[start] as string)) start = i;\n }\n return [...ring.slice(start), ...ring.slice(0, start)].join('\\u0000');\n}\n\n/** Structural checks on an already schema-valid graph. Returns every issue found. */\nexport function validateTaskGraph(graph: TaskGraph): TaskGraphIssue[] {\n const issues: TaskGraphIssue[] = [];\n const ids = new Set<string>();\n const reportedDuplicates = new Set<string>();\n\n for (const task of graph.tasks) {\n if (ids.has(task.id) && !reportedDuplicates.has(task.id)) {\n reportedDuplicates.add(task.id);\n issues.push({\n code: 'duplicate_id',\n taskId: task.id,\n message: `duplicate task id \"${task.id}\"`,\n });\n }\n ids.add(task.id);\n }\n\n for (const task of graph.tasks) {\n for (const dep of task.dependsOn) {\n if (dep === task.id) {\n issues.push({\n code: 'self_dependency',\n taskId: task.id,\n message: `task \"${task.id}\" depends on itself`,\n });\n } else if (!ids.has(dep)) {\n issues.push({\n code: 'unknown_dependency',\n taskId: task.id,\n message: `task \"${task.id}\" depends on unknown task \"${dep}\"`,\n });\n }\n }\n }\n\n for (const cycle of findCycles(graph)) {\n issues.push({\n code: 'cycle',\n cycle,\n message: `dependency cycle: ${cycle.join(' → ')}`,\n });\n }\n return issues;\n}\n\n/** Validates an arbitrary value (or JSON string) into a `TaskGraph`, or throws `TaskGraphError`. */\nexport function parseTaskGraph(input: unknown): TaskGraph {\n let value = input;\n if (typeof input === 'string') {\n try {\n value = JSON.parse(input);\n } catch (err) {\n throw new TaskGraphError([\n {\n code: 'invalid_json',\n message: `not valid JSON (${err instanceof Error ? err.message : String(err)})`,\n },\n ]);\n }\n }\n\n const parsed = taskGraphSchema.safeParse(value);\n if (!parsed.success) {\n throw new TaskGraphError(\n parsed.error.issues.map((issue) => ({\n code: 'schema' as const,\n message: `${issue.path.length > 0 ? issue.path.join('.') : '(root)'}: ${issue.message}`,\n })),\n );\n }\n\n const graph: TaskGraph = parsed.data;\n const issues = validateTaskGraph(graph);\n if (issues.length > 0) throw new TaskGraphError(issues);\n return graph;\n}\n\n// ---------------------------------------------------------------------------\n// Queries\n// ---------------------------------------------------------------------------\n\nfunction indexById(graph: TaskGraph): Map<string, TaskNode> {\n return new Map(graph.tasks.map((t) => [t.id, t]));\n}\n\n/** Tasks ordered so every task appears after its dependencies (file order breaks ties). */\nexport function topologicalOrder(graph: TaskGraph): TaskNode[] {\n const cycles = findCycles(graph);\n if (cycles.length > 0) {\n throw new TaskGraphError(\n cycles.map((cycle) => ({\n code: 'cycle' as const,\n cycle,\n message: `dependency cycle: ${cycle.join(' → ')}`,\n })),\n );\n }\n const byId = indexById(graph);\n const ordered: TaskNode[] = [];\n const visited = new Set<string>();\n const visit = (task: TaskNode): void => {\n if (visited.has(task.id)) return;\n visited.add(task.id);\n for (const dep of task.dependsOn) {\n const depTask = byId.get(dep);\n if (depTask) visit(depTask);\n }\n ordered.push(task);\n };\n for (const task of graph.tasks) visit(task);\n return ordered;\n}\n\nfunction isUnblocked(task: TaskNode, byId: Map<string, TaskNode>): boolean {\n return task.dependsOn.every((dep) => byId.get(dep)?.status === 'SUCCESS');\n}\n\n/** PENDING tasks whose dependencies are all SUCCESS: highest priority first, ties in file order. */\nexport function readyTasks(graph: TaskGraph): TaskNode[] {\n const byId = indexById(graph);\n return graph.tasks\n .map((task, index) => ({ task, index }))\n .filter(({ task }) => task.status === 'PENDING' && isUnblocked(task, byId))\n .sort((a, b) => (b.task.priority ?? 0) - (a.task.priority ?? 0) || a.index - b.index)\n .map(({ task }) => task);\n}\n\n/** The next task the runner should pick, if any. */\nexport function nextTask(graph: TaskGraph): TaskNode | undefined {\n return readyTasks(graph)[0];\n}\n\nexport interface BlockedTask {\n task: TaskNode;\n /** `waiting`: dependencies still pending/in progress. `failed-dependency`: a dependency FAILED. */\n reason: 'waiting' | 'failed-dependency';\n /** Direct dependencies responsible for the block. */\n blockedBy: string[];\n}\n\n/** PENDING tasks that cannot start yet, with the reason. */\nexport function blockedTasks(graph: TaskGraph): BlockedTask[] {\n const byId = indexById(graph);\n const result: BlockedTask[] = [];\n for (const task of graph.tasks) {\n if (task.status !== 'PENDING') continue;\n const failed = task.dependsOn.filter((d) => byId.get(d)?.status === 'FAILED');\n if (failed.length > 0) {\n result.push({ task, reason: 'failed-dependency', blockedBy: failed });\n continue;\n }\n const waiting = task.dependsOn.filter((d) => byId.get(d)?.status !== 'SUCCESS');\n if (waiting.length > 0) result.push({ task, reason: 'waiting', blockedBy: waiting });\n }\n return result;\n}\n\nexport type RunnableCheck =\n | { ok: true; task: TaskNode }\n | {\n ok: false;\n reason: 'unknown_task' | 'wrong_status' | 'blocked';\n message: string;\n /** For `blocked`: the direct dependencies that are not SUCCESS yet. */\n blockedBy?: string[];\n };\n\n/** Explains whether task `id` could be picked by the runner right now (PENDING and unblocked). */\nexport function checkRunnable(graph: TaskGraph, id: string): RunnableCheck {\n const byId = indexById(graph);\n const task = byId.get(id);\n if (!task) return { ok: false, reason: 'unknown_task', message: `unknown task \"${id}\"` };\n if (task.status !== 'PENDING') {\n return {\n ok: false,\n reason: 'wrong_status',\n message: `task \"${id}\" is ${task.status}; only PENDING tasks can run${\n task.status === 'IN_PROGRESS' ? '' : ' (reopen it first)'\n }`,\n };\n }\n const blockedBy = task.dependsOn.filter((dep) => byId.get(dep)?.status !== 'SUCCESS');\n if (blockedBy.length > 0) {\n return {\n ok: false,\n reason: 'blocked',\n blockedBy,\n message: `task \"${id}\" is blocked by unfinished dependencies: ${blockedBy\n .map((dep) => `\"${dep}\" (${byId.get(dep)?.status ?? 'missing'})`)\n .join(', ')}`,\n };\n }\n return { ok: true, task };\n}\n\nexport interface GraphSummary {\n total: number;\n counts: Record<TaskStatus, number>;\n /** Percentage of SUCCESS tasks, 0..100 with one decimal. */\n progress: number;\n}\n\nexport function summarize(graph: TaskGraph): GraphSummary {\n const counts: Record<TaskStatus, number> = { PENDING: 0, IN_PROGRESS: 0, SUCCESS: 0, FAILED: 0 };\n for (const task of graph.tasks) counts[task.status] += 1;\n const total = graph.tasks.length;\n const progress = total === 0 ? 0 : Math.round((counts.SUCCESS / total) * 1000) / 10;\n return { total, counts, progress };\n}\n\n// ---------------------------------------------------------------------------\n// Updates (immutable)\n// ---------------------------------------------------------------------------\n\nconst ALLOWED_TRANSITIONS: Record<TaskStatus, readonly TaskStatus[]> = {\n PENDING: ['IN_PROGRESS'],\n IN_PROGRESS: ['SUCCESS', 'FAILED', 'PENDING'],\n FAILED: ['PENDING'],\n SUCCESS: ['PENDING'],\n};\n\nexport function canTransition(from: TaskStatus, to: TaskStatus): boolean {\n return from === to || ALLOWED_TRANSITIONS[from].includes(to);\n}\n\nexport type TaskPatch = Partial<Omit<TaskNode, 'id'>>;\n\n/** Optional fields of a task that an edit may remove again. */\nexport type ClearableTaskField = 'description' | 'priority' | 'acceptance' | 'notes';\n\nexport interface UpdateOptions {\n /** Timestamp to stamp into `updatedAt` (defaults to now). */\n now?: Date;\n /** Optional fields to remove from the task (applied after the patch). */\n clear?: readonly ClearableTaskField[];\n}\n\n/**\n * Returns a new graph with `patch` applied to task `id`. Status changes must follow the allowed\n * transitions; moving to IN_PROGRESS increments `attempts`. The result is re-validated, so a\n * patch to `dependsOn` cannot introduce unknown ids or cycles.\n */\nexport function updateTask(\n graph: TaskGraph,\n id: string,\n patch: TaskPatch,\n opts: UpdateOptions = {},\n): TaskGraph {\n const index = graph.tasks.findIndex((t) => t.id === id);\n const current = graph.tasks[index];\n if (index < 0 || !current) {\n throw new TaskGraphError([\n { code: 'unknown_task', taskId: id, message: `unknown task \"${id}\"` },\n ]);\n }\n\n const next: TaskNode = { ...current, ...definedOnly(patch) };\n if (patch.status !== undefined && patch.status !== current.status) {\n if (!canTransition(current.status, patch.status)) {\n throw new TaskGraphError([\n {\n code: 'invalid_transition',\n taskId: id,\n message: `task \"${id}\": cannot move ${current.status} → ${patch.status} (allowed from ${current.status}: ${ALLOWED_TRANSITIONS[current.status].join(', ')})`,\n },\n ]);\n }\n if (patch.status === 'IN_PROGRESS') next.attempts = (current.attempts ?? 0) + 1;\n }\n for (const field of opts.clear ?? []) delete next[field];\n next.updatedAt = (opts.now ?? new Date()).toISOString();\n\n const tasks = graph.tasks.map((t, i) => (i === index ? next : t));\n const updated: TaskGraph = { ...graph, tasks };\n const issues = validateTaskGraph(updated);\n if (issues.length > 0) throw new TaskGraphError(issues);\n return updated;\n}\n\n/** What it takes to create a task; it always starts PENDING. */\nexport interface NewTask {\n id: string;\n title: string;\n description?: string;\n dependsOn?: string[];\n priority?: number;\n acceptance?: string[];\n notes?: string;\n}\n\n/** Returns a new graph with a PENDING task appended. Re-validated: duplicates, unknown ids, cycles. */\nexport function addTask(graph: TaskGraph, input: NewTask, opts: UpdateOptions = {}): TaskGraph {\n const stamp = (opts.now ?? new Date()).toISOString();\n const task: TaskNode = {\n id: input.id,\n title: input.title,\n status: 'PENDING',\n dependsOn: [...(input.dependsOn ?? [])],\n createdAt: stamp,\n updatedAt: stamp,\n ...(input.description !== undefined ? { description: input.description } : {}),\n ...(input.priority !== undefined ? { priority: input.priority } : {}),\n ...(input.acceptance !== undefined ? { acceptance: input.acceptance } : {}),\n ...(input.notes !== undefined ? { notes: input.notes } : {}),\n };\n const created: TaskGraph = { ...graph, tasks: [...graph.tasks, task] };\n const issues = validateTaskGraph(created);\n if (issues.length > 0) throw new TaskGraphError(issues);\n return created;\n}\n\n/** Ids of the tasks that list `id` in their `dependsOn`. */\nexport function dependentsOf(graph: TaskGraph, id: string): string[] {\n return graph.tasks.filter((t) => t.dependsOn.includes(id)).map((t) => t.id);\n}\n\n/**\n * Returns a new graph without task `id`. Refused (`has_dependents`) while other tasks depend on\n * it, and (`task_in_progress`) while the task is IN_PROGRESS.\n */\nexport function removeTask(graph: TaskGraph, id: string): TaskGraph {\n const task = graph.tasks.find((t) => t.id === id);\n if (!task) {\n throw new TaskGraphError([\n { code: 'unknown_task', taskId: id, message: `unknown task \"${id}\"` },\n ]);\n }\n const dependents = dependentsOf(graph, id);\n if (dependents.length > 0) {\n throw new TaskGraphError([\n {\n code: 'has_dependents',\n taskId: id,\n dependents,\n message: `cannot delete \"${id}\": ${dependents.map((d) => `\"${d}\"`).join(', ')} depend on it`,\n },\n ]);\n }\n if (task.status === 'IN_PROGRESS') {\n throw new TaskGraphError([\n {\n code: 'task_in_progress',\n taskId: id,\n message: `cannot delete \"${id}\" while it is IN_PROGRESS; reopen it first`,\n },\n ]);\n }\n return { ...graph, tasks: graph.tasks.filter((t) => t.id !== id) };\n}\n\nexport function setTaskStatus(\n graph: TaskGraph,\n id: string,\n status: TaskStatus,\n opts: UpdateOptions & { notes?: string } = {},\n): TaskGraph {\n const patch: TaskPatch = { status };\n if (opts.notes !== undefined) patch.notes = opts.notes;\n return updateTask(graph, id, patch, opts.now ? { now: opts.now } : {});\n}\n\nfunction definedOnly(patch: TaskPatch): TaskPatch {\n return Object.fromEntries(Object.entries(patch).filter(([, v]) => v !== undefined));\n}\n","import { randomBytes } from 'node:crypto';\nimport { mkdir, open, readFile, rm, stat } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { isNodeError } from './fs-util';\n\nexport interface LockOptions {\n /** A lock older than this is considered abandoned and is taken over. Default 30 000 ms. */\n staleMs?: number;\n /** How long to wait for a held lock before giving up. Default 10 000 ms. */\n timeoutMs?: number;\n /** Polling interval while waiting. Default 25 ms. */\n retryMs?: number;\n}\n\nexport interface LockInfo {\n pid: number;\n /** Epoch milliseconds when the lock was taken. */\n ts: number;\n token: string;\n}\n\nexport class LockTimeoutError extends Error {\n constructor(\n readonly lockPath: string,\n timeoutMs: number,\n ) {\n super(`Timed out after ${timeoutMs} ms waiting for lock ${lockPath}`);\n this.name = 'LockTimeoutError';\n }\n}\n\nconst TRANSIENT_OPEN_ERRORS = ['EPERM', 'EACCES', 'EBUSY'];\n\nconst sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n\nasync function readLockInfo(path: string): Promise<LockInfo | undefined> {\n try {\n const parsed: unknown = JSON.parse(await readFile(path, 'utf8'));\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n typeof (parsed as LockInfo).ts === 'number' &&\n typeof (parsed as LockInfo).pid === 'number'\n ) {\n return parsed as LockInfo;\n }\n } catch {\n // Missing or half-written lock files are handled by the caller.\n }\n return undefined;\n}\n\n/** Age of the lock in ms, from its recorded timestamp (falling back to the file mtime). */\nasync function lockAge(path: string): Promise<number | undefined> {\n const info = await readLockInfo(path);\n if (info) return Date.now() - info.ts;\n try {\n return Date.now() - (await stat(path)).mtimeMs;\n } catch {\n return undefined; // vanished: someone released it\n }\n}\n\n/**\n * Runs `fn` while holding an exclusive lock file at `lockPath`. The file holds `{ pid, ts }`;\n * a lock older than `staleMs` (crashed holder) is removed and re-acquired.\n */\nexport async function withFileLock<T>(\n lockPath: string,\n fn: () => Promise<T>,\n opts: LockOptions = {},\n): Promise<T> {\n const staleMs = opts.staleMs ?? 30_000;\n const timeoutMs = opts.timeoutMs ?? 10_000;\n const retryMs = opts.retryMs ?? 25;\n const token = randomBytes(8).toString('hex');\n const deadline = Date.now() + timeoutMs;\n\n await mkdir(dirname(lockPath), { recursive: true });\n\n for (;;) {\n try {\n const handle = await open(lockPath, 'wx');\n try {\n const info: LockInfo = { pid: process.pid, ts: Date.now(), token };\n await handle.writeFile(JSON.stringify(info));\n } finally {\n await handle.close();\n }\n break;\n } catch (err) {\n if (TRANSIENT_OPEN_ERRORS.some((code) => isNodeError(err, code))) {\n // Windows reports EPERM/EACCES while another process's delete of the lock is pending.\n if (Date.now() >= deadline) throw err;\n await sleep(retryMs);\n continue;\n }\n if (!isNodeError(err, 'EEXIST')) throw err;\n const age = await lockAge(lockPath);\n if (age !== undefined && age > staleMs) {\n await rm(lockPath, { force: true });\n continue;\n }\n if (Date.now() >= deadline) throw new LockTimeoutError(lockPath, timeoutMs);\n await sleep(retryMs);\n }\n }\n\n try {\n return await fn();\n } finally {\n // Only release a lock that is still ours (it may have been taken over after going stale).\n const current = await readLockInfo(lockPath);\n if (current?.token === token) {\n await rm(lockPath, { force: true, maxRetries: 5, retryDelay: 10 });\n }\n }\n}\n","import { access, mkdir } from 'node:fs/promises';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport type { EventBus } from '../events';\nimport { type ProjectPaths, projectPaths } from '../paths';\nimport type { TaskGraph, TaskNode, TaskStatus } from '../types';\nimport { atomicWriteFile, readFileIfExists } from './fs-util';\nimport {\n addTask as addGraphTask,\n type ClearableTaskField,\n type NewTask,\n parseTaskGraph,\n removeTask as removeGraphTask,\n setTaskStatus as setGraphTaskStatus,\n type TaskPatch,\n updateTask as updateGraphTask,\n} from './graph';\nimport { type LockOptions, withFileLock } from './lock';\nimport { getSection, touchLastUpdated, upsertSection } from './markdown';\n\n// ---------------------------------------------------------------------------\n// Project root 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 * Walks up from `startDir` to the first directory containing `.davecode/` or `.git`.\n * Returns `undefined` when the filesystem root is reached without a match.\n */\nexport async function findProjectRoot(startDir: string): Promise<string | undefined> {\n let dir = resolve(startDir);\n for (;;) {\n if ((await exists(join(dir, '.davecode'))) || (await exists(join(dir, '.git')))) return dir;\n const parent = dirname(dir);\n if (parent === dir) return undefined;\n dir = parent;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Templates\n// ---------------------------------------------------------------------------\n\nconst ACTIVITY_LOG_HEADING = 'Activity log';\n\nconst today = (now: Date) => now.toISOString().slice(0, 10);\n\nexport function stateTemplate(name: string, now = new Date()): string {\n return `# ${name}: project state\n\n_Last updated: ${today(now)}_\n\n## Current focus\n\nDescribe what is being worked on right now.\n\n## Done\n\n- Project brain initialised by DaveCode.\n\n## Blockers\n\nNone.\n\n## Activity log\n`;\n}\n\nexport function architectureTemplate(name: string): string {\n return `# ${name}: architecture (project brain)\n\nCondensed context injected into every autonomous task. Keep it short and factual.\n\n- **Stack:** languages, frameworks, package manager, test runner.\n- **Layout:** the main directories and what lives in each.\n- **Conventions:** naming, error handling, formatting, commit style.\n- **Quality gates:** the commands that must exit 0 before a task counts as done.\n`;\n}\n\nexport function taskGraphTemplate(): TaskGraph {\n return { version: 1, tasks: [] };\n}\n\nexport function serializeGraph(graph: TaskGraph): string {\n return `${JSON.stringify(graph, null, 2)}\\n`;\n}\n\n// ---------------------------------------------------------------------------\n// ProjectBrain\n// ---------------------------------------------------------------------------\n\nexport interface ProjectBrainOptions {\n /** Receives a `task.updated` event whenever a task is changed through the brain. */\n events?: EventBus;\n /** Clock override (tests). */\n now?: () => Date;\n /** Tuning for the `.davecode/.lock` file guarding read-modify-write cycles. */\n lock?: LockOptions;\n}\n\nexport interface ProjectBrainInitOptions extends ProjectBrainOptions {\n /** Project name used in the templates (defaults to the directory name). */\n name?: string;\n}\n\nexport interface ProjectBrainSnapshot {\n state: string;\n architecture: string;\n graph: TaskGraph;\n}\n\n/** A brain file is missing: the project was never initialised (`davecode init`). */\nexport class MissingBrainError extends Error {\n /** HTTP status hint and machine-readable code for the gateway's error handler. */\n readonly statusCode = 409;\n readonly code = 'no_brain';\n\n constructor(path: string) {\n super(`Missing project brain file: ${path} (run ProjectBrain.init first)`);\n this.name = 'MissingBrainError';\n }\n}\n\n/** Read/write access to `<repo>/.davecode/`: STATE.md, ARCHITECTURE.md and TASK_GRAPH.json. */\nexport class ProjectBrain {\n readonly paths: ProjectPaths;\n protected readonly events: EventBus | undefined;\n protected readonly now: () => Date;\n protected readonly lockOptions: LockOptions;\n\n constructor(\n readonly root: string,\n opts: ProjectBrainOptions = {},\n ) {\n this.paths = projectPaths(root);\n this.events = opts.events;\n this.now = opts.now ?? (() => new Date());\n this.lockOptions = opts.lock ?? {};\n }\n\n /** Path of the lock file shared by every process touching this brain. */\n get lockPath(): string {\n return join(this.paths.dir, '.lock');\n }\n\n /**\n * Runs `fn` while holding `.davecode/.lock` (pid + timestamp, stale after 30 s). Not re-entrant:\n * do not call locking methods of the same brain from inside `fn`.\n */\n withLock<T>(fn: () => Promise<T>): Promise<T> {\n return withFileLock(this.lockPath, fn, this.lockOptions);\n }\n\n /** Scaffolds any missing brain file from its template. Existing files are never overwritten. */\n static async init(root: string, opts: ProjectBrainInitOptions = {}): Promise<ProjectBrain> {\n const brain = new ProjectBrain(root, opts);\n const name = opts.name ?? basename(resolve(root));\n await mkdir(brain.paths.dir, { recursive: true });\n const files: Array<[string, string]> = [\n [brain.paths.state, stateTemplate(name, brain.now())],\n [brain.paths.architecture, architectureTemplate(name)],\n [brain.paths.taskGraph, serializeGraph(taskGraphTemplate())],\n ];\n for (const [path, content] of files) {\n if (!(await exists(path))) await atomicWriteFile(path, content);\n }\n return brain;\n }\n\n /** Finds the project root from `startDir` and opens its brain, or `undefined` if none. */\n static async find(\n startDir: string,\n opts: ProjectBrainOptions = {},\n ): Promise<ProjectBrain | undefined> {\n const root = await findProjectRoot(startDir);\n return root === undefined ? undefined : new ProjectBrain(root, opts);\n }\n\n /** True when all three brain files exist. */\n async isInitialised(): Promise<boolean> {\n const { state, architecture, taskGraph } = this.paths;\n return (await Promise.all([state, architecture, taskGraph].map(exists))).every(Boolean);\n }\n\n async load(): Promise<ProjectBrainSnapshot> {\n const [state, architecture, graph] = await Promise.all([\n this.readState(),\n this.readArchitecture(),\n this.readGraph(),\n ]);\n return { state, architecture, graph };\n }\n\n // -- STATE.md / ARCHITECTURE.md -------------------------------------------\n\n async readState(): Promise<string> {\n return this.readText(this.paths.state);\n }\n\n /** Replaces STATE.md verbatim. */\n async writeState(content: string): Promise<void> {\n await this.withLock(() => atomicWriteFile(this.paths.state, content));\n }\n\n /**\n * Replaces (or appends) the `## heading` section of STATE.md, preserving everything else, and\n * refreshes the `_Last updated: YYYY-MM-DD_` line when present.\n */\n async updateStateSection(heading: string, markdown: string): Promise<void> {\n await this.editState((state) => upsertSection(state, heading, markdown));\n }\n\n /** Appends `- <ISO timestamp>: entry` under `## Activity log` (created when missing). */\n async appendStateLog(entry: string): Promise<void> {\n const line = `- ${this.now().toISOString().slice(0, 19)}Z: ${entry.trim().replace(/\\s*\\r?\\n\\s*/g, ' ')}`;\n await this.editState((state) => {\n const existing = getSection(state, ACTIVITY_LOG_HEADING);\n return upsertSection(state, ACTIVITY_LOG_HEADING, existing ? `${existing}\\n${line}` : line);\n });\n }\n\n private async editState(change: (state: string) => string): Promise<void> {\n await this.withLock(async () => {\n const next = touchLastUpdated(change(await this.readState()), this.now());\n await atomicWriteFile(this.paths.state, next);\n });\n }\n\n async readArchitecture(): Promise<string> {\n return this.readText(this.paths.architecture);\n }\n\n // -- TASK_GRAPH.json ------------------------------------------------------\n\n /** Reads and validates the task graph. Throws `TaskGraphError` when it is invalid. */\n async readGraph(): Promise<TaskGraph> {\n return parseTaskGraph(await this.readText(this.paths.taskGraph));\n }\n\n /** Validates then atomically writes the graph (2-space JSON, trailing newline). */\n async writeGraph(graph: TaskGraph): Promise<void> {\n await this.withLock(() => this.writeGraphUnlocked(graph));\n }\n\n private async writeGraphUnlocked(graph: TaskGraph): Promise<void> {\n await atomicWriteFile(this.paths.taskGraph, serializeGraph(parseTaskGraph(graph)));\n }\n\n /** Applies `patch` to a task, persists the graph and emits `task.updated`. */\n async updateTask(\n id: string,\n patch: TaskPatch,\n opts: { clear?: readonly ClearableTaskField[] } = {},\n ): Promise<TaskNode> {\n return this.mutateGraph(id, (graph) =>\n updateGraphTask(graph, id, patch, { now: this.now(), ...opts }),\n );\n }\n\n /**\n * Appends a PENDING task, persists the graph and emits `task.updated`. Throws\n * `TaskGraphError` for a duplicate id, an unknown dependency or a cycle.\n */\n async createTask(input: NewTask): Promise<TaskNode> {\n return this.mutateGraph(input.id, (graph) => addGraphTask(graph, input, { now: this.now() }));\n }\n\n /**\n * Deletes a task, persists the graph and emits `task.removed`. Throws `TaskGraphError`\n * (`has_dependents`, `task_in_progress`, `unknown_task`) when it must not be removed.\n */\n async removeTask(id: string): Promise<TaskNode> {\n const removed = await this.withLock(async () => {\n const graph = await this.readGraph();\n const task = graph.tasks.find((t) => t.id === id);\n await this.writeGraphUnlocked(removeGraphTask(graph, id));\n return task as TaskNode;\n });\n this.events?.emit({ type: 'task.removed', taskId: id });\n return removed;\n }\n\n /** Moves a task to `status` (transition rules apply), persists and emits `task.updated`. */\n async setTaskStatus(\n id: string,\n status: TaskStatus,\n opts: { notes?: string } = {},\n ): Promise<TaskNode> {\n return this.mutateGraph(id, (graph) =>\n setGraphTaskStatus(graph, id, status, { ...opts, now: this.now() }),\n );\n }\n\n // -- internals ------------------------------------------------------------\n\n private async mutateGraph(\n id: string,\n change: (graph: TaskGraph) => TaskGraph,\n ): Promise<TaskNode> {\n const task = await this.withLock(async () => {\n const next = change(await this.readGraph());\n await this.writeGraphUnlocked(next);\n return next.tasks.find((t) => t.id === id) as TaskNode;\n });\n this.events?.emit({ type: 'task.updated', task });\n return task;\n }\n\n private async readText(path: string): Promise<string> {\n const content = await readFileIfExists(path);\n if (content === undefined) {\n throw new MissingBrainError(path);\n }\n return content;\n }\n}\n","import { z } from 'zod';\n\nconst providerKind = z.enum([\n 'anthropic',\n 'openai',\n 'gemini',\n 'openai-compatible',\n 'claude-cli',\n 'codex-cli',\n 'gemini-cli',\n 'antigravity-cli',\n 'gemini-web',\n]);\n\nexport const routeTargetSchema = z.object({\n provider: providerKind,\n model: z.string().min(1),\n accountId: z.string().optional(),\n});\n\nexport const routeSchema = z.object({\n name: z.string().regex(/^[a-z0-9][a-z0-9-]*$/, 'route names are lowercase kebab-case'),\n description: z.string().optional(),\n targets: z.array(routeTargetSchema).min(1),\n});\n\n/**\n * DaveCode configuration. Resolution order (later wins):\n * built-in defaults → ~/.davecode/config.json → <project>/.davecode/config.json → env vars.\n */\nexport const configSchema = z.object({\n server: z\n .object({\n host: z.string().default('127.0.0.1'),\n port: z.number().int().min(1).max(65535).default(4040),\n /** Optional bearer token required on /v1 and /api. Strongly recommended if host != localhost. */\n authToken: z.string().optional(),\n /** Serve the built dashboard from the gateway. */\n dashboard: z.boolean().default(true),\n })\n .prefault({}),\n\n routing: z\n .object({\n /** Route used when a client asks for `davecode/auto` or an unknown alias. */\n defaultRoute: z.string().default('auto'),\n routes: z.array(routeSchema).default([]),\n /** Start smoothing traffic away from an account above this utilization (spec: 85%). */\n backpressureThreshold: z.number().min(0).max(1).default(0.85),\n /** Shift weight to alternate accounts above this 5h-quota utilization (spec: 90%). */\n quotaShiftThreshold: z.number().min(0).max(1).default(0.9),\n /** Upper bound on failover hops for a single request. */\n maxFailovers: z.number().int().min(0).default(4),\n /** Default cooldown applied after a 429/503 when the upstream sends no Retry-After. */\n cooldownMs: z.number().int().min(0).default(60_000),\n })\n .prefault({}),\n\n experimental: z\n .object({\n /**\n * Enables the `gemini-web` provider that automates a consumer Gemini web session\n * through Chromium. May violate Google's Terms of Service. Use at your own risk.\n */\n geminiWeb: z.boolean().default(false),\n /**\n * Allows balancing across several subscription accounts of the same provider\n * (e.g. multiple Claude Pro logins). May violate the provider's Terms of Service.\n */\n multiAccountRotation: z.boolean().default(false),\n })\n .prefault({}),\n\n runner: z\n .object({\n maxRepairCycles: z.number().int().min(0).max(10).default(3),\n branchPrefix: z.string().default('davecode/task-'),\n /** Branch that successful tasks are merged into. */\n baseBranch: z.string().default('main'),\n /**\n * Route (`auto` → `davecode/auto`) or model id (`openai/gpt-5`) the runner uses for\n * implementation calls with the built-in executor.\n */\n route: z.string().default('auto'),\n /**\n * `builtin`: DaveCode's own tool loop over the router (default).\n * `claude-cli`: delegate each task to the Claude Code CLI of a `claude-cli` account.\n */\n executor: z.enum(['builtin', 'claude-cli']).default('builtin'),\n /**\n * Push the task branch and open a pull request with `gh` instead of merging locally.\n * Falls back to a local merge (with a warning) when `gh` or a remote is unavailable.\n */\n pullRequests: z.boolean().default(false),\n /** Commit STATE.md / TASK_GRAPH.json changes on the base branch after every task. */\n commitBrain: z.boolean().default(true),\n /** Timeout for each validation command and each `run_command` tool call. */\n commandTimeoutMs: z.number().int().min(1_000).default(600_000),\n /** How long the continuous loop sleeps when no task is ready. */\n idlePollMs: z.number().int().min(100).default(30_000),\n /** Model round-trips allowed per implementation or repair pass (built-in executor). */\n maxIterations: z.number().int().min(1).max(500).default(40),\n /** Total prompt + completion tokens one task may consume across all passes. */\n maxTaskTokens: z.number().int().min(1_000).default(1_500_000),\n /**\n * Executables the `run_command` tool may start (bare names, no paths). `git` is always\n * restricted to read-only subcommands.\n */\n allowedCommands: z\n .array(z.string().regex(/^[A-Za-z0-9][\\w.-]*$/, 'bare executable names only'))\n .default(['pnpm', 'npm', 'npx', 'node', 'git', 'tsc', 'biome', 'vitest']),\n claudeCli: z\n .object({\n /** `claude-cli` account whose sandbox is used; defaults to the first enabled one. */\n accountId: z.string().optional(),\n /** Model alias passed as `--model` (e.g. `sonnet`). */\n model: z.string().optional(),\n /** Claude Code tools pre-approved with `--allowedTools`. */\n allowedTools: z\n .array(z.string().min(1))\n .default([\n 'Read',\n 'Edit',\n 'Write',\n 'MultiEdit',\n 'Glob',\n 'Grep',\n 'LS',\n 'Bash(pnpm:*)',\n 'Bash(npm:*)',\n 'Bash(npx:*)',\n 'Bash(node:*)',\n 'Bash(git status:*)',\n 'Bash(git diff:*)',\n 'Bash(git log:*)',\n ]),\n /** Hard timeout for one CLI invocation. */\n timeoutMs: z.number().int().min(1_000).default(1_800_000),\n })\n .prefault({}),\n validate: z\n .object({\n lint: z.string().optional(),\n typecheck: z.string().optional(),\n test: z.string().optional(),\n })\n .prefault({}),\n judge: z\n .object({\n /**\n * `none`: deterministic checks only (free, default).\n * `jev`: ask TypeSafe Jev through the OpenRouter Decisions API (paid) whether the\n * acceptance criteria are met, with calibrated confidence. The API key is read from\n * the `OPENROUTER_API_KEY` or `JEV_API_KEY` environment variable, never from config.\n * `llm`: use one of your own routes as the judge.\n */\n kind: z.enum(['none', 'jev', 'llm']).default('none'),\n /** `jev`: model id (default `typesafe/jev-1.13`). `llm`: route or model id. */\n model: z.string().optional(),\n /** `jev`: Decisions API base URL (default `https://openrouter.ai/api/alpha`). */\n baseUrl: z.string().url().optional(),\n /** Minimum confidence (0..1) required for the judge to pass a task. */\n threshold: z.number().min(0).max(1).default(0.7),\n })\n .prefault({}),\n })\n .prefault({}),\n\n goal: z\n .object({\n /** Route (`auto` → `davecode/auto`) or model id for roles without their own route. */\n route: z.string().default('auto'),\n /** Plan → execute → review rounds before the goal stops. */\n maxRounds: z.number().int().min(1).max(20).default(4),\n /** Tasks across all rounds. */\n maxTasks: z.number().int().min(1).max(100).default(12),\n /** Prompt + completion tokens across every agent and runner pass. */\n maxTokens: z.number().int().min(10_000).default(1_000_000),\n /** Attempts per task before it stays FAILED (the reviewer may still re-plan around it). */\n maxTaskAttempts: z.number().int().min(1).max(5).default(2),\n /**\n * Hand `code` tasks to the autonomous runner (task branch, quality gates, merge). When\n * off, or when the runner cannot start, every task produces a markdown artifact instead.\n */\n codeTasks: z.boolean().default(true),\n /**\n * Extra or overridden roles, merged over the built-in planner, researcher, implementer,\n * reviewer and writer.\n */\n roles: z\n .record(\n z.string().regex(/^[a-z][a-z0-9-]{0,39}$/, 'role ids are lowercase kebab-case'),\n z.object({\n description: z.string().min(1).max(500).optional(),\n /** Route or model id this role uses. */\n route: z.string().min(1).optional(),\n /** Extra instructions appended to the role's system prompt. */\n instructions: z.string().max(4_000).optional(),\n /** Default task kind for this role. */\n kind: z.enum(['code', 'artifact']).optional(),\n }),\n )\n .default({}),\n })\n .prefault({}),\n\n logLevel: z.enum(['debug', 'info', 'warn', 'error']).default('info'),\n});\n\nexport type DaveConfig = z.infer<typeof configSchema>;\nexport type DaveConfigInput = z.input<typeof configSchema>;\n","import { readFile } from 'node:fs/promises';\nimport { z } from 'zod';\nimport { atomicWriteFile, isNodeError } from '../brain/fs-util';\nimport { type LockOptions, withFileLock } from '../brain/lock';\nimport { globalPaths, projectPaths } from '../paths';\nimport type { Route } from '../types';\nimport { ConfigError } from './loader';\nimport { configSchema } from './schema';\n\ntype PlainObject = Record<string, unknown>;\n\nconst isPlainObject = (value: unknown): value is PlainObject =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nexport interface RoutingUpdate {\n /** The complete new route list (replaces the old one). */\n routes: Route[];\n /** New default route; omitted leaves the stored value untouched. */\n defaultRoute?: string;\n}\n\nexport interface RoutingUpdateResult {\n /** The global config file that was written. */\n path: string;\n routes: Route[];\n defaultRoute: string;\n}\n\n/**\n * Read-modify-write of the global `config.json`: only `routing.routes` (and `routing.defaultRoute`)\n * change; every other key, including the rest of `routing`, is preserved. The file is replaced\n * atomically while holding a lock file, so concurrent writers (another gateway, the CLI) cannot\n * lose each other's changes and readers never see a torn file. An existing file that is malformed\n * or invalid is never overwritten: a {@link ConfigError} is thrown instead.\n */\nexport async function writeGlobalRouting(\n home: string,\n update: RoutingUpdate,\n lock: LockOptions = {},\n): Promise<RoutingUpdateResult> {\n const path = globalPaths(home).config;\n return withFileLock(\n `${path}.lock`,\n async () => {\n let current: PlainObject = {};\n try {\n const parsed: unknown = JSON.parse(await readFile(path, 'utf8'));\n if (!isPlainObject(parsed)) throw new ConfigError(path, 'expected a JSON object');\n current = parsed;\n } catch (err) {\n if (err instanceof ConfigError) throw err;\n if (!isNodeError(err, 'ENOENT')) {\n throw new ConfigError(path, `cannot update this file: ${(err as Error).message}`, {\n cause: err,\n });\n }\n }\n\n const routing = isPlainObject(current.routing) ? current.routing : {};\n const next: PlainObject = {\n ...current,\n routing: {\n ...routing,\n routes: update.routes,\n ...(update.defaultRoute !== undefined ? { defaultRoute: update.defaultRoute } : {}),\n },\n };\n const checked = configSchema.safeParse(next);\n if (!checked.success) throw new ConfigError(path, z.prettifyError(checked.error));\n\n await atomicWriteFile(path, `${JSON.stringify(next, null, 2)}\\n`);\n return {\n path,\n routes: checked.data.routing.routes,\n defaultRoute: checked.data.routing.defaultRoute,\n };\n },\n lock,\n );\n}\n\n/**\n * True when `<project>/.davecode/config.json` sets `routing.routes` or `routing.defaultRoute`:\n * the project layer wins over the global file, so a change written globally would not take\n * effect after a restart in that project.\n */\nexport async function projectOverridesRouting(projectRoot: string): Promise<boolean> {\n try {\n const parsed: unknown = JSON.parse(await readFile(projectPaths(projectRoot).config, 'utf8'));\n const routing = isPlainObject(parsed) ? parsed.routing : undefined;\n return isPlainObject(routing) && ('routes' in routing || 'defaultRoute' in routing);\n } catch {\n return false;\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { z } from 'zod';\nimport { davecodeHome, globalPaths, projectPaths } from '../paths';\nimport { configSchema, type DaveConfig, type DaveConfigInput } from './schema';\n\n/** Thrown when a config layer cannot be read, parsed or validated. */\nexport class ConfigError extends Error {\n /** File path or environment variable name the problem came from. */\n readonly source: string;\n\n constructor(source: string, message: string, options?: { cause?: unknown }) {\n super(`Invalid DaveCode config (${source}):\\n${message}`, options);\n this.name = 'ConfigError';\n this.source = source;\n }\n}\n\nexport interface LoadConfigOptions {\n /** DaveCode home (defaults to `DAVECODE_HOME` or `~/.davecode`). */\n home?: string;\n /** Repository root whose `.davecode/config.json` is layered on top of the global config. */\n projectRoot?: string;\n /** Environment used for `DAVECODE_*` overrides (defaults to `process.env`). */\n env?: NodeJS.ProcessEnv;\n /** Programmatic overrides applied last (e.g. CLI flags). */\n overrides?: DaveConfigInput;\n /**\n * Receives a message for every project-config key that was ignored because project files are\n * untrusted. Defaults to a one-time process warning on stderr per distinct message.\n */\n onWarning?: (message: string) => void;\n}\n\ntype PlainObject = Record<string, unknown>;\n\n/**\n * Keys a repository's `.davecode/config.json` may set. A cloned repository is untrusted input,\n * so everything not listed here is ignored (with a warning): the bind address and port, the auth\n * token, `experimental.*` opt-ins, judge endpoints and the runner's command and tool allow-lists.\n * `true` allows the whole subtree; an object allows only the keys it names.\n */\nexport const PROJECT_SETTABLE_KEYS = {\n logLevel: true,\n routing: true,\n goal: true,\n runner: {\n maxRepairCycles: true,\n branchPrefix: true,\n baseBranch: true,\n route: true,\n executor: true,\n pullRequests: true,\n commitBrain: true,\n commandTimeoutMs: true,\n idlePollMs: true,\n maxIterations: true,\n maxTaskTokens: true,\n validate: true,\n claudeCli: { accountId: true, model: true, timeoutMs: true },\n judge: { kind: true, model: true, threshold: true },\n },\n} as const;\n\ntype SettableTree = { readonly [key: string]: true | SettableTree };\n\n/** Split a project layer into the keys it may set and the dotted paths that were dropped. */\nexport function filterProjectLayer(layer: PlainObject): {\n allowed: PlainObject;\n dropped: string[];\n} {\n const dropped: string[] = [];\n const walk = (value: PlainObject, tree: SettableTree, prefix: string): PlainObject => {\n const out: PlainObject = {};\n for (const [key, v] of Object.entries(value)) {\n const rule = Object.hasOwn(tree, key) ? tree[key] : undefined;\n const path = prefix ? `${prefix}.${key}` : key;\n if (rule === true) {\n out[key] = v;\n } else if (rule && isPlainObject(v)) {\n const inner = walk(v, rule, path);\n if (Object.keys(inner).length > 0) out[key] = inner;\n } else {\n dropped.push(path);\n }\n }\n return out;\n };\n return { allowed: walk(layer, PROJECT_SETTABLE_KEYS as SettableTree, ''), dropped };\n}\n\nconst warned = new Set<string>();\nfunction defaultWarn(message: string): void {\n if (warned.has(message)) return;\n warned.add(message);\n process.emitWarning(message, 'DaveCodeConfigWarning');\n}\n\nfunction isPlainObject(value: unknown): value is PlainObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Deep-merge plain objects; arrays and primitives in `override` replace `base`. */\nexport function deepMerge(base: PlainObject, override: PlainObject): PlainObject {\n const out: PlainObject = { ...base };\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n const current = out[key];\n out[key] = isPlainObject(current) && isPlainObject(value) ? deepMerge(current, value) : value;\n }\n return out;\n}\n\nfunction readLayer(path: string, project?: (dropped: string[]) => void): PlainObject | undefined {\n let raw: string;\n try {\n raw = readFileSync(path, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return undefined;\n throw new ConfigError(path, `cannot read file: ${(err as Error).message}`, { cause: err });\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n throw new ConfigError(path, `malformed JSON: ${(err as Error).message}`, { cause: err });\n }\n if (!isPlainObject(parsed)) throw new ConfigError(path, 'expected a JSON object');\n let layer: PlainObject = parsed;\n if (project) {\n const { allowed, dropped } = filterProjectLayer(parsed);\n if (dropped.length > 0) project(dropped);\n layer = allowed;\n }\n // Validate each layer on its own so errors point at the file that caused them.\n const result = configSchema.safeParse(layer);\n if (!result.success) throw new ConfigError(path, z.prettifyError(result.error));\n return layer;\n}\n\nconst TRUE_VALUES = new Set(['1', 'true', 'yes', 'on']);\nconst FALSE_VALUES = new Set(['0', 'false', 'no', 'off', '']);\n\nfunction parseBool(name: string, value: string): boolean {\n const v = value.trim().toLowerCase();\n if (TRUE_VALUES.has(v)) return true;\n if (FALSE_VALUES.has(v)) return false;\n throw new ConfigError(name, `expected a boolean (true/false/1/0), got \"${value}\"`);\n}\n\nfunction parsePort(name: string, value: string): number {\n const n = Number(value);\n if (!Number.isInteger(n) || n < 1 || n > 65535) {\n throw new ConfigError(name, `expected a port number between 1 and 65535, got \"${value}\"`);\n }\n return n;\n}\n\nconst LOG_LEVELS = ['debug', 'info', 'warn', 'error'] as const;\n\n/** Translate `DAVECODE_*` environment variables into a config layer. */\nexport function envLayer(env: NodeJS.ProcessEnv): PlainObject {\n const server: PlainObject = {};\n const experimental: PlainObject = {};\n const layer: PlainObject = {};\n\n if (env.DAVECODE_HOST) server.host = env.DAVECODE_HOST;\n if (env.DAVECODE_PORT) server.port = parsePort('DAVECODE_PORT', env.DAVECODE_PORT);\n if (env.DAVECODE_AUTH_TOKEN) server.authToken = env.DAVECODE_AUTH_TOKEN;\n if (env.DAVECODE_LOG_LEVEL) {\n const level = env.DAVECODE_LOG_LEVEL.trim().toLowerCase();\n if (!(LOG_LEVELS as readonly string[]).includes(level)) {\n throw new ConfigError(\n 'DAVECODE_LOG_LEVEL',\n `expected one of ${LOG_LEVELS.join(', ')}, got \"${env.DAVECODE_LOG_LEVEL}\"`,\n );\n }\n layer.logLevel = level;\n }\n if (env.DAVECODE_EXPERIMENTAL_GEMINI_WEB !== undefined) {\n experimental.geminiWeb = parseBool(\n 'DAVECODE_EXPERIMENTAL_GEMINI_WEB',\n env.DAVECODE_EXPERIMENTAL_GEMINI_WEB,\n );\n }\n if (env.DAVECODE_EXPERIMENTAL_MULTI_ACCOUNT_ROTATION !== undefined) {\n experimental.multiAccountRotation = parseBool(\n 'DAVECODE_EXPERIMENTAL_MULTI_ACCOUNT_ROTATION',\n env.DAVECODE_EXPERIMENTAL_MULTI_ACCOUNT_ROTATION,\n );\n }\n\n if (Object.keys(server).length > 0) layer.server = server;\n if (Object.keys(experimental).length > 0) layer.experimental = experimental;\n return layer;\n}\n\n/**\n * Resolve the effective configuration. Later layers win:\n * built-in defaults ← `~/.davecode/config.json` ← `<project>/.davecode/config.json`\n * ← `DAVECODE_*` env vars ← `overrides`. Objects deep-merge, arrays replace.\n * Project files can only set the keys in {@link PROJECT_SETTABLE_KEYS}; others are ignored with a\n * warning. Missing files are skipped; invalid ones throw a {@link ConfigError} naming the file.\n */\nexport function loadConfig(options: LoadConfigOptions = {}): DaveConfig {\n const env = options.env ?? process.env;\n const home = options.home ?? davecodeHome(env);\n\n let merged: PlainObject = {};\n const globalLayer = readLayer(globalPaths(home).config);\n if (globalLayer) merged = deepMerge(merged, globalLayer);\n if (options.projectRoot) {\n const projectFile = projectPaths(options.projectRoot).config;\n const warn = options.onWarning ?? defaultWarn;\n const projectLayer = readLayer(projectFile, (dropped) =>\n warn(\n `Ignored ${dropped.join(', ')} in ${projectFile}: project config cannot set these keys. ` +\n 'Set them in your user config (~/.davecode/config.json) or with DAVECODE_* environment variables.',\n ),\n );\n if (projectLayer) merged = deepMerge(merged, projectLayer);\n }\n merged = deepMerge(merged, envLayer(env));\n if (options.overrides) merged = deepMerge(merged, options.overrides as PlainObject);\n\n const result = configSchema.safeParse(merged);\n if (!result.success) {\n throw new ConfigError('merged configuration', z.prettifyError(result.error));\n }\n return result.data;\n}\n","import type { AgentOutput, OrchestratorRun } from './orchestrator/contract';\nimport type {\n Account,\n AccountUsage,\n Goal,\n LogLevel,\n ProviderErrorKind,\n ProviderKind,\n RunnerStatus,\n TaskNode,\n} from './types';\n\n/**\n * Real-time events streamed to the dashboard (SSE `/api/events`) and the TUI.\n * Every event carries `ts` in epoch milliseconds. Never put secrets in events.\n */\nexport type DaveEvent =\n | {\n type: 'request.started';\n requestId: string;\n model: string;\n accountId: string;\n provider: ProviderKind;\n ts: number;\n }\n | {\n type: 'request.completed';\n requestId: string;\n model: string;\n accountId: string;\n provider: ProviderKind;\n promptTokens: number;\n completionTokens: number;\n latencyMs: number;\n ts: number;\n }\n | {\n type: 'request.failed';\n requestId: string;\n accountId: string;\n provider: ProviderKind;\n error: { kind: ProviderErrorKind; message: string; status?: number };\n ts: number;\n }\n | {\n type: 'router.failover';\n requestId: string;\n fromAccountId: string;\n toAccountId: string | null;\n reason: ProviderErrorKind;\n ts: number;\n }\n | { type: 'account.updated'; account: Account; ts: number }\n | { type: 'account.removed'; accountId: string; ts: number }\n | { type: 'quota.updated'; usage: AccountUsage; ts: number }\n | { type: 'task.updated'; task: TaskNode; ts: number }\n | { type: 'task.removed'; taskId: string; ts: number }\n | { type: 'runner.status'; status: RunnerStatus; ts: number }\n | { type: 'runner.log'; level: LogLevel; message: string; taskId?: string; ts: number }\n | { type: 'goal.updated'; goal: Goal; ts: number }\n | {\n type: 'goal.log';\n goalId: string;\n level: LogLevel;\n message: string;\n role?: string;\n taskId?: string;\n ts: number;\n }\n /** Full snapshot of a pane-orchestrator run, sent on every change. */\n | { type: 'orchestrator.run'; run: OrchestratorRun; ts: number }\n /** Live activity of one orchestrator task (or of the planner, with `taskId` \"plan\"). */\n | {\n type: 'orchestrator.output';\n runId: string;\n taskId: string;\n output: AgentOutput;\n ts: number;\n }\n | { type: 'log'; level: LogLevel; scope: string; message: string; ts: number };\n\nexport type DaveEventType = DaveEvent['type'];\n\n/** Distributes an event type over the union so `Omit` keeps each variant intact. */\ntype WithoutTs<E> = E extends DaveEvent ? Omit<E, 'ts'> & { ts?: number } : never;\nexport type DaveEventInput = WithoutTs<DaveEvent>;\n\n/** `seq` is a per-process, strictly increasing sequence number (the SSE `id:`). */\nexport type DaveEventHandler = (event: DaveEvent, seq: number) => void;\n\nexport interface SequencedEvent {\n seq: number;\n event: DaveEvent;\n}\n\n/**\n * In-process pub/sub with a bounded replay buffer so late subscribers\n * (a freshly opened dashboard tab) can catch up on recent activity.\n */\nexport class EventBus {\n private readonly handlers = new Set<DaveEventHandler>();\n private readonly buffer: SequencedEvent[] = [];\n private seq = 0;\n\n constructor(private readonly bufferSize = 500) {}\n\n emit(input: DaveEventInput): DaveEvent {\n const event = { ...input, ts: input.ts ?? Date.now() } as DaveEvent;\n const seq = ++this.seq;\n this.buffer.push({ seq, event });\n if (this.buffer.length > this.bufferSize) this.buffer.shift();\n for (const handler of this.handlers) {\n try {\n handler(event, seq);\n } catch {\n // A misbehaving subscriber must never break the emitter.\n }\n }\n return event;\n }\n\n /** Subscribe to all events. Returns an unsubscribe function. */\n subscribe(handler: DaveEventHandler): () => void {\n this.handlers.add(handler);\n return () => this.handlers.delete(handler);\n }\n\n /** Most recent events, oldest first. */\n recent(limit = this.bufferSize): DaveEvent[] {\n return this.buffer.slice(-limit).map((entry) => entry.event);\n }\n\n /** Sequence number of the latest emitted event (0 before the first). */\n get lastSeq(): number {\n return this.seq;\n }\n\n /**\n * Buffered events emitted after `afterSeq`, oldest first. A cursor from the future\n * (e.g. a client that saw a previous process) replays the whole buffer.\n */\n since(afterSeq: number): SequencedEvent[] {\n if (afterSeq > this.seq) return [...this.buffer];\n return this.buffer.filter((entry) => entry.seq > afterSeq);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type {\n ChatCompletionChunk,\n ChatMessage,\n FinishReason,\n ModelInfo,\n ToolCall,\n Usage,\n} from '../../types';\n\nexport type JsonObject = Record<string, unknown>;\n\nexport function isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function asString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function asNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nexport function asArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nexport function nowSeconds(): number {\n return Math.floor(Date.now() / 1000);\n}\n\nexport function newId(prefix = 'chatcmpl'): string {\n return `${prefix}-${randomUUID()}`;\n}\n\nexport function makeUsage(prompt: number, completion: number): Usage {\n return {\n prompt_tokens: prompt,\n completion_tokens: completion,\n total_tokens: prompt + completion,\n };\n}\n\n/** Strip a leading `provider/` prefix the router may have left on the model id. */\nexport function stripProviderPrefix(model: string, provider: string): string {\n return model.startsWith(`${provider}/`) ? model.slice(provider.length + 1) : model;\n}\n\nexport function joinUrl(base: string, path: string): string {\n return `${base.replace(/\\/+$/, '')}/${path.replace(/^\\/+/, '')}`;\n}\n\n/** Read `config[key]` as a trimmed non-empty string. */\nexport function configString(config: Record<string, unknown>, key: string): string | undefined {\n const value = config[key];\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nexport function configStringArray(config: Record<string, unknown>, key: string): string[] {\n const value = config[key];\n return Array.isArray(value)\n ? value.filter((v): v is string => typeof v === 'string' && v.length > 0)\n : [];\n}\n\nexport function configHeaders(config: Record<string, unknown>): Record<string, string> {\n const value = config.defaultHeaders;\n const out: Record<string, string> = {};\n if (isRecord(value)) {\n for (const [k, v] of Object.entries(value)) {\n if (typeof v === 'string') out[k] = v;\n }\n }\n return out;\n}\n\nexport function modelList(ids: string[], ownedBy: string): ModelInfo[] {\n const created = nowSeconds();\n return [...new Set(ids)].map((id) => ({ id, object: 'model', created, owned_by: ownedBy }));\n}\n\nexport function makeChunk(\n id: string,\n model: string,\n created: number,\n delta: ChatCompletionChunk['choices'][number]['delta'],\n finish: FinishReason = null,\n usage?: Usage,\n): ChatCompletionChunk {\n const out: ChatCompletionChunk = {\n id,\n object: 'chat.completion.chunk',\n created,\n model,\n choices: [{ index: 0, delta, finish_reason: finish }],\n };\n if (usage) out.usage = usage;\n return out;\n}\n\n/**\n * Build a streaming tool-call delta. OpenAI deltas carry an `index` that the shared\n * `ToolCall` type does not model, so the delta is cast to the message shape.\n */\nexport function toolCallDelta(\n index: number,\n parts: { id?: string; name?: string; arguments?: string },\n): Pick<ChatMessage, 'tool_calls'> {\n const fn: { name?: string; arguments: string } = { arguments: parts.arguments ?? '' };\n if (parts.name !== undefined) fn.name = parts.name;\n const call: Record<string, unknown> = { index, function: fn };\n if (parts.id !== undefined) {\n call.id = parts.id;\n call.type = 'function';\n }\n return { tool_calls: [call] as unknown as ToolCall[] };\n}\n\n/** Flatten OpenAI message content into plain text (images become a placeholder). */\nexport function contentToText(\n content: string | Array<{ type: string; text?: string }> | null | undefined,\n): string {\n if (content == null) return '';\n if (typeof content === 'string') return content;\n return content.map((p) => (p.type === 'text' ? (p.text ?? '') : '[image omitted]')).join('\\n');\n}\n","import { errorKindFromStatus, ProviderError, parseRetryAfter } from '../../errors';\nimport type { ProviderErrorKind, ProviderKind, ReportedLimitsInput } from '../../types';\nimport { asString, isRecord } from './util';\n\nexport interface ErrorScope {\n provider: ProviderKind;\n accountId: string;\n /** Secret to scrub from any message we surface. */\n secret?: string;\n /** Receives rate-limit state parsed from successful responses' headers. */\n reportLimits?: (limits: ReportedLimitsInput) => void;\n}\n\nconst CONTEXT_PATTERNS = [\n /prompt is too long/i,\n /context[_ ]length[_ ]exceeded/i,\n /maximum context length/i,\n /exceeds the maximum (number of )?tokens/i,\n /input token count.*exceeds/i,\n /too many tokens/i,\n];\n\nconst QUOTA_PATTERNS = [\n /insufficient[_ ]quota/i,\n /usage limit/i,\n /RESOURCE_EXHAUSTED/,\n /exceeded your current quota/i,\n /credit balance is too low/i,\n /5-hour limit/i,\n];\n\nconst OVERLOAD_PATTERNS = [/overloaded/i];\n\nconst AUTH_PATTERNS = [/api key not valid/i, /API_KEY_INVALID/, /invalid api key/i];\n\n/** Classify an error from message text only; returns undefined when nothing matches. */\nexport function classifyMessage(text: string): ProviderErrorKind | undefined {\n if (CONTEXT_PATTERNS.some((p) => p.test(text))) return 'context_length';\n if (QUOTA_PATTERNS.some((p) => p.test(text))) return 'quota_exhausted';\n if (OVERLOAD_PATTERNS.some((p) => p.test(text))) return 'unavailable';\n if (AUTH_PATTERNS.some((p) => p.test(text))) return 'auth';\n return undefined;\n}\n\n/** Google style `error.details[].retryDelay` (\"30s\" / \"1.5s\") from an error body, in ms. */\nexport function retryDelayFromBody(body: string): number | undefined {\n try {\n const json: unknown = JSON.parse(body);\n const details = isRecord(json) && isRecord(json.error) ? json.error.details : undefined;\n if (!Array.isArray(details)) return undefined;\n for (const d of details) {\n const delay = isRecord(d) ? asString(d.retryDelay) : undefined;\n const match = delay ? /^(\\d+(?:\\.\\d+)?)s$/.exec(delay) : null;\n if (match?.[1]) return Math.round(Number(match[1]) * 1000);\n }\n } catch {\n // not JSON\n }\n return undefined;\n}\n\nexport function redact(text: string, secret?: string): string {\n if (secret && secret.length >= 4) return text.split(secret).join('[redacted]');\n return text;\n}\n\n/** Pull a human message out of the many JSON error envelopes upstreams use. */\nexport function extractErrorMessage(body: string): { message: string; code?: string } {\n const trimmed = body.trim();\n if (!trimmed) return { message: '' };\n try {\n const json: unknown = JSON.parse(trimmed);\n if (isRecord(json)) {\n const err = json.error;\n if (isRecord(err)) {\n const message = asString(err.message) ?? JSON.stringify(err);\n const code = asString(err.code) ?? asString(err.type) ?? asString(err.status);\n return { message, code };\n }\n if (typeof err === 'string') return { message: err };\n const message = asString(json.message);\n if (message) return { message };\n }\n } catch {\n // not JSON\n }\n return { message: trimmed.slice(0, 500) };\n}\n\nconst ANTHROPIC_RESET = [\n 'anthropic-ratelimit-requests-reset',\n 'anthropic-ratelimit-tokens-reset',\n 'anthropic-ratelimit-input-tokens-reset',\n 'anthropic-ratelimit-output-tokens-reset',\n];\n\n/** Derive a retry hint in ms from `retry-after-ms`, `retry-after` or Anthropic reset headers. */\nexport function retryAfterFromHeaders(headers: Headers, now = Date.now()): number | undefined {\n const ms = headers.get('retry-after-ms');\n if (ms !== null && ms.trim() !== '' && Number.isFinite(Number(ms))) {\n return Math.max(0, Number(ms));\n }\n const standard = parseRetryAfter(headers.get('retry-after'), now);\n if (standard !== undefined) return standard;\n const candidates: Array<{ wait: number; exhausted: boolean }> = [];\n for (const name of ANTHROPIC_RESET) {\n const value = headers.get(name);\n if (!value) continue;\n const at = Date.parse(value);\n if (Number.isNaN(at)) continue;\n const remaining = headers.get(name.replace(/-reset$/, '-remaining'));\n candidates.push({ wait: Math.max(0, at - now), exhausted: remaining === '0' });\n }\n if (candidates.length === 0) return undefined;\n const exhausted = candidates.filter((c) => c.exhausted);\n const pool = exhausted.length > 0 ? exhausted : candidates;\n return Math.max(...pool.map((c) => c.wait));\n}\n\n/** Build a ProviderError from an upstream HTTP error response. */\nexport function errorFromHttp(\n status: number,\n body: string,\n headers: Headers,\n scope: ErrorScope,\n): ProviderError {\n const { message, code } = extractErrorMessage(body);\n let kind = errorKindFromStatus(status);\n const byText = classifyMessage(`${code ?? ''} ${message}`);\n if (byText && status < 500) kind = byText;\n if (status >= 500 && kind === 'unknown') kind = 'unavailable';\n const retryAfterMs =\n status === 429 || status === 503 || status === 529\n ? (retryAfterFromHeaders(headers) ?? retryDelayFromBody(body))\n : undefined;\n const text = redact(message || `HTTP ${status}`, scope.secret);\n return new ProviderError(`${scope.provider} upstream error (HTTP ${status}): ${text}`, {\n kind,\n status,\n provider: scope.provider,\n accountId: scope.accountId,\n retryAfterMs,\n });\n}\n\n/** Convert any thrown value (fetch failure, abort, parse error) into a ProviderError. */\nexport function toProviderError(\n err: unknown,\n scope: ErrorScope,\n signal?: AbortSignal,\n): ProviderError {\n if (err instanceof ProviderError) return err;\n const name = isRecord(err) ? asString(err.name) : undefined;\n const aborted = signal?.aborted === true || name === 'AbortError' || name === 'TimeoutError';\n if (aborted) {\n return new ProviderError(`${scope.provider} request aborted or timed out`, {\n kind: 'timeout',\n provider: scope.provider,\n accountId: scope.accountId,\n cause: err,\n });\n }\n const raw = err instanceof Error ? err.message : String(err);\n return new ProviderError(`${scope.provider} network error: ${redact(raw, scope.secret)}`, {\n kind: 'network',\n provider: scope.provider,\n accountId: scope.accountId,\n cause: err,\n });\n}\n","import type { ReportedLimits, ReportedLimitsInput } from '../types';\nimport type { Clock } from './window';\n\n/** Header observations without a reset time are trusted for this long. */\nconst DEFAULT_TTL_MS = 10 * 60_000;\n\nfunction num(value: string | null): number | undefined {\n if (value === null || value.trim() === '') return undefined;\n const n = Number(value);\n return Number.isFinite(n) && n >= 0 ? n : undefined;\n}\n\n/** OpenAI style durations: \"1s\", \"6m0s\", \"120ms\", \"1h2m3.5s\". */\nexport function parseDurationMs(text: string): number | undefined {\n const re = /(\\d+(?:\\.\\d+)?)(ms|h|m|s)/g;\n let total = 0;\n let matched = '';\n for (const m of text.matchAll(re)) {\n const n = Number(m[1]);\n total += m[2] === 'h' ? n * 3_600_000 : m[2] === 'm' ? n * 60_000 : m[2] === 's' ? n * 1000 : n;\n matched += m[0];\n }\n return matched.length > 0 && matched === text.trim() ? Math.round(total) : undefined;\n}\n\nfunction resetToIso(value: string | null, now: number): string | undefined {\n if (!value) return undefined;\n const asDate = Date.parse(value);\n if (!Number.isNaN(asDate) && /\\d{4}-\\d{2}-\\d{2}/.test(value)) {\n return new Date(asDate).toISOString();\n }\n const ms = parseDurationMs(value);\n return ms === undefined ? undefined : new Date(now + ms).toISOString();\n}\n\ninterface Dimension {\n remaining?: number;\n limit?: number;\n resetAt?: string;\n}\n\nfunction dimension(headers: Headers, names: [string, string, string], now: number): Dimension {\n const out: Dimension = {};\n const remaining = num(headers.get(names[0]));\n const limit = num(headers.get(names[1]));\n const resetAt = resetToIso(headers.get(names[2]), now);\n if (remaining !== undefined) out.remaining = remaining;\n if (limit !== undefined) out.limit = limit;\n if (resetAt !== undefined) out.resetAt = resetAt;\n return out;\n}\n\nfunction fraction(d: Dimension): number | undefined {\n return d.remaining !== undefined && d.limit !== undefined && d.limit > 0\n ? d.remaining / d.limit\n : undefined;\n}\n\n/**\n * Rate-limit state from response headers: Anthropic `anthropic-ratelimit-*` (RFC 3339 resets)\n * and OpenAI-style `x-ratelimit-*` (duration resets). `undefined` when none are present.\n */\nexport function limitsFromHeaders(\n headers: Headers,\n now = Date.now(),\n): ReportedLimitsInput | undefined {\n const pick = (a: Dimension, b: Dimension): Dimension => (a.remaining !== undefined ? a : b);\n const tokens = pick(\n pick(\n dimension(\n headers,\n [\n 'anthropic-ratelimit-tokens-remaining',\n 'anthropic-ratelimit-tokens-limit',\n 'anthropic-ratelimit-tokens-reset',\n ],\n now,\n ),\n dimension(\n headers,\n [\n 'anthropic-ratelimit-input-tokens-remaining',\n 'anthropic-ratelimit-input-tokens-limit',\n 'anthropic-ratelimit-input-tokens-reset',\n ],\n now,\n ),\n ),\n dimension(\n headers,\n ['x-ratelimit-remaining-tokens', 'x-ratelimit-limit-tokens', 'x-ratelimit-reset-tokens'],\n now,\n ),\n );\n const requests = pick(\n dimension(\n headers,\n [\n 'anthropic-ratelimit-requests-remaining',\n 'anthropic-ratelimit-requests-limit',\n 'anthropic-ratelimit-requests-reset',\n ],\n now,\n ),\n dimension(\n headers,\n [\n 'x-ratelimit-remaining-requests',\n 'x-ratelimit-limit-requests',\n 'x-ratelimit-reset-requests',\n ],\n now,\n ),\n );\n if (tokens.remaining === undefined && requests.remaining === undefined) return undefined;\n const out: ReportedLimitsInput = {};\n if (tokens.remaining !== undefined) out.tokensRemaining = tokens.remaining;\n if (tokens.limit !== undefined) out.tokensLimit = tokens.limit;\n if (requests.remaining !== undefined) out.requestsRemaining = requests.remaining;\n if (requests.limit !== undefined) out.requestsLimit = requests.limit;\n // The reset that matters is the tighter dimension's.\n const tighter = (fraction(tokens) ?? 1) <= (fraction(requests) ?? 1) ? tokens : requests;\n const resetAt = tighter.resetAt ?? tokens.resetAt ?? requests.resetAt;\n if (resetAt !== undefined) out.resetAt = resetAt;\n if (tokens.remaining === 0 || requests.remaining === 0) out.exhausted = true;\n return out;\n}\n\n/** Remaining fraction 0..1 of the tightest reported limit; `undefined` when none is known. */\nexport function reportedFraction(limits: ReportedLimitsInput): number | undefined {\n if (limits.exhausted) return 0;\n const parts: number[] = [];\n if (limits.tokensRemaining !== undefined && limits.tokensLimit) {\n parts.push(limits.tokensRemaining / limits.tokensLimit);\n }\n if (limits.requestsRemaining !== undefined && limits.requestsLimit) {\n parts.push(limits.requestsRemaining / limits.requestsLimit);\n }\n return parts.length > 0 ? Math.min(1, Math.max(0, Math.min(...parts))) : undefined;\n}\n\nexport interface ReportedLimitsStoreOptions {\n clock?: Clock;\n /** How long observations without `resetAt` stay valid (default 10 min). */\n ttlMs?: number;\n}\n\n/** Latest provider-reported limits per account, in memory, expiring at their reset time. */\nexport class ReportedLimitsStore {\n private readonly entries = new Map<string, ReportedLimits>();\n private readonly clock: Clock;\n private readonly ttlMs: number;\n\n constructor(options: ReportedLimitsStoreOptions = {}) {\n this.clock = options.clock ?? Date.now;\n this.ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;\n }\n\n report(accountId: string, input: ReportedLimitsInput, source: ReportedLimits['source']): void {\n this.entries.set(accountId, {\n ...input,\n source,\n observedAt: new Date(this.clock()).toISOString(),\n });\n }\n\n get(accountId: string): ReportedLimits | undefined {\n const entry = this.entries.get(accountId);\n if (!entry) return undefined;\n const now = this.clock();\n const expires = entry.resetAt\n ? Date.parse(entry.resetAt)\n : Date.parse(entry.observedAt) + this.ttlMs;\n if (!(expires > now)) {\n this.entries.delete(accountId);\n return undefined;\n }\n return entry;\n }\n\n /** True while the provider says the account cannot take more requests. */\n exhausted(accountId: string): boolean {\n const entry = this.get(accountId);\n return entry !== undefined && reportedFraction(entry) === 0;\n }\n\n forget(accountId: string): void {\n this.entries.delete(accountId);\n }\n}\n","/** Minimal streaming line / SSE / NDJSON parsers shared by all adapters. */\n\nexport type ByteChunk = Uint8Array | string;\n\n/** Adapt a fetch `Response.body` into an async iterable of byte chunks. */\nexport async function* bodyChunks(\n body: ReadableStream<Uint8Array> | null,\n): AsyncGenerator<Uint8Array> {\n if (!body) return;\n const reader = body.getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) return;\n if (value) yield value;\n }\n } finally {\n try {\n await reader.cancel();\n } catch {\n // already closed\n }\n reader.releaseLock();\n }\n}\n\n/** Split a chunk stream into lines (handles \\n, \\r\\n and a missing trailing newline). */\nexport async function* readLines(chunks: AsyncIterable<ByteChunk>): AsyncGenerator<string> {\n const decoder = new TextDecoder();\n let buffer = '';\n for await (const chunk of chunks) {\n buffer += typeof chunk === 'string' ? chunk : decoder.decode(chunk, { stream: true });\n let idx = buffer.indexOf('\\n');\n while (idx !== -1) {\n let line = buffer.slice(0, idx);\n if (line.endsWith('\\r')) line = line.slice(0, -1);\n yield line;\n buffer = buffer.slice(idx + 1);\n idx = buffer.indexOf('\\n');\n }\n }\n buffer += decoder.decode();\n if (buffer.length > 0) yield buffer.endsWith('\\r') ? buffer.slice(0, -1) : buffer;\n}\n\nexport interface SseEvent {\n event?: string;\n data: string;\n}\n\n/** Parse a Server-Sent Events stream into events (comments and `id:`/`retry:` are ignored). */\nexport async function* parseSse(chunks: AsyncIterable<ByteChunk>): AsyncGenerator<SseEvent> {\n let event: string | undefined;\n let data: string[] = [];\n for await (const line of readLines(chunks)) {\n if (line === '') {\n if (data.length > 0) yield { event, data: data.join('\\n') };\n event = undefined;\n data = [];\n continue;\n }\n if (line.startsWith(':')) continue;\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 if (field === 'event') event = value;\n else if (field === 'data') data.push(value);\n }\n if (data.length > 0) yield { event, data: data.join('\\n') };\n}\n\n/** Parse newline-delimited JSON. Non-JSON lines are passed to `onInvalid` and skipped. */\nexport async function* parseNdjson(\n chunks: AsyncIterable<ByteChunk>,\n onInvalid?: (line: string) => void,\n): AsyncGenerator<unknown> {\n for await (const line of readLines(chunks)) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n let value: unknown;\n try {\n value = JSON.parse(trimmed);\n } catch {\n onInvalid?.(trimmed);\n continue;\n }\n yield value;\n }\n}\n","import { limitsFromHeaders } from '../../rate-limiter/reported';\nimport { type ErrorScope, errorFromHttp, toProviderError } from './errors';\nimport { bodyChunks } from './lines';\n\nexport interface HttpRequest {\n url: string;\n method?: 'GET' | 'POST';\n headers: Record<string, string>;\n body?: unknown;\n signal?: AbortSignal;\n}\n\n/** fetch + uniform error mapping. Returns only successful (2xx) responses. */\nexport async function send(req: HttpRequest, scope: ErrorScope): Promise<Response> {\n let res: Response;\n try {\n res = await fetch(req.url, {\n method: req.method ?? 'POST',\n headers: {\n ...(req.body !== undefined ? { 'content-type': 'application/json' } : {}),\n ...req.headers,\n },\n body: req.body !== undefined ? JSON.stringify(req.body) : undefined,\n signal: req.signal,\n });\n } catch (err) {\n throw toProviderError(err, scope, req.signal);\n }\n if (!res.ok) {\n let text = '';\n try {\n text = await res.text();\n } catch {\n // ignore body read errors; the status is what matters\n }\n throw errorFromHttp(res.status, text, res.headers, scope);\n }\n if (scope.reportLimits) {\n const limits = limitsFromHeaders(res.headers);\n if (limits) {\n try {\n scope.reportLimits(limits);\n } catch {\n // Bookkeeping must never fail a successful request.\n }\n }\n }\n return res;\n}\n\nexport async function sendJson(req: HttpRequest, scope: ErrorScope): Promise<unknown> {\n const res = await send(req, scope);\n try {\n return (await res.json()) as unknown;\n } catch (err) {\n throw toProviderError(err, scope, req.signal);\n }\n}\n\n/** Iterate a response body, converting stream failures into ProviderErrors. */\nexport async function* guardedBody(\n res: Response,\n scope: ErrorScope,\n signal?: AbortSignal,\n): AsyncGenerator<Uint8Array> {\n try {\n yield* bodyChunks(res.body);\n } catch (err) {\n throw toProviderError(err, scope, signal);\n }\n}\n","import { ProviderError } from '../errors';\nimport type {\n ChatCompletion,\n ChatCompletionChunk,\n ChatMessage,\n ChatRequest,\n ContentPart,\n FinishReason,\n ModelInfo,\n Provider,\n ProviderCallContext,\n ToolCall,\n Usage,\n} from '../types';\nimport { classifyMessage, type ErrorScope, redact, toProviderError } from './shared/errors';\nimport { guardedBody, send, sendJson } from './shared/http';\nimport { parseSse } from './shared/lines';\nimport {\n asArray,\n asNumber,\n asString,\n configHeaders,\n configString,\n configStringArray,\n isRecord,\n type JsonObject,\n joinUrl,\n makeChunk,\n makeUsage,\n modelList,\n newId,\n nowSeconds,\n stripProviderPrefix,\n toolCallDelta,\n} from './shared/util';\n\nexport const ANTHROPIC_DEFAULT_BASE_URL = 'https://api.anthropic.com/v1';\nexport const ANTHROPIC_VERSION = '2023-06-01';\nexport const ANTHROPIC_DEFAULT_MAX_TOKENS = 8192;\n\ntype AnthropicBlock = JsonObject;\ninterface AnthropicMessage {\n role: 'user' | 'assistant';\n content: AnthropicBlock[];\n}\n\nexport interface AnthropicRequestBody {\n model: string;\n max_tokens: number;\n messages: AnthropicMessage[];\n system?: string;\n stream?: boolean;\n temperature?: number;\n top_p?: number;\n stop_sequences?: string[];\n tools?: Array<{ name: string; description?: string; input_schema: Record<string, unknown> }>;\n tool_choice?: JsonObject;\n metadata?: { user_id: string };\n}\n\n// ---------------------------------------------------------------------------\n// Request translation (OpenAI -> Anthropic)\n// ---------------------------------------------------------------------------\n\nfunction partToBlock(part: ContentPart): AnthropicBlock | undefined {\n if (part.type === 'text') return part.text ? { type: 'text', text: part.text } : undefined;\n const url = part.image_url.url;\n const data = /^data:([^;,]+)(;base64)?,(.*)$/s.exec(url);\n if (data) {\n return {\n type: 'image',\n source: { type: 'base64', media_type: data[1], data: data[3] },\n };\n }\n return { type: 'image', source: { type: 'url', url } };\n}\n\nfunction contentBlocks(content: ChatMessage['content']): AnthropicBlock[] {\n if (content == null) return [];\n if (typeof content === 'string') return content ? [{ type: 'text', text: content }] : [];\n return content.flatMap((p) => {\n const block = partToBlock(p);\n return block ? [block] : [];\n });\n}\n\nfunction textOf(content: ChatMessage['content']): string {\n if (content == null) return '';\n if (typeof content === 'string') return content;\n return content.flatMap((p) => (p.type === 'text' ? [p.text] : [])).join('\\n');\n}\n\nfunction parseToolArguments(raw: string): unknown {\n if (!raw.trim()) return {};\n try {\n const parsed: unknown = JSON.parse(raw);\n return isRecord(parsed) ? parsed : { value: parsed };\n } catch {\n return {};\n }\n}\n\nfunction pushMessage(\n out: AnthropicMessage[],\n role: 'user' | 'assistant',\n blocks: AnthropicBlock[],\n) {\n if (blocks.length === 0) return;\n const last = out[out.length - 1];\n if (last && last.role === role) last.content.push(...blocks);\n else out.push({ role, content: [...blocks] });\n}\n\n/** Convert an OpenAI-shaped chat request into an Anthropic Messages request. */\nexport function toAnthropicRequest(req: ChatRequest, model: string): AnthropicRequestBody {\n const systemParts: string[] = [];\n const messages: AnthropicMessage[] = [];\n for (const m of req.messages) {\n if (m.role === 'system') {\n const text = textOf(m.content);\n if (text) systemParts.push(text);\n } else if (m.role === 'user') {\n pushMessage(messages, 'user', contentBlocks(m.content));\n } else if (m.role === 'assistant') {\n const blocks = contentBlocks(m.content);\n for (const call of m.tool_calls ?? []) {\n blocks.push({\n type: 'tool_use',\n id: call.id,\n name: call.function.name,\n input: parseToolArguments(call.function.arguments),\n });\n }\n pushMessage(messages, 'assistant', blocks);\n } else {\n const text = textOf(m.content);\n pushMessage(messages, 'user', [\n {\n type: 'tool_result',\n tool_use_id: m.tool_call_id ?? '',\n content: text || '(empty)',\n },\n ]);\n }\n }\n // tool_result blocks must lead the user turn that answers a tool_use.\n for (const m of messages) {\n if (m.role === 'user') {\n m.content.sort((a, b) => Number(b.type === 'tool_result') - Number(a.type === 'tool_result'));\n }\n }\n\n const body: AnthropicRequestBody = {\n model,\n max_tokens: req.max_tokens ?? ANTHROPIC_DEFAULT_MAX_TOKENS,\n messages,\n };\n if (systemParts.length > 0) body.system = systemParts.join('\\n\\n');\n if (req.temperature !== undefined) body.temperature = req.temperature;\n if (req.top_p !== undefined) body.top_p = req.top_p;\n if (req.stop !== undefined) {\n const stops = (Array.isArray(req.stop) ? req.stop : [req.stop]).filter((s) => s.length > 0);\n if (stops.length > 0) body.stop_sequences = stops;\n }\n if (req.user) body.metadata = { user_id: req.user };\n if (req.tools && req.tools.length > 0) {\n body.tools = req.tools.map((t) => ({\n name: t.function.name,\n ...(t.function.description ? { description: t.function.description } : {}),\n input_schema: t.function.parameters ?? { type: 'object', properties: {} },\n }));\n const choice = req.tool_choice;\n if (choice === 'auto') body.tool_choice = { type: 'auto' };\n else if (choice === 'required') body.tool_choice = { type: 'any' };\n else if (choice === 'none') body.tool_choice = { type: 'none' };\n else if (choice && typeof choice === 'object') {\n body.tool_choice = { type: 'tool', name: choice.function.name };\n }\n }\n return body;\n}\n\n// ---------------------------------------------------------------------------\n// Response translation (Anthropic -> OpenAI)\n// ---------------------------------------------------------------------------\n\nexport function mapStopReason(reason: unknown): FinishReason {\n switch (reason) {\n case 'max_tokens':\n case 'model_context_window_exceeded':\n return 'length';\n case 'tool_use':\n return 'tool_calls';\n case 'refusal':\n return 'content_filter';\n case null:\n case undefined:\n return null;\n default:\n return 'stop';\n }\n}\n\nfunction toUsage(value: unknown): Usage | undefined {\n if (!isRecord(value)) return undefined;\n const input =\n (asNumber(value.input_tokens) ?? 0) +\n (asNumber(value.cache_creation_input_tokens) ?? 0) +\n (asNumber(value.cache_read_input_tokens) ?? 0);\n return makeUsage(input, asNumber(value.output_tokens) ?? 0);\n}\n\n/** Convert a non-streaming Anthropic message into an OpenAI chat completion. */\nexport function fromAnthropicMessage(json: unknown, model: string): ChatCompletion {\n const msg = isRecord(json) ? json : {};\n let text = '';\n const toolCalls: ToolCall[] = [];\n for (const block of asArray(msg.content)) {\n if (!isRecord(block)) continue;\n if (block.type === 'text') text += asString(block.text) ?? '';\n else if (block.type === 'tool_use') {\n toolCalls.push({\n id: asString(block.id) ?? newId('call'),\n type: 'function',\n function: {\n name: asString(block.name) ?? '',\n arguments: JSON.stringify(block.input ?? {}),\n },\n });\n }\n }\n const message: ChatMessage = {\n role: 'assistant',\n content: text || (toolCalls.length ? null : ''),\n };\n if (toolCalls.length > 0) message.tool_calls = toolCalls;\n return {\n id: asString(msg.id) ?? newId(),\n object: 'chat.completion',\n created: nowSeconds(),\n model: asString(msg.model) ?? model,\n choices: [{ index: 0, message, finish_reason: mapStopReason(msg.stop_reason) }],\n usage: toUsage(msg.usage) ?? makeUsage(0, 0),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Adapter\n// ---------------------------------------------------------------------------\n\n/**\n * Anthropic Messages API adapter (API key).\n *\n * Reads `account.config`: `baseUrl` (default `https://api.anthropic.com/v1`), `defaultHeaders`\n * (e.g. `anthropic-beta`), `models` (allow-list replacing the `/models` lookup).\n */\nexport class AnthropicProvider implements Provider {\n readonly kind = 'anthropic' as const;\n\n private scope(ctx: ProviderCallContext): ErrorScope {\n return {\n provider: this.kind,\n accountId: ctx.account.id,\n secret: ctx.secret,\n reportLimits: ctx.reportLimits,\n };\n }\n\n private baseUrl(ctx: ProviderCallContext): string {\n return configString(ctx.account.config, 'baseUrl') ?? ANTHROPIC_DEFAULT_BASE_URL;\n }\n\n private headers(ctx: ProviderCallContext): Record<string, string> {\n if (!ctx.secret) {\n throw new ProviderError('anthropic account has no API key configured', {\n kind: 'auth',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n return {\n 'anthropic-version': ANTHROPIC_VERSION,\n ...configHeaders(ctx.account.config),\n 'x-api-key': ctx.secret,\n };\n }\n\n async listModels(ctx: ProviderCallContext): Promise<ModelInfo[]> {\n const allow = configStringArray(ctx.account.config, 'models');\n if (allow.length > 0) return modelList(allow, this.kind);\n const json = await sendJson(\n {\n url: `${joinUrl(this.baseUrl(ctx), 'models')}?limit=1000`,\n method: 'GET',\n headers: this.headers(ctx),\n signal: ctx.signal,\n },\n this.scope(ctx),\n );\n const data = isRecord(json) ? asArray(json.data) : [];\n return modelList(\n data.flatMap((m) => (isRecord(m) && asString(m.id) ? [asString(m.id) as string] : [])),\n this.kind,\n );\n }\n\n async complete(req: ChatRequest, ctx: ProviderCallContext): Promise<ChatCompletion> {\n const model = stripProviderPrefix(req.model, this.kind);\n const json = await sendJson(\n {\n url: joinUrl(this.baseUrl(ctx), 'messages'),\n headers: this.headers(ctx),\n body: toAnthropicRequest(req, model),\n signal: ctx.signal,\n },\n this.scope(ctx),\n );\n return fromAnthropicMessage(json, model);\n }\n\n async *stream(req: ChatRequest, ctx: ProviderCallContext): AsyncGenerator<ChatCompletionChunk> {\n const model = stripProviderPrefix(req.model, this.kind);\n const scope = this.scope(ctx);\n const res = await send(\n {\n url: joinUrl(this.baseUrl(ctx), 'messages'),\n headers: this.headers(ctx),\n body: { ...toAnthropicRequest(req, model), stream: true },\n signal: ctx.signal,\n },\n scope,\n );\n\n let id = newId();\n let outModel = model;\n const created = nowSeconds();\n let inputTokens = 0;\n let cacheTokens = 0;\n let outputTokens = 0;\n let finish: FinishReason = null;\n let finished = false;\n let sawContent = false;\n // Anthropic content block index -> OpenAI tool_calls index.\n const toolIndex = new Map<number, number>();\n\n const finalChunk = (): ChatCompletionChunk =>\n makeChunk(\n id,\n outModel,\n created,\n {},\n finish ?? 'stop',\n makeUsage(inputTokens + cacheTokens, outputTokens),\n );\n\n try {\n for await (const event of parseSse(guardedBody(res, scope, ctx.signal))) {\n let json: unknown;\n try {\n json = JSON.parse(event.data);\n } catch {\n continue;\n }\n if (!isRecord(json)) continue;\n const type = asString(json.type) ?? event.event;\n\n if (type === 'message_start') {\n const message = isRecord(json.message) ? json.message : {};\n id = asString(message.id) ?? id;\n outModel = asString(message.model) ?? outModel;\n const usage = isRecord(message.usage) ? message.usage : {};\n inputTokens = asNumber(usage.input_tokens) ?? 0;\n cacheTokens =\n (asNumber(usage.cache_creation_input_tokens) ?? 0) +\n (asNumber(usage.cache_read_input_tokens) ?? 0);\n outputTokens = asNumber(usage.output_tokens) ?? 0;\n yield makeChunk(id, outModel, created, { role: 'assistant', content: '' });\n } else if (type === 'content_block_start') {\n const block = isRecord(json.content_block) ? json.content_block : {};\n if (block.type === 'tool_use') {\n const idx = toolIndex.size;\n toolIndex.set(asNumber(json.index) ?? idx, idx);\n sawContent = true;\n yield makeChunk(\n id,\n outModel,\n created,\n toolCallDelta(idx, {\n id: asString(block.id) ?? newId('call'),\n name: asString(block.name) ?? '',\n arguments: '',\n }),\n );\n }\n } else if (type === 'content_block_delta') {\n const delta = isRecord(json.delta) ? json.delta : {};\n if (delta.type === 'text_delta') {\n const text = asString(delta.text) ?? '';\n if (text) {\n sawContent = true;\n yield makeChunk(id, outModel, created, { content: text });\n }\n } else if (delta.type === 'input_json_delta') {\n const idx = toolIndex.get(asNumber(json.index) ?? -1);\n const partial = asString(delta.partial_json) ?? '';\n if (idx !== undefined && partial) {\n yield makeChunk(id, outModel, created, toolCallDelta(idx, { arguments: partial }));\n }\n }\n } else if (type === 'message_delta') {\n const delta = isRecord(json.delta) ? json.delta : {};\n const reason = mapStopReason(delta.stop_reason);\n if (reason) finish = reason;\n const usage = isRecord(json.usage) ? json.usage : {};\n const out = asNumber(usage.output_tokens);\n if (out !== undefined) outputTokens = out;\n const inp = asNumber(usage.input_tokens);\n if (inp !== undefined && inp > 0) inputTokens = inp;\n } else if (type === 'message_stop') {\n finished = true;\n yield finalChunk();\n return;\n } else if (type === 'error') {\n throw this.streamError(isRecord(json.error) ? json.error : {}, ctx);\n }\n }\n if (!finished && (sawContent || finish)) yield finalChunk();\n } catch (err) {\n throw toProviderError(err, scope, ctx.signal);\n }\n }\n\n private streamError(error: JsonObject, ctx: ProviderCallContext): ProviderError {\n const type = asString(error.type) ?? '';\n const message = asString(error.message) ?? 'upstream stream error';\n let kind = classifyMessage(`${type} ${message}`);\n if (!kind) {\n if (type === 'overloaded_error' || type === 'api_error') kind = 'unavailable';\n else if (type === 'rate_limit_error') kind = 'rate_limit';\n else if (type === 'authentication_error' || type === 'permission_error') kind = 'auth';\n else if (type === 'invalid_request_error') kind = 'bad_request';\n else kind = 'unknown';\n }\n return new ProviderError(`anthropic stream error (${type}): ${redact(message, ctx.secret)}`, {\n kind,\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n}\n","import path from 'node:path';\nimport { ProviderError } from '../errors';\nimport type {\n ChatCompletion,\n ChatCompletionChunk,\n ChatRequest,\n ModelInfo,\n Provider,\n ProviderCallContext,\n} from '../types';\nimport { classifyCliText, cliSettings, renderTranscript, runCli } from './shared/cli';\nimport { collectCompletion } from './shared/collect';\nimport { redact } from './shared/errors';\nimport {\n asNumber,\n asString,\n configString,\n configStringArray,\n isRecord,\n makeChunk,\n makeUsage,\n modelList,\n newId,\n nowSeconds,\n stripProviderPrefix,\n} from './shared/util';\n\nconst SAFE_MODEL = /^[\\w.:[\\]-]+$/;\n\n/**\n * Google Antigravity CLI adapter (`agy`, the user's own Google sign-in). Spawns\n * `agy --input-format stream-json --output-format stream-json --sandbox\n * --disable-slash-commands [--model m] --print=` and writes one\n * `{ \"event\": \"user\", \"message\": { \"content\": transcript } }` line to stdin, so long\n * conversations never hit command-line length limits.\n *\n * Output is NDJSON with an `event` envelope: `init`, `step_update` (`step_type`\n * `agent_response` carries `text_delta`) and one `result` per turn with `status`, `response`,\n * `error` and `usage` (`input_tokens`, `output_tokens`, `thinking_tokens`). Verified with\n * agy 1.4.8 on Windows (2026-10-28) against its headless documentation.\n *\n * Headless runs auto-allow file reads and writes in the working directory, so the default\n * working directory is the account's sandbox, never a project, and `--sandbox` restricts the\n * terminal. Antigravity keeps its login in the OS keyring with no per-account home, so all\n * Antigravity accounts share the machine's sign-in.\n *\n * Reads `account.config`: `binaryPath` (default `agy`), `binaryArgs` (prefix args), `models`,\n * `cwd` (default the sandbox dir).\n */\nexport class AntigravityCliProvider implements Provider {\n readonly kind = 'antigravity-cli' as const;\n\n async listModels(ctx: ProviderCallContext): Promise<ModelInfo[]> {\n const configured = configStringArray(ctx.account.config, 'models');\n return modelList(configured.length > 0 ? configured : ['default'], this.kind);\n }\n\n async complete(req: ChatRequest, ctx: ProviderCallContext): Promise<ChatCompletion> {\n return collectCompletion(this.stream(req, ctx), stripProviderPrefix(req.model, this.kind));\n }\n\n async *stream(req: ChatRequest, ctx: ProviderCallContext): AsyncGenerator<ChatCompletionChunk> {\n const model = stripProviderPrefix(req.model, this.kind);\n if (model && !SAFE_MODEL.test(model)) {\n throw new ProviderError('antigravity-cli: unsupported characters in model id', {\n kind: 'bad_request',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n const args = [\n '--input-format',\n 'stream-json',\n '--output-format',\n 'stream-json',\n '--sandbox',\n '--disable-slash-commands',\n ];\n if (model && model !== 'default') args.push('--model', model);\n // `--print` takes the prompt as its value; empty means \"read it from stdin\".\n args.push('--print=');\n\n const run = runCli({\n provider: this.kind,\n accountId: ctx.account.id,\n settings: cliSettings(ctx, 'agy'),\n args,\n env: {},\n cwd: configString(ctx.account.config, 'cwd') ?? path.resolve(ctx.sandboxDir),\n stdin: `${JSON.stringify({\n event: 'user',\n message: { content: renderTranscript(req.messages, true) },\n })}\\n`,\n signal: ctx.signal,\n });\n\n const id = newId();\n const created = nowSeconds();\n let started = false;\n let streamed = false;\n let completed = false;\n let failure: string | undefined;\n\n const fail = (message: string): ProviderError => {\n const { kind, retryAfterMs } = classifyCliText(message);\n return new ProviderError(`antigravity-cli: ${redact(message, ctx.secret).slice(0, 500)}`, {\n kind,\n retryAfterMs,\n provider: this.kind,\n accountId: ctx.account.id,\n });\n };\n const start = function* () {\n if (started) return;\n started = true;\n yield makeChunk(id, model, created, { role: 'assistant', content: '' });\n };\n\n for await (const raw of run.events) {\n if (!isRecord(raw)) continue;\n const event = asString(raw.event);\n\n if (event === 'step_update' && isRecord(raw.step_update)) {\n const step = raw.step_update;\n const delta = asString(step.text_delta);\n if (asString(step.step_type) === 'agent_response' && delta) {\n yield* start();\n streamed = true;\n yield makeChunk(id, model, created, { content: delta });\n }\n continue;\n }\n\n if (event === 'result' && isRecord(raw.result)) {\n const result = raw.result;\n if (asString(result.status) !== 'SUCCESS') {\n failure = asString(result.error) ?? `Antigravity ended with ${result.status}`;\n break;\n }\n completed = true;\n yield* start();\n const response = asString(result.response);\n if (!streamed && response) yield makeChunk(id, model, created, { content: response });\n const u = isRecord(result.usage) ? result.usage : {};\n const output = (asNumber(u.output_tokens) ?? 0) + (asNumber(u.thinking_tokens) ?? 0);\n yield makeChunk(\n id,\n model,\n created,\n {},\n 'stop',\n makeUsage(asNumber(u.input_tokens) ?? 0, output),\n );\n break;\n }\n }\n\n const exit = await run.exit;\n if (exit.aborted || ctx.signal?.aborted) {\n throw new ProviderError('antigravity-cli request aborted', {\n kind: 'timeout',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n if (failure) throw fail(failure);\n if (!completed) {\n throw fail(exit.stderr.trim() || `process exited with code ${exit.code ?? 'unknown'}`);\n }\n }\n}\n","/** Child-process helpers shared by the `claude-cli`, `codex-cli` and `gemini-cli` adapters. */\nimport { type ChildProcess, spawn, spawnSync } from 'node:child_process';\nimport { existsSync, mkdirSync, statSync } from 'node:fs';\nimport path from 'node:path';\nimport { ProviderError } from '../../errors';\nimport type {\n ChatMessage,\n ProviderCallContext,\n ProviderErrorKind,\n ProviderKind,\n} from '../../types';\nimport { classifyMessage } from './errors';\nimport { parseNdjson } from './lines';\nimport { contentToText } from './util';\n\nconst MAX_STDERR = 64 * 1024;\n\nexport interface CliSettings {\n /** Resolved command to execute. */\n command: string;\n /** Arguments that always precede the adapter's own (e.g. `['fake-cli.js']` for `node`). */\n prefixArgs: string[];\n}\n\n/** Read `config.binaryPath` / `config.binaryArgs`. */\nexport function cliSettings(ctx: ProviderCallContext, defaultBinary: string): CliSettings {\n const binary = ctx.account.config.binaryPath;\n const args = ctx.account.config.binaryArgs;\n return {\n command: typeof binary === 'string' && binary.trim() ? binary.trim() : defaultBinary,\n prefixArgs: Array.isArray(args) ? args.filter((a): a is string => typeof a === 'string') : [],\n };\n}\n\n/** Resolve a bare command name through PATH (honouring PATHEXT on Windows). */\nexport function resolveOnPath(command: string, env: NodeJS.ProcessEnv = process.env): string {\n if (command.includes('/') || command.includes('\\\\') || path.isAbsolute(command)) return command;\n const win = process.platform === 'win32';\n const dirs = (env.PATH ?? env.Path ?? '').split(path.delimiter).filter(Boolean);\n const exts = win\n ? ['', ...(env.PATHEXT ?? '.COM;.EXE;.BAT;.CMD').split(';').map((e) => e.toLowerCase())]\n : [''];\n // Prefer real executables over .cmd shims on Windows so no shell is needed.\n const ordered = win ? [...exts].sort((a, b) => rank(a) - rank(b)) : exts;\n for (const dir of dirs) {\n for (const ext of ordered) {\n const candidate = path.join(dir, command + ext);\n try {\n if (existsSync(candidate) && statSync(candidate).isFile()) return candidate;\n } catch {\n // unreadable PATH entry\n }\n }\n }\n return command;\n}\n\nfunction rank(ext: string): number {\n if (ext === '.exe' || ext === '.com') return 0;\n if (ext === '') return 1;\n return 2;\n}\n\n/** True when the command is a Windows batch shim that cannot be spawned without a shell. */\nexport function needsShell(command: string): boolean {\n return process.platform === 'win32' && /\\.(cmd|bat)$/i.test(command);\n}\n\n/**\n * Characters that cmd.exe never interprets. Deliberately excludes `%` and `!` (variable\n * expansion), quotes, whitespace and every operator, so no escaping is ever needed.\n */\nconst SHELL_SAFE = /^[\\w.:=@+\\-/\\\\[\\]]+$/;\n\n/** True when `arg` can be passed through cmd.exe verbatim. */\nexport function isShellSafeArg(arg: string): boolean {\n return SHELL_SAFE.test(arg);\n}\n\n/** Quote the resolved binary path (it may contain spaces); arguments must already be safe. */\nfunction quoteCommand(path: string): string {\n return isShellSafeArg(path) ? path : `\"${path}\"`;\n}\n\nexport interface CliRunOptions {\n provider: ProviderKind;\n accountId: string;\n settings: CliSettings;\n args: string[];\n env: Record<string, string>;\n cwd: string;\n stdin: string;\n signal?: AbortSignal;\n}\n\nexport interface CliExit {\n code: number | null;\n stderr: string;\n /** True when the process was killed because the caller aborted. */\n aborted: boolean;\n}\n\nexport interface CliRun {\n /** Parsed NDJSON events from stdout. */\n events: AsyncGenerator<unknown>;\n /** Resolves once the process has exited (after stdout is drained). */\n exit: Promise<CliExit>;\n}\n\nfunction killTree(child: ChildProcess): void {\n if (child.pid === undefined || child.exitCode !== null) return;\n if (process.platform === 'win32') {\n spawnSync('taskkill', ['/pid', String(child.pid), '/T', '/F'], { windowsHide: true });\n } else {\n child.kill('SIGTERM');\n }\n}\n\n/** Spawn a CLI, feed `stdin`, and expose its stdout as NDJSON events. */\nexport function runCli(opts: CliRunOptions): CliRun {\n mkdirSync(opts.cwd, { recursive: true });\n const resolved = resolveOnPath(opts.settings.command);\n const shell = needsShell(resolved);\n const args = [...opts.settings.prefixArgs, ...opts.args];\n const env = { ...process.env, ...opts.env };\n\n const fail = (message: string, cause?: unknown): ProviderError =>\n new ProviderError(message, {\n kind: 'unavailable',\n provider: opts.provider,\n accountId: opts.accountId,\n cause,\n });\n\n if (opts.signal?.aborted) {\n throw new ProviderError(`${opts.provider} request aborted`, {\n kind: 'timeout',\n provider: opts.provider,\n accountId: opts.accountId,\n });\n }\n\n if (shell) {\n // cmd.exe quoting cannot neutralise %VAR% expansion, so refuse anything that is not\n // trivially safe (e.g. a client-supplied model name) instead of trying to escape it.\n const unsafe = args.some((arg) => !isShellSafeArg(arg));\n if (unsafe || /[\"%!]/.test(resolved)) {\n throw new ProviderError(\n `${opts.provider}: refusing to pass an unsafe argument through the Windows shell`,\n { kind: 'bad_request', provider: opts.provider, accountId: opts.accountId },\n );\n }\n }\n\n const child = shell\n ? spawn(`${quoteCommand(resolved)} ${args.join(' ')}`, {\n cwd: opts.cwd,\n env,\n shell: true,\n windowsHide: true,\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n : spawn(resolved, args, {\n cwd: opts.cwd,\n env,\n windowsHide: true,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let stderr = '';\n let spawnError: Error | undefined;\n let aborted = false;\n child.stderr?.setEncoding('utf8');\n child.stderr?.on('data', (d: string) => {\n if (stderr.length < MAX_STDERR) stderr += d;\n });\n child.stdin?.on('error', () => {\n // child exited before reading stdin\n });\n child.stdin?.end(opts.stdin);\n\n const onAbort = () => {\n aborted = true;\n killTree(child);\n };\n opts.signal?.addEventListener('abort', onAbort, { once: true });\n\n const closed = new Promise<number | null>((resolve) => {\n child.once('error', (err) => {\n spawnError = err;\n resolve(null);\n });\n child.once('close', (code) => resolve(code));\n });\n\n const exit = closed.then((code): CliExit => {\n opts.signal?.removeEventListener('abort', onAbort);\n if (spawnError) {\n throw fail(\n `${opts.provider} CLI could not be started (${(spawnError as NodeJS.ErrnoException).code ?? spawnError.message}); check config.binaryPath`,\n spawnError,\n );\n }\n return { code, stderr, aborted };\n });\n // Avoid unhandled rejection noise when the consumer stops early.\n exit.catch(() => undefined);\n\n async function* events(): AsyncGenerator<unknown> {\n try {\n if (child.stdout) {\n yield* parseNdjson(child.stdout as AsyncIterable<Buffer>);\n }\n } finally {\n if (child.exitCode === null) killTree(child);\n }\n }\n\n return { events: events(), exit };\n}\n\n/** Render an OpenAI conversation as a plain-text transcript for a CLI prompt. */\nexport function renderTranscript(messages: ChatMessage[], includeSystem: boolean): string {\n const turns = messages.filter((m) => includeSystem || m.role !== 'system');\n const userTurns = turns.filter((m) => m.role !== 'system');\n const only = userTurns.length === 1 && userTurns[0]?.role === 'user';\n if (only && turns.length === 1) return contentToText(userTurns[0]?.content);\n\n const label: Record<ChatMessage['role'], string> = {\n system: 'System',\n user: 'User',\n assistant: 'Assistant',\n tool: 'Tool result',\n };\n const blocks = turns.map((m) => {\n let body = contentToText(m.content);\n for (const call of m.tool_calls ?? []) {\n body += `${body ? '\\n' : ''}[called tool ${call.function.name} with ${call.function.arguments}]`;\n }\n const name = m.role === 'tool' && m.name ? ` (${m.name})` : '';\n return `[${label[m.role]}${name}]\\n${body}`;\n });\n return `Below is the conversation so far. Reply only with the next assistant message.\\n\\n${blocks.join('\\n\\n')}\\n\\n[Assistant]\\n`;\n}\n\nexport function systemText(messages: ChatMessage[]): string {\n return messages\n .filter((m) => m.role === 'system')\n .map((m) => contentToText(m.content))\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/**\n * Classify a CLI failure message. Subscription CLIs report limits as plain text, so this is\n * heuristic: limits first, then auth, then transient server trouble.\n */\nexport function classifyCliText(\n text: string,\n now = Date.now(),\n): { kind: ProviderErrorKind; retryAfterMs?: number } {\n const ctxKind = classifyMessage(text);\n if (ctxKind === 'context_length') return { kind: ctxKind };\n if (\n /usage limit|5-hour limit|five-hour limit|weekly limit|hit your limit|limit reached|out of (credits|usage)|insufficient[_ ]quota|quota|RESOURCE_EXHAUSTED/i.test(\n text,\n )\n ) {\n return { kind: 'quota_exhausted', retryAfterMs: parseResetMs(text, now) };\n }\n if (/rate[ _-]?limit|too many requests|\\b429\\b/i.test(text)) {\n return { kind: 'rate_limit', retryAfterMs: parseResetMs(text, now) };\n }\n if (\n /not logged in|please run \\/login|\\/login|codex login|auth method|invalid api key|unauthori[sz]ed|authentication|oauth token|token (has )?expired|login required|sign in|IneligibleTierError|UNSUPPORTED_CLIENT|client is no longer supported|\\b401\\b/i.test(\n text,\n )\n ) {\n return { kind: 'auth' };\n }\n if (/overloaded|unavailable|internal server error|\\b(500|502|503|529)\\b/i.test(text)) {\n return { kind: 'unavailable' };\n }\n return { kind: ctxKind ?? 'unknown' };\n}\n\n/**\n * Parse a reset time out of CLI limit messages and return milliseconds from `now`.\n * Understands `...limit reached|1760000000` (epoch seconds/ms) and `resets 3pm`,\n * `resets 3:30 PM (America/New_York)` (next occurrence of that wall-clock time).\n */\nexport function parseResetMs(text: string, now = Date.now()): number | undefined {\n const epoch = /\\|\\s*(\\d{9,13})\\b/.exec(text)?.[1];\n if (epoch) {\n const n = Number(epoch);\n const at = epoch.length <= 10 ? n * 1000 : n;\n return Math.max(0, at - now);\n }\n const m = /resets?(?:\\s+at)?\\s+(\\d{1,2})(?::(\\d{2}))?\\s*(am|pm)?(?:\\s*\\(([^)]+)\\))?/i.exec(text);\n if (!m?.[1]) return undefined;\n let hour = Number(m[1]);\n const minute = Number(m[2] ?? '0');\n const meridiem = m[3]?.toLowerCase();\n if (meridiem === 'pm' && hour < 12) hour += 12;\n if (meridiem === 'am' && hour === 12) hour = 0;\n if (hour > 23 || minute > 59) return undefined;\n const tz = m[4]?.trim();\n let nowHour: number;\n let nowMinute: number;\n let nowSecond: number;\n try {\n const parts = new Intl.DateTimeFormat('en-US', {\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n hourCycle: 'h23',\n ...(tz ? { timeZone: tz } : {}),\n }).formatToParts(new Date(now));\n const get = (t: string) => Number(parts.find((p) => p.type === t)?.value ?? '0');\n nowHour = get('hour') % 24;\n nowMinute = get('minute');\n nowSecond = get('second');\n } catch {\n return undefined;\n }\n const nowSecs = nowHour * 3600 + nowMinute * 60 + nowSecond;\n let diff = hour * 3600 + minute * 60 - nowSecs;\n if (diff <= 0) diff += 24 * 3600;\n return diff * 1000;\n}\n","import type { ChatCompletion, ChatCompletionChunk, FinishReason } from '../../types';\nimport { makeUsage, newId, nowSeconds } from './util';\n\n/** Fold a chunk stream into a single non-streaming completion (text only; CLI adapters). */\nexport async function collectCompletion(\n chunks: AsyncIterable<ChatCompletionChunk>,\n model: string,\n): Promise<ChatCompletion> {\n let id = newId();\n let outModel = model;\n let text = '';\n let finish: FinishReason = null;\n let usage = makeUsage(0, 0);\n for await (const c of chunks) {\n id = c.id;\n outModel = c.model || outModel;\n if (c.usage) usage = c.usage;\n for (const choice of c.choices) {\n if (typeof choice.delta.content === 'string') text += choice.delta.content;\n if (choice.finish_reason) finish = choice.finish_reason;\n }\n }\n return {\n id,\n object: 'chat.completion',\n created: nowSeconds(),\n model: outModel,\n choices: [\n { index: 0, message: { role: 'assistant', content: text }, finish_reason: finish ?? 'stop' },\n ],\n usage,\n };\n}\n","import path from 'node:path';\nimport { ProviderError } from '../errors';\nimport type {\n ChatCompletion,\n ChatCompletionChunk,\n ChatRequest,\n FinishReason,\n ModelInfo,\n Provider,\n ProviderCallContext,\n} from '../types';\nimport {\n classifyCliText,\n cliSettings,\n needsShell,\n renderTranscript,\n resolveOnPath,\n runCli,\n systemText,\n} from './shared/cli';\nimport { collectCompletion } from './shared/collect';\nimport { redact } from './shared/errors';\nimport {\n asArray,\n asNumber,\n asString,\n configString,\n configStringArray,\n isRecord,\n makeChunk,\n makeUsage,\n modelList,\n newId,\n nowSeconds,\n stripProviderPrefix,\n} from './shared/util';\n\nconst DEFAULT_MODELS = ['default', 'sonnet', 'opus', 'haiku'];\nconst SAFE_MODEL = /^[\\w.:[\\]-]+$/;\n\n/**\n * Local Claude Code CLI adapter (subscription login). Spawns\n * `claude -p --output-format stream-json --verbose --include-partial-messages` headlessly with\n * `CLAUDE_CONFIG_DIR` set to the account's sandbox directory, so every account keeps its own\n * login. The conversation is sent on stdin as a transcript; the CLI's own tool use is not\n * surfaced, only its text. OpenAI `tools` in the request are ignored.\n *\n * Reads `account.config`: `binaryPath` (default `claude`), `binaryArgs` (prefix args, e.g.\n * `['script.js']` when `binaryPath` is `node`), `models` (advertised model list),\n * `systemPromptMode` (`append` (default) uses `--append-system-prompt`, `replace` uses\n * `--system-prompt`), `cwd` (working directory, default the sandbox dir).\n *\n * On Windows `.cmd`/`.bat` shims are run through the shell; the system prompt is then folded\n * into the stdin transcript instead of a command-line flag to avoid shell quoting problems.\n */\nexport class ClaudeCliProvider implements Provider {\n readonly kind = 'claude-cli' as const;\n\n async listModels(ctx: ProviderCallContext): Promise<ModelInfo[]> {\n const configured = configStringArray(ctx.account.config, 'models');\n return modelList(configured.length > 0 ? configured : DEFAULT_MODELS, this.kind);\n }\n\n async complete(req: ChatRequest, ctx: ProviderCallContext): Promise<ChatCompletion> {\n return collectCompletion(this.stream(req, ctx), stripProviderPrefix(req.model, this.kind));\n }\n\n async *stream(req: ChatRequest, ctx: ProviderCallContext): AsyncGenerator<ChatCompletionChunk> {\n const model = stripProviderPrefix(req.model, this.kind);\n const settings = cliSettings(ctx, 'claude');\n const shell = needsShell(resolveOnPath(settings.command));\n const system = systemText(req.messages);\n const args = [\n '-p',\n '--output-format',\n 'stream-json',\n '--verbose',\n '--include-partial-messages',\n ];\n args.push('--no-session-persistence');\n if (model && model !== 'default') {\n if (!SAFE_MODEL.test(model)) {\n throw new ProviderError('claude-cli: unsupported characters in model id', {\n kind: 'bad_request',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n args.push('--model', model);\n }\n if (system && !shell) {\n const flag =\n configString(ctx.account.config, 'systemPromptMode') === 'replace'\n ? '--system-prompt'\n : '--append-system-prompt';\n args.push(flag, system);\n }\n\n const run = runCli({\n provider: this.kind,\n accountId: ctx.account.id,\n settings,\n args,\n env: { CLAUDE_CONFIG_DIR: ctx.sandboxDir },\n cwd: configString(ctx.account.config, 'cwd') ?? path.resolve(ctx.sandboxDir),\n stdin: renderTranscript(req.messages, shell),\n signal: ctx.signal,\n });\n\n const id = newId();\n const created = nowSeconds();\n let outModel = model;\n let started = false;\n let emittedText = false;\n let finished = false;\n const streamedMessages = new Set<string>();\n\n const fail = (message: string): ProviderError => {\n const { kind, retryAfterMs } = classifyCliText(message);\n return new ProviderError(`claude-cli: ${redact(message, ctx.secret).slice(0, 500)}`, {\n kind,\n retryAfterMs,\n provider: this.kind,\n accountId: ctx.account.id,\n });\n };\n\n const abortError = () =>\n new ProviderError('claude-cli request aborted', {\n kind: 'timeout',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n\n for await (const raw of run.events) {\n if (!isRecord(raw)) continue;\n const type = asString(raw.type);\n const isSub = raw.parent_tool_use_id != null;\n\n if (type === 'system' && raw.subtype === 'init') {\n outModel = asString(raw.model) ?? outModel;\n continue;\n }\n\n if (type === 'stream_event' && !isSub && isRecord(raw.event)) {\n const ev = raw.event;\n if (ev.type === 'message_start' && isRecord(ev.message)) {\n const mid = asString(ev.message.id);\n if (mid) streamedMessages.add(mid);\n outModel = asString(ev.message.model) ?? outModel;\n } else if (\n ev.type === 'content_block_delta' &&\n isRecord(ev.delta) &&\n ev.delta.type === 'text_delta'\n ) {\n const text = asString(ev.delta.text);\n if (text) {\n if (!started) {\n started = true;\n yield makeChunk(id, outModel, created, { role: 'assistant', content: '' });\n }\n emittedText = true;\n yield makeChunk(id, outModel, created, { content: text });\n }\n }\n continue;\n }\n\n if (type === 'assistant' && !isSub && isRecord(raw.message)) {\n const mid = asString(raw.message.id);\n if (mid && streamedMessages.has(mid)) continue;\n const text = asArray(raw.message.content)\n .flatMap((b) => (isRecord(b) && b.type === 'text' ? [asString(b.text) ?? ''] : []))\n .join('');\n if (text) {\n if (!started) {\n started = true;\n yield makeChunk(id, outModel, created, { role: 'assistant', content: '' });\n }\n emittedText = true;\n yield makeChunk(id, outModel, created, { content: text });\n }\n continue;\n }\n\n if (type === 'result') {\n finished = true;\n const resultText = asString(raw.result) ?? '';\n const subtype = asString(raw.subtype) ?? '';\n if (raw.is_error === true || (subtype && subtype !== 'success')) {\n throw fail(resultText || `Claude CLI reported ${subtype || 'an error'}`);\n }\n if (!started) {\n started = true;\n yield makeChunk(id, outModel, created, { role: 'assistant', content: '' });\n }\n if (!emittedText && resultText) {\n yield makeChunk(id, outModel, created, { content: resultText });\n }\n const u = isRecord(raw.usage) ? raw.usage : {};\n const prompt =\n (asNumber(u.input_tokens) ?? 0) +\n (asNumber(u.cache_creation_input_tokens) ?? 0) +\n (asNumber(u.cache_read_input_tokens) ?? 0);\n const finish: FinishReason = raw.stop_reason === 'max_tokens' ? 'length' : 'stop';\n yield makeChunk(\n id,\n outModel,\n created,\n {},\n finish,\n makeUsage(prompt, asNumber(u.output_tokens) ?? 0),\n );\n }\n }\n\n const exit = await run.exit;\n if (exit.aborted || ctx.signal?.aborted) throw abortError();\n if (!finished) {\n const detail = exit.stderr.trim() || `process exited with code ${exit.code ?? 'unknown'}`;\n throw fail(detail);\n }\n }\n}\n","import path from 'node:path';\nimport { ProviderError } from '../errors';\nimport type {\n ChatCompletion,\n ChatCompletionChunk,\n ChatRequest,\n ModelInfo,\n Provider,\n ProviderCallContext,\n} from '../types';\nimport { classifyCliText, cliSettings, renderTranscript, runCli } from './shared/cli';\nimport { collectCompletion } from './shared/collect';\nimport { redact } from './shared/errors';\nimport {\n asNumber,\n asString,\n configString,\n configStringArray,\n isRecord,\n makeChunk,\n makeUsage,\n modelList,\n newId,\n nowSeconds,\n stripProviderPrefix,\n} from './shared/util';\n\nconst SAFE_MODEL = /^[\\w.:[\\]-]+$/;\n\n/** Pull the text of an agent message out of the (version-dependent) event shapes. */\nfunction agentText(item: Record<string, unknown>): string | undefined {\n const type = asString(item.type);\n if (type && type !== 'agent_message' && type !== 'assistant_message') return undefined;\n const text = asString(item.text) ?? asString(item.message);\n if (text !== undefined) return text;\n if (Array.isArray(item.content)) {\n return item.content.flatMap((c) => (isRecord(c) ? [asString(c.text) ?? ''] : [])).join('');\n }\n return undefined;\n}\n\nfunction errorText(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (isRecord(value)) return asString(value.message) ?? JSON.stringify(value);\n return undefined;\n}\n\n/**\n * Local OpenAI Codex CLI adapter (ChatGPT subscription login). Spawns\n * `codex exec --json --skip-git-repo-check --ephemeral --sandbox read-only [-m model] -` with\n * `CODEX_HOME` set to the account's sandbox directory and the transcript (system prompt\n * included) on stdin.\n *\n * The JSONL parser is deliberately tolerant. It understands the documented events\n * `thread.started`, `turn.started`, `item.completed` (`agent_message` items with `text`),\n * `turn.completed` (`usage.input_tokens` / `cached_input_tokens` / `output_tokens`),\n * `turn.failed` and `error`, plus the older `{ msg: { type, ... } }` envelope. Unknown events\n * are ignored. Codex emits whole messages (no token deltas), so each agent message is one chunk.\n * The event format and completion usage were verified with Codex CLI 0.163.0 (2026-10-24).\n *\n * Reads `account.config`: `binaryPath` (default `codex`), `binaryArgs` (prefix args), `models`,\n * `sandbox` (`read-only` default, passed to `--sandbox`), `cwd` (default the sandbox dir).\n */\nexport class CodexCliProvider implements Provider {\n readonly kind = 'codex-cli' as const;\n\n async listModels(ctx: ProviderCallContext): Promise<ModelInfo[]> {\n const configured = configStringArray(ctx.account.config, 'models');\n return modelList(configured.length > 0 ? configured : ['default'], this.kind);\n }\n\n async complete(req: ChatRequest, ctx: ProviderCallContext): Promise<ChatCompletion> {\n return collectCompletion(this.stream(req, ctx), stripProviderPrefix(req.model, this.kind));\n }\n\n async *stream(req: ChatRequest, ctx: ProviderCallContext): AsyncGenerator<ChatCompletionChunk> {\n const model = stripProviderPrefix(req.model, this.kind);\n const sandbox = configString(ctx.account.config, 'sandbox') ?? 'read-only';\n if (!SAFE_MODEL.test(sandbox) || (model && !SAFE_MODEL.test(model))) {\n throw new ProviderError('codex-cli: unsupported characters in model or sandbox setting', {\n kind: 'bad_request',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n const args = ['exec', '--json', '--skip-git-repo-check', '--ephemeral', '--sandbox', sandbox];\n if (model && model !== 'default') args.push('-m', model);\n args.push('-');\n\n const run = runCli({\n provider: this.kind,\n accountId: ctx.account.id,\n settings: cliSettings(ctx, 'codex'),\n args,\n env: { CODEX_HOME: ctx.sandboxDir },\n cwd: configString(ctx.account.config, 'cwd') ?? path.resolve(ctx.sandboxDir),\n stdin: renderTranscript(req.messages, true),\n signal: ctx.signal,\n });\n\n const id = newId();\n const created = nowSeconds();\n let started = false;\n let completed = false;\n let failure: string | undefined;\n\n const fail = (message: string): ProviderError => {\n const { kind, retryAfterMs } = classifyCliText(message);\n return new ProviderError(`codex-cli: ${redact(message, ctx.secret).slice(0, 500)}`, {\n kind,\n retryAfterMs,\n provider: this.kind,\n accountId: ctx.account.id,\n });\n };\n\n for await (const raw of run.events) {\n if (!isRecord(raw)) continue;\n // Older builds wrap events as { id, msg: { type, ... } }.\n const ev = isRecord(raw.msg) ? raw.msg : raw;\n const type = asString(ev.type) ?? '';\n\n let text: string | undefined;\n if (type === 'item.completed' && isRecord(ev.item)) text = agentText(ev.item);\n else if (type === 'agent_message') text = agentText(ev);\n\n if (text) {\n if (!started) {\n started = true;\n yield makeChunk(id, model, created, { role: 'assistant', content: '' });\n }\n yield makeChunk(id, model, created, { content: text });\n continue;\n }\n\n if (type === 'turn.failed' || type === 'error') {\n failure =\n errorText(ev.error) ?? errorText(ev.message) ?? failure ?? 'Codex reported an error';\n if (type === 'turn.failed') break;\n continue;\n }\n\n if (type === 'turn.completed' || type === 'task_complete') {\n completed = true;\n if (!started) {\n started = true;\n yield makeChunk(id, model, created, { role: 'assistant', content: '' });\n const last = asString(ev.last_agent_message);\n if (last) yield makeChunk(id, model, created, { content: last });\n }\n const u = isRecord(ev.usage) ? ev.usage : {};\n // cached_input_tokens is a subset of input_tokens in Codex's accounting.\n const prompt = asNumber(u.input_tokens) ?? 0;\n yield makeChunk(\n id,\n model,\n created,\n {},\n 'stop',\n makeUsage(prompt, asNumber(u.output_tokens) ?? 0),\n );\n break;\n }\n }\n\n const exit = await run.exit;\n if (exit.aborted || ctx.signal?.aborted) {\n throw new ProviderError('codex-cli request aborted', {\n kind: 'timeout',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n if (failure) throw fail(failure);\n if (!completed) {\n throw fail(exit.stderr.trim() || `process exited with code ${exit.code ?? 'unknown'}`);\n }\n }\n}\n","import { ProviderError } from '../errors';\nimport type {\n ChatCompletion,\n ChatCompletionChunk,\n ChatMessage,\n ChatRequest,\n ContentPart,\n FinishReason,\n ModelInfo,\n Provider,\n ProviderCallContext,\n ToolCall,\n Usage,\n} from '../types';\nimport { classifyMessage, type ErrorScope, redact, toProviderError } from './shared/errors';\nimport { guardedBody, send, sendJson } from './shared/http';\nimport { parseSse } from './shared/lines';\nimport {\n asArray,\n asNumber,\n asString,\n configHeaders,\n configString,\n configStringArray,\n isRecord,\n type JsonObject,\n joinUrl,\n makeChunk,\n makeUsage,\n modelList,\n newId,\n nowSeconds,\n stripProviderPrefix,\n toolCallDelta,\n} from './shared/util';\n\nexport const GEMINI_DEFAULT_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta';\n\ninterface GeminiContent {\n role: 'user' | 'model';\n parts: JsonObject[];\n}\n\nexport interface GeminiRequestBody {\n contents: GeminiContent[];\n systemInstruction?: { parts: JsonObject[] };\n generationConfig?: JsonObject;\n tools?: Array<{ functionDeclarations: JsonObject[] }>;\n toolConfig?: { functionCallingConfig: JsonObject };\n}\n\n// ---------------------------------------------------------------------------\n// Request translation (OpenAI -> Gemini)\n// ---------------------------------------------------------------------------\n\nconst MIME_BY_EXT: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n webp: 'image/webp',\n};\n\nfunction imagePart(url: string): JsonObject {\n const data = /^data:([^;,]+);base64,(.*)$/s.exec(url);\n if (data) return { inlineData: { mimeType: data[1], data: data[2] } };\n const ext = /\\.([a-z0-9]+)(?:\\?|#|$)/i.exec(url)?.[1]?.toLowerCase() ?? '';\n return { fileData: { mimeType: MIME_BY_EXT[ext] ?? 'image/jpeg', fileUri: url } };\n}\n\nfunction toParts(content: ChatMessage['content']): JsonObject[] {\n if (content == null) return [];\n if (typeof content === 'string') return content ? [{ text: content }] : [];\n return content.flatMap((p: ContentPart) => {\n if (p.type === 'text') return p.text ? [{ text: p.text }] : [];\n return [imagePart(p.image_url.url)];\n });\n}\n\nfunction textOf(content: ChatMessage['content']): string {\n if (content == null) return '';\n if (typeof content === 'string') return content;\n return content.flatMap((p) => (p.type === 'text' ? [p.text] : [])).join('\\n');\n}\n\nfunction parseArgs(raw: string): JsonObject {\n if (!raw.trim()) return {};\n try {\n const parsed: unknown = JSON.parse(raw);\n return isRecord(parsed) ? parsed : { value: parsed };\n } catch {\n return {};\n }\n}\n\n/** Gemini accepts an OpenAPI subset: drop keys it rejects. */\nfunction sanitizeSchema(schema: unknown): unknown {\n if (Array.isArray(schema)) return schema.map(sanitizeSchema);\n if (!isRecord(schema)) return schema;\n const out: JsonObject = {};\n for (const [k, v] of Object.entries(schema)) {\n if (k === '$schema' || k === 'additionalProperties' || k === '$id' || k === 'definitions')\n continue;\n out[k] = sanitizeSchema(v);\n }\n return out;\n}\n\nfunction pushContent(out: GeminiContent[], role: 'user' | 'model', parts: JsonObject[]) {\n if (parts.length === 0) return;\n const last = out[out.length - 1];\n if (last && last.role === role) last.parts.push(...parts);\n else out.push({ role, parts: [...parts] });\n}\n\nexport function toGeminiRequest(req: ChatRequest): GeminiRequestBody {\n const system: string[] = [];\n const contents: GeminiContent[] = [];\n const toolNames = new Map<string, string>();\n for (const m of req.messages) {\n if (m.role === 'system') {\n const text = textOf(m.content);\n if (text) system.push(text);\n } else if (m.role === 'user') {\n pushContent(contents, 'user', toParts(m.content));\n } else if (m.role === 'assistant') {\n const parts = toParts(m.content);\n for (const call of m.tool_calls ?? []) {\n toolNames.set(call.id, call.function.name);\n parts.push({\n functionCall: { name: call.function.name, args: parseArgs(call.function.arguments) },\n });\n }\n pushContent(contents, 'model', parts);\n } else {\n const name = (m.tool_call_id ? toolNames.get(m.tool_call_id) : undefined) ?? m.name ?? 'tool';\n const text = textOf(m.content);\n let response: JsonObject = { result: text };\n try {\n const parsed: unknown = JSON.parse(text);\n if (isRecord(parsed)) response = parsed;\n } catch {\n // plain text result\n }\n pushContent(contents, 'user', [{ functionResponse: { name, response } }]);\n }\n }\n\n const body: GeminiRequestBody = { contents };\n if (system.length > 0) body.systemInstruction = { parts: [{ text: system.join('\\n\\n') }] };\n\n const gen: JsonObject = {};\n if (req.temperature !== undefined) gen.temperature = req.temperature;\n if (req.top_p !== undefined) gen.topP = req.top_p;\n if (req.max_tokens !== undefined) gen.maxOutputTokens = req.max_tokens;\n if (req.stop !== undefined) gen.stopSequences = Array.isArray(req.stop) ? req.stop : [req.stop];\n if (Object.keys(gen).length > 0) body.generationConfig = gen;\n\n if (req.tools && req.tools.length > 0) {\n body.tools = [\n {\n functionDeclarations: req.tools.map((t) => {\n const decl: JsonObject = { name: t.function.name };\n if (t.function.description) decl.description = t.function.description;\n const params = t.function.parameters;\n const hasProps =\n isRecord(params?.properties) && Object.keys(params.properties).length > 0;\n if (params && hasProps) decl.parameters = sanitizeSchema(params);\n return decl;\n }),\n },\n ];\n const choice = req.tool_choice;\n if (choice === 'auto') body.toolConfig = { functionCallingConfig: { mode: 'AUTO' } };\n else if (choice === 'none') body.toolConfig = { functionCallingConfig: { mode: 'NONE' } };\n else if (choice === 'required') body.toolConfig = { functionCallingConfig: { mode: 'ANY' } };\n else if (choice && typeof choice === 'object') {\n body.toolConfig = {\n functionCallingConfig: { mode: 'ANY', allowedFunctionNames: [choice.function.name] },\n };\n }\n }\n return body;\n}\n\n// ---------------------------------------------------------------------------\n// Response translation (Gemini -> OpenAI)\n// ---------------------------------------------------------------------------\n\nexport function mapFinishReason(reason: unknown, hasToolCalls: boolean): FinishReason {\n if (typeof reason !== 'string') return hasToolCalls ? 'tool_calls' : null;\n switch (reason) {\n case 'MAX_TOKENS':\n return 'length';\n case 'SAFETY':\n case 'RECITATION':\n case 'BLOCKLIST':\n case 'PROHIBITED_CONTENT':\n case 'SPII':\n case 'IMAGE_SAFETY':\n case 'LANGUAGE':\n return 'content_filter';\n default:\n return hasToolCalls ? 'tool_calls' : 'stop';\n }\n}\n\nfunction toUsage(value: unknown): Usage | undefined {\n if (!isRecord(value)) return undefined;\n const prompt = asNumber(value.promptTokenCount) ?? 0;\n const completion =\n (asNumber(value.candidatesTokenCount) ?? 0) + (asNumber(value.thoughtsTokenCount) ?? 0);\n return makeUsage(prompt, completion);\n}\n\ninterface ParsedCandidate {\n text: string;\n calls: Array<{ name: string; args: unknown }>;\n finishReason: unknown;\n}\n\nfunction parseCandidate(json: unknown): ParsedCandidate {\n const candidate = isRecord(json) ? asArray(json.candidates)[0] : undefined;\n const content = isRecord(candidate) && isRecord(candidate.content) ? candidate.content : {};\n let text = '';\n const calls: ParsedCandidate['calls'] = [];\n for (const part of asArray(content.parts)) {\n if (!isRecord(part)) continue;\n if (typeof part.text === 'string' && part.thought !== true) text += part.text;\n if (isRecord(part.functionCall)) {\n calls.push({\n name: asString(part.functionCall.name) ?? '',\n args: part.functionCall.args ?? {},\n });\n }\n }\n const finishReason = isRecord(candidate) ? candidate.finishReason : undefined;\n return { text, calls, finishReason };\n}\n\nfunction blockReason(json: unknown): string | undefined {\n const feedback = isRecord(json) ? json.promptFeedback : undefined;\n return isRecord(feedback) ? asString(feedback.blockReason) : undefined;\n}\n\nexport function fromGeminiResponse(json: unknown, model: string): ChatCompletion {\n const { text, calls, finishReason } = parseCandidate(json);\n const toolCalls: ToolCall[] = calls.map((c) => ({\n id: newId('call'),\n type: 'function',\n function: { name: c.name, arguments: JSON.stringify(c.args) },\n }));\n const message: ChatMessage = {\n role: 'assistant',\n content: text || (toolCalls.length ? null : ''),\n };\n if (toolCalls.length > 0) message.tool_calls = toolCalls;\n const finish =\n blockReason(json) && !text\n ? 'content_filter'\n : mapFinishReason(finishReason, toolCalls.length > 0);\n const modelVersion = isRecord(json) ? asString(json.modelVersion) : undefined;\n const responseId = isRecord(json) ? asString(json.responseId) : undefined;\n return {\n id: responseId ? `chatcmpl-${responseId}` : newId(),\n object: 'chat.completion',\n created: nowSeconds(),\n model: modelVersion ?? model,\n choices: [{ index: 0, message, finish_reason: finish ?? 'stop' }],\n usage: toUsage(isRecord(json) ? json.usageMetadata : undefined) ?? makeUsage(0, 0),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Adapter\n// ---------------------------------------------------------------------------\n\n/**\n * Google Gemini API adapter (`generateContent` / `streamGenerateContent?alt=sse`), API key sent\n * as `x-goog-api-key`.\n *\n * Reads `account.config`: `baseUrl` (default `https://generativelanguage.googleapis.com/v1beta`),\n * `defaultHeaders`, `models` (allow-list replacing the `/models` lookup).\n *\n * Limitation: image URLs that are not `data:` URLs are sent as `fileData`, which Gemini only\n * accepts for Google-hosted URIs; inline images should use data URLs.\n */\nexport class GeminiProvider implements Provider {\n readonly kind = 'gemini' as const;\n\n private scope(ctx: ProviderCallContext): ErrorScope {\n return {\n provider: this.kind,\n accountId: ctx.account.id,\n secret: ctx.secret,\n reportLimits: ctx.reportLimits,\n };\n }\n\n private baseUrl(ctx: ProviderCallContext): string {\n return configString(ctx.account.config, 'baseUrl') ?? GEMINI_DEFAULT_BASE_URL;\n }\n\n private headers(ctx: ProviderCallContext): Record<string, string> {\n if (!ctx.secret) {\n throw new ProviderError('gemini account has no API key configured', {\n kind: 'auth',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n return { ...configHeaders(ctx.account.config), 'x-goog-api-key': ctx.secret };\n }\n\n private modelId(model: string): string {\n return stripProviderPrefix(model, this.kind).replace(/^models\\//, '');\n }\n\n async listModels(ctx: ProviderCallContext): Promise<ModelInfo[]> {\n const allow = configStringArray(ctx.account.config, 'models');\n if (allow.length > 0) return modelList(allow, this.kind);\n const json = await sendJson(\n {\n url: `${joinUrl(this.baseUrl(ctx), 'models')}?pageSize=1000`,\n method: 'GET',\n headers: this.headers(ctx),\n signal: ctx.signal,\n },\n this.scope(ctx),\n );\n const ids = (isRecord(json) ? asArray(json.models) : []).flatMap((m) => {\n if (!isRecord(m)) return [];\n const name = asString(m.name);\n const methods = asArray(m.supportedGenerationMethods);\n if (!name || (methods.length > 0 && !methods.includes('generateContent'))) return [];\n return [name.replace(/^models\\//, '')];\n });\n return modelList(ids, this.kind);\n }\n\n async complete(req: ChatRequest, ctx: ProviderCallContext): Promise<ChatCompletion> {\n const model = this.modelId(req.model);\n const json = await sendJson(\n {\n url: joinUrl(this.baseUrl(ctx), `models/${model}:generateContent`),\n headers: this.headers(ctx),\n body: toGeminiRequest(req),\n signal: ctx.signal,\n },\n this.scope(ctx),\n );\n return fromGeminiResponse(json, model);\n }\n\n async *stream(req: ChatRequest, ctx: ProviderCallContext): AsyncGenerator<ChatCompletionChunk> {\n const model = this.modelId(req.model);\n const scope = this.scope(ctx);\n const res = await send(\n {\n url: `${joinUrl(this.baseUrl(ctx), `models/${model}:streamGenerateContent`)}?alt=sse`,\n headers: this.headers(ctx),\n body: toGeminiRequest(req),\n signal: ctx.signal,\n },\n scope,\n );\n const id = newId();\n const created = nowSeconds();\n let outModel = model;\n let toolCount = 0;\n let finishReason: unknown;\n let usage: Usage | undefined;\n let blocked = false;\n let started = false;\n try {\n for await (const event of parseSse(guardedBody(res, scope, ctx.signal))) {\n let json: unknown;\n try {\n json = JSON.parse(event.data);\n } catch {\n continue;\n }\n if (!isRecord(json)) continue;\n if (isRecord(json.error)) throw this.streamError(json.error, ctx);\n if (!started) {\n started = true;\n yield makeChunk(id, outModel, created, { role: 'assistant', content: '' });\n }\n outModel = asString(json.modelVersion) ?? outModel;\n const { text, calls, finishReason: fr } = parseCandidate(json);\n if (text) yield makeChunk(id, outModel, created, { content: text });\n for (const call of calls) {\n yield makeChunk(\n id,\n outModel,\n created,\n toolCallDelta(toolCount++, {\n id: newId('call'),\n name: call.name,\n arguments: JSON.stringify(call.args),\n }),\n );\n }\n if (fr !== undefined && fr !== null) finishReason = fr;\n if (blockReason(json)) blocked = true;\n usage = toUsage(json.usageMetadata) ?? usage;\n }\n if (!started) yield makeChunk(id, outModel, created, { role: 'assistant', content: '' });\n const finish =\n (blocked && finishReason === undefined ? 'content_filter' : undefined) ??\n mapFinishReason(finishReason, toolCount > 0) ??\n 'stop';\n yield makeChunk(id, outModel, created, {}, finish, usage ?? makeUsage(0, 0));\n } catch (err) {\n throw toProviderError(err, scope, ctx.signal);\n }\n }\n\n private streamError(error: JsonObject, ctx: ProviderCallContext): ProviderError {\n const message = asString(error.message) ?? 'upstream stream error';\n const status = asString(error.status) ?? '';\n let kind = classifyMessage(`${status} ${message}`);\n if (!kind) {\n if (status === 'UNAVAILABLE' || status === 'INTERNAL') kind = 'unavailable';\n else if (status === 'DEADLINE_EXCEEDED') kind = 'timeout';\n else if (status === 'UNAUTHENTICATED' || status === 'PERMISSION_DENIED') kind = 'auth';\n else if (status === 'INVALID_ARGUMENT') kind = 'bad_request';\n else kind = 'unknown';\n }\n return new ProviderError(`gemini stream error (${status}): ${redact(message, ctx.secret)}`, {\n kind,\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n}\n","import path from 'node:path';\nimport { ProviderError } from '../errors';\nimport { geminiHomeEnv, seedGeminiHome } from '../identity/sandbox';\nimport type {\n ChatCompletion,\n ChatCompletionChunk,\n ChatRequest,\n ModelInfo,\n Provider,\n ProviderCallContext,\n} from '../types';\nimport { classifyCliText, cliSettings, renderTranscript, runCli } from './shared/cli';\nimport { collectCompletion } from './shared/collect';\nimport { redact } from './shared/errors';\nimport {\n asNumber,\n asString,\n configString,\n configStringArray,\n isRecord,\n makeChunk,\n makeUsage,\n modelList,\n newId,\n nowSeconds,\n stripProviderPrefix,\n} from './shared/util';\n\nconst DEFAULT_MODELS = ['default', 'gemini-2.5-pro', 'gemini-2.5-flash'];\nconst SAFE_MODEL = /^[\\w.:[\\]-]+$/;\n\n/**\n * Environment for every Gemini CLI process of an account: its home points at the sandbox and\n * API-key variables are blanked so a key in the parent environment never overrides the\n * account's Google login.\n */\nexport function geminiCliEnv(sandboxDir: string): Record<string, string> {\n return {\n ...geminiHomeEnv(path.resolve(sandboxDir)),\n GEMINI_API_KEY: '',\n GOOGLE_API_KEY: '',\n GOOGLE_GENAI_USE_VERTEXAI: '',\n };\n}\n\nfunction errorText(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (isRecord(value)) return asString(value.message) ?? JSON.stringify(value);\n return undefined;\n}\n\n/**\n * Local Gemini CLI adapter (official \"Login with Google\" subscription/free-tier login).\n * Spawns `gemini --output-format stream-json [-m model]` with the transcript (system prompt\n * included) on stdin, which runs Gemini CLI non-interactively. The account's sandbox becomes\n * the CLI's home (`GEMINI_CLI_HOME`, plus `HOME`/`USERPROFILE`), so `~/.gemini` (settings and\n * the cached Google OAuth credentials Gemini CLI writes itself) is per account. A fresh sandbox\n * is seeded with settings that select `oauth-personal`.\n *\n * The NDJSON parser is tolerant: it understands `message` events from the assistant (with or\n * without `delta`), `error` events, and the final `result` event (`status`, `error`,\n * `stats.input_tokens` / `stats.output_tokens`), plus a single `{ response, stats }` object as\n * printed by `--output-format json` on older builds. Unknown events (`init`, `tool_use`,\n * `tool_result`) are ignored. Gemini CLI 0.65.0 was tested locally (2026-10-24): official\n * Google sign-in succeeded, but Code Assist rejected the client with UNSUPPORTED_CLIENT.\n * Successful live completion remains unverified; see docs/PROVIDER-VERIFICATION.md.\n *\n * Reads `account.config`: `binaryPath` (default `gemini`), `binaryArgs` (prefix args),\n * `models`, `cwd` (default the sandbox dir).\n */\nexport class GeminiCliProvider implements Provider {\n readonly kind = 'gemini-cli' as const;\n\n async listModels(ctx: ProviderCallContext): Promise<ModelInfo[]> {\n const configured = configStringArray(ctx.account.config, 'models');\n return modelList(configured.length > 0 ? configured : DEFAULT_MODELS, this.kind);\n }\n\n async complete(req: ChatRequest, ctx: ProviderCallContext): Promise<ChatCompletion> {\n return collectCompletion(this.stream(req, ctx), stripProviderPrefix(req.model, this.kind));\n }\n\n async *stream(req: ChatRequest, ctx: ProviderCallContext): AsyncGenerator<ChatCompletionChunk> {\n const model = stripProviderPrefix(req.model, this.kind);\n if (model && !SAFE_MODEL.test(model)) {\n throw new ProviderError('gemini-cli: unsupported characters in model id', {\n kind: 'bad_request',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n const args = ['--output-format', 'stream-json'];\n if (model && model !== 'default') args.push('-m', model);\n\n seedGeminiHome(ctx.sandboxDir);\n const run = runCli({\n provider: this.kind,\n accountId: ctx.account.id,\n settings: cliSettings(ctx, 'gemini'),\n args,\n env: geminiCliEnv(ctx.sandboxDir),\n cwd: configString(ctx.account.config, 'cwd') ?? path.resolve(ctx.sandboxDir),\n stdin: renderTranscript(req.messages, true),\n signal: ctx.signal,\n });\n\n const id = newId();\n const created = nowSeconds();\n let started = false;\n let completed = false;\n let failure: string | undefined;\n\n const fail = (message: string): ProviderError => {\n const { kind, retryAfterMs } = classifyCliText(message);\n return new ProviderError(`gemini-cli: ${redact(message, ctx.secret).slice(0, 500)}`, {\n kind,\n retryAfterMs,\n provider: this.kind,\n accountId: ctx.account.id,\n });\n };\n const open = (): ChatCompletionChunk | undefined => {\n if (started) return undefined;\n started = true;\n return makeChunk(id, model, created, { role: 'assistant', content: '' });\n };\n const usageOf = (stats: unknown) => {\n const s = isRecord(stats) ? stats : {};\n return makeUsage(asNumber(s.input_tokens) ?? 0, asNumber(s.output_tokens) ?? 0);\n };\n\n for await (const ev of run.events) {\n if (!isRecord(ev)) continue;\n const type = asString(ev.type);\n\n if (type === undefined && typeof ev.response === 'string') {\n const first = open();\n if (first) yield first;\n if (ev.response) yield makeChunk(id, model, created, { content: ev.response });\n if (ev.error) failure = errorText(ev.error);\n else {\n completed = true;\n yield makeChunk(id, model, created, {}, 'stop', usageOf(ev.stats));\n }\n break;\n }\n\n if (type === 'message' && ev.role === 'assistant') {\n const text = asString(ev.content);\n if (text) {\n const first = open();\n if (first) yield first;\n yield makeChunk(id, model, created, { content: text });\n }\n continue;\n }\n\n if (type === 'error') {\n if (asString(ev.severity) === 'warning') continue;\n failure = errorText(ev.message) ?? errorText(ev.error) ?? 'Gemini CLI reported an error';\n continue;\n }\n\n if (type === 'result') {\n if (asString(ev.status) === 'error' || ev.error) {\n failure = errorText(ev.error) ?? failure ?? 'Gemini CLI reported an error';\n break;\n }\n completed = true;\n const first = open();\n if (first) yield first;\n yield makeChunk(id, model, created, {}, 'stop', usageOf(ev.stats));\n break;\n }\n }\n\n const exit = await run.exit;\n if (exit.aborted || ctx.signal?.aborted) {\n throw new ProviderError('gemini-cli request aborted', {\n kind: 'timeout',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n if (failure) throw fail(failure);\n if (!completed) {\n throw fail(exit.stderr.trim() || `process exited with code ${exit.code ?? 'unknown'}`);\n }\n }\n}\n","import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';\nimport { isAbsolute, join, relative, resolve } from 'node:path';\nimport { globalPaths } from '../paths';\nimport type { Account } from '../types';\n\nconst SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;\n/** Windows device names that cannot be used as directory names. */\nconst RESERVED = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])$/i;\n\n/**\n * Resolve `<root>/<accountId>`, rejecting ids that are not plain identifiers or that would\n * resolve outside `root` (path traversal, absolute paths, drive letters, reserved names).\n */\nexport function accountDir(root: string, accountId: string): string {\n if (!SAFE_ID.test(accountId) || RESERVED.test(accountId)) {\n throw new Error(`Invalid account id for an isolated directory: ${JSON.stringify(accountId)}`);\n }\n const base = resolve(root);\n const dir = resolve(base, accountId);\n const rel = relative(base, dir);\n if (rel === '' || rel.startsWith('..') || isAbsolute(rel)) {\n throw new Error(`Account directory escapes ${base}: ${JSON.stringify(accountId)}`);\n }\n return dir;\n}\n\n/**\n * Gemini CLI settings that select \"Login with Google\" (personal OAuth) so the first run in a\n * fresh sandbox starts Google's own sign-in instead of asking for an API key.\n */\nexport const GEMINI_CLI_SETTINGS = { security: { auth: { selectedType: 'oauth-personal' } } };\n\n/** Write `<home>/.gemini/settings.json` unless the user (or Gemini CLI) already created one. */\nexport function seedGeminiHome(home: string): void {\n const dir = join(home, '.gemini');\n const file = join(dir, 'settings.json');\n if (existsSync(file)) return;\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n writeFileSync(file, `${JSON.stringify(GEMINI_CLI_SETTINGS, null, 2)}\\n`, { mode: 0o600 });\n}\n\n/**\n * Point Gemini CLI's home at `home`. `GEMINI_CLI_HOME` is honoured by recent releases;\n * `HOME`/`USERPROFILE` cover older ones, since Gemini CLI keeps everything under\n * `os.homedir()/.gemini`.\n */\nexport function geminiHomeEnv(home: string): Record<string, string> {\n return { GEMINI_CLI_HOME: home, HOME: home, USERPROFILE: home };\n}\n\n/**\n * Per-account isolated directories for CLI providers (`~/.davecode/sandboxes/<accountId>`),\n * so accounts never share credentials, caches or rate-limit state.\n */\nexport class SandboxManager {\n readonly root: string;\n\n constructor(root: string = globalPaths().sandboxes) {\n this.root = resolve(root);\n }\n\n /** Path of an account's sandbox (not created). */\n dirFor(accountId: string): string {\n return accountDir(this.root, accountId);\n }\n\n /** Create the sandbox if needed and return its path. */\n ensure(accountId: string): string {\n const dir = this.dirFor(accountId);\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n return dir;\n }\n\n /** {@link ensure} plus any provider-specific first-run files (Gemini CLI auth selection). */\n prepare(account: Pick<Account, 'id' | 'provider'>): string {\n const dir = this.ensure(account.id);\n if (account.provider === 'gemini-cli') seedGeminiHome(dir);\n return dir;\n }\n\n /** Environment variables that point a CLI provider at the account's sandbox. */\n envFor(account: Pick<Account, 'id' | 'provider'>): Record<string, string> {\n switch (account.provider) {\n case 'claude-cli':\n return { CLAUDE_CONFIG_DIR: this.dirFor(account.id) };\n case 'codex-cli':\n return { CODEX_HOME: this.dirFor(account.id) };\n case 'gemini-cli':\n return geminiHomeEnv(this.dirFor(account.id));\n default:\n return {};\n }\n }\n\n /** Delete an account's sandbox and everything in it. */\n remove(accountId: string): void {\n rmSync(this.dirFor(accountId), { recursive: true, force: true });\n }\n}\n","/**\n * EXPERIMENTAL - TERMS OF SERVICE RISK.\n *\n * This adapter fronts a consumer Gemini web session (gemini.google.com) through an injected\n * driver. Automating a consumer web UI very likely violates Google's Terms of Service; accounts\n * used this way can be rate limited or suspended. It is disabled unless the user opts in with\n * `experimental.geminiWeb`, and nothing here talks to Google directly.\n *\n * This file deliberately contains NO browser automation: it does not import Playwright or any\n * Chromium code and never reads cookies. Whoever enables the feature supplies a\n * {@link GeminiWebDriver} implementation (for example one that drives a dedicated Chromium\n * profile in `ctx.sandboxDir`). Without a driver every call fails with an `unavailable` error.\n */\nimport { ProviderError } from '../errors';\nimport type {\n ChatCompletion,\n ChatCompletionChunk,\n ChatRequest,\n ModelInfo,\n Provider,\n ProviderCallContext,\n} from '../types';\nimport { renderTranscript } from './shared/cli';\nimport { collectCompletion } from './shared/collect';\nimport { toProviderError } from './shared/errors';\nimport {\n configStringArray,\n makeChunk,\n makeUsage,\n modelList,\n newId,\n nowSeconds,\n stripProviderPrefix,\n} from './shared/util';\n\n/** Bridge to a logged-in Gemini web session. Implemented outside of `core`. */\nexport interface GeminiWebDriver {\n /**\n * Send one prompt and stream back the reply as text fragments (deltas, not cumulative text).\n * Implementations should stop promptly when `signal` aborts and throw `ProviderError`\n * (e.g. kind `auth` when the session is logged out) for upstream failures.\n */\n send(\n prompt: string,\n options: { signal?: AbortSignal; sandboxDir?: string },\n ): AsyncIterable<string>;\n}\n\n/** Rough token estimate (the web UI exposes no usage data). */\nfunction estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * `gemini-web` adapter. Reads `account.config.models` (advertised model list; default\n * `['gemini-web']`). Usage in the final chunk is an estimate (about 4 characters per token).\n */\nexport class GeminiWebProvider implements Provider {\n readonly kind = 'gemini-web' as const;\n\n constructor(private readonly driver?: GeminiWebDriver) {}\n\n async listModels(ctx: ProviderCallContext): Promise<ModelInfo[]> {\n const configured = configStringArray(ctx.account.config, 'models');\n return modelList(configured.length > 0 ? configured : ['gemini-web'], this.kind);\n }\n\n async complete(req: ChatRequest, ctx: ProviderCallContext): Promise<ChatCompletion> {\n return collectCompletion(this.stream(req, ctx), stripProviderPrefix(req.model, this.kind));\n }\n\n async *stream(req: ChatRequest, ctx: ProviderCallContext): AsyncGenerator<ChatCompletionChunk> {\n const scope = { provider: this.kind, accountId: ctx.account.id, secret: ctx.secret };\n if (!this.driver) {\n throw new ProviderError(\n 'gemini-web is experimental and needs a GeminiWebDriver. It automates a consumer web ' +\n \"session, may violate Google's Terms of Service, and no driver is configured.\",\n { kind: 'unavailable', provider: this.kind, accountId: ctx.account.id },\n );\n }\n const model = stripProviderPrefix(req.model, this.kind);\n const prompt = renderTranscript(req.messages, true);\n const id = newId();\n const created = nowSeconds();\n let output = 0;\n try {\n yield makeChunk(id, model, created, { role: 'assistant', content: '' });\n for await (const text of this.driver.send(prompt, {\n signal: ctx.signal,\n sandboxDir: ctx.sandboxDir,\n })) {\n if (ctx.signal?.aborted) break;\n if (!text) continue;\n output += estimateTokens(text);\n yield makeChunk(id, model, created, { content: text });\n }\n if (ctx.signal?.aborted) throw new DOMException('aborted', 'AbortError');\n yield makeChunk(id, model, created, {}, 'stop', makeUsage(estimateTokens(prompt), output));\n } catch (err) {\n throw toProviderError(err, scope, ctx.signal);\n }\n }\n}\n","import { ProviderError } from '../errors';\nimport type {\n ChatCompletion,\n ChatCompletionChunk,\n ChatMessage,\n ChatRequest,\n FinishReason,\n ModelInfo,\n Provider,\n ProviderCallContext,\n ProviderKind,\n Usage,\n} from '../types';\nimport { classifyMessage, type ErrorScope, redact, toProviderError } from './shared/errors';\nimport { guardedBody, send, sendJson } from './shared/http';\nimport { parseSse } from './shared/lines';\nimport {\n asArray,\n asNumber,\n asString,\n configHeaders,\n configString,\n configStringArray,\n isRecord,\n joinUrl,\n makeUsage,\n modelList,\n newId,\n nowSeconds,\n stripProviderPrefix,\n} from './shared/util';\n\nexport const OPENAI_DEFAULT_BASE_URL = 'https://api.openai.com/v1';\n\nexport interface OpenAIProviderOptions {\n /** Provider kind reported by the adapter. */\n kind?: ProviderKind;\n /** Base URL used when `account.config.baseUrl` is absent. */\n defaultBaseUrl?: string;\n /** Fail with `bad_request` when no `config.baseUrl` is set. */\n requireBaseUrl?: boolean;\n /** Fail with `auth` when the context carries no secret. */\n requireSecret?: boolean;\n}\n\nconst FINISH_REASONS: ReadonlySet<string> = new Set([\n 'stop',\n 'length',\n 'tool_calls',\n 'content_filter',\n]);\n\nfunction toFinishReason(value: unknown): FinishReason {\n if (typeof value !== 'string') return null;\n if (FINISH_REASONS.has(value)) return value as FinishReason;\n if (value === 'function_call') return 'tool_calls';\n return 'stop';\n}\n\nfunction parseUsage(value: unknown): Usage | undefined {\n if (!isRecord(value)) return undefined;\n const prompt = asNumber(value.prompt_tokens) ?? 0;\n const completion = asNumber(value.completion_tokens) ?? 0;\n return {\n prompt_tokens: prompt,\n completion_tokens: completion,\n total_tokens: asNumber(value.total_tokens) ?? prompt + completion,\n };\n}\n\n/**\n * OpenAI Chat Completions adapter. Requests and responses are already in the gateway's wire\n * format, so this is mostly a passthrough with uniform error mapping. It is also the base class\n * of the `openai-compatible` adapter.\n *\n * Reads `account.config`: `baseUrl`, `defaultHeaders`, `models` (allow-list that replaces the\n * `/models` lookup), `includeUsage` (set `false` for servers rejecting `stream_options`).\n */\nexport class OpenAIProvider implements Provider {\n readonly kind: ProviderKind;\n protected readonly defaultBaseUrl: string | undefined;\n protected readonly requireBaseUrl: boolean;\n protected readonly requireSecret: boolean;\n\n constructor(options: OpenAIProviderOptions = {}) {\n this.kind = options.kind ?? 'openai';\n this.defaultBaseUrl =\n 'defaultBaseUrl' in options ? options.defaultBaseUrl : OPENAI_DEFAULT_BASE_URL;\n this.requireBaseUrl = options.requireBaseUrl ?? false;\n this.requireSecret = options.requireSecret ?? this.kind === 'openai';\n }\n\n protected scope(ctx: ProviderCallContext): ErrorScope {\n return {\n provider: this.kind,\n accountId: ctx.account.id,\n secret: ctx.secret,\n reportLimits: ctx.reportLimits,\n };\n }\n\n protected baseUrl(ctx: ProviderCallContext): string {\n const configured = configString(ctx.account.config, 'baseUrl');\n const url = configured ?? (this.requireBaseUrl ? undefined : this.defaultBaseUrl);\n if (!url) {\n throw new ProviderError(`${this.kind} requires account.config.baseUrl`, {\n kind: 'bad_request',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n return url;\n }\n\n protected headers(ctx: ProviderCallContext): Record<string, string> {\n if (this.requireSecret && !ctx.secret) {\n throw new ProviderError(`${this.kind} account has no API key configured`, {\n kind: 'auth',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n return {\n ...configHeaders(ctx.account.config),\n ...(ctx.secret ? { authorization: `Bearer ${ctx.secret}` } : {}),\n };\n }\n\n protected modelId(model: string): string {\n return stripProviderPrefix(model, this.kind);\n }\n\n async listModels(ctx: ProviderCallContext): Promise<ModelInfo[]> {\n const allow = configStringArray(ctx.account.config, 'models');\n if (allow.length > 0) return modelList(allow, this.kind);\n const json = await sendJson(\n {\n url: joinUrl(this.baseUrl(ctx), 'models'),\n method: 'GET',\n headers: this.headers(ctx),\n signal: ctx.signal,\n },\n this.scope(ctx),\n );\n const data = isRecord(json) ? asArray(json.data) : [];\n const ids = data.flatMap((m) =>\n isRecord(m) && asString(m.id) ? [asString(m.id) as string] : [],\n );\n return modelList(ids, this.kind);\n }\n\n async complete(req: ChatRequest, ctx: ProviderCallContext): Promise<ChatCompletion> {\n const body = { ...req, model: this.modelId(req.model), stream: false };\n const json = await sendJson(\n {\n url: joinUrl(this.baseUrl(ctx), 'chat/completions'),\n headers: this.headers(ctx),\n body,\n signal: ctx.signal,\n },\n this.scope(ctx),\n );\n return this.normalizeCompletion(json, body.model, ctx);\n }\n\n async *stream(req: ChatRequest, ctx: ProviderCallContext): AsyncGenerator<ChatCompletionChunk> {\n const includeUsage = ctx.account.config.includeUsage !== false;\n const body = {\n ...req,\n model: this.modelId(req.model),\n stream: true,\n ...(includeUsage ? { stream_options: { include_usage: true } } : {}),\n };\n const scope = this.scope(ctx);\n const res = await send(\n {\n url: joinUrl(this.baseUrl(ctx), 'chat/completions'),\n headers: this.headers(ctx),\n body,\n signal: ctx.signal,\n },\n scope,\n );\n try {\n for await (const event of parseSse(guardedBody(res, scope, ctx.signal))) {\n const data = event.data.trim();\n if (data === '[DONE]') return;\n let json: unknown;\n try {\n json = JSON.parse(data);\n } catch {\n continue;\n }\n if (!isRecord(json)) continue;\n if (isRecord(json.error)) throw this.streamError(json.error, ctx);\n yield this.normalizeChunk(json, body.model);\n }\n } catch (err) {\n throw toProviderError(err, scope, ctx.signal);\n }\n }\n\n private streamError(error: Record<string, unknown>, ctx: ProviderCallContext): ProviderError {\n const message = asString(error.message) ?? 'upstream stream error';\n const code = `${asString(error.code) ?? ''} ${asString(error.type) ?? ''}`;\n return new ProviderError(`${this.kind} stream error: ${redact(message, ctx.secret)}`, {\n kind: classifyMessage(`${code} ${message}`) ?? 'unavailable',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n\n private normalizeChunk(json: Record<string, unknown>, model: string): ChatCompletionChunk {\n const choices = asArray(json.choices).flatMap((c, i) => {\n if (!isRecord(c)) return [];\n const delta = isRecord(c.delta) ? (c.delta as Partial<ChatMessage>) : {};\n return [\n {\n index: asNumber(c.index) ?? i,\n delta,\n finish_reason: toFinishReason(c.finish_reason),\n },\n ];\n });\n const out: ChatCompletionChunk = {\n id: asString(json.id) ?? newId(),\n object: 'chat.completion.chunk',\n created: asNumber(json.created) ?? nowSeconds(),\n model: asString(json.model) ?? model,\n choices,\n };\n const usage = parseUsage(json.usage);\n if (usage) out.usage = usage;\n return out;\n }\n\n private normalizeCompletion(\n json: unknown,\n model: string,\n ctx: ProviderCallContext,\n ): ChatCompletion {\n if (!isRecord(json) || !Array.isArray(json.choices)) {\n throw new ProviderError(`${this.kind} returned an unexpected response shape`, {\n kind: 'unknown',\n provider: this.kind,\n accountId: ctx.account.id,\n });\n }\n const choices = json.choices.flatMap((c, i) => {\n if (!isRecord(c) || !isRecord(c.message)) return [];\n const message: ChatMessage = {\n ...(c.message as unknown as ChatMessage),\n role: 'assistant',\n content: (c.message.content as ChatMessage['content']) ?? null,\n };\n return [\n { index: asNumber(c.index) ?? i, message, finish_reason: toFinishReason(c.finish_reason) },\n ];\n });\n return {\n id: asString(json.id) ?? newId(),\n object: 'chat.completion',\n created: asNumber(json.created) ?? nowSeconds(),\n model: asString(json.model) ?? model,\n choices,\n usage: parseUsage(json.usage) ?? makeUsage(0, 0),\n };\n }\n}\n","import { OpenAIProvider } from './openai';\n\n/**\n * Any OpenAI-compatible endpoint: OpenRouter, vLLM, LiteLLM... Same wire format as {@link OpenAIProvider}, but `account.config.baseUrl` is\n * required, the API key is optional and extra headers come from `config.defaultHeaders`.\n *\n * Model ids are passed through untouched (OpenRouter ids contain slashes such as\n * `openai/gpt-4o`); only a leading `openai-compatible/` router prefix is removed.\n */\nexport class OpenAICompatibleProvider extends OpenAIProvider {\n constructor() {\n super({\n kind: 'openai-compatible',\n defaultBaseUrl: undefined,\n requireBaseUrl: true,\n requireSecret: false,\n });\n }\n}\n","import type { Provider, ProviderKind } from '../types';\nimport { AnthropicProvider } from './anthropic';\nimport { AntigravityCliProvider } from './antigravity-cli';\nimport { ClaudeCliProvider } from './claude-cli';\nimport { CodexCliProvider } from './codex-cli';\nimport { GeminiProvider } from './gemini';\nimport { GeminiCliProvider } from './gemini-cli';\nimport { type GeminiWebDriver, GeminiWebProvider } from './gemini-web';\nimport { OpenAIProvider } from './openai';\nimport { OpenAICompatibleProvider } from './openai-compatible';\n\nexport interface CreateProvidersOptions {\n /**\n * Driver for the EXPERIMENTAL `gemini-web` provider. Without one, that provider is still\n * registered but fails every call with an `unavailable` ProviderError.\n */\n geminiWebDriver?: GeminiWebDriver;\n}\n\n/** Build one stateless adapter per {@link ProviderKind}. */\nexport function createProviders(options: CreateProvidersOptions = {}): Map<ProviderKind, Provider> {\n const providers: Provider[] = [\n new OpenAIProvider(),\n new OpenAICompatibleProvider(),\n new AnthropicProvider(),\n new GeminiProvider(),\n new ClaudeCliProvider(),\n new CodexCliProvider(),\n new GeminiCliProvider(),\n new AntigravityCliProvider(),\n new GeminiWebProvider(options.geminiWebDriver),\n ];\n return new Map(providers.map((p) => [p.kind, p]));\n}\n","/**\n * Which `Account.config` keys the HTTP API may write, and the rule that keeps a stored secret\n * bound to the endpoint it was saved for.\n *\n * Executable settings (`binaryPath`, `binaryArgs`) and anything else not listed here can only\n * come from the machine's owner: the local `davecode` CLI working on `state.db` directly.\n */\nimport type { Account, ProviderKind } from '../types';\n\n/** Config keys that choose where requests (and the stored secret) are sent. */\nexport const ENDPOINT_CONFIG_KEYS: readonly string[] = ['baseUrl'];\n\nconst MODEL_KEYS = ['models', 'defaultModel'] as const;\n\n/** Keys the API may set per provider. Everything else is rejected. */\nexport const API_CONFIG_KEYS: Record<ProviderKind, readonly string[]> = {\n anthropic: ['baseUrl', ...MODEL_KEYS],\n openai: ['baseUrl', 'includeUsage', ...MODEL_KEYS],\n gemini: ['baseUrl', ...MODEL_KEYS],\n 'openai-compatible': ['baseUrl', 'includeUsage', ...MODEL_KEYS],\n 'claude-cli': [...MODEL_KEYS],\n 'codex-cli': [...MODEL_KEYS],\n 'gemini-cli': [...MODEL_KEYS],\n 'antigravity-cli': [...MODEL_KEYS],\n 'gemini-web': ['models'],\n};\n\nfunction isStringList(value: unknown): boolean {\n return Array.isArray(value) && value.every((v) => typeof v === 'string' && v.length > 0);\n}\n\n/**\n * Problems with a config object received over the API (empty when it is acceptable): unknown or\n * not-allowed keys for the provider (unless unchanged from `existing`), and malformed values for\n * the allowed ones.\n */\nexport function apiConfigIssues(\n provider: ProviderKind,\n config: Record<string, unknown>,\n existing: Record<string, unknown> = {},\n): string[] {\n const allowed = API_CONFIG_KEYS[provider];\n const issues: string[] = [];\n for (const [key, value] of Object.entries(config)) {\n if (!allowed.includes(key)) {\n // Echoing a value the account already has (a client sending back the whole config) is not a change.\n if (key in existing && JSON.stringify(existing[key]) === JSON.stringify(value)) continue;\n issues.push(\n `config.${key} cannot be set through the API for ${provider} accounts` +\n (allowed.length > 0 ? ` (allowed: ${allowed.join(', ')})` : ''),\n );\n continue;\n }\n if (key === 'baseUrl') {\n if (typeof value !== 'string' || !isHttpUrl(value)) {\n issues.push('config.baseUrl must be an http(s) URL without embedded credentials');\n }\n } else if (key === 'models') {\n if (!isStringList(value)) issues.push('config.models must be a list of model ids');\n } else if (key === 'defaultModel') {\n if (typeof value !== 'string' || !value) issues.push('config.defaultModel must be a string');\n } else if (key === 'includeUsage' && typeof value !== 'boolean') {\n issues.push('config.includeUsage must be true or false');\n }\n }\n return issues;\n}\n\nfunction isHttpUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return (\n (url.protocol === 'http:' || url.protocol === 'https:') && !url.username && !url.password\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Config to store after an API `PATCH`: the incoming API-writable keys replace the old ones,\n * while keys the API may not write (e.g. a `binaryPath` the owner set locally) are kept.\n */\nexport function mergeApiConfig(\n provider: ProviderKind,\n existing: Record<string, unknown>,\n incoming: Record<string, unknown>,\n): Record<string, unknown> {\n const allowed = API_CONFIG_KEYS[provider];\n const kept = Object.fromEntries(\n Object.entries(existing).filter(([key]) => !allowed.includes(key)),\n );\n return { ...kept, ...incoming };\n}\n\nfunction endpointOf(config: Record<string, unknown>): string {\n return ENDPOINT_CONFIG_KEYS.map((key) => {\n const value = config[key];\n return typeof value === 'string' ? value.trim().replace(/\\/+$/, '') : '';\n }).join('\\n');\n}\n\n/** True when `next` points the account at a different endpoint than `existing` does. */\nexport function endpointChanged(\n existing: Record<string, unknown>,\n next: Record<string, unknown>,\n): boolean {\n return endpointOf(existing) !== endpointOf(next);\n}\n\n/**\n * A stored secret is only ever sent to the endpoint it was saved with. Moving an account that\n * already holds a secret to another endpoint therefore needs the secret in the same request;\n * returns the error message when that is missing.\n */\nexport function endpointRebindIssue(\n existing: Pick<Account, 'config' | 'hasSecret'>,\n nextConfig: Record<string, unknown> | undefined,\n secretSupplied: boolean,\n): string | undefined {\n if (!nextConfig || secretSupplied || !existing.hasSecret) return undefined;\n if (!endpointChanged(existing.config, nextConfig)) return undefined;\n return 'Changing the endpoint of an account that has a stored secret requires sending the secret again in the same request';\n}\n","/**\n * Shared domain contracts for DaveCode.\n *\n * Every package (gateway, router, runner, CLI, dashboard) speaks these types.\n * Changing a shape here is a breaking change — update docs/API.md alongside it.\n */\n\n// ---------------------------------------------------------------------------\n// OpenAI-compatible chat wire format (subset served on /v1/chat/completions)\n// ---------------------------------------------------------------------------\n\nexport type ChatRole = 'system' | 'user' | 'assistant' | 'tool';\n\nexport type ContentPart =\n | { type: 'text'; text: string }\n | { type: 'image_url'; image_url: { url: string; detail?: 'auto' | 'low' | 'high' } };\n\nexport interface ToolCall {\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n}\n\nexport interface ToolDefinition {\n type: 'function';\n function: {\n name: string;\n description?: string;\n parameters?: Record<string, unknown>;\n };\n}\n\nexport interface ChatMessage {\n role: ChatRole;\n content: string | ContentPart[] | null;\n name?: string;\n tool_call_id?: string;\n tool_calls?: ToolCall[];\n}\n\nexport interface ChatRequest {\n /** Concrete model id, `provider/model`, or a DaveCode route such as `davecode/auto`. */\n model: string;\n messages: ChatMessage[];\n stream?: boolean;\n temperature?: number;\n top_p?: number;\n max_tokens?: number;\n stop?: string | string[];\n tools?: ToolDefinition[];\n tool_choice?: 'auto' | 'none' | 'required' | { type: 'function'; function: { name: string } };\n user?: string;\n}\n\nexport type FinishReason = 'stop' | 'length' | 'tool_calls' | 'content_filter' | null;\n\nexport interface Usage {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n}\n\nexport interface ChatCompletion {\n id: string;\n object: 'chat.completion';\n created: number;\n model: string;\n choices: Array<{\n index: number;\n message: ChatMessage;\n finish_reason: FinishReason;\n }>;\n usage: Usage;\n}\n\nexport interface ChatCompletionChunk {\n id: string;\n object: 'chat.completion.chunk';\n created: number;\n model: string;\n choices: Array<{\n index: number;\n delta: Partial<ChatMessage>;\n finish_reason: FinishReason;\n }>;\n usage?: Usage;\n}\n\nexport interface ModelInfo {\n id: string;\n object: 'model';\n created: number;\n owned_by: string;\n}\n\n// ---------------------------------------------------------------------------\n// Providers & accounts\n// ---------------------------------------------------------------------------\n\nexport type ProviderKind =\n /** Anthropic Messages API with an API key. */\n | 'anthropic'\n /** OpenAI API with an API key. */\n | 'openai'\n /** Google Gemini API (AI Studio / Vertex) with an API key. */\n | 'gemini'\n /** Any OpenAI-compatible endpoint: OpenRouter, vLLM, LiteLLM… */\n | 'openai-compatible'\n /** Local Claude Code CLI, isolated per account via CLAUDE_CONFIG_DIR. */\n | 'claude-cli'\n /** Local Codex CLI, isolated per account via CODEX_HOME. */\n | 'codex-cli'\n /** Local Gemini CLI (\"Login with Google\"), isolated per account via GEMINI_CLI_HOME. */\n | 'gemini-cli'\n /** Local Google Antigravity CLI (`agy`); its sign-in lives in the OS keyring, shared. */\n | 'antigravity-cli'\n /** EXPERIMENTAL, opt-in: Gemini web session driven through a Chromium profile. */\n | 'gemini-web';\n\n/**\n * Providers that automate consumer web sessions. They may violate the upstream\n * provider's Terms of Service and are disabled unless `experimental.geminiWeb` is on.\n */\nexport const EXPERIMENTAL_PROVIDER_KINDS: readonly ProviderKind[] = ['gemini-web'];\n\n/**\n * Subscription-backed providers (one human login per account). Rotating several of\n * these to get around per-account limits requires `experimental.multiAccountRotation`.\n */\nexport const SUBSCRIPTION_PROVIDER_KINDS: readonly ProviderKind[] = [\n 'claude-cli',\n 'codex-cli',\n 'gemini-cli',\n 'antigravity-cli',\n 'gemini-web',\n];\n\nexport interface QuotaLimits {\n /** Tokens per minute (60 s sliding window). */\n tpm?: number;\n /** Requests per minute (60 s sliding window). */\n rpm?: number;\n /** Tokens per rolling 5 hours (Claude Pro/Team style windows). */\n tokens5h?: number;\n /** Requests per rolling 5 hours. */\n requests5h?: number;\n /** Tokens per rolling 24 hours. */\n tokensDaily?: number;\n /** Requests per rolling 24 hours. */\n requestsDaily?: number;\n}\n\nexport type AccountStatus = 'active' | 'cooldown' | 'disabled' | 'error';\n\nexport interface SubscriptionPrice {\n /** Amount per period in `currency`, e.g. 20. */\n amount: number;\n /** ISO 4217 code, e.g. \"USD\". */\n currency: string;\n period: 'month' | 'year';\n}\n\n/**\n * What the user pays for an account, entered by hand (DaveCode never reads billing pages).\n * Dates are `YYYY-MM-DD` or full ISO timestamps.\n */\nexport interface SubscriptionInfo {\n /** Plan name as the vendor calls it, e.g. \"Claude Pro\", \"ChatGPT Plus\", \"API pay-as-you-go\". */\n plan?: string;\n /** Last payment date. */\n paidAt?: string;\n /** Next renewal (or quota reset) date. */\n renewsAt?: string;\n price?: SubscriptionPrice;\n notes?: string;\n}\n\nexport interface Account {\n id: string;\n provider: ProviderKind;\n /** Human-friendly name, e.g. \"Claude Pro — work\". */\n label: string;\n enabled: boolean;\n /** Lower number = tried first. */\n priority: number;\n /** Relative share of traffic among accounts with equal priority. */\n weight: number;\n limits: QuotaLimits;\n /** Plan, payment and renewal details; omitted when none were entered. */\n subscription?: SubscriptionInfo;\n /**\n * Non-secret provider settings (baseUrl, model allow-list, CLI binary path…).\n * Secrets (API keys, cookies, OAuth tokens) live encrypted in the keyring, never here.\n */\n config: Record<string, unknown>;\n status: AccountStatus;\n /** ISO timestamp until which the account is cooling down after a 429/503. */\n cooldownUntil?: string;\n lastError?: string;\n /** Whether the keyring holds a secret for this account. The secret itself is never exposed. */\n hasSecret?: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ProviderCallContext {\n account: Account;\n /** Decrypted secret for this account (API key, session token…), if any. */\n secret?: string;\n /** Isolated per-account directory (CLAUDE_CONFIG_DIR, CODEX_HOME, Chromium userDataDir). */\n sandboxDir: string;\n signal?: AbortSignal;\n /** Called with rate-limit state the upstream reported (response headers), if any. */\n reportLimits?: (limits: ReportedLimitsInput) => void;\n}\n\nexport interface Provider {\n readonly kind: ProviderKind;\n listModels(ctx: ProviderCallContext): Promise<ModelInfo[]>;\n complete(req: ChatRequest, ctx: ProviderCallContext): Promise<ChatCompletion>;\n stream(req: ChatRequest, ctx: ProviderCallContext): AsyncIterable<ChatCompletionChunk>;\n}\n\n// ---------------------------------------------------------------------------\n// Routing\n// ---------------------------------------------------------------------------\n\nexport interface RouteTarget {\n provider: ProviderKind;\n model: string;\n /** Pin the target to one account; omit to let the balancer pick. */\n accountId?: string;\n}\n\nexport interface Route {\n /** Exposed to clients as `davecode/<name>`. */\n name: string;\n description?: string;\n /** Ordered by preference; the router fails over down the list. */\n targets: RouteTarget[];\n}\n\n// ---------------------------------------------------------------------------\n// Quotas & usage\n// ---------------------------------------------------------------------------\n\nexport type QuotaWindow = '1m' | '5h' | '24h';\n\nexport interface WindowUsage {\n window: QuotaWindow;\n tokens: number;\n requests: number;\n tokenLimit?: number;\n requestLimit?: number;\n /** max(tokens/tokenLimit, requests/requestLimit), 0 when unlimited. Range 0..1+. */\n utilization: number;\n}\n\nexport interface AccountUsage {\n accountId: string;\n windows: Record<QuotaWindow, WindowUsage>;\n}\n\n/** Rate-limit state as a provider reports it (headers, CLI limit messages). */\nexport interface ReportedLimitsInput {\n tokensRemaining?: number;\n tokensLimit?: number;\n requestsRemaining?: number;\n requestsLimit?: number;\n /** ISO timestamp when the reported window resets. */\n resetAt?: string;\n /** The provider refused the request because the quota is used up (until `resetAt`). */\n exhausted?: boolean;\n}\n\nexport interface ReportedLimits extends ReportedLimitsInput {\n source: 'headers' | 'error';\n /** ISO timestamp of the observation. */\n observedAt: string;\n}\n\n/** One account in `GET /api/budget`: subscription details plus remaining capacity. */\nexport interface AccountBudget {\n accountId: string;\n label: string;\n provider: ProviderKind;\n enabled: boolean;\n subscription?: SubscriptionInfo;\n /** Whole days until `subscription.renewsAt` (negative when overdue). */\n renewsInDays?: number;\n /**\n * Remaining fraction 0..1 of the tightest limit, combining DaveCode's own windows and the\n * provider-reported limits. `null` when no limit is known (unmetered).\n */\n remaining: number | null;\n /** Window behind `remaining` when it comes from DaveCode's own limits. */\n tightestWindow?: QuotaWindow;\n usage: AccountUsage;\n reported?: ReportedLimits;\n /** Whether the router would currently send traffic to the account. */\n available: boolean;\n /** Why not, when `available` is false (disabled, cooldown, exhausted…). */\n unavailableReason?: string;\n}\n\nexport interface BudgetSnapshot {\n /** ISO timestamp. */\n generatedAt: string;\n accounts: AccountBudget[];\n /** Compact plain-text summary injected into the orchestrator and agent prompts. */\n context: string;\n}\n\n/**\n * How an account proves who it is upstream: an API key in the keyring, the vendor CLI's own\n * login inside the account sandbox, or a browser profile (experimental `gemini-web`).\n */\nexport type ConnectionMethod = 'api-key' | 'cli-login' | 'browser';\n\nexport type ConnectionStatus = 'connected' | 'not_connected' | 'unknown';\n\n/** Result of checking an account's credentials without exposing them. */\nexport interface AccountConnection {\n accountId: string;\n provider: ProviderKind;\n method: ConnectionMethod;\n status: ConnectionStatus;\n /** Plain-language explanation or caveat. Never contains credentials or account emails. */\n detail?: string;\n /** Command that runs the vendor's official login for this account (`cli-login` only). */\n loginCommand?: string;\n /** ISO timestamp. */\n checkedAt: string;\n}\n\n/** Outcome of a \"Connect subscription\" request. */\nexport interface ConnectResult {\n connection: AccountConnection;\n /** True when the gateway opened a terminal running the official login on its own machine. */\n launched: boolean;\n /** What to run by hand when nothing was launched (or the window was closed). */\n command: string;\n message: string;\n}\n\n/** `cancelled`: the client aborted (disconnect, Esc in the TUI); never counts against the account. */\nexport type UsageStatus = 'success' | 'error' | 'rate_limited' | 'cancelled';\n\nexport interface UsageRecord {\n id: string;\n requestId: string;\n accountId: string;\n provider: ProviderKind;\n model: string;\n promptTokens: number;\n completionTokens: number;\n latencyMs: number;\n status: UsageStatus;\n errorKind?: ProviderErrorKind;\n /** Epoch milliseconds. */\n ts: number;\n}\n\n/** One bucket of `GET /api/usage/timeseries`. Tokens are prompt + completion. */\nexport interface UsageBucket {\n /** Bucket start, epoch milliseconds. */\n ts: number;\n tokens: number;\n requests: number;\n byAccount: Record<string, { tokens: number; requests: number }>;\n}\n\n// ---------------------------------------------------------------------------\n// Dual-brain context & task graph\n// ---------------------------------------------------------------------------\n\nexport type TaskStatus = 'PENDING' | 'IN_PROGRESS' | 'SUCCESS' | 'FAILED';\n\nexport interface TaskNode {\n id: string;\n title: string;\n description?: string;\n status: TaskStatus;\n /** Ids of tasks that must be SUCCESS before this one is unblocked. */\n dependsOn: string[];\n /** Higher runs first among unblocked tasks. */\n priority?: number;\n /** Human-readable acceptance criteria checked by the validator/judge. */\n acceptance?: string[];\n attempts?: number;\n branch?: string;\n notes?: string;\n createdAt?: string;\n updatedAt?: string;\n}\n\nexport interface TaskGraph {\n version: 1;\n tasks: TaskNode[];\n}\n\n// ---------------------------------------------------------------------------\n// Autonomous runner\n// ---------------------------------------------------------------------------\n\nexport type RunnerState =\n | 'idle'\n | 'selecting'\n | 'preparing'\n | 'implementing'\n | 'validating'\n | 'repairing'\n | 'merging'\n | 'paused'\n | 'stopped'\n | 'error';\n\nexport interface RunnerStatus {\n state: RunnerState;\n taskId?: string;\n repairCycle?: number;\n startedAt?: string;\n lastError?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Goal mode (a team of role-based agents working toward one objective)\n// ---------------------------------------------------------------------------\n\n/**\n * `code` tasks are handed to the autonomous runner (branch, quality gates, merge).\n * `artifact` tasks produce a markdown document under `.davecode/goals/<goal-id>/`.\n */\nexport type GoalTaskKind = 'code' | 'artifact';\n\nexport interface GoalRole {\n /** Lowercase id the planner assigns tasks to, e.g. `researcher`. */\n id: string;\n description: string;\n /** Route or model id this role talks to (default: `goal.route`). */\n route?: string;\n}\n\nexport interface GoalTask {\n /** Unique within the goal (task-graph id syntax). */\n id: string;\n title: string;\n description?: string;\n role: string;\n kind: GoalTaskKind;\n status: TaskStatus;\n dependsOn: string[];\n acceptance?: string[];\n /** Planning round that created the task (1-based). */\n round: number;\n attempts: number;\n /** Workspace-relative path of the markdown artifact, once written. */\n artifact?: string;\n /** Project task-graph id the runner worked on (`code` tasks). */\n runnerTaskId?: string;\n /** Result summary or failure reason. */\n notes?: string;\n}\n\nexport type GoalStatus =\n | 'planning'\n | 'running'\n | 'reviewing'\n /** Dry run: the plan was made and nothing was executed. */\n | 'planned'\n | 'succeeded'\n | 'failed'\n | 'cancelled'\n /** A token cap was reached or no account had capacity left. */\n | 'budget_exhausted';\n\nexport interface GoalLimits {\n /** Plan → execute → review rounds. */\n maxRounds: number;\n /** Tasks across all rounds. */\n maxTasks: number;\n /** Prompt + completion tokens across every agent and runner pass. */\n maxTokens: number;\n tokensUsed: number;\n}\n\nexport interface Goal {\n id: string;\n objective: string;\n status: GoalStatus;\n /** Current round (1-based). */\n round: number;\n limits: GoalLimits;\n roles: GoalRole[];\n tasks: GoalTask[];\n /** Task being executed right now. */\n activeTaskId?: string;\n /** Reviewer's (or planner's, for dry runs) latest summary. */\n summary?: string;\n lastError?: string;\n dryRun?: boolean;\n createdAt: string;\n updatedAt: string;\n finishedAt?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Errors (kinds are mirrored by ProviderError in errors.ts)\n// ---------------------------------------------------------------------------\n\nexport type ProviderErrorKind =\n | 'rate_limit'\n | 'quota_exhausted'\n | 'unavailable'\n | 'context_length'\n | 'auth'\n | 'bad_request'\n | 'timeout'\n | 'network'\n | 'unknown';\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/** DaveCode app identity; separate from model-provider credentials. */\nexport type LoginProvider = 'google' | 'github';\n\nexport interface LoginUser {\n /** Provider-scoped stable subject, never an email address. */\n id: string;\n provider: LoginProvider;\n name: string;\n}\n\nexport interface LoginStatus {\n required: boolean;\n providers: LoginProvider[];\n user: LoginUser | null;\n}\n","export const VERSION = '0.7.0';\n","import type { Account, AccountUsage, QuotaLimits, QuotaWindow, WindowUsage } from '../types';\n\nexport type Clock = () => number;\n\nexport const QUOTA_WINDOWS: readonly QuotaWindow[] = ['1m', '5h', '24h'];\n\n/** Sliding window sizes in milliseconds. */\nexport const WINDOW_MS: Readonly<Record<QuotaWindow, number>> = {\n '1m': 60_000,\n '5h': 5 * 60 * 60_000,\n '24h': 24 * 60 * 60_000,\n};\n\n/** Events within the same slot are coalesced; bounds memory at 86 400 slots per account. */\nconst SLOT_MS = 1000;\nconst WINDOW_COUNT = QUOTA_WINDOWS.length;\n\n/** Token/request limits that apply to a window. Non-positive values mean \"unlimited\". */\nexport function limitsFor(\n window: QuotaWindow,\n limits: QuotaLimits,\n): { tokenLimit?: number; requestLimit?: number } {\n const pick = (v: number | undefined) => (v !== undefined && v > 0 ? v : undefined);\n const out: { tokenLimit?: number; requestLimit?: number } = {};\n let tokens: number | undefined;\n let requests: number | undefined;\n if (window === '1m') {\n tokens = pick(limits.tpm);\n requests = pick(limits.rpm);\n } else if (window === '5h') {\n tokens = pick(limits.tokens5h);\n requests = pick(limits.requests5h);\n } else {\n tokens = pick(limits.tokensDaily);\n requests = pick(limits.requestsDaily);\n }\n if (tokens !== undefined) out.tokenLimit = tokens;\n if (requests !== undefined) out.requestLimit = requests;\n return out;\n}\n\n/**\n * One account's activity: a time-ordered queue of 1 s slots shared by all windows, with a\n * head pointer and running sums per window. Each slot is appended once and evicted once\n * per window, so every operation is amortized O(1).\n */\nclass AccountSeries {\n private slotTs: number[] = [];\n private slotTokens: number[] = [];\n private slotRequests: number[] = [];\n /** Index of the oldest slot still inside each window. */\n private readonly heads = new Array<number>(WINDOW_COUNT).fill(0);\n private readonly tokenSums = new Array<number>(WINDOW_COUNT).fill(0);\n private readonly requestSums = new Array<number>(WINDOW_COUNT).fill(0);\n\n add(ts: number, tokens: number, requests: number): void {\n const last = this.slotTs.length - 1;\n let slot = Math.floor(ts / SLOT_MS) * SLOT_MS;\n // Keep the queue ordered: late (out-of-order) events are folded into the newest slot.\n if (last >= 0 && slot < this.slotTs[last]!) slot = this.slotTs[last]!;\n if (last >= 0 && this.slotTs[last] === slot) {\n this.slotTokens[last]! += tokens;\n this.slotRequests[last]! += requests;\n for (let w = 0; w < WINDOW_COUNT; w++) {\n if (this.heads[w]! <= last) {\n this.tokenSums[w]! += tokens;\n this.requestSums[w]! += requests;\n }\n }\n return;\n }\n this.slotTs.push(slot);\n this.slotTokens.push(tokens);\n this.slotRequests.push(requests);\n for (let w = 0; w < WINDOW_COUNT; w++) {\n this.tokenSums[w]! += tokens;\n this.requestSums[w]! += requests;\n }\n }\n\n /** Evict slots that fell out of each window as of `now`. */\n advance(now: number): void {\n const length = this.slotTs.length;\n for (let w = 0; w < WINDOW_COUNT; w++) {\n const cutoff = now - WINDOW_MS[QUOTA_WINDOWS[w]!];\n let head = this.heads[w]!;\n while (head < length && this.slotTs[head]! <= cutoff) {\n this.tokenSums[w]! -= this.slotTokens[head]!;\n this.requestSums[w]! -= this.slotRequests[head]!;\n head++;\n }\n this.heads[w] = head;\n }\n this.compact();\n }\n\n /**\n * Drop slots that left every window, either when nothing is left or once they make up\n * at least half of a non-trivial queue (amortized O(1)).\n */\n private compact(): void {\n const drop = Math.min(...this.heads);\n const length = this.slotTs.length;\n if (drop === 0) return;\n if (drop < length && (drop < 1024 || drop * 2 < length)) return;\n this.slotTs = this.slotTs.slice(drop);\n this.slotTokens = this.slotTokens.slice(drop);\n this.slotRequests = this.slotRequests.slice(drop);\n for (let w = 0; w < WINDOW_COUNT; w++) this.heads[w]! -= drop;\n }\n\n totals(windowIndex: number): { tokens: number; requests: number } {\n return { tokens: this.tokenSums[windowIndex]!, requests: this.requestSums[windowIndex]! };\n }\n\n get empty(): boolean {\n return this.heads.every((h) => h >= this.slotTs.length);\n }\n\n /** Number of stored slots, including evicted ones awaiting compaction. */\n get size(): number {\n return this.slotTs.length;\n }\n}\n\nexport interface QuotaEngineOptions {\n clock?: Clock;\n}\n\nexport interface RecordOptions {\n /** Event time (epoch ms); defaults to the engine clock. */\n ts?: number;\n /** Requests to count (default 1). */\n requests?: number;\n}\n\ntype QuotaAccount = Pick<Account, 'id' | 'limits'>;\n\n/**\n * In-memory sliding-window accounting (1 m, 5 h, 24 h) of tokens and requests per account.\n * Persistence and hydration live in {@link UsageTracker}.\n */\nexport class QuotaEngine {\n private readonly series = new Map<string, AccountSeries>();\n readonly clock: Clock;\n\n constructor(options: QuotaEngineOptions = {}) {\n this.clock = options.clock ?? Date.now;\n }\n\n record(accountId: string, tokens: number, options: RecordOptions = {}): void {\n let series = this.series.get(accountId);\n if (!series) {\n series = new AccountSeries();\n this.series.set(accountId, series);\n }\n series.add(options.ts ?? this.clock(), Math.max(0, tokens), Math.max(0, options.requests ?? 1));\n series.advance(this.clock());\n }\n\n private totals(accountId: string): Array<{ tokens: number; requests: number }> {\n const series = this.series.get(accountId);\n if (!series) return QUOTA_WINDOWS.map(() => ({ tokens: 0, requests: 0 }));\n series.advance(this.clock());\n const totals = QUOTA_WINDOWS.map((_, i) => series.totals(i));\n if (series.empty) this.series.delete(accountId);\n return totals;\n }\n\n usage(account: QuotaAccount): AccountUsage {\n const totals = this.totals(account.id);\n const windows = {} as Record<QuotaWindow, WindowUsage>;\n QUOTA_WINDOWS.forEach((window, i) => {\n const { tokens, requests } = totals[i]!;\n const limits = limitsFor(window, account.limits);\n const usage: WindowUsage = { window, tokens, requests, utilization: 0, ...limits };\n usage.utilization = Math.max(\n limits.tokenLimit ? tokens / limits.tokenLimit : 0,\n limits.requestLimit ? requests / limits.requestLimit : 0,\n );\n windows[window] = usage;\n });\n return { accountId: account.id, windows };\n }\n\n /** Highest utilization across all windows (0 when unlimited). */\n maxUtilization(account: QuotaAccount): number {\n const { windows } = this.usage(account);\n return Math.max(...QUOTA_WINDOWS.map((w) => windows[w].utilization));\n }\n\n /** True when one more request of `estimatedTokens` would overflow any window's limit. */\n wouldExceed(account: QuotaAccount, estimatedTokens: number): boolean {\n const totals = this.totals(account.id);\n return QUOTA_WINDOWS.some((window, i) => {\n const { tokens, requests } = totals[i]!;\n const { tokenLimit, requestLimit } = limitsFor(window, account.limits);\n if (tokenLimit !== undefined && tokens + estimatedTokens > tokenLimit) return true;\n if (requestLimit !== undefined && requests + 1 > requestLimit) return true;\n return false;\n });\n }\n\n /** Remaining capacity in the tightest window, 0..1 (1 when unlimited or idle). */\n headroom(account: QuotaAccount): number {\n return Math.min(1, Math.max(0, 1 - this.maxUtilization(account)));\n }\n\n /** Drop all in-memory state for an account (e.g. after deletion). */\n forget(accountId: string): void {\n this.series.delete(accountId);\n }\n\n /** Accounts currently tracked (for tests and diagnostics). */\n trackedAccounts(): string[] {\n return [...this.series.keys()];\n }\n\n /** Stored 1 s slots for an account (for tests and diagnostics). */\n slotCount(accountId: string): number {\n return this.series.get(accountId)?.size ?? 0;\n }\n}\n","import type { ReportedLimitsStore } from '../rate-limiter/reported';\nimport { reportedFraction } from '../rate-limiter/reported';\nimport { type Clock, QUOTA_WINDOWS, type QuotaEngine } from '../rate-limiter/window';\nimport type { Router, SkipReason } from '../router/router';\nimport type { AccountRepository } from '../storage/accounts';\nimport type {\n Account,\n AccountBudget,\n BudgetSnapshot,\n QuotaWindow,\n ReportedLimits,\n SubscriptionInfo,\n} from '../types';\n\nconst DAY_MS = 86_400_000;\n/** Accounts listed in the prompt context; the rest are summarised in one line. */\nconst CONTEXT_ACCOUNTS = 12;\n\nexport interface BudgetServiceOptions {\n accounts: Pick<AccountRepository, 'list'>;\n quota: QuotaEngine;\n reported: ReportedLimitsStore;\n router: Pick<Router, 'unavailableReason'>;\n clock?: Clock;\n}\n\nfunction isoTime(iso: string): string {\n return `${iso.slice(0, 16).replace('T', ' ')} UTC`;\n}\n\nfunction describeReason(\n reason: SkipReason,\n account: Account,\n reported: ReportedLimits | undefined,\n): string {\n switch (reason) {\n case 'disabled':\n return 'disabled';\n case 'error':\n return 'credentials rejected (fix the account)';\n case 'experimental':\n return 'experimental provider is off';\n case 'no_provider':\n return 'no adapter for this provider';\n case 'no_tools':\n return 'provider does not support tool calls';\n case 'subscription':\n return 'not the primary subscription account (rotation is off)';\n case 'cooldown':\n return account.cooldownUntil\n ? `cooling down until ${isoTime(account.cooldownUntil)}`\n : 'cooling down';\n case 'circuit_open':\n return 'paused after repeated failures';\n case 'quota':\n return reported && reportedFraction(reported) === 0\n ? `provider quota exhausted${reported.resetAt ? ` until ${isoTime(reported.resetAt)}` : ''}`\n : 'local quota limit reached';\n }\n}\n\nfunction priceText(subscription: SubscriptionInfo): string | undefined {\n const { price } = subscription;\n return price ? `${price.amount} ${price.currency}/${price.period}` : undefined;\n}\n\n/**\n * Per-account budget: subscription details, remaining capacity (own quota windows and\n * provider-reported limits) and availability, plus a compact text for agent prompts.\n */\nexport class BudgetService {\n private readonly clock: Clock;\n\n constructor(private readonly options: BudgetServiceOptions) {\n this.clock = options.clock ?? options.quota.clock;\n }\n\n accountBudget(account: Account, all?: readonly Account[]): AccountBudget {\n const usage = this.options.quota.usage(account);\n let own: number | undefined;\n let tightestWindow: QuotaWindow | undefined;\n for (const window of QUOTA_WINDOWS) {\n const w = usage.windows[window];\n if (w.tokenLimit === undefined && w.requestLimit === undefined) continue;\n const left = Math.max(0, 1 - w.utilization);\n if (own === undefined || left < own) {\n own = left;\n tightestWindow = window;\n }\n }\n const reported = this.options.reported.get(account.id);\n const fromProvider = reported ? reportedFraction(reported) : undefined;\n const parts = [own, fromProvider].filter((x): x is number => x !== undefined);\n const remaining = parts.length > 0 ? Math.min(...parts) : null;\n\n const reason = this.options.router.unavailableReason(account, all);\n const budget: AccountBudget = {\n accountId: account.id,\n label: account.label,\n provider: account.provider,\n enabled: account.enabled,\n remaining,\n usage,\n available: reason === undefined,\n };\n if (tightestWindow && own !== undefined && own === remaining) {\n budget.tightestWindow = tightestWindow;\n }\n if (account.subscription) {\n budget.subscription = account.subscription;\n const renews = account.subscription.renewsAt\n ? Date.parse(account.subscription.renewsAt)\n : Number.NaN;\n if (!Number.isNaN(renews)) budget.renewsInDays = Math.ceil((renews - this.clock()) / DAY_MS);\n }\n if (reported) budget.reported = reported;\n if (reason) budget.unavailableReason = describeReason(reason, account, reported);\n return budget;\n }\n\n snapshot(): BudgetSnapshot {\n const all = this.options.accounts.list();\n const accounts = all.map((account) => this.accountBudget(account, all));\n return {\n generatedAt: new Date(this.clock()).toISOString(),\n accounts,\n context: this.render(accounts),\n };\n }\n\n /** The compact text injected into the orchestrator and agent prompts. */\n context(): string {\n return this.snapshot().context;\n }\n\n private render(accounts: AccountBudget[]): string {\n const enabled = accounts.filter((a) => a.enabled);\n if (enabled.length === 0) return '';\n const available = enabled.filter((a) => a.available).length;\n const lines = [\n `ACCOUNT BUDGET (${isoTime(new Date(this.clock()).toISOString())}; ${available} of ${enabled.length} accounts available).`,\n 'The router already avoids exhausted accounts. When budget is scarce, keep prompts and outputs short and prefer fewer, larger steps.',\n ];\n for (const a of enabled.slice(0, CONTEXT_ACCOUNTS)) {\n const details: string[] = [];\n const plan = a.subscription?.plan;\n if (plan) details.push(plan);\n const price = a.subscription ? priceText(a.subscription) : undefined;\n if (price) details.push(price);\n if (a.renewsInDays !== undefined) {\n details.push(\n a.renewsInDays >= 0\n ? `renews in ${a.renewsInDays}d`\n : `renewal overdue ${-a.renewsInDays}d`,\n );\n }\n const head = `- ${a.label} [${a.provider}]${details.length ? ` (${details.join(', ')})` : ''}`;\n let state: string;\n if (!a.available) state = `unavailable: ${a.unavailableReason ?? 'unknown'}`;\n else if (a.remaining === null) state = 'no known limit';\n else {\n const pct = Math.round(a.remaining * 100);\n state = `${pct}% left${a.tightestWindow ? ` (${a.tightestWindow} window)` : ' (provider-reported)'}`;\n }\n lines.push(`${head}: ${state}`);\n }\n if (enabled.length > CONTEXT_ACCOUNTS) {\n lines.push(`- …and ${enabled.length - CONTEXT_ACCOUNTS} more accounts`);\n }\n return lines.join('\\n');\n }\n}\n","import { mkdirSync } from 'node:fs';\nimport { BudgetService } from './budget/service';\nimport { loadConfig } from './config/loader';\nimport type { DaveConfig, DaveConfigInput } from './config/schema';\nimport {\n projectOverridesRouting,\n type RoutingUpdate,\n type RoutingUpdateResult,\n writeGlobalRouting,\n} from './config/writer';\nimport { EventBus } from './events';\nimport { ChromiumProfileManager } from './identity/chromium';\nimport { ConnectionChecker, type StatusProbe } from './identity/connect';\nimport { Keyring } from './identity/keyring';\nimport { SandboxManager } from './identity/sandbox';\nimport { davecodeHome, type GlobalPaths, globalPaths } from './paths';\nimport { createProviders } from './providers/registry';\nimport { ReportedLimitsStore } from './rate-limiter/reported';\nimport { UsageTracker } from './rate-limiter/tracker';\nimport { type Clock, QuotaEngine } from './rate-limiter/window';\nimport { Router } from './router/router';\nimport { AccountRepository } from './storage/accounts';\nimport { AuditLog } from './storage/audit';\nimport { type Database, openDatabase } from './storage/database';\nimport { UsageRepository } from './storage/usage';\nimport type { Provider, ProviderKind } from './types';\n\nexport interface CreateEngineOptions {\n /** DaveCode home (default: `env.DAVECODE_HOME` or `~/.davecode`). */\n home?: string;\n /** Repository whose `.davecode/config.json` is layered over the global config. */\n projectRoot?: string;\n /** Environment for `DAVECODE_*` overrides and `DAVECODE_MASTER_KEY` (default `process.env`). */\n env?: NodeJS.ProcessEnv;\n /** Provider adapters by kind (default: every built-in adapter from `createProviders()`). */\n providers?: Map<ProviderKind, Provider>;\n /** Programmatic config overrides, applied after files and env vars. */\n config?: DaveConfigInput;\n /** SQLite path (default `<home>/state.db`); `':memory:'` for ephemeral engines. */\n databasePath?: string;\n /** Clock shared by quotas, cooldowns and timestamps (tests). */\n clock?: Clock;\n /** Runs vendor CLI status commands for connection checks (tests inject a fake). */\n statusProbe?: StatusProbe;\n}\n\n/** Fully wired DaveCode core, shared by the gateway, CLI and runner. */\nexport interface Engine {\n config: DaveConfig;\n home: string;\n paths: GlobalPaths;\n projectRoot?: string;\n /** Epoch ms when the engine was created. */\n startedAt: number;\n db: Database;\n events: EventBus;\n accounts: AccountRepository;\n usage: UsageRepository;\n audit: AuditLog;\n keyring: Keyring;\n sandboxes: SandboxManager;\n chromium: ChromiumProfileManager;\n quota: QuotaEngine;\n tracker: UsageTracker;\n /** Rate-limit state the providers reported (headers, limit errors), in memory. */\n reported: ReportedLimitsStore;\n router: Router;\n /** Subscription details + remaining capacity per account, and the agents' budget context. */\n budget: BudgetService;\n /** Whether each account's API key or vendor CLI login is in place. */\n connections: ConnectionChecker;\n providers: Map<ProviderKind, Provider>;\n /**\n * Replaces the route list (and optionally the default route): persists it to the **global**\n * `config.json` (other keys preserved, atomic write) and updates `config.routing` in place,\n * so the router, which reads `config.routing` on every request, uses it immediately.\n */\n updateRouting(\n update: RoutingUpdate,\n ): Promise<RoutingUpdateResult & { shadowedByProject: boolean }>;\n /** Close the database. Safe to call more than once. */\n close(): void;\n}\n\n/** Load config, open storage and wire identity, quotas and the router. */\nexport function createEngine(options: CreateEngineOptions = {}): Engine {\n const env = options.env ?? process.env;\n const home = options.home ?? davecodeHome(env);\n const clock = options.clock ?? Date.now;\n const config = loadConfig({\n home,\n env,\n ...(options.projectRoot ? { projectRoot: options.projectRoot } : {}),\n ...(options.config ? { overrides: options.config } : {}),\n });\n const paths = globalPaths(home);\n mkdirSync(home, { recursive: true });\n\n const db = openDatabase(options.databasePath ?? paths.database);\n try {\n const events = new EventBus();\n const accounts = new AccountRepository(db, clock);\n const usage = new UsageRepository(db);\n const audit = new AuditLog(db, clock);\n const keyring = new Keyring(db, { keyPath: paths.masterKey, env, now: clock });\n const sandboxes = new SandboxManager(paths.sandboxes);\n const chromium = new ChromiumProfileManager({\n root: paths.profiles,\n experimentalEnabled: config.experimental.geminiWeb,\n });\n const quota = new QuotaEngine({ clock });\n const tracker = new UsageTracker({\n usage,\n quota,\n events,\n getAccount: (id) => accounts.get(id),\n });\n tracker.hydrate();\n const reported = new ReportedLimitsStore({ clock });\n const providers = options.providers ?? createProviders();\n const router = new Router({\n config,\n accounts,\n providers,\n quota,\n tracker,\n events,\n sandboxes,\n chromium,\n keyring,\n clock,\n reported,\n });\n const budget = new BudgetService({ accounts, quota, reported, router, clock });\n const connections = new ConnectionChecker({\n sandboxes,\n clock,\n env,\n ...(options.statusProbe ? { probe: options.statusProbe } : {}),\n });\n\n let closed = false;\n const engine: Engine = {\n config,\n home,\n paths,\n startedAt: clock(),\n db,\n events,\n accounts,\n usage,\n audit,\n keyring,\n sandboxes,\n chromium,\n quota,\n tracker,\n reported,\n router,\n budget,\n connections,\n providers,\n async updateRouting(update) {\n const result = await writeGlobalRouting(home, update);\n config.routing.routes = result.routes;\n if (update.defaultRoute !== undefined) config.routing.defaultRoute = update.defaultRoute;\n const shadowedByProject = options.projectRoot\n ? await projectOverridesRouting(options.projectRoot)\n : false;\n return { ...result, shadowedByProject };\n },\n close() {\n if (closed) return;\n closed = true;\n db.close();\n },\n };\n if (options.projectRoot) engine.projectRoot = options.projectRoot;\n return engine;\n } catch (err) {\n db.close();\n throw err;\n }\n}\n","import { mkdirSync, rmSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { globalPaths } from '../paths';\nimport { accountDir } from './sandbox';\n\n/** Minimal view of a Playwright persistent `BrowserContext` (playwright-core is optional). */\nexport interface ChromiumContext {\n close(): Promise<void>;\n newPage(): Promise<unknown>;\n pages(): unknown[];\n}\n\nexport interface ChromiumLaunchOptions {\n /** Run without a visible window (default true). Use false for the interactive first login. */\n headless?: boolean;\n /** Extra Chromium command-line switches. */\n args?: string[];\n}\n\nexport interface ChromiumProfileManagerOptions {\n /** Directory holding one `userDataDir` per account (default `globalPaths().profiles`). */\n root?: string;\n /** Mirror of `config.experimental.geminiWeb`; launching is refused when false. */\n experimentalEnabled: boolean;\n /** Module loader for `playwright-core` (injectable for tests). */\n importPlaywright?: () => Promise<unknown>;\n}\n\n/** Thrown when a browser feature is used while its experimental flag is off. */\nexport class ExperimentalDisabledError extends Error {\n readonly code = 'experimental_disabled';\n constructor(message: string) {\n super(message);\n this.name = 'ExperimentalDisabledError';\n }\n}\n\n/** Thrown when the optional `playwright-core` peer dependency is missing or unusable. */\nexport class ChromiumUnavailableError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'ChromiumUnavailableError';\n }\n}\n\ntype LaunchPersistentContext = (\n userDataDir: string,\n options: { headless: boolean; args?: string[] },\n) => Promise<ChromiumContext>;\n\nfunction extractLauncher(mod: unknown): LaunchPersistentContext | undefined {\n const candidates = [mod, (mod as { default?: unknown } | null)?.default];\n for (const candidate of candidates) {\n if (typeof candidate !== 'object' || candidate === null) continue;\n const chromium = (candidate as { chromium?: unknown }).chromium;\n if (typeof chromium !== 'object' || chromium === null) continue;\n const launch = (chromium as { launchPersistentContext?: unknown }).launchPersistentContext;\n if (typeof launch === 'function') {\n return launch.bind(chromium) as LaunchPersistentContext;\n }\n }\n return undefined;\n}\n\nconst PLAYWRIGHT_MODULE = 'playwright-core';\n\nconst defaultImport = (): Promise<unknown> => import(/* @vite-ignore */ PLAYWRIGHT_MODULE);\n\n/**\n * Isolated Chromium profiles (`~/.davecode/profiles/<accountId>`) for experimental\n * browser-backed providers. Each account gets its own `userDataDir`, so cookies and\n * sessions never mix.\n */\nexport class ChromiumProfileManager {\n readonly root: string;\n private readonly experimentalEnabled: boolean;\n private readonly importPlaywright: () => Promise<unknown>;\n\n constructor(options: ChromiumProfileManagerOptions) {\n this.root = resolve(options.root ?? globalPaths().profiles);\n this.experimentalEnabled = options.experimentalEnabled;\n this.importPlaywright = options.importPlaywright ?? defaultImport;\n }\n\n /** The account's `userDataDir` (not created). */\n profileDir(accountId: string): string {\n return accountDir(this.root, accountId);\n }\n\n /** Create the profile directory if needed and return it. */\n ensure(accountId: string): string {\n const dir = this.profileDir(accountId);\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n return dir;\n }\n\n /** Delete the profile (cookies, local storage, cache). */\n remove(accountId: string): void {\n rmSync(this.profileDir(accountId), { recursive: true, force: true });\n }\n\n /** Launch a persistent Chromium context bound to the account's profile. */\n async launch(accountId: string, options: ChromiumLaunchOptions = {}): Promise<ChromiumContext> {\n if (!this.experimentalEnabled) {\n throw new ExperimentalDisabledError(\n 'Browser-backed providers are experimental and disabled. Set experimental.geminiWeb to true to opt in (this may violate the provider’s Terms of Service).',\n );\n }\n const dir = this.ensure(accountId);\n\n let mod: unknown;\n try {\n mod = await this.importPlaywright();\n } catch (err) {\n throw new ChromiumUnavailableError(\n 'playwright-core is not installed. Install it with `pnpm add playwright-core` and download a browser with `npx playwright install chromium`.',\n { cause: err },\n );\n }\n const launch = extractLauncher(mod);\n if (!launch) {\n throw new ChromiumUnavailableError(\n 'playwright-core was found but does not expose chromium.launchPersistentContext',\n );\n }\n const launchOptions: { headless: boolean; args?: string[] } = {\n headless: options.headless ?? true,\n };\n if (options.args) launchOptions.args = options.args;\n return launch(dir, launchOptions);\n }\n}\n","import { spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { geminiCliEnv } from '../providers/gemini-cli';\nimport { isShellSafeArg, needsShell, resolveOnPath } from '../providers/shared/cli';\nimport type {\n Account,\n AccountConnection,\n ConnectionMethod,\n ConnectionStatus,\n ProviderKind,\n} from '../types';\nimport type { SandboxManager } from './sandbox';\n\n/** A vendor CLI's own login and status commands. DaveCode never sees the credentials. */\nexport interface CliLoginSpec {\n /** Default binary (overridable per account with `config.binaryPath`). */\n binary: string;\n /** Arguments that start the vendor's official sign-in flow. */\n loginArgs: string[];\n /** Arguments of a non-interactive status command, when the CLI has one. */\n statusArgs?: string[];\n installHint: string;\n /** What the user will see while logging in. */\n instructions: string;\n}\n\nexport const CLI_LOGINS: Partial<Record<ProviderKind, CliLoginSpec>> = {\n 'claude-cli': {\n binary: 'claude',\n loginArgs: ['auth', 'login'],\n statusArgs: ['auth', 'status', '--json'],\n installHint: 'Install Claude Code: npm install -g @anthropic-ai/claude-code',\n instructions: 'Claude Code opens Anthropic’s sign-in page and exits once you are logged in.',\n },\n 'codex-cli': {\n binary: 'codex',\n loginArgs: ['login'],\n statusArgs: ['login', 'status'],\n installHint: 'Install Codex: npm install -g @openai/codex',\n instructions: 'Codex opens the ChatGPT sign-in page and exits once you are logged in.',\n },\n 'antigravity-cli': {\n binary: 'agy',\n loginArgs: [],\n statusArgs: ['models'],\n installHint: 'Install Antigravity: https://antigravity.google/docs/cli/install',\n instructions:\n 'Antigravity opens Google sign-in the first time it starts. Once its prompt appears, type /quit.',\n },\n 'gemini-cli': {\n binary: 'gemini',\n loginArgs: [],\n installHint: 'Install Gemini CLI: npm install -g @google/gemini-cli',\n instructions:\n 'Gemini CLI starts “Login with Google” in your browser. Once its prompt appears, type /quit.',\n },\n};\n\nexport function connectionMethod(provider: ProviderKind): ConnectionMethod {\n if (CLI_LOGINS[provider]) return 'cli-login';\n if (provider === 'gemini-web') return 'browser';\n return 'api-key';\n}\n\n/** DaveCode command that runs the official login for `accountId` inside its sandbox. */\nexport function loginCommandFor(accountId: string): string {\n return `davecode accounts login ${accountId}`;\n}\n\n/** Environment that points the vendor CLI at the account's sandbox. */\nexport function loginEnv(\n account: Pick<Account, 'id' | 'provider'>,\n sandboxes: SandboxManager,\n): Record<string, string> {\n if (account.provider === 'gemini-cli') return geminiCliEnv(sandboxes.dirFor(account.id));\n return sandboxes.envFor(account);\n}\n\n/** The binary to run for an account: `config.binaryPath` or the vendor default. */\nexport function cliBinaryFor(account: Pick<Account, 'provider' | 'config'>): string | undefined {\n const configured = account.config.binaryPath;\n if (typeof configured === 'string' && configured.trim()) return configured.trim();\n return CLI_LOGINS[account.provider]?.binary;\n}\n\nexport interface ProbeCommand {\n command: string;\n args: string[];\n /** Complete environment of the child (also used to resolve `command` on PATH). */\n env: NodeJS.ProcessEnv;\n cwd: string;\n timeoutMs: number;\n}\n\nexport interface ProbeResult {\n /** `null` when the process could not be started or timed out. */\n code: number | null;\n stdout: string;\n /** Set when the binary was not found. */\n missing?: boolean;\n timedOut?: boolean;\n}\n\n/** Runs a status command. Injectable so tests never spawn real vendor CLIs. */\nexport type StatusProbe = (cmd: ProbeCommand) => Promise<ProbeResult>;\n\nconst MAX_OUTPUT = 64 * 1024;\n\nexport const spawnProbe: StatusProbe = (cmd) =>\n new Promise((resolve) => {\n const resolved = resolveOnPath(cmd.command, cmd.env);\n const shell = needsShell(resolved);\n if (shell && (cmd.args.some((a) => !isShellSafeArg(a)) || /[\"%!]/.test(resolved))) {\n resolve({ code: null, stdout: '' });\n return;\n }\n const options = {\n cwd: cmd.cwd,\n env: cmd.env,\n windowsHide: true,\n stdio: ['ignore', 'pipe', 'ignore'] as ['ignore', 'pipe', 'ignore'],\n };\n const child = shell\n ? spawn(`\"${resolved}\" ${cmd.args.join(' ')}`, { ...options, shell: true })\n : spawn(resolved, cmd.args, options);\n let stdout = '';\n let timedOut = false;\n child.stdout?.setEncoding('utf8');\n child.stdout?.on('data', (d: string) => {\n if (stdout.length < MAX_OUTPUT) stdout += d;\n });\n const timer = setTimeout(() => {\n timedOut = true;\n child.kill();\n }, cmd.timeoutMs);\n child.once('error', (err) => {\n clearTimeout(timer);\n resolve({\n code: null,\n stdout: '',\n missing: (err as NodeJS.ErrnoException).code === 'ENOENT',\n });\n });\n child.once('close', (code) => {\n clearTimeout(timer);\n resolve(timedOut ? { code: null, stdout: '', timedOut } : { code, stdout });\n });\n });\n\nexport interface ConnectionCheckerOptions {\n sandboxes: SandboxManager;\n probe?: StatusProbe;\n clock?: () => number;\n /** Per status command (default 20 s). */\n timeoutMs?: number;\n /** Defaults to `process.platform`; Claude Code keeps macOS logins in the keychain. */\n platform?: NodeJS.Platform;\n /** Base environment of status commands (default `process.env`). */\n env?: NodeJS.ProcessEnv;\n}\n\n/**\n * Reports whether an account can authenticate, without reading or returning credentials:\n * API-key accounts check the keyring flag, CLI accounts ask the vendor CLI's own status\n * command (Claude Code, Codex) or look for the credential file the CLI writes (Gemini CLI).\n */\nexport class ConnectionChecker {\n private readonly sandboxes: SandboxManager;\n private readonly probe: StatusProbe;\n private readonly clock: () => number;\n private readonly timeoutMs: number;\n private readonly platform: NodeJS.Platform;\n private readonly env: NodeJS.ProcessEnv;\n\n constructor(options: ConnectionCheckerOptions) {\n this.sandboxes = options.sandboxes;\n this.probe = options.probe ?? spawnProbe;\n this.clock = options.clock ?? Date.now;\n this.timeoutMs = options.timeoutMs ?? 20_000;\n this.platform = options.platform ?? process.platform;\n this.env = options.env ?? process.env;\n }\n\n async check(account: Account): Promise<AccountConnection> {\n const method = connectionMethod(account.provider);\n const base = {\n accountId: account.id,\n provider: account.provider,\n method,\n checkedAt: new Date(this.clock()).toISOString(),\n };\n const result = (status: ConnectionStatus, detail?: string): AccountConnection => ({\n ...base,\n status,\n ...(detail ? { detail } : {}),\n ...(method === 'cli-login' ? { loginCommand: loginCommandFor(account.id) } : {}),\n });\n\n if (method === 'api-key') {\n if (account.hasSecret) return result('connected', 'API key stored in the encrypted keyring.');\n if (account.provider === 'openai-compatible') {\n return result('connected', 'No key stored; fine for local servers that need none.');\n }\n return result('not_connected', 'No API key stored. Add one to connect this account.');\n }\n if (method === 'browser') {\n return result(\n 'unknown',\n 'Signed in through its own Chromium profile; checking would mean opening the browser.',\n );\n }\n\n const spec = CLI_LOGINS[account.provider];\n const binary = cliBinaryFor(account);\n if (!spec || !binary) return result('unknown');\n const dir = this.sandboxes.dirFor(account.id);\n\n if (account.provider === 'gemini-cli') {\n return existsSync(join(dir, '.gemini', 'oauth_creds.json'))\n ? result(\n 'connected',\n 'Gemini CLI has cached Google credentials in this account’s sandbox (not validated online).',\n )\n : result('not_connected', 'No Google login in this account’s sandbox yet.');\n }\n\n const statusArgs = spec.statusArgs ?? [];\n const prefix = Array.isArray(account.config.binaryArgs)\n ? account.config.binaryArgs.filter((a): a is string => typeof a === 'string')\n : [];\n const probed = await this.probe({\n command: binary,\n args: [...prefix, ...statusArgs],\n env: { ...this.env, ...loginEnv(account, this.sandboxes) },\n cwd: this.sandboxes.ensure(account.id),\n timeoutMs: this.timeoutMs,\n });\n if (probed.missing)\n return result('unknown', `\\`${binary}\\` was not found. ${spec.installHint}`);\n if (probed.timedOut || probed.code === null) {\n return result('unknown', `\\`${binary}\\` did not report its login status.`);\n }\n\n if (account.provider === 'claude-cli') {\n const loggedIn = claudeLoggedIn(probed.stdout);\n if (loggedIn === undefined) {\n return result('unknown', 'Could not read Claude Code’s login status.');\n }\n if (!loggedIn)\n return result('not_connected', 'Claude Code is not logged in for this account.');\n // Elsewhere the login is a file in the sandbox. Without it Claude Code is reporting a login\n // from outside (the global one or an environment token), which requests here do not use.\n const isolated = this.platform === 'darwin' || existsSync(join(dir, '.credentials.json'));\n return isolated\n ? result('connected', 'Claude Code reports a login for this account.')\n : result(\n 'not_connected',\n 'Claude Code is signed in globally, but not for this account: sign in once for DaveCode.',\n );\n }\n\n if (account.provider === 'antigravity-cli') {\n // `agy models` needs a signed-in Google account; it fails without one.\n return probed.code === 0\n ? result(\n 'connected',\n 'Antigravity is signed in. Its login is shared by every Antigravity account on this machine.',\n )\n : result('not_connected', 'Antigravity is not signed in on this machine.');\n }\n\n // Codex: `codex login status` exits 0 when logged in.\n return probed.code === 0\n ? result('connected', 'Codex reports a login for this account.')\n : result('not_connected', 'Codex is not logged in for this account.');\n }\n}\n\nfunction claudeLoggedIn(stdout: string): boolean | undefined {\n const start = stdout.indexOf('{');\n const end = stdout.lastIndexOf('}');\n if (start < 0 || end <= start) return undefined;\n try {\n const parsed = JSON.parse(stdout.slice(start, end + 1)) as { loggedIn?: unknown };\n return typeof parsed.loggedIn === 'boolean' ? parsed.loggedIn : undefined;\n } catch {\n return undefined;\n }\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';\nimport { chmodSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { globalPaths } from '../paths';\nimport type { Database } from '../storage/database';\n\nconst ALGORITHM = 'aes-256-gcm';\nconst KEY_BYTES = 32;\nconst IV_BYTES = 12;\n\nexport class KeyringError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'KeyringError';\n }\n}\n\nexport interface KeyringOptions {\n /** Path of the master key file (default `globalPaths().masterKey`). */\n keyPath?: string;\n /** Environment; `DAVECODE_MASTER_KEY` (base64, 32 bytes) overrides the key file. */\n env?: NodeJS.ProcessEnv;\n /** Explicit 32-byte key (tests). Takes precedence over env and file. */\n key?: Buffer;\n now?: () => number;\n}\n\n/**\n * Load the master key: `DAVECODE_MASTER_KEY` if set, else the key file, creating it with\n * mode 0600 when missing (chmod is a no-op on Windows).\n */\nexport function loadMasterKey(keyPath: string, env: NodeJS.ProcessEnv = process.env): Buffer {\n const fromEnv = env.DAVECODE_MASTER_KEY;\n if (fromEnv !== undefined && fromEnv !== '') {\n const key = Buffer.from(fromEnv, 'base64');\n if (key.length !== KEY_BYTES) {\n throw new KeyringError(`DAVECODE_MASTER_KEY must be ${KEY_BYTES} bytes encoded as base64`);\n }\n return key;\n }\n\n try {\n const key = readFileSync(keyPath);\n if (key.length !== KEY_BYTES) {\n throw new KeyringError(`Master key at ${keyPath} is corrupt (expected ${KEY_BYTES} bytes)`);\n }\n return key;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n\n mkdirSync(dirname(keyPath), { recursive: true });\n const key = randomBytes(KEY_BYTES);\n try {\n // 'wx' fails if another process created the key in the meantime.\n writeFileSync(keyPath, key, { mode: 0o600, flag: 'wx' });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'EEXIST') return loadMasterKey(keyPath, {});\n throw err;\n }\n try {\n chmodSync(keyPath, 0o600);\n } catch {\n // Best effort; not supported on every filesystem.\n }\n return key;\n}\n\ninterface SecretRow {\n ciphertext: Buffer;\n iv: Buffer;\n auth_tag: Buffer;\n}\n\n/**\n * Per-account secret storage encrypted with AES-256-GCM. Every encryption uses a fresh\n * random IV and binds the ciphertext to its account id (AAD), so rows cannot be swapped.\n */\nexport class Keyring {\n private readonly key: Buffer;\n private readonly now: () => number;\n\n constructor(\n private readonly db: Database,\n options: KeyringOptions = {},\n ) {\n if (options.key && options.key.length !== KEY_BYTES) {\n throw new KeyringError(`Keyring key must be ${KEY_BYTES} bytes`);\n }\n this.key =\n options.key ??\n loadMasterKey(options.keyPath ?? globalPaths().masterKey, options.env ?? process.env);\n this.now = options.now ?? Date.now;\n }\n\n set(accountId: string, secret: string): void {\n const iv = randomBytes(IV_BYTES);\n const cipher = createCipheriv(ALGORITHM, this.key, iv);\n cipher.setAAD(Buffer.from(accountId, 'utf8'));\n const ciphertext = Buffer.concat([cipher.update(secret, 'utf8'), cipher.final()]);\n const authTag = cipher.getAuthTag();\n this.db\n .prepare(\n `INSERT INTO secrets (account_id, ciphertext, iv, auth_tag, updated_at)\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(account_id) DO UPDATE SET\n ciphertext = excluded.ciphertext, iv = excluded.iv,\n auth_tag = excluded.auth_tag, updated_at = excluded.updated_at`,\n )\n .run(accountId, ciphertext, iv, authTag, new Date(this.now()).toISOString());\n }\n\n /** Decrypt the secret for an account. Throws {@link KeyringError} if it was tampered with. */\n get(accountId: string): string | undefined {\n const row = this.db\n .prepare('SELECT ciphertext, iv, auth_tag FROM secrets WHERE account_id = ?')\n .get(accountId) as SecretRow | undefined;\n if (!row) return undefined;\n try {\n const decipher = createDecipheriv(ALGORITHM, this.key, row.iv);\n decipher.setAAD(Buffer.from(accountId, 'utf8'));\n decipher.setAuthTag(row.auth_tag);\n return Buffer.concat([decipher.update(row.ciphertext), decipher.final()]).toString('utf8');\n } catch (err) {\n throw new KeyringError(`Secret for account ${accountId} failed integrity check`, {\n cause: err,\n });\n }\n }\n\n has(accountId: string): boolean {\n return (\n this.db.prepare('SELECT 1 FROM secrets WHERE account_id = ?').get(accountId) !== undefined\n );\n }\n\n /** Remove a secret. Returns false if none was stored. */\n delete(accountId: string): boolean {\n return this.db.prepare('DELETE FROM secrets WHERE account_id = ?').run(accountId).changes > 0;\n }\n}\n","import type { EventBus } from '../events';\nimport type { UsageRepository } from '../storage/usage';\nimport type { Account, AccountUsage, UsageRecord } from '../types';\nimport { type QuotaEngine, WINDOW_MS } from './window';\n\nexport interface UsageTrackerOptions {\n usage: UsageRepository;\n quota: QuotaEngine;\n events: EventBus;\n /** Look up an account's limits when emitting `quota.updated` (unknown → unlimited). */\n getAccount: (id: string) => Pick<Account, 'id' | 'limits'> | undefined;\n}\n\n/**\n * Bridges persistent usage (`token_usage`) and the in-memory {@link QuotaEngine}: hydrates\n * the engine on startup and writes every new record to both, emitting `quota.updated`.\n */\nexport class UsageTracker {\n constructor(private readonly options: UsageTrackerOptions) {}\n\n /** Replay the last 24 h of usage into the quota engine. Returns the number of records. */\n hydrate(): number {\n const { quota, usage } = this.options;\n const since = quota.clock() - WINDOW_MS['24h'];\n const records = usage.since(since);\n for (const record of records) {\n quota.record(record.accountId, record.promptTokens + record.completionTokens, {\n ts: record.ts,\n });\n }\n return records.length;\n }\n\n /** Persist a usage record, count it against the account's windows and broadcast it. */\n record(record: UsageRecord): AccountUsage {\n const { quota, usage, events, getAccount } = this.options;\n usage.insert(record);\n quota.record(record.accountId, record.promptTokens + record.completionTokens, {\n ts: record.ts,\n });\n const current = this.usageFor(\n getAccount(record.accountId) ?? { id: record.accountId, limits: {} },\n );\n events.emit({ type: 'quota.updated', usage: current });\n return current;\n }\n\n usageFor(account: Pick<Account, 'id' | 'limits'>): AccountUsage {\n return this.options.quota.usage(account);\n }\n}\n","import { createRequire } from 'node:module';\nimport type { ChatMessage, ContentPart } from '../types';\n\n/** Anything that can be counted: raw text, a message list, or a whole request. */\nexport type TokenInput = string | ChatMessage[] | { messages: ChatMessage[] };\n\ninterface Encoder {\n encode(\n text: string,\n allowedSpecial?: string[] | 'all',\n disallowedSpecial?: string[] | 'all',\n ): number[];\n}\n\n/** Per-message framing overhead used by OpenAI chat formats. */\nconst MESSAGE_OVERHEAD = 4;\n/** Every reply is primed with a few tokens. */\nconst REPLY_PRIMING = 3;\n/** Flat estimate for an image part (low-detail tile). */\nconst IMAGE_TOKENS = 85;\n/** Texts longer than this are sampled and extrapolated to keep estimation cheap. */\nconst MAX_EXACT_CHARS = 100_000;\n\nlet encoder: Encoder | null | undefined;\n\nfunction loadEncoder(): Encoder | null {\n if (encoder !== undefined) return encoder;\n try {\n const require = createRequire(import.meta.url);\n const lite: unknown = require('js-tiktoken/lite');\n const ranks: unknown = require('js-tiktoken/ranks/o200k_base');\n const Tiktoken = (lite as { Tiktoken?: unknown }).Tiktoken;\n if (typeof Tiktoken !== 'function') throw new Error('js-tiktoken/lite has no Tiktoken');\n const bpe = (ranks as { default?: unknown }).default ?? ranks;\n encoder = new (Tiktoken as new (ranks: unknown) => Encoder)(bpe);\n } catch {\n encoder = null;\n }\n return encoder;\n}\n\n/** Cheap fallback used when the tokenizer cannot be initialised: ~4 characters per token. */\nexport function approximateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/** Count tokens in plain text with `o200k_base` (lazily initialised), or chars/4 as fallback. */\nexport function countTextTokens(text: string): number {\n if (text.length === 0) return 0;\n const enc = loadEncoder();\n if (!enc) return approximateTokens(text);\n try {\n if (text.length <= MAX_EXACT_CHARS) return enc.encode(text, [], []).length;\n const sample = enc.encode(text.slice(0, MAX_EXACT_CHARS), [], []).length;\n return Math.ceil((sample / MAX_EXACT_CHARS) * text.length);\n } catch {\n return approximateTokens(text);\n }\n}\n\nfunction contentTokens(content: string | ContentPart[] | null): number {\n if (content === null) return 0;\n if (typeof content === 'string') return countTextTokens(content);\n let total = 0;\n for (const part of content) {\n total += part.type === 'text' ? countTextTokens(part.text) : IMAGE_TOKENS;\n }\n return total;\n}\n\n/**\n * Estimate the prompt tokens of a string, message list or request. Used for quota\n * pre-checks and as a fallback when an upstream response omits `usage`.\n */\nexport function estimateTokens(input: TokenInput): number {\n if (typeof input === 'string') return countTextTokens(input);\n const messages = Array.isArray(input) ? input : input.messages;\n let total = REPLY_PRIMING;\n for (const message of messages) {\n total += MESSAGE_OVERHEAD + contentTokens(message.content);\n if (message.name) total += countTextTokens(message.name);\n for (const call of message.tool_calls ?? []) {\n total += countTextTokens(call.function.name) + countTextTokens(call.function.arguments);\n }\n }\n return total;\n}\n\n/** For tests: reset or replace the lazily created encoder (`null` forces the fallback). */\nexport function __setEncoderForTests(value: Encoder | null | undefined): void {\n encoder = value;\n}\n","import { randomBytes } from 'node:crypto';\n\n/** Random, URL-safe identifier such as `acc_3f9c0a7b12d4e6f8`. */\nexport function newId(prefix: string, bytes = 8): string {\n return `${prefix}_${randomBytes(bytes).toString('hex')}`;\n}\n","import type { Account, ProviderKind, Route } from '../types';\n\nexport const PROVIDER_KINDS: readonly ProviderKind[] = [\n 'anthropic',\n 'openai',\n 'gemini',\n 'openai-compatible',\n 'claude-cli',\n 'codex-cli',\n 'gemini-cli',\n 'antigravity-cli',\n 'gemini-web',\n];\n\n/** Prefix that addresses a configured route, e.g. `davecode/auto`. */\nexport const ROUTE_PREFIX = 'davecode/';\n\n/** How the `model` field of a request was interpreted. */\nexport type ModelSpec =\n /** A configured route; `route === undefined` means the implicit default route. */\n | { kind: 'route'; name: string; route?: Route }\n | { kind: 'provider'; provider: ProviderKind; model: string }\n | { kind: 'model'; model: string };\n\n/** One (account, concrete model) pair the router may try. */\nexport interface Candidate {\n account: Account;\n provider: ProviderKind;\n /** Model id sent upstream. */\n model: string;\n /** Position of the route target that produced this candidate (0 outside routes). */\n targetIndex: number;\n}\n\nfunction isProviderKind(value: string): value is ProviderKind {\n return (PROVIDER_KINDS as readonly string[]).includes(value);\n}\n\n/**\n * Interpret a request's `model`:\n * `davecode/<route>` (unknown names fall back to the default route), `<provider>/<model>`,\n * or a bare model id (which may itself contain slashes, e.g. OpenRouter ids).\n */\nexport function parseModel(\n model: string,\n routes: readonly Route[],\n defaultRoute: string,\n): ModelSpec {\n if (model.startsWith(ROUTE_PREFIX)) {\n const name = model.slice(ROUTE_PREFIX.length);\n const route =\n routes.find((r) => r.name === name) ?? routes.find((r) => r.name === defaultRoute);\n return route\n ? { kind: 'route', name: route.name, route }\n : { kind: 'route', name: defaultRoute };\n }\n const slash = model.indexOf('/');\n if (slash > 0) {\n const prefix = model.slice(0, slash);\n const rest = model.slice(slash + 1);\n if (isProviderKind(prefix) && rest.length > 0) {\n return { kind: 'provider', provider: prefix, model: rest };\n }\n }\n return { kind: 'model', model };\n}\n\n/** The account's explicit model allow-list (`config.models`), if any. */\nexport function configuredModels(account: Account): string[] | undefined {\n const models = account.config.models;\n if (!Array.isArray(models)) return undefined;\n const ids = models.filter((m): m is string => typeof m === 'string' && m.length > 0);\n return ids.length > 0 ? ids : undefined;\n}\n\n/** Model used for the implicit default route: `config.defaultModel`, else the first listed. */\nexport function defaultModelFor(account: Account): string | undefined {\n const explicit = account.config.defaultModel;\n if (typeof explicit === 'string' && explicit.length > 0) return explicit;\n return configuredModels(account)?.[0];\n}\n\n/** Provider families a bare model id most likely belongs to (empty when unknown). */\nexport function inferProviders(model: string): ProviderKind[] {\n const id = model.toLowerCase();\n if (id.startsWith('claude')) return ['anthropic', 'claude-cli'];\n if (/^(gpt-|chatgpt|codex|o\\d)/.test(id)) return ['openai', 'codex-cli'];\n if (id.startsWith('gemini')) return ['gemini', 'gemini-cli', 'antigravity-cli', 'gemini-web'];\n return [];\n}\n\n/**\n * Whether an account can serve `model`. With an allow-list the model must be listed;\n * without one the account is assumed to serve any model of its provider. For bare model\n * ids (`provider` undefined) the provider family is inferred from the id, and unknown\n * families go to OpenAI-compatible accounts.\n */\nexport function accountServes(account: Account, model: string, provider?: ProviderKind): boolean {\n if (provider !== undefined && account.provider !== provider) return false;\n const listed = configuredModels(account);\n if (listed) return listed.includes(model);\n if (provider !== undefined) return true;\n const families = inferProviders(model);\n return families.length > 0\n ? families.includes(account.provider)\n : account.provider === 'openai-compatible';\n}\n\n/** Every (account, model) pair matching the spec, before any availability filtering. */\nexport function resolveCandidates(spec: ModelSpec, accounts: readonly Account[]): Candidate[] {\n if (spec.kind === 'provider' || spec.kind === 'model') {\n const provider = spec.kind === 'provider' ? spec.provider : undefined;\n return accounts\n .filter((a) => accountServes(a, spec.model, provider))\n .map((account) => ({\n account,\n provider: account.provider,\n model: spec.model,\n targetIndex: 0,\n }));\n }\n if (!spec.route) {\n // Implicit default route: every account that declares a default model.\n const out: Candidate[] = [];\n for (const account of accounts) {\n const model = defaultModelFor(account);\n if (model) out.push({ account, provider: account.provider, model, targetIndex: 0 });\n }\n return out;\n }\n const out: Candidate[] = [];\n spec.route.targets.forEach((target, targetIndex) => {\n for (const account of accounts) {\n if (target.accountId !== undefined && account.id !== target.accountId) continue;\n if (!accountServes(account, target.model, target.provider)) continue;\n out.push({ account, provider: account.provider, model: target.model, targetIndex });\n }\n });\n return out;\n}\n","import type { Clock } from '../rate-limiter/window';\n\nexport type CircuitState = 'closed' | 'open' | 'half_open';\n\nexport interface CircuitBreakerOptions {\n /** Consecutive failures that open the circuit (default 5). */\n failureThreshold?: number;\n /** How long the circuit stays open before a half-open probe is allowed (default 60 s). */\n resetMs?: number;\n clock?: Clock;\n}\n\ninterface Circuit {\n failures: number;\n openedAt?: number;\n probing: boolean;\n}\n\n/**\n * Per-account circuit breaker. After `failureThreshold` consecutive failures the account is\n * skipped for `resetMs`; then a single probe request is let through (half-open). A success\n * closes the circuit, a failure re-opens it.\n */\nexport class CircuitBreaker {\n private readonly circuits = new Map<string, Circuit>();\n private readonly failureThreshold: number;\n private readonly resetMs: number;\n private readonly clock: Clock;\n\n constructor(options: CircuitBreakerOptions = {}) {\n this.failureThreshold = Math.max(1, options.failureThreshold ?? 5);\n this.resetMs = Math.max(0, options.resetMs ?? 60_000);\n this.clock = options.clock ?? Date.now;\n }\n\n state(id: string): CircuitState {\n const circuit = this.circuits.get(id);\n if (!circuit || circuit.openedAt === undefined) return 'closed';\n return this.clock() - circuit.openedAt >= this.resetMs ? 'half_open' : 'open';\n }\n\n /** Whether a request may be sent to the account right now (does not change state). */\n allow(id: string): boolean {\n const state = this.state(id);\n if (state === 'closed') return true;\n if (state === 'open') return false;\n return !this.circuits.get(id)?.probing;\n }\n\n /** Mark the start of an attempt; claims the probe slot when half-open. */\n onAttempt(id: string): void {\n const circuit = this.circuits.get(id);\n if (circuit && this.state(id) === 'half_open') circuit.probing = true;\n }\n\n onSuccess(id: string): void {\n this.circuits.delete(id);\n }\n\n onFailure(id: string): void {\n const circuit = this.circuits.get(id) ?? { failures: 0, probing: false };\n const wasProbing = circuit.probing;\n circuit.failures += 1;\n circuit.probing = false;\n if (wasProbing || circuit.failures >= this.failureThreshold) circuit.openedAt = this.clock();\n this.circuits.set(id, circuit);\n }\n\n /** The caller cancelled the attempt: release a half-open probe without counting a failure. */\n onCancel(id: string): void {\n const circuit = this.circuits.get(id);\n if (circuit) circuit.probing = false;\n }\n\n /** Forget an account (e.g. after deletion or manual re-enable). */\n reset(id: string): void {\n this.circuits.delete(id);\n }\n}\n","import type { ProviderError } from '../errors';\n\nexport type RouterErrorCode =\n /** No account can serve the requested model or route. */\n | 'model_not_found'\n /** Matching accounts exist but are disabled, in error, or have no provider adapter. */\n | 'no_available_account'\n /** Every matching account is cooling down, saturated or circuit-broken. */\n | 'no_capacity'\n /** The only matching accounts belong to a disabled experimental provider. */\n | 'experimental_disabled'\n /** Every attempted account was rate limited upstream. */\n | 'rate_limited'\n /** Every attempted account failed upstream. */\n | 'upstream_failed';\n\nconst STATUS: Record<RouterErrorCode, number> = {\n model_not_found: 404,\n no_available_account: 503,\n no_capacity: 429,\n experimental_disabled: 400,\n rate_limited: 429,\n upstream_failed: 502,\n};\n\nexport interface RouterErrorOptions {\n requestId: string;\n failovers?: number;\n lastError?: ProviderError;\n}\n\n/** A routing failure that is not a single upstream error (see {@link RouterErrorCode}). */\nexport class RouterError extends Error {\n readonly code: RouterErrorCode;\n /** Suggested HTTP status for the gateway. */\n readonly status: number;\n readonly requestId: string;\n readonly failovers: number;\n readonly lastError?: ProviderError;\n\n constructor(code: RouterErrorCode, message: string, options: RouterErrorOptions) {\n super(message, { cause: options.lastError });\n this.name = 'RouterError';\n this.code = code;\n this.status = STATUS[code];\n this.requestId = options.requestId;\n this.failovers = options.failovers ?? 0;\n this.lastError = options.lastError;\n }\n}\n","import type { DaveConfig } from '../config/schema';\nimport { ProviderError } from '../errors';\nimport type { EventBus } from '../events';\nimport type { ChromiumProfileManager } from '../identity/chromium';\nimport { CLI_LOGINS, loginCommandFor } from '../identity/connect';\nimport { type Keyring, KeyringError } from '../identity/keyring';\nimport type { SandboxManager } from '../identity/sandbox';\nimport { type ReportedLimitsStore, reportedFraction } from '../rate-limiter/reported';\nimport { countTextTokens, estimateTokens } from '../rate-limiter/tokens';\nimport type { UsageTracker } from '../rate-limiter/tracker';\nimport type { Clock, QuotaEngine } from '../rate-limiter/window';\nimport type { AccountRepository } from '../storage/accounts';\nimport { newId } from '../storage/ids';\nimport {\n type Account,\n type ChatCompletion,\n type ChatCompletionChunk,\n type ChatMessage,\n type ChatRequest,\n EXPERIMENTAL_PROVIDER_KINDS,\n type ModelInfo,\n type Provider,\n type ProviderCallContext,\n type ProviderErrorKind,\n type ProviderKind,\n SUBSCRIPTION_PROVIDER_KINDS,\n type UsageStatus,\n} from '../types';\nimport { type Candidate, configuredModels, parseModel, resolveCandidates } from './candidates';\nimport { CircuitBreaker, type CircuitBreakerOptions } from './circuit-breaker';\nimport { RouterError } from './errors';\n\nexport interface RouterOptions {\n config: DaveConfig;\n accounts: AccountRepository;\n providers: Map<ProviderKind, Provider>;\n quota: QuotaEngine;\n tracker: UsageTracker;\n events: EventBus;\n sandboxes: SandboxManager;\n /** Profile manager for browser-backed providers (`gemini-web`). */\n chromium?: ChromiumProfileManager;\n /** Source of decrypted account secrets. */\n keyring?: Keyring;\n clock?: Clock;\n /** Uniform [0, 1) source used for weighted balancing (inject for deterministic tests). */\n random?: () => number;\n /** Provider-reported limits: exhausted accounts are skipped, the rest weighted by what is left. */\n reported?: ReportedLimitsStore;\n /** Defaults: 5 consecutive failures, reset after `routing.cooldownMs`. */\n breaker?: CircuitBreakerOptions;\n}\n\n/** Routing outcome, surfaced by the gateway as `x-davecode-*` headers. */\nexport interface RoutingMeta {\n requestId: string;\n accountId: string;\n provider: ProviderKind;\n /** Concrete model sent upstream. */\n model: string;\n /** Failover hops taken before the serving account. */\n failovers: number;\n}\n\nexport interface RouteRequestOptions {\n /** Correlation id; generated when omitted. */\n requestId?: string;\n signal?: AbortSignal;\n}\n\nexport interface CompletionResult {\n completion: ChatCompletion;\n meta: RoutingMeta;\n}\n\nexport interface StreamResult {\n meta: RoutingMeta;\n /** Upstream chunks. Errors after the first chunk are thrown from the iterator. */\n chunks: AsyncIterable<ChatCompletionChunk>;\n}\n\n/** Why an account was not eligible for a request. */\nexport type SkipReason =\n | 'disabled'\n | 'error'\n | 'experimental'\n | 'no_provider'\n | 'no_tools'\n | 'subscription'\n | 'cooldown'\n | 'circuit_open'\n | 'quota';\n\nexport interface RankedCandidate extends Candidate {\n /** weight × headroom × backpressure factor. */\n effectiveWeight: number;\n /** True when the 5 h utilization is above `routing.quotaShiftThreshold`. */\n shifted: boolean;\n}\n\nexport interface RoutingPlan {\n candidates: RankedCandidate[];\n skipped: Array<{ accountId: string; model: string; reason: SkipReason }>;\n}\n\n/** Error kinds that count against an account's circuit breaker. */\nconst BREAKER_KINDS: ReadonlySet<ProviderErrorKind> = new Set([\n 'rate_limit',\n 'quota_exhausted',\n 'unavailable',\n 'timeout',\n 'network',\n 'unknown',\n]);\n\nconst CAPACITY_REASONS: ReadonlySet<SkipReason> = new Set(['cooldown', 'circuit_open', 'quota']);\n\nconst NON_TOOL_PROVIDERS: ReadonlySet<ProviderKind> = new Set([\n ...SUBSCRIPTION_PROVIDER_KINDS,\n ...EXPERIMENTAL_PROVIDER_KINDS,\n]);\n\nfunction messageText(message: Partial<ChatMessage> | undefined): string {\n if (!message) return '';\n let text = '';\n const { content } = message;\n if (typeof content === 'string') text += content;\n else if (Array.isArray(content)) {\n for (const part of content) if (part.type === 'text') text += part.text;\n }\n for (const call of message.tool_calls ?? []) {\n text += call.function?.name ?? '';\n text += call.function?.arguments ?? '';\n }\n return text;\n}\n\n/**\n * A vendor CLI's own sign-in advice (\"Run /login\") names commands that mean something else in\n * DaveCode, so auth failures on CLI-login accounts say how to sign in again here instead.\n */\nfunction signInMessage(account: Account): string | undefined {\n if (!CLI_LOGINS[account.provider]) return undefined;\n return `${account.label} needs you to sign in again. Run: ${loginCommandFor(account.id)}`;\n}\n\nfunction withSignInHint(error: ProviderError, account: Account): ProviderError {\n const message = error.kind === 'auth' ? signInMessage(account) : undefined;\n if (!message) return error;\n return new ProviderError(message, {\n kind: 'auth',\n provider: error.provider,\n accountId: error.accountId,\n ...(error.status !== undefined ? { status: error.status } : {}),\n cause: error,\n });\n}\n\nfunction toProviderError(err: unknown, account: Account): ProviderError {\n if (err instanceof ProviderError) return withSignInHint(err, account);\n if (err instanceof KeyringError) {\n return new ProviderError(err.message, {\n kind: 'auth',\n provider: account.provider,\n accountId: account.id,\n cause: err,\n });\n }\n const message = err instanceof Error ? err.message : String(err);\n return new ProviderError(message, {\n kind: 'unknown',\n provider: account.provider,\n accountId: account.id,\n cause: err,\n });\n}\n\n/**\n * Quota-aware account selection with hot failover (see docs/ARCHITECTURE.md\n * \"Routing & quotas\"). Providers are injected; the router never talks to the network itself.\n */\nexport class Router {\n readonly breaker: CircuitBreaker;\n private readonly clock: Clock;\n private readonly random: () => number;\n\n constructor(private readonly options: RouterOptions) {\n this.clock = options.clock ?? options.quota.clock;\n this.random = options.random ?? Math.random;\n this.breaker = new CircuitBreaker({\n resetMs: options.config.routing.cooldownMs,\n clock: this.clock,\n ...options.breaker,\n });\n }\n\n private get config(): DaveConfig {\n return this.options.config;\n }\n\n /** The single account per subscription provider allowed when rotation is off. */\n private primarySubscriptionAccounts(accounts: readonly Account[]): Map<ProviderKind, string> {\n const primary = new Map<ProviderKind, Account>();\n for (const account of accounts) {\n if (!account.enabled || !SUBSCRIPTION_PROVIDER_KINDS.includes(account.provider)) continue;\n const best = primary.get(account.provider);\n if (\n !best ||\n account.priority < best.priority ||\n (account.priority === best.priority && account.createdAt < best.createdAt)\n ) {\n primary.set(account.provider, account);\n }\n }\n return new Map([...primary].map(([kind, account]) => [kind, account.id]));\n }\n\n private skipReason(\n account: Account,\n estimate: number,\n primaries: Map<ProviderKind, string>,\n now: number,\n needsTools = false,\n ): SkipReason | undefined {\n if (!account.enabled || account.status === 'disabled') return 'disabled';\n if (account.status === 'error') return 'error';\n if (\n EXPERIMENTAL_PROVIDER_KINDS.includes(account.provider) &&\n !this.config.experimental.geminiWeb\n ) {\n return 'experimental';\n }\n if (!this.options.providers.has(account.provider)) return 'no_provider';\n if (needsTools && NON_TOOL_PROVIDERS.has(account.provider)) return 'no_tools';\n if (\n SUBSCRIPTION_PROVIDER_KINDS.includes(account.provider) &&\n !this.config.experimental.multiAccountRotation &&\n primaries.get(account.provider) !== account.id\n ) {\n return 'subscription';\n }\n if (account.cooldownUntil && Date.parse(account.cooldownUntil) > now) return 'cooldown';\n if (!this.breaker.allow(account.id)) return 'circuit_open';\n if (this.options.quota.wouldExceed(account, estimate)) return 'quota';\n if (this.options.reported?.exhausted(account.id)) return 'quota';\n return undefined;\n }\n\n /** Why the router would not send a request to `account` right now; `undefined` if it would. */\n unavailableReason(account: Account, accounts?: readonly Account[]): SkipReason | undefined {\n const primaries = this.primarySubscriptionAccounts(accounts ?? this.options.accounts.list());\n return this.skipReason(account, 0, primaries, this.clock());\n }\n\n /** Resolve, filter and rank the accounts that could serve `req`, best first. */\n plan(\n req: Pick<ChatRequest, 'model' | 'messages'> &\n Partial<Pick<ChatRequest, 'tools' | 'tool_choice'>>,\n estimate = estimateTokens(req.messages),\n ): RoutingPlan {\n const { routing } = this.config;\n const accounts = this.options.accounts.list();\n const spec = parseModel(req.model, routing.routes, routing.defaultRoute);\n const all = resolveCandidates(spec, accounts);\n const primaries = this.primarySubscriptionAccounts(accounts);\n const now = this.clock();\n const needsTools = Boolean(req.tools && req.tools.length > 0 && req.tool_choice !== 'none');\n\n const skipped: RoutingPlan['skipped'] = [];\n const ranked: Array<RankedCandidate & { key: number }> = [];\n for (const candidate of all) {\n const reason = this.skipReason(candidate.account, estimate, primaries, now, needsTools);\n if (reason) {\n skipped.push({ accountId: candidate.account.id, model: candidate.model, reason });\n continue;\n }\n const { account } = candidate;\n const usage = this.options.quota.usage(account);\n const maxUtil = Math.max(\n usage.windows['1m'].utilization,\n usage.windows['5h'].utilization,\n usage.windows['24h'].utilization,\n );\n const reported = this.options.reported?.get(account.id);\n const reportedLeft = reported ? (reportedFraction(reported) ?? 1) : 1;\n const headroom = Math.min(1, Math.max(0, 1 - maxUtil), reportedLeft);\n const bp = routing.backpressureThreshold;\n const backpressure = maxUtil > bp ? (bp >= 1 ? 0 : Math.max(0, (1 - maxUtil) / (1 - bp))) : 1;\n const effectiveWeight = Math.max(0, account.weight) * headroom * backpressure;\n const shifted = usage.windows['5h'].utilization >= routing.quotaShiftThreshold;\n // Weighted random order (Efraimidis–Spirakis): larger weight → larger key on average.\n const key = effectiveWeight > 0 ? this.random() ** (1 / effectiveWeight) : 0;\n ranked.push({ ...candidate, effectiveWeight, shifted, key });\n }\n\n ranked.sort(\n (a, b) =>\n a.targetIndex - b.targetIndex ||\n Number(a.shifted) - Number(b.shifted) ||\n a.account.priority - b.account.priority ||\n b.key - a.key ||\n b.effectiveWeight - a.effectiveWeight ||\n a.account.createdAt.localeCompare(b.account.createdAt) ||\n a.account.id.localeCompare(b.account.id),\n );\n return { candidates: ranked.map(({ key: _key, ...rest }) => rest), skipped };\n }\n\n private noCandidateError(req: ChatRequest, plan: RoutingPlan, requestId: string): RouterError {\n if (plan.skipped.length === 0) {\n return new RouterError('model_not_found', `No account can serve model \"${req.model}\"`, {\n requestId,\n });\n }\n const reasons = new Set(plan.skipped.map((s) => s.reason));\n if ([...reasons].some((r) => CAPACITY_REASONS.has(r))) {\n return new RouterError(\n 'no_capacity',\n `Every account for \"${req.model}\" is saturated or cooling down`,\n { requestId },\n );\n }\n if (reasons.size === 1 && reasons.has('experimental')) {\n return new RouterError(\n 'experimental_disabled',\n `\"${req.model}\" is only served by experimental providers; enable experimental.geminiWeb to use them`,\n { requestId },\n );\n }\n if (reasons.size === 1 && reasons.has('error')) {\n // Every account failed before (usually a lost login): repeat what fixes it.\n const failed = this.options.accounts.get(plan.skipped[0]!.accountId);\n const message = failed && (signInMessage(failed) ?? failed.lastError);\n if (message) return new RouterError('no_available_account', message, { requestId });\n }\n return new RouterError(\n 'no_available_account',\n `No available account for \"${req.model}\" (${[...reasons].join(', ')})`,\n { requestId },\n );\n }\n\n private contextFor(account: Account, signal?: AbortSignal): ProviderCallContext {\n const { chromium, sandboxes, keyring } = this.options;\n const sandboxDir =\n account.provider === 'gemini-web' && chromium\n ? chromium.ensure(account.id)\n : sandboxes.ensure(account.id);\n const ctx: ProviderCallContext = { account, sandboxDir };\n const secret = keyring?.get(account.id);\n if (secret !== undefined) ctx.secret = secret;\n if (signal) ctx.signal = signal;\n const { reported } = this.options;\n if (reported) ctx.reportLimits = (limits) => reported.report(account.id, limits, 'headers');\n return ctx;\n }\n\n private emitAccount(account: Account | undefined): void {\n if (account) this.options.events.emit({ type: 'account.updated', account });\n }\n\n private recordUsage(\n candidate: Candidate,\n requestId: string,\n status: UsageStatus,\n promptTokens: number,\n completionTokens: number,\n latencyMs: number,\n errorKind?: ProviderErrorKind,\n ): void {\n const record = {\n id: newId('use'),\n requestId,\n accountId: candidate.account.id,\n provider: candidate.provider,\n model: candidate.model,\n promptTokens,\n completionTokens,\n latencyMs,\n status,\n ts: this.clock(),\n ...(errorKind ? { errorKind } : {}),\n };\n this.options.tracker.record(record);\n }\n\n private onSuccess(\n candidate: Candidate,\n requestId: string,\n promptTokens: number,\n completionTokens: number,\n startedAt: number,\n ): void {\n const { account } = candidate;\n const latencyMs = Math.max(0, this.clock() - startedAt);\n this.breaker.onSuccess(account.id);\n const { reported } = this.options;\n if (reported?.get(account.id)?.source === 'error') reported.forget(account.id);\n this.recordUsage(candidate, requestId, 'success', promptTokens, completionTokens, latencyMs);\n const current = this.options.accounts.get(account.id);\n if (current && (current.status === 'cooldown' || current.lastError || current.cooldownUntil)) {\n this.emitAccount(\n this.options.accounts.update(account.id, {\n status: 'active',\n cooldownUntil: null,\n lastError: null,\n }),\n );\n }\n this.options.events.emit({\n type: 'request.completed',\n requestId,\n model: candidate.model,\n accountId: account.id,\n provider: candidate.provider,\n promptTokens,\n completionTokens,\n latencyMs,\n });\n }\n\n /** The caller aborted: record the attempt as cancelled without touching cooldowns. */\n private onCancelled(\n candidate: Candidate,\n requestId: string,\n startedAt: number,\n tokens: { prompt: number; completion: number } = { prompt: 0, completion: 0 },\n ): void {\n const latencyMs = Math.max(0, this.clock() - startedAt);\n this.breaker.onCancel(candidate.account.id);\n this.recordUsage(\n candidate,\n requestId,\n 'cancelled',\n tokens.prompt,\n tokens.completion,\n latencyMs,\n );\n }\n\n private onFailure(\n candidate: Candidate,\n requestId: string,\n error: ProviderError,\n startedAt: number,\n tokens: { prompt: number; completion: number } = { prompt: 0, completion: 0 },\n ): void {\n const { account } = candidate;\n const latencyMs = Math.max(0, this.clock() - startedAt);\n const rateLimited = error.kind === 'rate_limit' || error.kind === 'quota_exhausted';\n this.recordUsage(\n candidate,\n requestId,\n rateLimited ? 'rate_limited' : 'error',\n tokens.prompt,\n tokens.completion,\n latencyMs,\n error.kind,\n );\n this.options.events.emit({\n type: 'request.failed',\n requestId,\n accountId: account.id,\n provider: candidate.provider,\n error: {\n kind: error.kind,\n message: error.message,\n ...(error.status !== undefined ? { status: error.status } : {}),\n },\n });\n if (BREAKER_KINDS.has(error.kind)) this.breaker.onFailure(account.id);\n if (error.kind === 'quota_exhausted' && this.options.reported) {\n // Subscription limits (\"usage limit reached… resets 3pm\") last until the provider's reset.\n const resetAt =\n error.retryAfterMs !== undefined\n ? new Date(this.clock() + error.retryAfterMs).toISOString()\n : undefined;\n this.options.reported.report(\n account.id,\n { exhausted: true, ...(resetAt ? { resetAt } : {}) },\n 'error',\n );\n }\n\n if (error.kind === 'auth') {\n this.emitAccount(\n this.options.accounts.update(account.id, { status: 'error', lastError: error.message }),\n );\n } else if (error.failover && error.kind !== 'context_length') {\n // context_length is the prompt's fault, not the account's: fail over without cooldown.\n const cooldownMs = error.retryAfterMs ?? this.config.routing.cooldownMs;\n const until = new Date(this.clock() + cooldownMs).toISOString();\n this.emitAccount(\n this.options.accounts.update(account.id, {\n status: 'cooldown',\n cooldownUntil: until,\n lastError: error.message,\n }),\n );\n }\n }\n\n /**\n * Try ranked candidates in order until `attempt` succeeds, failing over on\n * failover-eligible errors up to `routing.maxFailovers` hops.\n */\n private async execute<T>(\n req: ChatRequest,\n options: RouteRequestOptions,\n attempt: (candidate: Candidate, ctx: ProviderCallContext, request: ChatRequest) => Promise<T>,\n ): Promise<{\n value: T;\n candidate: Candidate;\n meta: RoutingMeta;\n startedAt: number;\n estimate: number;\n }> {\n const requestId = options.requestId ?? newId('req');\n const estimate = estimateTokens(req.messages);\n const plan = this.plan(req, estimate);\n if (plan.candidates.length === 0) throw this.noCandidateError(req, plan, requestId);\n\n const maxAttempts = this.config.routing.maxFailovers + 1;\n const cooled = new Set<string>();\n const errors: ProviderError[] = [];\n let attempts = 0;\n let failovers = 0;\n\n const usable = (c: Candidate) => !cooled.has(c.account.id) && this.breaker.allow(c.account.id);\n\n for (let i = 0; i < plan.candidates.length && attempts < maxAttempts; i++) {\n const candidate = plan.candidates[i]!;\n if (!usable(candidate)) continue;\n attempts++;\n const { account } = candidate;\n this.breaker.onAttempt(account.id);\n this.options.events.emit({\n type: 'request.started',\n requestId,\n model: candidate.model,\n accountId: account.id,\n provider: candidate.provider,\n });\n const startedAt = this.clock();\n try {\n const ctx = this.contextFor(account, options.signal);\n const value = await attempt(candidate, ctx, { ...req, model: candidate.model });\n return {\n value,\n candidate,\n startedAt,\n estimate,\n meta: {\n requestId,\n accountId: account.id,\n provider: candidate.provider,\n model: candidate.model,\n failovers,\n },\n };\n } catch (err) {\n const error = toProviderError(err, account);\n if (options.signal?.aborted) {\n // The client went away: not the account's fault, so no cooldown and no failover.\n this.onCancelled(candidate, requestId, startedAt);\n throw error;\n }\n this.onFailure(candidate, requestId, error, startedAt);\n if (!error.failover) throw error;\n errors.push(error);\n if (error.kind !== 'context_length') cooled.add(account.id);\n const next = attempts < maxAttempts ? plan.candidates.slice(i + 1).find(usable) : undefined;\n this.options.events.emit({\n type: 'router.failover',\n requestId,\n fromAccountId: account.id,\n toAccountId: next?.account.id ?? null,\n reason: error.kind,\n });\n if (next) failovers++;\n }\n }\n\n const lastError = errors.at(-1);\n const allRateLimited =\n errors.length > 0 &&\n errors.every((e) => e.kind === 'rate_limit' || e.kind === 'quota_exhausted');\n if (errors.length === 0) {\n throw new RouterError('no_capacity', `Every account for \"${req.model}\" is unavailable`, {\n requestId,\n });\n }\n throw new RouterError(\n allRateLimited ? 'rate_limited' : 'upstream_failed',\n `All ${errors.length} attempt(s) for \"${req.model}\" failed${lastError ? `: ${lastError.message}` : ''}`,\n { requestId, failovers, ...(lastError ? { lastError } : {}) },\n );\n }\n\n /** Non-streaming completion with hot failover. */\n async complete(req: ChatRequest, options: RouteRequestOptions = {}): Promise<CompletionResult> {\n const { value, candidate, meta, startedAt, estimate } = await this.execute(\n req,\n options,\n (c, ctx, request) =>\n this.options.providers.get(c.provider)!.complete({ ...request, stream: false }, ctx),\n );\n const usage = value.usage;\n const hasUsage = usage && (usage.prompt_tokens > 0 || usage.completion_tokens > 0);\n const promptTokens = hasUsage ? usage.prompt_tokens : estimate;\n const completionTokens = hasUsage\n ? usage.completion_tokens\n : countTextTokens(value.choices.map((c) => messageText(c.message)).join(''));\n this.onSuccess(candidate, meta.requestId, promptTokens, completionTokens, startedAt);\n return { completion: value, meta };\n }\n\n /**\n * Streaming completion. Failover happens only until the first chunk arrives; the\n * returned promise resolves once a provider has produced it (or ended cleanly).\n */\n async stream(req: ChatRequest, options: RouteRequestOptions = {}): Promise<StreamResult> {\n const { value, candidate, meta, startedAt, estimate } = await this.execute(\n req,\n options,\n async (c, ctx, request) => {\n const iterator = this.options.providers\n .get(c.provider)!\n .stream({ ...request, stream: true }, ctx)\n [Symbol.asyncIterator]();\n const first = await iterator.next();\n return { iterator, first };\n },\n );\n return {\n meta,\n chunks: this.relay(\n value.iterator,\n value.first,\n candidate,\n meta,\n startedAt,\n estimate,\n options.signal,\n ),\n };\n }\n\n private async *relay(\n iterator: AsyncIterator<ChatCompletionChunk>,\n first: IteratorResult<ChatCompletionChunk>,\n candidate: Candidate,\n meta: RoutingMeta,\n startedAt: number,\n estimate: number,\n signal?: AbortSignal,\n ): AsyncGenerator<ChatCompletionChunk> {\n let text = '';\n let upstreamUsage: ChatCompletionChunk['usage'];\n let done = first.done === true;\n let failed = false;\n const track = (chunk: ChatCompletionChunk) => {\n if (chunk.usage) upstreamUsage = chunk.usage;\n for (const choice of chunk.choices) text += messageText(choice.delta);\n };\n const tokens = () => {\n const has =\n upstreamUsage && (upstreamUsage.prompt_tokens > 0 || upstreamUsage.completion_tokens > 0);\n return has && upstreamUsage\n ? { prompt: upstreamUsage.prompt_tokens, completion: upstreamUsage.completion_tokens }\n : { prompt: estimate, completion: countTextTokens(text) };\n };\n\n try {\n if (!first.done) {\n track(first.value);\n yield first.value;\n }\n while (!done) {\n const next = await iterator.next();\n if (next.done) {\n done = true;\n break;\n }\n track(next.value);\n yield next.value;\n }\n } catch (err) {\n failed = true;\n const error = toProviderError(err, candidate.account);\n if (signal?.aborted) {\n // Client disconnect or Esc in the TUI mid-stream: record what was used, blame no one.\n this.onCancelled(candidate, meta.requestId, startedAt, tokens());\n } else {\n this.onFailure(candidate, meta.requestId, error, startedAt, tokens());\n }\n throw error;\n } finally {\n if (!done && !failed) {\n // The consumer stopped early (client disconnect): release the upstream stream.\n try {\n await iterator.return?.();\n } catch {\n // Ignore cleanup errors from the provider.\n }\n }\n if (!failed) {\n const { prompt, completion } = tokens();\n this.onSuccess(candidate, meta.requestId, prompt, completion, startedAt);\n }\n }\n }\n\n /**\n * Models for `GET /v1/models`: every model of every usable account (allow-list, else the\n * provider's `listModels`), plus `davecode/<route>` for each route and the default route.\n */\n async listModels(): Promise<ModelInfo[]> {\n const { routing, experimental } = this.config;\n const accounts = this.options.accounts\n .list()\n .filter(\n (a) =>\n a.enabled &&\n (experimental.geminiWeb || !EXPERIMENTAL_PROVIDER_KINDS.includes(a.provider)),\n );\n const lists = await Promise.all(\n accounts.map(async (account): Promise<ModelInfo[]> => {\n const created = Math.floor(Date.parse(account.createdAt) / 1000) || 0;\n const listed = configuredModels(account);\n if (listed) {\n return listed.map((id) => ({ id, object: 'model', created, owned_by: account.provider }));\n }\n const provider = this.options.providers.get(account.provider);\n if (!provider) return [];\n try {\n return await provider.listModels(this.contextFor(account));\n } catch {\n return [];\n }\n }),\n );\n const models = new Map<string, ModelInfo>();\n for (const model of lists.flat()) if (!models.has(model.id)) models.set(model.id, model);\n const routeNames = routing.routes.map((r) => r.name);\n if (!routeNames.includes(routing.defaultRoute)) routeNames.unshift(routing.defaultRoute);\n for (const name of routeNames) {\n const id = `davecode/${name}`;\n models.set(id, { id, object: 'model', created: 0, owned_by: 'davecode' });\n }\n return [...models.values()];\n }\n}\n","import type { Account, AccountStatus, ProviderKind, QuotaLimits, SubscriptionInfo } from '../types';\nimport type { Database } from './database';\nimport { newId } from './ids';\n\nexport interface AccountCreateInput {\n provider: ProviderKind;\n label: string;\n enabled?: boolean;\n priority?: number;\n weight?: number;\n limits?: QuotaLimits;\n config?: Record<string, unknown>;\n subscription?: SubscriptionInfo;\n}\n\nexport interface AccountUpdateInput {\n label?: string;\n enabled?: boolean;\n priority?: number;\n weight?: number;\n limits?: QuotaLimits;\n config?: Record<string, unknown>;\n /** Replaces the subscription details; `null` clears them. */\n subscription?: SubscriptionInfo | null;\n status?: AccountStatus;\n /** ISO timestamp, or `null` to clear. */\n cooldownUntil?: string | null;\n /** Error summary, or `null` to clear. */\n lastError?: string | null;\n}\n\ninterface AccountRow {\n id: string;\n provider: string;\n label: string;\n enabled: number;\n priority: number;\n weight: number;\n limits: string;\n config: string;\n subscription: string;\n status: string;\n cooldown_until: string | null;\n last_error: string | null;\n created_at: string;\n updated_at: string;\n /** Computed by SELECT_ACCOUNT; absent on rows built in memory. */\n has_secret?: number;\n}\n\n/** Every read includes whether the keyring holds a secret, without exposing it. */\nconst SELECT_ACCOUNT = `SELECT a.*, EXISTS (SELECT 1 FROM secrets s WHERE s.account_id = a.id) AS has_secret\n FROM accounts a`;\n\nfunction parseObject(json: string): Record<string, unknown> {\n try {\n const value: unknown = JSON.parse(json);\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n } catch {\n return {};\n }\n}\n\nfunction toAccount(row: AccountRow): Account {\n const account: Account = {\n id: row.id,\n provider: row.provider as ProviderKind,\n label: row.label,\n enabled: row.enabled === 1,\n priority: row.priority,\n weight: row.weight,\n limits: parseObject(row.limits) as QuotaLimits,\n config: parseObject(row.config),\n status: row.status as AccountStatus,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n hasSecret: row.has_secret === 1,\n };\n const subscription = parseObject(row.subscription ?? '{}');\n if (Object.keys(subscription).length > 0) account.subscription = subscription as SubscriptionInfo;\n if (row.cooldown_until) account.cooldownUntil = row.cooldown_until;\n if (row.last_error) account.lastError = row.last_error;\n return account;\n}\n\n/** CRUD for provider accounts. Secrets are stored separately by the keyring. */\nexport class AccountRepository {\n constructor(\n private readonly db: Database,\n private readonly now: () => number = Date.now,\n ) {}\n\n create(input: AccountCreateInput): Account {\n const ts = new Date(this.now()).toISOString();\n const enabled = input.enabled ?? true;\n const row: AccountRow = {\n id: newId('acc'),\n provider: input.provider,\n label: input.label,\n enabled: enabled ? 1 : 0,\n priority: input.priority ?? 100,\n weight: input.weight ?? 1,\n limits: JSON.stringify(input.limits ?? {}),\n config: JSON.stringify(input.config ?? {}),\n subscription: JSON.stringify(input.subscription ?? {}),\n status: enabled ? 'active' : 'disabled',\n cooldown_until: null,\n last_error: null,\n created_at: ts,\n updated_at: ts,\n };\n this.db\n .prepare(\n `INSERT INTO accounts (id, provider, label, enabled, priority, weight, limits, config,\n subscription, status, cooldown_until, last_error, created_at, updated_at)\n VALUES (@id, @provider, @label, @enabled, @priority, @weight, @limits, @config,\n @subscription, @status, @cooldown_until, @last_error, @created_at, @updated_at)`,\n )\n .run(row);\n return toAccount(row);\n }\n\n /** All accounts ordered by priority, then creation time. */\n list(): Account[] {\n const rows = this.db\n .prepare(`${SELECT_ACCOUNT} ORDER BY a.priority ASC, a.created_at ASC, a.id ASC`)\n .all() as AccountRow[];\n return rows.map(toAccount);\n }\n\n get(id: string): Account | undefined {\n const row = this.db.prepare(`${SELECT_ACCOUNT} WHERE a.id = ?`).get(id) as\n | AccountRow\n | undefined;\n return row ? toAccount(row) : undefined;\n }\n\n /** Apply a partial update. Returns the updated account, or `undefined` if it does not exist. */\n update(id: string, patch: AccountUpdateInput): Account | undefined {\n const sets: string[] = [];\n const params: Record<string, unknown> = { id };\n const set = (column: string, value: unknown) => {\n sets.push(`${column} = @${column}`);\n params[column] = value;\n };\n if (patch.label !== undefined) set('label', patch.label);\n if (patch.enabled !== undefined) set('enabled', patch.enabled ? 1 : 0);\n if (patch.priority !== undefined) set('priority', patch.priority);\n if (patch.weight !== undefined) set('weight', patch.weight);\n if (patch.limits !== undefined) set('limits', JSON.stringify(patch.limits));\n if (patch.config !== undefined) set('config', JSON.stringify(patch.config));\n if (patch.subscription !== undefined) {\n set('subscription', JSON.stringify(patch.subscription ?? {}));\n }\n if (patch.status !== undefined) set('status', patch.status);\n if (patch.cooldownUntil !== undefined) set('cooldown_until', patch.cooldownUntil);\n if (patch.lastError !== undefined) set('last_error', patch.lastError);\n set('updated_at', new Date(this.now()).toISOString());\n const result = this.db\n .prepare(`UPDATE accounts SET ${sets.join(', ')} WHERE id = @id`)\n .run(params);\n return result.changes > 0 ? this.get(id) : undefined;\n }\n\n /** Delete an account (its secret and sessions cascade). Returns false if it did not exist. */\n delete(id: string): boolean {\n return this.db.prepare('DELETE FROM accounts WHERE id = ?').run(id).changes > 0;\n }\n}\n","import type { Database } from './database';\n\nexport interface AuditEntry {\n id: number;\n /** Epoch milliseconds. */\n ts: number;\n /** Who did it: `api`, `cli`, `router`, `runner`… */\n actor: string;\n /** What happened, e.g. `account.create`. */\n action: string;\n /** Affected resource id, if any. */\n target?: string;\n details: Record<string, unknown>;\n}\n\nexport interface AuditInput {\n actor: string;\n action: string;\n target?: string;\n /** Free-form context. Never put secrets here. */\n details?: Record<string, unknown>;\n}\n\ninterface AuditRow {\n id: number;\n ts: number;\n actor: string;\n action: string;\n target: string | null;\n details: string;\n}\n\nfunction parseDetails(json: string): Record<string, unknown> {\n try {\n const value: unknown = JSON.parse(json);\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n } catch {\n return {};\n }\n}\n\n/** Append-only audit trail (`audit_logs` table). */\nexport class AuditLog {\n constructor(\n private readonly db: Database,\n private readonly now: () => number = Date.now,\n ) {}\n\n record(input: AuditInput): AuditEntry {\n const ts = this.now();\n const details = input.details ?? {};\n const result = this.db\n .prepare('INSERT INTO audit_logs (ts, actor, action, target, details) VALUES (?, ?, ?, ?, ?)')\n .run(ts, input.actor, input.action, input.target ?? null, JSON.stringify(details));\n const entry: AuditEntry = {\n id: Number(result.lastInsertRowid),\n ts,\n actor: input.actor,\n action: input.action,\n details,\n };\n if (input.target !== undefined) entry.target = input.target;\n return entry;\n }\n\n /** Most recent entries first, optionally filtered by target. */\n list(options: { limit?: number; target?: string } = {}): AuditEntry[] {\n const limit = Math.max(0, Math.floor(options.limit ?? 100));\n const rows = (\n options.target === undefined\n ? this.db.prepare('SELECT * FROM audit_logs ORDER BY id DESC LIMIT ?').all(limit)\n : this.db\n .prepare('SELECT * FROM audit_logs WHERE target = ? ORDER BY id DESC LIMIT ?')\n .all(options.target, limit)\n ) as AuditRow[];\n return rows.map((row) => {\n const entry: AuditEntry = {\n id: row.id,\n ts: row.ts,\n actor: row.actor,\n action: row.action,\n details: parseDetails(row.details),\n };\n if (row.target !== null) entry.target = row.target;\n return entry;\n });\n }\n}\n","import { mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport BetterSqlite3 from 'better-sqlite3';\n\nexport type Database = BetterSqlite3.Database;\n\n/**\n * Ordered schema migrations. Index `i` upgrades the schema from version `i` to `i + 1`\n * (tracked in `PRAGMA user_version`). Never edit a shipped migration; append a new one.\n */\nexport const MIGRATIONS: readonly string[] = [\n `\n CREATE TABLE accounts (\n id TEXT PRIMARY KEY,\n provider TEXT NOT NULL,\n label TEXT NOT NULL,\n enabled INTEGER NOT NULL DEFAULT 1,\n priority INTEGER NOT NULL DEFAULT 100,\n weight REAL NOT NULL DEFAULT 1,\n limits TEXT NOT NULL DEFAULT '{}',\n config TEXT NOT NULL DEFAULT '{}',\n status TEXT NOT NULL DEFAULT 'active',\n cooldown_until TEXT,\n last_error TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE secrets (\n account_id TEXT PRIMARY KEY REFERENCES accounts(id) ON DELETE CASCADE,\n ciphertext BLOB NOT NULL,\n iv BLOB NOT NULL,\n auth_tag BLOB NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE sessions (\n id TEXT PRIMARY KEY,\n account_id TEXT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,\n kind TEXT NOT NULL,\n metadata TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n expires_at TEXT\n );\n CREATE INDEX idx_sessions_account ON sessions(account_id);\n\n CREATE TABLE token_usage (\n id TEXT PRIMARY KEY,\n request_id TEXT NOT NULL,\n account_id TEXT NOT NULL,\n provider TEXT NOT NULL,\n model TEXT NOT NULL,\n prompt_tokens INTEGER NOT NULL DEFAULT 0,\n completion_tokens INTEGER NOT NULL DEFAULT 0,\n latency_ms INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL,\n error_kind TEXT,\n ts INTEGER NOT NULL\n );\n CREATE INDEX idx_token_usage_account_ts ON token_usage(account_id, ts);\n CREATE INDEX idx_token_usage_ts ON token_usage(ts);\n\n CREATE TABLE audit_logs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n ts INTEGER NOT NULL,\n actor TEXT NOT NULL,\n action TEXT NOT NULL,\n target TEXT,\n details TEXT NOT NULL DEFAULT '{}'\n );\n CREATE INDEX idx_audit_logs_ts ON audit_logs(ts);\n `,\n `\n ALTER TABLE accounts ADD COLUMN subscription TEXT NOT NULL DEFAULT '{}';\n `,\n];\n\n/** Current schema version of the database. */\nexport function schemaVersion(db: Database): number {\n return db.pragma('user_version', { simple: true }) as number;\n}\n\n/** Apply pending migrations, each inside its own transaction. */\nexport function migrate(db: Database, migrations: readonly string[] = MIGRATIONS): number {\n let version = schemaVersion(db);\n if (version > migrations.length) {\n throw new Error(\n `Database schema version ${version} is newer than this DaveCode build supports (${migrations.length}). Upgrade DaveCode.`,\n );\n }\n for (; version < migrations.length; version++) {\n const sql = migrations[version]!;\n const next = version + 1;\n db.transaction(() => {\n db.exec(sql);\n db.pragma(`user_version = ${next}`);\n })();\n }\n return version;\n}\n\nexport interface OpenDatabaseOptions {\n /** Milliseconds to wait on a locked database before failing (default 5000). */\n busyTimeoutMs?: number;\n}\n\n/**\n * Open (creating if needed) the DaveCode SQLite database with WAL, foreign keys and a\n * busy timeout, then run migrations. Pass `':memory:'` for an ephemeral database.\n */\nexport function openDatabase(path: string, options: OpenDatabaseOptions = {}): Database {\n if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true });\n const db = new BetterSqlite3(path);\n try {\n db.pragma('journal_mode = WAL');\n db.pragma('foreign_keys = ON');\n db.pragma('synchronous = NORMAL');\n db.pragma(`busy_timeout = ${Math.max(0, Math.floor(options.busyTimeoutMs ?? 5000))}`);\n migrate(db);\n } catch (err) {\n db.close();\n throw err;\n }\n return db;\n}\n","import type {\n ProviderErrorKind,\n ProviderKind,\n UsageBucket,\n UsageRecord,\n UsageStatus,\n} from '../types';\nimport type { Database } from './database';\n\ninterface UsageRow {\n id: string;\n request_id: string;\n account_id: string;\n provider: string;\n model: string;\n prompt_tokens: number;\n completion_tokens: number;\n latency_ms: number;\n status: string;\n error_kind: string | null;\n ts: number;\n}\n\nfunction toRecord(row: UsageRow): UsageRecord {\n const record: UsageRecord = {\n id: row.id,\n requestId: row.request_id,\n accountId: row.account_id,\n provider: row.provider as ProviderKind,\n model: row.model,\n promptTokens: row.prompt_tokens,\n completionTokens: row.completion_tokens,\n latencyMs: row.latency_ms,\n status: row.status as UsageStatus,\n ts: row.ts,\n };\n if (row.error_kind) record.errorKind = row.error_kind as ProviderErrorKind;\n return record;\n}\n\nexport interface UsageTotals {\n tokens: number;\n promptTokens: number;\n completionTokens: number;\n requests: number;\n}\n\nexport interface TimeseriesOptions {\n /** Window start (epoch ms). Rounded down to a bucket boundary. */\n since: number;\n /** Window end (epoch ms, exclusive). */\n until: number;\n /** Bucket width in milliseconds. */\n bucketMs: number;\n}\n\n/** Persistent per-request token usage (`token_usage` table). */\nexport class UsageRepository {\n constructor(private readonly db: Database) {}\n\n insert(record: UsageRecord): void {\n this.db\n .prepare(\n `INSERT INTO token_usage (id, request_id, account_id, provider, model, prompt_tokens,\n completion_tokens, latency_ms, status, error_kind, ts)\n VALUES (@id, @requestId, @accountId, @provider, @model, @promptTokens,\n @completionTokens, @latencyMs, @status, @errorKind, @ts)`,\n )\n .run({ ...record, errorKind: record.errorKind ?? null });\n }\n\n /** Token and request totals for one account since `sinceTs` (inclusive). */\n totalsSince(accountId: string, sinceTs: number): UsageTotals {\n const row = this.db\n .prepare(\n `SELECT COALESCE(SUM(prompt_tokens), 0) AS p, COALESCE(SUM(completion_tokens), 0) AS c,\n COUNT(*) AS n\n FROM token_usage WHERE account_id = ? AND ts >= ?`,\n )\n .get(accountId, sinceTs) as { p: number; c: number; n: number };\n return { tokens: row.p + row.c, promptTokens: row.p, completionTokens: row.c, requests: row.n };\n }\n\n /** Every record since `sinceTs` (inclusive), oldest first. */\n since(sinceTs: number): UsageRecord[] {\n const rows = this.db\n .prepare('SELECT * FROM token_usage WHERE ts >= ? ORDER BY ts ASC, rowid ASC')\n .all(sinceTs) as UsageRow[];\n return rows.map(toRecord);\n }\n\n /** Most recent records first. */\n recent(limit = 100): UsageRecord[] {\n const rows = this.db\n .prepare('SELECT * FROM token_usage ORDER BY ts DESC, rowid DESC LIMIT ?')\n .all(Math.max(0, Math.floor(limit))) as UsageRow[];\n return rows.map(toRecord);\n }\n\n /**\n * Zero-filled, bucket-aligned time series for `GET /api/usage/timeseries`, oldest first.\n * Tokens are prompt + completion.\n */\n timeseries({ since, until, bucketMs }: TimeseriesOptions): UsageBucket[] {\n const width = Math.max(1, Math.floor(bucketMs));\n const start = Math.floor(since / width) * width;\n const count = Math.max(0, Math.ceil((until - start) / width));\n const buckets: UsageBucket[] = Array.from({ length: count }, (_, i) => ({\n ts: start + i * width,\n tokens: 0,\n requests: 0,\n byAccount: {},\n }));\n const rows = this.db\n .prepare(\n `SELECT CAST((ts - @start) / @width AS INTEGER) AS b, account_id AS accountId,\n SUM(prompt_tokens + completion_tokens) AS tokens, COUNT(*) AS requests\n FROM token_usage WHERE ts >= @start AND ts < @until\n GROUP BY b, account_id`,\n )\n .all({ start, width, until }) as Array<{\n b: number;\n accountId: string;\n tokens: number;\n requests: number;\n }>;\n for (const row of rows) {\n const bucket = buckets[row.b];\n if (!bucket) continue;\n bucket.tokens += row.tokens;\n bucket.requests += row.requests;\n bucket.byAccount[row.accountId] = { tokens: row.tokens, requests: row.requests };\n }\n return buckets;\n }\n\n /** Delete records older than `beforeTs`. Returns the number removed. */\n prune(beforeTs: number): number {\n return this.db.prepare('DELETE FROM token_usage WHERE ts < ?').run(beforeTs).changes;\n }\n}\n","/**\n * Safe child-process helpers for the autonomous runner: quote-aware command splitting, PATH\n * resolution with Windows `.cmd` shim rules, and bounded (tail-first) output capture.\n * Nothing here ever goes through a shell with untrusted text.\n */\nimport { type ChildProcess, spawn, spawnSync } from 'node:child_process';\nimport path from 'node:path';\nimport { isShellSafeArg, needsShell, resolveOnPath } from '../providers/shared/cli';\n\n/** Thrown when a command cannot be parsed or would be unsafe to start. */\nexport class CommandError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CommandError';\n }\n}\n\n/**\n * Splits a command line into argv. Supports single quotes (literal), double quotes (with `\\\"`\n * and `\\\\` escapes) and backslash escapes of whitespace and quotes outside quotes. Backslashes\n * before any other character are kept, so Windows paths survive. No globbing, no variables,\n * no operators: `&&`, `|` or `>` are ordinary arguments.\n */\nexport function splitCommand(command: string): string[] {\n const args: string[] = [];\n let current = '';\n let inArg = false;\n let quote: '\"' | \"'\" | undefined;\n for (let i = 0; i < command.length; i++) {\n const ch = command[i] as string;\n if (quote === \"'\") {\n if (ch === \"'\") quote = undefined;\n else current += ch;\n continue;\n }\n if (quote === '\"') {\n if (ch === '\"') quote = undefined;\n else if (ch === '\\\\' && (command[i + 1] === '\"' || command[i + 1] === '\\\\')) {\n current += command[i + 1];\n i++;\n } else current += ch;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n quote = ch;\n inArg = true;\n continue;\n }\n if (ch === '\\\\' && /[\\s\"'\\\\]/.test(command[i + 1] ?? '')) {\n current += command[i + 1];\n inArg = true;\n i++;\n continue;\n }\n if (/\\s/.test(ch)) {\n if (inArg) args.push(current);\n current = '';\n inArg = false;\n continue;\n }\n current += ch;\n inArg = true;\n }\n if (quote) throw new CommandError(`Unterminated ${quote} quote in command: ${command}`);\n if (inArg) args.push(current);\n return args;\n}\n\n/**\n * Keeps the last `max` characters of `text` (the end of a log is where the error usually is),\n * prefixed with a marker saying how much was dropped.\n */\nexport function truncateTail(text: string, max: number): string {\n if (text.length <= max) return text;\n const dropped = text.length - max;\n return `[… ${dropped} earlier characters truncated]\\n${text.slice(-max)}`;\n}\n\n/** Keeps the first `max` characters of `text`, with a trailing marker. */\nexport function truncateHead(text: string, max: number): string {\n if (text.length <= max) return text;\n return `${text.slice(0, max)}\\n[… ${text.length - max} more characters truncated]`;\n}\n\n/** PATH with `<cwd>/node_modules/.bin` first, so project-local tools resolve. */\nexport function projectEnv(cwd: string, base: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {\n const env = { ...base };\n const key = Object.keys(env).find((k) => k.toUpperCase() === 'PATH') ?? 'PATH';\n const bin = path.join(cwd, 'node_modules', '.bin');\n env[key] = env[key] ? `${bin}${path.delimiter}${env[key]}` : bin;\n return env;\n}\n\nexport interface RunProcessOptions {\n command: string;\n args: string[];\n cwd: string;\n /** Kill the process tree after this many milliseconds. */\n timeoutMs: number;\n env?: NodeJS.ProcessEnv;\n signal?: AbortSignal;\n /** Characters of stdout/stderr retained (tail). Default 64 KiB each. */\n maxOutputChars?: number;\n stdin?: string;\n}\n\nexport interface ProcessResult {\n /** Exit code, or `null` when killed or not started. */\n exitCode: number | null;\n stdout: string;\n stderr: string;\n durationMs: number;\n timedOut: boolean;\n aborted: boolean;\n}\n\nfunction killTree(child: ChildProcess): void {\n if (child.pid === undefined || child.exitCode !== null) return;\n if (process.platform === 'win32') {\n spawnSync('taskkill', ['/pid', String(child.pid), '/T', '/F'], { windowsHide: true });\n } else {\n try {\n // The child leads its own process group (detached), so this also reaches grandchildren.\n process.kill(-child.pid, 'SIGKILL');\n } catch {\n child.kill('SIGKILL');\n }\n }\n}\n\n/** Appends to a rolling buffer that never grows far beyond `max` characters. */\nclass TailBuffer {\n private text = '';\n private dropped = 0;\n constructor(private readonly max: number) {}\n push(chunk: string): void {\n this.text += chunk;\n if (this.text.length > this.max * 2) {\n const cut = this.text.length - this.max;\n this.dropped += cut;\n this.text = this.text.slice(cut);\n }\n }\n toString(): string {\n const full = this.text.length > this.max ? this.text.slice(-this.max) : this.text;\n const dropped = this.dropped + (this.text.length - full.length);\n return dropped > 0 ? `[… ${dropped} earlier characters truncated]\\n${full}` : full;\n }\n}\n\n/**\n * Resolves `command` through PATH (`env`), and decides how to start it. Windows `.cmd`/`.bat`\n * shims need cmd.exe, so for those every argument must be trivially shell-safe; anything else\n * is refused rather than escaped (mirrors `providers/shared/cli.ts`).\n */\nexport function prepareCommand(\n command: string,\n args: string[],\n env: NodeJS.ProcessEnv,\n): { file: string; args: string[]; shell: boolean } {\n const resolved = resolveOnPath(command, env);\n if (!needsShell(resolved)) return { file: resolved, args, shell: false };\n const unsafe = args.find((a) => !isShellSafeArg(a));\n if (unsafe !== undefined || /[\"%!^&|<>]/.test(resolved)) {\n throw new CommandError(\n `Refusing to run \"${command}\" through the Windows shell with argument ${JSON.stringify(\n unsafe ?? resolved,\n )}: only letters, digits and . : = @ + - / \\\\ [ ] are allowed for .cmd shims`,\n );\n }\n const file = isShellSafeArg(resolved) ? resolved : `\"${resolved}\"`;\n return { file: [file, ...args].join(' '), args: [], shell: true };\n}\n\n/** Runs a process without a shell (except vetted `.cmd` shims), with timeout and abort. */\nexport function runProcess(opts: RunProcessOptions): Promise<ProcessResult> {\n const started = Date.now();\n const max = opts.maxOutputChars ?? 64 * 1024;\n const env = opts.env ?? process.env;\n const stdout = new TailBuffer(max);\n const stderr = new TailBuffer(max);\n\n return new Promise<ProcessResult>((resolvePromise) => {\n let prepared: ReturnType<typeof prepareCommand>;\n try {\n prepared = prepareCommand(opts.command, opts.args, env);\n } catch (err) {\n resolvePromise({\n exitCode: null,\n stdout: '',\n stderr: err instanceof Error ? err.message : String(err),\n durationMs: 0,\n timedOut: false,\n aborted: false,\n });\n return;\n }\n if (opts.signal?.aborted) {\n resolvePromise({\n exitCode: null,\n stdout: '',\n stderr: 'aborted before start',\n durationMs: 0,\n timedOut: false,\n aborted: true,\n });\n return;\n }\n\n const child = spawn(prepared.file, prepared.args, {\n cwd: opts.cwd,\n env,\n shell: prepared.shell,\n // POSIX: own process group so a timeout kills the whole tree (see killTree).\n detached: process.platform !== 'win32',\n windowsHide: true,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n let timedOut = false;\n let aborted = false;\n let settled = false;\n child.stdout?.setEncoding('utf8');\n child.stderr?.setEncoding('utf8');\n child.stdout?.on('data', (d: string) => stdout.push(d));\n child.stderr?.on('data', (d: string) => stderr.push(d));\n child.stdin?.on('error', () => {\n // the child exited before reading stdin\n });\n child.stdin?.end(opts.stdin ?? '');\n\n const timer = setTimeout(() => {\n timedOut = true;\n killTree(child);\n }, opts.timeoutMs);\n const onAbort = () => {\n aborted = true;\n killTree(child);\n };\n opts.signal?.addEventListener('abort', onAbort, { once: true });\n\n const finish = (exitCode: number | null, extraErr?: string) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n opts.signal?.removeEventListener('abort', onAbort);\n if (extraErr) stderr.push(extraErr);\n resolvePromise({\n exitCode,\n stdout: stdout.toString(),\n stderr: stderr.toString(),\n durationMs: Date.now() - started,\n timedOut,\n aborted,\n });\n };\n child.once('error', (err) => {\n const code = (err as NodeJS.ErrnoException).code;\n finish(null, `failed to start \"${opts.command}\": ${code ?? err.message}`);\n });\n child.once('close', (code) => finish(timedOut || aborted ? null : code));\n });\n}\n","/**\n * File and command tools exposed to the built-in executor through OpenAI tool calling.\n * Every path is confined to the repository root (no absolute paths outside it, no `..`\n * escapes, no symlink escapes); `.git` is off-limits and `.davecode` (the project brain,\n * owned by the runner) is read-only.\n */\nimport type { Dirent } from 'node:fs';\nimport { mkdir, readdir, readFile, realpath, stat, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport type { ToolDefinition } from '../types';\nimport { projectEnv, runProcess, splitCommand, truncateHead, truncateTail } from './process';\n\n/** Thrown (and reported to the model) when a path would leave the repository. */\nexport class PathEscapeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'PathEscapeError';\n }\n}\n\n/** Default `runner.allowedCommands`. */\nexport const DEFAULT_ALLOWED_COMMANDS: readonly string[] = [\n 'pnpm',\n 'npm',\n 'npx',\n 'node',\n 'git',\n 'tsc',\n 'biome',\n 'vitest',\n];\n\n/** git subcommands `run_command` accepts: none of them modify the repository. */\nexport const READ_ONLY_GIT_SUBCOMMANDS: readonly string[] = [\n 'status',\n 'diff',\n 'log',\n 'show',\n 'ls-files',\n 'grep',\n 'rev-parse',\n 'blame',\n 'shortlog',\n 'describe',\n];\n\n/** Directories `search` never descends into. */\nconst SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'coverage', 'build', '.next', '.turbo']);\nconst MAX_FILE_BYTES = 1024 * 1024;\n\nconst isWindows = process.platform === 'win32';\nconst same = (a: string, b: string) => (isWindows ? a.toLowerCase() === b.toLowerCase() : a === b);\n\nfunction isInside(base: string, target: string): boolean {\n const rel = path.relative(base, target);\n return rel === '' || (rel !== '..' && !rel.startsWith(`..${path.sep}`) && !path.isAbsolute(rel));\n}\n\n/** realpath of the deepest existing ancestor, with the missing tail re-appended. */\nasync function realpathLenient(target: string): Promise<string> {\n const missing: string[] = [];\n let current = target;\n for (;;) {\n try {\n const real = await realpath(current);\n return missing.length > 0 ? path.join(real, ...missing.reverse()) : real;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== 'ENOENT' && code !== 'ENOTDIR') throw err;\n const parent = path.dirname(current);\n if (parent === current) return target;\n missing.push(path.basename(current));\n current = parent;\n }\n }\n}\n\nexport interface ResolvedPath {\n /** Absolute path (inside the root). */\n abs: string;\n /** Path relative to the root with forward slashes (`.` for the root itself). */\n rel: string;\n}\n\n/**\n * Resolves a model-supplied path inside `root`. Rejects NUL bytes, absolute paths outside the\n * root, `..` escapes, symlinks that point outside, anything under `.git`, and (for writes)\n * anything under `.davecode`.\n */\nexport async function resolveRepoPath(\n root: string,\n input: string,\n mode: 'read' | 'write' = 'read',\n): Promise<ResolvedPath> {\n if (input.includes('\\0')) throw new PathEscapeError('path contains a NUL byte');\n const base = path.resolve(root);\n const abs = path.resolve(base, input.trim() === '' ? '.' : input);\n if (!isInside(base, abs)) {\n throw new PathEscapeError(`path \"${input}\" is outside the repository`);\n }\n const realBase = await realpath(base);\n const real = await realpathLenient(abs);\n if (!isInside(realBase, real)) {\n throw new PathEscapeError(`path \"${input}\" resolves outside the repository (symlink)`);\n }\n const rel = path.relative(base, abs).split(path.sep).join('/') || '.';\n const first = rel.split('/')[0] ?? '';\n if (same(first, '.git')) throw new PathEscapeError('the .git directory is off-limits');\n if (mode === 'write' && same(first, '.davecode')) {\n throw new PathEscapeError('.davecode is managed by the runner and is read-only for tools');\n }\n return { abs, rel };\n}\n\n// ---------------------------------------------------------------------------\n// Tool schemas\n// ---------------------------------------------------------------------------\n\nconst listDirArgs = z.object({ path: z.string().default('.') });\nconst readFileArgs = z.object({\n path: z.string().min(1),\n offset: z.number().int().min(1).optional(),\n limit: z.number().int().min(1).optional(),\n});\nconst writeFileArgs = z.object({ path: z.string().min(1), content: z.string() });\nconst editFileArgs = z.object({\n path: z.string().min(1),\n old_string: z.string().min(1),\n new_string: z.string(),\n});\nconst searchArgs = z.object({\n query: z.string().min(1),\n regex: z.boolean().default(false),\n case_sensitive: z.boolean().default(false),\n path: z.string().default('.'),\n max_results: z.number().int().min(1).max(500).default(50),\n});\nconst runCommandArgs = z.object({\n command: z.string().min(1),\n args: z.array(z.string()).default([]),\n});\nconst finishArgs = z.object({ summary: z.string().min(1) });\n\nfunction fn(\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n): ToolDefinition {\n return {\n type: 'function',\n function: {\n name,\n description,\n parameters: { type: 'object', properties, required, additionalProperties: false },\n },\n };\n}\n\nconst str = (description: string) => ({ type: 'string', description });\n\nexport const TOOL_DEFINITIONS: readonly ToolDefinition[] = [\n fn(\n 'list_dir',\n 'List the entries of a directory in the repository (directories end with \"/\").',\n { path: str('Directory relative to the repository root (default \".\").') },\n [],\n ),\n fn(\n 'read_file',\n 'Read a UTF-8 text file. Large files are truncated; use offset/limit (1-based lines) to page.',\n {\n path: str('File path relative to the repository root.'),\n offset: { type: 'integer', minimum: 1, description: 'First line to return (1-based).' },\n limit: { type: 'integer', minimum: 1, description: 'Number of lines to return.' },\n },\n ['path'],\n ),\n fn(\n 'write_file',\n 'Create or overwrite a file with the given content. Parent directories are created.',\n { path: str('File path relative to the repository root.'), content: str('Full content.') },\n ['path', 'content'],\n ),\n fn(\n 'edit_file',\n 'Replace one exact occurrence of old_string with new_string. old_string must match exactly ' +\n 'once (include surrounding lines to make it unique).',\n {\n path: str('File path relative to the repository root.'),\n old_string: str('Exact text to replace (must be unique in the file).'),\n new_string: str('Replacement text.'),\n },\n ['path', 'old_string', 'new_string'],\n ),\n fn(\n 'search',\n 'Search file contents (substring or regex). Skips node_modules, .git, dist and coverage.',\n {\n query: str('Text or regular expression to find.'),\n regex: { type: 'boolean', description: 'Treat query as a regular expression.' },\n case_sensitive: { type: 'boolean', description: 'Case-sensitive match (default false).' },\n path: str('Directory or file to search (default \".\").'),\n max_results: { type: 'integer', minimum: 1, maximum: 500 },\n },\n ['query'],\n ),\n fn(\n 'run_command',\n 'Run an allow-listed executable in the repository root without a shell (e.g. command ' +\n '\"pnpm\", args [\"test\"]). No pipes, redirects or globbing. git is limited to read-only ' +\n 'subcommands. Output is truncated.',\n {\n command: str('Executable name, e.g. \"pnpm\", \"node\", \"git\".'),\n args: { type: 'array', items: { type: 'string' }, description: 'Arguments.' },\n },\n ['command'],\n ),\n fn(\n 'finish',\n 'Call when the task is fully implemented. The runner then runs the quality gates.',\n { summary: str('Concise summary of the changes, suitable for a commit message body.') },\n ['summary'],\n ),\n];\n\nconst READ_ONLY_TOOL_NAMES: ReadonlySet<string> = new Set(['list_dir', 'read_file', 'search']);\n\n/** Read-only subset of workspace tools (`list_dir`, `read_file`, `search`) for planning/research roles. */\nexport const READ_ONLY_TOOL_DEFINITIONS: readonly ToolDefinition[] = TOOL_DEFINITIONS.filter((t) =>\n READ_ONLY_TOOL_NAMES.has(t.function.name),\n);\n\n// ---------------------------------------------------------------------------\n// Execution\n// ---------------------------------------------------------------------------\n\nexport interface WorkspaceToolsOptions {\n root: string;\n /** Restrict tool calls to `list_dir`, `read_file`, and `search`. */\n readOnly?: boolean;\n /** Executables `run_command` may start (default {@link DEFAULT_ALLOWED_COMMANDS}). */\n allowedCommands?: readonly string[];\n /** Timeout for one `run_command` (default 10 min). */\n commandTimeoutMs?: number;\n /** Characters returned to the model per tool result (default 16 000). */\n maxOutputChars?: number;\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface ToolOutcome {\n /** Text returned to the model as the tool message. */\n output: string;\n ok: boolean;\n /** Set when the model called `finish`. */\n finished?: { summary: string };\n}\n\nclass ToolInputError extends Error {}\n\nfunction parseArgs<T>(schema: z.ZodType<T>, raw: string): T {\n let value: unknown;\n try {\n value = raw.trim() === '' ? {} : JSON.parse(raw);\n } catch {\n throw new ToolInputError('arguments are not valid JSON');\n }\n const parsed = schema.safeParse(value);\n if (!parsed.success) {\n throw new ToolInputError(\n parsed.error.issues.map((i) => `${i.path.join('.') || 'arguments'}: ${i.message}`).join('; '),\n );\n }\n return parsed.data;\n}\n\n/**\n * Repair tool arguments a model JSON-escaped twice (`\"a {\\\\n b\\\\n}\"` arrives as the literal\n * characters backslash + n). Only `\\n`/`\\t` sequences **outside** string literals are turned into\n * real newlines/tabs: outside quotes they are never valid code in mainstream languages, while\n * inside quotes (`\"line\\n\"`) they are legitimate escapes and are kept. Text that already contains a\n * real newline is returned unchanged.\n */\nexport function repairDoubleEscaped(text: string): string {\n if (text.includes('\\n') || !/\\\\[nt]/.test(text)) return text;\n let out = '';\n let quote: string | null = null;\n for (let i = 0; i < text.length; i++) {\n const char = text[i]!;\n const next = text[i + 1];\n if (char === '\\\\' && next !== undefined) {\n if (quote === null && (next === 'n' || next === 't')) {\n out += next === 'n' ? '\\n' : '\\t';\n } else {\n out += char + next;\n }\n i++;\n continue;\n }\n if (quote === null && (char === '\"' || char === \"'\" || char === '`')) quote = char;\n else if (char === quote) quote = null;\n out += char;\n }\n return out;\n}\n\nfunction countOccurrences(haystack: string, needle: string): number {\n let count = 0;\n let index = haystack.indexOf(needle);\n while (index !== -1) {\n count++;\n index = haystack.indexOf(needle, index + needle.length);\n }\n return count;\n}\n\nconst commandName = (command: string) =>\n path\n .basename(command)\n .replace(/\\.(exe|cmd|bat|com)$/i, '')\n .toLowerCase();\n\n/** The workspace tool belt for one repository. */\nexport class WorkspaceTools {\n readonly root: string;\n readonly readOnly: boolean;\n readonly allowedCommands: readonly string[];\n /** Repository-relative paths written or edited so far. */\n readonly changedFiles = new Set<string>();\n /** Successful write_file/edit_file calls so far (grows even when a file is edited again). */\n writeCount = 0;\n private readonly commandTimeoutMs: number;\n private readonly maxOutput: number;\n private readonly env: NodeJS.ProcessEnv | undefined;\n\n constructor(opts: WorkspaceToolsOptions) {\n this.root = path.resolve(opts.root);\n this.readOnly = opts.readOnly ?? false;\n this.allowedCommands = (opts.allowedCommands ?? DEFAULT_ALLOWED_COMMANDS).map((c) =>\n c.toLowerCase(),\n );\n this.commandTimeoutMs = opts.commandTimeoutMs ?? 600_000;\n this.maxOutput = opts.maxOutputChars ?? 16_000;\n this.env = opts.env;\n }\n\n definitions(): ToolDefinition[] {\n return [...TOOL_DEFINITIONS];\n }\n\n /** Executes one tool call. Never throws for bad input: errors become `ok: false` results. */\n async call(name: string, rawArgs: string, signal?: AbortSignal): Promise<ToolOutcome> {\n try {\n if (this.readOnly && !READ_ONLY_TOOL_NAMES.has(name)) {\n return { ok: false, output: `Error: tool \"${name}\" is not available in read-only mode` };\n }\n switch (name) {\n case 'list_dir':\n return this.ok(await this.listDir(parseArgs(listDirArgs, rawArgs)));\n case 'read_file':\n return this.ok(await this.readFile(parseArgs(readFileArgs, rawArgs)));\n case 'write_file':\n return this.ok(await this.writeFile(parseArgs(writeFileArgs, rawArgs)));\n case 'edit_file':\n return this.ok(await this.editFile(parseArgs(editFileArgs, rawArgs)));\n case 'search':\n return this.ok(await this.search(parseArgs(searchArgs, rawArgs)));\n case 'run_command':\n return await this.runCommand(parseArgs(runCommandArgs, rawArgs), signal);\n case 'finish': {\n const { summary } = parseArgs(finishArgs, rawArgs);\n return {\n ok: true,\n output: 'Finished. The runner will now validate.',\n finished: { summary },\n };\n }\n default:\n return { ok: false, output: `Error: unknown tool \"${name}\"` };\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return { ok: false, output: `Error: ${message}` };\n }\n }\n\n private ok(output: string): ToolOutcome {\n return { ok: true, output };\n }\n\n private async listDir(args: z.infer<typeof listDirArgs>): Promise<string> {\n const { abs, rel } = await resolveRepoPath(this.root, args.path);\n const entries = await readdir(abs, { withFileTypes: true });\n const names = entries\n .filter((e) => !(rel === '.' && e.name === '.git'))\n .map((e) => (e.isDirectory() ? `${e.name}/` : e.name))\n .sort();\n const shown = names.slice(0, 500);\n const more = names.length > shown.length ? `\\n[… ${names.length - shown.length} more]` : '';\n return shown.length > 0 ? `${shown.join('\\n')}${more}` : '(empty directory)';\n }\n\n private async readFile(args: z.infer<typeof readFileArgs>): Promise<string> {\n const { abs, rel } = await resolveRepoPath(this.root, args.path);\n const info = await stat(abs);\n if (!info.isFile()) throw new ToolInputError(`${rel} is not a file`);\n const buffer = await readFile(abs);\n if (buffer.subarray(0, 8000).includes(0)) throw new ToolInputError(`${rel} is a binary file`);\n let text = buffer.toString('utf8');\n if (args.offset !== undefined || args.limit !== undefined) {\n const lines = text.split('\\n');\n const start = (args.offset ?? 1) - 1;\n text = lines.slice(start, args.limit ? start + args.limit : undefined).join('\\n');\n }\n if (text.length > this.maxOutput) {\n return `${text.slice(0, this.maxOutput)}\\n[… truncated: ${text.length - this.maxOutput} more characters; use offset/limit to read further]`;\n }\n return text;\n }\n\n private async writeFile(args: z.infer<typeof writeFileArgs>): Promise<string> {\n const { abs, rel } = await resolveRepoPath(this.root, args.path, 'write');\n await mkdir(path.dirname(abs), { recursive: true });\n const content = repairDoubleEscaped(args.content);\n await writeFile(abs, content, 'utf8');\n this.changedFiles.add(rel);\n this.writeCount++;\n return `Wrote ${Buffer.byteLength(content)} bytes to ${rel}`;\n }\n\n private async editFile(args: z.infer<typeof editFileArgs>): Promise<string> {\n const { abs, rel } = await resolveRepoPath(this.root, args.path, 'write');\n const text = await readFile(abs, 'utf8');\n let oldString = args.old_string;\n let newString = repairDoubleEscaped(args.new_string);\n let count = countOccurrences(text, oldString);\n if (count === 0) {\n // Small models sometimes double-escape their arguments; try the repaired form.\n const repaired = repairDoubleEscaped(oldString);\n if (repaired !== oldString) {\n oldString = repaired;\n count = countOccurrences(text, oldString);\n }\n }\n if (count === 0 && text.includes('\\r\\n') && !oldString.includes('\\r\\n')) {\n // The model usually sends LF; retry against a CRLF file.\n oldString = oldString.replace(/\\n/g, '\\r\\n');\n newString = newString.replace(/\\r?\\n/g, '\\r\\n');\n count = countOccurrences(text, oldString);\n }\n if (count === 0) throw new ToolInputError(`old_string not found in ${rel}`);\n if (count > 1) {\n throw new ToolInputError(\n `old_string matches ${count} times in ${rel}; include more surrounding context`,\n );\n }\n const index = text.indexOf(oldString);\n const next = text.slice(0, index) + newString + text.slice(index + oldString.length);\n await writeFile(abs, next, 'utf8');\n this.changedFiles.add(rel);\n this.writeCount++;\n return `Edited ${rel}`;\n }\n\n private async search(args: z.infer<typeof searchArgs>): Promise<string> {\n const { abs } = await resolveRepoPath(this.root, args.path);\n let matcher: (line: string) => boolean;\n if (args.regex) {\n let re: RegExp;\n try {\n re = new RegExp(args.query, args.case_sensitive ? '' : 'i');\n } catch (err) {\n throw new ToolInputError(`invalid regex: ${err instanceof Error ? err.message : err}`);\n }\n matcher = (line) => re.test(line);\n } else {\n const needle = args.case_sensitive ? args.query : args.query.toLowerCase();\n matcher = (line) => (args.case_sensitive ? line : line.toLowerCase()).includes(needle);\n }\n\n const ignored = await this.loadGitignoreMatcher();\n const results: string[] = [];\n const visitFile = async (file: string) => {\n const rel = path.relative(this.root, file).split(path.sep).join('/');\n if (ignored(rel, path.basename(file), false)) return;\n const info = await stat(file);\n if (info.size > MAX_FILE_BYTES) return;\n const buffer = await readFile(file);\n if (buffer.subarray(0, 8000).includes(0)) return;\n const lines = buffer.toString('utf8').split('\\n');\n for (let i = 0; i < lines.length && results.length < args.max_results; i++) {\n const line = (lines[i] as string).replace(/\\r$/, '');\n if (matcher(line)) results.push(`${rel}:${i + 1}: ${line.trim().slice(0, 300)}`);\n }\n };\n const walk = async (dir: string): Promise<void> => {\n let entries: Dirent[];\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n entries.sort((a, b) => a.name.localeCompare(b.name));\n for (const entry of entries) {\n if (results.length >= args.max_results) return;\n const full = path.join(dir, entry.name);\n const rel = path.relative(this.root, full).split(path.sep).join('/');\n if (entry.isDirectory()) {\n if (!SKIP_DIRS.has(entry.name) && !ignored(rel, entry.name, true)) await walk(full);\n } else if (entry.isFile()) {\n await visitFile(full);\n }\n }\n };\n\n const info = await stat(abs);\n if (info.isFile()) await visitFile(abs);\n else await walk(abs);\n if (results.length === 0) return 'No matches.';\n const capped = results.length >= args.max_results ? `\\n[… capped at ${args.max_results}]` : '';\n return `${results.join('\\n')}${capped}`;\n }\n\n private async loadGitignoreMatcher(): Promise<\n (rel: string, name: string, isDir: boolean) => boolean\n > {\n let raw = '';\n try {\n raw = await readFile(path.join(this.root, '.gitignore'), 'utf8');\n } catch {\n return () => false;\n }\n const dirNames = new Set<string>();\n const pathPrefixes: string[] = [];\n const suffixes: string[] = [];\n for (const line of raw.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('!')) continue;\n const dirOnly = trimmed.endsWith('/');\n const clean = trimmed.replace(/^\\/+|\\/+$/g, '');\n if (!clean) continue;\n if (\n clean.startsWith('*.') &&\n !clean.slice(2).includes('/') &&\n !clean.slice(2).includes('*')\n ) {\n if (!dirOnly) suffixes.push(clean.slice(1));\n } else if (!clean.includes('*') && !clean.includes('?')) {\n if (clean.includes('/')) {\n pathPrefixes.push(clean);\n } else {\n dirNames.add(clean);\n if (!dirOnly) pathPrefixes.push(clean);\n }\n }\n }\n return (rel: string, name: string, isDir: boolean) => {\n if (dirNames.has(name)) return true;\n if (!isDir && suffixes.some((ext) => name.endsWith(ext))) return true;\n return pathPrefixes.some((p) => rel === p || rel.startsWith(`${p}/`));\n };\n }\n\n /** Throws when `command args` is not permitted by the allow-list. */\n assertCommandAllowed(command: string, args: readonly string[]): void {\n if (/[\\\\/]/.test(command) || command.includes('\\0')) {\n throw new ToolInputError('command must be a bare executable name, not a path');\n }\n const name = commandName(command);\n if (!this.allowedCommands.includes(name)) {\n throw new ToolInputError(\n `\"${command}\" is not allowed; allowed executables: ${this.allowedCommands.join(', ')}`,\n );\n }\n if (name === 'git') {\n const sub = args[0];\n if (!sub || !READ_ONLY_GIT_SUBCOMMANDS.includes(sub)) {\n throw new ToolInputError(\n `git is limited to read-only subcommands: ${READ_ONLY_GIT_SUBCOMMANDS.join(', ')}`,\n );\n }\n if (args.some((a) => /^--(output|ext-diff|exec)/.test(a))) {\n throw new ToolInputError('git options that write files or run programs are not allowed');\n }\n }\n }\n\n private async runCommand(\n args: z.infer<typeof runCommandArgs>,\n signal?: AbortSignal,\n ): Promise<ToolOutcome> {\n // Models often send the whole command line in `command` (\"node --test\"). Split it with the\n // same quote-aware splitter the validator uses; it is still never run through a shell.\n let command = args.command;\n let argv = args.args;\n if (argv.length === 0 && /\\s/.test(command.trim())) {\n const [head, ...rest] = splitCommand(command.trim());\n if (head) {\n command = head;\n argv = rest;\n }\n }\n this.assertCommandAllowed(command, argv);\n const result = await runProcess({\n command,\n args: argv,\n cwd: this.root,\n timeoutMs: this.commandTimeoutMs,\n env: projectEnv(this.root, this.env ?? process.env),\n maxOutputChars: this.maxOutput,\n ...(signal ? { signal } : {}),\n });\n const half = Math.floor(this.maxOutput / 2);\n const status = result.timedOut\n ? `timed out after ${this.commandTimeoutMs} ms`\n : result.aborted\n ? 'aborted'\n : `exit code ${result.exitCode ?? 'none'}`;\n const output = [\n `$ ${[command, ...argv].join(' ')}`,\n `${status} (${result.durationMs} ms)`,\n '--- stdout ---',\n truncateTail(result.stdout, half) || '(empty)',\n '--- stderr ---',\n truncateTail(result.stderr, half) || '(empty)',\n ].join('\\n');\n return { ok: result.exitCode === 0, output: truncateHead(output, this.maxOutput + 500) };\n }\n}\n","/**\n * Executors implement one task in the repository. The runner talks to them through the\n * {@link Executor} interface; the default `builtin` strategy is DaveCode's own OpenAI\n * tool-calling loop over the {@link Router}. The opt-in `claude-cli` strategy lives in\n * `claude-cli-executor.ts`.\n */\nimport { DAVECODE_SYSTEM_PROMPT } from '../brain/system-prompt';\nimport { countTextTokens, estimateTokens } from '../rate-limiter/tokens';\nimport type { Router } from '../router/router';\nimport type { ChatMessage, LogLevel, TaskNode } from '../types';\nimport { truncateHead } from './process';\nimport { WorkspaceTools } from './tools';\n\nexport type ExecutorLogger = (level: LogLevel, message: string) => void;\n\nexport interface ExecutorTask {\n task: TaskNode;\n /** Output of `buildTaskContext` (global brain, architecture, state, task). */\n context: string;\n /** Repository root; every file operation is confined to it. */\n root: string;\n /** Progress lines (never secrets or file contents). */\n log?: ExecutorLogger;\n}\n\nexport interface ExecutorRunOptions {\n /** 0 for the implementation pass, n for repair cycle n. */\n cycle: number;\n /** Failure report from the validator or judge (repair cycles). */\n failureReport?: string;\n signal?: AbortSignal;\n}\n\nexport type ExecutorStopReason =\n | 'finished'\n | 'no_tool_calls'\n | 'max_iterations'\n | 'token_budget'\n | 'completed';\n\nexport interface ExecutorResult {\n /** The model's own summary of the change (used in the commit body). */\n summary: string;\n stopReason: ExecutorStopReason;\n /** Model round-trips in this pass. */\n iterations: number;\n /** Tokens used by this pass (reported or estimated). */\n tokens: number;\n /** Tokens used by the task so far, across passes. */\n totalTokens: number;\n /** Files written by tools in this session (best effort; git is the source of truth). */\n changedFiles: string[];\n}\n\n/** One task's conversation. Repair passes continue the same session. */\nexport interface ExecutorSession {\n run(opts: ExecutorRunOptions): Promise<ExecutorResult>;\n}\n\nexport interface Executor {\n readonly name: string;\n createSession(task: ExecutorTask): ExecutorSession;\n}\n\n/** Thrown when a pass is aborted (runner stop). */\nexport class ExecutorAbortedError extends Error {\n constructor(message = 'executor aborted') {\n super(message);\n this.name = 'ExecutorAbortedError';\n }\n}\n\n/** Thrown when the executor cannot run at all (no account, CLI missing, upstream failure). */\nexport class ExecutorError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'ExecutorError';\n }\n}\n\nexport const TASK_INSTRUCTIONS = `You are implementing the CURRENT TASK described below in the repository that is your working directory.\n\nRules:\n- Inspect the code before changing it. Use the tools; every path is relative to the repository root.\n- Keep the change minimal and focused on the task and its acceptance criteria. Follow the existing conventions.\n- Do not edit anything under .davecode/ (the runner maintains it) and do not commit, merge or switch branches: the runner owns git.\n- You may run the project's checks with run_command before finishing.\n- When the task is complete, call the finish tool with a concise summary of the change.`;\n\n/** The user message that opens a task conversation. */\nexport function initialTaskPrompt(context: string): string {\n return `${TASK_INSTRUCTIONS}\\n\\n${context}`;\n}\n\n/** The user message for repair cycle `cycle`. */\nexport function repairPrompt(cycle: number, report: string, maxChars = 30_000): string {\n return `REPAIR CYCLE ${cycle}: the quality gates failed after your last change. Read the exact output below, diagnose the root cause, apply a targeted fix, and call finish again.\\n\\n${truncateHead(report.trim(), maxChars)}`;\n}\n\n/** `auto` → `davecode/auto`; anything containing `/` is used verbatim. */\nexport function routeModel(route: string): string {\n return route.includes('/') ? route : `davecode/${route}`;\n}\n\nexport interface BuiltinExecutorOptions {\n router: Pick<Router, 'complete'>;\n /** Route (`auto`) or model id; see {@link routeModel}. */\n route: string;\n /** Round-trips per pass (default 40). */\n maxIterations?: number;\n /** Tokens per task across passes (default 1 500 000). */\n maxTaskTokens?: number;\n allowedCommands?: readonly string[];\n commandTimeoutMs?: number;\n temperature?: number;\n env?: NodeJS.ProcessEnv;\n}\n\nconst KEEP_RECENT_TOOL_RESULTS = 12;\nconst HISTORY_SOFT_LIMIT_CHARS = 240_000;\n\nfunction textOf(content: ChatMessage['content']): string {\n if (typeof content === 'string') return content;\n if (!content) return '';\n return content.map((p) => (p.type === 'text' ? p.text : '')).join('');\n}\n\n/** Elides old tool results once the conversation grows large, keeping the recent ones. */\nfunction compactHistory(messages: ChatMessage[]): void {\n const size = messages.reduce((n, m) => n + textOf(m.content).length, 0);\n if (size <= HISTORY_SOFT_LIMIT_CHARS) return;\n const toolIndexes = messages.flatMap((m, i) => (m.role === 'tool' ? [i] : []));\n for (const i of toolIndexes.slice(0, -KEEP_RECENT_TOOL_RESULTS)) {\n const message = messages[i] as ChatMessage;\n const text = textOf(message.content);\n if (text.length > 300) {\n message.content = `${text.slice(0, 200)}\\n[… older tool output elided to save context]`;\n }\n }\n}\n\nfunction describeCall(name: string, rawArgs: string): string {\n try {\n const args = JSON.parse(rawArgs) as Record<string, unknown>;\n if (typeof args.path === 'string') return `${name} ${args.path}`;\n if (name === 'run_command' && typeof args.command === 'string') {\n const rest = Array.isArray(args.args) ? args.args.filter((a) => typeof a === 'string') : [];\n return `${name} ${[args.command, ...rest].join(' ').slice(0, 120)}`;\n }\n if (name === 'search' && typeof args.query === 'string') {\n return `${name} ${JSON.stringify(args.query.slice(0, 60))}`;\n }\n } catch {\n // fall through\n }\n return name;\n}\n\n/** DaveCode's own tool loop over the router (OpenAI tool calling). */\nexport class BuiltinExecutor implements Executor {\n readonly name = 'builtin';\n\n constructor(private readonly options: BuiltinExecutorOptions) {}\n\n createSession(input: ExecutorTask): ExecutorSession {\n const opts = this.options;\n const model = routeModel(opts.route);\n const maxIterations = opts.maxIterations ?? 40;\n const maxTaskTokens = opts.maxTaskTokens ?? 1_500_000;\n const tools = new WorkspaceTools({\n root: input.root,\n ...(opts.allowedCommands ? { allowedCommands: opts.allowedCommands } : {}),\n ...(opts.commandTimeoutMs ? { commandTimeoutMs: opts.commandTimeoutMs } : {}),\n ...(opts.env ? { env: opts.env } : {}),\n });\n const definitions = tools.definitions();\n const log: ExecutorLogger = input.log ?? (() => undefined);\n const messages: ChatMessage[] = [\n { role: 'system', content: DAVECODE_SYSTEM_PROMPT },\n { role: 'user', content: initialTaskPrompt(input.context) },\n ];\n let totalTokens = 0;\n\n const run = async (runOpts: ExecutorRunOptions): Promise<ExecutorResult> => {\n const { signal } = runOpts;\n if (runOpts.cycle > 0 && runOpts.failureReport) {\n messages.push({\n role: 'user',\n content: repairPrompt(runOpts.cycle, runOpts.failureReport),\n });\n }\n let iterations = 0;\n let passTokens = 0;\n let nudged = false;\n // Small models often call finish before editing anything; push back once per pass.\n const writesAtStart = tools.writeCount;\n let rejectedEmptyFinish = false;\n const result = (summary: string, stopReason: ExecutorStopReason): ExecutorResult => ({\n summary,\n stopReason,\n iterations,\n tokens: passTokens,\n totalTokens,\n changedFiles: [...tools.changedFiles],\n });\n\n while (iterations < maxIterations) {\n if (signal?.aborted) throw new ExecutorAbortedError();\n if (totalTokens >= maxTaskTokens) {\n log('warn', `token budget of ${maxTaskTokens} reached; stopping this pass`);\n return result('Stopped: per-task token budget reached.', 'token_budget');\n }\n compactHistory(messages);\n iterations++;\n let completion: Awaited<ReturnType<typeof opts.router.complete>>['completion'];\n try {\n ({ completion } = await opts.router.complete(\n {\n model,\n messages,\n tools: definitions,\n tool_choice: 'auto',\n ...(opts.temperature !== undefined ? { temperature: opts.temperature } : {}),\n },\n signal ? { signal } : {},\n ));\n } catch (err) {\n if (signal?.aborted) throw new ExecutorAbortedError();\n throw new ExecutorError(\n `model call failed: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n const message = completion.choices[0]?.message ?? { role: 'assistant', content: '' };\n const reported = completion.usage?.total_tokens ?? 0;\n const used =\n reported > 0\n ? reported\n : estimateTokens(messages) +\n countTextTokens(\n textOf(message.content) +\n (message.tool_calls ?? []).map((c) => c.function.arguments).join(''),\n );\n passTokens += used;\n totalTokens += used;\n\n const calls = message.tool_calls ?? [];\n const assistant: ChatMessage = { role: 'assistant', content: message.content ?? null };\n if (calls.length > 0) assistant.tool_calls = calls;\n messages.push(assistant);\n\n if (calls.length === 0) {\n const text = textOf(message.content).trim();\n if (!nudged) {\n nudged = true;\n messages.push({\n role: 'user',\n content:\n 'Continue with the tools. When the task is fully implemented, call the finish tool with a summary.',\n });\n continue;\n }\n log('warn', 'model stopped calling tools without calling finish');\n return result(text || 'No summary provided.', 'no_tool_calls');\n }\n nudged = false;\n\n let finished: string | undefined;\n for (const call of calls) {\n if (signal?.aborted) throw new ExecutorAbortedError();\n log('debug', `tool ${describeCall(call.function.name, call.function.arguments)}`);\n const outcome = await tools.call(call.function.name, call.function.arguments, signal);\n if (!outcome.ok) {\n const reason = outcome.output.split('\\n', 1)[0]?.slice(0, 200) ?? '';\n log('debug', `tool ${call.function.name} failed: ${reason}`);\n }\n if (outcome.finished) finished = outcome.finished.summary;\n messages.push({\n role: 'tool',\n tool_call_id: call.id,\n name: call.function.name,\n content: outcome.output,\n });\n }\n if (finished !== undefined) {\n if (tools.writeCount === writesAtStart && !rejectedEmptyFinish) {\n rejectedEmptyFinish = true;\n log('debug', 'finish rejected: no files were changed in this pass');\n messages.push({\n role: 'user',\n content:\n 'You called finish, but no files were changed in this pass, so the task cannot be ' +\n 'complete yet. Read the relevant files, change them with edit_file or write_file, ' +\n 'then call finish.',\n });\n continue;\n }\n return result(finished, 'finished');\n }\n }\n log('warn', `iteration limit of ${maxIterations} reached`);\n return result('Stopped: iteration limit reached.', 'max_iterations');\n };\n\n return { run };\n }\n}\n","/**\n * Opt-in `claude-cli` executor: delegates a task to the Claude Code CLI running headlessly in\n * the repository, with `CLAUDE_CONFIG_DIR` pointing at the chosen account's sandbox so the\n * login stays isolated. The prompt goes on stdin, never on the command line; on Windows `.cmd`\n * shims every argument must pass the strict shell-safe allow-list (see `providers/shared/cli`).\n */\nimport { DAVECODE_SYSTEM_PROMPT } from '../brain/system-prompt';\nimport type { SandboxManager } from '../identity/sandbox';\nimport {\n cliSettings,\n isShellSafeArg,\n needsShell,\n resolveOnPath,\n runCli,\n} from '../providers/shared/cli';\nimport { redact } from '../providers/shared/errors';\nimport { asNumber, asString, isRecord } from '../providers/shared/util';\nimport type { Account } from '../types';\nimport {\n type Executor,\n ExecutorAbortedError,\n ExecutorError,\n type ExecutorLogger,\n type ExecutorResult,\n type ExecutorRunOptions,\n type ExecutorSession,\n type ExecutorTask,\n repairPrompt,\n} from './executor';\n\nexport const CLAUDE_CLI_INSTRUCTIONS = `You are implementing the CURRENT TASK described below in the repository that is your working directory.\n\nRules:\n- Inspect the code before changing it. Keep the change minimal and focused on the task and its acceptance criteria. Follow the existing conventions.\n- Do not edit anything under .davecode/ (the runner maintains it) and do not commit, merge, push or switch branches: the runner owns git.\n- You may run the project's checks before finishing.\n- When the task is complete, reply with a concise summary of the change (it becomes the commit message body).`;\n\nexport interface ClaudeCliExecutorOptions {\n accounts: { list(): Account[] };\n sandboxes: Pick<SandboxManager, 'ensure'>;\n /** Account to use; defaults to the enabled `claude-cli` account with the best priority. */\n accountId?: string;\n /** `--model` alias (e.g. `sonnet`). */\n model?: string;\n /** Tools pre-approved with `--allowedTools`. */\n allowedTools: readonly string[];\n /** Hard timeout per CLI invocation (default 30 min). */\n timeoutMs?: number;\n /** Per-task token budget, checked before each invocation. */\n maxTaskTokens?: number;\n}\n\nconst SAFE_MODEL = /^[\\w.:[\\]-]+$/;\nconst SAFE_SESSION = /^[A-Za-z0-9-]{8,128}$/;\n\n/** Picks the account: explicit id, else the enabled `claude-cli` account with best priority. */\nexport function selectClaudeAccount(accounts: Account[], accountId?: string): Account {\n if (accountId) {\n const account = accounts.find((a) => a.id === accountId);\n if (account?.provider !== 'claude-cli') {\n throw new ExecutorError(\n `runner.claudeCli.accountId \"${accountId}\" is not a claude-cli account`,\n );\n }\n if (!account.enabled) throw new ExecutorError(`claude-cli account \"${accountId}\" is disabled`);\n return account;\n }\n const candidates = accounts\n .filter((a) => a.provider === 'claude-cli' && a.enabled && a.status !== 'disabled')\n .sort((a, b) => a.priority - b.priority || a.createdAt.localeCompare(b.createdAt));\n const first = candidates[0];\n if (!first) {\n throw new ExecutorError(\n 'runner.executor is \"claude-cli\" but no enabled claude-cli account exists; add one first',\n );\n }\n return first;\n}\n\nexport class ClaudeCliExecutor implements Executor {\n readonly name = 'claude-cli';\n\n constructor(private readonly options: ClaudeCliExecutorOptions) {}\n\n createSession(input: ExecutorTask): ExecutorSession {\n const log: ExecutorLogger = input.log ?? (() => undefined);\n let sessionId: string | undefined;\n let totalTokens = 0;\n\n const run = async (runOpts: ExecutorRunOptions): Promise<ExecutorResult> => {\n const opts = this.options;\n if (opts.maxTaskTokens !== undefined && totalTokens >= opts.maxTaskTokens) {\n return {\n summary: 'Stopped: per-task token budget reached.',\n stopReason: 'token_budget',\n iterations: 0,\n tokens: 0,\n totalTokens,\n changedFiles: [],\n };\n }\n const account = selectClaudeAccount(opts.accounts.list(), opts.accountId);\n const sandboxDir = opts.sandboxes.ensure(account.id);\n const settings = cliSettings({ account, sandboxDir }, 'claude');\n const shell = needsShell(resolveOnPath(settings.command));\n\n const args = ['-p', '--output-format', 'stream-json', '--verbose'];\n args.push('--permission-mode', 'acceptEdits');\n if (opts.model) {\n if (!SAFE_MODEL.test(opts.model)) {\n throw new ExecutorError('runner.claudeCli.model contains unsupported characters');\n }\n args.push('--model', opts.model);\n }\n const resume = runOpts.cycle > 0 && sessionId !== undefined && SAFE_SESSION.test(sessionId);\n if (resume && sessionId) args.push('--resume', sessionId);\n let tools = [...opts.allowedTools];\n if (shell) {\n const dropped = tools.filter((t) => !isShellSafeArg(t));\n if (dropped.length > 0) {\n log(\n 'warn',\n `claude is a Windows .cmd shim; not pre-approving tools with unsafe characters: ${dropped.join(', ')}`,\n );\n }\n tools = tools.filter(isShellSafeArg);\n }\n if (tools.length > 0) args.push('--allowedTools', ...tools);\n\n let prompt: string;\n if (resume && runOpts.failureReport) {\n prompt = repairPrompt(runOpts.cycle, runOpts.failureReport);\n } else {\n prompt = `${DAVECODE_SYSTEM_PROMPT}\\n\\n${CLAUDE_CLI_INSTRUCTIONS}\\n\\n${input.context}`;\n if (runOpts.cycle > 0 && runOpts.failureReport) {\n prompt += `\\n\\n${repairPrompt(runOpts.cycle, runOpts.failureReport)}`;\n }\n }\n\n const timeout = AbortSignal.timeout(opts.timeoutMs ?? 1_800_000);\n const signal = runOpts.signal ? AbortSignal.any([runOpts.signal, timeout]) : timeout;\n log(\n 'info',\n `delegating to Claude Code CLI (account ${account.id}${resume ? ', resumed' : ''})`,\n );\n\n let cli: ReturnType<typeof runCli>;\n try {\n cli = runCli({\n provider: 'claude-cli',\n accountId: account.id,\n settings,\n args,\n env: { CLAUDE_CONFIG_DIR: sandboxDir },\n cwd: input.root,\n stdin: prompt,\n signal,\n });\n } catch (err) {\n if (runOpts.signal?.aborted) throw new ExecutorAbortedError();\n throw new ExecutorError(err instanceof Error ? err.message : String(err), { cause: err });\n }\n\n let resultText: string | undefined;\n let isError = false;\n let tokens = 0;\n let turns = 0;\n try {\n for await (const raw of cli.events) {\n if (!isRecord(raw)) continue;\n const type = asString(raw.type);\n const sid = asString(raw.session_id);\n if (sid) sessionId = sid;\n if (type === 'assistant' && raw.parent_tool_use_id == null && isRecord(raw.message)) {\n turns++;\n const content = Array.isArray(raw.message.content) ? raw.message.content : [];\n for (const block of content) {\n if (isRecord(block) && block.type === 'tool_use') {\n log('debug', `claude tool ${asString(block.name) ?? 'unknown'}`);\n }\n }\n } else if (type === 'result') {\n resultText = asString(raw.result) ?? '';\n isError = raw.is_error === true || (asString(raw.subtype) ?? 'success') !== 'success';\n const usage = isRecord(raw.usage) ? raw.usage : {};\n tokens =\n (asNumber(usage.input_tokens) ?? 0) +\n (asNumber(usage.output_tokens) ?? 0) +\n (asNumber(usage.cache_creation_input_tokens) ?? 0);\n }\n }\n } catch (err) {\n if (runOpts.signal?.aborted) throw new ExecutorAbortedError();\n throw new ExecutorError(err instanceof Error ? err.message : String(err), { cause: err });\n }\n\n let exit: Awaited<typeof cli.exit>;\n try {\n exit = await cli.exit;\n } catch (err) {\n throw new ExecutorError(err instanceof Error ? err.message : String(err), { cause: err });\n }\n if (exit.aborted || signal.aborted) {\n if (runOpts.signal?.aborted) throw new ExecutorAbortedError();\n throw new ExecutorError(\n `Claude Code CLI timed out after ${opts.timeoutMs ?? 1_800_000} ms`,\n );\n }\n totalTokens += tokens;\n if (exit.code !== 0 || isError || resultText === undefined) {\n const detail = redact(\n (isError && resultText ? resultText : exit.stderr || resultText || '').trim(),\n ).slice(0, 1000);\n throw new ExecutorError(\n `Claude Code CLI failed (exit ${exit.code ?? 'none'})${detail ? `: ${detail}` : ''}`,\n );\n }\n return {\n summary: resultText.trim() || 'Implemented by Claude Code.',\n stopReason: 'completed',\n iterations: Math.max(1, turns),\n tokens,\n totalTokens,\n changedFiles: [],\n };\n };\n\n return { run };\n }\n}\n","/**\n * Minimal git wrapper for the autonomous runner. Every call is `execFile('git', args)`: no\n * shell, arguments passed verbatim. The wrapper never force-pushes and never rewrites history\n * on the base branch.\n */\nimport { execFile } from 'node:child_process';\nimport { resolveOnPath } from '../providers/shared/cli';\n\n/** Paths the runner owns (the project brain); excluded from task commits and dirty checks. */\nexport const BRAIN_DIR = '.davecode';\nconst BRAIN_FILES = [\n '.davecode/STATE.md',\n '.davecode/ARCHITECTURE.md',\n '.davecode/TASK_GRAPH.json',\n];\n\nexport class GitError extends Error {\n constructor(\n message: string,\n readonly args: readonly string[],\n readonly exitCode: number | null,\n readonly stderr: string,\n ) {\n super(message);\n this.name = 'GitError';\n }\n}\n\nexport interface GitOptions {\n /** git executable (default `git`). */\n binary?: string;\n /** Per-command timeout (default 120 s). */\n timeoutMs?: number;\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface CommitOptions {\n /** Skip commit hooks (used only for snapshots of failed attempts). */\n noVerify?: boolean;\n /** Allow a commit with no changes. */\n allowEmpty?: boolean;\n}\n\nexport interface PullRequestResult {\n /** `pr`: pushed and opened with gh. `unavailable`: gh/remote missing, caller should merge. */\n outcome: 'pr' | 'unavailable';\n url?: string;\n reason?: string;\n}\n\nconst SAFE_REF = /^(?!.*\\.\\.)(?!.*\\/\\/)(?!\\/)(?!.*\\/$)(?!.*\\.lock$)[A-Za-z0-9._/-]+$/;\n\n/** Rejects ref names git would refuse or that could be mistaken for options. */\nexport function assertSafeRef(name: string): string {\n if (!SAFE_REF.test(name) || name.startsWith('-')) {\n throw new GitError(`Unsafe git ref name: ${JSON.stringify(name)}`, [], null, '');\n }\n return name;\n}\n\nexport class Git {\n private readonly binary: string;\n private readonly timeoutMs: number;\n private readonly env: NodeJS.ProcessEnv;\n\n constructor(\n readonly cwd: string,\n opts: GitOptions = {},\n ) {\n this.env = { ...(opts.env ?? process.env), GIT_TERMINAL_PROMPT: '0' };\n this.binary = resolveOnPath(opts.binary ?? 'git', this.env);\n this.timeoutMs = opts.timeoutMs ?? 120_000;\n }\n\n /** Runs `git <args>` and returns stdout. Throws {@link GitError} on a non-zero exit. */\n run(args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(\n this.binary,\n args,\n {\n cwd: this.cwd,\n env: this.env,\n timeout: this.timeoutMs,\n maxBuffer: 64 * 1024 * 1024,\n windowsHide: true,\n encoding: 'utf8',\n },\n (err, stdout, stderr) => {\n if (err) {\n const code = typeof err.code === 'number' ? err.code : null;\n const detail = (stderr || stdout || err.message).trim().slice(0, 2000);\n reject(new GitError(`git ${args[0] ?? ''} failed: ${detail}`, args, code, stderr));\n return;\n }\n resolve(stdout);\n },\n );\n });\n }\n\n /** True when `cwd` is inside a git work tree. */\n async isRepo(): Promise<boolean> {\n try {\n return (await this.run(['rev-parse', '--is-inside-work-tree'])).trim() === 'true';\n } catch {\n return false;\n }\n }\n\n /** Absolute path of the work tree root. */\n async topLevel(): Promise<string> {\n return (await this.run(['rev-parse', '--show-toplevel'])).trim();\n }\n\n async currentBranch(): Promise<string> {\n return (await this.run(['rev-parse', '--abbrev-ref', 'HEAD'])).trim();\n }\n\n async branchExists(name: string): Promise<boolean> {\n try {\n await this.run(['rev-parse', '--verify', '--quiet', `refs/heads/${assertSafeRef(name)}`]);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Porcelain status entries (`XY path`). With `ignoreBrain`, changes under `.davecode/` are\n * left out: the runner and the dashboard write there continuously.\n */\n async status(opts: { ignoreBrain?: boolean } = {}): Promise<string[]> {\n const out = await this.run(['status', '--porcelain', '--untracked-files=all']);\n return out\n .split('\\n')\n .map((l) => l.replace(/\\r$/, ''))\n .filter((l) => l.trim().length > 0)\n .filter((l) => {\n if (!opts.ignoreBrain) return true;\n const file = l.slice(3).replace(/^\"|\"$/g, '');\n return !(file === BRAIN_DIR || file.startsWith(`${BRAIN_DIR}/`));\n });\n }\n\n async isClean(opts: { ignoreBrain?: boolean } = {}): Promise<boolean> {\n return (await this.status(opts)).length === 0;\n }\n\n async checkout(branch: string): Promise<void> {\n await this.run(['checkout', '--quiet', assertSafeRef(branch)]);\n }\n\n /** Creates `branch` from `base` and checks it out. */\n async createBranch(branch: string, base: string): Promise<void> {\n await this.run(['checkout', '--quiet', '-b', assertSafeRef(branch), assertSafeRef(base)]);\n }\n\n async renameBranch(from: string, to: string): Promise<void> {\n await this.run(['branch', '-m', assertSafeRef(from), assertSafeRef(to)]);\n }\n\n /** Deletes a fully merged branch (`-d`, never `-D`). */\n async deleteBranch(branch: string): Promise<void> {\n await this.run(['branch', '-d', assertSafeRef(branch)]);\n }\n\n /** Stages every change except the project brain. */\n async stageAll(): Promise<void> {\n await this.run(['add', '--all', '--', '.', `:(exclude)${BRAIN_DIR}`]);\n }\n\n /** True when the index differs from HEAD. */\n async hasStagedChanges(): Promise<boolean> {\n try {\n await this.run(['diff', '--cached', '--quiet']);\n return false;\n } catch (err) {\n if (err instanceof GitError && err.exitCode === 1) return true;\n throw err;\n }\n }\n\n /** Stages everything (brain excluded) and commits. Returns false when there was nothing. */\n async commitAll(message: string, opts: CommitOptions = {}): Promise<boolean> {\n await this.stageAll();\n if (!opts.allowEmpty && !(await this.hasStagedChanges())) return false;\n const args = ['commit', '--quiet', '-m', message];\n if (opts.noVerify) args.push('--no-verify');\n if (opts.allowEmpty) args.push('--allow-empty');\n await this.run(args);\n return true;\n }\n\n /**\n * Commits pending STATE.md / ARCHITECTURE.md / TASK_GRAPH.json changes on the current branch.\n * Ignored or untracked-and-ignored brain files are skipped. Returns false when nothing changed.\n */\n async commitBrain(message: string): Promise<boolean> {\n const out = await this.run(['status', '--porcelain', '--', ...BRAIN_FILES]);\n const changed = out\n .split('\\n')\n .map((l) => l.replace(/\\r$/, ''))\n .filter((l) => l.trim().length > 0)\n .map((l) => l.slice(3).replace(/^\"|\"$/g, ''))\n .filter((f) => BRAIN_FILES.includes(f));\n if (changed.length === 0) return false;\n await this.run(['add', '--', ...changed]);\n if (!(await this.hasStagedChanges())) return false;\n await this.run(['commit', '--quiet', '-m', message, '--', ...changed]);\n return true;\n }\n\n /** `git merge --no-ff` of `branch` into the current branch; aborts the merge on conflict. */\n async mergeNoFf(branch: string, message: string): Promise<void> {\n try {\n await this.run(['merge', '--no-ff', '--no-edit', '-m', message, assertSafeRef(branch)]);\n } catch (err) {\n await this.abortMerge();\n throw err;\n }\n }\n\n /** Aborts an in-progress merge, if any. */\n async abortMerge(): Promise<void> {\n try {\n await this.run(['merge', '--abort']);\n } catch {\n // no merge in progress\n }\n }\n\n /**\n * Restores a usable state after a failure on a task branch: aborts a pending merge, then\n * checks out `base`. Uncommitted work must have been committed (or discarded) first.\n */\n async restore(base: string): Promise<void> {\n await this.abortMerge();\n if ((await this.currentBranch()) !== base) await this.checkout(base);\n }\n\n /** Discards uncommitted changes outside the brain (tracked and untracked). */\n async discardChanges(): Promise<void> {\n const outsideBrain = ['--', '.', `:(exclude)${BRAIN_DIR}`];\n await this.run(['reset', '--quiet', 'HEAD', ...outsideBrain]);\n await this.run(['checkout', '--quiet', ...outsideBrain]);\n await this.run(['clean', '-fd', '--quiet', ...outsideBrain]);\n }\n\n /** `git diff --stat` of `range` (e.g. `main...branch`) or of the index with `cached`. */\n async diffStat(range?: string, opts: { cached?: boolean } = {}): Promise<string> {\n const args = ['diff', '--stat'];\n if (opts.cached) args.push('--cached');\n if (range) args.push(range);\n args.push('--', '.', `:(exclude)${BRAIN_DIR}`);\n return (await this.run(args)).trim();\n }\n\n /** Full patch for `range` or the index. */\n async diff(range?: string, opts: { cached?: boolean } = {}): Promise<string> {\n const args = ['diff'];\n if (opts.cached) args.push('--cached');\n if (range) args.push(range);\n args.push('--', '.', `:(exclude)${BRAIN_DIR}`);\n return this.run(args);\n }\n\n async hasRemote(name = 'origin'): Promise<boolean> {\n try {\n await this.run(['remote', 'get-url', name]);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Pushes `branch` (never with `--force`) and opens a PR with `gh`. Returns `unavailable` when\n * `gh` or the remote is missing so the caller can fall back to a local merge.\n */\n async openPullRequest(opts: {\n branch: string;\n base: string;\n title: string;\n body: string;\n gh?: string;\n }): Promise<PullRequestResult> {\n if (!(await this.hasRemote())) return { outcome: 'unavailable', reason: 'no \"origin\" remote' };\n const gh = resolveOnPath(opts.gh ?? 'gh', this.env);\n if (/\\.(cmd|bat)$/i.test(gh)) {\n return { outcome: 'unavailable', reason: 'gh is a shell shim; refusing to pass text args' };\n }\n const runGh = (args: string[]) =>\n new Promise<string>((resolve, reject) => {\n execFile(\n gh,\n args,\n { cwd: this.cwd, env: this.env, timeout: this.timeoutMs, windowsHide: true },\n (err, stdout, stderr) =>\n err ? reject(new Error((stderr || err.message).trim())) : resolve(stdout.trim()),\n );\n });\n try {\n await runGh(['--version']);\n } catch {\n return { outcome: 'unavailable', reason: 'gh CLI not found' };\n }\n await this.run(['push', '--set-upstream', 'origin', assertSafeRef(opts.branch)]);\n const url = await runGh([\n 'pr',\n 'create',\n '--base',\n assertSafeRef(opts.base),\n '--head',\n assertSafeRef(opts.branch),\n '--title',\n opts.title,\n '--body',\n opts.body,\n ]);\n return { outcome: 'pr', url: url.split('\\n').at(-1) ?? url };\n }\n}\n","/**\n * Optional acceptance judge, run after the deterministic checks pass (`runner.judge`):\n * `none` (free, always passes), `jev` (TypeSafe Jev via the OpenRouter Decisions API, paid) or\n * `llm` (one of the user's own routes returning a strict JSON verdict).\n */\nimport { z } from 'zod';\nimport type { DaveConfig } from '../config/schema';\nimport type { Router } from '../router/router';\nimport type { TaskNode } from '../types';\nimport { routeModel } from './executor';\nimport { truncateHead } from './process';\nimport type { ValidationReport } from './validator';\n\nexport type JudgeKind = DaveConfig['runner']['judge']['kind'];\nexport type JudgeConfig = DaveConfig['runner']['judge'];\n\nexport interface JudgeInput {\n task: TaskNode;\n /** `git diff --stat` of the change. */\n diffStat: string;\n /** Full patch (truncated before it is sent). */\n diff?: string;\n validation: ValidationReport;\n signal?: AbortSignal;\n}\n\nexport interface JudgeVerdict {\n kind: JudgeKind;\n pass: boolean;\n /** 0..1 when the judge reports one. */\n confidence?: number;\n reasons: string[];\n /** Upstream usage when reported (Jev: tokens and USD cost). */\n usage?: { inputTokens?: number; outputTokens?: number; cost?: number };\n}\n\nexport interface Judge {\n readonly kind: JudgeKind;\n judge(input: JudgeInput): Promise<JudgeVerdict>;\n}\n\n/**\n * The judge could not reach a verdict (missing key, HTTP error, malformed response). The task\n * must not be merged.\n */\nexport class JudgeError extends Error {\n constructor(\n message: string,\n readonly code: 'missing_key' | 'http' | 'invalid_response' | 'network',\n ) {\n super(message);\n this.name = 'JudgeError';\n }\n}\n\nexport const DEFAULT_JEV_BASE_URL = 'https://openrouter.ai/api/alpha';\nexport const DEFAULT_JEV_MODEL = 'typesafe/jev-1.13';\nconst MAX_DIFF_CHARS = 16_000;\nconst MAX_VALIDATION_CHARS = 6_000;\n\n/** Acceptance criteria to judge; falls back to the title/description when none are listed. */\nexport function acceptanceOf(task: TaskNode): string[] {\n if (task.acceptance && task.acceptance.length > 0) return task.acceptance;\n return [task.description ? `${task.title}: ${task.description}` : task.title];\n}\n\nfunction taskText(task: TaskNode): string {\n return task.description ? `${task.title}\\n\\n${task.description}` : task.title;\n}\n\n/** `none`: deterministic checks only. */\nexport class NoneJudge implements Judge {\n readonly kind = 'none' as const;\n async judge(): Promise<JudgeVerdict> {\n return {\n kind: 'none',\n pass: true,\n reasons: ['deterministic checks only (runner.judge.kind = none)'],\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// TypeSafe Jev (OpenRouter Decisions API)\n// ---------------------------------------------------------------------------\n\nconst jevResponseSchema = z.object({\n answers: z.object({\n acceptance_met: z.object({\n type: z.literal('noul'),\n noul: z.number().min(0).max(1),\n }),\n }),\n usage: z\n .object({\n input_tokens: z.number().optional(),\n output_tokens: z.number().optional(),\n cost: z.number().optional(),\n })\n .optional(),\n});\n\nexport interface JevJudgeOptions {\n threshold: number;\n model?: string;\n baseUrl?: string;\n /** Environment holding `OPENROUTER_API_KEY` or `JEV_API_KEY` (default `process.env`). */\n env?: NodeJS.ProcessEnv;\n fetch?: typeof fetch;\n /** Request timeout (default 60 s). */\n timeoutMs?: number;\n}\n\nexport class JevJudge implements Judge {\n readonly kind = 'jev' as const;\n\n constructor(private readonly options: JevJudgeOptions) {}\n\n /** The request body sent to `POST {baseUrl}/decisions`. */\n buildRequest(input: JudgeInput): Record<string, unknown> {\n return {\n model: this.options.model ?? DEFAULT_JEV_MODEL,\n state: {\n task: taskText(input.task),\n acceptance: acceptanceOf(input.task),\n diff_stat: input.diffStat,\n validation: truncateHead(input.validation.summary, MAX_VALIDATION_CHARS),\n ...(input.diff ? { diff: truncateHead(input.diff, MAX_DIFF_CHARS) } : {}),\n },\n questions: {\n acceptance_met: {\n type: 'noul',\n instructions: 'Does the change satisfy every acceptance criterion of the task?',\n criteria: {\n true: 'Every acceptance criterion is demonstrably satisfied by the diff and the passing checks.',\n false:\n 'At least one acceptance criterion is missing, only partially met, or cannot be verified from the evidence.',\n },\n },\n },\n };\n }\n\n async judge(input: JudgeInput): Promise<JudgeVerdict> {\n const env = this.options.env ?? process.env;\n const key = env.OPENROUTER_API_KEY?.trim() || env.JEV_API_KEY?.trim();\n if (!key) {\n throw new JudgeError(\n 'runner.judge.kind is \"jev\" but neither OPENROUTER_API_KEY nor JEV_API_KEY is set',\n 'missing_key',\n );\n }\n const base = (this.options.baseUrl ?? DEFAULT_JEV_BASE_URL).replace(/\\/+$/, '');\n const timeout = AbortSignal.timeout(this.options.timeoutMs ?? 60_000);\n const signal = input.signal ? AbortSignal.any([input.signal, timeout]) : timeout;\n const doFetch = this.options.fetch ?? fetch;\n\n let res: Response;\n try {\n res = await doFetch(`${base}/decisions`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${key}` },\n body: JSON.stringify(this.buildRequest(input)),\n signal,\n });\n } catch (err) {\n throw new JudgeError(\n `Jev request failed: ${err instanceof Error ? err.message : String(err)}`,\n 'network',\n );\n }\n const text = await res.text();\n if (!res.ok) {\n const detail = text.split(key).join('[redacted]').slice(0, 300);\n throw new JudgeError(`Jev returned HTTP ${res.status}: ${detail}`, 'http');\n }\n let json: unknown;\n try {\n json = JSON.parse(text);\n } catch {\n throw new JudgeError('Jev returned a non-JSON response', 'invalid_response');\n }\n const parsed = jevResponseSchema.safeParse(json);\n if (!parsed.success) {\n throw new JudgeError('Jev response has no acceptance_met noul answer', 'invalid_response');\n }\n const noul = parsed.data.answers.acceptance_met.noul;\n const pass = noul >= this.options.threshold;\n const usage = parsed.data.usage;\n return {\n kind: 'jev',\n pass,\n confidence: noul,\n reasons: [`Jev acceptance_met = ${noul.toFixed(3)} (threshold ${this.options.threshold})`],\n ...(usage\n ? {\n usage: {\n ...(usage.input_tokens !== undefined ? { inputTokens: usage.input_tokens } : {}),\n ...(usage.output_tokens !== undefined ? { outputTokens: usage.output_tokens } : {}),\n ...(usage.cost !== undefined ? { cost: usage.cost } : {}),\n },\n }\n : {}),\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// LLM judge over the user's own routes\n// ---------------------------------------------------------------------------\n\nexport const llmVerdictSchema = z.object({\n pass: z.boolean(),\n confidence: z.number().min(0).max(1),\n reasons: z.array(z.string()),\n});\n\nexport const LLM_JUDGE_PROMPT = `You are a strict code-review judge. Decide whether a change satisfies EVERY acceptance criterion of a task, using only the evidence provided (task, criteria, diff and the output of the deterministic checks, which already passed).\n\nRespond with ONLY a JSON object, no prose and no code fences:\n{\"pass\": boolean, \"confidence\": number between 0 and 1, \"reasons\": [short strings]}\n\nSet \"pass\" to false if any criterion is unmet, partially met, or cannot be verified from the evidence.`;\n\n/** Extracts the first JSON object from a model reply (tolerates code fences and prose). */\nexport function extractJsonObject(text: string): unknown {\n const fenced = /```(?:json)?\\s*([\\s\\S]*?)```/i.exec(text)?.[1];\n const candidate = (fenced ?? text).trim();\n const start = candidate.indexOf('{');\n const end = candidate.lastIndexOf('}');\n if (start === -1 || end <= start) throw new Error('no JSON object in the reply');\n return JSON.parse(candidate.slice(start, end + 1));\n}\n\nexport interface LlmJudgeOptions {\n router: Pick<Router, 'complete'>;\n /** Route or model id (`runner.judge.model`, defaults to `runner.route`). */\n route: string;\n threshold: number;\n}\n\nexport class LlmJudge implements Judge {\n readonly kind = 'llm' as const;\n\n constructor(private readonly options: LlmJudgeOptions) {}\n\n async judge(input: JudgeInput): Promise<JudgeVerdict> {\n const evidence = {\n task: taskText(input.task),\n acceptance: acceptanceOf(input.task),\n diff_stat: input.diffStat,\n diff: truncateHead(input.diff ?? '', MAX_DIFF_CHARS),\n validation: truncateHead(input.validation.summary, MAX_VALIDATION_CHARS),\n };\n let content: string;\n try {\n const { completion } = await this.options.router.complete(\n {\n model: routeModel(this.options.route),\n messages: [\n { role: 'system', content: LLM_JUDGE_PROMPT },\n { role: 'user', content: JSON.stringify(evidence, null, 2) },\n ],\n temperature: 0,\n },\n input.signal ? { signal: input.signal } : {},\n );\n const message = completion.choices[0]?.message.content;\n content = typeof message === 'string' ? message : '';\n } catch (err) {\n throw new JudgeError(\n `LLM judge call failed: ${err instanceof Error ? err.message : String(err)}`,\n 'network',\n );\n }\n let verdict: z.infer<typeof llmVerdictSchema>;\n try {\n verdict = llmVerdictSchema.parse(extractJsonObject(content));\n } catch {\n throw new JudgeError(\n `LLM judge did not return a valid verdict: ${content.slice(0, 200)}`,\n 'invalid_response',\n );\n }\n const pass = verdict.pass && verdict.confidence >= this.options.threshold;\n const reasons = [...verdict.reasons];\n if (verdict.pass && !pass) {\n reasons.push(\n `confidence ${verdict.confidence} is below the threshold ${this.options.threshold}`,\n );\n }\n return { kind: 'llm', pass, confidence: verdict.confidence, reasons };\n }\n}\n\nexport interface CreateJudgeDeps {\n router?: Pick<Router, 'complete'>;\n /** Fallback route for the `llm` judge when `judge.model` is unset. */\n defaultRoute?: string;\n env?: NodeJS.ProcessEnv;\n fetch?: typeof fetch;\n}\n\n/** Builds the judge selected by `runner.judge`. */\nexport function createJudge(config: JudgeConfig, deps: CreateJudgeDeps = {}): Judge {\n switch (config.kind) {\n case 'none':\n return new NoneJudge();\n case 'jev':\n return new JevJudge({\n threshold: config.threshold,\n ...(config.model ? { model: config.model } : {}),\n ...(config.baseUrl ? { baseUrl: config.baseUrl } : {}),\n ...(deps.env ? { env: deps.env } : {}),\n ...(deps.fetch ? { fetch: deps.fetch } : {}),\n });\n case 'llm': {\n if (!deps.router) throw new Error('the llm judge needs a router');\n return new LlmJudge({\n router: deps.router,\n route: config.model ?? deps.defaultRoute ?? 'auto',\n threshold: config.threshold,\n });\n }\n }\n}\n","/**\n * Deterministic quality gates: runs `runner.validate.lint`, `typecheck` and `test` (each\n * optional) in the repository and produces a {@link ValidationReport} whose `summary` is\n * written for both humans and the repairing model (exact stdout/stderr tails included).\n */\nimport { CommandError, projectEnv, runProcess, splitCommand } from './process';\n\nexport const VALIDATION_STEPS = ['lint', 'typecheck', 'test'] as const;\nexport type ValidationStepName = (typeof VALIDATION_STEPS)[number];\n\nexport type ValidationCommands = Partial<Record<ValidationStepName, string | undefined>>;\n\nexport interface ValidationStep {\n name: ValidationStepName;\n command: string;\n ok: boolean;\n exitCode: number | null;\n /** Tail of stdout (the end is kept because that is where errors are). */\n stdout: string;\n stderr: string;\n durationMs: number;\n timedOut: boolean;\n}\n\nexport interface ValidationReport {\n ok: boolean;\n steps: ValidationStep[];\n durationMs: number;\n /** Plain-text report: one status line per step, then the output of failing steps. */\n summary: string;\n}\n\nexport interface ValidatorOptions {\n root: string;\n commands: ValidationCommands;\n /** Per-command timeout (default 10 min). */\n timeoutMs?: number;\n /** Characters of stdout and of stderr kept per step (default 12 000 each). */\n maxOutputChars?: number;\n env?: NodeJS.ProcessEnv;\n}\n\nconst seconds = (ms: number) => `${(ms / 1000).toFixed(1)}s`;\n\nfunction statusLine(step: ValidationStep): string {\n if (step.ok) return `- ${step.name}: PASS (${seconds(step.durationMs)}) \\`${step.command}\\``;\n const why = step.timedOut ? 'timed out' : `exit ${step.exitCode ?? 'none'}`;\n return `- ${step.name}: FAIL, ${why} (${seconds(step.durationMs)}) \\`${step.command}\\``;\n}\n\n/** Renders the human/LLM-readable report for a set of steps. */\nexport function summarizeValidation(steps: ValidationStep[]): string {\n if (steps.length === 0) return 'Validation PASSED: no validation commands are configured.';\n const failed = steps.filter((s) => !s.ok);\n const lines = [\n failed.length === 0\n ? 'Validation PASSED.'\n : `Validation FAILED (${failed.map((s) => s.name).join(', ')}).`,\n ...steps.map(statusLine),\n ];\n for (const step of failed) {\n lines.push('', `### ${step.name} output (\\`${step.command}\\`)`);\n if (step.stdout.trim()) lines.push('stdout:', '```', step.stdout.trimEnd(), '```');\n if (step.stderr.trim()) lines.push('stderr:', '```', step.stderr.trimEnd(), '```');\n if (!step.stdout.trim() && !step.stderr.trim()) lines.push('(no output)');\n }\n return lines.join('\\n');\n}\n\nexport class Validator {\n constructor(private readonly options: ValidatorOptions) {}\n\n /** Configured steps in run order. */\n get configured(): Array<{ name: ValidationStepName; command: string }> {\n return VALIDATION_STEPS.flatMap((name) => {\n const command = this.options.commands[name]?.trim();\n return command ? [{ name, command }] : [];\n });\n }\n\n /** Runs every configured step (all of them, so the report shows every failure). */\n async validate(signal?: AbortSignal): Promise<ValidationReport> {\n const started = Date.now();\n const steps: ValidationStep[] = [];\n for (const { name, command } of this.configured) {\n if (signal?.aborted) break;\n steps.push(await this.runStep(name, command, signal));\n }\n return {\n ok: steps.every((s) => s.ok),\n steps,\n durationMs: Date.now() - started,\n summary: summarizeValidation(steps),\n };\n }\n\n private async runStep(\n name: ValidationStepName,\n command: string,\n signal?: AbortSignal,\n ): Promise<ValidationStep> {\n let argv: string[];\n try {\n argv = splitCommand(command);\n } catch (err) {\n return this.failed(name, command, err instanceof CommandError ? err.message : String(err));\n }\n const [file, ...args] = argv;\n if (!file) return this.failed(name, command, 'empty command');\n const result = await runProcess({\n command: file,\n args,\n cwd: this.options.root,\n timeoutMs: this.options.timeoutMs ?? 600_000,\n env: projectEnv(this.options.root, this.options.env ?? process.env),\n maxOutputChars: this.options.maxOutputChars ?? 12_000,\n ...(signal ? { signal } : {}),\n });\n return {\n name,\n command,\n ok: result.exitCode === 0,\n exitCode: result.exitCode,\n stdout: result.stdout,\n stderr: result.stderr,\n durationMs: result.durationMs,\n timedOut: result.timedOut,\n };\n }\n\n private failed(name: ValidationStepName, command: string, stderr: string): ValidationStep {\n return {\n name,\n command,\n ok: false,\n exitCode: null,\n stdout: '',\n stderr,\n durationMs: 0,\n timedOut: false,\n };\n }\n}\n","/**\n * The autonomous runner: walks the task DAG and, for each ready task, branches, implements,\n * validates, repairs (up to `runner.maxRepairCycles`), judges and merges. State machine as in\n * docs/ARCHITECTURE.md (\"Autonomous loop\"):\n *\n * idle → selecting → preparing → implementing → validating → (repairing → implementing)*\n * → merging → selecting … plus paused, stopped and error.\n *\n * Structurally satisfies the server's `RunnerControl` (`status`, `start`, `pause`, `stop`).\n */\nimport { buildTaskContext } from '../brain/context';\nimport type { GlobalBrain } from '../brain/global';\nimport { checkRunnable, nextTask } from '../brain/graph';\nimport type { ProjectBrain } from '../brain/project';\nimport type { DaveConfig } from '../config/schema';\nimport { EventBus } from '../events';\nimport type { LogLevel, RunnerState, RunnerStatus, TaskNode } from '../types';\nimport { type Executor, ExecutorAbortedError, ExecutorError } from './executor';\nimport { Git, GitError } from './git';\nimport { createJudge, type Judge, JudgeError, type JudgeVerdict } from './judge';\nimport { truncateHead } from './process';\nimport { type ValidationReport, Validator } from './validator';\nimport type { WorkspaceLock } from './workspace-lock';\n\nexport type RunnerConfig = DaveConfig['runner'];\n\nexport type RunnerErrorCode =\n | 'not_a_repo'\n | 'no_brain'\n | 'no_base_branch'\n | 'dirty_worktree'\n | 'invalid_graph'\n | 'busy'\n /** `taskId` does not exist in the task graph. */\n | 'task_not_found'\n /** `taskId` exists but is not PENDING. */\n | 'task_not_runnable'\n /** `taskId` is PENDING but depends on unfinished tasks. */\n | 'task_blocked';\n\n/** A precondition failed: the runner refuses to start. */\nexport class RunnerError extends Error {\n /** HTTP status hint for the gateway's error handler (404 for an unknown task, else 409). */\n readonly statusCode: number;\n\n constructor(\n readonly code: RunnerErrorCode,\n message: string,\n ) {\n super(message);\n this.name = 'RunnerError';\n this.statusCode = code === 'task_not_found' ? 404 : 409;\n }\n}\n\n/** Internal: unwinds the current step when `stop()` is requested. */\nclass StopSignal extends Error {\n constructor() {\n super('runner stopped');\n this.name = 'StopSignal';\n }\n}\n\nexport interface AutonomousRunnerOptions {\n /** Brain of the repository to work on; its root must be inside a git work tree. */\n brain: ProjectBrain;\n /** The parsed `runner` config section. */\n config: RunnerConfig;\n executor: Executor;\n /** Global brain injected into every task context. */\n global?: Pick<GlobalBrain, 'compose'>;\n /** Default: `runner.validate` commands with `runner.commandTimeoutMs`. */\n validator?: Pick<Validator, 'validate'>;\n /** Default: `createJudge(runner.judge)` (the `llm` judge needs `createRunner`). */\n judge?: Judge;\n /** Default: `new Git(brain.root)`. */\n git?: Git;\n /** Receives `runner.status` and `runner.log` (default: a private bus, see `events`). */\n events?: EventBus;\n /** Character budget for `buildTaskContext`. */\n contextBudgetChars?: number;\n /**\n * Shared with other users of the same working tree (goal mode). While another owner holds it,\n * `start()` and `runOnce()` reject with `busy`.\n */\n lock?: { lock: WorkspaceLock; owner: string };\n /** Extra text appended to every task context (e.g. the budget summary). */\n contextExtras?: () => string | Promise<string>;\n}\n\n/** Options for {@link AutonomousRunner.runOnce} and {@link AutonomousRunner.start}. */\nexport interface RunTaskOptions {\n /**\n * Run this task instead of the runner's own pick. It must exist, be PENDING and have every\n * dependency SUCCESS, otherwise a {@link RunnerError} (`task_not_found`, `task_not_runnable`\n * or `task_blocked`) is raised.\n */\n taskId?: string;\n}\n\nexport type RunOutcome = 'success' | 'failed' | 'idle' | 'stopped' | 'error';\n\nexport interface RunOnceResult {\n /**\n * `success`: merged (or PR opened). `failed`: task marked FAILED. `idle`: no task was ready.\n * `stopped`: interrupted by `stop()` (task back to PENDING). `error`: unexpected failure.\n */\n outcome: RunOutcome;\n /** The task as last written to the graph. */\n task?: TaskNode;\n /** Repair cycles used. */\n repairCycles: number;\n /** Executor summary of the final pass. */\n summary?: string;\n validation?: ValidationReport;\n verdict?: JudgeVerdict;\n /** How the change landed (`merge` locally or `pr` with its URL). */\n delivery?: { mode: 'merge' | 'pr'; url?: string };\n /** Task branch (kept for inspection when the task failed or was stopped). */\n branch?: string;\n error?: string;\n}\n\nconst CONVENTIONAL =\n /^(feat|fix|docs|chore|refactor|test|perf|build|ci|style|revert)(\\([^)]+\\))?!?: /;\n\n/** Conventional Commit message for a finished task. */\nexport function commitMessage(task: TaskNode, summary: string): string {\n const title = task.title.trim().replace(/\\s+/g, ' ');\n let header = CONVENTIONAL.test(title) ? title : `feat: ${title}`;\n if (header.length > 100) header = `${header.slice(0, 97)}...`;\n const body = truncateHead(summary.trim(), 2_000);\n return `${header}\\n\\n${body ? `${body}\\n\\n` : ''}DaveCode-Task: ${task.id}`;\n}\n\nexport class AutonomousRunner {\n readonly events: EventBus;\n readonly root: string;\n private readonly brain: ProjectBrain;\n private readonly config: RunnerConfig;\n private readonly executor: Executor;\n private readonly validator: Pick<Validator, 'validate'>;\n private readonly judge: Judge;\n private readonly git: Git;\n private readonly global: Pick<GlobalBrain, 'compose'> | undefined;\n private readonly contextBudgetChars: number | undefined;\n private readonly lock: AutonomousRunnerOptions['lock'];\n private readonly contextExtras: AutonomousRunnerOptions['contextExtras'];\n\n private current: RunnerStatus = { state: 'idle' };\n /** The running continuous loop or single run, if any. */\n private active: Promise<unknown> | undefined;\n private controller: AbortController | undefined;\n private idleSleep: AbortController | undefined;\n private stopRequested = false;\n private pauseRequested = false;\n private resumeState: RunnerState = 'selecting';\n private pauseWaiters: Array<() => void> = [];\n private last: RunOnceResult | undefined;\n\n constructor(options: AutonomousRunnerOptions) {\n this.brain = options.brain;\n this.root = options.brain.root;\n this.config = options.config;\n this.executor = options.executor;\n this.events = options.events ?? new EventBus();\n this.git = options.git ?? new Git(this.root);\n this.validator =\n options.validator ??\n new Validator({\n root: this.root,\n commands: options.config.validate,\n timeoutMs: options.config.commandTimeoutMs,\n });\n this.judge = options.judge ?? createJudge(options.config.judge);\n this.global = options.global;\n this.contextBudgetChars = options.contextBudgetChars;\n this.lock = options.lock;\n this.contextExtras = options.contextExtras;\n }\n\n /** Takes the workspace lock, or throws `busy` naming the current holder. */\n private acquireLock(): void {\n if (!this.lock) return;\n if (!this.lock.lock.acquire(this.lock.owner)) {\n throw new RunnerError(\n 'busy',\n `the working tree is busy (${this.lock.lock.holder ?? 'another task'} is running)`,\n );\n }\n }\n\n private releaseLock(): void {\n if (this.lock) this.lock.lock.release(this.lock.owner);\n }\n\n // -- public control surface -------------------------------------------------\n\n status(): RunnerStatus {\n return { ...this.current };\n }\n\n /** Result of the most recent task run. */\n get lastResult(): RunOnceResult | undefined {\n return this.last;\n }\n\n /** True while the continuous loop or a single run is in progress (including paused). */\n get running(): boolean {\n return this.active !== undefined;\n }\n\n /**\n * Starts the continuous (24/7) loop, or resumes it when paused. Resolves once the loop has\n * started. Rejects with {@link RunnerError} when a precondition fails (dirty tree, no brain…).\n */\n async start(opts: RunTaskOptions = {}): Promise<void> {\n if (this.pauseRequested) {\n this.resume();\n return;\n }\n if (this.active) return;\n this.acquireLock();\n this.stopRequested = false;\n let started: () => void = () => undefined;\n let refused: (err: unknown) => void = () => undefined;\n const ready = new Promise<void>((resolve, reject) => {\n started = resolve;\n refused = reject;\n });\n this.active = (async () => {\n try {\n await this.preflightChecks();\n if (opts.taskId !== undefined) await this.assertRunnable(opts.taskId);\n this.beginSession();\n } catch (err) {\n refused(err);\n return;\n }\n started();\n await this.loop(opts.taskId);\n })().finally(() => {\n this.active = undefined;\n this.releaseLock();\n });\n // Resolve once started; the loop keeps running in the background.\n await ready;\n }\n\n /**\n * Implements at most one task, then returns. For the CLI (`davecode run`). With `taskId` that\n * exact task is run (or a {@link RunnerError} explains why it cannot be).\n */\n async runOnce(opts: RunTaskOptions = {}): Promise<RunOnceResult> {\n if (this.active) throw new RunnerError('busy', 'the runner is already running');\n this.acquireLock();\n this.stopRequested = false;\n let resolveDone: () => void = () => undefined;\n this.active = new Promise<void>((r) => {\n resolveDone = r;\n });\n try {\n await this.preflightChecks();\n if (opts.taskId !== undefined) await this.assertRunnable(opts.taskId);\n this.beginSession();\n const result = await this.selectAndRun(opts.taskId);\n if (result.outcome !== 'error') {\n this.setState(this.stopRequested ? 'stopped' : 'idle', {});\n }\n return result;\n } catch (err) {\n if (err instanceof StopSignal) {\n this.setState('stopped', {});\n return { outcome: 'stopped', repairCycles: 0 };\n }\n if (!(err instanceof RunnerError)) this.fail(err);\n throw err;\n } finally {\n this.endSession();\n this.active = undefined;\n this.releaseLock();\n resolveDone();\n }\n }\n\n /** Pauses at the next step boundary. In-flight work (a model call, a test run) completes. */\n pause(): void {\n if (!this.active || this.pauseRequested) return;\n this.pauseRequested = true;\n this.resumeState = this.current.state === 'paused' ? 'selecting' : this.current.state;\n this.setState('paused', {});\n this.log('info', 'paused; the current step will finish first');\n }\n\n /** Resumes after {@link pause}. */\n resume(): void {\n if (!this.pauseRequested) return;\n this.pauseRequested = false;\n this.setState(this.resumeState, {});\n this.log('info', 'resumed');\n const waiters = this.pauseWaiters;\n this.pauseWaiters = [];\n for (const wake of waiters) wake();\n }\n\n /**\n * Stops safely: aborts the in-flight model call or command, keeps partial work on the task\n * branch, puts the task back to PENDING and returns to the base branch. Resolves when done.\n */\n async stop(): Promise<void> {\n if (!this.active) {\n if (this.current.state !== 'stopped') this.setState('stopped', {});\n return;\n }\n this.stopRequested = true;\n this.controller?.abort();\n this.idleSleep?.abort();\n const waiters = this.pauseWaiters;\n this.pauseWaiters = [];\n this.pauseRequested = false;\n for (const wake of waiters) wake();\n try {\n await this.active;\n } catch {\n // errors are reflected in status()\n }\n if (this.current.state !== 'error' && this.current.state !== 'stopped') {\n this.setState('stopped', {});\n }\n }\n\n // -- loop -------------------------------------------------------------------\n\n private beginSession(): void {\n this.controller = new AbortController();\n if (this.stopRequested) this.controller.abort();\n this.current = { state: this.current.state, startedAt: new Date().toISOString() };\n this.log('info', `runner started on ${this.root} (executor: ${this.executor.name})`);\n }\n\n private endSession(): void {\n this.controller = undefined;\n this.idleSleep = undefined;\n this.stopRequested = false;\n this.pauseRequested = false;\n this.pauseWaiters = [];\n }\n\n private async loop(firstTaskId?: string): Promise<void> {\n let target = firstTaskId;\n try {\n for (;;) {\n const result = await this.selectAndRun(target);\n target = undefined;\n if (result.outcome === 'error' || result.outcome === 'stopped') return;\n if (result.outcome === 'idle') {\n this.log('debug', `no ready task; polling again in ${this.config.idlePollMs} ms`);\n await this.sleep(this.config.idlePollMs);\n }\n }\n } catch (err) {\n if (!(err instanceof StopSignal)) this.fail(err);\n } finally {\n if (this.stopRequested && this.current.state !== 'error') this.setState('stopped', {});\n this.endSession();\n }\n }\n\n /** Throws a {@link RunnerError} naming why `taskId` cannot be run now. */\n private async assertRunnable(taskId: string): Promise<void> {\n const check = checkRunnable(await this.brain.readGraph(), taskId);\n if (check.ok) return;\n const code: RunnerErrorCode =\n check.reason === 'unknown_task'\n ? 'task_not_found'\n : check.reason === 'blocked'\n ? 'task_blocked'\n : 'task_not_runnable';\n throw new RunnerError(code, check.message);\n }\n\n private async selectAndRun(taskId?: string): Promise<RunOnceResult> {\n await this.transition('selecting', {});\n const graph = await this.brain.readGraph();\n let task = nextTask(graph);\n if (taskId !== undefined) {\n const check = checkRunnable(graph, taskId);\n if (check.ok) {\n task = check.task;\n } else {\n // Changed between the up-front check and now (e.g. edited from the dashboard).\n this.log('warn', `requested task is no longer runnable: ${check.message}`, taskId);\n }\n }\n if (!task) {\n this.setState('idle', {});\n return { outcome: 'idle', repairCycles: 0 };\n }\n const result = await this.runTask(task);\n this.last = result;\n return result;\n }\n\n private async sleep(ms: number): Promise<void> {\n if (this.stopRequested) throw new StopSignal();\n const controller = new AbortController();\n this.idleSleep = controller;\n await new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, ms);\n controller.signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n resolve();\n },\n { once: true },\n );\n });\n this.idleSleep = undefined;\n if (this.stopRequested) throw new StopSignal();\n }\n\n // -- preconditions ----------------------------------------------------------\n\n private async preflightChecks(): Promise<void> {\n try {\n if (!(await this.git.isRepo())) {\n throw new RunnerError('not_a_repo', `${this.root} is not inside a git repository`);\n }\n if (!(await this.brain.isInitialised())) {\n throw new RunnerError('no_brain', `no project brain in ${this.root} (run davecode init)`);\n }\n const base = this.config.baseBranch;\n if (!(await this.git.branchExists(base))) {\n throw new RunnerError('no_base_branch', `base branch \"${base}\" does not exist`);\n }\n const dirty = await this.git.status({ ignoreBrain: true });\n if (dirty.length > 0) {\n const files = dirty.slice(0, 10).map((l) => l.slice(3));\n throw new RunnerError(\n 'dirty_worktree',\n `refusing to start: the working tree has uncommitted changes (${files.join(', ')}${dirty.length > 10 ? ', …' : ''}). Commit or stash them first.`,\n );\n }\n let graph: Awaited<ReturnType<ProjectBrain['readGraph']>>;\n try {\n graph = await this.brain.readGraph();\n } catch (err) {\n throw new RunnerError('invalid_graph', err instanceof Error ? err.message : String(err));\n }\n for (const stale of graph.tasks.filter((t) => t.status === 'IN_PROGRESS')) {\n this.log(\n 'warn',\n `task ${stale.id} is IN_PROGRESS from an earlier run; set it back to PENDING to retry it`,\n stale.id,\n );\n }\n if ((await this.git.currentBranch()) !== base) {\n this.log('info', `checking out base branch ${base}`);\n await this.git.checkout(base);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n this.setState('error', { lastError: message });\n this.log('error', message);\n throw err;\n }\n }\n\n // -- one task ---------------------------------------------------------------\n\n private async runTask(selected: TaskNode): Promise<RunOnceResult> {\n const cfg = this.config;\n const id = selected.id;\n const branch = `${cfg.branchPrefix}${id}`;\n const signal = this.controller?.signal ?? new AbortController().signal;\n let task = await this.brain.updateTask(id, { status: 'IN_PROGRESS', branch });\n await this.brain.appendStateLog(\n `Started task \\`${id}\\` (${task.title}), attempt ${task.attempts ?? 1}, on \\`${branch}\\`.`,\n );\n this.log('info', `task ${id}: ${task.title} (attempt ${task.attempts ?? 1})`, id);\n\n let cycle = 0;\n let summary = '';\n let validation: ValidationReport | undefined;\n let verdict: JudgeVerdict | undefined;\n const partial = (): Omit<RunOnceResult, 'outcome'> => ({\n task,\n repairCycles: cycle,\n branch,\n ...(summary ? { summary } : {}),\n ...(validation ? { validation } : {}),\n ...(verdict ? { verdict } : {}),\n });\n\n try {\n await this.transition('preparing', { taskId: id, repairCycle: 0 });\n await this.prepareBranch(branch);\n const base = await buildTaskContext({\n project: this.brain,\n task,\n ...(this.global ? { global: this.global } : {}),\n ...(this.contextBudgetChars ? { budgetChars: this.contextBudgetChars } : {}),\n });\n const extras = this.contextExtras ? (await this.contextExtras()).trim() : '';\n const context = extras ? `${base}\\n\\n${extras}` : base;\n const session = this.executor.createSession({\n task,\n context,\n root: this.root,\n log: (level, message) => this.log(level, message, id),\n });\n\n let failureReport: string | undefined;\n for (;;) {\n await this.transition('implementing', { taskId: id, repairCycle: cycle });\n const result = await session.run({\n cycle,\n signal,\n ...(failureReport ? { failureReport } : {}),\n });\n summary = result.summary;\n this.log(\n 'info',\n `implementation pass ${cycle} ended (${result.stopReason}, ${result.iterations} iteration(s), ${result.totalTokens} tokens so far)`,\n id,\n );\n\n await this.transition('validating', { taskId: id, repairCycle: cycle });\n validation = await this.validator.validate(signal);\n if (signal.aborted) throw new StopSignal();\n this.log(validation.ok ? 'info' : 'warn', validation.summary.split('\\n')[0] ?? '', id);\n\n let failure: string | undefined;\n if (!validation.ok) {\n failure = validation.summary;\n } else {\n await this.git.stageAll();\n const diffStat = await this.git.diffStat(undefined, { cached: true });\n if (!diffStat) {\n failure =\n 'The quality gates passed but the task produced no file changes. Implement the task: the change must modify the repository.';\n } else {\n verdict = await this.judge.judge({\n task,\n diffStat,\n diff: await this.git.diff(undefined, { cached: true }),\n validation,\n signal,\n });\n this.log(\n verdict.pass ? 'info' : 'warn',\n `judge (${verdict.kind}): ${verdict.pass ? 'pass' : 'reject'}${verdict.confidence !== undefined ? ` at ${verdict.confidence.toFixed(2)}` : ''}`,\n id,\n );\n if (!verdict.pass) {\n failure = [\n `The acceptance judge (${verdict.kind}) rejected the change even though the checks passed.`,\n ...verdict.reasons.map((r) => `- ${r}`),\n '',\n 'Acceptance criteria:',\n ...(task.acceptance ?? [task.title]).map((c) => `- ${c}`),\n ].join('\\n');\n }\n }\n }\n if (failure === undefined) break;\n if (cycle >= cfg.maxRepairCycles) {\n return await this.failTask(\n task,\n branch,\n `quality gates still failing after ${cycle} repair cycle(s)`,\n failure,\n partial,\n );\n }\n cycle++;\n await this.transition('repairing', { taskId: id, repairCycle: cycle });\n this.log('warn', `repair cycle ${cycle}/${cfg.maxRepairCycles}`, id);\n failureReport = failure;\n }\n\n await this.transition('merging', { taskId: id, repairCycle: cycle });\n const delivery = await this.deliver(task, branch, summary);\n task = await this.brain.setTaskStatus(id, 'SUCCESS', {\n notes: truncateHead(\n `${summary}${delivery.url ? `\\n\\nPull request: ${delivery.url}` : ''}`.trim(),\n 1_000,\n ),\n });\n await this.brain.appendStateLog(\n `Task \\`${id}\\` SUCCESS after ${cycle} repair cycle(s); ${\n delivery.mode === 'pr'\n ? `pull request ${delivery.url}`\n : `merged into \\`${cfg.baseBranch}\\``\n }.`,\n );\n await this.commitBrain(`chore(davecode): mark task ${id} as SUCCESS`);\n this.log('info', `task ${id} SUCCESS`, id);\n return { outcome: 'success', ...partial(), task, delivery };\n } catch (err) {\n if (err instanceof StopSignal || err instanceof ExecutorAbortedError || signal.aborted) {\n return await this.interruptTask(task, branch, partial);\n }\n if (err instanceof JudgeError || err instanceof ExecutorError || err instanceof GitError) {\n const message = err.message;\n return await this.failTask(task, branch, message, message, partial);\n }\n // Unexpected: clean up as well as possible, mark the task FAILED and surface the error.\n const message = err instanceof Error ? err.message : String(err);\n try {\n await this.failTask(task, branch, `unexpected error: ${message}`, message, partial);\n } catch {\n // the brain or git may be the problem; the error state below says why\n }\n this.fail(err);\n return { outcome: 'error', ...partial(), error: message };\n }\n }\n\n /** Checks out the base branch and creates a fresh task branch (archiving a stale one). */\n private async prepareBranch(branch: string): Promise<void> {\n const base = this.config.baseBranch;\n if ((await this.git.currentBranch()) !== base) await this.git.checkout(base);\n if (await this.git.branchExists(branch)) {\n let n = 1;\n while (await this.git.branchExists(`${branch}-attempt-${n}`)) n++;\n await this.git.renameBranch(branch, `${branch}-attempt-${n}`);\n this.log('info', `kept the previous attempt as ${branch}-attempt-${n}`);\n }\n await this.git.createBranch(branch, base);\n }\n\n /** Commits the change on the task branch, then merges it (or opens a PR). */\n private async deliver(\n task: TaskNode,\n branch: string,\n summary: string,\n ): Promise<{ mode: 'merge' | 'pr'; url?: string }> {\n const base = this.config.baseBranch;\n const message = commitMessage(task, summary);\n await this.git.commitAll(message);\n\n if (this.config.pullRequests) {\n try {\n const pr = await this.git.openPullRequest({\n branch,\n base,\n title: message.split('\\n')[0] ?? task.title,\n body: message,\n });\n if (pr.outcome === 'pr') {\n await this.git.checkout(base);\n this.log('info', `opened pull request ${pr.url ?? ''}`.trim(), task.id);\n return { mode: 'pr', ...(pr.url ? { url: pr.url } : {}) };\n }\n this.log('warn', `pull request mode unavailable (${pr.reason}); merging locally`, task.id);\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n this.log('warn', `could not open a pull request (${reason}); merging locally`, task.id);\n }\n }\n\n await this.git.checkout(base);\n await this.git.mergeNoFf(branch, `Merge ${branch}: ${task.title}`);\n await this.git.deleteBranch(branch);\n return { mode: 'merge' };\n }\n\n /** Leaves the work on the task branch and returns to the base branch. */\n private async parkWork(branch: string, message: string): Promise<void> {\n const base = this.config.baseBranch;\n await this.git.abortMerge();\n if ((await this.git.currentBranch()) === branch) {\n try {\n await this.git.commitAll(message, { noVerify: true });\n } catch (err) {\n this.log('warn', `could not snapshot the attempt (${(err as Error).message}); discarding`);\n await this.git.discardChanges();\n }\n }\n await this.git.restore(base);\n }\n\n private async failTask(\n task: TaskNode,\n branch: string,\n reason: string,\n report: string,\n partial: () => Omit<RunOnceResult, 'outcome'>,\n ): Promise<RunOnceResult> {\n await this.parkWork(branch, `wip(davecode): failed attempt for task ${task.id}`);\n const failed = await this.brain.setTaskStatus(task.id, 'FAILED', {\n notes: truncateHead(`FAILED: ${reason}\\n\\n${report}`, 4_000),\n });\n await this.brain.appendStateLog(\n `Task \\`${task.id}\\` FAILED: ${reason}. Work kept on \\`${branch}\\`.`,\n );\n await this.commitBrain(`chore(davecode): mark task ${task.id} as FAILED`);\n this.log('error', `task ${task.id} FAILED: ${reason}`, task.id);\n return { outcome: 'failed', ...partial(), task: failed, error: reason };\n }\n\n private async interruptTask(\n task: TaskNode,\n branch: string,\n partial: () => Omit<RunOnceResult, 'outcome'>,\n ): Promise<RunOnceResult> {\n await this.parkWork(branch, `wip(davecode): interrupted attempt for task ${task.id}`);\n const pending = await this.brain.setTaskStatus(task.id, 'PENDING', {\n notes: `Interrupted by stop; partial work kept on ${branch}.`,\n });\n await this.brain.appendStateLog(\n `Task \\`${task.id}\\` interrupted by stop; partial work kept on \\`${branch}\\`.`,\n );\n await this.commitBrain(`chore(davecode): task ${task.id} interrupted`);\n this.log('warn', `task ${task.id} interrupted; back to PENDING`, task.id);\n return { outcome: 'stopped', ...partial(), task: pending };\n }\n\n private async commitBrain(message: string): Promise<void> {\n if (!this.config.commitBrain) return;\n try {\n await this.git.commitBrain(message);\n } catch (err) {\n this.log('warn', `could not commit the project brain: ${(err as Error).message}`);\n }\n }\n\n // -- state & events ---------------------------------------------------------\n\n /** Waits at a step boundary (pause), aborts on stop, then enters `state`. */\n private async transition(state: RunnerState, patch: Partial<RunnerStatus>): Promise<void> {\n await this.checkpoint();\n this.setState(state, patch);\n }\n\n private async checkpoint(): Promise<void> {\n if (this.stopRequested) throw new StopSignal();\n while (this.pauseRequested) {\n await new Promise<void>((resolve) => this.pauseWaiters.push(resolve));\n if (this.stopRequested) throw new StopSignal();\n }\n }\n\n private setState(state: RunnerState, patch: Partial<RunnerStatus>): void {\n const next: RunnerStatus = { state };\n const keepTask = state !== 'idle' && state !== 'selecting' && state !== 'stopped';\n const taskId = 'taskId' in patch ? patch.taskId : keepTask ? this.current.taskId : undefined;\n const repairCycle =\n 'repairCycle' in patch ? patch.repairCycle : keepTask ? this.current.repairCycle : undefined;\n if (taskId !== undefined) next.taskId = taskId;\n if (repairCycle !== undefined) next.repairCycle = repairCycle;\n if (this.current.startedAt) next.startedAt = this.current.startedAt;\n const lastError = 'lastError' in patch ? patch.lastError : this.current.lastError;\n if (lastError !== undefined) next.lastError = lastError;\n this.current = next;\n this.events.emit({ type: 'runner.status', status: { ...next } });\n }\n\n private fail(err: unknown): void {\n const message = err instanceof Error ? err.message : String(err);\n this.setState('error', { lastError: message });\n this.log('error', message);\n }\n\n private log(level: LogLevel, message: string, taskId?: string): void {\n this.events.emit({\n type: 'runner.log',\n level,\n message,\n ...(taskId !== undefined ? { taskId } : {}),\n });\n }\n}\n","/** Wires an {@link AutonomousRunner} from a core {@link Engine}: the entry point for the CLI. */\nimport { GlobalBrain } from '../brain/global';\nimport type { ProjectBrain } from '../brain/project';\nimport type { Engine } from '../engine';\nimport { ClaudeCliExecutor } from './claude-cli-executor';\nimport { BuiltinExecutor, type Executor } from './executor';\nimport { Git } from './git';\nimport { createJudge, type Judge } from './judge';\nimport { AutonomousRunner, type AutonomousRunnerOptions, type RunnerConfig } from './runner';\nimport { Validator } from './validator';\n\ntype EngineDeps = Pick<Engine, 'config' | 'router' | 'accounts' | 'sandboxes' | 'events' | 'paths'>;\n\n/** Builds the executor selected by `runner.executor` (`cfg` overrides `engine.config.runner`). */\nexport function createExecutor(\n engine: Omit<EngineDeps, 'events' | 'paths'>,\n cfg: RunnerConfig = engine.config.runner,\n): Executor {\n if (cfg.executor === 'claude-cli') {\n return new ClaudeCliExecutor({\n accounts: engine.accounts,\n sandboxes: engine.sandboxes,\n allowedTools: cfg.claudeCli.allowedTools,\n timeoutMs: cfg.claudeCli.timeoutMs,\n maxTaskTokens: cfg.maxTaskTokens,\n ...(cfg.claudeCli.accountId ? { accountId: cfg.claudeCli.accountId } : {}),\n ...(cfg.claudeCli.model ? { model: cfg.claudeCli.model } : {}),\n });\n }\n return new BuiltinExecutor({\n router: engine.router,\n route: cfg.route,\n maxIterations: cfg.maxIterations,\n maxTaskTokens: cfg.maxTaskTokens,\n allowedCommands: cfg.allowedCommands,\n commandTimeoutMs: cfg.commandTimeoutMs,\n });\n}\n\nexport interface CreateRunnerOptions {\n /** Brain of the repository to work on (construct it with `{ events: engine.events }`). */\n brain: ProjectBrain;\n /** Global brain (default: `~/.davecode/brain`); `false` to leave it out of the context. */\n global?: GlobalBrain | false;\n /** Override the executor chosen by `runner.executor`. */\n executor?: Executor;\n /** Override the judge chosen by `runner.judge`. */\n judge?: Judge;\n /** Override `engine.config.runner` (e.g. a tighter `maxTaskTokens`). */\n config?: RunnerConfig;\n /** Workspace lock shared with goal mode. */\n lock?: AutonomousRunnerOptions['lock'];\n /** Extra text appended to every task context. */\n contextExtras?: AutonomousRunnerOptions['contextExtras'];\n /** Environment for the judge's API key lookup (default `process.env`). */\n env?: NodeJS.ProcessEnv;\n fetch?: typeof fetch;\n}\n\n/** An {@link AutonomousRunner} for `brain.root` using the engine's config, router and events. */\nexport function createRunner(engine: EngineDeps, opts: CreateRunnerOptions): AutonomousRunner {\n const cfg = opts.config ?? engine.config.runner;\n const global =\n opts.global === false ? undefined : (opts.global ?? new GlobalBrain(engine.paths.brain));\n return new AutonomousRunner({\n brain: opts.brain,\n config: cfg,\n executor: opts.executor ?? createExecutor(engine, cfg),\n judge:\n opts.judge ??\n createJudge(cfg.judge, {\n router: engine.router,\n defaultRoute: cfg.route,\n ...(opts.env ? { env: opts.env } : {}),\n ...(opts.fetch ? { fetch: opts.fetch } : {}),\n }),\n validator: new Validator({\n root: opts.brain.root,\n commands: cfg.validate,\n timeoutMs: cfg.commandTimeoutMs,\n }),\n git: new Git(opts.brain.root),\n events: engine.events,\n ...(global ? { global } : {}),\n ...(opts.lock ? { lock: opts.lock } : {}),\n ...(opts.contextExtras ? { contextExtras: opts.contextExtras } : {}),\n });\n}\n","/**\n * In-process mutual exclusion over one repository's working tree. The autonomous runner and goal\n * mode both check out branches and commit, so only one owner may drive the tree at a time. The\n * lock is re-entrant per owner: goal mode holds it as `goal` for the whole run and the runners it\n * creates for code tasks acquire it under the same owner.\n */\nexport class WorkspaceLock {\n private owner: string | undefined;\n private depth = 0;\n\n /** Current owner, if any. */\n get holder(): string | undefined {\n return this.owner;\n }\n\n /** Takes the lock for `owner`. Returns false when another owner holds it. */\n acquire(owner: string): boolean {\n if (this.owner !== undefined && this.owner !== owner) return false;\n this.owner = owner;\n this.depth++;\n return true;\n }\n\n /** Releases one acquisition by `owner`; a no-op for anyone else. */\n release(owner: string): void {\n if (this.owner !== owner) return;\n this.depth--;\n if (this.depth <= 0) {\n this.depth = 0;\n this.owner = undefined;\n }\n }\n}\n","import { basename, resolve } from 'node:path';\nimport type { TaskGraph, TaskNode } from '../types';\nimport { readFileIfExists } from './fs-util';\nimport { type ClearableTaskField, type NewTask, parseTaskGraph, type TaskPatch } from './graph';\nimport type { ProjectBrain } from './project';\n\n/**\n * Adapter from a {@link ProjectBrain} to the gateway's `BrainSource` shape (`project()`,\n * `graph()`, `state()`, `architecture()` plus the task write methods when the brain has them),\n * matched structurally so core never imports the server. Missing brain files read as empty instead of failing the request; an\n * invalid task graph still throws `TaskGraphError`.\n */\nexport class ProjectBrainSource {\n readonly name: string;\n\n /** Write methods; present only when the wrapped brain can write. */\n createTask?: (input: NewTask) => Promise<TaskNode>;\n updateTask?: (\n id: string,\n patch: TaskPatch,\n opts?: { clear?: readonly ClearableTaskField[] },\n ) => Promise<TaskNode>;\n removeTask?: (id: string) => Promise<TaskNode>;\n\n constructor(\n private readonly brain: Pick<ProjectBrain, 'root' | 'paths'> &\n Partial<Pick<ProjectBrain, 'createTask' | 'updateTask' | 'removeTask'>>,\n name?: string,\n ) {\n this.name = name ?? basename(resolve(brain.root));\n if (brain.createTask && brain.updateTask && brain.removeTask) {\n const writable = brain as Pick<ProjectBrain, 'createTask' | 'updateTask' | 'removeTask'>;\n this.createTask = (input) => writable.createTask(input);\n this.updateTask = (id, patch, opts) => writable.updateTask(id, patch, opts);\n this.removeTask = (id) => writable.removeTask(id);\n }\n }\n\n project(): { root: string; name: string } {\n return { root: this.brain.root, name: this.name };\n }\n\n async graph(): Promise<TaskGraph> {\n const raw = await readFileIfExists(this.brain.paths.taskGraph);\n return raw === undefined ? { version: 1, tasks: [] } : parseTaskGraph(raw);\n }\n\n async state(): Promise<string> {\n return (await readFileIfExists(this.brain.paths.state)) ?? '';\n }\n\n async architecture(): Promise<string> {\n return (await readFileIfExists(this.brain.paths.architecture)) ?? '';\n }\n}\n","import { createHash, randomBytes } from 'node:crypto';\nimport { z } from 'zod';\n\n/** Where DaveCode accounts live: a Supabase Auth project and its public (publishable) key. */\nexport interface AccountServiceConfig {\n url: string;\n publishableKey: string;\n}\n\n/**\n * The hosted account service. The publishable key is public by design (it only identifies the\n * project); every request still needs the user's own credentials. `DAVECODE_ACCOUNT_URL` and\n * `DAVECODE_ACCOUNT_KEY` point a build at another project (development, tests).\n */\nexport const ACCOUNT_SERVICE: AccountServiceConfig = {\n url: 'https://auth.davecode.app',\n publishableKey: 'davecode-cli',\n};\n\nexport function accountService(\n env: NodeJS.ProcessEnv = process.env,\n): AccountServiceConfig | undefined {\n const url = env.DAVECODE_ACCOUNT_URL ?? ACCOUNT_SERVICE.url;\n const publishableKey = env.DAVECODE_ACCOUNT_KEY ?? ACCOUNT_SERVICE.publishableKey;\n return url && publishableKey ? { url: url.replace(/\\/+$/, ''), publishableKey } : undefined;\n}\n\nexport type OAuthProvider = 'google' | 'github';\nexport const OAUTH_PROVIDERS: readonly OAuthProvider[] = ['google', 'github'];\n\nexport interface AccountUser {\n id: string;\n email?: string;\n name?: string;\n /** How the account signs in: `google`, `github` or `email`. */\n provider?: string;\n}\n\nexport interface AccountSession {\n accessToken: string;\n refreshToken: string;\n /** Epoch milliseconds. */\n expiresAt: number;\n user: AccountUser;\n}\n\n/** Upstream rejections, mapped to a message that is safe to show. */\nexport class AccountError extends Error {\n constructor(\n message: string,\n readonly status?: number,\n /** The service's machine-readable error, such as `invalid_grant`. */\n readonly code?: string,\n ) {\n super(message);\n this.name = 'AccountError';\n }\n}\n\nconst userSchema = z.object({\n id: z.string().min(1),\n email: z.string().optional().nullable(),\n app_metadata: z.object({ provider: z.string().optional() }).passthrough().optional(),\n user_metadata: z\n .object({ full_name: z.string().optional(), name: z.string().optional() })\n .passthrough()\n .optional(),\n});\n\nconst sessionSchema = z.object({\n access_token: z.string().min(1),\n refresh_token: z.string().min(1),\n expires_in: z.number().positive(),\n user: userSchema,\n});\n\nconst settingsSchema = z.object({ external: z.record(z.string(), z.boolean()) });\n\nconst errorSchema = z\n .object({\n error_description: z.string().optional(),\n msg: z.string().optional(),\n message: z.string().optional(),\n error: z.string().optional(),\n })\n .passthrough();\n\n/** A PKCE verifier and its S256 challenge. */\nexport function pkcePair(): { verifier: string; challenge: string } {\n const verifier = randomBytes(48).toString('base64url');\n return { verifier, challenge: createHash('sha256').update(verifier).digest('base64url') };\n}\n\nfunction toSession(raw: unknown, now: number): AccountSession {\n const parsed = sessionSchema.safeParse(raw);\n if (!parsed.success) throw new AccountError('The account service sent an unexpected reply.');\n const { user } = parsed.data;\n return {\n accessToken: parsed.data.access_token,\n refreshToken: parsed.data.refresh_token,\n expiresAt: now + parsed.data.expires_in * 1000,\n user: {\n id: user.id,\n ...(user.email ? { email: user.email } : {}),\n ...((user.user_metadata?.full_name ?? user.user_metadata?.name)\n ? { name: (user.user_metadata?.full_name ?? user.user_metadata?.name) as string }\n : {}),\n ...(user.app_metadata?.provider ? { provider: user.app_metadata.provider } : {}),\n },\n };\n}\n\nexport interface AccountClientOptions {\n fetch?: typeof fetch;\n now?: () => number;\n}\n\n/** Signs-up result: a session, or a pending confirmation e-mail. */\nexport type SignUpResult = { session: AccountSession } | { confirmEmail: true };\n\n/** Thin client for the Supabase Auth REST endpoints DaveCode needs. */\nexport class AccountClient {\n private readonly fetch: typeof fetch;\n private readonly now: () => number;\n\n constructor(\n readonly service: AccountServiceConfig,\n options: AccountClientOptions = {},\n ) {\n this.fetch = options.fetch ?? globalThis.fetch;\n this.now = options.now ?? Date.now;\n }\n\n /**\n * The hosted sign-in page (Google, GitHub or email). Every method ends by sending the browser\n * to `redirectTo` with `?code=` bound to `challenge`.\n */\n loginUrl(redirectTo: string, challenge: string): string {\n const url = new URL(`${this.service.url}/login`);\n url.searchParams.set('redirect_to', redirectTo);\n url.searchParams.set('code_challenge', challenge);\n return url.toString();\n }\n\n /** A page of the hosted service, such as `/login/done`. */\n pageUrl(path: string): string {\n return `${this.service.url}${path}`;\n }\n\n /** Browser URL that starts Google or GitHub sign-in and returns to `redirectTo` with `?code=`. */\n authorizeUrl(provider: OAuthProvider, redirectTo: string, challenge: string): string {\n const url = new URL(`${this.service.url}/auth/v1/authorize`);\n url.searchParams.set('provider', provider);\n url.searchParams.set('redirect_to', redirectTo);\n url.searchParams.set('code_challenge', challenge);\n url.searchParams.set('code_challenge_method', 's256');\n return url.toString();\n }\n\n exchangeCode(code: string, verifier: string): Promise<AccountSession> {\n return this.session('token?grant_type=pkce', { auth_code: code, code_verifier: verifier });\n }\n\n signInWithPassword(email: string, password: string): Promise<AccountSession> {\n return this.session('token?grant_type=password', { email, password });\n }\n\n /** Create an e-mail account. With confirmation on, the link returns to `redirectTo`. */\n async signUp(\n email: string,\n password: string,\n redirectTo: string,\n challenge: string,\n ): Promise<SignUpResult> {\n const raw = await this.post(`signup?redirect_to=${encodeURIComponent(redirectTo)}`, {\n email,\n password,\n code_challenge: challenge,\n code_challenge_method: 's256',\n });\n if (sessionSchema.safeParse(raw).success) return { session: toSession(raw, this.now()) };\n return { confirmEmail: true };\n }\n\n /** Sign-in methods the service has enabled; on any failure, assume all of them. */\n async providers(): Promise<OAuthProvider[]> {\n try {\n const response = await this.fetch(`${this.service.url}/auth/v1/settings`, {\n headers: { apikey: this.service.publishableKey },\n signal: AbortSignal.timeout(10_000),\n });\n const parsed = settingsSchema.safeParse(await response.json());\n if (!response.ok || !parsed.success) return [...OAUTH_PROVIDERS];\n return OAUTH_PROVIDERS.filter((p) => parsed.data.external[p] !== false);\n } catch {\n return [...OAUTH_PROVIDERS];\n }\n }\n\n refresh(refreshToken: string): Promise<AccountSession> {\n return this.session('token?grant_type=refresh_token', { refresh_token: refreshToken });\n }\n\n /** Revoke the session on the server. Best effort: the local copy is removed regardless. */\n async signOut(accessToken: string): Promise<void> {\n await this.fetch(`${this.service.url}/auth/v1/logout?scope=local`, {\n method: 'POST',\n headers: { apikey: this.service.publishableKey, Authorization: `Bearer ${accessToken}` },\n signal: AbortSignal.timeout(10_000),\n }).catch(() => undefined);\n }\n\n private async session(path: string, body: unknown): Promise<AccountSession> {\n return toSession(await this.post(path, body), this.now());\n }\n\n private async post(path: string, body: unknown): Promise<unknown> {\n let response: Response;\n try {\n response = await this.fetch(`${this.service.url}/auth/v1/${path}`, {\n method: 'POST',\n headers: { apikey: this.service.publishableKey, 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(20_000),\n });\n } catch {\n throw new AccountError('Cannot reach the DaveCode account service. Check your connection.');\n }\n const raw: unknown = await response.json().catch(() => undefined);\n if (!response.ok) {\n const error = errorSchema.safeParse(raw);\n const detail = error.success\n ? (error.data.error_description ?? error.data.msg ?? error.data.message)\n : undefined;\n throw new AccountError(\n detail ?? `Sign-in failed (HTTP ${response.status}).`,\n response.status,\n error.success ? error.data.error : undefined,\n );\n }\n return raw;\n }\n}\n","import { randomBytes } from 'node:crypto';\nimport { createServer, type ServerResponse } from 'node:http';\nimport type { AddressInfo } from 'node:net';\nimport {\n type AccountClient,\n AccountError,\n type AccountSession,\n type OAuthProvider,\n pkcePair,\n} from './client';\n\nexport interface AccountLoginOptions {\n client: AccountClient;\n /** Go straight to this provider instead of the hosted page that offers every method. */\n provider?: OAuthProvider;\n /** Give up after this long (default 10 minutes). */\n timeoutMs?: number;\n}\n\nexport interface AccountLogin {\n /** Open this in the browser: the hosted sign-in page. */\n url: string;\n /** Resolves with the new session, rejects on failure, timeout or {@link AccountLogin.close}. */\n session: Promise<AccountSession>;\n close(): Promise<void>;\n}\n\nfunction redirect(res: ServerResponse, location: string) {\n res.writeHead(302, { Location: location, 'Cache-Control': 'no-store' });\n res.end();\n}\n\n/**\n * Sign in the way Claude Code and Codex do: the browser opens the hosted sign-in page, and a\n * one-shot listener on 127.0.0.1 (random port, random path) only receives the final redirect\n * with a PKCE-bound code. The CLI exchanges it, sends the browser to the hosted \"signed in\"\n * page and stops listening.\n */\nexport async function startAccountLogin(options: AccountLoginOptions): Promise<AccountLogin> {\n const { client } = options;\n const callbackPath = `/s/${randomBytes(18).toString('base64url')}/callback`;\n const pkce = pkcePair();\n let finish: (session: AccountSession) => void = () => {};\n let fail: (error: Error) => void = () => {};\n let settled = false;\n const session = new Promise<AccountSession>((resolve, reject) => {\n finish = resolve;\n fail = reject;\n });\n // Callers may only await `session` later; avoid an unhandled rejection meanwhile.\n session.catch(() => {});\n\n const server = createServer((req, res) => {\n void (async () => {\n const url = new URL(req.url ?? '/', 'http://127.0.0.1');\n if (req.method !== 'GET' || url.pathname !== callbackPath || settled) {\n res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });\n res.end('Not found');\n return;\n }\n const code = url.searchParams.get('code');\n if (!code) {\n settled = true;\n fail(\n new AccountError(\n url.searchParams.get('error_description') ?? 'The sign-in was not completed.',\n ),\n );\n redirect(res, client.pageUrl('/login/failed'));\n return;\n }\n settled = true;\n try {\n finish(await client.exchangeCode(code, pkce.verifier));\n redirect(res, client.pageUrl('/login/done'));\n } catch (err) {\n fail(err instanceof AccountError ? err : new AccountError('Sign-in failed.'));\n redirect(res, client.pageUrl('/login/failed'));\n }\n })().catch(() => {\n if (!res.headersSent) res.writeHead(500).end();\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(0, '127.0.0.1', () => resolve());\n });\n const port = (server.address() as AddressInfo).port;\n\n const close = () =>\n new Promise<void>((resolve) => {\n server.closeAllConnections();\n server.close(() => resolve());\n });\n const timeout = setTimeout(\n () => {\n fail(new AccountError('Sign-in timed out. Run davecode login to try again.'));\n },\n options.timeoutMs ?? 10 * 60_000,\n );\n timeout.unref();\n // Give the browser a moment to follow the final redirect before the listener goes away.\n void session.then(\n () => setTimeout(() => void close(), 1_000).unref(),\n () => setTimeout(() => void close(), 1_000).unref(),\n );\n\n const redirectTo = `http://127.0.0.1:${port}${callbackPath}`;\n return {\n url: options.provider\n ? client.authorizeUrl(options.provider, redirectTo, pkce.challenge)\n : client.loginUrl(redirectTo, pkce.challenge),\n session,\n close: async () => {\n clearTimeout(timeout);\n fail(new AccountError('Sign-in cancelled.'));\n await close();\n },\n };\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';\nimport { mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { z } from 'zod';\nimport { loadMasterKey } from '../identity/keyring';\nimport { globalPaths } from '../paths';\nimport { type AccountClient, AccountError, type AccountSession } from './client';\n\nconst AAD = Buffer.from('davecode-account', 'utf8');\n/** Refresh this long before the access token expires. */\nconst REFRESH_MARGIN_MS = 60_000;\nconst LOCK_STALE_MS = 60_000;\nconst LOCK_WAIT_MS = 30_000;\nconst LOCK_POLL_MS = 50;\n/** Errors from the service that mean \"this refresh token is dead\", not \"try again later\". */\nconst INVALID_TOKEN_CODES = new Set([\n 'invalid_grant',\n 'refresh_token_not_found',\n 'refresh_token_already_used',\n 'session_not_found',\n 'session_expired',\n]);\n\nconst fileSchema = z.object({\n v: z.literal(1),\n iv: z.string(),\n tag: z.string(),\n data: z.string(),\n});\n\nconst sessionSchema = z.object({\n accessToken: z.string().min(1),\n refreshToken: z.string().min(1),\n expiresAt: z.number(),\n user: z.object({\n id: z.string().min(1),\n email: z.string().optional(),\n name: z.string().optional(),\n provider: z.string().optional(),\n }),\n});\n\nexport function accountFile(home: string): string {\n return join(home, 'account.json');\n}\n\n/**\n * The signed-in DaveCode account, encrypted at rest with the keyring's master key (AES-256-GCM).\n * Tokens never leave this file except in requests to the account service.\n */\nexport class AccountStore {\n private readonly path: string;\n private readonly key: Buffer;\n\n constructor(\n readonly home: string,\n env: NodeJS.ProcessEnv = process.env,\n ) {\n this.path = accountFile(home);\n this.key = loadMasterKey(globalPaths(home).masterKey, env);\n }\n\n load(): AccountSession | undefined {\n let raw: string;\n try {\n raw = readFileSync(this.path, 'utf8');\n } catch {\n return undefined;\n }\n try {\n const file = fileSchema.parse(JSON.parse(raw));\n const decipher = createDecipheriv('aes-256-gcm', this.key, Buffer.from(file.iv, 'base64'));\n decipher.setAAD(AAD);\n decipher.setAuthTag(Buffer.from(file.tag, 'base64'));\n const plain = Buffer.concat([\n decipher.update(Buffer.from(file.data, 'base64')),\n decipher.final(),\n ]).toString('utf8');\n return sessionSchema.parse(JSON.parse(plain)) as AccountSession;\n } catch {\n // A corrupt or foreign file means \"signed out\", never a crash.\n return undefined;\n }\n }\n\n save(session: AccountSession): void {\n const iv = randomBytes(12);\n const cipher = createCipheriv('aes-256-gcm', this.key, iv);\n cipher.setAAD(AAD);\n const data = Buffer.concat([cipher.update(JSON.stringify(session), 'utf8'), cipher.final()]);\n mkdirSync(dirname(this.path), { recursive: true });\n writeFileSync(\n this.path,\n `${JSON.stringify({\n v: 1,\n iv: iv.toString('base64'),\n tag: cipher.getAuthTag().toString('base64'),\n data: data.toString('base64'),\n })}\\n`,\n { mode: 0o600 },\n );\n }\n\n clear(): void {\n rmSync(this.path, { force: true });\n }\n\n /**\n * The current session, refreshed when it is about to expire. Returns undefined when signed out\n * or when the service revoked the session; offline, an unexpired session is still returned.\n */\n async current(client: AccountClient, now = Date.now()): Promise<AccountSession | undefined> {\n const first = this.load();\n if (!first) return undefined;\n if (first.expiresAt - REFRESH_MARGIN_MS > now) return first;\n // One process refreshes at a time: the others wait, then pick up what it saved.\n const release = await this.lock();\n try {\n const session = this.load();\n if (!session) return undefined;\n if (session.expiresAt - REFRESH_MARGIN_MS > now) return session;\n try {\n const fresh = await client.refresh(session.refreshToken);\n this.save(fresh);\n return fresh;\n } catch (err) {\n if (isInvalidToken(err)) {\n // Only the token we used is dead; a newer one saved meanwhile is not ours to clear.\n if (this.load()?.refreshToken === session.refreshToken) this.clear();\n return this.load();\n }\n // Unreachable, rate limited or failing service: keep the cached identity and try later.\n return session;\n }\n } finally {\n release();\n }\n }\n\n /**\n * A cross-process lock: a file created exclusively next to account.json. A lock older than\n * LOCK_STALE_MS belongs to a process that died, and is taken over. After LOCK_WAIT_MS the\n * refresh goes ahead without it (the service tolerates two refreshes racing).\n */\n private async lock(): Promise<() => void> {\n const path = `${this.path}.lock`;\n const owner = `${process.pid}:${randomBytes(8).toString('hex')}`;\n mkdirSync(dirname(path), { recursive: true });\n const deadline = Date.now() + LOCK_WAIT_MS;\n for (;;) {\n try {\n writeFileSync(path, owner, { flag: 'wx', mode: 0o600 });\n return () => {\n try {\n if (readFileSync(path, 'utf8') === owner) rmSync(path, { force: true });\n } catch {\n // Already gone or taken over as stale: nothing of ours to remove.\n }\n };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST' && !isWindowsBusy(err))\n return () => undefined;\n }\n try {\n if (Date.now() - statSync(path).mtimeMs > LOCK_STALE_MS) rmSync(path, { force: true });\n } catch {\n // Released between the check and the stat: try again straight away.\n }\n if (Date.now() >= deadline) return () => undefined;\n await new Promise((resolve) => setTimeout(resolve, LOCK_POLL_MS));\n }\n }\n}\n\n/** The service said this refresh token is no good (as opposed to being busy or down). */\nfunction isInvalidToken(err: unknown): boolean {\n if (!(err instanceof AccountError) || err.status === undefined) return false;\n if (err.code) return INVALID_TOKEN_CODES.has(err.code);\n return err.status === 400 || err.status === 401;\n}\n\nconst isWindowsBusy = (err: unknown) =>\n ['EPERM', 'EBUSY'].includes((err as NodeJS.ErrnoException).code ?? '');\n","import {\n AccountClient,\n type AccountServiceConfig,\n type AccountUser,\n accountService,\n type OAuthProvider,\n} from './client';\nimport { type AccountLogin, startAccountLogin } from './login-server';\nimport { AccountStore } from './store';\n\n/** What a local app may know about the signed-in account: identity only, never tokens. */\nexport interface AccountState {\n signedIn: boolean;\n user: AccountUser | null;\n /** A browser sign-in is waiting to finish. */\n pending: boolean;\n /** Why the last sign-in did not finish, safe to show. */\n error: string | null;\n}\n\nexport interface AccountLoginStart {\n /** Show this link when the browser could not be opened. */\n url: string;\n opened: boolean;\n}\n\n/** The machine's DaveCode account, shared with `davecode login` through the same store. */\nexport interface AccountControl {\n state(): Promise<AccountState>;\n /** Opens the browser and returns without waiting; a new sign-in replaces a pending one. */\n login(provider?: OAuthProvider): Promise<AccountLoginStart>;\n cancel(): Promise<void>;\n logout(): Promise<void>;\n /** Stops listening for a pending sign-in. */\n close(): Promise<void>;\n}\n\nexport interface AccountControlOptions {\n home: string;\n env?: NodeJS.ProcessEnv;\n /** Opens a URL in the user's browser. Resolves false when it could not. */\n open(url: string): Promise<boolean>;\n service?: AccountServiceConfig;\n fetch?: typeof fetch;\n /** Give up on a sign-in after this long (default 10 minutes). */\n timeoutMs?: number;\n}\n\nconst SIGN_IN_FAILED = 'Sign-in did not finish. Please try again.';\n\n/** Undefined when this build has no account service. */\nexport function createAccountControl(options: AccountControlOptions): AccountControl | undefined {\n const service = options.service ?? accountService(options.env);\n if (!service) return undefined;\n const client = new AccountClient(service, options.fetch ? { fetch: options.fetch } : {});\n // Built on use: reading the master key must not be able to stop a gateway from starting.\n const store = () => new AccountStore(options.home, options.env);\n let active: AccountLogin | undefined;\n let error: string | null = null;\n\n async function stop(): Promise<void> {\n const login = active;\n active = undefined;\n await login?.close();\n }\n\n async function finish(login: AccountLogin): Promise<void> {\n try {\n const session = await login.session;\n if (active !== login) return;\n active = undefined;\n store().save(session);\n } catch {\n // A replaced or cancelled sign-in is not a failure the user needs to hear about.\n if (active !== login) return;\n active = undefined;\n error = SIGN_IN_FAILED;\n }\n }\n\n return {\n async state() {\n const session = await store().current(client);\n return {\n signedIn: Boolean(session),\n user: session?.user ?? null,\n pending: active !== undefined,\n error,\n };\n },\n async login(provider) {\n await stop();\n error = null;\n const login = await startAccountLogin({\n client,\n ...(provider ? { provider } : {}),\n ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),\n });\n active = login;\n void finish(login);\n const opened = await options.open(login.url).catch(() => false);\n return { url: login.url, opened };\n },\n async cancel() {\n error = null;\n await stop();\n },\n async logout() {\n await stop();\n error = null;\n const accounts = store();\n const session = accounts.load();\n try {\n if (session) await client.signOut(session.accessToken);\n } catch {\n // Offline or rejected: this machine still signs out, and the token expires by itself.\n }\n accounts.clear();\n },\n close: stop,\n };\n}\n","/**\n * Brand assets shared by the CLI, the sign-in pages and the apps. The masters live in\n * `assets/brand/`; change the logo there and here, and everything that draws it follows.\n */\n\n/** The bird mark as an inline SVG (inherits `currentColor`). */\nexport const BRAND_MARK_SVG =\n '<svg viewBox=\"0 0 1214 1214\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">' +\n '<path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M324.3 1096.5C324.6 1095.4 326.5 1088.3 328.5 1080.8C341.4 1031.3 375.8 953.4 419.7 874.0C445.8 826.9 448.4 822.4 471.8 783.0C501.5 733.1 530.1 687.6 556.4 648.5C563.7 637.5 569.7 628.4 569.5 628.2C569.4 628.1 563.1 631.7 555.4 636.3C513.8 661.4 468.0 683.9 411.0 707.5C337.2 737.9 321.7 744.7 296.0 757.2C241.9 783.5 199.1 809.4 152.0 844.3C119.5 868.4 98.8 885.9 71.3 912.4C64.0 919.5 58.0 925.0 58.0 924.7C58.0 923.1 64.7 902.4 68.8 891.0C116.1 762.1 215.0 644.2 351.0 554.8C385.2 532.3 411.6 516.9 445.5 499.4C521.4 460.4 589.4 435.7 636.0 430.0C676.8 425.1 715.1 437.0 743.9 463.6C763.4 481.6 779.0 509.9 785.2 538.5C787.7 550.1 788.7 579.7 787.1 592.5C782.6 626.4 769.7 661.5 746.5 702.0C717.7 752.5 675.6 806.9 627.0 856.4C599.5 884.4 575.9 905.4 542.5 931.6C510.0 957.1 500.7 964.2 432.5 1015.0C409.4 1032.3 382.6 1052.5 373.0 1060.0C354.5 1074.4 327.4 1095.5 325.1 1097.4C324.0 1098.3 323.8 1098.1 324.3 1096.5ZM783.2 1017.8C797.1 999.5 820.2 966.0 831.7 947.5C868.5 888.3 888.8 840.5 903.4 778.5C917.9 716.9 921.2 643.7 912.0 591.0C904.6 549.3 889.7 511.9 866.7 477.5C856.6 462.3 853.1 457.8 837.4 439.6C817.4 416.6 806.6 402.0 800.5 389.5C793.6 375.5 791.7 368.1 791.7 356.0C791.7 335.3 799.3 319.6 819.0 299.9C849.7 269.2 900.2 247.9 956.8 241.9C963.0 241.2 967.7 240.3 967.3 239.9C966.1 238.8 948.5 236.3 933.0 234.9C913.6 233.2 875.2 234.3 859.0 237.0C839.7 240.2 827.8 242.9 813.0 247.5C753.9 265.9 700.6 300.9 659.2 348.5C648.9 360.4 636.6 376.5 632.4 383.5C630.3 387.1 629.0 388.2 624.7 389.6C603.8 396.4 554.6 417.6 513.5 437.5C447.6 469.4 395.4 496.8 341.5 528.1L337.5 530.4L339.5 527.9C340.6 526.6 346.2 520.3 352.0 514.0C374.4 489.6 390.2 470.8 411.2 443.5C429.3 419.9 444.6 398.2 488.5 333.5C510.5 301.0 529.1 278.0 550.9 256.3C593.0 214.1 640.3 183.6 691.5 165.5C727.7 152.8 756.5 147.7 792.5 147.7C854.3 147.8 906.4 164.9 954.1 200.6C967.5 210.8 974.1 214.6 981.5 217.0C991.4 220.1 1022.1 231.9 1038.5 238.8C1061.9 248.7 1099.0 267.4 1097.7 268.7C1097.4 268.9 1089.3 268.5 1079.7 267.9C1033.7 264.7 984.5 274.1 946.2 293.4C932.3 300.4 915.0 313.0 903.4 324.5C881.0 346.6 870.0 369.6 870.0 394.4C870.0 413.7 876.8 433.1 894.7 465.2C908.8 490.3 914.6 501.1 922.8 517.5C961.3 594.3 980.0 662.5 980.0 725.4C980.0 770.9 967.3 818.9 944.4 860.4C927.6 890.8 912.0 911.0 882.5 940.6C856.5 966.7 828.5 989.7 797.0 1010.7C779.6 1022.2 780.0 1022.0 783.2 1017.8Z\"/></svg>';\n\n/** The bird in half-block characters (two pixels per cell), from `assets/brand/logo-source.png`. */\nconst LOGO_ART = [\n ' ▄▄▄█▄▄▄',\n ' ▄███▀▀███▀▀',\n ' ███▀ █▀',\n ' ██▄▄██▄ ▀█',\n ' ▄█████████ █',\n ' ▄████▀█████ █',\n ' ▄██▀▀ ▄████▀ █▀',\n '▄▀▀ ▄███▀ ▄█',\n ' ▄██▀ ▄▀',\n ' ▀',\n];\n\n/**\n * The logo as terminal lines. `unicode: false` swaps the blocks for ASCII on terminals that\n * cannot draw them.\n */\nexport function brandLogo(unicode = true): string[] {\n if (unicode) return [...LOGO_ART];\n return LOGO_ART.map((line) =>\n line.replaceAll('█', '#').replaceAll('▀', '\"').replaceAll('▄', '.'),\n );\n}\n","/**\n * Changes: review what the agents changed and ship it. Every pane can work in the project's own\n * checkout (`main`) or in an isolated git worktree on its own branch (`davecode/pane-<id>`).\n * For each workspace the user sees the changed files and their diff, and can commit, push and\n * open a pull request in one step, or merge an isolated branch back into the checkout.\n *\n * This file is the shared contract between the service (`service.ts`), the HTTP routes, the\n * desktop app and the UI. Change it only together with `docs/API.md`.\n */\nimport { z } from 'zod';\n\nexport const CHANGES_LIMITS = {\n /** Most isolated workspaces per project. */\n maxWorkspaces: 12,\n labelMaxLength: 60,\n messageMaxLength: 5000,\n titleMaxLength: 200,\n bodyMaxLength: 20_000,\n /** Largest patch returned by `diff` (characters); longer patches are cut and flagged. */\n diffMaxLength: 1_000_000,\n /** Largest untracked file rendered as a patch (bytes); bigger ones are listed as binary. */\n untrackedMaxBytes: 512 * 1024,\n /** Largest patch handed to an agent to write the commit message (characters). */\n suggestDiffMaxLength: 40_000,\n /** Hard timeout for an agent writing the commit message. */\n suggestTimeoutMs: 3 * 60_000,\n} as const;\n\n/** The id of the project's own checkout. Isolated workspaces use short lowercase ids. */\nexport const MAIN_WORKSPACE_ID = 'main';\nexport const WORKSPACE_ID_PATTERN = /^[a-z0-9]{4,24}$/;\n/** Branch prefix of isolated workspaces before they get a name from their pull request. */\nexport const PANE_BRANCH_PREFIX = 'davecode/pane-';\n\nexport const workspaceIdSchema = z\n .string()\n .refine((id) => id === MAIN_WORKSPACE_ID || WORKSPACE_ID_PATTERN.test(id), 'invalid workspace');\n\nexport type ChangedFileStatus = 'added' | 'modified' | 'deleted' | 'renamed' | 'untracked';\n\nexport interface ChangedFile {\n /** Path relative to the workspace root, with `/` separators. */\n path: string;\n /** Previous path of a renamed file. */\n oldPath?: string;\n status: ChangedFileStatus;\n additions: number;\n deletions: number;\n binary: boolean;\n}\n\nexport interface ChangesWorkspace {\n /** `main` for the project checkout, or the isolated workspace's id. */\n id: string;\n /** What the user called it (the agent's name for panes), or the project folder's name. */\n label: string;\n /** True for a git worktree on its own branch; false for the project checkout. */\n isolated: boolean;\n /** Absolute path of the working tree. */\n path: string;\n /** Checked-out branch; absent when HEAD is detached. */\n branch?: string;\n /** Branch an isolated workspace started from, and the default base of its pull request. */\n baseBranch?: string;\n /**\n * Files that differ: for the checkout, uncommitted changes against HEAD; for an isolated\n * workspace, everything since it left `baseBranch` (its commits plus uncommitted work).\n */\n files: ChangedFile[];\n additions: number;\n deletions: number;\n /** Uncommitted changes exist (tracked or untracked). */\n dirty: boolean;\n /** Commits not yet in `baseBranch` (isolated) or not yet pushed (checkout with upstream). */\n ahead: number;\n /** `origin/<branch>` when the branch tracks a remote branch. */\n upstream?: string;\n /** Commits on this branch that its upstream lacks; equals `ahead` without an upstream. */\n unpushed: number;\n /** The repository has an `origin` remote. */\n hasRemote: boolean;\n createdAt?: string;\n}\n\nexport interface ChangesDiff {\n /** Unified patch (git format), untracked files included as new files. */\n patch: string;\n /** The patch was longer than `diffMaxLength` and was cut. */\n truncated: boolean;\n}\n\n/** A commit message and pull request text, written by an agent or derived from the file list. */\nexport interface ChangesSuggestion {\n message: string;\n title: string;\n body: string;\n /** Who wrote it: an agent id, or `davecode` for the deterministic fallback. */\n by: 'davecode' | 'claude' | 'codex' | 'agy';\n}\n\nexport type ShipPhase = 'branch' | 'commit' | 'push' | 'pr';\n\nexport interface ShipStep {\n phase: ShipPhase;\n ok: boolean;\n /** What happened: the new branch, the commit, the pull request URL, or why it failed. */\n detail: string;\n}\n\nexport interface ShipResult {\n /** Every requested step succeeded. */\n ok: boolean;\n steps: ShipStep[];\n /** Short commit id when a commit was made. */\n commit?: string;\n /** Branch the work ended up on. */\n branch?: string;\n prUrl?: string;\n /** The workspace after shipping. */\n workspace: ChangesWorkspace;\n}\n\nconst safeRef = z\n .string()\n .regex(/^(?!.*\\.\\.)(?!.*\\/\\/)(?!\\/)(?!.*\\/$)(?!.*\\.lock$)(?!-)[A-Za-z0-9._/-]{1,200}$/);\n\nexport const createWorkspaceSchema = z.object({\n label: z.string().trim().min(1).max(CHANGES_LIMITS.labelMaxLength).optional(),\n});\nexport type CreateWorkspaceInput = z.infer<typeof createWorkspaceSchema>;\n\nexport const suggestSchema = z.object({\n /** Agent that writes the text; without one, DaveCode derives it from the file list. */\n agent: z.enum(['claude', 'codex', 'agy']).optional(),\n});\nexport type SuggestInput = z.infer<typeof suggestSchema>;\n\n/**\n * One click from the review panel. Steps run in order and stop at the first failure:\n * `branch` (only for a pull request from the default branch, or to name a pane branch),\n * `commit` (when `message` is given and there are changes), `push` (when `push` or `pr`),\n * then `pr`.\n */\nexport const shipSchema = z.object({\n message: z.string().trim().min(1).max(CHANGES_LIMITS.messageMaxLength).optional(),\n push: z.boolean().default(false),\n pr: z\n .object({\n title: z.string().trim().min(1).max(CHANGES_LIMITS.titleMaxLength),\n body: z.string().max(CHANGES_LIMITS.bodyMaxLength).default(''),\n draft: z.boolean().default(false),\n /** Default: `baseBranch` for isolated workspaces, the remote's default branch otherwise. */\n base: safeRef.optional(),\n })\n .optional(),\n});\nexport type ShipInput = z.input<typeof shipSchema>;\n\nexport const mergeSchema = z.object({\n /** Commits uncommitted work in the isolated workspace with this message before merging. */\n message: z.string().trim().min(1).max(CHANGES_LIMITS.messageMaxLength).optional(),\n});\nexport type MergeInput = z.infer<typeof mergeSchema>;\n\nexport const removeSchema = z.object({\n /** Also delete the workspace's branch. By default it stays, so no work is lost. */\n deleteBranch: z.boolean().default(false),\n});\nexport type RemoveInput = z.input<typeof removeSchema>;\n\nexport interface ChangesService {\n /** The checkout first, then isolated workspaces, oldest first. */\n list(): Promise<ChangesWorkspace[]>;\n get(id: string): Promise<ChangesWorkspace>;\n /** A new worktree on `davecode/pane-<id>`, branched from the checkout's current commit. */\n create(input?: CreateWorkspaceInput): Promise<ChangesWorkspace>;\n /** Patch of the workspace's changes, or of one file. */\n diff(id: string, file?: string): Promise<ChangesDiff>;\n /** Commit message and pull request text for the workspace's changes. */\n suggest(id: string, input?: SuggestInput): Promise<ChangesSuggestion>;\n ship(id: string, input: ShipInput): Promise<ShipResult>;\n /** Merges an isolated workspace's branch into the checkout's current branch. */\n merge(id: string, input?: MergeInput): Promise<ChangesWorkspace>;\n /** Removes an isolated workspace's worktree (and its branch with `deleteBranch`). */\n remove(id: string, input?: RemoveInput): Promise<void>;\n}\n\nexport type ChangesErrorCode =\n | 'not_found'\n | 'not_a_repository'\n | 'invalid'\n | 'limit'\n | 'nothing_to_commit'\n | 'dirty'\n | 'conflict'\n | 'unavailable';\n\nexport class ChangesError extends Error {\n constructor(\n readonly code: ChangesErrorCode,\n message: string,\n ) {\n super(message);\n this.name = 'ChangesError';\n }\n}\n","/**\n * Changes service: isolated pane worktrees, their status and diff, and the one-click\n * commit → push → pull request flow. Every git call goes through `Git` (`execFile`, no shell);\n * `gh` is run the same way. Nothing is ever force-pushed and no history is rewritten.\n */\nimport { execFile } from 'node:child_process';\nimport { createHash, randomBytes } from 'node:crypto';\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n realpathSync,\n rmSync,\n statSync,\n writeFileSync,\n} from 'node:fs';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport { assertSafeRef, Git, GitError } from '../autonomous/git';\nimport type { AgentRunner } from '../orchestrator/contract';\nimport { scrubSecrets } from '../orchestrator/runners';\nimport { resolveOnPath } from '../providers/shared/cli';\nimport {\n CHANGES_LIMITS,\n type ChangedFile,\n ChangesError,\n type ChangesService,\n type ChangesSuggestion,\n type ChangesWorkspace,\n MAIN_WORKSPACE_ID,\n mergeSchema,\n PANE_BRANCH_PREFIX,\n removeSchema,\n type ShipResult,\n type ShipStep,\n shipSchema,\n suggestSchema,\n WORKSPACE_ID_PATTERN,\n} from './contract';\nimport {\n countLines,\n looksBinary,\n mergeFileLists,\n newFilePatch,\n parseNameStatus,\n parseNumStat,\n scrubUrls,\n slugify,\n} from './parse';\nimport { agentPrompt, fallbackSuggestion, parseAgentSuggestion } from './suggest';\n\n/** The hash of the empty tree: the diff base of a repository without commits. */\nconst EMPTY_TREE = '4b825dc642cb6eb9a060e54bf8d69288fbee4904';\nconst FALLBACK_IDENTITY = ['-c', 'user.name=DaveCode', '-c', 'user.email=davecode@localhost'];\n/** Commit hooks and pushes can be slow; status calls use the default 2 minutes. */\nconst SLOW_MS = 10 * 60_000;\n\n/**\n * Where the isolated pane worktrees of `projectDir` live: under the DaveCode home, outside the\n * repository, one folder per project (first 16 hex digits of its path's SHA-256).\n */\nexport function paneWorktreesDir(home: string, projectDir: string): string {\n const key = createHash('sha256').update(path.resolve(projectDir)).digest('hex').slice(0, 16);\n return path.join(home, 'panes', key);\n}\n\n/** The worktree of pane workspace `id`, or undefined when the id is not a valid one. */\nexport function paneWorkspacePath(\n home: string,\n projectDir: string,\n id: string,\n): string | undefined {\n if (!WORKSPACE_ID_PATTERN.test(id)) return undefined;\n return path.join(paneWorktreesDir(home, projectDir), id);\n}\n\nexport interface ChangesServiceOptions {\n /** Absolute project root (the user's checkout). */\n projectDir: string;\n /** DaveCode home; isolated worktrees go under `<home>/panes/<project key>/`. */\n home: string;\n /** Environment for git and gh (default `process.env`). */\n env?: NodeJS.ProcessEnv;\n /** Writes commit messages from the patch. Without it only the file-list suggestion exists. */\n writer?: AgentRunner;\n /** GitHub CLI executable (default `gh`). */\n gh?: string;\n /** Runs `gh <args>` in `cwd` and returns stdout (tests). Default: the `gh` executable. */\n runGh?: (cwd: string, args: string[]) => Promise<string>;\n now?: () => Date;\n}\n\nconst metaSchema = z.object({\n id: z.string().regex(WORKSPACE_ID_PATTERN),\n label: z.string(),\n baseBranch: z.string().optional(),\n baseCommit: z.string(),\n createdAt: z.string(),\n});\ntype Meta = z.infer<typeof metaSchema>;\n\ninterface Target {\n id: string;\n label: string;\n path: string;\n isolated: boolean;\n meta?: Meta;\n}\n\nfunction short(err: unknown): string {\n const raw =\n err instanceof GitError\n ? err.stderr || err.message\n : err instanceof Error\n ? err.message\n : String(err);\n const text = scrubSecrets(scrubUrls(raw));\n return text.length <= 300 ? text : `${text.slice(0, 299)}…`;\n}\n\nfunction nul(out: string): string[] {\n return out.split('\\0').filter((f) => f.length > 0);\n}\n\nfunction samePath(a: string, b: string): boolean {\n const real = (p: string) => {\n try {\n return realpathSync.native(p);\n } catch {\n return path.resolve(p);\n }\n };\n const [x, y] = [real(a), real(b)];\n return process.platform === 'win32' ? x.toLowerCase() === y.toLowerCase() : x === y;\n}\n\nexport function createChangesService(options: ChangesServiceOptions): ChangesService {\n const projectDir = path.resolve(options.projectDir);\n const panesDir = paneWorktreesDir(options.home, projectDir);\n const env = options.env ?? process.env;\n const now = options.now ?? (() => new Date());\n const gitAt = (cwd: string, slow = false) =>\n new Git(cwd, { env, ...(slow ? { timeoutMs: SLOW_MS } : {}) });\n const repo = gitAt(projectDir);\n\n // Worktree creation, commits, merges and removal touch shared repository state.\n let queue: Promise<unknown> = Promise.resolve();\n const serial = <T>(fn: () => Promise<T>): Promise<T> => {\n const next = queue.then(fn, fn);\n queue = next.catch(() => undefined);\n return next;\n };\n\n const identity = new Map<string, boolean>();\n /** `-c user.*` overrides, only when git has no usable identity of its own. */\n async function identityArgs(g: Git): Promise<string[]> {\n if (identity.get(g.cwd)) return [];\n try {\n await g.run(['var', 'GIT_AUTHOR_IDENT']);\n await g.run(['var', 'GIT_COMMITTER_IDENT']);\n identity.set(g.cwd, true);\n return [];\n } catch {\n return FALLBACK_IDENTITY;\n }\n }\n\n async function assertRepo(): Promise<string> {\n if (!(await repo.isRepo())) {\n throw new ChangesError('not_a_repository', 'This folder is not a git repository.');\n }\n try {\n return (await repo.run(['rev-parse', '--verify', '--quiet', 'HEAD^{commit}'])).trim();\n } catch {\n throw new ChangesError('not_a_repository', 'This repository has no commits yet.');\n }\n }\n\n const metaFile = (id: string) => path.join(panesDir, `${id}.json`);\n\n function readMeta(id: string): Meta | undefined {\n try {\n const parsed = metaSchema.safeParse(JSON.parse(readFileSync(metaFile(id), 'utf8')));\n return parsed.success && parsed.data.id === id ? parsed.data : undefined;\n } catch {\n return undefined;\n }\n }\n\n function isolatedIds(): string[] {\n if (!existsSync(panesDir)) return [];\n return readdirSync(panesDir)\n .filter((name) => name.endsWith('.json'))\n .map((name) => name.slice(0, -5))\n .filter((id) => WORKSPACE_ID_PATTERN.test(id) && existsSync(path.join(panesDir, id)));\n }\n\n function target(id: string): Target {\n if (id === MAIN_WORKSPACE_ID) {\n return { id, label: path.basename(projectDir), path: projectDir, isolated: false };\n }\n const meta = WORKSPACE_ID_PATTERN.test(id) ? readMeta(id) : undefined;\n const dir = path.join(panesDir, id);\n if (!meta || !existsSync(dir)) throw new ChangesError('not_found', `unknown workspace \"${id}\"`);\n return { id, label: meta.label, path: dir, isolated: true, meta };\n }\n\n async function optional(g: Git, args: string[]): Promise<string | undefined> {\n try {\n const out = (await g.run(args)).trim();\n return out || undefined;\n } catch {\n return undefined;\n }\n }\n\n async function count(g: Git, range: string[]): Promise<number> {\n const out = await optional(g, ['rev-list', '--count', ...range]);\n return out ? Number(out) || 0 : 0;\n }\n\n /** What the workspace's changes are measured against. */\n async function diffBase(g: Git, t: Target): Promise<string> {\n const head = await optional(g, ['rev-parse', '--verify', '--quiet', 'HEAD^{commit}']);\n if (!head) return EMPTY_TREE;\n if (!t.isolated || !t.meta) return head;\n if (t.meta.baseBranch) {\n const base = await optional(g, ['merge-base', `refs/heads/${t.meta.baseBranch}`, 'HEAD']);\n if (base) return base;\n }\n return (await optional(g, ['merge-base', t.meta.baseCommit, 'HEAD'])) ?? t.meta.baseCommit;\n }\n\n async function untrackedFiles(g: Git, root: string): Promise<ChangedFile[]> {\n const paths = nul(await g.run(['ls-files', '--others', '--exclude-standard', '-z']));\n return paths.map((rel) => {\n const content = readUntracked(root, rel);\n const binary = !content || looksBinary(content);\n return {\n path: rel,\n status: 'untracked',\n additions: binary ? 0 : countLines(content.toString('utf8')),\n deletions: 0,\n binary,\n };\n });\n }\n\n /** The file's bytes, or undefined when it is too large to render (or vanished). */\n function readUntracked(root: string, rel: string): Buffer | undefined {\n const file = path.join(root, rel);\n try {\n if (statSync(file).size > CHANGES_LIMITS.untrackedMaxBytes) return undefined;\n return readFileSync(file);\n } catch {\n return undefined;\n }\n }\n\n async function changedFiles(g: Git, t: Target): Promise<{ base: string; files: ChangedFile[] }> {\n const base = await diffBase(g, t);\n const common = ['-c', 'core.quotepath=false', 'diff', '--no-ext-diff', '-M', '-z'];\n const [names, stats, untracked] = await Promise.all([\n g.run([...common, '--name-status', base]),\n g.run([...common, '--numstat', base]),\n untrackedFiles(g, t.path),\n ]);\n return { base, files: mergeFileLists(parseNameStatus(names), parseNumStat(stats), untracked) };\n }\n\n async function describe(t: Target): Promise<ChangesWorkspace> {\n const g = gitAt(t.path);\n const [branch, { files }, porcelain, hasRemote] = await Promise.all([\n optional(g, ['symbolic-ref', '--quiet', '--short', 'HEAD']),\n changedFiles(g, t),\n g.run(['status', '--porcelain', '-z', '--untracked-files=all']),\n g.hasRemote(),\n ]);\n const upstream = branch\n ? await optional(g, ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'])\n : undefined;\n let ahead = 0;\n let unpushed = 0;\n if (t.isolated && t.meta) {\n const base = t.meta.baseBranch ? `refs/heads/${t.meta.baseBranch}` : t.meta.baseCommit;\n ahead = await count(g, [`${base}..HEAD`]);\n }\n if (upstream) unpushed = await count(g, ['@{u}..HEAD']);\n else if (t.isolated) unpushed = ahead;\n else if (hasRemote) unpushed = await count(g, ['HEAD', '--not', '--remotes']);\n if (!t.isolated) ahead = unpushed;\n return {\n id: t.id,\n label: t.label,\n isolated: t.isolated,\n path: t.path,\n ...(branch ? { branch } : {}),\n ...(t.meta?.baseBranch ? { baseBranch: t.meta.baseBranch } : {}),\n files,\n additions: files.reduce((sum, f) => sum + f.additions, 0),\n deletions: files.reduce((sum, f) => sum + f.deletions, 0),\n dirty: porcelain.length > 0,\n ahead,\n ...(upstream ? { upstream } : {}),\n unpushed,\n hasRemote,\n ...(t.meta ? { createdAt: t.meta.createdAt } : {}),\n };\n }\n\n async function uniqueBranch(g: Git, wanted: string): Promise<string> {\n for (let n = 1; n < 100; n++) {\n const name = n === 1 ? wanted : `${wanted}-${n}`;\n if (!(await g.branchExists(name))) return name;\n }\n return `${wanted}-${randomBytes(3).toString('hex')}`;\n }\n\n /** The remote's default branch, else `main` or `master` if present, else undefined. */\n async function defaultBranch(g: Git): Promise<string | undefined> {\n const head = await optional(g, [\n 'symbolic-ref',\n '--quiet',\n '--short',\n 'refs/remotes/origin/HEAD',\n ]);\n if (head?.startsWith('origin/')) return head.slice('origin/'.length);\n for (const name of ['main', 'master']) if (await g.branchExists(name)) return name;\n return undefined;\n }\n\n function runGh(cwd: string, args: string[]): Promise<string> {\n if (options.runGh) return options.runGh(cwd, args);\n const gh = resolveOnPath(options.gh ?? 'gh', env);\n if (/\\.(cmd|bat)$/i.test(gh)) {\n return Promise.reject(new Error('gh is a shell shim; DaveCode will not pass text to it'));\n }\n return new Promise((resolve, reject) => {\n execFile(\n gh,\n args,\n {\n cwd,\n env: { ...env, GH_PROMPT_DISABLED: '1' },\n timeout: SLOW_MS,\n windowsHide: true,\n encoding: 'utf8',\n },\n (err, stdout, stderr) => {\n if (err) {\n const missing = (err as NodeJS.ErrnoException).code === 'ENOENT';\n reject(\n new Error(\n missing\n ? 'GitHub CLI (gh) is not installed. Install it and run `gh auth login`.'\n : (stderr || err.message).trim(),\n ),\n );\n } else resolve(stdout.trim());\n },\n );\n });\n }\n\n async function commitAll(g: Git, message: string): Promise<string | undefined> {\n await g.run(['add', '-A']);\n if (!(await g.hasStagedChanges())) return undefined;\n await g.run([...(await identityArgs(g)), 'commit', '--quiet', '-m', message]);\n return (await g.run(['rev-parse', '--short', 'HEAD'])).trim();\n }\n\n function writeMeta(meta: Meta): void {\n mkdirSync(panesDir, { recursive: true });\n writeFileSync(metaFile(meta.id), `${JSON.stringify(meta, null, 2)}\\n`);\n }\n\n async function removeWorktree(dir: string): Promise<void> {\n try {\n await repo.run(['worktree', 'remove', '--force', dir]);\n } catch {\n // not registered, or already gone\n }\n if (existsSync(dir))\n rmSync(dir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });\n try {\n await repo.run(['worktree', 'prune']);\n } catch {\n // nothing to prune\n }\n }\n\n const service: ChangesService = {\n async list() {\n await assertRepo();\n const isolated = isolatedIds()\n .map((id) => target(id))\n .sort((a, b) => (a.meta?.createdAt ?? '').localeCompare(b.meta?.createdAt ?? ''));\n return Promise.all([target(MAIN_WORKSPACE_ID), ...isolated].map(describe));\n },\n\n async get(id) {\n await assertRepo();\n return describe(target(id));\n },\n\n create(input = {}) {\n return serial(async () => {\n const head = await assertRepo();\n if (isolatedIds().length >= CHANGES_LIMITS.maxWorkspaces) {\n throw new ChangesError(\n 'limit',\n `At most ${CHANGES_LIMITS.maxWorkspaces} isolated workspaces per project. Remove one first.`,\n );\n }\n const id = randomBytes(4).toString('hex').slice(0, 6);\n const dir = path.join(panesDir, id);\n const baseBranch = await optional(repo, ['symbolic-ref', '--quiet', '--short', 'HEAD']);\n const branch = await uniqueBranch(repo, `${PANE_BRANCH_PREFIX}${id}`);\n mkdirSync(panesDir, { recursive: true });\n await repo.run(['worktree', 'add', '-b', assertSafeRef(branch), dir, head]);\n writeMeta({\n id,\n label: input.label ?? 'Isolated',\n ...(baseBranch ? { baseBranch } : {}),\n baseCommit: head,\n createdAt: now().toISOString(),\n });\n return describe(target(id));\n });\n },\n\n async diff(id, file) {\n await assertRepo();\n const t = target(id);\n const g = gitAt(t.path);\n const { base, files } = await changedFiles(g, t);\n let selected = files;\n if (file !== undefined) {\n selected = files.filter((f) => f.path === file || f.oldPath === file);\n if (selected.length === 0) throw new ChangesError('not_found', `\"${file}\" has no changes`);\n }\n const tracked = selected.filter((f) => f.status !== 'untracked');\n let patch = '';\n if (tracked.length > 0) {\n const paths = tracked.flatMap((f) => (f.oldPath ? [f.oldPath, f.path] : [f.path]));\n patch = await g.run([\n '-c',\n 'core.quotepath=false',\n 'diff',\n '--no-ext-diff',\n '--no-color',\n '-M',\n base,\n '--',\n ...(file === undefined ? [] : paths),\n ]);\n }\n for (const f of selected) {\n if (f.status === 'untracked') patch += newFilePatch(f.path, readUntracked(t.path, f.path));\n }\n const truncated = patch.length > CHANGES_LIMITS.diffMaxLength;\n return { patch: truncated ? patch.slice(0, CHANGES_LIMITS.diffMaxLength) : patch, truncated };\n },\n\n async suggest(id, input = {}) {\n const { agent } = suggestSchema.parse(input);\n await assertRepo();\n const t = target(id);\n const workspace = await describe(t);\n if (workspace.files.length === 0) {\n throw new ChangesError('nothing_to_commit', 'There are no changes to describe.');\n }\n const fallback = fallbackSuggestion(workspace.files);\n if (!agent) return fallback;\n if (!options.writer) {\n throw new ChangesError('unavailable', 'No agent can write the message on this gateway.');\n }\n const { patch } = await service.diff(id);\n const controller = new AbortController();\n const result = await options.writer.run({\n agent,\n cwd: t.path,\n prompt: agentPrompt({\n ...(workspace.branch ? { branch: workspace.branch } : {}),\n files: workspace.files,\n patch,\n }),\n mode: 'plan',\n signal: controller.signal,\n timeoutMs: CHANGES_LIMITS.suggestTimeoutMs,\n onOutput: () => {},\n });\n const parsed = result.ok ? parseAgentSuggestion(result.text) : undefined;\n if (!parsed) {\n const why = result.ok\n ? 'it did not reply with the expected JSON'\n : (result.error ?? 'it failed');\n throw new ChangesError('unavailable', `${agent} could not write the message: ${why}`);\n }\n return { ...parsed, by: agent } satisfies ChangesSuggestion;\n },\n\n ship(id, input) {\n const request = shipSchema.parse(input);\n return serial(async (): Promise<ShipResult> => {\n await assertRepo();\n const t = target(id);\n const g = gitAt(t.path, true);\n const steps: ShipStep[] = [];\n let branch = await optional(g, ['symbolic-ref', '--quiet', '--short', 'HEAD']);\n let commit: string | undefined;\n let prUrl: string | undefined;\n const wantPush = request.push || request.pr !== undefined;\n if (!branch && (wantPush || request.pr)) {\n throw new ChangesError('invalid', 'HEAD is detached. Check out a branch first.');\n }\n const finish = async (ok: boolean): Promise<ShipResult> => ({\n ok,\n steps,\n ...(commit ? { commit } : {}),\n ...(branch ? { branch } : {}),\n ...(prUrl ? { prUrl } : {}),\n workspace: await describe(t),\n });\n const step = async (phase: ShipStep['phase'], work: () => Promise<string>) => {\n try {\n steps.push({ phase, ok: true, detail: await work() });\n return true;\n } catch (err) {\n steps.push({ phase, ok: false, detail: short(err) });\n return false;\n }\n };\n\n const before = await describe(t);\n if (request.message && !before.dirty && !wantPush) {\n throw new ChangesError('nothing_to_commit', 'There is nothing to commit.');\n }\n if (!request.message && !wantPush) {\n throw new ChangesError('invalid', 'Give a commit message, push or a pull request.');\n }\n\n // branch: a pull request needs its own branch; pane branches get a readable name.\n const base =\n request.pr?.base ??\n (t.isolated ? t.meta?.baseBranch : undefined) ??\n (request.pr ? await defaultBranch(g) : undefined);\n if (request.pr && branch) {\n const current = branch;\n const slug = slugify(request.pr.title);\n if (!t.isolated && current === base) {\n const ok = await step('branch', async () => {\n const name = await uniqueBranch(g, `davecode/${slug}`);\n await g.run(['switch', '--quiet', '-c', assertSafeRef(name)]);\n branch = name;\n return `Created ${name} from ${current}`;\n });\n if (!ok) return finish(false);\n } else if (t.isolated && current.startsWith(PANE_BRANCH_PREFIX) && !before.upstream) {\n const ok = await step('branch', async () => {\n const name = await uniqueBranch(g, `davecode/${slug}`);\n await g.run(['branch', '-m', assertSafeRef(current), assertSafeRef(name)]);\n branch = name;\n return `Renamed ${current} to ${name}`;\n });\n if (!ok) return finish(false);\n }\n }\n\n if (request.message && before.dirty) {\n const message = request.message;\n const ok = await step('commit', async () => {\n commit = await commitAll(g, message);\n if (!commit) throw new Error('Nothing was staged.');\n return `Committed ${commit}`;\n });\n if (!ok) return finish(false);\n }\n\n if (wantPush && branch) {\n const name = branch;\n const ok = await step('push', async () => {\n if (!(await g.hasRemote())) throw new Error('This repository has no \"origin\" remote.');\n await g.run(['push', '--quiet', '--set-upstream', 'origin', assertSafeRef(name)]);\n return `Pushed ${name} to origin`;\n });\n if (!ok) return finish(false);\n }\n\n if (request.pr && branch) {\n const pr = request.pr;\n const head = branch;\n const ok = await step('pr', async () => {\n if (!base) throw new Error('Could not tell which branch the pull request targets.');\n if (base === head) throw new Error(`The pull request would merge ${head} into itself.`);\n const args = [\n 'pr',\n 'create',\n '--base',\n assertSafeRef(base),\n '--head',\n assertSafeRef(head),\n ];\n args.push('--title', pr.title, '--body', pr.body || pr.title);\n if (pr.draft) args.push('--draft');\n try {\n const out = await runGh(t.path, args);\n prUrl = out.split('\\n').at(-1)?.trim() || out;\n } catch (err) {\n const text = err instanceof Error ? err.message : String(err);\n if (!/already exists/i.test(text)) throw err;\n prUrl = await runGh(t.path, ['pr', 'view', head, '--json', 'url', '--jq', '.url']);\n }\n return prUrl;\n });\n if (!ok) return finish(false);\n }\n return finish(true);\n });\n },\n\n merge(id, input = {}) {\n const { message } = mergeSchema.parse(input);\n return serial(async () => {\n await assertRepo();\n const t = target(id);\n if (!t.isolated)\n throw new ChangesError('invalid', 'Only an isolated workspace can be merged.');\n const g = gitAt(t.path, true);\n const branch = await optional(g, ['symbolic-ref', '--quiet', '--short', 'HEAD']);\n if (!branch) throw new ChangesError('invalid', 'The workspace has no branch checked out.');\n let state = await describe(t);\n if (state.dirty) {\n if (!message) {\n throw new ChangesError(\n 'dirty',\n 'The workspace has uncommitted changes. Commit them first.',\n );\n }\n await commitAll(g, message);\n state = await describe(t);\n }\n if (state.ahead === 0)\n throw new ChangesError('nothing_to_commit', 'There is nothing to merge.');\n const into = await optional(repo, ['symbolic-ref', '--quiet', '--short', 'HEAD']);\n if (!into) throw new ChangesError('invalid', 'The project checkout is on a detached HEAD.');\n if (samePath(t.path, projectDir))\n throw new ChangesError('invalid', 'Cannot merge into itself.');\n const main = gitAt(projectDir, true);\n try {\n await main.run([\n ...(await identityArgs(main)),\n 'merge',\n '--no-ff',\n '--no-edit',\n '-m',\n `Merge ${t.label} (${branch}) into ${into}`,\n assertSafeRef(branch),\n ]);\n } catch (err) {\n const conflicts = nul(\n (await optional(main, ['diff', '--name-only', '-z', '--diff-filter=U'])) ?? '',\n );\n await main.abortMerge();\n throw new ChangesError(\n 'conflict',\n conflicts.length > 0\n ? `The merge conflicts in ${conflicts.join(', ')}. Nothing was changed.`\n : `The merge failed: ${short(err)}`,\n );\n }\n return describe(target(MAIN_WORKSPACE_ID));\n });\n },\n\n remove(id, input = {}) {\n const { deleteBranch } = removeSchema.parse(input);\n return serial(async () => {\n const t = target(id);\n if (!t.isolated)\n throw new ChangesError('invalid', 'The project checkout cannot be removed.');\n const branch = await optional(gitAt(t.path), [\n 'symbolic-ref',\n '--quiet',\n '--short',\n 'HEAD',\n ]);\n await removeWorktree(t.path);\n rmSync(metaFile(id), { force: true });\n if (deleteBranch && branch) {\n try {\n await repo.run(['branch', '-D', assertSafeRef(branch)]);\n } catch {\n // already gone\n }\n }\n });\n },\n };\n return service;\n}\n","/**\n * Headless runners for the pane orchestrator. Each run spawns a vendor CLI the user already\n * signed in to (Claude Code `claude`, Codex `codex`, Antigravity `agy`) with the prompt on\n * stdin, and reduces its NDJSON stream to plain-text {@link AgentOutput} lines.\n *\n * The CLIs use their normal global sign-in, exactly like the desktop terminal panes: no\n * `CLAUDE_CONFIG_DIR` / `CODEX_HOME` sandbox is set.\n *\n * `plan` mode must not modify files:\n * - claude: `--permission-mode plan`, the built-in tools reduced to `Read Glob Grep` with\n * `--tools`, and `--strict-mcp-config` so no MCP server (and none of its write tools) loads.\n * The model cannot write even if it ignores plan mode, because no write tool exists.\n * - codex: `--sandbox read-only` (enforced by the OS sandbox), with `approval_policy=never` so\n * a user config asking for approvals cannot hang the headless run.\n * - agy: its `--mode plan` is only a prompt (a `/plan` expansion, ignored with\n * `--disable-slash-commands`) and headless runs auto-allow writes in the working directory,\n * so plan runs happen in a fresh empty temp directory that is removed afterwards. The prompt\n * is prefixed with a note that the repository is not visible.\n */\nimport { existsSync, mkdtempSync, realpathSync, rmSync, statSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\nimport {\n classifyCliText,\n isShellSafeArg,\n needsShell,\n resolveOnPath,\n runCli,\n} from '../providers/shared/cli';\nimport { redact } from '../providers/shared/errors';\nimport { asArray, asNumber, asString, isRecord } from '../providers/shared/util';\nimport type { ProviderKind } from '../types';\nimport {\n type AgentAvailability,\n type AgentOutput,\n type AgentRunner,\n type AgentRunRequest,\n type AgentRunResult,\n ORCHESTRATOR_AGENTS,\n type OrchestratorAgent,\n} from './contract';\n\nexport interface AgentBinary {\n /** Executable name (resolved on PATH) or absolute path. */\n command: string;\n /** Arguments placed before the runner's own (e.g. a script path when `command` is node). */\n args?: string[];\n}\n\nexport interface CliAgentRunnerOptions {\n /** Environment for the CLIs (default `process.env`). Their global sign-in is used. */\n env?: NodeJS.ProcessEnv;\n /** Override the executable per agent (defaults `claude`, `codex`, `agy`). */\n binaries?: Partial<Record<OrchestratorAgent, AgentBinary>>;\n /** Parent of the scratch directories used for Antigravity plan runs (default OS temp). */\n scratchDir?: string;\n}\n\nconst MAX_TEXT_CHUNK = 2000;\nconst MAX_TOOL_LINE = 200;\nconst MAX_ERROR = 300;\n\ninterface AgentInfo {\n label: string;\n binary: string;\n provider: ProviderKind;\n signIn: string;\n}\n\nconst AGENTS: Record<OrchestratorAgent, AgentInfo> = {\n claude: {\n label: 'Claude Code',\n binary: 'claude',\n provider: 'claude-cli',\n signIn: 'run `claude` in a terminal and sign in',\n },\n codex: {\n label: 'Codex',\n binary: 'codex',\n provider: 'codex-cli',\n signIn: 'run `codex login` in a terminal',\n },\n agy: {\n label: 'Antigravity',\n binary: 'agy',\n provider: 'antigravity-cli',\n signIn: 'run `agy` in a terminal and sign in',\n },\n};\n\nexport const AGY_PLAN_NOTE =\n 'Note: you are running in an empty scratch directory, not inside the project, so you cannot ' +\n \"see the repository's files. Answer from the information in this message only and do not \" +\n 'create files.';\n\n/** The CLI arguments for an agent and mode (prompt excluded: it always goes on stdin). */\nexport function agentArgs(agent: OrchestratorAgent, mode: AgentRunRequest['mode']): string[] {\n switch (agent) {\n case 'claude':\n return mode === 'plan'\n ? [\n '-p',\n '--output-format',\n 'stream-json',\n '--verbose',\n '--permission-mode',\n 'plan',\n '--tools',\n 'Read',\n 'Glob',\n 'Grep',\n '--strict-mcp-config',\n ]\n : ['-p', '--output-format', 'stream-json', '--verbose', '--permission-mode', 'acceptEdits'];\n case 'codex':\n return [\n 'exec',\n '--json',\n '--skip-git-repo-check',\n '--sandbox',\n mode === 'plan' ? 'read-only' : 'workspace-write',\n '-c',\n 'approval_policy=never',\n '-',\n ];\n case 'agy':\n return [\n '--input-format',\n 'stream-json',\n '--output-format',\n 'stream-json',\n '--sandbox',\n '--disable-slash-commands',\n '--print=',\n ];\n }\n}\n\n/** The canonical spelling of an existing path, or the path itself. */\nfunction realPath(p: string): string {\n try {\n return realpathSync.native(p);\n } catch {\n return path.resolve(p);\n }\n}\n\nfunction agentStdin(\n agent: OrchestratorAgent,\n mode: AgentRunRequest['mode'],\n prompt: string,\n): string {\n if (agent === 'agy') {\n const content = mode === 'plan' ? `${AGY_PLAN_NOTE}\\n\\n${prompt}` : prompt;\n return `${JSON.stringify({ event: 'user', message: { content } })}\\n`;\n }\n // `claude -p` treats a leading slash as a slash command.\n if (agent === 'claude' && prompt.trimStart().startsWith('/')) return `Task:\\n${prompt}`;\n return prompt;\n}\n\nfunction abortError(): Error {\n const err = new Error('The agent run was aborted');\n err.name = 'AbortError';\n return err;\n}\n\nconst SECRET_PATTERNS: Array<[RegExp, string]> = [\n [/\\b(?:sk|rk|pk)-[A-Za-z0-9_-]{8,}/g, '[redacted]'],\n [/\\b(?:ghp|gho|ghs|ghu|github_pat)_[A-Za-z0-9_]{8,}/g, '[redacted]'],\n [/\\bAIza[A-Za-z0-9_-]{20,}/g, '[redacted]'],\n [/\\bya29\\.[A-Za-z0-9._-]{10,}/g, '[redacted]'],\n [/\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]*/g, '[redacted]'],\n [/\\b(bearer)\\s+[^\\s\"']+/gi, '$1 [redacted]'],\n [\n /\\b(api[_-]?key|access[_-]?token|refresh[_-]?token|token|secret|password|authorization)([\"']?\\s*[:=]\\s*[\"']?)[^\\s\"',}]+/gi,\n '$1$2[redacted]',\n ],\n];\n\n/** Removes anything that looks like a credential and collapses whitespace. */\nexport function scrubSecrets(text: string): string {\n let out = redact(text);\n for (const [pattern, replacement] of SECRET_PATTERNS) out = out.replace(pattern, replacement);\n return out.replace(/\\s+/g, ' ').trim();\n}\n\nfunction clip(text: string, max: number): string {\n return text.length <= max ? text : `${text.slice(0, max - 1)}…`;\n}\n\nfunction shortError(text: string): string {\n return clip(scrubSecrets(text), MAX_ERROR);\n}\n\nfunction formatDuration(ms: number): string {\n if (ms >= 60_000) return `${Math.round(ms / 60_000)} min`;\n return `${Math.max(1, Math.ceil(ms / 1000))} s`;\n}\n\nfunction tail(text: string, max = 400): string {\n const t = text.trim();\n return t.length <= max ? t : t.slice(t.length - max);\n}\n\n/** `Edit src/x.ts`: a tool name plus a short hint taken from its input. */\nfunction toolLine(name: string, input: unknown, cwd: string): string {\n let hint: string | undefined;\n if (isRecord(input)) {\n const lower = new Map(Object.entries(input).map(([k, v]) => [k.toLowerCase(), v]));\n for (const key of [\n 'file_path',\n 'filepath',\n 'absolutepath',\n 'path',\n 'targetfile',\n 'command',\n 'commandline',\n 'cmd',\n 'pattern',\n 'query',\n 'url',\n 'description',\n ]) {\n const value = lower.get(key);\n const str = typeof value === 'string' ? value : Array.isArray(value) ? value.join(' ') : '';\n if (str.trim()) {\n hint = str;\n break;\n }\n }\n }\n if (hint && path.isAbsolute(hint)) {\n // Agents may report the resolved path (macOS /private/var, Windows long names).\n for (const base of new Set([cwd, realPath(cwd)])) {\n const rel = path.relative(base, hint);\n if (rel && !rel.startsWith('..') && !path.isAbsolute(rel)) {\n hint = rel.split(path.sep).join('/');\n break;\n }\n }\n }\n return clip(scrubSecrets(hint ? `${name} ${hint}` : name), MAX_TOOL_LINE);\n}\n\n// --- Stream parsers ----------------------------------------------------------------------------\n\ninterface ParseState {\n /** Final reply. */\n text: string;\n /** The CLI reported a successful end of the turn. */\n completed: boolean;\n /** Failure reported in-stream. */\n failure?: string;\n tokens?: number;\n}\n\ninterface StreamParser {\n state: ParseState;\n handle(event: unknown): void;\n flush(): void;\n}\n\ntype Emit = (chunk: AgentOutput) => void;\n\nfunction claudeParser(emit: Emit, cwd: string): StreamParser {\n const state: ParseState = { text: '', completed: false };\n let lastAssistant = '';\n return {\n state,\n flush() {},\n handle(raw) {\n if (!isRecord(raw)) return;\n const type = asString(raw.type);\n if (type === 'system' && raw.subtype === 'init') {\n const model = asString(raw.model);\n emit({\n kind: 'status',\n text: model ? `Claude Code started (${model})` : 'Claude Code started',\n });\n return;\n }\n if (type === 'assistant' && raw.parent_tool_use_id == null && isRecord(raw.message)) {\n const texts: string[] = [];\n for (const block of asArray(raw.message.content)) {\n if (!isRecord(block)) continue;\n if (block.type === 'text') {\n const t = asString(block.text)?.trim();\n if (t) texts.push(t);\n } else if (block.type === 'tool_use') {\n emit({\n kind: 'tool',\n text: toolLine(asString(block.name) ?? 'tool', block.input, cwd),\n });\n }\n }\n if (texts.length > 0) {\n lastAssistant = texts.join('\\n');\n emit({ kind: 'text', text: clip(lastAssistant, MAX_TEXT_CHUNK) });\n }\n return;\n }\n if (type === 'result') {\n const result = asString(raw.result) ?? '';\n const subtype = asString(raw.subtype) ?? 'success';\n const u = isRecord(raw.usage) ? raw.usage : undefined;\n if (u) {\n state.tokens =\n (asNumber(u.input_tokens) ?? 0) +\n (asNumber(u.cache_creation_input_tokens) ?? 0) +\n (asNumber(u.cache_read_input_tokens) ?? 0) +\n (asNumber(u.output_tokens) ?? 0);\n }\n if (raw.is_error === true || subtype !== 'success') {\n state.failure = result || `Claude Code reported ${subtype}`;\n return;\n }\n state.completed = true;\n state.text = result || lastAssistant;\n }\n },\n };\n}\n\nfunction codexErrorText(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (isRecord(value)) return asString(value.message) ?? JSON.stringify(value);\n return undefined;\n}\n\nfunction codexItemLine(item: Record<string, unknown>, cwd: string): string | undefined {\n const type = asString(item.type) ?? 'item';\n switch (type) {\n case 'reasoning':\n case 'todo_list':\n return undefined;\n case 'command_execution':\n return toolLine('Run', { command: asString(item.command) ?? '' }, cwd);\n case 'file_change': {\n const files = asArray(item.changes)\n .flatMap((c) => (isRecord(c) && asString(c.path) ? [asString(c.path) as string] : []))\n .map((f) => toolLine('', { path: f }, cwd).trim());\n return clip(`Edit ${files.join(', ')}`.trim(), MAX_TOOL_LINE);\n }\n case 'mcp_tool_call': {\n const name = [asString(item.server), asString(item.tool)].filter(Boolean).join('.');\n return toolLine(name || 'MCP tool', undefined, cwd);\n }\n case 'web_search':\n return toolLine('Search', { query: asString(item.query) ?? '' }, cwd);\n default:\n return toolLine(type, item, cwd);\n }\n}\n\nfunction codexParser(emit: Emit, cwd: string): StreamParser {\n const state: ParseState = { text: '', completed: false };\n const announced = new Set<string>();\n let lastError: string | undefined;\n return {\n state,\n flush() {\n if (!state.completed && !state.failure && lastError) state.failure = lastError;\n },\n handle(raw) {\n if (!isRecord(raw)) return;\n const ev = isRecord(raw.msg) ? raw.msg : raw;\n const type = asString(ev.type) ?? '';\n if (type === 'thread.started') {\n emit({ kind: 'status', text: 'Codex started' });\n return;\n }\n if ((type === 'item.started' || type === 'item.completed') && isRecord(ev.item)) {\n const item = ev.item;\n const itemType = asString(item.type);\n if (itemType === 'agent_message' || itemType === 'assistant_message') {\n if (type !== 'item.completed') return;\n const text = (asString(item.text) ?? asString(item.message) ?? '').trim();\n if (text) {\n state.text = text;\n emit({ kind: 'text', text: clip(text, MAX_TEXT_CHUNK) });\n }\n return;\n }\n if (itemType === 'error') {\n const message = asString(item.message);\n if (message && type === 'item.completed')\n emit({ kind: 'error', text: shortError(message) });\n return;\n }\n const id = asString(item.id) ?? `${itemType}-${announced.size}`;\n // A file change is only known once completed; other items show as soon as they start.\n if (itemType === 'file_change' && type !== 'item.completed') return;\n if (announced.has(id)) return;\n announced.add(id);\n const line = codexItemLine(item, cwd);\n if (line) emit({ kind: 'tool', text: line });\n return;\n }\n if (type === 'turn.completed' || type === 'task_complete') {\n state.completed = true;\n const last = asString(ev.last_agent_message);\n if (!state.text && last) state.text = last;\n const u = isRecord(ev.usage) ? ev.usage : undefined;\n if (u) state.tokens = (asNumber(u.input_tokens) ?? 0) + (asNumber(u.output_tokens) ?? 0);\n return;\n }\n if (type === 'turn.failed') {\n state.failure = codexErrorText(ev.error) ?? lastError ?? 'Codex reported an error';\n return;\n }\n if (type === 'error') {\n // Codex also reports transient retries this way; only fatal if the turn never completes.\n lastError = codexErrorText(ev.message) ?? codexErrorText(ev.error) ?? lastError;\n if (lastError) emit({ kind: 'error', text: shortError(lastError) });\n return;\n }\n if (type === 'agent_message') {\n const text = (asString(ev.message) ?? '').trim();\n if (text) {\n state.text = text;\n emit({ kind: 'text', text: clip(text, MAX_TEXT_CHUNK) });\n }\n }\n },\n };\n}\n\nfunction agyParser(emit: Emit, cwd: string): StreamParser {\n const state: ParseState = { text: '', completed: false };\n const announced = new Set<string>();\n let streamed = '';\n let buffer = '';\n let bufferStep: string | undefined;\n const flushText = () => {\n const text = buffer.trim();\n buffer = '';\n bufferStep = undefined;\n if (text) emit({ kind: 'text', text: clip(text, MAX_TEXT_CHUNK) });\n };\n return {\n state,\n flush: flushText,\n handle(raw) {\n if (!isRecord(raw)) return;\n const event = asString(raw.event);\n if (event === 'init') {\n emit({ kind: 'status', text: 'Antigravity started' });\n return;\n }\n if (event === 'step_update' && isRecord(raw.step_update)) {\n const step = raw.step_update;\n const stepType = asString(step.step_type);\n const index = String(asNumber(step.step_index) ?? asString(step.step_index) ?? '');\n if (stepType === 'agent_response') {\n if (bufferStep !== undefined && bufferStep !== index) flushText();\n const delta = asString(step.text_delta);\n if (delta) {\n bufferStep = index;\n buffer += delta;\n streamed += delta;\n }\n if (asString(step.state) === 'DONE') flushText();\n return;\n }\n if (stepType === 'tool') {\n flushText();\n if (announced.has(index)) return;\n announced.add(index);\n const info = isRecord(step.tool_info) ? step.tool_info : {};\n const name = asString(step.tool_name) ?? asString(info.name) ?? 'tool';\n emit({ kind: 'tool', text: toolLine(name, info.parameters, cwd) });\n }\n return;\n }\n if (event === 'result' && isRecord(raw.result)) {\n flushText();\n const result = raw.result;\n const u = isRecord(result.usage) ? result.usage : undefined;\n if (u) {\n state.tokens =\n (asNumber(u.input_tokens) ?? 0) +\n (asNumber(u.output_tokens) ?? 0) +\n (asNumber(u.thinking_tokens) ?? 0);\n }\n const status = asString(result.status);\n if (status !== 'SUCCESS') {\n state.failure =\n asString(result.error) ?? `Antigravity ended with ${status ?? 'an error'}`;\n return;\n }\n state.completed = true;\n state.text = (asString(result.response) ?? streamed).trim();\n }\n },\n };\n}\n\nconst PARSERS: Record<OrchestratorAgent, (emit: Emit, cwd: string) => StreamParser> = {\n claude: claudeParser,\n codex: codexParser,\n agy: agyParser,\n};\n\n// --- Runner ------------------------------------------------------------------------------------\n\n/** `detail` is shown; `evidence` (detail plus stderr) decides whether it is a sign-in/limit issue. */\nfunction failureMessage(\n info: AgentInfo,\n detail: string,\n evidence: string,\n code: number | null,\n): string {\n const { kind } = classifyCliText(evidence);\n if (kind === 'auth') return `${info.label} is not signed in: ${info.signIn}`;\n const clean = scrubSecrets(detail);\n if (kind === 'quota_exhausted') return shortError(`${info.label} usage limit reached: ${clean}`);\n if (kind === 'rate_limit') return shortError(`${info.label} is rate limited: ${clean}`);\n const exit = code !== null && code !== 0 ? ` (exit ${code})` : '';\n return shortError(`${info.label} failed${exit}${clean ? `: ${clean}` : ''}`);\n}\n\nexport function createCliAgentRunner(options: CliAgentRunnerOptions = {}): AgentRunner {\n const env = options.env ?? process.env;\n const childEnv: Record<string, string> = {};\n for (const [k, v] of Object.entries(env)) if (typeof v === 'string') childEnv[k] = v;\n\n const resolveBinary = (agent: OrchestratorAgent): { command: string; prefix: string[] } => {\n const override = options.binaries?.[agent];\n const command = override?.command ?? AGENTS[agent].binary;\n return { command: resolveOnPath(command, env), prefix: override?.args ?? [] };\n };\n\n const isAvailable = (agent: OrchestratorAgent): boolean => {\n const { command } = resolveBinary(agent);\n if (!path.isAbsolute(command)) return false;\n try {\n return existsSync(command) && statSync(command).isFile();\n } catch {\n return false;\n }\n };\n\n async function run(request: AgentRunRequest): Promise<AgentRunResult> {\n if (request.signal.aborted) throw abortError();\n const info = AGENTS[request.agent];\n const { command, prefix } = resolveBinary(request.agent);\n const args = agentArgs(request.agent, request.mode);\n if (needsShell(command) && ![...prefix, ...args].every(isShellSafeArg)) {\n return { ok: false, text: '', error: `${info.label}: unsafe argument for the Windows shell` };\n }\n\n const emit: Emit = (chunk) => {\n try {\n request.onOutput(chunk);\n } catch {\n // a broken listener must not break the run\n }\n };\n\n // Antigravity cannot be kept read-only, so plan runs see an empty directory.\n let scratch: string | undefined;\n let cwd = request.cwd;\n if (request.agent === 'agy' && request.mode === 'plan') {\n scratch = mkdtempSync(path.join(options.scratchDir ?? tmpdir(), 'davecode-agy-plan-'));\n cwd = scratch;\n }\n\n const timeout = AbortSignal.timeout(request.timeoutMs);\n const signal = AbortSignal.any([request.signal, timeout]);\n const timedOut = (): AgentRunResult => ({\n ok: false,\n text: '',\n error: `${info.label} timed out after ${formatDuration(request.timeoutMs)}`,\n });\n\n try {\n let cli: ReturnType<typeof runCli>;\n try {\n cli = runCli({\n provider: info.provider,\n accountId: 'orchestrator',\n settings: { command, prefixArgs: prefix },\n args,\n env: childEnv,\n cwd,\n stdin: agentStdin(request.agent, request.mode, request.prompt),\n signal,\n });\n } catch (err) {\n if (request.signal.aborted) throw abortError();\n if (timeout.aborted) return timedOut();\n return { ok: false, text: '', error: shortError(errText(err)) };\n }\n\n const parser = PARSERS[request.agent](emit, cwd);\n let streamError: string | undefined;\n try {\n for await (const event of cli.events) parser.handle(event);\n } catch (err) {\n streamError = errText(err);\n }\n parser.flush();\n\n let exit: Awaited<typeof cli.exit>;\n try {\n exit = await cli.exit;\n } catch {\n if (request.signal.aborted) throw abortError();\n return {\n ok: false,\n text: '',\n error: `${info.label} could not be started: is \\`${info.binary}\\` installed and on PATH?`,\n };\n }\n if (request.signal.aborted) throw abortError();\n if (exit.aborted || timeout.aborted) return { ...timedOut(), text: parser.state.text };\n\n const { state } = parser;\n if (state.completed && !state.failure && exit.code === 0) {\n return {\n ok: true,\n text: state.text,\n ...(state.tokens !== undefined ? { tokens: state.tokens } : {}),\n };\n }\n const detail =\n state.failure ??\n streamError ??\n (tail(exit.stderr) ||\n (exit.code === 0 ? 'the CLI ended without a final result' : 'no output'));\n return {\n ok: false,\n text: state.text,\n error: failureMessage(info, detail, `${detail}\\n${tail(exit.stderr)}`, exit.code),\n ...(state.tokens !== undefined ? { tokens: state.tokens } : {}),\n };\n } finally {\n if (scratch) {\n try {\n rmSync(scratch, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });\n } catch {\n // best effort: the OS temp dir is cleaned eventually\n }\n }\n }\n }\n\n return {\n async availability(): Promise<AgentAvailability[]> {\n return ORCHESTRATOR_AGENTS.map((agent) => ({ agent, available: isAvailable(agent) }));\n },\n run,\n };\n}\n\nfunction errText(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","/**\n * Pane orchestrator: the DaveCode agent that splits one objective across the vendor CLIs the\n * user already signed in to (Claude Code, Codex, Antigravity), runs each subtask headlessly in\n * its own git worktree, merges the results into an integration branch and lets the user apply\n * it. It never touches the user's working tree until they apply, and never pushes.\n *\n * This file is the shared contract between the engine (`service.ts`), the headless runners\n * (`runners.ts`), the git workspace (`workspace.ts`), the HTTP routes and the UI. Change it\n * only together with `docs/API.md`.\n */\nimport { z } from 'zod';\n\n/** The agents the orchestrator can drive. Same ids as the desktop pane kinds. */\nexport const ORCHESTRATOR_AGENTS = ['claude', 'codex', 'agy'] as const;\nexport type OrchestratorAgent = (typeof ORCHESTRATOR_AGENTS)[number];\n\nexport const ORCHESTRATOR_LIMITS = {\n objectiveMaxLength: 4000,\n /** Most tasks a plan may contain. */\n maxTasks: 8,\n /** Default when the request does not say. */\n defaultMaxTasks: 5,\n /** Most tasks running at the same time. */\n maxParallel: 3,\n /** Hard timeout for one headless agent run. */\n taskTimeoutMs: 30 * 60_000,\n /** Hard timeout for the planning run. */\n planTimeoutMs: 5 * 60_000,\n /** Longest summary kept per task (characters, head kept). */\n summaryMaxLength: 4000,\n} as const;\n\nexport type OrchestratorRunStatus =\n /** The planner agent is splitting the objective. */\n | 'planning'\n /** Tasks are running or waiting for their dependencies. */\n | 'running'\n /** Every task finished; results are on the integration branch. */\n | 'done'\n /** Planning failed, or no task succeeded. */\n | 'failed'\n | 'cancelled';\n\nexport type OrchestratorTaskStatus =\n | 'pending'\n | 'running'\n /** Finished, committed and merged into the integration branch. */\n | 'done'\n | 'failed'\n /** Finished, but its branch conflicts with the integration branch. It stays unmerged. */\n | 'conflict'\n | 'cancelled'\n /** Never ran because a dependency did not finish. */\n | 'skipped';\n\nexport interface OrchestratorTask {\n /** `t1`, `t2`, … in plan order. */\n id: string;\n title: string;\n agent: OrchestratorAgent;\n /** The full instruction the agent receives. */\n prompt: string;\n /** Ids of tasks whose results this one builds on. */\n dependsOn: string[];\n status: OrchestratorTaskStatus;\n /** Git branch holding this task's commit. */\n branch?: string;\n /** The agent's final reply, truncated to `summaryMaxLength`. */\n summary?: string;\n /** Files the task changed, relative to the project root. */\n changedFiles?: string[];\n /** Short, redacted reason for `failed`, `conflict` or `skipped`. Never a secret. */\n error?: string;\n startedAt?: string;\n finishedAt?: string;\n}\n\nexport interface OrchestratorRun {\n id: string;\n objective: string;\n status: OrchestratorRunStatus;\n /** Agents the user allowed for this run. */\n agents: OrchestratorAgent[];\n /** The agent that wrote the plan. */\n planner?: OrchestratorAgent;\n /** Branch and commit the run started from. */\n baseBranch?: string;\n baseCommit?: string;\n /** `davecode/run-<id>`: every successful task merged together. */\n integrationBranch?: string;\n tasks: OrchestratorTask[];\n /** One-paragraph outcome written when the run ends. */\n summary?: string;\n /** Short, redacted reason when the run failed. */\n error?: string;\n /** Set once the integration branch was merged into `baseBranch`. */\n appliedAt?: string;\n createdAt: string;\n updatedAt: string;\n}\n\n/** A piece of an agent's live activity, already reduced to plain text for display. */\nexport interface AgentOutput {\n kind: 'text' | 'tool' | 'status' | 'error';\n text: string;\n}\n\nexport interface AgentAvailability {\n agent: OrchestratorAgent;\n /** Its CLI is on PATH. Sign-in is not checked: a signed-out CLI fails its task. */\n available: boolean;\n}\n\n// --- Headless agent runs (runners.ts) ---------------------------------------------------------\n\nexport interface AgentRunRequest {\n agent: OrchestratorAgent;\n /** Working directory: a task worktree, or the project root for planning. */\n cwd: string;\n /** Sent on stdin, never on the command line. */\n prompt: string;\n /** `plan` must not modify files; `edit` may edit files inside `cwd`. */\n mode: 'plan' | 'edit';\n signal: AbortSignal;\n timeoutMs: number;\n onOutput(chunk: AgentOutput): void;\n}\n\nexport interface AgentRunResult {\n ok: boolean;\n /** The agent's final reply. */\n text: string;\n /** Short, redacted reason when `ok` is false. */\n error?: string;\n tokens?: number;\n}\n\nexport interface AgentRunner {\n availability(): Promise<AgentAvailability[]>;\n /** Resolves (never rejects) unless the signal aborted, which rejects with an AbortError. */\n run(request: AgentRunRequest): Promise<AgentRunResult>;\n}\n\n// --- Git workspace (workspace.ts) -------------------------------------------------------------\n\nexport interface TaskWorkspace {\n /** Absolute path of the task's worktree. */\n path: string;\n branch: string;\n}\n\nexport type WorkspaceResult = { ok: true } | { ok: false; reason: string };\n\nexport interface OrchestratorWorkspace {\n /** The project is a git repository with at least one commit; returns where HEAD is. */\n check(): Promise<{ ok: true; branch: string; commit: string } | { ok: false; reason: string }>;\n /** Creates `davecode/run-<runId>` at `baseCommit` and returns its name. */\n createIntegration(runId: string, baseCommit: string): Promise<string>;\n /** A fresh worktree on `davecode/run-<runId>-<taskId>`, branched from `base` (branch/commit). */\n createTask(runId: string, taskId: string, base: string): Promise<TaskWorkspace>;\n /** Commits everything the agent changed in the worktree; returns the changed files. */\n commitTask(workspace: TaskWorkspace, message: string): Promise<string[]>;\n /** Merges a task branch into the integration branch; aborts and reports on conflict. */\n mergeIntoIntegration(runId: string, branch: string, message: string): Promise<WorkspaceResult>;\n /** Merges the integration branch into the branch the run started from, if the tree is clean. */\n apply(runId: string, baseBranch: string): Promise<WorkspaceResult>;\n /** Removes the run's worktrees. Branches stay, so nothing the agents did is lost. */\n cleanup(runId: string): Promise<void>;\n}\n\n// --- Service (service.ts) ---------------------------------------------------------------------\n\nexport const startRunSchema = z.object({\n objective: z.string().trim().min(1).max(ORCHESTRATOR_LIMITS.objectiveMaxLength),\n /** Defaults to every available agent. */\n agents: z.array(z.enum(ORCHESTRATOR_AGENTS)).min(1).max(3).optional(),\n maxTasks: z.number().int().min(1).max(ORCHESTRATOR_LIMITS.maxTasks).optional(),\n /** The agent that splits the objective. It must be installed, but need not take tasks.\n * Defaults to the first allowed agent in the order claude, codex, agy. */\n planner: z.enum(ORCHESTRATOR_AGENTS).optional(),\n});\nexport type StartRunInput = z.infer<typeof startRunSchema>;\n\nexport type OrchestratorErrorCode =\n | 'not_found'\n | 'no_agents'\n | 'not_a_repository'\n | 'busy'\n | 'not_appliable';\n\nexport class OrchestratorError extends Error {\n constructor(\n readonly code: OrchestratorErrorCode,\n message: string,\n ) {\n super(message);\n this.name = 'OrchestratorError';\n }\n}\n\nexport interface OrchestratorService {\n agents(): Promise<AgentAvailability[]>;\n /**\n * Validates, records and returns the run in `planning`; the work continues in the background.\n * Rejects with `OrchestratorError`: `no_agents`, `not_a_repository`, or `busy` (one active run\n * per project).\n */\n start(input: StartRunInput): Promise<OrchestratorRun>;\n get(id: string): OrchestratorRun | undefined;\n /** Newest first. */\n list(): OrchestratorRun[];\n /** Stops the agents of an active run. False when the run is unknown or already over. */\n cancel(id: string): boolean;\n /** Rejects with `not_found` or `not_appliable` (not `done`, already applied, dirty tree…). */\n apply(id: string): Promise<OrchestratorRun>;\n /** Cancels active runs and waits for their agents to stop. */\n close(): Promise<void>;\n}\n","/**\n * Pure helpers for the changes service: parsing `git diff -z` output and rendering untracked\n * files as patches. No I/O here, so every case is unit-testable.\n */\nimport type { ChangedFile, ChangedFileStatus } from './contract';\n\n/** NUL-separated tokens without the trailing empty one. */\nfunction tokens(out: string): string[] {\n const parts = out.split('\\0');\n if (parts.at(-1) === '') parts.pop();\n return parts;\n}\n\nfunction statusOf(letter: string): ChangedFileStatus {\n switch (letter[0]) {\n case 'A':\n return 'added';\n case 'D':\n return 'deleted';\n case 'R':\n return 'renamed';\n case 'C':\n return 'added';\n default:\n // M, T (type change) and U (unmerged) all read as \"modified\" in a review.\n return 'modified';\n }\n}\n\n/** `git diff --name-status -z -M`: `M\\0path\\0`, `R100\\0old\\0new\\0`. */\nexport function parseNameStatus(\n out: string,\n): { path: string; oldPath?: string; status: ChangedFileStatus }[] {\n const parts = tokens(out);\n const files: { path: string; oldPath?: string; status: ChangedFileStatus }[] = [];\n for (let i = 0; i < parts.length; ) {\n const code = parts[i++] ?? '';\n if (!code) continue;\n if (code[0] === 'R' || code[0] === 'C') {\n const oldPath = parts[i++] ?? '';\n const path = parts[i++] ?? '';\n files.push(\n code[0] === 'R' ? { path, oldPath, status: 'renamed' } : { path, status: 'added' },\n );\n } else {\n files.push({ path: parts[i++] ?? '', status: statusOf(code) });\n }\n }\n return files.filter((f) => f.path.length > 0);\n}\n\nexport interface NumStat {\n additions: number;\n deletions: number;\n binary: boolean;\n}\n\n/**\n * `git diff --numstat -z -M`: `3\\t1\\tpath\\0` for a plain change, `3\\t1\\t\\0old\\0new\\0` for a\n * rename, and `-\\t-\\t…` for a binary file. Keyed by the new path.\n */\nexport function parseNumStat(out: string): Map<string, NumStat> {\n const parts = tokens(out);\n const stats = new Map<string, NumStat>();\n for (let i = 0; i < parts.length; ) {\n const head = parts[i++] ?? '';\n const match = /^(-|\\d+)\\t(-|\\d+)\\t(.*)$/s.exec(head);\n if (!match) continue;\n const [, added = '0', deleted = '0', inline = ''] = match;\n let path = inline;\n if (inline === '') {\n i++; // old path\n path = parts[i++] ?? '';\n }\n const binary = added === '-' || deleted === '-';\n stats.set(path, {\n additions: binary ? 0 : Number(added),\n deletions: binary ? 0 : Number(deleted),\n binary,\n });\n }\n return stats;\n}\n\nexport function mergeFileLists(\n tracked: { path: string; oldPath?: string; status: ChangedFileStatus }[],\n stats: Map<string, NumStat>,\n untracked: ChangedFile[],\n): ChangedFile[] {\n const files: ChangedFile[] = tracked.map((file) => {\n const stat = stats.get(file.path) ?? { additions: 0, deletions: 0, binary: false };\n return { ...file, ...stat };\n });\n const seen = new Set(files.map((f) => f.path));\n for (const file of untracked) if (!seen.has(file.path)) files.push(file);\n return files.sort((a, b) => a.path.localeCompare(b.path));\n}\n\n/** True when the buffer looks binary (a NUL byte in its first 8 KB, like git's heuristic). */\nexport function looksBinary(content: Buffer): boolean {\n return content.subarray(0, 8000).includes(0);\n}\n\n/** Lines a text file adds when it is new: a final line without `\\n` still counts. */\nexport function countLines(text: string): number {\n if (text.length === 0) return 0;\n const breaks = text.split('\\n').length - 1;\n return text.endsWith('\\n') ? breaks : breaks + 1;\n}\n\n/** A git-style patch that creates `path` with `content` (or marks it binary). */\nexport function newFilePatch(path: string, content: Buffer | undefined): string {\n const header = `diff --git a/${path} b/${path}\\nnew file mode 100644\\n`;\n if (!content || looksBinary(content)) {\n return `${header}Binary files /dev/null and b/${path} differ\\n`;\n }\n const text = content.toString('utf8');\n if (text.length === 0) return header;\n const lines = text.split('\\n');\n const trailingNewline = text.endsWith('\\n');\n if (trailingNewline) lines.pop();\n const body = lines.map((line) => `+${line}`).join('\\n');\n const hunk = `@@ -0,0 +1,${lines.length} @@\\n${body}\\n`;\n return `${header}--- /dev/null\\n+++ b/${path}\\n${hunk}${trailingNewline ? '' : '\\\\\n'}`;\n}\n\n/** Lowercase, dash-separated branch fragment from a title; never empty. */\nexport function slugify(text: string, max = 40): string {\n const slug = text\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[̀-ͯ]/g, '')\n // A Conventional Commits prefix (\"feat(ui): …\") says nothing about the branch.\n .replace(/^[a-z]+(\\([^)]*\\))?!?:\\s*/, '')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, max)\n .replace(/-+$/g, '');\n return slug || 'changes';\n}\n\n/** Removes credentials from URLs (`https://user:token@host`) in git or gh output. */\nexport function scrubUrls(text: string): string {\n return text.replace(/(\\b[a-z][a-z0-9+.-]*:\\/\\/)[^/@\\s]+@/gi, '$1***@');\n}\n","/**\n * Commit message and pull request text. The deterministic version reads only the file list, so\n * it is free and instant; an agent can do better from the patch itself (`agentPrompt` and\n * `parseAgentSuggestion`).\n */\nimport { z } from 'zod';\nimport { CHANGES_LIMITS, type ChangedFile, type ChangesSuggestion } from './contract';\n\nconst DOC = /(^|\\/)docs?\\/|\\.(md|mdx|txt|rst)$/i;\nconst TEST = /(^|\\/)(__tests__|tests?)\\/|\\.(test|spec)\\.[a-z0-9]+$/i;\nconst PACKAGE = /^(?:packages|apps|libs|services)\\/([^/]+)\\//;\nconst MAX_LISTED = 30;\n\nfunction basename(path: string): string {\n return path.split('/').at(-1) ?? path;\n}\n\n/** `docs`, `test` or `chore`: the file list cannot tell a feature from a fix. */\nfunction commitType(files: ChangedFile[]): string {\n if (files.every((f) => DOC.test(f.path))) return 'docs';\n if (files.every((f) => TEST.test(f.path))) return 'test';\n return 'chore';\n}\n\n/** The package every file belongs to, if they share one. */\nfunction commitScope(files: ChangedFile[]): string | undefined {\n const scopes = new Set(files.map((f) => PACKAGE.exec(f.path)?.[1]));\n if (scopes.size !== 1) return undefined;\n const [scope] = scopes;\n return scope;\n}\n\nfunction subject(files: ChangedFile[]): string {\n if (files.length === 1) {\n const [file] = files as [ChangedFile];\n const verb =\n file.status === 'added' || file.status === 'untracked'\n ? 'add'\n : file.status === 'deleted'\n ? 'remove'\n : file.status === 'renamed'\n ? 'rename'\n : 'update';\n return `${verb} ${basename(file.path)}`;\n }\n return `update ${files.length} files`;\n}\n\nfunction fileLine(file: ChangedFile): string {\n const counts = file.binary ? 'binary' : `+${file.additions} −${file.deletions}`;\n const from = file.oldPath ? ` (from \\`${file.oldPath}\\`)` : '';\n return `- \\`${file.path}\\`${from} — ${counts}`;\n}\n\n/** A Conventional Commits message and pull request text derived from the changed files. */\nexport function fallbackSuggestion(files: ChangedFile[]): ChangesSuggestion {\n if (files.length === 0) {\n return { message: 'chore: update', title: 'chore: update', body: '', by: 'davecode' };\n }\n const scope = commitScope(files);\n const message = `${commitType(files)}${scope ? `(${scope})` : ''}: ${subject(files)}`;\n const listed = files.slice(0, MAX_LISTED).map(fileLine);\n if (files.length > MAX_LISTED) listed.push(`- …and ${files.length - MAX_LISTED} more`);\n const body = `## Changes\\n\\n${listed.join('\\n')}\\n`;\n return { message, title: message, body, by: 'davecode' };\n}\n\n/** What an agent is asked: metadata only, from the file list and the (possibly cut) patch. */\nexport function agentPrompt(input: {\n branch?: string;\n files: ChangedFile[];\n patch: string;\n}): string {\n const max = CHANGES_LIMITS.suggestDiffMaxLength;\n const patch =\n input.patch.length > max ? `${input.patch.slice(0, max)}\\n[patch truncated]` : input.patch;\n const files = input.files\n .map(\n (f) =>\n `${f.status} ${f.path}${f.binary ? ' (binary)' : ` (+${f.additions} -${f.deletions})`}`,\n )\n .join('\\n');\n return [\n 'Write the git commit message and pull request text for the changes below.',\n 'Do not modify any file and do not run any command: only read the patch.',\n 'Reply with a single JSON object and nothing else (no code fence):',\n '{\"message\": \"<Conventional Commits subject, imperative mood, at most 72 characters>\",',\n ' \"title\": \"<pull request title, at most 72 characters>\",',\n ' \"body\": \"<pull request description in Markdown: one short paragraph, then a bullet list of the main changes>\"}',\n 'Write in the same language as the code comments; default to English.',\n '',\n `Branch: ${input.branch ?? '(detached)'}`,\n 'Changed files:',\n files,\n '',\n 'Patch:',\n patch,\n ].join('\\n');\n}\n\nconst agentReplySchema = z.object({\n message: z.string().trim().min(1).max(CHANGES_LIMITS.messageMaxLength),\n title: z.string().trim().min(1).max(CHANGES_LIMITS.titleMaxLength),\n body: z.string().max(CHANGES_LIMITS.bodyMaxLength).default(''),\n});\n\n/** The JSON object in an agent's reply (code fences and chatter around it are tolerated). */\nexport function parseAgentSuggestion(text: string): Omit<ChangesSuggestion, 'by'> | undefined {\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start < 0 || end <= start) return undefined;\n let json: unknown;\n try {\n json = JSON.parse(text.slice(start, end + 1));\n } catch {\n return undefined;\n }\n const parsed = agentReplySchema.safeParse(json);\n return parsed.success ? parsed.data : undefined;\n}\n","/**\n * Goal mode planning primitives: the role catalogue, the JSON contracts the planner and reviewer\n * must answer with (validated with zod), their prompts, and the deterministic safety guard that\n * turns any outbound action (email, posting, payments…) into a draft artifact.\n */\nimport { z } from 'zod';\nimport { findCycles } from '../brain/graph';\nimport type { DaveConfig } from '../config/schema';\nimport type { GoalRole, GoalTask, GoalTaskKind } from '../types';\n\nexport type GoalConfig = DaveConfig['goal'];\n\n/** A role with everything the orchestrator needs to prompt it. */\nexport interface ResolvedRole extends GoalRole {\n kind: GoalTaskKind;\n instructions?: string;\n}\n\nexport const DEFAULT_ROLES: readonly ResolvedRole[] = [\n {\n id: 'planner',\n description: 'Breaks the objective into a plan, defines milestones and success criteria.',\n kind: 'artifact',\n },\n {\n id: 'researcher',\n description:\n 'Analyses markets, users, competitors and options from its own knowledge and the workspace; cannot browse the web.',\n kind: 'artifact',\n },\n {\n id: 'implementer',\n description: 'Writes and changes code in the repository (handed to the autonomous runner).',\n kind: 'code',\n },\n {\n id: 'reviewer',\n description: 'Critically reviews other outputs for gaps, risks and quality.',\n kind: 'artifact',\n },\n {\n id: 'writer',\n description:\n 'Writes positioning, marketing copy, landing-page text, documentation and drafts of messages.',\n kind: 'artifact',\n },\n];\n\n/** Built-in roles merged with `goal.roles` (config entries override or add roles). */\nexport function resolveRoles(config: Pick<GoalConfig, 'roles'>): ResolvedRole[] {\n const roles = new Map<string, ResolvedRole>(DEFAULT_ROLES.map((r) => [r.id, { ...r }]));\n for (const [id, override] of Object.entries(config.roles)) {\n const base = roles.get(id);\n const role: ResolvedRole = {\n id,\n description: override.description ?? base?.description ?? id,\n kind: override.kind ?? base?.kind ?? 'artifact',\n };\n if (override.route) role.route = override.route;\n const instructions = override.instructions ?? base?.instructions;\n if (instructions) role.instructions = instructions;\n roles.set(id, role);\n }\n return [...roles.values()];\n}\n\n/** Public shape stored on the goal (no prompt text). */\nexport function publicRoles(roles: readonly ResolvedRole[]): GoalRole[] {\n return roles.map(({ id, description, route }) =>\n route ? { id, description, route } : { id, description },\n );\n}\n\n// ---------------------------------------------------------------------------\n// Safety guard\n// ---------------------------------------------------------------------------\n\n/**\n * Actions that reach third parties. DaveCode never performs them: a task asking for one becomes\n * an artifact that drafts it for a human to review and execute.\n */\nconst OUTBOUND = [\n /\\b(send|sending|email|e-mail|emailing|mail out)\\b/i,\n /\\b(tweet|dm|direct message|share on)\\b/i,\n /\\b(post|publish)\\b[^.\\n]{0,60}\\b(on|to)\\b/i,\n /\\b(pay|purchase|buy|checkout|subscribe to|sign up|signup|register (for|on|at))\\b/i,\n /\\b(outreach|cold[- ]?(call|email)|contact (the|our|potential|prospects?|customers?|leads?))\\b/i,\n /\\b(launch (the )?ads?|run (the )?ads?|ad campaign|deploy to production|go live)\\b/i,\n];\n\n/**\n * The subset that also disqualifies a `code` task: operating something live, as opposed to\n * writing code that could (an \"email validation\" feature is fine; \"email the leads\" is not).\n */\nconst OPERATIONAL = [\n /\\b(deploy|release|publish)\\b[^.\\n]*\\b(production|prod|npm|app store|play store|live)\\b/i,\n /\\b(go live|pay|purchase|buy|checkout)\\b/i,\n /\\b(send|email|e-mail|message)\\b[^.\\n]*\\b(customers?|users?|leads?|prospects?|subscribers?|mailing list|newsletter)\\b/i,\n /\\b(post|tweet|publish)\\b[^.\\n]*\\b(twitter|x\\.com|linkedin|facebook|instagram|reddit|hacker news|product hunt)\\b/i,\n];\n\nfunction firstMatch(patterns: readonly RegExp[], text: string): string | undefined {\n for (const pattern of patterns) {\n const match = pattern.exec(text);\n if (match) return match[0];\n }\n return undefined;\n}\n\n/** The first outbound-action phrase found in `text`, if any. */\nexport function outboundAction(text: string): string | undefined {\n return firstMatch(OUTBOUND, text);\n}\n\nexport const DRAFT_NOTICE =\n 'DaveCode never performs outbound actions (emails, posts, payments, sign-ups, deployments). Produce a ready-to-use DRAFT for a human to review and execute.';\n\n/**\n * Forces tasks that ask for an outbound action into draft artifacts. Artifact tasks only get\n * the draft title and notice (they can only ever write markdown); code tasks are converted when\n * they ask to operate something live. Returns a new task.\n */\nexport function applySafetyGuard(task: GoalTask): GoalTask {\n const text = `${task.title}\\n${task.description ?? ''}`;\n const action = task.kind === 'code' ? firstMatch(OPERATIONAL, text) : firstMatch(OUTBOUND, text);\n if (!action) return task;\n const title = /^draft\\b/i.test(task.title) ? task.title : `Draft: ${task.title}`;\n const description = [task.description?.trim(), DRAFT_NOTICE].filter(Boolean).join('\\n\\n');\n return { ...task, kind: 'artifact', title: title.slice(0, 300), description };\n}\n\n// ---------------------------------------------------------------------------\n// Planner / reviewer JSON contracts\n// ---------------------------------------------------------------------------\n\nexport const plannedTaskSchema = z.object({\n id: z.string().min(1).max(80),\n title: z.string().trim().min(1).max(300),\n description: z.string().max(8_000).optional(),\n role: z.string().min(1).max(40),\n kind: z.enum(['code', 'artifact']).optional(),\n dependsOn: z.array(z.string().min(1)).max(50).default([]),\n acceptance: z.array(z.string().min(1).max(1_000)).max(20).optional(),\n});\nexport type PlannedTask = z.infer<typeof plannedTaskSchema>;\n\nexport const planSchema = z.object({\n summary: z.string().max(4_000).optional(),\n tasks: z.array(plannedTaskSchema).min(1).max(100),\n});\nexport type Plan = z.infer<typeof planSchema>;\n\nexport const reviewSchema = z.object({\n /** The objective is achieved as far as DaveCode can take it. */\n done: z.boolean(),\n summary: z.string().max(8_000),\n /** Ids of FAILED tasks worth another attempt. */\n retry: z.array(z.string()).max(50).default([]),\n /** New tasks for the next round. */\n tasks: z.array(plannedTaskSchema).max(50).default([]),\n});\nexport type Review = z.infer<typeof reviewSchema>;\n\nconst TASK_ID = /^[a-z0-9]+(?:[-_.][a-z0-9]+)*$/;\n\n/** Lowercase kebab-case id that satisfies the task-graph id rules. */\nexport function sanitizeTaskId(raw: string): string {\n const id = raw\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 60)\n .replace(/-+$/g, '');\n return TASK_ID.test(id) ? id : 'task';\n}\n\nexport interface NormalizeOptions {\n existing: readonly GoalTask[];\n roles: readonly ResolvedRole[];\n round: number;\n /** How many new tasks may still be added (goal.maxTasks minus existing). */\n room: number;\n /** False when code tasks cannot run: they become artifacts (implementation plans). */\n codeTasks: boolean;\n}\n\n/**\n * Turns planner output into goal tasks: unique valid ids, known roles (unknown ones fall back to\n * `implementer` for code and `writer` otherwise), dependencies restricted to known tasks, no\n * cycles, the task cap, and the safety guard.\n */\nexport function normalizeTasks(\n planned: readonly PlannedTask[],\n opts: NormalizeOptions,\n): GoalTask[] {\n const roleById = new Map(opts.roles.map((r) => [r.id, r]));\n const taken = new Set(opts.existing.map((t) => t.id));\n const idMap = new Map<string, string>();\n const out: GoalTask[] = [];\n\n for (const p of planned.slice(0, Math.max(0, opts.room))) {\n let id = sanitizeTaskId(p.id);\n for (let n = 2; taken.has(id); n++) id = `${sanitizeTaskId(p.id)}-${n}`;\n taken.add(id);\n idMap.set(p.id, id);\n let role = roleById.get(p.role.toLowerCase());\n const requested: GoalTaskKind = p.kind ?? role?.kind ?? 'artifact';\n if (!role)\n role = roleById.get(requested === 'code' ? 'implementer' : 'writer') ?? opts.roles[0];\n const kind: GoalTaskKind = requested === 'code' && opts.codeTasks ? 'code' : 'artifact';\n const task: GoalTask = {\n id,\n title: p.title,\n role: role?.id ?? 'writer',\n kind,\n status: 'PENDING',\n dependsOn: p.dependsOn,\n round: opts.round,\n attempts: 0,\n };\n const description =\n requested === 'code' && kind === 'artifact'\n ? [\n p.description,\n 'Code tasks cannot run here: write a precise implementation plan instead.',\n ]\n .filter(Boolean)\n .join('\\n\\n')\n : p.description;\n if (description) task.description = description;\n if (p.acceptance?.length) task.acceptance = p.acceptance;\n out.push(applySafetyGuard(task));\n }\n\n const known = new Set([...opts.existing.map((t) => t.id), ...out.map((t) => t.id)]);\n for (const task of out) {\n task.dependsOn = [\n ...new Set(task.dependsOn.map((d) => idMap.get(d) ?? sanitizeTaskId(d))),\n ].filter((d) => d !== task.id && known.has(d));\n }\n\n // Break any cycle among the new tasks by dropping the closing edge.\n for (;;) {\n const graph = {\n version: 1 as const,\n tasks: [...opts.existing, ...out].map((t) => ({\n id: t.id,\n title: t.title,\n status: t.status,\n dependsOn: t.dependsOn,\n })),\n };\n const cycle = findCycles(graph)[0];\n if (!cycle) break;\n const from = cycle[cycle.length - 2];\n const to = cycle[cycle.length - 1];\n const task = out.find((t) => t.id === from);\n if (!task) break;\n task.dependsOn = task.dependsOn.filter((d) => d !== to);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Prompts\n// ---------------------------------------------------------------------------\n\nexport const SAFETY_RULES = `Hard rules (non-negotiable):\n- You run inside DaveCode with no internet access and no ability to contact anyone.\n- Never send emails or messages, post or publish anything, make payments or purchases, sign up for services, or deploy. When such a step is useful, produce a DRAFT for a human to review and execute.\n- Never invent credentials, personal data or facts presented as verified; label assumptions and estimates clearly.\n- Stay within the objective; prefer concrete, actionable outputs.`;\n\nfunction roleList(roles: readonly ResolvedRole[]): string {\n return roles.map((r) => `- ${r.id} (${r.kind}): ${r.description}`).join('\\n');\n}\n\nexport function plannerPrompt(roles: readonly ResolvedRole[], codeTasks: boolean): string {\n return `You are the planner of a small team of AI agents working toward one objective. Decompose the objective into a dependency graph of concrete tasks and assign each task to one role.\n\nRoles:\n${roleList(roles)}\n\nTask kinds:\n- \"artifact\": the role writes one markdown document (analysis, plan, copy, checklist, draft).\n- \"code\": the implementer changes the repository; an autonomous runner branches, runs the quality gates and merges.${codeTasks ? '' : '\\n Code tasks are NOT available in this workspace: plan artifact tasks only.'}\n\n${SAFETY_RULES}\n\nPlan at most the number of tasks you are allowed, smallest useful set first. Ids are short lowercase kebab-case. Use dependsOn so later tasks build on earlier outputs.\n\nRespond with ONLY a JSON object, no prose and no code fences:\n{\"summary\": \"one paragraph plan\", \"tasks\": [{\"id\": \"market-research\", \"title\": \"...\", \"description\": \"...\", \"role\": \"researcher\", \"kind\": \"artifact\", \"dependsOn\": [], \"acceptance\": [\"...\"]}]}`;\n}\n\nexport const REVIEWER_PROMPT = `You are the reviewer of a team of AI agents working toward one objective. Judge the results so far against the objective.\n\n${SAFETY_RULES}\n\nDecide:\n- \"done\": true when the objective is achieved as far as an offline team can take it (remaining steps are outbound actions a human must do from the drafts).\n- otherwise propose the next round: \"retry\" lists FAILED task ids worth another attempt, \"tasks\" lists new tasks (same shape as the planner's, dependsOn may reference existing ids).\n\nRespond with ONLY a JSON object, no prose and no code fences:\n{\"done\": false, \"summary\": \"progress, gaps and what a human must do next\", \"retry\": [], \"tasks\": []}`;\n\nexport function roleSystemPrompt(role: ResolvedRole): string {\n return [\n `You are the ${role.id} of a small team of AI agents. ${role.description}`,\n SAFETY_RULES,\n 'Write your deliverable as a single, well-structured markdown document. Do not wrap it in code fences. Start with a level-1 heading.',\n role.instructions?.trim(),\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n","/**\n * Bridges goal `code` tasks to the autonomous runner: each one is mirrored into the project's\n * TASK_GRAPH.json and run with `runOnce({ taskId })`, so it gets the usual branch, quality gates,\n * judge and merge. Tokens are metered per task and capped by the goal's remaining budget.\n */\n\nimport { createExecutor, createRunner } from '../autonomous/create';\nimport type {\n Executor,\n ExecutorResult,\n ExecutorSession,\n ExecutorTask,\n} from '../autonomous/executor';\nimport { Git } from '../autonomous/git';\nimport { type AutonomousRunner, type RunnerConfig, RunnerError } from '../autonomous/runner';\nimport type { WorkspaceLock } from '../autonomous/workspace-lock';\nimport type { ProjectBrain } from '../brain/project';\nimport type { Engine } from '../engine';\nimport type { Goal, GoalTask } from '../types';\nimport type { CodeTaskResult, CodeTaskRunner } from './orchestrator';\nimport { sanitizeTaskId } from './plan';\n\ntype EngineDeps = Pick<Engine, 'config' | 'router' | 'accounts' | 'sandboxes' | 'events' | 'paths'>;\n\n/** Sums the tokens of every pass of every session it creates. */\nexport class MeteredExecutor implements Executor {\n tokens = 0;\n\n constructor(private readonly inner: Executor) {}\n\n get name(): string {\n return this.inner.name;\n }\n\n createSession(task: ExecutorTask): ExecutorSession {\n const session = this.inner.createSession(task);\n return {\n run: async (opts): Promise<ExecutorResult> => {\n const result = await session.run(opts);\n this.tokens += Math.max(0, result.tokens);\n return result;\n },\n };\n }\n}\n\n/** Runner-shaped dependency, so tests can swap the real runner. */\nexport type GoalTaskRunner = Pick<AutonomousRunner, 'runOnce' | 'stop'>;\n\nexport interface RunnerCodeTasksOptions {\n engine: EngineDeps;\n brain: ProjectBrain;\n /** Shared with the main runner; goal mode holds it as `owner` for the whole goal. */\n lock: WorkspaceLock;\n owner?: string;\n contextExtras?: () => string | Promise<string>;\n /** Override the executor chosen by `runner.executor` (tests). */\n executor?: Executor;\n /** Override how the per-task runner is built (tests). */\n makeRunner?: (config: RunnerConfig, executor: Executor) => GoalTaskRunner;\n}\n\n/** Floor for a task's token cap so a nearly spent goal still gets a meaningful attempt. */\nconst MIN_TASK_TOKENS = 10_000;\n\nexport class RunnerCodeTasks implements CodeTaskRunner {\n private readonly owner: string;\n\n constructor(private readonly options: RunnerCodeTasksOptions) {\n this.owner = options.owner ?? 'goal';\n }\n\n async available(): Promise<{ ok: true } | { ok: false; reason: string }> {\n const { brain, engine } = this.options;\n const git = new Git(brain.root);\n if (!(await git.isRepo()))\n return { ok: false, reason: `${brain.root} is not a git repository` };\n if (!(await brain.isInitialised())) {\n return { ok: false, reason: 'the project brain is missing (run davecode init)' };\n }\n const base = engine.config.runner.baseBranch;\n if (!(await git.branchExists(base))) {\n return { ok: false, reason: `base branch \"${base}\" does not exist` };\n }\n if ((await git.status({ ignoreBrain: true })).length > 0) {\n return { ok: false, reason: 'the working tree has uncommitted changes' };\n }\n return { ok: true };\n }\n\n async run(\n task: GoalTask,\n opts: { goal: Goal; maxTokens: number; signal: AbortSignal },\n ): Promise<CodeTaskResult> {\n const { brain, engine } = this.options;\n const runnerTaskId = sanitizeTaskId(`goal-${opts.goal.id.slice(-6)}-${task.id}`);\n const graph = await brain.readGraph();\n const existing = graph.tasks.find((t) => t.id === runnerTaskId);\n if (existing?.status === 'SUCCESS') {\n return { ok: true, summary: existing.notes ?? 'already done', tokens: 0, runnerTaskId };\n }\n if (!existing) {\n await brain.createTask({\n id: runnerTaskId,\n title: task.title,\n description: [\n task.description,\n `Part of DaveCode goal ${opts.goal.id}: ${opts.goal.objective}`,\n ]\n .filter(Boolean)\n .join('\\n\\n'),\n ...(task.acceptance?.length ? { acceptance: task.acceptance } : {}),\n });\n } else if (existing.status !== 'PENDING') {\n await brain.setTaskStatus(runnerTaskId, 'PENDING', { notes: 'retried by goal mode' });\n }\n\n const base = engine.config.runner;\n const config: RunnerConfig = {\n ...base,\n maxTaskTokens: Math.max(MIN_TASK_TOKENS, Math.min(base.maxTaskTokens, opts.maxTokens)),\n };\n const metered = new MeteredExecutor(this.options.executor ?? createExecutor(engine, config));\n const runner =\n this.options.makeRunner?.(config, metered) ??\n createRunner(engine, {\n brain,\n config,\n executor: metered,\n lock: { lock: this.options.lock, owner: this.owner },\n ...(this.options.contextExtras ? { contextExtras: this.options.contextExtras } : {}),\n });\n\n const onAbort = () => void runner.stop();\n opts.signal.addEventListener('abort', onAbort, { once: true });\n try {\n const result = await runner.runOnce({ taskId: runnerTaskId });\n return {\n ok: result.outcome === 'success',\n summary: result.summary ?? result.error ?? result.outcome,\n tokens: metered.tokens,\n runnerTaskId,\n ...(result.outcome === 'stopped' ? { stopped: true } : {}),\n };\n } catch (err) {\n if (!(err instanceof RunnerError)) throw err;\n return { ok: false, summary: err.message, tokens: metered.tokens, runnerTaskId };\n } finally {\n opts.signal.removeEventListener('abort', onAbort);\n }\n }\n}\n","/**\n * Goal mode: a planner decomposes an objective into a task graph, role agents execute the ready\n * tasks (artifacts through the router, code through the autonomous runner), a reviewer judges the\n * results and re-plans. Bounded by rounds, a task cap and a token budget; cancellable; never takes\n * outbound actions (see `applySafetyGuard`).\n */\nimport type { z } from 'zod';\nimport { routeModel } from '../autonomous/executor';\nimport { extractJsonObject } from '../autonomous/judge';\nimport { truncateHead } from '../autonomous/process';\nimport { READ_ONLY_TOOL_DEFINITIONS, WorkspaceTools } from '../autonomous/tools';\nimport type { EventBus } from '../events';\nimport { countTextTokens } from '../rate-limiter/tokens';\nimport { RouterError } from '../router/errors';\nimport type { Router } from '../router/router';\nimport { newId } from '../storage/ids';\nimport type { ChatMessage, Goal, GoalStatus, GoalTask, LogLevel } from '../types';\nimport {\n type GoalConfig,\n normalizeTasks,\n type Plan,\n plannerPrompt,\n planSchema,\n publicRoles,\n REVIEWER_PROMPT,\n type ResolvedRole,\n type Review,\n resolveRoles,\n reviewSchema,\n roleSystemPrompt,\n} from './plan';\nimport type { GoalStore } from './store';\n\nexport interface CodeTaskResult {\n ok: boolean;\n summary: string;\n /** Tokens the runner spent on the task. */\n tokens: number;\n /** Project task-graph id the runner worked on. */\n runnerTaskId?: string;\n /** Interrupted by cancellation. */\n stopped?: boolean;\n}\n\n/** Hands `code` tasks to the autonomous runner (see `RunnerCodeTasks`). */\nexport interface CodeTaskRunner {\n /** Whether code tasks can run at all (git repo, clean tree…) and why not. */\n available(): Promise<{ ok: true } | { ok: false; reason: string }>;\n run(\n task: GoalTask,\n opts: { goal: Goal; maxTokens: number; signal: AbortSignal },\n ): Promise<CodeTaskResult>;\n}\n\nexport interface GoalOrchestratorOptions {\n router: Pick<Router, 'complete'>;\n store: GoalStore;\n events: EventBus;\n config: GoalConfig;\n codeRunner?: CodeTaskRunner;\n /** Attach read-only repository tools (`list_dir`, `read_file`, `search`) to agent calls. */\n readTools?: boolean;\n /** Compact budget summary (remaining quota per account) shown to every agent. */\n budgetContext?: () => string | Promise<string>;\n /** Project architecture/state summary shown to the planner and reviewer. */\n projectContext?: () => string | Promise<string>;\n now?: () => Date;\n}\n\nexport interface NewGoalInput {\n objective: string;\n maxRounds?: number;\n maxTasks?: number;\n maxTokens?: number;\n /** Plan only. */\n dryRun?: boolean;\n}\n\nconst TERMINAL: ReadonlySet<GoalStatus> = new Set([\n 'planned',\n 'succeeded',\n 'failed',\n 'cancelled',\n 'budget_exhausted',\n]);\n\nexport function isTerminalGoal(goal: Pick<Goal, 'status'>): boolean {\n return TERMINAL.has(goal.status);\n}\n\nclass Cancelled extends Error {}\nclass OutOfBudget extends Error {}\n\nconst MAX_DEP_CHARS = 6_000;\nconst MAX_DEPS_TOTAL = 20_000;\nconst MAX_REVIEW_EXCERPT = 1_500;\nconst MAX_TOOL_ROUNDS = 6;\n\nexport class GoalOrchestrator {\n private readonly now: () => Date;\n private readonly tools: WorkspaceTools;\n\n constructor(private readonly options: GoalOrchestratorOptions) {\n this.now = options.now ?? (() => new Date());\n this.tools = new WorkspaceTools({ root: options.store.root, readOnly: true });\n }\n\n /** A fresh goal (not yet persisted) with limits clamped to the config. */\n create(input: NewGoalInput): Goal {\n const cfg = this.options.config;\n const stamp = this.now().toISOString();\n const goal: Goal = {\n id: newId('goal', 6),\n objective: input.objective.trim(),\n status: 'planning',\n round: 0,\n limits: {\n maxRounds: Math.min(input.maxRounds ?? cfg.maxRounds, cfg.maxRounds),\n maxTasks: Math.min(input.maxTasks ?? cfg.maxTasks, cfg.maxTasks),\n maxTokens: Math.min(input.maxTokens ?? cfg.maxTokens, cfg.maxTokens),\n tokensUsed: 0,\n },\n roles: publicRoles(resolveRoles(cfg)),\n tasks: [],\n createdAt: stamp,\n updatedAt: stamp,\n };\n if (input.dryRun) goal.dryRun = true;\n return goal;\n }\n\n /** Runs `goal` to a terminal status. Never throws: failures end up in `status`/`lastError`. */\n async run(goal: Goal, signal: AbortSignal): Promise<Goal> {\n const cfg = this.options.config;\n const roles = resolveRoles(cfg);\n try {\n const code = await this.codeAvailability();\n if (!code.ok) this.log(goal, 'info', `code tasks disabled: ${code.reason}`);\n\n if (goal.round === 0 || goal.tasks.length === 0) {\n goal.round = 1;\n await this.update(goal, { status: 'planning' });\n this.log(goal, 'info', `planning: ${goal.objective}`, 'planner');\n const plan = await this.plan(goal, roles, code.ok, signal);\n goal.tasks = normalizeTasks(plan.tasks, {\n existing: [],\n roles,\n round: 1,\n room: goal.limits.maxTasks,\n codeTasks: code.ok,\n });\n if (plan.summary) goal.summary = plan.summary;\n this.log(goal, 'info', `planned ${goal.tasks.length} task(s)`, 'planner');\n if (goal.dryRun) return await this.finish(goal, 'planned');\n } else {\n this.log(goal, 'info', `executing planned goal (${goal.tasks.length} task(s))`, 'planner');\n }\n\n for (;;) {\n await this.update(goal, { status: 'running' });\n await this.executeReady(goal, roles, signal);\n\n await this.update(goal, { status: 'reviewing' });\n this.log(goal, 'info', `reviewing round ${goal.round}`, 'reviewer');\n const review = await this.review(goal, roles, signal);\n goal.summary = review.summary;\n if (review.done) return await this.finish(goal, 'succeeded');\n if (goal.round >= goal.limits.maxRounds) {\n goal.lastError = `reached ${goal.limits.maxRounds} round(s) without completing the objective`;\n return await this.finish(goal, 'failed');\n }\n\n const retried = this.applyRetries(goal, review.retry);\n const added = normalizeTasks(review.tasks, {\n existing: goal.tasks,\n roles,\n round: goal.round + 1,\n room: goal.limits.maxTasks - goal.tasks.length,\n codeTasks: code.ok,\n });\n if (retried === 0 && added.length === 0) {\n goal.lastError =\n goal.tasks.length >= goal.limits.maxTasks\n ? `reached the cap of ${goal.limits.maxTasks} task(s) without completing the objective`\n : 'the reviewer proposed no further work but the objective is not done';\n return await this.finish(goal, 'failed');\n }\n goal.tasks.push(...added);\n goal.round++;\n this.log(\n goal,\n 'info',\n `round ${goal.round}: ${added.length} new task(s), ${retried} retried`,\n 'reviewer',\n );\n }\n } catch (err) {\n for (const task of goal.tasks) if (task.status === 'IN_PROGRESS') task.status = 'PENDING';\n delete goal.activeTaskId;\n if (err instanceof Cancelled || signal.aborted) return await this.finish(goal, 'cancelled');\n if (err instanceof OutOfBudget) {\n goal.lastError = err.message;\n return await this.finish(goal, 'budget_exhausted');\n }\n goal.lastError = err instanceof Error ? err.message : String(err);\n this.log(goal, 'error', goal.lastError);\n return await this.finish(goal, 'failed');\n }\n }\n\n // -- phases -----------------------------------------------------------------\n\n private async codeAvailability(): Promise<{ ok: true } | { ok: false; reason: string }> {\n if (!this.options.config.codeTasks) return { ok: false, reason: 'goal.codeTasks is off' };\n if (!this.options.codeRunner) return { ok: false, reason: 'no project runner available' };\n try {\n return await this.options.codeRunner.available();\n } catch (err) {\n return { ok: false, reason: err instanceof Error ? err.message : String(err) };\n }\n }\n\n private async plan(\n goal: Goal,\n roles: readonly ResolvedRole[],\n codeTasks: boolean,\n signal: AbortSignal,\n ): Promise<Plan> {\n const user = [\n `OBJECTIVE:\\n${goal.objective}`,\n `You may plan at most ${goal.limits.maxTasks} task(s) in total; the team has ${goal.limits.maxRounds} round(s) of plan → execute → review.`,\n await this.sharedContext(),\n ]\n .filter(Boolean)\n .join('\\n\\n');\n return this.askJson(\n planSchema,\n goal,\n this.roleFor(roles, 'planner'),\n plannerPrompt(roles, codeTasks),\n user,\n signal,\n );\n }\n\n private async review(\n goal: Goal,\n roles: readonly ResolvedRole[],\n signal: AbortSignal,\n ): Promise<Review> {\n const lines: string[] = [];\n for (const task of goal.tasks) {\n lines.push(\n `- [${task.status}] ${task.id} (${task.role}, ${task.kind}, round ${task.round}, ${task.attempts} attempt(s)): ${task.title}`,\n );\n if (task.notes) lines.push(` notes: ${truncateHead(task.notes, 500).replace(/\\n/g, ' ')}`);\n if (task.artifact) {\n const text = await this.options.store.readArtifact(goal.id, task.id);\n if (text)\n lines.push(` output excerpt:\\n${indent(truncateHead(text, MAX_REVIEW_EXCERPT))}`);\n }\n }\n const user = [\n `OBJECTIVE:\\n${goal.objective}`,\n `Round ${goal.round} of ${goal.limits.maxRounds}. Room for ${Math.max(0, goal.limits.maxTasks - goal.tasks.length)} more task(s).`,\n `TASKS:\\n${lines.join('\\n')}`,\n await this.sharedContext(),\n ]\n .filter(Boolean)\n .join('\\n\\n');\n return this.askJson(\n reviewSchema,\n goal,\n this.roleFor(roles, 'reviewer'),\n REVIEWER_PROMPT,\n user,\n signal,\n );\n }\n\n /** Runs ready tasks until none is left; failed tasks are retried up to `maxTaskAttempts`. */\n private async executeReady(\n goal: Goal,\n roles: readonly ResolvedRole[],\n signal: AbortSignal,\n ): Promise<void> {\n for (;;) {\n const task = readyGoalTasks(goal)[0];\n if (!task) return;\n this.checkpoint(goal, signal);\n task.attempts++;\n task.status = 'IN_PROGRESS';\n await this.update(goal, { activeTaskId: task.id });\n this.log(goal, 'info', `${task.title} (attempt ${task.attempts})`, task.role, task.id);\n try {\n if (task.kind === 'code') await this.runCodeTask(goal, task, signal);\n else await this.runArtifactTask(goal, task, this.roleFor(roles, task.role), signal);\n // runCodeTask/runArtifactTask set the outcome; re-read it past the narrowing above.\n const outcome = (task as GoalTask).status;\n this.log(\n goal,\n outcome === 'SUCCESS' ? 'info' : 'warn',\n `${task.id}: ${outcome}`,\n task.role,\n task.id,\n );\n } catch (err) {\n if (err instanceof Cancelled || err instanceof OutOfBudget || signal.aborted) throw err;\n if (\n err instanceof RouterError &&\n (err.code === 'no_capacity' || err.code === 'rate_limited')\n ) {\n throw new OutOfBudget(`no account has capacity left (${err.message})`);\n }\n task.status = 'FAILED';\n task.notes = truncateHead(err instanceof Error ? err.message : String(err), 2_000);\n this.log(goal, 'warn', `${task.id} failed: ${task.notes}`, task.role, task.id);\n }\n if (task.status === 'FAILED' && task.attempts < this.options.config.maxTaskAttempts) {\n task.status = 'PENDING';\n }\n delete goal.activeTaskId;\n await this.update(goal, {});\n }\n }\n\n private async runArtifactTask(\n goal: Goal,\n task: GoalTask,\n role: ResolvedRole,\n signal: AbortSignal,\n ): Promise<void> {\n const parts = [`OBJECTIVE OF THE TEAM:\\n${goal.objective}`, `YOUR TASK: ${task.title}`];\n if (task.description) parts.push(task.description);\n if (task.acceptance?.length) {\n parts.push(`Acceptance criteria:\\n${task.acceptance.map((c) => `- ${c}`).join('\\n')}`);\n }\n let budget = MAX_DEPS_TOTAL;\n for (const depId of task.dependsOn) {\n const dep = goal.tasks.find((t) => t.id === depId);\n if (!dep || budget <= 0) continue;\n const text = dep.artifact\n ? await this.options.store.readArtifact(goal.id, dep.id)\n : dep.notes;\n if (!text) continue;\n const excerpt = truncateHead(text, Math.min(MAX_DEP_CHARS, budget));\n budget -= excerpt.length;\n parts.push(`OUTPUT OF ${dep.id} (${dep.role}): ${dep.title}\\n${excerpt}`);\n }\n const shared = await this.sharedContext(false);\n if (shared) parts.push(shared);\n\n const reply = (\n await this.ask(goal, role, roleSystemPrompt(role), parts.join('\\n\\n'), signal)\n ).trim();\n if (!reply) throw new Error('the agent returned an empty reply');\n task.artifact = await this.options.store.writeArtifact(goal.id, task.id, stripFence(reply));\n task.status = 'SUCCESS';\n task.notes = `Wrote ${task.artifact}`;\n }\n\n private async runCodeTask(goal: Goal, task: GoalTask, signal: AbortSignal): Promise<void> {\n const runner = this.options.codeRunner;\n if (!runner) throw new Error('no project runner available for code tasks');\n const result = await runner.run(task, {\n goal,\n maxTokens: goal.limits.maxTokens - goal.limits.tokensUsed,\n signal,\n });\n this.addTokens(goal, result.tokens);\n if (result.runnerTaskId) task.runnerTaskId = result.runnerTaskId;\n if (result.stopped || signal.aborted) throw new Cancelled();\n task.status = result.ok ? 'SUCCESS' : 'FAILED';\n task.notes = truncateHead(result.summary || (result.ok ? 'done' : 'failed'), 2_000);\n }\n\n private applyRetries(goal: Goal, ids: readonly string[]): number {\n let count = 0;\n for (const id of new Set(ids)) {\n const task = goal.tasks.find((t) => t.id === id);\n if (task?.status !== 'FAILED') continue;\n task.status = 'PENDING';\n task.attempts = 0;\n count++;\n }\n return count;\n }\n\n // -- model calls ------------------------------------------------------------\n\n private roleFor(roles: readonly ResolvedRole[], id: string): ResolvedRole {\n return roles.find((r) => r.id === id) ?? { id, description: id, kind: 'artifact' };\n }\n\n private async ask(\n goal: Goal,\n role: ResolvedRole,\n system: string,\n user: string,\n signal: AbortSignal,\n ): Promise<string> {\n const model = routeModel(role.route ?? this.options.config.route);\n const messages: ChatMessage[] = [\n { role: 'system', content: system },\n { role: 'user', content: user },\n ];\n let attachTools = this.options.readTools === true;\n for (let round = 0; round <= MAX_TOOL_ROUNDS; round++) {\n this.checkpoint(goal, signal);\n const allowTools = attachTools && round < MAX_TOOL_ROUNDS;\n let completion: Awaited<ReturnType<typeof this.options.router.complete>>['completion'];\n try {\n ({ completion } = await this.options.router.complete(\n {\n model,\n messages,\n ...(allowTools ? { tools: [...READ_ONLY_TOOL_DEFINITIONS] } : {}),\n },\n { signal },\n ));\n } catch (err) {\n if (allowTools && err instanceof RouterError && err.code === 'no_available_account') {\n attachTools = false;\n ({ completion } = await this.options.router.complete({ model, messages }, { signal }));\n } else {\n throw err;\n }\n }\n const message = completion.choices[0]?.message;\n const content = message?.content;\n const text = typeof content === 'string' ? content : '';\n const usage = completion.usage;\n this.addTokens(\n goal,\n usage && usage.prompt_tokens + usage.completion_tokens > 0\n ? usage.prompt_tokens + usage.completion_tokens\n : countTextTokens(system) + countTextTokens(user) + countTextTokens(text),\n );\n const calls = message?.tool_calls ?? [];\n if (calls.length === 0 || round === MAX_TOOL_ROUNDS) return text;\n messages.push({ role: 'assistant', content: content ?? null, tool_calls: calls });\n for (const call of calls) {\n this.log(goal, 'debug', `tool ${call.function.name}`, role.id, goal.activeTaskId);\n const outcome = await this.tools.call(call.function.name, call.function.arguments, signal);\n messages.push({\n role: 'tool',\n tool_call_id: call.id,\n name: call.function.name,\n content: outcome.output,\n });\n }\n }\n return '';\n }\n\n /** Asks for a JSON reply matching `schema`; one corrective retry on malformed output. */\n private async askJson<T>(\n schema: z.ZodType<T>,\n goal: Goal,\n role: ResolvedRole,\n system: string,\n user: string,\n signal: AbortSignal,\n ): Promise<T> {\n let problem = '';\n for (let attempt = 0; attempt < 2; attempt++) {\n const prompt =\n attempt === 0\n ? user\n : `${user}\\n\\nYour previous reply was rejected (${problem}). Respond with ONLY the JSON object in the required shape.`;\n const reply = await this.ask(goal, role, system, prompt, signal);\n try {\n const parsed = schema.safeParse(extractJsonObject(reply));\n if (parsed.success) return parsed.data;\n problem = parsed.error.issues\n .slice(0, 3)\n .map((i) => `${i.path.join('.') || 'reply'}: ${i.message}`)\n .join('; ');\n } catch (err) {\n problem = err instanceof Error ? err.message : String(err);\n }\n this.log(goal, 'warn', `invalid JSON from the ${role.id}: ${problem}`, role.id);\n }\n throw new Error(`the ${role.id} did not return valid JSON (${problem})`);\n }\n\n private async sharedContext(includeProject = true): Promise<string> {\n const parts: string[] = [];\n if (includeProject && this.options.projectContext) {\n const project = (await this.options.projectContext()).trim();\n if (project) parts.push(`PROJECT CONTEXT:\\n${project}`);\n }\n if (this.options.budgetContext) {\n const budget = (await this.options.budgetContext()).trim();\n if (budget) parts.push(budget);\n }\n return parts.join('\\n\\n');\n }\n\n // -- bookkeeping ------------------------------------------------------------\n\n private checkpoint(goal: Goal, signal: AbortSignal): void {\n if (signal.aborted) throw new Cancelled();\n if (goal.limits.tokensUsed >= goal.limits.maxTokens) {\n throw new OutOfBudget(\n `token budget exhausted (${goal.limits.tokensUsed}/${goal.limits.maxTokens})`,\n );\n }\n }\n\n private addTokens(goal: Goal, tokens: number): void {\n if (Number.isFinite(tokens) && tokens > 0) goal.limits.tokensUsed += Math.round(tokens);\n }\n\n private async update(\n goal: Goal,\n patch: Partial<Pick<Goal, 'status' | 'activeTaskId'>>,\n ): Promise<void> {\n Object.assign(goal, patch);\n goal.updatedAt = this.now().toISOString();\n await this.options.store.save(goal);\n this.options.events.emit({ type: 'goal.updated', goal: structuredClone(goal) });\n }\n\n private async finish(goal: Goal, status: GoalStatus): Promise<Goal> {\n delete goal.activeTaskId;\n goal.finishedAt = this.now().toISOString();\n await this.update(goal, { status });\n this.log(\n goal,\n status === 'succeeded' || status === 'planned' ? 'info' : 'warn',\n `goal ${status}${goal.lastError ? `: ${goal.lastError}` : ''} (${goal.limits.tokensUsed} tokens)`,\n );\n return goal;\n }\n\n private log(goal: Goal, level: LogLevel, message: string, role?: string, taskId?: string): void {\n this.options.events.emit({\n type: 'goal.log',\n goalId: goal.id,\n level,\n message,\n ...(role ? { role } : {}),\n ...(taskId ? { taskId } : {}),\n });\n }\n}\n\n/** PENDING tasks whose dependencies all succeeded, in plan order. */\nexport function readyGoalTasks(goal: Pick<Goal, 'tasks'>): GoalTask[] {\n const status = new Map(goal.tasks.map((t) => [t.id, t.status]));\n return goal.tasks.filter(\n (t) => t.status === 'PENDING' && t.dependsOn.every((d) => status.get(d) === 'SUCCESS'),\n );\n}\n\nfunction indent(text: string): string {\n return text\n .split('\\n')\n .map((l) => ` ${l}`)\n .join('\\n');\n}\n\n/** Models sometimes wrap the whole document in a ```markdown fence. */\nfunction stripFence(text: string): string {\n const match = /^```(?:markdown|md)?\\s*\\n([\\s\\S]*?)\\n```\\s*$/i.exec(text);\n return match?.[1] ?? text;\n}\n","/**\n * One goal at a time per workspace: starts goals in the background, exposes their state and\n * cancels them. Structurally satisfies the server's `GoalControl`.\n */\nimport type { WorkspaceLock } from '../autonomous/workspace-lock';\nimport type { Goal } from '../types';\nimport { type GoalOrchestrator, isTerminalGoal, type NewGoalInput } from './orchestrator';\nimport type { GoalStore } from './store';\n\nexport type GoalErrorCode = 'busy' | 'not_found' | 'invalid';\n\nexport class GoalError extends Error {\n /** HTTP status hint for the gateway. */\n readonly statusCode: number;\n\n constructor(\n readonly code: GoalErrorCode,\n message: string,\n ) {\n super(message);\n this.name = 'GoalError';\n this.statusCode = code === 'not_found' ? 404 : code === 'invalid' ? 400 : 409;\n }\n}\n\nexport interface GoalServiceOptions {\n orchestrator: GoalOrchestrator;\n store: GoalStore;\n /** Workspace lock shared with the autonomous runner (not needed for dry runs). */\n lock?: WorkspaceLock;\n owner?: string;\n now?: () => Date;\n}\n\ninterface ActiveGoal {\n goal: Goal;\n controller: AbortController;\n done: Promise<Goal>;\n}\n\nexport interface GoalArtifact {\n taskId: string;\n path: string;\n content: string;\n}\n\nexport class GoalService {\n private active: ActiveGoal | undefined;\n private readonly owner: string;\n private readonly now: () => Date;\n\n constructor(private readonly options: GoalServiceOptions) {\n this.owner = options.owner ?? 'goal';\n this.now = options.now ?? (() => new Date());\n }\n\n get activeGoalId(): string | undefined {\n return this.active?.goal.id;\n }\n\n /** Validates, persists and starts a goal in the background. Resolves with its initial state. */\n async start(input: NewGoalInput): Promise<Goal> {\n if (!input.objective.trim()) throw new GoalError('invalid', 'the objective is empty');\n if (this.active) {\n throw new GoalError('busy', `goal ${this.active.goal.id} is still running; cancel it first`);\n }\n const lock = input.dryRun ? undefined : this.options.lock;\n if (lock && !lock.acquire(this.owner)) {\n throw new GoalError(\n 'busy',\n `the working tree is busy (${lock.holder ?? 'another task'} is running)`,\n );\n }\n try {\n const goal = this.options.orchestrator.create(input);\n await this.options.store.save(goal);\n this.launch(goal, lock);\n return structuredClone(goal);\n } catch (err) {\n lock?.release(this.owner);\n throw err;\n }\n }\n\n /**\n * Executes a `planned` (dry-run) goal in the background without re-planning round 1.\n * Resolves with the updated goal (`status: 'running'`).\n */\n async execute(id: string): Promise<Goal> {\n if (this.active) {\n throw new GoalError('busy', `goal ${this.active.goal.id} is still running; cancel it first`);\n }\n const goal = await this.options.store.load(id);\n if (!goal) throw new GoalError('not_found', `unknown goal \"${id}\"`);\n if (goal.status !== 'planned') {\n throw new GoalError(\n 'invalid',\n `goal \"${id}\" is ${goal.status}; only a planned goal can be executed`,\n );\n }\n const lock = this.options.lock;\n if (lock && !lock.acquire(this.owner)) {\n throw new GoalError(\n 'busy',\n `the working tree is busy (${lock.holder ?? 'another task'} is running)`,\n );\n }\n try {\n delete goal.dryRun;\n delete goal.finishedAt;\n delete goal.lastError;\n goal.status = 'running';\n goal.updatedAt = this.now().toISOString();\n await this.options.store.save(goal);\n this.launch(goal, lock);\n return structuredClone(goal);\n } catch (err) {\n lock?.release(this.owner);\n throw err;\n }\n }\n\n /** Reads the markdown artifact produced by `taskId` in goal `id`. */\n async readArtifact(id: string, taskId: string): Promise<GoalArtifact> {\n const goal = await this.get(id);\n if (!goal) throw new GoalError('not_found', `unknown goal \"${id}\"`);\n const task = goal.tasks.find((t) => t.id === taskId);\n if (!task?.artifact) {\n throw new GoalError('not_found', `task \"${taskId}\" has no artifact in goal \"${id}\"`);\n }\n const content = await this.options.store.readArtifact(id, taskId);\n if (content === undefined) {\n throw new GoalError('not_found', `artifact file for task \"${taskId}\" was not found`);\n }\n return { taskId: task.id, path: task.artifact, content };\n }\n\n private launch(goal: Goal, lock: WorkspaceLock | undefined): void {\n const controller = new AbortController();\n const done = this.options.orchestrator\n .run(goal, controller.signal)\n .catch((err: unknown) => {\n goal.status = 'failed';\n goal.lastError = err instanceof Error ? err.message : String(err);\n return goal;\n })\n .finally(() => {\n if (this.active?.goal === goal) this.active = undefined;\n lock?.release(this.owner);\n });\n this.active = { goal, controller, done };\n }\n\n async get(id: string): Promise<Goal | undefined> {\n if (this.active?.goal.id === id) return structuredClone(this.active.goal);\n return this.options.store.load(id);\n }\n\n /** Every goal of the workspace, newest first. */\n async list(): Promise<Goal[]> {\n const stored = await this.options.store.list();\n const active = this.active?.goal;\n if (!active) return stored;\n const rest = stored.filter((g) => g.id !== active.id);\n return [structuredClone(active), ...rest];\n }\n\n /**\n * Cancels a running goal and resolves once it has stopped. A goal left unfinished by an earlier\n * process is marked cancelled; a finished goal is returned unchanged.\n */\n async cancel(id: string): Promise<Goal> {\n if (this.active?.goal.id === id) {\n this.active.controller.abort();\n return structuredClone(await this.active.done);\n }\n const goal = await this.options.store.load(id);\n if (!goal) throw new GoalError('not_found', `unknown goal \"${id}\"`);\n if (isTerminalGoal(goal)) return goal;\n const stamp = this.now().toISOString();\n goal.status = 'cancelled';\n goal.updatedAt = stamp;\n goal.finishedAt = stamp;\n delete goal.activeTaskId;\n await this.options.store.save(goal);\n return goal;\n }\n\n /** Resolves when the goal is finished (immediately for stored goals). */\n async wait(id: string): Promise<Goal | undefined> {\n if (this.active?.goal.id === id) return structuredClone(await this.active.done);\n return this.options.store.load(id);\n }\n}\n","/**\n * Goal persistence: `<repo>/.davecode/goals/<goal-id>/goal.json` plus one markdown artifact per\n * task. Living under `.davecode/` keeps goal output out of the runner's dirty-tree check and out\n * of the project's own source tree.\n */\nimport { readdir } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { z } from 'zod';\nimport { atomicWriteFile, isNodeError, readFileIfExists } from '../brain/fs-util';\nimport { taskStatusSchema } from '../brain/graph';\nimport { projectPaths } from '../paths';\nimport type { Goal } from '../types';\n\nconst GOAL_ID = /^goal_[a-z0-9]{6,32}$/;\n\nconst goalTaskSchema = z.object({\n id: z.string().min(1),\n title: z.string(),\n description: z.string().optional(),\n role: z.string(),\n kind: z.enum(['code', 'artifact']),\n status: taskStatusSchema,\n dependsOn: z.array(z.string()),\n acceptance: z.array(z.string()).optional(),\n round: z.number().int().min(1),\n attempts: z.number().int().min(0),\n artifact: z.string().optional(),\n runnerTaskId: z.string().optional(),\n notes: z.string().optional(),\n});\n\nexport const goalSchema = z.object({\n id: z.string().regex(GOAL_ID),\n objective: z.string().min(1),\n status: z.enum([\n 'planning',\n 'running',\n 'reviewing',\n 'planned',\n 'succeeded',\n 'failed',\n 'cancelled',\n 'budget_exhausted',\n ]),\n round: z.number().int().min(0),\n limits: z.object({\n maxRounds: z.number().int().min(1),\n maxTasks: z.number().int().min(1),\n maxTokens: z.number().int().min(1),\n tokensUsed: z.number().int().min(0),\n }),\n roles: z.array(\n z.object({ id: z.string(), description: z.string(), route: z.string().optional() }),\n ),\n tasks: z.array(goalTaskSchema),\n activeTaskId: z.string().optional(),\n summary: z.string().optional(),\n lastError: z.string().optional(),\n dryRun: z.boolean().optional(),\n createdAt: z.string(),\n updatedAt: z.string(),\n finishedAt: z.string().optional(),\n});\n\nexport function isGoalId(id: string): boolean {\n return GOAL_ID.test(id);\n}\n\nexport class GoalStore {\n readonly dir: string;\n\n constructor(readonly root: string) {\n this.dir = join(projectPaths(root).dir, 'goals');\n }\n\n goalDir(id: string): string {\n if (!isGoalId(id)) throw new Error(`invalid goal id: ${id}`);\n return join(this.dir, id);\n }\n\n async save(goal: Goal): Promise<void> {\n await atomicWriteFile(\n join(this.goalDir(goal.id), 'goal.json'),\n `${JSON.stringify(goal, null, 2)}\\n`,\n );\n }\n\n /** The goal, or `undefined` when unknown. Throws when `goal.json` is corrupt. */\n async load(id: string): Promise<Goal | undefined> {\n if (!isGoalId(id)) return undefined;\n const text = await readFileIfExists(join(this.goalDir(id), 'goal.json'));\n if (text === undefined) return undefined;\n return goalSchema.parse(JSON.parse(text)) as Goal;\n }\n\n /** Every readable goal, newest first. Corrupt entries are skipped. */\n async list(): Promise<Goal[]> {\n let names: string[];\n try {\n names = await readdir(this.dir);\n } catch (err) {\n if (isNodeError(err, 'ENOENT')) return [];\n throw err;\n }\n const goals: Goal[] = [];\n for (const name of names.filter(isGoalId)) {\n try {\n const goal = await this.load(name);\n if (goal) goals.push(goal);\n } catch {\n // unreadable goal.json: not listed\n }\n }\n return goals.sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n }\n\n /** Writes a task's markdown artifact and returns its repository-relative path (`/`-separated). */\n async writeArtifact(goalId: string, taskId: string, markdown: string): Promise<string> {\n const path = join(this.goalDir(goalId), `${taskId}.md`);\n await atomicWriteFile(path, markdown.endsWith('\\n') ? markdown : `${markdown}\\n`);\n return relative(this.root, path).split('\\\\').join('/');\n }\n\n async readArtifact(goalId: string, taskId: string): Promise<string | undefined> {\n if (!isGoalId(goalId) || !/^[-a-zA-Z0-9_]{1,64}$/.test(taskId)) return undefined;\n return readFileIfExists(join(this.goalDir(goalId), `${taskId}.md`));\n }\n}\n","/** Wires a {@link GoalService} from a core {@link Engine}: the entry point for the CLI and server. */\nimport type { Executor } from '../autonomous/executor';\nimport { truncateHead } from '../autonomous/process';\nimport { WorkspaceLock } from '../autonomous/workspace-lock';\nimport type { ProjectBrain } from '../brain/project';\nimport type { Engine } from '../engine';\nimport { RunnerCodeTasks } from './code-tasks';\nimport { GoalOrchestrator } from './orchestrator';\nimport { GoalService } from './service';\nimport { GoalStore } from './store';\n\ntype EngineDeps = Pick<Engine, 'config' | 'router' | 'accounts' | 'sandboxes' | 'events' | 'paths'>;\n\nexport interface CreateGoalServiceOptions {\n /** Project brain: enables code tasks and project context. Its root holds the goals. */\n brain: ProjectBrain;\n /** Shared with the autonomous runner of the same working tree (default: a private lock). */\n lock?: WorkspaceLock;\n /** Compact budget summary shown to every agent and runner pass. */\n budgetContext?: () => string | Promise<string>;\n /** Override the runner's executor for code tasks (tests). */\n executor?: Executor;\n}\n\nconst PROJECT_CONTEXT_CHARS = 3_000;\n\nexport function createGoalService(engine: EngineDeps, opts: CreateGoalServiceOptions): GoalService {\n const { brain } = opts;\n const lock = opts.lock ?? new WorkspaceLock();\n const store = new GoalStore(brain.root);\n const codeRunner = new RunnerCodeTasks({\n engine,\n brain,\n lock,\n ...(opts.budgetContext ? { contextExtras: opts.budgetContext } : {}),\n ...(opts.executor ? { executor: opts.executor } : {}),\n });\n const projectContext = async (): Promise<string> => {\n if (!(await brain.isInitialised())) return '';\n const [architecture, state] = await Promise.all([brain.readArchitecture(), brain.readState()]);\n return [\n `ARCHITECTURE.md:\\n${truncateHead(architecture.trim(), PROJECT_CONTEXT_CHARS)}`,\n `STATE.md:\\n${truncateHead(state.trim(), PROJECT_CONTEXT_CHARS)}`,\n ].join('\\n\\n');\n };\n const orchestrator = new GoalOrchestrator({\n router: engine.router,\n store,\n events: engine.events,\n config: engine.config.goal,\n codeRunner,\n projectContext,\n ...(opts.budgetContext ? { budgetContext: opts.budgetContext } : {}),\n });\n return new GoalService({ orchestrator, store, lock });\n}\n","/**\n * Pane orchestrator engine: plans an objective with one agent, runs the subtasks in parallel in\n * their own worktrees (dependencies first), merges each result into the integration branch and\n * lets the user apply it. Talks only to the injected `AgentRunner` and `OrchestratorWorkspace`.\n */\nimport { randomBytes } from 'node:crypto';\nimport type { EventBus } from '../events';\nimport {\n type AgentAvailability,\n type AgentOutput,\n type AgentRunner,\n type AgentRunResult,\n ORCHESTRATOR_AGENTS,\n ORCHESTRATOR_LIMITS,\n type OrchestratorAgent,\n OrchestratorError,\n type OrchestratorRun,\n type OrchestratorService,\n type OrchestratorTask,\n type OrchestratorWorkspace,\n type StartRunInput,\n startRunSchema,\n type TaskWorkspace,\n} from './contract';\nimport {\n buildPlanPrompt,\n buildRepairPrompt,\n buildTaskPrompt,\n type PlanPromptInput,\n parsePlan,\n pickPlanner,\n} from './plan';\nimport { OrchestratorStore } from './store';\n\nexport interface OrchestratorServiceOptions {\n /** Absolute project root. */\n projectDir: string;\n /** DaveCode home: runs are kept under `<home>/orchestrator/`. */\n home: string;\n events: EventBus;\n runner: AgentRunner;\n workspace: OrchestratorWorkspace;\n now?: () => Date;\n /** Run id generator (default: 12 random hex characters). */\n newId?: () => string;\n}\n\n/** Longest error kept on a run or task. */\nconst ERROR_MAX_LENGTH = 300;\n/** Longest text of one `orchestrator.output` event. */\nconst OUTPUT_MAX_LENGTH = 2000;\n/** Runs kept in memory, as on disk. */\nconst RUNS_KEPT = 20;\n\nexport const INTERRUPTED_ERROR = 'Interrupted: DaveCode closed while this run was active.';\n\nconst ACTIVE_STATUSES: ReadonlySet<OrchestratorRun['status']> = new Set(['planning', 'running']);\n\ninterface ActiveRun {\n run: OrchestratorRun;\n controller: AbortController;\n done: Promise<void>;\n}\n\n/** The run ended with a short, user-facing reason (planning failed…). */\nclass RunFailure extends Error {}\n\nfunction clip(text: string, max: number): string {\n const trimmed = text.trim();\n return trimmed.length > max ? `${trimmed.slice(0, max - 1)}…` : trimmed;\n}\n\nfunction errorText(err: unknown): string {\n const message = err instanceof Error ? err.message : String(err);\n return clip(message || 'unknown error', ERROR_MAX_LENGTH);\n}\n\nfunction isAbortError(err: unknown): boolean {\n return (\n typeof err === 'object' &&\n err !== null &&\n 'name' in err &&\n ((err as { name: unknown }).name === 'AbortError' ||\n (err as { name: unknown }).name === 'TimeoutError')\n );\n}\n\n/** Serializes async work: each call starts after the previous one settled. */\nclass Queue {\n private tail: Promise<unknown> = Promise.resolve();\n\n run<T>(work: () => Promise<T>): Promise<T> {\n const next = this.tail.then(work, work);\n this.tail = next.catch(() => undefined);\n return next;\n }\n}\n\nconst isActive = (run: OrchestratorRun) => ACTIVE_STATUSES.has(run.status);\n\nexport function createOrchestratorService(\n options: OrchestratorServiceOptions,\n): OrchestratorService {\n return new OrchestratorEngine(options);\n}\n\nclass OrchestratorEngine implements OrchestratorService {\n private readonly now: () => Date;\n private readonly newId: () => string;\n private readonly store: OrchestratorStore;\n /** Newest first. */\n private runs: OrchestratorRun[];\n private readonly active = new Map<string, ActiveRun>();\n private readonly applying = new Set<string>();\n /** A `start` that passed the busy check but has not registered its run yet. */\n private starting = false;\n /** Every git mutation goes through here: worktree, commit and merge must not interleave. */\n private readonly git = new Queue();\n\n constructor(private readonly options: OrchestratorServiceOptions) {\n this.now = options.now ?? (() => new Date());\n this.newId = options.newId ?? (() => randomBytes(6).toString('hex'));\n this.store = new OrchestratorStore(options.home, options.projectDir);\n this.runs = this.store.load();\n this.recoverInterrupted();\n }\n\n // --- Public API ------------------------------------------------------------------------------\n\n agents(): Promise<AgentAvailability[]> {\n return this.options.runner.availability();\n }\n\n async start(rawInput: StartRunInput): Promise<OrchestratorRun> {\n const input = startRunSchema.parse(rawInput);\n this.assertIdle();\n this.starting = true;\n try {\n const { workspace, runner } = this.options;\n let head: { branch: string; commit: string };\n try {\n const checked = await workspace.check();\n if (!checked.ok) throw new OrchestratorError('not_a_repository', clip(checked.reason, 300));\n head = { branch: checked.branch, commit: checked.commit };\n } catch (err) {\n if (err instanceof OrchestratorError) throw err;\n throw new OrchestratorError('not_a_repository', errorText(err));\n }\n\n const availability = await runner.availability();\n const available = new Set(availability.filter((a) => a.available).map((a) => a.agent));\n const wanted = new Set<OrchestratorAgent>(input.agents ?? ORCHESTRATOR_AGENTS);\n const agents = ORCHESTRATOR_AGENTS.filter((a) => wanted.has(a) && available.has(a));\n if (agents.length === 0) {\n throw new OrchestratorError(\n 'no_agents',\n input.agents\n ? `None of the selected agents (${input.agents.join(', ')}) is installed.`\n : 'No agent CLI (claude, codex, agy) was found on PATH.',\n );\n }\n\n if (input.planner && !available.has(input.planner)) {\n throw new OrchestratorError(\n 'no_agents',\n `The chosen planner (${input.planner}) is not installed.`,\n );\n }\n const planner = input.planner ?? pickPlanner(agents);\n\n const id = this.newId();\n let integrationBranch: string;\n try {\n integrationBranch = await this.git.run(() => workspace.createIntegration(id, head.commit));\n } catch (err) {\n throw new OrchestratorError('not_a_repository', errorText(err));\n }\n\n const stamp = this.stamp();\n const run: OrchestratorRun = {\n id,\n objective: input.objective,\n status: 'planning',\n agents,\n planner,\n baseBranch: head.branch,\n baseCommit: head.commit,\n integrationBranch,\n tasks: [],\n createdAt: stamp,\n updatedAt: stamp,\n };\n this.runs.unshift(run);\n this.trim();\n const active: ActiveRun = {\n run,\n controller: new AbortController(),\n done: Promise.resolve(),\n };\n this.active.set(id, active);\n this.changed(run);\n active.done = this.execute(active, input.maxTasks ?? ORCHESTRATOR_LIMITS.defaultMaxTasks)\n .catch(() => undefined)\n .finally(() => {\n this.active.delete(id);\n });\n return structuredClone(run);\n } finally {\n this.starting = false;\n }\n }\n\n get(id: string): OrchestratorRun | undefined {\n const run = this.find(id);\n return run ? structuredClone(run) : undefined;\n }\n\n list(): OrchestratorRun[] {\n return this.runs.map((run) => structuredClone(run));\n }\n\n cancel(id: string): boolean {\n const active = this.active.get(id);\n if (!active || !isActive(active.run)) return false;\n active.controller.abort();\n return true;\n }\n\n async apply(id: string): Promise<OrchestratorRun> {\n const run = this.find(id);\n if (!run) throw new OrchestratorError('not_found', `No orchestrator run ${id}.`);\n if (run.status !== 'done') {\n throw new OrchestratorError(\n 'not_appliable',\n `The run is ${run.status}; only a finished run can be applied.`,\n );\n }\n if (run.appliedAt) throw new OrchestratorError('not_appliable', 'The run was already applied.');\n if (!run.integrationBranch || !run.baseBranch) {\n throw new OrchestratorError('not_appliable', 'The run has no integration branch to apply.');\n }\n if (this.applying.has(id)) {\n throw new OrchestratorError('not_appliable', 'The run is already being applied.');\n }\n const baseBranch = run.baseBranch;\n this.applying.add(id);\n try {\n let result: Awaited<ReturnType<OrchestratorWorkspace['apply']>>;\n try {\n result = await this.git.run(() => this.options.workspace.apply(id, baseBranch));\n } catch (err) {\n result = { ok: false, reason: errorText(err) };\n }\n if (!result.ok) throw new OrchestratorError('not_appliable', clip(result.reason, 300));\n run.appliedAt = this.stamp();\n this.changed(run);\n return structuredClone(run);\n } finally {\n this.applying.delete(id);\n }\n }\n\n async close(): Promise<void> {\n const pending = [...this.active.values()];\n for (const active of pending) active.controller.abort();\n await Promise.all(pending.map((active) => active.done));\n await this.store.flush();\n }\n\n // --- Run lifecycle ---------------------------------------------------------------------------\n\n private async execute(active: ActiveRun, maxTasks: number): Promise<void> {\n const { run, controller } = active;\n try {\n run.tasks = await this.plan(active, maxTasks);\n if (controller.signal.aborted) throw controller.signal.reason;\n run.status = 'running';\n this.changed(run);\n await this.runTasks(active);\n this.finish(run, controller.signal.aborted);\n } catch (err) {\n if (controller.signal.aborted || isAbortError(err)) {\n this.finish(run, true);\n } else {\n for (const task of run.tasks) this.endTask(task, 'cancelled');\n run.status = 'failed';\n run.error = errorText(err);\n run.summary = `The run failed: ${run.error}`;\n this.changed(run);\n }\n } finally {\n try {\n await this.options.workspace.cleanup(run.id);\n } catch {\n // Leftover worktrees are harmless; the branches hold the work.\n }\n }\n }\n\n private async plan(active: ActiveRun, maxTasks: number): Promise<OrchestratorTask[]> {\n const { run } = active;\n const planner = run.planner!;\n const promptInput: PlanPromptInput = { objective: run.objective, agents: run.agents, maxTasks };\n const ask = async (prompt: string): Promise<AgentRunResult> => {\n const result = await this.options.runner.run({\n agent: planner,\n cwd: this.options.projectDir,\n prompt,\n mode: 'plan',\n signal: active.controller.signal,\n timeoutMs: ORCHESTRATOR_LIMITS.planTimeoutMs,\n onOutput: (chunk) => this.output(run.id, 'plan', chunk),\n });\n if (!result.ok) {\n throw new RunFailure(\n `The planner (${planner}) failed: ${result.error ?? 'no reason given'}`,\n );\n }\n return result;\n };\n\n this.output(run.id, 'plan', { kind: 'status', text: `Planning with ${planner}…` });\n const first = await ask(buildPlanPrompt(promptInput));\n const parsed = parsePlan(first.text, { agents: run.agents, maxTasks });\n if (parsed.ok) return parsed.tasks;\n\n this.output(run.id, 'plan', {\n kind: 'status',\n text: `The plan was not usable (${parsed.error}); asking ${planner} to fix it.`,\n });\n const second = await ask(buildRepairPrompt(promptInput, first.text, parsed.error));\n const repaired = parsePlan(second.text, { agents: run.agents, maxTasks });\n if (repaired.ok) return repaired.tasks;\n throw new RunFailure(`The planner did not return a usable plan: ${repaired.error}`);\n }\n\n private async runTasks(active: ActiveRun): Promise<void> {\n const { run, controller } = active;\n const running = new Map<string, Promise<void>>();\n const busyAgents = new Set<OrchestratorAgent>();\n\n while (!controller.signal.aborted) {\n this.skipBlocked(run);\n for (const task of run.tasks) {\n if (running.size >= ORCHESTRATOR_LIMITS.maxParallel) break;\n if (task.status !== 'pending' || busyAgents.has(task.agent)) continue;\n if (!task.dependsOn.every((dep) => this.taskById(run, dep)?.status === 'done')) continue;\n busyAgents.add(task.agent);\n const work = this.runTask(active, task).finally(() => {\n running.delete(task.id);\n busyAgents.delete(task.agent);\n });\n running.set(task.id, work);\n }\n if (running.size === 0) break;\n await Promise.race(running.values());\n }\n await Promise.all(running.values());\n\n for (const task of run.tasks) {\n if (task.status !== 'pending') continue;\n if (controller.signal.aborted) this.endTask(task, 'cancelled');\n else this.endTask(task, 'skipped', 'Its dependencies never finished.');\n }\n }\n\n /** Pending tasks that depend on a task that ended without `done` will never run. */\n private skipBlocked(run: OrchestratorRun): void {\n let changed = true;\n while (changed) {\n changed = false;\n for (const task of run.tasks) {\n if (task.status !== 'pending') continue;\n const blocker = task.dependsOn\n .map((dep) => this.taskById(run, dep))\n .find(\n (dep) =>\n dep && dep.status !== 'done' && dep.status !== 'pending' && dep.status !== 'running',\n );\n if (!blocker) continue;\n this.endTask(\n task,\n 'skipped',\n `Depends on ${blocker.id} (${blocker.title}), which ended ${blocker.status}.`,\n );\n this.changed(run);\n changed = true;\n }\n }\n }\n\n /** Never rejects: every outcome ends up on the task. */\n private async runTask(active: ActiveRun, task: OrchestratorTask): Promise<void> {\n const { run, controller } = active;\n const { workspace, runner } = this.options;\n const signal = controller.signal;\n task.status = 'running';\n task.startedAt = this.stamp();\n this.changed(run);\n try {\n const ws: TaskWorkspace = await this.git.run(() =>\n workspace.createTask(run.id, task.id, run.integrationBranch!),\n );\n task.branch = ws.branch;\n if (signal.aborted) throw signal.reason;\n this.changed(run);\n\n this.output(run.id, task.id, {\n kind: 'status',\n text: `Starting ${task.agent} on ${ws.branch}`,\n });\n const result = await runner.run({\n agent: task.agent,\n cwd: ws.path,\n prompt: buildTaskPrompt({ objective: run.objective, task, tasks: run.tasks }),\n mode: 'edit',\n signal,\n timeoutMs: ORCHESTRATOR_LIMITS.taskTimeoutMs,\n onOutput: (chunk) => this.output(run.id, task.id, chunk),\n });\n if (signal.aborted) throw signal.reason;\n if (result.text.trim())\n task.summary = clip(result.text, ORCHESTRATOR_LIMITS.summaryMaxLength);\n if (!result.ok) {\n this.endTask(task, 'failed', result.error ?? `${task.agent} did not finish the task.`);\n return;\n }\n\n const files = await this.git.run(() => workspace.commitTask(ws, `davecode: ${task.title}`));\n task.changedFiles = files;\n if (files.length > 0) {\n const merged = await this.git.run(() =>\n workspace.mergeIntoIntegration(\n run.id,\n ws.branch,\n `davecode: merge ${task.id} ${task.title}`,\n ),\n );\n if (!merged.ok) {\n this.endTask(task, 'conflict', merged.reason);\n return;\n }\n }\n this.endTask(task, 'done');\n } catch (err) {\n if (signal.aborted || isAbortError(err)) this.endTask(task, 'cancelled');\n else this.endTask(task, 'failed', errorText(err));\n } finally {\n this.changed(run);\n }\n }\n\n /** Final status and deterministic summary. */\n private finish(run: OrchestratorRun, cancelled: boolean): void {\n for (const task of run.tasks) {\n if (task.status === 'pending' || task.status === 'running') this.endTask(task, 'cancelled');\n }\n const total = run.tasks.length;\n const done = run.tasks.filter((t) => t.status === 'done').length;\n const notes = run.tasks.filter((t) => t.status !== 'done').map((t) => describeOutcome(t));\n const where = run.integrationBranch ?? 'the integration branch';\n\n if (cancelled) {\n run.status = 'cancelled';\n run.summary =\n total === 0\n ? 'Cancelled while planning.'\n : `Cancelled: ${done} of ${total} tasks had finished on ${where}.`;\n } else if (done > 0) {\n run.status = 'done';\n const tail = notes.length > 0 ? ` ${notes.join('; ')}.` : '';\n run.summary = `${done} of ${total} tasks finished on ${where}.${tail} Apply it to merge into ${run.baseBranch ?? 'the base branch'}.`;\n } else {\n run.status = 'failed';\n run.error = 'No task finished.';\n run.summary = `None of the ${total} tasks finished. ${notes.join('; ')}.`;\n }\n this.changed(run);\n }\n\n private endTask(\n task: OrchestratorTask,\n status: OrchestratorTask['status'],\n error?: string,\n ): void {\n if (task.status !== 'pending' && task.status !== 'running') return;\n task.status = status;\n if (error) task.error = clip(error, ERROR_MAX_LENGTH);\n if (task.startedAt) task.finishedAt = this.stamp();\n }\n\n // --- Helpers ---------------------------------------------------------------------------------\n\n private assertIdle(): void {\n const current = [...this.active.values()].find((a) => isActive(a.run));\n if (current || this.starting) {\n throw new OrchestratorError(\n 'busy',\n current\n ? `Run ${current.run.id} is still ${current.run.status}; cancel it or wait for it to end.`\n : 'Another run is starting.',\n );\n }\n }\n\n private recoverInterrupted(): void {\n const interrupted = this.runs.filter(isActive);\n if (interrupted.length === 0) return;\n const stamp = this.stamp();\n for (const run of interrupted) {\n for (const task of run.tasks) {\n if (task.status === 'running') {\n task.status = 'failed';\n task.error = INTERRUPTED_ERROR;\n task.finishedAt = stamp;\n } else if (task.status === 'pending') {\n task.status = 'cancelled';\n }\n }\n run.status = 'failed';\n run.error = INTERRUPTED_ERROR;\n run.updatedAt = stamp;\n const { workspace } = this.options;\n Promise.resolve()\n .then(() => workspace.cleanup(run.id))\n .catch(() => undefined);\n }\n void this.store.save(this.runs);\n }\n\n private find(id: string): OrchestratorRun | undefined {\n return this.runs.find((run) => run.id === id);\n }\n\n private taskById(run: OrchestratorRun, id: string): OrchestratorTask | undefined {\n return run.tasks.find((task) => task.id === id);\n }\n\n private stamp(): string {\n return this.now().toISOString();\n }\n\n /** Keeps the newest runs, never dropping an active one. */\n private trim(): void {\n if (this.runs.length <= RUNS_KEPT) return;\n const keep = new Set(this.runs.slice(0, RUNS_KEPT));\n this.runs = this.runs.filter((run) => keep.has(run) || this.active.has(run.id));\n }\n\n /** Records a state change: bump `updatedAt`, persist, emit a snapshot. */\n private changed(run: OrchestratorRun): void {\n run.updatedAt = this.stamp();\n void this.store.save(this.runs);\n this.options.events.emit({\n type: 'orchestrator.run',\n run: structuredClone(run),\n ts: this.now().getTime(),\n });\n }\n\n private output(runId: string, taskId: string, chunk: AgentOutput): void {\n const text =\n chunk.text.length > OUTPUT_MAX_LENGTH ? chunk.text.slice(0, OUTPUT_MAX_LENGTH) : chunk.text;\n if (!text && chunk.kind !== 'error') return;\n this.options.events.emit({\n type: 'orchestrator.output',\n runId,\n taskId,\n output: { kind: chunk.kind, text },\n ts: this.now().getTime(),\n });\n }\n}\n\nfunction describeOutcome(task: OrchestratorTask): string {\n const reason = task.error ? `: ${clip(task.error, 120)}` : '';\n switch (task.status) {\n case 'conflict':\n return `${task.id} conflicts with the integration branch${reason}`;\n case 'failed':\n return `${task.id} failed${reason}`;\n case 'skipped':\n return `${task.id} was skipped${reason}`;\n case 'cancelled':\n return `${task.id} was cancelled`;\n default:\n return `${task.id} is ${task.status}`;\n }\n}\n","/**\n * Pane orchestrator planning: the prompts the planner and the task agents receive, and the\n * validation that turns the planner's JSON reply into a safe, acyclic list of tasks.\n */\nimport { z } from 'zod';\nimport { extractJsonObject } from '../autonomous/judge';\nimport {\n ORCHESTRATOR_AGENTS,\n ORCHESTRATOR_LIMITS,\n type OrchestratorAgent,\n type OrchestratorTask,\n} from './contract';\n\n/** One line per agent, shown to the planner so it can pick who does what. */\nexport const AGENT_DESCRIPTIONS: Record<OrchestratorAgent, string> = {\n claude:\n 'Claude Code (Anthropic): careful multi-file changes, refactors and reasoning about existing code.',\n codex: 'Codex CLI (OpenAI): focused implementation work, scripts, tests and quick fixes.',\n agy: 'Antigravity (Google): broad feature work, front-end and UI changes, exploratory tasks.',\n};\n\nconst TITLE_MAX_LENGTH = 120;\nconst PROMPT_MAX_LENGTH = 8000;\n/** Longest piece of a previous reply quoted back to the planner in the repair prompt. */\nconst REPAIR_REPLY_MAX_LENGTH = 6000;\n\n/** The first allowed agent in the fixed order claude, codex, agy. */\nexport function pickPlanner(agents: readonly OrchestratorAgent[]): OrchestratorAgent | undefined {\n return ORCHESTRATOR_AGENTS.find((agent) => agents.includes(agent));\n}\n\nconst REPLY_SHAPE =\n '{\"tasks\":[{\"title\":string,\"agent\":\"claude\"|\"codex\"|\"agy\",\"prompt\":string,\"dependsOn\":[number]}]}';\n\nexport interface PlanPromptInput {\n objective: string;\n agents: readonly OrchestratorAgent[];\n maxTasks: number;\n}\n\nexport function buildPlanPrompt(input: PlanPromptInput): string {\n const agentLines = input.agents.map((agent) => `- ${agent}: ${AGENT_DESCRIPTIONS[agent]}`);\n return [\n 'You are the planner of DaveCode, which splits one objective across several coding agents.',\n 'Do not change any file. Read the repository as much as you need, then answer with a plan.',\n '',\n 'Objective:',\n input.objective,\n '',\n 'Agents you may assign tasks to:',\n ...agentLines,\n '',\n 'Rules:',\n `- Use at most ${input.maxTasks} task${input.maxTasks === 1 ? '' : 's'}. Fewer is better when the objective is small.`,\n '- Tasks run in parallel, each in its own separate copy of the repository, and their changes are merged afterwards. Give tasks different files to touch wherever possible so the merges do not conflict.',\n '- When a task needs the result of another task, list it in \"dependsOn\" (1-based positions in the \"tasks\" array). It then starts only after those tasks finished and were merged.',\n '- Each \"prompt\" must be self-contained: the agent sees only its own prompt and the repository, not this plan or the other prompts. Say exactly what to build or change, where, and how to know it is done.',\n '- Write every \"title\" and \"prompt\" in the language of the objective.',\n '- Spread the work over the agents according to their strengths.',\n '',\n 'Reply with ONLY a JSON object, no prose and no code fence, of this shape:',\n REPLY_SHAPE,\n ].join('\\n');\n}\n\n/** Second chance after an unusable reply: the previous answer plus why it was rejected. */\nexport function buildRepairPrompt(\n input: PlanPromptInput,\n previousReply: string,\n error: string,\n): string {\n const reply =\n previousReply.length > REPAIR_REPLY_MAX_LENGTH\n ? `${previousReply.slice(0, REPAIR_REPLY_MAX_LENGTH)}…`\n : previousReply;\n return [\n 'Your previous plan could not be used.',\n `Problem: ${error}`,\n '',\n 'Your previous reply:',\n reply.trim() || '(empty)',\n '',\n `Objective: ${input.objective}`,\n `Allowed agents: ${input.agents.join(', ')}. At most ${input.maxTasks} tasks, at least one.`,\n 'Dependencies are 1-based task positions and must not form a cycle.',\n 'Do not change any file. Reply with ONLY a JSON object of this shape:',\n REPLY_SHAPE,\n ].join('\\n');\n}\n\nexport interface TaskPromptInput {\n objective: string;\n task: Pick<OrchestratorTask, 'id' | 'title' | 'prompt' | 'dependsOn'>;\n /** Every task of the plan, used to describe the parallel work and the dependencies. */\n tasks: ReadonlyArray<Pick<OrchestratorTask, 'id' | 'title' | 'agent'>>;\n}\n\nexport function buildTaskPrompt(input: TaskPromptInput): string {\n const others = input.tasks.filter((t) => t.id !== input.task.id);\n const deps = input.tasks.filter((t) => input.task.dependsOn.includes(t.id));\n const lines = [\n 'You are one of several coding agents working together on one objective, coordinated by DaveCode.',\n '',\n 'Overall objective:',\n input.objective,\n '',\n `Your task: ${input.task.title}`,\n input.task.prompt,\n '',\n ];\n if (deps.length > 0) {\n lines.push(\n 'The results of these tasks are already in your copy of the repository:',\n ...deps.map((t) => `- ${t.title}`),\n '',\n );\n }\n if (others.length > 0) {\n lines.push(\n 'Other agents work on these parts in parallel, in their own copies of the repository:',\n ...others.map((t) => `- ${t.title} (${t.agent})`),\n '',\n );\n }\n lines.push(\n 'Rules:',\n '- Keep to the scope of your task; leave the other parts to the other agents.',\n '- Do not commit, push, create or switch branches. DaveCode commits and merges your changes.',\n '- Do not read or modify anything under `.davecode/`.',\n '- When you are done, finish with a short summary of what you changed and anything left open.',\n );\n return lines.join('\\n');\n}\n\n// --- Parsing the planner's reply --------------------------------------------------------------\n\nconst dependencySchema = z.union([z.number(), z.string()]);\n\nconst plannedTaskSchema = z.object({\n title: z.string().trim().min(1),\n agent: z.string().optional(),\n prompt: z.string().trim().min(1),\n dependsOn: z.array(dependencySchema).nullish(),\n});\n\nexport const planReplySchema = z.object({\n tasks: z.array(plannedTaskSchema).min(1, 'the plan has no tasks'),\n});\n\nexport interface ParsePlanOptions {\n /** Allowed agents for the run (non-empty). */\n agents: readonly OrchestratorAgent[];\n maxTasks: number;\n}\n\nexport type ParsePlanResult =\n | { ok: true; tasks: OrchestratorTask[] }\n | { ok: false; error: string };\n\n/** `2`, `\"2\"` and `\"t2\"` all mean the second task. */\nfunction dependencyIndex(value: number | string): number | undefined {\n if (typeof value === 'number') return Number.isInteger(value) ? value : undefined;\n const match = /^\\s*t?(\\d+)\\s*$/i.exec(value);\n return match?.[1] ? Number(match[1]) : undefined;\n}\n\nfunction clip(text: string, max: number): string {\n return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n}\n\nfunction describeZodError(error: z.ZodError): string {\n const issue = error.issues[0];\n if (!issue) return 'the reply does not match the expected shape';\n const path = issue.path.length > 0 ? `${issue.path.join('.')}: ` : '';\n return `${path}${issue.message}`;\n}\n\n/** Returns one cycle as `[a, b, …, a]`, or undefined when the tasks are acyclic. */\nexport function findCycle(tasks: ReadonlyArray<Pick<OrchestratorTask, 'id' | 'dependsOn'>>) {\n const byId = new Map(tasks.map((t) => [t.id, t]));\n const done = new Set<string>();\n const stack: string[] = [];\n const onStack = new Set<string>();\n const visit = (id: string): string[] | undefined => {\n stack.push(id);\n onStack.add(id);\n for (const dep of byId.get(id)?.dependsOn ?? []) {\n if (onStack.has(dep)) return [...stack.slice(stack.indexOf(dep)), dep];\n if (!done.has(dep) && byId.has(dep)) {\n const cycle = visit(dep);\n if (cycle) return cycle;\n }\n }\n stack.pop();\n onStack.delete(id);\n done.add(id);\n return undefined;\n };\n for (const task of tasks) {\n if (done.has(task.id)) continue;\n const cycle = visit(task.id);\n if (cycle) return cycle;\n }\n return undefined;\n}\n\n/**\n * Validates and normalizes a planner reply: ids `t1…tN`, at most `maxTasks` tasks, unknown or\n * disallowed agents reassigned round-robin over the allowed ones, dependencies that are out of\n * range or point at the task itself dropped. Cycles are rejected.\n */\nexport function parsePlan(text: string, options: ParsePlanOptions): ParsePlanResult {\n if (options.agents.length === 0) return { ok: false, error: 'no agents are allowed' };\n let raw: unknown;\n try {\n raw = extractJsonObject(text);\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n return { ok: false, error: `the reply is not a valid JSON object (${clip(reason, 120)})` };\n }\n const parsed = planReplySchema.safeParse(raw);\n if (!parsed.success) return { ok: false, error: describeZodError(parsed.error) };\n\n const maxTasks = Math.max(1, Math.min(options.maxTasks, ORCHESTRATOR_LIMITS.maxTasks));\n const planned = parsed.data.tasks.slice(0, maxTasks);\n let roundRobin = 0;\n const tasks = planned.map((p, index): OrchestratorTask => {\n const allowed = options.agents.find((a) => a === p.agent?.trim().toLowerCase());\n const agent = allowed ?? options.agents[roundRobin++ % options.agents.length]!;\n const deps = new Set<string>();\n for (const value of p.dependsOn ?? []) {\n const dep = dependencyIndex(value);\n if (dep === undefined || dep < 1 || dep > planned.length || dep === index + 1) continue;\n deps.add(`t${dep}`);\n }\n return {\n id: `t${index + 1}`,\n title: clip(p.title.replace(/\\s+/g, ' '), TITLE_MAX_LENGTH),\n agent,\n prompt: clip(p.prompt, PROMPT_MAX_LENGTH),\n dependsOn: [...deps],\n status: 'pending',\n };\n });\n\n const cycle = findCycle(tasks);\n if (cycle) {\n return { ok: false, error: `the dependencies form a cycle (${cycle.join(' -> ')})` };\n }\n return { ok: true, tasks };\n}\n","/**\n * Pane orchestrator persistence: every run of one project in a single JSON file under the\n * DaveCode home, `<home>/orchestrator/<sha256(projectDir) prefix>/runs.json`. Outside the project\n * so the agents' worktrees and the user's tree never see it.\n */\nimport { createHash } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { z } from 'zod';\nimport { atomicWriteFile } from '../brain/fs-util';\nimport { ORCHESTRATOR_AGENTS, type OrchestratorRun } from './contract';\n\n/** Runs kept on disk (newest by `createdAt`). */\nexport const ORCHESTRATOR_RUNS_KEPT = 20;\n\nconst agentSchema = z.enum(ORCHESTRATOR_AGENTS);\n\nconst taskSchema = z.object({\n id: z.string().min(1),\n title: z.string(),\n agent: agentSchema,\n prompt: z.string(),\n dependsOn: z.array(z.string()),\n status: z.enum(['pending', 'running', 'done', 'failed', 'conflict', 'cancelled', 'skipped']),\n branch: z.string().optional(),\n summary: z.string().optional(),\n changedFiles: z.array(z.string()).optional(),\n error: z.string().optional(),\n startedAt: z.string().optional(),\n finishedAt: z.string().optional(),\n});\n\nexport const orchestratorRunSchema = z.object({\n id: z.string().min(1),\n objective: z.string(),\n status: z.enum(['planning', 'running', 'done', 'failed', 'cancelled']),\n agents: z.array(agentSchema),\n planner: agentSchema.optional(),\n baseBranch: z.string().optional(),\n baseCommit: z.string().optional(),\n integrationBranch: z.string().optional(),\n tasks: z.array(taskSchema),\n summary: z.string().optional(),\n error: z.string().optional(),\n appliedAt: z.string().optional(),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\n\nconst fileSchema = z.object({\n version: z.literal(1),\n runs: z.array(z.unknown()),\n});\n\n/** `<home>/orchestrator/<first 16 hex of sha256(projectDir)>/runs.json`. */\nexport function orchestratorRunsPath(home: string, projectDir: string): string {\n let key = resolve(projectDir);\n if (process.platform === 'win32') key = key.toLowerCase();\n const hash = createHash('sha256').update(key).digest('hex').slice(0, 16);\n return join(home, 'orchestrator', hash, 'runs.json');\n}\n\n/** Newest first by `createdAt`; ties keep their order. */\nfunction newestFirst(runs: readonly OrchestratorRun[]): OrchestratorRun[] {\n return [...runs].sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n}\n\nexport class OrchestratorStore {\n readonly path: string;\n private queued: string | undefined;\n private writing: Promise<void> | undefined;\n\n constructor(home: string, projectDir: string) {\n this.path = orchestratorRunsPath(home, projectDir);\n }\n\n /**\n * The stored runs, newest first. A missing or corrupt file yields no runs; a run that does not\n * validate is skipped.\n */\n load(): OrchestratorRun[] {\n let text: string;\n try {\n text = readFileSync(this.path, 'utf8');\n } catch {\n return [];\n }\n let file: z.infer<typeof fileSchema>;\n try {\n file = fileSchema.parse(JSON.parse(text));\n } catch {\n return [];\n }\n const runs: OrchestratorRun[] = [];\n for (const entry of file.runs) {\n const parsed = orchestratorRunSchema.safeParse(entry);\n if (parsed.success) runs.push(parsed.data as OrchestratorRun);\n }\n return newestFirst(runs).slice(0, ORCHESTRATOR_RUNS_KEPT);\n }\n\n /**\n * Snapshots `runs` now and writes them atomically in the background, keeping the newest\n * {@link ORCHESTRATOR_RUNS_KEPT}. Writes are serialized; a snapshot that is still queued is\n * replaced by the newer one. Resolves once that snapshot (or a newer one) is on disk; never\n * rejects (a failed write is retried by the next save).\n */\n save(runs: readonly OrchestratorRun[]): Promise<void> {\n const kept = newestFirst(runs).slice(0, ORCHESTRATOR_RUNS_KEPT);\n this.queued = `${JSON.stringify({ version: 1, runs: kept }, null, 2)}\\n`;\n if (!this.writing) {\n this.writing = this.drain().finally(() => {\n this.writing = undefined;\n });\n }\n return this.writing;\n }\n\n /** Waits for every queued write. */\n async flush(): Promise<void> {\n while (this.writing) await this.writing;\n }\n\n private async drain(): Promise<void> {\n while (this.queued !== undefined) {\n const content = this.queued;\n this.queued = undefined;\n try {\n await atomicWriteFile(this.path, content);\n } catch {\n // Disk full, permissions…: keep the runs in memory; the next save tries again.\n }\n }\n }\n}\n","/**\n * Git workspace for the pane orchestrator. Every task gets its own worktree on\n * `davecode/run-<runId>-<taskId>`; finished tasks are merged into `davecode/run-<runId>` inside\n * a separate integration worktree, so the user's working tree is only touched by `apply`.\n * Nothing is ever pushed, and branches survive `cleanup` so no agent work is lost.\n */\nimport { existsSync, realpathSync, rmSync } from 'node:fs';\nimport path from 'node:path';\nimport { assertSafeRef, Git, GitError } from '../autonomous/git';\nimport type { OrchestratorWorkspace, TaskWorkspace, WorkspaceResult } from './contract';\n\nexport interface GitWorkspaceOptions {\n /** Absolute project root (a git repository). */\n projectDir: string;\n /** Worktrees live under `<worktreesDir>/<runId>/<taskId>`, outside the project. */\n worktreesDir: string;\n /** Environment for git (default `process.env`). */\n env?: NodeJS.ProcessEnv;\n}\n\nconst SAFE_ID = /^[A-Za-z0-9_-]+$/;\nconst INTEGRATION_DIR = 'integration';\nconst BRAIN_DIR = '.davecode';\nconst FALLBACK_IDENTITY = ['-c', 'user.name=DaveCode', '-c', 'user.email=davecode@localhost'];\n\nfunction assertId(kind: string, value: string): string {\n if (!SAFE_ID.test(value)) {\n throw new GitError(`Invalid ${kind}: ${JSON.stringify(value)}`, [], null, '');\n }\n return value;\n}\n\nfunction lines(out: string): string[] {\n return out\n .split('\\n')\n .map((l) => l.replace(/\\r$/, ''))\n .filter((l) => l.trim().length > 0);\n}\n\n/** NUL-separated `--name-only -z` output. */\nfunction nulList(out: string): string[] {\n return out.split('\\0').filter((f) => f.length > 0);\n}\n\nfunction errMessage(err: unknown): string {\n const raw = err instanceof Error ? err.message : String(err);\n const text = raw.replace(/\\s+/g, ' ').trim();\n return text.length <= 300 ? text : `${text.slice(0, 299)}…`;\n}\n\n/** The canonical spelling of an existing path (macOS /private/var, Windows 8.3 names). */\nfunction realPath(p: string): string {\n try {\n return realpathSync.native(p);\n } catch {\n return path.resolve(p);\n }\n}\n\nfunction samePath(a: string, b: string): boolean {\n const na = realPath(a);\n const nb = realPath(b);\n return process.platform === 'win32' ? na.toLowerCase() === nb.toLowerCase() : na === nb;\n}\n\nfunction isInside(child: string, parent: string): boolean {\n const rel = path.relative(realPath(parent), realPath(child));\n return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));\n}\n\nexport function createGitWorkspace(options: GitWorkspaceOptions): OrchestratorWorkspace {\n const projectDir = path.resolve(options.projectDir);\n const worktreesDir = path.resolve(options.worktreesDir);\n const gitAt = (cwd: string) => new Git(cwd, { env: options.env });\n const repo = gitAt(projectDir);\n\n const runDir = (runId: string) => path.join(worktreesDir, assertId('run id', runId));\n const integrationPath = (runId: string) => path.join(runDir(runId), INTEGRATION_DIR);\n const integrationBranch = (runId: string) => `davecode/run-${assertId('run id', runId)}`;\n /** Commit each task worktree started from, so agent-made commits are still reported. */\n const taskBases = new Map<string, string>();\n\n // Worktree creation, merges and removal all touch shared repository state; run one at a time.\n let queue: Promise<unknown> = Promise.resolve();\n const serial = <T>(fn: () => Promise<T>): Promise<T> => {\n const next = queue.then(fn, fn);\n queue = next.catch(() => undefined);\n return next;\n };\n\n let hasIdentity = false;\n /** `-c user.*` overrides, only when git has no usable identity of its own. */\n async function identityArgs(g: Git): Promise<string[]> {\n if (hasIdentity) return [];\n try {\n // Strict, like `git commit`: fails when no name/email is configured or in the environment.\n await g.run(['var', 'GIT_AUTHOR_IDENT']);\n await g.run(['var', 'GIT_COMMITTER_IDENT']);\n hasIdentity = true;\n return [];\n } catch {\n return FALLBACK_IDENTITY;\n }\n }\n\n async function removeWorktree(target: string): Promise<void> {\n try {\n await repo.run(['worktree', 'remove', '--force', target]);\n } catch {\n // not a registered worktree, or already gone\n }\n if (existsSync(target)) {\n rmSync(target, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });\n }\n try {\n await repo.run(['worktree', 'prune']);\n } catch {\n // nothing to prune\n }\n }\n\n /** `git worktree add -B`: creates the branch, or resets it if a previous attempt left it. */\n async function addWorktree(target: string, branch: string, base: string): Promise<void> {\n const args = ['worktree', 'add', '-B', assertSafeRef(branch), target, assertSafeRef(base)];\n try {\n await repo.run(args);\n } catch {\n // A previous attempt left the directory or its registration behind.\n await removeWorktree(target);\n await repo.run(args);\n }\n }\n\n /** Merges `branch` into the checkout at `g`; on failure aborts and names the conflicts. */\n async function merge(g: Git, branch: string, message: string, noVerify: boolean) {\n const args = [...(await identityArgs(g)), 'merge', '--no-ff', '--no-edit', '-m', message];\n if (noVerify) args.push('--no-verify');\n args.push(assertSafeRef(branch));\n try {\n await g.run(args);\n return { ok: true } as const;\n } catch (err) {\n let conflicts: string[] = [];\n try {\n conflicts = nulList(await g.run(['diff', '--name-only', '-z', '--diff-filter=U']));\n } catch {\n // no merge state to inspect\n }\n await g.abortMerge();\n const reason =\n conflicts.length > 0\n ? `Conflicts in ${conflicts.join(', ')}`\n : `Merge failed: ${errMessage(err)}`;\n return { ok: false, reason } as const;\n }\n }\n\n return {\n async check() {\n if (!(await repo.isRepo())) {\n return {\n ok: false,\n reason:\n 'This folder is not a git repository. Run `git init` and commit once to orchestrate agents.',\n };\n }\n let commit: string;\n try {\n commit = (await repo.run(['rev-parse', '--verify', '--quiet', 'HEAD^{commit}'])).trim();\n } catch {\n return {\n ok: false,\n reason: 'This repository has no commits yet. Commit once to orchestrate agents.',\n };\n }\n let branch: string;\n try {\n branch = (await repo.run(['symbolic-ref', '--quiet', '--short', 'HEAD'])).trim();\n } catch {\n return {\n ok: false,\n reason: 'HEAD is detached. Check out a branch to orchestrate agents.',\n };\n }\n return { ok: true, branch, commit };\n },\n\n createIntegration(runId, baseCommit) {\n return serial(async () => {\n const branch = integrationBranch(runId);\n await addWorktree(integrationPath(runId), branch, baseCommit);\n return branch;\n });\n },\n\n createTask(runId, taskId, base) {\n return serial(async (): Promise<TaskWorkspace> => {\n assertId('task id', taskId);\n if (taskId === INTEGRATION_DIR) {\n throw new GitError(`Invalid task id: ${JSON.stringify(taskId)}`, [], null, '');\n }\n const branch = `${integrationBranch(runId)}-${taskId}`;\n const target = path.join(runDir(runId), taskId);\n const baseCommit = (\n await repo.run(['rev-parse', '--verify', '--quiet', `${assertSafeRef(base)}^{commit}`])\n ).trim();\n await addWorktree(target, branch, baseCommit);\n taskBases.set(path.resolve(target), baseCommit);\n return { path: target, branch };\n });\n },\n\n commitTask(workspace, message) {\n return serial(async () => {\n const g = gitAt(workspace.path);\n await g.run(['add', '-A']);\n // The project brain belongs to the user's checkout, never to a task commit.\n await g.run(['reset', '-q', '--', BRAIN_DIR]);\n const committed = await g.hasStagedChanges();\n if (committed) {\n await g.run([\n ...(await identityArgs(g)),\n 'commit',\n '--quiet',\n '--no-verify',\n '-m',\n message,\n ]);\n }\n // Diffing from the recorded base also reports commits the agent made itself. Without\n // one, only the commit just made is reported.\n const base = taskBases.get(path.resolve(workspace.path));\n if (base) return nulList(await g.run(['diff', '--name-only', '-z', base, 'HEAD']));\n if (!committed) return [];\n return nulList(await g.run(['diff', '--name-only', '-z', 'HEAD~1', 'HEAD']));\n });\n },\n\n mergeIntoIntegration(runId, branch, message) {\n return serial(async (): Promise<WorkspaceResult> => {\n const target = integrationPath(runId);\n if (!existsSync(target)) {\n return { ok: false, reason: `The integration worktree for run ${runId} is missing` };\n }\n // DaveCode-internal merge: the project's hooks need a full install the worktree lacks.\n return merge(gitAt(target), branch, message, true);\n });\n },\n\n apply(runId, baseBranch) {\n return serial(async (): Promise<WorkspaceResult> => {\n const branch = integrationBranch(runId);\n if (!(await repo.branchExists(branch))) {\n return { ok: false, reason: `Branch ${branch} does not exist` };\n }\n let current: string;\n try {\n current = (await repo.run(['symbolic-ref', '--quiet', '--short', 'HEAD'])).trim();\n } catch {\n current = 'a detached HEAD';\n }\n if (current !== baseBranch) {\n return {\n ok: false,\n reason: `Check out ${baseBranch} first: the run started there (you are on ${current}).`,\n };\n }\n const dirty = lines(\n await repo.run(['status', '--porcelain', '--untracked-files=no']),\n ).filter((l) => {\n const file = l.slice(3).replace(/^\"|\"$/g, '');\n return !(file === BRAIN_DIR || file.startsWith(`${BRAIN_DIR}/`));\n });\n if (dirty.length > 0) {\n return { ok: false, reason: 'Commit or stash your changes first.' };\n }\n return merge(repo, branch, `davecode: apply run ${runId}`, false);\n });\n },\n\n cleanup(runId) {\n return serial(async () => {\n let dir: string;\n try {\n dir = runDir(runId);\n } catch {\n return;\n }\n try {\n const listed = lines(await repo.run(['worktree', 'list', '--porcelain']))\n .filter((l) => l.startsWith('worktree '))\n .map((l) => l.slice('worktree '.length))\n .filter((p) => isInside(p, dir) && !samePath(p, projectDir));\n for (const target of listed) {\n try {\n await repo.run(['worktree', 'remove', '--force', target]);\n } catch {\n // already gone; prune below\n }\n taskBases.delete(path.resolve(target));\n }\n } catch {\n // not a repository any more: still remove the directory\n }\n try {\n rmSync(dir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });\n } catch {\n // best effort\n }\n // Prune after deleting the folder: a worktree git listed under another spelling of the\n // path (macOS /private/var, Windows 8.3 names) was not removed above and is stale now.\n try {\n await repo.run(['worktree', 'prune']);\n } catch {\n // ignore\n }\n });\n },\n };\n}\n"],"mappings":"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","names":["seconds","rm","join","randomBytes","z","mkdir","readFile","stat","dirname","path","existsSync","mkdirSync","resolve","rmSync","spawn","readFileSync","writeFileSync","spawnSync","readdir","writeFile","basename","createHash","createCipheriv","createDecipheriv","statSync","execFile","realpathSync","relative","lines","heading","taskText","sleep","fn","isPlainObject","message","tokens","SAFE_MODEL","abortError","textOf","toUsage","DEFAULT_MODELS","errorText","open","key","require","estimateTokens","newId","out","toProviderError","killTree","parseArgs","info","sessionSchema","str","plannedTaskSchema","clip","fileSchema","tail","SAFE_ID","BRAIN_DIR","FALLBACK_IDENTITY","realPath","samePath","isInside"]}
|