@deepseek-harness-tui/dsh-tui 0.11.0 → 0.11.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 +6 -1
- package/cordis.patch.yml +4 -3
- package/cordis.yml +3 -2
- package/lib/types/activityPrefs.d.ts +24 -0
- package/lib/types/activityPrefs.d.ts.map +1 -1
- package/lib/types/activityPrefs.js +50 -1
- package/lib/types/adapter/channel/state.d.ts.map +1 -1
- package/lib/types/adapter/channel/state.js +3 -1
- package/lib/types/adapter/channel/ui-policy.d.ts +1 -1
- package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
- package/lib/types/adapter/channel/ui-policy.js +1 -1
- package/lib/types/adapter/ports/channel-ui.d.ts +8 -4
- package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-view.d.ts +0 -12
- package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel.d.ts +4 -1
- package/lib/types/adapter/ports/channel.d.ts.map +1 -1
- package/lib/types/components/ActivityLine.d.ts +7 -2
- package/lib/types/components/ActivityLine.d.ts.map +1 -1
- package/lib/types/components/ActivityLine.js +0 -8
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +2 -1
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +48 -2
- package/lib/types/components/SplitDiffView.d.ts.map +1 -1
- package/lib/types/components/SplitDiffView.js +2 -1
- package/lib/types/components/SubagentCard.d.ts.map +1 -1
- package/lib/types/components/SubagentCard.js +12 -6
- package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
- package/lib/types/components/SubagentDetailScene.js +8 -3
- package/lib/types/components/design-system/HintLine.d.ts +1 -2
- package/lib/types/components/design-system/HintLine.d.ts.map +1 -1
- package/lib/types/components/design-system/HintLine.js +1 -2
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -1
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +2 -1
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +2 -2
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +30 -26
- package/lib/types/dsh-adapter/activity-store.d.ts +221 -0
- package/lib/types/dsh-adapter/activity-store.d.ts.map +1 -0
- package/lib/types/dsh-adapter/activity-store.js +359 -0
- package/lib/types/dsh-adapter/channel/background-action.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/background-action.js +1 -0
- package/lib/types/dsh-adapter/channel/binding-events.d.ts +8 -6
- package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/binding-events.js +5 -4
- package/lib/types/dsh-adapter/channel/compaction.d.ts +0 -1
- package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/compaction.js +0 -2
- package/lib/types/dsh-adapter/channel/model-switch.d.ts +1 -2
- package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/model-switch.js +1 -1
- package/lib/types/dsh-adapter/channel/session-adoption.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/session-adoption.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-adoption.js +1 -0
- package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-live-adoption.js +1 -0
- package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-metadata.js +4 -2
- package/lib/types/dsh-adapter/channel/session-reset.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-reset.js +0 -1
- package/lib/types/dsh-adapter/channel/session-resume.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-resume.js +1 -0
- package/lib/types/dsh-adapter/channel/state.d.ts +6 -1
- package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/state.js +2 -2
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +21 -1
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/subagent-projection.js +173 -6
- package/lib/types/dsh-adapter/channel/types.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.d.ts +1 -1
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +15 -14
- package/lib/types/dsh-adapter/compat/index.d.ts +1 -1
- package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/compat/index.js +1 -1
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts +18 -0
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -1
- package/lib/types/dsh-adapter/compat/sessionLog.js +18 -3
- package/lib/types/dsh-adapter/compat/settings.d.ts +2 -0
- package/lib/types/dsh-adapter/compat/settings.d.ts.map +1 -1
- package/lib/types/dsh-adapter/compat/settings.js +14 -0
- package/lib/types/dsh-adapter/contract.d.ts +4 -3
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +5 -3
- package/lib/types/dsh-adapter/plugin.d.ts +1 -1
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +25 -8
- package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
- package/lib/types/dsh-adapter/settings-sections.js +7 -4
- package/lib/types/dsh-adapter/subagents.d.ts +16 -3
- package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
- package/lib/types/dsh-adapter/subagents.js +86 -24
- package/lib/types/history.d.ts +13 -1
- package/lib/types/history.d.ts.map +1 -1
- package/lib/types/history.js +15 -2
- package/lib/types/i18n.d.ts +90 -1
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +55 -1
- package/lib/types/ink/log-update.d.ts.map +1 -1
- package/lib/types/ink/log-update.js +19 -1
- package/lib/types/ink/selection.d.ts +28 -0
- package/lib/types/ink/selection.d.ts.map +1 -1
- package/lib/types/ink/selection.js +36 -1
- package/lib/types/screens/Chat.d.ts +4 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +13 -5
- package/lib/types/screens/StatusLine.d.ts +5 -1
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +2 -2
- package/lib/types/utils/fold-long-lines.d.ts +1 -1
- package/lib/types/utils/fold-long-lines.js +1 -1
- package/lib/types/working-activity.d.ts +10 -9
- package/lib/types/working-activity.d.ts.map +1 -1
- package/lib/types/working-activity.js +17 -10
- package/package.json +99 -95
- package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +0 -19
- package/lib/types/components/design-system/KeyboardShortcutHint.d.ts.map +0 -1
- package/lib/types/components/design-system/KeyboardShortcutHint.js +0 -14
- package/lib/types/dsh-adapter/channel/activity.d.ts +0 -20
- package/lib/types/dsh-adapter/channel/activity.d.ts.map +0 -1
- package/lib/types/dsh-adapter/channel/activity.js +0 -113
- package/lib/types/terminal-utils/terminal.d.ts +0 -18
- package/lib/types/terminal-utils/terminal.d.ts.map +0 -1
- package/lib/types/terminal-utils/terminal.js +0 -96
|
@@ -24,7 +24,7 @@ import { imagePathMediaType, parsePastedImagePath, stageClipboardFilePaths } fro
|
|
|
24
24
|
import { editInExternalEditor } from '../utils/externalEditor.js';
|
|
25
25
|
import { setPromptEditorNode, EditorButton } from './PromptEditor.js';
|
|
26
26
|
import { isHiddenCommandName, parseCommandName } from '../commands.js';
|
|
27
|
-
import { appendHistory } from '../history.js';
|
|
27
|
+
import { appendHistory, HISTORY_LIMIT, loadHistoryOldestFirst } from '../history.js';
|
|
28
28
|
import { mentionAtCaret } from '../utils/mentions.js';
|
|
29
29
|
import { preserveSelection } from '../utils/fileSuggestions.js';
|
|
30
30
|
import { isMod } from '../utils/modifiers.js';
|
|
@@ -35,7 +35,6 @@ import { HelpMenu } from './HelpMenu.js';
|
|
|
35
35
|
import { OverlayAbove } from './OverlayAbove.js';
|
|
36
36
|
import { SuggestionCard, cardContentWidth } from './SuggestionCard.js';
|
|
37
37
|
import { filterLiveImageBindings, isUsableDraftSnapshot, resolveBindingGeneration, } from './promptDraftCache.js';
|
|
38
|
-
const HISTORY_LIMIT = 50;
|
|
39
38
|
/**
|
|
40
39
|
* Visible text of the session-entry control at the head of the input row:
|
|
41
40
|
* U+2338 APL FUNCTIONAL SYMBOL QUAD COLON plus a separator space.
|
|
@@ -535,6 +534,8 @@ export function PromptInput({ channel, suspended = false, draftCache, helpOpen,
|
|
|
535
534
|
const history = React.useRef([]);
|
|
536
535
|
const historyIndex = React.useRef(-1);
|
|
537
536
|
const historyDraft = React.useRef({ text: '', images: [] });
|
|
537
|
+
/** The persisted history is read lazily, once per mount (see seedHistory). */
|
|
538
|
+
const historySeeded = React.useRef(false);
|
|
538
539
|
/** Visible `[Image #N]` labels are presentation only; this sidecar carries
|
|
539
540
|
* the non-reusable capability for the current draft. History/rewind text
|
|
540
541
|
* restored without this map can never bind to a later image by accident. */
|
|
@@ -1096,7 +1097,26 @@ export function PromptInput({ channel, suspended = false, draftCache, helpOpen,
|
|
|
1096
1097
|
return;
|
|
1097
1098
|
}
|
|
1098
1099
|
};
|
|
1100
|
+
/**
|
|
1101
|
+
* Seed the walk with the persisted history (issue #986). `↑`/`↓` used to
|
|
1102
|
+
* see only what this process submitted, so a restart lost every earlier
|
|
1103
|
+
* entry. Seeding before the first push keeps ONE chronological list —
|
|
1104
|
+
* persisted entries first, this run's submits behind them — instead of two
|
|
1105
|
+
* lists to merge at recall time. Restored text carries no image capability
|
|
1106
|
+
* (the file stores text only), which is also what keeps a recalled entry
|
|
1107
|
+
* from binding to a later staged image by accident.
|
|
1108
|
+
*/
|
|
1109
|
+
const seedHistory = () => {
|
|
1110
|
+
if (historySeeded.current)
|
|
1111
|
+
return;
|
|
1112
|
+
historySeeded.current = true;
|
|
1113
|
+
history.current = loadHistoryOldestFirst().map(entry => ({ text: entry.text, images: [] }));
|
|
1114
|
+
historyIndex.current = -1;
|
|
1115
|
+
};
|
|
1099
1116
|
const rememberHistory = (text, images) => {
|
|
1117
|
+
// Both entries into the walk (a submit and ↑) must see the persisted
|
|
1118
|
+
// prefix, so seed here rather than merging two lists later.
|
|
1119
|
+
seedHistory();
|
|
1100
1120
|
history.current.push({
|
|
1101
1121
|
text,
|
|
1102
1122
|
images: images.map(image => ({ ...image })),
|
|
@@ -1203,6 +1223,30 @@ export function PromptInput({ channel, suspended = false, draftCache, helpOpen,
|
|
|
1203
1223
|
setFileSelected(0);
|
|
1204
1224
|
channel.notify(t('input-retracted'), { timeoutMs: 2000 });
|
|
1205
1225
|
};
|
|
1226
|
+
/**
|
|
1227
|
+
* Withdraw the queued copy of the text `↑` just recalled (issue #986): the
|
|
1228
|
+
* message is still parked in the inbox, so editing it and sending again
|
|
1229
|
+
* would run the same text twice. Alt+Up withdraws explicitly; walking the
|
|
1230
|
+
* history to the same text has to land in the same place. The newest match
|
|
1231
|
+
* wins — `↑` walks newest-first and the queue is FIFO. A message the
|
|
1232
|
+
* running turn already claimed cannot be withdrawn, and saying so beats
|
|
1233
|
+
* pretending it was.
|
|
1234
|
+
*/
|
|
1235
|
+
const retractRecalledCopy = (text) => {
|
|
1236
|
+
let target;
|
|
1237
|
+
for (const item of channel.pending) {
|
|
1238
|
+
if (item.text === text)
|
|
1239
|
+
target = item;
|
|
1240
|
+
}
|
|
1241
|
+
if (target === undefined)
|
|
1242
|
+
return;
|
|
1243
|
+
if (channel.removePending(target.id)) {
|
|
1244
|
+
channel.notify(t('input-retracted'), { timeoutMs: 2000 });
|
|
1245
|
+
}
|
|
1246
|
+
else {
|
|
1247
|
+
channel.notify(t('input-cannot-retract'), { color: 'warning', timeoutMs: 2500 });
|
|
1248
|
+
}
|
|
1249
|
+
};
|
|
1206
1250
|
/**
|
|
1207
1251
|
* Ctrl+Enter: abort the running turn and send the input immediately — the
|
|
1208
1252
|
* model stops what it is doing and starts on this message right away.
|
|
@@ -2086,6 +2130,7 @@ export function PromptInput({ channel, suspended = false, draftCache, helpOpen,
|
|
|
2086
2130
|
setSelectedCommand(index => index <= 0 ? suggestions.length - 1 : index - 1);
|
|
2087
2131
|
return;
|
|
2088
2132
|
}
|
|
2133
|
+
seedHistory();
|
|
2089
2134
|
if (history.current.length === 0)
|
|
2090
2135
|
return;
|
|
2091
2136
|
if (historyIndex.current < 0) {
|
|
@@ -2101,6 +2146,7 @@ export function PromptInput({ channel, suspended = false, draftCache, helpOpen,
|
|
|
2101
2146
|
const entry = history.current[historyIndex.current];
|
|
2102
2147
|
if (entry === undefined)
|
|
2103
2148
|
return;
|
|
2149
|
+
retractRecalledCopy(entry.text);
|
|
2104
2150
|
updateFoldBlock(null);
|
|
2105
2151
|
restoreDraftImages(entry);
|
|
2106
2152
|
setInput(entry.text);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SplitDiffView.d.ts","sourceRoot":"","sources":["../../../src/components/SplitDiffView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAO7D,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AACjE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;
|
|
1
|
+
{"version":3,"file":"SplitDiffView.d.ts","sourceRoot":"","sources":["../../../src/components/SplitDiffView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAO7D,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AACjE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAI/E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAwR3D,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,OAAO,EACP,OAAO,EACP,cAAuB,EACvB,MAAM,GACP,EAAE;IACD,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAA;IACxC;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAC3C,GAAG,KAAK,CAAC,SAAS,CAwFlB"}
|
|
@@ -10,6 +10,7 @@ import { highlightLines, syntaxThemeSignature } from '../terminal-utils/syntaxRu
|
|
|
10
10
|
export { chalkFromToken } from '../terminal-utils/syntaxTheme.js';
|
|
11
11
|
export { parseAnsiRuns, highlightLines } from '../terminal-utils/syntaxRuns.js';
|
|
12
12
|
import { getTheme } from '../theme.js';
|
|
13
|
+
import { t } from '../i18n.js';
|
|
13
14
|
import { useTheme } from './design-system/ThemeProvider.js';
|
|
14
15
|
import { revealLinesOf } from './smoothReveal.js';
|
|
15
16
|
/** Replace tabs so width math and alignment hold (pi convention). */
|
|
@@ -274,5 +275,5 @@ export function SplitDiffView({ diffs, width, maxRows, verbose, toolBackground =
|
|
|
274
275
|
? undefined
|
|
275
276
|
: { segments: newRuns !== undefined ? mergeRuns(newRuns, row.newWords) : row.newWords };
|
|
276
277
|
return (_jsxs(Box, { flexDirection: "row", children: [_jsx(PaneLine, { side: oldSide, kind: row.kind === 'add' ? 'context' : row.kind, tone: "old", width: paneWidth, toolBackground: toolBackground }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { dimColor: true, children: "\u2502" }) }), _jsx(PaneLine, { side: newSide, kind: row.kind === 'del' ? 'context' : row.kind, tone: "new", width: paneWidth, toolBackground: toolBackground, padLeft: true })] }, index));
|
|
277
|
-
}), hidden > 0 && (_jsx(Text, { dimColor: true, children:
|
|
278
|
+
}), hidden > 0 && (_jsx(Text, { dimColor: true, children: t('lines-folded-expand', { n: hidden }) }))] }));
|
|
278
279
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubagentCard.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAGhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AAO9D,MAAM,WAAW,iBAAiB;IAAG,QAAQ,EAAE,aAAa,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CAAE;AAEpH,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,iBAAiB,GAAG,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"SubagentCard.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAGhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AAO9D,MAAM,WAAW,iBAAiB;IAAG,QAAQ,EAAE,aAAa,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CAAE;AAEpH,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAgD/F"}
|
|
@@ -9,7 +9,11 @@ function formatDuration(ms) {
|
|
|
9
9
|
}
|
|
10
10
|
export function SubagentCard({ subagent, focused, onClick }) {
|
|
11
11
|
const running = subagent.status === 'running' || subagent.status === 'starting';
|
|
12
|
-
|
|
12
|
+
// Only a live run ticks; discovered history (`unknown`) has no end time to
|
|
13
|
+
// count from, so it must not accumulate a fake growing duration.
|
|
14
|
+
const elapsed = running
|
|
15
|
+
? Date.now() - subagent.startedAt
|
|
16
|
+
: subagent.completedAt !== undefined ? subagent.completedAt - subagent.startedAt : undefined;
|
|
13
17
|
const total = subagent.tokens?.total ?? ((subagent.tokens?.input ?? 0) + (subagent.tokens?.output ?? 0) || 0);
|
|
14
18
|
// Mouse affordance: clickable cards tint on hover; the keyboard-focused
|
|
15
19
|
// card keeps its brand-color header (no double highlight).
|
|
@@ -22,12 +26,14 @@ export function SubagentCard({ subagent, focused, onClick }) {
|
|
|
22
26
|
const liveLine = running ? subagent.output[subagent.output.length - 1] : undefined;
|
|
23
27
|
const minimal = isMinimalMode();
|
|
24
28
|
const glyph = running ? (minimal ? '·' : '🟡')
|
|
25
|
-
: subagent.status === '
|
|
26
|
-
: (minimal ? '
|
|
29
|
+
: subagent.status === 'unknown' ? (minimal ? '·' : '⚪')
|
|
30
|
+
: subagent.status === 'failed' || subagent.status === 'cancelled' ? (minimal ? '×' : '🔴')
|
|
31
|
+
: (minimal ? '✓' : '🟢');
|
|
27
32
|
const glyphColor = minimal ? undefined
|
|
28
33
|
: running ? 'warning'
|
|
29
|
-
: subagent.status === '
|
|
30
|
-
: '
|
|
34
|
+
: subagent.status === 'unknown' ? 'subtle'
|
|
35
|
+
: subagent.status === 'failed' || subagent.status === 'cancelled' ? 'error'
|
|
36
|
+
: 'success';
|
|
31
37
|
const hoverTint = onClick !== undefined && hovered && !focused;
|
|
32
|
-
return _jsxs(Box, { flexDirection: "column", paddingLeft: 1, marginBottom: 1, onClick: onClick, onMouseEnter: onClick !== undefined ? () => setHovered(true) : undefined, onMouseLeave: onClick !== undefined ? () => setHovered(false) : undefined, backgroundColor: hoverTint ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: glyphColor, children: glyph }), _jsx(Text, { bold: true, color: focused ? 'accent' : undefined, children: `${t('subagent-card-prefix')}${subagent.description}` }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: ' · ' }), _jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }),
|
|
38
|
+
return _jsxs(Box, { flexDirection: "column", paddingLeft: 1, marginBottom: 1, onClick: onClick, onMouseEnter: onClick !== undefined ? () => setHovered(true) : undefined, onMouseLeave: onClick !== undefined ? () => setHovered(false) : undefined, backgroundColor: hoverTint ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: glyphColor, children: glyph }), _jsx(Text, { bold: true, color: focused ? 'accent' : undefined, children: `${t('subagent-card-prefix')}${subagent.description}` }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: ' · ' }), _jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }), _jsxs(Text, { dimColor: true, children: [elapsed !== undefined ? ` · ${formatDuration(elapsed)} · ` : ' · ', total || '—', " tok \u00B7 ", subagent.toolCalls.length, " tools"] })] })] }), liveLine && _jsx(Text, { dimColor: true, wrap: "truncate", children: ` │ ${liveLine}` })] });
|
|
33
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubagentDetailScene.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentDetailScene.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;
|
|
1
|
+
{"version":3,"file":"SubagentDetailScene.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentDetailScene.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAwGhE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,aAAa,CAAA;IACvB,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,WAAW,GACZ,EAAE,wBAAwB,GAAG,KAAK,CAAC,SAAS,CAiN5C"}
|
|
@@ -28,6 +28,8 @@ function statusGlyph(status) {
|
|
|
28
28
|
return { glyph: minimal ? '×' : '🔴', color: minimal ? undefined : 'error', label: 'failed' };
|
|
29
29
|
if (status === 'cancelled')
|
|
30
30
|
return { glyph: minimal ? '×' : '🔴', color: minimal ? undefined : 'error', label: 'cancelled' };
|
|
31
|
+
if (status === 'unknown')
|
|
32
|
+
return { glyph: minimal ? '·' : '⚪', color: minimal ? undefined : 'subtle', label: 'history' };
|
|
31
33
|
return { glyph: minimal ? '·' : '🟡', color: minimal ? undefined : 'warning', label: 'running' };
|
|
32
34
|
}
|
|
33
35
|
const PAGES = ['summary', 'output', 'tools'];
|
|
@@ -37,7 +39,7 @@ function StatRow({ label, children }) {
|
|
|
37
39
|
}
|
|
38
40
|
/** Two-column key/value stats grid (Kimi Code settled summary style). */
|
|
39
41
|
function StatGrid({ subagent, totalTokens, elapsed, statusLabel, statusColor }) {
|
|
40
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatRow, { label: t('subagent-status-label'), children: _jsx(Text, { color: statusColor, children: statusLabel }) }), _jsx(StatRow, { label: t('subagent-model'), children: _jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }) }), _jsx(StatRow, { label: t('subagent-duration'), children: _jsx(Text, { children: formatDuration(elapsed) }) }), _jsx(StatRow, { label: "tokens", children: _jsxs(Text, { children: [totalTokens || '—', subagent.tokens?.input !== undefined ? ` (in ${subagent.tokens.input} · out ${subagent.tokens.output ?? 0})` : ''] }) }), _jsx(StatRow, { label: t('subagent-tools'), children: _jsx(Text, { children: subagent.toolCalls.length }) }), _jsx(StatRow, { label: t('subagent-started'), children: _jsx(Text, { children: formatTimestamp(subagent.startedAt) }) }), subagent.completedAt !== undefined && (_jsx(StatRow, { label: t('subagent-completed'), children: _jsx(Text, { children: formatTimestamp(subagent.completedAt) }) }))] }));
|
|
42
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatRow, { label: t('subagent-status-label'), children: _jsx(Text, { color: statusColor, children: statusLabel }) }), _jsx(StatRow, { label: t('subagent-model'), children: _jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }) }), _jsx(StatRow, { label: t('subagent-duration'), children: _jsx(Text, { children: elapsed !== undefined ? formatDuration(elapsed) : '—' }) }), _jsx(StatRow, { label: "tokens", children: _jsxs(Text, { children: [totalTokens || '—', subagent.tokens?.input !== undefined ? ` (in ${subagent.tokens.input} · out ${subagent.tokens.output ?? 0})` : ''] }) }), _jsx(StatRow, { label: t('subagent-tools'), children: _jsx(Text, { children: subagent.toolCalls.length }) }), _jsx(StatRow, { label: t('subagent-started'), children: _jsx(Text, { children: formatTimestamp(subagent.startedAt) }) }), subagent.completedAt !== undefined && (_jsx(StatRow, { label: t('subagent-completed'), children: _jsx(Text, { children: formatTimestamp(subagent.completedAt) }) }))] }));
|
|
41
43
|
}
|
|
42
44
|
/** Tool args line: JSON-looking args get cli-highlight syntax colors (loaded
|
|
43
45
|
* lazily through the shared promise); anything else stays a dim flat line. */
|
|
@@ -77,7 +79,10 @@ export function SubagentDetailScene({ subagent, onBack, onInterrupt, }) {
|
|
|
77
79
|
const { rows, columns } = useTerminalSize();
|
|
78
80
|
const [page, setPage] = React.useState('summary');
|
|
79
81
|
const isRunning = subagent.status === 'running' || subagent.status === 'starting';
|
|
80
|
-
|
|
82
|
+
// Only a live run ticks; discovered history (`unknown`) shows no duration.
|
|
83
|
+
const elapsed = isRunning
|
|
84
|
+
? Date.now() - subagent.startedAt
|
|
85
|
+
: subagent.completedAt !== undefined ? subagent.completedAt - subagent.startedAt : undefined;
|
|
81
86
|
const info = statusGlyph(subagent.status);
|
|
82
87
|
const totalTokens = subagent.tokens?.total ?? ((subagent.tokens?.input ?? 0) + (subagent.tokens?.output ?? 0) || 0);
|
|
83
88
|
const pageIndex = PAGES.indexOf(page);
|
|
@@ -137,6 +142,6 @@ export function SubagentDetailScene({ subagent, onBack, onInterrupt, }) {
|
|
|
137
142
|
const active = page === name;
|
|
138
143
|
return (_jsxs(React.Fragment, { children: [_jsx(Box, { onClick: () => setPage(name), backgroundColor: !active ? 'userMessageBackgroundHover' : undefined, children: _jsx(Text, { color: active ? 'accent' : undefined, bold: active, inverse: active, children: ` ${label} ` }) }), _jsx(Text, { dimColor: true, children: name === PAGES[PAGES.length - 1] ? '' : '│' })] }, name));
|
|
139
144
|
};
|
|
140
|
-
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: info.color, bold: true, children: info.glyph }), _jsx(Text, { bold: true, children: `${t('subagent-card-prefix')}${subagent.description}` }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { color: info.color, children: info.label }), _jsx(Box, { flexGrow: 1 }), _jsx(ExitButton, { onClick: onBack })] }), _jsxs(Text, { children: [_jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }),
|
|
145
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: info.color, bold: true, children: info.glyph }), _jsx(Text, { bold: true, children: `${t('subagent-card-prefix')}${subagent.description}` }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { color: info.color, children: info.label }), _jsx(Box, { flexGrow: 1 }), _jsx(ExitButton, { onClick: onBack })] }), _jsxs(Text, { children: [_jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }), _jsxs(Text, { dimColor: true, children: [elapsed !== undefined ? ` · ${formatDuration(elapsed)} · ` : ' · ', totalTokens || '—', " tok \u00B7 ", subagent.toolCalls.length, " tools"] })] }), _jsxs(Text, { dimColor: true, children: [`${t('subagent-started')} ${formatTimestamp(subagent.startedAt)}`
|
|
141
146
|
+ (subagent.completedAt ? ` · ${t('subagent-completed')} ${formatTimestamp(subagent.completedAt)}` : ''), ` · id ${subagent.agentId}`] }), subagent.error && (_jsx(Box, { marginTop: 0, children: _jsx(Text, { color: "error", wrap: "wrap", children: `${t('subagent-error-label')}: ${subagent.error}` }) })), _jsxs(Box, { flexDirection: "row", gap: 0, marginTop: 1, children: [tab('summary', t('subagent-tab-summary')), tab('output', t('subagent-output-label')), tab('tools', t('subagent-tools')), _jsx(Text, { dimColor: true, children: ` ${pageIndex + 1}/${PAGES.length}` })] }), _jsx(Text, { dimColor: true, children: '─'.repeat(Math.max(20, Math.min(72, columns - 6))) }), _jsx(Box, { flexDirection: "column", paddingX: 1, maxHeight: Math.max(10, rows - 14), children: _jsxs(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, children: [page === 'summary' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatGrid, { subagent: subagent, totalTokens: totalTokens, elapsed: elapsed, statusLabel: info.label, statusColor: info.color }), subagent.summary && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { dimColor: true, bold: true, children: '─ summary ' }), _jsx(Text, { wrap: "wrap", children: subagent.summary })] })), !subagent.summary && (_jsx(Text, { dimColor: true, children: isRunning ? t('subagent-no-output') : t('subagent-no-summary') }))] })), page === 'output' && (subagent.outputEvents.length === 0 && subagent.output.length === 0 ? (_jsx(Text, { dimColor: true, children: t('subagent-no-output') })) : (subagent.outputEvents.map((line, index) => (_jsxs(Text, { wrap: "wrap", dimColor: line.kind === 'thinking' || line.kind === 'system', color: line.kind === 'error' ? 'error' : undefined, children: [line.kind === 'thinking' ? ' ⌁ ' : ' ', line.text, !line.settled && isRunning ? ' ▍' : ''] }, index))))), page === 'tools' && (subagent.toolCalls.length === 0 ? (_jsx(Text, { dimColor: true, children: t('subagent-no-tools') })) : (subagent.toolCalls.map((tool, index) => (_jsxs(Box, { flexDirection: "column", marginTop: index === 0 ? 0 : 1, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: tool.status === 'failed' ? 'error' : tool.status === 'running' ? 'warning' : 'success', children: tool.status === 'running' ? '·' : tool.status === 'failed' ? '×' : '✓' }), _jsx(Text, { color: toolNameColor(tool.name), children: tool.name }), tool.endedAt && _jsx(Text, { dimColor: true, children: formatDuration(tool.endedAt - tool.startedAt) })] }), tool.argsPreview && (_jsx(Box, { flexDirection: "row", paddingLeft: 2, children: _jsx(JsonArgsText, { raw: tool.argsPreview }) })), tool.resultPreview && (_jsx(Box, { flexDirection: "row", paddingLeft: 2, children: _jsx(Text, { dimColor: true, wrap: "wrap", children: `⎿ ${tool.resultPreview}` }) })), tool.error && (_jsx(Box, { flexDirection: "row", paddingLeft: 2, children: _jsx(Text, { color: "error", wrap: "wrap", children: tool.error }) }))] }, tool.id ?? index)))))] }) }), _jsx(Divider, { color: "subtle", title: "" }), _jsxs(Box, { marginTop: 0, flexDirection: "row", children: [_jsx(Text, { dimColor: true, children: `←/→ ${t('subagent-hint-page')} · ↑/↓ ${t('subagent-hint-scroll')}` }), isRunning && onInterrupt && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: ' · ' }), _jsx(Box, { onClick: () => onInterrupt(subagent.agentId), children: _jsx(Text, { dimColor: true, bold: true, color: "warning", children: "X interrupt" }) })] })), _jsx(Text, { dimColor: true, children: ` · Esc ${t('subagent-hint-back')}` })] })] }));
|
|
142
147
|
}
|
|
@@ -2,8 +2,7 @@ import React from 'react';
|
|
|
2
2
|
/**
|
|
3
3
|
* Localized shortcut-hint line: renders a `t('hint-*')` string, with the
|
|
4
4
|
* `**primary shortcut**` segment (the main action's key, wrapped in `**` in
|
|
5
|
-
* the dict) in bold
|
|
6
|
-
* prop used to give. Wrap in `<Text dimColor italic>` for the common dim
|
|
5
|
+
* the dict) in bold. Wrap in `<Text dimColor italic>` for the common dim
|
|
7
6
|
* styling, like the Byline it replaces.
|
|
8
7
|
*/
|
|
9
8
|
export declare function HintLine({ text }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HintLine.d.ts","sourceRoot":"","sources":["../../../../src/components/design-system/HintLine.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB
|
|
1
|
+
{"version":3,"file":"HintLine.d.ts","sourceRoot":"","sources":["../../../../src/components/design-system/HintLine.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,KAAK,CAAC,SAAS,CAUpE"}
|
|
@@ -3,8 +3,7 @@ import Text from './ThemedText.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Localized shortcut-hint line: renders a `t('hint-*')` string, with the
|
|
5
5
|
* `**primary shortcut**` segment (the main action's key, wrapped in `**` in
|
|
6
|
-
* the dict) in bold
|
|
7
|
-
* prop used to give. Wrap in `<Text dimColor italic>` for the common dim
|
|
6
|
+
* the dict) in bold. Wrap in `<Text dimColor italic>` for the common dim
|
|
8
7
|
* styling, like the Byline it replaces.
|
|
9
8
|
*/
|
|
10
9
|
export function HintLine({ text }) {
|
|
@@ -26,7 +26,8 @@ type Props = {
|
|
|
26
26
|
onClick?(event: ClickEvent): void;
|
|
27
27
|
};
|
|
28
28
|
/**
|
|
29
|
-
* Thinking block: settled rows fold to `⚓ Thinking
|
|
29
|
+
* Thinking block: settled rows fold to `⚓ Thinking` plus the localized
|
|
30
|
+
* ctrl+o expand hint (hint-expand-ctrl-o);
|
|
30
31
|
* streaming rows switch between a three-line preview and the full reasoning
|
|
31
32
|
* text on click. The live leading mark is a rotating braille spinner
|
|
32
33
|
* (`⠋⠙⠹…`, Kimi Code style), settling back to the static anchor (`⚓`). When
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantThinkingMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantThinkingMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAczB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAUjE,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB;;;sDAGkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4CAA4C;IAC5C,eAAe,EAAE,OAAO,CAAA;IACxB,4EAA4E;IAC5E,OAAO,EAAE,OAAO,CAAA;IAChB;;4CAEwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;8EAE0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CAClC,CAAA;AAED
|
|
1
|
+
{"version":3,"file":"AssistantThinkingMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantThinkingMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAczB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAUjE,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB;;;sDAGkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4CAA4C;IAC5C,eAAe,EAAE,OAAO,CAAA;IACxB,4EAA4E;IAC5E,OAAO,EAAE,OAAO,CAAA;IAChB;;4CAEwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;8EAE0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CAClC,CAAA;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,OAAO,EACP,SAAiB,EACjB,OAAe,EACf,UAAU,EACV,UAAkB,EAClB,OAAO,GACR,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAuIzB"}
|
|
@@ -17,7 +17,8 @@ import { isMinimalMode } from '../../minimalMode.js';
|
|
|
17
17
|
* to exactly this many rows, keeps the block height stream-independent. */
|
|
18
18
|
const PREVIEW_ROWS = 3;
|
|
19
19
|
/**
|
|
20
|
-
* Thinking block: settled rows fold to `⚓ Thinking
|
|
20
|
+
* Thinking block: settled rows fold to `⚓ Thinking` plus the localized
|
|
21
|
+
* ctrl+o expand hint (hint-expand-ctrl-o);
|
|
21
22
|
* streaming rows switch between a three-line preview and the full reasoning
|
|
22
23
|
* text on click. The live leading mark is a rotating braille spinner
|
|
23
24
|
* (`⠋⠙⠹…`, Kimi Code style), settling back to the static anchor (`⚓`). When
|
|
@@ -15,8 +15,8 @@ type Props = {
|
|
|
15
15
|
isExpanded?: boolean;
|
|
16
16
|
/**
|
|
17
17
|
* Mouse click (fullscreen): toggles the row's expansion — same action as
|
|
18
|
-
* clicking other transcript rows. Also makes the
|
|
19
|
-
* hint actionable with the mouse.
|
|
18
|
+
* clicking other transcript rows. Also makes the localized ctrl+o expand
|
|
19
|
+
* hint (lines-folded-expand) actionable with the mouse.
|
|
20
20
|
*/
|
|
21
21
|
onClick?(event: ClickEvent): void;
|
|
22
22
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantToolUseMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantToolUseMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAA8C,OAAO,EAAE,MAAM,8BAA8B,CAAA;AASvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAIjE,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,OAAO,CAAA;IACb,4CAA4C;IAC5C,eAAe,EAAE,OAAO,CAAA;IACxB,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAA;IAChB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,kEAAkE;IAClE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IACjC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,2EAA2E;IAC3E,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;8CAC0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;
|
|
1
|
+
{"version":3,"file":"AssistantToolUseMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantToolUseMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAA8C,OAAO,EAAE,MAAM,8BAA8B,CAAA;AASvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAIjE,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,OAAO,CAAA;IACb,4CAA4C;IAC5C,eAAe,EAAE,OAAO,CAAA;IACxB,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAA;IAChB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,kEAAkE;IAClE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IACjC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,2EAA2E;IAC3E,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;8CAC0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AA2FD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,KAAK,CAKtD;AAsVD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,IAAI,EACJ,eAAe,EACf,OAAO,EACP,UAAkB,EAClB,UAAkB,EAClB,OAAO,EACP,QAAQ,EACR,UAAmB,EACnB,cAAuB,EACvB,UAAU,EACV,mBAA2B,EAC3B,YAAoB,EACpB,KAAa,EACb,aAAa,GACd,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CA2PzB"}
|
|
@@ -14,25 +14,29 @@ import { foldLongLines } from '../../utils/fold-long-lines.js';
|
|
|
14
14
|
import { getLang, t } from '../../i18n.js';
|
|
15
15
|
import { revealLinesOf, snapReveal } from '../smoothReveal.js';
|
|
16
16
|
import { useRevealVersion } from '../../hooks/useRevealVersion.js';
|
|
17
|
-
/** Tool display names
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
/** Tool display names localize through the `tool-name-*` dictionary family
|
|
18
|
+
* (i18n.ts): DSH emits lowercase tool ids (`bash`), display names resolve
|
|
19
|
+
* per language — proper nouns (Bash, PowerShell) stay identical in zh.
|
|
20
|
+
* Unmapped ids (plugins, new upstream tools) fall back to the id with its
|
|
21
|
+
* first letter uppercased: that is a name, not copy — there is nothing to
|
|
22
|
+
* translate. Keys appear as literals here, so verify-i18n's dead-key scan
|
|
23
|
+
* sees them without a DYNAMIC_PREFIXES entry. */
|
|
24
|
+
const TOOL_NAME_KEYS = {
|
|
25
|
+
bash: 'tool-name-bash',
|
|
26
|
+
powershell: 'tool-name-powershell',
|
|
27
|
+
read: 'tool-name-read',
|
|
28
|
+
glob: 'tool-name-glob',
|
|
29
|
+
grep: 'tool-name-grep',
|
|
30
|
+
write: 'tool-name-write',
|
|
31
|
+
edit: 'tool-name-edit',
|
|
32
|
+
todo_write: 'tool-name-todo_write',
|
|
33
|
+
subagent: 'tool-name-subagent',
|
|
34
|
+
web_search: 'tool-name-web_search',
|
|
35
|
+
};
|
|
20
36
|
function displayName(name) {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
read: 'Read',
|
|
25
|
-
glob: 'Glob',
|
|
26
|
-
grep: 'Grep',
|
|
27
|
-
write: 'Write',
|
|
28
|
-
edit: 'Edit',
|
|
29
|
-
todo_write: 'TodoWrite',
|
|
30
|
-
subagent: 'Task',
|
|
31
|
-
web_search: 'WebSearch',
|
|
32
|
-
};
|
|
33
|
-
const mapped = KNOWN[name];
|
|
34
|
-
if (mapped)
|
|
35
|
-
return mapped;
|
|
37
|
+
const key = TOOL_NAME_KEYS[name];
|
|
38
|
+
if (key !== undefined)
|
|
39
|
+
return t(key);
|
|
36
40
|
if (name.length === 0)
|
|
37
41
|
return name;
|
|
38
42
|
return name[0].toUpperCase() + name.slice(1);
|
|
@@ -145,10 +149,10 @@ function viewLines(view) {
|
|
|
145
149
|
const out = (('output' in view ? view.output : undefined) ?? '').trimEnd();
|
|
146
150
|
const lines = out === '' ? [] : out.split('\n').map(plain);
|
|
147
151
|
if ('exitCode' in view && view.exitCode !== undefined && view.exitCode !== 0) {
|
|
148
|
-
lines.push({ text:
|
|
152
|
+
lines.push({ text: t('tool-exit-code', { code: view.exitCode }), tone: 'error' });
|
|
149
153
|
}
|
|
150
154
|
if ('signal' in view && view.signal !== undefined) {
|
|
151
|
-
lines.push({ text:
|
|
155
|
+
lines.push({ text: t('tool-killed-signal', { name: String(view.signal) }), tone: 'error' });
|
|
152
156
|
}
|
|
153
157
|
return lines;
|
|
154
158
|
}
|
|
@@ -160,7 +164,7 @@ function viewLines(view) {
|
|
|
160
164
|
if (view.shape === 'paths') {
|
|
161
165
|
const lines = view.paths.map(plain);
|
|
162
166
|
if (view.truncated)
|
|
163
|
-
lines.push(dim(
|
|
167
|
+
lines.push(dim(t('search-results-total', { n: view.total })));
|
|
164
168
|
return lines;
|
|
165
169
|
}
|
|
166
170
|
const lines = [];
|
|
@@ -187,7 +191,7 @@ function capLines(lines, max, verbose) {
|
|
|
187
191
|
return lines;
|
|
188
192
|
return [
|
|
189
193
|
...lines.slice(0, max),
|
|
190
|
-
{ ...dim(
|
|
194
|
+
{ ...dim(t('lines-folded-expand', { n: lines.length - max })), revealOnHover: true },
|
|
191
195
|
];
|
|
192
196
|
}
|
|
193
197
|
/** Long-line clip for the body rows (utils/fold-long-lines.ts): the line cap
|
|
@@ -326,7 +330,7 @@ function HeaderTitle({ name, title, isTerminal, folded, displayArgs, argsLanguag
|
|
|
326
330
|
return (_jsxs(_Fragment, { children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }), displayArgs !== '' && (_jsxs(Box, { flexWrap: "nowrap", ...headerTooltip, children: [_jsx(Text, { children: "(" }), _jsx(SyntaxText, { text: clipHeaderArgs(displayArgs), sourceText: displayArgs, language: argsLanguage }), _jsx(Text, { children: ")" })] }))] }));
|
|
327
331
|
}
|
|
328
332
|
if (isTerminal) {
|
|
329
|
-
return (_jsxs(_Fragment, { children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }), _jsx(Box, { flexWrap: "nowrap", ...headerTooltip, children: folded === undefined ? (_jsxs(Text, { children: ["(", title, ")"] })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: ["(", folded.first, ")"] }), folded.hiddenLines > 0 && (_jsx(Text, { dimColor: true, children: `
|
|
333
|
+
return (_jsxs(_Fragment, { children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }), _jsx(Box, { flexWrap: "nowrap", ...headerTooltip, children: folded === undefined ? (_jsxs(Text, { children: ["(", title, ")"] })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: ["(", folded.first, ")"] }), folded.hiddenLines > 0 && (_jsx(Text, { dimColor: true, children: ` ${t('lines-folded-expand', { n: folded.hiddenLines })}` }))] })) })] }));
|
|
330
334
|
}
|
|
331
335
|
const trimmed = title.trim();
|
|
332
336
|
if (trimmed === '') {
|
|
@@ -439,7 +443,7 @@ export function AssistantToolUseMessage({ tool, marginTopOnTurn, verbose, isSele
|
|
|
439
443
|
body = result.trimEnd().split('\n').map(plain);
|
|
440
444
|
}
|
|
441
445
|
if (isRunning && body.length === 0) {
|
|
442
|
-
body = [dim(
|
|
446
|
+
body = [dim(t('tool-running-elapsed', { duration: formatDuration(Math.max(0, Date.now() - (tool.startedAt ?? Date.now()))) }))];
|
|
443
447
|
}
|
|
444
448
|
}
|
|
445
449
|
const cap = view?.card === 'diff' ? DIFF_BODY_MAX_LINES : TEXT_BODY_MAX_LINES;
|
|
@@ -479,8 +483,8 @@ export function AssistantToolUseMessage({ tool, marginTopOnTurn, verbose, isSele
|
|
|
479
483
|
// Hover affordance for the click-to-toggle row: the theme's tool-card blue
|
|
480
484
|
// face marks the call's content area while the pointer dwells (the
|
|
481
485
|
// toolBackground treatment steps up one level to the strong card face), the
|
|
482
|
-
// collapsed
|
|
483
|
-
// clock stops dimming, and a ▾/▴ discloses the row is a toggle.
|
|
486
|
+
// collapsed fold hint (lines-folded-expand) steps from dim to text, the
|
|
487
|
+
// elapsed clock stops dimming, and a ▾/▴ discloses the row is a toggle.
|
|
484
488
|
// No layout change: the indicator is a fixed column on the header line, the
|
|
485
489
|
// body never moves.
|
|
486
490
|
const [hovered, setHovered] = React.useState(false);
|