wave-code 0.5.0 → 0.6.1

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 (95) hide show
  1. package/dist/components/App.d.ts.map +1 -1
  2. package/dist/components/App.js +38 -2
  3. package/dist/components/BackgroundTaskManager.d.ts +6 -0
  4. package/dist/components/BackgroundTaskManager.d.ts.map +1 -0
  5. package/dist/components/{TaskManager.js → BackgroundTaskManager.js} +1 -1
  6. package/dist/components/ChatInterface.d.ts.map +1 -1
  7. package/dist/components/ChatInterface.js +39 -5
  8. package/dist/components/CommandSelector.d.ts.map +1 -1
  9. package/dist/components/CommandSelector.js +10 -2
  10. package/dist/components/CompressDisplay.d.ts.map +1 -1
  11. package/dist/components/CompressDisplay.js +6 -10
  12. package/dist/components/ConfirmationDetails.d.ts +9 -0
  13. package/dist/components/ConfirmationDetails.d.ts.map +1 -0
  14. package/dist/components/ConfirmationDetails.js +53 -0
  15. package/dist/components/{Confirmation.d.ts → ConfirmationSelector.d.ts} +3 -3
  16. package/dist/components/ConfirmationSelector.d.ts.map +1 -0
  17. package/dist/components/{Confirmation.js → ConfirmationSelector.js} +34 -96
  18. package/dist/components/DiffDisplay.d.ts.map +1 -1
  19. package/dist/components/DiffDisplay.js +44 -1
  20. package/dist/components/FileSelector.d.ts.map +1 -1
  21. package/dist/components/FileSelector.js +2 -2
  22. package/dist/components/HistorySearch.d.ts.map +1 -1
  23. package/dist/components/HistorySearch.js +12 -4
  24. package/dist/components/InputBox.d.ts +1 -3
  25. package/dist/components/InputBox.d.ts.map +1 -1
  26. package/dist/components/InputBox.js +7 -17
  27. package/dist/components/LoadingIndicator.d.ts +11 -0
  28. package/dist/components/LoadingIndicator.d.ts.map +1 -0
  29. package/dist/components/LoadingIndicator.js +6 -0
  30. package/dist/components/Markdown.d.ts.map +1 -1
  31. package/dist/components/Markdown.js +114 -121
  32. package/dist/components/MessageItem.d.ts.map +1 -1
  33. package/dist/components/MessageItem.js +1 -2
  34. package/dist/components/MessageList.d.ts +2 -3
  35. package/dist/components/MessageList.d.ts.map +1 -1
  36. package/dist/components/MessageList.js +7 -7
  37. package/dist/components/PlanDisplay.d.ts.map +1 -1
  38. package/dist/components/PlanDisplay.js +4 -12
  39. package/dist/components/RewindCommand.d.ts +4 -0
  40. package/dist/components/RewindCommand.d.ts.map +1 -1
  41. package/dist/components/RewindCommand.js +19 -2
  42. package/dist/components/SubagentBlock.d.ts.map +1 -1
  43. package/dist/components/SubagentBlock.js +9 -6
  44. package/dist/components/TaskList.d.ts +3 -0
  45. package/dist/components/TaskList.d.ts.map +1 -0
  46. package/dist/components/TaskList.js +49 -0
  47. package/dist/components/ToolResultDisplay.js +1 -1
  48. package/dist/contexts/useChat.d.ts +11 -3
  49. package/dist/contexts/useChat.d.ts.map +1 -1
  50. package/dist/contexts/useChat.js +36 -31
  51. package/dist/hooks/useInputManager.d.ts +2 -13
  52. package/dist/hooks/useInputManager.d.ts.map +1 -1
  53. package/dist/hooks/useInputManager.js +8 -57
  54. package/dist/hooks/useTasks.d.ts +2 -0
  55. package/dist/hooks/useTasks.d.ts.map +1 -0
  56. package/dist/hooks/useTasks.js +5 -0
  57. package/dist/managers/InputManager.d.ts +4 -28
  58. package/dist/managers/InputManager.d.ts.map +1 -1
  59. package/dist/managers/InputManager.js +22 -128
  60. package/package.json +5 -6
  61. package/src/components/App.tsx +50 -3
  62. package/src/components/{TaskManager.tsx → BackgroundTaskManager.tsx} +4 -2
  63. package/src/components/ChatInterface.tsx +79 -23
  64. package/src/components/CommandSelector.tsx +35 -17
  65. package/src/components/CompressDisplay.tsx +5 -22
  66. package/src/components/ConfirmationDetails.tsx +108 -0
  67. package/src/components/{Confirmation.tsx → ConfirmationSelector.tsx} +69 -184
  68. package/src/components/DiffDisplay.tsx +62 -1
  69. package/src/components/FileSelector.tsx +0 -2
  70. package/src/components/HistorySearch.tsx +45 -21
  71. package/src/components/InputBox.tsx +11 -33
  72. package/src/components/LoadingIndicator.tsx +56 -0
  73. package/src/components/Markdown.tsx +126 -323
  74. package/src/components/MessageItem.tsx +1 -3
  75. package/src/components/MessageList.tsx +10 -67
  76. package/src/components/PlanDisplay.tsx +4 -27
  77. package/src/components/RewindCommand.tsx +38 -1
  78. package/src/components/SubagentBlock.tsx +25 -16
  79. package/src/components/TaskList.tsx +70 -0
  80. package/src/components/ToolResultDisplay.tsx +2 -2
  81. package/src/contexts/useChat.tsx +57 -40
  82. package/src/hooks/useInputManager.ts +9 -73
  83. package/src/hooks/useTasks.ts +6 -0
  84. package/src/managers/InputManager.ts +25 -159
  85. package/dist/components/Confirmation.d.ts.map +0 -1
  86. package/dist/components/MemoryDisplay.d.ts +0 -8
  87. package/dist/components/MemoryDisplay.d.ts.map +0 -1
  88. package/dist/components/MemoryDisplay.js +0 -25
  89. package/dist/components/MemoryTypeSelector.d.ts +0 -8
  90. package/dist/components/MemoryTypeSelector.d.ts.map +0 -1
  91. package/dist/components/MemoryTypeSelector.js +0 -38
  92. package/dist/components/TaskManager.d.ts +0 -6
  93. package/dist/components/TaskManager.d.ts.map +0 -1
  94. package/src/components/MemoryDisplay.tsx +0 -62
  95. package/src/components/MemoryTypeSelector.tsx +0 -98
@@ -1,11 +1,11 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from "react";
3
3
  import { Box, Text, Static } from "ink";
4
4
  import { MessageItem } from "./MessageItem.js";
5
- export const MessageList = React.memo(({ messages, isLoading = false, isCommandRunning = false, isCompressing = false, latestTotalTokens = 0, isExpanded = false, }) => {
5
+ export const MessageList = React.memo(({ messages, isLoading = false, isCommandRunning = false, isExpanded = false, forceStaticLastMessage = false, }) => {
6
6
  // Empty message state
7
7
  if (messages.length === 0) {
8
- return (_jsx(Box, { flexDirection: "column", paddingY: 1, children: _jsx(Text, { color: "gray", children: "Welcome to WAVE Code Assistant!" }) }));
8
+ return (_jsx(Box, { flexDirection: "column", gap: 1, children: _jsx(Box, { flexDirection: "column", paddingY: 1, children: _jsx(Text, { color: "gray", children: "Welcome to WAVE Code Assistant!" }) }) }));
9
9
  }
10
10
  // Limit messages when expanded to prevent long rendering times
11
11
  const maxExpandedMessages = 20;
@@ -17,22 +17,22 @@ export const MessageList = React.memo(({ messages, isLoading = false, isCommandR
17
17
  ? messages.length - maxExpandedMessages
18
18
  : 0;
19
19
  // Compute which messages to render statically vs dynamically
20
- const shouldRenderLastDynamic = isLoading || isCommandRunning;
20
+ const shouldRenderLastDynamic = !forceStaticLastMessage && (isLoading || isCommandRunning);
21
21
  const staticMessages = shouldRenderLastDynamic
22
22
  ? displayMessages.slice(0, -1)
23
23
  : displayMessages;
24
24
  const dynamicMessages = shouldRenderLastDynamic && displayMessages.length > 0
25
25
  ? [displayMessages[displayMessages.length - 1]]
26
26
  : [];
27
- return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [omittedCount > 0 && (_jsx(Box, { children: _jsxs(Text, { color: "gray", dimColor: true, children: ["... ", omittedCount, " earlier message", omittedCount !== 1 ? "s" : "", " ", "omitted (showing latest ", maxExpandedMessages, ")"] }) })), _jsx(Static, { items: staticMessages, children: (message, key) => {
27
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, paddingBottom: 1, children: [omittedCount > 0 && (_jsx(Box, { children: _jsxs(Text, { color: "gray", dimColor: true, children: ["... ", omittedCount, " earlier message", omittedCount !== 1 ? "s" : "", " ", "omitted (showing latest ", maxExpandedMessages, ")"] }) })), _jsx(Static, { items: staticMessages, children: (message, key) => {
28
28
  // Get previous message
29
29
  const previousMessage = key > 0 ? staticMessages[key - 1] : undefined;
30
30
  return (_jsx(MessageItem, { message: message, shouldShowHeader: previousMessage?.role !== message.role, isExpanded: isExpanded }, key));
31
31
  } }), dynamicMessages.map((message, index) => {
32
32
  const messageIndex = staticMessages.length + index;
33
33
  const previousMessage = messageIndex > 0 ? displayMessages[messageIndex - 1] : undefined;
34
- return (_jsx(Box, { marginTop: -1, children: _jsx(MessageItem, { message: message, shouldShowHeader: previousMessage?.role !== message.role, isExpanded: isExpanded }) }, `dynamic-${index}`));
35
- }), (isLoading || isCommandRunning || isCompressing) && (_jsxs(Box, { flexDirection: "column", gap: 1, children: [isLoading && (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "\uD83D\uDCAD AI is thinking... " }), _jsxs(Text, { color: "gray", dimColor: true, children: ["|", " "] }), _jsx(Text, { color: "red", bold: true, children: "Esc" }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "to abort"] })] })), isCommandRunning && (_jsx(Text, { color: "blue", children: "\uD83D\uDE80 Command is running..." })), isCompressing && (_jsx(Text, { color: "magenta", children: "\uD83D\uDDDC\uFE0F Compressing message history..." }))] })), messages.length > 0 && (_jsx(Box, { children: _jsxs(Box, { justifyContent: "space-between", width: "100%", children: [_jsx(Box, { children: _jsxs(Text, { color: "gray", children: ["Messages ", messages.length, latestTotalTokens > 0 && (_jsxs(_Fragment, { children: [_jsxs(Text, { color: "gray", dimColor: true, children: [" ", "|", " "] }), _jsx(Text, { color: "blue", bold: true, children: latestTotalTokens.toLocaleString() }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "tokens"] })] }))] }) }), _jsxs(Text, { color: "gray", dimColor: true, children: [_jsx(Text, { color: "cyan", children: "Ctrl+O" }), " Toggle", " ", isExpanded ? "Collapse" : "Expand"] })] }) }))] }));
34
+ return (_jsx(Box, { children: _jsx(MessageItem, { message: message, shouldShowHeader: previousMessage?.role !== message.role, isExpanded: isExpanded }) }, `dynamic-${index}`));
35
+ })] }));
36
36
  });
37
37
  // Add display name for debugging
38
38
  MessageList.displayName = "MessageList";
@@ -1 +1 @@
1
- {"version":3,"file":"PlanDisplay.d.ts","sourceRoot":"","sources":["../../src/components/PlanDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAIvC,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA+BlD,CAAC"}
1
+ {"version":3,"file":"PlanDisplay.d.ts","sourceRoot":"","sources":["../../src/components/PlanDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAQlD,CAAC"}
@@ -1,14 +1,6 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useMemo } from "react";
3
- import { Box, Text, useStdout } from "ink";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box } from "ink";
4
3
  import { Markdown } from "./Markdown.js";
5
- export const PlanDisplay = ({ plan, isExpanded = false, }) => {
6
- const { stdout } = useStdout();
7
- const maxHeight = useMemo(() => {
8
- // Similar to DiffDisplay.tsx maxHeight calculation
9
- return Math.max(5, (stdout?.rows || 24) - 25);
10
- }, [stdout?.rows]);
11
- const lines = useMemo(() => plan.split("\n"), [plan]);
12
- const isOverflowing = !isExpanded && lines.length > maxHeight;
13
- return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Box, { flexDirection: "column", height: isOverflowing ? maxHeight : undefined, overflow: "hidden", children: _jsx(Markdown, { children: plan }) }), isOverflowing && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "yellow", dimColor: true, children: ["... (plan truncated, ", lines.length, " lines total)"] }) }))] }));
4
+ export const PlanDisplay = ({ plan }) => {
5
+ return (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(Box, { flexDirection: "column", children: _jsx(Markdown, { children: plan }) }) }));
14
6
  };
@@ -4,6 +4,10 @@ export interface RewindCommandProps {
4
4
  messages: Message[];
5
5
  onSelect: (index: number) => void;
6
6
  onCancel: () => void;
7
+ getFullMessageThread?: () => Promise<{
8
+ messages: Message[];
9
+ sessionIds: string[];
10
+ }>;
7
11
  }
8
12
  export declare const RewindCommand: React.FC<RewindCommandProps>;
9
13
  //# sourceMappingURL=RewindCommand.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RewindCommand.d.ts","sourceRoot":"","sources":["../../src/components/RewindCommand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,gBAAgB,CAAC;AAEzD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAuGtD,CAAC"}
1
+ {"version":3,"file":"RewindCommand.d.ts","sourceRoot":"","sources":["../../src/components/RewindCommand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,gBAAgB,CAAC;AAEzD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,OAAO,CAAC;QACnC,QAAQ,EAAE,OAAO,EAAE,CAAC;QACpB,UAAU,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC,CAAC;CACJ;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAwItD,CAAC"}
@@ -1,12 +1,26 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from "react";
2
+ import React, { useState } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
- export const RewindCommand = ({ messages, onSelect, onCancel, }) => {
4
+ export const RewindCommand = ({ messages: initialMessages, onSelect, onCancel, getFullMessageThread, }) => {
5
+ const [messages, setMessages] = useState(initialMessages);
6
+ const [isLoading, setIsLoading] = useState(!!getFullMessageThread);
7
+ React.useEffect(() => {
8
+ if (getFullMessageThread) {
9
+ getFullMessageThread().then(({ messages: fullMessages }) => {
10
+ setMessages(fullMessages);
11
+ setIsLoading(false);
12
+ });
13
+ }
14
+ }, [getFullMessageThread]);
5
15
  // Filter user messages as checkpoints
6
16
  const checkpoints = messages
7
17
  .map((msg, index) => ({ msg, index }))
8
18
  .filter(({ msg }) => msg.role === "user");
9
19
  const [selectedIndex, setSelectedIndex] = useState(checkpoints.length - 1);
20
+ // Update selectedIndex when checkpoints change (after loading full thread)
21
+ React.useEffect(() => {
22
+ setSelectedIndex(checkpoints.length - 1);
23
+ }, [checkpoints.length]);
10
24
  useInput((input, key) => {
11
25
  if (key.return) {
12
26
  if (checkpoints.length > 0 && selectedIndex >= 0) {
@@ -27,6 +41,9 @@ export const RewindCommand = ({ messages, onSelect, onCancel, }) => {
27
41
  return;
28
42
  }
29
43
  });
44
+ if (isLoading) {
45
+ return (_jsx(Box, { flexDirection: "column", paddingX: 1, borderStyle: "single", borderColor: "cyan", borderLeft: false, borderRight: false, children: _jsx(Text, { color: "cyan", children: "Loading full message thread..." }) }));
46
+ }
30
47
  if (checkpoints.length === 0) {
31
48
  return (_jsxs(Box, { flexDirection: "column", paddingX: 1, borderStyle: "single", borderColor: "yellow", borderLeft: false, borderRight: false, children: [_jsx(Text, { color: "yellow", children: "No user messages found to rewind to." }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
32
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SubagentBlock.d.ts","sourceRoot":"","sources":["../../src/components/SubagentBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIzE,UAAU,kBAAkB;IAC1B,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAoItD,CAAC"}
1
+ {"version":3,"file":"SubagentBlock.d.ts","sourceRoot":"","sources":["../../src/components/SubagentBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIzE,UAAU,kBAAkB;IAC1B,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA6ItD,CAAC"}
@@ -1,15 +1,18 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
2
3
  import { Box, Text } from "ink";
3
4
  import { useChat } from "../contexts/useChat.js";
4
5
  import { Markdown } from "./Markdown.js";
5
6
  export const SubagentBlock = ({ block }) => {
6
- const { subagentMessages } = useChat();
7
+ const { subagentMessages, subagentLatestTokens } = useChat();
8
+ // Get messages for this subagent from context
9
+ const messages = useMemo(() => subagentMessages[block.subagentId] || [], [subagentMessages, block.subagentId]);
10
+ // Get latest turn tokens for this subagent
11
+ const latestTurnTokens = subagentLatestTokens[block.subagentId] || 0;
7
12
  // If the subagent is running in the background, don't show the block
8
13
  if (block.runInBackground) {
9
14
  return null;
10
15
  }
11
- // Get messages for this subagent from context
12
- const messages = subagentMessages[block.subagentId] || [];
13
16
  // Status indicator mapping
14
17
  const getStatusIndicator = (status) => {
15
18
  switch (status) {
@@ -47,7 +50,7 @@ export const SubagentBlock = ({ block }) => {
47
50
  }
48
51
  return { tools: tools.reverse(), totalToolCount }; // Reverse to show oldest first, newest last
49
52
  };
50
- const { tools: lastTwoTools, totalToolCount } = getLastTwoTools();
53
+ const { tools: lastTwoTools } = getLastTwoTools();
51
54
  // Get the last text message content if completed
52
55
  const getLastTextMessage = () => {
53
56
  if (block.status !== "completed")
@@ -66,5 +69,5 @@ export const SubagentBlock = ({ block }) => {
66
69
  return null;
67
70
  };
68
71
  const lastTextMessage = getLastTextMessage();
69
- return (_jsxs(Box, { borderRight: false, borderTop: false, borderBottom: false, borderStyle: "classic", borderColor: "magenta", paddingX: 1, paddingY: 0, flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { flexDirection: "row", gap: 1, children: _jsxs(Box, { flexDirection: "row", alignItems: "center", children: [_jsxs(Text, { color: "cyan", children: ["\uD83E\uDD16 ", block.subagentName] }), _jsxs(Text, { color: statusInfo.color, dimColor: false, children: [" ", statusInfo.icon] }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "(", messages.length, " messages)"] })] }) }), lastTextMessage && (_jsx(Box, { marginTop: 1, children: _jsx(Markdown, { children: lastTextMessage }) })), block.status !== "completed" && lastTwoTools.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, gap: 1, children: [totalToolCount > 2 && (_jsx(Text, { color: "gray", dimColor: true, children: "..." })), lastTwoTools.map((tool, index) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "magenta", children: "\uD83D\uDD27 " }), _jsx(Text, { color: "white", children: tool.name }), tool.compactParams && (_jsxs(Text, { color: "gray", children: [" ", tool.compactParams] }))] }, index)))] }))] }));
72
+ return (_jsxs(Box, { borderRight: false, borderTop: false, borderBottom: false, borderStyle: "classic", borderColor: "magenta", paddingX: 1, flexDirection: "column", children: [_jsx(Box, { flexDirection: "row", gap: 1, children: _jsxs(Box, { flexDirection: "row", alignItems: "center", children: [_jsxs(Text, { color: "cyan", children: ["\uD83E\uDD16 ", block.subagentName] }), _jsxs(Text, { color: statusInfo.color, dimColor: false, children: [" ", statusInfo.icon] }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "(", messages.length, " messages", latestTurnTokens > 0 && (_jsxs(_Fragment, { children: [" | ", _jsx(Text, { color: "blue", bold: true, children: latestTurnTokens.toLocaleString() }), " tokens"] })), ")"] })] }) }), lastTextMessage && (_jsx(Box, { children: _jsx(Markdown, { children: lastTextMessage }) })), block.status !== "completed" && lastTwoTools.length > 0 && (_jsx(Box, { flexDirection: "column", children: lastTwoTools.map((tool, index) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "magenta", children: "\uD83D\uDD27 " }), _jsx(Text, { color: "white", children: tool.name }), tool.compactParams && (_jsxs(Text, { color: "gray", children: [" ", tool.compactParams] }))] }, index))) }))] }));
70
73
  };
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ export declare const TaskList: React.FC;
3
+ //# sourceMappingURL=TaskList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskList.d.ts","sourceRoot":"","sources":["../../src/components/TaskList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAgE5B,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useChat } from "../contexts/useChat.js";
3
+ import { Box, Text, useStdout } from "ink";
4
+ import { useTasks } from "../hooks/useTasks.js";
5
+ export const TaskList = () => {
6
+ const tasks = useTasks();
7
+ const { isTaskListVisible } = useChat();
8
+ const { stdout } = useStdout();
9
+ const terminalWidth = stdout?.columns ?? 80;
10
+ const maxSubjectWidth = Math.max(20, terminalWidth - 10);
11
+ if (tasks.length === 0 || !isTaskListVisible) {
12
+ return null;
13
+ }
14
+ const getStatusIcon = (status, isBlocked) => {
15
+ if (isBlocked) {
16
+ return _jsx(Text, { color: "red", children: "\uD83D\uDD12" });
17
+ }
18
+ switch (status) {
19
+ case "pending":
20
+ return _jsx(Text, { color: "gray", children: "\u25CB" });
21
+ case "in_progress":
22
+ return _jsx(Text, { color: "yellow", children: "\u25CF" });
23
+ case "completed":
24
+ return _jsx(Text, { color: "green", children: "\u2713" });
25
+ case "deleted":
26
+ return _jsx(Text, { color: "red", children: "\u2715" });
27
+ default:
28
+ return _jsx(Text, { color: "gray", children: "?" });
29
+ }
30
+ };
31
+ const truncate = (text, maxWidth) => {
32
+ if (text.length <= maxWidth) {
33
+ return text;
34
+ }
35
+ return text.slice(0, maxWidth - 3) + "...";
36
+ };
37
+ return (_jsx(Box, { flexDirection: "column", children: tasks.map((task) => {
38
+ const isDimmed = task.status === "completed" || task.status === "deleted";
39
+ const isBlocked = task.blockedBy && task.blockedBy.length > 0;
40
+ const blockingTaskIds = isBlocked
41
+ ? task.blockedBy.map((id) => `#${id}`)
42
+ : [];
43
+ const blockedByText = isBlocked && blockingTaskIds.length > 0
44
+ ? ` (Blocked by: ${blockingTaskIds.join(", ")})`
45
+ : "";
46
+ const fullText = `${task.subject}${blockedByText}`;
47
+ return (_jsxs(Box, { gap: 1, children: [getStatusIcon(task.status, isBlocked), _jsx(Text, { dimColor: isDimmed, children: truncate(fullText, maxSubjectWidth) })] }, task.id));
48
+ }) }));
49
+ };
@@ -50,5 +50,5 @@ export const ToolResultDisplay = ({ block, isExpanded = false, }) => {
50
50
  return null;
51
51
  };
52
52
  const shortResult = getShortResult();
53
- return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: "magenta", children: "\uD83D\uDD27 " }), _jsx(Text, { color: "white", children: toolName }), !isExpanded && compactParams && (_jsxs(Text, { color: "gray", children: [" ", compactParams] })), _jsxs(Text, { color: getStatusColor(), children: [" ", getStatusText()] }), hasImages() && _jsxs(Text, { color: "blue", children: [" ", getImageIndicator()] }), isBackgroundable && _jsx(Text, { color: "gray", children: " [Ctrl-B] Background" })] }), !isExpanded && shortResult && !error && (_jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: shortResult.split("\n").map((line, index) => (_jsx(Text, { color: "white", 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 }))] }));
53
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: "magenta", children: "\uD83D\uDD27 " }), _jsx(Text, { color: "white", children: toolName }), !isExpanded && compactParams && (_jsxs(Text, { color: "gray", children: [" ", compactParams] })), _jsxs(Text, { color: getStatusColor(), children: [" ", getStatusText()] }), hasImages() && _jsxs(Text, { color: "blue", children: [" ", getImageIndicator()] }), isBackgroundable && _jsx(Text, { color: "gray", children: " [Ctrl-B] Background" })] }), !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 }))] }));
54
54
  };
@@ -1,12 +1,13 @@
1
1
  import React from "react";
2
- import type { Message, McpServerStatus, BackgroundTask, SlashCommand, PermissionDecision, PermissionMode } from "wave-agent-sdk";
2
+ import type { Message, McpServerStatus, BackgroundTask, Task, SlashCommand, PermissionDecision, PermissionMode } from "wave-agent-sdk";
3
3
  export interface ChatContextType {
4
4
  messages: Message[];
5
5
  isLoading: boolean;
6
6
  isCommandRunning: boolean;
7
7
  isCompressing: boolean;
8
- userInputHistory: string[];
9
8
  isExpanded: boolean;
9
+ isTaskListVisible: boolean;
10
+ setIsTaskListVisible: (visible: boolean) => void;
10
11
  sessionId: string;
11
12
  sendMessage: (content: string, images?: Array<{
12
13
  path: string;
@@ -14,11 +15,11 @@ export interface ChatContextType {
14
15
  }>) => Promise<void>;
15
16
  abortMessage: () => void;
16
17
  latestTotalTokens: number;
17
- saveMemory: (message: string, type: "project" | "user") => Promise<void>;
18
18
  mcpServers: McpServerStatus[];
19
19
  connectMcpServer: (serverName: string) => Promise<boolean>;
20
20
  disconnectMcpServer: (serverName: string) => Promise<boolean>;
21
21
  backgroundTasks: BackgroundTask[];
22
+ sessionTasks: Task[];
22
23
  getBackgroundTaskOutput: (taskId: string) => {
23
24
  stdout: string;
24
25
  stderr: string;
@@ -28,6 +29,7 @@ export interface ChatContextType {
28
29
  slashCommands: SlashCommand[];
29
30
  hasSlashCommand: (commandId: string) => boolean;
30
31
  subagentMessages: Record<string, Message[]>;
32
+ subagentLatestTokens: Record<string, number>;
31
33
  permissionMode: PermissionMode;
32
34
  setPermissionMode: (mode: PermissionMode) => void;
33
35
  isConfirmationVisible: boolean;
@@ -44,6 +46,12 @@ export interface ChatContextType {
44
46
  backgroundCurrentTask: () => void;
45
47
  rewindId: number;
46
48
  handleRewindSelect: (index: number) => Promise<void>;
49
+ getFullMessageThread: () => Promise<{
50
+ messages: Message[];
51
+ sessionIds: string[];
52
+ }>;
53
+ wasLastDetailsTooTall: number;
54
+ setWasLastDetailsTooTall: React.Dispatch<React.SetStateAction<number>>;
47
55
  }
48
56
  export declare const useChat: () => ChatContextType;
49
57
  export interface ChatProviderProps {
@@ -1 +1 @@
1
- {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EACf,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACf,MAAM,gBAAgB,CAAC;AAUxB,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAE3B,UAAU,EAAE,OAAO,CAAC;IAEpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,CACX,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,KAC/C,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAE1B,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,mBAAmB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9D,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,uBAAuB,EAAE,CACvB,MAAM,EAAE,MAAM,KACX;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/D,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAEhD,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAEhD,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IAE5C,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAElD,qBAAqB,EAAE,OAAO,CAAC;IAC/B,cAAc,CAAC,EAAE;QACf,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAChC,CAAC;IACF,gBAAgB,EAAE,CAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,eAAe,CAAC,EAAE,MAAM,EACxB,oBAAoB,CAAC,EAAE,OAAO,KAC3B,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,0BAA0B,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnE,wBAAwB,EAAE,MAAM,IAAI,CAAC;IAErC,qBAAqB,EAAE,MAAM,IAAI,CAAC;IAElC,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD;AAID,eAAO,MAAM,OAAO,uBAMnB,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAucpD,CAAC"}
1
+ {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
@@ -17,6 +17,7 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
17
17
  const { restoreSessionId, continueLastSession } = useAppConfig();
18
18
  // Message Display State
19
19
  const [isExpanded, setIsExpanded] = useState(false);
20
+ const [isTaskListVisible, setIsTaskListVisible] = useState(true);
20
21
  // AI State
21
22
  const [messages, setMessages] = useState([]);
22
23
  const [isLoading, setIsLoading] = useState(false);
@@ -24,15 +25,17 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
24
25
  const [sessionId, setSessionId] = useState("");
25
26
  const [isCommandRunning, setIsCommandRunning] = useState(false);
26
27
  const [isCompressing, setIsCompressing] = useState(false);
27
- const [userInputHistory, setUserInputHistory] = useState([]);
28
28
  // MCP State
29
29
  const [mcpServers, setMcpServers] = useState([]);
30
30
  // Background tasks state
31
31
  const [backgroundTasks, setBackgroundTasks] = useState([]);
32
+ // Session tasks state
33
+ const [sessionTasks, setSessionTasks] = useState([]);
32
34
  // Command state
33
35
  const [slashCommands, setSlashCommands] = useState([]);
34
36
  // Subagent messages state
35
37
  const [subagentMessages, setSubagentMessages] = useState({});
38
+ const [subagentLatestTokens, setSubagentLatestTokens] = useState({});
36
39
  // Permission state
37
40
  const [permissionMode, setPermissionModeState] = useState("default");
38
41
  // Confirmation state with queue-based architecture
@@ -42,6 +45,8 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
42
45
  const [currentConfirmation, setCurrentConfirmation] = useState(null);
43
46
  // Rewind state
44
47
  const [rewindId, setRewindId] = useState(0);
48
+ // Confirmation too tall state
49
+ const [wasLastDetailsTooTall, setWasLastDetailsTooTall] = useState(0);
45
50
  const agentRef = useRef(null);
46
51
  // Permission confirmation methods with queue support
47
52
  const showConfirmation = useCallback(async (toolName, toolInput, suggestedPrefix, hidePersistentOption) => {
@@ -69,22 +74,20 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
69
74
  setMcpServers([...servers]);
70
75
  },
71
76
  onSessionIdChange: (sessionId) => {
72
- process.stdout.write("\x1Bc", () => {
73
- setSessionId(sessionId);
74
- });
77
+ setSessionId(sessionId);
75
78
  },
76
79
  onLatestTotalTokensChange: (tokens) => {
77
80
  setlatestTotalTokens(tokens);
78
81
  },
79
- onUserInputHistoryChange: (history) => {
80
- setUserInputHistory([...history]);
81
- },
82
82
  onCompressionStateChange: (isCompressingState) => {
83
83
  setIsCompressing(isCompressingState);
84
84
  },
85
85
  onTasksChange: (tasks) => {
86
86
  setBackgroundTasks([...tasks]);
87
87
  },
88
+ onSessionTasksChange: (tasks) => {
89
+ setSessionTasks([...tasks]);
90
+ },
88
91
  onSubagentMessagesChange: (subagentId, messages) => {
89
92
  logger.debug("onSubagentMessagesChange", subagentId, messages.length);
90
93
  setSubagentMessages((prev) => ({
@@ -92,6 +95,12 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
92
95
  [subagentId]: [...messages],
93
96
  }));
94
97
  },
98
+ onSubagentLatestTotalTokensChange: (subagentId, tokens) => {
99
+ setSubagentLatestTokens((prev) => ({
100
+ ...prev,
101
+ [subagentId]: tokens,
102
+ }));
103
+ },
95
104
  onPermissionModeChange: (mode) => {
96
105
  setPermissionModeState(mode);
97
106
  },
@@ -133,7 +142,6 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
133
142
  setlatestTotalTokens(agent.latestTotalTokens);
134
143
  setIsCommandRunning(agent.isCommandRunning);
135
144
  setIsCompressing(agent.isCompressing);
136
- setUserInputHistory(agent.userInputHistory);
137
145
  setPermissionModeState(agent.getPermissionMode());
138
146
  // Get initial MCP servers state
139
147
  const mcpServers = agent.getMcpServers?.() || [];
@@ -179,15 +187,6 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
179
187
  if (!hasTextContent && !hasImageAttachments)
180
188
  return;
181
189
  try {
182
- // Handle memory mode - check if it's a memory message (starts with # and only one line)
183
- if (content.startsWith("#") && !content.includes("\n")) {
184
- const memoryText = content.substring(1).trim();
185
- if (!memoryText)
186
- return;
187
- // In memory mode, don't add user message, only wait for user to choose memory type then add assistant message
188
- // Don't auto-save, wait for user to choose memory type
189
- return;
190
- }
191
190
  // Handle bash mode - check if it's a bash command (starts with ! and only one line)
192
191
  if (content.startsWith("!") && !content.includes("\n")) {
193
192
  const command = content.substring(1).trim();
@@ -227,10 +226,6 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
227
226
  const abortMessage = useCallback(() => {
228
227
  agentRef.current?.abortMessage();
229
228
  }, []);
230
- // Memory save function - delegate to Agent
231
- const saveMemory = useCallback(async (message, type) => {
232
- await agentRef.current?.saveMemory(message, type);
233
- }, []);
234
229
  // Permission management methods
235
230
  const setPermissionMode = useCallback((mode) => {
236
231
  setPermissionModeState((prev) => {
@@ -309,26 +304,31 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
309
304
  try {
310
305
  await agentRef.current.truncateHistory(index);
311
306
  // Clear terminal screen after rewind
312
- process.stdout.write("\x1Bc", () => {
313
- setRewindId((prev) => prev + 1);
314
- });
307
+ setRewindId((prev) => prev + 1);
315
308
  }
316
309
  catch (error) {
317
310
  logger.error("Failed to rewind:", error);
318
311
  }
319
312
  }
320
313
  }, []);
314
+ const getFullMessageThread = useCallback(async () => {
315
+ if (agentRef.current) {
316
+ return await agentRef.current.getFullMessageThread();
317
+ }
318
+ return { messages: [], sessionIds: [] };
319
+ }, []);
321
320
  // Listen for Ctrl+O hotkey to toggle collapse/expand state and ESC to cancel confirmation
322
321
  useInput((input, key) => {
323
322
  if (key.ctrl && input === "o") {
324
323
  // Clear terminal screen when expanded state changes
325
- process.stdout.write("\x1Bc", () => {
326
- setIsExpanded((prev) => {
327
- const newExpanded = !prev;
328
- return newExpanded;
329
- });
324
+ setIsExpanded((prev) => {
325
+ const newExpanded = !prev;
326
+ return newExpanded;
330
327
  });
331
328
  }
329
+ if (key.ctrl && input === "t") {
330
+ setIsTaskListVisible((prev) => !prev);
331
+ }
332
332
  // Handle ESC key to cancel confirmation
333
333
  if (key.escape && isConfirmationVisible) {
334
334
  handleConfirmationCancel();
@@ -338,23 +338,25 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
338
338
  messages,
339
339
  isLoading,
340
340
  isCommandRunning,
341
- userInputHistory,
342
341
  isExpanded,
342
+ isTaskListVisible,
343
+ setIsTaskListVisible,
343
344
  sessionId,
344
345
  sendMessage,
345
346
  abortMessage,
346
347
  latestTotalTokens,
347
348
  isCompressing,
348
- saveMemory,
349
349
  mcpServers,
350
350
  connectMcpServer,
351
351
  disconnectMcpServer,
352
352
  backgroundTasks,
353
+ sessionTasks,
353
354
  getBackgroundTaskOutput,
354
355
  stopBackgroundTask,
355
356
  slashCommands,
356
357
  hasSlashCommand,
357
358
  subagentMessages,
359
+ subagentLatestTokens,
358
360
  permissionMode,
359
361
  setPermissionMode,
360
362
  isConfirmationVisible,
@@ -366,6 +368,9 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
366
368
  backgroundCurrentTask,
367
369
  rewindId,
368
370
  handleRewindSelect,
371
+ getFullMessageThread,
372
+ wasLastDetailsTooTall,
373
+ setWasLastDetailsTooTall,
369
374
  };
370
375
  return (_jsx(ChatContext.Provider, { value: contextValue, children: children }));
371
376
  };
@@ -14,9 +14,7 @@ export declare const useInputManager: (callbacks?: Partial<InputManagerCallbacks
14
14
  slashPosition: number;
15
15
  showHistorySearch: boolean;
16
16
  historySearchQuery: string;
17
- showMemoryTypeSelector: boolean;
18
- memoryMessage: string;
19
- showTaskManager: boolean;
17
+ showBackgroundTaskManager: boolean;
20
18
  showMcpManager: boolean;
21
19
  showRewindManager: boolean;
22
20
  permissionMode: PermissionMode;
@@ -51,17 +49,8 @@ export declare const useInputManager: (callbacks?: Partial<InputManagerCallbacks
51
49
  checkForSlashDeletion: (cursorPos: number) => boolean;
52
50
  handleHistorySearchSelect: (prompt: string) => void;
53
51
  handleCancelHistorySearch: () => void;
54
- activateMemoryTypeSelector: (message: string) => void;
55
- handleMemoryTypeSelect: (type: "project" | "user") => Promise<void>;
56
- handleCancelMemoryTypeSelect: () => void;
57
- setUserInputHistory: (history: string[]) => void;
58
- navigateHistory: (direction: "up" | "down", currentInput: string) => {
59
- newInput: string;
60
- newCursorPosition: number;
61
- };
62
- resetHistoryNavigation: () => void;
63
52
  handleSpecialCharInput: (char: string) => void;
64
- setShowTaskManager: (show: boolean) => void;
53
+ setShowBackgroundTaskManager: (show: boolean) => void;
65
54
  setShowMcpManager: (show: boolean) => void;
66
55
  setShowRewindManager: (show: boolean) => void;
67
56
  setPermissionMode: (mode: PermissionMode) => void;
@@ -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,EACL,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACd,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhD,eAAO,MAAM,eAAe,GAC1B,YAAW,OAAO,CAAC,qBAAqB,CAAM;;;;;;;;;;;;;;;;;;;;+BAgIpC,MAAM,aACD,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,KAAK,IAAI;oCAQrD,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,KAAK,IAAI;;;;;;qCA2Bd,MAAM;iCAK7C,MAAM;;;;;mCAe+B,MAAM;oCAIL,MAAM;wCAKF,MAAM;mCAKjD,MAAM;;;;mCAYN,MAAM;;;;;sCAemC,MAAM;uCAIL,MAAM;wCAKL,MAAM;;0CASJ,MAAM;mCAKhD,SAAS,GAAG,MAAM;;mCAWiB,MAAM,EAAE;iCAK5C,IAAI,GAAG,MAAM,gBAAgB,MAAM;;;;;mCAgBC,MAAM;+BA8Ef,OAAO;8BAGR,OAAO;iCAGJ,OAAO;8BAIV,cAAc;0BAMlB,MAAM,YAAY,MAAM;2BAGvB,MAAM;;;8BAWH,MAAM;mCAKxB,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,cAC1D,OAAO,qBACA,OAAO;uCAUkB,MAAM;;yBAU1C,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;yBAvIgB,MAAM;kCAIG,MAAM;;CA0J9D,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,EACL,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACd,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhD,eAAO,MAAM,eAAe,GAC1B,YAAW,OAAO,CAAC,qBAAqB,CAAM;;;;;;;;;;;;;;;;;;+BAiHpC,MAAM,aACD,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,KAAK,IAAI;oCAQrD,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,KAAK,IAAI;;;;;;qCA2Bd,MAAM;iCAK7C,MAAM;;;;;mCAe+B,MAAM;oCAIL,MAAM;wCAKF,MAAM;mCAKjD,MAAM;;;;mCAYN,MAAM;;;;;sCAemC,MAAM;uCAIL,MAAM;wCAKL,MAAM;;mCASX,MAAM;yCAkEL,OAAO;8BAGlB,OAAO;iCAGJ,OAAO;8BAIV,cAAc;0BAMlB,MAAM,YAAY,MAAM;2BAGvB,MAAM;;;8BAWH,MAAM;mCAKxB,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,cAC1D,OAAO,qBACA,OAAO;uCAUkB,MAAM;;yBAU1C,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;yBA3HgB,MAAM;kCAIG,MAAM;;CA8I9D,CAAC"}