@iaforged/context-code 1.1.7 → 1.2.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.
- package/README.md +56 -0
- package/dist/src/commands/agent/agent.js +62 -0
- package/dist/src/commands/agent/index.js +1 -1
- package/dist/src/commands/model/model.js +9 -5
- package/dist/src/commands/orchestrate/index.js +2 -2
- package/dist/src/commands/orchestrate/orchestrate.js +12 -627
- package/dist/src/commands/tasks/index.js +1 -1
- package/dist/src/commands/tasks/tasks.js +8 -3
- package/dist/src/commands/team/index.js +2 -2
- package/dist/src/commands/team/team.js +12 -589
- package/dist/src/commands/timeline/index.js +8 -0
- package/dist/src/commands/timeline/timeline.js +194 -0
- package/dist/src/commands/workspace/workspace.js +3 -3
- package/dist/src/commands.js +2 -6
- package/dist/src/components/AgentActivitySidebar.js +50 -0
- package/dist/src/components/AgentProgressLine.js +5 -5
- package/dist/src/components/ModelPicker.js +252 -441
- package/dist/src/components/PromptInput/Notifications.js +1 -1
- package/dist/src/components/PromptInput/PromptInput.js +7 -3
- package/dist/src/components/PromptInput/PromptInputFooter.js +10 -29
- package/dist/src/components/Spinner/TeammateSpinnerLine.js +20 -62
- package/dist/src/components/Spinner/TeammateSpinnerTree.js +16 -258
- package/dist/src/components/Spinner/teammateSelectHint.js +1 -1
- package/dist/src/components/Spinner/utils.js +3 -6
- package/dist/src/components/ThemeBrowser.js +120 -0
- package/dist/src/components/ThemePicker.js +113 -321
- package/dist/src/components/design-system/ThemeProvider.js +3 -0
- package/dist/src/components/mcp/MCPListPanel.js +138 -444
- package/dist/src/components/permissions/SandboxPermissionRequest.js +5 -5
- package/dist/src/components/teams/TeamStatus.js +7 -71
- package/dist/src/constants/spinnerVerbs.js +80 -180
- package/dist/src/context/modalStackContext.js +12 -0
- package/dist/src/hooks/useTextInput.js +28 -18
- package/dist/src/main.js +12 -0
- package/dist/src/screens/REPL.js +386 -320
- package/dist/src/services/api/errors.js +1 -1
- package/dist/src/services/api/openai.js +70 -22
- package/dist/src/services/api/withRetry.js +3 -2
- package/dist/src/skills/loadSkillsDir.js +1 -0
- package/dist/src/tools/AgentTool/UI.js +8 -8
- package/dist/src/tools/AgentTool/loadAgentsDir.js +9 -4
- package/dist/src/tools/AgentTool/providerAgents.js +71 -0
- package/dist/src/tools/BashTool/bashSecurity.js +1 -1
- package/dist/src/utils/handlePromptSubmit.js +12 -2
- package/dist/src/utils/processUserInput/processSlashCommand.js +9 -5
- package/dist/src/utils/sembleMcp/common.js +5 -0
- package/dist/src/utils/sembleMcp/setup.js +119 -0
- package/dist/src/utils/theme.js +24 -3
- package/dist/src/utils/themes/bootstrap.js +109 -0
- package/dist/src/utils/themes/builtin/opencode/_index.json +41 -0
- package/dist/src/utils/themes/builtin/opencode/amoled.json +49 -0
- package/dist/src/utils/themes/builtin/opencode/aura.json +51 -0
- package/dist/src/utils/themes/builtin/opencode/ayu.json +51 -0
- package/dist/src/utils/themes/builtin/opencode/carbonfox.json +53 -0
- package/dist/src/utils/themes/builtin/opencode/catppuccin-frappe.json +85 -0
- package/dist/src/utils/themes/builtin/opencode/catppuccin-macchiato.json +85 -0
- package/dist/src/utils/themes/builtin/opencode/catppuccin.json +45 -0
- package/dist/src/utils/themes/builtin/opencode/cobalt2.json +87 -0
- package/dist/src/utils/themes/builtin/opencode/cursor.json +91 -0
- package/dist/src/utils/themes/builtin/opencode/dracula.json +49 -0
- package/dist/src/utils/themes/builtin/opencode/everforest.json +89 -0
- package/dist/src/utils/themes/builtin/opencode/flexoki.json +86 -0
- package/dist/src/utils/themes/builtin/opencode/github.json +85 -0
- package/dist/src/utils/themes/builtin/opencode/gruvbox.json +45 -0
- package/dist/src/utils/themes/builtin/opencode/kanagawa.json +89 -0
- package/dist/src/utils/themes/builtin/opencode/lucent-orng.json +87 -0
- package/dist/src/utils/themes/builtin/opencode/material.json +87 -0
- package/dist/src/utils/themes/builtin/opencode/matrix.json +91 -0
- package/dist/src/utils/themes/builtin/opencode/mercury.json +86 -0
- package/dist/src/utils/themes/builtin/opencode/monokai.json +49 -0
- package/dist/src/utils/themes/builtin/opencode/nightowl.json +46 -0
- package/dist/src/utils/themes/builtin/opencode/nord.json +46 -0
- package/dist/src/utils/themes/builtin/opencode/oc-2.json +88 -0
- package/dist/src/utils/themes/builtin/opencode/one-dark.json +89 -0
- package/dist/src/utils/themes/builtin/opencode/onedarkpro.json +45 -0
- package/dist/src/utils/themes/builtin/opencode/opencode.json +89 -0
- package/dist/src/utils/themes/builtin/opencode/orng.json +87 -0
- package/dist/src/utils/themes/builtin/opencode/osaka-jade.json +88 -0
- package/dist/src/utils/themes/builtin/opencode/palenight.json +85 -0
- package/dist/src/utils/themes/builtin/opencode/rosepine.json +85 -0
- package/dist/src/utils/themes/builtin/opencode/shadesofpurple.json +51 -0
- package/dist/src/utils/themes/builtin/opencode/solarized.json +49 -0
- package/dist/src/utils/themes/builtin/opencode/synthwave84.json +87 -0
- package/dist/src/utils/themes/builtin/opencode/tokyonight.json +47 -0
- package/dist/src/utils/themes/builtin/opencode/vercel.json +90 -0
- package/dist/src/utils/themes/builtin/opencode/vesper.json +51 -0
- package/dist/src/utils/themes/builtin/opencode/zenburn.json +87 -0
- package/dist/src/utils/themes/index.js +4 -0
- package/dist/src/utils/themes/loader.js +147 -0
- package/dist/src/utils/themes/opencodeMapper.js +124 -0
- package/dist/src/utils/themes/resolver.js +66 -0
- package/dist/src/utils/themes/types.js +1 -0
- package/docs/MCP_SERVERS.md +27 -1
- package/docs/comandos.md +16 -4
- package/package.json +1 -1
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import figures from 'figures';
|
|
3
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { createHistoryAuthCtx, fetchLatestEvents, fetchOlderEvents, } from '../../assistant/sessionHistory.js';
|
|
5
|
+
import { getSessionId } from '../../bootstrap/state.js';
|
|
6
|
+
import { Select } from '../../components/CustomSelect/select.js';
|
|
7
|
+
import { Spinner } from '../../components/Spinner.js';
|
|
8
|
+
import { FuzzyPicker } from '../../components/design-system/FuzzyPicker.js';
|
|
9
|
+
import { stringWidth } from '../../ink/stringWidth.js';
|
|
10
|
+
import { setClipboard } from '../../ink/termio/osc.js';
|
|
11
|
+
import { Box, Text } from '../../ink.js';
|
|
12
|
+
import { formatRelativeTimeAgo, truncateToWidth } from '../../utils/format.js';
|
|
13
|
+
import { logForDebugging } from '../../utils/debug.js';
|
|
14
|
+
const AGE_WIDTH = 8;
|
|
15
|
+
const MAX_PREVIEW_WIDTH = 140;
|
|
16
|
+
const MAX_PREVIEW_CHARS = 220;
|
|
17
|
+
const MAX_PAGES = 30;
|
|
18
|
+
function extractPreviewText(content) {
|
|
19
|
+
if (typeof content === 'string') {
|
|
20
|
+
const cleaned = content.trim();
|
|
21
|
+
return cleaned.length > 0 ? cleaned : null;
|
|
22
|
+
}
|
|
23
|
+
if (!Array.isArray(content))
|
|
24
|
+
return null;
|
|
25
|
+
const textBlock = content.find(b => b?.type === 'text' && typeof b.text === 'string');
|
|
26
|
+
const text = textBlock?.text?.trim();
|
|
27
|
+
return text && text.length > 0 ? text : null;
|
|
28
|
+
}
|
|
29
|
+
function isHumanUserMessage(msg) {
|
|
30
|
+
if (msg.type !== 'user')
|
|
31
|
+
return false;
|
|
32
|
+
if (msg.parent_tool_use_id != null || msg.isSynthetic || msg.isReplay)
|
|
33
|
+
return false;
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
function asTimelineItem(msg, sessionId) {
|
|
37
|
+
if (!isHumanUserMessage(msg))
|
|
38
|
+
return null;
|
|
39
|
+
if (!msg.uuid)
|
|
40
|
+
return null;
|
|
41
|
+
const previewText = extractPreviewText(msg.message?.content);
|
|
42
|
+
if (!previewText)
|
|
43
|
+
return null;
|
|
44
|
+
const timestamp = msg.timestamp ?? new Date().toISOString();
|
|
45
|
+
const age = formatRelativeTimeAgo(new Date(timestamp));
|
|
46
|
+
return {
|
|
47
|
+
sessionId,
|
|
48
|
+
messageId: msg.uuid,
|
|
49
|
+
preview: previewText.slice(0, MAX_PREVIEW_CHARS),
|
|
50
|
+
fullText: previewText,
|
|
51
|
+
timestamp,
|
|
52
|
+
age: age + ' '.repeat(Math.max(0, AGE_WIDTH - stringWidth(age))),
|
|
53
|
+
lower: previewText.toLowerCase(),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
async function loadTimelineItems(sessionId) {
|
|
57
|
+
const ctx = await createHistoryAuthCtx(sessionId);
|
|
58
|
+
const latest = await fetchLatestEvents(ctx);
|
|
59
|
+
if (!latest)
|
|
60
|
+
return [];
|
|
61
|
+
const events = [...latest.events];
|
|
62
|
+
let cursor = latest.firstId;
|
|
63
|
+
let hasMore = latest.hasMore;
|
|
64
|
+
let pageCount = 1;
|
|
65
|
+
while (hasMore && cursor && pageCount < MAX_PAGES) {
|
|
66
|
+
const page = await fetchOlderEvents(ctx, cursor);
|
|
67
|
+
if (!page)
|
|
68
|
+
break;
|
|
69
|
+
events.unshift(...page.events);
|
|
70
|
+
cursor = page.firstId;
|
|
71
|
+
hasMore = page.hasMore;
|
|
72
|
+
pageCount++;
|
|
73
|
+
}
|
|
74
|
+
if (hasMore) {
|
|
75
|
+
logForDebugging(`[timeline] Stopped pagination at MAX_PAGES=${MAX_PAGES} for session ${sessionId}`);
|
|
76
|
+
}
|
|
77
|
+
const items = events
|
|
78
|
+
.map(msg => asTimelineItem(msg, sessionId))
|
|
79
|
+
.filter((item) => item !== null)
|
|
80
|
+
.reverse();
|
|
81
|
+
return items;
|
|
82
|
+
}
|
|
83
|
+
function TimelinePicker({ onDone, onJumpToMessage, onOpenMessageSelectorAtMessage, }) {
|
|
84
|
+
const [loading, setLoading] = useState(true);
|
|
85
|
+
const [items, setItems] = useState([]);
|
|
86
|
+
const [query, setQuery] = useState('');
|
|
87
|
+
const [selectedItem, setSelectedItem] = useState(null);
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
let cancelled = false;
|
|
90
|
+
void (async () => {
|
|
91
|
+
try {
|
|
92
|
+
const sessionId = getSessionId();
|
|
93
|
+
const loaded = await loadTimelineItems(sessionId);
|
|
94
|
+
if (!cancelled)
|
|
95
|
+
setItems(loaded);
|
|
96
|
+
}
|
|
97
|
+
catch (_error) {
|
|
98
|
+
if (!cancelled)
|
|
99
|
+
setItems([]);
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
if (!cancelled)
|
|
103
|
+
setLoading(false);
|
|
104
|
+
}
|
|
105
|
+
})();
|
|
106
|
+
return () => {
|
|
107
|
+
cancelled = true;
|
|
108
|
+
};
|
|
109
|
+
}, []);
|
|
110
|
+
const filtered = useMemo(() => {
|
|
111
|
+
const q = query.trim().toLowerCase();
|
|
112
|
+
if (!q)
|
|
113
|
+
return items;
|
|
114
|
+
return items.filter(item => item.lower.includes(q));
|
|
115
|
+
}, [items, query]);
|
|
116
|
+
if (loading) {
|
|
117
|
+
return (_jsxs(Box, { children: [_jsx(Spinner, {}), _jsx(Text, { children: " Loading timeline\u2026" })] }));
|
|
118
|
+
}
|
|
119
|
+
if (selectedItem) {
|
|
120
|
+
const options = [
|
|
121
|
+
{
|
|
122
|
+
label: 'Copy',
|
|
123
|
+
value: 'copy',
|
|
124
|
+
description: 'Copy message content to input (no auto-submit)',
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
label: 'Fork',
|
|
128
|
+
value: 'fork',
|
|
129
|
+
description: 'Prepare /branch flow (current CLI has no messageId fork)',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
label: 'Revert',
|
|
133
|
+
value: 'revert',
|
|
134
|
+
description: 'Open existing /rewind flow',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
label: 'Back',
|
|
138
|
+
value: 'back',
|
|
139
|
+
},
|
|
140
|
+
];
|
|
141
|
+
const handleAction = async (action) => {
|
|
142
|
+
if (action === 'back') {
|
|
143
|
+
setSelectedItem(null);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (action === 'copy') {
|
|
147
|
+
const raw = await setClipboard(selectedItem.fullText);
|
|
148
|
+
if (raw)
|
|
149
|
+
process.stdout.write(raw);
|
|
150
|
+
onDone('Timeline message copied to input and clipboard.', {
|
|
151
|
+
display: 'system',
|
|
152
|
+
nextInput: selectedItem.fullText,
|
|
153
|
+
submitNextInput: false,
|
|
154
|
+
jumpToMessageId: selectedItem.messageId,
|
|
155
|
+
});
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (action === 'fork') {
|
|
159
|
+
onDone(`Prepared /branch and kept focus on selected timeline message (${selectedItem.messageId}).`, {
|
|
160
|
+
display: 'system',
|
|
161
|
+
nextInput: '/branch',
|
|
162
|
+
submitNextInput: false,
|
|
163
|
+
jumpToMessageId: selectedItem.messageId,
|
|
164
|
+
});
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
onJumpToMessage(selectedItem.messageId);
|
|
168
|
+
onOpenMessageSelectorAtMessage(selectedItem.messageId);
|
|
169
|
+
onDone('Opened rewind selector at selected timeline message.', {
|
|
170
|
+
display: 'skip',
|
|
171
|
+
});
|
|
172
|
+
};
|
|
173
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { bold: true, children: "Timeline actions" }), _jsx(Text, { dimColor: true, children: new Date(selectedItem.timestamp).toLocaleString() }), _jsx(Text, { children: selectedItem.preview }), _jsxs(Text, { dimColor: true, children: [figures.pointer, " messageId: ", selectedItem.messageId] }), _jsx(Select, { options: options, onChange: value => {
|
|
174
|
+
void handleAction(value);
|
|
175
|
+
}, onCancel: () => setSelectedItem(null) })] }));
|
|
176
|
+
}
|
|
177
|
+
return (_jsx(FuzzyPicker, { title: "Session timeline", placeholder: "Filter user messages\u2026", items: filtered, getKey: item => item.messageId, onQueryChange: setQuery, onSelect: item => {
|
|
178
|
+
onJumpToMessage(item.messageId);
|
|
179
|
+
setSelectedItem(item);
|
|
180
|
+
}, onCancel: () => onDone('Timeline cancelled'), emptyMessage: q => items.length === 0
|
|
181
|
+
? 'No user messages found in current session'
|
|
182
|
+
: q
|
|
183
|
+
? 'No matching messages'
|
|
184
|
+
: 'No user messages found', selectAction: "select message", renderItem: (item, isFocused) => (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: item.age }), _jsxs(Text, { color: isFocused ? 'suggestion' : undefined, children: [' ', truncateToWidth(item.preview, MAX_PREVIEW_WIDTH)] })] })), renderPreview: item => (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderDimColor: true, paddingX: 1, children: [_jsx(Text, { dimColor: true, children: new Date(item.timestamp).toLocaleString() }), _jsx(Text, { children: item.preview }), _jsxs(Text, { dimColor: true, children: [figures.pointer, " sessionId: ", item.sessionId] }), _jsxs(Text, { dimColor: true, children: [figures.pointer, " messageId: ", item.messageId] })] })) }));
|
|
185
|
+
}
|
|
186
|
+
export const call = async (onDone, _context, _args) => {
|
|
187
|
+
const onJumpToMessage = (messageId) => {
|
|
188
|
+
_context.jumpToMessage?.(messageId);
|
|
189
|
+
};
|
|
190
|
+
const onOpenMessageSelectorAtMessage = (messageId) => {
|
|
191
|
+
_context.openMessageSelectorAtMessage?.(messageId);
|
|
192
|
+
};
|
|
193
|
+
return (_jsx(TimelinePicker, { onDone: onDone, onJumpToMessage: onJumpToMessage, onOpenMessageSelectorAtMessage: onOpenMessageSelectorAtMessage }));
|
|
194
|
+
};
|
|
@@ -169,8 +169,8 @@ function buildSetupGuideMessage() {
|
|
|
169
169
|
'6. Crea o actualiza los equipos internos del team.',
|
|
170
170
|
'',
|
|
171
171
|
'Despues puedes ejecutar:',
|
|
172
|
-
'/
|
|
173
|
-
'
|
|
172
|
+
'/agent',
|
|
173
|
+
'Describe el objetivo directamente en el hilo principal',
|
|
174
174
|
'/run resume <run-id>',
|
|
175
175
|
'',
|
|
176
176
|
'Nota: si todavia no tienes provider/profile listo, abre solo /workspace setup y elige "Preparar proveedor/perfil".',
|
|
@@ -382,7 +382,7 @@ async function runWorkspaceSetup(setup) {
|
|
|
382
382
|
});
|
|
383
383
|
lines.push(`- Equipo creado: ${entry.unitName} -> ${entry.provider}/${entry.agentName}`);
|
|
384
384
|
}
|
|
385
|
-
lines.push('', 'Listo. Siguientes comandos recomendados:',
|
|
385
|
+
lines.push('', 'Listo. Siguientes comandos recomendados:', '/agent', 'Describe tu objetivo y delega en los agentes disponibles', '/run list', '/run resume <run-id>');
|
|
386
386
|
return lines.join('\n');
|
|
387
387
|
}
|
|
388
388
|
async function setWorkspaceState(onDone, provider, enabled) {
|
package/dist/src/commands.js
CHANGED
|
@@ -46,7 +46,6 @@ import session from './commands/session/index.js';
|
|
|
46
46
|
import share from './commands/share/index.js';
|
|
47
47
|
import skills from './commands/skills/index.js';
|
|
48
48
|
import status from './commands/status/index.js';
|
|
49
|
-
import tasks from './commands/tasks/index.js';
|
|
50
49
|
import teleport from './commands/teleport/index.js';
|
|
51
50
|
import telegram from './commands/telegram/index.js';
|
|
52
51
|
import whatsapp from './commands/whatsapp/index.js';
|
|
@@ -59,6 +58,7 @@ import securityReview from './commands/security-review.js';
|
|
|
59
58
|
import bughunter from './commands/bughunter/index.js';
|
|
60
59
|
import terminalSetup from './commands/terminalSetup/index.js';
|
|
61
60
|
import theme from './commands/theme/index.js';
|
|
61
|
+
import timeline from './commands/timeline/index.js';
|
|
62
62
|
import vim from './commands/vim/index.js';
|
|
63
63
|
// Dead code elimination: conditional imports
|
|
64
64
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
@@ -150,10 +150,8 @@ import profile from './commands/profile/index.js';
|
|
|
150
150
|
import policy from './commands/policy/index.js';
|
|
151
151
|
import run from './commands/run/index.js';
|
|
152
152
|
import workspace from './commands/workspace/index.js';
|
|
153
|
-
import orchestrate from './commands/orchestrate/index.js';
|
|
154
153
|
import provider from './commands/provider/index.js';
|
|
155
154
|
import tag from './commands/tag/index.js';
|
|
156
|
-
import team from './commands/team/index.js';
|
|
157
155
|
import teamAuto from './commands/team-auto/index.js';
|
|
158
156
|
import limites from './commands/limites/index.js';
|
|
159
157
|
import outputStyle from './commands/output-style/index.js';
|
|
@@ -240,7 +238,6 @@ const COMMANDS = memoize(() => [
|
|
|
240
238
|
policy,
|
|
241
239
|
run,
|
|
242
240
|
workspace,
|
|
243
|
-
orchestrate,
|
|
244
241
|
provider,
|
|
245
242
|
outputStyle,
|
|
246
243
|
remoteEnv,
|
|
@@ -257,10 +254,10 @@ const COMMANDS = memoize(() => [
|
|
|
257
254
|
statusline,
|
|
258
255
|
stickers,
|
|
259
256
|
tag,
|
|
260
|
-
team,
|
|
261
257
|
teamAuto,
|
|
262
258
|
limites,
|
|
263
259
|
theme,
|
|
260
|
+
timeline,
|
|
264
261
|
feedback,
|
|
265
262
|
review,
|
|
266
263
|
ultrareview,
|
|
@@ -291,7 +288,6 @@ const COMMANDS = memoize(() => [
|
|
|
291
288
|
login(),
|
|
292
289
|
passes,
|
|
293
290
|
...(peersCmd ? [peersCmd] : []),
|
|
294
|
-
tasks,
|
|
295
291
|
telegram,
|
|
296
292
|
whatsapp,
|
|
297
293
|
...(workflowsCmd ? [workflowsCmd] : []),
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import figures from 'figures';
|
|
4
|
+
import { Box, Text, wrapText } from '../ink.js';
|
|
5
|
+
import { useAppState } from '../state/AppState.js';
|
|
6
|
+
import { getVisibleAgentTasks } from './CoordinatorAgentStatus.js';
|
|
7
|
+
import { isTerminalStatus } from './tasks/taskStatusUtils.js';
|
|
8
|
+
import { formatDuration, formatNumber } from '../utils/format.js';
|
|
9
|
+
export function AgentActivitySidebar({ width = 34 }) {
|
|
10
|
+
const tasks = useAppState(s => s.tasks);
|
|
11
|
+
const agentNameRegistry = useAppState(s => s.agentNameRegistry);
|
|
12
|
+
const viewingAgentTaskId = useAppState(s => s.viewingAgentTaskId);
|
|
13
|
+
const visibleTasks = getVisibleAgentTasks(tasks);
|
|
14
|
+
const [, setTick] = React.useState(0);
|
|
15
|
+
React.useEffect(() => {
|
|
16
|
+
if (visibleTasks.length === 0)
|
|
17
|
+
return;
|
|
18
|
+
const timer = setInterval(() => setTick(n => n + 1), 1000);
|
|
19
|
+
return () => clearInterval(timer);
|
|
20
|
+
}, [visibleTasks.length]);
|
|
21
|
+
const nameByAgentId = React.useMemo(() => {
|
|
22
|
+
const inv = new Map();
|
|
23
|
+
for (const [name, id] of agentNameRegistry)
|
|
24
|
+
inv.set(id, name);
|
|
25
|
+
return inv;
|
|
26
|
+
}, [agentNameRegistry]);
|
|
27
|
+
// Keep startup layout clean; only show the sidebar when there is real activity.
|
|
28
|
+
if (visibleTasks.length === 0)
|
|
29
|
+
return null;
|
|
30
|
+
return (_jsxs(Box, { width: width, minWidth: width, maxWidth: width, marginLeft: 1, borderStyle: "round", borderColor: "border", flexDirection: "column", children: [_jsx(Box, { paddingX: 1, children: _jsx(Text, { bold: true, color: "accent", children: "Agentes" }) }), _jsx(Box, { paddingX: 1, children: _jsxs(Text, { dimColor: true, children: [visibleTasks.length, " activos"] }) }), _jsx(Box, { flexDirection: "column", paddingX: 1, marginTop: 1, children: visibleTasks.slice(-8).map(task => {
|
|
31
|
+
const isRunning = !isTerminalStatus(task.status);
|
|
32
|
+
const pausedMs = task.totalPausedMs ?? 0;
|
|
33
|
+
const elapsedMs = Math.max(0, isRunning
|
|
34
|
+
? Date.now() - task.startTime - pausedMs
|
|
35
|
+
: (task.endTime ?? task.startTime) - task.startTime - pausedMs);
|
|
36
|
+
const elapsed = formatDuration(elapsedMs);
|
|
37
|
+
const name = nameByAgentId.get(task.id) ?? 'agente';
|
|
38
|
+
const desc = task.progress?.summary || task.description || 'Procesando';
|
|
39
|
+
const tokenCount = task.progress?.tokenCount;
|
|
40
|
+
const statusIcon = isRunning ? figures.play : figures.squareSmallFilled;
|
|
41
|
+
const activeMark = viewingAgentTaskId === task.id ? '*' : 'o';
|
|
42
|
+
const header = `${activeMark} ${statusIcon} ${name} - ${elapsed}`;
|
|
43
|
+
const headerText = wrapText(header, width - 4, 'truncate-end');
|
|
44
|
+
const descText = wrapText(desc, width - 4, 'truncate-end');
|
|
45
|
+
const tokenText = tokenCount !== undefined && tokenCount > 0
|
|
46
|
+
? `tokens ${formatNumber(tokenCount)}`
|
|
47
|
+
: 'tokens -';
|
|
48
|
+
return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: viewingAgentTaskId === task.id, children: headerText }), _jsx(Text, { dimColor: true, children: descText }), _jsx(Text, { dimColor: true, children: tokenText })] }, task.id));
|
|
49
|
+
}) })] }));
|
|
50
|
+
}
|
|
@@ -13,12 +13,12 @@ export function AgentProgressLine(t0) {
|
|
|
13
13
|
if ($[0] !== isBackgrounded || $[1] !== isResolved || $[2] !== lastToolInfo || $[3] !== taskDescription) {
|
|
14
14
|
t3 = () => {
|
|
15
15
|
if (!isResolved) {
|
|
16
|
-
return lastToolInfo || "
|
|
16
|
+
return lastToolInfo || "Inicializando\u2026";
|
|
17
17
|
}
|
|
18
18
|
if (isBackgrounded) {
|
|
19
|
-
return taskDescription ?? "
|
|
19
|
+
return taskDescription ?? "Ejecutándose en segundo plano";
|
|
20
20
|
}
|
|
21
|
-
return "
|
|
21
|
+
return "Listo";
|
|
22
22
|
};
|
|
23
23
|
$[0] = isBackgrounded;
|
|
24
24
|
$[1] = isResolved;
|
|
@@ -42,7 +42,7 @@ export function AgentProgressLine(t0) {
|
|
|
42
42
|
const t5 = !isResolved;
|
|
43
43
|
let t6;
|
|
44
44
|
if ($[7] !== agentType || $[8] !== color || $[9] !== description || $[10] !== descriptionColor || $[11] !== hideType || $[12] !== name) {
|
|
45
|
-
t6 = hideType ? _jsxs(_Fragment, { children: [_jsx(Text, { bold: true, children: name ?? description ?? agentType }), name && description && _jsxs(Text, { dimColor:
|
|
45
|
+
t6 = hideType ? _jsxs(_Fragment, { children: [_jsx(Text, { bold: true, color: color, children: name ?? description ?? agentType }), name && description && _jsxs(Text, { color: descriptionColor ?? color, dimColor: descriptionColor == null, children: [": ", description] })] }) : _jsxs(_Fragment, { children: [_jsx(Text, { bold: true, color: color, children: agentType }), description && _jsxs(_Fragment, { children: [" (", _jsx(Text, { color: descriptionColor ?? color, children: description }), ")"] })] });
|
|
46
46
|
$[7] = agentType;
|
|
47
47
|
$[8] = color;
|
|
48
48
|
$[9] = description;
|
|
@@ -56,7 +56,7 @@ export function AgentProgressLine(t0) {
|
|
|
56
56
|
}
|
|
57
57
|
let t7;
|
|
58
58
|
if ($[14] !== isBackgrounded || $[15] !== tokens || $[16] !== toolUseCount) {
|
|
59
|
-
t7 = !isBackgrounded && _jsxs(_Fragment, { children: [" \xB7 ", toolUseCount, "
|
|
59
|
+
t7 = !isBackgrounded && _jsxs(_Fragment, { children: [" \xB7 ", toolUseCount, " herramienta ", toolUseCount === 1 ? "usada" : "usadas", tokens !== null && _jsxs(_Fragment, { children: [" \u00B7 ", formatNumber(tokens), " tokens"] })] });
|
|
60
60
|
$[14] = isBackgrounded;
|
|
61
61
|
$[15] = tokens;
|
|
62
62
|
$[16] = toolUseCount;
|