@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,7 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useState } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
+ import { isKeyReleaseEvent } from "../key-events.js";
4
5
  import { useTheme } from "../theme.js";
6
+ import { stripTerminalMouseSequences } from "../terminal-mouse.js";
5
7
  export function ApprovalSelect({ options, onSubmit, onCancel, hint, initialIndex = 0, }) {
6
8
  const theme = useTheme();
7
9
  const [focusIndex, setFocusIndex] = useState(Math.max(0, Math.min(initialIndex, options.length - 1)));
@@ -22,6 +24,14 @@ export function ApprovalSelect({ options, onSubmit, onCancel, hint, initialIndex
22
24
  const hasEditableValue = !!focused?.editableValue;
23
25
  const currentValue = focused?.editableValue ? editedValues[focused.id] ?? "" : "";
24
26
  useInput((input, key) => {
27
+ if (isKeyReleaseEvent(key))
28
+ return;
29
+ const strippedMouseInput = stripTerminalMouseSequences(input);
30
+ if (strippedMouseInput !== input) {
31
+ if (!strippedMouseInput)
32
+ return;
33
+ input = strippedMouseInput;
34
+ }
25
35
  if (amending) {
26
36
  if (key.escape) {
27
37
  setAmending(false);
@@ -1,2 +1 @@
1
- export type ResolvedTheme = "light" | "dark";
2
- export declare function detectTerminalTheme(timeoutMs?: number): Promise<ResolvedTheme>;
1
+ export { detectTerminalTheme, themeFromMacOsAppearance, type ResolvedTheme, } from "../tui/detect-theme.js";
@@ -1,87 +1 @@
1
- export async function detectTerminalTheme(timeoutMs = 150) {
2
- const fromEnv = parseColorFgBg(process.env.COLORFGBG);
3
- if (fromEnv)
4
- return fromEnv;
5
- if (process.stdout.isTTY && process.stdin.isTTY) {
6
- const fromOsc = await queryOsc11(timeoutMs);
7
- if (fromOsc)
8
- return fromOsc;
9
- }
10
- return "dark";
11
- }
12
- function parseColorFgBg(value) {
13
- if (!value)
14
- return null;
15
- const parts = value.split(";");
16
- const last = parts[parts.length - 1];
17
- if (!last)
18
- return null;
19
- const bg = parseInt(last, 10);
20
- if (Number.isNaN(bg))
21
- return null;
22
- if (bg >= 0 && bg <= 6)
23
- return "dark";
24
- if (bg >= 7 && bg <= 15)
25
- return "light";
26
- return null;
27
- }
28
- function queryOsc11(timeoutMs) {
29
- return new Promise((resolve) => {
30
- const stdin = process.stdin;
31
- const stdout = process.stdout;
32
- let settled = false;
33
- const originalRaw = stdin.isRaw;
34
- let buffer = "";
35
- const cleanup = () => {
36
- stdin.removeListener("data", onData);
37
- try {
38
- stdin.setRawMode(originalRaw);
39
- }
40
- catch {
41
- // ignore - terminal may have already restored
42
- }
43
- stdin.pause();
44
- };
45
- const finish = (result) => {
46
- if (settled)
47
- return;
48
- settled = true;
49
- clearTimeout(timer);
50
- cleanup();
51
- resolve(result);
52
- };
53
- const onData = (chunk) => {
54
- buffer += chunk.toString("utf8");
55
- const match = buffer.match(/\x1b\]11;rgb:([0-9a-fA-F]+)\/([0-9a-fA-F]+)\/([0-9a-fA-F]+)(?:\x07|\x1b\\)/);
56
- if (!match)
57
- return;
58
- const [, r, g, b] = match;
59
- const lum = relativeLuminance(parseHexChannel(r), parseHexChannel(g), parseHexChannel(b));
60
- finish(lum > 0.5 ? "light" : "dark");
61
- };
62
- try {
63
- stdin.setRawMode(true);
64
- }
65
- catch {
66
- resolve(null);
67
- return;
68
- }
69
- stdin.resume();
70
- stdin.on("data", onData);
71
- const timer = setTimeout(() => finish(null), timeoutMs);
72
- try {
73
- stdout.write("\x1b]11;?\x07");
74
- }
75
- catch {
76
- finish(null);
77
- }
78
- });
79
- }
80
- function parseHexChannel(hex) {
81
- const max = (1 << (hex.length * 4)) - 1;
82
- return parseInt(hex, 16) / max;
83
- }
84
- function relativeLuminance(r, g, b) {
85
- const channel = (c) => c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
86
- return 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b);
87
- }
1
+ export { detectTerminalTheme, themeFromMacOsAppearance, } from "../tui/detect-theme.js";
@@ -20,6 +20,7 @@ export interface DisplayMessage {
20
20
  }
21
21
  export declare function userInputStatusBadgeLabel(status?: UserInputStatus): string | undefined;
22
22
  export declare function setUserInputStatus(message: DisplayMessage, inputStatus?: UserInputStatus): DisplayMessage;
23
+ export declare function moveStatusMessageToEnd(messages: DisplayMessage[], key: string, inputStatus?: UserInputStatus): DisplayMessage[];
23
24
  /**
24
25
  * Aborted assistant messages carry a model-facing interruption note appended
25
26
  * to their content (whole content, or a "\n\n"-joined suffix after partial
@@ -14,6 +14,17 @@ export function setUserInputStatus(message, inputStatus) {
14
14
  const { inputStatus: _inputStatus, ...rest } = message;
15
15
  return rest;
16
16
  }
17
+ export function moveStatusMessageToEnd(messages, key, inputStatus) {
18
+ const index = messages.findIndex((message) => message.key === key);
19
+ if (index === -1)
20
+ return messages;
21
+ const message = messages[index];
22
+ return [
23
+ ...messages.slice(0, index),
24
+ ...messages.slice(index + 1),
25
+ setUserInputStatus(message, inputStatus),
26
+ ];
27
+ }
17
28
  /**
18
29
  * Aborted assistant messages carry a model-facing interruption note appended
19
30
  * to their content (whole content, or a "\n\n"-joined suffix after partial
@@ -1,7 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useMemo, useState } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
+ import { isKeyReleaseEvent } from "./key-events.js";
4
5
  import { useTheme } from "./theme.js";
6
+ import { stripTerminalMouseSequences } from "./terminal-mouse.js";
5
7
  import { submitFeedback, FeedbackSubmitError } from "../feedback/submit.js";
6
8
  export function FeedbackDialog({ base, initialDescription, onDismiss, onResult }) {
7
9
  const theme = useTheme();
@@ -39,6 +41,14 @@ export function FeedbackDialog({ base, initialDescription, onDismiss, onResult }
39
41
  }
40
42
  };
41
43
  useInput((input, key) => {
44
+ if (isKeyReleaseEvent(key))
45
+ return;
46
+ const strippedMouseInput = stripTerminalMouseSequences(input);
47
+ if (strippedMouseInput !== input) {
48
+ if (!strippedMouseInput)
49
+ return;
50
+ input = strippedMouseInput;
51
+ }
42
52
  if (stage === "submitting")
43
53
  return;
44
54
  if (stage === "done") {
@@ -6,7 +6,9 @@ import { existsSync, statSync } from "node:fs";
6
6
  import { isAbsolute, resolve as resolvePath, basename } from "node:path";
7
7
  import { homedir } from "node:os";
8
8
  import { registerApp } from "@larksuiteoapi/node-sdk";
9
+ import { isKeyReleaseEvent } from "./key-events.js";
9
10
  import { useTheme } from "./theme.js";
11
+ import { stripTerminalMouseSequences } from "./terminal-mouse.js";
10
12
  import { bootstrapConfig } from "../feishu/config.js";
11
13
  import { ScopeRegistry } from "../feishu/scope/scope-registry.js";
12
14
  const EMPTY_VALUES = { chatId: "", cwd: "", displayName: "" };
@@ -100,6 +102,14 @@ export function FeishuSetupPicker({ onComplete, onCancel }) {
100
102
  onCancel();
101
103
  };
102
104
  useInput((input, key) => {
105
+ if (isKeyReleaseEvent(key))
106
+ return;
107
+ const strippedMouseInput = stripTerminalMouseSequences(input);
108
+ if (strippedMouseInput !== input) {
109
+ if (!strippedMouseInput)
110
+ return;
111
+ input = strippedMouseInput;
112
+ }
103
113
  if (key.escape) {
104
114
  // Esc at any stage = cancel/skip.
105
115
  if (stage.kind === "credentialed") {
@@ -1,6 +1,7 @@
1
1
  import type { PermissionMode } from "../types.js";
2
2
  export interface FooterData {
3
3
  mode?: PermissionMode;
4
+ goalLine?: string;
4
5
  }
5
6
  /**
6
7
  * Bottom status line. Path / provider / model moved into the welcome banner;
@@ -8,9 +8,15 @@ import { PERMISSION_MODE_INFO } from "../permission/mode.js";
8
8
  * (zero rows) in the default mode.
9
9
  */
10
10
  export function FooterBar({ data }) {
11
- if (!data.mode || data.mode === "default")
11
+ const showMode = !!data.mode && data.mode !== "default";
12
+ const goalLine = data.goalLine?.trim();
13
+ if (!showMode && !goalLine)
12
14
  return null;
13
- return (_jsx(Box, { paddingX: 1, flexShrink: 0, children: _jsx(ModeBadge, { mode: data.mode }) }));
15
+ return (_jsxs(Box, { paddingX: 1, flexShrink: 0, flexDirection: "column", children: [goalLine && _jsx(GoalBadge, { line: goalLine }), showMode && _jsx(ModeBadge, { mode: data.mode })] }));
16
+ }
17
+ function GoalBadge({ line }) {
18
+ const theme = useTheme();
19
+ return (_jsx(Text, { color: theme.muted, children: line }));
14
20
  }
15
21
  function ModeBadge({ mode }) {
16
22
  const theme = useTheme();
@@ -7,6 +7,8 @@ export interface SubmitPayload {
7
7
  /** Text shown in the composer/transcript when it differs from the real text. */
8
8
  displayText?: string;
9
9
  images: ImageAttachment[];
10
+ /** First UI-only [Image #N] label reserved for this submitted payload. */
11
+ imageDisplayStart?: number;
10
12
  }
11
13
  interface InputBoxProps {
12
14
  onSubmit: (payload: SubmitPayload) => void;
@@ -15,11 +17,6 @@ interface InputBoxProps {
15
17
  * turn instead of its idle-time behavior.
16
18
  */
17
19
  onQueue?: (payload: SubmitPayload) => void;
18
- /**
19
- * Receives scroll intent when Up/Down arrows are classified as synthetic
20
- * wheel events (terminal alternate-scroll) rather than keyboard presses.
21
- */
22
- onWheelScroll?: (direction: "up" | "down", lines: number) => void;
23
20
  onPasteNotice?: (notice: string) => void;
24
21
  disabled?: boolean;
25
22
  cursorResetEpoch?: number;
@@ -27,8 +24,14 @@ interface InputBoxProps {
27
24
  draftEpoch?: number;
28
25
  onDraftApplied?: () => void;
29
26
  skillRegistry?: SkillRegistry;
27
+ localSlashCommands?: Array<{
28
+ name: string;
29
+ description: string;
30
+ }>;
30
31
  terminalColumns: number;
31
32
  cwd: string;
33
+ sessionFile?: string;
34
+ nextImageLabelStart?: number;
32
35
  }
33
36
  export declare function needsCursorRowCompensation(nextOutputHeight: number, viewportRows: number, previousOutputHeight: number | null): boolean;
34
37
  export declare function resolveCursorRowCompensation(input: {
@@ -41,21 +44,54 @@ export declare function resolveCursorRowCompensation(input: {
41
44
  export declare function isCtrlCInput(input: string, key: {
42
45
  ctrl?: boolean;
43
46
  }): boolean;
47
+ export declare function shouldUseLineComposerFrame(_background: string): boolean;
48
+ export declare function shouldUseHardwareComposerCursor(env?: Record<string, string | undefined>): boolean;
49
+ export declare function composerVerticalArrowDirection(key: {
50
+ upArrow?: boolean;
51
+ downArrow?: boolean;
52
+ eventType?: string;
53
+ }): "up" | "down" | undefined;
54
+ export declare function resolveSoftwareCursorCellStyle(input: {
55
+ visible: boolean;
56
+ cursorBackground: string;
57
+ cursorForeground: string;
58
+ textColor: string;
59
+ rowBackground?: string;
60
+ }): {
61
+ backgroundColor?: string;
62
+ color: string;
63
+ };
44
64
  /**
45
65
  * Split a composer line around the cursor so the cell under it can render as
46
66
  * an inverse-video software cursor. The visible cursor must not depend on the
47
67
  * real terminal cursor: Ink only re-arms its one-shot cursor escape when the
48
68
  * component owning useCursor re-commits, so frames produced by other
49
69
  * components' local state (the waiting spinner, viewport scrolling) hide the
50
- * hardware cursor for most of an agent run. Drawing the cell ourselves keeps
51
- * the cursor visible on every frame; the real (mostly hidden) cursor is still
52
- * positioned for IME anchoring.
70
+ * hardware cursor for most of an agent run. Drawing and blinking the cell
71
+ * ourselves keeps it visible while preserving normal typing feedback; the real
72
+ * cursor is still positioned for IME anchoring.
53
73
  */
54
74
  export declare function splitLineAtCursor(lineText: string, charOffset: number): {
55
75
  before: string;
56
76
  at: string;
57
77
  after: string;
58
78
  };
79
+ export interface TextHighlightRange {
80
+ start: number;
81
+ end: number;
82
+ }
83
+ export type ComposerTextSegmentKind = "normal" | "command" | "cursor";
84
+ export interface ComposerTextSegment {
85
+ kind: ComposerTextSegmentKind;
86
+ text: string;
87
+ }
88
+ export declare function resolveSlashCommandHighlightRange(input: string, commandNames: Iterable<string>): TextHighlightRange | null;
89
+ export declare function splitComposerTextSegments(input: {
90
+ text: string;
91
+ absStart: number;
92
+ highlight: TextHighlightRange | null;
93
+ cursorOffset?: number;
94
+ }): ComposerTextSegment[];
59
95
  export declare function shouldSubmitExactSlashSuggestion(input: string, suggestionName?: string): boolean;
60
96
  export declare function resolveSlashEnterAction(input: string, suggestions: Array<{
61
97
  name: string;
@@ -80,4 +116,29 @@ export declare function insertNewlineAtCursor(text: string, cursor: number): {
80
116
  text: string;
81
117
  cursor: number;
82
118
  };
83
- export declare function InputBox({ onSubmit, onQueue, onWheelScroll, onPasteNotice, disabled, cursorResetEpoch, draftText, draftEpoch, onDraftApplied, skillRegistry, terminalColumns, cwd, }: InputBoxProps): import("react/jsx-runtime").JSX.Element;
119
+ export declare function previousWordBoundary(text: string, cursor: number): number;
120
+ export declare function nextWordBoundary(text: string, cursor: number): number;
121
+ export declare function lineStartBoundary(text: string, cursor: number): number;
122
+ export declare function lineEndBoundary(text: string, cursor: number): number;
123
+ export declare function deleteToLineStart(text: string, cursor: number): {
124
+ text: string;
125
+ cursor: number;
126
+ };
127
+ export declare function deleteToLineEnd(text: string, cursor: number): {
128
+ text: string;
129
+ cursor: number;
130
+ };
131
+ export declare function deleteAtCursor(text: string, cursor: number): {
132
+ text: string;
133
+ cursor: number;
134
+ };
135
+ export type ComposerEditAction = "word-left" | "word-right" | "line-start" | "line-end" | "delete-line-start" | "delete-line-end";
136
+ export declare function resolveComposerEditAction(input: string, key: {
137
+ ctrl?: boolean;
138
+ meta?: boolean;
139
+ leftArrow?: boolean;
140
+ rightArrow?: boolean;
141
+ home?: boolean;
142
+ end?: boolean;
143
+ }): ComposerEditAction | null;
144
+ export declare function InputBox({ onSubmit, onQueue, onPasteNotice, disabled, cursorResetEpoch, draftText, draftEpoch, onDraftApplied, skillRegistry, localSlashCommands, terminalColumns, cwd, sessionFile, nextImageLabelStart, }: InputBoxProps): import("react/jsx-runtime").JSX.Element;