wave-code 0.8.4 → 0.9.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 (38) hide show
  1. package/dist/components/ChatInterface.d.ts.map +1 -1
  2. package/dist/components/ChatInterface.js +26 -7
  3. package/dist/components/HelpView.d.ts.map +1 -1
  4. package/dist/components/HelpView.js +1 -0
  5. package/dist/components/InputBox.js +4 -3
  6. package/dist/components/MessageBlockItem.d.ts.map +1 -1
  7. package/dist/components/MessageBlockItem.js +1 -1
  8. package/dist/components/MessageList.d.ts +2 -1
  9. package/dist/components/MessageList.d.ts.map +1 -1
  10. package/dist/components/MessageList.js +14 -4
  11. package/dist/components/QueuedMessageList.d.ts +3 -0
  12. package/dist/components/QueuedMessageList.d.ts.map +1 -0
  13. package/dist/components/QueuedMessageList.js +17 -0
  14. package/dist/components/ReasoningDisplay.d.ts +1 -0
  15. package/dist/components/ReasoningDisplay.d.ts.map +1 -1
  16. package/dist/components/ReasoningDisplay.js +3 -3
  17. package/dist/components/ToolDisplay.js +1 -1
  18. package/dist/contexts/useChat.d.ts +7 -0
  19. package/dist/contexts/useChat.d.ts.map +1 -1
  20. package/dist/contexts/useChat.js +17 -1
  21. package/dist/hooks/useInputManager.d.ts +3 -3
  22. package/dist/hooks/useInputManager.d.ts.map +1 -1
  23. package/dist/hooks/useInputManager.js +10 -9
  24. package/dist/managers/inputHandlers.d.ts +7 -4
  25. package/dist/managers/inputHandlers.d.ts.map +1 -1
  26. package/dist/managers/inputHandlers.js +165 -42
  27. package/package.json +2 -2
  28. package/src/components/ChatInterface.tsx +42 -15
  29. package/src/components/HelpView.tsx +1 -0
  30. package/src/components/InputBox.tsx +17 -17
  31. package/src/components/MessageBlockItem.tsx +8 -3
  32. package/src/components/MessageList.tsx +16 -3
  33. package/src/components/QueuedMessageList.tsx +31 -0
  34. package/src/components/ReasoningDisplay.tsx +8 -2
  35. package/src/components/ToolDisplay.tsx +2 -2
  36. package/src/contexts/useChat.tsx +29 -1
  37. package/src/hooks/useInputManager.ts +9 -21
  38. package/src/managers/inputHandlers.ts +197 -56
@@ -1 +1 @@
1
- {"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../src/components/ChatInterface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAYtE,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EA6IjC,CAAC"}
1
+ {"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../src/components/ChatInterface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAatE,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAuKjC,CAAC"}
@@ -5,6 +5,7 @@ import { MessageList } from "./MessageList.js";
5
5
  import { InputBox } from "./InputBox.js";
6
6
  import { LoadingIndicator } from "./LoadingIndicator.js";
7
7
  import { TaskList } from "./TaskList.js";
8
+ import { QueuedMessageList } from "./QueuedMessageList.js";
8
9
  import { ConfirmationDetails } from "./ConfirmationDetails.js";
9
10
  import { ConfirmationSelector } from "./ConfirmationSelector.js";
10
11
  import { useChat } from "../contexts/useChat.js";
@@ -12,6 +13,7 @@ export const ChatInterface = () => {
12
13
  const { stdout } = useStdout();
13
14
  const [detailsHeight, setDetailsHeight] = useState(0);
14
15
  const [selectorHeight, setSelectorHeight] = useState(0);
16
+ const [dynamicBlocksHeight, setDynamicBlocksHeight] = useState(0);
15
17
  const [isConfirmationTooTall, setIsConfirmationTooTall] = useState(false);
16
18
  const { messages, isLoading, isCommandRunning, isCompressing, sendMessage, abortMessage, mcpServers, connectMcpServer, disconnectMcpServer, isExpanded, sessionId, latestTotalTokens, slashCommands, hasSlashCommand, isConfirmationVisible, confirmingTool, handleConfirmationDecision, handleConfirmationCancel: originalHandleConfirmationCancel, setWasLastDetailsTooTall, version, workdir, getModelConfig, } = useChat();
17
19
  const model = getModelConfig().model;
@@ -21,16 +23,33 @@ export const ChatInterface = () => {
21
23
  const handleSelectorHeightMeasured = useCallback((height) => {
22
24
  setSelectorHeight(height);
23
25
  }, []);
26
+ const handleDynamicBlocksHeightMeasured = useCallback((height) => {
27
+ setDynamicBlocksHeight(height);
28
+ }, []);
24
29
  useLayoutEffect(() => {
30
+ if (!isConfirmationVisible) {
31
+ setIsConfirmationTooTall(false);
32
+ setDetailsHeight(0);
33
+ setSelectorHeight(0);
34
+ setDynamicBlocksHeight(0);
35
+ return;
36
+ }
37
+ if (isConfirmationTooTall) {
38
+ return;
39
+ }
25
40
  const terminalHeight = stdout?.rows || 24;
26
- const totalHeight = detailsHeight + selectorHeight;
41
+ const totalHeight = detailsHeight + selectorHeight + dynamicBlocksHeight;
27
42
  if (totalHeight > terminalHeight) {
28
43
  setIsConfirmationTooTall(true);
29
44
  }
30
- else {
31
- setIsConfirmationTooTall(false);
32
- }
33
- }, [detailsHeight, selectorHeight, stdout?.rows]);
45
+ }, [
46
+ detailsHeight,
47
+ selectorHeight,
48
+ dynamicBlocksHeight,
49
+ stdout?.rows,
50
+ isConfirmationVisible,
51
+ isConfirmationTooTall,
52
+ ]);
34
53
  const handleConfirmationCancel = useCallback(() => {
35
54
  if (isConfirmationTooTall) {
36
55
  setWasLastDetailsTooTall((prev) => prev + 1);
@@ -55,7 +74,7 @@ export const ChatInterface = () => {
55
74
  ]);
56
75
  if (!sessionId)
57
76
  return null;
58
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(MessageList, { messages: messages, isExpanded: isExpanded, forceStatic: isConfirmationVisible && isConfirmationTooTall, version: version, workdir: workdir, model: model }), (isLoading || isCommandRunning || isCompressing) &&
77
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(MessageList, { messages: messages, isExpanded: isExpanded, forceStatic: isConfirmationVisible && isConfirmationTooTall, version: version, workdir: workdir, model: model, onDynamicBlocksHeightMeasured: handleDynamicBlocksHeightMeasured }), (isLoading || isCommandRunning || isCompressing) &&
59
78
  !isConfirmationVisible &&
60
- !isExpanded && (_jsx(LoadingIndicator, { isLoading: isLoading, isCommandRunning: isCommandRunning, isCompressing: isCompressing, latestTotalTokens: latestTotalTokens })), !isConfirmationVisible && !isExpanded && _jsx(TaskList, {}), isConfirmationVisible && (_jsxs(_Fragment, { children: [_jsx(ConfirmationDetails, { toolName: confirmingTool.name, toolInput: confirmingTool.input, isExpanded: isExpanded, onHeightMeasured: handleDetailsHeightMeasured, isStatic: isConfirmationTooTall }), _jsx(ConfirmationSelector, { toolName: confirmingTool.name, toolInput: confirmingTool.input, suggestedPrefix: confirmingTool.suggestedPrefix, hidePersistentOption: confirmingTool.hidePersistentOption, isExpanded: isExpanded, onDecision: wrappedHandleConfirmationDecision, onCancel: handleConfirmationCancel, onAbort: abortMessage, onHeightMeasured: handleSelectorHeightMeasured })] })), !isConfirmationVisible && !isExpanded && (_jsx(InputBox, { isLoading: isLoading, isCommandRunning: isCommandRunning, sendMessage: sendMessage, abortMessage: abortMessage, mcpServers: mcpServers, connectMcpServer: connectMcpServer, disconnectMcpServer: disconnectMcpServer, slashCommands: slashCommands, hasSlashCommand: hasSlashCommand }))] }));
79
+ !isExpanded && (_jsx(LoadingIndicator, { isLoading: isLoading, isCommandRunning: isCommandRunning, isCompressing: isCompressing, latestTotalTokens: latestTotalTokens })), !isConfirmationVisible && !isExpanded && _jsx(TaskList, {}), isConfirmationVisible && (_jsxs(_Fragment, { children: [_jsx(ConfirmationDetails, { toolName: confirmingTool.name, toolInput: confirmingTool.input, isExpanded: isExpanded, onHeightMeasured: handleDetailsHeightMeasured, isStatic: isConfirmationTooTall }), _jsx(ConfirmationSelector, { toolName: confirmingTool.name, toolInput: confirmingTool.input, suggestedPrefix: confirmingTool.suggestedPrefix, hidePersistentOption: confirmingTool.hidePersistentOption, isExpanded: isExpanded, onDecision: wrappedHandleConfirmationDecision, onCancel: handleConfirmationCancel, onAbort: abortMessage, onHeightMeasured: handleSelectorHeightMeasured })] })), !isConfirmationVisible && !isExpanded && (_jsxs(_Fragment, { children: [_jsx(QueuedMessageList, {}), _jsx(InputBox, { isLoading: isLoading, isCommandRunning: isCommandRunning, sendMessage: sendMessage, abortMessage: abortMessage, mcpServers: mcpServers, connectMcpServer: connectMcpServer, disconnectMcpServer: disconnectMcpServer, slashCommands: slashCommands, hasSlashCommand: hasSlashCommand })] }))] }));
61
80
  };
@@ -1 +1 @@
1
- {"version":3,"file":"HelpView.d.ts","sourceRoot":"","sources":["../../src/components/HelpView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;CAC3B;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAoK5C,CAAC"}
1
+ {"version":3,"file":"HelpView.d.ts","sourceRoot":"","sources":["../../src/components/HelpView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;CAC3B;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAqK5C,CAAC"}
@@ -46,6 +46,7 @@ export const HelpView = ({ onCancel, commands = [], }) => {
46
46
  { key: "Ctrl+T", description: "Toggle task list" },
47
47
  { key: "Ctrl+B", description: "Background current task" },
48
48
  { key: "Ctrl+V", description: "Paste image" },
49
+ { key: "Ctrl+J", description: "Newline" },
49
50
  { key: "Shift+Tab", description: "Cycle permission mode" },
50
51
  {
51
52
  key: "Esc",
@@ -14,7 +14,7 @@ import { useInputManager } from "../hooks/useInputManager.js";
14
14
  import { useChat } from "../contexts/useChat.js";
15
15
  export const INPUT_PLACEHOLDER_TEXT = "Type your message (use /help for more info)...";
16
16
  export const INPUT_PLACEHOLDER_TEXT_PREFIX = INPUT_PLACEHOLDER_TEXT.substring(0, 10);
17
- export const InputBox = ({ isLoading = false, isCommandRunning = false, sendMessage = () => { }, abortMessage = () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
17
+ export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
18
18
  const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, clearMessages, } = useChat();
19
19
  // Input manager with all input state and functionality (including images)
20
20
  const { inputText, cursorPosition,
@@ -47,7 +47,7 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, sendMess
47
47
  }, [chatPermissionMode, setPermissionMode]);
48
48
  // Use the InputManager's unified input handler
49
49
  useInput(async (input, key) => {
50
- await handleInput(input, key, attachedImages, isLoading, isCommandRunning, clearImages);
50
+ await handleInput(input, key, attachedImages, clearImages);
51
51
  });
52
52
  const handleRewindCancel = () => {
53
53
  if (setShowRewindManager) {
@@ -56,6 +56,7 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, sendMess
56
56
  };
57
57
  const isPlaceholder = !inputText;
58
58
  const placeholderText = INPUT_PLACEHOLDER_TEXT;
59
+ const isShellCommand = inputText?.startsWith("!") && !inputText.includes("\n");
59
60
  // handleCommandSelectorInsert is already memoized in useInputManager, no need to wrap again
60
61
  // Split text into three parts: before cursor, cursor position, after cursor
61
62
  const displayText = isPlaceholder ? placeholderText : inputText;
@@ -87,5 +88,5 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, sendMess
87
88
  showMcpManager ||
88
89
  showRewindManager ||
89
90
  showHelp ||
90
- showStatusCommand || (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { borderStyle: "single", borderColor: "gray", borderLeft: false, borderRight: false, children: _jsx(Text, { color: isPlaceholder ? "gray" : "white", children: shouldShowCursor ? (_jsxs(_Fragment, { children: [beforeCursor, _jsx(Text, { backgroundColor: "white", color: "black", children: atCursor }), afterCursor] })) : (displayText) }) }), _jsx(Box, { paddingRight: 1, justifyContent: "space-between", width: "100%", children: _jsxs(Text, { color: "gray", children: ["Mode:", " ", _jsx(Text, { color: permissionMode === "plan" ? "yellow" : "cyan", children: permissionMode }), " ", "(Shift+Tab to cycle)"] }) })] }))] }));
91
+ showStatusCommand || (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { borderStyle: "single", borderColor: "gray", borderLeft: false, borderRight: false, children: _jsx(Text, { color: isPlaceholder ? "gray" : "white", children: shouldShowCursor ? (_jsxs(_Fragment, { children: [beforeCursor, _jsx(Text, { backgroundColor: "white", color: "black", children: atCursor }), afterCursor] })) : (displayText) }) }), _jsx(Box, { paddingRight: 1, justifyContent: "space-between", width: "100%", children: isShellCommand ? (_jsxs(Text, { color: "gray", children: ["Shell: ", _jsx(Text, { color: "yellow", children: "Run shell command" })] })) : (_jsxs(Text, { color: "gray", children: ["Mode:", " ", _jsx(Text, { color: permissionMode === "plan" ? "yellow" : "cyan", children: permissionMode }), " ", "(Shift+Tab to cycle)"] })) })] }))] }));
91
92
  };
@@ -1 +1 @@
1
- {"version":3,"file":"MessageBlockItem.d.ts","sourceRoot":"","sources":["../../src/components/MessageBlockItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAQ5D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,GAAI,6CAK9B,qBAAqB,4CA4DvB,CAAC"}
1
+ {"version":3,"file":"MessageBlockItem.d.ts","sourceRoot":"","sources":["../../src/components/MessageBlockItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAQ5D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,GAAI,6CAK9B,qBAAqB,4CAiEvB,CAAC"}
@@ -7,5 +7,5 @@ import { CompressDisplay } from "./CompressDisplay.js";
7
7
  import { ReasoningDisplay } from "./ReasoningDisplay.js";
8
8
  import { Markdown } from "./Markdown.js";
9
9
  export const MessageBlockItem = ({ block, message, isExpanded, paddingTop = 0, }) => {
10
- return (_jsxs(Box, { flexDirection: "column", paddingTop: paddingTop, children: [block.type === "text" && block.content.trim() && (_jsxs(Box, { children: [block.customCommandContent && (_jsxs(Text, { color: "cyan", bold: true, children: ["$", " "] })), block.source === MessageSource.HOOK && (_jsxs(Text, { color: "magenta", bold: true, children: ["~", " "] })), message.role === "user" ? (_jsx(Text, { backgroundColor: "gray", color: "white", children: block.content })) : (_jsx(Markdown, { children: block.content }))] })), block.type === "error" && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", block.content] }) })), block.type === "bang" && (_jsx(BangDisplay, { block: block, isExpanded: isExpanded })), block.type === "tool" && (_jsx(ToolDisplay, { block: block, isExpanded: isExpanded })), block.type === "image" && (_jsxs(Box, { children: [_jsx(Text, { color: "magenta", bold: true, children: "# Image" }), block.imageUrls && block.imageUrls.length > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ", "(", block.imageUrls.length, ")"] }))] })), block.type === "compress" && (_jsx(CompressDisplay, { block: block, isExpanded: isExpanded })), block.type === "reasoning" && _jsx(ReasoningDisplay, { block: block })] }));
10
+ return (_jsxs(Box, { flexDirection: "column", paddingTop: paddingTop, children: [block.type === "text" && block.content.trim() && (_jsxs(Box, { children: [block.customCommandContent && (_jsxs(Text, { color: "cyan", bold: true, children: ["$", " "] })), block.source === MessageSource.HOOK && (_jsxs(Text, { color: "magenta", bold: true, children: ["~", " "] })), message.role === "user" || isExpanded ? (_jsx(Text, { backgroundColor: message.role === "user" ? "gray" : undefined, color: "white", children: block.content })) : (_jsx(Markdown, { children: block.content }))] })), block.type === "error" && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", block.content] }) })), block.type === "bang" && (_jsx(BangDisplay, { block: block, isExpanded: isExpanded })), block.type === "tool" && (_jsx(ToolDisplay, { block: block, isExpanded: isExpanded })), block.type === "image" && (_jsxs(Box, { children: [_jsx(Text, { color: "magenta", bold: true, children: "# Image" }), block.imageUrls && block.imageUrls.length > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ", "(", block.imageUrls.length, ")"] }))] })), block.type === "compress" && (_jsx(CompressDisplay, { block: block, isExpanded: isExpanded })), block.type === "reasoning" && (_jsx(ReasoningDisplay, { block: block, isExpanded: isExpanded }))] }));
11
11
  };
@@ -7,6 +7,7 @@ export interface MessageListProps {
7
7
  version?: string;
8
8
  workdir?: string;
9
9
  model?: string;
10
+ onDynamicBlocksHeightMeasured?: (height: number) => void;
10
11
  }
11
- export declare const MessageList: React.MemoExoticComponent<({ messages, isExpanded, forceStatic, version, workdir, model, }: MessageListProps) => import("react/jsx-runtime").JSX.Element>;
12
+ export declare const MessageList: React.MemoExoticComponent<({ messages, isExpanded, forceStatic, version, workdir, model, onDynamicBlocksHeightMeasured, }: MessageListProps) => import("react/jsx-runtime").JSX.Element>;
12
13
  //# sourceMappingURL=MessageList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,WAAW,8FAQnB,gBAAgB,6CAmGpB,CAAC"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAGvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED,eAAO,MAAM,WAAW,6HASnB,gBAAgB,6CA8GpB,CAAC"}
@@ -1,9 +1,9 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import React from "react";
2
+ import React, { useLayoutEffect, useRef } from "react";
3
3
  import os from "os";
4
- import { Box, Text, Static } from "ink";
4
+ import { Box, Text, Static, measureElement } from "ink";
5
5
  import { MessageBlockItem } from "./MessageBlockItem.js";
6
- export const MessageList = React.memo(({ messages, isExpanded = false, forceStatic = false, version, workdir, model, }) => {
6
+ export const MessageList = React.memo(({ messages, isExpanded = false, forceStatic = false, version, workdir, model, onDynamicBlocksHeightMeasured, }) => {
7
7
  const welcomeMessage = (_jsxs(Box, { flexDirection: "column", paddingTop: 1, children: [_jsxs(Text, { color: "gray", children: ["WAVE", version ? ` v${version}` : "", model ? ` • ${model}` : ""] }), workdir && (_jsx(Text, { color: "gray", wrap: "truncate-middle", children: workdir.replace(os.homedir(), "~") }))] }));
8
8
  // Limit messages when expanded to prevent long rendering times
9
9
  const maxExpandedMessages = 20;
@@ -35,6 +35,16 @@ export const MessageList = React.memo(({ messages, isExpanded = false, forceStat
35
35
  });
36
36
  const staticBlocks = blocksWithStatus.filter((b) => !b.isDynamic);
37
37
  const dynamicBlocks = blocksWithStatus.filter((b) => b.isDynamic);
38
+ const dynamicBlocksRef = useRef(null);
39
+ useLayoutEffect(() => {
40
+ if (dynamicBlocksRef.current) {
41
+ const { height } = measureElement(dynamicBlocksRef.current);
42
+ onDynamicBlocksHeightMeasured?.(height);
43
+ }
44
+ else {
45
+ onDynamicBlocksHeightMeasured?.(0);
46
+ }
47
+ }, [dynamicBlocks, isExpanded, onDynamicBlocksHeightMeasured]);
38
48
  const staticItems = [
39
49
  { isWelcome: true, key: "welcome", block: undefined, message: undefined },
40
50
  ...staticBlocks.map((b) => ({ ...b, isWelcome: false })),
@@ -44,7 +54,7 @@ export const MessageList = React.memo(({ messages, isExpanded = false, forceStat
44
54
  return (_jsx(React.Fragment, { children: welcomeMessage }, item.key));
45
55
  }
46
56
  return (_jsx(MessageBlockItem, { block: item.block, message: item.message, isExpanded: isExpanded, paddingTop: 1 }, item.key));
47
- } })), dynamicBlocks.length > 0 && (_jsx(Box, { flexDirection: "column", children: dynamicBlocks.map((item) => (_jsx(MessageBlockItem, { block: item.block, message: item.message, isExpanded: isExpanded, paddingTop: 1 }, item.key))) }))] }));
57
+ } })), dynamicBlocks.length > 0 && (_jsx(Box, { ref: dynamicBlocksRef, flexDirection: "column", children: dynamicBlocks.map((item) => (_jsx(MessageBlockItem, { block: item.block, message: item.message, isExpanded: isExpanded, paddingTop: 1 }, item.key))) }))] }));
48
58
  });
49
59
  // Add display name for debugging
50
60
  MessageList.displayName = "MessageList";
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ export declare const QueuedMessageList: React.FC;
3
+ //# sourceMappingURL=QueuedMessageList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueuedMessageList.d.ts","sourceRoot":"","sources":["../../src/components/QueuedMessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EA0BrC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useChat } from "../contexts/useChat.js";
3
+ import { Box, Text } from "ink";
4
+ export const QueuedMessageList = () => {
5
+ const { queuedMessages = [] } = useChat();
6
+ if (queuedMessages.length === 0) {
7
+ return null;
8
+ }
9
+ return (_jsx(Box, { flexDirection: "column", children: queuedMessages.map((msg, index) => {
10
+ const content = msg.content.trim();
11
+ const hasImages = msg.images && msg.images.length > 0;
12
+ const displayText = content || (hasImages ? "[Images]" : "");
13
+ return (_jsx(Box, { children: _jsx(Text, { color: "gray", italic: true, children: displayText.length > 60
14
+ ? `${displayText.substring(0, 57)}...`
15
+ : displayText }) }, index));
16
+ }) }));
17
+ };
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import type { ReasoningBlock } from "wave-agent-sdk";
3
3
  interface ReasoningDisplayProps {
4
4
  block: ReasoningBlock;
5
+ isExpanded?: boolean;
5
6
  }
6
7
  export declare const ReasoningDisplay: React.FC<ReasoningDisplayProps>;
7
8
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"ReasoningDisplay.d.ts","sourceRoot":"","sources":["../../src/components/ReasoningDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,UAAU,qBAAqB;IAC7B,KAAK,EAAE,cAAc,CAAC;CACvB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAuB5D,CAAC"}
1
+ {"version":3,"file":"ReasoningDisplay.d.ts","sourceRoot":"","sources":["../../src/components/ReasoningDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,UAAU,qBAAqB;IAC7B,KAAK,EAAE,cAAc,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA4B5D,CAAC"}
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Box } from "ink";
2
+ import { Box, Text } from "ink";
3
3
  import { Markdown } from "./Markdown.js";
4
- export const ReasoningDisplay = ({ block, }) => {
4
+ export const ReasoningDisplay = ({ block, isExpanded = false, }) => {
5
5
  const { content } = block;
6
6
  if (!content || !content.trim()) {
7
7
  return null;
8
8
  }
9
- return (_jsx(Box, { borderRight: false, borderTop: false, borderBottom: false, borderStyle: "classic", borderColor: "blue", paddingLeft: 1, children: _jsx(Box, { flexDirection: "column", children: _jsx(Markdown, { children: content }) }) }));
9
+ return (_jsx(Box, { borderRight: false, borderTop: false, borderBottom: false, borderStyle: "classic", borderColor: "blue", paddingLeft: 1, children: _jsx(Box, { flexDirection: "column", children: isExpanded ? (_jsx(Text, { color: "white", children: content })) : (_jsx(Markdown, { children: content })) }) }));
10
10
  };
@@ -40,5 +40,5 @@ export const ToolDisplay = ({ block, isExpanded = false, }) => {
40
40
  return null;
41
41
  };
42
42
  const shortResult = getShortResult();
43
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsxs(Box, { flexShrink: 0, children: [_jsx(Text, { color: getStatusColor(), children: "\u25CF " }), _jsx(Text, { color: "white", children: toolName })] }), !isExpanded && compactParams && (_jsxs(Text, { color: "gray", children: [" ", compactParams] })), hasImages() && _jsxs(Text, { color: "blue", children: [" ", getImageIndicator()] })] }), !isExpanded && shortResult && !error && (_jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: shortResult.split("\n").map((line, index) => (_jsx(Text, { color: "gray", children: line }, index))) })), isExpanded && parameters && (_jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Parameters:" }), _jsx(Text, { color: "gray", children: parameters })] })), isExpanded && result && (_jsx(Box, { flexDirection: "column", children: _jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "green", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Result:" }), _jsx(Text, { color: "white", children: result })] }) })), error && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", typeof error === "string" ? error : String(error)] }) })), stage === "end" && success && (_jsx(DiffDisplay, { toolName: name, parameters: parameters, startLineNumber: block.startLineNumber }))] }));
43
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsxs(Box, { flexShrink: 0, children: [_jsx(Text, { color: getStatusColor(), children: "\u25CF " }), _jsx(Text, { color: "white", children: toolName })] }), !isExpanded && compactParams && (_jsxs(Text, { color: "gray", children: [" ", compactParams] })), hasImages() && _jsxs(Text, { color: "blue", children: [" ", getImageIndicator()] })] }), !isExpanded && shortResult && !error && (_jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: shortResult.split("\n").map((line, index) => (_jsx(Text, { color: "gray", children: line }, index))) })), isExpanded && parameters && (_jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Parameters:" }), _jsx(Text, { color: "gray", children: parameters })] })), isExpanded && result && (_jsx(Box, { flexDirection: "column", children: _jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "green", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Result:" }), _jsx(Text, { color: "white", children: result })] }) })), error && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", typeof error === "string" ? error : String(error)] }) })), !isExpanded && stage === "end" && success && (_jsx(DiffDisplay, { toolName: name, parameters: parameters, startLineNumber: block.startLineNumber }))] }));
44
44
  };
@@ -9,6 +9,13 @@ export interface ChatContextType {
9
9
  isExpanded: boolean;
10
10
  isTaskListVisible: boolean;
11
11
  setIsTaskListVisible: (visible: boolean) => void;
12
+ queuedMessages: Array<{
13
+ content: string;
14
+ images?: Array<{
15
+ path: string;
16
+ mimeType: string;
17
+ }>;
18
+ }>;
12
19
  sessionId: string;
13
20
  sendMessage: (content: string, images?: Array<{
14
21
  path: string;
@@ -1 +1 @@
1
- {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
@@ -22,6 +22,7 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, tools, w
22
22
  isExpandedRef.current = isExpanded;
23
23
  }, [isExpanded]);
24
24
  const [isTaskListVisible, setIsTaskListVisible] = useState(true);
25
+ const [queuedMessages, setQueuedMessages] = useState([]);
25
26
  // AI State
26
27
  const [messages, setMessages] = useState([]);
27
28
  const [isLoading, setIsLoading] = useState(false);
@@ -203,6 +204,10 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, tools, w
203
204
  const hasImageAttachments = images && images.length > 0;
204
205
  if (!hasTextContent && !hasImageAttachments)
205
206
  return;
207
+ if (isLoading || isCommandRunning) {
208
+ setQueuedMessages((prev) => [...prev, { content, images }]);
209
+ return;
210
+ }
206
211
  try {
207
212
  // Handle bash mode - check if it's a bash command (starts with ! and only one line)
208
213
  if (content.startsWith("!") && !content.includes("\n")) {
@@ -238,12 +243,22 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, tools, w
238
243
  console.error("Failed to send message:", error);
239
244
  // Loading state will be automatically updated by the useEffect that watches messages
240
245
  }
241
- }, []);
246
+ }, [isLoading, isCommandRunning]);
247
+ // Process queued messages when idle
248
+ useEffect(() => {
249
+ if (!isLoading && !isCommandRunning && queuedMessages.length > 0) {
250
+ const nextMessage = queuedMessages[0];
251
+ setQueuedMessages((prev) => prev.slice(1));
252
+ sendMessage(nextMessage.content, nextMessage.images);
253
+ }
254
+ }, [isLoading, isCommandRunning, queuedMessages, sendMessage]);
242
255
  // Unified interrupt method, interrupt both AI messages and command execution
243
256
  const abortMessage = useCallback(() => {
257
+ setQueuedMessages([]);
244
258
  agentRef.current?.abortMessage();
245
259
  }, []);
246
260
  const clearMessages = useCallback(() => {
261
+ setQueuedMessages([]);
247
262
  agentRef.current?.clearMessages();
248
263
  }, []);
249
264
  // Permission management methods
@@ -390,6 +405,7 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, tools, w
390
405
  isExpanded,
391
406
  isTaskListVisible,
392
407
  setIsTaskListVisible,
408
+ queuedMessages,
393
409
  sessionId,
394
410
  sendMessage,
395
411
  abortMessage,
@@ -48,7 +48,7 @@ export declare const useInputManager: (callbacks?: Partial<InputManagerCallbacks
48
48
  checkForSlashDeletion: (cursorPos: number) => boolean;
49
49
  handleHistorySearchSelect: (prompt: string) => void;
50
50
  handleCancelHistorySearch: () => void;
51
- handleSpecialCharInput: (char: string) => void;
51
+ processSelectorInput: (char: string) => void;
52
52
  setShowBackgroundTaskManager: (show: boolean) => void;
53
53
  setShowMcpManager: (show: boolean) => void;
54
54
  setShowRewindManager: (show: boolean) => void;
@@ -64,14 +64,14 @@ export declare const useInputManager: (callbacks?: Partial<InputManagerCallbacks
64
64
  id: number;
65
65
  path: string;
66
66
  mimeType: string;
67
- }>, isLoading?: boolean, isCommandRunning?: boolean) => Promise<void>;
67
+ }>) => Promise<void>;
68
68
  expandLongTextPlaceholders: (text: string) => string;
69
69
  clearLongTextMap: () => void;
70
70
  handleInput: (input: string, key: Key, attachedImages: Array<{
71
71
  id: number;
72
72
  path: string;
73
73
  mimeType: string;
74
- }>, isLoading?: boolean, isCommandRunning?: boolean, clearImages?: () => void) => Promise<boolean>;
74
+ }>, clearImages?: () => void) => Promise<boolean>;
75
75
  setInputText: (text: string) => void;
76
76
  setCursorPosition: (position: number) => void;
77
77
  manager: null;
@@ -1 +1 @@
1
- {"version":3,"file":"useInputManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useInputManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAGL,qBAAqB,EACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAkC,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhF,eAAO,MAAM,eAAe,GAC1B,YAAW,OAAO,CAAC,qBAAqB,CAAM;;;;;;;;;;;;;;;;;;;;+BAsIA,MAAM;;;;;qCAoBA,MAAM;iCAIV,MAAM;;;;;mCAaJ,MAAM;oCAIL,MAAM;wCAIF,MAAM;mCAIX,MAAM;;;;mCASN,MAAM;;;;;sCAgCH,MAAM;uCAIL,MAAM;wCAQL,MAAM;;mCAUX,MAAM;yCAkBA,OAAO;8BAIlB,OAAO;iCAIJ,OAAO;wBAIhB,OAAO;iCAIE,OAAO;8BAIV,cAAc;0BAKlB,MAAM,YAAY,MAAM;2BAIvB,MAAM;;;8BAYH,MAAM;mCAW/B,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,cAC1D,OAAO,qBACA,OAAO;uCAcyB,MAAM;;yBAajD,MAAM,OACR,GAAG,kBACQ,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,cAC1D,OAAO,qBACA,OAAO,gBACX,MAAM,IAAI;yBA9FY,MAAM;kCAIG,MAAM;;CA2LxD,CAAC"}
1
+ {"version":3,"file":"useInputManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useInputManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAGL,qBAAqB,EACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAkC,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhF,eAAO,MAAM,eAAe,GAC1B,YAAW,OAAO,CAAC,qBAAqB,CAAM;;;;;;;;;;;;;;;;;;;;+BAsIA,MAAM;;;;;qCAoBA,MAAM;iCAIV,MAAM;;;;;mCAaJ,MAAM;oCAIL,MAAM;wCAIF,MAAM;mCAIX,MAAM;;;;mCASN,MAAM;;;;;sCAkCH,MAAM;uCAIL,MAAM;wCAQL,MAAM;;iCAUb,MAAM;yCAYE,OAAO;8BAIlB,OAAO;iCAIJ,OAAO;wBAIhB,OAAO;iCAIE,OAAO;8BAIV,cAAc;0BAKlB,MAAM,YAAY,MAAM;2BAIvB,MAAM;;;8BAYH,MAAM;mCAW/B,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;uCAYnB,MAAM;;yBAajD,MAAM,OACR,GAAG,kBACQ,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,gBACvD,MAAM,IAAI;yBAxFY,MAAM;kCAIG,MAAM;;CAmLxD,CAAC"}
@@ -135,9 +135,10 @@ export const useInputManager = (callbacks = {}) => {
135
135
  const handleCommandInsert = useCallback((command) => {
136
136
  const currentState = stateRef.current;
137
137
  if (currentState.slashPosition >= 0) {
138
+ const wordEnd = handlers.getWordEnd(currentState.inputText, currentState.slashPosition);
138
139
  const beforeSlash = currentState.inputText.substring(0, currentState.slashPosition);
139
- const afterQuery = currentState.inputText.substring(currentState.cursorPosition);
140
- const newInput = beforeSlash + `/${command} ` + afterQuery;
140
+ const afterWord = currentState.inputText.substring(wordEnd);
141
+ const newInput = beforeSlash + `/${command} ` + afterWord;
141
142
  const newCursorPosition = beforeSlash.length + command.length + 2;
142
143
  dispatch({ type: "SET_INPUT_TEXT", payload: newInput });
143
144
  dispatch({ type: "SET_CURSOR_POSITION", payload: newCursorPosition });
@@ -168,8 +169,8 @@ export const useInputManager = (callbacks = {}) => {
168
169
  const handleCancelHistorySearch = useCallback(() => {
169
170
  dispatch({ type: "CANCEL_HISTORY_SEARCH" });
170
171
  }, []);
171
- const handleSpecialCharInput = useCallback((char) => {
172
- handlers.handleSpecialCharInput(stateRef.current, dispatch, char, stateRef.current.cursorPosition, stateRef.current.inputText);
172
+ const processSelectorInput = useCallback((char) => {
173
+ handlers.processSelectorInput(stateRef.current, dispatch, char);
173
174
  }, []);
174
175
  const setInputText = useCallback((text) => {
175
176
  dispatch({ type: "SET_INPUT_TEXT", payload: text });
@@ -211,8 +212,8 @@ export const useInputManager = (callbacks = {}) => {
211
212
  const handlePasteInput = useCallback((input) => {
212
213
  handlers.handlePasteInput(stateRef.current, dispatch, callbacksRef.current, input);
213
214
  }, []);
214
- const handleSubmit = useCallback(async (attachedImages, isLoading = false, isCommandRunning = false) => {
215
- await handlers.handleSubmit(stateRef.current, dispatch, callbacksRef.current, isLoading, isCommandRunning, attachedImages);
215
+ const handleSubmit = useCallback(async (attachedImages) => {
216
+ await handlers.handleSubmit(stateRef.current, dispatch, callbacksRef.current, attachedImages);
216
217
  }, []);
217
218
  const expandLongTextPlaceholders = useCallback((text) => {
218
219
  return handlers.expandLongTextPlaceholders(text, stateRef.current.longTextMap);
@@ -220,8 +221,8 @@ export const useInputManager = (callbacks = {}) => {
220
221
  const clearLongTextMap = useCallback(() => {
221
222
  dispatch({ type: "CLEAR_LONG_TEXT_MAP" });
222
223
  }, []);
223
- const handleInput = useCallback(async (input, key, attachedImages, isLoading = false, isCommandRunning = false, clearImages) => {
224
- return await handlers.handleInput(stateRef.current, dispatch, callbacksRef.current, input, key, isLoading, isCommandRunning, clearImages);
224
+ const handleInput = useCallback(async (input, key, attachedImages, clearImages) => {
225
+ return await handlers.handleInput(stateRef.current, dispatch, callbacksRef.current, input, key, clearImages);
225
226
  }, []);
226
227
  return {
227
228
  // State
@@ -267,7 +268,7 @@ export const useInputManager = (callbacks = {}) => {
267
268
  handleHistorySearchSelect,
268
269
  handleCancelHistorySearch,
269
270
  // Special handling
270
- handleSpecialCharInput,
271
+ processSelectorInput,
271
272
  // Bash/MCP Manager
272
273
  setShowBackgroundTaskManager,
273
274
  setShowMcpManager,
@@ -2,16 +2,19 @@ import { Key } from "ink";
2
2
  import { PermissionMode } from "wave-agent-sdk";
3
3
  import { InputState, InputAction, InputManagerCallbacks } from "./inputReducer.js";
4
4
  export declare const expandLongTextPlaceholders: (text: string, longTextMap: Record<string, string>) => string;
5
- export declare const handleSubmit: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, isLoading?: boolean, isCommandRunning?: boolean, attachedImagesOverride?: Array<{
5
+ export declare const handleSubmit: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, attachedImagesOverride?: Array<{
6
6
  id: number;
7
7
  path: string;
8
8
  mimeType: string;
9
9
  }>) => Promise<void>;
10
10
  export declare const handlePasteImage: (dispatch: React.Dispatch<InputAction>) => Promise<boolean>;
11
11
  export declare const cyclePermissionMode: (currentMode: PermissionMode, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>) => void;
12
+ export declare const getAtSelectorPosition: (text: string, cursorPosition: number) => number;
13
+ export declare const getSlashSelectorPosition: (text: string, cursorPosition: number) => number;
12
14
  export declare const updateSearchQueriesForActiveSelectors: (state: InputState, dispatch: React.Dispatch<InputAction>, inputText: string, cursorPosition: number) => void;
13
- export declare const handleSpecialCharInput: (state: InputState, dispatch: React.Dispatch<InputAction>, char: string, cursorPosition: number, inputText: string) => void;
15
+ export declare const processSelectorInput: (state: InputState, dispatch: React.Dispatch<InputAction>, char: string) => void;
14
16
  export declare const handlePasteInput: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, input: string) => void;
17
+ export declare const getWordEnd: (text: string, startPos: number) => number;
15
18
  export declare const handleCommandSelect: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, command: string) => {
16
19
  newInput: string;
17
20
  newCursorPosition: number;
@@ -23,6 +26,6 @@ export declare const handleFileSelect: (state: InputState, dispatch: React.Dispa
23
26
  export declare const checkForAtDeletion: (state: InputState, dispatch: React.Dispatch<InputAction>, cursorPosition: number) => boolean;
24
27
  export declare const checkForSlashDeletion: (state: InputState, dispatch: React.Dispatch<InputAction>, cursorPosition: number) => boolean;
25
28
  export declare const handleSelectorInput: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, input: string, key: Key) => boolean;
26
- export declare const handleNormalInput: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, input: string, key: Key, isLoading?: boolean, isCommandRunning?: boolean, clearImages?: () => void) => Promise<boolean>;
27
- export declare const handleInput: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, input: string, key: Key, isLoading?: boolean, isCommandRunning?: boolean, clearImages?: () => void) => Promise<boolean>;
29
+ export declare const handleNormalInput: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, input: string, key: Key, clearImages?: () => void) => Promise<boolean>;
30
+ export declare const handleInput: (state: InputState, dispatch: React.Dispatch<InputAction>, callbacks: Partial<InputManagerCallbacks>, input: string, key: Key, clearImages?: () => void) => Promise<boolean>;
28
31
  //# sourceMappingURL=inputHandlers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inputHandlers.d.ts","sourceRoot":"","sources":["../../src/managers/inputHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAwB,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EACL,UAAU,EACV,WAAW,EACX,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,eAAO,MAAM,0BAA0B,GACrC,MAAM,MAAM,EACZ,aAAa,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAClC,MAcF,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,YAAW,OAAe,EAC1B,mBAAkB,OAAe,EACjC,yBAAyB,KAAK,CAAC;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,KACD,OAAO,CAAC,IAAI,CAmCd,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,KACpC,OAAO,CAAC,OAAO,CAiBjB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,aAAa,cAAc,EAC3B,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,SAc1C,CAAC;AAEF,eAAO,MAAM,qCAAqC,GAChD,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,MAAM,EACjB,gBAAgB,MAAM,KACrB,IAYF,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,MAAM,MAAM,EACZ,gBAAgB,MAAM,EACtB,WAAW,MAAM,KAChB,IAgBF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,KACZ,IAuCF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,SAAS,MAAM;;;CAgDhB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,UAAU,MAAM;;;CAkBjB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,gBAAgB,MAAM,KACrB,OAMF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,gBAAgB,MAAM,KACrB,OAMF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,EACb,KAAK,GAAG,KACP,OAgEF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,EACb,KAAK,GAAG,EACR,YAAW,OAAe,EAC1B,mBAAkB,OAAe,EACjC,cAAc,MAAM,IAAI,KACvB,OAAO,CAAC,OAAO,CA0EjB,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,EACb,KAAK,GAAG,EACR,YAAW,OAAe,EAC1B,mBAAkB,OAAe,EACjC,cAAc,MAAM,IAAI,KACvB,OAAO,CAAC,OAAO,CAsFjB,CAAC"}
1
+ {"version":3,"file":"inputHandlers.d.ts","sourceRoot":"","sources":["../../src/managers/inputHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAwB,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EACL,UAAU,EACV,WAAW,EACX,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,eAAO,MAAM,0BAA0B,GACrC,MAAM,MAAM,EACZ,aAAa,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAClC,MAcF,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,yBAAyB,KAAK,CAAC;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,KACD,OAAO,CAAC,IAAI,CA+Bd,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,KACpC,OAAO,CAAC,OAAO,CAiBjB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,aAAa,cAAc,EAC3B,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,SAc1C,CAAC;AAgCF,eAAO,MAAM,qBAAqB,GAChC,MAAM,MAAM,EACZ,gBAAgB,MAAM,KACrB,MAaF,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,MAAM,MAAM,EACZ,gBAAgB,MAAM,KACrB,MAaF,CAAC;AAEF,eAAO,MAAM,qCAAqC,GAChD,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,MAAM,EACjB,gBAAgB,MAAM,KACrB,IAYF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,MAAM,MAAM,KACX,IAkDF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,KACZ,IA2BF,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,EAAE,UAAU,MAAM,KAAG,MAM3D,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,SAAS,MAAM;;;CAiDhB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,UAAU,MAAM;;;CAmBjB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,gBAAgB,MAAM,KACrB,OAMF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,gBAAgB,MAAM,KACrB,OAMF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,EACb,KAAK,GAAG,KACP,OAwEF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,EACb,KAAK,GAAG,EACR,cAAc,MAAM,IAAI,KACvB,OAAO,CAAC,OAAO,CA4HjB,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,EACb,KAAK,GAAG,EACR,cAAc,MAAM,IAAI,KACvB,OAAO,CAAC,OAAO,CAmFjB,CAAC"}