@deepseek-harness-tui/dsh-tui 0.8.7 → 0.9.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.
- package/README.md +29 -10
- package/bin/dsh-tui.js +1 -1
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +4 -2
- package/lib/types/components/ActivityPicker.d.ts +4 -1
- package/lib/types/components/ActivityPicker.d.ts.map +1 -1
- package/lib/types/components/ActivityPicker.js +2 -2
- package/lib/types/components/BtwPanel.d.ts.map +1 -1
- package/lib/types/components/BtwPanel.js +1 -1
- package/lib/types/components/Chat/SubagentMessage.d.ts +2 -1
- package/lib/types/components/Chat/SubagentMessage.d.ts.map +1 -1
- package/lib/types/components/Chat/SubagentMessage.js +11 -3
- package/lib/types/components/CommandSuggestions.d.ts +21 -4
- package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
- package/lib/types/components/CommandSuggestions.js +41 -14
- package/lib/types/components/EffortSlider.d.ts +4 -1
- package/lib/types/components/EffortSlider.d.ts.map +1 -1
- package/lib/types/components/EffortSlider.js +4 -2
- package/lib/types/components/ExtensionDialog.js +6 -2
- package/lib/types/components/FileSuggestions.d.ts +26 -5
- package/lib/types/components/FileSuggestions.d.ts.map +1 -1
- package/lib/types/components/FileSuggestions.js +53 -16
- package/lib/types/components/GoalTodoPanel.d.ts +26 -2
- package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
- package/lib/types/components/GoalTodoPanel.js +86 -17
- package/lib/types/components/HelpMenu.d.ts +7 -1
- package/lib/types/components/HelpMenu.d.ts.map +1 -1
- package/lib/types/components/HelpMenu.js +12 -4
- package/lib/types/components/HistorySearchDialog.d.ts +4 -1
- package/lib/types/components/HistorySearchDialog.d.ts.map +1 -1
- package/lib/types/components/HistorySearchDialog.js +2 -2
- package/lib/types/components/LangPicker.d.ts +14 -0
- package/lib/types/components/LangPicker.d.ts.map +1 -0
- package/lib/types/components/LangPicker.js +17 -0
- package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
- package/lib/types/components/LoadedContextPanel.js +3 -1
- package/lib/types/components/LogoV2.d.ts +5 -1
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +12 -3
- package/lib/types/components/Markdown.d.ts.map +1 -1
- package/lib/types/components/Markdown.js +12 -3
- package/lib/types/components/MessageList.d.ts +43 -2
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +553 -41
- package/lib/types/components/ModelPicker.d.ts +4 -1
- package/lib/types/components/ModelPicker.d.ts.map +1 -1
- package/lib/types/components/ModelPicker.js +2 -2
- package/lib/types/components/PermissionsPicker.d.ts +21 -0
- package/lib/types/components/PermissionsPicker.d.ts.map +1 -0
- package/lib/types/components/PermissionsPicker.js +27 -0
- package/lib/types/components/PlanPicker.d.ts +15 -0
- package/lib/types/components/PlanPicker.d.ts.map +1 -0
- package/lib/types/components/PlanPicker.js +18 -0
- package/lib/types/components/PresetPicker.d.ts +4 -1
- package/lib/types/components/PresetPicker.d.ts.map +1 -1
- package/lib/types/components/PresetPicker.js +2 -2
- package/lib/types/components/PromptInput.d.ts +4 -3
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +273 -50
- package/lib/types/components/RewindPicker.d.ts +12 -1
- package/lib/types/components/RewindPicker.d.ts.map +1 -1
- package/lib/types/components/RewindPicker.js +6 -4
- package/lib/types/components/ScrollbarGutter.d.ts +28 -0
- package/lib/types/components/ScrollbarGutter.d.ts.map +1 -0
- package/lib/types/components/ScrollbarGutter.js +68 -0
- package/lib/types/components/Select.d.ts +8 -1
- package/lib/types/components/Select.d.ts.map +1 -1
- package/lib/types/components/Select.js +4 -2
- package/lib/types/components/SkillsPicker.d.ts +4 -1
- package/lib/types/components/SkillsPicker.d.ts.map +1 -1
- package/lib/types/components/SkillsPicker.js +2 -2
- package/lib/types/components/SubagentCard.d.ts +2 -1
- package/lib/types/components/SubagentCard.d.ts.map +1 -1
- package/lib/types/components/SubagentCard.js +6 -1
- package/lib/types/components/SubagentDashboard.d.ts +4 -0
- package/lib/types/components/SubagentDashboard.d.ts.map +1 -1
- package/lib/types/components/SubagentDashboard.js +9 -1
- package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
- package/lib/types/components/SubagentDetailScene.js +5 -4
- package/lib/types/components/SuggestionCard.d.ts +63 -0
- package/lib/types/components/SuggestionCard.d.ts.map +1 -0
- package/lib/types/components/SuggestionCard.js +77 -0
- package/lib/types/components/ThemePicker.d.ts +4 -1
- package/lib/types/components/ThemePicker.d.ts.map +1 -1
- package/lib/types/components/ThemePicker.js +2 -2
- package/lib/types/components/ThinkingToggle.d.ts +4 -1
- package/lib/types/components/ThinkingToggle.d.ts.map +1 -1
- package/lib/types/components/ThinkingToggle.js +2 -2
- package/lib/types/components/TimelineRail.d.ts +53 -0
- package/lib/types/components/TimelineRail.d.ts.map +1 -0
- package/lib/types/components/TimelineRail.js +190 -0
- package/lib/types/components/WorkspaceFlowPicker.d.ts +6 -1
- package/lib/types/components/WorkspaceFlowPicker.d.ts.map +1 -1
- package/lib/types/components/WorkspaceFlowPicker.js +4 -2
- package/lib/types/components/WorkspaceMenuPicker.d.ts +19 -0
- package/lib/types/components/WorkspaceMenuPicker.d.ts.map +1 -0
- package/lib/types/components/WorkspaceMenuPicker.js +19 -0
- package/lib/types/components/WorkspacePicker.d.ts +4 -1
- package/lib/types/components/WorkspacePicker.d.ts.map +1 -1
- package/lib/types/components/WorkspacePicker.js +2 -2
- package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -1
- package/lib/types/components/approvals/ApprovalPanel.js +5 -1
- package/lib/types/components/design-system/ListItem.d.ts +8 -1
- package/lib/types/components/design-system/ListItem.d.ts.map +1 -1
- package/lib/types/components/design-system/ListItem.js +8 -3
- package/lib/types/components/messages/AssistantTextMessage.d.ts +5 -2
- package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantTextMessage.js +6 -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 +10 -4
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +8 -1
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +4 -2
- package/lib/types/components/messages/UserPromptMessage.d.ts +2 -1
- package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.js +34 -2
- package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
- package/lib/types/components/questions/PlanReviewPanel.js +13 -2
- package/lib/types/components/sessions/SessionListRow.d.ts +4 -1
- package/lib/types/components/sessions/SessionListRow.d.ts.map +1 -1
- package/lib/types/components/sessions/SessionListRow.js +4 -2
- package/lib/types/components/trajectory/HotspotView.d.ts +7 -1
- package/lib/types/components/trajectory/HotspotView.d.ts.map +1 -1
- package/lib/types/components/trajectory/HotspotView.js +8 -2
- package/lib/types/components/trajectory/Ledger.d.ts +9 -1
- package/lib/types/components/trajectory/Ledger.d.ts.map +1 -1
- package/lib/types/components/trajectory/Ledger.js +23 -5
- package/lib/types/components/trajectory/WaveBand.d.ts +10 -1
- package/lib/types/components/trajectory/WaveBand.d.ts.map +1 -1
- package/lib/types/components/trajectory/WaveBand.js +7 -2
- package/lib/types/dsh-adapter/channel.d.ts +27 -6
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +432 -66
- package/lib/types/dsh-adapter/contract.d.ts +58 -18
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +124 -36
- package/lib/types/dsh-adapter/index.d.ts +10 -2
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +10 -13
- package/lib/types/dsh-adapter/plugin.d.ts +0 -9
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +136 -6
- package/lib/types/i18n.d.ts +194 -16
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +73 -10
- package/lib/types/ink/components/AlternateScreen.d.ts.map +1 -1
- package/lib/types/ink/components/AlternateScreen.js +13 -1
- package/lib/types/ink/components/App.d.ts +12 -1
- package/lib/types/ink/components/App.d.ts.map +1 -1
- package/lib/types/ink/components/App.js +101 -4
- package/lib/types/ink/components/ClockContext.d.ts.map +1 -1
- package/lib/types/ink/components/ClockContext.js +2 -0
- package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
- package/lib/types/ink/components/ScrollBox.js +170 -91
- package/lib/types/ink/constants.d.ts +9 -0
- package/lib/types/ink/constants.d.ts.map +1 -1
- package/lib/types/ink/constants.js +9 -0
- package/lib/types/ink/events/click-event.d.ts +7 -16
- package/lib/types/ink/events/click-event.d.ts.map +1 -1
- package/lib/types/ink/events/click-event.js +16 -19
- package/lib/types/ink/events/event-handlers.d.ts +11 -1
- package/lib/types/ink/events/event-handlers.d.ts.map +1 -1
- package/lib/types/ink/events/event-handlers.js +2 -0
- package/lib/types/ink/events/input-event.d.ts +9 -0
- package/lib/types/ink/events/input-event.d.ts.map +1 -1
- package/lib/types/ink/events/input-event.js +4 -0
- package/lib/types/ink/events/pointer-event.d.ts +61 -0
- package/lib/types/ink/events/pointer-event.d.ts.map +1 -0
- package/lib/types/ink/events/pointer-event.js +61 -0
- package/lib/types/ink/events/wheel-event.d.ts +17 -0
- package/lib/types/ink/events/wheel-event.d.ts.map +1 -0
- package/lib/types/ink/events/wheel-event.js +20 -0
- package/lib/types/ink/geometry-trace.d.ts +51 -0
- package/lib/types/ink/geometry-trace.d.ts.map +1 -0
- package/lib/types/ink/geometry-trace.js +83 -0
- package/lib/types/ink/hit-test.d.ts +56 -1
- package/lib/types/ink/hit-test.d.ts.map +1 -1
- package/lib/types/ink/hit-test.js +146 -8
- package/lib/types/ink/ink.d.ts +58 -1
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +268 -52
- package/lib/types/ink/node-cache.d.ts +5 -0
- package/lib/types/ink/node-cache.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.d.ts +8 -0
- package/lib/types/ink/parse-keypress.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.js +101 -12
- package/lib/types/ink/render-node-to-output.d.ts +16 -3
- package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
- package/lib/types/ink/render-node-to-output.js +144 -25
- package/lib/types/ink/selection.d.ts +29 -4
- package/lib/types/ink/selection.d.ts.map +1 -1
- package/lib/types/ink/selection.js +41 -5
- package/lib/types/ink/timeline-rail.d.ts +138 -0
- package/lib/types/ink/timeline-rail.d.ts.map +1 -0
- package/lib/types/ink/timeline-rail.js +179 -0
- package/lib/types/ink/wrap-text.d.ts.map +1 -1
- package/lib/types/ink/wrap-text.js +47 -5
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +819 -337
- package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
- package/lib/types/screens/SessionBrowser.js +56 -29
- package/lib/types/screens/Settings.d.ts.map +1 -1
- package/lib/types/screens/Settings.js +64 -22
- package/lib/types/screens/StatusLine.d.ts +2 -1
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +17 -1
- package/lib/types/screens/TrajectoryScene.d.ts.map +1 -1
- package/lib/types/screens/TrajectoryScene.js +81 -14
- package/lib/types/screens/chatOverlay.d.ts +221 -0
- package/lib/types/screens/chatOverlay.d.ts.map +1 -0
- package/lib/types/screens/chatOverlay.js +114 -0
- package/lib/types/tips.d.ts.map +1 -1
- package/lib/types/tips.js +64 -10
- package/lib/types/tuiDisplayPrefs.d.ts +15 -0
- package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
- package/lib/types/tuiDisplayPrefs.js +9 -0
- package/lib/types/utils/debug.d.ts +10 -0
- package/lib/types/utils/debug.d.ts.map +1 -1
- package/lib/types/utils/debug.js +24 -0
- package/lib/types/utils/fileSuggestions.d.ts +19 -0
- package/lib/types/utils/fileSuggestions.d.ts.map +1 -0
- package/lib/types/utils/fileSuggestions.js +40 -0
- package/lib/types/utils/mentions.d.ts.map +1 -1
- package/lib/types/utils/mentions.js +3 -1
- package/lib/types/utils/paths.d.ts.map +1 -1
- package/lib/types/utils/paths.js +1 -0
- package/package.json +69 -66
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AskUserQuestionPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/AskUserQuestionPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AASvE,MAAM,MAAM,yBAAyB,GAAG;IACtC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;QAC9B;;oEAE4D;QAC5D,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;QAClC;0EACkE;QAClE,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;CAC9B,CAAA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,EAAE,yBAAyB,GAAG,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"AskUserQuestionPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/AskUserQuestionPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AASvE,MAAM,MAAM,yBAAyB,GAAG;IACtC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;QAC9B;;oEAE4D;QAC5D,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;QAClC;0EACkE;QAClE,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;CAC9B,CAAA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,EAAE,yBAAyB,GAAG,KAAK,CAAC,SAAS,CA+Y7C"}
|
|
@@ -241,7 +241,39 @@ export function AskUserQuestionPanel({ question, position, total, answered, onAn
|
|
|
241
241
|
const remaining = total - answered;
|
|
242
242
|
const headerTitle = ` ${t('question-header-progress', { position, total, remaining: remaining > 1 ? t('question-remaining-more', { n: remaining }) : '' })} `;
|
|
243
243
|
const cursorChar = customCursor < customText.length ? customText[customCursor] : ' ';
|
|
244
|
-
|
|
244
|
+
/** Mouse: click the input row to focus it (same as Tab). */
|
|
245
|
+
const focusInputRow = () => {
|
|
246
|
+
if (hideCustomInput)
|
|
247
|
+
return;
|
|
248
|
+
setFocusIndex(options.length);
|
|
249
|
+
setError(null);
|
|
250
|
+
};
|
|
251
|
+
/**
|
|
252
|
+
* Mouse: click an option row. Multi-select toggles the checkmark (same as
|
|
253
|
+
* Space); single-select answers immediately with that option plus any
|
|
254
|
+
* typed text (same as focusing the row and pressing Enter) — one click =
|
|
255
|
+
* one answer, matching ApprovalPanel's click semantics.
|
|
256
|
+
*/
|
|
257
|
+
const clickOption = (index) => {
|
|
258
|
+
if (multiSelect) {
|
|
259
|
+
setChecked(previous => {
|
|
260
|
+
const next = new Set(previous);
|
|
261
|
+
if (next.has(index))
|
|
262
|
+
next.delete(index);
|
|
263
|
+
else
|
|
264
|
+
next.add(index);
|
|
265
|
+
return next;
|
|
266
|
+
});
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
const label = options[index]?.label;
|
|
270
|
+
if (label === undefined)
|
|
271
|
+
return;
|
|
272
|
+
const text = customText.trim();
|
|
273
|
+
onAnswer({ selected: [label], ...(text !== '' ? { custom: text } : {}) });
|
|
274
|
+
};
|
|
275
|
+
const [hoverIndex, setHoverIndex] = React.useState(-1);
|
|
276
|
+
const renderInputRow = () => (_jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, onClick: focusInputRow, onMouseEnter: () => setHoverIndex(options.length), onMouseLeave: () => setHoverIndex(current => (current === options.length ? -1 : current)), backgroundColor: hoverIndex === options.length && !inputFocused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'claude' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'claude' : 'suggestion', children: PENCIL }) }), _jsxs(Box, { flexDirection: "row", marginLeft: 1, children: [_jsx(Text, { bold: inputFocused, color: inputFocused ? 'claude' : 'suggestion', children: t('question-custom-tab') }), attached !== null && (_jsx(Text, { color: "suggestion", children: t('question-attached-label', { label: attached }) })), _jsx(Text, { dimColor: true, children: "\uFF1A" }), customText === '' && !inputFocused ? (_jsx(Text, { ref: caretRef, dimColor: true, children: t('question-direct-input') })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: customText.slice(0, customCursor) }), inputFocused
|
|
245
277
|
? _jsx(Text, { ref: caretRef, inverse: true, children: cursorChar })
|
|
246
278
|
: _jsx(Text, { ref: caretRef, color: "suggestion", children: "\u258F" }), _jsx(Text, { wrap: "wrap", children: customText.slice(inputFocused ? customCursor + 1 : customCursor) })] }))] })] }));
|
|
247
279
|
const renderOptions = () => (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [options.slice(optionWindow.start, optionWindow.end).map((option, index) => {
|
|
@@ -259,7 +291,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, onAn
|
|
|
259
291
|
const description = windowedOptions
|
|
260
292
|
? option.description?.replace(/\s+/gu, ' ').trim()
|
|
261
293
|
: option.description;
|
|
262
|
-
return (_jsxs(Box, { flexDirection: "row", marginTop: !windowedOptions && focused ? 1 : 0, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'claude' : undefined, bold: focused, children: pointer }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'claude' : undefined, bold: selected, children: selected ? (multiSelect ? CHECKED : '●') : UNCHECKED }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [_jsx(Text, { bold: focused || selected, color: focused ? 'claude' : undefined, wrap: windowedOptions ? 'truncate' : 'wrap', children: label }), description !== undefined && (_jsx(Text, { dimColor: true, wrap: windowedOptions ? 'truncate' : 'wrap', children: description }))] })] }, `${absoluteIndex}:${option.label}`));
|
|
294
|
+
return (_jsxs(Box, { flexDirection: "row", marginTop: !windowedOptions && focused ? 1 : 0, onClick: () => clickOption(absoluteIndex), onMouseEnter: () => setHoverIndex(absoluteIndex), onMouseLeave: () => setHoverIndex(current => (current === absoluteIndex ? -1 : current)), backgroundColor: hoverIndex === absoluteIndex && !focused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'claude' : undefined, bold: focused, children: pointer }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'claude' : undefined, bold: selected, children: selected ? (multiSelect ? CHECKED : '●') : UNCHECKED }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [_jsx(Text, { bold: focused || selected, color: focused ? 'claude' : undefined, wrap: windowedOptions ? 'truncate' : 'wrap', children: label }), description !== undefined && (_jsx(Text, { dimColor: true, wrap: windowedOptions ? 'truncate' : 'wrap', children: description }))] })] }, `${absoluteIndex}:${option.label}`));
|
|
263
295
|
}), hideCustomInput ? null : renderInputRow()] }));
|
|
264
296
|
const hintParts = inputFocused
|
|
265
297
|
? [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlanReviewPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/PlanReviewPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAKvE,MAAM,MAAM,oBAAoB,GAAG;IACjC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;CAC9B,CAAA;AAED,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,EAAE,oBAAoB,GAAG,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"PlanReviewPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/PlanReviewPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAKvE,MAAM,MAAM,oBAAoB,GAAG;IACjC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;CAC9B,CAAA;AAED,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,EAAE,oBAAoB,GAAG,KAAK,CAAC,SAAS,CAmQxC"}
|
|
@@ -168,11 +168,22 @@ export function PlanReviewPanel({ question, onAnswer, onCancel, }) {
|
|
|
168
168
|
}
|
|
169
169
|
}, { isActive: true });
|
|
170
170
|
const cursorChar = cursor < feedback.length ? feedback[cursor] : ' ';
|
|
171
|
+
/** Mouse: click a decision row = focus it + submit (same as Enter). */
|
|
172
|
+
const [hoverIndex, setHoverIndex] = React.useState(-1);
|
|
173
|
+
const clickOption = (index) => {
|
|
174
|
+
setFocusIndex(index);
|
|
175
|
+
submitOption(index);
|
|
176
|
+
};
|
|
177
|
+
/** Mouse: click the feedback row to focus it. */
|
|
178
|
+
const focusFeedbackRow = () => {
|
|
179
|
+
setFocusIndex(options.length);
|
|
180
|
+
setError(null);
|
|
181
|
+
};
|
|
171
182
|
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, paddingLeft: 2, paddingRight: 2, width: "100%", children: [_jsx(Divider, { color: "permission", title: ` ${question.header ?? t('plan-review-fallback-header')} `, padding: 4 }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, wrap: "wrap", children: question.question }), question.detail !== undefined && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(Markdown, { children: question.detail }) }))] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [options.map((option, index) => {
|
|
172
183
|
const focused = index === focusIndex;
|
|
173
184
|
const isApprove = option.label === approveLabel;
|
|
174
|
-
return (_jsxs(Box, { flexDirection: "row", marginTop: focused ? 1 : 0, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'claude' : undefined, bold: focused, children: focused ? POINTER : ' ' }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [_jsxs(Text, { bold: focused, color: focused || isApprove ? 'claude' : undefined, wrap: "wrap", children: [index + 1, ". ", option.label] }), option.description !== undefined && (_jsx(Text, { dimColor: true, wrap: "wrap", children: option.description }))] })] }, option.label));
|
|
175
|
-
}), _jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'claude' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'claude' : 'suggestion', children: PENCIL }) }), _jsx(Box, { flexDirection: "row", marginLeft: 1, children: feedback === '' && !inputFocused ? (_jsx(Text, { ref: caretRef, dimColor: true, children: t('plan-review-feedback-placeholder') })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: feedback.slice(0, cursor) }), inputFocused
|
|
185
|
+
return (_jsxs(Box, { flexDirection: "row", marginTop: focused ? 1 : 0, onClick: () => clickOption(index), onMouseEnter: () => setHoverIndex(index), onMouseLeave: () => setHoverIndex(current => (current === index ? -1 : current)), backgroundColor: hoverIndex === index && !focused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'claude' : undefined, bold: focused, children: focused ? POINTER : ' ' }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [_jsxs(Text, { bold: focused, color: focused || isApprove ? 'claude' : undefined, wrap: "wrap", children: [index + 1, ". ", option.label] }), option.description !== undefined && (_jsx(Text, { dimColor: true, wrap: "wrap", children: option.description }))] })] }, option.label));
|
|
186
|
+
}), _jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, onClick: focusFeedbackRow, onMouseEnter: () => setHoverIndex(options.length), onMouseLeave: () => setHoverIndex(current => (current === options.length ? -1 : current)), backgroundColor: hoverIndex === options.length && !inputFocused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'claude' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'claude' : 'suggestion', children: PENCIL }) }), _jsx(Box, { flexDirection: "row", marginLeft: 1, children: feedback === '' && !inputFocused ? (_jsx(Text, { ref: caretRef, dimColor: true, children: t('plan-review-feedback-placeholder') })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: feedback.slice(0, cursor) }), inputFocused
|
|
176
187
|
? _jsx(Text, { ref: caretRef, inverse: true, children: cursorChar })
|
|
177
188
|
: _jsx(Text, { ref: caretRef, color: "suggestion", children: "\u258F" }), _jsx(Text, { wrap: "wrap", children: feedback.slice(inputFocused ? cursor + 1 : cursor) })] })) })] })] }), error !== null && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "error", children: error }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: t('plan-review-hint') }) })] }));
|
|
178
189
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { ClickEvent } from '../../ink/events/click-event.js';
|
|
2
3
|
import type { SessionSummary } from '../../dsh-adapter/sessions/index.js';
|
|
3
4
|
/**
|
|
4
5
|
* One session in the browser's list: a title line and a metadata line.
|
|
@@ -13,7 +14,7 @@ import type { SessionSummary } from '../../dsh-adapter/sessions/index.js';
|
|
|
13
14
|
* stay exactly two lines at every terminal width, and a row that wraps
|
|
14
15
|
* destroys the alignment that lets the eye scan a list at all.
|
|
15
16
|
*/
|
|
16
|
-
export declare function SessionListRow({ session, width, depth, focused, now, }: {
|
|
17
|
+
export declare function SessionListRow({ session, width, depth, focused, now, onClick, }: {
|
|
17
18
|
session: SessionSummary;
|
|
18
19
|
/** Columns available to the row, indentation included. */
|
|
19
20
|
width: number;
|
|
@@ -22,5 +23,7 @@ export declare function SessionListRow({ session, width, depth, focused, now, }:
|
|
|
22
23
|
focused: boolean;
|
|
23
24
|
/** Epoch ms used for every relative time in this render pass. */
|
|
24
25
|
now: number;
|
|
26
|
+
/** 鼠标点击行(fullscreen):恢复该会话(与 Enter 同路径)。 */
|
|
27
|
+
onClick?(event: ClickEvent): void;
|
|
25
28
|
}): React.ReactNode;
|
|
26
29
|
//# sourceMappingURL=SessionListRow.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionListRow.d.ts","sourceRoot":"","sources":["../../../../src/components/sessions/SessionListRow.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"SessionListRow.d.ts","sourceRoot":"","sources":["../../../../src/components/sessions/SessionListRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAGvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAQjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAA;AAEzE;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,KAAK,EACL,KAAK,EACL,OAAO,EACP,GAAG,EACH,OAAO,GACR,EAAE;IACD,OAAO,EAAE,cAAc,CAAA;IACvB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAA;IACb,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAA;IACX,4CAA4C;IAC5C,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CAClC,GAAG,KAAK,CAAC,SAAS,CA4ClB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
2
3
|
import { Box, Text } from '../../ui.js';
|
|
3
4
|
import { t } from '../../i18n.js';
|
|
4
5
|
import { formatBytes, formatWhen, kindMark, titleColor, truncateWidth, } from '../../sessions/format.js';
|
|
@@ -15,11 +16,12 @@ import { formatBytes, formatWhen, kindMark, titleColor, truncateWidth, } from '.
|
|
|
15
16
|
* stay exactly two lines at every terminal width, and a row that wraps
|
|
16
17
|
* destroys the alignment that lets the eye scan a list at all.
|
|
17
18
|
*/
|
|
18
|
-
export function SessionListRow({ session, width, depth, focused, now, }) {
|
|
19
|
+
export function SessionListRow({ session, width, depth, focused, now, onClick, }) {
|
|
19
20
|
const indent = depth * 2;
|
|
20
21
|
// Two cells for the focus marker, plus the indent for a nested run.
|
|
21
22
|
const body = Math.max(8, width - 2 - indent);
|
|
22
23
|
const mark = kindMark(session.kind);
|
|
24
|
+
const [hovered, setHovered] = useState(false);
|
|
23
25
|
const facts = [formatWhen(session.updatedAt, now)];
|
|
24
26
|
if (session.branch !== undefined)
|
|
25
27
|
facts.push(session.branch);
|
|
@@ -31,5 +33,5 @@ export function SessionListRow({ session, width, depth, focused, now, }) {
|
|
|
31
33
|
if (session.childCount > 0 && depth === 0) {
|
|
32
34
|
facts.push(t('session-children', { n: session.childCount }));
|
|
33
35
|
}
|
|
34
|
-
return (_jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [_jsxs(Box, { children: [_jsx(Text, { color: focused ? 'suggestion' : 'subtle', children: `${' '.repeat(indent)}${focused ? '❯ ' : ' '}` }), mark !== undefined && _jsx(Text, { color: mark.color, children: `${mark.glyph} ` }), _jsx(Text, { color: titleColor(session.title.source, focused), bold: focused, children: truncateWidth(session.label ?? session.title.text, body - (mark === undefined ? 0 : 2)) })] }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: `${' '.repeat(indent + 2)}${truncateWidth(facts.join(' · '), body)}` }) })] }));
|
|
36
|
+
return (_jsxs(Box, { flexDirection: "column", flexShrink: 0, onClick: onClick, onMouseEnter: onClick !== undefined ? () => setHovered(true) : undefined, onMouseLeave: onClick !== undefined ? () => setHovered(false) : undefined, backgroundColor: hovered && !focused ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { children: [_jsx(Text, { color: focused ? 'suggestion' : 'subtle', children: `${' '.repeat(indent)}${focused ? '❯ ' : ' '}` }), mark !== undefined && _jsx(Text, { color: mark.color, children: `${mark.glyph} ` }), _jsx(Text, { color: titleColor(session.title.source, focused), bold: focused, children: truncateWidth(session.label ?? session.title.text, body - (mark === undefined ? 0 : 2)) })] }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: `${' '.repeat(indent + 2)}${truncateWidth(facts.join(' · '), body)}` }) })] }));
|
|
35
37
|
}
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import type { HotspotRow, HotspotSort, TrajAggregate } from '../../dsh-adapter/types.js';
|
|
3
3
|
/** Flatten the three sections into the single list the cursor walks. */
|
|
4
4
|
export declare function hotspotRows(agg: TrajAggregate): HotspotRow[];
|
|
5
|
-
export declare function HotspotView({ agg, sort, width, height, cursor, tick, switchTick, }: {
|
|
5
|
+
export declare function HotspotView({ agg, sort, width, height, cursor, tick, switchTick, onRowClick, }: {
|
|
6
6
|
agg: TrajAggregate;
|
|
7
7
|
sort: HotspotSort;
|
|
8
8
|
width: number;
|
|
@@ -10,5 +10,11 @@ export declare function HotspotView({ agg, sort, width, height, cursor, tick, sw
|
|
|
10
10
|
cursor: number;
|
|
11
11
|
tick: number;
|
|
12
12
|
switchTick: number;
|
|
13
|
+
/**
|
|
14
|
+
* Mouse pick (fullscreen): reports the clicked row's cursor index — the
|
|
15
|
+
* scene jumps back to the timeline positioned on the group's first member
|
|
16
|
+
* (same path as the keyboard Enter). Hover shows a dim `▸` pointer.
|
|
17
|
+
*/
|
|
18
|
+
onRowClick?: (cursorIndex: number) => void;
|
|
13
19
|
}): React.ReactNode;
|
|
14
20
|
//# sourceMappingURL=HotspotView.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HotspotView.d.ts","sourceRoot":"","sources":["../../../../src/components/trajectory/HotspotView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AA6CxF,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,UAAU,EAAE,CAE5D;AAOD,wBAAgB,WAAW,CAAC,EAC1B,GAAG,EACH,IAAI,EACJ,KAAK,EACL,MAAM,EACN,MAAM,EACN,IAAI,EACJ,UAAU,GACX,EAAE;IACD,GAAG,EAAE,aAAa,CAAA;IAClB,IAAI,EAAE,WAAW,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"HotspotView.d.ts","sourceRoot":"","sources":["../../../../src/components/trajectory/HotspotView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AA6CxF,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,UAAU,EAAE,CAE5D;AAOD,wBAAgB,WAAW,CAAC,EAC1B,GAAG,EACH,IAAI,EACJ,KAAK,EACL,MAAM,EACN,MAAM,EACN,IAAI,EACJ,UAAU,EACV,UAAU,GACX,EAAE;IACD,GAAG,EAAE,aAAa,CAAA;IAClB,IAAI,EAAE,WAAW,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;CAC3C,GAAG,KAAK,CAAC,SAAS,CA6FlB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
2
3
|
import { Box, Text, useTheme } from '../../ui.js';
|
|
3
4
|
import { getTheme } from '../../theme.js';
|
|
4
5
|
import { formatDuration, formatTokens, truncateWidth } from '../../trajectory/format.js';
|
|
@@ -40,9 +41,10 @@ export function hotspotRows(agg) {
|
|
|
40
41
|
function valueOf(row, sort) {
|
|
41
42
|
return sort === 'count' ? row.count : sort === 'tokens' ? row.tokens : row.totalMs;
|
|
42
43
|
}
|
|
43
|
-
export function HotspotView({ agg, sort, width, height, cursor, tick, switchTick, }) {
|
|
44
|
+
export function HotspotView({ agg, sort, width, height, cursor, tick, switchTick, onRowClick, }) {
|
|
44
45
|
const [themeName] = useTheme();
|
|
45
46
|
const theme = getTheme(themeName);
|
|
47
|
+
const [hoverIndex, setHoverIndex] = React.useState(-1);
|
|
46
48
|
const labelWidth = Math.min(18, Math.max(10, Math.floor(width * 0.16)));
|
|
47
49
|
const barWidth = Math.max(6, Math.min(30, width - labelWidth - 34));
|
|
48
50
|
// Build the flat list once, tagging each row with its section's scale.
|
|
@@ -72,12 +74,16 @@ export function HotspotView({ agg, sort, width, height, cursor, tick, switchTick
|
|
|
72
74
|
}
|
|
73
75
|
const { row, max, colorKey } = entry;
|
|
74
76
|
const focused = entry.cursorIndex === cursor;
|
|
77
|
+
// 鼠标:行点击跳回 timeline 定位;悬停轻指示(dim ▸,不刷背景)
|
|
78
|
+
const hovered = onRowClick !== undefined && hoverIndex === entry.cursorIndex;
|
|
75
79
|
// Stagger the settle by row so a section reads top-down on switch.
|
|
76
80
|
const dim = reproject(tick - offset, switchTick);
|
|
77
81
|
const base = row.error === true ? theme.error : theme[colorKey];
|
|
78
82
|
const stats = `${row.count}×` +
|
|
79
83
|
(row.tokens > 0 ? ` · ${formatTokens(row.tokens)}` : '') +
|
|
80
84
|
(row.count > 0 && row.totalMs > 0 ? ` · ⌀${formatDuration(row.totalMs / row.count)}` : '');
|
|
81
|
-
return (_jsxs(Box, { flexDirection: "row", width: "100%", height: 1, flexShrink: 0, gap: 1,
|
|
85
|
+
return (_jsxs(Box, { flexDirection: "row", width: "100%", height: 1, flexShrink: 0, gap: 1, onClick: onRowClick === undefined ? undefined : () => onRowClick(entry.cursorIndex), onMouseEnter: onRowClick === undefined ? undefined : () => setHoverIndex(entry.cursorIndex), onMouseLeave: onRowClick === undefined
|
|
86
|
+
? undefined
|
|
87
|
+
: () => setHoverIndex(previous => (previous === entry.cursorIndex ? -1 : previous)), children: [_jsx(Box, { flexShrink: 0, width: 2, children: _jsx(Text, { color: focused ? 'suggestion' : 'inactive', children: focused || hovered ? '▸' : ' ' }) }), _jsx(Box, { flexShrink: 0, width: labelWidth, children: _jsx(Text, { color: focused ? 'suggestion' : row.error === true ? 'error' : undefined, children: truncateWidth(row.label, labelWidth) }) }), _jsx(Box, { flexShrink: 0, width: barWidth, children: _jsx(Text, { color: mix(base, theme.background, dim), children: bar(valueOf(row, sort), max, barWidth) }) }), _jsx(Box, { flexShrink: 0, width: 8, justifyContent: "flex-end", children: _jsx(Text, { bold: true, color: row.error === true ? 'error' : undefined, children: formatDuration(row.totalMs) }) }), _jsx(Box, { flexShrink: 1, overflow: "hidden", children: _jsx(Text, { color: "subtle", children: truncateWidth(stats, Math.max(4, width - labelWidth - barWidth - 16)) }) })] }, `r${entry.cursorIndex}`));
|
|
82
88
|
}) }));
|
|
83
89
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { ClickEvent } from '../../ink/events/click-event.js';
|
|
2
3
|
import type { TrajNode } from '../../dsh-adapter/types.js';
|
|
3
|
-
export declare function Ledger({ rows, start, height, cursor, width, tick, arrivalTick, arrivalFrom, }: {
|
|
4
|
+
export declare function Ledger({ rows, start, height, cursor, width, tick, arrivalTick, arrivalFrom, onRowClick, }: {
|
|
4
5
|
/** The (possibly filtered) ledger. */
|
|
5
6
|
rows: readonly TrajNode[];
|
|
6
7
|
/** Index of the first visible row. */
|
|
@@ -16,5 +17,12 @@ export declare function Ledger({ rows, start, height, cursor, width, tick, arriv
|
|
|
16
17
|
arrivalTick: number;
|
|
17
18
|
/** Rows at or after this index are the ones that just arrived. */
|
|
18
19
|
arrivalFrom: number;
|
|
20
|
+
/**
|
|
21
|
+
* Mouse pick (fullscreen): reports the clicked row's absolute index — the
|
|
22
|
+
* scene jumps the cursor to it (same semantics as the keyboard jumps).
|
|
23
|
+
* Hover on a non-focused row shows a dim `▸` pointer — light indication,
|
|
24
|
+
* no background wash (the ledger is content, not a menu).
|
|
25
|
+
*/
|
|
26
|
+
onRowClick?: (index: number, event: ClickEvent) => void;
|
|
19
27
|
}): React.ReactNode;
|
|
20
28
|
//# sourceMappingURL=Ledger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Ledger.d.ts","sourceRoot":"","sources":["../../../../src/components/trajectory/Ledger.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"Ledger.d.ts","sourceRoot":"","sources":["../../../../src/components/trajectory/Ledger.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAgBjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AA6C1D,wBAAgB,MAAM,CAAC,EACrB,IAAI,EACJ,KAAK,EACL,MAAM,EACN,MAAM,EACN,KAAK,EACL,IAAI,EACJ,WAAW,EACX,WAAW,EACX,UAAU,GACX,EAAE;IACD,sCAAsC;IACtC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAA;IACzB,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAA;IACd,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAA;IACnB,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;CACxD,GAAG,KAAK,CAAC,SAAS,CAsKlB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
2
3
|
import { Box, Text, useTheme } from '../../ui.js';
|
|
3
4
|
import { burstDurationMs, burstErrors, previewText } from '../../dsh-adapter/trajectory/index.js';
|
|
4
5
|
import { costGlyph, formatDuration, formatClock, heatColor, KIND_BADGE, KIND_BADGE_BG, KIND_FG, KIND_GLYPH, ledgerLayout, } from '../../trajectory/format.js';
|
|
@@ -46,9 +47,10 @@ function spineGlyph(rows, index) {
|
|
|
46
47
|
return SPINE.close;
|
|
47
48
|
return SPINE.mid;
|
|
48
49
|
}
|
|
49
|
-
export function Ledger({ rows, start, height, cursor, width, tick, arrivalTick, arrivalFrom, }) {
|
|
50
|
+
export function Ledger({ rows, start, height, cursor, width, tick, arrivalTick, arrivalFrom, onRowClick, }) {
|
|
50
51
|
const [themeName] = useTheme();
|
|
51
52
|
const theme = getTheme(themeName);
|
|
53
|
+
const [hoverIndex, setHoverIndex] = React.useState(-1);
|
|
52
54
|
const layout = ledgerLayout(width);
|
|
53
55
|
const visible = rows.slice(start, start + height);
|
|
54
56
|
const arriving = arrive(tick, arrivalTick);
|
|
@@ -65,6 +67,22 @@ export function Ledger({ rows, start, height, cursor, width, tick, arrivalTick,
|
|
|
65
67
|
const running = node.status === 'running';
|
|
66
68
|
const isNew = index >= arrivalFrom && arriving > 0;
|
|
67
69
|
const duration = node.burst === undefined ? node.durationMs : burstDurationMs(node.burst);
|
|
70
|
+
// 鼠标:行点击跳光标;悬停在非焦点行亮出 dim ▸(轻指示,不刷背景)
|
|
71
|
+
const hovered = onRowClick !== undefined && hoverIndex === index;
|
|
72
|
+
const pointer = focused || hovered ? '▸' : ' ';
|
|
73
|
+
const rowEvents = onRowClick === undefined
|
|
74
|
+
? undefined
|
|
75
|
+
: {
|
|
76
|
+
onClick: (event) => {
|
|
77
|
+
onRowClick(index, event);
|
|
78
|
+
},
|
|
79
|
+
onMouseEnter: () => {
|
|
80
|
+
setHoverIndex(index);
|
|
81
|
+
},
|
|
82
|
+
onMouseLeave: () => {
|
|
83
|
+
setHoverIndex(previous => (previous === index ? -1 : previous));
|
|
84
|
+
},
|
|
85
|
+
};
|
|
68
86
|
// ── structural rows are RULES, not rows ────────────────────────────
|
|
69
87
|
//
|
|
70
88
|
// A ledger with five hundred entries needs chapters. Turn and step
|
|
@@ -82,7 +100,7 @@ export function Ledger({ rows, start, height, cursor, width, tick, arrivalTick,
|
|
|
82
100
|
// attention than the work between them. Only the turn, which is the
|
|
83
101
|
// session's actual chapter break, gets a rule.
|
|
84
102
|
if (!isTurn) {
|
|
85
|
-
return (_jsxs(Box, { flexDirection: "row", width: "100%", height: 1, flexShrink: 0, gap: 1, children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { color: "subtle", children: `${
|
|
103
|
+
return (_jsxs(Box, { flexDirection: "row", width: "100%", height: 1, flexShrink: 0, gap: 1, ...rowEvents, children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { color: "subtle", children: `${pointer}╵` }) }), _jsx(Box, { flexGrow: 1, flexShrink: 1, overflow: "hidden", children: _jsx(Text, { color: focused ? 'suggestion' : 'subtle', wrap: "truncate", children: node.label }) }), _jsx(Box, { flexShrink: 0, children: _jsx(Text, { color: heatColor(duration), children: costGlyph(duration) }) }), _jsx(Box, { flexShrink: 0, justifyContent: "flex-end", width: 7, children: _jsx(Text, { color: heatColor(duration), children: right }) })] }, `${node.seq}:step`));
|
|
86
104
|
}
|
|
87
105
|
const tone = failed ? 'error' : running ? 'success' : 'inactiveShimmer';
|
|
88
106
|
// Idle before a turn is wall-clock the session spent waiting on the
|
|
@@ -92,9 +110,9 @@ export function Ledger({ rows, start, height, cursor, width, tick, arrivalTick,
|
|
|
92
110
|
const previous = rows[index - 1];
|
|
93
111
|
const idle = previous === undefined ? 0 : node.time - (previous.time + (previous.durationMs ?? 0));
|
|
94
112
|
const idleText = idle >= IDLE_FLOOR_MS ? ` ⋯ ${formatDuration(idle)}` : '';
|
|
95
|
-
const head = `${
|
|
113
|
+
const head = `${pointer}━━ ${node.label}${idleText} `;
|
|
96
114
|
const fill = Math.max(2, width - stringWidth(head) - stringWidth(right) - 2);
|
|
97
|
-
return (_jsx(Box, { width: "100%", height: 1, flexShrink: 0, children: _jsxs(Text, { color: tone, bold: true, children: [`${
|
|
115
|
+
return (_jsx(Box, { width: "100%", height: 1, flexShrink: 0, ...rowEvents, children: _jsxs(Text, { color: tone, bold: true, children: [`${pointer}━━ ${node.label}`, _jsx(Text, { color: "subtle", children: idleText }), _jsx(Text, { color: "inactive", children: ` ${'━'.repeat(fill)} ` }), _jsx(Text, { color: failed ? 'error' : heatColor(duration), children: right })] }) }, `${node.seq}:turn`));
|
|
98
116
|
}
|
|
99
117
|
const spineColor = failed ? 'error' : running ? 'success' : node.seed === true ? 'subtle' : 'inactive';
|
|
100
118
|
const badgeBg = KIND_BADGE_BG[node.kind];
|
|
@@ -107,6 +125,6 @@ export function Ledger({ rows, start, height, cursor, width, tick, arrivalTick,
|
|
|
107
125
|
const outcome = layout.outcome && node.outcome !== undefined && node.outcome !== ''
|
|
108
126
|
? previewText(node.outcome, Math.max(8, Math.floor(layout.detail * 0.3)))
|
|
109
127
|
: '';
|
|
110
|
-
return (_jsxs(Box, { flexDirection: "row", width: "100%", height: 1, flexShrink: 0, gap: 1, children: [_jsx(Box, { flexShrink: 0, children: _jsxs(Text, { color: spineColor, children: [
|
|
128
|
+
return (_jsxs(Box, { flexDirection: "row", width: "100%", height: 1, flexShrink: 0, gap: 1, ...rowEvents, children: [_jsx(Box, { flexShrink: 0, children: _jsxs(Text, { color: spineColor, children: [pointer, spineGlyph(rows, index)] }) }), layout.index && (_jsx(Box, { flexShrink: 0, width: 8, children: _jsx(Text, { color: "subtle", children: formatClock(node.time) }) })), _jsx(Box, { flexShrink: 0, children: _jsx(Text, { color: isNew ? mix(theme[KIND_FG[node.kind]], theme.text, arriving) : KIND_FG[node.kind], backgroundColor: badgeBg, bold: true, children: badge }) }), _jsx(Box, { flexGrow: 1, flexShrink: 1, overflow: "hidden", children: _jsxs(Text, { wrap: "truncate", color: focused ? 'suggestion' : node.seed === true ? 'subtle' : undefined, children: [label, detail === '' ? '' : ' ', _jsx(Text, { color: focused ? 'suggestion' : 'inactive', children: detail }), outcome === '' ? '' : _jsx(Text, { color: "subtle", children: ` → ${outcome}` })] }) }), _jsx(Box, { flexShrink: 0, children: _jsx(Text, { color: running ? 'success' : heatColor(duration), children: costGlyph(duration) }) }), _jsx(Box, { flexShrink: 0, justifyContent: "flex-end", width: 7, children: _jsx(Text, { color: running ? 'success' : heatColor(duration), children: running ? '…' : duration === undefined ? '' : formatDuration(duration) }) })] }, `${node.seq}:${node.kind}`));
|
|
111
129
|
}) }));
|
|
112
130
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { ClickEvent } from '../../ink/events/click-event.js';
|
|
2
3
|
import type { WaveBand as Band } from '../../dsh-adapter/types.js';
|
|
3
|
-
export declare function WaveBand({ band, width, cursorColumn, viewportStart, viewportEnd, matches, tick, alertTick, }: {
|
|
4
|
+
export declare function WaveBand({ band, width, cursorColumn, viewportStart, viewportEnd, matches, tick, alertTick, onColumnClick, }: {
|
|
4
5
|
band: Band;
|
|
5
6
|
/** Rendered width in cells; equals `band.buckets.length`. */
|
|
6
7
|
width: number;
|
|
@@ -19,6 +20,14 @@ export declare function WaveBand({ band, width, cursorColumn, viewportStart, vie
|
|
|
19
20
|
tick: number;
|
|
20
21
|
/** Tick the most recent alert was triggered on. */
|
|
21
22
|
alertTick: number;
|
|
23
|
+
/**
|
|
24
|
+
* Mouse pick (fullscreen): reports the clicked column (0-based within the
|
|
25
|
+
* band; the ruler row counts too — its ▐▌ bracket is the seek affordance).
|
|
26
|
+
* The scene jumps to that column's nearest event via bucket.firstIndex,
|
|
27
|
+
* which empty columns inherit from their predecessor for exactly this
|
|
28
|
+
* purpose. No hover: column density makes per-cell indication noise.
|
|
29
|
+
*/
|
|
30
|
+
onColumnClick?: (column: number, event: ClickEvent) => void;
|
|
22
31
|
}): React.ReactNode;
|
|
23
32
|
/**
|
|
24
33
|
* Convert a theme colour to the `#rrggbb` form chalk needs.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WaveBand.d.ts","sourceRoot":"","sources":["../../../../src/components/trajectory/WaveBand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"WaveBand.d.ts","sourceRoot":"","sources":["../../../../src/components/trajectory/WaveBand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAIjE,OAAO,KAAK,EAAE,QAAQ,IAAI,IAAI,EAAe,MAAM,4BAA4B,CAAA;AAmD/E,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,YAAY,EACZ,aAAa,EACb,WAAW,EACX,OAAO,EACP,IAAI,EACJ,SAAS,EACT,aAAa,GACd,EAAE;IACD,IAAI,EAAE,IAAI,CAAA;IACV,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC7B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;CAC5D,GAAG,KAAK,CAAC,SAAS,CA2GlB;AAED;;;;;;GAMG;AACH,iBAAS,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMrC;AAED,6EAA6E;AAC7E,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAA"}
|
|
@@ -50,7 +50,7 @@ function channelColor(channel, theme) {
|
|
|
50
50
|
default: return theme.subtle;
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
export function WaveBand({ band, width, cursorColumn, viewportStart, viewportEnd, matches, tick, alertTick, }) {
|
|
53
|
+
export function WaveBand({ band, width, cursorColumn, viewportStart, viewportEnd, matches, tick, alertTick, onColumnClick, }) {
|
|
54
54
|
const [themeName] = useTheme();
|
|
55
55
|
const theme = getTheme(themeName);
|
|
56
56
|
if (band.buckets.length === 0) {
|
|
@@ -123,7 +123,12 @@ export function WaveBand({ band, width, cursorColumn, viewportStart, viewportEnd
|
|
|
123
123
|
? chalk.hex(toHex(theme.permission))(glyph)
|
|
124
124
|
: chalk.hex(toHex(theme.subtle))(glyph);
|
|
125
125
|
}
|
|
126
|
-
return (_jsxs(Box, { flexDirection: "column", flexShrink: 0,
|
|
126
|
+
return (_jsxs(Box, { flexDirection: "column", flexShrink: 0, onClick: onColumnClick === undefined
|
|
127
|
+
? undefined
|
|
128
|
+
: (event) => {
|
|
129
|
+
const column = Math.max(0, Math.min(band.buckets.length - 1, event.localCol));
|
|
130
|
+
onColumnClick(column, event);
|
|
131
|
+
}, children: [_jsx(Text, { children: wave }), _jsx(Text, { children: rulerText })] }));
|
|
127
132
|
}
|
|
128
133
|
/**
|
|
129
134
|
* Convert a theme colour to the `#rrggbb` form chalk needs.
|
|
@@ -5,9 +5,10 @@ import { type SessionEvent } from '@deepseek-ai/dsh-session';
|
|
|
5
5
|
import type { Context } from '@deepseek-ai/cordis';
|
|
6
6
|
import { type CommandCompletion, type LocalCommand } from '../commands.js';
|
|
7
7
|
import { type PreviewEntry, type SessionSummary } from './sessions/index.js';
|
|
8
|
+
import { type FileCandidate } from '../utils/fileSuggestions.js';
|
|
8
9
|
import type { ProviderSetupHost } from './providerWizard.js';
|
|
9
10
|
import { type SessionModeSpec } from '../sessionModes.js';
|
|
10
|
-
import { type StatusBarConfig, type ToolBackground } from '../tuiDisplayPrefs.js';
|
|
11
|
+
import { type ScrollGutterMode, type StatusBarConfig, type ToolBackground } from '../tuiDisplayPrefs.js';
|
|
11
12
|
import { type SubagentState } from './subagents.js';
|
|
12
13
|
export type { SubagentState } from './subagents.js';
|
|
13
14
|
import type { SpinnerMode } from '../components/Spinner/spinnerMode.js';
|
|
@@ -375,6 +376,10 @@ export interface Channel {
|
|
|
375
376
|
readonly thinkingFold: 'preview' | 'full';
|
|
376
377
|
/** Live tool-card background treatment. */
|
|
377
378
|
readonly toolBackground: ToolBackground;
|
|
379
|
+
/** What the fullscreen transcript's right gutter shows (settings
|
|
380
|
+
* `dsh-tui.scrollGutter`: turn timeline / proportional scrollbar /
|
|
381
|
+
* nothing). */
|
|
382
|
+
readonly scrollGutter: ScrollGutterMode;
|
|
378
383
|
/** Live status-footer visibility and compactness preferences. */
|
|
379
384
|
readonly statusBar: Readonly<StatusBarConfig>;
|
|
380
385
|
/** Whether the header's pixel whale art shows (settings `dsh-tui.whale`). */
|
|
@@ -389,10 +394,11 @@ export interface Channel {
|
|
|
389
394
|
readonly contextBarEnabled: boolean;
|
|
390
395
|
/**
|
|
391
396
|
* Current same-session goal projection, when a goal exists. Derived live
|
|
392
|
-
* from the durable
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
397
|
+
* from the durable goal events in the session log — top-level
|
|
398
|
+
* `goal/change` snapshots (every goal mutation appends one) plus the
|
|
399
|
+
* goal-sourced continuation rounds that advance the counter — so this
|
|
400
|
+
* snapshot tracks create/edit/pause/resume/complete/block/clear in real
|
|
401
|
+
* time and replays correctly on resume/rewind.
|
|
396
402
|
*/
|
|
397
403
|
readonly goal: ChannelGoal | undefined;
|
|
398
404
|
/**
|
|
@@ -592,7 +598,12 @@ export interface Channel {
|
|
|
592
598
|
settingsSections(): readonly TuiSettingsSection[];
|
|
593
599
|
/** Subscribe to settings-section register/unregister events. */
|
|
594
600
|
subscribeSettingsSections(listener: () => void): () => void;
|
|
595
|
-
/**
|
|
601
|
+
/** Structured `@` file completion, using the session's remote fs service. */
|
|
602
|
+
listFileCandidates(query: string, options?: {
|
|
603
|
+
signal?: AbortSignal;
|
|
604
|
+
topK?: number;
|
|
605
|
+
}): Promise<readonly FileCandidate[]>;
|
|
606
|
+
/** Backward-compatible top-level/recursive listing. */
|
|
596
607
|
listFiles(): Promise<readonly string[]>;
|
|
597
608
|
/** Every session the persistence backend stores, classified and unfiltered
|
|
598
609
|
* — the browser (`/resume`) decides which of them a given view shows. */
|
|
@@ -734,6 +745,8 @@ export interface ChannelState {
|
|
|
734
745
|
thinkingFold: 'preview' | 'full';
|
|
735
746
|
/** Tool-card background treatment (see the public Channel type). */
|
|
736
747
|
toolBackground: ToolBackground;
|
|
748
|
+
/** Transcript gutter mode (see the public Channel type). */
|
|
749
|
+
scrollGutter: ScrollGutterMode;
|
|
737
750
|
/** Status-footer preferences (see the public Channel type). */
|
|
738
751
|
statusBar: StatusBarConfig;
|
|
739
752
|
/** Apply a diff-layout change (see the public Channel type). */
|
|
@@ -742,6 +755,8 @@ export interface ChannelState {
|
|
|
742
755
|
setThinkingFold(mode: 'preview' | 'full'): void;
|
|
743
756
|
/** Apply a tool-card background change. */
|
|
744
757
|
setToolBackground(background: ToolBackground): void;
|
|
758
|
+
/** Apply a transcript gutter mode change. */
|
|
759
|
+
setScrollGutter(mode: ScrollGutterMode): void;
|
|
745
760
|
/** Apply status-footer preference changes. */
|
|
746
761
|
setStatusBar(config: Partial<StatusBarConfig>): void;
|
|
747
762
|
/** Whale header art switch (see the public Channel type). */
|
|
@@ -867,6 +882,10 @@ export interface ChannelState {
|
|
|
867
882
|
settingsSections(): readonly TuiSettingsSection[];
|
|
868
883
|
/** Subscribe to settings-section register/unregister events. */
|
|
869
884
|
subscribeSettingsSections(listener: () => void): () => void;
|
|
885
|
+
listFileCandidates(query: string, options?: {
|
|
886
|
+
signal?: AbortSignal;
|
|
887
|
+
topK?: number;
|
|
888
|
+
}): Promise<readonly FileCandidate[]>;
|
|
870
889
|
listFiles(): Promise<readonly string[]>;
|
|
871
890
|
listSessions(): Promise<readonly SessionSummary[]>;
|
|
872
891
|
/** Trailing exchanges of a persisted session (see the public Channel type). */
|
|
@@ -932,6 +951,8 @@ export declare function createChannel(ctx: Context, initialAgent: Agent, options
|
|
|
932
951
|
thinkingFold?: 'preview' | 'full';
|
|
933
952
|
/** Tool-card background treatment; default `none`. */
|
|
934
953
|
toolBackground?: ToolBackground;
|
|
954
|
+
/** Transcript gutter mode; default `timeline` (settings `dsh-tui.scrollGutter`). */
|
|
955
|
+
scrollGutter?: ScrollGutterMode;
|
|
935
956
|
/** Status-footer field visibility and compactness. */
|
|
936
957
|
statusBar?: Partial<StatusBarConfig>;
|
|
937
958
|
/** Show the header's pixel whale art; default on. */
|