skydive-cli 0.3.0 → 0.4.0-beta.1033
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/CHANGELOG.md +27 -0
- package/README.md +28 -2
- package/dist/js/billing-blocked-CwfG1BTR.mjs +71 -0
- package/dist/js/billing-blocked-euid6MN9.mjs +4 -0
- package/dist/js/bin.mjs +247 -89
- package/dist/js/{boot-HAgDg_b4.mjs → boot-C6THTSAl.mjs} +312 -50
- package/dist/js/chat/tui/chunks/grammars/assets/bash.highlights.scm +56 -0
- package/dist/js/chat/tui/chunks/grammars/assets/bash.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/c.highlights.scm +81 -0
- package/dist/js/chat/tui/chunks/grammars/assets/c.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/cpp.highlights.scm +70 -0
- package/dist/js/chat/tui/chunks/grammars/assets/cpp.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/css.highlights.scm +76 -0
- package/dist/js/chat/tui/chunks/grammars/assets/css.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/go.highlights.scm +123 -0
- package/dist/js/chat/tui/chunks/grammars/assets/go.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/html.highlights.scm +13 -0
- package/dist/js/chat/tui/chunks/grammars/assets/html.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/java.highlights.scm +149 -0
- package/dist/js/chat/tui/chunks/grammars/assets/java.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/json.highlights.scm +16 -0
- package/dist/js/chat/tui/chunks/grammars/assets/json.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/lua.highlights.scm +201 -0
- package/dist/js/chat/tui/chunks/grammars/assets/lua.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/python.highlights.scm +137 -0
- package/dist/js/chat/tui/chunks/grammars/assets/python.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/ruby.highlights.scm +154 -0
- package/dist/js/chat/tui/chunks/grammars/assets/ruby.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/rust.highlights.scm +161 -0
- package/dist/js/chat/tui/chunks/grammars/assets/rust.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/toml.highlights.scm +53 -0
- package/dist/js/chat/tui/chunks/grammars/assets/toml.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/assets/yaml.highlights.scm +79 -0
- package/dist/js/chat/tui/chunks/grammars/assets/yaml.wasm +0 -0
- package/dist/js/chat/tui/chunks/grammars/grammars.ts +146 -0
- package/dist/js/client-BpAnESuq.mjs +6 -0
- package/dist/js/{client-Dc7GZ3PG.mjs → client-DiaJZQG6.mjs} +1 -1
- package/dist/js/{daemon-Co4CtpXZ.mjs → daemon-BSSZpzto.mjs} +2 -2
- package/dist/js/daemon-ybnlDUgi.mjs +7 -0
- package/dist/js/{install-CMYBFvR2.mjs → install-DCcGbpsS.mjs} +2 -2
- package/dist/js/{print-Cd-bVSEJ.mjs → print-CiaU2ygh.mjs} +84 -2
- package/dist/js/{print-share-7qfpQtWK.mjs → print-share-DlO5RSBt.mjs} +1 -1
- package/dist/js/{print-CPCFci60.mjs → print-vUf9stcK.mjs} +3 -2
- package/dist/js/{raw-pty-BcjbTjHJ.mjs → raw-pty-DAmb8uqt.mjs} +1 -1
- package/dist/js/raw-pty-t5DC-e1T.mjs +5 -0
- package/dist/js/{rest-BlN_uWmL.mjs → rest-CG7VpQ56.mjs} +13 -2
- package/dist/js/rest-DfpoRJ_Q.mjs +5 -0
- package/package.json +1 -1
- package/dist/js/client-DuwxEDG4.mjs +0 -5
- package/dist/js/daemon-Ch_MSDmQ.mjs +0 -6
- package/dist/js/raw-pty-ChUHav4d.mjs +0 -5
- package/dist/js/rest-CDTXCmUb.mjs +0 -4
- /package/dist/js/{client-DfcJFEbh.mjs → client-D8s9vY4p.mjs} +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as setActiveWorkspace, S as listWorkspaces, a as WORDMARK, b as getActiveWorkspaceId, c as applyTheme, d as noColorRequested, f as theme, g as themeVersion, h as themeModeFromColorFgBg, i as MARK_CELLS, l as findTheme, m as themeMode, n as buildCrashReport, p as themeForMode, r as writeCrashReport, s as DEFAULT_THEME_ID, t as installCrashHandler, u as monoTheme, v as themesForMode } from "./install-
|
|
3
|
-
import {
|
|
4
|
-
import { a as errorMessage, i as sendErrorMessage, n as createRestClient, o as isRecord, r as errorDetail, t as HttpError } from "./rest-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { t as
|
|
2
|
+
import { C as setActiveWorkspace, S as listWorkspaces, a as WORDMARK, b as getActiveWorkspaceId, c as applyTheme, d as noColorRequested, f as theme, g as themeVersion, h as themeModeFromColorFgBg, i as MARK_CELLS, l as findTheme, m as themeMode, n as buildCrashReport, p as themeForMode, r as writeCrashReport, s as DEFAULT_THEME_ID, t as installCrashHandler, u as monoTheme, v as themesForMode } from "./install-DCcGbpsS.mjs";
|
|
3
|
+
import { B as saveTheme, D as getSavedTheme, E as getReviewStateDir, L as resolveWebUrl, S as getConfigPath, c as cardActionErrorMessage, d as reconcileMaskedInput, f as resolveConnectUrl, i as resolveAgent, l as parseExternalOauthConnectParams, m as specKeyFor, p as parseConnectCard, s as MASK_CHAR, u as parseOauthConnectParams, v as DEFAULT_API_URL, y as DEFAULT_APP_URL } from "./print-CiaU2ygh.mjs";
|
|
4
|
+
import { a as errorMessage, i as sendErrorMessage, n as createRestClient, o as isRecord, r as errorDetail, t as HttpError } from "./rest-CG7VpQ56.mjs";
|
|
5
|
+
import { i as billingBlockedOutcomeFromSendResponse } from "./billing-blocked-CwfG1BTR.mjs";
|
|
6
|
+
import { t as PortalClient } from "./client-DiaJZQG6.mjs";
|
|
7
|
+
import { d as makeLineParser, f as parseDaemonMessage, l as daemonPaths, n as ensureDaemonRunning, s as LOCAL_PROTOCOL_VERSION, u as encodeLine } from "./daemon-BSSZpzto.mjs";
|
|
8
|
+
import { t as SandboxStream } from "./client-D8s9vY4p.mjs";
|
|
9
|
+
import { t as runRawPtyPassthrough } from "./raw-pty-DAmb8uqt.mjs";
|
|
9
10
|
import * as os$1 from "node:os";
|
|
10
11
|
import { homedir, platform, release, tmpdir } from "node:os";
|
|
11
12
|
import path, { basename, extname, isAbsolute, join, win32 } from "node:path";
|
|
@@ -16,7 +17,7 @@ import { execFile, spawn } from "node:child_process";
|
|
|
16
17
|
import { createHash, randomUUID } from "node:crypto";
|
|
17
18
|
import { connect, createConnection } from "node:net";
|
|
18
19
|
import { access, appendFile, mkdir, mkdtemp, readFile, readdir, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
19
|
-
import { MarkdownRenderable, RenderableEvents, StyledText, SyntaxStyle, createCliRenderer, decodePasteBytes, detectLinks, fg, link } from "@opentui/core";
|
|
20
|
+
import { MarkdownRenderable, RenderableEvents, StyledText, SyntaxStyle, addDefaultParsers, createCliRenderer, decodePasteBytes, detectLinks, fg, link } from "@opentui/core";
|
|
20
21
|
import { createRoot, extend, useKeyboard, usePaste, useRenderer, useTerminalDimensions } from "@opentui/react";
|
|
21
22
|
import { createContext, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
22
23
|
import { create } from "zustand";
|
|
@@ -69,6 +70,7 @@ const useStore = create((set, get) => ({
|
|
|
69
70
|
themeLocked: false,
|
|
70
71
|
appUrl: null,
|
|
71
72
|
sessionToken: null,
|
|
73
|
+
authKind: "session",
|
|
72
74
|
workspaceName: null,
|
|
73
75
|
rest: null,
|
|
74
76
|
promptHistoryPath: null,
|
|
@@ -437,10 +439,11 @@ function createPortalClient(opts) {
|
|
|
437
439
|
* user turns sharing on from the chat screen. Detaching on unmount leaves the
|
|
438
440
|
* daemon running for any other attached CLIs.
|
|
439
441
|
*/
|
|
440
|
-
function usePortal({ appUrl, sessionToken, shareMachine }) {
|
|
442
|
+
function usePortal({ appUrl, sessionToken, shareMachine, enabled = true }) {
|
|
441
443
|
const syncPortal = useStore((s) => s.syncPortal);
|
|
442
444
|
const setPortalClient = useStore((s) => s.setPortalClient);
|
|
443
445
|
useEffect(() => {
|
|
446
|
+
if (!enabled) return;
|
|
444
447
|
const client = createPortalClient({
|
|
445
448
|
appUrl,
|
|
446
449
|
sessionToken,
|
|
@@ -463,6 +466,7 @@ function usePortal({ appUrl, sessionToken, shareMachine }) {
|
|
|
463
466
|
appUrl,
|
|
464
467
|
sessionToken,
|
|
465
468
|
shareMachine,
|
|
469
|
+
enabled,
|
|
466
470
|
syncPortal,
|
|
467
471
|
setPortalClient
|
|
468
472
|
]);
|
|
@@ -1687,8 +1691,13 @@ function AgentPickerScreen() {
|
|
|
1687
1691
|
const [cache, setCache] = useState({});
|
|
1688
1692
|
const [state, setState] = useState({ kind: "loading" });
|
|
1689
1693
|
useKeyboard((key) => {
|
|
1690
|
-
if (key.name === "w" && key.ctrl)
|
|
1691
|
-
|
|
1694
|
+
if (key.name === "w" && key.ctrl) {
|
|
1695
|
+
if (useStore.getState().authKind === "api-key") {
|
|
1696
|
+
useStore.getState().showToast({ message: "API keys are pinned to one workspace. Run `skydive auth login --web` to switch workspaces." });
|
|
1697
|
+
return;
|
|
1698
|
+
}
|
|
1699
|
+
goTo({ kind: "workspace-picker" });
|
|
1700
|
+
} else if (key.name === "n" && key.ctrl) goTo({ kind: "agent-create" });
|
|
1692
1701
|
else if (key.name === "tab") setScope((s) => s === "mine" ? "org" : "mine");
|
|
1693
1702
|
});
|
|
1694
1703
|
useEffect(() => {
|
|
@@ -1797,6 +1806,8 @@ function FilterableAgentList({ agents, scope, onPick }) {
|
|
|
1797
1806
|
useKeyboard((key) => {
|
|
1798
1807
|
if (key.name === "up") setHighlight(Math.max(0, clamped - 1));
|
|
1799
1808
|
else if (key.name === "down") setHighlight(Math.min(Math.max(0, filtered.length - 1), clamped + 1));
|
|
1809
|
+
else if (key.name === "pageup" || key.name === "pgup") setHighlight(Math.max(0, clamped - Math.max(1, visibleRows - 1)));
|
|
1810
|
+
else if (key.name === "pagedown" || key.name === "pgdn") setHighlight(Math.min(Math.max(0, filtered.length - 1), clamped + Math.max(1, visibleRows - 1)));
|
|
1800
1811
|
else if (key.name === "return") {
|
|
1801
1812
|
const agent = filtered[clamped];
|
|
1802
1813
|
if (!agent) return;
|
|
@@ -1831,6 +1842,9 @@ function FilterableAgentList({ agents, scope, onPick }) {
|
|
|
1831
1842
|
fg: theme.muted,
|
|
1832
1843
|
children: "search "
|
|
1833
1844
|
}), /* @__PURE__ */ jsx("input", {
|
|
1845
|
+
textColor: theme.fg,
|
|
1846
|
+
focusedTextColor: theme.fg,
|
|
1847
|
+
placeholderColor: theme.dim,
|
|
1834
1848
|
placeholder: "type to filter…",
|
|
1835
1849
|
focused: true,
|
|
1836
1850
|
width: Math.max(10, width - 12),
|
|
@@ -2029,6 +2043,9 @@ function AgentCreateScreen() {
|
|
|
2029
2043
|
flexShrink: 0
|
|
2030
2044
|
},
|
|
2031
2045
|
children: /* @__PURE__ */ jsx("input", {
|
|
2046
|
+
textColor: theme.fg,
|
|
2047
|
+
focusedTextColor: theme.fg,
|
|
2048
|
+
placeholderColor: theme.dim,
|
|
2032
2049
|
placeholder: "Agent name",
|
|
2033
2050
|
onInput: (value) => {
|
|
2034
2051
|
setName(value);
|
|
@@ -2269,6 +2286,31 @@ function CollapseHint() {
|
|
|
2269
2286
|
children: "· click to collapse"
|
|
2270
2287
|
});
|
|
2271
2288
|
}
|
|
2289
|
+
/** Collapsed line cap for tool error output. */
|
|
2290
|
+
const maxErrorLines = 8;
|
|
2291
|
+
/**
|
|
2292
|
+
* Tool error output, clamped like ok output: collapsed it clips to
|
|
2293
|
+
* `maxErrorLines` with the "+N more · click to expand" tail; expanded it
|
|
2294
|
+
* renders in full, word-wrapped. Same click-to-toggle box as the rest of
|
|
2295
|
+
* the block — a failing command's output shouldn't flood the scrollback
|
|
2296
|
+
* just because it arrived on the error channel.
|
|
2297
|
+
*/
|
|
2298
|
+
function ErrorLines({ text, expanded }) {
|
|
2299
|
+
if (expanded) return /* @__PURE__ */ jsx(ExpandedLines, {
|
|
2300
|
+
text,
|
|
2301
|
+
fg: theme.error
|
|
2302
|
+
});
|
|
2303
|
+
return /* @__PURE__ */ jsx("box", {
|
|
2304
|
+
style: { flexDirection: "column" },
|
|
2305
|
+
children: clipLines(text, {
|
|
2306
|
+
maxLines: maxErrorLines,
|
|
2307
|
+
maxLineLen: 100
|
|
2308
|
+
}).map((line, idx) => /* @__PURE__ */ jsx("text", {
|
|
2309
|
+
fg: theme.error,
|
|
2310
|
+
children: line
|
|
2311
|
+
}, idx))
|
|
2312
|
+
});
|
|
2313
|
+
}
|
|
2272
2314
|
/** Indents tool output two columns under its header — no rule, just space. */
|
|
2273
2315
|
function Indented({ children }) {
|
|
2274
2316
|
return /* @__PURE__ */ jsx("box", {
|
|
@@ -2669,6 +2711,8 @@ function ConversationList({ agent, conversations, complete, showAutomated, onTog
|
|
|
2669
2711
|
if (key.name === "escape") onPick({ kind: "agent-picker" });
|
|
2670
2712
|
else if (key.name === "up") setHighlight(Math.max(0, clamped - 1));
|
|
2671
2713
|
else if (key.name === "down") setHighlight(Math.min(Math.max(0, rows.length - 1), clamped + 1));
|
|
2714
|
+
else if (key.name === "pageup" || key.name === "pgup") setHighlight(Math.max(0, clamped - Math.max(1, visibleRows - 1)));
|
|
2715
|
+
else if (key.name === "pagedown" || key.name === "pgdn") setHighlight(Math.min(Math.max(0, rows.length - 1), clamped + Math.max(1, visibleRows - 1)));
|
|
2672
2716
|
else if (key.name === "d" && key.ctrl) {
|
|
2673
2717
|
const row = rows[clamped];
|
|
2674
2718
|
if (row?.kind === "conv") {
|
|
@@ -2704,6 +2748,9 @@ function ConversationList({ agent, conversations, complete, showAutomated, onTog
|
|
|
2704
2748
|
fg: theme.muted,
|
|
2705
2749
|
children: "search "
|
|
2706
2750
|
}), /* @__PURE__ */ jsx("input", {
|
|
2751
|
+
textColor: theme.fg,
|
|
2752
|
+
focusedTextColor: theme.fg,
|
|
2753
|
+
placeholderColor: theme.dim,
|
|
2707
2754
|
placeholder: "type to filter…",
|
|
2708
2755
|
focused: confirmId === null,
|
|
2709
2756
|
width: Math.max(10, width - 12),
|
|
@@ -3056,8 +3103,13 @@ function syntaxStyleTable() {
|
|
|
3056
3103
|
"keyword.function": { fg: theme.syntaxMagenta },
|
|
3057
3104
|
"keyword.return": { fg: theme.syntaxMagenta },
|
|
3058
3105
|
"keyword.operator": { fg: theme.syntaxMagenta },
|
|
3106
|
+
conditional: { fg: theme.syntaxMagenta },
|
|
3107
|
+
repeat: { fg: theme.syntaxMagenta },
|
|
3108
|
+
preproc: { fg: theme.syntaxMagenta },
|
|
3059
3109
|
string: { fg: theme.syntaxGreen },
|
|
3060
3110
|
"string.special": { fg: theme.syntaxTeal },
|
|
3111
|
+
escape: { fg: theme.syntaxTeal },
|
|
3112
|
+
"string.escape": { fg: theme.syntaxTeal },
|
|
3061
3113
|
character: { fg: theme.syntaxGreen },
|
|
3062
3114
|
comment: {
|
|
3063
3115
|
fg: theme.dim,
|
|
@@ -3066,10 +3118,13 @@ function syntaxStyleTable() {
|
|
|
3066
3118
|
function: { fg: theme.syntaxBlue },
|
|
3067
3119
|
"function.method": { fg: theme.syntaxBlue },
|
|
3068
3120
|
"function.builtin": { fg: theme.syntaxCyan },
|
|
3121
|
+
method: { fg: theme.syntaxBlue },
|
|
3069
3122
|
variable: { fg: theme.fg },
|
|
3070
3123
|
"variable.builtin": { fg: theme.syntaxRed },
|
|
3071
3124
|
"variable.parameter": { fg: theme.syntaxYellow },
|
|
3072
3125
|
"variable.member": { fg: theme.syntaxTeal },
|
|
3126
|
+
parameter: { fg: theme.syntaxYellow },
|
|
3127
|
+
field: { fg: theme.syntaxTeal },
|
|
3073
3128
|
type: { fg: theme.syntaxCyan },
|
|
3074
3129
|
"type.builtin": { fg: theme.syntaxCyan },
|
|
3075
3130
|
constant: { fg: theme.syntaxOrange },
|
|
@@ -3084,6 +3139,7 @@ function syntaxStyleTable() {
|
|
|
3084
3139
|
"punctuation.bracket": { fg: theme.muted },
|
|
3085
3140
|
"punctuation.delimiter": { fg: theme.muted },
|
|
3086
3141
|
"punctuation.special": { fg: theme.syntaxCyan },
|
|
3142
|
+
delimiter: { fg: theme.muted },
|
|
3087
3143
|
constructor: { fg: theme.syntaxBlue },
|
|
3088
3144
|
module: { fg: theme.syntaxBlue },
|
|
3089
3145
|
label: { fg: theme.syntaxCyan },
|
|
@@ -3199,6 +3255,22 @@ function StatusLine({ item }) {
|
|
|
3199
3255
|
}
|
|
3200
3256
|
}
|
|
3201
3257
|
|
|
3258
|
+
//#endregion
|
|
3259
|
+
//#region src/chat/tui/chunks/system-notice-item.tsx
|
|
3260
|
+
/**
|
|
3261
|
+
* Platform system-notice row: the server stopped or refused work for a
|
|
3262
|
+
* platform reason (today: billing-blocked), so it reads as a warning-toned
|
|
3263
|
+
* notice — visually distinct from the ✗ transport/agent error row. The text
|
|
3264
|
+
* already carries the full guidance, produced server-side or derived from a
|
|
3265
|
+
* typed outcome by the producer that pushed the item.
|
|
3266
|
+
*/
|
|
3267
|
+
function SystemNoticeItem({ item }) {
|
|
3268
|
+
return /* @__PURE__ */ jsxs("text", {
|
|
3269
|
+
fg: theme.warning,
|
|
3270
|
+
children: ["◆ ", item.text.trim()]
|
|
3271
|
+
});
|
|
3272
|
+
}
|
|
3273
|
+
|
|
3202
3274
|
//#endregion
|
|
3203
3275
|
//#region src/chat/tui/chunks/error-item.tsx
|
|
3204
3276
|
/**
|
|
@@ -3331,9 +3403,9 @@ function ToolGeneric({ item }) {
|
|
|
3331
3403
|
fg: theme.dim,
|
|
3332
3404
|
children: " · click to expand"
|
|
3333
3405
|
})]
|
|
3334
|
-
}) : /* @__PURE__ */ jsx(
|
|
3335
|
-
|
|
3336
|
-
|
|
3406
|
+
}) : /* @__PURE__ */ jsx(ErrorLines, {
|
|
3407
|
+
text: item.output.errorText,
|
|
3408
|
+
expanded
|
|
3337
3409
|
}) }) : null,
|
|
3338
3410
|
expanded && /* @__PURE__ */ jsx(Indented, { children: /* @__PURE__ */ jsx(CollapseHint, {}) })
|
|
3339
3411
|
]
|
|
@@ -3480,10 +3552,16 @@ function trimCommonIndent(hunks) {
|
|
|
3480
3552
|
for (const hunk of hunks) hunk.lines = hunk.lines.map((line) => isContentLine(line) ? line[0] + line.slice(1 + min) : line);
|
|
3481
3553
|
}
|
|
3482
3554
|
/**
|
|
3483
|
-
*
|
|
3484
|
-
*
|
|
3485
|
-
*
|
|
3486
|
-
*
|
|
3555
|
+
* Maps a file extension to the tree-sitter filetype used to highlight it in
|
|
3556
|
+
* diffs and the file/review pane. OpenTUI bundles parsers for
|
|
3557
|
+
* javascript(+react), typescript(+react), markdown, and zig; the rest are
|
|
3558
|
+
* registered by ./grammars. An extension absent here returns
|
|
3559
|
+
* undefined, which skips the highlight pass (the diff still renders red/green)
|
|
3560
|
+
* rather than asking the client for a parser it doesn't have.
|
|
3561
|
+
*
|
|
3562
|
+
* Keep the filetype values in sync with the canonical `filetype`/`aliases`
|
|
3563
|
+
* registered in ./grammars/grammars.ts — an extension mapping to a filetype no
|
|
3564
|
+
* parser is registered for just renders plain.
|
|
3487
3565
|
*/
|
|
3488
3566
|
const FILETYPE_BY_EXT = {
|
|
3489
3567
|
ts: "typescript",
|
|
@@ -3496,7 +3574,34 @@ const FILETYPE_BY_EXT = {
|
|
|
3496
3574
|
jsx: "javascriptreact",
|
|
3497
3575
|
md: "markdown",
|
|
3498
3576
|
markdown: "markdown",
|
|
3499
|
-
zig: "zig"
|
|
3577
|
+
zig: "zig",
|
|
3578
|
+
py: "python",
|
|
3579
|
+
pyi: "python",
|
|
3580
|
+
pyw: "python",
|
|
3581
|
+
sh: "bash",
|
|
3582
|
+
bash: "bash",
|
|
3583
|
+
zsh: "bash",
|
|
3584
|
+
go: "go",
|
|
3585
|
+
rs: "rust",
|
|
3586
|
+
c: "c",
|
|
3587
|
+
h: "c",
|
|
3588
|
+
cpp: "cpp",
|
|
3589
|
+
cxx: "cpp",
|
|
3590
|
+
cc: "cpp",
|
|
3591
|
+
hpp: "cpp",
|
|
3592
|
+
hxx: "cpp",
|
|
3593
|
+
hh: "cpp",
|
|
3594
|
+
java: "java",
|
|
3595
|
+
rb: "ruby",
|
|
3596
|
+
css: "css",
|
|
3597
|
+
html: "html",
|
|
3598
|
+
htm: "html",
|
|
3599
|
+
json: "json",
|
|
3600
|
+
jsonc: "json",
|
|
3601
|
+
yaml: "yaml",
|
|
3602
|
+
yml: "yaml",
|
|
3603
|
+
toml: "toml",
|
|
3604
|
+
lua: "lua"
|
|
3500
3605
|
};
|
|
3501
3606
|
function filetypeForPath(filePath) {
|
|
3502
3607
|
const base = filePath.split("/").pop() ?? filePath;
|
|
@@ -3711,10 +3816,10 @@ function ToolEdit({ item }) {
|
|
|
3711
3816
|
fg: theme.muted,
|
|
3712
3817
|
children: "(no changes)"
|
|
3713
3818
|
}) }) : null,
|
|
3714
|
-
item.output?.kind === "error" && /* @__PURE__ */
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
}) }),
|
|
3819
|
+
item.output?.kind === "error" && /* @__PURE__ */ jsxs(Indented, { children: [/* @__PURE__ */ jsx(ErrorLines, {
|
|
3820
|
+
text: item.output.errorText,
|
|
3821
|
+
expanded
|
|
3822
|
+
}), expanded && isClipped(item.output.errorText, maxErrorLines) && /* @__PURE__ */ jsx(CollapseHint, {})] }),
|
|
3718
3823
|
item.output?.kind === "ok" && pairs === null && inputReady && /* @__PURE__ */ jsx(Indented, { children: /* @__PURE__ */ jsx("text", {
|
|
3719
3824
|
fg: theme.muted,
|
|
3720
3825
|
children: summarize(item.output.value, 60)
|
|
@@ -3840,12 +3945,13 @@ function PlainDiff({ diff }) {
|
|
|
3840
3945
|
//#endregion
|
|
3841
3946
|
//#region src/chat/tui/chunks/tool-bash.tsx
|
|
3842
3947
|
const maxLines$1 = 8;
|
|
3948
|
+
const maxCommandLines = 3;
|
|
3843
3949
|
/**
|
|
3844
3950
|
* Rich view for the `bash`/`shell` tool. Leads with the model-authored
|
|
3845
3951
|
* summary when present (mirroring web chat's activity labels), with the
|
|
3846
3952
|
* command on its own dim line beneath; then its output
|
|
3847
3953
|
* (truncated to keep the scrollback usable — click the block to toggle the
|
|
3848
|
-
* full output
|
|
3954
|
+
* full command and output).
|
|
3849
3955
|
*/
|
|
3850
3956
|
function ToolBash({ item }) {
|
|
3851
3957
|
const glyph = toolGlyph(item.state);
|
|
@@ -3854,6 +3960,10 @@ function ToolBash({ item }) {
|
|
|
3854
3960
|
const output = item.output?.kind === "ok" ? typeof item.output.value === "string" ? item.output.value : extractStdout(item.output.value) : null;
|
|
3855
3961
|
const summary = getToolCallSummary(item.input);
|
|
3856
3962
|
const [expanded, setExpanded] = useState(false);
|
|
3963
|
+
const commandText = command || "(empty command)";
|
|
3964
|
+
const headerCommandLine = commandText.split("\n", 1)[0] ?? commandText;
|
|
3965
|
+
const commandBlockText = summary !== null ? `$ ${commandText}` : commandText.slice(headerCommandLine.length + 1);
|
|
3966
|
+
const showCommandBlock = commandBlockText.length > 0;
|
|
3857
3967
|
return /* @__PURE__ */ jsxs("box", {
|
|
3858
3968
|
style: {
|
|
3859
3969
|
flexDirection: "column",
|
|
@@ -3866,14 +3976,19 @@ function ToolBash({ item }) {
|
|
|
3866
3976
|
children: [glyph.ch, " "]
|
|
3867
3977
|
}), /* @__PURE__ */ jsx("span", {
|
|
3868
3978
|
fg: theme.tool,
|
|
3869
|
-
children: summary !== null ? summary : `$ ${
|
|
3979
|
+
children: summary !== null ? summary : `$ ${headerCommandLine}`
|
|
3870
3980
|
})] }),
|
|
3871
|
-
|
|
3981
|
+
showCommandBlock && /* @__PURE__ */ jsx(Indented, { children: expanded ? /* @__PURE__ */ jsx(ExpandedLines, {
|
|
3982
|
+
text: commandBlockText,
|
|
3983
|
+
fg: theme.muted
|
|
3984
|
+
}) : clipLines(commandBlockText, {
|
|
3985
|
+
maxLines: maxCommandLines,
|
|
3986
|
+
maxLineLen: 100
|
|
3987
|
+
}).map((line, idx) => /* @__PURE__ */ jsx("text", {
|
|
3872
3988
|
fg: theme.muted,
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
output !== null && output.length > 0 && /* @__PURE__ */ jsxs(Indented, { children: [expanded ? /* @__PURE__ */ jsx(ExpandedLines, {
|
|
3989
|
+
children: line
|
|
3990
|
+
}, idx)) }),
|
|
3991
|
+
output !== null && output.length > 0 && /* @__PURE__ */ jsx(Indented, { children: expanded ? /* @__PURE__ */ jsx(ExpandedLines, {
|
|
3877
3992
|
text: output,
|
|
3878
3993
|
fg: theme.muted
|
|
3879
3994
|
}) : clipLines(output, {
|
|
@@ -3882,11 +3997,12 @@ function ToolBash({ item }) {
|
|
|
3882
3997
|
}).map((line, idx) => /* @__PURE__ */ jsx("text", {
|
|
3883
3998
|
fg: theme.muted,
|
|
3884
3999
|
children: line
|
|
3885
|
-
}, idx))
|
|
3886
|
-
item.output?.kind === "error" && /* @__PURE__ */ jsx(Indented, { children: /* @__PURE__ */ jsx(
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
}) })
|
|
4000
|
+
}, idx)) }),
|
|
4001
|
+
item.output?.kind === "error" && /* @__PURE__ */ jsx(Indented, { children: /* @__PURE__ */ jsx(ErrorLines, {
|
|
4002
|
+
text: item.output.errorText,
|
|
4003
|
+
expanded
|
|
4004
|
+
}) }),
|
|
4005
|
+
expanded && (showCommandBlock && isClipped(commandBlockText, maxCommandLines) || output !== null && isClipped(output, maxLines$1) || item.output?.kind === "error" && isClipped(item.output.errorText, maxErrorLines)) && /* @__PURE__ */ jsx(Indented, { children: /* @__PURE__ */ jsx(CollapseHint, {}) })
|
|
3890
4006
|
]
|
|
3891
4007
|
});
|
|
3892
4008
|
}
|
|
@@ -3954,10 +4070,10 @@ function ToolRead({ item }) {
|
|
|
3954
4070
|
fg: theme.muted,
|
|
3955
4071
|
children: line
|
|
3956
4072
|
}, idx)), expanded && isClipped(preview, maxLines) && /* @__PURE__ */ jsx(CollapseHint, {})] }),
|
|
3957
|
-
item.output?.kind === "error" && /* @__PURE__ */
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
}) })
|
|
4073
|
+
item.output?.kind === "error" && /* @__PURE__ */ jsxs(Indented, { children: [/* @__PURE__ */ jsx(ErrorLines, {
|
|
4074
|
+
text: item.output.errorText,
|
|
4075
|
+
expanded
|
|
4076
|
+
}), expanded && isClipped(item.output.errorText, maxErrorLines) && /* @__PURE__ */ jsx(CollapseHint, {})] })
|
|
3961
4077
|
]
|
|
3962
4078
|
});
|
|
3963
4079
|
}
|
|
@@ -4038,10 +4154,10 @@ function ToolGrep({ item }) {
|
|
|
4038
4154
|
}),
|
|
4039
4155
|
expanded && matches.length > maxMatches && /* @__PURE__ */ jsx(CollapseHint, {})
|
|
4040
4156
|
] }),
|
|
4041
|
-
item.output?.kind === "error" && /* @__PURE__ */
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
}) })
|
|
4157
|
+
item.output?.kind === "error" && /* @__PURE__ */ jsxs(Indented, { children: [/* @__PURE__ */ jsx(ErrorLines, {
|
|
4158
|
+
text: item.output.errorText,
|
|
4159
|
+
expanded
|
|
4160
|
+
}), expanded && isClipped(item.output.errorText, maxErrorLines) && /* @__PURE__ */ jsx(CollapseHint, {})] })
|
|
4045
4161
|
]
|
|
4046
4162
|
});
|
|
4047
4163
|
}
|
|
@@ -4165,6 +4281,10 @@ function RenderItem({ item }) {
|
|
|
4165
4281
|
barColor: null,
|
|
4166
4282
|
children: /* @__PURE__ */ jsx(ErrorItem, { item })
|
|
4167
4283
|
});
|
|
4284
|
+
case "system-notice": return /* @__PURE__ */ jsx(Row, {
|
|
4285
|
+
barColor: null,
|
|
4286
|
+
children: /* @__PURE__ */ jsx(SystemNoticeItem, { item })
|
|
4287
|
+
});
|
|
4168
4288
|
case "card": return /* @__PURE__ */ jsx(Row, {
|
|
4169
4289
|
barColor: null,
|
|
4170
4290
|
children: /* @__PURE__ */ jsx(CardItem, { item })
|
|
@@ -4804,6 +4924,15 @@ function uiMessagesToItems(messages) {
|
|
|
4804
4924
|
const out = [];
|
|
4805
4925
|
for (const m of messages) {
|
|
4806
4926
|
if (m.role === "user") {
|
|
4927
|
+
const billingNotice = billingBlockedNoticeText(m.parts);
|
|
4928
|
+
if (billingNotice) {
|
|
4929
|
+
out.push({
|
|
4930
|
+
kind: "system-notice",
|
|
4931
|
+
id: m.id,
|
|
4932
|
+
text: billingNotice
|
|
4933
|
+
});
|
|
4934
|
+
continue;
|
|
4935
|
+
}
|
|
4807
4936
|
const text = m.parts.map((p) => p.type === "text" ? p.text : "").join("").trim();
|
|
4808
4937
|
const attachments = m.parts.filter((p) => p.type === "data-anyone-attachment").map((p) => {
|
|
4809
4938
|
const data = isRecord(p) && "data" in p && isRecord(p.data) ? p.data : null;
|
|
@@ -4898,6 +5027,14 @@ function uiMessagesToItems(messages) {
|
|
|
4898
5027
|
}
|
|
4899
5028
|
return out.map(clampItem);
|
|
4900
5029
|
}
|
|
5030
|
+
function billingBlockedNoticeText(parts) {
|
|
5031
|
+
for (const part of parts) {
|
|
5032
|
+
if (part.type !== "data-anyone-system-notification") continue;
|
|
5033
|
+
const data = isRecord(part) && isRecord(part.data) ? part.data : null;
|
|
5034
|
+
if (data && data.kind === "billing-blocked" && typeof data.text === "string" && data.text.trim()) return data.text;
|
|
5035
|
+
}
|
|
5036
|
+
return null;
|
|
5037
|
+
}
|
|
4901
5038
|
function mapToolState(raw) {
|
|
4902
5039
|
switch (raw) {
|
|
4903
5040
|
case "output-error": return "error";
|
|
@@ -5600,6 +5737,10 @@ const keybindGroups = [
|
|
|
5600
5737
|
keys: "/plan [show|hide]",
|
|
5601
5738
|
action: "show / hide the pinned plan card"
|
|
5602
5739
|
},
|
|
5740
|
+
{
|
|
5741
|
+
keys: "/rename <title>",
|
|
5742
|
+
action: "rename this conversation (for everyone)"
|
|
5743
|
+
},
|
|
5603
5744
|
{
|
|
5604
5745
|
keys: "/",
|
|
5605
5746
|
action: "open the command menu (start of message)"
|
|
@@ -5711,6 +5852,10 @@ const keybindGroups = [
|
|
|
5711
5852
|
keys: "↑ / ↓",
|
|
5712
5853
|
action: "move selection"
|
|
5713
5854
|
},
|
|
5855
|
+
{
|
|
5856
|
+
keys: "pgup / pgdn",
|
|
5857
|
+
action: "move selection a page at a time"
|
|
5858
|
+
},
|
|
5714
5859
|
{
|
|
5715
5860
|
keys: "↵",
|
|
5716
5861
|
action: "open agent"
|
|
@@ -5736,6 +5881,10 @@ const keybindGroups = [
|
|
|
5736
5881
|
keys: "↑ / ↓",
|
|
5737
5882
|
action: "move selection"
|
|
5738
5883
|
},
|
|
5884
|
+
{
|
|
5885
|
+
keys: "pgup / pgdn",
|
|
5886
|
+
action: "move selection a page at a time"
|
|
5887
|
+
},
|
|
5739
5888
|
{
|
|
5740
5889
|
keys: "↵",
|
|
5741
5890
|
action: "open conversation"
|
|
@@ -5915,6 +6064,9 @@ function HelpModal({ onClose }) {
|
|
|
5915
6064
|
fg: theme.muted,
|
|
5916
6065
|
children: "search "
|
|
5917
6066
|
}), /* @__PURE__ */ jsx("input", {
|
|
6067
|
+
textColor: theme.fg,
|
|
6068
|
+
focusedTextColor: theme.fg,
|
|
6069
|
+
placeholderColor: theme.dim,
|
|
5918
6070
|
placeholder: "type to filter…",
|
|
5919
6071
|
focused: true,
|
|
5920
6072
|
width: Math.max(10, width - 12),
|
|
@@ -6052,6 +6204,13 @@ const slashCommands = [
|
|
|
6052
6204
|
description: "archive this conversation and hide it from your list",
|
|
6053
6205
|
action: { kind: "archive-conversation" }
|
|
6054
6206
|
},
|
|
6207
|
+
{
|
|
6208
|
+
name: "rename",
|
|
6209
|
+
aliases: ["title"],
|
|
6210
|
+
argsHint: "<new title>",
|
|
6211
|
+
description: "rename this conversation (for everyone)",
|
|
6212
|
+
action: { kind: "rename-conversation" }
|
|
6213
|
+
},
|
|
6055
6214
|
{
|
|
6056
6215
|
name: "conversation",
|
|
6057
6216
|
aliases: ["conversations", "conv"],
|
|
@@ -6471,6 +6630,9 @@ function FilterableModelList({ models, currentModel, modelLocked, agentId, onSel
|
|
|
6471
6630
|
fg: theme.muted,
|
|
6472
6631
|
children: "search "
|
|
6473
6632
|
}), /* @__PURE__ */ jsx("input", {
|
|
6633
|
+
textColor: theme.fg,
|
|
6634
|
+
focusedTextColor: theme.fg,
|
|
6635
|
+
placeholderColor: theme.dim,
|
|
6474
6636
|
placeholder: "type to filter…",
|
|
6475
6637
|
focused: true,
|
|
6476
6638
|
width: Math.max(10, width - 12),
|
|
@@ -7415,6 +7577,9 @@ function ReviewFileSearch({ query, onQueryChange, placeholder = "filter files…
|
|
|
7415
7577
|
fg: theme.accent,
|
|
7416
7578
|
children: "/ "
|
|
7417
7579
|
}), /* @__PURE__ */ jsx("input", {
|
|
7580
|
+
textColor: theme.fg,
|
|
7581
|
+
focusedTextColor: theme.fg,
|
|
7582
|
+
placeholderColor: theme.dim,
|
|
7418
7583
|
placeholder,
|
|
7419
7584
|
focused: true,
|
|
7420
7585
|
width: "100%",
|
|
@@ -8134,6 +8299,9 @@ function WorkspaceFilesTab({ agentId, viewportWidth, viewportHeight, active, she
|
|
|
8134
8299
|
height: 3
|
|
8135
8300
|
},
|
|
8136
8301
|
children: /* @__PURE__ */ jsx("input", {
|
|
8302
|
+
textColor: theme.fg,
|
|
8303
|
+
focusedTextColor: theme.fg,
|
|
8304
|
+
placeholderColor: theme.dim,
|
|
8137
8305
|
placeholder: "Leave a comment…",
|
|
8138
8306
|
focused: true,
|
|
8139
8307
|
width: Math.max(8, width - 10),
|
|
@@ -8661,6 +8829,9 @@ function ReviewPane({ agentId, conversationId, items, viewportWidth, viewportHei
|
|
|
8661
8829
|
height: 3
|
|
8662
8830
|
},
|
|
8663
8831
|
children: /* @__PURE__ */ jsx("input", {
|
|
8832
|
+
textColor: theme.fg,
|
|
8833
|
+
focusedTextColor: theme.fg,
|
|
8834
|
+
placeholderColor: theme.dim,
|
|
8664
8835
|
placeholder: "Leave a comment…",
|
|
8665
8836
|
focused: true,
|
|
8666
8837
|
width: Math.max(8, sourceWidth - 8),
|
|
@@ -9185,6 +9356,10 @@ function routeInput(raw) {
|
|
|
9185
9356
|
kind: "open-conversation",
|
|
9186
9357
|
ref: match.rest
|
|
9187
9358
|
} : { kind: "conversation-picker" };
|
|
9359
|
+
case "rename-conversation": return {
|
|
9360
|
+
kind: "rename-conversation",
|
|
9361
|
+
title: match.rest
|
|
9362
|
+
};
|
|
9188
9363
|
case "plan": {
|
|
9189
9364
|
const arg = match.rest.toLowerCase();
|
|
9190
9365
|
return {
|
|
@@ -9651,8 +9826,14 @@ function ChatScreen({ agent, conversation }) {
|
|
|
9651
9826
|
setItems((prev) => applyChunk(prev, event.chunk, streamAgentName));
|
|
9652
9827
|
return;
|
|
9653
9828
|
}
|
|
9829
|
+
const billingOutcome = event.outcome;
|
|
9654
9830
|
const errorText = event.error;
|
|
9655
|
-
if (
|
|
9831
|
+
if (billingOutcome) setItems((prev) => [...prev, {
|
|
9832
|
+
kind: "system-notice",
|
|
9833
|
+
id: crypto.randomUUID(),
|
|
9834
|
+
text: billingOutcome.message
|
|
9835
|
+
}]);
|
|
9836
|
+
else if (event.status !== "ok" && errorText) setItems((prev) => [...prev, {
|
|
9656
9837
|
kind: "error",
|
|
9657
9838
|
id: crypto.randomUUID(),
|
|
9658
9839
|
text: errorText
|
|
@@ -9787,7 +9968,15 @@ function ChatScreen({ agent, conversation }) {
|
|
|
9787
9968
|
}
|
|
9788
9969
|
attachToRun(result.runId, result.agentName ?? null);
|
|
9789
9970
|
} catch (err) {
|
|
9790
|
-
|
|
9971
|
+
const billing = err instanceof HttpError ? billingBlockedOutcomeFromSendResponse({
|
|
9972
|
+
status: err.status,
|
|
9973
|
+
body: err.body
|
|
9974
|
+
}) : null;
|
|
9975
|
+
setItems((prev) => [...prev.filter((m) => m.id !== optimisticId), billing ? {
|
|
9976
|
+
kind: "system-notice",
|
|
9977
|
+
id: crypto.randomUUID(),
|
|
9978
|
+
text: billing.message
|
|
9979
|
+
} : {
|
|
9791
9980
|
kind: "error",
|
|
9792
9981
|
id: crypto.randomUUID(),
|
|
9793
9982
|
text: sendErrorMessage(err)
|
|
@@ -10375,6 +10564,38 @@ function ChatScreen({ agent, conversation }) {
|
|
|
10375
10564
|
goTo,
|
|
10376
10565
|
agent
|
|
10377
10566
|
]);
|
|
10567
|
+
const renameConversation = useCallback((rawTitle) => {
|
|
10568
|
+
const title = rawTitle.trim();
|
|
10569
|
+
if (!title) {
|
|
10570
|
+
useStore.getState().showToast({ message: "usage: /rename <new title>" });
|
|
10571
|
+
return;
|
|
10572
|
+
}
|
|
10573
|
+
if (title.length > 100) {
|
|
10574
|
+
useStore.getState().showToast({
|
|
10575
|
+
variant: "error",
|
|
10576
|
+
message: `title is too long (${String(title.length)}/100 characters)`
|
|
10577
|
+
});
|
|
10578
|
+
return;
|
|
10579
|
+
}
|
|
10580
|
+
if (!conversationId) {
|
|
10581
|
+
useStore.getState().showToast({ message: "nothing to rename yet — send a message to start this one" });
|
|
10582
|
+
return;
|
|
10583
|
+
}
|
|
10584
|
+
if (!rest) return;
|
|
10585
|
+
rest.renameConversation({
|
|
10586
|
+
conversationId,
|
|
10587
|
+
title
|
|
10588
|
+
}).then(() => {
|
|
10589
|
+
useStore.getState().setChatTitle(title);
|
|
10590
|
+
useStore.getState().showToast({
|
|
10591
|
+
variant: "success",
|
|
10592
|
+
message: `renamed to “${title}”`
|
|
10593
|
+
});
|
|
10594
|
+
}).catch((err) => useStore.getState().showToast({
|
|
10595
|
+
variant: "error",
|
|
10596
|
+
message: `couldn't rename: ${errorMessage(err)}`
|
|
10597
|
+
}));
|
|
10598
|
+
}, [conversationId, rest]);
|
|
10378
10599
|
/**
|
|
10379
10600
|
* Leave this conversation for another screen without ending its run: drop
|
|
10380
10601
|
* our own SSE subscription and nothing else — never `rest.cancelRun` — so
|
|
@@ -10434,7 +10655,10 @@ function ChatScreen({ agent, conversation }) {
|
|
|
10434
10655
|
leaveForScreen
|
|
10435
10656
|
]);
|
|
10436
10657
|
const toggleShare = useCallback(() => {
|
|
10437
|
-
if (!portalClient)
|
|
10658
|
+
if (!portalClient) {
|
|
10659
|
+
useStore.getState().showToast({ message: useStore.getState().authKind === "api-key" ? "local access needs a browser session — run `skydive auth login --web`" : "local access is unavailable in this session" });
|
|
10660
|
+
return;
|
|
10661
|
+
}
|
|
10438
10662
|
if (portal.status === "off") {
|
|
10439
10663
|
declinedRef.current.delete(agent.id);
|
|
10440
10664
|
portalClient.enable();
|
|
@@ -10475,7 +10699,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
10475
10699
|
}, [agent.id, setPortalPrompt]);
|
|
10476
10700
|
const openPortalAccess = useCallback(() => {
|
|
10477
10701
|
if (!portalClient) {
|
|
10478
|
-
useStore.getState().showToast({ message: "local access is unavailable in this session" });
|
|
10702
|
+
useStore.getState().showToast({ message: useStore.getState().authKind === "api-key" ? "local access needs a browser session — run `skydive auth login --web`" : "local access is unavailable in this session" });
|
|
10479
10703
|
return;
|
|
10480
10704
|
}
|
|
10481
10705
|
switch (portal.status) {
|
|
@@ -10540,6 +10764,9 @@ function ChatScreen({ agent, conversation }) {
|
|
|
10540
10764
|
case "archive-conversation":
|
|
10541
10765
|
archiveConversation();
|
|
10542
10766
|
break;
|
|
10767
|
+
case "rename-conversation":
|
|
10768
|
+
renameConversation(routed.title);
|
|
10769
|
+
break;
|
|
10543
10770
|
case "new-conversation":
|
|
10544
10771
|
if (runRef.current.kind !== "idle") {
|
|
10545
10772
|
useStore.getState().showToast({ message: "finish or cancel the run first (ctrl+c)" });
|
|
@@ -10653,6 +10880,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
10653
10880
|
runSandboxExec,
|
|
10654
10881
|
runSandboxPty,
|
|
10655
10882
|
archiveConversation,
|
|
10883
|
+
renameConversation,
|
|
10656
10884
|
forkAndContinue,
|
|
10657
10885
|
leaveForScreen,
|
|
10658
10886
|
openConversationRef,
|
|
@@ -11235,6 +11463,9 @@ function ChatScreen({ agent, conversation }) {
|
|
|
11235
11463
|
},
|
|
11236
11464
|
children: /* @__PURE__ */ jsx("textarea", {
|
|
11237
11465
|
ref: composerRef,
|
|
11466
|
+
textColor: theme.fg,
|
|
11467
|
+
focusedTextColor: theme.fg,
|
|
11468
|
+
placeholderColor: theme.dim,
|
|
11238
11469
|
placeholder: forking ? "forking into a new chat…" : `message ${agent.name}…`,
|
|
11239
11470
|
keyBindings: composerKeyBindings,
|
|
11240
11471
|
onContentChange: handleComposerChange,
|
|
@@ -11367,12 +11598,18 @@ function CredentialPromptBox({ prompt, height, onInput, onSubmit }) {
|
|
|
11367
11598
|
]
|
|
11368
11599
|
}),
|
|
11369
11600
|
field.secret ? /* @__PURE__ */ jsx("input", {
|
|
11601
|
+
textColor: theme.fg,
|
|
11602
|
+
focusedTextColor: theme.fg,
|
|
11603
|
+
placeholderColor: theme.dim,
|
|
11370
11604
|
value: MASK_CHAR.repeat(prompt.current.length),
|
|
11371
11605
|
placeholder: field.placeholder ?? "",
|
|
11372
11606
|
onInput,
|
|
11373
11607
|
onSubmit,
|
|
11374
11608
|
focused: !prompt.submitting
|
|
11375
11609
|
}, field.key) : /* @__PURE__ */ jsx("input", {
|
|
11610
|
+
textColor: theme.fg,
|
|
11611
|
+
focusedTextColor: theme.fg,
|
|
11612
|
+
placeholderColor: theme.dim,
|
|
11376
11613
|
placeholder: field.placeholder ?? "",
|
|
11377
11614
|
onInput,
|
|
11378
11615
|
onSubmit,
|
|
@@ -11486,6 +11723,7 @@ function ToastView() {
|
|
|
11486
11723
|
maxWidth: Math.min(60, Math.max(20, width - 6)),
|
|
11487
11724
|
border: true,
|
|
11488
11725
|
borderColor: toastColor(toast.variant),
|
|
11726
|
+
backgroundColor: theme.surface ?? "#1a1a1a",
|
|
11489
11727
|
paddingLeft: 1,
|
|
11490
11728
|
paddingRight: 1
|
|
11491
11729
|
},
|
|
@@ -11499,7 +11737,7 @@ function ToastView() {
|
|
|
11499
11737
|
|
|
11500
11738
|
//#endregion
|
|
11501
11739
|
//#region src/chat/tui/app.tsx
|
|
11502
|
-
function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notifications, agentSelector, conversationId, newConversation }) {
|
|
11740
|
+
function App({ appUrl, sessionToken, authKind, shareMachine, promptHistoryPath, notifications, agentSelector, conversationId, newConversation }) {
|
|
11503
11741
|
const renderer = useRenderer();
|
|
11504
11742
|
const screen = useStore((s) => s.screen);
|
|
11505
11743
|
const chatTitle = useStore((s) => s.chatTitle);
|
|
@@ -11515,7 +11753,8 @@ function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notificati
|
|
|
11515
11753
|
usePortal({
|
|
11516
11754
|
appUrl,
|
|
11517
11755
|
sessionToken,
|
|
11518
|
-
shareMachine
|
|
11756
|
+
shareMachine,
|
|
11757
|
+
enabled: authKind === "session"
|
|
11519
11758
|
});
|
|
11520
11759
|
useEffect(() => {
|
|
11521
11760
|
agentHost.transition({ state: "idle" });
|
|
@@ -11543,6 +11782,7 @@ function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notificati
|
|
|
11543
11782
|
const fail = useStore((s) => s.fail);
|
|
11544
11783
|
const setWorkspaceName = useStore((s) => s.setWorkspaceName);
|
|
11545
11784
|
useEffect(() => {
|
|
11785
|
+
if (authKind !== "session") return;
|
|
11546
11786
|
let cancelled = false;
|
|
11547
11787
|
(async () => {
|
|
11548
11788
|
const [activeId, workspaces] = await Promise.all([getActiveWorkspaceId({
|
|
@@ -11561,6 +11801,7 @@ function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notificati
|
|
|
11561
11801
|
}, [
|
|
11562
11802
|
appUrl,
|
|
11563
11803
|
sessionToken,
|
|
11804
|
+
authKind,
|
|
11564
11805
|
setWorkspaceName
|
|
11565
11806
|
]);
|
|
11566
11807
|
useEffect(() => {
|
|
@@ -11899,6 +12140,24 @@ var LinkifiedMarkdownRenderable = class extends MarkdownRenderable {
|
|
|
11899
12140
|
}
|
|
11900
12141
|
};
|
|
11901
12142
|
|
|
12143
|
+
//#endregion
|
|
12144
|
+
//#region src/chat/tui/chunks/grammars/index.ts
|
|
12145
|
+
/**
|
|
12146
|
+
* Register the extra tree-sitter grammars (python, go, rust, bash, …) before
|
|
12147
|
+
* the renderer boots its tree-sitter client, so fenced code blocks and diffs
|
|
12148
|
+
* in those languages highlight instead of rendering as plain text.
|
|
12149
|
+
*
|
|
12150
|
+
* `addDefaultParsers` merges by filetype into the set the client registers on
|
|
12151
|
+
* init, so this must run BEFORE `createCliRenderer`. The grammar definitions
|
|
12152
|
+
* live in ./grammars.ts, which is externalized from the tsdown bundle (it
|
|
12153
|
+
* imports `.wasm`/`.scm` assets rolldown can't parse) — so we reach it through
|
|
12154
|
+
* a dynamic import that both Bun-runtime (npm) and the compiled binary resolve.
|
|
12155
|
+
*/
|
|
12156
|
+
async function registerGrammars() {
|
|
12157
|
+
const { EXTRA_GRAMMARS } = await import("./chat/tui/chunks/grammars/grammars.js");
|
|
12158
|
+
addDefaultParsers(EXTRA_GRAMMARS);
|
|
12159
|
+
}
|
|
12160
|
+
|
|
11902
12161
|
//#endregion
|
|
11903
12162
|
//#region src/chat/memory-watchdog.ts
|
|
11904
12163
|
const MB = 1024 * 1024;
|
|
@@ -12066,12 +12325,14 @@ async function settleBootThemeMode({ source, applyThemeMode, graceMs = THEME_QUE
|
|
|
12066
12325
|
* module — and the heavy OpenTUI dependency graph it pulls in — is
|
|
12067
12326
|
* dynamically imported and never loaded on the Node management path.
|
|
12068
12327
|
*/
|
|
12069
|
-
async function runChat({ appUrl, sessionToken, shareMachine, promptHistoryPath, theme: themeOverride, notifications, agentSelector, conversationId, newConversation, seedPrompt }) {
|
|
12328
|
+
async function runChat({ appUrl, sessionToken, authKind = "session", shareMachine, promptHistoryPath, theme: themeOverride, notifications, agentSelector, conversationId, newConversation, seedPrompt }) {
|
|
12329
|
+
await registerGrammars();
|
|
12070
12330
|
const watchdog = startMemoryWatchdog();
|
|
12071
12331
|
installCrashHandler({ memoryProvider: () => watchdog.snapshot() });
|
|
12072
12332
|
const renderer = await createCliRenderer({ exitOnCtrlC: false });
|
|
12073
12333
|
extend({ markdown: LinkifiedMarkdownRenderable });
|
|
12074
12334
|
useStore.setState({
|
|
12335
|
+
authKind,
|
|
12075
12336
|
seedPrompt: seedPrompt ?? null,
|
|
12076
12337
|
autoGrantMachine: Boolean(seedPrompt && shareMachine),
|
|
12077
12338
|
newConversationIntent: newConversation
|
|
@@ -12091,6 +12352,7 @@ async function runChat({ appUrl, sessionToken, shareMachine, promptHistoryPath,
|
|
|
12091
12352
|
createRoot(renderer).render(/* @__PURE__ */ jsx(App, {
|
|
12092
12353
|
appUrl,
|
|
12093
12354
|
sessionToken,
|
|
12355
|
+
authKind,
|
|
12094
12356
|
shareMachine,
|
|
12095
12357
|
promptHistoryPath,
|
|
12096
12358
|
notifications,
|