@chances-ai/client 24.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.
Files changed (121) hide show
  1. package/dist/client-core/client.d.ts +145 -0
  2. package/dist/client-core/client.d.ts.map +1 -0
  3. package/dist/client-core/client.js +533 -0
  4. package/dist/client-core/client.js.map +1 -0
  5. package/dist/client-core/index.d.ts +16 -0
  6. package/dist/client-core/index.d.ts.map +1 -0
  7. package/dist/client-core/index.js +15 -0
  8. package/dist/client-core/index.js.map +1 -0
  9. package/dist/client-core/reverse-map.d.ts +66 -0
  10. package/dist/client-core/reverse-map.d.ts.map +1 -0
  11. package/dist/client-core/reverse-map.js +86 -0
  12. package/dist/client-core/reverse-map.js.map +1 -0
  13. package/dist/client-core/store.d.ts +144 -0
  14. package/dist/client-core/store.d.ts.map +1 -0
  15. package/dist/client-core/store.js +36 -0
  16. package/dist/client-core/store.js.map +1 -0
  17. package/dist/client-core/transport.d.ts +53 -0
  18. package/dist/client-core/transport.d.ts.map +1 -0
  19. package/dist/client-core/transport.js +103 -0
  20. package/dist/client-core/transport.js.map +1 -0
  21. package/dist/web-ui/approval-badge.d.ts +17 -0
  22. package/dist/web-ui/approval-badge.d.ts.map +1 -0
  23. package/dist/web-ui/approval-badge.js +24 -0
  24. package/dist/web-ui/approval-badge.js.map +1 -0
  25. package/dist/web-ui/button.d.ts +10 -0
  26. package/dist/web-ui/button.d.ts.map +1 -0
  27. package/dist/web-ui/button.js +16 -0
  28. package/dist/web-ui/button.js.map +1 -0
  29. package/dist/web-ui/code-view.d.ts +6 -0
  30. package/dist/web-ui/code-view.d.ts.map +1 -0
  31. package/dist/web-ui/code-view.js +14 -0
  32. package/dist/web-ui/code-view.js.map +1 -0
  33. package/dist/web-ui/code-viewer.d.ts +11 -0
  34. package/dist/web-ui/code-viewer.d.ts.map +1 -0
  35. package/dist/web-ui/code-viewer.js +55 -0
  36. package/dist/web-ui/code-viewer.js.map +1 -0
  37. package/dist/web-ui/commands.d.ts +23 -0
  38. package/dist/web-ui/commands.d.ts.map +1 -0
  39. package/dist/web-ui/commands.js +26 -0
  40. package/dist/web-ui/commands.js.map +1 -0
  41. package/dist/web-ui/control-panel.d.ts +9 -0
  42. package/dist/web-ui/control-panel.d.ts.map +1 -0
  43. package/dist/web-ui/control-panel.js +70 -0
  44. package/dist/web-ui/control-panel.js.map +1 -0
  45. package/dist/web-ui/diff-view.d.ts +8 -0
  46. package/dist/web-ui/diff-view.d.ts.map +1 -0
  47. package/dist/web-ui/diff-view.js +28 -0
  48. package/dist/web-ui/diff-view.js.map +1 -0
  49. package/dist/web-ui/environment-panel.d.ts +9 -0
  50. package/dist/web-ui/environment-panel.d.ts.map +1 -0
  51. package/dist/web-ui/environment-panel.js +38 -0
  52. package/dist/web-ui/environment-panel.js.map +1 -0
  53. package/dist/web-ui/file-tree.d.ts +9 -0
  54. package/dist/web-ui/file-tree.d.ts.map +1 -0
  55. package/dist/web-ui/file-tree.js +77 -0
  56. package/dist/web-ui/file-tree.js.map +1 -0
  57. package/dist/web-ui/help-view.d.ts +13 -0
  58. package/dist/web-ui/help-view.d.ts.map +1 -0
  59. package/dist/web-ui/help-view.js +15 -0
  60. package/dist/web-ui/help-view.js.map +1 -0
  61. package/dist/web-ui/helpers.d.ts +77 -0
  62. package/dist/web-ui/helpers.d.ts.map +1 -0
  63. package/dist/web-ui/helpers.js +176 -0
  64. package/dist/web-ui/helpers.js.map +1 -0
  65. package/dist/web-ui/hooks.d.ts +7 -0
  66. package/dist/web-ui/hooks.d.ts.map +1 -0
  67. package/dist/web-ui/hooks.js +26 -0
  68. package/dist/web-ui/hooks.js.map +1 -0
  69. package/dist/web-ui/index.d.ts +32 -0
  70. package/dist/web-ui/index.d.ts.map +1 -0
  71. package/dist/web-ui/index.js +38 -0
  72. package/dist/web-ui/index.js.map +1 -0
  73. package/dist/web-ui/markdown.d.ts +12 -0
  74. package/dist/web-ui/markdown.d.ts.map +1 -0
  75. package/dist/web-ui/markdown.js +55 -0
  76. package/dist/web-ui/markdown.js.map +1 -0
  77. package/dist/web-ui/model-picker.d.ts +9 -0
  78. package/dist/web-ui/model-picker.d.ts.map +1 -0
  79. package/dist/web-ui/model-picker.js +119 -0
  80. package/dist/web-ui/model-picker.js.map +1 -0
  81. package/dist/web-ui/permission.d.ts +7 -0
  82. package/dist/web-ui/permission.d.ts.map +1 -0
  83. package/dist/web-ui/permission.js +25 -0
  84. package/dist/web-ui/permission.js.map +1 -0
  85. package/dist/web-ui/primitives.d.ts +59 -0
  86. package/dist/web-ui/primitives.d.ts.map +1 -0
  87. package/dist/web-ui/primitives.js +38 -0
  88. package/dist/web-ui/primitives.js.map +1 -0
  89. package/dist/web-ui/progress.d.ts +28 -0
  90. package/dist/web-ui/progress.d.ts.map +1 -0
  91. package/dist/web-ui/progress.js +45 -0
  92. package/dist/web-ui/progress.js.map +1 -0
  93. package/dist/web-ui/prompt-input.d.ts +15 -0
  94. package/dist/web-ui/prompt-input.d.ts.map +1 -0
  95. package/dist/web-ui/prompt-input.js +129 -0
  96. package/dist/web-ui/prompt-input.js.map +1 -0
  97. package/dist/web-ui/question-view.d.ts +7 -0
  98. package/dist/web-ui/question-view.d.ts.map +1 -0
  99. package/dist/web-ui/question-view.js +60 -0
  100. package/dist/web-ui/question-view.js.map +1 -0
  101. package/dist/web-ui/segments.d.ts +8 -0
  102. package/dist/web-ui/segments.d.ts.map +1 -0
  103. package/dist/web-ui/segments.js +19 -0
  104. package/dist/web-ui/segments.js.map +1 -0
  105. package/dist/web-ui/session-sidebar.d.ts +15 -0
  106. package/dist/web-ui/session-sidebar.d.ts.map +1 -0
  107. package/dist/web-ui/session-sidebar.js +10 -0
  108. package/dist/web-ui/session-sidebar.js.map +1 -0
  109. package/dist/web-ui/status-bar.d.ts +10 -0
  110. package/dist/web-ui/status-bar.d.ts.map +1 -0
  111. package/dist/web-ui/status-bar.js +10 -0
  112. package/dist/web-ui/status-bar.js.map +1 -0
  113. package/dist/web-ui/theme-context.d.ts +13 -0
  114. package/dist/web-ui/theme-context.d.ts.map +1 -0
  115. package/dist/web-ui/theme-context.js +31 -0
  116. package/dist/web-ui/theme-context.js.map +1 -0
  117. package/dist/web-ui/transcript.d.ts +27 -0
  118. package/dist/web-ui/transcript.d.ts.map +1 -0
  119. package/dist/web-ui/transcript.js +56 -0
  120. package/dist/web-ui/transcript.js.map +1 -0
  121. package/package.json +56 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-view.js","sourceRoot":"","sources":["../../src/web-ui/code-view.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAO7C,MAAM,UAAU,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,EAAiB;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,OAAO,CACL,KAAC,GAAG,IAAC,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,YAC/B,KAAC,YAAY,IAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,GAAI,GAClD,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { GitStatusResult, ReadFileResult, RpcClient } from "../client-core/index.js";
2
+ export interface CodeViewerProps {
3
+ client: RpcClient;
4
+ openFile: ReadFileResult | null;
5
+ gitStatus: GitStatusResult | null;
6
+ /** A turn is running — on its falling edge an agent edit may have landed, so a
7
+ * loaded diff is invalidated + refetched (codex M5 SHOULD: stale-diff fix). */
8
+ busy?: boolean;
9
+ }
10
+ export declare function CodeViewer({ client, openFile, gitStatus, busy }: CodeViewerProps): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=code-viewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-viewer.d.ts","sourceRoot":"","sources":["../../src/web-ui/code-viewer.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAQ1F,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;IAClC;oFACgF;IAChF,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,eAAe,2CAyFhF"}
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * (v23 M5 / docs/6.6 §3) The right-pane code viewer — read-only. Renders the
4
+ * store's open file (`RpcClient.openFileInViewer` → `read_file`) with the shared
5
+ * `CodeView` (highlight.js segments), or, when the file is changed in git, a
6
+ * Code/Diff toggle that fetches `RpcClient.gitDiff(path)` and renders the shared
7
+ * `DiffBlock`. Binary / truncated files degrade gracefully.
8
+ *
9
+ * Reuses the SAME renderers as the transcript (`CodeView`/`DiffBlock`/`Theme`) —
10
+ * no Monaco, no second highlight path. Browser-safe, no node.
11
+ */
12
+ import { useEffect, useState } from "react";
13
+ import { Button } from "./button.js";
14
+ import { CodeView } from "./code-view.js";
15
+ import { DiffBlock } from "./diff-view.js";
16
+ import { langFromPath } from "./helpers.js";
17
+ import { Box, Txt } from "./primitives.js";
18
+ import { useUiTheme } from "./theme-context.js";
19
+ export function CodeViewer({ client, openFile, gitStatus, busy }) {
20
+ const theme = useUiTheme();
21
+ const [tab, setTab] = useState("code");
22
+ const [diff, setDiff] = useState(null);
23
+ const path = openFile?.path ?? null;
24
+ const changed = path !== null && (gitStatus?.files ?? []).some((f) => f.path === path);
25
+ // Reset to the code tab whenever a different file opens.
26
+ useEffect(() => {
27
+ setTab("code");
28
+ setDiff(null);
29
+ }, [path]);
30
+ // (codex M5 SHOULD) When a turn finishes, an agent edit may have changed the
31
+ // open file — drop the cached diff so the Diff tab refetches fresh content
32
+ // (otherwise it shows the pre-turn diff). Keyed on the falling edge of `busy`.
33
+ useEffect(() => {
34
+ if (!busy)
35
+ setDiff(null);
36
+ }, [busy]);
37
+ // Lazily fetch the diff when the diff tab is first shown for a changed file.
38
+ useEffect(() => {
39
+ if (tab !== "diff" || path === null || diff !== null)
40
+ return;
41
+ let live = true;
42
+ void client.gitDiff(path).then((r) => {
43
+ if (live)
44
+ setDiff(r.diff);
45
+ });
46
+ return () => {
47
+ live = false;
48
+ };
49
+ }, [tab, path, diff, client]);
50
+ if (!openFile) {
51
+ return (_jsx(Box, { style: { height: "100%" }, alignItems: "center", justifyContent: "center", children: _jsx(Txt, { color: theme.synComment, fontSize: 13, children: "Select a file to view" }) }));
52
+ }
53
+ return (_jsxs(Box, { style: { height: "100%", overflow: "hidden" }, children: [_jsxs(Box, { flexDirection: "row", alignItems: "center", gap: 8, paddingHorizontal: 10, paddingVertical: 6, borderBottomWidth: 1, borderColor: "var(--ch-border)", children: [_jsx(Txt, { color: "var(--ch-fg)", fontSize: 12, style: { flex: 1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", fontFamily: "ui-monospace, monospace" }, children: openFile.path }), changed ? (_jsxs(_Fragment, { children: [_jsx(Button, { label: "Code", color: tab === "code" ? theme.accent : theme.synComment, onPress: () => setTab("code") }), _jsx(Button, { label: "Diff", color: tab === "diff" ? theme.accent : theme.synComment, onPress: () => setTab("diff") })] })) : null] }), _jsx(Box, { style: { flex: 1, overflow: "auto" }, paddingVertical: 6, children: openFile.binary ? (_jsx(Txt, { color: theme.synComment, fontSize: 13, style: { paddingLeft: 10 }, children: "Binary file \u2014 not shown" })) : tab === "diff" && changed ? (diff === null ? (_jsx(Txt, { color: theme.synComment, fontSize: 13, style: { paddingLeft: 10 }, children: "Loading diff\u2026" })) : diff === "" ? (_jsx(Txt, { color: theme.synComment, fontSize: 13, style: { paddingLeft: 10 }, children: "No diff" })) : (_jsx(DiffBlock, { diff: diff, anchored: true }))) : (_jsxs(_Fragment, { children: [_jsx(CodeView, { code: openFile.content, lang: langFromPath(openFile.path) }), openFile.truncated ? (_jsx(Txt, { color: theme.warning, fontSize: 12, style: { paddingLeft: 10, paddingTop: 6 }, children: "\u2026 file truncated (open externally to see the rest)" })) : null] })) })] }));
54
+ }
55
+ //# sourceMappingURL=code-viewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-viewer.js","sourceRoot":"","sources":["../../src/web-ui/code-viewer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * (v22 / docs/6.5b §C5) Client-side slash commands for the web panel. UNLIKE the
3
+ * TUI's slashes (dispatched through the engine's PluginHost), the web speaks ACP
4
+ * to the engine and has no command backend — so these are PURE client-side
5
+ * actions on the RpcClient / store / view (clear the transcript, toggle theme,
6
+ * show help). It's a small extensible registry; engine-backed commands (/resume,
7
+ * /compact, /mcp, …) are a CLI-architecture concern and intentionally absent.
8
+ */
9
+ /** A web slash command. `run` performs a pure client-side action. */
10
+ export interface WebCommand {
11
+ /** Without the leading slash, e.g. `clear`. */
12
+ name: string;
13
+ description: string;
14
+ run: () => void;
15
+ }
16
+ /** Suggestions for the typeahead: when the input is a bare `/token` (no space
17
+ * yet — a command word, not arguments), the commands whose name starts with the
18
+ * token. Empty `/` lists all. A non-slash input or one past the first space
19
+ * yields nothing (it's a prompt / arguments). Pure — unit-tested. */
20
+ export declare function suggestWebCommands(input: string, commands: readonly WebCommand[]): WebCommand[];
21
+ /** Parse the command word out of a `/name …` line (lowercased, no slash). */
22
+ export declare function parseCommandName(input: string): string;
23
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/web-ui/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,qEAAqE;AACrE,MAAM,WAAW,UAAU;IACzB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,IAAI,CAAC;CACjB;AAED;;;sEAGsE;AACtE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,EAAE,CAM/F;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * (v22 / docs/6.5b §C5) Client-side slash commands for the web panel. UNLIKE the
3
+ * TUI's slashes (dispatched through the engine's PluginHost), the web speaks ACP
4
+ * to the engine and has no command backend — so these are PURE client-side
5
+ * actions on the RpcClient / store / view (clear the transcript, toggle theme,
6
+ * show help). It's a small extensible registry; engine-backed commands (/resume,
7
+ * /compact, /mcp, …) are a CLI-architecture concern and intentionally absent.
8
+ */
9
+ /** Suggestions for the typeahead: when the input is a bare `/token` (no space
10
+ * yet — a command word, not arguments), the commands whose name starts with the
11
+ * token. Empty `/` lists all. A non-slash input or one past the first space
12
+ * yields nothing (it's a prompt / arguments). Pure — unit-tested. */
13
+ export function suggestWebCommands(input, commands) {
14
+ if (!input.startsWith("/"))
15
+ return [];
16
+ const token = input.slice(1);
17
+ if (token.includes(" "))
18
+ return []; // past the command word → arguments/prompt
19
+ const lower = token.toLowerCase();
20
+ return commands.filter((c) => c.name.toLowerCase().startsWith(lower));
21
+ }
22
+ /** Parse the command word out of a `/name …` line (lowercased, no slash). */
23
+ export function parseCommandName(input) {
24
+ return input.slice(1).split(/\s+/)[0].toLowerCase();
25
+ }
26
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/web-ui/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH;;;sEAGsE;AACtE,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,QAA+B;IAC/E,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC,CAAC,2CAA2C;IAC/E,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC;AACvD,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { RpcClient } from "../client-core/index.js";
2
+ import { type Mode } from "./theme-context.js";
3
+ export interface ControlPanelProps {
4
+ client: RpcClient;
5
+ /** Initial colour mode (defaults to dark). */
6
+ defaultMode?: Mode;
7
+ }
8
+ export declare function ControlPanel({ client, defaultMode }: ControlPanelProps): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=control-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-panel.d.ts","sourceRoot":"","sources":["../../src/web-ui/control-panel.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAiBzD,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,2CA6H/E"}
@@ -0,0 +1,70 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * (v17 M1 B3; v22) The composed control panel — the single component `apps/web`
4
+ * mounts. It owns colour-mode state and wires the client-core `RpcClient` (store +
5
+ * transcript) to the presentational pieces: header (model picker + theme toggle),
6
+ * the scrolling transcript, and the footer (permission card + prompt composer +
7
+ * status line).
8
+ *
9
+ * v22 retired Tamagui: the root sets ui-core's `themeCssVars(mode)` as inline CSS
10
+ * custom properties (`--ch-bg`/`--ch-fg`/`--ch-border` + the palette), so the
11
+ * whole subtree resolves chrome colors from one source of truth without a
12
+ * provider. Transcript CONTENT colors still come from the ui-core `Theme` via
13
+ * `UiThemeProvider` (the shared palette). HeroUI v3 components (modals, pickers)
14
+ * need no provider — they arrive in later commits.
15
+ *
16
+ * It is a pure function of the injected `RpcClient` — no transport, no engine,
17
+ * no `node:*` — so the whole tree is browser-safe and the `vite build` that
18
+ * bundles it is the end-to-end browser-safety proof (docs/6.1 §4 / M1 B3).
19
+ */
20
+ import { useMemo, useState } from "react";
21
+ import { themeCssVars } from "@chances-ai/ui-core";
22
+ import { ApprovalBadge } from "./approval-badge.js";
23
+ import { Button } from "./button.js";
24
+ import { CodeViewer } from "./code-viewer.js";
25
+ import { EnvironmentPanel } from "./environment-panel.js";
26
+ import { FileTree } from "./file-tree.js";
27
+ import { HelpView } from "./help-view.js";
28
+ import { useClientState, useTranscript } from "./hooks.js";
29
+ import { ModelPicker } from "./model-picker.js";
30
+ import { PermissionPrompt } from "./permission.js";
31
+ import { Box } from "./primitives.js";
32
+ import { Progress } from "./progress.js";
33
+ import { PromptInput } from "./prompt-input.js";
34
+ import { QuestionView } from "./question-view.js";
35
+ import { SessionSidebar } from "./session-sidebar.js";
36
+ import { StatusBar } from "./status-bar.js";
37
+ import { themeFor, UiThemeProvider } from "./theme-context.js";
38
+ import { Transcript } from "./transcript.js";
39
+ export function ControlPanel({ client, defaultMode = "dark" }) {
40
+ const [mode, setMode] = useState(defaultMode);
41
+ const [helpOpen, setHelpOpen] = useState(false);
42
+ const state = useClientState(client.store);
43
+ const lines = useTranscript(client.view);
44
+ const theme = themeFor(mode);
45
+ const controlsLocked = state.busy || state.status !== "ready";
46
+ // (v22) Client-side slash commands — pure actions on the client/view/UI (the
47
+ // web has no engine command backend; see commands.ts). `setMode`'s functional
48
+ // form keeps the registry stable across renders.
49
+ const commands = useMemo(() => [
50
+ { name: "clear", description: "clear the transcript", run: () => client.view.clearLines() },
51
+ { name: "theme", description: "toggle light / dark", run: () => setMode((m) => (m === "dark" ? "light" : "dark")) },
52
+ { name: "help", description: "show commands + shortcuts", run: () => setHelpOpen(true) },
53
+ ], [client]);
54
+ const runCommand = (name) => {
55
+ commands.find((c) => c.name === name)?.run();
56
+ };
57
+ // (v23 M5) The 3-pane IDE — file tree / code viewer / environment panel — is
58
+ // shown only when the agent advertises read-only workspace queries; a plain ACP
59
+ // server (no `workspaceQueries`) degrades to the conversation column alone.
60
+ const showWorkspace = state.workspaceQueriesSupported;
61
+ return (_jsx(UiThemeProvider, { value: theme, children: _jsxs("div", { "data-theme": mode, style: {
62
+ ...themeCssVars(mode),
63
+ height: "100vh",
64
+ display: "flex",
65
+ flexDirection: "column",
66
+ background: "var(--ch-bg)",
67
+ color: "var(--ch-fg)",
68
+ }, children: [_jsxs(Box, { flexDirection: "row", alignItems: "center", gap: 12, paddingHorizontal: 16, paddingVertical: 10, borderBottomWidth: 1, borderColor: "var(--ch-border)", flexWrap: "wrap", children: [_jsx("span", { style: { color: theme.accent, fontWeight: 700 }, children: "chances" }), _jsx(Box, { flex: 1 }), _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(Box, { borderTopWidth: 1, borderColor: "var(--ch-border)", children: _jsx(EnvironmentPanel, { client: client, gitStatus: state.gitStatus, busy: state.busy }) })) : null, _jsxs(Box, { paddingHorizontal: 16, paddingVertical: 10, gap: 8, borderTopWidth: 1, 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] }) }));
69
+ }
70
+ //# sourceMappingURL=control-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-panel.js","sourceRoot":"","sources":["../../src/web-ui/control-panel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface DiffBlockProps {
2
+ diff: string;
3
+ /** write ⇒ whole-file-anchored (show the line-number gutter); edit ⇒ snippet. */
4
+ anchored: boolean;
5
+ }
6
+ /** Render a parsed `linesDiff` block. */
7
+ export declare function DiffBlock({ diff, anchored }: DiffBlockProps): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=diff-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-view.d.ts","sourceRoot":"","sources":["../../src/web-ui/diff-view.tsx"],"names":[],"mappings":"AAYA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,yCAAyC;AACzC,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,cAAc,2CAS3D"}
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * (v17 M1 B3; v22) Structured write/edit diff, the web twin of the TUI's
4
+ * `StructuredDiff`. ui-core's `parseDiff` (the shared correctness core) turns a
5
+ * `linesDiff` block into rows; each row renders as a full-width line with an
6
+ * add/remove background, an optional line-number gutter (anchored = write), and
7
+ * word-level intra-line highlights for sub-threshold pairs.
8
+ */
9
+ import { parseDiff } from "@chances-ai/ui-core";
10
+ import { diffRowBg, MONO, wordBg } from "./helpers.js";
11
+ import { Box, Txt } from "./primitives.js";
12
+ import { useUiTheme } from "./theme-context.js";
13
+ /** Render a parsed `linesDiff` block. */
14
+ export function DiffBlock({ diff, anchored }) {
15
+ const { rows } = parseDiff(diff, { anchored });
16
+ return (_jsx(Box, { borderRadius: 4, overflow: "hidden", marginTop: 4, children: rows.map((row, i) => (_jsx(DiffLine, { row: row, anchored: anchored }, i))) }));
17
+ }
18
+ function DiffLine({ row, anchored }) {
19
+ const theme = useUiTheme();
20
+ if (row.kind === "elision") {
21
+ return (_jsx(Txt, { color: theme.synComment, fontSize: 12, style: { fontFamily: MONO, display: "block", paddingLeft: 8, paddingRight: 8 }, children: row.text }));
22
+ }
23
+ const sigil = row.kind === "add" ? "+" : "-";
24
+ return (_jsxs(Box, { flexDirection: "row", backgroundColor: diffRowBg(row.kind, theme), paddingHorizontal: 8, children: [anchored ? (_jsxs(Txt, { color: theme.synComment, fontSize: 12, style: { fontFamily: MONO, userSelect: "none" }, children: [String(row.lineNo ?? "").padStart(4), " "] })) : null, _jsxs(Txt, { flex: 1, fontSize: 12, style: { fontFamily: MONO, whiteSpace: "pre-wrap", overflowWrap: "anywhere" }, children: [sigil, " ", row.words
25
+ ? row.words.map((w, i) => (_jsx(Txt, { backgroundColor: w.changed ? wordBg(row.kind, theme) : undefined, children: w.text }, i)))
26
+ : row.text] })] }));
27
+ }
28
+ //# sourceMappingURL=diff-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-view.js","sourceRoot":"","sources":["../../src/web-ui/diff-view.tsx"],"names":[],"mappings":";AAAA;;;;;;GAMG;AACH,OAAO,EAAE,SAAS,EAAgB,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAQhD,yCAAyC;AACzC,MAAM,UAAU,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAkB;IAC1D,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC/C,OAAO,CACL,KAAC,GAAG,IAAC,YAAY,EAAE,CAAC,EAAE,QAAQ,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,YACjD,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CACpB,KAAC,QAAQ,IAAS,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,IAA/B,CAAC,CAAkC,CACnD,CAAC,GACE,CACP,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAuC;IACtE,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,CACL,KAAC,GAAG,IACF,KAAK,EAAE,KAAK,CAAC,UAAU,EACvB,QAAQ,EAAE,EAAE,EACZ,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAE7E,GAAG,CAAC,IAAI,GACL,CACP,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAC7C,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,KAAK,EAAC,eAAe,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAC,aACvF,QAAQ,CAAC,CAAC,CAAC,CACV,MAAC,GAAG,IAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,aACxF,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,IACtC,CACP,CAAC,CAAC,CAAC,IAAI,EACR,MAAC,GAAG,IAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,aACtG,KAAK,EAAE,GAAG,EACV,GAAG,CAAC,KAAK;wBACR,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CACtB,KAAC,GAAG,IAAS,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,YAC1E,CAAC,CAAC,IAAI,IADC,CAAC,CAEL,CACP,CAAC;wBACJ,CAAC,CAAC,GAAG,CAAC,IAAI,IACR,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { GitStatusResult, RpcClient } from "../client-core/index.js";
2
+ export interface EnvironmentPanelProps {
3
+ client: RpcClient;
4
+ gitStatus: GitStatusResult | null;
5
+ /** A turn is running — when it flips back to false we refresh (an edit landed). */
6
+ busy: boolean;
7
+ }
8
+ export declare function EnvironmentPanel({ client, gitStatus, busy }: EnvironmentPanelProps): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=environment-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment-panel.d.ts","sourceRoot":"","sources":["../../src/web-ui/environment-panel.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAI1E,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;IAClC,mFAAmF;IACnF,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,qBAAqB,2CAkElF"}
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * (v23 M5 / docs/6.6 §3) The center-column "environment" card — the conversation's
4
+ * git context: branch, ahead/behind, changed-file count, and aggregate
5
+ * insertions/deletions. Refreshes `git_status` on mount and whenever a turn
6
+ * finishes (so an agent edit reflects immediately), plus a whole-tree
7
+ * `git_diff` for the +N/-M shortstat.
8
+ *
9
+ * Reads the shared store `gitStatus`; the shortstat is component-local. Hidden by
10
+ * the panel when the agent doesn't advertise `workspaceQueries`. Browser-safe.
11
+ */
12
+ import { useEffect, useState } from "react";
13
+ import { Box, Txt } from "./primitives.js";
14
+ import { useUiTheme } from "./theme-context.js";
15
+ export function EnvironmentPanel({ client, gitStatus, busy }) {
16
+ const theme = useUiTheme();
17
+ const [shortstat, setShortstat] = useState({ added: 0, removed: 0 });
18
+ // Refresh status + the aggregate shortstat on mount and after each turn ends.
19
+ useEffect(() => {
20
+ if (busy)
21
+ return; // refresh on the falling edge (turn just finished) + on mount
22
+ let live = true;
23
+ void client.refreshGitStatus();
24
+ void client.gitDiff().then((r) => {
25
+ if (live)
26
+ setShortstat(r.shortstat);
27
+ });
28
+ return () => {
29
+ live = false;
30
+ };
31
+ }, [busy, client]);
32
+ if (!gitStatus || !gitStatus.repo) {
33
+ return (_jsx(Box, { flexDirection: "row", alignItems: "center", gap: 8, paddingHorizontal: 12, paddingVertical: 6, children: _jsx(Txt, { color: theme.synComment, fontSize: 12, children: "no git repository" }) }));
34
+ }
35
+ const changed = gitStatus.files.length;
36
+ return (_jsxs(Box, { flexDirection: "row", alignItems: "center", gap: 14, paddingHorizontal: 12, paddingVertical: 6, style: { fontFamily: "ui-monospace, monospace", flexWrap: "wrap" }, children: [_jsx(Txt, { color: theme.synComment, fontSize: 11, style: { textTransform: "uppercase", letterSpacing: 0.5 }, children: "env" }), _jsxs(Txt, { color: theme.accent, fontSize: 12, children: ["\u2387 ", gitStatus.branch ?? "(detached)"] }), gitStatus.ahead > 0 ? (_jsxs(Txt, { color: theme.synComment, fontSize: 12, children: ["\u2191", gitStatus.ahead] })) : null, gitStatus.behind > 0 ? (_jsxs(Txt, { color: theme.synComment, fontSize: 12, children: ["\u2193", gitStatus.behind] })) : null, _jsxs(Txt, { color: "var(--ch-fg)", fontSize: 12, children: [changed, " changed"] }), _jsxs(Box, { flexDirection: "row", gap: 6, children: [_jsxs(Txt, { color: theme.success, fontSize: 12, children: ["+", shortstat.added] }), _jsxs(Txt, { color: theme.error, fontSize: 12, children: ["-", shortstat.removed] })] })] }));
37
+ }
38
+ //# sourceMappingURL=environment-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment-panel.js","sourceRoot":"","sources":["../../src/web-ui/environment-panel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { GitStatusResult, RpcClient } from "../client-core/index.js";
2
+ export interface FileTreeProps {
3
+ client: RpcClient;
4
+ gitStatus: GitStatusResult | null;
5
+ /** The currently-open file (for row highlight). */
6
+ openPath?: string;
7
+ }
8
+ export declare function FileTree({ client, gitStatus, openPath }: FileTreeProps): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=file-tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-tree.d.ts","sourceRoot":"","sources":["../../src/web-ui/file-tree.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAa,eAAe,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAKrF,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,2CAkGtE"}
@@ -0,0 +1,77 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * (v23 M5 / docs/6.6 §3) The right-pane file tree — a lazy, one-level-at-a-time
4
+ * explorer over the workspace, fed by `RpcClient.listFiles(dir)` (the
5
+ * `_chances/unstable/list_files` query). Folders fetch their children on first
6
+ * expand (no whole-tree walk); a file opens in the code viewer
7
+ * (`RpcClient.openFileInViewer`). Git status badges come from the shared store
8
+ * `gitStatus` (matched by repo-relative path).
9
+ *
10
+ * Pure-presentational over the injected client — browser-safe, no node.
11
+ */
12
+ import { useEffect, useState } from "react";
13
+ import { gitBadge } from "./helpers.js";
14
+ import { Box, Txt } from "./primitives.js";
15
+ import { useUiTheme } from "./theme-context.js";
16
+ const childPath = (dir, name) => (dir === "." || dir === "" ? name : `${dir}/${name}`);
17
+ export function FileTree({ client, gitStatus, openPath }) {
18
+ const theme = useUiTheme();
19
+ // dir → its immediate children (lazy cache); expanded set of dir paths.
20
+ const [childrenByDir, setChildrenByDir] = useState({});
21
+ const [expanded, setExpanded] = useState({});
22
+ const [error, setError] = useState(null);
23
+ async function loadDir(dir) {
24
+ if (childrenByDir[dir])
25
+ return;
26
+ try {
27
+ const res = await client.listFiles(dir);
28
+ setChildrenByDir((prev) => ({ ...prev, [dir]: res.entries }));
29
+ }
30
+ catch (e) {
31
+ setError(e.message ?? String(e));
32
+ }
33
+ }
34
+ // Load the workspace root on mount.
35
+ useEffect(() => {
36
+ void loadDir(".");
37
+ // eslint-disable-next-line react-hooks/exhaustive-deps
38
+ }, []);
39
+ function toggle(dir) {
40
+ setExpanded((prev) => ({ ...prev, [dir]: !prev[dir] }));
41
+ void loadDir(dir);
42
+ }
43
+ const statusByPath = new Map((gitStatus?.files ?? []).map((f) => [f.path, f.status]));
44
+ function renderEntries(dir, depth) {
45
+ const entries = childrenByDir[dir];
46
+ if (!entries)
47
+ return null;
48
+ return entries.map((e) => {
49
+ const path = childPath(dir, e.name);
50
+ const isDir = e.kind === "dir";
51
+ const isOpen = expanded[path] === true;
52
+ const badge = gitBadge(statusByPath.get(path) ?? "");
53
+ const selected = !isDir && path === openPath;
54
+ return (_jsxs("div", { children: [_jsxs("div", { role: "button", tabIndex: 0, onClick: () => (isDir ? toggle(path) : void client.openFileInViewer(path)), onKeyDown: (ev) => {
55
+ if (ev.key === "Enter" || ev.key === " ") {
56
+ ev.preventDefault();
57
+ isDir ? toggle(path) : void client.openFileInViewer(path);
58
+ }
59
+ }, style: {
60
+ display: "flex",
61
+ alignItems: "center",
62
+ gap: 4,
63
+ cursor: "pointer",
64
+ paddingLeft: 8 + depth * 12,
65
+ paddingRight: 8,
66
+ paddingTop: 1,
67
+ paddingBottom: 1,
68
+ fontSize: 13,
69
+ borderRadius: 4,
70
+ background: selected ? "var(--ch-border)" : undefined,
71
+ fontFamily: "system-ui, sans-serif",
72
+ }, children: [_jsx(Txt, { color: theme.synComment, style: { width: 10, userSelect: "none" }, children: isDir ? (isOpen ? "▾" : "▸") : "" }), _jsx(Txt, { color: isDir ? theme.accent : "var(--ch-fg)", style: { flex: 1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }, children: e.name }), badge ? (_jsx(Txt, { color: theme[badge.tone], fontWeight: 700, style: { width: 12, textAlign: "center", userSelect: "none" }, children: badge.char })) : null] }), isDir && isOpen ? renderEntries(path, depth + 1) : null] }, path));
73
+ });
74
+ }
75
+ return (_jsxs(Box, { style: { height: "100%", overflowY: "auto" }, paddingVertical: 6, children: [_jsx(Txt, { color: theme.synComment, fontSize: 11, style: { paddingLeft: 8, textTransform: "uppercase", letterSpacing: 0.5 }, children: "Files" }), error ? (_jsx(Txt, { color: theme.error, fontSize: 12, style: { paddingLeft: 8, paddingTop: 4 }, children: error })) : (_jsx(Box, { marginTop: 4, children: renderEntries(".", 0) }))] }));
76
+ }
77
+ //# sourceMappingURL=file-tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-tree.js","sourceRoot":"","sources":["../../src/web-ui/file-tree.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * (v22 / docs/6.5b §C5) The `/help` overlay — lists the web panel's client-side
3
+ * slash commands + the key shortcuts. The web twin of the TUI's tabbed /help, in
4
+ * a single centered card (the web command set is small). Click the backdrop or
5
+ * Close to dismiss.
6
+ */
7
+ import type { WebCommand } from "./commands.js";
8
+ export interface HelpViewProps {
9
+ commands: WebCommand[];
10
+ onClose: () => void;
11
+ }
12
+ export declare function HelpView({ commands, onClose }: HelpViewProps): import("react/jsx-runtime").JSX.Element;
13
+ //# sourceMappingURL=help-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help-view.d.ts","sourceRoot":"","sources":["../../src/web-ui/help-view.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKhD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AASD,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,aAAa,2CA6C5D"}
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Txt } from "./primitives.js";
3
+ import { Button } from "./button.js";
4
+ import { useUiTheme } from "./theme-context.js";
5
+ const SHORTCUTS = [
6
+ ["Enter", "send the message"],
7
+ ["Shift+Enter", "newline"],
8
+ ["/", "open the command typeahead"],
9
+ ["Esc", "interrupt a running turn"],
10
+ ];
11
+ export function HelpView({ commands, onClose }) {
12
+ const theme = useUiTheme();
13
+ return (_jsx("div", { role: "dialog", "aria-label": "help", onClick: onClose, style: { position: "fixed", inset: 0, background: "rgba(0,0,0,0.5)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 50 }, children: _jsx("div", { onClick: (e) => e.stopPropagation(), style: { minWidth: 360, maxWidth: 520, maxHeight: "80vh", overflowY: "auto", background: "var(--ch-bg)", color: "var(--ch-fg)", border: `1px solid var(--ch-border)`, borderRadius: 10, padding: 16 }, children: _jsxs(Box, { gap: 10, children: [_jsx(Txt, { color: theme.accent, fontWeight: 700, children: "chances \u2014 help" }), _jsx(Txt, { color: theme.synComment, fontWeight: 600, children: "Slash commands" }), commands.map((c) => (_jsxs(Txt, { color: "var(--ch-fg)", children: [_jsxs(Txt, { color: theme.accent, children: ["/", c.name] }), _jsxs(Txt, { color: theme.synComment, children: [" \u2014 ", c.description] })] }, c.name))), _jsx(Txt, { color: theme.synComment, fontWeight: 600, children: "Shortcuts" }), SHORTCUTS.map(([key, desc]) => (_jsxs(Txt, { color: "var(--ch-fg)", children: [_jsx(Txt, { color: theme.accent, children: key }), _jsxs(Txt, { color: theme.synComment, children: [" \u2014 ", desc] })] }, key))), _jsx(Box, { flexDirection: "row", children: _jsx(Button, { label: "Close", color: theme.synComment, onPress: onClose }) })] }) }) }));
14
+ }
15
+ //# sourceMappingURL=help-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help-view.js","sourceRoot":"","sources":["../../src/web-ui/help-view.tsx"],"names":[],"mappings":";AAOA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAOhD,MAAM,SAAS,GAA4B;IACzC,CAAC,OAAO,EAAE,kBAAkB,CAAC;IAC7B,CAAC,aAAa,EAAE,SAAS,CAAC;IAC1B,CAAC,GAAG,EAAE,4BAA4B,CAAC;IACnC,CAAC,KAAK,EAAE,0BAA0B,CAAC;CACpC,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAiB;IAC3D,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,OAAO,CACL,cACE,IAAI,EAAC,QAAQ,gBACF,MAAM,EACjB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,YAElJ,cACE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,EACnC,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,4BAA4B,EAAE,YAAY,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,YAErM,MAAC,GAAG,IAAC,GAAG,EAAE,EAAE,aACV,KAAC,GAAG,IAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,oCAEnC,EAEN,KAAC,GAAG,IAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,+BAEvC,EACL,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACnB,MAAC,GAAG,IAAc,KAAK,EAAC,cAAc,aACpC,MAAC,GAAG,IAAC,KAAK,EAAE,KAAK,CAAC,MAAM,kBAAI,CAAC,CAAC,IAAI,IAAO,EACzC,MAAC,GAAG,IAAC,KAAK,EAAE,KAAK,CAAC,UAAU,yBAAM,CAAC,CAAC,WAAW,IAAO,KAF9C,CAAC,CAAC,IAAI,CAGV,CACP,CAAC,EAEF,KAAC,GAAG,IAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,0BAEvC,EACL,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAC9B,MAAC,GAAG,IAAW,KAAK,EAAC,cAAc,aACjC,KAAC,GAAG,IAAC,KAAK,EAAE,KAAK,CAAC,MAAM,YAAG,GAAG,GAAO,EACrC,MAAC,GAAG,IAAC,KAAK,EAAE,KAAK,CAAC,UAAU,yBAAM,IAAI,IAAO,KAFrC,GAAG,CAGP,CACP,CAAC,EAEF,KAAC,GAAG,IAAC,aAAa,EAAC,KAAK,YACtB,KAAC,MAAM,IAAC,KAAK,EAAC,OAAO,EAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,GAAI,GAC/D,IACF,GACF,GACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * (v17 M1 B3) Pure, framework-free helpers for the web control panel — colour
3
+ * lookups, label formatting, key/permission logic. Extracted out of the `.tsx`
4
+ * components so the BEHAVIOUR is unit-tested directly (no DOM, no Tamagui), and
5
+ * the components stay thin presentational shells. Everything here is a pure
6
+ * function of its inputs (the ui-core `Theme` + protocol/view types).
7
+ */
8
+ import { type HlScope, type Line, type Theme } from "@chances-ai/ui-core";
9
+ import type { ConnectionStatus, ModelInfo, Usage } from "../client-core/index.js";
10
+ /** Web monospace stack for code / diffs / the prompt box (a CSS value, applied
11
+ * via the `style` escape hatch — `fontFamily` is not a Tamagui token here). */
12
+ export declare const MONO = "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
13
+ /** The `⏺` tool dot colour: running (no result yet) → accent, ok → success,
14
+ * failed → error. `undefined` ⇒ inherit (NO_COLOR palette). */
15
+ export declare function toolDotColor(line: Pick<Line, "ok">, theme: Theme): string | undefined;
16
+ /** Map a highlight scope to its themed colour, or `undefined` for plain text. */
17
+ export declare function segmentColor(scope: HlScope, theme: Theme): string | undefined;
18
+ /** Full-line background for a diff row (`undefined` for elision / NO_COLOR). */
19
+ export declare function diffRowBg(kind: "add" | "remove" | "elision", theme: Theme): string | undefined;
20
+ /** Word-level (intra-line) background for a changed word on an add/remove row. */
21
+ export declare function wordBg(kind: "add" | "remove" | "elision", theme: Theme): string | undefined;
22
+ /** `provider/model` — the option label + select value for {@link ModelInfo}. */
23
+ export declare function modelLabel(info: ModelInfo): string;
24
+ /** (v22) Case-insensitive substring filter over `provider/model` labels. Empty
25
+ * query ⇒ every model (the picker's initial open state). Pure — unit-tested. */
26
+ export declare function filterModels(models: readonly ModelInfo[], query: string): ModelInfo[];
27
+ /** Whether a key event in the prompt box should submit: Enter without Shift,
28
+ * and not mid-IME-composition (so CJK candidate selection doesn't submit). */
29
+ export declare function shouldSubmit(e: {
30
+ key: string;
31
+ shiftKey: boolean;
32
+ nativeEvent?: {
33
+ isComposing?: boolean;
34
+ };
35
+ }): boolean;
36
+ /** A permission button spec. The view turns each into a pressable that calls
37
+ * `RpcClient.answerPermission(allow, remember)`. */
38
+ export interface PermissionAction {
39
+ key: string;
40
+ label: string;
41
+ allow: boolean;
42
+ remember: boolean;
43
+ /** Theme role the button is tinted with. */
44
+ tone: "success" | "accent" | "error";
45
+ }
46
+ /** The three permission choices, in display order (mirrors the TUI y / a / n). */
47
+ export declare function permissionActions(): PermissionAction[];
48
+ /** The colour a `tone` resolves to against a palette. */
49
+ export declare function toneColor(tone: PermissionAction["tone"], theme: Theme): string | undefined;
50
+ /** A ready-to-render permission button: label + tint + the bound press handler.
51
+ * The `PermissionPrompt` renders this list 1:1, so testing the builder tests
52
+ * the actual button wiring (allow/remember pairing) without a DOM. */
53
+ export interface PermissionButton {
54
+ key: string;
55
+ label: string;
56
+ color?: string;
57
+ onPress: () => void;
58
+ }
59
+ /** Build the permission buttons, each press bound to `onAnswer(allow, remember)`
60
+ * for its action. The single source of the prompt's interactive behaviour. */
61
+ export declare function buildPermissionButtons(theme: Theme, onAnswer: (allow: boolean, remember: boolean) => void): PermissionButton[];
62
+ /** Human-readable connection status for the status bar. */
63
+ export declare function statusText(status: ConnectionStatus): string;
64
+ /** Status dot / label colour. */
65
+ export declare function statusColor(status: ConnectionStatus, theme: Theme): string | undefined;
66
+ /** Compact usage line: `in→out tok · $cost`. */
67
+ export declare function formatUsage(u: Usage): string;
68
+ /** Map a file extension to a highlight.js language the shared `highlightToSegments`
69
+ * knows (its registered set). `undefined` ⇒ render as plain text. Pure. */
70
+ export declare function langFromPath(path: string): string | undefined;
71
+ /** A git porcelain XY status code → a one-letter badge + theme tone for the file
72
+ * tree. `??` untracked, `A` added, `M` modified, `D` deleted, `R` renamed. Pure. */
73
+ export declare function gitBadge(status: string): {
74
+ char: string;
75
+ tone: "success" | "warning" | "error" | "accent";
76
+ } | null;
77
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/web-ui/helpers.ts"],"names":[],"mappings":"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"}