deepagentsdk 0.11.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/dist/adapters/elements/index.cjs +324 -0
  2. package/dist/adapters/elements/index.cjs.map +1 -0
  3. package/dist/adapters/elements/index.d.cts +212 -0
  4. package/dist/adapters/elements/index.d.mts +212 -0
  5. package/dist/adapters/elements/index.mjs +320 -0
  6. package/dist/adapters/elements/index.mjs.map +1 -0
  7. package/dist/agent-CrH-He58.mjs +2974 -0
  8. package/dist/agent-CrH-He58.mjs.map +1 -0
  9. package/dist/agent-Cuks-Idh.cjs +3396 -0
  10. package/dist/agent-Cuks-Idh.cjs.map +1 -0
  11. package/dist/chunk-CbDLau6x.cjs +34 -0
  12. package/dist/cli/index.cjs +3162 -0
  13. package/dist/cli/index.cjs.map +1 -0
  14. package/dist/cli/index.d.cts +1 -0
  15. package/dist/cli/index.d.mts +1 -0
  16. package/dist/cli/index.mjs +3120 -0
  17. package/dist/cli/index.mjs.map +1 -0
  18. package/dist/file-saver-BJCqMIb5.mjs +655 -0
  19. package/dist/file-saver-BJCqMIb5.mjs.map +1 -0
  20. package/dist/file-saver-C6O2LAvg.cjs +679 -0
  21. package/dist/file-saver-C6O2LAvg.cjs.map +1 -0
  22. package/dist/index.cjs +1471 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.cts +1581 -0
  25. package/dist/index.d.mts +1581 -0
  26. package/dist/index.mjs +1371 -0
  27. package/dist/index.mjs.map +1 -0
  28. package/dist/load-79a2H4m0.cjs +163 -0
  29. package/dist/load-79a2H4m0.cjs.map +1 -0
  30. package/dist/load-94gjHorc.mjs +3 -0
  31. package/dist/load-B6CA5js_.mjs +142 -0
  32. package/dist/load-B6CA5js_.mjs.map +1 -0
  33. package/dist/load-C2qVmZMp.cjs +3 -0
  34. package/dist/types-4g9UvXal.d.mts +1151 -0
  35. package/dist/types-IulnvhFg.d.cts +1151 -0
  36. package/package.json +26 -12
  37. package/src/adapters/elements/index.ts +0 -27
  38. package/src/adapters/elements/messageAdapter.ts +0 -165
  39. package/src/adapters/elements/statusAdapter.ts +0 -39
  40. package/src/adapters/elements/types.ts +0 -97
  41. package/src/adapters/elements/useElementsAdapter.ts +0 -261
  42. package/src/agent.ts +0 -1258
  43. package/src/backends/composite.ts +0 -273
  44. package/src/backends/filesystem.ts +0 -692
  45. package/src/backends/index.ts +0 -22
  46. package/src/backends/local-sandbox.ts +0 -175
  47. package/src/backends/persistent.ts +0 -593
  48. package/src/backends/sandbox.ts +0 -510
  49. package/src/backends/state.ts +0 -244
  50. package/src/backends/utils.ts +0 -287
  51. package/src/checkpointer/file-saver.ts +0 -98
  52. package/src/checkpointer/index.ts +0 -5
  53. package/src/checkpointer/kv-saver.ts +0 -82
  54. package/src/checkpointer/memory-saver.ts +0 -82
  55. package/src/checkpointer/types.ts +0 -125
  56. package/src/cli/components/ApiKeyInput.tsx +0 -300
  57. package/src/cli/components/FilePreview.tsx +0 -237
  58. package/src/cli/components/Input.tsx +0 -277
  59. package/src/cli/components/Message.tsx +0 -93
  60. package/src/cli/components/ModelSelection.tsx +0 -338
  61. package/src/cli/components/SlashMenu.tsx +0 -101
  62. package/src/cli/components/StatusBar.tsx +0 -89
  63. package/src/cli/components/Subagent.tsx +0 -91
  64. package/src/cli/components/TodoList.tsx +0 -133
  65. package/src/cli/components/ToolApproval.tsx +0 -70
  66. package/src/cli/components/ToolCall.tsx +0 -144
  67. package/src/cli/components/ToolCallSummary.tsx +0 -175
  68. package/src/cli/components/Welcome.tsx +0 -75
  69. package/src/cli/components/index.ts +0 -24
  70. package/src/cli/hooks/index.ts +0 -12
  71. package/src/cli/hooks/useAgent.ts +0 -933
  72. package/src/cli/index.tsx +0 -1066
  73. package/src/cli/theme.ts +0 -205
  74. package/src/cli/utils/model-list.ts +0 -365
  75. package/src/constants/errors.ts +0 -29
  76. package/src/constants/limits.ts +0 -195
  77. package/src/index.ts +0 -176
  78. package/src/middleware/agent-memory.ts +0 -330
  79. package/src/prompts.ts +0 -196
  80. package/src/skills/index.ts +0 -2
  81. package/src/skills/load.ts +0 -191
  82. package/src/skills/types.ts +0 -53
  83. package/src/tools/execute.ts +0 -167
  84. package/src/tools/filesystem.ts +0 -418
  85. package/src/tools/index.ts +0 -39
  86. package/src/tools/subagent.ts +0 -443
  87. package/src/tools/todos.ts +0 -101
  88. package/src/tools/web.ts +0 -567
  89. package/src/types/backend.ts +0 -177
  90. package/src/types/core.ts +0 -220
  91. package/src/types/events.ts +0 -430
  92. package/src/types/index.ts +0 -94
  93. package/src/types/structured-output.ts +0 -43
  94. package/src/types/subagent.ts +0 -96
  95. package/src/types.ts +0 -22
  96. package/src/utils/approval.ts +0 -213
  97. package/src/utils/events.ts +0 -416
  98. package/src/utils/eviction.ts +0 -181
  99. package/src/utils/index.ts +0 -34
  100. package/src/utils/model-parser.ts +0 -38
  101. package/src/utils/patch-tool-calls.ts +0 -233
  102. package/src/utils/project-detection.ts +0 -32
  103. package/src/utils/summarization.ts +0 -254
@@ -1,338 +0,0 @@
1
- /**
2
- * Model Selection Panel - Interactive model selection with arrow keys.
3
- */
4
-
5
- import React, { useState, useEffect, useMemo } from "react";
6
- import { Box, Text, useInput } from "ink";
7
- import { Spinner } from "@inkjs/ui";
8
- import { colors, emoji } from "../theme";
9
- import {
10
- getModelsByProvider,
11
- detectAvailableProviders,
12
- type AvailableModel,
13
- } from "../utils/model-list";
14
-
15
- interface ModelSelectionPanelProps {
16
- currentModel?: string;
17
- /** Callback when a model is selected */
18
- onModelSelect?: (modelId: string) => void;
19
- /** Callback to close the panel */
20
- onClose?: () => void;
21
- }
22
-
23
- interface LoadingState {
24
- loading: boolean;
25
- anthropicModels: AvailableModel[];
26
- openaiModels: AvailableModel[];
27
- errors: { provider: string; error: string }[];
28
- }
29
-
30
- export function ModelSelectionPanel({
31
- currentModel,
32
- onModelSelect,
33
- onClose,
34
- }: ModelSelectionPanelProps): React.ReactElement {
35
- const providers = detectAvailableProviders();
36
- const hasAnyKey = providers.anthropic || providers.openai;
37
-
38
- const [state, setState] = useState<LoadingState>({
39
- loading: true,
40
- anthropicModels: [],
41
- openaiModels: [],
42
- errors: [],
43
- });
44
-
45
- const [selectedIndex, setSelectedIndex] = useState(0);
46
-
47
- // Combine all models into a flat list for navigation
48
- const allModels = useMemo(() => {
49
- const models: AvailableModel[] = [];
50
- if (state.anthropicModels.length > 0) {
51
- models.push(...state.anthropicModels);
52
- }
53
- if (state.openaiModels.length > 0) {
54
- models.push(...state.openaiModels);
55
- }
56
- return models;
57
- }, [state.anthropicModels, state.openaiModels]);
58
-
59
- // Find current model index to set initial selection
60
- useEffect(() => {
61
- if (allModels.length > 0 && currentModel) {
62
- const currentIndex = allModels.findIndex((m) => isCurrentModel(currentModel, m));
63
- if (currentIndex >= 0) {
64
- setSelectedIndex(currentIndex);
65
- }
66
- }
67
- }, [allModels, currentModel]);
68
-
69
- // Handle keyboard input
70
- useInput((input, key) => {
71
- if (state.loading) return;
72
-
73
- if (key.upArrow) {
74
- setSelectedIndex((prev) => (prev > 0 ? prev - 1 : allModels.length - 1));
75
- } else if (key.downArrow) {
76
- setSelectedIndex((prev) => (prev < allModels.length - 1 ? prev + 1 : 0));
77
- } else if (key.return) {
78
- const selectedModel = allModels[selectedIndex];
79
- if (selectedModel) {
80
- onModelSelect?.(selectedModel.id);
81
- onClose?.();
82
- }
83
- } else if (key.escape) {
84
- onClose?.();
85
- }
86
- });
87
-
88
- // Fetch models on mount
89
- useEffect(() => {
90
- if (!hasAnyKey) {
91
- setState({ loading: false, anthropicModels: [], openaiModels: [], errors: [] });
92
- return;
93
- }
94
-
95
- let cancelled = false;
96
-
97
- async function loadModels() {
98
- try {
99
- const result = await getModelsByProvider();
100
- if (!cancelled) {
101
- setState({
102
- loading: false,
103
- anthropicModels: result.anthropic || [],
104
- openaiModels: result.openai || [],
105
- errors: result.errors,
106
- });
107
- }
108
- } catch (error) {
109
- if (!cancelled) {
110
- setState({
111
- loading: false,
112
- anthropicModels: [],
113
- openaiModels: [],
114
- errors: [{ provider: "Unknown", error: String(error) }],
115
- });
116
- }
117
- }
118
- }
119
-
120
- loadModels();
121
-
122
- return () => {
123
- cancelled = true;
124
- };
125
- }, [hasAnyKey]);
126
-
127
- // No API keys configured
128
- if (!hasAnyKey) {
129
- return (
130
- <Box
131
- flexDirection="column"
132
- borderStyle="single"
133
- borderColor={colors.warning}
134
- paddingX={2}
135
- paddingY={1}
136
- marginY={1}
137
- >
138
- <Text bold color={colors.warning}>
139
- ⚠️ No API Keys Found
140
- </Text>
141
- <Box height={1} />
142
- <Text>Add an API key first to see available models.</Text>
143
- <Box height={1} />
144
- <Text color={colors.primary}>Run /apikey to add your API key</Text>
145
- <Box height={1} />
146
- <Text dimColor>Supported providers:</Text>
147
- <Text dimColor> • Anthropic (Claude)</Text>
148
- <Text dimColor> • OpenAI (GPT)</Text>
149
- </Box>
150
- );
151
- }
152
-
153
- // Loading state
154
- if (state.loading) {
155
- return (
156
- <Box
157
- flexDirection="column"
158
- borderStyle="single"
159
- borderColor={colors.muted}
160
- paddingX={2}
161
- paddingY={1}
162
- marginY={1}
163
- >
164
- <Text bold color={colors.info}>
165
- {emoji.model} Select Model
166
- </Text>
167
- <Box height={1} />
168
- <Box>
169
- <Spinner label="Fetching models from API..." />
170
- </Box>
171
- </Box>
172
- );
173
- }
174
-
175
- // Check if we have any models
176
- const hasModels = allModels.length > 0;
177
-
178
- // No models found (API errors)
179
- if (!hasModels && state.errors.length > 0) {
180
- return (
181
- <Box
182
- flexDirection="column"
183
- borderStyle="single"
184
- borderColor={colors.error}
185
- paddingX={2}
186
- paddingY={1}
187
- marginY={1}
188
- >
189
- <Text bold color={colors.error}>
190
- {emoji.error} Failed to Fetch Models
191
- </Text>
192
- <Box height={1} />
193
- {state.errors.map((err, i) => (
194
- <Text key={i} color={colors.error}>
195
- {err.provider}: {err.error}
196
- </Text>
197
- ))}
198
- <Box height={1} />
199
- <Text dimColor>Check your API key and try again with /apikey</Text>
200
- </Box>
201
- );
202
- }
203
-
204
- // Calculate the offset for each provider section
205
- let anthropicOffset = 0;
206
- let openaiOffset = state.anthropicModels.length;
207
-
208
- return (
209
- <Box
210
- flexDirection="column"
211
- borderStyle="single"
212
- borderColor={colors.primary}
213
- paddingX={2}
214
- paddingY={1}
215
- marginY={1}
216
- >
217
- <Text bold color={colors.info}>
218
- {emoji.model} Select Model
219
- </Text>
220
- <Box height={1} />
221
-
222
- {/* Show any errors */}
223
- {state.errors.length > 0 && (
224
- <>
225
- {state.errors.map((err, i) => (
226
- <Text key={i} color={colors.warning}>
227
- {emoji.warning} {err.provider}: {err.error}
228
- </Text>
229
- ))}
230
- <Box height={1} />
231
- </>
232
- )}
233
-
234
- {/* Anthropic Models */}
235
- {state.anthropicModels.length > 0 && (
236
- <>
237
- <Text bold color={colors.primary}>
238
- Anthropic Claude
239
- </Text>
240
- {state.anthropicModels.map((model, index) => {
241
- const globalIndex = anthropicOffset + index;
242
- const isSelected = globalIndex === selectedIndex;
243
- const isCurrent = isCurrentModel(currentModel, model);
244
- return (
245
- <ModelItem
246
- key={model.id}
247
- model={model}
248
- isSelected={isSelected}
249
- isCurrent={isCurrent}
250
- />
251
- );
252
- })}
253
- <Box height={1} />
254
- </>
255
- )}
256
-
257
- {/* OpenAI Models */}
258
- {state.openaiModels.length > 0 && (
259
- <>
260
- <Text bold color={colors.primary}>
261
- OpenAI GPT
262
- </Text>
263
- {state.openaiModels.map((model, index) => {
264
- const globalIndex = openaiOffset + index;
265
- const isSelected = globalIndex === selectedIndex;
266
- const isCurrent = isCurrentModel(currentModel, model);
267
- return (
268
- <ModelItem
269
- key={model.id}
270
- model={model}
271
- isSelected={isSelected}
272
- isCurrent={isCurrent}
273
- />
274
- );
275
- })}
276
- <Box height={1} />
277
- </>
278
- )}
279
-
280
- {/* Navigation hint */}
281
- <Text dimColor>↑/↓ Navigate • Enter Select • Esc Cancel</Text>
282
- </Box>
283
- );
284
- }
285
-
286
- /**
287
- * Check if a model matches the current model.
288
- */
289
- function isCurrentModel(currentModel: string | undefined, model: AvailableModel): boolean {
290
- if (!currentModel) return false;
291
- return (
292
- currentModel === model.id ||
293
- currentModel === model.name ||
294
- currentModel === `${model.provider}/${model.name}` ||
295
- (currentModel.startsWith(`${model.provider}/`) && currentModel === model.id)
296
- );
297
- }
298
-
299
- interface ModelItemProps {
300
- model: AvailableModel;
301
- isSelected: boolean;
302
- isCurrent: boolean;
303
- }
304
-
305
- function ModelItem({ model, isSelected, isCurrent }: ModelItemProps): React.ReactElement {
306
- // Determine the indicator
307
- let indicator = " ";
308
- let textColor: string | undefined = undefined;
309
- let isBold = false;
310
-
311
- if (isSelected) {
312
- indicator = "▸ ";
313
- textColor = colors.primary;
314
- isBold = true;
315
- }
316
-
317
- if (isCurrent) {
318
- indicator = isSelected ? "▸✓" : " ✓";
319
- textColor = isSelected ? colors.primary : colors.success;
320
- }
321
-
322
- return (
323
- <Box marginLeft={1}>
324
- <Text color={isSelected ? colors.primary : isCurrent ? colors.success : undefined}>
325
- {indicator}
326
- </Text>
327
- <Text color={textColor} bold={isBold}>
328
- {model.id}
329
- </Text>
330
- {model.description && (
331
- <>
332
- <Text dimColor> - </Text>
333
- <Text dimColor>{model.description}</Text>
334
- </>
335
- )}
336
- </Box>
337
- );
338
- }
@@ -1,101 +0,0 @@
1
- /**
2
- * Slash command autocomplete menu component.
3
- */
4
- import React from "react";
5
- import { Box, Text } from "ink";
6
- import { colors, filterCommands, type SlashCommand } from "../theme";
7
-
8
- interface SlashMenuProps {
9
- /** Current input value to filter commands */
10
- filter: string;
11
- /** Maximum number of items to show */
12
- maxItems?: number;
13
- }
14
-
15
- export function SlashMenu({
16
- filter,
17
- maxItems = 8,
18
- }: SlashMenuProps): React.ReactElement | null {
19
- // Only show menu when input starts with /
20
- if (!filter.startsWith("/")) {
21
- return null;
22
- }
23
-
24
- const filtered = filterCommands(filter);
25
-
26
- if (filtered.length === 0) {
27
- return (
28
- <Box paddingLeft={2} marginTop={1}>
29
- <Text dimColor>No matching commands</Text>
30
- </Box>
31
- );
32
- }
33
-
34
- const displayItems = filtered.slice(0, maxItems);
35
- const hasMore = filtered.length > maxItems;
36
-
37
- return (
38
- <Box flexDirection="column" marginTop={1} paddingLeft={2}>
39
- {displayItems.map((cmd) => (
40
- <SlashMenuItem key={cmd.command} command={cmd} />
41
- ))}
42
- {hasMore && (
43
- <Text dimColor>... and {filtered.length - maxItems} more</Text>
44
- )}
45
- </Box>
46
- );
47
- }
48
-
49
- interface SlashMenuItemProps {
50
- command: SlashCommand;
51
- }
52
-
53
- function SlashMenuItem({ command }: SlashMenuItemProps): React.ReactElement {
54
- const aliases =
55
- command.aliases.length > 0 ? ` (${command.aliases.join(", ")})` : "";
56
-
57
- return (
58
- <Box>
59
- <Text color={colors.info}>{command.command}</Text>
60
- <Text dimColor>{aliases}</Text>
61
- <Text dimColor> - {command.description}</Text>
62
- </Box>
63
- );
64
- }
65
-
66
- /**
67
- * Full slash menu panel for /help command.
68
- */
69
- export function SlashMenuPanel(): React.ReactElement {
70
- const commands = filterCommands();
71
-
72
- return (
73
- <Box
74
- flexDirection="column"
75
- borderStyle="single"
76
- borderColor={colors.muted}
77
- paddingX={2}
78
- paddingY={1}
79
- marginY={1}
80
- >
81
- <Text bold color={colors.info}>
82
- Available Commands
83
- </Text>
84
- <Box height={1} />
85
- {commands.map((cmd) => (
86
- <Box key={cmd.command} flexDirection="column" marginBottom={1}>
87
- <Box>
88
- <Text color={colors.info}>{cmd.command}</Text>
89
- {cmd.aliases.length > 0 && (
90
- <Text dimColor> ({cmd.aliases.join(", ")})</Text>
91
- )}
92
- </Box>
93
- <Box paddingLeft={2}>
94
- <Text dimColor>{cmd.description}</Text>
95
- </Box>
96
- </Box>
97
- ))}
98
- </Box>
99
- );
100
- }
101
-
@@ -1,89 +0,0 @@
1
- /**
2
- * Compact status bar component.
3
- * Clean, minimal design inspired by Claude Code and OpenAI Codex.
4
- */
5
- import React from "react";
6
- import { Box, Text } from "ink";
7
- import { colors } from "../theme";
8
-
9
- interface FeatureFlags {
10
- promptCaching: boolean;
11
- eviction: boolean;
12
- summarization: boolean;
13
- }
14
-
15
- interface StatusBarProps {
16
- /** Current working directory */
17
- workDir: string;
18
- /** Current model name */
19
- model: string;
20
- /** Optional status indicator (idle, generating, etc.) */
21
- status?: "idle" | "thinking" | "streaming" | "tool-call" | "subagent" | "done" | "error";
22
- /** Feature flags to display */
23
- features?: FeatureFlags;
24
- /** Whether auto-approve mode is enabled */
25
- autoApproveEnabled?: boolean;
26
- /** Current session ID if checkpointing is enabled */
27
- sessionId?: string;
28
- }
29
-
30
- export function StatusBar({
31
- workDir,
32
- model,
33
- status = "idle",
34
- features,
35
- autoApproveEnabled = false,
36
- sessionId,
37
- }: StatusBarProps): React.ReactElement {
38
- // Get short model name
39
- const shortModel = model.split("/").pop() || model;
40
-
41
- // Status indicator - minimal
42
- const getStatusDisplay = () => {
43
- switch (status) {
44
- case "thinking":
45
- return <Text color={colors.warning}>●</Text>;
46
- case "streaming":
47
- return <Text color={colors.success}>●</Text>;
48
- case "tool-call":
49
- return <Text color={colors.tool}>●</Text>;
50
- case "subagent":
51
- return <Text color={colors.secondary}>●</Text>;
52
- case "error":
53
- return <Text color={colors.error}>●</Text>;
54
- case "done":
55
- return <Text color={colors.success}>●</Text>;
56
- default:
57
- return <Text dimColor>○</Text>;
58
- }
59
- };
60
-
61
- // Feature badges - compact
62
- const featureBadges: string[] = [];
63
- if (features?.promptCaching) featureBadges.push("⚡");
64
- if (features?.eviction) featureBadges.push("📦");
65
- if (features?.summarization) featureBadges.push("📝");
66
-
67
- return (
68
- <Box marginTop={1}>
69
- <Text dimColor>
70
- {getStatusDisplay()} {shortModel}
71
- {featureBadges.length > 0 && ` ${featureBadges.join(" ")}`}
72
- {" · "}
73
- {autoApproveEnabled ? (
74
- <Text color={colors.success}>🟢 Auto-approve</Text>
75
- ) : (
76
- <Text color={colors.warning}>🔴 Safe mode</Text>
77
- )}
78
- {sessionId && (
79
- <>
80
- {" · "}
81
- <Text dimColor>Session: {sessionId}</Text>
82
- </>
83
- )}
84
- {" · "}? for shortcuts
85
- </Text>
86
- </Box>
87
- );
88
- }
89
-
@@ -1,91 +0,0 @@
1
- /**
2
- * Subagent status display components.
3
- */
4
- import React from "react";
5
- import { Box, Text } from "ink";
6
- import { Spinner, StatusMessage } from "@inkjs/ui";
7
- import { emoji, colors } from "../theme";
8
-
9
- interface SubagentStartProps {
10
- /** Subagent name */
11
- name: string;
12
- /** Task description */
13
- task: string;
14
- /** Maximum task length to display */
15
- maxTaskLength?: number;
16
- }
17
-
18
- export function SubagentStart({
19
- name,
20
- task,
21
- maxTaskLength = 60,
22
- }: SubagentStartProps): React.ReactElement {
23
- const shortTask =
24
- task.length > maxTaskLength
25
- ? task.substring(0, maxTaskLength) + "..."
26
- : task;
27
-
28
- return (
29
- <Box flexDirection="column" marginY={1}>
30
- <Box>
31
- <Spinner
32
- label={`${emoji.subagent} Starting subagent: ${name}`}
33
- />
34
- </Box>
35
- <Box paddingLeft={4}>
36
- <Text dimColor>└─ {shortTask}</Text>
37
- </Box>
38
- </Box>
39
- );
40
- }
41
-
42
- interface SubagentFinishProps {
43
- /** Subagent name */
44
- name: string;
45
- }
46
-
47
- export function SubagentFinish({
48
- name,
49
- }: SubagentFinishProps): React.ReactElement {
50
- return (
51
- <Box marginY={1}>
52
- <StatusMessage variant="success">
53
- {emoji.subagent} Subagent {name} completed
54
- </StatusMessage>
55
- </Box>
56
- );
57
- }
58
-
59
- /**
60
- * Subagent running indicator (for when a subagent is actively working).
61
- */
62
- interface SubagentRunningProps {
63
- name: string;
64
- task: string;
65
- }
66
-
67
- export function SubagentRunning({
68
- name,
69
- task,
70
- }: SubagentRunningProps): React.ReactElement {
71
- const shortTask = task.length > 50 ? task.substring(0, 50) + "..." : task;
72
-
73
- return (
74
- <Box
75
- flexDirection="column"
76
- borderStyle="single"
77
- borderColor={colors.secondary}
78
- paddingX={2}
79
- paddingY={1}
80
- marginY={1}
81
- >
82
- <Box>
83
- <Spinner label={`${emoji.subagent} ${name}`} />
84
- </Box>
85
- <Box paddingLeft={2}>
86
- <Text dimColor>{shortTask}</Text>
87
- </Box>
88
- </Box>
89
- );
90
- }
91
-