@dmrlzz/davecode 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +5 -4
  2. package/bin/davecode.js +0 -0
  3. package/dist/{ChatApp-FO5SABXB.js → ChatApp-BO7QMBWD.js} +289 -137
  4. package/dist/ChatApp-BO7QMBWD.js.map +1 -0
  5. package/dist/{RunnerView-DLVR7C22.js → RunnerView-A7JSPUW5.js} +5 -5
  6. package/dist/account-UGNLJPQ4.js +23 -0
  7. package/dist/accounts-NM7IWP53.js +37 -0
  8. package/dist/{budget-RBHCEDPP.js → budget-INAW6FXD.js} +6 -6
  9. package/dist/chat-U4QJQ7M6.js +359 -0
  10. package/dist/chat-U4QJQ7M6.js.map +1 -0
  11. package/dist/{chunk-C7FDRA3U.js → chunk-3Q2KCXLN.js} +660 -139
  12. package/dist/chunk-3Q2KCXLN.js.map +1 -0
  13. package/dist/{chunk-BOLFK3BH.js → chunk-5LKOJBUL.js} +2 -2
  14. package/dist/{accounts-MTMGYKEP.js → chunk-CWBVNS3L.js} +24 -17
  15. package/dist/chunk-CWBVNS3L.js.map +1 -0
  16. package/dist/{chunk-PIIJ3RSI.js → chunk-DZ2FDABF.js} +1269 -1265
  17. package/dist/chunk-DZ2FDABF.js.map +1 -0
  18. package/dist/{chunk-OYEYNDOO.js → chunk-GE22VBCY.js} +3 -3
  19. package/dist/chunk-GHDOUII5.js +144 -0
  20. package/dist/chunk-GHDOUII5.js.map +1 -0
  21. package/dist/{chunk-MSLLH5XP.js → chunk-GZJ6JSO7.js} +4 -4
  22. package/dist/{chunk-VVCXGQMY.js → chunk-MC7RIPL7.js} +17 -8
  23. package/dist/chunk-MC7RIPL7.js.map +1 -0
  24. package/dist/{chunk-23KTE7IK.js → chunk-MOK5D3XJ.js} +2 -2
  25. package/dist/{chunk-OXRMGR72.js → chunk-PGPXE6LF.js} +2 -2
  26. package/dist/chunk-QA3O6RA2.js +81 -0
  27. package/dist/chunk-QA3O6RA2.js.map +1 -0
  28. package/dist/chunk-ROIUTNQV.js +20 -0
  29. package/dist/chunk-ROIUTNQV.js.map +1 -0
  30. package/dist/{chunk-IVZHKUCD.js → chunk-Z6NQDJEN.js} +3 -3
  31. package/dist/{config-FRMY5OHG.js → config-YEAPBMBX.js} +5 -5
  32. package/dist/dashboard/assets/Accounts-CeVyX4a3.js +1 -0
  33. package/dist/dashboard/assets/Badge-CGY6DgGx.js +55 -0
  34. package/dist/dashboard/assets/{Callout-B9g_wPDi.js → Callout-DauCk_cW.js} +1 -1
  35. package/dist/dashboard/assets/{Field-BfabPEcY.js → Field-OXMnT9Tb.js} +1 -1
  36. package/dist/dashboard/assets/{Goals-BsV-6m94.js → Goals-DH-KDh8M.js} +1 -1
  37. package/dist/dashboard/assets/{Library-CEA9P1m-.js → Library-C15szLjZ.js} +1 -1
  38. package/dist/dashboard/assets/{Markdown-ClRsddnB.js → Markdown-Xhao3sgL.js} +7 -7
  39. package/dist/dashboard/assets/Panel-Du40pM7n.js +1 -0
  40. package/dist/dashboard/assets/{RoutesPage-Dh-BJ3ir.js → RoutesPage-Cj1OelGO.js} +1 -1
  41. package/dist/dashboard/assets/{Runner-C_e9l5l2.js → Runner-BK1-ZF7h.js} +1 -1
  42. package/dist/dashboard/assets/{Settings-C6Yc1Gjg.js → Settings-C1nzQQhe.js} +1 -1
  43. package/dist/dashboard/assets/{Switch-CUpOJjUT.js → Switch-bwtIJ00H.js} +1 -1
  44. package/dist/dashboard/assets/Tasks-x4s8IiPG.js +2 -0
  45. package/dist/dashboard/assets/{Traffic-CE6wZSMr.js → Traffic-CV7TaTid.js} +1 -1
  46. package/dist/dashboard/assets/{Workspace-CxFxvkA6.js → Workspace-DAL-MBc0.js} +1 -1
  47. package/dist/dashboard/assets/arrow-up-goM9r-I9.js +1 -0
  48. package/dist/dashboard/assets/{forms-D6UIYgC5.js → forms-DtpfI65-.js} +1 -1
  49. package/dist/dashboard/assets/index-BCi-Vuvh.js +104 -0
  50. package/dist/dashboard/assets/{index-1iH716Xy.css → index-CcJFhc98.css} +1 -1
  51. package/dist/dashboard/assets/{task-errors-CE4oEr8H.js → task-errors-B2pgjUGN.js} +1 -1
  52. package/dist/dashboard/assets/{trash-CWqeZ7eg.js → trash-BVojETtF.js} +1 -1
  53. package/dist/dashboard/favicon.svg +1 -7
  54. package/dist/dashboard/index.html +4 -4
  55. package/dist/{dist-ZPXEVBEC.js → dist-RRQGUBL3.js} +24 -2
  56. package/dist/dist-RRQGUBL3.js.map +1 -0
  57. package/dist/{doctor-7RUD4D3A.js → doctor-MQYK44S2.js} +5 -5
  58. package/dist/{goal-JFRNPBSD.js → goal-6NUX4AIT.js} +5 -5
  59. package/dist/index.js +48 -30
  60. package/dist/index.js.map +1 -1
  61. package/dist/{init-NFYNO3A3.js → init-AXYIWAB3.js} +6 -6
  62. package/dist/{prompts-L37J72YW.js → prompts-TZ7UC42M.js} +9 -5
  63. package/dist/prompts-TZ7UC42M.js.map +1 -0
  64. package/dist/{run-ARUPXFFB.js → run-QRTLHFB3.js} +10 -10
  65. package/dist/runtime.js +18 -0
  66. package/dist/runtime.js.map +1 -0
  67. package/dist/{start-CFPOVIAR.js → start-O5I5TSO2.js} +5 -5
  68. package/dist/{status-E4EACVE2.js → status-LEA3RVUX.js} +6 -6
  69. package/dist/status-LEA3RVUX.js.map +1 -0
  70. package/dist/{tasks-ZIK6BVEX.js → tasks-XOTVICVZ.js} +6 -6
  71. package/package.json +21 -15
  72. package/dist/ChatApp-FO5SABXB.js.map +0 -1
  73. package/dist/accounts-MTMGYKEP.js.map +0 -1
  74. package/dist/chat-ZDXX3N6X.js +0 -95
  75. package/dist/chat-ZDXX3N6X.js.map +0 -1
  76. package/dist/chunk-C7FDRA3U.js.map +0 -1
  77. package/dist/chunk-DYQ56FBT.js +0 -47
  78. package/dist/chunk-DYQ56FBT.js.map +0 -1
  79. package/dist/chunk-PIIJ3RSI.js.map +0 -1
  80. package/dist/chunk-VVCXGQMY.js.map +0 -1
  81. package/dist/dashboard/assets/Accounts-BR3ZfVk4.js +0 -1
  82. package/dist/dashboard/assets/Badge-B-qzNRrZ.js +0 -55
  83. package/dist/dashboard/assets/Panel-B9tSgX6l.js +0 -1
  84. package/dist/dashboard/assets/Tasks-CTku0rR3.js +0 -2
  85. package/dist/dashboard/assets/arrow-up-DL3CuFOO.js +0 -1
  86. package/dist/dashboard/assets/index-BMWr9EKo.js +0 -104
  87. package/dist/prompts-L37J72YW.js.map +0 -1
  88. /package/dist/{RunnerView-DLVR7C22.js.map → RunnerView-A7JSPUW5.js.map} +0 -0
  89. /package/dist/{dist-ZPXEVBEC.js.map → account-UGNLJPQ4.js.map} +0 -0
  90. /package/dist/{status-E4EACVE2.js.map → accounts-NM7IWP53.js.map} +0 -0
  91. /package/dist/{budget-RBHCEDPP.js.map → budget-INAW6FXD.js.map} +0 -0
  92. /package/dist/{chunk-BOLFK3BH.js.map → chunk-5LKOJBUL.js.map} +0 -0
  93. /package/dist/{chunk-OYEYNDOO.js.map → chunk-GE22VBCY.js.map} +0 -0
  94. /package/dist/{chunk-MSLLH5XP.js.map → chunk-GZJ6JSO7.js.map} +0 -0
  95. /package/dist/{chunk-23KTE7IK.js.map → chunk-MOK5D3XJ.js.map} +0 -0
  96. /package/dist/{chunk-OXRMGR72.js.map → chunk-PGPXE6LF.js.map} +0 -0
  97. /package/dist/{chunk-IVZHKUCD.js.map → chunk-Z6NQDJEN.js.map} +0 -0
  98. /package/dist/{config-FRMY5OHG.js.map → config-YEAPBMBX.js.map} +0 -0
  99. /package/dist/{doctor-7RUD4D3A.js.map → doctor-MQYK44S2.js.map} +0 -0
  100. /package/dist/{goal-JFRNPBSD.js.map → goal-6NUX4AIT.js.map} +0 -0
  101. /package/dist/{init-NFYNO3A3.js.map → init-AXYIWAB3.js.map} +0 -0
  102. /package/dist/{run-ARUPXFFB.js.map → run-QRTLHFB3.js.map} +0 -0
  103. /package/dist/{start-CFPOVIAR.js.map → start-O5I5TSO2.js.map} +0 -0
  104. /package/dist/{tasks-ZIK6BVEX.js.map → tasks-XOTVICVZ.js.map} +0 -0
@@ -0,0 +1,359 @@
1
+ import {
2
+ accountsEnabled,
3
+ chatAccountActions,
4
+ currentAccount,
5
+ describeUser,
6
+ signIn
7
+ } from "./chunk-GHDOUII5.js";
8
+ import {
9
+ accountsLogin
10
+ } from "./chunk-CWBVNS3L.js";
11
+ import {
12
+ openAccounts
13
+ } from "./chunk-Z6NQDJEN.js";
14
+ import {
15
+ PromptCancelledError
16
+ } from "./chunk-IC3TDONV.js";
17
+ import {
18
+ brandBanner
19
+ } from "./chunk-ROIUTNQV.js";
20
+ import "./chunk-SF5ZEAP4.js";
21
+ import {
22
+ readPreferences,
23
+ writePreferences
24
+ } from "./chunk-QA3O6RA2.js";
25
+ import {
26
+ GatewayClient,
27
+ detectProjectRoot,
28
+ findGateway,
29
+ startRuntime,
30
+ which
31
+ } from "./chunk-DZ2FDABF.js";
32
+ import {
33
+ CliError,
34
+ EXIT
35
+ } from "./chunk-7XVXEO7U.js";
36
+ import {
37
+ CLI_LOGINS,
38
+ VERSION,
39
+ loadConfig,
40
+ writeGlobalRouting
41
+ } from "./chunk-3Q2KCXLN.js";
42
+ import {
43
+ createTheme
44
+ } from "./chunk-MC7RIPL7.js";
45
+
46
+ // src/commands/chat.ts
47
+ import { homedir } from "os";
48
+ import { resolve, sep } from "path";
49
+
50
+ // src/tui/backend.ts
51
+ function httpBackend(client, inProcess) {
52
+ return {
53
+ url: client.baseUrl,
54
+ inProcess,
55
+ health: () => client.health(1500).catch(() => void 0),
56
+ stream: (request, signal) => client.chatStream(request, signal),
57
+ models: async () => (await client.get("/v1/models")).data,
58
+ routes: () => client.get("/api/routes"),
59
+ accounts: async () => (await client.get("/api/accounts")).accounts,
60
+ usage: async () => (await client.get("/api/usage")).usage,
61
+ tasks: () => client.get("/api/tasks"),
62
+ runner: async () => (await client.get("/api/runner")).status
63
+ };
64
+ }
65
+
66
+ // src/commands/onboard.ts
67
+ import { execFile } from "child_process";
68
+ var AGENTS = [
69
+ {
70
+ provider: "claude-cli",
71
+ name: "Claude Code",
72
+ models: [
73
+ { value: "default", label: "Default", hint: "Claude Code decides" },
74
+ { value: "opus", label: "Opus", hint: "most capable" },
75
+ { value: "sonnet", label: "Sonnet", hint: "balanced" },
76
+ { value: "haiku", label: "Haiku", hint: "fastest" }
77
+ ]
78
+ },
79
+ {
80
+ provider: "codex-cli",
81
+ name: "Codex",
82
+ models: [{ value: "default", label: "Default", hint: "Codex decides" }]
83
+ },
84
+ {
85
+ provider: "antigravity-cli",
86
+ name: "Antigravity",
87
+ models: [{ value: "default", label: "Default", hint: "Antigravity decides" }]
88
+ }
89
+ ];
90
+ function parseAgyModels(stdout) {
91
+ return stdout.split(/\r?\n/).map((line) => line.split(" ")).filter(([id, name]) => id && name && /^[\w.:-]+$/.test(id.trim())).map(([id, name]) => ({ value: id.trim(), label: name.trim() }));
92
+ }
93
+ function agyModels(binary, env) {
94
+ return new Promise((resolve2) => {
95
+ execFile(
96
+ binary,
97
+ ["models"],
98
+ { env, timeout: 3e4, windowsHide: true },
99
+ (error, stdout) => resolve2(error ? [] : parseAgyModels(String(stdout)))
100
+ );
101
+ });
102
+ }
103
+ var OTHER_MODEL = "__other__";
104
+ async function prompterFor(ctx, deps) {
105
+ if (deps.prompter) return deps.prompter;
106
+ const { createInkPrompter } = await import("./prompts-TZ7UC42M.js");
107
+ return createInkPrompter({ stdout: ctx.io.stdout, stdin: ctx.io.stdin, theme: ctx.theme });
108
+ }
109
+ function welcome(ctx) {
110
+ const { theme } = ctx;
111
+ ctx.out();
112
+ const text = [
113
+ `${theme.bold("Welcome to DaveCode")} ${theme.dim(`v${VERSION}`)}`,
114
+ theme.dim("Run Claude Code, Codex and Antigravity side by side.")
115
+ ];
116
+ for (const line of brandBanner(theme, text, ctx.columns)) ctx.out(` ${line}`);
117
+ ctx.out();
118
+ }
119
+ function withTheme(ctx, mode) {
120
+ return {
121
+ ...ctx,
122
+ theme: createTheme({ color: ctx.theme.color, unicode: ctx.theme.unicode, mode }),
123
+ errTheme: createTheme({ color: ctx.errTheme.color, unicode: ctx.errTheme.unicode, mode })
124
+ };
125
+ }
126
+ async function chooseTheme(ctx, prompter) {
127
+ return prompter.select(
128
+ "Choose a look for the terminal",
129
+ [
130
+ { value: "dark", label: "Dark", hint: "white text on black" },
131
+ { value: "light", label: "Light", hint: "black text on white" },
132
+ { value: "auto", label: "Match my terminal" }
133
+ ],
134
+ readPreferences(ctx.home).theme ?? "dark"
135
+ );
136
+ }
137
+ async function signInStep(ctx, prompter, deps) {
138
+ const choice = await prompter.select("Sign in to continue", [
139
+ { value: "browser", label: "Sign in with your browser", hint: "Google, GitHub or email" },
140
+ { value: "quit", label: "Quit" }
141
+ ]);
142
+ if (choice === "quit") throw new PromptCancelledError();
143
+ const session = await signIn(ctx, deps);
144
+ ctx.out(
145
+ `${ctx.theme.ok(ctx.theme.glyph.ok)} Signed in as ${ctx.theme.bold(describeUser(session))}`
146
+ );
147
+ ctx.out();
148
+ }
149
+ async function setDefaultRoute(ctx, route) {
150
+ const global = loadConfig({ home: ctx.home, env: ctx.env });
151
+ await writeGlobalRouting(ctx.home, {
152
+ routes: [...global.routing.routes.filter((r) => r.name !== route.name), route],
153
+ defaultRoute: route.name
154
+ });
155
+ }
156
+ async function connectAgent(ctx, provider, prompter, backend, deps = {}) {
157
+ const { theme } = ctx;
158
+ const which2 = deps.which ?? ((binary) => which(binary, ctx.env));
159
+ const agent = AGENTS.find((a) => a.provider === provider);
160
+ const spec = CLI_LOGINS[provider];
161
+ if (!agent || !spec) throw new Error(`${provider} is not an agent DaveCode can connect`);
162
+ if (!which2(spec.binary)) {
163
+ ctx.out(theme.warn(` ${agent.name} is not installed.`));
164
+ ctx.out(theme.dim(` ${spec.installHint}`));
165
+ ctx.out();
166
+ return false;
167
+ }
168
+ const account = (await backend.list()).find((a) => a.provider === provider) ?? await backend.create({ provider, label: agent.name });
169
+ const connection = await backend.connection(account.id).catch(() => void 0);
170
+ if (connection?.status !== "connected" || account.status === "error") {
171
+ const exit = await (deps.vendorLogin ?? ((c, id) => accountsLogin(c, id, [], {}, { backend })))(
172
+ ctx,
173
+ account.id
174
+ );
175
+ if (exit !== 0) {
176
+ ctx.out(theme.warn(` ${agent.name} did not finish signing in. You can retry later with:`));
177
+ ctx.out(theme.dim(` davecode accounts login ${account.id}`));
178
+ }
179
+ } else {
180
+ ctx.out(`${theme.ok(theme.glyph.ok)} ${agent.name} is already signed in.`);
181
+ }
182
+ const discovered = provider === "antigravity-cli" ? await (deps.models ?? (() => agyModels(which2(spec.binary) ?? spec.binary, ctx.env)))(
183
+ provider
184
+ ) : [];
185
+ let model = await prompter.select(`Model for ${agent.name}`, [
186
+ ...agent.models,
187
+ ...discovered,
188
+ { value: OTHER_MODEL, label: "Another model\u2026", hint: "type its id" }
189
+ ]);
190
+ if (model === OTHER_MODEL) {
191
+ model = await prompter.text("Model id", {
192
+ validate: (v) => /^[\w.:[\]-]+$/.test(v.trim()) ? void 0 : "Use letters, digits, . : - _"
193
+ });
194
+ model = model.trim();
195
+ }
196
+ await setDefaultRoute(ctx, {
197
+ name: "auto",
198
+ description: `${agent.name} (${model})`,
199
+ targets: [{ provider, model, accountId: account.id }]
200
+ });
201
+ ctx.out(`${theme.ok(theme.glyph.ok)} DaveCode will use ${theme.bold(agent.name)} \xB7 ${model}`);
202
+ ctx.out();
203
+ return true;
204
+ }
205
+ function agentChoices(ctx, deps = {}) {
206
+ const which2 = deps.which ?? ((binary) => which(binary, ctx.env));
207
+ return AGENTS.map((agent) => ({
208
+ value: agent.provider,
209
+ label: agent.name,
210
+ hint: which2(CLI_LOGINS[agent.provider]?.binary ?? "") ? "installed" : "not installed"
211
+ }));
212
+ }
213
+ async function connectAgentStep(ctx, prompter, backend, deps) {
214
+ for (; ; ) {
215
+ const choice = await prompter.select("Connect your first agent", [
216
+ ...agentChoices(ctx, deps),
217
+ { value: "later", label: "Later", hint: "davecode accounts add" }
218
+ ]);
219
+ if (choice === "later") return;
220
+ if (await connectAgent(ctx, choice, prompter, backend, deps)) return;
221
+ }
222
+ }
223
+ async function ensureReady(ctx, deps = {}) {
224
+ const prefs = readPreferences(ctx.home);
225
+ const needsAccount = accountsEnabled(ctx, deps) && !await currentAccount(ctx, deps);
226
+ if (prefs.onboarded && !needsAccount) return ctx;
227
+ let current = ctx;
228
+ const prompter = await prompterFor(ctx, deps);
229
+ try {
230
+ if (!prefs.onboarded) {
231
+ welcome(ctx);
232
+ const mode = await chooseTheme(ctx, prompter);
233
+ writePreferences(ctx.home, { theme: mode });
234
+ current = withTheme(ctx, mode);
235
+ }
236
+ if (needsAccount) await signInStep(current, prompter, deps);
237
+ if (!prefs.onboarded) {
238
+ const backend = deps.backend ?? await openAccounts({ home: current.home, env: current.env, local: true });
239
+ try {
240
+ const existing = await backend.list();
241
+ if (existing.length === 0) await connectAgentStep(current, prompter, backend, deps);
242
+ } finally {
243
+ if (!deps.backend) backend.close();
244
+ }
245
+ writePreferences(current.home, { onboarded: true });
246
+ }
247
+ return current;
248
+ } catch (err) {
249
+ if (err instanceof PromptCancelledError) {
250
+ ctx.err(ctx.errTheme.dim("Setup cancelled. Run davecode again to continue."));
251
+ return void 0;
252
+ }
253
+ throw err;
254
+ }
255
+ }
256
+
257
+ // src/commands/chat.ts
258
+ function displayPath(path) {
259
+ const home = homedir();
260
+ return path === home || path.startsWith(home + sep) ? `~${path.slice(home.length)}` : path;
261
+ }
262
+ async function chatCommand(ctx, opts) {
263
+ if (!ctx.io.stdin.isTTY || !ctx.io.stdout.isTTY) {
264
+ throw new CliError("The chat TUI needs an interactive terminal", {
265
+ hint: "For scripts, call the OpenAI-compatible API: POST http://127.0.0.1:4040/v1/chat/completions"
266
+ });
267
+ }
268
+ const ready = await ensureReady(ctx);
269
+ if (!ready) return EXIT.failure;
270
+ ctx = ready;
271
+ const projectRoot = opts.project ? resolve(ctx.cwd, opts.project) : await detectProjectRoot(ctx.cwd, ctx.home);
272
+ for (; ; ) {
273
+ const provider = await runChat(ctx, opts, projectRoot);
274
+ if (!provider) return EXIT.ok;
275
+ await connectFromChat(ctx, provider);
276
+ }
277
+ }
278
+ async function connectFromChat(ctx, provider) {
279
+ const { createInkPrompter } = await import("./prompts-TZ7UC42M.js");
280
+ const prompter = createInkPrompter({
281
+ stdout: ctx.io.stdout,
282
+ stdin: ctx.io.stdin,
283
+ theme: ctx.theme
284
+ });
285
+ const backend = await openAccounts({ home: ctx.home, env: ctx.env, local: true });
286
+ try {
287
+ ctx.out();
288
+ await connectAgent(ctx, provider, prompter, backend);
289
+ } catch (err) {
290
+ if (!(err instanceof PromptCancelledError)) throw err;
291
+ } finally {
292
+ backend.close();
293
+ }
294
+ }
295
+ async function runChat(ctx, opts, projectRoot) {
296
+ const config = loadConfig({
297
+ home: ctx.home,
298
+ env: ctx.env,
299
+ ...projectRoot ? { projectRoot } : {}
300
+ });
301
+ let runtime;
302
+ let backend;
303
+ const running = await findGateway(config);
304
+ if (running) {
305
+ backend = httpBackend(running.client, false);
306
+ } else {
307
+ runtime = await startRuntime({
308
+ home: ctx.home,
309
+ env: ctx.env,
310
+ cwd: ctx.cwd,
311
+ host: "127.0.0.1",
312
+ port: 0,
313
+ dashboard: false,
314
+ ...projectRoot ? { projectDir: projectRoot } : { noProject: true }
315
+ });
316
+ const target = config.server.authToken ? { baseUrl: runtime.url, token: config.server.authToken } : { baseUrl: runtime.url };
317
+ backend = httpBackend(new GatewayClient(target), true);
318
+ }
319
+ const accountActions = chatAccountActions(ctx);
320
+ let connectTo;
321
+ const connect = {
322
+ agents: async () => agentChoices(ctx),
323
+ choose: (provider) => {
324
+ connectTo = provider;
325
+ }
326
+ };
327
+ try {
328
+ const [{ render }, { createElement }, { ChatApp }] = await Promise.all([
329
+ import("ink"),
330
+ import("react"),
331
+ import("./ChatApp-BO7QMBWD.js")
332
+ ]);
333
+ const instance = render(
334
+ createElement(ChatApp, {
335
+ backend,
336
+ theme: ctx.theme,
337
+ model: opts.model ?? `davecode/${config.routing.defaultRoute}`,
338
+ version: VERSION,
339
+ project: displayPath(projectRoot ?? ctx.cwd),
340
+ ...accountActions ? { account: accountActions } : {},
341
+ connect
342
+ }),
343
+ {
344
+ stdout: ctx.io.stdout,
345
+ stdin: process.stdin,
346
+ exitOnCtrlC: false,
347
+ kittyKeyboard: { mode: "auto", flags: ["disambiguateEscapeCodes"] }
348
+ }
349
+ );
350
+ await instance.waitUntilExit();
351
+ } finally {
352
+ await runtime?.close();
353
+ }
354
+ return connectTo;
355
+ }
356
+ export {
357
+ chatCommand
358
+ };
359
+ //# sourceMappingURL=chat-U4QJQ7M6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/chat.ts","../src/tui/backend.ts","../src/commands/onboard.ts"],"sourcesContent":["import { homedir } from 'node:os';\nimport { resolve, sep } from 'node:path';\nimport { loadConfig, type ProviderKind, VERSION } from '@davecode/core';\nimport { findGateway, GatewayClient } from '../client';\nimport type { CliContext } from '../context';\nimport { CliError, EXIT } from '../errors';\nimport { openAccounts } from '../lib/accounts-backend';\nimport { PromptCancelledError } from '../lib/prompter';\nimport { detectProjectRoot, type Runtime, startRuntime } from '../runtime';\nimport { type ChatBackend, httpBackend } from '../tui/backend';\nimport { chatAccountActions } from './account';\nimport { agentChoices, connectAgent, ensureReady } from './onboard';\n\nexport interface ChatOptions {\n model?: string;\n project?: string;\n}\n\n/**\n * Open the chat TUI against the running gateway, or start an in-process gateway on an ephemeral\n * loopback port when none is running (it stops when the TUI exits).\n */\n/** `C:\\Users\\me\\code\\app` → `~\\code\\app`, for the banner. */\nfunction displayPath(path: string): string {\n const home = homedir();\n return path === home || path.startsWith(home + sep) ? `~${path.slice(home.length)}` : path;\n}\n\nexport async function chatCommand(ctx: CliContext, opts: ChatOptions): Promise<number> {\n if (!ctx.io.stdin.isTTY || !ctx.io.stdout.isTTY) {\n throw new CliError('The chat TUI needs an interactive terminal', {\n hint: 'For scripts, call the OpenAI-compatible API: POST http://127.0.0.1:4040/v1/chat/completions',\n });\n }\n const ready = await ensureReady(ctx);\n if (!ready) return EXIT.failure;\n ctx = ready;\n const projectRoot = opts.project\n ? resolve(ctx.cwd, opts.project)\n : await detectProjectRoot(ctx.cwd, ctx.home);\n // /connect closes the chat so the vendor login can use the terminal, then opens it again.\n for (;;) {\n const provider = await runChat(ctx, opts, projectRoot);\n if (!provider) return EXIT.ok;\n await connectFromChat(ctx, provider);\n }\n}\n\nasync function connectFromChat(ctx: CliContext, provider: ProviderKind): Promise<void> {\n const { createInkPrompter } = await import('../tui/prompts');\n const prompter = createInkPrompter({\n stdout: ctx.io.stdout,\n stdin: ctx.io.stdin,\n theme: ctx.theme,\n });\n const backend = await openAccounts({ home: ctx.home, env: ctx.env, local: true });\n try {\n ctx.out();\n await connectAgent(ctx, provider, prompter, backend);\n } catch (err) {\n if (!(err instanceof PromptCancelledError)) throw err;\n } finally {\n backend.close();\n }\n}\n\n/** One chat session; resolves with the agent picked in /connect, if any. */\nasync function runChat(\n ctx: CliContext,\n opts: ChatOptions,\n projectRoot: string | undefined,\n): Promise<ProviderKind | undefined> {\n const config = loadConfig({\n home: ctx.home,\n env: ctx.env,\n ...(projectRoot ? { projectRoot } : {}),\n });\n\n let runtime: Runtime | undefined;\n let backend: ChatBackend;\n const running = await findGateway(config);\n if (running) {\n backend = httpBackend(running.client, false);\n } else {\n runtime = await startRuntime({\n home: ctx.home,\n env: ctx.env,\n cwd: ctx.cwd,\n host: '127.0.0.1',\n port: 0,\n dashboard: false,\n ...(projectRoot ? { projectDir: projectRoot } : { noProject: true }),\n });\n const target = config.server.authToken\n ? { baseUrl: runtime.url, token: config.server.authToken }\n : { baseUrl: runtime.url };\n backend = httpBackend(new GatewayClient(target), true);\n }\n\n const accountActions = chatAccountActions(ctx);\n let connectTo: ProviderKind | undefined;\n const connect = {\n agents: async () => agentChoices(ctx),\n choose: (provider: string) => {\n connectTo = provider as ProviderKind;\n },\n };\n try {\n const [{ render }, { createElement }, { ChatApp }] = await Promise.all([\n import('ink'),\n import('react'),\n import('../tui/ChatApp'),\n ]);\n const instance = render(\n createElement(ChatApp, {\n backend,\n theme: ctx.theme,\n model: opts.model ?? `davecode/${config.routing.defaultRoute}`,\n version: VERSION,\n project: displayPath(projectRoot ?? ctx.cwd),\n ...(accountActions ? { account: accountActions } : {}),\n connect,\n }),\n {\n stdout: ctx.io.stdout as NodeJS.WriteStream,\n stdin: process.stdin,\n exitOnCtrlC: false,\n kittyKeyboard: { mode: 'auto', flags: ['disambiguateEscapeCodes'] },\n },\n );\n await instance.waitUntilExit();\n } finally {\n await runtime?.close();\n }\n return connectTo;\n}\n","import type {\n Account,\n AccountUsage,\n ChatCompletionChunk,\n ChatRequest,\n ModelInfo,\n Route,\n RunnerStatus,\n TaskGraph,\n} from '@davecode/core';\nimport type { GatewayClient, HealthResponse, StreamMeta } from '../client';\n\n/** What the TUI needs from a gateway. Backed by HTTP in production and by fakes in tests. */\nexport interface ChatBackend {\n /** Base URL, e.g. `http://127.0.0.1:4040`. */\n url: string;\n /** The gateway was started inside this process (no `davecode start` running). */\n inProcess: boolean;\n health(): Promise<HealthResponse | undefined>;\n stream(\n request: ChatRequest,\n signal: AbortSignal,\n ): Promise<{ meta: StreamMeta; chunks: AsyncIterable<ChatCompletionChunk> }>;\n models(): Promise<ModelInfo[]>;\n routes(): Promise<{ defaultRoute: string; routes: Route[] }>;\n accounts(): Promise<Account[]>;\n usage(): Promise<AccountUsage[]>;\n tasks(): Promise<{ project: { root: string; name: string } | null; graph: TaskGraph }>;\n runner(): Promise<RunnerStatus>;\n}\n\nexport function httpBackend(client: GatewayClient, inProcess: boolean): ChatBackend {\n return {\n url: client.baseUrl,\n inProcess,\n health: () => client.health(1500).catch(() => undefined),\n stream: (request, signal) => client.chatStream(request, signal),\n models: async () => (await client.get<{ data: ModelInfo[] }>('/v1/models')).data,\n routes: () => client.get('/api/routes'),\n accounts: async () => (await client.get<{ accounts: Account[] }>('/api/accounts')).accounts,\n usage: async () => (await client.get<{ usage: AccountUsage[] }>('/api/usage')).usage,\n tasks: () => client.get('/api/tasks'),\n runner: async () => (await client.get<{ status: RunnerStatus }>('/api/runner')).status,\n };\n}\n","import { execFile } from 'node:child_process';\nimport {\n CLI_LOGINS,\n loadConfig,\n type ProviderKind,\n type Route,\n VERSION,\n writeGlobalRouting,\n} from '@davecode/core';\nimport type { CliContext } from '../context';\nimport { type AccountsBackend, openAccounts } from '../lib/accounts-backend';\nimport { readPreferences, writePreferences } from '../lib/preferences';\nimport { which as whichOnPath } from '../lib/proc';\nimport { PromptCancelledError, type Prompter } from '../lib/prompter';\nimport { brandBanner } from '../ui/banner';\nimport { createTheme, type ThemeMode } from '../ui/theme';\nimport { type AccountDeps, accountsEnabled, currentAccount, describeUser, signIn } from './account';\nimport { accountsLogin } from './accounts';\n\n/** Agents DaveCode can drive today, in the order they are offered. */\nexport const AGENTS: ReadonlyArray<{\n provider: ProviderKind;\n name: string;\n models: Array<{ value: string; label: string; hint?: string }>;\n}> = [\n {\n provider: 'claude-cli',\n name: 'Claude Code',\n models: [\n { value: 'default', label: 'Default', hint: 'Claude Code decides' },\n { value: 'opus', label: 'Opus', hint: 'most capable' },\n { value: 'sonnet', label: 'Sonnet', hint: 'balanced' },\n { value: 'haiku', label: 'Haiku', hint: 'fastest' },\n ],\n },\n {\n provider: 'codex-cli',\n name: 'Codex',\n models: [{ value: 'default', label: 'Default', hint: 'Codex decides' }],\n },\n {\n provider: 'antigravity-cli',\n name: 'Antigravity',\n models: [{ value: 'default', label: 'Default', hint: 'Antigravity decides' }],\n },\n];\n\ntype ModelChoice = { value: string; label: string; hint?: string };\n\n/** Antigravity lists its models with `agy models` as `id<TAB>name` lines. */\nexport function parseAgyModels(stdout: string): ModelChoice[] {\n return stdout\n .split(/\\r?\\n/)\n .map((line) => line.split('\\t'))\n .filter(([id, name]) => id && name && /^[\\w.:-]+$/.test(id.trim()))\n .map(([id, name]) => ({ value: (id as string).trim(), label: (name as string).trim() }));\n}\n\nfunction agyModels(binary: string, env: NodeJS.ProcessEnv): Promise<ModelChoice[]> {\n return new Promise((resolve) => {\n execFile(binary, ['models'], { env, timeout: 30_000, windowsHide: true }, (error, stdout) =>\n resolve(error ? [] : parseAgyModels(String(stdout))),\n );\n });\n}\n\nconst OTHER_MODEL = '__other__';\n\nexport interface OnboardDeps extends AccountDeps {\n prompter?: Prompter;\n backend?: AccountsBackend;\n which?: (binary: string) => string | undefined;\n /** Models an agent offers beyond its built-in list (defaults to asking `agy models`). */\n models?: (provider: ProviderKind) => Promise<ModelChoice[]>;\n /** Runs the vendor's official login for an account (defaults to `accounts login`). */\n vendorLogin?: (ctx: CliContext, accountId: string) => Promise<number>;\n}\n\nasync function prompterFor(ctx: CliContext, deps: OnboardDeps): Promise<Prompter> {\n if (deps.prompter) return deps.prompter;\n const { createInkPrompter } = await import('../tui/prompts');\n return createInkPrompter({ stdout: ctx.io.stdout, stdin: ctx.io.stdin, theme: ctx.theme });\n}\n\nfunction welcome(ctx: CliContext): void {\n const { theme } = ctx;\n ctx.out();\n const text = [\n `${theme.bold('Welcome to DaveCode')} ${theme.dim(`v${VERSION}`)}`,\n theme.dim('Run Claude Code, Codex and Antigravity side by side.'),\n ];\n for (const line of brandBanner(theme, text, ctx.columns)) ctx.out(` ${line}`);\n ctx.out();\n}\n\nfunction withTheme(ctx: CliContext, mode: ThemeMode): CliContext {\n return {\n ...ctx,\n theme: createTheme({ color: ctx.theme.color, unicode: ctx.theme.unicode, mode }),\n errTheme: createTheme({ color: ctx.errTheme.color, unicode: ctx.errTheme.unicode, mode }),\n };\n}\n\nasync function chooseTheme(ctx: CliContext, prompter: Prompter): Promise<ThemeMode> {\n return prompter.select<ThemeMode>(\n 'Choose a look for the terminal',\n [\n { value: 'dark', label: 'Dark', hint: 'white text on black' },\n { value: 'light', label: 'Light', hint: 'black text on white' },\n { value: 'auto', label: 'Match my terminal' },\n ],\n readPreferences(ctx.home).theme ?? 'dark',\n );\n}\n\nasync function signInStep(ctx: CliContext, prompter: Prompter, deps: OnboardDeps): Promise<void> {\n const choice = await prompter.select('Sign in to continue', [\n { value: 'browser', label: 'Sign in with your browser', hint: 'Google, GitHub or email' },\n { value: 'quit', label: 'Quit' },\n ]);\n if (choice === 'quit') throw new PromptCancelledError();\n const session = await signIn(ctx, deps);\n ctx.out(\n `${ctx.theme.ok(ctx.theme.glyph.ok)} Signed in as ${ctx.theme.bold(describeUser(session))}`,\n );\n ctx.out();\n}\n\nasync function setDefaultRoute(ctx: CliContext, route: Route): Promise<void> {\n const global = loadConfig({ home: ctx.home, env: ctx.env });\n await writeGlobalRouting(ctx.home, {\n routes: [...global.routing.routes.filter((r) => r.name !== route.name), route],\n defaultRoute: route.name,\n });\n}\n\n/**\n * Connect one agent: reuse its account (or create one), run the official login when it is not\n * signed in, choose a model and make it the default route. Returns false when the agent is not\n * installed.\n */\nexport async function connectAgent(\n ctx: CliContext,\n provider: ProviderKind,\n prompter: Prompter,\n backend: AccountsBackend,\n deps: OnboardDeps = {},\n): Promise<boolean> {\n const { theme } = ctx;\n const which = deps.which ?? ((binary: string) => whichOnPath(binary, ctx.env));\n const agent = AGENTS.find((a) => a.provider === provider);\n const spec = CLI_LOGINS[provider];\n if (!agent || !spec) throw new Error(`${provider} is not an agent DaveCode can connect`);\n if (!which(spec.binary)) {\n ctx.out(theme.warn(` ${agent.name} is not installed.`));\n ctx.out(theme.dim(` ${spec.installHint}`));\n ctx.out();\n return false;\n }\n\n const account =\n (await backend.list()).find((a) => a.provider === provider) ??\n (await backend.create({ provider, label: agent.name }));\n const connection = await backend.connection(account.id).catch(() => undefined);\n if (connection?.status !== 'connected' || account.status === 'error') {\n const exit = await (deps.vendorLogin ?? ((c, id) => accountsLogin(c, id, [], {}, { backend })))(\n ctx,\n account.id,\n );\n if (exit !== 0) {\n ctx.out(theme.warn(` ${agent.name} did not finish signing in. You can retry later with:`));\n ctx.out(theme.dim(` davecode accounts login ${account.id}`));\n }\n } else {\n ctx.out(`${theme.ok(theme.glyph.ok)} ${agent.name} is already signed in.`);\n }\n\n const discovered =\n provider === 'antigravity-cli'\n ? await (deps.models ?? (() => agyModels(which(spec.binary) ?? spec.binary, ctx.env)))(\n provider,\n )\n : [];\n let model = await prompter.select(`Model for ${agent.name}`, [\n ...agent.models,\n ...discovered,\n { value: OTHER_MODEL, label: 'Another model…', hint: 'type its id' },\n ]);\n if (model === OTHER_MODEL) {\n model = await prompter.text('Model id', {\n validate: (v) =>\n /^[\\w.:[\\]-]+$/.test(v.trim()) ? undefined : 'Use letters, digits, . : - _',\n });\n model = model.trim();\n }\n await setDefaultRoute(ctx, {\n name: 'auto',\n description: `${agent.name} (${model})`,\n targets: [{ provider, model, accountId: account.id }],\n });\n ctx.out(`${theme.ok(theme.glyph.ok)} DaveCode will use ${theme.bold(agent.name)} · ${model}`);\n ctx.out();\n return true;\n}\n\n/** The agent picker shared by first-run setup and /connect. */\nexport function agentChoices(\n ctx: CliContext,\n deps: Pick<OnboardDeps, 'which'> = {},\n): Array<{ value: ProviderKind; label: string; hint: string }> {\n const which = deps.which ?? ((binary: string) => whichOnPath(binary, ctx.env));\n return AGENTS.map((agent) => ({\n value: agent.provider,\n label: agent.name,\n hint: which(CLI_LOGINS[agent.provider]?.binary ?? '') ? 'installed' : 'not installed',\n }));\n}\n\n/** First agent: pick one that is installed, log in with its official CLI, choose a model. */\nasync function connectAgentStep(\n ctx: CliContext,\n prompter: Prompter,\n backend: AccountsBackend,\n deps: OnboardDeps,\n): Promise<void> {\n for (;;) {\n const choice = await prompter.select<string>('Connect your first agent', [\n ...agentChoices(ctx, deps),\n { value: 'later', label: 'Later', hint: 'davecode accounts add' },\n ]);\n if (choice === 'later') return;\n if (await connectAgent(ctx, choice as ProviderKind, prompter, backend, deps)) return;\n }\n}\n\n/**\n * First-run setup, Claude Code style: logo, look, DaveCode account, first agent. Later runs\n * only ask to sign in again when the session is gone. Returns the context to continue with\n * (the chosen theme applied), or undefined when the user quits.\n */\nexport async function ensureReady(\n ctx: CliContext,\n deps: OnboardDeps = {},\n): Promise<CliContext | undefined> {\n const prefs = readPreferences(ctx.home);\n const needsAccount = accountsEnabled(ctx, deps) && !(await currentAccount(ctx, deps));\n if (prefs.onboarded && !needsAccount) return ctx;\n\n let current = ctx;\n const prompter = await prompterFor(ctx, deps);\n try {\n if (!prefs.onboarded) {\n welcome(ctx);\n const mode = await chooseTheme(ctx, prompter);\n writePreferences(ctx.home, { theme: mode });\n current = withTheme(ctx, mode);\n }\n if (needsAccount) await signInStep(current, prompter, deps);\n if (!prefs.onboarded) {\n const backend =\n deps.backend ?? (await openAccounts({ home: current.home, env: current.env, local: true }));\n try {\n const existing = await backend.list();\n if (existing.length === 0) await connectAgentStep(current, prompter, backend, deps);\n } finally {\n if (!deps.backend) backend.close();\n }\n writePreferences(current.home, { onboarded: true });\n }\n return current;\n } catch (err) {\n if (err instanceof PromptCancelledError) {\n ctx.err(ctx.errTheme.dim('Setup cancelled. Run davecode again to continue.'));\n return undefined;\n }\n throw err;\n }\n}\n"],"mappings":"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","names":["resolve","which"]}