@bubblebrain-ai/bubble 0.0.23 → 0.0.25

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 (168) hide show
  1. package/README.md +1 -1
  2. package/dist/config.d.ts +3 -0
  3. package/dist/config.js +22 -6
  4. package/dist/goal/command.d.ts +20 -0
  5. package/dist/goal/command.js +71 -0
  6. package/dist/goal/engine.d.ts +33 -0
  7. package/dist/goal/engine.js +65 -0
  8. package/dist/goal/format.d.ts +18 -0
  9. package/dist/goal/format.js +112 -0
  10. package/dist/goal/prompts.d.ts +13 -0
  11. package/dist/goal/prompts.js +84 -0
  12. package/dist/goal/store.d.ts +64 -0
  13. package/dist/goal/store.js +174 -0
  14. package/dist/goal/tools.d.ts +10 -0
  15. package/dist/goal/tools.js +70 -0
  16. package/dist/goal/usage.d.ts +2 -0
  17. package/dist/goal/usage.js +3 -0
  18. package/dist/main.js +29 -42
  19. package/dist/model-catalog.js +11 -0
  20. package/dist/provider-transform.js +17 -0
  21. package/dist/provider.js +20 -5
  22. package/dist/session-types.d.ts +3 -0
  23. package/dist/tools/index.d.ts +3 -0
  24. package/dist/tools/index.js +2 -0
  25. package/dist/tui/detect-theme.d.ts +1 -0
  26. package/dist/tui/detect-theme.js +23 -0
  27. package/dist/tui/image-display.d.ts +13 -0
  28. package/dist/tui/image-display.js +49 -0
  29. package/dist/tui/input-history.d.ts +37 -6
  30. package/dist/tui/input-history.js +194 -23
  31. package/dist/tui/model-switch.d.ts +42 -0
  32. package/dist/tui/model-switch.js +55 -0
  33. package/dist/tui-ink/app.d.ts +32 -2
  34. package/dist/tui-ink/app.js +1360 -522
  35. package/dist/tui-ink/approval/select.js +10 -0
  36. package/dist/tui-ink/detect-theme.d.ts +1 -2
  37. package/dist/tui-ink/detect-theme.js +1 -87
  38. package/dist/tui-ink/display-history.d.ts +1 -0
  39. package/dist/tui-ink/display-history.js +11 -0
  40. package/dist/tui-ink/feedback-dialog.js +10 -0
  41. package/dist/tui-ink/feishu-setup-picker.js +10 -0
  42. package/dist/tui-ink/footer.d.ts +1 -0
  43. package/dist/tui-ink/footer.js +8 -2
  44. package/dist/tui-ink/input-box.d.ts +70 -9
  45. package/dist/tui-ink/input-box.js +354 -120
  46. package/dist/tui-ink/input-history.d.ts +1 -16
  47. package/dist/tui-ink/input-history.js +1 -79
  48. package/dist/tui-ink/input-queue.d.ts +12 -0
  49. package/dist/tui-ink/input-queue.js +17 -0
  50. package/dist/tui-ink/key-events.d.ts +9 -0
  51. package/dist/tui-ink/key-events.js +8 -0
  52. package/dist/tui-ink/markdown.js +1 -1
  53. package/dist/tui-ink/message-list.d.ts +3 -1
  54. package/dist/tui-ink/message-list.js +42 -24
  55. package/dist/tui-ink/model-picker.d.ts +24 -2
  56. package/dist/tui-ink/model-picker.js +224 -20
  57. package/dist/tui-ink/plan-confirm.js +10 -0
  58. package/dist/tui-ink/question-dialog.js +10 -0
  59. package/dist/tui-ink/run.d.ts +11 -0
  60. package/dist/tui-ink/run.js +21 -28
  61. package/dist/tui-ink/session-picker.js +3 -0
  62. package/dist/tui-ink/submit-dedupe.d.ts +5 -0
  63. package/dist/tui-ink/submit-dedupe.js +25 -0
  64. package/dist/tui-ink/terminal-mouse.d.ts +13 -1
  65. package/dist/tui-ink/terminal-mouse.js +63 -21
  66. package/dist/tui-ink/theme.d.ts +6 -3
  67. package/dist/tui-ink/theme.js +10 -4
  68. package/dist/tui-ink/transcript-input.d.ts +8 -0
  69. package/dist/tui-ink/transcript-input.js +9 -0
  70. package/dist/tui-ink/transcript-viewport-math.d.ts +1 -2
  71. package/dist/tui-ink/transcript-viewport-math.js +1 -2
  72. package/dist/tui-ink/welcome.d.ts +1 -0
  73. package/dist/tui-ink/welcome.js +25 -28
  74. package/package.json +1 -5
  75. package/dist/tui/clipboard.d.ts +0 -1
  76. package/dist/tui/clipboard.js +0 -53
  77. package/dist/tui/escape-confirmation.d.ts +0 -15
  78. package/dist/tui/escape-confirmation.js +0 -30
  79. package/dist/tui/global-key-router.d.ts +0 -3
  80. package/dist/tui/global-key-router.js +0 -87
  81. package/dist/tui/markdown-inline.d.ts +0 -22
  82. package/dist/tui/markdown-inline.js +0 -68
  83. package/dist/tui/markdown-theme-rules.d.ts +0 -23
  84. package/dist/tui/markdown-theme-rules.js +0 -164
  85. package/dist/tui/markdown-theme.d.ts +0 -5
  86. package/dist/tui/markdown-theme.js +0 -27
  87. package/dist/tui/opencode-spinner.d.ts +0 -22
  88. package/dist/tui/opencode-spinner.js +0 -216
  89. package/dist/tui/prompt-keybindings.d.ts +0 -42
  90. package/dist/tui/prompt-keybindings.js +0 -35
  91. package/dist/tui/render-signature.d.ts +0 -1
  92. package/dist/tui/render-signature.js +0 -7
  93. package/dist/tui/run.d.ts +0 -65
  94. package/dist/tui/run.js +0 -9934
  95. package/dist/tui/sidebar-mcp.d.ts +0 -31
  96. package/dist/tui/sidebar-mcp.js +0 -62
  97. package/dist/tui/sidebar-state.d.ts +0 -12
  98. package/dist/tui/sidebar-state.js +0 -69
  99. package/dist/tui/streaming-tool-args.d.ts +0 -15
  100. package/dist/tui/streaming-tool-args.js +0 -30
  101. package/dist/tui/tool-renderers/fallback.d.ts +0 -2
  102. package/dist/tui/tool-renderers/fallback.js +0 -75
  103. package/dist/tui/tool-renderers/registry.d.ts +0 -3
  104. package/dist/tui/tool-renderers/registry.js +0 -11
  105. package/dist/tui/tool-renderers/subagent.d.ts +0 -2
  106. package/dist/tui/tool-renderers/subagent.js +0 -135
  107. package/dist/tui/tool-renderers/types.d.ts +0 -36
  108. package/dist/tui/tool-renderers/types.js +0 -1
  109. package/dist/tui/tool-renderers/write-preview.d.ts +0 -12
  110. package/dist/tui/tool-renderers/write-preview.js +0 -32
  111. package/dist/tui/tool-renderers/write.d.ts +0 -6
  112. package/dist/tui/tool-renderers/write.js +0 -88
  113. package/dist/tui-opentui/app.d.ts +0 -54
  114. package/dist/tui-opentui/app.js +0 -1371
  115. package/dist/tui-opentui/approval/approval-dialog.d.ts +0 -15
  116. package/dist/tui-opentui/approval/approval-dialog.js +0 -155
  117. package/dist/tui-opentui/approval/diff-view.d.ts +0 -9
  118. package/dist/tui-opentui/approval/diff-view.js +0 -43
  119. package/dist/tui-opentui/approval/select.d.ts +0 -37
  120. package/dist/tui-opentui/approval/select.js +0 -91
  121. package/dist/tui-opentui/detect-theme.d.ts +0 -2
  122. package/dist/tui-opentui/detect-theme.js +0 -87
  123. package/dist/tui-opentui/display-history.d.ts +0 -56
  124. package/dist/tui-opentui/display-history.js +0 -130
  125. package/dist/tui-opentui/edit-diff.d.ts +0 -11
  126. package/dist/tui-opentui/edit-diff.js +0 -57
  127. package/dist/tui-opentui/feedback-dialog.d.ts +0 -21
  128. package/dist/tui-opentui/feedback-dialog.js +0 -164
  129. package/dist/tui-opentui/feishu-setup-picker.d.ts +0 -7
  130. package/dist/tui-opentui/feishu-setup-picker.js +0 -272
  131. package/dist/tui-opentui/file-mentions.d.ts +0 -29
  132. package/dist/tui-opentui/file-mentions.js +0 -174
  133. package/dist/tui-opentui/footer.d.ts +0 -26
  134. package/dist/tui-opentui/footer.js +0 -40
  135. package/dist/tui-opentui/image-paste.d.ts +0 -54
  136. package/dist/tui-opentui/image-paste.js +0 -288
  137. package/dist/tui-opentui/input-box.d.ts +0 -32
  138. package/dist/tui-opentui/input-box.js +0 -462
  139. package/dist/tui-opentui/input-history.d.ts +0 -16
  140. package/dist/tui-opentui/input-history.js +0 -79
  141. package/dist/tui-opentui/markdown.d.ts +0 -66
  142. package/dist/tui-opentui/markdown.js +0 -127
  143. package/dist/tui-opentui/message-list.d.ts +0 -31
  144. package/dist/tui-opentui/message-list.js +0 -131
  145. package/dist/tui-opentui/model-picker.d.ts +0 -63
  146. package/dist/tui-opentui/model-picker.js +0 -450
  147. package/dist/tui-opentui/plan-confirm.d.ts +0 -9
  148. package/dist/tui-opentui/plan-confirm.js +0 -124
  149. package/dist/tui-opentui/question-dialog.d.ts +0 -10
  150. package/dist/tui-opentui/question-dialog.js +0 -110
  151. package/dist/tui-opentui/recent-activity.d.ts +0 -8
  152. package/dist/tui-opentui/recent-activity.js +0 -71
  153. package/dist/tui-opentui/run-session-picker.d.ts +0 -10
  154. package/dist/tui-opentui/run-session-picker.js +0 -28
  155. package/dist/tui-opentui/run.d.ts +0 -38
  156. package/dist/tui-opentui/run.js +0 -48
  157. package/dist/tui-opentui/session-picker.d.ts +0 -12
  158. package/dist/tui-opentui/session-picker.js +0 -120
  159. package/dist/tui-opentui/theme.d.ts +0 -89
  160. package/dist/tui-opentui/theme.js +0 -157
  161. package/dist/tui-opentui/todos.d.ts +0 -9
  162. package/dist/tui-opentui/todos.js +0 -45
  163. package/dist/tui-opentui/trace-groups.d.ts +0 -27
  164. package/dist/tui-opentui/trace-groups.js +0 -455
  165. package/dist/tui-opentui/use-terminal-size.d.ts +0 -4
  166. package/dist/tui-opentui/use-terminal-size.js +0 -5
  167. package/dist/tui-opentui/welcome.d.ts +0 -25
  168. package/dist/tui-opentui/welcome.js +0 -77
@@ -1,127 +0,0 @@
1
- import { jsx as _jsx } from "@opentui/react/jsx-runtime";
2
- /** @jsxImportSource @opentui/react */
3
- /**
4
- * Markdown rendering for the OpenTUI-based TUI.
5
- *
6
- * The previous Ink implementation hand-parsed markdown into block primitives
7
- * because Ink had no native markdown support. OpenTUI ships
8
- * `MarkdownRenderable` as a built-in (tree-sitter backed), so most of the
9
- * 600+ lines of parsing logic collapse to a single intrinsic element.
10
- *
11
- * Public exports are kept compatible with the old Ink module so consumers
12
- * (message-list, plan-confirm) don't need import changes.
13
- */
14
- import React from "react";
15
- import { useTheme } from "./theme.js";
16
- /**
17
- * Detect the byte offset where the last complete block ends. Used by the
18
- * streaming renderer to keep already-finalized blocks stable while the
19
- * trailing block is still being typed.
20
- */
21
- export function findLastBlockStart(text) {
22
- // Walk backwards to find the start of the trailing incomplete block.
23
- // A block break is a blank line (two newlines) at column 0. If we are
24
- // inside an unclosed ```/~~~ fence, the trailing block extends back to
25
- // the fence opener.
26
- const lastFenceOpen = findUnclosedFenceStart(text);
27
- if (lastFenceOpen !== -1)
28
- return lastFenceOpen;
29
- const idx = text.lastIndexOf("\n\n");
30
- return idx === -1 ? 0 : idx + 2;
31
- }
32
- function findUnclosedFenceStart(text) {
33
- let cursor = 0;
34
- let openAt = -1;
35
- let openMarker = null;
36
- for (const line of text.split("\n")) {
37
- const trimmed = line.replace(/^ {0,3}/, "");
38
- if (openMarker === null) {
39
- if (trimmed.startsWith("```")) {
40
- openMarker = "`";
41
- openAt = cursor;
42
- }
43
- else if (trimmed.startsWith("~~~")) {
44
- openMarker = "~";
45
- openAt = cursor;
46
- }
47
- }
48
- else if (trimmed.startsWith(openMarker.repeat(3))) {
49
- openMarker = null;
50
- openAt = -1;
51
- }
52
- cursor += line.length + 1;
53
- }
54
- return openMarker === null ? -1 : openAt;
55
- }
56
- /** Stub kept for test compatibility — OpenTUI parses internally. */
57
- export function parseMarkdownBlocks(text) {
58
- const lines = text.split("\n");
59
- const blocks = [];
60
- let i = 0;
61
- while (i < lines.length) {
62
- const line = lines[i];
63
- if (line.startsWith("```")) {
64
- const lang = line.slice(3).trim();
65
- i++;
66
- const codeLines = [];
67
- while (i < lines.length && !lines[i].startsWith("```")) {
68
- codeLines.push(lines[i]);
69
- i++;
70
- }
71
- blocks.push({ type: "code", lang, lines: codeLines });
72
- i++;
73
- continue;
74
- }
75
- if (/^#{1,6}\s/.test(line)) {
76
- const match = /^(#{1,6})\s+(.*)$/.exec(line);
77
- if (match) {
78
- blocks.push({ type: "heading", level: match[1].length, text: match[2] });
79
- i++;
80
- continue;
81
- }
82
- }
83
- if (line.trim() === "") {
84
- i++;
85
- continue;
86
- }
87
- const paragraph = [];
88
- while (i < lines.length && lines[i].trim() !== "" && !lines[i].startsWith("```")) {
89
- paragraph.push(lines[i]);
90
- i++;
91
- }
92
- blocks.push({ type: "paragraph", lines: paragraph });
93
- }
94
- return blocks;
95
- }
96
- /** Stub kept for test compatibility. */
97
- export function parseMarkdownInlineSegments(text, style = {}) {
98
- return [{ text, ...style }];
99
- }
100
- /**
101
- * Render a complete (non-streaming) markdown blob. OpenTUI's MarkdownRenderable
102
- * handles parse + style + code highlighting via tree-sitter internally.
103
- */
104
- export function MarkdownContent({ content, terminalColumns }) {
105
- const theme = useTheme();
106
- if (!content)
107
- return null;
108
- return (_jsx("box", { style: { flexDirection: "column", width: terminalColumns ? terminalColumns - 2 : undefined }, children: React.createElement("markdown", {
109
- content,
110
- style: {
111
- textColor: theme.userMessageText,
112
- codeBackgroundColor: theme.inputBg,
113
- codeTextColor: theme.code,
114
- headerColor: theme.brand,
115
- linkColor: theme.traceCommand,
116
- },
117
- }) }));
118
- }
119
- /**
120
- * Streaming variant. With OpenTUI's double-buffered renderer there's no
121
- * tearing penalty for re-parsing on every token — the renderer composes the
122
- * full frame natively before swapping. So we just delegate to the same
123
- * primitive and let it handle partial input.
124
- */
125
- export function StreamingMarkdown({ content, terminalColumns }) {
126
- return _jsx(MarkdownContent, { content: content, terminalColumns: terminalColumns });
127
- }
@@ -1,31 +0,0 @@
1
- /** @jsxImportSource @opentui/react */
2
- import React from "react";
3
- import type { DisplayMessage, DisplayMessagePart, DisplayToolCall } from "./display-history.js";
4
- export interface PendingApprovalHint {
5
- toolName: "edit" | "write" | "bash";
6
- path?: string;
7
- command?: string;
8
- }
9
- interface MessageListProps {
10
- messages: DisplayMessage[];
11
- streamingContent: string;
12
- streamingReasoning: string;
13
- streamingTools: DisplayToolCall[];
14
- streamingParts: DisplayMessagePart[];
15
- terminalColumns: number;
16
- verboseTrace: boolean;
17
- pendingApproval?: PendingApprovalHint | null;
18
- nowTick?: number;
19
- welcomeBanner?: React.ReactNode;
20
- }
21
- /**
22
- * Scrollback-style message list following opencode visual rules:
23
- *
24
- * - User messages: `›` (U+203A) prefix in accent color, plain text body
25
- * - Assistant messages: full-width body in `theme.text`, no chrome
26
- * - Reasoning: `Thinking:` prefix in textMuted
27
- * - Tools: dim title row + paddingLeft=1 body
28
- * - No borders, no bubbles, no role badges — everything is text rhythm
29
- */
30
- export declare function MessageList({ messages, streamingContent, streamingReasoning, streamingTools, streamingParts, terminalColumns, verboseTrace, welcomeBanner, }: MessageListProps): React.ReactNode;
31
- export {};
@@ -1,131 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@opentui/react/jsx-runtime";
2
- import { useTheme } from "./theme.js";
3
- import { MarkdownContent, StreamingMarkdown } from "./markdown.js";
4
- import { EDIT_COLLAPSED_DIFF_LINES, getEditDiffDetails } from "./edit-diff.js";
5
- import { sanitizeInternalReminderBlocks } from "../agent/internal-reminder-sanitizer.js";
6
- /**
7
- * Scrollback-style message list following opencode visual rules:
8
- *
9
- * - User messages: `›` (U+203A) prefix in accent color, plain text body
10
- * - Assistant messages: full-width body in `theme.text`, no chrome
11
- * - Reasoning: `Thinking:` prefix in textMuted
12
- * - Tools: dim title row + paddingLeft=1 body
13
- * - No borders, no bubbles, no role badges — everything is text rhythm
14
- */
15
- export function MessageList({ messages, streamingContent, streamingReasoning, streamingTools, streamingParts, terminalColumns, verboseTrace, welcomeBanner, }) {
16
- const hasStreaming = !!(streamingContent ||
17
- streamingReasoning ||
18
- streamingTools.length > 0 ||
19
- streamingParts.length > 0);
20
- return (_jsxs("box", { style: { flexDirection: "column", flexShrink: 0 }, children: [welcomeBanner, messages.map((msg, i) => (_jsx(MessageItem, { message: msg, terminalColumns: terminalColumns, verboseTrace: verboseTrace }, msg.key ?? `message-${i}`))), hasStreaming && (_jsx(StreamingMessage, { content: streamingContent, reasoning: streamingReasoning, tools: streamingTools, parts: streamingParts, terminalColumns: terminalColumns, verboseTrace: verboseTrace }))] }));
21
- }
22
- function MessageItem({ message, terminalColumns, verboseTrace, }) {
23
- const theme = useTheme();
24
- if (message.role === "user") {
25
- return _jsx(UserMessageBlock, { content: message.content, theme: theme });
26
- }
27
- if (message.role === "error") {
28
- return (_jsx("box", { style: { marginBottom: 1, flexDirection: "column" }, children: _jsx("text", { fg: theme.error, content: `Error: ${message.content}` }) }));
29
- }
30
- if (message.syntheticKind === "ui_compact_summary") {
31
- return _jsx(CompactionSummaryBlock, { message: message, theme: theme });
32
- }
33
- const visibleReasoning = sanitizeInternalReminderBlocks(message.reasoning ?? "").trim();
34
- const hasVisible = !!message.content ||
35
- (message.toolCalls?.length ?? 0) > 0 ||
36
- (message.parts?.length ?? 0) > 0 ||
37
- (!!visibleReasoning && verboseTrace);
38
- if (!hasVisible)
39
- return null;
40
- return (_jsxs("box", { style: { marginTop: 1, marginBottom: 1, flexDirection: "column" }, children: [visibleReasoning && verboseTrace && _jsx(ReasoningBlock, { reasoning: visibleReasoning, theme: theme }), message.parts && message.parts.length > 0 ? (_jsx(MessageParts, { parts: message.parts, terminalColumns: terminalColumns, verboseTrace: verboseTrace, theme: theme })) : (_jsxs(_Fragment, { children: [message.toolCalls && _jsx(ToolsPart, { toolCalls: message.toolCalls, terminalColumns: terminalColumns, verboseTrace: verboseTrace, theme: theme }), message.content && _jsx(MarkdownContent, { content: message.content, terminalColumns: terminalColumns })] }))] }));
41
- }
42
- function StreamingMessage({ content, reasoning, tools, parts, terminalColumns, verboseTrace, }) {
43
- const theme = useTheme();
44
- const visibleReasoning = sanitizeInternalReminderBlocks(reasoning).trim();
45
- const visibleParts = parts.length > 0 ? parts : fallbackStreamingParts(content, tools);
46
- return (_jsxs("box", { style: { flexDirection: "column", marginTop: 1 }, children: [visibleReasoning && verboseTrace && _jsx(ReasoningBlock, { reasoning: visibleReasoning, theme: theme }), visibleParts.length > 0 && (_jsx(MessageParts, { parts: visibleParts, terminalColumns: terminalColumns, verboseTrace: verboseTrace, streaming: true, theme: theme }))] }));
47
- }
48
- function fallbackStreamingParts(content, tools) {
49
- const out = [];
50
- if (tools.length > 0)
51
- out.push({ type: "tools", toolCalls: tools });
52
- if (content)
53
- out.push({ type: "text", content });
54
- return out;
55
- }
56
- function MessageParts({ parts, terminalColumns, verboseTrace, streaming = false, theme, }) {
57
- return (_jsx("box", { style: { flexDirection: "column" }, children: parts.map((part, idx) => {
58
- if (part.type === "text") {
59
- if (streaming && idx === parts.length - 1) {
60
- return _jsx(StreamingMarkdown, { content: part.content, terminalColumns: terminalColumns }, `text-${idx}`);
61
- }
62
- return _jsx(MarkdownContent, { content: part.content, terminalColumns: terminalColumns }, `text-${idx}`);
63
- }
64
- return _jsx(ToolsPart, { toolCalls: part.toolCalls, terminalColumns: terminalColumns, verboseTrace: verboseTrace, theme: theme }, `tools-${idx}`);
65
- }) }));
66
- }
67
- /**
68
- * User message: `›` prefix in accent color, body in accent color. No border
69
- * or background — flows in scrollback as raw colored text. opencode pattern.
70
- */
71
- function UserMessageBlock({ content, theme }) {
72
- const lines = content.split("\n");
73
- return (_jsx("box", { style: { marginTop: 1, marginBottom: 1, flexDirection: "column" }, children: lines.map((line, i) => (_jsxs("text", { fg: theme.userMessageText, children: [i === 0 ? "› " : " ", line || " "] }, `u-${i}`))) }));
74
- }
75
- function ReasoningBlock({ reasoning, theme }) {
76
- return (_jsx("box", { style: { flexDirection: "column", marginBottom: 1 }, children: reasoning.split("\n").map((line, i) => (_jsxs("text", { fg: theme.textMuted, children: [i === 0 ? "Thinking: " : " ", line] }, `r-${i}`))) }));
77
- }
78
- function CompactionSummaryBlock({ message, theme }) {
79
- return (_jsxs("box", { style: { flexDirection: "column", marginTop: 1, marginBottom: 1 }, children: [_jsx("text", { fg: theme.textMuted, attributes: 1, content: "\u2500\u2500 context compacted \u2500\u2500" }), message.content && (_jsx("text", { fg: theme.textMuted, content: message.content }))] }));
80
- }
81
- function ToolsPart({ toolCalls, terminalColumns, verboseTrace, theme, }) {
82
- return (_jsx("box", { style: { flexDirection: "column", marginTop: 1 }, children: toolCalls.map((tc) => (_jsx(ToolCard, { tool: tc, terminalColumns: terminalColumns, verboseTrace: verboseTrace, theme: theme }, tc.id))) }));
83
- }
84
- /**
85
- * Tool card: dim title line + indented body. No icons, no per-tool colors —
86
- * pure text rhythm so the eye reads the header as a section break and the
87
- * body as content. Matches opencode's `theme.block` pattern.
88
- */
89
- function ToolCard({ tool, terminalColumns, verboseTrace, theme, }) {
90
- const pending = isToolPending(tool);
91
- const error = tool.isError;
92
- const target = describeToolTarget(tool);
93
- const headerColor = pending ? theme.toolPending : error ? theme.toolError : theme.textMuted;
94
- const titleText = target ? `${tool.name} ${target}` : tool.name;
95
- const editDetails = (tool.name === "edit" || tool.name === "apply_patch" || tool.name === "multiedit" || tool.name === "write")
96
- ? getEditDiffDetails(tool)
97
- : null;
98
- return (_jsxs("box", { style: { flexDirection: "column", marginBottom: 1 }, children: [_jsx("text", { fg: headerColor, content: titleText }), _jsxs("box", { style: { paddingLeft: 1, flexDirection: "column" }, children: [!pending && tool.result && verboseTrace && (_jsx(ToolResultPreview, { result: tool.result, error: error, terminalColumns: terminalColumns, theme: theme })), !tool.resultCollapsed && editDetails && editDetails.diff && (_jsx(EditDiffPreview, { diff: editDetails.diff, theme: theme }))] })] }));
99
- }
100
- function isToolPending(tool) {
101
- return tool.result === undefined && tool.resultCollapsed !== true;
102
- }
103
- function describeToolTarget(tool) {
104
- const args = tool.args || {};
105
- if (typeof args.path === "string")
106
- return args.path;
107
- if (typeof args.command === "string")
108
- return args.command.slice(0, 80);
109
- if (typeof args.pattern === "string")
110
- return args.pattern;
111
- if (typeof args.url === "string")
112
- return args.url;
113
- if (typeof args.query === "string")
114
- return args.query;
115
- return "";
116
- }
117
- function ToolResultPreview({ result, error, terminalColumns, theme, }) {
118
- const lines = result.split("\n").slice(0, 8);
119
- const maxLen = Math.max(20, terminalColumns - 8);
120
- return (_jsx("box", { style: { flexDirection: "column" }, children: lines.map((line, i) => (_jsx("text", { fg: error ? theme.toolError : theme.text, content: line.length > maxLen ? line.slice(0, maxLen - 1) + "…" : line }, `r-${i}`))) }));
121
- }
122
- function EditDiffPreview({ diff, theme }) {
123
- const allLines = diff.split("\n");
124
- const shown = allLines.slice(0, EDIT_COLLAPSED_DIFF_LINES);
125
- const overflow = allLines.length - shown.length;
126
- return (_jsxs("box", { style: { flexDirection: "column" }, children: [shown.map((line, i) => {
127
- const kind = line.startsWith("+") ? "+" : line.startsWith("-") ? "-" : " ";
128
- const fg = kind === "+" ? theme.diffAddFg : kind === "-" ? theme.diffRemoveFg : theme.textMuted;
129
- return _jsx("text", { fg: fg, content: line }, `d-${i}`);
130
- }), overflow > 0 && _jsx("text", { fg: theme.textMuted, content: ` … +${overflow} more lines` })] }));
131
- }
@@ -1,63 +0,0 @@
1
- /** @jsxImportSource @opentui/react */
2
- import React from "react";
3
- import { ProviderRegistry } from "../provider-registry.js";
4
- export { padVisual, truncateVisual } from "../text-display.js";
5
- export interface ModelPickerOption {
6
- id: string;
7
- label: string;
8
- group: string;
9
- providerBadge: string;
10
- }
11
- export type PickerKeyAction = "up" | "down" | "enter" | "escape" | "backspace" | "delete";
12
- export declare function resolvePickerKeyAction(input: string, key: {
13
- upArrow?: boolean;
14
- downArrow?: boolean;
15
- return?: boolean;
16
- escape?: boolean;
17
- backspace?: boolean;
18
- delete?: boolean;
19
- }): PickerKeyAction | undefined;
20
- export declare function isPrintablePickerInput(input: string): boolean;
21
- export declare function formatSkillPickerRow(skill: {
22
- name: string;
23
- description?: string;
24
- }, options: {
25
- selected: boolean;
26
- width: number;
27
- }): string;
28
- export interface ModelPickerProps {
29
- registry: ProviderRegistry;
30
- current: string;
31
- recent: string[];
32
- onSelect: (model: string) => void;
33
- onCancel: () => void;
34
- }
35
- export declare function ModelPicker({ registry, current, recent, onSelect, onCancel }: ModelPickerProps): React.ReactNode;
36
- export declare function buildLocalModelOptions(registry: ProviderRegistry, current: string, recent: string[]): ModelPickerOption[];
37
- export interface ProviderPickerProps {
38
- providers: Array<{
39
- id: string;
40
- name: string;
41
- enabled: boolean;
42
- }>;
43
- current?: string;
44
- onSelect: (providerId: string) => void;
45
- onCancel: () => void;
46
- title?: string;
47
- }
48
- export declare function ProviderPicker({ providers, current, onSelect, onCancel, title }: ProviderPickerProps): React.ReactNode;
49
- export interface KeyPickerProps {
50
- providerName: string;
51
- onSubmit: (key: string) => void;
52
- onCancel: () => void;
53
- }
54
- export declare function KeyPicker({ providerName, onSubmit, onCancel }: KeyPickerProps): React.ReactNode;
55
- export interface SkillPickerProps {
56
- skills: Array<{
57
- name: string;
58
- description: string;
59
- }>;
60
- onSelect: (name: string) => void;
61
- onCancel: () => void;
62
- }
63
- export declare function SkillPicker({ skills, onSelect, onCancel }: SkillPickerProps): React.ReactNode;