wave-code 0.4.0 → 0.5.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 (50) hide show
  1. package/dist/commands/plugin/uninstall.js +1 -1
  2. package/dist/components/CommandSelector.js +3 -3
  3. package/dist/components/Confirmation.d.ts.map +1 -1
  4. package/dist/components/Confirmation.js +72 -19
  5. package/dist/components/DiffDisplay.d.ts +0 -1
  6. package/dist/components/DiffDisplay.d.ts.map +1 -1
  7. package/dist/components/DiffDisplay.js +38 -59
  8. package/dist/components/InputBox.d.ts.map +1 -1
  9. package/dist/components/InputBox.js +6 -5
  10. package/dist/components/Markdown.d.ts.map +1 -1
  11. package/dist/components/Markdown.js +4 -3
  12. package/dist/components/PlanDisplay.d.ts.map +1 -1
  13. package/dist/components/PlanDisplay.js +2 -2
  14. package/dist/components/PluginDetail.js +1 -1
  15. package/dist/components/SubagentBlock.d.ts.map +1 -1
  16. package/dist/components/SubagentBlock.js +4 -0
  17. package/dist/components/TaskManager.d.ts +6 -0
  18. package/dist/components/TaskManager.d.ts.map +1 -0
  19. package/dist/components/TaskManager.js +114 -0
  20. package/dist/components/ToolResultDisplay.d.ts.map +1 -1
  21. package/dist/components/ToolResultDisplay.js +2 -1
  22. package/dist/contexts/useChat.d.ts +5 -4
  23. package/dist/contexts/useChat.d.ts.map +1 -1
  24. package/dist/contexts/useChat.js +16 -12
  25. package/dist/hooks/useInputManager.d.ts +2 -2
  26. package/dist/hooks/useInputManager.js +10 -10
  27. package/dist/hooks/usePluginManager.d.ts.map +1 -1
  28. package/dist/hooks/usePluginManager.js +8 -4
  29. package/dist/managers/InputManager.d.ts +7 -6
  30. package/dist/managers/InputManager.d.ts.map +1 -1
  31. package/dist/managers/InputManager.js +17 -12
  32. package/package.json +6 -6
  33. package/src/commands/plugin/uninstall.ts +1 -1
  34. package/src/components/CommandSelector.tsx +3 -3
  35. package/src/components/Confirmation.tsx +114 -24
  36. package/src/components/DiffDisplay.tsx +60 -106
  37. package/src/components/InputBox.tsx +9 -7
  38. package/src/components/Markdown.tsx +10 -4
  39. package/src/components/PlanDisplay.tsx +14 -19
  40. package/src/components/PluginDetail.tsx +1 -1
  41. package/src/components/SubagentBlock.tsx +5 -0
  42. package/src/components/{BashShellManager.tsx → TaskManager.tsx} +79 -75
  43. package/src/components/ToolResultDisplay.tsx +4 -0
  44. package/src/contexts/useChat.tsx +25 -20
  45. package/src/hooks/useInputManager.ts +10 -10
  46. package/src/hooks/usePluginManager.ts +10 -4
  47. package/src/managers/InputManager.ts +22 -15
  48. package/dist/components/BashShellManager.d.ts +0 -6
  49. package/dist/components/BashShellManager.d.ts.map +0 -1
  50. package/dist/components/BashShellManager.js +0 -116
@@ -3,7 +3,7 @@ export async function uninstallPluginCommand(argv) {
3
3
  const marketplaceService = new MarketplaceService();
4
4
  const workdir = process.cwd();
5
5
  try {
6
- await marketplaceService.uninstallPlugin(argv.plugin);
6
+ await marketplaceService.uninstallPlugin(argv.plugin, workdir);
7
7
  console.log(`Successfully uninstalled plugin: ${argv.plugin}`);
8
8
  const configurationService = new ConfigurationService();
9
9
  const pluginManager = new PluginManager({ workdir });
@@ -3,9 +3,9 @@ import { useState } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
4
  const AVAILABLE_COMMANDS = [
5
5
  {
6
- id: "bashes",
7
- name: "bashes",
8
- description: "View and manage background bash shells",
6
+ id: "tasks",
7
+ name: "tasks",
8
+ description: "View and manage background tasks (shells and subagents)",
9
9
  handler: () => { }, // Handler here won't be used, actual processing is in the hook
10
10
  },
11
11
  {
@@ -1 +1 @@
1
- {"version":3,"file":"Confirmation.d.ts","sourceRoot":"","sources":["../../src/components/Confirmation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,kBAAkB,EAAwB,MAAM,gBAAgB,CAAC;AAmD/E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAQD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqapD,CAAC"}
1
+ {"version":3,"file":"Confirmation.d.ts","sourceRoot":"","sources":["../../src/components/Confirmation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,kBAAkB,EAAwB,MAAM,gBAAgB,CAAC;AAmD/E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AASD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA8fpD,CAAC"}
@@ -40,6 +40,7 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
40
40
  const [state, setState] = useState({
41
41
  selectedOption: "allow",
42
42
  alternativeText: "",
43
+ alternativeCursorPosition: 0,
43
44
  hasUserInput: false,
44
45
  });
45
46
  // Specialized state for AskUserQuestion
@@ -48,6 +49,7 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
48
49
  const [selectedOptionIndices, setSelectedOptionIndices] = useState(new Set());
49
50
  const [userAnswers, setUserAnswers] = useState({});
50
51
  const [otherText, setOtherText] = useState("");
52
+ const [otherCursorPosition, setOtherCursorPosition] = useState(0);
51
53
  const questions = toolInput?.questions || [];
52
54
  const currentQuestion = questions[currentQuestionIndex];
53
55
  const getAutoOptionText = () => {
@@ -107,6 +109,7 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
107
109
  setSelectedOptionIndex(0);
108
110
  setSelectedOptionIndices(new Set());
109
111
  setOtherText("");
112
+ setOtherCursorPosition(0);
110
113
  }
111
114
  else {
112
115
  // All questions answered
@@ -150,11 +153,34 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
150
153
  return;
151
154
  }
152
155
  if (isOtherFocused) {
156
+ if (key.leftArrow) {
157
+ setOtherCursorPosition((prev) => Math.max(0, prev - 1));
158
+ return;
159
+ }
160
+ if (key.rightArrow) {
161
+ setOtherCursorPosition((prev) => Math.min(otherText.length, prev + 1));
162
+ return;
163
+ }
153
164
  if (key.backspace || key.delete) {
154
- setOtherText((prev) => prev.slice(0, -1));
165
+ if (otherCursorPosition > 0) {
166
+ setOtherText((prev) => {
167
+ const next = prev.slice(0, otherCursorPosition - 1) +
168
+ prev.slice(otherCursorPosition);
169
+ return next;
170
+ });
171
+ setOtherCursorPosition((prev) => prev - 1);
172
+ }
173
+ return;
155
174
  }
156
- else if (input && !key.ctrl && !key.meta) {
157
- setOtherText((prev) => prev + input);
175
+ if (input && !key.ctrl && !key.meta) {
176
+ setOtherText((prev) => {
177
+ const next = prev.slice(0, otherCursorPosition) +
178
+ input +
179
+ prev.slice(otherCursorPosition);
180
+ return next;
181
+ });
182
+ setOtherCursorPosition((prev) => prev + input.length);
183
+ return;
158
184
  }
159
185
  return;
160
186
  }
@@ -198,6 +224,22 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
198
224
  }
199
225
  return;
200
226
  }
227
+ if (state.selectedOption === "alternative") {
228
+ if (key.leftArrow) {
229
+ setState((prev) => ({
230
+ ...prev,
231
+ alternativeCursorPosition: Math.max(0, prev.alternativeCursorPosition - 1),
232
+ }));
233
+ return;
234
+ }
235
+ if (key.rightArrow) {
236
+ setState((prev) => ({
237
+ ...prev,
238
+ alternativeCursorPosition: Math.min(prev.alternativeText.length, prev.alternativeCursorPosition + 1),
239
+ }));
240
+ return;
241
+ }
242
+ }
201
243
  // Handle arrow keys for navigation
202
244
  if (key.upArrow) {
203
245
  setState((prev) => {
@@ -230,30 +272,42 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
230
272
  // Handle text input for alternative option
231
273
  if (input && !key.ctrl && !key.meta && !("alt" in key && key.alt)) {
232
274
  // Focus on alternative option when user starts typing
233
- setState((prev) => ({
234
- selectedOption: "alternative",
235
- alternativeText: prev.alternativeText + input,
236
- hasUserInput: true,
237
- }));
238
- return;
239
- }
240
- // Handle backspace and delete (same behavior - delete one character)
241
- if (key.backspace || key.delete) {
242
275
  setState((prev) => {
243
- const newText = prev.alternativeText.slice(0, -1);
276
+ const nextText = prev.alternativeText.slice(0, prev.alternativeCursorPosition) +
277
+ input +
278
+ prev.alternativeText.slice(prev.alternativeCursorPosition);
244
279
  return {
245
280
  ...prev,
246
281
  selectedOption: "alternative",
247
- alternativeText: newText,
248
- hasUserInput: newText.length > 0,
282
+ alternativeText: nextText,
283
+ alternativeCursorPosition: prev.alternativeCursorPosition + input.length,
284
+ hasUserInput: true,
249
285
  };
250
286
  });
251
287
  return;
252
288
  }
289
+ // Handle backspace and delete
290
+ if (key.backspace || key.delete) {
291
+ setState((prev) => {
292
+ if (prev.alternativeCursorPosition > 0) {
293
+ const nextText = prev.alternativeText.slice(0, prev.alternativeCursorPosition - 1) +
294
+ prev.alternativeText.slice(prev.alternativeCursorPosition);
295
+ return {
296
+ ...prev,
297
+ selectedOption: "alternative",
298
+ alternativeText: nextText,
299
+ alternativeCursorPosition: prev.alternativeCursorPosition - 1,
300
+ hasUserInput: nextText.length > 0,
301
+ };
302
+ }
303
+ return prev;
304
+ });
305
+ return;
306
+ }
253
307
  });
254
308
  const placeholderText = "Type here to tell Wave what to do differently";
255
309
  const showPlaceholder = state.selectedOption === "alternative" && !state.hasUserInput;
256
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Tool: ", toolName] }), _jsx(Text, { color: "yellow", children: getActionDescription(toolName, toolInput) }), _jsx(DiffDisplay, { toolName: toolName, parameters: JSON.stringify(toolInput), isExpanded: isExpanded }), toolName === ASK_USER_QUESTION_TOOL_NAME &&
310
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Tool: ", toolName] }), _jsx(Text, { color: "yellow", children: getActionDescription(toolName, toolInput) }), _jsx(DiffDisplay, { toolName: toolName, parameters: JSON.stringify(toolInput) }), toolName === ASK_USER_QUESTION_TOOL_NAME &&
257
311
  currentQuestion &&
258
312
  !isExpanded && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Box, { backgroundColor: getHeaderColor(currentQuestion.header), paddingX: 1, marginRight: 1, children: _jsx(Text, { color: "black", bold: true, children: currentQuestion.header.slice(0, 12).toUpperCase() }) }), _jsx(Text, { bold: true, children: currentQuestion.question })] }), _jsx(Box, { flexDirection: "column", children: (() => {
259
313
  const isMultiSelect = !!currentQuestion.multiSelect;
@@ -264,12 +318,11 @@ export const Confirmation = ({ toolName, toolInput, suggestedPrefix, hidePersist
264
318
  : isSelected;
265
319
  const isOther = index === currentQuestion.options.length;
266
320
  const isRecommended = !isOther && option.isRecommended;
267
- return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "yellow" : undefined, children: [isSelected ? "> " : " ", isMultiSelect ? (isChecked ? "[x] " : "[ ] ") : "", option.label, isRecommended && (_jsxs(Text, { color: "green", bold: true, children: [" ", "(Recommended)"] })), option.description ? ` - ${option.description}` : "", isOther && isSelected && (_jsxs(Text, { children: [":", " ", otherText || (_jsx(Text, { color: "gray", dimColor: true, children: "[Type your answer...]" }))] }))] }) }, index));
321
+ return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "yellow" : undefined, children: [isSelected ? "> " : " ", isMultiSelect ? (isChecked ? "[x] " : "[ ] ") : "", option.label, isRecommended && (_jsxs(Text, { color: "green", bold: true, children: [" ", "(Recommended)"] })), option.description ? ` - ${option.description}` : "", isOther && isSelected && (_jsxs(Text, { children: [":", " ", otherText ? (_jsxs(_Fragment, { children: [otherText.slice(0, otherCursorPosition), _jsx(Text, { backgroundColor: "white", color: "black", children: otherText[otherCursorPosition] || " " }), otherText.slice(otherCursorPosition + 1)] })) : (_jsx(Text, { color: "gray", dimColor: true, children: "[Type your answer...]" }))] }))] }) }, index));
268
322
  });
269
323
  })() }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Question ", currentQuestionIndex + 1, " of ", questions.length, " \u2022", currentQuestion.multiSelect ? " Space to toggle •" : "", " Use \u2191\u2193 to navigate \u2022 Enter to confirm"] }) })] })), toolName !== ASK_USER_QUESTION_TOOL_NAME &&
270
324
  toolName === EXIT_PLAN_MODE_TOOL_NAME &&
271
325
  !!toolInput?.plan_content && (_jsx(PlanDisplay, { plan: toolInput.plan_content, isExpanded: isExpanded })), toolName !== ASK_USER_QUESTION_TOOL_NAME && !isExpanded && (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Do you want to proceed?" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "allow" ? "black" : "white", backgroundColor: state.selectedOption === "allow" ? "yellow" : undefined, bold: state.selectedOption === "allow", children: [state.selectedOption === "allow" ? "> " : " ", toolName === EXIT_PLAN_MODE_TOOL_NAME
272
326
  ? "Yes, proceed with default mode"
273
- : "Yes"] }) }, "allow-option"), !hidePersistentOption && (_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "auto" ? "black" : "white", backgroundColor: state.selectedOption === "auto" ? "yellow" : undefined, bold: state.selectedOption === "auto", children: [state.selectedOption === "auto" ? "> " : " ", getAutoOptionText()] }) }, "auto-option")), _jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "alternative" ? "black" : "white", backgroundColor: state.selectedOption === "alternative" ? "yellow" : undefined, bold: state.selectedOption === "alternative", children: [state.selectedOption === "alternative" ? "> " : " ", showPlaceholder ? (_jsx(Text, { color: "gray", dimColor: true, children: placeholderText })) : (_jsx(Text, { children: state.alternativeText ||
274
- "Type here to tell Wave what to do differently" }))] }) }, "alternative-option")] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate \u2022 ESC to cancel" }) })] }))] }));
327
+ : "Yes"] }) }, "allow-option"), !hidePersistentOption && (_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "auto" ? "black" : "white", backgroundColor: state.selectedOption === "auto" ? "yellow" : undefined, bold: state.selectedOption === "auto", children: [state.selectedOption === "auto" ? "> " : " ", getAutoOptionText()] }) }, "auto-option")), _jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "alternative" ? "black" : "white", backgroundColor: state.selectedOption === "alternative" ? "yellow" : undefined, bold: state.selectedOption === "alternative", children: [state.selectedOption === "alternative" ? "> " : " ", showPlaceholder ? (_jsx(Text, { color: "gray", dimColor: true, children: placeholderText })) : (_jsx(Text, { children: state.alternativeText ? (_jsxs(_Fragment, { children: [state.alternativeText.slice(0, state.alternativeCursorPosition), _jsx(Text, { backgroundColor: "white", color: "black", children: state.alternativeText[state.alternativeCursorPosition] || " " }), state.alternativeText.slice(state.alternativeCursorPosition + 1)] })) : ("Type here to tell Wave what to do differently") }))] }) }, "alternative-option")] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate \u2022 ESC to cancel" }) })] }))] }));
275
328
  };
@@ -2,7 +2,6 @@ import React from "react";
2
2
  interface DiffDisplayProps {
3
3
  toolName?: string;
4
4
  parameters?: string;
5
- isExpanded?: boolean;
6
5
  }
7
6
  export declare const DiffDisplay: React.FC<DiffDisplayProps>;
8
7
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"DiffDisplay.d.ts","sourceRoot":"","sources":["../../src/components/DiffDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAUvC,UAAU,gBAAgB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA6SlD,CAAC"}
1
+ {"version":3,"file":"DiffDisplay.d.ts","sourceRoot":"","sources":["../../src/components/DiffDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAUvC,UAAU,gBAAgB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA4OlD,CAAC"}
@@ -1,14 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React, { useMemo } from "react";
3
- import { Box, Text, useStdout } from "ink";
3
+ import { Box, Text } from "ink";
4
4
  import { WRITE_TOOL_NAME, EDIT_TOOL_NAME, MULTI_EDIT_TOOL_NAME, } from "wave-agent-sdk";
5
5
  import { transformToolBlockToChanges } from "../utils/toolParameterTransforms.js";
6
6
  import { diffLines, diffWords } from "diff";
7
- export const DiffDisplay = ({ toolName, parameters, isExpanded = false, }) => {
8
- const { stdout } = useStdout();
9
- const maxHeight = useMemo(() => {
10
- return Math.max(5, (stdout?.rows || 24) - 20);
11
- }, [stdout?.rows]);
7
+ export const DiffDisplay = ({ toolName, parameters, }) => {
12
8
  const showDiff = toolName &&
13
9
  [WRITE_TOOL_NAME, EDIT_TOOL_NAME, MULTI_EDIT_TOOL_NAME].includes(toolName);
14
10
  // Diff detection and transformation using typed parameters
@@ -58,7 +54,7 @@ export const DiffDisplay = ({ toolName, parameters, isExpanded = false, }) => {
58
54
  };
59
55
  }
60
56
  };
61
- // Render expanded diff display using word-level diff for all changes
57
+ // Render expanded diff display
62
58
  const renderExpandedDiff = () => {
63
59
  try {
64
60
  if (changes.length === 0)
@@ -68,8 +64,8 @@ export const DiffDisplay = ({ toolName, parameters, isExpanded = false, }) => {
68
64
  try {
69
65
  // Get line-level diff to understand the structure
70
66
  const lineDiffs = diffLines(change.oldContent || "", change.newContent || "");
67
+ // Process line diffs
71
68
  const diffElements = [];
72
- // Process line diffs and apply word-level diff to changed lines
73
69
  lineDiffs.forEach((part, partIndex) => {
74
70
  if (part.added) {
75
71
  const lines = part.value
@@ -97,41 +93,28 @@ export const DiffDisplay = ({ toolName, parameters, isExpanded = false, }) => {
97
93
  });
98
94
  }
99
95
  });
100
- // Now look for pairs of removed/added lines that can be word-diffed
101
- let i = 0;
102
- while (i < diffElements.length) {
103
- const current = diffElements[i];
104
- const next = i + 1 < diffElements.length ? diffElements[i + 1] : null;
105
- // Check if we have a removed line followed by an added line
106
- const currentKey = React.isValidElement(current) ? current.key : "";
107
- const nextKey = React.isValidElement(next) ? next.key : "";
108
- const isCurrentRemoved = typeof currentKey === "string" && currentKey.includes("remove-");
109
- const isNextAdded = typeof nextKey === "string" && nextKey.includes("add-");
110
- if (isCurrentRemoved &&
111
- isNextAdded &&
112
- React.isValidElement(current) &&
113
- React.isValidElement(next)) {
114
- // Extract the text content from the removed and added lines
115
- const removedText = extractTextFromElement(current);
116
- const addedText = extractTextFromElement(next);
117
- if (removedText && addedText) {
118
- // Apply word-level diff
119
- const { removedParts, addedParts } = renderWordLevelDiff(removedText, addedText, `word-${changeIndex}-${i}`);
120
- allElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "red", children: "-" }), removedParts] }, `word-diff-removed-${changeIndex}-${i}`));
121
- allElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "green", children: "+" }), addedParts] }, `word-diff-added-${changeIndex}-${i}`));
122
- i += 2; // Skip the next element since we processed it
123
- }
124
- else {
125
- // Fallback to original elements
126
- allElements.push(current);
127
- i += 1;
128
- }
96
+ // If it's a single line change (one removed, one added), use word-level diff
97
+ if (diffElements.length === 2 &&
98
+ React.isValidElement(diffElements[0]) &&
99
+ React.isValidElement(diffElements[1]) &&
100
+ typeof diffElements[0].key === "string" &&
101
+ diffElements[0].key.includes("remove-") &&
102
+ typeof diffElements[1].key === "string" &&
103
+ diffElements[1].key.includes("add-")) {
104
+ const removedText = extractTextFromElement(diffElements[0]);
105
+ const addedText = extractTextFromElement(diffElements[1]);
106
+ if (removedText && addedText) {
107
+ const { removedParts, addedParts } = renderWordLevelDiff(removedText, addedText, `word-${changeIndex}`);
108
+ allElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "red", children: "-" }), removedParts] }, `word-diff-removed-${changeIndex}`));
109
+ allElements.push(_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "green", children: "+" }), addedParts] }, `word-diff-added-${changeIndex}`));
129
110
  }
130
111
  else {
131
- allElements.push(current);
132
- i += 1;
112
+ allElements.push(...diffElements);
133
113
  }
134
114
  }
115
+ else {
116
+ allElements.push(...diffElements);
117
+ }
135
118
  }
136
119
  catch (error) {
137
120
  console.warn(`Error rendering diff for change ${changeIndex}:`, error);
@@ -139,35 +122,31 @@ export const DiffDisplay = ({ toolName, parameters, isExpanded = false, }) => {
139
122
  allElements.push(_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "red", children: ["-", change.oldContent || ""] }), _jsxs(Text, { color: "green", children: ["+", change.newContent || ""] })] }, `fallback-${changeIndex}`));
140
123
  }
141
124
  });
142
- const isTruncated = !isExpanded && allElements.length > maxHeight;
143
- const displayElements = isTruncated
144
- ? allElements.slice(0, maxHeight - 1)
145
- : allElements;
146
- return (_jsxs(Box, { flexDirection: "column", children: [displayElements, isTruncated && (_jsxs(Text, { color: "yellow", dimColor: true, children: ["... (truncated ", allElements.length - (maxHeight - 1), " more lines)"] }))] }));
125
+ return _jsx(Box, { flexDirection: "column", children: allElements });
147
126
  }
148
127
  catch (error) {
149
128
  console.warn("Error rendering expanded diff:", error);
150
129
  return (_jsx(Box, { children: _jsx(Text, { color: "gray", children: "Error rendering diff display" }) }));
151
130
  }
152
131
  };
153
- // Helper function to extract text content from a React element
154
- const extractTextFromElement = (element) => {
155
- if (!React.isValidElement(element))
156
- return null;
157
- // Navigate through Box -> Text structure
158
- const children = element.props.children;
159
- if (Array.isArray(children) && children.length >= 2) {
160
- const textElement = children[1]; // Second child should be the Text with content
161
- if (React.isValidElement(textElement) &&
162
- textElement.props.children) {
163
- return textElement.props.children;
164
- }
165
- }
166
- return null;
167
- };
168
132
  // Don't render anything if no diff should be shown
169
133
  if (!showDiff) {
170
134
  return null;
171
135
  }
172
136
  return (_jsx(Box, { flexDirection: "column", children: _jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "cyan", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Diff:" }), renderExpandedDiff()] }) }));
173
137
  };
138
+ // Helper function to extract text content from a React element
139
+ const extractTextFromElement = (element) => {
140
+ if (!React.isValidElement(element))
141
+ return null;
142
+ // Navigate through Box -> Text structure
143
+ const children = element.props.children;
144
+ if (Array.isArray(children) && children.length >= 2) {
145
+ const textElement = children[1]; // Second child should be the Text with content
146
+ if (React.isValidElement(textElement) &&
147
+ textElement.props.children) {
148
+ return textElement.props.children;
149
+ }
150
+ }
151
+ return null;
152
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAazC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,+GAC2E,CAAC;AAE/G,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,KAC/C,IAAI,CAAC;IACV,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1E,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/D,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAClD;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA+N5C,CAAC"}
1
+ {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAazC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,+GAC2E,CAAC;AAE/G,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,KAC/C,IAAI,CAAC;IACV,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1E,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/D,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAClD;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAiO5C,CAAC"}
@@ -6,7 +6,7 @@ import { FileSelector } from "./FileSelector.js";
6
6
  import { CommandSelector } from "./CommandSelector.js";
7
7
  import { HistorySearch } from "./HistorySearch.js";
8
8
  import { MemoryTypeSelector } from "./MemoryTypeSelector.js";
9
- import { BashShellManager } from "./BashShellManager.js";
9
+ import { TaskManager } from "./TaskManager.js";
10
10
  import { McpManager } from "./McpManager.js";
11
11
  import { RewindCommand } from "./RewindCommand.js";
12
12
  import { useInputManager } from "../hooks/useInputManager.js";
@@ -14,7 +14,7 @@ import { useChat } from "../contexts/useChat.js";
14
14
  export const INPUT_PLACEHOLDER_TEXT = "Type your message (use @ to reference files, / for commands, # to add memory, Ctrl+R to search history)...";
15
15
  export const INPUT_PLACEHOLDER_TEXT_PREFIX = INPUT_PLACEHOLDER_TEXT.substring(0, 10);
16
16
  export const InputBox = ({ isLoading = false, isCommandRunning = false, userInputHistory = [], sendMessage = () => { }, abortMessage = () => { }, saveMemory = async () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
17
- const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, messages, } = useChat();
17
+ const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, } = useChat();
18
18
  // Input manager with all input state and functionality (including images)
19
19
  const { inputText, cursorPosition,
20
20
  // Image management
@@ -27,8 +27,8 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, userInpu
27
27
  showMemoryTypeSelector, memoryMessage, handleMemoryTypeSelect, handleCancelMemoryTypeSelect,
28
28
  // History search
29
29
  showHistorySearch, historySearchQuery,
30
- // Bash/MCP Manager
31
- showBashManager, showMcpManager, showRewindManager, setShowBashManager, setShowMcpManager, setShowRewindManager,
30
+ // Task/MCP Manager
31
+ showTaskManager, showMcpManager, showRewindManager, setShowTaskManager, setShowMcpManager, setShowRewindManager,
32
32
  // Permission mode
33
33
  permissionMode, setPermissionMode,
34
34
  // Input history
@@ -41,6 +41,7 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, userInpu
41
41
  onHasSlashCommand: hasSlashCommand,
42
42
  onSaveMemory: saveMemory,
43
43
  onAbortMessage: abortMessage,
44
+ onBackgroundCurrentTask: backgroundCurrentTask,
44
45
  onPermissionModeChange: setChatPermissionMode,
45
46
  });
46
47
  // Sync permission mode from useChat to InputManager
@@ -83,5 +84,5 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, userInpu
83
84
  if (showRewindManager) {
84
85
  return (_jsx(RewindCommand, { messages: messages, onSelect: handleRewindSelectWithClose, onCancel: handleRewindCancel }));
85
86
  }
86
- return (_jsxs(Box, { flexDirection: "column", children: [showFileSelector && (_jsx(FileSelector, { files: filteredFiles, searchQuery: searchQuery, onSelect: handleFileSelect, onCancel: handleCancelFileSelect })), showCommandSelector && (_jsx(CommandSelector, { searchQuery: commandSearchQuery, onSelect: handleCommandSelect, onInsert: handleCommandInsert, onCancel: handleCancelCommandSelect, commands: slashCommands })), showHistorySearch && (_jsx(HistorySearch, { searchQuery: historySearchQuery, onSelect: handleHistorySearchSelect, onCancel: handleCancelHistorySearch })), showMemoryTypeSelector && (_jsx(MemoryTypeSelector, { message: memoryMessage, onSelect: handleMemoryTypeSelect, onCancel: handleCancelMemoryTypeSelect })), showBashManager && (_jsx(BashShellManager, { onCancel: () => setShowBashManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showBashManager || showMcpManager || showRewindManager || (_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, children: _jsxs(Text, { color: "gray", children: ["Mode:", " ", _jsx(Text, { color: permissionMode === "plan" ? "yellow" : "cyan", children: permissionMode }), " ", "(Shift+Tab to cycle)"] }) })] }))] }));
87
+ return (_jsxs(Box, { flexDirection: "column", children: [showFileSelector && (_jsx(FileSelector, { files: filteredFiles, searchQuery: searchQuery, onSelect: handleFileSelect, onCancel: handleCancelFileSelect })), showCommandSelector && (_jsx(CommandSelector, { searchQuery: commandSearchQuery, onSelect: handleCommandSelect, onInsert: handleCommandInsert, onCancel: handleCancelCommandSelect, commands: slashCommands })), showHistorySearch && (_jsx(HistorySearch, { searchQuery: historySearchQuery, onSelect: handleHistorySearchSelect, onCancel: handleCancelHistorySearch })), showMemoryTypeSelector && (_jsx(MemoryTypeSelector, { message: memoryMessage, onSelect: handleMemoryTypeSelect, onCancel: handleCancelMemoryTypeSelect })), showTaskManager && (_jsx(TaskManager, { onCancel: () => setShowTaskManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showTaskManager || showMcpManager || showRewindManager || (_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, children: _jsxs(Text, { color: "gray", children: ["Mode:", " ", _jsx(Text, { color: permissionMode === "plan" ? "yellow" : "cyan", children: permissionMode }), " ", "(Shift+Tab to cycle)"] }) })] }))] }));
87
88
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAKvC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB;AA8UD,eAAO,MAAM,QAAQ,2CAA6B,aAAa,6CAQ7D,CAAC"}
1
+ {"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAKvC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAoVD,eAAO,MAAM,QAAQ,2CAA6B,aAAa,6CAQ7D,CAAC"}
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import React, { useMemo } from "react";
3
3
  import { Box, Text, useStdout } from "ink";
4
4
  import { marked } from "marked";
5
- import { highlight } from "cli-highlight";
5
+ import { highlight, supportsLanguage } from "cli-highlight";
6
6
  const unescapeHtml = (html) => {
7
7
  return html
8
8
  .replace(/&amp;/g, "&")
@@ -89,7 +89,7 @@ const BlockRenderer = ({ tokens }) => {
89
89
  const content = lines.slice(1, -1).join("\n");
90
90
  const highlighted = content
91
91
  ? highlight(unescapeHtml(content), {
92
- language: t.lang,
92
+ language: t.lang && supportsLanguage(t.lang) ? t.lang : undefined,
93
93
  ignoreIllegals: true,
94
94
  })
95
95
  : "";
@@ -102,7 +102,8 @@ const BlockRenderer = ({ tokens }) => {
102
102
  return (_jsx(Box, { flexDirection: "column", marginBottom: 1, paddingLeft: 2, children: t.items.map((item, i) => {
103
103
  const start = t.start || 1;
104
104
  return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "gray", children: t.ordered ? `${start + i}. ` : "• " }), _jsx(Box, { flexDirection: "column", flexGrow: 1, children: item.tokens.map((itemToken, itemIndex) => {
105
- if (itemToken.type === "text") {
105
+ if (itemToken.type === "text" ||
106
+ itemToken.type === "paragraph") {
106
107
  const it = itemToken;
107
108
  return (_jsx(Box, { flexDirection: "row", children: _jsx(Text, { children: _jsx(InlineRenderer, { tokens: it.tokens || [itemToken] }) }) }, itemIndex));
108
109
  }
@@ -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,CAoClD,CAAC"}
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"}
@@ -6,9 +6,9 @@ export const PlanDisplay = ({ plan, isExpanded = false, }) => {
6
6
  const { stdout } = useStdout();
7
7
  const maxHeight = useMemo(() => {
8
8
  // Similar to DiffDisplay.tsx maxHeight calculation
9
- return Math.max(5, (stdout?.rows || 24) - 20);
9
+ return Math.max(5, (stdout?.rows || 24) - 25);
10
10
  }, [stdout?.rows]);
11
11
  const lines = useMemo(() => plan.split("\n"), [plan]);
12
12
  const isOverflowing = !isExpanded && lines.length > maxHeight;
13
- return (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "cyan", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Plan Content:" }), _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)"] }) }))] }) }));
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)"] }) }))] }));
14
14
  };
@@ -14,8 +14,8 @@ export const PluginDetail = () => {
14
14
  const plugin = discoverablePlugins.find((p) => `${p.name}@${p.marketplace}` === state.selectedId) ||
15
15
  installedPlugins.find((p) => `${p.name}@${p.marketplace}` === state.selectedId);
16
16
  const INSTALLED_ACTIONS = [
17
- { id: "uninstall", label: "Uninstall plugin" },
18
17
  { id: "update", label: "Update plugin (reinstall)" },
18
+ { id: "uninstall", label: "Uninstall plugin" },
19
19
  ];
20
20
  const isInstalledAndEnabled = plugin && "enabled" in plugin && plugin.enabled;
21
21
  useInput((input, key) => {
@@ -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,CA+HtD,CAAC"}
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"}
@@ -4,6 +4,10 @@ import { useChat } from "../contexts/useChat.js";
4
4
  import { Markdown } from "./Markdown.js";
5
5
  export const SubagentBlock = ({ block }) => {
6
6
  const { subagentMessages } = useChat();
7
+ // If the subagent is running in the background, don't show the block
8
+ if (block.runInBackground) {
9
+ return null;
10
+ }
7
11
  // Get messages for this subagent from context
8
12
  const messages = subagentMessages[block.subagentId] || [];
9
13
  // Status indicator mapping
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ export interface TaskManagerProps {
3
+ onCancel: () => void;
4
+ }
5
+ export declare const TaskManager: React.FC<TaskManagerProps>;
6
+ //# sourceMappingURL=TaskManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskManager.d.ts","sourceRoot":"","sources":["../../src/components/TaskManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAcnD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA2SlD,CAAC"}