dexto 1.5.3 → 1.5.5

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 (93) hide show
  1. package/README.md +371 -408
  2. package/dist/agents/coding-agent/coding-agent.yml +30 -0
  3. package/dist/cli/cli-subscriber.d.ts +3 -1
  4. package/dist/cli/cli-subscriber.d.ts.map +1 -1
  5. package/dist/cli/cli-subscriber.js +23 -1
  6. package/dist/cli/commands/interactive-commands/commands.d.ts.map +1 -1
  7. package/dist/cli/commands/interactive-commands/commands.js +2 -1
  8. package/dist/cli/commands/interactive-commands/general-commands.d.ts.map +1 -1
  9. package/dist/cli/commands/interactive-commands/general-commands.js +184 -6
  10. package/dist/cli/commands/interactive-commands/session/index.d.ts +2 -1
  11. package/dist/cli/commands/interactive-commands/session/index.d.ts.map +1 -1
  12. package/dist/cli/commands/interactive-commands/session/index.js +2 -1
  13. package/dist/cli/commands/interactive-commands/session/session-commands.d.ts +7 -0
  14. package/dist/cli/commands/interactive-commands/session/session-commands.d.ts.map +1 -1
  15. package/dist/cli/commands/interactive-commands/session/session-commands.js +16 -0
  16. package/dist/cli/commands/setup.js +12 -12
  17. package/dist/cli/ink-cli/InkCLIRefactored.d.ts +3 -1
  18. package/dist/cli/ink-cli/InkCLIRefactored.d.ts.map +1 -1
  19. package/dist/cli/ink-cli/InkCLIRefactored.js +36 -7
  20. package/dist/cli/ink-cli/components/Footer.d.ts +4 -1
  21. package/dist/cli/ink-cli/components/Footer.d.ts.map +1 -1
  22. package/dist/cli/ink-cli/components/Footer.js +62 -18
  23. package/dist/cli/ink-cli/components/StatusBar.d.ts +2 -1
  24. package/dist/cli/ink-cli/components/StatusBar.d.ts.map +1 -1
  25. package/dist/cli/ink-cli/components/StatusBar.js +12 -3
  26. package/dist/cli/ink-cli/components/TodoPanel.d.ts +23 -0
  27. package/dist/cli/ink-cli/components/TodoPanel.d.ts.map +1 -0
  28. package/dist/cli/ink-cli/components/TodoPanel.js +60 -0
  29. package/dist/cli/ink-cli/components/chat/MessageItem.d.ts.map +1 -1
  30. package/dist/cli/ink-cli/components/chat/MessageItem.js +14 -3
  31. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts.map +1 -1
  32. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.js +3 -2
  33. package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts.map +1 -1
  34. package/dist/cli/ink-cli/components/modes/StaticCLI.js +3 -2
  35. package/dist/cli/ink-cli/components/overlays/ContextStatsOverlay.d.ts +26 -0
  36. package/dist/cli/ink-cli/components/overlays/ContextStatsOverlay.d.ts.map +1 -0
  37. package/dist/cli/ink-cli/components/overlays/ContextStatsOverlay.js +241 -0
  38. package/dist/cli/ink-cli/components/overlays/SessionRenameOverlay.d.ts +21 -0
  39. package/dist/cli/ink-cli/components/overlays/SessionRenameOverlay.d.ts.map +1 -0
  40. package/dist/cli/ink-cli/components/overlays/SessionRenameOverlay.js +63 -0
  41. package/dist/cli/ink-cli/components/overlays/SessionSelectorRefactored.js +2 -2
  42. package/dist/cli/ink-cli/components/shared/MarkdownText.d.ts.map +1 -1
  43. package/dist/cli/ink-cli/components/shared/MarkdownText.js +30 -3
  44. package/dist/cli/ink-cli/constants/processingPhrases.d.ts.map +1 -1
  45. package/dist/cli/ink-cli/constants/processingPhrases.js +21 -3
  46. package/dist/cli/ink-cli/constants/tips.d.ts.map +1 -1
  47. package/dist/cli/ink-cli/constants/tips.js +2 -0
  48. package/dist/cli/ink-cli/containers/InputContainer.d.ts +3 -1
  49. package/dist/cli/ink-cli/containers/InputContainer.d.ts.map +1 -1
  50. package/dist/cli/ink-cli/containers/InputContainer.js +11 -1
  51. package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
  52. package/dist/cli/ink-cli/containers/OverlayContainer.js +53 -2
  53. package/dist/cli/ink-cli/contexts/SoundContext.d.ts +23 -0
  54. package/dist/cli/ink-cli/contexts/SoundContext.d.ts.map +1 -0
  55. package/dist/cli/ink-cli/contexts/SoundContext.js +22 -0
  56. package/dist/cli/ink-cli/contexts/index.d.ts +1 -0
  57. package/dist/cli/ink-cli/contexts/index.d.ts.map +1 -1
  58. package/dist/cli/ink-cli/contexts/index.js +1 -0
  59. package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts +8 -2
  60. package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts.map +1 -1
  61. package/dist/cli/ink-cli/hooks/useAgentEvents.js +69 -3
  62. package/dist/cli/ink-cli/hooks/useCLIState.d.ts +4 -2
  63. package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -1
  64. package/dist/cli/ink-cli/hooks/useCLIState.js +11 -0
  65. package/dist/cli/ink-cli/services/processStream.d.ts +6 -0
  66. package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -1
  67. package/dist/cli/ink-cli/services/processStream.js +47 -2
  68. package/dist/cli/ink-cli/state/initialState.d.ts.map +1 -1
  69. package/dist/cli/ink-cli/state/initialState.js +1 -0
  70. package/dist/cli/ink-cli/state/types.d.ts +25 -1
  71. package/dist/cli/ink-cli/state/types.d.ts.map +1 -1
  72. package/dist/cli/ink-cli/utils/commandOverlays.d.ts.map +1 -1
  73. package/dist/cli/ink-cli/utils/commandOverlays.js +4 -0
  74. package/dist/cli/ink-cli/utils/index.d.ts +1 -0
  75. package/dist/cli/ink-cli/utils/index.d.ts.map +1 -1
  76. package/dist/cli/ink-cli/utils/index.js +2 -0
  77. package/dist/cli/ink-cli/utils/messageFormatting.d.ts.map +1 -1
  78. package/dist/cli/ink-cli/utils/messageFormatting.js +3 -2
  79. package/dist/cli/ink-cli/utils/soundNotification.d.ts +71 -0
  80. package/dist/cli/ink-cli/utils/soundNotification.d.ts.map +1 -0
  81. package/dist/cli/ink-cli/utils/soundNotification.js +203 -0
  82. package/dist/cli/utils/options.d.ts.map +1 -1
  83. package/dist/cli/utils/options.js +10 -2
  84. package/dist/config/cli-overrides.d.ts +2 -0
  85. package/dist/config/cli-overrides.d.ts.map +1 -1
  86. package/dist/config/cli-overrides.js +9 -0
  87. package/dist/index.js +12 -6
  88. package/dist/webui/assets/index-BglIVTSG.css +1 -0
  89. package/dist/webui/assets/index-DVQWNLpT.js +2059 -0
  90. package/dist/webui/index.html +2 -2
  91. package/package.json +10 -8
  92. package/dist/webui/assets/index-CUVc7IDL.css +0 -1
  93. package/dist/webui/assets/index-SGm5dxhp.js +0 -2054
@@ -0,0 +1,241 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * ContextStatsOverlay Component
4
+ * Interactive overlay for viewing context window usage statistics
5
+ * Features:
6
+ * - Stacked colored progress bar showing breakdown
7
+ * - Navigate with arrow keys to highlight items
8
+ * - Press Enter to expand/collapse sections (e.g., Tools)
9
+ */
10
+ import { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
11
+ import { Box, Text } from 'ink';
12
+ const BREAKDOWN_ITEMS = [
13
+ 'systemPrompt',
14
+ 'tools',
15
+ 'messages',
16
+ 'freeSpace',
17
+ 'autoCompactBuffer',
18
+ ];
19
+ // Colors for each breakdown category
20
+ const ITEM_COLORS = {
21
+ systemPrompt: 'cyan',
22
+ tools: 'yellow',
23
+ messages: 'blue',
24
+ freeSpace: 'gray',
25
+ autoCompactBuffer: 'magenta',
26
+ };
27
+ /**
28
+ * Format token count for display (e.g., 1500 -> "1.5k")
29
+ */
30
+ function formatTokens(tokens) {
31
+ if (tokens >= 1000) {
32
+ return `${(tokens / 1000).toFixed(1)}k`;
33
+ }
34
+ return tokens.toLocaleString();
35
+ }
36
+ function createStackedBar(breakdown, maxContextTokens, thresholdPercent, totalWidth = 40) {
37
+ const segments = [];
38
+ // Calculate auto compact buffer (the reserved margin for early compaction)
39
+ // maxContextTokens already has thresholdPercent applied, so derive buffer as:
40
+ // buffer = maxContextTokens * (1 - thresholdPercent) / thresholdPercent
41
+ const autoCompactBuffer = thresholdPercent > 0 && thresholdPercent < 1.0
42
+ ? Math.floor((maxContextTokens * (1 - thresholdPercent)) / thresholdPercent)
43
+ : 0;
44
+ // Total space = effective limit + buffer
45
+ const totalTokenSpace = maxContextTokens + autoCompactBuffer;
46
+ // Calculate widths for each segment (proportional to token count)
47
+ const usedTokens = breakdown.systemPrompt + breakdown.tools.total + breakdown.messages;
48
+ const freeTokens = Math.max(0, maxContextTokens - usedTokens);
49
+ // Helper to calculate width (minimum 1 char if tokens > 0, proportional otherwise)
50
+ const getWidth = (tokens) => {
51
+ if (tokens <= 0)
52
+ return 0;
53
+ const proportional = Math.round((tokens / totalTokenSpace) * totalWidth);
54
+ return Math.max(1, proportional);
55
+ };
56
+ // Add used segments
57
+ const sysWidth = getWidth(breakdown.systemPrompt);
58
+ const toolsWidth = getWidth(breakdown.tools.total);
59
+ const msgsWidth = getWidth(breakdown.messages);
60
+ const freeWidth = getWidth(freeTokens);
61
+ const reservedWidth = getWidth(autoCompactBuffer);
62
+ // Adjust to fit total width (take from free space)
63
+ const totalUsed = sysWidth + toolsWidth + msgsWidth + freeWidth + reservedWidth;
64
+ const adjustment = totalUsed - totalWidth;
65
+ // Apply adjustment to free space (it's the most flexible)
66
+ const adjustedFreeWidth = Math.max(0, freeWidth - adjustment);
67
+ if (sysWidth > 0) {
68
+ segments.push({
69
+ char: '█',
70
+ color: ITEM_COLORS.systemPrompt,
71
+ width: sysWidth,
72
+ item: 'systemPrompt',
73
+ });
74
+ }
75
+ if (toolsWidth > 0) {
76
+ segments.push({ char: '█', color: ITEM_COLORS.tools, width: toolsWidth, item: 'tools' });
77
+ }
78
+ if (msgsWidth > 0) {
79
+ segments.push({
80
+ char: '█',
81
+ color: ITEM_COLORS.messages,
82
+ width: msgsWidth,
83
+ item: 'messages',
84
+ });
85
+ }
86
+ if (adjustedFreeWidth > 0) {
87
+ segments.push({ char: '░', color: 'gray', width: adjustedFreeWidth, item: 'freeSpace' });
88
+ }
89
+ if (reservedWidth > 0) {
90
+ segments.push({
91
+ char: '▒',
92
+ color: ITEM_COLORS.autoCompactBuffer,
93
+ width: reservedWidth,
94
+ item: 'autoCompactBuffer',
95
+ });
96
+ }
97
+ return segments;
98
+ }
99
+ /**
100
+ * Context stats overlay with selectable breakdown items
101
+ */
102
+ const ContextStatsOverlay = forwardRef(function ContextStatsOverlay({ isVisible, onClose, agent, sessionId }, ref) {
103
+ const [stats, setStats] = useState(null);
104
+ const [isLoading, setIsLoading] = useState(false);
105
+ const [error, setError] = useState(null);
106
+ const [selectedIndex, setSelectedIndex] = useState(0);
107
+ const [expandedSections, setExpandedSections] = useState(new Set());
108
+ // Fetch stats when overlay becomes visible
109
+ useEffect(() => {
110
+ if (!isVisible) {
111
+ setStats(null);
112
+ setError(null);
113
+ setSelectedIndex(0);
114
+ setExpandedSections(new Set());
115
+ return;
116
+ }
117
+ let cancelled = false;
118
+ setIsLoading(true);
119
+ const fetchStats = async () => {
120
+ try {
121
+ const contextStats = await agent.getContextStats(sessionId);
122
+ if (!cancelled) {
123
+ setStats(contextStats);
124
+ setIsLoading(false);
125
+ }
126
+ }
127
+ catch (err) {
128
+ if (!cancelled) {
129
+ setError(err instanceof Error ? err.message : String(err));
130
+ setIsLoading(false);
131
+ }
132
+ }
133
+ };
134
+ fetchStats();
135
+ return () => {
136
+ cancelled = true;
137
+ };
138
+ }, [isVisible, agent, sessionId]);
139
+ // Handle keyboard input
140
+ useImperativeHandle(ref, () => ({
141
+ handleInput: (_input, key) => {
142
+ if (!isVisible)
143
+ return false;
144
+ // Escape or 'q' to close
145
+ if (key.escape || _input === 'q') {
146
+ onClose();
147
+ return true;
148
+ }
149
+ // Arrow keys for navigation
150
+ if (key.upArrow) {
151
+ setSelectedIndex((prev) => Math.max(0, prev - 1));
152
+ return true;
153
+ }
154
+ if (key.downArrow) {
155
+ setSelectedIndex((prev) => Math.min(BREAKDOWN_ITEMS.length - 1, prev + 1));
156
+ return true;
157
+ }
158
+ // Enter to expand/collapse
159
+ if (key.return) {
160
+ const item = BREAKDOWN_ITEMS[selectedIndex];
161
+ // Only tools is expandable for now
162
+ if (item === 'tools') {
163
+ setExpandedSections((prev) => {
164
+ const next = new Set(prev);
165
+ if (next.has(item)) {
166
+ next.delete(item);
167
+ }
168
+ else {
169
+ next.add(item);
170
+ }
171
+ return next;
172
+ });
173
+ return true;
174
+ }
175
+ }
176
+ return false;
177
+ },
178
+ }), [isVisible, onClose, selectedIndex]);
179
+ if (!isVisible)
180
+ return null;
181
+ // Loading state
182
+ if (isLoading) {
183
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "\uD83D\uDCCA Context Usage" }), _jsx(Text, { color: "gray", children: "Loading..." })] }));
184
+ }
185
+ // Error state
186
+ if (error) {
187
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 2, paddingY: 1, children: [_jsx(Text, { color: "red", bold: true, children: "\u274C Error" }), _jsx(Text, { color: "gray", children: error }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", dimColor: true, children: "Press Esc to close" }) })] }));
188
+ }
189
+ if (!stats)
190
+ return null;
191
+ // Calculate auto compact buffer early so it's available for pct()
192
+ // maxContextTokens already has thresholdPercent applied, so we need to derive
193
+ // the buffer as: maxContextTokens * (1 - thresholdPercent) / thresholdPercent
194
+ const autoCompactBuffer = stats.thresholdPercent > 0 && stats.thresholdPercent < 1.0
195
+ ? Math.floor((stats.maxContextTokens * (1 - stats.thresholdPercent)) /
196
+ stats.thresholdPercent)
197
+ : 0;
198
+ // Total token space = effective limit + buffer (matches the visual bar)
199
+ const totalTokenSpace = stats.maxContextTokens + autoCompactBuffer;
200
+ // Calculate percentage helper (relative to total token space for bar consistency)
201
+ const pct = (tokens) => {
202
+ const percent = totalTokenSpace > 0 ? ((tokens / totalTokenSpace) * 100).toFixed(1) : '0.0';
203
+ return `${percent}%`;
204
+ };
205
+ const usedTokens = stats.estimatedTokens + autoCompactBuffer;
206
+ const tokenDisplay = `~${formatTokens(usedTokens)}`;
207
+ const isToolsExpanded = expandedSections.has('tools');
208
+ // Create stacked bar segments
209
+ // Uses maxContextTokens (effective limit) + autoCompactBuffer as the full bar
210
+ const barSegments = createStackedBar(stats.breakdown, stats.maxContextTokens, stats.thresholdPercent);
211
+ // Helper to render a breakdown row with colored indicator
212
+ const renderRow = (index, item, label, tokens, isLast, expandable) => {
213
+ const isSelected = selectedIndex === index;
214
+ const prefix = isLast ? '└─' : '├─';
215
+ const expandIcon = expandable ? (isToolsExpanded ? '▼' : '▶') : ' ';
216
+ const itemColor = ITEM_COLORS[item];
217
+ // Use different characters for different types
218
+ const indicator = item === 'freeSpace' ? '░' : item === 'autoCompactBuffer' ? '▒' : '█';
219
+ return (_jsxs(Box, { children: [_jsxs(Text, { color: isSelected ? 'white' : 'gray', children: [prefix, " "] }), _jsx(Text, { color: itemColor, bold: isSelected, children: indicator }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', bold: isSelected, children: [' ', expandIcon, " ", label, ": ", formatTokens(tokens), " (", pct(tokens), ")"] }), isSelected && expandable && (_jsxs(Text, { color: "gray", dimColor: true, children: [' ', "(Enter to ", isToolsExpanded ? 'collapse' : 'expand', ")"] }))] }, item));
220
+ };
221
+ // Calculate free space using the actual/estimated tokens
222
+ // maxContextTokens is already the effective limit (with threshold applied)
223
+ const freeTokens = Math.max(0, stats.maxContextTokens - stats.estimatedTokens);
224
+ // Buffer percent for display (autoCompactBuffer already calculated above)
225
+ const bufferPercent = Math.round((1 - stats.thresholdPercent) * 100);
226
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "\uD83D\uDCCA Context Usage" }), _jsxs(Text, { color: "gray", children: [" - ", stats.modelDisplayName] })] }), _jsx(Box, { children: barSegments.map((segment, idx) => {
227
+ const isHighlighted = BREAKDOWN_ITEMS[selectedIndex] === segment.item;
228
+ return (_jsx(Text, { color: "white", children: isHighlighted
229
+ ? '▼'.repeat(segment.width)
230
+ : ' '.repeat(segment.width) }, idx));
231
+ }) }), _jsx(Box, { children: barSegments.map((segment, idx) => (_jsx(Text, { color: segment.color, children: segment.char.repeat(segment.width) }, idx))) }), _jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: "gray", children: [tokenDisplay, " / ", formatTokens(totalTokenSpace), " tokens"] }), _jsx(Text, { color: "gray", children: " \u2022 " }), _jsxs(Text, { color: stats.usagePercent > 80
232
+ ? 'red'
233
+ : stats.usagePercent > 60
234
+ ? 'yellow'
235
+ : 'green', children: [stats.usagePercent, "% used"] })] }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "white", children: "Breakdown:" }), renderRow(0, 'systemPrompt', 'System prompt', stats.breakdown.systemPrompt, false), renderRow(1, 'tools', `Tools (${stats.breakdown.tools.perTool.length})`, stats.breakdown.tools.total, false, true), isToolsExpanded && (_jsx(Box, { flexDirection: "column", marginLeft: 4, children: stats.breakdown.tools.perTool.length === 0 ? (_jsx(Text, { color: "gray", dimColor: true, children: "No tools registered" })) : ([...stats.breakdown.tools.perTool]
236
+ .sort((a, b) => b.tokens - a.tokens)
237
+ .map((tool, idx, arr) => (_jsxs(Text, { color: "gray", dimColor: true, children: [idx === arr.length - 1 ? '└─' : '├─', ' ', _jsx(Text, { color: "yellow", dimColor: true, children: tool.name }), ": ", formatTokens(tool.tokens), " (", pct(tool.tokens), ")"] }, tool.name)))) })), renderRow(2, 'messages', 'Messages', stats.breakdown.messages, false), renderRow(3, 'freeSpace', 'Free space', freeTokens, false), renderRow(4, 'autoCompactBuffer', bufferPercent > 0
238
+ ? `Auto compact buffer (${bufferPercent}%)`
239
+ : 'Auto compact buffer', autoCompactBuffer, true)] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: ["Messages: ", stats.filteredMessageCount, " visible (", stats.messageCount, " total)"] }), stats.prunedToolCount > 0 && (_jsxs(Text, { color: "yellow", children: ["\uD83D\uDDD1\uFE0F ", stats.prunedToolCount, " tool output(s) pruned"] })), stats.hasSummary && (_jsx(Text, { color: "blue", children: "\uD83D\uDCE6 Context has been compacted (summary present)" })), stats.usagePercent > 100 && (_jsx(Text, { color: "yellow", children: "\uD83D\uDCA1 Use /compact to manually compact, or send a message to trigger auto-compaction" }))] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", dimColor: true, children: "\u2191\u2193: navigate | Enter: expand/collapse | Esc: close" }) })] }));
240
+ });
241
+ export default ContextStatsOverlay;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * SessionRenameOverlay Component
3
+ * Interactive overlay for renaming the current session
4
+ */
5
+ import React from 'react';
6
+ import type { Key } from '../../hooks/useInputOrchestrator.js';
7
+ export interface SessionRenameOverlayProps {
8
+ isVisible: boolean;
9
+ currentTitle: string | undefined;
10
+ onRename: (newTitle: string) => void;
11
+ onClose: () => void;
12
+ }
13
+ export interface SessionRenameOverlayHandle {
14
+ handleInput: (input: string, key: Key) => boolean;
15
+ }
16
+ /**
17
+ * Session rename overlay - allows user to edit the session title
18
+ */
19
+ declare const SessionRenameOverlay: React.ForwardRefExoticComponent<SessionRenameOverlayProps & React.RefAttributes<SessionRenameOverlayHandle>>;
20
+ export default SessionRenameOverlay;
21
+ //# sourceMappingURL=SessionRenameOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionRenameOverlay.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/SessionRenameOverlay.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAA4E,MAAM,OAAO,CAAC;AAEjG,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAE/D,MAAM,WAAW,yBAAyB;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACvC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED;;GAEG;AACH,QAAA,MAAM,oBAAoB,8GAkHzB,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * SessionRenameOverlay Component
4
+ * Interactive overlay for renaming the current session
5
+ */
6
+ import { useState, useEffect, forwardRef, useImperativeHandle, useCallback } from 'react';
7
+ import { Box, Text } from 'ink';
8
+ /**
9
+ * Session rename overlay - allows user to edit the session title
10
+ */
11
+ const SessionRenameOverlay = forwardRef(function SessionRenameOverlay({ isVisible, currentTitle, onRename, onClose }, ref) {
12
+ const [title, setTitle] = useState(currentTitle || '');
13
+ const [error, setError] = useState(null);
14
+ // Reset when becoming visible
15
+ useEffect(() => {
16
+ if (isVisible) {
17
+ setTitle(currentTitle || '');
18
+ setError(null);
19
+ }
20
+ }, [isVisible, currentTitle]);
21
+ const handleSubmit = useCallback(() => {
22
+ const trimmedTitle = title.trim();
23
+ if (!trimmedTitle) {
24
+ setError('Title cannot be empty');
25
+ return;
26
+ }
27
+ onRename(trimmedTitle);
28
+ }, [title, onRename]);
29
+ // Handle keyboard input
30
+ useImperativeHandle(ref, () => ({
31
+ handleInput: (input, key) => {
32
+ if (!isVisible)
33
+ return false;
34
+ // Escape to close
35
+ if (key.escape) {
36
+ onClose();
37
+ return true;
38
+ }
39
+ // Enter to submit
40
+ if (key.return) {
41
+ handleSubmit();
42
+ return true;
43
+ }
44
+ // Backspace
45
+ if (key.backspace || key.delete) {
46
+ setTitle((prev) => prev.slice(0, -1));
47
+ setError(null);
48
+ return true;
49
+ }
50
+ // Regular character input
51
+ if (input && !key.ctrl && !key.meta) {
52
+ setTitle((prev) => prev + input);
53
+ setError(null);
54
+ return true;
55
+ }
56
+ return false;
57
+ },
58
+ }), [isVisible, onClose, handleSubmit]);
59
+ if (!isVisible)
60
+ return null;
61
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, marginTop: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Rename Session" }) }), currentTitle && (_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "gray", children: "Current: " }), _jsx(Text, { color: "white", children: currentTitle })] })), _jsx(Box, { flexDirection: "column", children: _jsx(Text, { bold: true, children: "Enter new title:" }) }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "> " }), _jsx(Text, { children: title }), _jsx(Text, { color: "cyan", children: "_" })] }), error && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "red", children: error }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "Enter to save \u2022 Esc to cancel" }) })] }));
62
+ });
63
+ export default SessionRenameOverlay;
@@ -84,12 +84,12 @@ const SessionSelector = forwardRef(function SessionSelector({ isVisible, onSelec
84
84
  // Format session for display
85
85
  const formatSession = (session) => {
86
86
  const parts = [];
87
- // Add title if available, otherwise use "Session" as fallback
87
+ // Add title if available, otherwise use "New Session" as fallback
88
88
  if (session.metadata?.title) {
89
89
  parts.push(session.metadata.title);
90
90
  }
91
91
  else {
92
- parts.push('Session');
92
+ parts.push('New Session');
93
93
  }
94
94
  // Always show short ID
95
95
  parts.push(session.id.slice(0, 8));
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownText.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/shared/MarkdownText.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAwB,MAAM,OAAO,CAAC;AAU7C,UAAU,aAAa;IACnB,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,eAAe,GAAG,MAAM,GAAG,KAAK,CAAC;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,iBAAS,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAuE1D;AAyID,UAAU,iBAAiB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAkED,QAAA,MAAM,YAAY,+CAA6B,CAAC;AAMhD,UAAU,iBAAiB;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AA4RD,eAAO,MAAM,YAAY,+CAA6B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC"}
1
+ {"version":3,"file":"MarkdownText.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/shared/MarkdownText.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAwB,MAAM,OAAO,CAAC;AAW7C,UAAU,aAAa;IACnB,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,eAAe,GAAG,MAAM,GAAG,KAAK,CAAC;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,iBAAS,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAuE1D;AAyID,UAAU,iBAAiB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAkED,QAAA,MAAM,YAAY,+CAA6B,CAAC;AAMhD,UAAU,iBAAiB;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAoTD,eAAO,MAAM,YAAY,+CAA6B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC"}
@@ -14,6 +14,7 @@ import { Text, Box, useStdout } from 'ink';
14
14
  import chalk from 'chalk';
15
15
  import wrapAnsi from 'wrap-ansi';
16
16
  import stringWidth from 'string-width';
17
+ import { highlight, supportsLanguage } from 'cli-highlight';
17
18
  /**
18
19
  * Parse inline markdown and return segments.
19
20
  * Uses a single regex to find all inline patterns, processes in order.
@@ -156,8 +157,8 @@ const WrappedParagraphInternal = ({ text, defaultColor, bulletPrefix, isFirstPar
156
157
  // Parse markdown and convert to ANSI string
157
158
  const segments = parseInlineMarkdown(text);
158
159
  const ansiString = segmentsToAnsi(segments, defaultColor);
159
- // Calculate available width
160
- const prefixWidth = bulletPrefix && isFirstParagraph ? stringWidth(bulletPrefix) : 0;
160
+ // Calculate available width - always account for bullet indent since all lines get it
161
+ const prefixWidth = bulletPrefix ? stringWidth(bulletPrefix) : 0;
161
162
  const availableWidth = Math.max(20, terminalWidth - prefixWidth);
162
163
  // Word-wrap the ANSI string
163
164
  const wrapped = wrapAnsi(ansiString, availableWidth, {
@@ -351,7 +352,33 @@ const RenderListItemInternal = ({ indent, marker, text, defaultColor, }) => {
351
352
  };
352
353
  const RenderListItem = memo(RenderListItemInternal);
353
354
  const RenderCodeBlockInternal = ({ lines, language, isPending, }) => {
354
- return (_jsxs(Box, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: [language && _jsx(Text, { color: "gray", children: language }), _jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [lines.map((line, i) => (_jsx(Text, { color: "cyan", children: line }, i))), isPending && _jsx(Text, { color: "gray", children: "..." })] })] }));
355
+ // Memoize the highlighted code to avoid re-highlighting on every render
356
+ const highlightedCode = useMemo(() => {
357
+ const code = lines.join('\n');
358
+ // If we have a language and it's supported, use syntax highlighting
359
+ if (language && supportsLanguage(language)) {
360
+ try {
361
+ return highlight(code, { language, ignoreIllegals: true });
362
+ }
363
+ catch {
364
+ // Fall back to plain cyan if highlighting fails
365
+ return chalk.cyan(code);
366
+ }
367
+ }
368
+ // If no language specified, try auto-detection
369
+ if (!language && code.trim()) {
370
+ try {
371
+ return highlight(code, { ignoreIllegals: true });
372
+ }
373
+ catch {
374
+ // Fall back to plain cyan if auto-detection fails
375
+ return chalk.cyan(code);
376
+ }
377
+ }
378
+ // Fallback: plain cyan text
379
+ return chalk.cyan(code);
380
+ }, [lines, language]);
381
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: [language && _jsx(Text, { color: "gray", children: language }), _jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsx(Text, { children: highlightedCode }), isPending && _jsx(Text, { color: "gray", children: "..." })] })] }));
355
382
  };
356
383
  const RenderCodeBlock = memo(RenderCodeBlockInternal);
357
384
  // ============================================================================
@@ -1 +1 @@
1
- {"version":3,"file":"processingPhrases.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/constants/processingPhrases.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAiErC,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAGxC"}
1
+ {"version":3,"file":"processingPhrases.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/constants/processingPhrases.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAmFrC,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAGxC"}
@@ -33,6 +33,14 @@ export const processingPhrases = [
33
33
  'Elementary, my dear Watson…',
34
34
  'Identity theft is not a joke, Jim! …',
35
35
  "I'm not superstitious, but I am a little stitious…",
36
+ 'Why waste time say lot word when few word do trick?…',
37
+ "You're a wizard, Harry…",
38
+ "I'll be back…",
39
+ 'Houston, we have a problem…',
40
+ 'Are you not entertained?…',
41
+ 'To infinity and beyond…',
42
+ 'Snakes. Why did it have to be snakes?…',
43
+ 'Hakuna matata…',
36
44
  // Playful
37
45
  'Let me cook…',
38
46
  'Manifesting greatness…',
@@ -50,17 +58,27 @@ export const processingPhrases = [
50
58
  'Zapping…',
51
59
  'Braining…',
52
60
  'Using all 3 brain cells…',
61
+ "I'm not lazy, I'm just on energy-saving mode…",
62
+ 'I came. I saw. I made it awkward…',
63
+ 'My boss told me to have a good day, so I went home…',
64
+ "I put the 'pro' in procrastination…",
65
+ 'Delulu is the solulu…',
66
+ 'Zombies eat brains. You are safe…',
53
67
  //'Installing malware (just kidding)…',
54
68
  // Vines
55
69
  'Look at all those chickens…',
56
70
  'What are those!!…',
57
71
  'He needs some milk…',
58
72
  'Something came in the mail today…',
59
- 'Road work ahead? Sure hope it does…',
73
+ 'Road work ahead? I sure hope it does…',
60
74
  'Merry Chrysler…',
61
- "I'm in me mum's car. Broom broom…",
62
- 'I could have dropped my croissant',
75
+ "I'm in me mum's car. Vroom vroom…",
76
+ 'Stop! I could have dropped my croissant!…',
63
77
  'That was legitness…',
78
+ 'Why are you running?…',
79
+ 'What da dog doin?…',
80
+ 'Can I pet that dawg?…',
81
+ 'And they were roommates!…',
64
82
  // Nerdy
65
83
  'Attention is all I need…',
66
84
  'Transformer powers activate…',
@@ -1 +1 @@
1
- {"version":3,"file":"tips.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/constants/tips.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,IAAI,EAAE,MAAM,EAyCxB,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAGrC"}
1
+ {"version":3,"file":"tips.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/constants/tips.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,IAAI,EAAE,MAAM,EA2CxB,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAGrC"}
@@ -23,6 +23,8 @@ export const tips = [
23
23
  'Use /copy to copy the previous response…',
24
24
  'Use /shortcuts to see all available shortcuts…',
25
25
  'Use /sysprompt to see the current system prompt…',
26
+ 'Use /context to see the current token usage…',
27
+ 'Use /compact to summarize the current session…',
26
28
  // Keyboard shortcut tips
27
29
  'Press Escape to cancel the current request…',
28
30
  'Press Ctrl+C twice to exit dexto…',
@@ -8,7 +8,7 @@
8
8
  import React from 'react';
9
9
  import type { DextoAgent, QueuedMessage } from '@dexto/core';
10
10
  import { InputService } from '../services/index.js';
11
- import type { Message, UIState, InputState, SessionState } from '../state/types.js';
11
+ import type { Message, UIState, InputState, SessionState, TodoItem } from '../state/types.js';
12
12
  import type { ApprovalRequest } from '../components/ApprovalPrompt.js';
13
13
  import type { TextBuffer } from '../components/shared/text-buffer.js';
14
14
  /** Handle for imperative access to InputContainer */
@@ -40,6 +40,8 @@ interface InputContainerProps {
40
40
  setApproval: React.Dispatch<React.SetStateAction<ApprovalRequest | null>>;
41
41
  /** Setter for approval queue (for queued approvals via processStream) */
42
42
  setApprovalQueue: React.Dispatch<React.SetStateAction<ApprovalRequest[]>>;
43
+ /** Setter for todo items (for todo tool updates via processStream) */
44
+ setTodos: React.Dispatch<React.SetStateAction<TodoItem[]>>;
43
45
  agent: DextoAgent;
44
46
  inputService: InputService;
45
47
  /** Optional keyboard scroll handler (for alternate buffer mode) */
@@ -1 +1 @@
1
- {"version":3,"file":"InputContainer.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/containers/InputContainer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAA0E,MAAM,OAAO,CAAC;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAoC,aAAa,EAAE,MAAM,aAAa,CAAC;AAE/F,OAAO,EAAE,YAAY,EAAiB,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EACR,OAAO,EACP,OAAO,EACP,UAAU,EACV,YAAY,EAGf,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAMtE,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACjC,yEAAyE;IACzE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED,UAAU,mBAAmB;IACzB,yCAAyC;IACzC,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,UAAU,CAAC;IAClB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,8CAA8C;IAC9C,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/D,2DAA2D;IAC3D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,mEAAmE;IACnE,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,iFAAiF;IACjF,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACnE,iCAAiC;IACjC,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACzE,8EAA8E;IAC9E,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,yEAAyE;IACzE,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1E,KAAK,EAAE,UAAU,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC;IACtD,6EAA6E;IAC7E,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,kGAqrB1B,CAAC"}
1
+ {"version":3,"file":"InputContainer.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/containers/InputContainer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAA0E,MAAM,OAAO,CAAC;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAoC,aAAa,EAAE,MAAM,aAAa,CAAC;AAE/F,OAAO,EAAE,YAAY,EAAiB,MAAM,sBAAsB,CAAC;AAEnE,OAAO,KAAK,EACR,OAAO,EACP,OAAO,EACP,UAAU,EACV,YAAY,EAGZ,QAAQ,EACX,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAMtE,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACjC,yEAAyE;IACzE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED,UAAU,mBAAmB;IACzB,yCAAyC;IACzC,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,UAAU,CAAC;IAClB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,8CAA8C;IAC9C,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/D,2DAA2D;IAC3D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,mEAAmE;IACnE,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,iFAAiF;IACjF,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACnE,iCAAiC;IACjC,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACzE,8EAA8E;IAC9E,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,yEAAyE;IACzE,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1E,sEAAsE;IACtE,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,UAAU,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC;IACtD,6EAA6E;IAC7E,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,kGAgsB1B,CAAC"}
@@ -9,6 +9,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
9
9
  import { useCallback, useRef, useEffect, useImperativeHandle, forwardRef } from 'react';
10
10
  import { InputArea } from '../components/input/InputArea.js';
11
11
  import { processStream } from '../services/index.js';
12
+ import { useSoundService } from '../contexts/index.js';
12
13
  import { createUserMessage } from '../utils/messageFormatting.js';
13
14
  import { generateMessageId } from '../utils/idGenerator.js';
14
15
  import { capture } from '../../../analytics/index.js';
@@ -16,9 +17,11 @@ import { capture } from '../../../analytics/index.js';
16
17
  * Smart container for input area
17
18
  * Manages submission, history, and overlay triggers
18
19
  */
19
- export const InputContainer = forwardRef(function InputContainer({ buffer, input, ui, session, approval, queuedMessages, setInput, setUi, setSession, setMessages, setPendingMessages, setDequeuedBuffer, setQueuedMessages, setApproval, setApprovalQueue, agent, inputService, onKeyboardScroll, useStreaming = true, }, ref) {
20
+ export const InputContainer = forwardRef(function InputContainer({ buffer, input, ui, session, approval, queuedMessages, setInput, setUi, setSession, setMessages, setPendingMessages, setDequeuedBuffer, setQueuedMessages, setApproval, setApprovalQueue, setTodos, agent, inputService, onKeyboardScroll, useStreaming = true, }, ref) {
20
21
  // Track pending session creation to prevent race conditions
21
22
  const sessionCreationPromiseRef = useRef(null);
23
+ // Sound notification service from context
24
+ const soundService = useSoundService();
22
25
  // Ref to track autoApproveEdits so processStream can read latest value mid-stream
23
26
  const autoApproveEditsRef = useRef(ui.autoApproveEdits);
24
27
  useEffect(() => {
@@ -388,6 +391,7 @@ export const InputContainer = forwardRef(function InputContainer({ buffer, input
388
391
  setPendingMessages,
389
392
  setDequeuedBuffer,
390
393
  setUi,
394
+ setSession,
391
395
  setQueuedMessages,
392
396
  setApproval,
393
397
  setApprovalQueue,
@@ -395,6 +399,8 @@ export const InputContainer = forwardRef(function InputContainer({ buffer, input
395
399
  useStreaming,
396
400
  autoApproveEditsRef,
397
401
  eventBus: agent.agentEventBus,
402
+ setTodos,
403
+ ...(soundService && { soundService }),
398
404
  });
399
405
  return; // processStream handles UI state
400
406
  }
@@ -492,6 +498,7 @@ export const InputContainer = forwardRef(function InputContainer({ buffer, input
492
498
  setPendingMessages,
493
499
  setDequeuedBuffer,
494
500
  setUi,
501
+ setSession,
495
502
  setQueuedMessages,
496
503
  setApproval,
497
504
  setApprovalQueue,
@@ -499,6 +506,8 @@ export const InputContainer = forwardRef(function InputContainer({ buffer, input
499
506
  useStreaming,
500
507
  autoApproveEditsRef,
501
508
  eventBus: agent.agentEventBus,
509
+ setTodos,
510
+ ...(soundService && { soundService }),
502
511
  });
503
512
  if (isFirstMessage) {
504
513
  agent.generateSessionTitle(currentSessionId).catch(() => {
@@ -542,6 +551,7 @@ export const InputContainer = forwardRef(function InputContainer({ buffer, input
542
551
  ui.activeOverlay,
543
552
  session.id,
544
553
  useStreaming,
554
+ soundService,
545
555
  ]);
546
556
  // Determine if input should be active (not blocked by approval/overlay/history search)
547
557
  // Input stays active for filter-type overlays (so user can keep typing to filter)
@@ -1 +1 @@
1
- {"version":3,"file":"OverlayContainer.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/containers/OverlayContainer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAyE,MAAM,OAAO,CAAC;AAE9F,OAAO,KAAK,EAAE,UAAU,EAAmD,MAAM,aAAa,CAAC;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AAE5D,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAGH,KAAK,eAAe,EACvB,MAAM,iCAAiC,CAAC;AA0EzC,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAK3D,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED,UAAU,qBAAqB;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1E,KAAK,EAAE,UAAU,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,4EAA4E;IAC5E,qBAAqB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,sGA+2D5B,CAAC"}
1
+ {"version":3,"file":"OverlayContainer.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/containers/OverlayContainer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAyE,MAAM,OAAO,CAAC;AAE9F,OAAO,KAAK,EAAE,UAAU,EAAmD,MAAM,aAAa,CAAC;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AAE5D,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAGH,KAAK,eAAe,EACvB,MAAM,iCAAiC,CAAC;AAgFzC,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAK3D,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED,UAAU,qBAAqB;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1E,KAAK,EAAE,UAAU,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,4EAA4E;IAC5E,qBAAqB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,sGAi8D5B,CAAC"}