@chances-ai/client 24.2.0 → 25.0.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/dist/client-core/client.d.ts +47 -1
- package/dist/client-core/client.d.ts.map +1 -1
- package/dist/client-core/client.js +143 -15
- package/dist/client-core/client.js.map +1 -1
- package/dist/client-core/store.d.ts +36 -0
- package/dist/client-core/store.d.ts.map +1 -1
- package/dist/client-core/store.js +4 -0
- package/dist/client-core/store.js.map +1 -1
- package/dist/client-core/transport.d.ts +1 -1
- package/dist/client-core/transport.d.ts.map +1 -1
- package/dist/client-core/transport.js +5 -1
- package/dist/client-core/transport.js.map +1 -1
- package/dist/web-ui/code-editor.d.ts +19 -0
- package/dist/web-ui/code-editor.d.ts.map +1 -0
- package/dist/web-ui/code-editor.js +111 -0
- package/dist/web-ui/code-editor.js.map +1 -0
- package/dist/web-ui/control-panel.d.ts.map +1 -1
- package/dist/web-ui/control-panel.js +20 -2
- package/dist/web-ui/control-panel.js.map +1 -1
- package/dist/web-ui/file-tree.d.ts.map +1 -1
- package/dist/web-ui/file-tree.js +7 -2
- package/dist/web-ui/file-tree.js.map +1 -1
- package/dist/web-ui/session-hotkeys.d.ts +14 -0
- package/dist/web-ui/session-hotkeys.d.ts.map +1 -0
- package/dist/web-ui/session-hotkeys.js +38 -0
- package/dist/web-ui/session-hotkeys.js.map +1 -0
- package/dist/web-ui/session-sidebar.d.ts +4 -2
- package/dist/web-ui/session-sidebar.d.ts.map +1 -1
- package/dist/web-ui/session-sidebar.js +25 -7
- package/dist/web-ui/session-sidebar.js.map +1 -1
- package/dist/web-ui/settings.d.ts +13 -0
- package/dist/web-ui/settings.d.ts.map +1 -0
- package/dist/web-ui/settings.js +27 -0
- package/dist/web-ui/settings.js.map +1 -0
- package/dist/web-ui/terminal.d.ts +10 -0
- package/dist/web-ui/terminal.d.ts.map +1 -0
- package/dist/web-ui/terminal.js +115 -0
- package/dist/web-ui/terminal.js.map +1 -0
- package/package.json +25 -5
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* (7.5 W2) The right-pane Monaco read-WRITE editor — the editable counterpart of
|
|
4
|
+
* the read-only `CodeViewer`. Mounted (lazily) by `ControlPanel` only when the
|
|
5
|
+
* agent advertises `workspaceEdits`; a viewer under a controller lease (or a
|
|
6
|
+
* binary file) gets a read-only editor. Save (⌘/Ctrl+S or the Save button) calls
|
|
7
|
+
* `RpcClient.applyEdit` — fail-closed containment + the controller-lease gate live
|
|
8
|
+
* server-side; the fanned `workspace_changed` re-reads the file into the store.
|
|
9
|
+
*
|
|
10
|
+
* Monaco + this file are code-split (`React.lazy` in `control-panel.tsx`) so the
|
|
11
|
+
* chat-only bundle never loads the editor (the W6 lazy-load gate). Theme is
|
|
12
|
+
* derived from the SAME ui-core seed engine as the transcript via
|
|
13
|
+
* `seedThemeToMonaco` (decision [11.10]) — no second palette.
|
|
14
|
+
*
|
|
15
|
+
* Browser-only (Monaco needs a real DOM/canvas) → not happy-dom-testable; the
|
|
16
|
+
* pure decision helpers below ARE unit-tested (`code-editor.test.ts`).
|
|
17
|
+
*/
|
|
18
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
19
|
+
import Editor, { loader } from "@monaco-editor/react";
|
|
20
|
+
import { seedThemeToMonaco } from "@chances-ai/design-system";
|
|
21
|
+
import { Row, Surface, Text } from "@chances-ai/design-system";
|
|
22
|
+
import { Button } from "./button.js";
|
|
23
|
+
import { langFromPath } from "./helpers.js";
|
|
24
|
+
// Local-first: load Monaco's core from a LOCALLY-served copy (`/monaco/vs`,
|
|
25
|
+
// copied from the `monaco-editor` package into apps/web's static dir at build)
|
|
26
|
+
// instead of @monaco-editor/react's default jsDelivr CDN — so the editor works
|
|
27
|
+
// offline / on a LAN-only deploy and ships no third-party runtime origin. Runs
|
|
28
|
+
// when this lazy chunk loads (before any Editor mounts). Monaco stays OUT of the
|
|
29
|
+
// JS bundle (the AMD loader fetches `vs` on demand) → the chat-only bundle is
|
|
30
|
+
// unaffected (W6 lazy-load gate).
|
|
31
|
+
loader.config({ paths: { vs: "/monaco/vs" } });
|
|
32
|
+
// -- pure helpers (unit-tested) --------------------------------------------
|
|
33
|
+
/** Monaco theme id per colour mode (registered in `beforeMount`). */
|
|
34
|
+
export function monacoThemeId(mode) {
|
|
35
|
+
return `chances-${mode}`;
|
|
36
|
+
}
|
|
37
|
+
/** Map our highlight.js-style language id (langFromPath) to a Monaco language id.
|
|
38
|
+
* Monaco falls back to plaintext for an unknown id, so only the few that differ
|
|
39
|
+
* need translating. */
|
|
40
|
+
export function editorLanguage(path) {
|
|
41
|
+
const lang = langFromPath(path);
|
|
42
|
+
if (!lang)
|
|
43
|
+
return "plaintext";
|
|
44
|
+
const remap = { bash: "shell", xml: "html" };
|
|
45
|
+
return remap[lang] ?? lang;
|
|
46
|
+
}
|
|
47
|
+
/** The draft differs from what's on disk ⇒ a Save is meaningful. */
|
|
48
|
+
export function isDirty(draft, openFile) {
|
|
49
|
+
return openFile !== null && !openFile.binary && draft !== openFile.content;
|
|
50
|
+
}
|
|
51
|
+
export function CodeEditor({ client, openFile, canWrite, mode }) {
|
|
52
|
+
const [draft, setDraft] = useState(openFile?.content ?? "");
|
|
53
|
+
const [saving, setSaving] = useState(false);
|
|
54
|
+
const [saveError, setSaveError] = useState(null);
|
|
55
|
+
// Latest draft for the Monaco ⌘S command (registered once, closes over a ref).
|
|
56
|
+
const draftRef = useRef(draft);
|
|
57
|
+
draftRef.current = draft;
|
|
58
|
+
const pathRef = useRef(openFile?.path ?? null);
|
|
59
|
+
pathRef.current = openFile?.path ?? null;
|
|
60
|
+
// Reset the draft whenever a different file opens OR the store re-reads it
|
|
61
|
+
// (e.g. after our own save's `workspace_changed`, or an agent edit).
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
setDraft(openFile?.content ?? "");
|
|
64
|
+
setSaveError(null);
|
|
65
|
+
}, [openFile?.path, openFile?.content]);
|
|
66
|
+
const dirty = isDirty(draft, openFile);
|
|
67
|
+
const save = useCallback(async () => {
|
|
68
|
+
const path = pathRef.current;
|
|
69
|
+
if (path === null || !canWrite)
|
|
70
|
+
return;
|
|
71
|
+
setSaving(true);
|
|
72
|
+
setSaveError(null);
|
|
73
|
+
try {
|
|
74
|
+
await client.applyEdit({ path, content: draftRef.current });
|
|
75
|
+
// The relay fans `workspace_changed` → the store re-reads → the effect
|
|
76
|
+
// above resets the draft and clears `dirty`.
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
setSaveError(e.message ?? "save failed");
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
setSaving(false);
|
|
83
|
+
}
|
|
84
|
+
}, [client, canWrite]);
|
|
85
|
+
const beforeMount = useCallback((monaco) => {
|
|
86
|
+
// Derive both themes from the seed engine so inline colours match the
|
|
87
|
+
// transcript; register under a mode-keyed id.
|
|
88
|
+
monaco.editor.defineTheme(monacoThemeId("dark"), seedThemeToMonaco("default", "dark"));
|
|
89
|
+
monaco.editor.defineTheme(monacoThemeId("light"), seedThemeToMonaco("default", "light"));
|
|
90
|
+
}, []);
|
|
91
|
+
const onMount = useCallback((editor, monaco) => {
|
|
92
|
+
// ⌘/Ctrl+S saves (only meaningful when writable).
|
|
93
|
+
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => void save());
|
|
94
|
+
}, [save]);
|
|
95
|
+
if (!openFile) {
|
|
96
|
+
return (_jsx(Surface, { align: "center", justify: "center", className: "h-full", children: _jsx(Text, { className: "text-[13px]", style: { color: "var(--ch-text-weak)" }, children: "Select a file to edit" }) }));
|
|
97
|
+
}
|
|
98
|
+
if (openFile.binary) {
|
|
99
|
+
return (_jsx(Surface, { align: "center", justify: "center", className: "h-full", children: _jsx(Text, { className: "text-[13px]", style: { color: "var(--ch-text-weak)" }, children: "Binary file \u2014 not shown" }) }));
|
|
100
|
+
}
|
|
101
|
+
const readOnly = !canWrite;
|
|
102
|
+
return (_jsxs(Surface, { className: "h-full overflow-hidden", children: [_jsxs(Row, { align: "center", gap: "sm", className: "border-b px-2.5 py-1.5", style: { borderColor: "var(--ch-border)" }, children: [_jsxs(Text, { className: "flex-1 truncate font-mono text-[12px]", style: { color: "var(--ch-fg)" }, children: [dirty ? "● " : "", openFile.path, readOnly ? " (read-only)" : ""] }), saveError ? (_jsx(Text, { className: "text-[11px]", style: { color: "var(--ch-error)" }, children: saveError })) : null, !readOnly && dirty ? _jsx(Button, { label: saving ? "Saving…" : "Save", onPress: () => void save() }) : null] }), _jsx(Surface, { grow: true, className: "min-h-0", children: _jsx(Editor, { height: "100%", theme: monacoThemeId(mode), path: openFile.path, language: editorLanguage(openFile.path), value: draft, onChange: (v) => setDraft(v ?? ""), beforeMount: beforeMount, onMount: onMount, options: {
|
|
103
|
+
readOnly,
|
|
104
|
+
minimap: { enabled: false },
|
|
105
|
+
scrollBeyondLastLine: false,
|
|
106
|
+
fontSize: 12,
|
|
107
|
+
automaticLayout: true,
|
|
108
|
+
renderValidationDecorations: "off",
|
|
109
|
+
} }) })] }));
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=code-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-editor.js","sourceRoot":"","sources":["../../src/web-ui/code-editor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-panel.d.ts","sourceRoot":"","sources":["../../src/web-ui/control-panel.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"control-panel.d.ts","sourceRoot":"","sources":["../../src/web-ui/control-panel.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AA2BzD,OAAO,EAA6B,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAG1E,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,SAAS,CAAC;IAClB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,WAAoB,EAAE,EAAE,iBAAiB,2CAwK/E"}
|
|
@@ -17,12 +17,20 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
17
17
|
* no `node:*` — so the whole tree is browser-safe and the `vite build` that
|
|
18
18
|
* bundles it is the end-to-end browser-safety proof (docs/6.1 §4 / M1 B3).
|
|
19
19
|
*/
|
|
20
|
-
import { useMemo, useState } from "react";
|
|
20
|
+
import { lazy, Suspense, useMemo, useState } from "react";
|
|
21
21
|
import { themeCssVars } from "@chances-ai/ui-core";
|
|
22
22
|
import { heroUiThemeClassName, Row, Surface } from "@chances-ai/design-system";
|
|
23
23
|
import { ApprovalBadge } from "./approval-badge.js";
|
|
24
24
|
import { Button } from "./button.js";
|
|
25
25
|
import { CodeViewer } from "./code-viewer.js";
|
|
26
|
+
// (7.5 W2) Monaco is heavy → code-split it. The chat-only path (no workspaceEdits
|
|
27
|
+
// capability) never imports this chunk, so the base bundle stays light (the W6
|
|
28
|
+
// lazy-load gate). The read-only `CodeViewer` is the Suspense fallback + the
|
|
29
|
+
// no-write-capability fallback.
|
|
30
|
+
const CodeEditor = lazy(() => import("./code-editor.js").then((m) => ({ default: m.CodeEditor })));
|
|
31
|
+
// (7.5 W3) xterm is heavy + browser-only → code-split; loads only when the agent
|
|
32
|
+
// advertises `terminal` (off by default server-side).
|
|
33
|
+
const TerminalPane = lazy(() => import("./terminal.js").then((m) => ({ default: m.TerminalPane })));
|
|
26
34
|
import { EnvironmentPanel } from "./environment-panel.js";
|
|
27
35
|
import { FileTree } from "./file-tree.js";
|
|
28
36
|
import { HelpView } from "./help-view.js";
|
|
@@ -33,16 +41,26 @@ import { Progress } from "./progress.js";
|
|
|
33
41
|
import { PromptInput } from "./prompt-input.js";
|
|
34
42
|
import { QuestionView } from "./question-view.js";
|
|
35
43
|
import { SessionSidebar } from "./session-sidebar.js";
|
|
44
|
+
import { useSessionHotkeys } from "./session-hotkeys.js";
|
|
45
|
+
import { SettingsPanel } from "./settings.js";
|
|
36
46
|
import { StatusBar } from "./status-bar.js";
|
|
37
47
|
import { themeFor, UiThemeProvider } from "./theme-context.js";
|
|
38
48
|
import { Transcript } from "./transcript.js";
|
|
39
49
|
export function ControlPanel({ client, defaultMode = "dark" }) {
|
|
40
50
|
const [mode, setMode] = useState(defaultMode);
|
|
41
51
|
const [helpOpen, setHelpOpen] = useState(false);
|
|
52
|
+
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
42
53
|
const state = useClientState(client.store);
|
|
43
54
|
const lines = useTranscript(client.view);
|
|
44
55
|
const theme = themeFor(mode);
|
|
45
56
|
const controlsLocked = state.busy || state.status !== "ready";
|
|
57
|
+
// (7.5 §14 / [12.14]) Keyboard quick-switch: Alt+1..9 slots + Cmd/Ctrl+K cycle.
|
|
58
|
+
useSessionHotkeys({
|
|
59
|
+
enabled: state.listSessionsSupported,
|
|
60
|
+
sessions: state.sessions,
|
|
61
|
+
activeId: state.sessionId,
|
|
62
|
+
onSwitch: (id) => void client.loadSession(id),
|
|
63
|
+
});
|
|
46
64
|
// (v22) Client-side slash commands — pure actions on the client/view/UI (the
|
|
47
65
|
// web has no engine command backend; see commands.ts). `setMode`'s functional
|
|
48
66
|
// form keeps the registry stable across renders.
|
|
@@ -70,6 +88,6 @@ export function ControlPanel({ client, defaultMode = "dark" }) {
|
|
|
70
88
|
flexDirection: "column",
|
|
71
89
|
background: "var(--ch-bg)",
|
|
72
90
|
color: "var(--ch-fg)",
|
|
73
|
-
}, children: [_jsxs(Row, { align: "center", gap: "md", className: "flex-wrap border-b px-4 py-2.5", style: { borderColor: "var(--ch-border)" }, children: [_jsx("span", { style: { color: theme.accent, fontWeight: 700 }, children: "chances" }), _jsx(Surface, { grow: true }), _jsx(ApprovalBadge, { mode: state.approvalMode, disabled: state.status !== "ready" || !state.approvalSupported, onCycle: () => void client.cycleApprovalMode() }), _jsx(ModelPicker, { models: state.models, selected: state.selected, disabled: controlsLocked, onSelect: (m) => void client.setModel(m) }), _jsx(Button, { label: mode === "dark" ? "☀ light" : "☾ dark", color: theme.synComment, onPress: () => setMode(mode === "dark" ? "light" : "dark") })] }), _jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "row", minHeight: 0 }, children: [showWorkspace ? (_jsx("div", { style: { width: 220, flexShrink: 0, borderRight: "1px solid var(--ch-border)", overflow: "hidden" }, children: _jsx(SessionSidebar, { state: state, onNewChat: () => client.view.clearLines() }) })) : null, _jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "column", minWidth: 0 }, children: [_jsx("div", { style: { flex: 1, paddingLeft: 16, paddingRight: 16, overflowY: "auto" }, children: _jsx(Transcript, { lines: lines, committedCount: client.view.committedCount }) }), showWorkspace ? (_jsx(Surface, { className: "border-t", style: { borderColor: "var(--ch-border)" }, children: _jsx(EnvironmentPanel, { client: client, gitStatus: state.gitStatus, busy: state.busy }) })) : null, _jsxs(Surface, { gap: "sm", className: "border-t px-4 py-2.5", style: { borderColor: "var(--ch-border)" }, children: [state.pendingPermission ? (_jsx(PermissionPrompt, { pending: state.pendingPermission, onAnswer: (allow, remember) => client.answerPermission(allow, remember) })) : null, state.pendingQuestion ? (_jsx(QuestionView, { pending: state.pendingQuestion, onAnswer: (a) => client.answerQuestion(a) })) : null, state.busy ? _jsx(Progress, { active: true }) : null, _jsx(PromptInput, { busy: state.busy, disabled: state.status !== "ready", onSubmit: (t) => client.prompt(t), onAbort: () => client.abort(), commands: commands, onCommand: runCommand }), _jsx(StatusBar, { state: state })] })] }), showWorkspace ? (_jsxs("div", { style: { width: 340, flexShrink: 0, borderLeft: "1px solid var(--ch-border)", display: "flex", flexDirection: "column", minHeight: 0 }, children: [_jsx("div", { style: { flex: 1, minHeight: 0, borderBottom: "1px solid var(--ch-border)", overflow: "hidden" }, children: _jsx(FileTree, { client: client, gitStatus: state.gitStatus, openPath: state.openFile?.path }) }), _jsx("div", { style: { flex: 1, minHeight: 0, overflow: "hidden" }, children: _jsx(CodeViewer, { client: client, openFile: state.openFile, gitStatus: state.gitStatus, busy: state.busy }) })] })) : null] }), helpOpen ? _jsx(HelpView, { commands: commands, onClose: () => setHelpOpen(false) }) : null] }) }));
|
|
91
|
+
}, children: [_jsxs(Row, { align: "center", gap: "md", className: "flex-wrap border-b px-4 py-2.5", style: { borderColor: "var(--ch-border)" }, children: [_jsx("span", { style: { color: theme.accent, fontWeight: 700 }, children: "chances" }), _jsx(Surface, { grow: true }), _jsx(ApprovalBadge, { mode: state.approvalMode, disabled: state.status !== "ready" || !state.approvalSupported, onCycle: () => void client.cycleApprovalMode() }), _jsx(ModelPicker, { models: state.models, selected: state.selected, disabled: controlsLocked, onSelect: (m) => void client.setModel(m) }), _jsx(Button, { label: mode === "dark" ? "☀ light" : "☾ dark", color: theme.synComment, onPress: () => setMode(mode === "dark" ? "light" : "dark") }), _jsx(Button, { label: "\u2699", color: theme.synComment, onPress: () => setSettingsOpen(true) })] }), settingsOpen ? (_jsx(SettingsPanel, { mode: mode, onToggleMode: () => setMode((m) => (m === "dark" ? "light" : "dark")), approvalMode: state.approvalMode, approvalSupported: state.approvalSupported && state.status === "ready", onCycleApproval: () => void client.cycleApprovalMode(), multiSession: state.listSessionsSupported, onClose: () => setSettingsOpen(false) })) : null, _jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "row", minHeight: 0 }, children: [showWorkspace ? (_jsx("div", { style: { width: 220, flexShrink: 0, borderRight: "1px solid var(--ch-border)", overflow: "hidden" }, children: _jsx(SessionSidebar, { state: state, onNewChat: () => (state.listSessionsSupported ? void client.newSession() : client.view.clearLines()), onSwitchSession: (id) => void client.loadSession(id) }) })) : null, _jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "column", minWidth: 0 }, children: [_jsx("div", { style: { flex: 1, paddingLeft: 16, paddingRight: 16, overflowY: "auto" }, children: _jsx(Transcript, { lines: lines, committedCount: client.view.committedCount }) }), showWorkspace ? (_jsx(Surface, { className: "border-t", style: { borderColor: "var(--ch-border)" }, children: _jsx(EnvironmentPanel, { client: client, gitStatus: state.gitStatus, busy: state.busy }) })) : null, _jsxs(Surface, { gap: "sm", className: "border-t px-4 py-2.5", style: { borderColor: "var(--ch-border)" }, children: [state.pendingPermission ? (_jsx(PermissionPrompt, { pending: state.pendingPermission, onAnswer: (allow, remember) => client.answerPermission(allow, remember) })) : null, state.pendingQuestion ? (_jsx(QuestionView, { pending: state.pendingQuestion, onAnswer: (a) => client.answerQuestion(a) })) : null, state.busy ? _jsx(Progress, { active: true }) : null, _jsx(PromptInput, { busy: state.busy, disabled: state.status !== "ready", onSubmit: (t) => client.prompt(t), onAbort: () => client.abort(), commands: commands, onCommand: runCommand }), _jsx(StatusBar, { state: state })] })] }), showWorkspace ? (_jsxs("div", { style: { width: 340, flexShrink: 0, borderLeft: "1px solid var(--ch-border)", display: "flex", flexDirection: "column", minHeight: 0 }, children: [_jsx("div", { style: { flex: 1, minHeight: 0, borderBottom: "1px solid var(--ch-border)", overflow: "hidden" }, children: _jsx(FileTree, { client: client, gitStatus: state.gitStatus, openPath: state.openFile?.path }) }), _jsx("div", { style: { flex: 1, minHeight: 0, overflow: "hidden" }, children: state.workspaceEditsSupported ? (_jsx(Suspense, { fallback: _jsx(CodeViewer, { client: client, openFile: state.openFile, gitStatus: state.gitStatus, busy: state.busy }), children: _jsx(CodeEditor, { client: client, openFile: state.openFile, canWrite: state.workspaceEditsSupported && state.isController, mode: mode }) })) : (_jsx(CodeViewer, { client: client, openFile: state.openFile, gitStatus: state.gitStatus, busy: state.busy })) }), state.terminalSupported ? (_jsx("div", { style: { flex: 1, minHeight: 0, borderTop: "1px solid var(--ch-border)", overflow: "hidden" }, children: _jsx(Suspense, { fallback: null, children: _jsx(TerminalPane, { client: client, mode: mode }) }) })) : null] })) : null] }), helpOpen ? _jsx(HelpView, { commands: commands, onClose: () => setHelpOpen(false) }) : null] }) }));
|
|
74
92
|
}
|
|
75
93
|
//# sourceMappingURL=control-panel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-panel.js","sourceRoot":"","sources":["../../src/web-ui/control-panel.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"control-panel.js","sourceRoot":"","sources":["../../src/web-ui/control-panel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-tree.d.ts","sourceRoot":"","sources":["../../src/web-ui/file-tree.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAa,eAAe,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAIrF,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;IAClC,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"file-tree.d.ts","sourceRoot":"","sources":["../../src/web-ui/file-tree.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAa,eAAe,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAIrF,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;IAClC,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,aAAa,2CA4GtE"}
|
package/dist/web-ui/file-tree.js
CHANGED
|
@@ -10,7 +10,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
10
10
|
* Pure-presentational over the injected client — browser-safe, no node.
|
|
11
11
|
*/
|
|
12
12
|
import { useEffect, useState } from "react";
|
|
13
|
-
import { Surface, Text } from "@chances-ai/design-system";
|
|
13
|
+
import { ChangeBar, Surface, Text } from "@chances-ai/design-system";
|
|
14
14
|
import { gitBadge } from "./helpers.js";
|
|
15
15
|
import { useUiTheme } from "./theme-context.js";
|
|
16
16
|
const childPath = (dir, name) => (dir === "." || dir === "" ? name : `${dir}/${name}`);
|
|
@@ -41,6 +41,10 @@ export function FileTree({ client, gitStatus, openPath }) {
|
|
|
41
41
|
void loadDir(dir);
|
|
42
42
|
}
|
|
43
43
|
const statusByPath = new Map((gitStatus?.files ?? []).map((f) => [f.path, f.status]));
|
|
44
|
+
// (7.5 W5) Per-file line counts → the 5-block change-bar (when git supplied numstat).
|
|
45
|
+
const countsByPath = new Map((gitStatus?.files ?? [])
|
|
46
|
+
.filter((f) => f.added !== undefined || f.removed !== undefined)
|
|
47
|
+
.map((f) => [f.path, { added: f.added ?? 0, removed: f.removed ?? 0 }]));
|
|
44
48
|
function renderEntries(dir, depth) {
|
|
45
49
|
const entries = childrenByDir[dir];
|
|
46
50
|
if (!entries)
|
|
@@ -50,6 +54,7 @@ export function FileTree({ client, gitStatus, openPath }) {
|
|
|
50
54
|
const isDir = e.kind === "dir";
|
|
51
55
|
const isOpen = expanded[path] === true;
|
|
52
56
|
const badge = gitBadge(statusByPath.get(path) ?? "");
|
|
57
|
+
const counts = isDir ? undefined : countsByPath.get(path);
|
|
53
58
|
const selected = !isDir && path === openPath;
|
|
54
59
|
return (_jsxs("div", { children: [_jsxs("div", { role: "button", tabIndex: 0, onClick: () => (isDir ? toggle(path) : void client.openFileInViewer(path)), onKeyDown: (ev) => {
|
|
55
60
|
if (ev.key === "Enter" || ev.key === " ") {
|
|
@@ -69,7 +74,7 @@ export function FileTree({ client, gitStatus, openPath }) {
|
|
|
69
74
|
borderRadius: 4,
|
|
70
75
|
background: selected ? "var(--ch-border)" : undefined,
|
|
71
76
|
fontFamily: "system-ui, sans-serif",
|
|
72
|
-
}, children: [_jsx(Text, { className: "select-none", style: { width: 10, color: theme.synComment }, children: isDir ? (isOpen ? "▾" : "▸") : "" }), _jsx(Text, { className: "flex-1 truncate", style: { color: isDir ? theme.accent : "var(--ch-fg)" }, children: e.name }), badge ? (_jsx(Text, { weight: "bold", className: "select-none text-center", style: { width: 12, color: theme[badge.tone] }, children: badge.char })) : null] }), isDir && isOpen ? renderEntries(path, depth + 1) : null] }, path));
|
|
77
|
+
}, children: [_jsx(Text, { className: "select-none", style: { width: 10, color: theme.synComment }, children: isDir ? (isOpen ? "▾" : "▸") : "" }), _jsx(Text, { className: "flex-1 truncate", style: { color: isDir ? theme.accent : "var(--ch-fg)" }, children: e.name }), counts && (counts.added > 0 || counts.removed > 0) ? (_jsx(ChangeBar, { additions: counts.added, deletions: counts.removed })) : null, badge ? (_jsx(Text, { weight: "bold", className: "select-none text-center", style: { width: 12, color: theme[badge.tone] }, children: badge.char })) : null] }), isDir && isOpen ? renderEntries(path, depth + 1) : null] }, path));
|
|
73
78
|
});
|
|
74
79
|
}
|
|
75
80
|
return (_jsxs(Surface, { overflow: "scroll", className: "h-full py-1.5", children: [_jsx(Text, { className: "pl-2 text-[11px] uppercase tracking-wide", style: { color: theme.synComment }, children: "Files" }), error ? (_jsx(Text, { className: "pl-2 pt-1 text-[12px]", style: { color: theme.error }, children: error })) : (_jsx(Surface, { className: "mt-1", children: renderEntries(".", 0) }))] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-tree.js","sourceRoot":"","sources":["../../src/web-ui/file-tree.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"file-tree.js","sourceRoot":"","sources":["../../src/web-ui/file-tree.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAShD,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,IAAY,EAAU,EAAE,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;AAE/G,MAAM,UAAU,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAiB;IACrE,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,wEAAwE;IACxE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAA8B,EAAE,CAAC,CAAC;IACpF,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAA0B,EAAE,CAAC,CAAC;IACtE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,KAAK,UAAU,OAAO,CAAC,GAAW;QAChC,IAAI,aAAa,CAAC,GAAG,CAAC;YAAE,OAAO;QAC/B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACxC,gBAAgB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,QAAQ,CAAE,CAAW,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;QAClB,uDAAuD;IACzD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,MAAM,CAAC,GAAW;QACzB,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACxD,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACtF,sFAAsF;IACtF,MAAM,YAAY,GAAG,IAAI,GAAG,CAC1B,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC;SACrB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC;SAC/D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAC1E,CAAC;IAEF,SAAS,aAAa,CAAC,GAAW,EAAE,KAAa;QAC/C,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACvB,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC;YAC/B,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;YACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACrD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC1D,MAAM,QAAQ,GAAG,CAAC,KAAK,IAAI,IAAI,KAAK,QAAQ,CAAC;YAC7C,OAAO,CACL,0BACE,eACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAC1E,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE;4BAChB,IAAI,EAAE,CAAC,GAAG,KAAK,OAAO,IAAI,EAAE,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;gCACzC,EAAE,CAAC,cAAc,EAAE,CAAC;gCACpB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;4BAC5D,CAAC;wBACH,CAAC,EACD,KAAK,EAAE;4BACL,OAAO,EAAE,MAAM;4BACf,UAAU,EAAE,QAAQ;4BACpB,GAAG,EAAE,CAAC;4BACN,MAAM,EAAE,SAAS;4BACjB,WAAW,EAAE,CAAC,GAAG,KAAK,GAAG,EAAE;4BAC3B,YAAY,EAAE,CAAC;4BACf,UAAU,EAAE,CAAC;4BACb,aAAa,EAAE,CAAC;4BAChB,QAAQ,EAAE,EAAE;4BACZ,YAAY,EAAE,CAAC;4BACf,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS;4BACrD,UAAU,EAAE,uBAAuB;yBACpC,aAED,KAAC,IAAI,IAAC,SAAS,EAAC,aAAa,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,YACxE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAC7B,EACP,KAAC,IAAI,IAAC,SAAS,EAAC,iBAAiB,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,EAAE,YACtF,CAAC,CAAC,IAAI,GACF,EACN,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CACpD,KAAC,SAAS,IAAC,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,GAAI,CAClE,CAAC,CAAC,CAAC,IAAI,EACP,KAAK,CAAC,CAAC,CAAC,CACP,KAAC,IAAI,IAAC,MAAM,EAAC,MAAM,EAAC,SAAS,EAAC,yBAAyB,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,YACnG,KAAK,CAAC,IAAI,GACN,CACR,CAAC,CAAC,CAAC,IAAI,IACJ,EACL,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAzChD,IAAI,CA0CR,CACP,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CACL,MAAC,OAAO,IAAC,QAAQ,EAAC,QAAQ,EAAC,SAAS,EAAC,eAAe,aAClD,KAAC,IAAI,IAAC,SAAS,EAAC,0CAA0C,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,sBAEtF,EACN,KAAK,CAAC,CAAC,CAAC,CACP,KAAC,IAAI,IAAC,SAAS,EAAC,uBAAuB,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,YAClE,KAAK,GACD,CACR,CAAC,CAAC,CAAC,CACF,KAAC,OAAO,IAAC,SAAS,EAAC,MAAM,YAAE,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC,GAAW,CAC5D,IACO,CACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface SessionHotkeyOptions {
|
|
2
|
+
/** Only active when the agent advertises multi-session (listSessions cap). */
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
/** The session list in display order (slot N = sessions[N-1]). */
|
|
5
|
+
sessions: ReadonlyArray<{
|
|
6
|
+
id: string;
|
|
7
|
+
}>;
|
|
8
|
+
/** The currently-active session id (for Cmd/Ctrl+K cycling). */
|
|
9
|
+
activeId: string | null;
|
|
10
|
+
/** Switch to a session by id (`RpcClient.loadSession`). */
|
|
11
|
+
onSwitch: (id: string) => void;
|
|
12
|
+
}
|
|
13
|
+
export declare function useSessionHotkeys({ enabled, sessions, activeId, onSwitch }: SessionHotkeyOptions): void;
|
|
14
|
+
//# sourceMappingURL=session-hotkeys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-hotkeys.d.ts","sourceRoot":"","sources":["../../src/web-ui/session-hotkeys.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,oBAAoB;IACnC,8EAA8E;IAC9E,OAAO,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,QAAQ,EAAE,aAAa,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxC,gEAAgE;IAChE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,2DAA2D;IAC3D,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,wBAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,oBAAoB,GAAG,IAAI,CAwBvG"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* (7.5 §14 / decision [12.14]) Keyboard quick-switch for the web multi-session
|
|
3
|
+
* sidebar — the browser twin of the TUI's rebindable quick-switch action:
|
|
4
|
+
* · Alt+1..9 → jump to session slot N (the leader+digit slots, opt-in via
|
|
5
|
+
* the modifier so they never collide with typing).
|
|
6
|
+
* · Cmd/Ctrl+K → cycle to the NEXT session (a fast round-robin switch).
|
|
7
|
+
* No-op unless multi-session is advertised. Listens on `window` so it works from
|
|
8
|
+
* anywhere in the SPA (a `keydown` inside the composer still bubbles to window).
|
|
9
|
+
*/
|
|
10
|
+
import { useEffect } from "react";
|
|
11
|
+
export function useSessionHotkeys({ enabled, sessions, activeId, onSwitch }) {
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (!enabled || sessions.length === 0)
|
|
14
|
+
return;
|
|
15
|
+
const handler = (e) => {
|
|
16
|
+
// Alt+1..9 → slot N (no Ctrl/Meta, so it can't clash with browser chrome).
|
|
17
|
+
if (e.altKey && !e.ctrlKey && !e.metaKey && /^[1-9]$/.test(e.key)) {
|
|
18
|
+
const target = sessions[Number(e.key) - 1];
|
|
19
|
+
if (target && target.id !== activeId) {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
onSwitch(target.id);
|
|
22
|
+
}
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Cmd/Ctrl+K → next session (round-robin).
|
|
26
|
+
if ((e.metaKey || e.ctrlKey) && (e.key === "k" || e.key === "K") && sessions.length > 1) {
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
const cur = sessions.findIndex((s) => s.id === activeId);
|
|
29
|
+
const next = sessions[(cur + 1) % sessions.length];
|
|
30
|
+
if (next && next.id !== activeId)
|
|
31
|
+
onSwitch(next.id);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
window.addEventListener("keydown", handler);
|
|
35
|
+
return () => window.removeEventListener("keydown", handler);
|
|
36
|
+
}, [enabled, sessions, activeId, onSwitch]);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=session-hotkeys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-hotkeys.js","sourceRoot":"","sources":["../../src/web-ui/session-hotkeys.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAalC,MAAM,UAAU,iBAAiB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAwB;IAC/F,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC9C,MAAM,OAAO,GAAG,CAAC,CAAgB,EAAQ,EAAE;YACzC,2EAA2E;YAC3E,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClE,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC3C,IAAI,MAAM,IAAI,MAAM,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;oBACrC,CAAC,CAAC,cAAc,EAAE,CAAC;oBACnB,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACtB,CAAC;gBACD,OAAO;YACT,CAAC;YACD,2CAA2C;YAC3C,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxF,CAAC,CAAC,cAAc,EAAE,CAAC;gBACnB,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;gBACzD,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACnD,IAAI,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,QAAQ;oBAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACtD,CAAC;QACH,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC5C,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { ClientState } from "../client-core/index.js";
|
|
2
2
|
export interface SessionSidebarProps {
|
|
3
3
|
state: ClientState;
|
|
4
|
-
/**
|
|
4
|
+
/** "New chat" — starts a fresh session (multi) or clears the transcript (single). */
|
|
5
5
|
onNewChat: () => void;
|
|
6
|
+
/** Switch to an existing session (multi only). */
|
|
7
|
+
onSwitchSession?: (id: string) => void;
|
|
6
8
|
}
|
|
7
|
-
export declare function SessionSidebar({ state, onNewChat }: SessionSidebarProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function SessionSidebar({ state, onNewChat, onSwitchSession }: SessionSidebarProps): import("react/jsx-runtime").JSX.Element;
|
|
8
10
|
//# sourceMappingURL=session-sidebar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-sidebar.d.ts","sourceRoot":"","sources":["../../src/web-ui/session-sidebar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session-sidebar.d.ts","sourceRoot":"","sources":["../../src/web-ui/session-sidebar.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAK3D,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,WAAW,CAAC;IACnB,qFAAqF;IACrF,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,kDAAkD;IAClD,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,EAAE,mBAAmB,2CA2ExF"}
|
|
@@ -1,17 +1,35 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* (v23 M5 /
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* "New chat"
|
|
7
|
-
*
|
|
3
|
+
* (v23 M5 / 7.5 W4) The left rail. When the agent advertises multi-session
|
|
4
|
+
* (`listSessions` cap), this renders the SWITCHABLE session list (newest-first,
|
|
5
|
+
* active highlighted) sourced from ui-core's `SessionSummary` — "same sessions
|
|
6
|
+
* everywhere" (decision [12.14]) — with "New chat" starting a fresh session and a
|
|
7
|
+
* row click switching the active one. Without the cap it degrades to the lean
|
|
8
|
+
* single-session rail. Browser-safe, pure over the injected state + callbacks.
|
|
8
9
|
*/
|
|
9
10
|
import { Row, Surface, Text } from "@chances-ai/design-system";
|
|
10
11
|
import { Button } from "./button.js";
|
|
11
12
|
import { statusColor, statusText } from "./helpers.js";
|
|
12
13
|
import { useUiTheme } from "./theme-context.js";
|
|
13
|
-
export function SessionSidebar({ state, onNewChat }) {
|
|
14
|
+
export function SessionSidebar({ state, onNewChat, onSwitchSession }) {
|
|
14
15
|
const theme = useUiTheme();
|
|
15
|
-
|
|
16
|
+
const multi = state.listSessionsSupported;
|
|
17
|
+
return (_jsxs(Surface, { className: "h-full gap-2.5 p-2.5", children: [_jsx(Text, { weight: "bold", className: "text-[15px]", style: { color: theme.accent }, children: "chances" }), _jsx(Button, { label: "\uFF0B New chat", color: theme.accent, onPress: onNewChat }), _jsxs(Surface, { gap: "xs", className: "mt-2 min-h-0", grow: multi, children: [_jsx(Text, { className: "text-[11px] uppercase tracking-wide", style: { color: theme.synComment }, children: multi ? "Sessions" : "Session" }), multi ? (_jsx(Surface, { grow: true, overflow: "auto", gap: "xs", children: state.sessions.length === 0 ? (_jsx(Text, { className: "text-[12px]", style: { color: theme.synComment }, children: "No sessions yet" })) : (state.sessions.map((s, i) => {
|
|
18
|
+
const active = s.id === state.sessionId;
|
|
19
|
+
return (_jsxs("button", { type: "button", onClick: () => onSwitchSession?.(s.id),
|
|
20
|
+
// (7.5 §14) Alt+1..9 quick-switch slots ([12.14]); the title shows it.
|
|
21
|
+
title: i < 9 ? `${s.id} (Alt+${i + 1})` : s.id, style: {
|
|
22
|
+
display: "flex",
|
|
23
|
+
alignItems: "center",
|
|
24
|
+
gap: 6,
|
|
25
|
+
textAlign: "left",
|
|
26
|
+
padding: "4px 6px",
|
|
27
|
+
borderRadius: 4,
|
|
28
|
+
cursor: "pointer",
|
|
29
|
+
background: active ? "var(--ch-surface-raised, rgba(127,127,127,0.15))" : "transparent",
|
|
30
|
+
border: "none",
|
|
31
|
+
color: active ? "var(--ch-fg)" : theme.synComment,
|
|
32
|
+
}, children: [_jsx("span", { style: { fontSize: 9, color: s.busy ? theme.accent : "transparent", flex: "0 0 auto" }, "aria-label": s.busy ? "busy" : undefined, children: "\u25CF" }), _jsx("span", { style: { flex: 1, fontSize: 12, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: s.title || s.id })] }, s.id));
|
|
33
|
+
})) })) : (_jsx(Text, { className: "truncate font-mono text-[12px]", style: { color: state.sessionId ? "var(--ch-fg)" : theme.synComment }, children: state.sessionId ?? "—" }))] }), !multi ? _jsx(Surface, { grow: true }) : null, _jsxs(Row, { align: "center", className: "gap-1.5", children: [_jsx(Text, { className: "text-[12px]", style: { color: statusColor(state.status, theme) }, children: "\u25CF" }), _jsx(Text, { className: "text-[12px]", style: { color: theme.synComment }, children: statusText(state.status) })] })] }));
|
|
16
34
|
}
|
|
17
35
|
//# sourceMappingURL=session-sidebar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-sidebar.js","sourceRoot":"","sources":["../../src/web-ui/session-sidebar.tsx"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"session-sidebar.js","sourceRoot":"","sources":["../../src/web-ui/session-sidebar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Mode } from "./theme-context.js";
|
|
2
|
+
export interface SettingsPanelProps {
|
|
3
|
+
mode: Mode;
|
|
4
|
+
onToggleMode: () => void;
|
|
5
|
+
approvalMode: string;
|
|
6
|
+
approvalSupported: boolean;
|
|
7
|
+
onCycleApproval: () => void;
|
|
8
|
+
/** Whether multi-session quick-switch shortcuts apply (listSessions cap). */
|
|
9
|
+
multiSession: boolean;
|
|
10
|
+
onClose: () => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function SettingsPanel({ mode, onToggleMode, approvalMode, approvalSupported, onCycleApproval, multiSession, onClose }: SettingsPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/web-ui/settings.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAG/C,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,IAAI,CAAC;IACX,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,6EAA6E;IAC7E,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAUD,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,kBAAkB,2CAoDhJ"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* (7.5 §14 / DoD W5) The settings surface — a lightweight modal consolidating the
|
|
4
|
+
* session-level preferences plus a read-only keybindings reference. Theme + model +
|
|
5
|
+
* approval also live inline in the topbar (fast access); this panel is the single
|
|
6
|
+
* place that ALSO documents the web keyboard shortcuts (the TUI's rebindable
|
|
7
|
+
* keybindings.json is authored CLI-side — the web shows the effective bindings).
|
|
8
|
+
*
|
|
9
|
+
* Browser-safe, pure over the injected state + callbacks. Rendered only when open.
|
|
10
|
+
*/
|
|
11
|
+
import { Row, Surface, Text } from "@chances-ai/design-system";
|
|
12
|
+
import { Button } from "./button.js";
|
|
13
|
+
import { useUiTheme } from "./theme-context.js";
|
|
14
|
+
const SHORTCUTS = [
|
|
15
|
+
{ keys: "Enter", what: "Send message" },
|
|
16
|
+
{ keys: "Esc", what: "Abort the running turn" },
|
|
17
|
+
{ keys: "/", what: "Slash commands" },
|
|
18
|
+
{ keys: "Cmd/Ctrl + K", what: "Switch to the next session", multiOnly: true },
|
|
19
|
+
{ keys: "Alt + 1…9", what: "Jump to session slot N", multiOnly: true },
|
|
20
|
+
];
|
|
21
|
+
export function SettingsPanel({ mode, onToggleMode, approvalMode, approvalSupported, onCycleApproval, multiSession, onClose }) {
|
|
22
|
+
const theme = useUiTheme();
|
|
23
|
+
return (_jsx("div", {
|
|
24
|
+
// Backdrop — click outside closes.
|
|
25
|
+
onClick: onClose, style: { position: "fixed", inset: 0, background: "rgba(0,0,0,0.4)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 50 }, children: _jsxs(Surface, { onClick: (e) => e.stopPropagation(), className: "gap-3 p-4", style: { width: 380, maxWidth: "90vw", borderRadius: 8, border: "1px solid var(--ch-border)", background: "var(--ch-bg)" }, children: [_jsxs(Row, { align: "center", children: [_jsx(Text, { weight: "bold", className: "text-[15px]", children: "Settings" }), _jsx(Surface, { grow: true }), _jsx(Button, { label: "\u2715", color: theme.synComment, onPress: onClose })] }), _jsxs(Row, { align: "center", className: "justify-between", children: [_jsx(Text, { className: "text-[13px]", children: "Theme" }), _jsx(Button, { label: mode === "dark" ? "☀ light" : "☾ dark", color: theme.synComment, onPress: onToggleMode })] }), _jsxs(Row, { align: "center", className: "justify-between", children: [_jsx(Text, { className: "text-[13px]", children: "Approval mode" }), _jsx(Button, { label: approvalMode, color: theme.accent, disabled: !approvalSupported, onPress: onCycleApproval })] }), _jsx(Text, { weight: "bold", className: "mt-1 text-[11px] uppercase tracking-wide", style: { color: theme.synComment }, children: "Keyboard shortcuts" }), _jsx(Surface, { gap: "xs", children: SHORTCUTS.filter((s) => !s.multiOnly || multiSession).map((s) => (_jsxs(Row, { align: "center", className: "justify-between", children: [_jsx(Text, { className: "text-[12px]", style: { color: theme.synComment }, children: s.what }), _jsx(Text, { className: "font-mono text-[12px]", children: s.keys })] }, s.keys))) })] }) }));
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/web-ui/settings.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "@xterm/xterm/css/xterm.css";
|
|
2
|
+
import type { RpcClient } from "../client-core/index.js";
|
|
3
|
+
import type { Mode } from "./theme-context.js";
|
|
4
|
+
export interface TerminalPaneProps {
|
|
5
|
+
client: RpcClient;
|
|
6
|
+
/** Re-mounts on mode change so the canvas colours track the panel chrome. */
|
|
7
|
+
mode: Mode;
|
|
8
|
+
}
|
|
9
|
+
export declare function TerminalPane({ client, mode }: TerminalPaneProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=terminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/web-ui/terminal.tsx"],"names":[],"mappings":"AAkBA,OAAO,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAI/C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,SAAS,CAAC;IAClB,6EAA6E;IAC7E,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CA2F/D"}
|