@deepseek-harness-tui/dsh-tui 0.8.1 → 0.8.2
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 +22 -13
- package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -0
- package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -0
- package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -0
- package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -0
- package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -0
- package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -0
- package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -0
- package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -0
- package/dsh-ecosystem-spec/registry/README.md +14 -0
- package/dsh-ecosystem-spec/registry/contracts/scene-v1alpha1.json +13 -0
- package/dsh-ecosystem-spec/registry/contracts/settings-section-v1alpha1.json +13 -0
- package/dsh-ecosystem-spec/registry/contracts/tui-channel-v1alpha1.json +30 -0
- package/dsh-ecosystem-spec/registry/contracts/workspace-provider-v1alpha1.json +6 -0
- package/{ecosystem-spec → dsh-ecosystem-spec}/registry/permissions-0.1.json +1 -1
- package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -0
- package/lib/types/command-trees.d.ts +2 -1
- package/lib/types/command-trees.d.ts.map +1 -1
- package/lib/types/command-trees.js +1 -1
- package/lib/types/components/LoadedContextPanel.d.ts +10 -5
- package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
- package/lib/types/components/LoadedContextPanel.js +18 -7
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +16 -7
- package/lib/types/components/Markdown.d.ts +13 -1
- package/lib/types/components/Markdown.d.ts.map +1 -1
- package/lib/types/components/Markdown.js +15 -1
- package/lib/types/components/MessageList.d.ts +3 -1
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +90 -9
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +26 -12
- package/lib/types/components/StreamingMarkdown.d.ts +2 -8
- package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
- package/lib/types/components/StreamingMarkdown.js +51 -9
- package/lib/types/components/activityFrames.d.ts +1 -1
- package/lib/types/components/activityFrames.d.ts.map +1 -1
- package/lib/types/components/activityFrames.js +4 -1
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts +5 -1
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +26 -3
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +12 -1
- package/lib/types/dsh-adapter/channel.d.ts +31 -4
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +267 -102
- package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -1
- package/lib/types/dsh-adapter/childStderr.js +10 -0
- package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -1
- package/lib/types/dsh-adapter/command-attribution.js +2 -2
- package/lib/types/dsh-adapter/command-trees.d.ts +7 -1
- package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -1
- package/lib/types/dsh-adapter/command-trees.js +70 -20
- package/lib/types/dsh-adapter/component-identity.d.ts +5 -0
- package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -1
- package/lib/types/dsh-adapter/component-identity.js +14 -14
- package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -1
- package/lib/types/dsh-adapter/decision-guard.js +10 -16
- package/lib/types/dsh-adapter/dialogs.d.ts +2 -3
- package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -1
- package/lib/types/dsh-adapter/dialogs.js +114 -60
- package/lib/types/dsh-adapter/effect-ledger.d.ts +0 -8
- package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -1
- package/lib/types/dsh-adapter/effect-ledger.js +73 -53
- package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -1
- package/lib/types/dsh-adapter/extension-events.js +39 -1
- package/lib/types/dsh-adapter/grants.d.ts.map +1 -1
- package/lib/types/dsh-adapter/grants.js +43 -14
- package/lib/types/dsh-adapter/host-access.d.ts +37 -0
- package/lib/types/dsh-adapter/host-access.d.ts.map +1 -0
- package/lib/types/dsh-adapter/host-access.js +652 -0
- package/lib/types/dsh-adapter/host-descriptor.d.ts +2 -2
- package/lib/types/dsh-adapter/host-descriptor.d.ts.map +1 -1
- package/lib/types/dsh-adapter/host-descriptor.js +31 -8
- package/lib/types/dsh-adapter/index.d.ts +4 -0
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +1 -0
- package/lib/types/dsh-adapter/message-observer.d.ts +10 -15
- package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -1
- package/lib/types/dsh-adapter/message-observer.js +114 -70
- package/lib/types/dsh-adapter/plugin-host.d.ts +39 -6
- package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin-host.js +139 -44
- package/lib/types/dsh-adapter/plugin-storage.d.ts +0 -5
- package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin-storage.js +48 -36
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +80 -16
- package/lib/types/dsh-adapter/promptDebug.d.ts +0 -6
- package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -1
- package/lib/types/dsh-adapter/promptDebug.js +13 -4
- package/lib/types/dsh-adapter/renderers.d.ts +6 -14
- package/lib/types/dsh-adapter/renderers.d.ts.map +1 -1
- package/lib/types/dsh-adapter/renderers.js +81 -46
- package/lib/types/dsh-adapter/scenes.d.ts +8 -4
- package/lib/types/dsh-adapter/scenes.d.ts.map +1 -1
- package/lib/types/dsh-adapter/scenes.js +136 -37
- package/lib/types/dsh-adapter/settings-sections.d.ts +7 -3
- package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
- package/lib/types/dsh-adapter/settings-sections.js +106 -26
- package/lib/types/dsh-adapter/shortcuts.d.ts +8 -10
- package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -1
- package/lib/types/dsh-adapter/shortcuts.js +108 -36
- package/lib/types/dsh-adapter/status.d.ts +6 -7
- package/lib/types/dsh-adapter/status.d.ts.map +1 -1
- package/lib/types/dsh-adapter/status.js +88 -22
- package/lib/types/dsh-adapter/workspaces.d.ts +16 -5
- package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -1
- package/lib/types/dsh-adapter/workspaces.js +287 -170
- package/lib/types/extensions.d.ts +10 -5
- package/lib/types/extensions.d.ts.map +1 -1
- package/lib/types/extensions.js +11 -5
- package/lib/types/force-production-react.d.ts +1 -0
- package/lib/types/force-production-react.d.ts.map +1 -0
- package/lib/types/force-production-react.js +12 -0
- package/lib/types/i18n.d.ts +14 -6
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +4 -2
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +1 -0
- package/lib/types/ink/components/App.d.ts +2 -0
- package/lib/types/ink/components/App.d.ts.map +1 -1
- package/lib/types/ink/components/App.js +4 -0
- package/lib/types/ink/ink.d.ts +20 -3
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +57 -5
- package/lib/types/ink/log-update.d.ts.map +1 -1
- package/lib/types/ink/log-update.js +128 -9
- package/lib/types/ink/output.d.ts +28 -2
- package/lib/types/ink/output.d.ts.map +1 -1
- package/lib/types/ink/output.js +158 -12
- package/lib/types/ink/screen.d.ts +39 -0
- package/lib/types/ink/screen.d.ts.map +1 -1
- package/lib/types/ink/screen.js +117 -0
- package/lib/types/ink/terminal.d.ts.map +1 -1
- package/lib/types/ink/terminal.js +10 -2
- package/lib/types/ink/wrapAnsi.d.ts +1 -1
- package/lib/types/ink/wrapAnsi.d.ts.map +1 -1
- package/lib/types/ink/wrapAnsi.js +29 -2
- package/lib/types/plugin-host.d.ts +13 -11
- package/lib/types/plugin-host.d.ts.map +1 -1
- package/lib/types/plugin-host.js +16 -16
- package/lib/types/plugin-spec/registry.d.ts +2 -2
- package/lib/types/plugin-spec/registry.d.ts.map +1 -1
- package/lib/types/plugin-spec/registry.js +113 -18
- package/lib/types/plugin-spec/tui-extension.d.ts.map +1 -1
- package/lib/types/plugin-spec/tui-extension.js +2 -0
- package/lib/types/plugin-spec/validate.d.ts.map +1 -1
- package/lib/types/plugin-spec/validate.js +20 -1
- package/lib/types/scenes.d.ts +2 -1
- package/lib/types/scenes.d.ts.map +1 -1
- package/lib/types/scenes.js +1 -1
- package/lib/types/screens/Chat.d.ts +3 -3
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +38 -17
- package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
- package/lib/types/screens/SessionBrowser.js +10 -3
- package/lib/types/sessions/view.d.ts +3 -2
- package/lib/types/sessions/view.d.ts.map +1 -1
- package/lib/types/sessions/view.js +18 -0
- package/lib/types/settings-sections.d.ts +2 -1
- package/lib/types/settings-sections.d.ts.map +1 -1
- package/lib/types/settings-sections.js +1 -1
- package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
- package/lib/types/utils/execFileNoThrow.js +3 -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/@dsh-std/command/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/command/package.json +1 -1
- package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
- package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
- package/node_modules/@dsh-std/connection/lib/memory.js +1 -0
- package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/node_modules/@dsh-std/connection/package.json +1 -1
- package/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/core/package.json +1 -1
- package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
- package/node_modules/@dsh-std/manifest/package.json +1 -1
- package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/messages/package.json +1 -1
- package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
- package/node_modules/@dsh-std/presentation/README.md +2 -1
- package/node_modules/@dsh-std/presentation/README.zh.md +2 -1
- package/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
- package/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
- package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
- package/node_modules/@dsh-std/presentation/lib/index.d.ts +44 -1
- package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -1
- package/node_modules/@dsh-std/presentation/lib/index.js +6 -3
- package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/presentation/package.json +7 -3
- package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/storage/package.json +1 -1
- package/package.json +10 -5
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +2 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +2 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts +44 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +6 -3
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +7 -3
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +1 -1
- package/ecosystem-spec/registry/registry-0.15.json +0 -57
- /package/{ecosystem-spec → dsh-ecosystem-spec}/registry/contracts/decision-events-v1alpha1.json +0 -0
- /package/{ecosystem-spec → dsh-ecosystem-spec}/registry/host-descriptor.tui.example.json +0 -0
- /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/conformance-claim.schema.json +0 -0
- /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/effect-ledger-record.schema.json +0 -0
- /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/host-descriptor.schema.json +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tui.channel",
|
|
3
|
+
"version": "v1alpha1",
|
|
4
|
+
"coordinates": {
|
|
5
|
+
"apiVersion": "tui.dsh/v1alpha1",
|
|
6
|
+
"kind": "Channel"
|
|
7
|
+
},
|
|
8
|
+
"kind": "capability",
|
|
9
|
+
"caller": "a negotiated TUI endpoint",
|
|
10
|
+
"permissions": [],
|
|
11
|
+
"operations": [
|
|
12
|
+
{"name": "open", "input": "workspace/session selector", "output": "complete channel snapshot"},
|
|
13
|
+
{"name": "subscribe", "input": "channel id and last observed version", "output": "snapshot progress stream"},
|
|
14
|
+
{"name": "invoke", "input": "channel method and JSON arguments", "output": "method progress, JSON result and optional snapshot"},
|
|
15
|
+
{"name": "close", "input": "channel id", "output": "closed acknowledgement"}
|
|
16
|
+
],
|
|
17
|
+
"wireRevision": 6,
|
|
18
|
+
"features": [
|
|
19
|
+
"commands", "credentials", "diagnostics", "files", "models", "modes",
|
|
20
|
+
"presets", "presentation", "provider-setup", "scenes", "session-history", "session-input",
|
|
21
|
+
"session-lifecycle", "session-state", "settings", "skills", "subagents",
|
|
22
|
+
"trace", "workspaces"
|
|
23
|
+
],
|
|
24
|
+
"errors": ["CHANNEL_NOT_FOUND", "FEATURE_UNAVAILABLE", "INVALID_ARGUMENT", "PERMISSION_DENIED", "REVISION_MISMATCH", "PROVIDER_FAILURE"],
|
|
25
|
+
"concurrency": "state mutations are serialized per channel; independent read operations may run concurrently",
|
|
26
|
+
"timeout": "the caller supplies connection invocation cancellation; subscriptions remain open until cancelled or closed",
|
|
27
|
+
"cleanup": "connection close or facet deactivate releases subscriptions, uploads and channel attachments",
|
|
28
|
+
"privacyClass": "sensitive",
|
|
29
|
+
"securityBoundary": false
|
|
30
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
{"name":"storage.local.write","default":"deny","revocable":true,"scope":"plugin namespace"},
|
|
6
6
|
{"name":"commands.invoke","default":"allow","revocable":true,"scope":"declared command id","rationale":"调用由宿主或用户通过一次 invocation 主动发起,不同于数据访问类权限——插件无法仅凭此权限被动读取任何数据,故默认允许;撤销只关闭该 command ID 的调用入口"},
|
|
7
7
|
{"name":"messages.observe.read","default":"deny","revocable":true,"scope":"message observation scope"},
|
|
8
|
-
{"name":"session.input.intercept","default":"deny","revocable":true,"scope":"decision event subscription","rationale":"拦截类订阅(RFC 0005 D-7):能否决/改写用户输入,严格强于观察,故默认拒绝;TUI 实验实现见 tui.dsh
|
|
8
|
+
{"name":"session.input.intercept","default":"deny","revocable":true,"scope":"decision event subscription","rationale":"拦截类订阅(RFC 0005 D-7):能否决/改写用户输入,严格强于观察,故默认拒绝;TUI 实验实现见 tui.dsh.decision-events"},
|
|
9
9
|
{"name":"session.rewind.intercept","default":"deny","revocable":true,"scope":"decision event subscription","rationale":"同 session.input.intercept——可否决会话回退或注入回退模式"},
|
|
10
10
|
{"name":"session.switch.intercept","default":"deny","revocable":true,"scope":"decision event subscription","rationale":"同 session.input.intercept——可否决会话切换"},
|
|
11
11
|
{"name":"session.compact.intercept","default":"deny","revocable":true,"scope":"decision event subscription","rationale":"同 session.input.intercept——可否决手动压缩"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"profileVersion": "tui-admission/0.15",
|
|
3
|
+
"std": {
|
|
4
|
+
"repository": "https://github.com/Yan-Zero/dsh-std",
|
|
5
|
+
"submodule": "vendor/dsh-std",
|
|
6
|
+
"manifestVersion": "0.15"
|
|
7
|
+
},
|
|
8
|
+
"imports": [
|
|
9
|
+
{
|
|
10
|
+
"name": "commands",
|
|
11
|
+
"coordinates": {
|
|
12
|
+
"apiVersion": "commands.dsh/v1alpha1",
|
|
13
|
+
"kind": "Command"
|
|
14
|
+
},
|
|
15
|
+
"package": "@dsh-std/command",
|
|
16
|
+
"kind": "capability",
|
|
17
|
+
"permissions": [
|
|
18
|
+
"commands.invoke"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "storage.local",
|
|
23
|
+
"coordinates": {
|
|
24
|
+
"apiVersion": "storage.dsh/v1alpha1",
|
|
25
|
+
"kind": "LocalStorage"
|
|
26
|
+
},
|
|
27
|
+
"package": "@dsh-std/storage",
|
|
28
|
+
"kind": "capability",
|
|
29
|
+
"permissions": [
|
|
30
|
+
"storage.local.read",
|
|
31
|
+
"storage.local.write"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "messages.observe",
|
|
36
|
+
"coordinates": {
|
|
37
|
+
"apiVersion": "messages.dsh/v1alpha1",
|
|
38
|
+
"kind": "MessageObserver"
|
|
39
|
+
},
|
|
40
|
+
"package": "@dsh-std/messages",
|
|
41
|
+
"kind": "event",
|
|
42
|
+
"permissions": [
|
|
43
|
+
"messages.observe.read"
|
|
44
|
+
],
|
|
45
|
+
"eventEnvelope": "@dsh-std/messages/schema/message-observer-envelope-0.15.json"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "presentation.open-external",
|
|
49
|
+
"coordinates": {
|
|
50
|
+
"apiVersion": "presentation.dsh/v1alpha1",
|
|
51
|
+
"kind": "OpenExternal"
|
|
52
|
+
},
|
|
53
|
+
"package": "@dsh-std/presentation",
|
|
54
|
+
"kind": "capability",
|
|
55
|
+
"permissions": []
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "presentation.user-interaction",
|
|
59
|
+
"coordinates": {
|
|
60
|
+
"apiVersion": "presentation.dsh/v1alpha1",
|
|
61
|
+
"kind": "UserInteraction"
|
|
62
|
+
},
|
|
63
|
+
"package": "@dsh-std/presentation",
|
|
64
|
+
"kind": "capability",
|
|
65
|
+
"permissions": []
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "presentation.external-redirect",
|
|
69
|
+
"coordinates": {
|
|
70
|
+
"apiVersion": "presentation.dsh/v1alpha1",
|
|
71
|
+
"kind": "ExternalRedirect"
|
|
72
|
+
},
|
|
73
|
+
"package": "@dsh-std/presentation",
|
|
74
|
+
"kind": "capability",
|
|
75
|
+
"permissions": []
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"definitions": [
|
|
79
|
+
{
|
|
80
|
+
"name": "tui.decision-events",
|
|
81
|
+
"authority": "dsh-tui",
|
|
82
|
+
"coordinates": {
|
|
83
|
+
"apiVersion": "tui.dsh/v1alpha1",
|
|
84
|
+
"kind": "DecisionEvents"
|
|
85
|
+
},
|
|
86
|
+
"kind": "capability",
|
|
87
|
+
"profile": "registry/contracts/decision-events-v1alpha1.json",
|
|
88
|
+
"profileHash": "sha256:56440dde1b00c210b22761a0cba139ce0a20207330567777cebe1e48b494ceb0",
|
|
89
|
+
"permissions": [
|
|
90
|
+
"session.input.intercept",
|
|
91
|
+
"session.rewind.intercept",
|
|
92
|
+
"session.switch.intercept",
|
|
93
|
+
"session.compact.intercept"
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "tui.channel",
|
|
98
|
+
"authority": "dsh-tui",
|
|
99
|
+
"coordinates": {
|
|
100
|
+
"apiVersion": "tui.dsh/v1alpha1",
|
|
101
|
+
"kind": "Channel"
|
|
102
|
+
},
|
|
103
|
+
"kind": "capability",
|
|
104
|
+
"profile": "registry/contracts/tui-channel-v1alpha1.json",
|
|
105
|
+
"profileHash": "sha256:2d0668656d999a8cacd363cd3c76207f9392118be8a83e6dd5f81b54ae063fe6",
|
|
106
|
+
"permissions": []
|
|
107
|
+
}
|
|
108
|
+
],
|
|
109
|
+
"extensions": [
|
|
110
|
+
{
|
|
111
|
+
"name": "workspace.provider",
|
|
112
|
+
"authority": "dsh-std",
|
|
113
|
+
"coordinates": {
|
|
114
|
+
"apiVersion": "workspace.dsh/v1alpha1",
|
|
115
|
+
"kind": "WorkspaceProvider"
|
|
116
|
+
},
|
|
117
|
+
"kind": "extension",
|
|
118
|
+
"package": "@dsh-std/workspace",
|
|
119
|
+
"permissions": []
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"name": "tui.settings-section",
|
|
123
|
+
"authority": "dsh-tui",
|
|
124
|
+
"coordinates": {
|
|
125
|
+
"apiVersion": "tui.dsh/v1alpha1",
|
|
126
|
+
"kind": "SettingsSection"
|
|
127
|
+
},
|
|
128
|
+
"kind": "extension",
|
|
129
|
+
"profile": "registry/contracts/settings-section-v1alpha1.json",
|
|
130
|
+
"profileHash": "sha256:685b0f17fe489f458e9b799811f61c42b858330584e95ecb97e7216b5be100ac",
|
|
131
|
+
"permissions": []
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"name": "tui.scene",
|
|
135
|
+
"authority": "dsh-tui",
|
|
136
|
+
"coordinates": {
|
|
137
|
+
"apiVersion": "tui.dsh/v1alpha1",
|
|
138
|
+
"kind": "Scene"
|
|
139
|
+
},
|
|
140
|
+
"kind": "extension",
|
|
141
|
+
"profile": "registry/contracts/scene-v1alpha1.json",
|
|
142
|
+
"profileHash": "sha256:69ce3ae26d60dea2ed170376db8a1fb5860c94bd192c62681423c1d848ec2b26",
|
|
143
|
+
"permissions": []
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
"facetApiVersions": [
|
|
147
|
+
"v1alpha1"
|
|
148
|
+
]
|
|
149
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { name, TuiCommandTreeRuntime } from './dsh-adapter/command-trees.js';
|
|
2
|
+
export type { TuiCommandTreeProvider } from './dsh-adapter/command-trees.js';
|
|
2
3
|
export { default } from './dsh-adapter/command-trees.js';
|
|
3
4
|
//# sourceMappingURL=command-trees.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-trees.d.ts","sourceRoot":"","sources":["../../src/command-trees.ts"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"file":"command-trees.d.ts","sourceRoot":"","sources":["../../src/command-trees.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AAC5E,YAAY,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// Re-export shim: the Cordis-backed implementation lives behind the adapter
|
|
2
2
|
// boundary so UI consumers never import official @deepseek-ai/* packages.
|
|
3
|
-
export
|
|
3
|
+
export { name, TuiCommandTreeRuntime } from './dsh-adapter/command-trees.js';
|
|
4
4
|
export { default } from './dsh-adapter/command-trees.js';
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { LoadedContext } from '../dsh-adapter/channel.js';
|
|
3
3
|
/**
|
|
4
|
-
* The startup context
|
|
4
|
+
* The startup context panel: a collapsed one-line summary of what a
|
|
5
5
|
* fresh conversation will load for the current agent (system prompt
|
|
6
6
|
* sections, workspace instruction files, dynamic context, skill catalog,
|
|
7
|
-
* tools)
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* tools), expandable to the grouped details with Ctrl+P. The `/context`
|
|
8
|
+
* local command still prints the same details as a transcript report.
|
|
9
|
+
* The panel renders only while the transcript is still empty — the first
|
|
10
|
+
* message's rows take over. Renders nothing for an empty snapshot.
|
|
10
11
|
* @param context - the channel's loaded-context snapshot.
|
|
12
|
+
* @param open - whether the grouped details are shown.
|
|
13
|
+
* @param onToggle - flips `open`; fired by the Ctrl+P keybinding.
|
|
11
14
|
*/
|
|
12
|
-
export declare function LoadedContextPanel({ context }: {
|
|
15
|
+
export declare function LoadedContextPanel({ context, open, onToggle, }: {
|
|
13
16
|
context: LoadedContext;
|
|
17
|
+
open: boolean;
|
|
18
|
+
onToggle: () => void;
|
|
14
19
|
}): React.ReactNode;
|
|
15
20
|
//# sourceMappingURL=LoadedContextPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoadedContextPanel.d.ts","sourceRoot":"","sources":["../../../src/components/LoadedContextPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"LoadedContextPanel.d.ts","sourceRoot":"","sources":["../../../src/components/LoadedContextPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,aAAa,EAAsB,MAAM,2BAA2B,CAAA;AA+BlF;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,aAAa,CAAA;IACtB,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,MAAM,IAAI,CAAA;CACrB,GAAG,KAAK,CAAC,SAAS,CAoElB"}
|
|
@@ -1,19 +1,30 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { t } from '../i18n.js';
|
|
3
3
|
import { Box, Text } from '../ui.js';
|
|
4
|
-
import { summarizeLoadedContext } from '../utils/loaded-context.js';
|
|
4
|
+
import { summarizeLoadedContext, truncateContextText } from '../utils/loaded-context.js';
|
|
5
|
+
/** One named entry (section or dynamic context) with its full text. */
|
|
6
|
+
function Entry({ entry }) {
|
|
7
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, dimColor: true, children: entry.name }), _jsx(Text, { dimColor: true, wrap: "wrap", children: truncateContextText(entry.text) })] }));
|
|
8
|
+
}
|
|
9
|
+
/** A titled group of rows inside the expanded panel. */
|
|
10
|
+
function Group({ title, children }) {
|
|
11
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, color: "subtle", children: title }), _jsx(Box, { flexDirection: "column", paddingLeft: 2, children: children })] }));
|
|
12
|
+
}
|
|
5
13
|
/**
|
|
6
|
-
* The startup context
|
|
14
|
+
* The startup context panel: a collapsed one-line summary of what a
|
|
7
15
|
* fresh conversation will load for the current agent (system prompt
|
|
8
16
|
* sections, workspace instruction files, dynamic context, skill catalog,
|
|
9
|
-
* tools)
|
|
10
|
-
*
|
|
11
|
-
*
|
|
17
|
+
* tools), expandable to the grouped details with Ctrl+P. The `/context`
|
|
18
|
+
* local command still prints the same details as a transcript report.
|
|
19
|
+
* The panel renders only while the transcript is still empty — the first
|
|
20
|
+
* message's rows take over. Renders nothing for an empty snapshot.
|
|
12
21
|
* @param context - the channel's loaded-context snapshot.
|
|
22
|
+
* @param open - whether the grouped details are shown.
|
|
23
|
+
* @param onToggle - flips `open`; fired by the Ctrl+P keybinding.
|
|
13
24
|
*/
|
|
14
|
-
export function LoadedContextPanel({ context }) {
|
|
25
|
+
export function LoadedContextPanel({ context, open, onToggle, }) {
|
|
15
26
|
const summary = summarizeLoadedContext(context);
|
|
16
27
|
if (summary === '')
|
|
17
28
|
return null;
|
|
18
|
-
return (
|
|
29
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: [_jsx(Box, { paddingX: 1, backgroundColor: open ? 'userMessageBackground' : undefined, children: _jsxs(Text, { bold: open, wrap: "truncate", children: [open ? '▼' : '▶', " ", _jsxs(Text, { dimColor: true, children: ["\uFF08Ctrl+P", open ? t('context-panel-collapse') : t('context-panel-expand'), "\uFF09"] }), " ", t('context-loaded'), " \u00B7 ", summary] }) }), open && (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingTop: 1, children: [context.sections.length > 0 && (_jsx(Group, { title: t('context-panel-sections', { n: context.sections.length }), children: context.sections.map(section => (_jsx(Entry, { entry: section }, section.name))) })), context.files.length > 0 && (_jsx(Group, { title: t('context-panel-files', { n: context.files.length }), children: context.files.map(file => (_jsx(Text, { dimColor: true, children: file.displayPath }, file.displayPath))) })), context.contexts.length > 0 && (_jsx(Group, { title: t('context-panel-runtime', { n: context.contexts.length }), children: context.contexts.map(entry => (_jsx(Entry, { entry: entry }, entry.name))) })), context.skills.length > 0 && (_jsx(Group, { title: t('context-panel-skills', { n: context.skills.length }), children: context.skills.map(skill => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, dimColor: true, children: skill.name }), _jsx(Text, { dimColor: true, wrap: "wrap", children: skill.description })] }, skill.name))) })), context.tools.length > 0 && (_jsx(Group, { title: t('context-panel-tools', { n: context.tools.length }), children: context.tools.map(tool => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, dimColor: true, children: tool.name }), _jsx(Text, { dimColor: true, wrap: "wrap", children: truncateContextText(tool.description, 160) })] }, tool.name))) })), _jsx(Text, { dimColor: true, children: "\u00B7 /context" })] }))] }));
|
|
19
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LogoV2.d.ts","sourceRoot":"","sources":["../../../src/components/LogoV2.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"LogoV2.d.ts","sourceRoot":"","sources":["../../../src/components/LogoV2.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAwDzB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,MAAM,EACN,GAAG,EACH,SAAiB,GAClB,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,iFAAiF;IACjF,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,GAAG,KAAK,CAAC,SAAS,CAqFlB"}
|
|
@@ -9,6 +9,7 @@ import { getTheme } from '../theme.js';
|
|
|
9
9
|
import { useTheme } from './design-system/ThemeProvider.js';
|
|
10
10
|
import { parseRGB } from './Spinner/spinnerUtils.js';
|
|
11
11
|
import { renderBigText } from './bigfont.js';
|
|
12
|
+
import { stringWidth } from '../ink/stringWidth.js';
|
|
12
13
|
import { BRAND, FLASH, ICE, PALE, sweep } from './shimmer.js';
|
|
13
14
|
import { STANDARD_FRAME_INDEX, WhaleArt } from './Whale.js';
|
|
14
15
|
import { OPENING_SEQUENCE } from './whaleFrames.js';
|
|
@@ -35,13 +36,16 @@ const WHALE_MIN_COLUMNS = 64;
|
|
|
35
36
|
*/
|
|
36
37
|
const FULL_WHALE_WIDTH = 40;
|
|
37
38
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
39
|
+
* Center of the whale art's bounding box: sprite columns 3..34 (center
|
|
40
|
+
* 18.5) of the 40-wide box. The welcome tagline is indented so its own
|
|
41
|
+
* center lands on this column — for the 14-column Chinese tagline that is
|
|
42
|
+
* 18.5 − 7 = 11.5 → 12 leading spaces. (Centering on the full 40-column
|
|
43
|
+
* box would need 13, which reads one column right of the whale body.)
|
|
44
|
+
* The pad is recomputed from the rendered tagline's display width so
|
|
45
|
+
* longer locales — e.g. the 21-column English tagline → 8 — stay
|
|
46
|
+
* centered under the art too.
|
|
43
47
|
*/
|
|
44
|
-
const
|
|
48
|
+
const WHALE_CENTER = 18.5;
|
|
45
49
|
/** `max` → `Max` (effort levels arrive lower-case from the adapter). */
|
|
46
50
|
function capitalize(text) {
|
|
47
51
|
return text.length === 0 ? text : text[0].toUpperCase() + text.slice(1);
|
|
@@ -89,7 +93,12 @@ export function LogoV2({ model, effort, cwd, skipIntro = false, }) {
|
|
|
89
93
|
// Frozen clock for the settled header: t=0 parks every sweep highlight
|
|
90
94
|
// off-screen, leaving the static gradient behind.
|
|
91
95
|
const t = settled ? 0 : time;
|
|
96
|
+
const tagline = tr('logo-tagline');
|
|
97
|
+
// Indent that centers the tagline under the whale art's bounding box.
|
|
98
|
+
const welcomePad = showWhale
|
|
99
|
+
? Math.max(0, Math.round(WHALE_CENTER - stringWidth(tagline) / 2))
|
|
100
|
+
: 2;
|
|
92
101
|
const bigDeepSeek = renderBigText('DEEPSEEK', t, wordmarkRGB, taglineRGB, FLASH, 60);
|
|
93
102
|
const bigHarness = renderBigText('HARNESS', t, taglineRGB, PALE, FLASH, 60);
|
|
94
|
-
return (_jsxs(Box, { ref: ref, flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { flexDirection: "row", gap: 2, width: "100%", alignItems: "center", children: [showWhale && _jsx(WhaleArt, { frameIndex: frameIndex, width: FULL_WHALE_WIDTH }), _jsxs(Box, { flexDirection: "column", flexShrink: 1, children: [_jsxs(Text, { wrap: "truncate-end", children: [sweep('✦ dsh-TUI', t, wordmarkRGB, wordmarkShimmerRGB, 60), _jsx(Text, { dimColor: true, children: ' v' + VERSION })] }), bigDeepSeek.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `ds-${index}`))), bigHarness.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `h-${index}`))), _jsxs(Text, { wrap: "truncate-end", children: [model, effort !== undefined && _jsx(Text, { dimColor: true, children: ' · ' + capitalize(effort) + ' effort' })] }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: cwd }), _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { dimColor: true, children: tr('logo-tip-prefix') }), "/model", _jsxs(Text, { dimColor: true, children: [" ", tr('logo-tip-model'), " \u00B7 "] }), "/help", _jsxs(Text, { dimColor: true, children: [" ", tr('logo-tip-help'), " \u00B7 "] }), "Tab", _jsxs(Text, { dimColor: true, children: [" ", tr('logo-tip-tab')] })] })] })] }), _jsx(Box, { marginTop: 1, paddingLeft:
|
|
103
|
+
return (_jsxs(Box, { ref: ref, flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { flexDirection: "row", gap: 2, width: "100%", alignItems: "center", children: [showWhale && _jsx(WhaleArt, { frameIndex: frameIndex, width: FULL_WHALE_WIDTH }), _jsxs(Box, { flexDirection: "column", flexShrink: 1, children: [_jsxs(Text, { wrap: "truncate-end", children: [sweep('✦ dsh-TUI', t, wordmarkRGB, wordmarkShimmerRGB, 60), _jsx(Text, { dimColor: true, children: ' v' + VERSION })] }), bigDeepSeek.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `ds-${index}`))), bigHarness.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `h-${index}`))), _jsxs(Text, { wrap: "truncate-end", children: [model, effort !== undefined && _jsx(Text, { dimColor: true, children: ' · ' + capitalize(effort) + ' effort' })] }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: cwd }), _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { dimColor: true, children: tr('logo-tip-prefix') }), "/model", _jsxs(Text, { dimColor: true, children: [" ", tr('logo-tip-model'), " \u00B7 "] }), "/help", _jsxs(Text, { dimColor: true, children: [" ", tr('logo-tip-help'), " \u00B7 "] }), "Tab", _jsxs(Text, { dimColor: true, children: [" ", tr('logo-tip-tab')] })] })] })] }), _jsx(Box, { marginTop: 1, paddingLeft: welcomePad, children: _jsx(Text, { children: sweep(tagline, t, taglineRGB, FLASH, 60) }) })] }));
|
|
95
104
|
}
|
|
@@ -18,7 +18,19 @@ type Props = {
|
|
|
18
18
|
/**
|
|
19
19
|
* 混合渲染 Markdown 内容:表格用带边框的 flexbox 组件,其余内容由
|
|
20
20
|
* formatToken 生成 ANSI 字符串放入 Text。高亮对象异步就绪后自动刷新。
|
|
21
|
+
*
|
|
22
|
+
* memo by content: finished transcript blocks render with the SAME string
|
|
23
|
+
* identity for the whole session (StreamingMarkdown keeps its stable prefix
|
|
24
|
+
* identity-stable precisely to hit this); without the memo every parent
|
|
25
|
+
* re-render re-ran the full token→ANSI→yoga pipeline for every settled
|
|
26
|
+
* block — the dominant long-output stall (string-width via wrap-ansi, 60%+
|
|
27
|
+
* of CPU in streaming profiles).
|
|
28
|
+
*/
|
|
29
|
+
declare function MarkdownImpl({ children, dimColor, cacheTokens }: Props): React.ReactNode;
|
|
30
|
+
/**
|
|
31
|
+
* Memoized Markdown: skips the whole token→ANSI→layout pipeline when the
|
|
32
|
+
* content string is the same reference (see MarkdownImpl's doc comment).
|
|
21
33
|
*/
|
|
22
|
-
export declare
|
|
34
|
+
export declare const Markdown: React.MemoExoticComponent<typeof MarkdownImpl>;
|
|
23
35
|
export {};
|
|
24
36
|
//# sourceMappingURL=Markdown.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB;;;;;;;;GAQG;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;AA4GD
|
|
1
|
+
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB;;;;;;;;GAQG;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;AA4GD;;;;;;;;;;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"}
|
|
@@ -90,8 +90,15 @@ function renderTokensToNodes(tokens, highlight, dimColor) {
|
|
|
90
90
|
/**
|
|
91
91
|
* 混合渲染 Markdown 内容:表格用带边框的 flexbox 组件,其余内容由
|
|
92
92
|
* formatToken 生成 ANSI 字符串放入 Text。高亮对象异步就绪后自动刷新。
|
|
93
|
+
*
|
|
94
|
+
* memo by content: finished transcript blocks render with the SAME string
|
|
95
|
+
* identity for the whole session (StreamingMarkdown keeps its stable prefix
|
|
96
|
+
* identity-stable precisely to hit this); without the memo every parent
|
|
97
|
+
* re-render re-ran the full token→ANSI→yoga pipeline for every settled
|
|
98
|
+
* block — the dominant long-output stall (string-width via wrap-ansi, 60%+
|
|
99
|
+
* of CPU in streaming profiles).
|
|
93
100
|
*/
|
|
94
|
-
|
|
101
|
+
function MarkdownImpl({ children, dimColor = false, cacheTokens = true }) {
|
|
95
102
|
const [highlight, setHighlight] = React.useState(null);
|
|
96
103
|
React.useEffect(() => {
|
|
97
104
|
let mounted = true;
|
|
@@ -110,3 +117,10 @@ export function Markdown({ children, dimColor = false, cacheTokens = true }) {
|
|
|
110
117
|
}, [children, dimColor, highlight, cacheTokens]);
|
|
111
118
|
return (_jsx(Box, { flexDirection: "column", gap: 1, children: renderedNodes }));
|
|
112
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Memoized Markdown: skips the whole token→ANSI→layout pipeline when the
|
|
122
|
+
* content string is the same reference (see MarkdownImpl's doc comment).
|
|
123
|
+
*/
|
|
124
|
+
export const Markdown = React.memo(MarkdownImpl, (prev, next) => prev.children === next.children &&
|
|
125
|
+
prev.dimColor === next.dimColor &&
|
|
126
|
+
prev.cacheTokens === next.cacheTokens);
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { type ScrollBoxHandle } from '../ui.js';
|
|
3
3
|
import type { ChatRow } from '../dsh-adapter/channel.js';
|
|
4
4
|
import type { DOMElement } from '../ink/dom.js';
|
|
5
|
-
export declare function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, model, diffLayout, showAll, onToggleAll, onLoadOlder, thinkingVisible, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, failureHintRowId, failureHint, }: {
|
|
5
|
+
export declare function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, model, diffLayout, thinkingFold, showAll, onToggleAll, onLoadOlder, thinkingVisible, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, failureHintRowId, failureHint, }: {
|
|
6
6
|
rows: readonly ChatRow[];
|
|
7
7
|
expanded: boolean;
|
|
8
8
|
expandedRows: ReadonlySet<number>;
|
|
@@ -11,6 +11,8 @@ export declare function MessageList({ rows, expanded, expandedRows, selectedId,
|
|
|
11
11
|
model: string;
|
|
12
12
|
/** Edit/Write diff presentation preference (forwarded to tool cards). */
|
|
13
13
|
diffLayout?: 'auto' | 'split' | 'unified';
|
|
14
|
+
/** Thinking-block display mode from channel (`preview`/`full`). */
|
|
15
|
+
thinkingFold?: 'preview' | 'full';
|
|
14
16
|
showAll: boolean;
|
|
15
17
|
onToggleAll: () => void;
|
|
16
18
|
/** Restore folded-away older rows from the session log (CC-style "load
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAA8B,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAyC,MAAM,2BAA2B,CAAA;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAuC/C,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,WAAW,EACX,KAAK,EACL,UAAmB,EACnB,OAAO,EACP,WAAW,EACX,WAAW,EACX,eAAsB,EACtB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB;2EACuE;IACvE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/D,oDAAoD;IACpD,YAAY,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IACrC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B;8EAC0E;IAC1E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAA8B,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAyC,MAAM,2BAA2B,CAAA;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAuC/C,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,WAAW,EACX,KAAK,EACL,UAAmB,EACnB,YAAwB,EACxB,OAAO,EACP,WAAW,EACX,WAAW,EACX,eAAsB,EACtB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,mEAAmE;IACnE,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB;2EACuE;IACvE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/D,oDAAoD;IACpD,YAAY,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IACrC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B;8EAC0E;IAC1E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,qBA6VA;AAmRD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,MAAM,EACN,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG,KAAK,CAAC,SAAS,CAMlB"}
|
|
@@ -37,7 +37,7 @@ const DEFAULT_ROW_HEIGHT = 2;
|
|
|
37
37
|
/** Cold-start estimate of the header block above the rows; corrected by the
|
|
38
38
|
* first layout measurement. */
|
|
39
39
|
const DEFAULT_HEADER_LINES = 14;
|
|
40
|
-
export function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, model, diffLayout = 'auto', showAll, onToggleAll, onLoadOlder, thinkingVisible = true, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, failureHintRowId, failureHint, }) {
|
|
40
|
+
export function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, model, diffLayout = 'auto', thinkingFold = 'preview', showAll, onToggleAll, onLoadOlder, thinkingVisible = true, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, failureHintRowId, failureHint, }) {
|
|
41
41
|
const hiddenCount = rows.length - MAX_RENDERED_ROWS;
|
|
42
42
|
// The thinking filter runs BEFORE virtualization so window indices line up.
|
|
43
43
|
const visibleRows = (showAll || hiddenCount <= 0
|
|
@@ -65,7 +65,7 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
|
|
|
65
65
|
return undefined;
|
|
66
66
|
};
|
|
67
67
|
// --- layout virtualization ---------------------------------------------
|
|
68
|
-
const { columns } = useTerminalSize();
|
|
68
|
+
const { columns, rows: termRows } = useTerminalSize();
|
|
69
69
|
// Measured row heights, remembered after a row unmounts so virtualization
|
|
70
70
|
// can compute total content height. Bounded: row ids grow monotonically
|
|
71
71
|
// and rows are never removed from the transcript (foldRows keeps the
|
|
@@ -75,6 +75,31 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
|
|
|
75
75
|
const HEIGHTS_CACHE_MAX = 5000;
|
|
76
76
|
const heightsRef = React.useRef(new Map());
|
|
77
77
|
const localRefs = React.useRef(new Map());
|
|
78
|
+
/** Row ids that have been mounted (and therefore painted into the
|
|
79
|
+
* terminal) at least once. The sticky window may skip a row ONLY after
|
|
80
|
+
* this: an unpainted row above the window has no scrollback copy, so
|
|
81
|
+
* skipping it would erase it from the user's history entirely — preset
|
|
82
|
+
* history at boot (session resume) landed exactly there. Cleared when
|
|
83
|
+
* the list head changes identity (rewind / new session / loadOlder
|
|
84
|
+
* prepends restored rows that must paint again). */
|
|
85
|
+
const paintedOnceRef = React.useRef(new Set());
|
|
86
|
+
const paintedBaseRef = React.useRef(undefined);
|
|
87
|
+
/** Window-expansion hold: after the window WIDENS (new rows mounted),
|
|
88
|
+
* refuse to tighten for a short hold so the mounted rows actually reach
|
|
89
|
+
* the terminal. React commits within one ink frame coalesce — a render
|
|
90
|
+
* that mounts rows followed by the measure-tick re-render that drops
|
|
91
|
+
* them paints only the DROPPED layout, and never-mounted rows have no
|
|
92
|
+
* scrollback copy (preset history at boot vanished — CI
|
|
93
|
+
* repro-inline-scrollback). After the hold, tightening is visually
|
|
94
|
+
* free: those rows sit in scrollback and the diff skips them. */
|
|
95
|
+
const lastStartRef = React.useRef(-1);
|
|
96
|
+
const holdUntilRef = React.useRef(0);
|
|
97
|
+
const listHeadId = visibleRows[0]?.id;
|
|
98
|
+
if (listHeadId !== undefined && paintedBaseRef.current !== undefined && listHeadId !== paintedBaseRef.current) {
|
|
99
|
+
paintedOnceRef.current = new Set();
|
|
100
|
+
}
|
|
101
|
+
if (listHeadId !== undefined)
|
|
102
|
+
paintedBaseRef.current = listHeadId;
|
|
78
103
|
/** Content-space offset of visibleRows[0] (header + dividers), measured. */
|
|
79
104
|
const baseRef = React.useRef(null);
|
|
80
105
|
const measureQueuedRef = React.useRef(false);
|
|
@@ -128,6 +153,15 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
|
|
|
128
153
|
// back to the real bottom: a self-sustaining ping-pong that blanks the
|
|
129
154
|
// transcript mid-stream.
|
|
130
155
|
if (sticky && visibleRows.length > 0) {
|
|
156
|
+
// Sticky (follow-bottom): the viewport shows the TAIL of the content —
|
|
157
|
+
// mount exactly the tail window the floor walk covers, not everything
|
|
158
|
+
// from the scrollTop scan. Main-screen ScrollBox reports its viewport
|
|
159
|
+
// as the CONTENT height (the terminal itself is the scroller), so both
|
|
160
|
+
// the scan and an unclamped floor walk mount EVERY row in long
|
|
161
|
+
// sessions — and React's commit traverses every fiber of every mounted
|
|
162
|
+
// row per frame (measured as the dominant long-session stall). The
|
|
163
|
+
// user only ever sees terminal rows: clamp the walk-back coverage to
|
|
164
|
+
// the TERMINAL viewport plus overscan.
|
|
131
165
|
start = Math.min(start, visibleRows.length - 1);
|
|
132
166
|
// Blank-band guard: sticky scrollTop tracks the renderer's FRESH Yoga
|
|
133
167
|
// scrollHeight, while these offsets use per-row heights measured one to
|
|
@@ -135,15 +169,44 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
|
|
|
135
169
|
// deeper through the underestimated offsets than the real viewport does,
|
|
136
170
|
// unmounting rows that are still on screen (visible spacer band). Walk
|
|
137
171
|
// backwards from the tail with the known heights and mount at least one
|
|
138
|
-
// viewport plus overscan of content above it, so the window
|
|
139
|
-
// open a gap inside what the user is looking at.
|
|
140
|
-
let covered = viewport + OVERSCAN_LINES;
|
|
172
|
+
// terminal viewport plus overscan of content above it, so the window
|
|
173
|
+
// can never open a gap inside what the user is looking at.
|
|
174
|
+
let covered = Math.min(viewport, termRows) + OVERSCAN_LINES;
|
|
141
175
|
let floor = visibleRows.length - 1;
|
|
142
176
|
while (floor > 0 && covered > 0) {
|
|
143
177
|
covered -= heightOf(visibleRows[floor]);
|
|
144
178
|
floor--;
|
|
145
179
|
}
|
|
146
|
-
|
|
180
|
+
// The walk exhausted the whole list: every row is within coverage —
|
|
181
|
+
// floor+1 here would drop row 0 (its content then has no terminal copy
|
|
182
|
+
// anywhere; preset history lost its head — CI repro-inline-scrollback).
|
|
183
|
+
start = floor === 0 && covered > 0 ? 0 : floor + 1;
|
|
184
|
+
// Paint-at-least-once: extend the window over any row that has never
|
|
185
|
+
// been mounted. A row the window skips keeps only its terminal/scrollback
|
|
186
|
+
// copy — a row that was never painted has NO copy anywhere, so preset
|
|
187
|
+
// history (session resume, repro-inline-scrollback's #39 family) would
|
|
188
|
+
// vanish from the user's scrollback. Extending mounts everything above
|
|
189
|
+
// on the first frame (topPad 0, full paint), then the set fills and the
|
|
190
|
+
// window tightens to the tail.
|
|
191
|
+
const paintedOnce = paintedOnceRef.current;
|
|
192
|
+
for (let i = 0; i < start; i++) {
|
|
193
|
+
if (!paintedOnce.has(visibleRows[i].id)) {
|
|
194
|
+
start = i;
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Expansion hold — AFTER the extension so it tracks the FINAL window:
|
|
199
|
+
// never tighten within the hold window after a widen. React commits
|
|
200
|
+
// inside one ink frame coalesce; a mount followed by the measure-tick
|
|
201
|
+
// re-render that drops the row paints only the DROPPED layout, and the
|
|
202
|
+
// row's painted-once mark (set at the first commit) is a lie.
|
|
203
|
+
if (lastStartRef.current >= 0 && start > lastStartRef.current && performance.now() < holdUntilRef.current) {
|
|
204
|
+
start = lastStartRef.current;
|
|
205
|
+
}
|
|
206
|
+
if (lastStartRef.current < 0 || start < lastStartRef.current) {
|
|
207
|
+
holdUntilRef.current = performance.now() + 120;
|
|
208
|
+
}
|
|
209
|
+
lastStartRef.current = start;
|
|
147
210
|
}
|
|
148
211
|
if (forceMountRowId !== undefined && forceMountRowId !== null) {
|
|
149
212
|
const idx = visibleRows.findIndex(row => row.id === forceMountRowId);
|
|
@@ -152,6 +215,15 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
|
|
|
152
215
|
end = Math.max(end, idx + 1);
|
|
153
216
|
}
|
|
154
217
|
}
|
|
218
|
+
// The newest failed tool call carries the trajectory footnote
|
|
219
|
+
// (failureHint). Virtualization must not unmount it: before the window
|
|
220
|
+
// clamp the row was always mounted, now keep mounting it explicitly while
|
|
221
|
+
// the hint is live (verify-trace-scene's footnote check).
|
|
222
|
+
if (failureHintRowId !== undefined && failureHintRowId !== null) {
|
|
223
|
+
const idx = visibleRows.findIndex(row => row.id === failureHintRowId);
|
|
224
|
+
if (idx !== -1)
|
|
225
|
+
start = Math.min(start, idx);
|
|
226
|
+
}
|
|
155
227
|
const topPad = offsets[start] ?? 0;
|
|
156
228
|
const mountedBottom = end < visibleRows.length ? offsets[end] : total;
|
|
157
229
|
const bottomPad = total - mountedBottom;
|
|
@@ -185,6 +257,12 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
|
|
|
185
257
|
// mounted coverage so burst scrolls never show blank spacer.
|
|
186
258
|
React.useLayoutEffect(() => {
|
|
187
259
|
let changed = false;
|
|
260
|
+
// Mounted ⇒ painted: record rows eligible for window skipping.
|
|
261
|
+
const paintedOnce = paintedOnceRef.current;
|
|
262
|
+
for (const id of localRefs.current.keys()) {
|
|
263
|
+
if (!paintedOnce.has(id))
|
|
264
|
+
paintedOnce.add(id);
|
|
265
|
+
}
|
|
188
266
|
for (const [id, el] of localRefs.current) {
|
|
189
267
|
const h = el.yogaNode?.getComputedHeight();
|
|
190
268
|
if (h !== undefined && h > 0 && heightsRef.current.get(id) !== h) {
|
|
@@ -256,10 +334,10 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
|
|
|
256
334
|
// spacing; only the very first row of the whole list has none.
|
|
257
335
|
const addMargin = margins.get(row.id) === true;
|
|
258
336
|
const tool = row.tool;
|
|
259
|
-
return (_jsx(MemoRow, { rowId: row.id, kind: row.kind, text: row.text, executionTarget: row.executionTarget, streaming: row.streaming === true, durationMs: row.durationMs, time: row.time, addMargin: addMargin, isSelected: selectedId === row.id, isExpanded: expandedRows.has(row.id), expanded: expanded, model: model, diffLayout: diffLayout, 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, nowSec: tool?.status === 'running' ? nowSec : undefined, onToggleRow: onToggleRow, setRowRef: setRowRef }, row.id));
|
|
337
|
+
return (_jsx(MemoRow, { rowId: row.id, kind: row.kind, text: row.text, executionTarget: row.executionTarget, streaming: row.streaming === true, durationMs: row.durationMs, time: row.time, addMargin: addMargin, isSelected: selectedId === row.id, isExpanded: expandedRows.has(row.id), expanded: expanded, model: model, diffLayout: diffLayout, thinkingFold: thinkingFold, 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, nowSec: tool?.status === 'running' ? nowSec : undefined, onToggleRow: onToggleRow, setRowRef: setRowRef }, row.id));
|
|
260
338
|
}), bottomPad > 0 && _jsx(Box, { height: bottomPad, flexShrink: 0 })] }));
|
|
261
339
|
}
|
|
262
|
-
function TranscriptRow({ rowId, kind, text, executionTarget, streaming, durationMs, time, addMargin, isSelected, isExpanded, expanded, model, diffLayout, background, toolCallId, toolName, toolArgsText, toolArgsFull, toolStatus, toolResultText, toolResultFull, toolErrorText, toolFootnote, toolCallView, toolResultView, toolStartedAt, toolDurationMs, onToggleRow, setRowRef, }) {
|
|
340
|
+
function TranscriptRow({ rowId, kind, text, executionTarget, streaming, durationMs, time, addMargin, isSelected, isExpanded, expanded, model, diffLayout, thinkingFold, background, toolCallId, toolName, toolArgsText, toolArgsFull, toolStatus, toolResultText, toolResultFull, toolErrorText, toolFootnote, toolCallView, toolResultView, toolStartedAt, toolDurationMs, onToggleRow, setRowRef, }) {
|
|
263
341
|
const ref = React.useCallback((el) => {
|
|
264
342
|
setRowRef(rowId, el);
|
|
265
343
|
}, [setRowRef, rowId]);
|
|
@@ -272,7 +350,10 @@ function TranscriptRow({ rowId, kind, text, executionTarget, streaming, duration
|
|
|
272
350
|
case 'assistant':
|
|
273
351
|
return streaming ? (_jsxs(Box, { alignItems: "flex-start", flexDirection: "row", marginTop: addMargin ? 1 : 0, width: "100%", backgroundColor: background, children: [_jsx(Box, { minWidth: 2, children: _jsx(Text, { color: "text", children: "\u25CF" }) }), _jsx(Box, { flexDirection: "column", children: _jsx(StreamingMarkdown, { children: stripNarration(text) }) })] })) : (_jsxs(Box, { width: "100%", flexDirection: "column", backgroundColor: background, ref: ref, children: [expanded && (_jsx(Box, { flexDirection: "row", justifyContent: "flex-end", gap: 1, marginTop: 1, children: _jsx(MessageMetadata, { timestamp: time, model: model }) })), _jsx(AssistantTextMessage, { text: stripNarration(text), addMargin: addMargin, isSelected: isSelected, isExpanded: isExpanded, onClick: onClick })] }));
|
|
274
352
|
case 'reasoning':
|
|
275
|
-
return (_jsx(Box, { flexDirection: "column", ref: ref, children: _jsx(AssistantThinkingMessage, { thinking: text, addMargin: addMargin,
|
|
353
|
+
return (_jsx(Box, { flexDirection: "column", ref: ref, children: _jsx(AssistantThinkingMessage, { thinking: text, addMargin: addMargin, preview: streaming &&
|
|
354
|
+
thinkingFold === 'preview' &&
|
|
355
|
+
!expanded &&
|
|
356
|
+
!isExpanded,
|
|
276
357
|
// Streaming reasoning shows expanded live, then folds
|
|
277
358
|
// automatically once the turn settles (unless Ctrl+O or a
|
|
278
359
|
// single-row expansion keeps it open).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PromptInput.d.ts","sourceRoot":"","sources":["../../../src/components/PromptInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AASzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAkDxD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,IAAI,OAAO,CAAA;IAClB,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,IAAI,IAAI,CAAA;IACpB;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACrD,6EAA6E;IAC7E,eAAe,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,IAAI,IAAI,CAAA;IACvB,8EAA8E;IAC9E,eAAe,CAAC,IAAI,IAAI,CAAA;IACxB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;CACzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,cAAc,EACd,eAAe,EACf,aAAa,GACd,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"PromptInput.d.ts","sourceRoot":"","sources":["../../../src/components/PromptInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AASzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAkDxD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,IAAI,OAAO,CAAA;IAClB,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,IAAI,IAAI,CAAA;IACpB;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACrD,6EAA6E;IAC7E,eAAe,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,IAAI,IAAI,CAAA;IACvB,8EAA8E;IAC9E,eAAe,CAAC,IAAI,IAAI,CAAA;IACxB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;CACzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,cAAc,EACd,eAAe,EACf,aAAa,GACd,EAAE,gBAAgB,qBA65BlB"}
|