@dmrlzz/davecode 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ChatApp-YMHKIAAH.js → ChatApp-Z6PQIZ5J.js} +7 -6
- package/dist/{ChatApp-YMHKIAAH.js.map → ChatApp-Z6PQIZ5J.js.map} +1 -1
- package/dist/{account-5QFYCVYM.js → account-RTPS2V6O.js} +4 -3
- package/dist/{accounts-756BMMAL.js → accounts-IYQ4ZRL7.js} +6 -5
- package/dist/{budget-PGSNCVVK.js → budget-N2ZB66FF.js} +5 -4
- package/dist/{budget-PGSNCVVK.js.map → budget-N2ZB66FF.js.map} +1 -1
- package/dist/{chat-D3T4YG5D.js → chat-6TX6JX45.js} +9 -8
- package/dist/{chat-D3T4YG5D.js.map → chat-6TX6JX45.js.map} +1 -1
- package/dist/chunk-732GIHRQ.js +23 -0
- package/dist/chunk-732GIHRQ.js.map +1 -0
- package/dist/{chunk-6SHOBL2X.js → chunk-BJTXMET2.js} +2 -2
- package/dist/{chunk-JFWMLYV7.js → chunk-KUY3QHGS.js} +130 -89
- package/dist/chunk-KUY3QHGS.js.map +1 -0
- package/dist/{chunk-K5AA65RS.js → chunk-LEU46DGH.js} +2 -2
- package/dist/{chunk-HENE4DA6.js → chunk-QKY3OKVG.js} +71 -3
- package/dist/chunk-QKY3OKVG.js.map +1 -0
- package/dist/{chunk-6WUVR3R2.js → chunk-UEV5K3DH.js} +3 -3
- package/dist/{chunk-JSRPO2AR.js → chunk-UNK3EQD6.js} +4 -4
- package/dist/{chunk-IOATP7KH.js → chunk-WAARDGCZ.js} +5 -21
- package/dist/chunk-WAARDGCZ.js.map +1 -0
- package/dist/{chunk-ZNUNYYN6.js → chunk-YNAMNQLW.js} +3 -3
- package/dist/{config-TKGGYEN7.js → config-YQKY2AA4.js} +4 -3
- package/dist/{config-TKGGYEN7.js.map → config-YQKY2AA4.js.map} +1 -1
- package/dist/dashboard/assets/{Accounts-DciFUg4y.js → Accounts-DXiGsutB.js} +1 -1
- package/dist/dashboard/assets/{Callout-WgXHDPg0.js → Callout-1E8Wsl9W.js} +1 -1
- package/dist/dashboard/assets/{Goals-C6HL1PNE.js → Goals-kL4VAxw3.js} +1 -1
- package/dist/dashboard/assets/{Library-DwpBYTbK.js → Library-DZxBVUo_.js} +1 -1
- package/dist/dashboard/assets/{Panes-DxFSwhb7.js → Panes-C-TJekjs.js} +1 -1
- package/dist/dashboard/assets/{RoutesPage-Cyo0MNd7.js → RoutesPage-DWYm9tW8.js} +1 -1
- package/dist/dashboard/assets/{Runner-CIL7RxpN.js → Runner-CmHBjECR.js} +1 -1
- package/dist/dashboard/assets/{Settings-B_PEB585.js → Settings-BANphxva.js} +1 -1
- package/dist/dashboard/assets/{Tasks-DEfPSaE6.js → Tasks-cSx1PKyQ.js} +1 -1
- package/dist/dashboard/assets/{Traffic-Dcz-WhsP.js → Traffic-DEAuM6jq.js} +1 -1
- package/dist/dashboard/assets/{Workspace-9UCw9q7C.js → Workspace-BQFjc1jH.js} +1 -1
- package/dist/dashboard/assets/index-B8kld9xo.js +104 -0
- package/dist/dashboard/index.html +1 -1
- package/dist/{dist-F3NRJ5FK.js → dist-PIC255RX.js} +4 -2
- package/dist/{doctor-V4XXVVGK.js → doctor-PQC7JQPP.js} +4 -3
- package/dist/{doctor-V4XXVVGK.js.map → doctor-PQC7JQPP.js.map} +1 -1
- package/dist/{goal-RUHYPVPA.js → goal-STLEU7C7.js} +4 -3
- package/dist/{goal-RUHYPVPA.js.map → goal-STLEU7C7.js.map} +1 -1
- package/dist/index.js +31 -31
- package/dist/{init-54FKQZ2Z.js → init-NHU5LJSS.js} +4 -3
- package/dist/{init-54FKQZ2Z.js.map → init-NHU5LJSS.js.map} +1 -1
- package/dist/{run-4R25J2VN.js → run-7HWSHMRJ.js} +4 -3
- package/dist/{run-4R25J2VN.js.map → run-7HWSHMRJ.js.map} +1 -1
- package/dist/runtime.js +3 -2
- package/dist/{start-GRHW3TGE.js → start-WVAEAQWL.js} +4 -3
- package/dist/{start-GRHW3TGE.js.map → start-WVAEAQWL.js.map} +1 -1
- package/dist/{status-QR2HNPBK.js → status-ZRHPFLFT.js} +5 -4
- package/dist/{tasks-BHWDV4JS.js → tasks-JVWXUNXN.js} +5 -4
- package/dist/{tasks-BHWDV4JS.js.map → tasks-JVWXUNXN.js.map} +1 -1
- package/package.json +4 -4
- package/dist/chunk-HENE4DA6.js.map +0 -1
- package/dist/chunk-IOATP7KH.js.map +0 -1
- package/dist/chunk-JFWMLYV7.js.map +0 -1
- package/dist/dashboard/assets/index-CpztPbom.js +0 -104
- /package/dist/{account-5QFYCVYM.js.map → account-RTPS2V6O.js.map} +0 -0
- /package/dist/{accounts-756BMMAL.js.map → accounts-IYQ4ZRL7.js.map} +0 -0
- /package/dist/{chunk-6SHOBL2X.js.map → chunk-BJTXMET2.js.map} +0 -0
- /package/dist/{chunk-K5AA65RS.js.map → chunk-LEU46DGH.js.map} +0 -0
- /package/dist/{chunk-6WUVR3R2.js.map → chunk-UEV5K3DH.js.map} +0 -0
- /package/dist/{chunk-JSRPO2AR.js.map → chunk-UNK3EQD6.js.map} +0 -0
- /package/dist/{chunk-ZNUNYYN6.js.map → chunk-YNAMNQLW.js.map} +0 -0
- /package/dist/{dist-F3NRJ5FK.js.map → dist-PIC255RX.js.map} +0 -0
- /package/dist/{status-QR2HNPBK.js.map → status-ZRHPFLFT.js.map} +0 -0
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
document.documentElement.dataset.theme = storedTheme;
|
|
21
21
|
}
|
|
22
22
|
</script>
|
|
23
|
-
<script type="module" crossorigin src="./assets/index-
|
|
23
|
+
<script type="module" crossorigin src="./assets/index-B8kld9xo.js"></script>
|
|
24
24
|
<link rel="modulepreload" crossorigin href="./assets/cn-BwE4cei0.js">
|
|
25
25
|
<link rel="modulepreload" crossorigin href="./assets/Badge-DUGKlx3Z.js">
|
|
26
26
|
<link rel="stylesheet" crossorigin href="./assets/index-BEmBgsbP.css">
|
|
@@ -115,6 +115,7 @@ import {
|
|
|
115
115
|
configuredModels,
|
|
116
116
|
connectionMethod,
|
|
117
117
|
countTextTokens,
|
|
118
|
+
createAccountControl,
|
|
118
119
|
createEngine,
|
|
119
120
|
createExecutor,
|
|
120
121
|
createGoalService,
|
|
@@ -194,7 +195,7 @@ import {
|
|
|
194
195
|
validateTaskGraph,
|
|
195
196
|
withFileLock,
|
|
196
197
|
writeGlobalRouting
|
|
197
|
-
} from "./chunk-
|
|
198
|
+
} from "./chunk-QKY3OKVG.js";
|
|
198
199
|
export {
|
|
199
200
|
ACCOUNT_SERVICE,
|
|
200
201
|
API_CONFIG_KEYS,
|
|
@@ -312,6 +313,7 @@ export {
|
|
|
312
313
|
configuredModels,
|
|
313
314
|
connectionMethod,
|
|
314
315
|
countTextTokens,
|
|
316
|
+
createAccountControl,
|
|
315
317
|
createEngine,
|
|
316
318
|
createExecutor,
|
|
317
319
|
createGoalService,
|
|
@@ -392,4 +394,4 @@ export {
|
|
|
392
394
|
withFileLock,
|
|
393
395
|
writeGlobalRouting
|
|
394
396
|
};
|
|
395
|
-
//# sourceMappingURL=dist-
|
|
397
|
+
//# sourceMappingURL=dist-PIC255RX.js.map
|
|
@@ -10,14 +10,15 @@ import {
|
|
|
10
10
|
detectProjectRoot,
|
|
11
11
|
resolveDashboardDir,
|
|
12
12
|
which
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-KUY3QHGS.js";
|
|
14
14
|
import {
|
|
15
15
|
EXIT
|
|
16
16
|
} from "./chunk-7XVXEO7U.js";
|
|
17
|
+
import "./chunk-732GIHRQ.js";
|
|
17
18
|
import {
|
|
18
19
|
loadConfig,
|
|
19
20
|
openDatabase
|
|
20
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-QKY3OKVG.js";
|
|
21
22
|
import "./chunk-MC7RIPL7.js";
|
|
22
23
|
|
|
23
24
|
// src/commands/doctor.ts
|
|
@@ -276,4 +277,4 @@ export {
|
|
|
276
277
|
renderDoctor,
|
|
277
278
|
runDoctor
|
|
278
279
|
};
|
|
279
|
-
//# sourceMappingURL=doctor-
|
|
280
|
+
//# sourceMappingURL=doctor-PQC7JQPP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/doctor.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { mkdir, rm, writeFile } from 'node:fs/promises';\nimport { createServer } from 'node:net';\nimport { join } from 'node:path';\nimport { type DaveConfig, loadConfig, openDatabase } from '@davecode/core';\nimport { connectHost, GatewayClient } from '../client';\nimport { type CliContext, printJson } from '../context';\nimport { EXIT } from '../errors';\nimport { which } from '../lib/proc';\nimport { detectProjectRoot, resolveDashboardDir } from '../runtime';\nimport { padEnd } from '../ui/format';\n\nexport type CheckStatus = 'ok' | 'warn' | 'fail';\n\nexport interface CheckResult {\n id: string;\n label: string;\n status: CheckStatus;\n detail: string;\n fix?: string;\n}\n\n/** Everything doctor touches outside its own logic, injectable for tests. */\nexport interface DoctorProbes {\n nodeVersion: string;\n loadConfig(): DaveConfig;\n /** Open an in-memory database; resolves with a detail string. */\n loadSqlite(): Promise<string>;\n /** Throws when `dir` cannot be created or written. */\n checkWritable(dir: string): Promise<void>;\n exists(path: string): boolean;\n portInUse(host: string, port: number): Promise<boolean>;\n /** Version of the DaveCode gateway answering on `baseUrl`, if any. */\n gatewayVersion(baseUrl: string, token?: string): Promise<string | undefined>;\n which(command: string): string | undefined;\n /** True when `url` answers with any HTTP response within the timeout. */\n reachable(url: string): Promise<boolean>;\n dashboardDir(): string | undefined;\n}\n\nexport interface DoctorInput {\n home: string;\n env: NodeJS.ProcessEnv;\n}\n\nconst MIN_NODE: [number, number] = [22, 12];\n\nexport function nodeVersionOk(version: string): boolean {\n const [major = 0, minor = 0] = version.replace(/^v/, '').split('.').map(Number);\n return major > MIN_NODE[0] || (major === MIN_NODE[0] && minor >= MIN_NODE[1]);\n}\n\nexport async function runDoctor(input: DoctorInput, probes: DoctorProbes): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n const add = (r: CheckResult) => results.push(r);\n\n add(\n nodeVersionOk(probes.nodeVersion)\n ? { id: 'node', label: 'Node.js', status: 'ok', detail: probes.nodeVersion }\n : {\n id: 'node',\n label: 'Node.js',\n status: 'fail',\n detail: `${probes.nodeVersion} (needs ${MIN_NODE.join('.')}+)`,\n fix: 'Install Node.js 22.12 or newer: https://nodejs.org',\n },\n );\n\n let config: DaveConfig | undefined;\n try {\n config = probes.loadConfig();\n add({ id: 'config', label: 'Config', status: 'ok', detail: 'valid' });\n } catch (err) {\n add({\n id: 'config',\n label: 'Config',\n status: 'fail',\n detail: (err as Error).message.split('\\n').slice(0, 3).join(' '),\n fix: 'Fix the file named above; `davecode config path` lists every config location.',\n });\n }\n\n try {\n add({ id: 'sqlite', label: 'better-sqlite3', status: 'ok', detail: await probes.loadSqlite() });\n } catch (err) {\n add({\n id: 'sqlite',\n label: 'better-sqlite3',\n status: 'fail',\n detail: `cannot load: ${(err as Error).message.split('\\n')[0]}`,\n fix: 'Rebuild the native module: pnpm rebuild better-sqlite3 (needs a C++ toolchain if no prebuilt binary matches your Node version).',\n });\n }\n\n try {\n await probes.checkWritable(input.home);\n add({ id: 'home', label: 'Home directory', status: 'ok', detail: `${input.home} is writable` });\n } catch (err) {\n add({\n id: 'home',\n label: 'Home directory',\n status: 'fail',\n detail: `${input.home} is not writable (${(err as NodeJS.ErrnoException).code ?? (err as Error).message})`,\n fix: 'Fix the permissions or point DaveCode elsewhere with --home <dir> / DAVECODE_HOME.',\n });\n }\n\n const keyPath = join(input.home, 'master.key');\n if (input.env.DAVECODE_MASTER_KEY) {\n add({\n id: 'master-key',\n label: 'Master key',\n status: 'ok',\n detail: 'from DAVECODE_MASTER_KEY',\n });\n } else if (probes.exists(keyPath)) {\n add({ id: 'master-key', label: 'Master key', status: 'ok', detail: keyPath });\n } else {\n add({\n id: 'master-key',\n label: 'Master key',\n status: 'warn',\n detail: 'not created yet',\n fix: 'It is generated on first use (davecode start or accounts add). Back it up: without it stored secrets cannot be decrypted.',\n });\n }\n\n if (config) {\n const { host, port, authToken } = config.server;\n const baseUrl = `http://${connectHost(host)}:${port}`;\n if (!(await probes.portInUse(host, port))) {\n add({ id: 'port', label: 'Gateway port', status: 'ok', detail: `${host}:${port} is free` });\n } else {\n const version = await probes.gatewayVersion(baseUrl, authToken);\n add(\n version\n ? {\n id: 'port',\n label: 'Gateway port',\n status: 'ok',\n detail: `DaveCode ${version} is already running at ${baseUrl}`,\n }\n : {\n id: 'port',\n label: 'Gateway port',\n status: 'fail',\n detail: `${host}:${port} is used by another program`,\n fix: `Stop it, or use another port: davecode start --port ${port + 1} (or DAVECODE_PORT).`,\n },\n );\n }\n }\n\n const tools: Array<{ cmd: string; label: string; required: boolean; why: string; fix: string }> =\n [\n {\n cmd: 'git',\n label: 'git',\n required: true,\n why: 'needed by the autonomous runner (task branches and merges)',\n fix: 'Install git: https://git-scm.com/downloads',\n },\n {\n cmd: 'claude',\n label: 'Claude Code CLI',\n required: false,\n why: 'only for claude-cli accounts',\n fix: 'npm install -g @anthropic-ai/claude-code',\n },\n {\n cmd: 'codex',\n label: 'Codex CLI',\n required: false,\n why: 'only for codex-cli accounts',\n fix: 'npm install -g @openai/codex',\n },\n {\n cmd: 'gemini',\n label: 'Gemini CLI',\n required: false,\n why: 'only for gemini-cli accounts',\n fix: 'npm install -g @google/gemini-cli',\n },\n {\n cmd: 'gh',\n label: 'GitHub CLI',\n required: false,\n why: 'optional, for opening pull requests',\n fix: 'Install gh: https://cli.github.com',\n },\n ];\n for (const tool of tools) {\n const path = probes.which(tool.cmd);\n add(\n path\n ? { id: tool.cmd, label: tool.label, status: 'ok', detail: path }\n : {\n id: tool.cmd,\n label: tool.label,\n status: tool.required ? 'fail' : 'warn',\n detail: `not found on PATH (${tool.why})`,\n fix: tool.fix,\n },\n );\n }\n\n const dashboard = probes.dashboardDir();\n add(\n dashboard\n ? { id: 'dashboard', label: 'Dashboard build', status: 'ok', detail: dashboard }\n : {\n id: 'dashboard',\n label: 'Dashboard build',\n status: 'warn',\n detail: 'not built (the gateway still works without it)',\n fix: 'pnpm --filter @davecode/ui build',\n },\n );\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Real probes\n// ---------------------------------------------------------------------------\n\nfunction portInUse(host: string, port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = createServer();\n server.once('error', (err: NodeJS.ErrnoException) => {\n resolve(err.code === 'EADDRINUSE' || err.code === 'EACCES');\n });\n server.listen({ host, port, exclusive: true }, () => {\n server.close(() => resolve(false));\n });\n });\n}\n\nexport function defaultProbes(\n ctx: Pick<CliContext, 'home' | 'env'>,\n projectRoot?: string,\n): DoctorProbes {\n return {\n nodeVersion: process.version,\n loadConfig: () =>\n loadConfig({ home: ctx.home, env: ctx.env, ...(projectRoot ? { projectRoot } : {}) }),\n async loadSqlite() {\n const db = openDatabase(':memory:');\n try {\n const row = db.prepare('select sqlite_version() as v').get() as { v: string };\n return `loads (SQLite ${row.v})`;\n } finally {\n db.close();\n }\n },\n async checkWritable(dir) {\n await mkdir(dir, { recursive: true });\n const probe = join(dir, `.doctor-${process.pid}.tmp`);\n await writeFile(probe, 'ok');\n await rm(probe, { force: true });\n },\n exists: existsSync,\n portInUse,\n async gatewayVersion(baseUrl, token) {\n const client = new GatewayClient({ baseUrl, ...(token ? { token } : {}) });\n try {\n return (await client.health(800))?.version;\n } catch {\n return undefined;\n }\n },\n which: (cmd) => which(cmd, ctx.env),\n async reachable(url) {\n try {\n await fetch(url, { signal: AbortSignal.timeout(800) });\n return true;\n } catch {\n return false;\n }\n },\n dashboardDir: () => resolveDashboardDir(ctx.env),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Command\n// ---------------------------------------------------------------------------\n\nexport function renderDoctor(ctx: Pick<CliContext, 'theme'>, results: CheckResult[]): string[] {\n const { theme } = ctx;\n const lines = [theme.bold(theme.accent('DaveCode doctor')), ''];\n const width = Math.max(...results.map((r) => r.label.length)) + 2;\n for (const r of results) {\n const mark =\n r.status === 'ok'\n ? theme.ok(theme.glyph.ok)\n : r.status === 'warn'\n ? theme.warn(theme.glyph.warn)\n : theme.error(theme.glyph.fail);\n const detail = r.status === 'ok' ? theme.dim(r.detail) : r.detail;\n lines.push(` ${mark} ${padEnd(r.label, width)} ${detail}`);\n if (r.fix && r.status !== 'ok')\n lines.push(` ${' '.repeat(width)}${theme.dim(`fix: ${r.fix}`)}`);\n }\n const count = (s: CheckStatus) => results.filter((r) => r.status === s).length;\n const fails = count('fail');\n const warns = count('warn');\n lines.push('');\n lines.push(\n [\n theme.ok(`${count('ok')} ok`),\n warns ? theme.warn(`${warns} warning${warns === 1 ? '' : 's'}`) : `${warns} warnings`,\n fails ? theme.error(`${fails} failure${fails === 1 ? '' : 's'}`) : '0 failures',\n ].join(theme.dim(' · ')),\n );\n return lines;\n}\n\nexport async function doctorCommand(\n ctx: CliContext,\n probes?: Partial<DoctorProbes>,\n): Promise<number> {\n const projectRoot = await detectProjectRoot(ctx.cwd, ctx.home);\n const merged: DoctorProbes = { ...defaultProbes(ctx, projectRoot), ...probes };\n const results = await runDoctor({ home: ctx.home, env: ctx.env }, merged);\n const failed = results.some((r) => r.status === 'fail');\n if (ctx.json) {\n printJson(ctx, { ok: !failed, checks: results });\n } else {\n for (const line of renderDoctor(ctx, results)) ctx.out(line);\n }\n return failed ? EXIT.failure : EXIT.ok;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/commands/doctor.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { mkdir, rm, writeFile } from 'node:fs/promises';\nimport { createServer } from 'node:net';\nimport { join } from 'node:path';\nimport { type DaveConfig, loadConfig, openDatabase } from '@davecode/core';\nimport { connectHost, GatewayClient } from '../client';\nimport { type CliContext, printJson } from '../context';\nimport { EXIT } from '../errors';\nimport { which } from '../lib/proc';\nimport { detectProjectRoot, resolveDashboardDir } from '../runtime';\nimport { padEnd } from '../ui/format';\n\nexport type CheckStatus = 'ok' | 'warn' | 'fail';\n\nexport interface CheckResult {\n id: string;\n label: string;\n status: CheckStatus;\n detail: string;\n fix?: string;\n}\n\n/** Everything doctor touches outside its own logic, injectable for tests. */\nexport interface DoctorProbes {\n nodeVersion: string;\n loadConfig(): DaveConfig;\n /** Open an in-memory database; resolves with a detail string. */\n loadSqlite(): Promise<string>;\n /** Throws when `dir` cannot be created or written. */\n checkWritable(dir: string): Promise<void>;\n exists(path: string): boolean;\n portInUse(host: string, port: number): Promise<boolean>;\n /** Version of the DaveCode gateway answering on `baseUrl`, if any. */\n gatewayVersion(baseUrl: string, token?: string): Promise<string | undefined>;\n which(command: string): string | undefined;\n /** True when `url` answers with any HTTP response within the timeout. */\n reachable(url: string): Promise<boolean>;\n dashboardDir(): string | undefined;\n}\n\nexport interface DoctorInput {\n home: string;\n env: NodeJS.ProcessEnv;\n}\n\nconst MIN_NODE: [number, number] = [22, 12];\n\nexport function nodeVersionOk(version: string): boolean {\n const [major = 0, minor = 0] = version.replace(/^v/, '').split('.').map(Number);\n return major > MIN_NODE[0] || (major === MIN_NODE[0] && minor >= MIN_NODE[1]);\n}\n\nexport async function runDoctor(input: DoctorInput, probes: DoctorProbes): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n const add = (r: CheckResult) => results.push(r);\n\n add(\n nodeVersionOk(probes.nodeVersion)\n ? { id: 'node', label: 'Node.js', status: 'ok', detail: probes.nodeVersion }\n : {\n id: 'node',\n label: 'Node.js',\n status: 'fail',\n detail: `${probes.nodeVersion} (needs ${MIN_NODE.join('.')}+)`,\n fix: 'Install Node.js 22.12 or newer: https://nodejs.org',\n },\n );\n\n let config: DaveConfig | undefined;\n try {\n config = probes.loadConfig();\n add({ id: 'config', label: 'Config', status: 'ok', detail: 'valid' });\n } catch (err) {\n add({\n id: 'config',\n label: 'Config',\n status: 'fail',\n detail: (err as Error).message.split('\\n').slice(0, 3).join(' '),\n fix: 'Fix the file named above; `davecode config path` lists every config location.',\n });\n }\n\n try {\n add({ id: 'sqlite', label: 'better-sqlite3', status: 'ok', detail: await probes.loadSqlite() });\n } catch (err) {\n add({\n id: 'sqlite',\n label: 'better-sqlite3',\n status: 'fail',\n detail: `cannot load: ${(err as Error).message.split('\\n')[0]}`,\n fix: 'Rebuild the native module: pnpm rebuild better-sqlite3 (needs a C++ toolchain if no prebuilt binary matches your Node version).',\n });\n }\n\n try {\n await probes.checkWritable(input.home);\n add({ id: 'home', label: 'Home directory', status: 'ok', detail: `${input.home} is writable` });\n } catch (err) {\n add({\n id: 'home',\n label: 'Home directory',\n status: 'fail',\n detail: `${input.home} is not writable (${(err as NodeJS.ErrnoException).code ?? (err as Error).message})`,\n fix: 'Fix the permissions or point DaveCode elsewhere with --home <dir> / DAVECODE_HOME.',\n });\n }\n\n const keyPath = join(input.home, 'master.key');\n if (input.env.DAVECODE_MASTER_KEY) {\n add({\n id: 'master-key',\n label: 'Master key',\n status: 'ok',\n detail: 'from DAVECODE_MASTER_KEY',\n });\n } else if (probes.exists(keyPath)) {\n add({ id: 'master-key', label: 'Master key', status: 'ok', detail: keyPath });\n } else {\n add({\n id: 'master-key',\n label: 'Master key',\n status: 'warn',\n detail: 'not created yet',\n fix: 'It is generated on first use (davecode start or accounts add). Back it up: without it stored secrets cannot be decrypted.',\n });\n }\n\n if (config) {\n const { host, port, authToken } = config.server;\n const baseUrl = `http://${connectHost(host)}:${port}`;\n if (!(await probes.portInUse(host, port))) {\n add({ id: 'port', label: 'Gateway port', status: 'ok', detail: `${host}:${port} is free` });\n } else {\n const version = await probes.gatewayVersion(baseUrl, authToken);\n add(\n version\n ? {\n id: 'port',\n label: 'Gateway port',\n status: 'ok',\n detail: `DaveCode ${version} is already running at ${baseUrl}`,\n }\n : {\n id: 'port',\n label: 'Gateway port',\n status: 'fail',\n detail: `${host}:${port} is used by another program`,\n fix: `Stop it, or use another port: davecode start --port ${port + 1} (or DAVECODE_PORT).`,\n },\n );\n }\n }\n\n const tools: Array<{ cmd: string; label: string; required: boolean; why: string; fix: string }> =\n [\n {\n cmd: 'git',\n label: 'git',\n required: true,\n why: 'needed by the autonomous runner (task branches and merges)',\n fix: 'Install git: https://git-scm.com/downloads',\n },\n {\n cmd: 'claude',\n label: 'Claude Code CLI',\n required: false,\n why: 'only for claude-cli accounts',\n fix: 'npm install -g @anthropic-ai/claude-code',\n },\n {\n cmd: 'codex',\n label: 'Codex CLI',\n required: false,\n why: 'only for codex-cli accounts',\n fix: 'npm install -g @openai/codex',\n },\n {\n cmd: 'gemini',\n label: 'Gemini CLI',\n required: false,\n why: 'only for gemini-cli accounts',\n fix: 'npm install -g @google/gemini-cli',\n },\n {\n cmd: 'gh',\n label: 'GitHub CLI',\n required: false,\n why: 'optional, for opening pull requests',\n fix: 'Install gh: https://cli.github.com',\n },\n ];\n for (const tool of tools) {\n const path = probes.which(tool.cmd);\n add(\n path\n ? { id: tool.cmd, label: tool.label, status: 'ok', detail: path }\n : {\n id: tool.cmd,\n label: tool.label,\n status: tool.required ? 'fail' : 'warn',\n detail: `not found on PATH (${tool.why})`,\n fix: tool.fix,\n },\n );\n }\n\n const dashboard = probes.dashboardDir();\n add(\n dashboard\n ? { id: 'dashboard', label: 'Dashboard build', status: 'ok', detail: dashboard }\n : {\n id: 'dashboard',\n label: 'Dashboard build',\n status: 'warn',\n detail: 'not built (the gateway still works without it)',\n fix: 'pnpm --filter @davecode/ui build',\n },\n );\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Real probes\n// ---------------------------------------------------------------------------\n\nfunction portInUse(host: string, port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = createServer();\n server.once('error', (err: NodeJS.ErrnoException) => {\n resolve(err.code === 'EADDRINUSE' || err.code === 'EACCES');\n });\n server.listen({ host, port, exclusive: true }, () => {\n server.close(() => resolve(false));\n });\n });\n}\n\nexport function defaultProbes(\n ctx: Pick<CliContext, 'home' | 'env'>,\n projectRoot?: string,\n): DoctorProbes {\n return {\n nodeVersion: process.version,\n loadConfig: () =>\n loadConfig({ home: ctx.home, env: ctx.env, ...(projectRoot ? { projectRoot } : {}) }),\n async loadSqlite() {\n const db = openDatabase(':memory:');\n try {\n const row = db.prepare('select sqlite_version() as v').get() as { v: string };\n return `loads (SQLite ${row.v})`;\n } finally {\n db.close();\n }\n },\n async checkWritable(dir) {\n await mkdir(dir, { recursive: true });\n const probe = join(dir, `.doctor-${process.pid}.tmp`);\n await writeFile(probe, 'ok');\n await rm(probe, { force: true });\n },\n exists: existsSync,\n portInUse,\n async gatewayVersion(baseUrl, token) {\n const client = new GatewayClient({ baseUrl, ...(token ? { token } : {}) });\n try {\n return (await client.health(800))?.version;\n } catch {\n return undefined;\n }\n },\n which: (cmd) => which(cmd, ctx.env),\n async reachable(url) {\n try {\n await fetch(url, { signal: AbortSignal.timeout(800) });\n return true;\n } catch {\n return false;\n }\n },\n dashboardDir: () => resolveDashboardDir(ctx.env),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Command\n// ---------------------------------------------------------------------------\n\nexport function renderDoctor(ctx: Pick<CliContext, 'theme'>, results: CheckResult[]): string[] {\n const { theme } = ctx;\n const lines = [theme.bold(theme.accent('DaveCode doctor')), ''];\n const width = Math.max(...results.map((r) => r.label.length)) + 2;\n for (const r of results) {\n const mark =\n r.status === 'ok'\n ? theme.ok(theme.glyph.ok)\n : r.status === 'warn'\n ? theme.warn(theme.glyph.warn)\n : theme.error(theme.glyph.fail);\n const detail = r.status === 'ok' ? theme.dim(r.detail) : r.detail;\n lines.push(` ${mark} ${padEnd(r.label, width)} ${detail}`);\n if (r.fix && r.status !== 'ok')\n lines.push(` ${' '.repeat(width)}${theme.dim(`fix: ${r.fix}`)}`);\n }\n const count = (s: CheckStatus) => results.filter((r) => r.status === s).length;\n const fails = count('fail');\n const warns = count('warn');\n lines.push('');\n lines.push(\n [\n theme.ok(`${count('ok')} ok`),\n warns ? theme.warn(`${warns} warning${warns === 1 ? '' : 's'}`) : `${warns} warnings`,\n fails ? theme.error(`${fails} failure${fails === 1 ? '' : 's'}`) : '0 failures',\n ].join(theme.dim(' · ')),\n );\n return lines;\n}\n\nexport async function doctorCommand(\n ctx: CliContext,\n probes?: Partial<DoctorProbes>,\n): Promise<number> {\n const projectRoot = await detectProjectRoot(ctx.cwd, ctx.home);\n const merged: DoctorProbes = { ...defaultProbes(ctx, projectRoot), ...probes };\n const results = await runDoctor({ home: ctx.home, env: ctx.env }, merged);\n const failed = results.some((r) => r.status === 'fail');\n if (ctx.json) {\n printJson(ctx, { ok: !failed, checks: results });\n } else {\n for (const line of renderDoctor(ctx, results)) ctx.out(line);\n }\n return failed ? EXIT.failure : EXIT.ok;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -9,17 +9,18 @@ import {
|
|
|
9
9
|
detectProjectRoot,
|
|
10
10
|
findGateway,
|
|
11
11
|
wireProject
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KUY3QHGS.js";
|
|
13
13
|
import {
|
|
14
14
|
CliError,
|
|
15
15
|
EXIT
|
|
16
16
|
} from "./chunk-7XVXEO7U.js";
|
|
17
|
+
import "./chunk-732GIHRQ.js";
|
|
17
18
|
import {
|
|
18
19
|
GoalStore,
|
|
19
20
|
createEngine,
|
|
20
21
|
isTerminalGoal,
|
|
21
22
|
loadConfig
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-QKY3OKVG.js";
|
|
23
24
|
import "./chunk-MC7RIPL7.js";
|
|
24
25
|
|
|
25
26
|
// src/commands/goal.ts
|
|
@@ -299,4 +300,4 @@ export {
|
|
|
299
300
|
goalsList,
|
|
300
301
|
goalsShow
|
|
301
302
|
};
|
|
302
|
-
//# sourceMappingURL=goal-
|
|
303
|
+
//# sourceMappingURL=goal-STLEU7C7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/goal.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport {\n createEngine,\n type DaveEvent,\n type Engine,\n type Goal,\n GoalStore,\n isTerminalGoal,\n loadConfig,\n} from '@davecode/core';\nimport { findGateway, type GatewayClient, GatewayError } from '../client';\nimport { type CliContext, printJson } from '../context';\nimport { CliError, EXIT } from '../errors';\nimport { detectProjectRoot, wireProject } from '../runtime';\nimport { formatDuration } from '../ui/format';\nimport type { Theme } from '../ui/theme';\n\nexport interface GoalOptions {\n maxRounds?: number;\n maxTasks?: number;\n maxTokens?: number;\n dryRun?: boolean;\n project?: string;\n}\n\n/** Goal control used by the command: in-process `GoalService` or the gateway's `/api/goals`. */\ninterface GoalBackend {\n start(input: GoalStartBody): Promise<Goal>;\n cancel(id: string): Promise<Goal>;\n /** Resolves with the finished goal. */\n wait(id: string): Promise<Goal>;\n}\n\ninterface GoalStartBody {\n objective: string;\n maxRounds?: number;\n maxTasks?: number;\n maxTokens?: number;\n dryRun?: boolean;\n}\n\n/** Test seams. */\nexport interface GoalDeps {\n engine?: Engine;\n /** Resolves when the user asks to stop (default: SIGINT/SIGTERM). */\n interrupt?: () => Promise<void>;\n noGateway?: boolean;\n}\n\nasync function projectRoot(ctx: CliContext, project?: string): Promise<string> {\n const root = project ? resolve(ctx.cwd, project) : await detectProjectRoot(ctx.cwd, ctx.home);\n if (!root || !existsSync(root)) {\n throw new CliError('Not inside a project', {\n hint: 'Run goal mode inside a repository with a project brain (`git init` and `davecode init`).',\n });\n }\n return root;\n}\n\nfunction interruptSignal(deps: GoalDeps): { promise: Promise<void>; dispose(): void } {\n if (deps.interrupt) return { promise: deps.interrupt(), dispose: () => {} };\n let dispose = () => {};\n const promise = new Promise<void>((done) => {\n const handler = () => {\n dispose();\n done();\n };\n dispose = () => {\n process.off('SIGINT', handler);\n process.off('SIGTERM', handler);\n };\n process.on('SIGINT', handler);\n process.on('SIGTERM', handler);\n });\n return { promise, dispose };\n}\n\nfunction explainGoalError(err: unknown): unknown {\n const code =\n err instanceof GatewayError ? err.code : (err as { code?: unknown } | undefined)?.code;\n const message = err instanceof Error ? err.message : String(err);\n if (code === 'busy') {\n return new CliError(message, {\n hint: 'Wait for the runner or the other goal to finish, or stop it from the dashboard.',\n });\n }\n if (code === 'goals_unavailable') {\n return new CliError('The running gateway has no project to run goals in', {\n hint: 'Restart `davecode start` inside this repository, or stop it so `davecode goal` runs in-process.',\n });\n }\n return err;\n}\n\n// ---------------------------------------------------------------------------\n// Printing\n// ---------------------------------------------------------------------------\n\nconst STATUS_GLYPH: Record<Goal['tasks'][number]['status'], (t: Theme) => string> = {\n SUCCESS: (t) => t.ok(t.glyph.success),\n FAILED: (t) => t.error(t.glyph.failed),\n IN_PROGRESS: (t) => t.accent(t.glyph.running),\n PENDING: (t) => t.dim(t.glyph.pending),\n};\n\nfunction printEvent(ctx: CliContext, goalId: string, event: DaveEvent): void {\n if (event.type !== 'goal.log' || event.goalId !== goalId || event.level === 'debug') return;\n const theme = ctx.errTheme;\n const time = new Date(event.ts).toTimeString().slice(0, 8);\n const who = event.role ? theme.accent(`[${event.role}]`) : theme.dim('[goal]');\n const message =\n event.level === 'error'\n ? theme.error(event.message)\n : event.level === 'warn'\n ? theme.warn(event.message)\n : event.message;\n ctx.err(`${theme.dim(time)} ${who} ${message}`);\n}\n\nexport function describeGoal(theme: Theme, goal: Goal): string[] {\n const lines: string[] = [];\n const colour =\n goal.status === 'succeeded' || goal.status === 'planned'\n ? theme.ok\n : goal.status === 'cancelled' || goal.status === 'budget_exhausted'\n ? theme.warn\n : goal.status === 'failed'\n ? theme.error\n : theme.accent;\n lines.push(\n `${theme.bold(goal.id)} ${colour(goal.status)} ${theme.dim(`round ${goal.round}/${goal.limits.maxRounds}`)}`,\n );\n lines.push(` ${goal.objective}`);\n lines.push(\n theme.dim(\n ` tokens ${goal.limits.tokensUsed.toLocaleString('en-US')} / ${goal.limits.maxTokens.toLocaleString('en-US')} · tasks ${goal.tasks.length} / ${goal.limits.maxTasks}`,\n ),\n );\n if (goal.tasks.length > 0) lines.push('');\n for (const task of goal.tasks) {\n const glyph = STATUS_GLYPH[task.status](theme);\n lines.push(\n `${glyph} ${theme.bold(task.id)} ${theme.dim(`${task.role}·${task.kind}`)} ${task.title}`,\n );\n if (task.artifact) lines.push(theme.dim(` ${task.artifact}`));\n else if (task.status === 'FAILED' && task.notes) {\n lines.push(theme.dim(` ${task.notes.split('\\n')[0]?.slice(0, 160) ?? ''}`));\n }\n }\n if (goal.summary) lines.push('', goal.summary.trim());\n if (goal.lastError) lines.push('', theme.error(goal.lastError));\n return lines;\n}\n\nexport function goalExitCode(goal: Goal): number {\n if (goal.status === 'succeeded' || goal.status === 'planned') return EXIT.ok;\n if (goal.status === 'cancelled') return 130;\n return EXIT.failure;\n}\n\n// ---------------------------------------------------------------------------\n// Backends\n// ---------------------------------------------------------------------------\n\nfunction gatewayBackend(\n client: GatewayClient,\n onEvent: (e: DaveEvent) => void,\n): {\n backend: GoalBackend;\n close(): Promise<void>;\n} {\n const controller = new AbortController();\n const finished = new Map<string, (goal: Goal) => void>();\n const pump = (async () => {\n try {\n for await (const event of client.events(controller.signal)) {\n onEvent(event);\n if (event.type === 'goal.updated' && isTerminalGoal(event.goal)) {\n finished.get(event.goal.id)?.(event.goal);\n }\n }\n } catch {\n // aborted or disconnected\n }\n })();\n const backend: GoalBackend = {\n start: async (input) => (await client.post<{ goal: Goal }>('/api/goals', input)).goal,\n cancel: async (id) =>\n (\n await client.post<{ goal: Goal }>(`/api/goals/${id}/cancel`, undefined, {\n timeoutMs: 10 * 60_000,\n })\n ).goal,\n wait: (id) =>\n new Promise<Goal>((resolveGoal) => {\n finished.set(id, resolveGoal);\n // The goal may have finished before the listener was registered.\n void client\n .get<{ goal: Goal }>(`/api/goals/${id}`)\n .then(({ goal }) => {\n if (isTerminalGoal(goal)) resolveGoal(goal);\n })\n .catch(() => undefined);\n }),\n };\n return {\n backend,\n close: async () => {\n controller.abort();\n await pump;\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Commands\n// ---------------------------------------------------------------------------\n\n/** `davecode goal \"<objective>\"`: plan and run a goal with the agent team, following its log. */\nexport async function goalCommand(\n ctx: CliContext,\n words: string[],\n opts: GoalOptions,\n deps: GoalDeps = {},\n): Promise<number> {\n const objective = words.join(' ').trim();\n if (!objective)\n throw new CliError('Describe the objective', {\n hint: 'davecode goal \"Launch a landing page for my app\"',\n });\n const root = await projectRoot(ctx, opts.project);\n const input: GoalStartBody = {\n objective,\n ...(opts.maxRounds !== undefined ? { maxRounds: opts.maxRounds } : {}),\n ...(opts.maxTasks !== undefined ? { maxTasks: opts.maxTasks } : {}),\n ...(opts.maxTokens !== undefined ? { maxTokens: opts.maxTokens } : {}),\n ...(opts.dryRun ? { dryRun: true } : {}),\n };\n\n const config =\n deps.engine?.config ?? loadConfig({ home: ctx.home, env: ctx.env, projectRoot: root });\n const gateway = deps.noGateway ? undefined : await findGateway(config).catch(() => undefined);\n let goalId: string | undefined;\n const onEvent = (event: DaveEvent) => {\n if (goalId) printEvent(ctx, goalId, event);\n };\n\n let engine: Engine | undefined;\n let backend: GoalBackend;\n let close: () => Promise<void>;\n if (gateway) {\n const remote = gatewayBackend(gateway.client, onEvent);\n backend = remote.backend;\n close = remote.close;\n if (!ctx.json) ctx.err(ctx.errTheme.dim(`Using the gateway at ${gateway.client.baseUrl}`));\n } else {\n engine = deps.engine ?? createEngine({ home: ctx.home, env: ctx.env, projectRoot: root });\n const { goals } = wireProject(engine, root, { env: ctx.env });\n const unsubscribe = engine.events.subscribe(onEvent);\n backend = {\n start: (body) => goals.start(body),\n cancel: (id) => goals.cancel(id),\n wait: async (id) => {\n const goal = await goals.wait(id);\n if (!goal) throw new CliError(`Goal ${id} disappeared`);\n return goal;\n },\n };\n const owned = !deps.engine;\n const used = engine;\n close = async () => {\n unsubscribe();\n if (owned) used.close();\n };\n }\n\n const interrupt = interruptSignal(deps);\n const started = Date.now();\n try {\n let goal: Goal;\n try {\n goal = await backend.start(input);\n } catch (err) {\n throw explainGoalError(err);\n }\n goalId = goal.id;\n if (!ctx.json) {\n ctx.err(\n ctx.errTheme.dim(\n `Goal ${goal.id} started${input.dryRun ? ' (dry run: plan only)' : ''}. Ctrl+C cancels.`,\n ),\n );\n }\n let cancelling = false;\n void interrupt.promise.then(() => {\n cancelling = true;\n if (!ctx.json) ctx.err(ctx.errTheme.dim('Cancelling…'));\n void backend.cancel(goal.id).catch(() => undefined);\n });\n goal = await backend.wait(goal.id);\n if (ctx.json) printJson(ctx, { goal, cancelled: cancelling });\n else {\n ctx.out();\n for (const line of describeGoal(ctx.theme, goal)) ctx.out(line);\n ctx.out(ctx.theme.dim(` took ${formatDuration((Date.now() - started) / 1000)}`));\n if (goal.tasks.some((t) => t.artifact)) {\n ctx.out(ctx.theme.dim(` artifacts in ${root}`));\n }\n }\n return goalExitCode(goal);\n } finally {\n interrupt.dispose();\n await close();\n }\n}\n\n/** `davecode goals`: goals of this repository, newest first (read from `.davecode/goals`). */\nexport async function goalsList(ctx: CliContext, opts: { project?: string }): Promise<number> {\n const root = await projectRoot(ctx, opts.project);\n const goals = await new GoalStore(root).list();\n if (ctx.json) {\n printJson(ctx, { goals });\n return EXIT.ok;\n }\n if (goals.length === 0) {\n ctx.out(ctx.theme.dim('No goals yet. Start one with `davecode goal \"<objective>\"`.'));\n return EXIT.ok;\n }\n for (const goal of goals) {\n const done = goal.tasks.filter((t) => t.status === 'SUCCESS').length;\n ctx.out(\n `${ctx.theme.bold(goal.id)} ${goal.status.padEnd(16)} ${ctx.theme.dim(`${done}/${goal.tasks.length} tasks · ${goal.createdAt.slice(0, 16).replace('T', ' ')}`)} ${goal.objective.slice(0, 80)}`,\n );\n }\n return EXIT.ok;\n}\n\n/** `davecode goals show <id>`. */\nexport async function goalsShow(\n ctx: CliContext,\n id: string,\n opts: { project?: string },\n): Promise<number> {\n const root = await projectRoot(ctx, opts.project);\n const goal = await new GoalStore(root).load(id);\n if (!goal)\n throw new CliError(`Unknown goal \"${id}\"`, { hint: 'See `davecode goals` for the ids.' });\n if (ctx.json) printJson(ctx, { goal });\n else for (const line of describeGoal(ctx.theme, goal)) ctx.out(line);\n return EXIT.ok;\n}\n\n/** `davecode goals cancel <id>`: through the gateway when one runs it, else marks it cancelled. */\nexport async function goalsCancel(\n ctx: CliContext,\n id: string,\n opts: { project?: string },\n deps: GoalDeps = {},\n): Promise<number> {\n const root = await projectRoot(ctx, opts.project);\n const config =\n deps.engine?.config ?? loadConfig({ home: ctx.home, env: ctx.env, projectRoot: root });\n const gateway = deps.noGateway ? undefined : await findGateway(config).catch(() => undefined);\n let goal: Goal;\n if (gateway) {\n goal = (\n await gateway.client.post<{ goal: Goal }>(`/api/goals/${id}/cancel`, undefined, {\n timeoutMs: 10 * 60_000,\n })\n ).goal;\n } else {\n const store = new GoalStore(root);\n const stored = await store.load(id);\n if (!stored)\n throw new CliError(`Unknown goal \"${id}\"`, { hint: 'See `davecode goals` for the ids.' });\n goal = stored;\n if (!isTerminalGoal(goal)) {\n const stamp = new Date().toISOString();\n goal.status = 'cancelled';\n goal.updatedAt = stamp;\n goal.finishedAt = stamp;\n delete goal.activeTaskId;\n await store.save(goal);\n }\n }\n if (ctx.json) printJson(ctx, { goal });\n else ctx.out(`${ctx.theme.bold(goal.id)} ${goal.status}`);\n return EXIT.ok;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/commands/goal.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport {\n createEngine,\n type DaveEvent,\n type Engine,\n type Goal,\n GoalStore,\n isTerminalGoal,\n loadConfig,\n} from '@davecode/core';\nimport { findGateway, type GatewayClient, GatewayError } from '../client';\nimport { type CliContext, printJson } from '../context';\nimport { CliError, EXIT } from '../errors';\nimport { detectProjectRoot, wireProject } from '../runtime';\nimport { formatDuration } from '../ui/format';\nimport type { Theme } from '../ui/theme';\n\nexport interface GoalOptions {\n maxRounds?: number;\n maxTasks?: number;\n maxTokens?: number;\n dryRun?: boolean;\n project?: string;\n}\n\n/** Goal control used by the command: in-process `GoalService` or the gateway's `/api/goals`. */\ninterface GoalBackend {\n start(input: GoalStartBody): Promise<Goal>;\n cancel(id: string): Promise<Goal>;\n /** Resolves with the finished goal. */\n wait(id: string): Promise<Goal>;\n}\n\ninterface GoalStartBody {\n objective: string;\n maxRounds?: number;\n maxTasks?: number;\n maxTokens?: number;\n dryRun?: boolean;\n}\n\n/** Test seams. */\nexport interface GoalDeps {\n engine?: Engine;\n /** Resolves when the user asks to stop (default: SIGINT/SIGTERM). */\n interrupt?: () => Promise<void>;\n noGateway?: boolean;\n}\n\nasync function projectRoot(ctx: CliContext, project?: string): Promise<string> {\n const root = project ? resolve(ctx.cwd, project) : await detectProjectRoot(ctx.cwd, ctx.home);\n if (!root || !existsSync(root)) {\n throw new CliError('Not inside a project', {\n hint: 'Run goal mode inside a repository with a project brain (`git init` and `davecode init`).',\n });\n }\n return root;\n}\n\nfunction interruptSignal(deps: GoalDeps): { promise: Promise<void>; dispose(): void } {\n if (deps.interrupt) return { promise: deps.interrupt(), dispose: () => {} };\n let dispose = () => {};\n const promise = new Promise<void>((done) => {\n const handler = () => {\n dispose();\n done();\n };\n dispose = () => {\n process.off('SIGINT', handler);\n process.off('SIGTERM', handler);\n };\n process.on('SIGINT', handler);\n process.on('SIGTERM', handler);\n });\n return { promise, dispose };\n}\n\nfunction explainGoalError(err: unknown): unknown {\n const code =\n err instanceof GatewayError ? err.code : (err as { code?: unknown } | undefined)?.code;\n const message = err instanceof Error ? err.message : String(err);\n if (code === 'busy') {\n return new CliError(message, {\n hint: 'Wait for the runner or the other goal to finish, or stop it from the dashboard.',\n });\n }\n if (code === 'goals_unavailable') {\n return new CliError('The running gateway has no project to run goals in', {\n hint: 'Restart `davecode start` inside this repository, or stop it so `davecode goal` runs in-process.',\n });\n }\n return err;\n}\n\n// ---------------------------------------------------------------------------\n// Printing\n// ---------------------------------------------------------------------------\n\nconst STATUS_GLYPH: Record<Goal['tasks'][number]['status'], (t: Theme) => string> = {\n SUCCESS: (t) => t.ok(t.glyph.success),\n FAILED: (t) => t.error(t.glyph.failed),\n IN_PROGRESS: (t) => t.accent(t.glyph.running),\n PENDING: (t) => t.dim(t.glyph.pending),\n};\n\nfunction printEvent(ctx: CliContext, goalId: string, event: DaveEvent): void {\n if (event.type !== 'goal.log' || event.goalId !== goalId || event.level === 'debug') return;\n const theme = ctx.errTheme;\n const time = new Date(event.ts).toTimeString().slice(0, 8);\n const who = event.role ? theme.accent(`[${event.role}]`) : theme.dim('[goal]');\n const message =\n event.level === 'error'\n ? theme.error(event.message)\n : event.level === 'warn'\n ? theme.warn(event.message)\n : event.message;\n ctx.err(`${theme.dim(time)} ${who} ${message}`);\n}\n\nexport function describeGoal(theme: Theme, goal: Goal): string[] {\n const lines: string[] = [];\n const colour =\n goal.status === 'succeeded' || goal.status === 'planned'\n ? theme.ok\n : goal.status === 'cancelled' || goal.status === 'budget_exhausted'\n ? theme.warn\n : goal.status === 'failed'\n ? theme.error\n : theme.accent;\n lines.push(\n `${theme.bold(goal.id)} ${colour(goal.status)} ${theme.dim(`round ${goal.round}/${goal.limits.maxRounds}`)}`,\n );\n lines.push(` ${goal.objective}`);\n lines.push(\n theme.dim(\n ` tokens ${goal.limits.tokensUsed.toLocaleString('en-US')} / ${goal.limits.maxTokens.toLocaleString('en-US')} · tasks ${goal.tasks.length} / ${goal.limits.maxTasks}`,\n ),\n );\n if (goal.tasks.length > 0) lines.push('');\n for (const task of goal.tasks) {\n const glyph = STATUS_GLYPH[task.status](theme);\n lines.push(\n `${glyph} ${theme.bold(task.id)} ${theme.dim(`${task.role}·${task.kind}`)} ${task.title}`,\n );\n if (task.artifact) lines.push(theme.dim(` ${task.artifact}`));\n else if (task.status === 'FAILED' && task.notes) {\n lines.push(theme.dim(` ${task.notes.split('\\n')[0]?.slice(0, 160) ?? ''}`));\n }\n }\n if (goal.summary) lines.push('', goal.summary.trim());\n if (goal.lastError) lines.push('', theme.error(goal.lastError));\n return lines;\n}\n\nexport function goalExitCode(goal: Goal): number {\n if (goal.status === 'succeeded' || goal.status === 'planned') return EXIT.ok;\n if (goal.status === 'cancelled') return 130;\n return EXIT.failure;\n}\n\n// ---------------------------------------------------------------------------\n// Backends\n// ---------------------------------------------------------------------------\n\nfunction gatewayBackend(\n client: GatewayClient,\n onEvent: (e: DaveEvent) => void,\n): {\n backend: GoalBackend;\n close(): Promise<void>;\n} {\n const controller = new AbortController();\n const finished = new Map<string, (goal: Goal) => void>();\n const pump = (async () => {\n try {\n for await (const event of client.events(controller.signal)) {\n onEvent(event);\n if (event.type === 'goal.updated' && isTerminalGoal(event.goal)) {\n finished.get(event.goal.id)?.(event.goal);\n }\n }\n } catch {\n // aborted or disconnected\n }\n })();\n const backend: GoalBackend = {\n start: async (input) => (await client.post<{ goal: Goal }>('/api/goals', input)).goal,\n cancel: async (id) =>\n (\n await client.post<{ goal: Goal }>(`/api/goals/${id}/cancel`, undefined, {\n timeoutMs: 10 * 60_000,\n })\n ).goal,\n wait: (id) =>\n new Promise<Goal>((resolveGoal) => {\n finished.set(id, resolveGoal);\n // The goal may have finished before the listener was registered.\n void client\n .get<{ goal: Goal }>(`/api/goals/${id}`)\n .then(({ goal }) => {\n if (isTerminalGoal(goal)) resolveGoal(goal);\n })\n .catch(() => undefined);\n }),\n };\n return {\n backend,\n close: async () => {\n controller.abort();\n await pump;\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Commands\n// ---------------------------------------------------------------------------\n\n/** `davecode goal \"<objective>\"`: plan and run a goal with the agent team, following its log. */\nexport async function goalCommand(\n ctx: CliContext,\n words: string[],\n opts: GoalOptions,\n deps: GoalDeps = {},\n): Promise<number> {\n const objective = words.join(' ').trim();\n if (!objective)\n throw new CliError('Describe the objective', {\n hint: 'davecode goal \"Launch a landing page for my app\"',\n });\n const root = await projectRoot(ctx, opts.project);\n const input: GoalStartBody = {\n objective,\n ...(opts.maxRounds !== undefined ? { maxRounds: opts.maxRounds } : {}),\n ...(opts.maxTasks !== undefined ? { maxTasks: opts.maxTasks } : {}),\n ...(opts.maxTokens !== undefined ? { maxTokens: opts.maxTokens } : {}),\n ...(opts.dryRun ? { dryRun: true } : {}),\n };\n\n const config =\n deps.engine?.config ?? loadConfig({ home: ctx.home, env: ctx.env, projectRoot: root });\n const gateway = deps.noGateway ? undefined : await findGateway(config).catch(() => undefined);\n let goalId: string | undefined;\n const onEvent = (event: DaveEvent) => {\n if (goalId) printEvent(ctx, goalId, event);\n };\n\n let engine: Engine | undefined;\n let backend: GoalBackend;\n let close: () => Promise<void>;\n if (gateway) {\n const remote = gatewayBackend(gateway.client, onEvent);\n backend = remote.backend;\n close = remote.close;\n if (!ctx.json) ctx.err(ctx.errTheme.dim(`Using the gateway at ${gateway.client.baseUrl}`));\n } else {\n engine = deps.engine ?? createEngine({ home: ctx.home, env: ctx.env, projectRoot: root });\n const { goals } = wireProject(engine, root, { env: ctx.env });\n const unsubscribe = engine.events.subscribe(onEvent);\n backend = {\n start: (body) => goals.start(body),\n cancel: (id) => goals.cancel(id),\n wait: async (id) => {\n const goal = await goals.wait(id);\n if (!goal) throw new CliError(`Goal ${id} disappeared`);\n return goal;\n },\n };\n const owned = !deps.engine;\n const used = engine;\n close = async () => {\n unsubscribe();\n if (owned) used.close();\n };\n }\n\n const interrupt = interruptSignal(deps);\n const started = Date.now();\n try {\n let goal: Goal;\n try {\n goal = await backend.start(input);\n } catch (err) {\n throw explainGoalError(err);\n }\n goalId = goal.id;\n if (!ctx.json) {\n ctx.err(\n ctx.errTheme.dim(\n `Goal ${goal.id} started${input.dryRun ? ' (dry run: plan only)' : ''}. Ctrl+C cancels.`,\n ),\n );\n }\n let cancelling = false;\n void interrupt.promise.then(() => {\n cancelling = true;\n if (!ctx.json) ctx.err(ctx.errTheme.dim('Cancelling…'));\n void backend.cancel(goal.id).catch(() => undefined);\n });\n goal = await backend.wait(goal.id);\n if (ctx.json) printJson(ctx, { goal, cancelled: cancelling });\n else {\n ctx.out();\n for (const line of describeGoal(ctx.theme, goal)) ctx.out(line);\n ctx.out(ctx.theme.dim(` took ${formatDuration((Date.now() - started) / 1000)}`));\n if (goal.tasks.some((t) => t.artifact)) {\n ctx.out(ctx.theme.dim(` artifacts in ${root}`));\n }\n }\n return goalExitCode(goal);\n } finally {\n interrupt.dispose();\n await close();\n }\n}\n\n/** `davecode goals`: goals of this repository, newest first (read from `.davecode/goals`). */\nexport async function goalsList(ctx: CliContext, opts: { project?: string }): Promise<number> {\n const root = await projectRoot(ctx, opts.project);\n const goals = await new GoalStore(root).list();\n if (ctx.json) {\n printJson(ctx, { goals });\n return EXIT.ok;\n }\n if (goals.length === 0) {\n ctx.out(ctx.theme.dim('No goals yet. Start one with `davecode goal \"<objective>\"`.'));\n return EXIT.ok;\n }\n for (const goal of goals) {\n const done = goal.tasks.filter((t) => t.status === 'SUCCESS').length;\n ctx.out(\n `${ctx.theme.bold(goal.id)} ${goal.status.padEnd(16)} ${ctx.theme.dim(`${done}/${goal.tasks.length} tasks · ${goal.createdAt.slice(0, 16).replace('T', ' ')}`)} ${goal.objective.slice(0, 80)}`,\n );\n }\n return EXIT.ok;\n}\n\n/** `davecode goals show <id>`. */\nexport async function goalsShow(\n ctx: CliContext,\n id: string,\n opts: { project?: string },\n): Promise<number> {\n const root = await projectRoot(ctx, opts.project);\n const goal = await new GoalStore(root).load(id);\n if (!goal)\n throw new CliError(`Unknown goal \"${id}\"`, { hint: 'See `davecode goals` for the ids.' });\n if (ctx.json) printJson(ctx, { goal });\n else for (const line of describeGoal(ctx.theme, goal)) ctx.out(line);\n return EXIT.ok;\n}\n\n/** `davecode goals cancel <id>`: through the gateway when one runs it, else marks it cancelled. */\nexport async function goalsCancel(\n ctx: CliContext,\n id: string,\n opts: { project?: string },\n deps: GoalDeps = {},\n): Promise<number> {\n const root = await projectRoot(ctx, opts.project);\n const config =\n deps.engine?.config ?? loadConfig({ home: ctx.home, env: ctx.env, projectRoot: root });\n const gateway = deps.noGateway ? undefined : await findGateway(config).catch(() => undefined);\n let goal: Goal;\n if (gateway) {\n goal = (\n await gateway.client.post<{ goal: Goal }>(`/api/goals/${id}/cancel`, undefined, {\n timeoutMs: 10 * 60_000,\n })\n ).goal;\n } else {\n const store = new GoalStore(root);\n const stored = await store.load(id);\n if (!stored)\n throw new CliError(`Unknown goal \"${id}\"`, { hint: 'See `davecode goals` for the ids.' });\n goal = stored;\n if (!isTerminalGoal(goal)) {\n const stamp = new Date().toISOString();\n goal.status = 'cancelled';\n goal.updatedAt = stamp;\n goal.finishedAt = stamp;\n delete goal.activeTaskId;\n await store.save(goal);\n }\n }\n if (ctx.json) printJson(ctx, { goal });\n else ctx.out(`${ctx.theme.bold(goal.id)} ${goal.status}`);\n return EXIT.ok;\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -36,12 +36,12 @@ Docs: https://github.com/DMRLZZ/DaveCode#readme`
|
|
|
36
36
|
run(async (ctx) => {
|
|
37
37
|
const globals = program.opts();
|
|
38
38
|
if (globals.version) {
|
|
39
|
-
const { VERSION } = await import("./dist-
|
|
39
|
+
const { VERSION } = await import("./dist-PIC255RX.js");
|
|
40
40
|
ctx.out(`davecode ${VERSION}`);
|
|
41
41
|
return EXIT.ok;
|
|
42
42
|
}
|
|
43
43
|
if (ctx.interactive) {
|
|
44
|
-
const { chatCommand } = await import("./chat-
|
|
44
|
+
const { chatCommand } = await import("./chat-6TX6JX45.js");
|
|
45
45
|
return chatCommand(ctx, {});
|
|
46
46
|
}
|
|
47
47
|
program.outputHelp();
|
|
@@ -74,43 +74,43 @@ function collect(value, previous = []) {
|
|
|
74
74
|
function registerCommands(program, run) {
|
|
75
75
|
program.command("app").description("start your local workspace in a Chrome or Edge app window").addOption(new Option("-p, --port <port>", "port to listen on").argParser(parsePort)).option("--project <dir>", "repository to open").action(
|
|
76
76
|
run(async (ctx, opts) => {
|
|
77
|
-
const { startCommand } = await import("./start-
|
|
77
|
+
const { startCommand } = await import("./start-WVAEAQWL.js");
|
|
78
78
|
return startCommand(ctx, { ...opts, host: "127.0.0.1", app: true });
|
|
79
79
|
})
|
|
80
80
|
);
|
|
81
81
|
program.command("start").description("start the gateway (OpenAI-compatible /v1, dashboard API and web dashboard)").addOption(new Option("-p, --port <port>", "port to listen on").argParser(parsePort)).option("--host <host>", "interface to bind (default 127.0.0.1)").option("--no-dashboard", "do not serve the web dashboard").option("--project <dir>", "repository whose project brain to serve (default: detected)").option("--verbose", "print gateway request logs").option("-q, --quiet", "do not print the live activity log").action(
|
|
82
82
|
run(async (ctx, opts) => {
|
|
83
|
-
const { startCommand } = await import("./start-
|
|
83
|
+
const { startCommand } = await import("./start-WVAEAQWL.js");
|
|
84
84
|
return startCommand(ctx, opts);
|
|
85
85
|
})
|
|
86
86
|
);
|
|
87
87
|
program.command("status").description("gateway health, accounts and 1m/5h/24h quota usage").action(
|
|
88
88
|
run(async (ctx) => {
|
|
89
|
-
const { statusCommand } = await import("./status-
|
|
89
|
+
const { statusCommand } = await import("./status-ZRHPFLFT.js");
|
|
90
90
|
return statusCommand(ctx);
|
|
91
91
|
})
|
|
92
92
|
);
|
|
93
93
|
program.command("chat").description("chat TUI (also what bare `davecode` opens in a terminal)").option("-m, --model <id>", "model or route, e.g. davecode/auto or anthropic/claude-sonnet-5-5").option("--project <dir>", "repository whose brain an in-process gateway serves").action(
|
|
94
94
|
run(async (ctx, opts) => {
|
|
95
|
-
const { chatCommand } = await import("./chat-
|
|
95
|
+
const { chatCommand } = await import("./chat-6TX6JX45.js");
|
|
96
96
|
return chatCommand(ctx, opts);
|
|
97
97
|
})
|
|
98
98
|
);
|
|
99
99
|
program.command("login").description("sign in to your DaveCode account in the browser").action(
|
|
100
100
|
run(async (ctx) => {
|
|
101
|
-
const { loginCommand } = await import("./account-
|
|
101
|
+
const { loginCommand } = await import("./account-RTPS2V6O.js");
|
|
102
102
|
return loginCommand(ctx);
|
|
103
103
|
})
|
|
104
104
|
);
|
|
105
105
|
program.command("logout").description("sign out of your DaveCode account").action(
|
|
106
106
|
run(async (ctx) => {
|
|
107
|
-
const { logoutCommand } = await import("./account-
|
|
107
|
+
const { logoutCommand } = await import("./account-RTPS2V6O.js");
|
|
108
108
|
return logoutCommand(ctx);
|
|
109
109
|
})
|
|
110
110
|
);
|
|
111
111
|
program.command("account").description("show the signed-in DaveCode account").action(
|
|
112
112
|
run(async (ctx) => {
|
|
113
|
-
const { accountCommand } = await import("./account-
|
|
113
|
+
const { accountCommand } = await import("./account-RTPS2V6O.js");
|
|
114
114
|
return accountCommand(ctx);
|
|
115
115
|
})
|
|
116
116
|
);
|
|
@@ -118,13 +118,13 @@ function registerCommands(program, run) {
|
|
|
118
118
|
registerProject(program, run);
|
|
119
119
|
program.command("budget").description("plans, renewals and remaining quota per account (what agents are told)").option("--context", "print only the summary injected into agent prompts").option("--local", "read the local database even if a gateway is running").action(
|
|
120
120
|
run(async (ctx, opts) => {
|
|
121
|
-
const { budgetCommand } = await import("./budget-
|
|
121
|
+
const { budgetCommand } = await import("./budget-N2ZB66FF.js");
|
|
122
122
|
return budgetCommand(ctx, opts);
|
|
123
123
|
})
|
|
124
124
|
);
|
|
125
125
|
program.command("doctor").description("check the environment and print fixes").action(
|
|
126
126
|
run(async (ctx) => {
|
|
127
|
-
const { doctorCommand } = await import("./doctor-
|
|
127
|
+
const { doctorCommand } = await import("./doctor-PQC7JQPP.js");
|
|
128
128
|
return doctorCommand(ctx);
|
|
129
129
|
})
|
|
130
130
|
);
|
|
@@ -138,7 +138,7 @@ Exit codes with --once: 0 success or nothing to do, 1 failed or error, 130 stopp
|
|
|
138
138
|
Ctrl+C stops safely: partial work stays on the task branch and the task goes back to PENDING.`
|
|
139
139
|
).action(
|
|
140
140
|
run(async (ctx, opts) => {
|
|
141
|
-
const { runCommand } = await import("./run-
|
|
141
|
+
const { runCommand } = await import("./run-7HWSHMRJ.js");
|
|
142
142
|
return runCommand(ctx, opts);
|
|
143
143
|
})
|
|
144
144
|
);
|
|
@@ -166,26 +166,26 @@ Examples:
|
|
|
166
166
|
davecode goal "Add a /health endpoint with tests" --max-rounds 2`
|
|
167
167
|
).action(
|
|
168
168
|
run(async (ctx, words, opts) => {
|
|
169
|
-
const { goalCommand } = await import("./goal-
|
|
169
|
+
const { goalCommand } = await import("./goal-STLEU7C7.js");
|
|
170
170
|
return goalCommand(ctx, words, opts);
|
|
171
171
|
})
|
|
172
172
|
);
|
|
173
173
|
const goals = program.command("goals").description("goals of this repository");
|
|
174
174
|
goals.command("list", { isDefault: true }).alias("ls").description("goals, newest first").option("--project <dir>", "repository (default: detected)").action(
|
|
175
175
|
run(async (ctx, opts) => {
|
|
176
|
-
const { goalsList } = await import("./goal-
|
|
176
|
+
const { goalsList } = await import("./goal-STLEU7C7.js");
|
|
177
177
|
return goalsList(ctx, opts);
|
|
178
178
|
})
|
|
179
179
|
);
|
|
180
180
|
goals.command("show <id>").description("tasks, artifacts and summary of a goal").option("--project <dir>", "repository (default: detected)").action(
|
|
181
181
|
run(async (ctx, id, opts) => {
|
|
182
|
-
const { goalsShow } = await import("./goal-
|
|
182
|
+
const { goalsShow } = await import("./goal-STLEU7C7.js");
|
|
183
183
|
return goalsShow(ctx, id, opts);
|
|
184
184
|
})
|
|
185
185
|
);
|
|
186
186
|
goals.command("cancel <id>").description("cancel a running goal").option("--project <dir>", "repository (default: detected)").action(
|
|
187
187
|
run(async (ctx, id, opts) => {
|
|
188
|
-
const { goalsCancel } = await import("./goal-
|
|
188
|
+
const { goalsCancel } = await import("./goal-STLEU7C7.js");
|
|
189
189
|
return goalsCancel(ctx, id, opts);
|
|
190
190
|
})
|
|
191
191
|
);
|
|
@@ -193,20 +193,20 @@ Examples:
|
|
|
193
193
|
function registerProject(program, run) {
|
|
194
194
|
program.command("init").description("scaffold the project brain (.davecode/) in this repository").option("--name <name>", "project name used in STATE.md and ARCHITECTURE.md").option("--config", "write a starter .davecode/config.json without asking").option("--no-config", "do not write .davecode/config.json").action(
|
|
195
195
|
run(async (ctx, opts) => {
|
|
196
|
-
const { initCommand } = await import("./init-
|
|
196
|
+
const { initCommand } = await import("./init-NHU5LJSS.js");
|
|
197
197
|
return initCommand(ctx, opts);
|
|
198
198
|
})
|
|
199
199
|
);
|
|
200
200
|
const tasks = program.command("tasks").description("show and edit the task graph");
|
|
201
201
|
tasks.command("list", { isDefault: true }).alias("ls").description("task tree with status and blocked reasons").action(
|
|
202
202
|
run(async (ctx) => {
|
|
203
|
-
const { tasksList } = await import("./tasks-
|
|
203
|
+
const { tasksList } = await import("./tasks-JVWXUNXN.js");
|
|
204
204
|
return tasksList(ctx);
|
|
205
205
|
})
|
|
206
206
|
);
|
|
207
207
|
tasks.command("next").description("the task the runner would pick next").action(
|
|
208
208
|
run(async (ctx) => {
|
|
209
|
-
const { tasksNext } = await import("./tasks-
|
|
209
|
+
const { tasksNext } = await import("./tasks-JVWXUNXN.js");
|
|
210
210
|
return tasksNext(ctx);
|
|
211
211
|
})
|
|
212
212
|
);
|
|
@@ -217,33 +217,33 @@ function registerProject(program, run) {
|
|
|
217
217
|
).action(
|
|
218
218
|
run(
|
|
219
219
|
async (ctx, id, title, opts) => {
|
|
220
|
-
const { tasksAdd } = await import("./tasks-
|
|
220
|
+
const { tasksAdd } = await import("./tasks-JVWXUNXN.js");
|
|
221
221
|
return tasksAdd(ctx, id, title, opts);
|
|
222
222
|
}
|
|
223
223
|
)
|
|
224
224
|
);
|
|
225
225
|
tasks.command("status <id> <status>").description("move a task to PENDING | IN_PROGRESS | SUCCESS | FAILED").option("--notes <text>", "note stored on the task").action(
|
|
226
226
|
run(async (ctx, id, status, opts) => {
|
|
227
|
-
const { tasksStatus } = await import("./tasks-
|
|
227
|
+
const { tasksStatus } = await import("./tasks-JVWXUNXN.js");
|
|
228
228
|
return tasksStatus(ctx, id, status, opts);
|
|
229
229
|
})
|
|
230
230
|
);
|
|
231
231
|
const config = program.command("config").description("show the resolved configuration");
|
|
232
232
|
config.command("show", { isDefault: true }).description("resolved config as JSON (secrets redacted)").action(
|
|
233
233
|
run(async (ctx) => {
|
|
234
|
-
const { configShow } = await import("./config-
|
|
234
|
+
const { configShow } = await import("./config-YQKY2AA4.js");
|
|
235
235
|
return configShow(ctx);
|
|
236
236
|
})
|
|
237
237
|
);
|
|
238
238
|
config.command("path").description("where config, state and brains live").action(
|
|
239
239
|
run(async (ctx) => {
|
|
240
|
-
const { configPath } = await import("./config-
|
|
240
|
+
const { configPath } = await import("./config-YQKY2AA4.js");
|
|
241
241
|
return configPath(ctx);
|
|
242
242
|
})
|
|
243
243
|
);
|
|
244
244
|
config.command("get <key>").description("one value by dotted key, e.g. server.port").action(
|
|
245
245
|
run(async (ctx, key) => {
|
|
246
|
-
const { configGet } = await import("./config-
|
|
246
|
+
const { configGet } = await import("./config-YQKY2AA4.js");
|
|
247
247
|
return configGet(ctx, key);
|
|
248
248
|
})
|
|
249
249
|
);
|
|
@@ -267,7 +267,7 @@ Examples:
|
|
|
267
267
|
davecode accounts add --provider claude-cli --label "Claude Pro" --yes`
|
|
268
268
|
).action(
|
|
269
269
|
run(async (ctx, opts) => {
|
|
270
|
-
const { accountsAdd } = await import("./accounts-
|
|
270
|
+
const { accountsAdd } = await import("./accounts-IYQ4ZRL7.js");
|
|
271
271
|
return accountsAdd(ctx, opts);
|
|
272
272
|
})
|
|
273
273
|
);
|
|
@@ -276,7 +276,7 @@ function registerAccounts(program, run) {
|
|
|
276
276
|
const accounts = program.command("accounts").description("manage provider accounts");
|
|
277
277
|
accounts.command("list", { isDefault: true }).alias("ls").description("list accounts").option("--local", "read the local database even if a gateway is running").action(
|
|
278
278
|
run(async (ctx, opts) => {
|
|
279
|
-
const { accountsList } = await import("./accounts-
|
|
279
|
+
const { accountsList } = await import("./accounts-IYQ4ZRL7.js");
|
|
280
280
|
return accountsList(ctx, opts);
|
|
281
281
|
})
|
|
282
282
|
);
|
|
@@ -286,7 +286,7 @@ function registerAccounts(program, run) {
|
|
|
286
286
|
);
|
|
287
287
|
accounts.command("remove <id>").alias("rm").description("remove an account, its secret and its sandbox").option("-y, --yes", "do not ask for confirmation").option("--local", "write to the local database even if a gateway is running").action(
|
|
288
288
|
run(async (ctx, id, opts) => {
|
|
289
|
-
const { accountsRemove } = await import("./accounts-
|
|
289
|
+
const { accountsRemove } = await import("./accounts-IYQ4ZRL7.js");
|
|
290
290
|
return accountsRemove(ctx, id, opts);
|
|
291
291
|
})
|
|
292
292
|
);
|
|
@@ -296,7 +296,7 @@ function registerAccounts(program, run) {
|
|
|
296
296
|
]) {
|
|
297
297
|
accounts.command(`${name} <id>`).description(`${name} an account${enabled ? " (also clears error and cooldown state)" : ""}`).option("--local", "write to the local database even if a gateway is running").action(
|
|
298
298
|
run(async (ctx, id, opts) => {
|
|
299
|
-
const { accountsSetEnabled } = await import("./accounts-
|
|
299
|
+
const { accountsSetEnabled } = await import("./accounts-IYQ4ZRL7.js");
|
|
300
300
|
return accountsSetEnabled(ctx, id, enabled, opts);
|
|
301
301
|
})
|
|
302
302
|
);
|
|
@@ -308,7 +308,7 @@ Entered by hand: DaveCode never reads billing pages. Example:
|
|
|
308
308
|
davecode accounts plan acc_123 --plan "Claude Pro" --price 20 --renews 2026-11-01`
|
|
309
309
|
).action(
|
|
310
310
|
run(async (ctx, id, opts) => {
|
|
311
|
-
const { accountsPlan } = await import("./accounts-
|
|
311
|
+
const { accountsPlan } = await import("./accounts-IYQ4ZRL7.js");
|
|
312
312
|
return accountsPlan(ctx, id, opts);
|
|
313
313
|
})
|
|
314
314
|
);
|
|
@@ -324,7 +324,7 @@ Extra arguments after -- replace the default ones (e.g. -- login --device-auth f
|
|
|
324
324
|
).action(
|
|
325
325
|
run(
|
|
326
326
|
async (ctx, id, args, opts) => {
|
|
327
|
-
const { accountsLogin } = await import("./accounts-
|
|
327
|
+
const { accountsLogin } = await import("./accounts-IYQ4ZRL7.js");
|
|
328
328
|
return accountsLogin(ctx, id, args, opts);
|
|
329
329
|
}
|
|
330
330
|
)
|
|
@@ -338,7 +338,7 @@ connected, start the vendor's own sign-in. Example:
|
|
|
338
338
|
davecode accounts connect acc_123 --check`
|
|
339
339
|
).action(
|
|
340
340
|
run(async (ctx, id, opts) => {
|
|
341
|
-
const { accountsConnect } = await import("./accounts-
|
|
341
|
+
const { accountsConnect } = await import("./accounts-IYQ4ZRL7.js");
|
|
342
342
|
return accountsConnect(ctx, id, opts);
|
|
343
343
|
})
|
|
344
344
|
);
|
|
@@ -6,16 +6,17 @@ import {
|
|
|
6
6
|
} from "./chunk-QA3O6RA2.js";
|
|
7
7
|
import {
|
|
8
8
|
detectProjectRoot
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KUY3QHGS.js";
|
|
10
10
|
import {
|
|
11
11
|
CliError,
|
|
12
12
|
EXIT
|
|
13
13
|
} from "./chunk-7XVXEO7U.js";
|
|
14
|
+
import "./chunk-732GIHRQ.js";
|
|
14
15
|
import {
|
|
15
16
|
ProjectBrain,
|
|
16
17
|
configSchema,
|
|
17
18
|
projectPaths
|
|
18
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-QKY3OKVG.js";
|
|
19
20
|
import "./chunk-MC7RIPL7.js";
|
|
20
21
|
|
|
21
22
|
// src/commands/init.ts
|
|
@@ -191,4 +192,4 @@ export {
|
|
|
191
192
|
ensureLockIgnored,
|
|
192
193
|
initCommand
|
|
193
194
|
};
|
|
194
|
-
//# sourceMappingURL=init-
|
|
195
|
+
//# sourceMappingURL=init-NHU5LJSS.js.map
|