@deepseek-harness-tui/dsh-tui 0.10.2 → 0.11.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 +171 -124
- package/bin/dsh-tui.js +748 -22
- package/cordis.patch.yml +38 -10
- package/cordis.yml +2 -0
- package/lib/types/adapter/channel/session-projection.d.ts.map +1 -1
- package/lib/types/adapter/channel/session-projection.js +2 -0
- package/lib/types/adapter/channel/ui-policy.d.ts +4 -1
- package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
- package/lib/types/adapter/channel/ui-policy.js +5 -1
- package/lib/types/adapter/kernel/host-facade.d.ts.map +1 -1
- package/lib/types/adapter/kernel/host-facade.js +1 -0
- package/lib/types/adapter/kernel/replay.d.ts.map +1 -1
- package/lib/types/adapter/kernel/replay.js +3 -0
- package/lib/types/adapter/kernel/runtime.d.ts.map +1 -1
- package/lib/types/adapter/kernel/runtime.js +2 -0
- package/lib/types/adapter/kernel/slices/workspace.d.ts.map +1 -1
- package/lib/types/adapter/kernel/slices/workspace.js +1 -0
- package/lib/types/adapter/ports/channel-ui.d.ts +22 -2
- package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-view.d.ts +66 -0
- package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-workspace.d.ts +23 -0
- package/lib/types/adapter/ports/channel-workspace.d.ts.map +1 -1
- package/lib/types/adapter/ports/workspace.d.ts +2 -0
- package/lib/types/adapter/ports/workspace.d.ts.map +1 -1
- package/lib/types/adapter/upstream/workspace-driver.d.ts.map +1 -1
- package/lib/types/adapter/upstream/workspace-driver.js +10 -2
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +1 -0
- package/lib/types/components/ContextBarView.d.ts +15 -7
- package/lib/types/components/ContextBarView.d.ts.map +1 -1
- package/lib/types/components/ContextBarView.js +26 -22
- package/lib/types/components/ImagePreviewOverlay.d.ts.map +1 -1
- package/lib/types/components/ImagePreviewOverlay.js +11 -5
- package/lib/types/components/Markdown.d.ts +11 -1
- package/lib/types/components/Markdown.d.ts.map +1 -1
- package/lib/types/components/Markdown.js +20 -2
- package/lib/types/components/MermaidDiagram.d.ts +13 -0
- package/lib/types/components/MermaidDiagram.d.ts.map +1 -0
- package/lib/types/components/MermaidDiagram.js +61 -0
- package/lib/types/components/MessageList.d.ts +26 -1
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +72 -7
- package/lib/types/components/PageMargin.d.ts +1 -1
- package/lib/types/components/PromptInput.d.ts +37 -1
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +243 -28
- package/lib/types/components/ScrollbarGutter.d.ts +20 -5
- package/lib/types/components/ScrollbarGutter.d.ts.map +1 -1
- package/lib/types/components/ScrollbarGutter.js +88 -10
- package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
- package/lib/types/components/StreamingMarkdown.js +30 -28
- package/lib/types/components/Tooltip.d.ts.map +1 -1
- package/lib/types/components/Tooltip.js +45 -7
- package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -1
- package/lib/types/components/messages/UserPromptMessage.js +5 -7
- package/lib/types/components/messages/useImageInspection.d.ts.map +1 -1
- package/lib/types/components/messages/useImageInspection.js +19 -9
- package/lib/types/components/promptDraftCache.d.ts +102 -0
- package/lib/types/components/promptDraftCache.d.ts.map +1 -0
- package/lib/types/components/promptDraftCache.js +76 -0
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts +17 -1
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.js +40 -7
- package/lib/types/components/questions/QuestionMinimizedBar.d.ts +12 -0
- package/lib/types/components/questions/QuestionMinimizedBar.d.ts.map +1 -0
- package/lib/types/components/questions/QuestionMinimizedBar.js +43 -0
- package/lib/types/components/sessions/SessionListRow.d.ts +23 -1
- package/lib/types/components/sessions/SessionListRow.d.ts.map +1 -1
- package/lib/types/components/sessions/SessionListRow.js +52 -5
- package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts +49 -0
- package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts.map +1 -0
- package/lib/types/components/workspaces/HomeWorkspaceRow.js +50 -0
- package/lib/types/dsh-adapter/bundled-presets.d.ts +10 -0
- package/lib/types/dsh-adapter/bundled-presets.d.ts.map +1 -0
- package/lib/types/dsh-adapter/bundled-presets.js +80 -0
- package/lib/types/dsh-adapter/channel/action-readiness.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/action-readiness.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/action-readiness.js +3 -0
- package/lib/types/dsh-adapter/channel/agent-view-projection.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/agent-view-projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/agent-view-projection.js +19 -2
- package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/background-action.js +52 -29
- package/lib/types/dsh-adapter/channel/binding.d.ts +19 -2
- package/lib/types/dsh-adapter/channel/binding.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/binding.js +78 -18
- package/lib/types/dsh-adapter/channel/composer-images.d.ts +5 -0
- package/lib/types/dsh-adapter/channel/composer-images.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/composer-images.js +105 -6
- package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts +8 -0
- package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/context-bookkeeping.js +3 -2
- package/lib/types/dsh-adapter/channel/ide-selection.d.ts +58 -0
- package/lib/types/dsh-adapter/channel/ide-selection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/ide-selection.js +226 -0
- package/lib/types/dsh-adapter/channel/input-delivery.d.ts +6 -1
- package/lib/types/dsh-adapter/channel/input-delivery.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/input-delivery.js +9 -1
- package/lib/types/dsh-adapter/channel/local-actions.d.ts +3 -19
- package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/local-actions.js +2 -1
- package/lib/types/dsh-adapter/channel/model-actions.d.ts +4 -1
- package/lib/types/dsh-adapter/channel/model-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/model-actions.js +82 -6
- package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/model-switch.js +49 -31
- package/lib/types/dsh-adapter/channel/projection.d.ts +4 -0
- package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/projection.js +29 -19
- package/lib/types/dsh-adapter/channel/reports.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/reports.js +4 -12
- package/lib/types/dsh-adapter/channel/session-fork.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-fork.js +26 -2
- package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +3 -0
- 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 +10 -0
- package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-metadata.js +2 -2
- package/lib/types/dsh-adapter/channel/session-resume.d.ts +11 -2
- package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-resume.js +291 -94
- package/lib/types/dsh-adapter/channel/session-rewind.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-rewind.js +34 -16
- package/lib/types/dsh-adapter/channel/session-tree-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-tree-actions.js +19 -3
- package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/settings-host.js +4 -3
- package/lib/types/dsh-adapter/channel/state.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/state.js +1 -1
- package/lib/types/dsh-adapter/channel/transcript.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/transcript.js +6 -12
- package/lib/types/dsh-adapter/channel/types.d.ts +6 -1
- package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/workspace-actions.d.ts +4 -1
- package/lib/types/dsh-adapter/channel/workspace-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/workspace-actions.js +41 -1
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +67 -6
- package/lib/types/dsh-adapter/compat/messages.d.ts +15 -0
- package/lib/types/dsh-adapter/compat/messages.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/messages.js +15 -0
- package/lib/types/dsh-adapter/compat/settings.d.ts +33 -0
- package/lib/types/dsh-adapter/compat/settings.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/settings.js +43 -0
- package/lib/types/dsh-adapter/compat/shell.d.ts +25 -0
- package/lib/types/dsh-adapter/compat/shell.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/shell.js +11 -0
- package/lib/types/dsh-adapter/contract.d.ts +4 -4
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +15 -6
- package/lib/types/dsh-adapter/ide-channel.d.ts +224 -0
- package/lib/types/dsh-adapter/ide-channel.d.ts.map +1 -0
- package/lib/types/dsh-adapter/ide-channel.js +556 -0
- package/lib/types/dsh-adapter/index.d.ts +18 -3
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +32 -5
- package/lib/types/dsh-adapter/plugin.d.ts +5 -2
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +173 -42
- package/lib/types/dsh-adapter/preset-resolution.d.ts +8 -0
- package/lib/types/dsh-adapter/preset-resolution.d.ts.map +1 -1
- package/lib/types/dsh-adapter/preset-resolution.js +10 -0
- package/lib/types/dsh-adapter/session-mount-heartbeat.d.ts +53 -0
- package/lib/types/dsh-adapter/session-mount-heartbeat.d.ts.map +1 -0
- package/lib/types/dsh-adapter/session-mount-heartbeat.js +100 -0
- package/lib/types/dsh-adapter/sessionTree.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sessionTree.js +3 -2
- package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
- package/lib/types/dsh-adapter/subagents.js +6 -5
- package/lib/types/dsh-adapter/workspaces.d.ts +46 -3
- package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -1
- package/lib/types/dsh-adapter/workspaces.js +116 -0
- package/lib/types/effortPrefs.d.ts +15 -3
- package/lib/types/effortPrefs.d.ts.map +1 -1
- package/lib/types/effortPrefs.js +37 -3
- package/lib/types/homePrefs.d.ts +15 -0
- package/lib/types/homePrefs.d.ts.map +1 -0
- package/lib/types/homePrefs.js +53 -0
- package/lib/types/i18n.d.ts +257 -296
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +78 -84
- package/lib/types/ink/colorize.d.ts +10 -0
- package/lib/types/ink/colorize.d.ts.map +1 -1
- package/lib/types/ink/colorize.js +21 -0
- package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
- package/lib/types/ink/components/ScrollBox.js +12 -1
- package/lib/types/ink/dom.d.ts +1 -0
- package/lib/types/ink/dom.d.ts.map +1 -1
- package/lib/types/ink/hooks/use-copy-on-select.d.ts +5 -1
- package/lib/types/ink/hooks/use-copy-on-select.d.ts.map +1 -1
- package/lib/types/ink/hooks/use-copy-on-select.js +15 -1
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +36 -1
- package/lib/types/ink/output.d.ts +10 -1
- package/lib/types/ink/output.d.ts.map +1 -1
- package/lib/types/ink/output.js +109 -17
- package/lib/types/ink/render-border.d.ts +6 -1
- package/lib/types/ink/render-border.d.ts.map +1 -1
- package/lib/types/ink/render-border.js +25 -9
- package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
- package/lib/types/ink/render-node-to-output.js +48 -6
- package/lib/types/ink/renderer.d.ts +6 -0
- package/lib/types/ink/renderer.d.ts.map +1 -1
- package/lib/types/ink/renderer.js +2 -1
- package/lib/types/ink/selection.d.ts +60 -0
- package/lib/types/ink/selection.d.ts.map +1 -1
- package/lib/types/ink/selection.js +129 -0
- package/lib/types/ink/sixel-graphics.d.ts +19 -1
- package/lib/types/ink/sixel-graphics.d.ts.map +1 -1
- package/lib/types/ink/sixel-graphics.js +124 -12
- package/lib/types/ink/terminal-image.d.ts +18 -1
- package/lib/types/ink/terminal-image.d.ts.map +1 -1
- package/lib/types/ink/terminal.d.ts +17 -0
- package/lib/types/ink/terminal.d.ts.map +1 -1
- package/lib/types/ink/terminal.js +20 -1
- package/lib/types/screens/Chat.d.ts +17 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +284 -72
- package/lib/types/screens/SessionSupervisor.d.ts +84 -0
- package/lib/types/screens/SessionSupervisor.d.ts.map +1 -0
- package/lib/types/screens/SessionSupervisor.js +350 -0
- package/lib/types/screens/SessionTree.js +2 -2
- package/lib/types/screens/Settings.d.ts.map +1 -1
- package/lib/types/screens/Settings.js +32 -9
- package/lib/types/screens/StatusLine.d.ts +13 -0
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +36 -17
- package/lib/types/screens/StatusMetrics.d.ts +79 -22
- package/lib/types/screens/StatusMetrics.d.ts.map +1 -1
- package/lib/types/screens/StatusMetrics.js +153 -88
- package/lib/types/screens/sessionSupervisor/model.d.ts +83 -0
- package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -0
- package/lib/types/screens/sessionSupervisor/model.js +69 -0
- package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts +120 -0
- package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -0
- package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +593 -0
- package/lib/types/sessionMounts.d.ts +272 -0
- package/lib/types/sessionMounts.d.ts.map +1 -0
- package/lib/types/sessionMounts.js +706 -0
- package/lib/types/sessions/format.d.ts.map +1 -1
- package/lib/types/sessions/format.js +4 -1
- package/lib/types/sessions/resumeFailure.d.ts +38 -0
- package/lib/types/sessions/resumeFailure.d.ts.map +1 -0
- package/lib/types/sessions/resumeFailure.js +58 -0
- package/lib/types/terminal-utils/mermaid.d.ts +44 -0
- package/lib/types/terminal-utils/mermaid.d.ts.map +1 -0
- package/lib/types/terminal-utils/mermaid.js +83 -0
- package/lib/types/tips.d.ts.map +1 -1
- package/lib/types/tips.js +175 -19
- package/lib/types/tuiDisplayPrefs.d.ts +7 -9
- package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
- package/lib/types/tuiDisplayPrefs.js +31 -28
- package/lib/types/update.d.ts +61 -0
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +194 -0
- package/lib/types/utils/imageResize.d.ts +90 -0
- package/lib/types/utils/imageResize.d.ts.map +1 -0
- package/lib/types/utils/imageResize.js +272 -0
- package/lib/types/utils/keymap.d.ts +5 -1
- package/lib/types/utils/keymap.d.ts.map +1 -1
- package/lib/types/utils/keymap.js +23 -0
- package/lib/types/workspaces.d.ts +2 -1
- package/lib/types/workspaces.d.ts.map +1 -1
- package/lib/types/workspaces.js +1 -1
- package/node_modules/@deepseek-harness-tui/dsh-auth/package.json +10 -10
- package/package.json +120 -103
- package/presets/liangshen/.dsh-tui-managed.json +1 -1
- package/presets/liangshen/agent.cordis.yml +15 -0
- package/lib/types/screens/AgentView.d.ts +0 -23
- package/lib/types/screens/AgentView.d.ts.map +0 -1
- package/lib/types/screens/AgentView.js +0 -546
- package/lib/types/screens/SessionBrowser.d.ts +0 -42
- package/lib/types/screens/SessionBrowser.d.ts.map +0 -1
- package/lib/types/screens/SessionBrowser.js +0 -911
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../../src/adapter/ports/workspace.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../../src/adapter/ports/workspace.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,CAAA;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,MAAM,0BAA0B,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,GAC1F;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,CAAA;AAErE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,0BAA0B,CAAC,GAAG,0BAA0B,CAAA;CAC9I;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,OAAO,EAAE;QACf,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAC5B,GAAG,OAAO,CAAA;IACX,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;QAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;QAChC,QAAQ,CAAC,MAAM,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;QAC1C,QAAQ,CAAC,MAAM,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;QAC1C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;KAC3B,CAAC,CAAA;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC,CAAA;IACvF,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAA;IAC/G,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAAA;IAC1C,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAA;IAChE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;IAChE,qEAAqE;IACrE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACrC,QAAQ,IAAI,SAAS,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC,EAAE,CAAA;IACrF,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC,CAAA;CAC5H;AAED,MAAM,MAAM,qBAAqB,GAAG,YAAY,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-driver.d.ts","sourceRoot":"","sources":["../../../../src/adapter/upstream/workspace-driver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAqB,MAAM,gBAAgB,CAAA;AAClE,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"workspace-driver.d.ts","sourceRoot":"","sources":["../../../../src/adapter/upstream/workspace-driver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAqB,MAAM,gBAAgB,CAAA;AAClE,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAA;AA2DtE,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,CAqBjE;AAqGD,eAAO,MAAM,eAAe,EAAE,cAY7B,CAAA"}
|
|
@@ -22,6 +22,7 @@ const WORKSPACE_FEATURES = Object.freeze([
|
|
|
22
22
|
'host.workspaces.commands',
|
|
23
23
|
'host.workspaces.commandShell',
|
|
24
24
|
'host.workspaces.rename',
|
|
25
|
+
'host.workspaces.remove',
|
|
25
26
|
'host.workspaces.runCommand',
|
|
26
27
|
]);
|
|
27
28
|
function serviceEvidence(id) {
|
|
@@ -157,8 +158,14 @@ async function verifyWorkspaceLive(ctx) {
|
|
|
157
158
|
out.push(degradedFeature('host.workspaces.commands', [serviceEvidence('tuiWorkspaces'), probeEvidence('tuiWorkspaces.commands()', errorText(error))], 'tuiWorkspaces.commands() live-probe'));
|
|
158
159
|
}
|
|
159
160
|
// No safe auto-reversible P3 probe for command-shell execution, renaming,
|
|
160
|
-
// or provider command execution
|
|
161
|
-
|
|
161
|
+
// ledger registration/removal, or provider command execution: each mutates
|
|
162
|
+
// durable state a probe cannot undo. These stay feature-degraded.
|
|
163
|
+
for (const feature of [
|
|
164
|
+
'host.workspaces.commandShell',
|
|
165
|
+
'host.workspaces.rename',
|
|
166
|
+
'host.workspaces.remove',
|
|
167
|
+
'host.workspaces.runCommand',
|
|
168
|
+
]) {
|
|
162
169
|
out.push(degradedFeature(feature, [serviceEvidence('tuiWorkspaces')], `${feature}.live-probe`));
|
|
163
170
|
}
|
|
164
171
|
return out;
|
|
@@ -171,6 +178,7 @@ function createWorkspacePort(host) {
|
|
|
171
178
|
describe: cwd => host.describe(cwd),
|
|
172
179
|
commandShell: cwd => host.commandShell(cwd),
|
|
173
180
|
rename: (cwd, title) => host.rename(cwd, title),
|
|
181
|
+
remove: cwd => host.remove(cwd),
|
|
174
182
|
commands: () => host.commands(),
|
|
175
183
|
runCommand: (name, input, cwd, signal) => host.runCommand(name, input, cwd, signal),
|
|
176
184
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AAChH,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AAWhH,+EAA+E;AAC/E,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,KAAK,SAAS,qBAAqB,EAAE,CAAA;AAEpG;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AAChH,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AAWhH,+EAA+E;AAC/E,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,KAAK,SAAS,qBAAqB,EAAE,CAAA;AAEpG;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,YAAY,EAgExC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,YAAY,EAElD,CAAA;AAED,0DAA0D;AAC1D,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAEpD,CAAA;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAIhG;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAIhD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,SAAS,YAAY,EAAmB,GAC7C,OAAO,CAKT;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,SAAS,YAAY,EAAmB,GAC7C,YAAY,EAAE,CAKhB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,SAAS,YAAY,EAAmB,EAC/C,QAAQ,GAAE,eAA0B,GACnC,iBAAiB,EAAE,CAuCrB"}
|
package/lib/types/commands.js
CHANGED
|
@@ -74,6 +74,7 @@ export const LOCAL_COMMANDS = [
|
|
|
74
74
|
{ name: 'terminal-setup', description: 'Show terminal setup instructions' },
|
|
75
75
|
{ name: 'connect', description: 'Connect to a remote machine' },
|
|
76
76
|
{ name: 'workspace', description: 'Resume, rename, or open a workspace' },
|
|
77
|
+
{ name: 'home', description: 'Workspace home: manage workspaces and open their sessions' },
|
|
77
78
|
// Help / exit
|
|
78
79
|
{ name: 'help', description: 'Show shortcuts and commands' },
|
|
79
80
|
{ name: 'tips', description: 'Show usage tips and shortcuts' },
|
|
@@ -3,11 +3,19 @@ import type { Color } from '../ink/styles.js';
|
|
|
3
3
|
import { type ContextSegments } from '../screens/StatusMetrics.js';
|
|
4
4
|
/**
|
|
5
5
|
* The hoverable JSX twin of `renderContextBar`: the same segmented context
|
|
6
|
-
* bar (same largest-remainder column split, same
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* bar (same largest-remainder column split, same free-segment readout),
|
|
7
|
+
* rendered as one Box per segment so the bar can react to the pointer.
|
|
8
|
+
*
|
|
9
|
+
* A used segment is its fill color and nothing else — no label (community
|
|
10
|
+
* feedback on the old `s`/`p`/`t` letters: they read as noise on a row that is
|
|
11
|
+
* already decorative, and they never fit the narrow segments anyway). The only
|
|
12
|
+
* text left is the free segment's right-aligned usage readout.
|
|
13
|
+
*
|
|
14
|
+
* ONE hover target for the whole bar rather than one per segment. The colors
|
|
15
|
+
* are named where there is room for words: hovering anywhere on the bar parks
|
|
16
|
+
* the full per-content-type breakdown on the footer's supplemental row. A
|
|
17
|
+
* per-segment target also made every crossing of the five fills an
|
|
18
|
+
* enter+leave pair, hence a footer re-render per crossing.
|
|
11
19
|
*
|
|
12
20
|
* The component path follows the ANSI path's geometry: this exists so the bar
|
|
13
21
|
* can react to the pointer, not to restyle it.
|
|
@@ -26,8 +34,8 @@ export declare function ContextBarView({ segments, usedTokens, contextWindow, wi
|
|
|
26
34
|
freeFill: Color;
|
|
27
35
|
freeText: Color;
|
|
28
36
|
};
|
|
29
|
-
/** Hover signal:
|
|
37
|
+
/** Hover signal: true while the pointer is anywhere on the bar, false on
|
|
30
38
|
* leave. Absent handlers render a static bar (tests, headless embeds). */
|
|
31
|
-
onHover?: (
|
|
39
|
+
onHover?: (hovered: boolean) => void;
|
|
32
40
|
}): React.ReactNode;
|
|
33
41
|
//# sourceMappingURL=ContextBarView.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextBarView.d.ts","sourceRoot":"","sources":["../../../src/components/ContextBarView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,
|
|
1
|
+
{"version":3,"file":"ContextBarView.d.ts","sourceRoot":"","sources":["../../../src/components/ContextBarView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAQL,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAA;AAEpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,UAAU,EACV,aAAa,EACb,KAAK,EACL,MAAM,EACN,OAAO,GACR,EAAE;IACD,oCAAoC;IACpC,QAAQ,EAAE,eAAe,CAAA;IACzB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAA;IAClB,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,MAAM,CAAC,EAAE;QAAE,QAAQ,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE,KAAK,CAAA;KAAE,CAAA;IAC7C;+EAC2E;IAC3E,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CACrC,GAAG,KAAK,CAAC,SAAS,CA2DlB"}
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from '../ui.js';
|
|
3
|
-
import { USED_SEGMENTS, allocateBarColumns,
|
|
4
|
-
/** Free-segment colors matching StatusMetrics' dark-theme defaults. */
|
|
5
|
-
const FREE_FILL = '#E8E8E8';
|
|
6
|
-
const FREE_TEXT = '#4A4A4A';
|
|
7
|
-
const USED_TEXT = '#FFFFFF';
|
|
3
|
+
import { FREE_SEGMENT_FILL, FREE_SEGMENT_TEXT, USED_SEGMENTS, allocateBarColumns, contextBarReadout, contextPressureStep, rightAlignBarText, } from '../screens/StatusMetrics.js';
|
|
8
4
|
/**
|
|
9
5
|
* The hoverable JSX twin of `renderContextBar`: the same segmented context
|
|
10
|
-
* bar (same largest-remainder column split, same
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
6
|
+
* bar (same largest-remainder column split, same free-segment readout),
|
|
7
|
+
* rendered as one Box per segment so the bar can react to the pointer.
|
|
8
|
+
*
|
|
9
|
+
* A used segment is its fill color and nothing else — no label (community
|
|
10
|
+
* feedback on the old `s`/`p`/`t` letters: they read as noise on a row that is
|
|
11
|
+
* already decorative, and they never fit the narrow segments anyway). The only
|
|
12
|
+
* text left is the free segment's right-aligned usage readout.
|
|
13
|
+
*
|
|
14
|
+
* ONE hover target for the whole bar rather than one per segment. The colors
|
|
15
|
+
* are named where there is room for words: hovering anywhere on the bar parks
|
|
16
|
+
* the full per-content-type breakdown on the footer's supplemental row. A
|
|
17
|
+
* per-segment target also made every crossing of the five fills an
|
|
18
|
+
* enter+leave pair, hence a footer re-render per crossing.
|
|
15
19
|
*
|
|
16
20
|
* The component path follows the ANSI path's geometry: this exists so the bar
|
|
17
21
|
* can react to the pointer, not to restyle it.
|
|
@@ -22,25 +26,25 @@ export function ContextBarView({ segments, usedTokens, contextWindow, width, col
|
|
|
22
26
|
const freeTokens = Math.max(0, contextWindow - usedTokens);
|
|
23
27
|
const values = [...USED_SEGMENTS.map(segment => segments[segment.key]), freeTokens];
|
|
24
28
|
const columns = allocateBarColumns(values, width);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
// The readout is the bar's only text, and its one pressure signal: amber
|
|
30
|
+
// from 80% occupancy, red from 95% (the footer's shared thresholds). The
|
|
31
|
+
// theme key wins over the free-text color, which stays for comfortable
|
|
32
|
+
// occupancy.
|
|
33
|
+
const readout = contextBarReadout(usedTokens, contextWindow);
|
|
34
|
+
const pressure = contextPressureStep((usedTokens / contextWindow) * 100);
|
|
28
35
|
const nodes = [];
|
|
29
36
|
for (const [index, segment] of USED_SEGMENTS.entries()) {
|
|
30
37
|
const segmentWidth = columns[index] ?? 0;
|
|
31
38
|
if (segmentWidth <= 0)
|
|
32
39
|
continue;
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
// Childless on purpose: the renderer fills a node's own rect with its
|
|
41
|
+
// backgroundColor, so the segment is a pure colored block (render-node-to-
|
|
42
|
+
// output's ownBackgroundColor fill).
|
|
43
|
+
nodes.push(_jsx(Box, { width: segmentWidth, height: 1, flexShrink: 0, backgroundColor: segment.color }, segment.key));
|
|
35
44
|
}
|
|
36
45
|
const freeWidth = columns[USED_SEGMENTS.length] ?? 0;
|
|
37
46
|
if (freeWidth > 0) {
|
|
38
|
-
nodes.push(_jsx(Box, { width: freeWidth, height: 1, flexShrink: 0, backgroundColor: colors?.freeFill ??
|
|
39
|
-
`ctx ${total} ${percent} ${free}`,
|
|
40
|
-
`${total} ${percent} ${free}`,
|
|
41
|
-
`${total} ${percent}`,
|
|
42
|
-
percent,
|
|
43
|
-
], freeWidth) }) }, "free"));
|
|
47
|
+
nodes.push(_jsx(Box, { width: freeWidth, height: 1, flexShrink: 0, backgroundColor: colors?.freeFill ?? FREE_SEGMENT_FILL, children: _jsx(Text, { color: pressure ?? colors?.freeText ?? FREE_SEGMENT_TEXT, wrap: "truncate", children: rightAlignBarText(readout, freeWidth) }) }, "free"));
|
|
44
48
|
}
|
|
45
|
-
return (_jsx(Box, { flexDirection: "row", flexShrink: 0, width: width, children: nodes }));
|
|
49
|
+
return (_jsx(Box, { flexDirection: "row", flexShrink: 0, width: width, onMouseEnter: onHover === undefined ? undefined : () => onHover(true), onMouseLeave: onHover === undefined ? undefined : () => onHover(false), children: nodes }));
|
|
46
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImagePreviewOverlay.d.ts","sourceRoot":"","sources":["../../../src/components/ImagePreviewOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAQzB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAA;AAiC1E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,OAAO,EACP,MAAM,EACN,KAAK,EACL,UAAU,GACX,EAAE;IACD,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAA;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACrE;mCAC+B;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE;QACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;QACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;QACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,CAAA;QAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAC5B,CAAA;CACF,GAAG,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"ImagePreviewOverlay.d.ts","sourceRoot":"","sources":["../../../src/components/ImagePreviewOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAQzB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAA;AAiC1E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,OAAO,EACP,MAAM,EACN,KAAK,EACL,UAAU,GACX,EAAE;IACD,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAA;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACrE;mCAC+B;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE;QACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;QACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;QACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,CAAA;QAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAC5B,CAAA;CACF,GAAG,KAAK,CAAC,SAAS,CAwNlB"}
|
|
@@ -106,10 +106,16 @@ export function ImagePreviewOverlay({ image, onClose, region, title, navigation,
|
|
|
106
106
|
const graphicsFit = columns >= MIN_GRAPHICS_COLUMNS && rows >= MIN_GRAPHICS_ROWS;
|
|
107
107
|
const graphicsAvailable = useTerminalImages(graphicsFit);
|
|
108
108
|
const cell = useTerminalImageCellSize();
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const
|
|
109
|
+
// Zoom belongs to the attachment (`image.id`), not to the facade object:
|
|
110
|
+
// a caller may hand a fresh facade for the same attachment on every
|
|
111
|
+
// render, and keying on the object would reset the view each commit (#885).
|
|
112
|
+
const imageId = image.id;
|
|
113
|
+
const [view, setView] = React.useState({ imageId, zoom: 0 });
|
|
114
|
+
React.useEffect(() => {
|
|
115
|
+
setView(previous => previous.imageId === imageId ? previous : { imageId, zoom: 0 });
|
|
116
|
+
}, [imageId]);
|
|
117
|
+
const zoom = view.imageId === imageId && cell && graphicsAvailable ? view.zoom : 0;
|
|
118
|
+
const setZoom = (value) => setView({ imageId, zoom: value });
|
|
113
119
|
const maxImageColumns = Math.max(1, Math.min(columns - 2, Math.floor(columns * PREVIEW_MAX_WIDTH_RATIO)) - CARD_CHROME_COLS);
|
|
114
120
|
const navigationRows = navigation && navigation.total > 1 && rows >= 6 ? 1 : 0;
|
|
115
121
|
const maxImageRows = Math.max(1, Math.min(rows - 2, Math.floor(rows * PREVIEW_MAX_HEIGHT_RATIO)) - CARD_CHROME_ROWS - 1 - navigationRows);
|
|
@@ -239,7 +245,7 @@ function OriginalImageLink({ image, label }) {
|
|
|
239
245
|
React.useEffect(() => {
|
|
240
246
|
setStatus('idle');
|
|
241
247
|
return () => { pending.current?.abort(); pending.current = null; };
|
|
242
|
-
}, [image]);
|
|
248
|
+
}, [image.id]);
|
|
243
249
|
const tooltip = useTooltip(image.path ?? image.name ?? t('image-preview-open-original'));
|
|
244
250
|
return _jsx(Box, { height: 1, flexShrink: 0, ...tooltip, onDragStart: stopControlDrag, onClick: event => {
|
|
245
251
|
event.stopImmediatePropagation();
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { type Token } from 'marked';
|
|
2
3
|
/**
|
|
3
4
|
* Markdown 渲染组件:marked 分词 + ANSI 格式化。
|
|
4
5
|
*
|
|
5
|
-
* 表格 token 交给 MarkdownTable 渲染为带边框的 flexbox
|
|
6
|
+
* 表格 token 交给 MarkdownTable 渲染为带边框的 flexbox 布局,mermaid
|
|
7
|
+
* 代码块交给 MermaidDiagram 画成 box-drawing 图(两者都需要终端宽度,
|
|
8
|
+
* 所以是独立节点而不是 ANSI 字符串);
|
|
6
9
|
* 其余块级内容由 formatToken 转成 ANSI 字符串,按块边界分批放进
|
|
7
10
|
* Text(只去整段首尾空白)。代码块高亮由 cli-highlight 异步提供,
|
|
8
11
|
* 加载完成后自动触发一次重渲染。无 markdown 语法的纯文本走快速
|
|
@@ -15,6 +18,13 @@ type Props = {
|
|
|
15
18
|
/** 为 false 时跳过 token 缓存(流式尾部的内容逐帧变化,缓存必然失效) */
|
|
16
19
|
cacheTokens?: boolean;
|
|
17
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Tokens that render as their own layout node (a width-aware component)
|
|
23
|
+
* instead of joining the ANSI text run. StreamingMarkdown consults the same
|
|
24
|
+
* predicate: a standalone node has a fixed one-row gap to its neighbours
|
|
25
|
+
* rather than the newline-derived spacing of text blocks.
|
|
26
|
+
*/
|
|
27
|
+
export declare function isStandaloneToken(token: Token): boolean;
|
|
18
28
|
/**
|
|
19
29
|
* 混合渲染 Markdown 内容:表格用带边框的 flexbox 组件,其余内容由
|
|
20
30
|
* formatToken 生成 ANSI 字符串放入 Text。高亮对象异步就绪后自动刷新。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAU,KAAK,KAAK,EAAe,MAAM,QAAQ,CAAA;AAQxD;;;;;;;;;;GAUG;AAEH,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AA4ED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAEvD;AAgFD;;;;;;;;;;GAUG;AACH,iBAAS,YAAY,CAAC,EAAE,QAAQ,EAAE,QAAgB,EAAE,WAAkB,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CA6BhG;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,gDAMpB,CAAA"}
|
|
@@ -4,7 +4,9 @@ import { marked } from 'marked';
|
|
|
4
4
|
import { Box, Text } from '../ui.js';
|
|
5
5
|
import { configureMarked, formatToken, stripPromptXMLTags } from '../terminal-utils/markdown.js';
|
|
6
6
|
import { getCliHighlightPromise } from '../terminal-utils/cliHighlight.js';
|
|
7
|
+
import { isMermaidLang } from '../terminal-utils/mermaid.js';
|
|
7
8
|
import { MarkdownTable } from './MarkdownTable.js';
|
|
9
|
+
import { MermaidDiagram } from './MermaidDiagram.js';
|
|
8
10
|
// ---- token 缓存 ----
|
|
9
11
|
//
|
|
10
12
|
// marked.lexer 在组件重挂载时是最贵的开销;消息内容不可变,相同文本
|
|
@@ -73,8 +75,20 @@ function lexWithCache(content, allowCache) {
|
|
|
73
75
|
return tokens;
|
|
74
76
|
}
|
|
75
77
|
/**
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
+
* Tokens that render as their own layout node (a width-aware component)
|
|
79
|
+
* instead of joining the ANSI text run. StreamingMarkdown consults the same
|
|
80
|
+
* predicate: a standalone node has a fixed one-row gap to its neighbours
|
|
81
|
+
* rather than the newline-derived spacing of text blocks.
|
|
82
|
+
*/
|
|
83
|
+
export function isStandaloneToken(token) {
|
|
84
|
+
return token.type === 'table' || isMermaidToken(token);
|
|
85
|
+
}
|
|
86
|
+
function isMermaidToken(token) {
|
|
87
|
+
return token.type === 'code' && isMermaidLang(token.lang);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 把 lexer 产出的 token 列表转成 React 节点序列:table 与 mermaid 块独立
|
|
91
|
+
* 渲染,其余 token 的 ANSI 文本按完整块分批拼接,只去整段首尾空白。
|
|
78
92
|
*/
|
|
79
93
|
function renderTokensToNodes(tokens, highlight, dimColor) {
|
|
80
94
|
const nodes = [];
|
|
@@ -108,6 +122,10 @@ function renderTokensToNodes(tokens, highlight, dimColor) {
|
|
|
108
122
|
flushAnsiText();
|
|
109
123
|
nodes.push(_jsx(MarkdownTable, { token: token, highlight: highlight }, nodes.length));
|
|
110
124
|
}
|
|
125
|
+
else if (isMermaidToken(token)) {
|
|
126
|
+
flushAnsiText();
|
|
127
|
+
nodes.push(_jsx(MermaidDiagram, { token: token, highlight: highlight, dimColor: dimColor }, nodes.length));
|
|
128
|
+
}
|
|
111
129
|
else {
|
|
112
130
|
ansiText += formatToken(token, 0, null, null, highlight);
|
|
113
131
|
// A top-level token boundary keeps inline formatting and code fences
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Tokens } from 'marked';
|
|
3
|
+
import type { CliHighlight } from '../terminal-utils/cliHighlight.js';
|
|
4
|
+
type Props = {
|
|
5
|
+
token: Tokens.Code;
|
|
6
|
+
highlight: CliHighlight | null;
|
|
7
|
+
dimColor: boolean;
|
|
8
|
+
/** Override terminal width (useful for testing). */
|
|
9
|
+
forceWidth?: number;
|
|
10
|
+
};
|
|
11
|
+
export declare function MermaidDiagram({ token, highlight, dimColor, forceWidth }: Props): React.ReactNode;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=MermaidDiagram.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MermaidDiagram.d.ts","sourceRoot":"","sources":["../../../src/components/MermaidDiagram.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAOpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAA;AA6BrE,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAC,IAAI,CAAA;IAClB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;IAC9B,QAAQ,EAAE,OAAO,CAAA;IACjB,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAmBD,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAgCjG"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Box, Text } from '../ui.js';
|
|
4
|
+
import { useTerminalSize } from '../ink/hooks/use-terminal-size.js';
|
|
5
|
+
import { stringWidth } from '../ink/stringWidth.js';
|
|
6
|
+
import { getTheme } from '../theme.js';
|
|
7
|
+
import { useTheme } from './design-system/ThemeProvider.js';
|
|
8
|
+
import { formatToken } from '../terminal-utils/markdown.js';
|
|
9
|
+
import { getMermaidEnginePromise, paintMermaidArt, peekMermaidEngine, renderMermaid, } from '../terminal-utils/mermaid.js';
|
|
10
|
+
import { getMermaidDiagrams, subscribeMermaidDiagrams } from '../tuiDisplayPrefs.js';
|
|
11
|
+
import { t } from '../i18n.js';
|
|
12
|
+
/**
|
|
13
|
+
* A ```mermaid fence rendered as Unicode box-drawing art.
|
|
14
|
+
*
|
|
15
|
+
* The art is shown on its own, indented like a code-block body; the
|
|
16
|
+
* ```mermaid fence line is a code-block affordance and a diagram needs none.
|
|
17
|
+
* Whenever there is no art to show (setting off, engine still loading or
|
|
18
|
+
* unavailable, unsupported diagram type, nothing parsed, or the layout is
|
|
19
|
+
* wider than the viewport) the block falls back to the ordinary code-block
|
|
20
|
+
* rendering — fence line included, because that IS a code block — and a
|
|
21
|
+
* too-wide diagram adds a caption with the width it needs.
|
|
22
|
+
*/
|
|
23
|
+
/** Same viewport slack MarkdownTable keeps for gutters and message insets. */
|
|
24
|
+
const SAFETY_MARGIN = 4;
|
|
25
|
+
const INDENT = ' ';
|
|
26
|
+
/** Column budget the indent takes: display width, not string length. */
|
|
27
|
+
const INDENT_WIDTH = stringWidth(INDENT);
|
|
28
|
+
/** The lazily loaded engine: available on first render once any earlier
|
|
29
|
+
* diagram loaded it, otherwise resolved after mount. */
|
|
30
|
+
function useMermaidEngine() {
|
|
31
|
+
const [engine, setEngine] = React.useState(() => peekMermaidEngine() ?? null);
|
|
32
|
+
React.useEffect(() => {
|
|
33
|
+
if (engine !== null)
|
|
34
|
+
return;
|
|
35
|
+
let mounted = true;
|
|
36
|
+
void getMermaidEnginePromise().then(loaded => {
|
|
37
|
+
if (mounted && loaded !== null)
|
|
38
|
+
setEngine(loaded);
|
|
39
|
+
});
|
|
40
|
+
return () => {
|
|
41
|
+
mounted = false;
|
|
42
|
+
};
|
|
43
|
+
}, [engine]);
|
|
44
|
+
return engine;
|
|
45
|
+
}
|
|
46
|
+
export function MermaidDiagram({ token, highlight, dimColor, forceWidth }) {
|
|
47
|
+
const enabled = React.useSyncExternalStore(subscribeMermaidDiagrams, getMermaidDiagrams);
|
|
48
|
+
const engine = useMermaidEngine();
|
|
49
|
+
const { columns } = useTerminalSize();
|
|
50
|
+
const [themeName] = useTheme();
|
|
51
|
+
const theme = getTheme(themeName);
|
|
52
|
+
const width = Math.max(0, forceWidth ?? columns);
|
|
53
|
+
// Layout is width-independent (the engine draws at natural size), so a
|
|
54
|
+
// resize or theme switch only re-paints; streaming changes token.text
|
|
55
|
+
// every frame and re-lays out — sub-millisecond for a warm engine.
|
|
56
|
+
const art = React.useMemo(() => (enabled && engine !== null ? renderMermaid(engine, token.text) : null), [enabled, engine, token.text]);
|
|
57
|
+
if (art === null || art.width > width - INDENT_WIDTH - SAFETY_MARGIN) {
|
|
58
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { dimColor: dimColor, children: formatToken(token, 0, null, null, highlight).trimEnd() }), art !== null && (_jsx(Text, { color: "inactive", children: INDENT + t('mermaid-too-wide', { width: art.width }) }))] }));
|
|
59
|
+
}
|
|
60
|
+
return (_jsx(Text, { dimColor: dimColor, children: paintMermaidArt(art, theme).map(line => INDENT + line).join('\n') }));
|
|
61
|
+
}
|
|
@@ -5,7 +5,26 @@ import type { TranscriptImage } from '../dsh-adapter/transcript-images.js';
|
|
|
5
5
|
import type { DOMElement } from '../ink/dom.js';
|
|
6
6
|
import { type TimelineSnapshot } from '../ink/timeline-rail.js';
|
|
7
7
|
import type { ToolBackground } from '../tuiDisplayPrefs.js';
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Display form of an IDE-selection path (T-FIX-01): when the path lives
|
|
10
|
+
* under the session cwd, strip that prefix so the indicator line reads
|
|
11
|
+
* `src/a.ts` instead of a long absolute path (UAT finding — the extension
|
|
12
|
+
* anchors at its workspace root while the TUI session cwd is the git
|
|
13
|
+
* worktree root, so raw paths are long and redundant). Pure display layer:
|
|
14
|
+
* the `<attached-file>` block keeps its absolute path for the model.
|
|
15
|
+
*
|
|
16
|
+
* Comparison reuses normalizeIdePath (the ide-channel lock matcher's
|
|
17
|
+
* normalizer: backslashes folded to forward slashes, trailing slashes
|
|
18
|
+
* stripped, case folded on case-insensitive filesystems) so Windows forms
|
|
19
|
+
* like `d:/x` vs `D:\X` still match. Prefix hits return the remainder
|
|
20
|
+
* (`src/a.ts`); everything else — outside cwd, empty/undefined cwd, or the
|
|
21
|
+
* path being the cwd itself — returns the input unchanged. NOT basename:
|
|
22
|
+
* that would drop the directory context and collide on same-named files.
|
|
23
|
+
* `caseInsensitive` is parameterized so verifiers can pin either mode on
|
|
24
|
+
* any host.
|
|
25
|
+
*/
|
|
26
|
+
export declare function displaySelectionPath(path: string, sessionCwd: string | undefined, caseInsensitive?: boolean): string;
|
|
27
|
+
export declare function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, streamViewToggledRows, onToggleStreamView, model, diffLayout, thinkingFold, toolBackground, foldTerminalCommand, smoothStreaming, activityFrames, showAll, onToggleAll, onLoadOlder, thinkingVisible, historyPaintEnabled, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, onTimeline, failureHintRowId, failureHint, onOpenSubagent, onOpenJobs, onOpenFile, sessionCwd, onPreviewImage, suppressImageGraphics, }: {
|
|
9
28
|
rows: readonly ChatRow[];
|
|
10
29
|
expanded: boolean;
|
|
11
30
|
expandedRows: ReadonlySet<number>;
|
|
@@ -93,6 +112,12 @@ export declare function MessageList({ rows, expanded, expandedRows, selectedId,
|
|
|
93
112
|
onOpenJobs?: () => void;
|
|
94
113
|
/** 点击工具卡内的文件路径(打开文件操作菜单)。 */
|
|
95
114
|
onOpenFile?: (path: string) => void;
|
|
115
|
+
/** Session working directory (fs path, `channel.cwd`): the IDE-selection
|
|
116
|
+
* indicator line strips this prefix for display (T-FIX-01). Optional —
|
|
117
|
+
* repro/verify harnesses that predate the field render unchanged with
|
|
118
|
+
* raw paths. The real fs cwd, NOT displayCwd: remote URI display forms
|
|
119
|
+
* can't prefix-match selection paths. */
|
|
120
|
+
sessionCwd?: string | undefined;
|
|
96
121
|
/** 点击 transcript 缩略图(打开共享的大图预览 overlay)。 */
|
|
97
122
|
onPreviewImage?: (image: TranscriptImage) => void;
|
|
98
123
|
/** Modal preview owns the terminal-image frame budget while open. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAEvC,OAAO,EAA8B,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAE3E,OAAO,KAAK,EAAE,OAAO,EAA8D,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/MessageList.tsx"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
import React, { useState } from 'react';
|
|
3
3
|
import { getLang, subscribeLang, t } from '../i18n.js';
|
|
4
4
|
import { Box, Text, useTerminalSize } from '../ui.js';
|
|
5
|
+
import { normalizeIdePath } from '../dsh-adapter/ide-channel.js';
|
|
5
6
|
import { Divider } from './design-system/Divider.js';
|
|
6
7
|
import { UserPromptMessage } from './messages/UserPromptMessage.js';
|
|
7
8
|
import { AssistantTextMessage } from './messages/AssistantTextMessage.js';
|
|
@@ -92,6 +93,48 @@ function revealDisplayLen(row, enabled) {
|
|
|
92
93
|
}
|
|
93
94
|
return row.text.length;
|
|
94
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Display form of an IDE-selection path (T-FIX-01): when the path lives
|
|
98
|
+
* under the session cwd, strip that prefix so the indicator line reads
|
|
99
|
+
* `src/a.ts` instead of a long absolute path (UAT finding — the extension
|
|
100
|
+
* anchors at its workspace root while the TUI session cwd is the git
|
|
101
|
+
* worktree root, so raw paths are long and redundant). Pure display layer:
|
|
102
|
+
* the `<attached-file>` block keeps its absolute path for the model.
|
|
103
|
+
*
|
|
104
|
+
* Comparison reuses normalizeIdePath (the ide-channel lock matcher's
|
|
105
|
+
* normalizer: backslashes folded to forward slashes, trailing slashes
|
|
106
|
+
* stripped, case folded on case-insensitive filesystems) so Windows forms
|
|
107
|
+
* like `d:/x` vs `D:\X` still match. Prefix hits return the remainder
|
|
108
|
+
* (`src/a.ts`); everything else — outside cwd, empty/undefined cwd, or the
|
|
109
|
+
* path being the cwd itself — returns the input unchanged. NOT basename:
|
|
110
|
+
* that would drop the directory context and collide on same-named files.
|
|
111
|
+
* `caseInsensitive` is parameterized so verifiers can pin either mode on
|
|
112
|
+
* any host.
|
|
113
|
+
*/
|
|
114
|
+
export function displaySelectionPath(path, sessionCwd, caseInsensitive = process.platform === 'win32' || process.platform === 'darwin') {
|
|
115
|
+
if (sessionCwd === undefined || sessionCwd === '')
|
|
116
|
+
return path;
|
|
117
|
+
// Shared normalizer (lock matching uses the same): backslashes fold to
|
|
118
|
+
// forward slashes, trailing slashes stripped — transforms that preserve
|
|
119
|
+
// character positions, so slicing the canonical path at the cwd's length
|
|
120
|
+
// keeps the file's own casing in the displayed relative string. Folding
|
|
121
|
+
// decides only WHETHER the prefix matches, never what gets sliced off.
|
|
122
|
+
const pathNorm = normalizeIdePath(path, false);
|
|
123
|
+
const cwdNorm = normalizeIdePath(sessionCwd, false);
|
|
124
|
+
if (cwdNorm === '' || cwdNorm.length >= pathNorm.length)
|
|
125
|
+
return path;
|
|
126
|
+
// The POSIX root `/` is a prefix of every absolute path without a further
|
|
127
|
+
// separator — `/repo/file.ts` under cwd `/` displays as `repo/file.ts`.
|
|
128
|
+
// (A `startsWith('/' + '/')` check would never match; coderabbit review.)
|
|
129
|
+
if (cwdNorm === '/') {
|
|
130
|
+
return pathNorm.startsWith('/') ? pathNorm.slice(1) : path;
|
|
131
|
+
}
|
|
132
|
+
const foldedPath = normalizeIdePath(pathNorm, caseInsensitive);
|
|
133
|
+
const foldedCwd = normalizeIdePath(cwdNorm, caseInsensitive);
|
|
134
|
+
if (!foldedPath.startsWith(`${foldedCwd}/`))
|
|
135
|
+
return path;
|
|
136
|
+
return pathNorm.slice(cwdNorm.length + 1);
|
|
137
|
+
}
|
|
95
138
|
/**
|
|
96
139
|
* Per-kind layout signature PARTS: the O(1) identity of every input that
|
|
97
140
|
* decides a row's rendered HEIGHT (see sigRef in MessageList). Fields are
|
|
@@ -113,7 +156,7 @@ function revealDisplayLen(row, enabled) {
|
|
|
113
156
|
* (parts.slice()).
|
|
114
157
|
*/
|
|
115
158
|
const signatureScratch = [];
|
|
116
|
-
function signatureParts(row, columns, expanded, expandedRows, streamViewToggledRows, thinkingVisible, thinkingFold, diffLayout, foldTerminalCommand, model, failureHintRowId, failureHint, displayTextLen) {
|
|
159
|
+
function signatureParts(row, columns, expanded, expandedRows, streamViewToggledRows, thinkingVisible, thinkingFold, diffLayout, foldTerminalCommand, model, failureHintRowId, failureHint, displayTextLen, sessionCwd) {
|
|
117
160
|
signatureScratch.length = 0;
|
|
118
161
|
// Universal height inputs: width reflows every row; kind switches height
|
|
119
162
|
// semantics wholesale; text length drives wrapping. `displayTextLen` is the
|
|
@@ -156,8 +199,26 @@ function signatureParts(row, columns, expanded, expandedRows, streamViewToggledR
|
|
|
156
199
|
// Folded one-liner vs full summary text.
|
|
157
200
|
signatureScratch.push(expanded, expandedRows.has(row.id));
|
|
158
201
|
break;
|
|
202
|
+
case 'user':
|
|
203
|
+
// T06: the selection indicator line above the bubble adds one rendered
|
|
204
|
+
// row whose text wraps with width — its presence and content length
|
|
205
|
+
// are height inputs. Missing this would leave offscreen spacer heights
|
|
206
|
+
// stale when the field arrives (scroll jump, DESIGN R4).
|
|
207
|
+
// T-FIX-01: the indicator renders the cwd-relative display path, so
|
|
208
|
+
// the signature hashes THAT string — a cwd switch (/workspace) that
|
|
209
|
+
// changes the display form must invalidate the cached height too.
|
|
210
|
+
// width is the display-CELL width (emoji / CJK / combining / ANSI
|
|
211
|
+
// differ from JS length), not the JS string length — two paths with
|
|
212
|
+
// equal length but different terminal widths must not share a cached
|
|
213
|
+
// height (coderabbit review, repo width convention).
|
|
214
|
+
signatureScratch.push(row.selectionAttached === undefined ? 0 : 1, stringWidth(displaySelectionPath(row.selectionAttached?.path ?? '', sessionCwd)), String(row.selectionAttached?.lines ?? ''));
|
|
215
|
+
// Long-line fold: expanding a folded row swaps the folded preview for
|
|
216
|
+
// the raw line (thousands of rows), so both expansion switches are
|
|
217
|
+
// height inputs on user rows too — same rationale as the default arm.
|
|
218
|
+
signatureScratch.push(expanded, expandedRows.has(row.id));
|
|
219
|
+
break;
|
|
159
220
|
default:
|
|
160
|
-
//
|
|
221
|
+
// notice / interrupt / local / local-output: height follows
|
|
161
222
|
// text + columns alone (selection/background never change height) —
|
|
162
223
|
// EXCEPT the long-line fold: expanding a folded row swaps ~10 rows of
|
|
163
224
|
// folded text for the raw line (thousands), so both expansion switches
|
|
@@ -169,7 +230,7 @@ function signatureParts(row, columns, expanded, expandedRows, streamViewToggledR
|
|
|
169
230
|
}
|
|
170
231
|
return signatureScratch;
|
|
171
232
|
}
|
|
172
|
-
export function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, streamViewToggledRows = NO_STREAM_VIEW_TOGGLED, onToggleStreamView = NOOP_TOGGLE_STREAM_VIEW, model, diffLayout = 'auto', thinkingFold = 'preview', toolBackground = 'none', foldTerminalCommand = false, smoothStreaming = false, activityFrames, showAll, onToggleAll, onLoadOlder, thinkingVisible = true, historyPaintEnabled = true, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, onTimeline, failureHintRowId, failureHint, onOpenSubagent, onOpenJobs, onOpenFile, onPreviewImage, suppressImageGraphics = false, }) {
|
|
233
|
+
export function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, streamViewToggledRows = NO_STREAM_VIEW_TOGGLED, onToggleStreamView = NOOP_TOGGLE_STREAM_VIEW, model, diffLayout = 'auto', thinkingFold = 'preview', toolBackground = 'none', foldTerminalCommand = false, smoothStreaming = false, activityFrames, showAll, onToggleAll, onLoadOlder, thinkingVisible = true, historyPaintEnabled = true, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, onTimeline, failureHintRowId, failureHint, onOpenSubagent, onOpenJobs, onOpenFile, sessionCwd, onPreviewImage, suppressImageGraphics = false, }) {
|
|
173
234
|
const lang = React.useSyncExternalStore(subscribeLang, getLang);
|
|
174
235
|
const hiddenCount = rows.length - RENDERED_ROW_CAP;
|
|
175
236
|
// The thinking filter runs BEFORE virtualization so window indices line up.
|
|
@@ -396,7 +457,7 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
|
|
|
396
457
|
// reasoning height at once, remounting the widened window over rows
|
|
397
458
|
// whose rendering never changed (Yoga spike + measure churn for
|
|
398
459
|
// nothing). Base parts cover the universal height inputs.
|
|
399
|
-
const parts = signatureParts(row, columns, expanded, expandedRows, streamViewToggledRows, thinkingVisible, thinkingFold, diffLayout, foldTerminalCommand, model, failureHintRowId, failureHint, revealDisplayLen(row, smoothStreaming));
|
|
460
|
+
const parts = signatureParts(row, columns, expanded, expandedRows, streamViewToggledRows, thinkingVisible, thinkingFold, diffLayout, foldTerminalCommand, model, failureHintRowId, failureHint, revealDisplayLen(row, smoothStreaming), sessionCwd);
|
|
400
461
|
const cachedParts = sigs.get(row.id);
|
|
401
462
|
let same = false;
|
|
402
463
|
if (cachedParts !== undefined && cachedParts.length === parts.length) {
|
|
@@ -959,7 +1020,7 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
|
|
|
959
1020
|
else if (row.kind === 'reasoning' && smoothStreaming) {
|
|
960
1021
|
displayText = revealTextOf(`r${row.id}`, row.text, { enabled: true, active: displayStreaming });
|
|
961
1022
|
}
|
|
962
|
-
return (_jsx(MemoRow, { rowId: row.id, kind: row.kind, text: displayText, images: row.images, textFull: row.kind === 'reasoning' ? row.text : undefined, executionTarget: row.executionTarget, streaming: displayStreaming, durationMs: row.durationMs, time: row.time, marginTopOnTurn: marginTopOnTurn, isSelected: selectedId === row.id, isExpanded: expandedRows.has(row.id), expanded: expanded, model: model, diffLayout: diffLayout, thinkingFold: thinkingFold, toolBackground: toolBackground, foldTerminalCommand: foldTerminalCommand, smoothStreaming: smoothStreaming, fresh: row.fresh === true, revealVersion: revealVersion, activityFrames: activityFrames, background: rowBackground(row.id), toolCallId: tool?.callId, toolName: tool?.name, toolArgsText: tool?.argsText, toolArgsFull: tool?.argsFull, toolStatus: tool?.status, toolResultText: tool?.resultText, toolResultFull: tool?.resultFull, toolErrorText: tool?.errorText, toolFootnote: failureHintRowId === row.id ? failureHint : undefined, toolCallView: tool?.callView, toolResultView: tool?.resultView, toolStartedAt: tool?.startedAt, toolDurationMs: tool?.durationMs, subagent: subagent, job: job, onToggleRow: onToggleRow, onToggleStreamView: onToggleStreamView, streamViewToggled: streamViewToggledRows.has(row.id), onOpenSubagent: onOpenSubagent, onOpenJobs: onOpenJobs, onOpenFile: onOpenFile, onPreviewImage: onPreviewImage, suppressImageGraphics: suppressImageGraphics, setRowRef: setRowRef }, row.id));
|
|
1023
|
+
return (_jsx(MemoRow, { rowId: row.id, kind: row.kind, text: displayText, images: row.images, textFull: row.kind === 'reasoning' ? row.text : undefined, executionTarget: row.executionTarget, selectionAttached: row.selectionAttached, streaming: displayStreaming, durationMs: row.durationMs, time: row.time, marginTopOnTurn: marginTopOnTurn, isSelected: selectedId === row.id, isExpanded: expandedRows.has(row.id), expanded: expanded, model: model, diffLayout: diffLayout, thinkingFold: thinkingFold, toolBackground: toolBackground, foldTerminalCommand: foldTerminalCommand, smoothStreaming: smoothStreaming, fresh: row.fresh === true, revealVersion: revealVersion, activityFrames: activityFrames, background: rowBackground(row.id), toolCallId: tool?.callId, toolName: tool?.name, toolArgsText: tool?.argsText, toolArgsFull: tool?.argsFull, toolStatus: tool?.status, toolResultText: tool?.resultText, toolResultFull: tool?.resultFull, toolErrorText: tool?.errorText, toolFootnote: failureHintRowId === row.id ? failureHint : undefined, toolCallView: tool?.callView, toolResultView: tool?.resultView, toolStartedAt: tool?.startedAt, toolDurationMs: tool?.durationMs, subagent: subagent, job: job, onToggleRow: onToggleRow, onToggleStreamView: onToggleStreamView, streamViewToggled: streamViewToggledRows.has(row.id), onOpenSubagent: onOpenSubagent, onOpenJobs: onOpenJobs, onOpenFile: onOpenFile, sessionCwd: sessionCwd, onPreviewImage: onPreviewImage, suppressImageGraphics: suppressImageGraphics, setRowRef: setRowRef }, row.id));
|
|
963
1024
|
}), bottomPad > 0 && _jsx(Box, { height: bottomPad, flexShrink: 0 })] }));
|
|
964
1025
|
}
|
|
965
1026
|
/** Load-earlier / show-previous divider row with a mouse hover tint — the
|
|
@@ -968,7 +1029,7 @@ function ClickableDivider({ title, onClick }) {
|
|
|
968
1029
|
const [hovered, setHovered] = useState(false);
|
|
969
1030
|
return (_jsx(Box, { marginTop: 1, onClick: onClick, onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), backgroundColor: hovered ? 'userMessageBackgroundHover' : undefined, children: _jsx(Divider, { title: title }) }));
|
|
970
1031
|
}
|
|
971
|
-
function TranscriptRow({ rowId, kind, text, images, textFull, executionTarget, streaming, durationMs, time, marginTopOnTurn, isSelected, isExpanded, expanded, model, diffLayout, smoothStreaming, fresh, revealVersion, thinkingFold, toolBackground, foldTerminalCommand, activityFrames, background, toolCallId, toolName, toolArgsText, toolArgsFull, toolStatus, toolResultText, toolResultFull, toolErrorText, toolFootnote, toolCallView, toolResultView, toolStartedAt, toolDurationMs, subagent, job, onToggleRow, onToggleStreamView, streamViewToggled, onOpenSubagent, onOpenJobs, onOpenFile, onPreviewImage, suppressImageGraphics, setRowRef, }) {
|
|
1032
|
+
function TranscriptRow({ rowId, kind, text, images, textFull, executionTarget, selectionAttached, sessionCwd, streaming, durationMs, time, marginTopOnTurn, isSelected, isExpanded, expanded, model, diffLayout, smoothStreaming, fresh, revealVersion, thinkingFold, toolBackground, foldTerminalCommand, activityFrames, background, toolCallId, toolName, toolArgsText, toolArgsFull, toolStatus, toolResultText, toolResultFull, toolErrorText, toolFootnote, toolCallView, toolResultView, toolStartedAt, toolDurationMs, subagent, job, onToggleRow, onToggleStreamView, streamViewToggled, onOpenSubagent, onOpenJobs, onOpenFile, onPreviewImage, suppressImageGraphics, setRowRef, }) {
|
|
972
1033
|
const ref = React.useCallback((el) => {
|
|
973
1034
|
setRowRef(rowId, el);
|
|
974
1035
|
}, [setRowRef, rowId]);
|
|
@@ -1018,7 +1079,11 @@ function TranscriptRow({ rowId, kind, text, images, textFull, executionTarget, s
|
|
|
1018
1079
|
const foldClickable = foldable && folded.hiddenChars > 0;
|
|
1019
1080
|
switch (kind) {
|
|
1020
1081
|
case 'user':
|
|
1021
|
-
return (_jsxs(Box, { flexDirection: "column", ref: ref, onClick: foldClickable ? foldOnClick : undefined, children: [
|
|
1082
|
+
return (_jsxs(Box, { flexDirection: "column", ref: ref, onClick: foldClickable ? foldOnClick : undefined, children: [selectionAttached && (_jsxs(Text, { dimColor: true, children: ['⧉ ', t('selection-attached', {
|
|
1083
|
+
lines: selectionAttached.lines,
|
|
1084
|
+
count: selectionAttached.lines,
|
|
1085
|
+
path: displaySelectionPath(selectionAttached.path, sessionCwd),
|
|
1086
|
+
})] })), text !== '' && (_jsx(UserPromptMessage, { text: displayText, marginTopOnTurn: marginTopOnTurn, isSelected: isSelected })), images !== undefined && (_jsx(Box, { marginTop: text === '' && marginTopOnTurn ? 1 : 0, children: _jsx(TranscriptImages, { images: images, onPreview: onPreviewImage, suppressGraphics: suppressImageGraphics }) }))] }));
|
|
1022
1087
|
case 'assistant':
|
|
1023
1088
|
return streaming ? (_jsxs(Box, { alignItems: "flex-start", flexDirection: "row", marginTop: marginTopOnTurn ? 1 : 0, width: "100%", backgroundColor: background, ref: ref, onClick: foldClickable ? foldOnClick : undefined, children: [_jsx(Box, { minWidth: 2, children: _jsx(Text, { color: "text", children: "\u25CF" }) }), _jsxs(Box, { flexDirection: "column", children: [_jsx(StreamingMarkdown, { children: stripNarration(displayText) }), images !== undefined && _jsx(TranscriptImages, { images: images, indent: 0, onPreview: onPreviewImage, suppressGraphics: suppressImageGraphics })] })] })) : (_jsxs(Box, { width: "100%", flexDirection: "column", backgroundColor: background, ref: ref, onClick: foldClickable ? foldOnClick : undefined, children: [expanded && (_jsx(Box, { flexDirection: "row", justifyContent: "flex-end", gap: 1, marginTop: 1, children: _jsx(MessageMetadata, { timestamp: time, model: model }) })), _jsx(AssistantTextMessage, { text: stripNarration(displayText), marginTopOnTurn: marginTopOnTurn, isSelected: isSelected, isExpanded: isExpanded }), images !== undefined && _jsx(TranscriptImages, { images: images, onPreview: onPreviewImage, suppressGraphics: suppressImageGraphics })] }));
|
|
1024
1089
|
case 'reasoning': {
|
|
@@ -17,7 +17,7 @@ import React from 'react';
|
|
|
17
17
|
* 组件(换行宽度、虚拟化、输入区预算、表格布局……)无需各自知道
|
|
18
18
|
* 边距存在——它们拿到的就是内容区尺寸;
|
|
19
19
|
* 3. 坐标层:`PageInsetContext` 报告内容区相对屏幕原点的偏移,供少数
|
|
20
|
-
* 以「屏幕坐标」做 absolute 定位的浮层(Tooltip
|
|
20
|
+
* 以「屏幕坐标」做 absolute 定位的浮层(Tooltip、会话列表
|
|
21
21
|
* 右键菜单)补偿——它们的锚点来自指针事件(屏幕坐标),而 absolute
|
|
22
22
|
* 盒子相对的是内缩后的内容区原点。
|
|
23
23
|
*
|