@dmrlzz/davecode 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/bin/davecode.js +0 -0
- package/dist/{ChatApp-FO5SABXB.js → ChatApp-CJBICQGA.js} +289 -137
- package/dist/ChatApp-CJBICQGA.js.map +1 -0
- package/dist/{RunnerView-DLVR7C22.js → RunnerView-A7JSPUW5.js} +5 -5
- package/dist/account-QWDPJWAA.js +23 -0
- package/dist/accounts-IQMR72FC.js +37 -0
- package/dist/{budget-RBHCEDPP.js → budget-XANOUVWO.js} +6 -6
- package/dist/chat-KDDRNC5V.js +359 -0
- package/dist/chat-KDDRNC5V.js.map +1 -0
- package/dist/{accounts-MTMGYKEP.js → chunk-44AFJL2X.js} +24 -17
- package/dist/chunk-44AFJL2X.js.map +1 -0
- package/dist/{chunk-BOLFK3BH.js → chunk-5LKOJBUL.js} +2 -2
- package/dist/{chunk-23KTE7IK.js → chunk-AZKACMME.js} +2 -2
- package/dist/{chunk-PIIJ3RSI.js → chunk-FYPMA55O.js} +1269 -1265
- package/dist/chunk-FYPMA55O.js.map +1 -0
- package/dist/{chunk-OYEYNDOO.js → chunk-GE22VBCY.js} +3 -3
- package/dist/{chunk-C7FDRA3U.js → chunk-HSBJDV3O.js} +660 -139
- package/dist/chunk-HSBJDV3O.js.map +1 -0
- package/dist/chunk-JLATEHS7.js +20 -0
- package/dist/chunk-JLATEHS7.js.map +1 -0
- package/dist/{chunk-VVCXGQMY.js → chunk-MC7RIPL7.js} +17 -8
- package/dist/chunk-MC7RIPL7.js.map +1 -0
- package/dist/{chunk-MSLLH5XP.js → chunk-PGAJIGUF.js} +4 -4
- package/dist/{chunk-OXRMGR72.js → chunk-PGPXE6LF.js} +2 -2
- package/dist/chunk-QA3O6RA2.js +81 -0
- package/dist/chunk-QA3O6RA2.js.map +1 -0
- package/dist/chunk-W7GPBEBZ.js +144 -0
- package/dist/chunk-W7GPBEBZ.js.map +1 -0
- package/dist/{chunk-IVZHKUCD.js → chunk-WQ7MEWDF.js} +3 -3
- package/dist/{config-FRMY5OHG.js → config-YTUPIYZT.js} +5 -5
- package/dist/dashboard/assets/Accounts-cq8RLMoI.js +1 -0
- package/dist/dashboard/assets/Badge-Z4RBdO9j.js +55 -0
- package/dist/dashboard/assets/Callout-w8BTYh4k.js +1 -0
- package/dist/dashboard/assets/Field-Cmpgg_1z.js +1 -0
- package/dist/dashboard/assets/Goals-Bw02to72.js +1 -0
- package/dist/dashboard/assets/Library-DK7mlpRb.js +1 -0
- package/dist/dashboard/assets/{Markdown-ClRsddnB.js → Markdown-DCZ4Awcc.js} +8 -8
- package/dist/dashboard/assets/Panes-_KTf8pbZ.js +8 -0
- package/dist/dashboard/assets/Panes-kHJ-D0s7.css +1 -0
- package/dist/dashboard/assets/RoutesPage-QV0oPRW9.js +4 -0
- package/dist/dashboard/assets/Runner-CkHBLQl0.js +1 -0
- package/dist/dashboard/assets/Settings-BLz2gTBR.js +1 -0
- package/dist/dashboard/assets/Switch-DPYlLseH.js +1 -0
- package/dist/dashboard/assets/Tasks-BiUQSTpt.js +2 -0
- package/dist/dashboard/assets/Traffic-BVfBuC70.js +1 -0
- package/dist/dashboard/assets/Workspace-CJTgiiU5.js +1 -0
- package/dist/dashboard/assets/arrow-up-DjhzZprp.js +1 -0
- package/dist/dashboard/assets/cn-BwE4cei0.js +1 -0
- package/dist/dashboard/assets/forms-DVIUAxAc.js +1 -0
- package/dist/dashboard/assets/index-BDBa5cb0.js +104 -0
- package/dist/dashboard/assets/index-BEmBgsbP.css +2 -0
- package/dist/dashboard/assets/task-errors-Daqwi0ue.js +1 -0
- package/dist/dashboard/assets/trash-BTuDcSaQ.js +1 -0
- package/dist/dashboard/favicon.svg +1 -7
- package/dist/dashboard/index.html +4 -4
- package/dist/{dist-ZPXEVBEC.js → dist-37VQSHHA.js} +24 -2
- package/dist/dist-37VQSHHA.js.map +1 -0
- package/dist/{doctor-7RUD4D3A.js → doctor-PYUQRRCB.js} +5 -5
- package/dist/{goal-JFRNPBSD.js → goal-SXZUDUCL.js} +5 -5
- package/dist/index.js +48 -30
- package/dist/index.js.map +1 -1
- package/dist/{init-NFYNO3A3.js → init-Z2AFQEEP.js} +6 -6
- package/dist/{prompts-L37J72YW.js → prompts-TZ7UC42M.js} +9 -5
- package/dist/prompts-TZ7UC42M.js.map +1 -0
- package/dist/{run-ARUPXFFB.js → run-AOS7L3RT.js} +10 -10
- package/dist/runtime.js +18 -0
- package/dist/runtime.js.map +1 -0
- package/dist/{start-CFPOVIAR.js → start-CEPXKZUE.js} +5 -5
- package/dist/{status-E4EACVE2.js → status-WNJ3GGKU.js} +6 -6
- package/dist/status-WNJ3GGKU.js.map +1 -0
- package/dist/{tasks-ZIK6BVEX.js → tasks-TFUTUMWB.js} +6 -6
- package/package.json +21 -15
- package/dist/ChatApp-FO5SABXB.js.map +0 -1
- package/dist/accounts-MTMGYKEP.js.map +0 -1
- package/dist/chat-ZDXX3N6X.js +0 -95
- package/dist/chat-ZDXX3N6X.js.map +0 -1
- package/dist/chunk-C7FDRA3U.js.map +0 -1
- package/dist/chunk-DYQ56FBT.js +0 -47
- package/dist/chunk-DYQ56FBT.js.map +0 -1
- package/dist/chunk-PIIJ3RSI.js.map +0 -1
- package/dist/chunk-VVCXGQMY.js.map +0 -1
- package/dist/dashboard/assets/Accounts-BR3ZfVk4.js +0 -1
- package/dist/dashboard/assets/Badge-B-qzNRrZ.js +0 -55
- package/dist/dashboard/assets/Callout-B9g_wPDi.js +0 -1
- package/dist/dashboard/assets/Field-BfabPEcY.js +0 -1
- package/dist/dashboard/assets/Goals-BsV-6m94.js +0 -1
- package/dist/dashboard/assets/Library-CEA9P1m-.js +0 -1
- package/dist/dashboard/assets/Panel-B9tSgX6l.js +0 -1
- package/dist/dashboard/assets/RoutesPage-Dh-BJ3ir.js +0 -4
- package/dist/dashboard/assets/Runner-C_e9l5l2.js +0 -1
- package/dist/dashboard/assets/Settings-C6Yc1Gjg.js +0 -1
- package/dist/dashboard/assets/Switch-CUpOJjUT.js +0 -1
- package/dist/dashboard/assets/Tasks-CTku0rR3.js +0 -2
- package/dist/dashboard/assets/Traffic-CE6wZSMr.js +0 -1
- package/dist/dashboard/assets/Workspace-CxFxvkA6.js +0 -1
- package/dist/dashboard/assets/arrow-up-DL3CuFOO.js +0 -1
- package/dist/dashboard/assets/forms-D6UIYgC5.js +0 -1
- package/dist/dashboard/assets/index-1iH716Xy.css +0 -2
- package/dist/dashboard/assets/index-BMWr9EKo.js +0 -104
- package/dist/dashboard/assets/task-errors-CE4oEr8H.js +0 -1
- package/dist/dashboard/assets/trash-CWqeZ7eg.js +0 -1
- package/dist/prompts-L37J72YW.js.map +0 -1
- /package/dist/{RunnerView-DLVR7C22.js.map → RunnerView-A7JSPUW5.js.map} +0 -0
- /package/dist/{dist-ZPXEVBEC.js.map → account-QWDPJWAA.js.map} +0 -0
- /package/dist/{status-E4EACVE2.js.map → accounts-IQMR72FC.js.map} +0 -0
- /package/dist/{budget-RBHCEDPP.js.map → budget-XANOUVWO.js.map} +0 -0
- /package/dist/{chunk-BOLFK3BH.js.map → chunk-5LKOJBUL.js.map} +0 -0
- /package/dist/{chunk-23KTE7IK.js.map → chunk-AZKACMME.js.map} +0 -0
- /package/dist/{chunk-OYEYNDOO.js.map → chunk-GE22VBCY.js.map} +0 -0
- /package/dist/{chunk-MSLLH5XP.js.map → chunk-PGAJIGUF.js.map} +0 -0
- /package/dist/{chunk-OXRMGR72.js.map → chunk-PGPXE6LF.js.map} +0 -0
- /package/dist/{chunk-IVZHKUCD.js.map → chunk-WQ7MEWDF.js.map} +0 -0
- /package/dist/{config-FRMY5OHG.js.map → config-YTUPIYZT.js.map} +0 -0
- /package/dist/{doctor-7RUD4D3A.js.map → doctor-PYUQRRCB.js.map} +0 -0
- /package/dist/{goal-JFRNPBSD.js.map → goal-SXZUDUCL.js.map} +0 -0
- /package/dist/{init-NFYNO3A3.js.map → init-Z2AFQEEP.js.map} +0 -0
- /package/dist/{run-ARUPXFFB.js.map → run-AOS7L3RT.js.map} +0 -0
- /package/dist/{start-CFPOVIAR.js.map → start-CEPXKZUE.js.map} +0 -0
- /package/dist/{tasks-ZIK6BVEX.js.map → tasks-TFUTUMWB.js.map} +0 -0
|
@@ -1,35 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatTaskTree,
|
|
3
|
+
summaryLine
|
|
4
|
+
} from "./chunk-AZKACMME.js";
|
|
5
|
+
import {
|
|
6
|
+
brandBanner
|
|
7
|
+
} from "./chunk-JLATEHS7.js";
|
|
1
8
|
import {
|
|
2
9
|
Spinner
|
|
3
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5LKOJBUL.js";
|
|
4
11
|
import {
|
|
5
12
|
ThemeProvider,
|
|
6
13
|
useTheme
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import {
|
|
9
|
-
formatTaskTree,
|
|
10
|
-
summaryLine
|
|
11
|
-
} from "./chunk-23KTE7IK.js";
|
|
14
|
+
} from "./chunk-PGPXE6LF.js";
|
|
12
15
|
import {
|
|
13
16
|
emptyUsage,
|
|
14
17
|
renderAccounts
|
|
15
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-PGAJIGUF.js";
|
|
16
19
|
import {
|
|
17
20
|
bar,
|
|
18
|
-
formatDuration,
|
|
19
21
|
formatTokens,
|
|
20
22
|
levelStyle,
|
|
21
23
|
padEnd,
|
|
22
24
|
percent,
|
|
23
25
|
visibleWidth
|
|
24
26
|
} from "./chunk-SF5ZEAP4.js";
|
|
25
|
-
import "./chunk-
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-PIIJ3RSI.js";
|
|
27
|
+
import "./chunk-QA3O6RA2.js";
|
|
28
|
+
import "./chunk-FYPMA55O.js";
|
|
28
29
|
import "./chunk-7XVXEO7U.js";
|
|
29
|
-
import "./chunk-
|
|
30
|
+
import "./chunk-HSBJDV3O.js";
|
|
31
|
+
import "./chunk-MC7RIPL7.js";
|
|
30
32
|
|
|
31
33
|
// src/tui/ChatApp.tsx
|
|
32
|
-
import { Box as
|
|
34
|
+
import { Box as Box5, Static, useApp, useInput, usePaste, useStdout, useWindowSize } from "ink";
|
|
33
35
|
import { useCallback, useEffect, useReducer, useRef, useState } from "react";
|
|
34
36
|
|
|
35
37
|
// src/tui/chat-state.ts
|
|
@@ -327,55 +329,95 @@ function InputBox({
|
|
|
327
329
|
}
|
|
328
330
|
);
|
|
329
331
|
}
|
|
330
|
-
function SlashHints({
|
|
332
|
+
function SlashHints({
|
|
333
|
+
commands,
|
|
334
|
+
width,
|
|
335
|
+
selected = 0
|
|
336
|
+
}) {
|
|
331
337
|
const theme = useTheme();
|
|
332
338
|
if (commands.length === 0) return null;
|
|
333
339
|
const nameWidth = Math.max(...commands.map((c) => c.name.length + (c.args ? c.args.length + 1 : 0))) + 3;
|
|
334
|
-
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingX:
|
|
335
|
-
|
|
336
|
-
/* @__PURE__ */
|
|
337
|
-
|
|
340
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingX: 1, width, children: commands.map((c, i) => {
|
|
341
|
+
const active = i === selected;
|
|
342
|
+
return /* @__PURE__ */ jsxs(Text, { wrap: "truncate-end", children: [
|
|
343
|
+
/* @__PURE__ */ jsx(Text, { bold: active, dimColor: !active && theme.ink.dim, children: `${active ? theme.glyph.prompt : " "} ${`/${c.name}${c.args ? ` ${c.args}` : ""}`.padEnd(nameWidth)}` }),
|
|
344
|
+
/* @__PURE__ */ jsx(Text, { dimColor: theme.ink.dim, children: c.description })
|
|
345
|
+
] }, c.name);
|
|
346
|
+
}) });
|
|
338
347
|
}
|
|
339
348
|
|
|
340
|
-
// src/tui/components/
|
|
349
|
+
// src/tui/components/Picker.tsx
|
|
341
350
|
import { Box as Box2, Text as Text2 } from "ink";
|
|
342
351
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
352
|
+
function Picker({
|
|
353
|
+
title,
|
|
354
|
+
options,
|
|
355
|
+
index
|
|
356
|
+
}) {
|
|
357
|
+
const theme = useTheme();
|
|
358
|
+
const numbered = options.length <= 9;
|
|
359
|
+
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginTop: 1, children: [
|
|
360
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, children: title }),
|
|
361
|
+
options.map((option, i) => {
|
|
362
|
+
const on = i === index;
|
|
363
|
+
return /* @__PURE__ */ jsxs2(Text2, { dimColor: !on && theme.ink.dim, children: [
|
|
364
|
+
on ? "\u203A " : " ",
|
|
365
|
+
numbered ? `${i + 1}. ` : "",
|
|
366
|
+
/* @__PURE__ */ jsx2(Text2, { bold: on, children: option.label }),
|
|
367
|
+
option.hint ? /* @__PURE__ */ jsxs2(Text2, { dimColor: theme.ink.dim, children: [
|
|
368
|
+
" ",
|
|
369
|
+
option.hint
|
|
370
|
+
] }) : null
|
|
371
|
+
] }, option.value);
|
|
372
|
+
}),
|
|
373
|
+
/* @__PURE__ */ jsxs2(Text2, { dimColor: theme.ink.dim, children: [
|
|
374
|
+
"\u2191\u2193 select \xB7 enter choose",
|
|
375
|
+
numbered ? " \xB7 1-9" : "",
|
|
376
|
+
" \xB7 esc cancel"
|
|
377
|
+
] })
|
|
378
|
+
] });
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// src/tui/components/StatusLine.tsx
|
|
382
|
+
import { Box as Box3, Text as Text3 } from "ink";
|
|
383
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
343
384
|
function statusSegments(theme, state, info, width) {
|
|
344
385
|
const sep = theme.dim(" \xB7 ");
|
|
345
|
-
const left2 = [theme.accent(state.model)];
|
|
386
|
+
const left2 = [[9, theme.accent(state.model)]];
|
|
346
387
|
if (state.lastAccount) {
|
|
347
388
|
const name = state.lastAccount.label ?? state.lastAccount.id;
|
|
348
|
-
left2.push(
|
|
389
|
+
left2.push([
|
|
390
|
+
8,
|
|
349
391
|
`${name}${state.lastAccount.provider ? theme.dim(` (${state.lastAccount.provider})`) : ""}`
|
|
350
|
-
);
|
|
392
|
+
]);
|
|
393
|
+
}
|
|
394
|
+
if (state.totalFailovers > 0) {
|
|
395
|
+
left2.push([7, theme.warn(`${state.lastFailovers}/${state.totalFailovers} failovers`)]);
|
|
396
|
+
}
|
|
397
|
+
if (state.tokens.prompt + state.tokens.completion > 0) {
|
|
398
|
+
const arrows = theme.unicode ? ["\u2191", "\u2193"] : ["in", "out"];
|
|
399
|
+
left2.push([
|
|
400
|
+
5,
|
|
401
|
+
theme.dim(
|
|
402
|
+
`${formatTokens(state.tokens.prompt)}${arrows[0]} ${formatTokens(state.tokens.completion)}${arrows[1]}`
|
|
403
|
+
)
|
|
404
|
+
]);
|
|
351
405
|
}
|
|
352
|
-
const failovers = state.totalFailovers > 0 ? theme.warn(`${state.lastFailovers}/${state.totalFailovers} failovers`) : theme.dim("0 failovers");
|
|
353
|
-
left2.push(failovers);
|
|
354
|
-
const arrows = theme.unicode ? ["\u2191", "\u2193"] : ["in", "out"];
|
|
355
|
-
left2.push(
|
|
356
|
-
theme.dim(
|
|
357
|
-
`${formatTokens(state.tokens.prompt)}${arrows[0]} ${formatTokens(state.tokens.completion)}${arrows[1]}`
|
|
358
|
-
)
|
|
359
|
-
);
|
|
360
406
|
if (state.quota5h !== void 0) {
|
|
361
|
-
left2.push(
|
|
407
|
+
left2.push([
|
|
408
|
+
6,
|
|
362
409
|
`${theme.dim("5h")} ${bar(theme, state.quota5h, 6)} ${levelStyle(theme, state.quota5h)(percent(state.quota5h))}`
|
|
363
|
-
);
|
|
410
|
+
]);
|
|
364
411
|
}
|
|
365
|
-
|
|
366
|
-
let right2;
|
|
412
|
+
let right2 = "";
|
|
367
413
|
if (info.notice) right2 = theme.warn(info.notice);
|
|
368
|
-
else if (state.connection === "
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const priorities = [0, 1, 2, 4, 3];
|
|
373
|
-
let kept = left2.map((_, i) => i);
|
|
374
|
-
const render = () => kept.map((i) => left2[i]).join(sep);
|
|
414
|
+
else if (state.connection === "connecting") right2 = theme.dim("connecting");
|
|
415
|
+
else if (state.connection === "offline") right2 = theme.error("offline");
|
|
416
|
+
let kept = left2;
|
|
417
|
+
const render = () => kept.map(([, text]) => text).join(sep);
|
|
375
418
|
while (kept.length > 1 && visibleWidth(render()) + visibleWidth(right2) + 2 > width) {
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
kept = kept.filter((i) => i !== drop);
|
|
419
|
+
const lowest = Math.min(...kept.map(([p]) => p));
|
|
420
|
+
kept = kept.filter(([p]) => p !== lowest);
|
|
379
421
|
}
|
|
380
422
|
return { left: render(), right: right2 };
|
|
381
423
|
}
|
|
@@ -386,15 +428,15 @@ function StatusLine({
|
|
|
386
428
|
}) {
|
|
387
429
|
const theme = useTheme();
|
|
388
430
|
const { left: left2, right: right2 } = statusSegments(theme, state, info, width - 2);
|
|
389
|
-
return /* @__PURE__ */
|
|
390
|
-
/* @__PURE__ */
|
|
391
|
-
/* @__PURE__ */
|
|
431
|
+
return /* @__PURE__ */ jsxs3(Box3, { width, justifyContent: "space-between", paddingX: 1, children: [
|
|
432
|
+
/* @__PURE__ */ jsx3(Text3, { wrap: "truncate-end", children: left2 }),
|
|
433
|
+
/* @__PURE__ */ jsx3(Text3, { wrap: "truncate-start", children: right2 })
|
|
392
434
|
] });
|
|
393
435
|
}
|
|
394
436
|
|
|
395
437
|
// src/tui/components/Transcript.tsx
|
|
396
|
-
import { Box as
|
|
397
|
-
import { jsx as
|
|
438
|
+
import { Box as Box4, Text as Text4 } from "ink";
|
|
439
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
398
440
|
function metaLine(meta) {
|
|
399
441
|
const parts = [];
|
|
400
442
|
if (meta.accountLabel ?? meta.accountId) {
|
|
@@ -409,46 +451,46 @@ function metaLine(meta) {
|
|
|
409
451
|
return parts.join(" \xB7 ");
|
|
410
452
|
}
|
|
411
453
|
function Marker({ color, glyph }) {
|
|
412
|
-
return /* @__PURE__ */
|
|
454
|
+
return /* @__PURE__ */ jsx4(Box4, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx4(Text4, { color, children: glyph }) });
|
|
413
455
|
}
|
|
414
456
|
function EntryView({ entry }) {
|
|
415
457
|
const theme = useTheme();
|
|
416
458
|
switch (entry.kind) {
|
|
417
459
|
case "banner":
|
|
418
|
-
return /* @__PURE__ */
|
|
460
|
+
return /* @__PURE__ */ jsx4(Box4, { marginBottom: 1, children: /* @__PURE__ */ jsx4(Text4, { children: entry.text }) });
|
|
419
461
|
case "user":
|
|
420
|
-
return /* @__PURE__ */
|
|
421
|
-
/* @__PURE__ */
|
|
422
|
-
/* @__PURE__ */
|
|
462
|
+
return /* @__PURE__ */ jsxs4(Box4, { marginBottom: 1, children: [
|
|
463
|
+
/* @__PURE__ */ jsx4(Marker, { color: theme.ink.accent, glyph: theme.glyph.prompt }),
|
|
464
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: theme.ink.dim, children: entry.text })
|
|
423
465
|
] });
|
|
424
466
|
case "assistant":
|
|
425
|
-
return /* @__PURE__ */
|
|
426
|
-
/* @__PURE__ */
|
|
427
|
-
/* @__PURE__ */
|
|
428
|
-
/* @__PURE__ */
|
|
467
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginBottom: 1, children: [
|
|
468
|
+
/* @__PURE__ */ jsxs4(Box4, { children: [
|
|
469
|
+
/* @__PURE__ */ jsx4(Marker, { color: theme.ink.accent, glyph: theme.glyph.dot }),
|
|
470
|
+
/* @__PURE__ */ jsx4(Text4, { children: entry.text || (entry.meta?.cancelled ? "(cancelled before any output)" : "") })
|
|
429
471
|
] }),
|
|
430
|
-
entry.meta ? /* @__PURE__ */
|
|
472
|
+
entry.meta ? /* @__PURE__ */ jsx4(Box4, { paddingLeft: 2, children: /* @__PURE__ */ jsx4(Text4, { dimColor: theme.ink.dim, children: metaLine(entry.meta) }) }) : null
|
|
431
473
|
] });
|
|
432
474
|
case "error":
|
|
433
|
-
return /* @__PURE__ */
|
|
434
|
-
/* @__PURE__ */
|
|
435
|
-
/* @__PURE__ */
|
|
475
|
+
return /* @__PURE__ */ jsxs4(Box4, { marginBottom: 1, children: [
|
|
476
|
+
/* @__PURE__ */ jsx4(Marker, { color: theme.ink.error, glyph: theme.glyph.fail }),
|
|
477
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.ink.error, children: entry.text })
|
|
436
478
|
] });
|
|
437
479
|
default:
|
|
438
|
-
return /* @__PURE__ */
|
|
480
|
+
return /* @__PURE__ */ jsx4(Box4, { marginBottom: 1, paddingLeft: 2, children: /* @__PURE__ */ jsx4(Text4, { children: entry.text }) });
|
|
439
481
|
}
|
|
440
482
|
}
|
|
441
483
|
function StreamingView({ streaming, now }) {
|
|
442
484
|
const theme = useTheme();
|
|
443
485
|
const seconds = Math.max(0, (now - streaming.startedAt) / 1e3).toFixed(0);
|
|
444
|
-
return /* @__PURE__ */
|
|
445
|
-
streaming.text ? /* @__PURE__ */
|
|
446
|
-
/* @__PURE__ */
|
|
447
|
-
/* @__PURE__ */
|
|
486
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginBottom: 1, children: [
|
|
487
|
+
streaming.text ? /* @__PURE__ */ jsxs4(Box4, { children: [
|
|
488
|
+
/* @__PURE__ */ jsx4(Marker, { color: theme.ink.accent, glyph: theme.glyph.dot }),
|
|
489
|
+
/* @__PURE__ */ jsx4(Text4, { children: streaming.text })
|
|
448
490
|
] }) : null,
|
|
449
|
-
/* @__PURE__ */
|
|
450
|
-
/* @__PURE__ */
|
|
451
|
-
/* @__PURE__ */
|
|
491
|
+
/* @__PURE__ */ jsxs4(Box4, { paddingLeft: streaming.text ? 2 : 0, children: [
|
|
492
|
+
/* @__PURE__ */ jsx4(Spinner, {}),
|
|
493
|
+
/* @__PURE__ */ jsxs4(Text4, { dimColor: theme.ink.dim, children: [
|
|
452
494
|
" ",
|
|
453
495
|
streaming.text ? "streaming" : "thinking",
|
|
454
496
|
" ",
|
|
@@ -462,10 +504,17 @@ function StreamingView({ streaming, now }) {
|
|
|
462
504
|
// src/tui/slash.ts
|
|
463
505
|
var SLASH_COMMANDS = [
|
|
464
506
|
{ name: "model", args: "[id]", description: "show models or switch, e.g. /model davecode/auto" },
|
|
507
|
+
{
|
|
508
|
+
name: "connect",
|
|
509
|
+
description: "connect Claude Code, Codex or Antigravity, or sign in to one again"
|
|
510
|
+
},
|
|
465
511
|
{ name: "route", description: "routes and their failover targets" },
|
|
466
512
|
{ name: "accounts", description: "accounts with 5h quota usage" },
|
|
467
513
|
{ name: "tasks", description: "the project task graph" },
|
|
468
|
-
{ name: "status", description: "
|
|
514
|
+
{ name: "status", description: "model, agents and whether they are signed in" },
|
|
515
|
+
{ name: "login", description: "sign in to your DaveCode account in the browser" },
|
|
516
|
+
{ name: "logout", description: "sign out of your DaveCode account" },
|
|
517
|
+
{ name: "account", description: "the signed-in DaveCode account" },
|
|
469
518
|
{ name: "clear", description: "clear the transcript and start a new conversation" },
|
|
470
519
|
{ name: "help", description: "commands and keyboard shortcuts", aliases: ["?"] },
|
|
471
520
|
{ name: "exit", description: "quit DaveCode", aliases: ["quit", "q"] }
|
|
@@ -487,16 +536,11 @@ function slashSuggestions(input) {
|
|
|
487
536
|
(c) => c.name.startsWith(prefix) || c.aliases?.some((a) => a.startsWith(prefix) && prefix)
|
|
488
537
|
);
|
|
489
538
|
}
|
|
490
|
-
function completeSlash(input) {
|
|
491
|
-
const [first] = slashSuggestions(input);
|
|
492
|
-
if (!first) return void 0;
|
|
493
|
-
return `/${first.name}${first.args ? " " : ""}`;
|
|
494
|
-
}
|
|
495
539
|
var KEY_HINTS = [
|
|
496
540
|
["Enter", "send"],
|
|
497
541
|
["Shift+Enter, Ctrl+J or \\ Enter", "new line"],
|
|
498
542
|
["\u2191 / \u2193", "move between lines, then through history"],
|
|
499
|
-
["
|
|
543
|
+
["/", "command menu: \u2191 / \u2193 to choose, Enter to run, Tab to fill, Esc to close"],
|
|
500
544
|
["Esc", "cancel the response in flight"],
|
|
501
545
|
["Ctrl+U / Ctrl+K / Ctrl+W", "delete to line start / line end / previous word"],
|
|
502
546
|
["Ctrl+C twice", "exit"]
|
|
@@ -575,49 +619,72 @@ async function tasksText(theme, backend, columns) {
|
|
|
575
619
|
...formatTaskTree(theme, graph, { width: columns })
|
|
576
620
|
].join("\n");
|
|
577
621
|
}
|
|
578
|
-
async function statusText(theme, backend) {
|
|
622
|
+
async function statusText(theme, backend, model) {
|
|
579
623
|
const health = await backend.health();
|
|
580
|
-
if (!health) return theme.error(
|
|
581
|
-
const runner = await
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
624
|
+
if (!health) return theme.error("DaveCode is not answering. Restart it with davecode.");
|
|
625
|
+
const [accounts, runner] = await Promise.all([
|
|
626
|
+
backend.accounts(),
|
|
627
|
+
backend.runner().catch(() => void 0)
|
|
628
|
+
]);
|
|
629
|
+
const state = (status) => status === "error" ? theme.error("needs sign-in \xB7 /connect") : status === "cooldown" ? theme.warn("cooling down") : status === "disabled" ? theme.dim("off") : theme.ok("ready");
|
|
630
|
+
const lines2 = [`${theme.dim("model ")} ${model}`];
|
|
631
|
+
if (accounts.length === 0) lines2.push(`${theme.dim("agents")} none yet \xB7 /connect`);
|
|
632
|
+
for (const [i, account] of accounts.entries()) {
|
|
633
|
+
lines2.push(
|
|
634
|
+
`${theme.dim(i === 0 ? "agents" : " ")} ${account.label} ${state(account.status)}`
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
lines2.push(`${theme.dim("runner")} ${runner ? runner.state : "unknown"}`);
|
|
638
|
+
return lines2.join("\n");
|
|
588
639
|
}
|
|
589
640
|
|
|
590
641
|
// src/tui/ChatApp.tsx
|
|
591
|
-
import { jsx as
|
|
592
|
-
var PLACEHOLDER = "Ask anything
|
|
642
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
643
|
+
var PLACEHOLDER = "Ask anything, or type / for commands";
|
|
593
644
|
var EXIT_WINDOW_MS = 2e3;
|
|
594
645
|
function errorText(err) {
|
|
595
646
|
return err instanceof Error ? err.message : String(err);
|
|
596
647
|
}
|
|
597
|
-
function Chat({
|
|
648
|
+
function Chat({
|
|
649
|
+
backend,
|
|
650
|
+
model,
|
|
651
|
+
version,
|
|
652
|
+
project,
|
|
653
|
+
account,
|
|
654
|
+
connect,
|
|
655
|
+
pollMs = 1e4,
|
|
656
|
+
now = Date.now
|
|
657
|
+
}) {
|
|
598
658
|
const theme = useTheme();
|
|
599
659
|
const { exit } = useApp();
|
|
600
660
|
const { write } = useStdout();
|
|
601
661
|
const { columns } = useWindowSize();
|
|
602
662
|
const width = Math.max(20, columns);
|
|
663
|
+
const widthRef = useRef(width);
|
|
664
|
+
widthRef.current = width;
|
|
603
665
|
const [state, dispatch] = useReducer(chatReducer, model, initialChatState);
|
|
604
666
|
const [editor, setEditor] = useState(emptyEditor);
|
|
605
667
|
const [historyIndex, setHistoryIndex] = useState();
|
|
606
668
|
const [notice, setNotice] = useState();
|
|
607
669
|
const [clock, setClock] = useState(now());
|
|
670
|
+
const [slashIndex, setSlashIndex] = useState(0);
|
|
671
|
+
const [picker, setPicker] = useState();
|
|
608
672
|
const abortRef = useRef(void 0);
|
|
609
673
|
const exitArmedAt = useRef(void 0);
|
|
610
674
|
const labels = useRef(/* @__PURE__ */ new Map());
|
|
611
675
|
const stateRef = useRef(state);
|
|
612
676
|
stateRef.current = state;
|
|
613
677
|
useEffect(() => {
|
|
614
|
-
const where = backend.inProcess ? `${backend.url} (in-process)` : backend.url;
|
|
615
678
|
dispatch({
|
|
616
679
|
type: "banner",
|
|
617
|
-
text:
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
680
|
+
text: brandBanner(
|
|
681
|
+
theme,
|
|
682
|
+
[
|
|
683
|
+
`${theme.bold("DaveCode")} ${theme.dim(`v${version}`)}`,
|
|
684
|
+
...project ? [theme.dim(project)] : []
|
|
685
|
+
],
|
|
686
|
+
widthRef.current
|
|
687
|
+
).join("\n")
|
|
621
688
|
});
|
|
622
689
|
let alive = true;
|
|
623
690
|
const check = async () => {
|
|
@@ -635,7 +702,7 @@ ${theme.dim(
|
|
|
635
702
|
clearInterval(timer);
|
|
636
703
|
abortRef.current?.abort();
|
|
637
704
|
};
|
|
638
|
-
}, [backend,
|
|
705
|
+
}, [backend, pollMs, project, theme, version]);
|
|
639
706
|
useEffect(() => {
|
|
640
707
|
if (!state.streaming) return;
|
|
641
708
|
const timer = setInterval(() => setClock(now()), 250);
|
|
@@ -663,11 +730,11 @@ ${theme.dim(
|
|
|
663
730
|
[backend]
|
|
664
731
|
);
|
|
665
732
|
const send = useCallback(
|
|
666
|
-
async (
|
|
667
|
-
dispatch({ type: "user", text });
|
|
733
|
+
async (text2) => {
|
|
734
|
+
dispatch({ type: "user", text: text2 });
|
|
668
735
|
const conversation = [
|
|
669
736
|
...stateRef.current.conversation,
|
|
670
|
-
{ role: "user", content:
|
|
737
|
+
{ role: "user", content: text2 }
|
|
671
738
|
];
|
|
672
739
|
const controller = new AbortController();
|
|
673
740
|
abortRef.current = controller;
|
|
@@ -706,14 +773,17 @@ ${theme.dim(
|
|
|
706
773
|
} else {
|
|
707
774
|
const status = err.status;
|
|
708
775
|
if (status === 0) dispatch({ type: "connection", connection: "offline" });
|
|
709
|
-
|
|
776
|
+
let text3 = errorText(err);
|
|
777
|
+
if (connect)
|
|
778
|
+
text3 = text3.replace(/Run: davecode accounts login \S+/, "Type /connect to sign in.");
|
|
779
|
+
dispatch({ type: "stream-end", now: now(), error: text3 });
|
|
710
780
|
}
|
|
711
781
|
} finally {
|
|
712
782
|
if (abortRef.current === controller) abortRef.current = void 0;
|
|
713
783
|
}
|
|
714
784
|
if (accountId) void refreshQuota(accountId);
|
|
715
785
|
},
|
|
716
|
-
[backend, now, refreshQuota]
|
|
786
|
+
[backend, connect, now, refreshQuota]
|
|
717
787
|
);
|
|
718
788
|
const runSlash = useCallback(
|
|
719
789
|
async (input) => {
|
|
@@ -741,17 +811,55 @@ ${theme.dim(
|
|
|
741
811
|
write("\x1B[2J\x1B[3J\x1B[H");
|
|
742
812
|
dispatch({ type: "clear" });
|
|
743
813
|
break;
|
|
744
|
-
case "model":
|
|
814
|
+
case "model": {
|
|
815
|
+
const choose = (id) => {
|
|
816
|
+
dispatch({ type: "set-model", model: id });
|
|
817
|
+
dispatch({ type: "info", text: `Model set to ${theme.accent(id)}` });
|
|
818
|
+
};
|
|
745
819
|
if (args) {
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
}
|
|
820
|
+
choose(args);
|
|
821
|
+
break;
|
|
822
|
+
}
|
|
823
|
+
const ids = (await backend.models()).map((m) => m.id).sort(
|
|
824
|
+
(a, b) => Number(!a.startsWith("davecode/")) - Number(!b.startsWith("davecode/")) || a.localeCompare(b)
|
|
825
|
+
);
|
|
826
|
+
if (ids.length === 0) {
|
|
749
827
|
dispatch({
|
|
750
828
|
type: "info",
|
|
751
829
|
text: await modelsText(theme, backend, stateRef.current.model)
|
|
752
830
|
});
|
|
831
|
+
break;
|
|
753
832
|
}
|
|
833
|
+
const current = stateRef.current.model;
|
|
834
|
+
setPicker({
|
|
835
|
+
title: "Choose a model",
|
|
836
|
+
options: ids.map((id) => ({
|
|
837
|
+
value: id,
|
|
838
|
+
label: id,
|
|
839
|
+
...id === current ? { hint: "(current)" } : {}
|
|
840
|
+
})),
|
|
841
|
+
index: Math.max(0, ids.indexOf(current)),
|
|
842
|
+
pick: choose
|
|
843
|
+
});
|
|
754
844
|
break;
|
|
845
|
+
}
|
|
846
|
+
case "connect": {
|
|
847
|
+
if (!connect) {
|
|
848
|
+
dispatch({ type: "info", text: "Connect agents with davecode accounts add." });
|
|
849
|
+
break;
|
|
850
|
+
}
|
|
851
|
+
setPicker({
|
|
852
|
+
title: "Connect an agent",
|
|
853
|
+
options: await connect.agents(),
|
|
854
|
+
index: 0,
|
|
855
|
+
pick: (provider) => {
|
|
856
|
+
abortRef.current?.abort();
|
|
857
|
+
connect.choose(provider);
|
|
858
|
+
exit();
|
|
859
|
+
}
|
|
860
|
+
});
|
|
861
|
+
break;
|
|
862
|
+
}
|
|
755
863
|
case "route":
|
|
756
864
|
dispatch({ type: "info", text: await routesText(theme, backend) });
|
|
757
865
|
break;
|
|
@@ -765,22 +873,39 @@ ${theme.dim(
|
|
|
765
873
|
dispatch({ type: "info", text: await tasksText(theme, backend, width - 4) });
|
|
766
874
|
break;
|
|
767
875
|
case "status":
|
|
768
|
-
dispatch({
|
|
876
|
+
dispatch({
|
|
877
|
+
type: "info",
|
|
878
|
+
text: await statusText(theme, backend, stateRef.current.model)
|
|
879
|
+
});
|
|
769
880
|
break;
|
|
881
|
+
case "login":
|
|
882
|
+
case "logout":
|
|
883
|
+
case "account": {
|
|
884
|
+
if (!account) {
|
|
885
|
+
dispatch({
|
|
886
|
+
type: "info",
|
|
887
|
+
text: "DaveCode accounts are not available in this build."
|
|
888
|
+
});
|
|
889
|
+
break;
|
|
890
|
+
}
|
|
891
|
+
const text2 = command.name === "login" ? await account.login((note) => dispatch({ type: "info", text: theme.dim(note) })) : command.name === "logout" ? await account.logout() : await account.status();
|
|
892
|
+
dispatch({ type: "info", text: text2 });
|
|
893
|
+
break;
|
|
894
|
+
}
|
|
770
895
|
}
|
|
771
896
|
} catch (err) {
|
|
772
897
|
dispatch({ type: "error", text: `/${command.name} failed: ${errorText(err)}` });
|
|
773
898
|
}
|
|
774
899
|
},
|
|
775
|
-
[backend, exit, theme, width, write]
|
|
900
|
+
[account, backend, connect, exit, theme, width, write]
|
|
776
901
|
);
|
|
777
902
|
const submit = useCallback(() => {
|
|
778
|
-
const
|
|
779
|
-
if (!
|
|
780
|
-
if (parseSlash(
|
|
903
|
+
const text2 = textOf(editor).trim();
|
|
904
|
+
if (!text2) return;
|
|
905
|
+
if (parseSlash(text2).kind !== "none") {
|
|
781
906
|
setEditor(emptyEditor);
|
|
782
907
|
setHistoryIndex(void 0);
|
|
783
|
-
void runSlash(
|
|
908
|
+
void runSlash(text2);
|
|
784
909
|
return;
|
|
785
910
|
}
|
|
786
911
|
if (stateRef.current.streaming) {
|
|
@@ -789,7 +914,7 @@ ${theme.dim(
|
|
|
789
914
|
}
|
|
790
915
|
setEditor(emptyEditor);
|
|
791
916
|
setHistoryIndex(void 0);
|
|
792
|
-
void send(
|
|
917
|
+
void send(text2);
|
|
793
918
|
}, [editor, runSlash, send]);
|
|
794
919
|
const recall = (direction) => {
|
|
795
920
|
const { history } = stateRef.current;
|
|
@@ -814,6 +939,37 @@ ${theme.dim(
|
|
|
814
939
|
return;
|
|
815
940
|
}
|
|
816
941
|
exitArmedAt.current = void 0;
|
|
942
|
+
if (picker) {
|
|
943
|
+
const count = picker.options.length;
|
|
944
|
+
const move = (index) => setPicker({ ...picker, index });
|
|
945
|
+
if (key.escape) return setPicker(void 0);
|
|
946
|
+
if (key.upArrow) return move((picker.index - 1 + count) % count);
|
|
947
|
+
if (key.downArrow) return move((picker.index + 1) % count);
|
|
948
|
+
const digit = count <= 9 && /^[1-9]$/.test(input) ? Number(input) - 1 : void 0;
|
|
949
|
+
if (key.return || digit !== void 0 && digit < count) {
|
|
950
|
+
const option = picker.options[digit ?? picker.index];
|
|
951
|
+
setPicker(void 0);
|
|
952
|
+
if (option) picker.pick(option.value);
|
|
953
|
+
}
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
956
|
+
const menu = slashSuggestions(textOf(editor));
|
|
957
|
+
if (menu.length > 0) {
|
|
958
|
+
const selected = menu[Math.min(slashIndex, menu.length - 1)];
|
|
959
|
+
if (key.upArrow) return setSlashIndex((i) => (i - 1 + menu.length) % menu.length);
|
|
960
|
+
if (key.downArrow) return setSlashIndex((i) => (i + 1) % menu.length);
|
|
961
|
+
if (key.escape) return setEditor(emptyEditor);
|
|
962
|
+
if (key.tab) {
|
|
963
|
+
setEditor(fromText(`/${selected.name}${selected.args ? " " : ""}`));
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
if (key.return && !key.shift && !key.meta) {
|
|
967
|
+
setEditor(emptyEditor);
|
|
968
|
+
setHistoryIndex(void 0);
|
|
969
|
+
void runSlash(`/${selected.name}`);
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
817
973
|
if (key.escape) {
|
|
818
974
|
if (stateRef.current.streaming) abortRef.current?.abort();
|
|
819
975
|
return;
|
|
@@ -828,11 +984,7 @@ ${theme.dim(
|
|
|
828
984
|
else submit();
|
|
829
985
|
return;
|
|
830
986
|
}
|
|
831
|
-
if (key.tab)
|
|
832
|
-
const completed = completeSlash(textOf(editor));
|
|
833
|
-
if (completed) setEditor(fromText(completed));
|
|
834
|
-
return;
|
|
835
|
-
}
|
|
987
|
+
if (key.tab) return;
|
|
836
988
|
if (key.upArrow) {
|
|
837
989
|
const moved = up(editor);
|
|
838
990
|
if (moved) setEditor(moved);
|
|
@@ -861,33 +1013,33 @@ ${theme.dim(
|
|
|
861
1013
|
if (key.ctrl || key.meta || !input) return;
|
|
862
1014
|
setEditor((e) => insert(e, input));
|
|
863
1015
|
});
|
|
864
|
-
usePaste((
|
|
865
|
-
setEditor((e) => insert(e,
|
|
1016
|
+
usePaste((text2) => {
|
|
1017
|
+
setEditor((e) => insert(e, text2));
|
|
866
1018
|
});
|
|
867
|
-
const
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
/* @__PURE__ */
|
|
872
|
-
/* @__PURE__ */
|
|
873
|
-
/* @__PURE__ */
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
...notice ? { notice } : {}
|
|
1019
|
+
const text = textOf(editor);
|
|
1020
|
+
const suggestions = slashSuggestions(text);
|
|
1021
|
+
useEffect(() => setSlashIndex(0), [text]);
|
|
1022
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", width, children: [
|
|
1023
|
+
/* @__PURE__ */ jsx5(Static, { items: state.entries, children: (entry) => /* @__PURE__ */ jsx5(EntryView, { entry }, entry.id) }, state.epoch),
|
|
1024
|
+
state.streaming ? /* @__PURE__ */ jsx5(StreamingView, { streaming: state.streaming, now: clock }) : null,
|
|
1025
|
+
picker ? /* @__PURE__ */ jsx5(Picker, { title: picker.title, options: picker.options, index: picker.index }) : /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1026
|
+
/* @__PURE__ */ jsx5(InputBox, { editor, width, placeholder: PLACEHOLDER }),
|
|
1027
|
+
/* @__PURE__ */ jsx5(
|
|
1028
|
+
SlashHints,
|
|
1029
|
+
{
|
|
1030
|
+
commands: suggestions,
|
|
1031
|
+
width,
|
|
1032
|
+
selected: Math.min(slashIndex, Math.max(0, suggestions.length - 1))
|
|
882
1033
|
}
|
|
883
|
-
|
|
884
|
-
)
|
|
1034
|
+
)
|
|
1035
|
+
] }),
|
|
1036
|
+
!picker && suggestions.length === 0 ? /* @__PURE__ */ jsx5(StatusLine, { state, width, info: notice ? { notice } : {} }) : null
|
|
885
1037
|
] });
|
|
886
1038
|
}
|
|
887
1039
|
function ChatApp(props) {
|
|
888
|
-
return /* @__PURE__ */
|
|
1040
|
+
return /* @__PURE__ */ jsx5(ThemeProvider, { theme: props.theme, children: /* @__PURE__ */ jsx5(Chat, { ...props }) });
|
|
889
1041
|
}
|
|
890
1042
|
export {
|
|
891
1043
|
ChatApp
|
|
892
1044
|
};
|
|
893
|
-
//# sourceMappingURL=ChatApp-
|
|
1045
|
+
//# sourceMappingURL=ChatApp-CJBICQGA.js.map
|