@bubblebrain-ai/bubble 0.0.12 → 0.0.13

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 (128) hide show
  1. package/dist/agent/input-controller.d.ts +11 -0
  2. package/dist/agent/input-controller.js +30 -0
  3. package/dist/agent.d.ts +6 -4
  4. package/dist/agent.js +38 -0
  5. package/dist/main.js +58 -9
  6. package/dist/slash-commands/commands.js +27 -0
  7. package/dist/slash-commands/types.d.ts +10 -0
  8. package/dist/tui/clipboard.d.ts +1 -0
  9. package/dist/tui/clipboard.js +53 -0
  10. package/dist/tui/detect-theme.d.ts +2 -0
  11. package/dist/tui/detect-theme.js +87 -0
  12. package/dist/tui/display-history.d.ts +62 -0
  13. package/dist/tui/display-history.js +305 -0
  14. package/dist/tui/edit-diff.d.ts +11 -0
  15. package/dist/tui/edit-diff.js +52 -0
  16. package/dist/tui/escape-confirmation.d.ts +15 -0
  17. package/dist/tui/escape-confirmation.js +30 -0
  18. package/dist/tui/file-mentions.d.ts +29 -0
  19. package/dist/tui/file-mentions.js +174 -0
  20. package/dist/tui/global-key-router.d.ts +3 -0
  21. package/dist/tui/global-key-router.js +87 -0
  22. package/dist/tui/image-paste.d.ts +95 -0
  23. package/dist/tui/image-paste.js +505 -0
  24. package/dist/tui/input-history.d.ts +16 -0
  25. package/dist/tui/input-history.js +79 -0
  26. package/dist/tui/markdown-inline.d.ts +22 -0
  27. package/dist/tui/markdown-inline.js +68 -0
  28. package/dist/tui/markdown-theme-rules.d.ts +23 -0
  29. package/dist/tui/markdown-theme-rules.js +164 -0
  30. package/dist/tui/markdown-theme.d.ts +5 -0
  31. package/dist/tui/markdown-theme.js +27 -0
  32. package/dist/tui/opencode-spinner.d.ts +22 -0
  33. package/dist/tui/opencode-spinner.js +216 -0
  34. package/dist/tui/prompt-keybindings.d.ts +42 -0
  35. package/dist/tui/prompt-keybindings.js +35 -0
  36. package/dist/tui/recent-activity.d.ts +8 -0
  37. package/dist/tui/recent-activity.js +71 -0
  38. package/dist/tui/render-signature.d.ts +1 -0
  39. package/dist/tui/render-signature.js +7 -0
  40. package/dist/tui/run.d.ts +45 -0
  41. package/dist/tui/run.js +8816 -0
  42. package/dist/tui/session-display.d.ts +6 -0
  43. package/dist/tui/session-display.js +12 -0
  44. package/dist/tui/sidebar-mcp.d.ts +31 -0
  45. package/dist/tui/sidebar-mcp.js +62 -0
  46. package/dist/tui/sidebar-state.d.ts +12 -0
  47. package/dist/tui/sidebar-state.js +69 -0
  48. package/dist/tui/streaming-tool-args.d.ts +15 -0
  49. package/dist/tui/streaming-tool-args.js +30 -0
  50. package/dist/tui/tool-renderers/fallback.d.ts +2 -0
  51. package/dist/tui/tool-renderers/fallback.js +75 -0
  52. package/dist/tui/tool-renderers/registry.d.ts +3 -0
  53. package/dist/tui/tool-renderers/registry.js +11 -0
  54. package/dist/tui/tool-renderers/subagent.d.ts +2 -0
  55. package/dist/tui/tool-renderers/subagent.js +135 -0
  56. package/dist/tui/tool-renderers/types.d.ts +36 -0
  57. package/dist/tui/tool-renderers/types.js +1 -0
  58. package/dist/tui/tool-renderers/write-preview.d.ts +12 -0
  59. package/dist/tui/tool-renderers/write-preview.js +30 -0
  60. package/dist/tui/tool-renderers/write.d.ts +6 -0
  61. package/dist/tui/tool-renderers/write.js +88 -0
  62. package/dist/tui/trace-groups.d.ts +27 -0
  63. package/dist/tui/trace-groups.js +412 -0
  64. package/dist/tui/wordmark.d.ts +15 -0
  65. package/dist/tui/wordmark.js +179 -0
  66. package/dist/tui-ink/app.js +44 -5
  67. package/dist/tui-ink/message-list.js +9 -1
  68. package/dist/tui-ink/theme.d.ts +3 -9
  69. package/dist/tui-ink/theme.js +39 -45
  70. package/dist/tui-ink/welcome.js +22 -78
  71. package/dist/tui-opentui/app.d.ts +54 -0
  72. package/dist/tui-opentui/app.js +1363 -0
  73. package/dist/tui-opentui/approval/approval-dialog.d.ts +15 -0
  74. package/dist/tui-opentui/approval/approval-dialog.js +139 -0
  75. package/dist/tui-opentui/approval/diff-view.d.ts +9 -0
  76. package/dist/tui-opentui/approval/diff-view.js +43 -0
  77. package/dist/tui-opentui/approval/select.d.ts +37 -0
  78. package/dist/tui-opentui/approval/select.js +91 -0
  79. package/dist/tui-opentui/detect-theme.d.ts +2 -0
  80. package/dist/tui-opentui/detect-theme.js +87 -0
  81. package/dist/tui-opentui/display-history.d.ts +55 -0
  82. package/dist/tui-opentui/display-history.js +129 -0
  83. package/dist/tui-opentui/edit-diff.d.ts +11 -0
  84. package/dist/tui-opentui/edit-diff.js +52 -0
  85. package/dist/tui-opentui/feedback-dialog.d.ts +21 -0
  86. package/dist/tui-opentui/feedback-dialog.js +164 -0
  87. package/dist/tui-opentui/feishu-setup-picker.d.ts +7 -0
  88. package/dist/tui-opentui/feishu-setup-picker.js +272 -0
  89. package/dist/tui-opentui/file-mentions.d.ts +29 -0
  90. package/dist/tui-opentui/file-mentions.js +174 -0
  91. package/dist/tui-opentui/footer.d.ts +26 -0
  92. package/dist/tui-opentui/footer.js +40 -0
  93. package/dist/tui-opentui/image-paste.d.ts +54 -0
  94. package/dist/tui-opentui/image-paste.js +288 -0
  95. package/dist/tui-opentui/input-box.d.ts +34 -0
  96. package/dist/tui-opentui/input-box.js +471 -0
  97. package/dist/tui-opentui/input-history.d.ts +16 -0
  98. package/dist/tui-opentui/input-history.js +79 -0
  99. package/dist/tui-opentui/markdown.d.ts +66 -0
  100. package/dist/tui-opentui/markdown.js +127 -0
  101. package/dist/tui-opentui/message-list.d.ts +31 -0
  102. package/dist/tui-opentui/message-list.js +125 -0
  103. package/dist/tui-opentui/model-picker.d.ts +63 -0
  104. package/dist/tui-opentui/model-picker.js +450 -0
  105. package/dist/tui-opentui/plan-confirm.d.ts +9 -0
  106. package/dist/tui-opentui/plan-confirm.js +124 -0
  107. package/dist/tui-opentui/question-dialog.d.ts +10 -0
  108. package/dist/tui-opentui/question-dialog.js +110 -0
  109. package/dist/tui-opentui/recent-activity.d.ts +8 -0
  110. package/dist/tui-opentui/recent-activity.js +71 -0
  111. package/dist/tui-opentui/run-session-picker.d.ts +10 -0
  112. package/dist/tui-opentui/run-session-picker.js +28 -0
  113. package/dist/tui-opentui/run.d.ts +38 -0
  114. package/dist/tui-opentui/run.js +48 -0
  115. package/dist/tui-opentui/session-picker.d.ts +12 -0
  116. package/dist/tui-opentui/session-picker.js +120 -0
  117. package/dist/tui-opentui/theme.d.ts +89 -0
  118. package/dist/tui-opentui/theme.js +157 -0
  119. package/dist/tui-opentui/todos.d.ts +9 -0
  120. package/dist/tui-opentui/todos.js +45 -0
  121. package/dist/tui-opentui/trace-groups.d.ts +27 -0
  122. package/dist/tui-opentui/trace-groups.js +412 -0
  123. package/dist/tui-opentui/use-terminal-size.d.ts +4 -0
  124. package/dist/tui-opentui/use-terminal-size.js +5 -0
  125. package/dist/tui-opentui/welcome.d.ts +25 -0
  126. package/dist/tui-opentui/welcome.js +77 -0
  127. package/dist/types.d.ts +24 -0
  128. package/package.json +5 -1
@@ -59,7 +59,15 @@ function StreamingMessage({ content, reasoning, tools, parts, terminalColumns, v
59
59
  const visibleParts = deferredParts.length > 0
60
60
  ? deferredParts
61
61
  : fallbackStreamingParts(deferredContent, tools);
62
- return (_jsxs(Box, { flexDirection: "column", children: [deferredReasoning && verboseTrace && (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(ReasoningTraceBlock, { reasoning: deferredReasoning }) })), visibleParts.length > 0 && (_jsx(Box, { marginTop: 1, marginBottom: 1, flexDirection: "column", children: _jsx(MessageParts, { parts: visibleParts, terminalColumns: terminalColumns, verboseTrace: verboseTrace, pendingApproval: pendingApproval, showExpandHint: true, nowTick: nowTick, showActivity: true, streaming: true }) }))] }));
62
+ return (_jsxs(Box, { flexDirection: "column", children: [deferredReasoning && verboseTrace && (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(ReasoningTraceBlock, { reasoning: deferredReasoning }) })), visibleParts.length > 0 && (
63
+ // marginTop intentionally 0: this Box only mounts on the first non-empty
64
+ // streaming frame, so a marginTop=1 here would visibly insert a blank
65
+ // line under the user message right at that moment (the "spinner sits
66
+ // close, then content appears with a sudden gap, then spinner slides
67
+ // down" effect users perceive as flicker on the DOM xterm renderer).
68
+ // marginBottom=1 stays so streamed text doesn't collide with the
69
+ // WaitingIndicator rendered below.
70
+ _jsx(Box, { marginTop: 0, marginBottom: 1, flexDirection: "column", children: _jsx(MessageParts, { parts: visibleParts, terminalColumns: terminalColumns, verboseTrace: verboseTrace, pendingApproval: pendingApproval, showExpandHint: true, nowTick: nowTick, showActivity: true, streaming: true }) }))] }));
63
71
  }
64
72
  function MessageParts({ parts, terminalColumns, verboseTrace, pendingApproval, showExpandHint, nowTick, showActivity = false, streaming = false, }) {
65
73
  const lastToolsPartIndex = findLastToolsPartIndex(parts);
@@ -49,15 +49,9 @@ export interface Theme {
49
49
  }
50
50
  export declare const darkTheme: Theme;
51
51
  /**
52
- * Light palette. Two ground rules drove the color choices:
53
- * 1. Named ANSI colors that render OK on both backgrounds (red/green/blue)
54
- * are kept by name so the user's terminal palette overrides remain
55
- * effective.
56
- * 2. Specific hex values are used wherever the dark palette assumed a dark
57
- * background (notably accent/code/trace colors and message bubbles).
58
- * Each hex was picked to clear WCAG AA contrast (4.5:1) against a near-
59
- * white background (#fafafa) or, when applicable, against the explicit
60
- * surface color in the same palette (e.g. diffAddFg vs diffAdd).
52
+ * Light palette aligned with the restored OpenTUI runtime: paper-neutral
53
+ * surfaces, blue focus/user rails, warm command accent, and semantic tool
54
+ * colors tuned for readable contrast on a light terminal background.
61
55
  */
62
56
  export declare const lightTheme: Theme;
63
57
  export declare const ThemeProvider: import("react").Provider<Theme>;
@@ -47,53 +47,47 @@ export const darkTheme = {
47
47
  diffRemoveFg: "#F48771",
48
48
  };
49
49
  /**
50
- * Light palette. Two ground rules drove the color choices:
51
- * 1. Named ANSI colors that render OK on both backgrounds (red/green/blue)
52
- * are kept by name so the user's terminal palette overrides remain
53
- * effective.
54
- * 2. Specific hex values are used wherever the dark palette assumed a dark
55
- * background (notably accent/code/trace colors and message bubbles).
56
- * Each hex was picked to clear WCAG AA contrast (4.5:1) against a near-
57
- * white background (#fafafa) or, when applicable, against the explicit
58
- * surface color in the same palette (e.g. diffAddFg vs diffAdd).
50
+ * Light palette aligned with the restored OpenTUI runtime: paper-neutral
51
+ * surfaces, blue focus/user rails, warm command accent, and semantic tool
52
+ * colors tuned for readable contrast on a light terminal background.
59
53
  */
60
54
  export const lightTheme = {
61
- user: "green",
62
- agent: "blue",
63
- error: "red",
64
- warning: "#9A6500", // ANSI yellow is invisible on white — go to dark amber.
65
- success: "green",
66
- accent: "#0E5A85", // dark teal — replaces "cyan" which washes out on white.
67
- border: "gray",
68
- borderActive: "#0E5A85",
69
- inputBorder: "#6B5FB8",
70
- inputBorderDisabled: "#c5c3d0",
71
- inputBg: "#eeeef6",
72
- inputBgDisabled: "#e2e2ec",
73
- inputText: "#1c1c24",
74
- inputPlaceholder: "#7a7886",
75
- muted: "gray",
76
- dim: "gray",
77
- thinking: "magenta",
78
- thinkingDim: "gray",
79
- toolName: "#0E5A85",
80
- toolResult: "gray",
81
- toolError: "red",
82
- toolPending: "#9A6500",
83
- code: "#9A6500",
84
- traceAction: "#B85A20",
85
- traceCount: "#5a5a5a",
86
- traceDetail: "gray",
87
- traceCommand: "#1A5FA0",
88
- tracePending: "#9A6500",
89
- userMessageBorder: "#6B5FB8",
90
- userMessageBg: "#e8e6f4",
91
- userMessageText: "#1c1c24",
92
- userRail: "#6B5FB8",
93
- diffAdd: "#d4f4d4",
94
- diffRemove: "#f4d4d4",
95
- diffAddFg: "#1c1c24",
96
- diffRemoveFg: "#1c1c24",
55
+ user: "#356FD2",
56
+ agent: "#171717",
57
+ error: "#B62633",
58
+ warning: "#8B4A00",
59
+ success: "#2F7D4A",
60
+ accent: "#8B4A00",
61
+ border: "#B9BDB8",
62
+ borderActive: "#356FD2",
63
+ inputBorder: "#356FD2",
64
+ inputBorderDisabled: "#D7DAD4",
65
+ inputBg: "#F1F3F0",
66
+ inputBgDisabled: "#E6E8E3",
67
+ inputText: "#171717",
68
+ inputPlaceholder: "#6F7377",
69
+ muted: "#6F7377",
70
+ dim: "#8B9094",
71
+ thinking: "#5F666D",
72
+ thinkingDim: "#8B9094",
73
+ toolName: "#495057",
74
+ toolResult: "#171717",
75
+ toolError: "#B62633",
76
+ toolPending: "#8B4A00",
77
+ code: "#2F7D4A",
78
+ traceAction: "#8B4A00",
79
+ traceCount: "#6F7377",
80
+ traceDetail: "#8B9094",
81
+ traceCommand: "#257E8A",
82
+ tracePending: "#8B4A00",
83
+ userMessageBorder: "#356FD2",
84
+ userMessageBg: "#F1F3F0",
85
+ userMessageText: "#234B93",
86
+ userRail: "#356FD2",
87
+ diffAdd: "#D7E8D8",
88
+ diffRemove: "#F7DADC",
89
+ diffAddFg: "#173D2D",
90
+ diffRemoveFg: "#5D1922",
97
91
  };
98
92
  const ThemeContext = createContext(darkTheme);
99
93
  export const ThemeProvider = ThemeContext.Provider;
@@ -3,80 +3,10 @@ import React from "react";
3
3
  import { Box, Text } from "ink";
4
4
  import { createRequire } from "node:module";
5
5
  import { useTheme } from "./theme.js";
6
+ import { BUBBLE_COMPACT_WORDMARK, BUBBLE_WORDMARK, bubbleWordmarkLineText, bubbleWordmarkMaxWidth, } from "../tui/wordmark.js";
6
7
  const require = createRequire(import.meta.url);
7
8
  const PACKAGE_VERSION = readPackageVersion();
8
- const BUBBLE_LOGO_LETTERS = [
9
- [
10
- "██████ ",
11
- "██ ██",
12
- "██ ██",
13
- "██████ ",
14
- "██ ██",
15
- "██ ██",
16
- "██████ ",
17
- ],
18
- [
19
- "██ ██",
20
- "██ ██",
21
- "██ ██",
22
- "██ ██",
23
- "██ ██",
24
- "██ ██",
25
- " █████ ",
26
- ],
27
- [
28
- "██████ ",
29
- "██ ██",
30
- "██ ██",
31
- "██████ ",
32
- "██ ██",
33
- "██ ██",
34
- "██████ ",
35
- ],
36
- [
37
- "██████ ",
38
- "██ ██",
39
- "██ ██",
40
- "██████ ",
41
- "██ ██",
42
- "██ ██",
43
- "██████ ",
44
- ],
45
- [
46
- "██ ",
47
- "██ ",
48
- "██ ",
49
- "██ ",
50
- "██ ",
51
- "██ ",
52
- "███████",
53
- ],
54
- [
55
- "███████",
56
- "██ ",
57
- "██ ",
58
- "██████ ",
59
- "██ ",
60
- "██ ",
61
- "███████",
62
- ],
63
- ];
64
- /**
65
- * Derive a 6-step logo gradient from the active theme tokens so the banner
66
- * stays readable on both dark and light backgrounds.
67
- */
68
- function logoColors(theme) {
69
- return [
70
- theme.userMessageText,
71
- theme.userMessageText,
72
- theme.inputBorder,
73
- theme.inputBorder,
74
- theme.traceCommand,
75
- theme.traceCommand,
76
- ];
77
- }
78
- const COMPACT_LOGO = ["B", "U", "B", "B", "L", "E"];
79
- const WIDE_LOGO_MIN_WIDTH = 52;
9
+ const WIDE_LOGO_MIN_WIDTH = bubbleWordmarkMaxWidth(BUBBLE_WORDMARK) + 4;
80
10
  export function shouldShowWelcomeBanner({ startedWithVisibleHistory, }) {
81
11
  // Keep banner visibility tied to the initial history, not transient overlays,
82
12
  // so opening and closing a picker does not move it in the transcript.
@@ -96,18 +26,32 @@ export function WelcomeBanner({ terminalColumns, modelLabel, cwd, tips, skillsCo
96
26
  : "Type / for commands and @ to reference files";
97
27
  const modelLine = modelLabel ? `${modelLabel}${cwd ? ` · ${cwd}` : ""}` : cwd;
98
28
  return (_jsxs(Box, { width: effectiveWidth, flexDirection: "column", alignItems: "center", marginBottom: 1, children: [_jsx(Box, { flexDirection: "column", alignItems: "center", children: useWideLogo
99
- ? BUBBLE_LOGO_LETTERS[0].map((_, rowIndex) => (_jsx(LogoRow, { rowIndex: rowIndex }, `logo-row-${rowIndex}`)))
29
+ ? BUBBLE_WORDMARK.map((line, rowIndex) => (_jsx(LogoRow, { line: line }, `logo-row-${rowIndex}`)))
100
30
  : _jsx(CompactLogo, {}) }), _jsx(Box, { marginTop: 2, children: _jsx(Text, { bold: true, color: theme.muted, children: PACKAGE_VERSION }) }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { bold: true, color: theme.userMessageText, children: "TIP: " }), _jsx(Text, { bold: true, color: theme.userMessageText, children: tip })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.muted, children: "shift+tab to cycle modes \u00B7 ctrl+r for reasoning \u00B7 ctrl+o for trace" }) }), modelLine && (_jsx(Box, { children: _jsx(Text, { color: theme.muted, children: truncateToWidth(modelLine, effectiveWidth - 4) }) })), _jsxs(Box, { marginTop: 1, children: [_jsx(StatusItem, { label: "Skills", count: skillsCount, ok: skillsCount > 0 }), _jsx(Text, { color: theme.muted, children: " " }), _jsx(StatusItem, { label: "MCPs", count: mcpConnectedCount, total: mcpTotalCount, ok: mcpTotalCount === 0 || mcpConnectedCount === mcpTotalCount }), _jsx(Text, { color: theme.muted, children: " " }), _jsx(StatusItem, { label: "AGENTS.md", ok: hasAgentsFile })] })] }));
101
31
  }
102
- function LogoRow({ rowIndex }) {
32
+ function LogoRow({ line }) {
103
33
  const theme = useTheme();
104
- const colors = logoColors(theme);
105
- return (_jsx(Box, { children: BUBBLE_LOGO_LETTERS.map((letter, index) => (_jsxs(React.Fragment, { children: [_jsx(Text, { bold: true, color: colors[index], children: letter[rowIndex] }), index < BUBBLE_LOGO_LETTERS.length - 1 && _jsx(Text, { children: " " })] }, `${index}-${rowIndex}`))) }));
34
+ if (!line.segments) {
35
+ return _jsx(Text, { bold: true, color: logoColor(theme, line.tone ?? "caption"), children: line.text ?? "" });
36
+ }
37
+ return (_jsx(Box, { children: line.segments.map((segment, index) => (_jsx(React.Fragment, { children: _jsx(Text, { bold: true, color: logoColor(theme, segment.tone), children: segment.text }) }, `${index}-${segment.text}`))) }));
106
38
  }
107
39
  function CompactLogo() {
108
40
  const theme = useTheme();
109
- const colors = logoColors(theme);
110
- return (_jsx(Box, { children: COMPACT_LOGO.map((letter, index) => (_jsx(Text, { bold: true, color: colors[index], children: letter }, `${letter}-${index}`))) }));
41
+ const line = BUBBLE_COMPACT_WORDMARK[0];
42
+ if (!line?.segments) {
43
+ return _jsx(Text, { bold: true, color: theme.warning, children: bubbleWordmarkLineText(line ?? { text: "" }) });
44
+ }
45
+ return (_jsx(Box, { children: line.segments.map((segment, index) => (_jsx(Text, { bold: true, color: logoColor(theme, segment.tone), children: segment.text }, `${segment.text}-${index}`))) }));
46
+ }
47
+ function logoColor(theme, tone) {
48
+ switch (tone) {
49
+ case "brand": return theme.warning;
50
+ case "ink": return theme.userMessageText;
51
+ case "stone": return theme.muted;
52
+ case "soft": return theme.dim;
53
+ case "caption": return theme.muted;
54
+ }
111
55
  }
112
56
  function StatusItem({ label, count, total, ok, }) {
113
57
  const theme = useTheme();
@@ -0,0 +1,54 @@
1
+ /** @jsxImportSource @opentui/react */
2
+ import React from "react";
3
+ import { type Agent } from "../agent.js";
4
+ import type { CliArgs } from "../cli.js";
5
+ import type { SessionManager } from "../session.js";
6
+ import type { PlanDecision, Provider } from "../types.js";
7
+ import { type ResolvedTheme, type ThemeMode } from "./theme.js";
8
+ import { ProviderRegistry } from "../provider-registry.js";
9
+ import { SkillRegistry } from "../skills/registry.js";
10
+ import type { ApprovalDecision, ApprovalRequest } from "../approval/types.js";
11
+ import type { BashAllowlist } from "../approval/session-cache.js";
12
+ import type { SettingsManager } from "../permissions/settings.js";
13
+ import type { McpManager } from "../mcp/manager.js";
14
+ import type { LspService } from "../lsp/index.js";
15
+ import type { QuestionController } from "../question/index.js";
16
+ import type { MemoryScope } from "../memory/index.js";
17
+ export interface PlanHandlerRef {
18
+ current?: (plan: string) => Promise<PlanDecision>;
19
+ }
20
+ export interface ApprovalHandlerRef {
21
+ current?: (req: ApprovalRequest) => Promise<ApprovalDecision>;
22
+ }
23
+ interface AppProps {
24
+ agent: Agent;
25
+ args: CliArgs;
26
+ sessionManager?: SessionManager;
27
+ createProvider?: (providerId: string, apiKey: string, baseURL: string) => Provider;
28
+ registry?: ProviderRegistry;
29
+ skillRegistry?: SkillRegistry;
30
+ planHandlerRef?: PlanHandlerRef;
31
+ approvalHandlerRef?: ApprovalHandlerRef;
32
+ questionController?: QuestionController;
33
+ bashAllowlist?: BashAllowlist;
34
+ settingsManager?: SettingsManager;
35
+ lspService?: LspService;
36
+ mcpManager?: McpManager;
37
+ themeMode?: ThemeMode;
38
+ themeOverrides?: Record<string, string>;
39
+ detectedTheme?: ResolvedTheme;
40
+ onThemeModeChange?: (mode: ThemeMode) => void;
41
+ flushMemory?: () => Promise<void>;
42
+ runMemoryCompaction?: () => Promise<string>;
43
+ runMemorySummary?: (scope?: MemoryScope) => Promise<string>;
44
+ runMemoryRefresh?: (scope?: MemoryScope) => Promise<string>;
45
+ /** Whether the bypassPermissions mode is reachable via Shift+Tab cycling. */
46
+ bypassEnabled?: boolean;
47
+ onExit?: (summary: ExitSummary) => void;
48
+ }
49
+ export interface ExitSummary {
50
+ /** Wall-clock duration of the session, in milliseconds. */
51
+ wallMs: number;
52
+ }
53
+ export declare function App({ agent, args, sessionManager, createProvider, registry, skillRegistry, planHandlerRef, approvalHandlerRef, questionController, bashAllowlist, settingsManager, lspService, mcpManager, themeMode: initialThemeMode, themeOverrides, detectedTheme, onThemeModeChange, flushMemory, runMemoryCompaction, runMemorySummary, runMemoryRefresh, bypassEnabled, onExit }: AppProps): React.ReactNode;
54
+ export {};