@deepseek-harness-tui/dsh-tui 0.10.0 → 0.10.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 +5 -2
- package/bin/dsh-tui.js +99 -33
- package/cordis.patch.yml +25 -5
- package/lib/types/adapter/channel/actions.d.ts +17 -0
- package/lib/types/adapter/channel/actions.d.ts.map +1 -0
- package/lib/types/adapter/channel/actions.js +28 -0
- package/lib/types/adapter/channel/consumer.d.ts +34 -0
- package/lib/types/adapter/channel/consumer.d.ts.map +1 -0
- package/lib/types/adapter/channel/consumer.js +87 -0
- package/lib/types/adapter/channel/features.d.ts +12 -0
- package/lib/types/adapter/channel/features.d.ts.map +1 -0
- package/lib/types/adapter/channel/features.js +41 -0
- package/lib/types/adapter/channel/host-registry.d.ts +40 -0
- package/lib/types/adapter/channel/host-registry.d.ts.map +1 -0
- package/lib/types/adapter/channel/host-registry.js +120 -0
- package/lib/types/adapter/channel/index.d.ts +22 -0
- package/lib/types/adapter/channel/index.d.ts.map +1 -0
- package/lib/types/adapter/channel/index.js +21 -0
- package/lib/types/adapter/channel/internal-token.d.ts +12 -0
- package/lib/types/adapter/channel/internal-token.d.ts.map +1 -0
- package/lib/types/adapter/channel/internal-token.js +11 -0
- package/lib/types/adapter/channel/plugins.d.ts +17 -0
- package/lib/types/adapter/channel/plugins.d.ts.map +1 -0
- package/lib/types/adapter/channel/plugins.js +47 -0
- package/lib/types/adapter/channel/projection.d.ts +15 -0
- package/lib/types/adapter/channel/projection.d.ts.map +1 -0
- package/lib/types/adapter/channel/projection.js +59 -0
- package/lib/types/adapter/channel/provider.d.ts +52 -0
- package/lib/types/adapter/channel/provider.d.ts.map +1 -0
- package/lib/types/adapter/channel/provider.js +231 -0
- package/lib/types/adapter/channel/read-view.d.ts +4 -0
- package/lib/types/adapter/channel/read-view.d.ts.map +1 -0
- package/lib/types/adapter/channel/read-view.js +132 -0
- package/lib/types/adapter/channel/session-projection.d.ts +56 -0
- package/lib/types/adapter/channel/session-projection.d.ts.map +1 -0
- package/lib/types/adapter/channel/session-projection.js +247 -0
- package/lib/types/adapter/channel/state.d.ts +11 -0
- package/lib/types/adapter/channel/state.d.ts.map +1 -0
- package/lib/types/adapter/channel/state.js +55 -0
- package/lib/types/adapter/channel/transcript.d.ts +15 -0
- package/lib/types/adapter/channel/transcript.d.ts.map +1 -0
- package/lib/types/adapter/channel/transcript.js +22 -0
- package/lib/types/adapter/channel/ui-policy.d.ts +106 -0
- package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -0
- package/lib/types/adapter/channel/ui-policy.js +166 -0
- package/lib/types/adapter/channel/ui.d.ts +16 -0
- package/lib/types/adapter/channel/ui.d.ts.map +1 -0
- package/lib/types/adapter/channel/ui.js +168 -0
- package/lib/types/adapter/index.d.ts +20 -0
- package/lib/types/adapter/index.d.ts.map +1 -0
- package/lib/types/adapter/index.js +19 -0
- package/lib/types/adapter/kernel/contract-catalog.d.ts +12 -0
- package/lib/types/adapter/kernel/contract-catalog.d.ts.map +1 -0
- package/lib/types/adapter/kernel/contract-catalog.js +11 -0
- package/lib/types/adapter/kernel/diagnostics.d.ts +18 -0
- package/lib/types/adapter/kernel/diagnostics.d.ts.map +1 -0
- package/lib/types/adapter/kernel/diagnostics.js +16 -0
- package/lib/types/adapter/kernel/driver-types.d.ts +16 -0
- package/lib/types/adapter/kernel/driver-types.d.ts.map +1 -0
- package/lib/types/adapter/kernel/driver-types.js +8 -0
- package/lib/types/adapter/kernel/host-facade.d.ts +65 -0
- package/lib/types/adapter/kernel/host-facade.d.ts.map +1 -0
- package/lib/types/adapter/kernel/host-facade.js +215 -0
- package/lib/types/adapter/kernel/host-probe-access.d.ts +71 -0
- package/lib/types/adapter/kernel/host-probe-access.d.ts.map +1 -0
- package/lib/types/adapter/kernel/host-probe-access.js +121 -0
- package/lib/types/adapter/kernel/index.d.ts +20 -0
- package/lib/types/adapter/kernel/index.d.ts.map +1 -0
- package/lib/types/adapter/kernel/index.js +19 -0
- package/lib/types/adapter/kernel/kernel-runtime.d.ts +138 -0
- package/lib/types/adapter/kernel/kernel-runtime.d.ts.map +1 -0
- package/lib/types/adapter/kernel/kernel-runtime.js +572 -0
- package/lib/types/adapter/kernel/ledger.d.ts +55 -0
- package/lib/types/adapter/kernel/ledger.d.ts.map +1 -0
- package/lib/types/adapter/kernel/ledger.js +33 -0
- package/lib/types/adapter/kernel/legacy-facade.d.ts +22 -0
- package/lib/types/adapter/kernel/legacy-facade.d.ts.map +1 -0
- package/lib/types/adapter/kernel/legacy-facade.js +34 -0
- package/lib/types/adapter/kernel/lifecycle.d.ts +38 -0
- package/lib/types/adapter/kernel/lifecycle.d.ts.map +1 -0
- package/lib/types/adapter/kernel/lifecycle.js +53 -0
- package/lib/types/adapter/kernel/replay-isolation.d.ts +27 -0
- package/lib/types/adapter/kernel/replay-isolation.d.ts.map +1 -0
- package/lib/types/adapter/kernel/replay-isolation.js +45 -0
- package/lib/types/adapter/kernel/replay.d.ts +132 -0
- package/lib/types/adapter/kernel/replay.d.ts.map +1 -0
- package/lib/types/adapter/kernel/replay.js +425 -0
- package/lib/types/adapter/kernel/runtime-context.d.ts +15 -0
- package/lib/types/adapter/kernel/runtime-context.d.ts.map +1 -0
- package/lib/types/adapter/kernel/runtime-context.js +24 -0
- package/lib/types/adapter/kernel/runtime.d.ts +70 -0
- package/lib/types/adapter/kernel/runtime.d.ts.map +1 -0
- package/lib/types/adapter/kernel/runtime.js +325 -0
- package/lib/types/adapter/kernel/slices/channel.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/channel.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/channel.js +8 -0
- package/lib/types/adapter/kernel/slices/decisions.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/decisions.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/decisions.js +10 -0
- package/lib/types/adapter/kernel/slices/extensions.d.ts +8 -0
- package/lib/types/adapter/kernel/slices/extensions.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/extensions.js +43 -0
- package/lib/types/adapter/kernel/slices/index.d.ts +19 -0
- package/lib/types/adapter/kernel/slices/index.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/index.js +36 -0
- package/lib/types/adapter/kernel/slices/presentation.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/presentation.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/presentation.js +14 -0
- package/lib/types/adapter/kernel/slices/scenes.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/scenes.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/scenes.js +14 -0
- package/lib/types/adapter/kernel/slices/settings.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/settings.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/settings.js +12 -0
- package/lib/types/adapter/kernel/slices/types.d.ts +20 -0
- package/lib/types/adapter/kernel/slices/types.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/types.js +12 -0
- package/lib/types/adapter/kernel/slices/workspace.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/workspace.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/workspace.js +15 -0
- package/lib/types/adapter/ports/channel-catalog.d.ts +90 -0
- package/lib/types/adapter/ports/channel-catalog.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-catalog.js +2 -0
- package/lib/types/adapter/ports/channel-display.d.ts +90 -0
- package/lib/types/adapter/ports/channel-display.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-display.js +2 -0
- package/lib/types/adapter/ports/channel-session.d.ts +229 -0
- package/lib/types/adapter/ports/channel-session.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-session.js +2 -0
- package/lib/types/adapter/ports/channel-settings.d.ts +273 -0
- package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-settings.js +1 -0
- package/lib/types/adapter/ports/channel-ui.d.ts +569 -0
- package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-ui.js +1 -0
- package/lib/types/adapter/ports/channel-view.d.ts +609 -0
- package/lib/types/adapter/ports/channel-view.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-view.js +2 -0
- package/lib/types/adapter/ports/channel-workspace.d.ts +45 -0
- package/lib/types/adapter/ports/channel-workspace.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-workspace.js +2 -0
- package/lib/types/adapter/ports/channel.d.ts +145 -0
- package/lib/types/adapter/ports/channel.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel.js +22 -0
- package/lib/types/adapter/ports/decisions.d.ts +18 -0
- package/lib/types/adapter/ports/decisions.d.ts.map +1 -0
- package/lib/types/adapter/ports/decisions.js +9 -0
- package/lib/types/adapter/ports/descriptor.d.ts +25 -0
- package/lib/types/adapter/ports/descriptor.d.ts.map +1 -0
- package/lib/types/adapter/ports/descriptor.js +11 -0
- package/lib/types/adapter/ports/extensions.d.ts +86 -0
- package/lib/types/adapter/ports/extensions.d.ts.map +1 -0
- package/lib/types/adapter/ports/extensions.js +9 -0
- package/lib/types/adapter/ports/index.d.ts +23 -0
- package/lib/types/adapter/ports/index.d.ts.map +1 -0
- package/lib/types/adapter/ports/index.js +14 -0
- package/lib/types/adapter/ports/owner.d.ts +19 -0
- package/lib/types/adapter/ports/owner.d.ts.map +1 -0
- package/lib/types/adapter/ports/owner.js +9 -0
- package/lib/types/adapter/ports/presentation.d.ts +81 -0
- package/lib/types/adapter/ports/presentation.d.ts.map +1 -0
- package/lib/types/adapter/ports/presentation.js +10 -0
- package/lib/types/adapter/ports/scenes.d.ts +24 -0
- package/lib/types/adapter/ports/scenes.d.ts.map +1 -0
- package/lib/types/adapter/ports/scenes.js +8 -0
- package/lib/types/adapter/ports/settings.d.ts +44 -0
- package/lib/types/adapter/ports/settings.d.ts.map +1 -0
- package/lib/types/adapter/ports/settings.js +9 -0
- package/lib/types/adapter/ports/workspace.d.ts +60 -0
- package/lib/types/adapter/ports/workspace.d.ts.map +1 -0
- package/lib/types/adapter/ports/workspace.js +8 -0
- package/lib/types/adapter/spec/index.d.ts +11 -0
- package/lib/types/adapter/spec/index.d.ts.map +1 -0
- package/lib/types/adapter/spec/index.js +10 -0
- package/lib/types/adapter/spec/profile.d.ts +10 -0
- package/lib/types/adapter/spec/profile.d.ts.map +1 -0
- package/lib/types/adapter/spec/profile.js +9 -0
- package/lib/types/adapter/spec/protocol-constants.d.ts +60 -0
- package/lib/types/adapter/spec/protocol-constants.d.ts.map +1 -0
- package/lib/types/adapter/spec/protocol-constants.js +129 -0
- package/lib/types/adapter/spec/tui-contributions.d.ts +18 -0
- package/lib/types/adapter/spec/tui-contributions.d.ts.map +1 -0
- package/lib/types/adapter/spec/tui-contributions.js +19 -0
- package/lib/types/adapter/standard/admission.d.ts +11 -0
- package/lib/types/adapter/standard/admission.d.ts.map +1 -0
- package/lib/types/adapter/standard/admission.js +10 -0
- package/lib/types/adapter/standard/descriptor.d.ts +74 -0
- package/lib/types/adapter/standard/descriptor.d.ts.map +1 -0
- package/lib/types/adapter/standard/descriptor.js +356 -0
- package/lib/types/{dsh-adapter → adapter/standard}/grants.d.ts +8 -3
- package/lib/types/adapter/standard/grants.d.ts.map +1 -0
- package/lib/types/{dsh-adapter → adapter/standard}/grants.js +14 -8
- package/lib/types/adapter/standard/index.d.ts +25 -0
- package/lib/types/adapter/standard/index.d.ts.map +1 -0
- package/lib/types/adapter/standard/index.js +24 -0
- package/lib/types/adapter/standard/negotiate.d.ts.map +1 -0
- package/lib/types/{plugin-spec → adapter/standard}/permission-scope.d.ts +3 -8
- package/lib/types/adapter/standard/permission-scope.d.ts.map +1 -0
- package/lib/types/{plugin-spec → adapter/standard}/permission-scope.js +4 -26
- package/lib/types/adapter/standard/protocols.d.ts +12 -0
- package/lib/types/adapter/standard/protocols.d.ts.map +1 -0
- package/lib/types/adapter/standard/protocols.js +11 -0
- package/lib/types/adapter/standard/registry.d.ts.map +1 -0
- package/lib/types/{plugin-spec → adapter/standard}/registry.js +3 -15
- package/lib/types/adapter/standard/schema-check.d.ts.map +1 -0
- package/lib/types/{plugin-spec → adapter/standard}/schema-check.js +4 -2
- package/lib/types/adapter/standard/tui-extension.d.ts +25 -0
- package/lib/types/adapter/standard/tui-extension.d.ts.map +1 -0
- package/lib/types/adapter/standard/tui-extension.js +45 -0
- package/lib/types/{plugin-spec → adapter/standard}/types.d.ts +3 -9
- package/lib/types/adapter/standard/types.d.ts.map +1 -0
- package/lib/types/{plugin-spec → adapter/standard}/validate.d.ts +3 -3
- package/lib/types/adapter/standard/validate.d.ts.map +1 -0
- package/lib/types/{plugin-spec → adapter/standard}/validate.js +14 -13
- package/lib/types/adapter/upstream/channel-driver.d.ts +22 -0
- package/lib/types/adapter/upstream/channel-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/channel-driver.js +424 -0
- package/lib/types/adapter/upstream/decisions-driver.d.ts +15 -0
- package/lib/types/adapter/upstream/decisions-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/decisions-driver.js +141 -0
- package/lib/types/adapter/upstream/detection.d.ts +26 -0
- package/lib/types/adapter/upstream/detection.d.ts.map +1 -0
- package/lib/types/adapter/upstream/detection.js +9 -0
- package/lib/types/adapter/upstream/driver.d.ts +50 -0
- package/lib/types/adapter/upstream/driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/driver.js +8 -0
- package/lib/types/adapter/upstream/extensions-driver.d.ts +24 -0
- package/lib/types/adapter/upstream/extensions-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/extensions-driver.js +697 -0
- package/lib/types/adapter/upstream/host-descriptor-driver.d.ts +45 -0
- package/lib/types/adapter/upstream/host-descriptor-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/host-descriptor-driver.js +606 -0
- package/lib/types/adapter/upstream/index.d.ts +18 -0
- package/lib/types/adapter/upstream/index.d.ts.map +1 -0
- package/lib/types/adapter/upstream/index.js +15 -0
- package/lib/types/adapter/upstream/presentation-driver.d.ts +17 -0
- package/lib/types/adapter/upstream/presentation-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/presentation-driver.js +129 -0
- package/lib/types/adapter/upstream/scenes-driver.d.ts +18 -0
- package/lib/types/adapter/upstream/scenes-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/scenes-driver.js +170 -0
- package/lib/types/adapter/upstream/settings-driver.d.ts +20 -0
- package/lib/types/adapter/upstream/settings-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/settings-driver.js +173 -0
- package/lib/types/adapter/upstream/workspace-driver.d.ts +19 -0
- package/lib/types/adapter/upstream/workspace-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/workspace-driver.js +190 -0
- package/lib/types/api.d.ts +1 -1
- package/lib/types/api.d.ts.map +1 -1
- package/lib/types/commands.d.ts +2 -41
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +1 -1
- package/lib/types/components/Chat/JobCard.d.ts.map +1 -1
- package/lib/types/components/Chat/JobCard.js +8 -1
- package/lib/types/components/GoalTodoPanel.d.ts +2 -1
- package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
- package/lib/types/components/HistorySearchDialog.d.ts.map +1 -1
- package/lib/types/components/HistorySearchDialog.js +7 -5
- package/lib/types/components/Markdown.d.ts +2 -2
- package/lib/types/components/Markdown.d.ts.map +1 -1
- package/lib/types/components/Markdown.js +28 -3
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +46 -17
- package/lib/types/components/ModelPicker.d.ts +1 -1
- package/lib/types/components/ModelPicker.d.ts.map +1 -1
- package/lib/types/components/ModelPicker.js +8 -4
- package/lib/types/components/OverlayAbove.d.ts +22 -1
- package/lib/types/components/OverlayAbove.d.ts.map +1 -1
- package/lib/types/components/OverlayAbove.js +74 -5
- package/lib/types/components/PromptInput.d.ts +2 -1
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/RewindPicker.d.ts.map +1 -1
- package/lib/types/components/RewindPicker.js +14 -6
- package/lib/types/components/SkillsPicker.d.ts.map +1 -1
- package/lib/types/components/SkillsPicker.js +6 -4
- package/lib/types/components/Spinner/spinnerMode.d.ts +1 -5
- package/lib/types/components/Spinner/spinnerMode.d.ts.map +1 -1
- package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
- package/lib/types/components/StreamingMarkdown.js +61 -9
- package/lib/types/components/design-system/ThemedBox.d.ts +4 -2
- package/lib/types/components/design-system/ThemedBox.d.ts.map +1 -1
- package/lib/types/components/design-system/ThemedBox.js +2 -2
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +69 -25
- package/lib/types/components/overlayBudget.d.ts +39 -0
- package/lib/types/components/overlayBudget.d.ts.map +1 -0
- package/lib/types/components/overlayBudget.js +43 -0
- package/lib/types/deepseekBalance.d.ts +2 -36
- package/lib/types/deepseekBalance.d.ts.map +1 -1
- package/lib/types/deepseekBalance.js +0 -14
- package/lib/types/deepseekPricing.d.ts +2 -1
- package/lib/types/deepseekPricing.d.ts.map +1 -1
- package/lib/types/deepseekPricing.js +8 -1
- package/lib/types/dsh-adapter/approvals.d.ts +11 -1
- package/lib/types/dsh-adapter/approvals.d.ts.map +1 -1
- package/lib/types/dsh-adapter/approvals.js +32 -12
- package/lib/types/dsh-adapter/channel/action-readiness.d.ts +20 -0
- package/lib/types/dsh-adapter/channel/action-readiness.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/action-readiness.js +83 -0
- package/lib/types/dsh-adapter/channel/activity.d.ts +20 -0
- package/lib/types/dsh-adapter/channel/activity.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/activity.js +113 -0
- package/lib/types/dsh-adapter/channel/agent-view-projection.d.ts +64 -0
- package/lib/types/dsh-adapter/channel/agent-view-projection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/agent-view-projection.js +295 -0
- package/lib/types/dsh-adapter/channel/background-action.d.ts +41 -0
- package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/background-action.js +86 -0
- package/lib/types/dsh-adapter/channel/binding-events.d.ts +65 -0
- package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/binding-events.js +169 -0
- package/lib/types/dsh-adapter/channel/binding.d.ts +41 -0
- package/lib/types/dsh-adapter/channel/binding.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/binding.js +227 -0
- package/lib/types/dsh-adapter/channel/command-completions.d.ts +29 -0
- package/lib/types/dsh-adapter/channel/command-completions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/command-completions.js +94 -0
- package/lib/types/dsh-adapter/channel/commands.d.ts +8 -0
- package/lib/types/dsh-adapter/channel/commands.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/commands.js +9 -0
- package/lib/types/dsh-adapter/channel/compaction.d.ts +19 -0
- package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/compaction.js +116 -0
- package/lib/types/dsh-adapter/channel/composer-images.d.ts +57 -0
- package/lib/types/dsh-adapter/channel/composer-images.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/composer-images.js +217 -0
- package/lib/types/dsh-adapter/channel/composer-mentions.d.ts +15 -0
- package/lib/types/dsh-adapter/channel/composer-mentions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/composer-mentions.js +200 -0
- package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts +26 -0
- package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/context-bookkeeping.js +30 -0
- package/lib/types/dsh-adapter/channel/decisions.d.ts +19 -0
- package/lib/types/dsh-adapter/channel/decisions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/decisions.js +90 -0
- package/lib/types/dsh-adapter/channel/emitter.d.ts +10 -0
- package/lib/types/dsh-adapter/channel/emitter.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/emitter.js +71 -0
- package/lib/types/dsh-adapter/channel/external-commands.d.ts +31 -0
- package/lib/types/dsh-adapter/channel/external-commands.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/external-commands.js +187 -0
- package/lib/types/dsh-adapter/channel/file-actions.d.ts +20 -0
- package/lib/types/dsh-adapter/channel/file-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/file-actions.js +45 -0
- package/lib/types/dsh-adapter/channel/input-actions.d.ts +13 -0
- package/lib/types/dsh-adapter/channel/input-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/input-actions.js +135 -0
- package/lib/types/dsh-adapter/channel/input-delivery.d.ts +37 -0
- package/lib/types/dsh-adapter/channel/input-delivery.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/input-delivery.js +305 -0
- package/lib/types/dsh-adapter/channel/job-projection.d.ts +28 -0
- package/lib/types/dsh-adapter/channel/job-projection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/job-projection.js +150 -0
- package/lib/types/dsh-adapter/channel/lifetime-resources.d.ts +9 -0
- package/lib/types/dsh-adapter/channel/lifetime-resources.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/lifetime-resources.js +33 -0
- package/lib/types/dsh-adapter/channel/loaded-context.d.ts +40 -0
- package/lib/types/dsh-adapter/channel/loaded-context.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/loaded-context.js +62 -0
- package/lib/types/dsh-adapter/channel/local-actions.d.ts +70 -0
- package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/local-actions.js +108 -0
- package/lib/types/dsh-adapter/channel/mentions.d.ts +29 -0
- package/lib/types/dsh-adapter/channel/mentions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/mentions.js +235 -0
- package/lib/types/dsh-adapter/channel/mode-actions.d.ts +30 -0
- package/lib/types/dsh-adapter/channel/mode-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/mode-actions.js +247 -0
- package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts +35 -0
- package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/mode-permission-actions.js +199 -0
- package/lib/types/dsh-adapter/channel/mode-permission.d.ts +58 -0
- package/lib/types/dsh-adapter/channel/mode-permission.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/mode-permission.js +240 -0
- package/lib/types/dsh-adapter/channel/mode-roster.d.ts +51 -0
- package/lib/types/dsh-adapter/channel/mode-roster.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/mode-roster.js +119 -0
- package/lib/types/dsh-adapter/channel/model-actions.d.ts +46 -0
- package/lib/types/dsh-adapter/channel/model-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/model-actions.js +275 -0
- package/lib/types/dsh-adapter/channel/model-switch.d.ts +32 -0
- package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/model-switch.js +98 -0
- package/lib/types/dsh-adapter/channel/notifications.d.ts +9 -0
- package/lib/types/dsh-adapter/channel/notifications.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/notifications.js +24 -0
- package/lib/types/dsh-adapter/channel/owner.d.ts +18 -0
- package/lib/types/dsh-adapter/channel/owner.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/owner.js +73 -0
- package/lib/types/dsh-adapter/channel/paths.d.ts +31 -0
- package/lib/types/dsh-adapter/channel/paths.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/paths.js +147 -0
- package/lib/types/dsh-adapter/channel/permissions.d.ts +40 -0
- package/lib/types/dsh-adapter/channel/permissions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/permissions.js +187 -0
- package/lib/types/dsh-adapter/channel/preferences.d.ts +3 -0
- package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/preferences.js +103 -0
- package/lib/types/dsh-adapter/channel/projection-helpers.d.ts +13 -0
- package/lib/types/dsh-adapter/channel/projection-helpers.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/projection-helpers.js +63 -0
- package/lib/types/dsh-adapter/channel/projection.d.ts +40 -0
- package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/projection.js +1021 -0
- package/lib/types/dsh-adapter/channel/reports.d.ts +32 -0
- package/lib/types/dsh-adapter/channel/reports.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/reports.js +171 -0
- package/lib/types/dsh-adapter/channel/session-actions.d.ts +13 -0
- package/lib/types/dsh-adapter/channel/session-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-actions.js +29 -0
- package/lib/types/dsh-adapter/channel/session-adoption.d.ts +32 -0
- package/lib/types/dsh-adapter/channel/session-adoption.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-adoption.js +35 -0
- package/lib/types/dsh-adapter/channel/session-fork.d.ts +19 -0
- package/lib/types/dsh-adapter/channel/session-fork.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-fork.js +85 -0
- package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +32 -0
- package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-live-adoption.js +62 -0
- package/lib/types/dsh-adapter/channel/session-metadata.d.ts +81 -0
- package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-metadata.js +209 -0
- package/lib/types/dsh-adapter/channel/session-reset.d.ts +11 -0
- package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-reset.js +44 -0
- package/lib/types/dsh-adapter/channel/session-resume.d.ts +56 -0
- package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-resume.js +240 -0
- package/lib/types/dsh-adapter/channel/session-rewind.d.ts +19 -0
- package/lib/types/dsh-adapter/channel/session-rewind.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-rewind.js +128 -0
- package/lib/types/dsh-adapter/channel/session-tree-actions.d.ts +19 -0
- package/lib/types/dsh-adapter/channel/session-tree-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-tree-actions.js +138 -0
- package/lib/types/dsh-adapter/channel/session-tree.d.ts +10 -0
- package/lib/types/dsh-adapter/channel/session-tree.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-tree.js +503 -0
- package/lib/types/dsh-adapter/channel/settings-host.d.ts +4 -0
- package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/settings-host.js +256 -0
- package/lib/types/dsh-adapter/channel/skill-catalog.d.ts +33 -0
- package/lib/types/dsh-adapter/channel/skill-catalog.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/skill-catalog.js +215 -0
- package/lib/types/dsh-adapter/channel/state.d.ts +46 -0
- package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/state.js +31 -0
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +47 -0
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/subagent-projection.js +140 -0
- package/lib/types/dsh-adapter/channel/transcript.d.ts +73 -0
- package/lib/types/dsh-adapter/channel/transcript.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/transcript.js +312 -0
- package/lib/types/dsh-adapter/channel/types.d.ts +162 -0
- package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/types.js +1 -0
- package/lib/types/dsh-adapter/channel/usage.d.ts +13 -0
- package/lib/types/dsh-adapter/channel/usage.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/usage.js +48 -0
- package/lib/types/dsh-adapter/channel/workspace-actions.d.ts +20 -0
- package/lib/types/dsh-adapter/channel/workspace-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/workspace-actions.js +56 -0
- package/lib/types/dsh-adapter/channel-facade-actions.d.ts +25 -0
- package/lib/types/dsh-adapter/channel-facade-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel-facade-actions.js +55 -0
- package/lib/types/dsh-adapter/channel-scene-outlet.d.ts +6 -0
- package/lib/types/dsh-adapter/channel-scene-outlet.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel-scene-outlet.js +13 -0
- package/lib/types/dsh-adapter/channel-ui.d.ts +9 -0
- package/lib/types/dsh-adapter/channel-ui.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel-ui.js +128 -0
- package/lib/types/dsh-adapter/channel.d.ts +9 -1525
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +753 -8145
- package/lib/types/dsh-adapter/command-trees.d.ts +1 -0
- package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -1
- package/lib/types/dsh-adapter/command-trees.js +20 -1
- package/lib/types/dsh-adapter/compat/liveSession.d.ts +8 -4
- package/lib/types/dsh-adapter/compat/liveSession.d.ts.map +1 -1
- package/lib/types/dsh-adapter/compat/liveSession.js +28 -3
- package/lib/types/dsh-adapter/compat/persistence.d.ts +21 -0
- package/lib/types/dsh-adapter/compat/persistence.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/persistence.js +17 -0
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts +50 -11
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -1
- package/lib/types/dsh-adapter/compat/sessionLog.js +325 -36
- package/lib/types/dsh-adapter/component-identity.d.ts +1 -1
- package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -1
- package/lib/types/dsh-adapter/component-identity.js +1 -1
- package/lib/types/dsh-adapter/contract.d.ts +11 -9
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +19 -12
- package/lib/types/dsh-adapter/decision-guard.d.ts +56 -12
- package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -1
- package/lib/types/dsh-adapter/decision-guard.js +134 -22
- package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -1
- package/lib/types/dsh-adapter/dialogs.js +13 -0
- package/lib/types/dsh-adapter/effect-ledger.d.ts +5 -0
- package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -1
- package/lib/types/dsh-adapter/effect-ledger.js +53 -15
- package/lib/types/dsh-adapter/extension-events.d.ts +2 -9
- package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -1
- package/lib/types/dsh-adapter/extension-events.js +0 -20
- package/lib/types/dsh-adapter/extensions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/extensions.js +3 -2
- package/lib/types/dsh-adapter/host-grants.d.ts +23 -0
- package/lib/types/dsh-adapter/host-grants.d.ts.map +1 -0
- package/lib/types/dsh-adapter/host-grants.js +45 -0
- package/lib/types/dsh-adapter/jobs.d.ts +2 -46
- package/lib/types/dsh-adapter/jobs.d.ts.map +1 -1
- package/lib/types/dsh-adapter/jobs.js +0 -25
- package/lib/types/dsh-adapter/message-observer.d.ts +15 -2
- package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -1
- package/lib/types/dsh-adapter/message-observer.js +157 -28
- package/lib/types/dsh-adapter/plugin-host.d.ts +80 -11
- package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin-host.js +438 -41
- package/lib/types/dsh-adapter/plugin-storage.d.ts +11 -1
- package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin-storage.js +150 -11
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +75 -34
- package/lib/types/dsh-adapter/plugins-info.d.ts +2 -2
- package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugins-info.js +11 -6
- package/lib/types/dsh-adapter/presets.d.ts.map +1 -1
- package/lib/types/dsh-adapter/presets.js +3 -2
- package/lib/types/dsh-adapter/providerWizard.d.ts +2 -159
- package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -1
- package/lib/types/dsh-adapter/questions.d.ts +8 -0
- package/lib/types/dsh-adapter/questions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/questions.js +18 -0
- package/lib/types/dsh-adapter/recap.d.ts +1 -9
- package/lib/types/dsh-adapter/recap.d.ts.map +1 -1
- package/lib/types/dsh-adapter/recap.js +0 -14
- package/lib/types/dsh-adapter/renderers.d.ts +1 -0
- package/lib/types/dsh-adapter/renderers.d.ts.map +1 -1
- package/lib/types/dsh-adapter/renderers.js +26 -1
- package/lib/types/dsh-adapter/scenes.d.ts +3 -1
- package/lib/types/dsh-adapter/scenes.d.ts.map +1 -1
- package/lib/types/dsh-adapter/scenes.js +31 -0
- package/lib/types/dsh-adapter/sessionTree.d.ts +14 -95
- package/lib/types/dsh-adapter/sessionTree.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sessionTree.js +51 -36
- package/lib/types/dsh-adapter/sessions/digest.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sessions/digest.js +40 -19
- package/lib/types/dsh-adapter/sessions/frames.js +2 -0
- package/lib/types/dsh-adapter/sessions/index.d.ts +1 -1
- package/lib/types/dsh-adapter/sessions/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sessions/index.js +1 -1
- package/lib/types/dsh-adapter/sessions/list.d.ts +23 -0
- package/lib/types/dsh-adapter/sessions/list.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sessions/list.js +28 -17
- package/lib/types/dsh-adapter/sessions/store.d.ts +2 -2
- package/lib/types/dsh-adapter/sessions/store.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sessions/store.js +12 -11
- package/lib/types/dsh-adapter/sessions/types.d.ts +4 -128
- package/lib/types/dsh-adapter/sessions/types.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sessions/types.js +0 -13
- package/lib/types/dsh-adapter/settings-sections.d.ts +4 -95
- package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
- package/lib/types/dsh-adapter/settings-sections.js +50 -13
- package/lib/types/dsh-adapter/settingsEditor.d.ts +2 -36
- package/lib/types/dsh-adapter/settingsEditor.d.ts.map +1 -1
- package/lib/types/dsh-adapter/settingsEditor.js +0 -18
- package/lib/types/dsh-adapter/shortcuts.d.ts +5 -0
- package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -1
- package/lib/types/dsh-adapter/shortcuts.js +49 -0
- package/lib/types/dsh-adapter/status.d.ts +5 -0
- package/lib/types/dsh-adapter/status.d.ts.map +1 -1
- package/lib/types/dsh-adapter/status.js +29 -0
- package/lib/types/dsh-adapter/subagents.d.ts +9 -49
- package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
- package/lib/types/dsh-adapter/subagents.js +92 -1
- package/lib/types/dsh-adapter/themes.d.ts +1 -0
- package/lib/types/dsh-adapter/themes.d.ts.map +1 -1
- package/lib/types/dsh-adapter/themes.js +29 -0
- package/lib/types/dsh-adapter/toast.d.ts +13 -0
- package/lib/types/dsh-adapter/toast.d.ts.map +1 -1
- package/lib/types/dsh-adapter/toast.js +31 -1
- package/lib/types/dsh-adapter/trajectory/aggregate.d.ts +2 -1
- package/lib/types/dsh-adapter/trajectory/aggregate.d.ts.map +1 -1
- package/lib/types/dsh-adapter/trajectory/aggregate.js +2 -1
- package/lib/types/dsh-adapter/trajectory/guards.d.ts +37 -18
- package/lib/types/dsh-adapter/trajectory/guards.d.ts.map +1 -1
- package/lib/types/dsh-adapter/trajectory/guards.js +43 -5
- package/lib/types/dsh-adapter/trajectory/inspect.d.ts +2 -2
- package/lib/types/dsh-adapter/trajectory/inspect.d.ts.map +1 -1
- package/lib/types/dsh-adapter/trajectory/projection.d.ts +31 -13
- package/lib/types/dsh-adapter/trajectory/projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/trajectory/projection.js +71 -14
- package/lib/types/dsh-adapter/trajectory/types.d.ts +1 -1
- package/lib/types/dsh-adapter/trajectory/types.d.ts.map +1 -1
- package/lib/types/dsh-adapter/transcript-images.d.ts +2 -19
- package/lib/types/dsh-adapter/transcript-images.d.ts.map +1 -1
- package/lib/types/dsh-adapter/workspaces.d.ts +2 -49
- package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -1
- package/lib/types/dsh-adapter/workspaces.js +23 -3
- package/lib/types/i18n.d.ts +19 -7
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +8 -3
- package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
- package/lib/types/ink/components/ScrollBox.js +30 -33
- package/lib/types/ink/dom.d.ts.map +1 -1
- package/lib/types/ink/dom.js +32 -64
- package/lib/types/ink/get-max-width.d.ts +7 -15
- package/lib/types/ink/get-max-width.d.ts.map +1 -1
- package/lib/types/ink/get-max-width.js +7 -20
- package/lib/types/ink/ink.d.ts +1 -0
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +22 -3
- package/lib/types/ink/layout/node.d.ts +2 -0
- package/lib/types/ink/layout/node.d.ts.map +1 -1
- package/lib/types/ink/layout/yoga.d.ts +1 -0
- package/lib/types/ink/layout/yoga.d.ts.map +1 -1
- package/lib/types/ink/layout/yoga.js +3 -0
- package/lib/types/ink/node-cache.d.ts +11 -0
- package/lib/types/ink/node-cache.d.ts.map +1 -1
- package/lib/types/ink/node-cache.js +3 -0
- package/lib/types/ink/output.d.ts +6 -1
- package/lib/types/ink/output.d.ts.map +1 -1
- package/lib/types/ink/output.js +55 -65
- package/lib/types/ink/render-node-to-output.d.ts +24 -1
- package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
- package/lib/types/ink/render-node-to-output.js +195 -71
- package/lib/types/ink/renderer.d.ts.map +1 -1
- package/lib/types/ink/renderer.js +14 -2
- package/lib/types/ink/styles.d.ts +12 -0
- package/lib/types/ink/styles.d.ts.map +1 -1
- package/lib/types/ink/tabstops.d.ts +3 -2
- package/lib/types/ink/tabstops.d.ts.map +1 -1
- package/lib/types/ink/tabstops.js +5 -4
- package/lib/types/ink/wrap-text.js +2 -2
- package/lib/types/modelGroups.d.ts +1 -1
- package/lib/types/modelGroups.d.ts.map +1 -1
- package/lib/types/modelRoute.js +1 -1
- package/lib/types/native-ts/yoga-layout/index.d.ts +8 -3
- package/lib/types/native-ts/yoga-layout/index.d.ts.map +1 -1
- package/lib/types/native-ts/yoga-layout/index.js +23 -8
- package/lib/types/plugin-host.d.ts +3 -4
- package/lib/types/plugin-host.d.ts.map +1 -1
- package/lib/types/plugin-host.js +8 -6
- package/lib/types/screens/AgentView.d.ts +1 -1
- package/lib/types/screens/AgentView.d.ts.map +1 -1
- package/lib/types/screens/Chat.d.ts +3 -2
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +91 -17
- package/lib/types/screens/SessionBrowser.d.ts +1 -1
- package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
- package/lib/types/screens/SessionTree.d.ts +1 -1
- package/lib/types/screens/SessionTree.d.ts.map +1 -1
- package/lib/types/screens/Settings.d.ts +1 -1
- package/lib/types/screens/Settings.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.d.ts +1 -1
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +40 -1
- package/lib/types/screens/TrajectoryScene.d.ts +1 -1
- package/lib/types/screens/TrajectoryScene.d.ts.map +1 -1
- package/lib/types/sessionModes.d.ts +11 -15
- package/lib/types/sessionModes.d.ts.map +1 -1
- package/lib/types/sessionModes.js +11 -0
- package/lib/types/tuiDisplayPrefs.d.ts +2 -68
- package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
- package/lib/types/tuiDisplayPrefs.js +5 -1
- package/lib/types/utils/credentials.d.ts +13 -0
- package/lib/types/utils/credentials.d.ts.map +1 -0
- package/lib/types/utils/credentials.js +41 -0
- package/lib/types/utils/fileSuggestions.d.ts +2 -9
- package/lib/types/utils/fileSuggestions.d.ts.map +1 -1
- package/lib/types/utils/fold-long-lines.d.ts +38 -0
- package/lib/types/utils/fold-long-lines.d.ts.map +1 -0
- package/lib/types/utils/fold-long-lines.js +91 -0
- package/node_modules/@deepseek-harness-tui/dsh-auth/lib/pi-ai.d.ts +1 -1
- package/node_modules/@deepseek-harness-tui/dsh-auth/lib/profiles.js +4 -0
- package/node_modules/@deepseek-harness-tui/dsh-auth/lib/service.js +15 -2
- package/node_modules/@deepseek-harness-tui/dsh-auth/package.json +10 -10
- package/package.json +125 -81
- package/presets/liangshen/.dsh-tui-managed.json +1 -1
- package/presets/liangshen/agent.cordis.yml +20 -4
- package/presets/liangshen/compaction-epoch.mjs +3 -1
- package/presets/liangshen/instruction-hint.mjs +2 -1
- package/presets/liangshen/session-events.mjs +8 -0
- package/lib/types/dsh-adapter/grants.d.ts.map +0 -1
- package/lib/types/dsh-adapter/host-descriptor.d.ts +0 -24
- package/lib/types/dsh-adapter/host-descriptor.d.ts.map +0 -1
- package/lib/types/dsh-adapter/host-descriptor.js +0 -169
- package/lib/types/dsh-adapter/plugin-test-utils.d.ts +0 -62
- package/lib/types/dsh-adapter/plugin-test-utils.d.ts.map +0 -1
- package/lib/types/dsh-adapter/plugin-test-utils.js +0 -61
- package/lib/types/plugin-spec/negotiate.d.ts.map +0 -1
- package/lib/types/plugin-spec/permission-scope.d.ts.map +0 -1
- package/lib/types/plugin-spec/registry.d.ts.map +0 -1
- package/lib/types/plugin-spec/schema-check.d.ts.map +0 -1
- package/lib/types/plugin-spec/tui-extension.d.ts +0 -16
- package/lib/types/plugin-spec/tui-extension.d.ts.map +0 -1
- package/lib/types/plugin-spec/tui-extension.js +0 -79
- package/lib/types/plugin-spec/types.d.ts.map +0 -1
- package/lib/types/plugin-spec/validate.d.ts.map +0 -1
- package/lib/types/test-utils.d.ts +0 -2
- package/lib/types/test-utils.d.ts.map +0 -1
- package/lib/types/test-utils.js +0 -8
- /package/lib/types/{plugin-spec → adapter/standard}/negotiate.d.ts +0 -0
- /package/lib/types/{plugin-spec → adapter/standard}/negotiate.js +0 -0
- /package/lib/types/{plugin-spec → adapter/standard}/registry.d.ts +0 -0
- /package/lib/types/{plugin-spec → adapter/standard}/schema-check.d.ts +0 -0
- /package/lib/types/{plugin-spec → adapter/standard}/types.js +0 -0
|
@@ -0,0 +1,1021 @@
|
|
|
1
|
+
import { isSubagentToolName, parseJobOutputId, toolCommandOf, BACKGROUND_START_ACK, todoPanelItems } from './projection-helpers.js';
|
|
2
|
+
import { ARGS_PREVIEW_LIMIT, harnessToolResultView, LOCAL_OUTPUT_LIMIT, prepareReplayEvents, preview, RESULT_PREVIEW_LIMIT, toolErrorText } from './transcript.js';
|
|
3
|
+
import { estimateTokens, isTokenDelta, tokenDeltaChars, usageOutputTokens } from './usage.js';
|
|
4
|
+
import { transcriptImagesOf } from '../transcript-images.js';
|
|
5
|
+
import { isPeakHour } from '../../deepseekPricing.js';
|
|
6
|
+
import { t } from '../../i18n.js';
|
|
7
|
+
import { logForDebugging } from '../../utils/debug.js';
|
|
8
|
+
import { cleanRenderText } from '../sanitize.js';
|
|
9
|
+
import { NOTICE_CELLS } from './decisions.js';
|
|
10
|
+
import { markChannelReadDirty } from '../../adapter/channel/read-view.js';
|
|
11
|
+
/** One authoritative reducer for both durable replay and live session events. */
|
|
12
|
+
export function createChannelProjection(state, deps) {
|
|
13
|
+
/** The in-progress assistant text row; `undefined` when no step is streaming. */
|
|
14
|
+
let streaming;
|
|
15
|
+
/** The in-progress reasoning row; `undefined` when no reasoning is streaming. */
|
|
16
|
+
let reasoning;
|
|
17
|
+
/** Reasoning rows sealed by an assistant/message this turn. They stay
|
|
18
|
+
* `streaming: true` — expanded in the transcript — until turn/end folds
|
|
19
|
+
* them (WebUI AssistantMarkdown keepOpen parity: thinking holds open
|
|
20
|
+
* through the whole in-flight turn, tool-call steps included). */
|
|
21
|
+
const sealedReasoning = [];
|
|
22
|
+
/** Wall-clock start of the current reasoning row (durationMs on settle). */
|
|
23
|
+
let reasoningStart = 0;
|
|
24
|
+
/** Decode-throughput fold for the current turn. DSH defines one step as
|
|
25
|
+
* one model call plus its tools; summing only first-token → message spans
|
|
26
|
+
* excludes tool execution and per-request TTFT from generation speed. */
|
|
27
|
+
let tpsTurn;
|
|
28
|
+
let tpsBeforeTurn;
|
|
29
|
+
let tpsTurnDecodeMs = 0;
|
|
30
|
+
let tpsTurnDecodeTokens = 0;
|
|
31
|
+
let tpsTurnSampled = false;
|
|
32
|
+
let tpsStep;
|
|
33
|
+
/** Tool cards by callId, so tool/result can settle the running card. */
|
|
34
|
+
const toolCards = new Map();
|
|
35
|
+
/**
|
|
36
|
+
* Session events are delivered live and can also be replayed around a
|
|
37
|
+
* reconnect. A repeated sealed message must not create a second assistant
|
|
38
|
+
* row for the same durable sequence number.
|
|
39
|
+
*/
|
|
40
|
+
const handledAssistantMessages = new Set();
|
|
41
|
+
const handledAssistantChunks = new Set();
|
|
42
|
+
/** One Agent runs one request at a time. Durable step boundaries also let
|
|
43
|
+
* a freshly attached projector accept chunks whose start it missed. */
|
|
44
|
+
let openStep;
|
|
45
|
+
let activeAttempt;
|
|
46
|
+
let lastStreamRevision = -1;
|
|
47
|
+
const assistantRowsByStep = new Map();
|
|
48
|
+
const lastTextDelta = new Map();
|
|
49
|
+
const stepKey = (turn, step) => `${turn}:${step}`;
|
|
50
|
+
const touchRow = (row) => { markChannelReadDirty(row); markChannelReadDirty(state.rows); };
|
|
51
|
+
const appendRow = (row) => { state.rows.push(row); markChannelReadDirty(state.rows); };
|
|
52
|
+
const removeRow = (row) => {
|
|
53
|
+
const index = state.rows.indexOf(row);
|
|
54
|
+
if (index !== -1) {
|
|
55
|
+
state.rows.splice(index, 1);
|
|
56
|
+
markChannelReadDirty(state.rows);
|
|
57
|
+
}
|
|
58
|
+
if (streaming === row)
|
|
59
|
+
streaming = undefined;
|
|
60
|
+
if (reasoning === row)
|
|
61
|
+
reasoning = undefined;
|
|
62
|
+
if (lastReasoningRow?.row === row)
|
|
63
|
+
lastReasoningRow = undefined;
|
|
64
|
+
const sealedIndex = sealedReasoning.indexOf(row);
|
|
65
|
+
if (sealedIndex !== -1)
|
|
66
|
+
sealedReasoning.splice(sealedIndex, 1);
|
|
67
|
+
lastTextDelta.delete(row);
|
|
68
|
+
};
|
|
69
|
+
const discardAttempt = (turn, step) => {
|
|
70
|
+
const key = stepKey(turn, step);
|
|
71
|
+
const row = assistantRowsByStep.get(key);
|
|
72
|
+
if (row !== undefined && row.seq === undefined) {
|
|
73
|
+
state.responseChars = Math.max(0, state.responseChars - row.text.length);
|
|
74
|
+
removeRow(row);
|
|
75
|
+
assistantRowsByStep.delete(key);
|
|
76
|
+
}
|
|
77
|
+
if (lastReasoningRow !== undefined && lastReasoningRow.turn === turn && lastReasoningRow.step === step && lastReasoningRow.row.seq === undefined) {
|
|
78
|
+
removeRow(lastReasoningRow.row);
|
|
79
|
+
}
|
|
80
|
+
if (activeAttempt !== undefined && activeAttempt.turn === turn && activeAttempt.step === step)
|
|
81
|
+
activeAttempt = undefined;
|
|
82
|
+
if (tpsStep !== undefined && tpsStep.turn === turn && tpsStep.step === step) {
|
|
83
|
+
tpsStep.firstTokenTime = undefined;
|
|
84
|
+
tpsStep.outputChars = 0;
|
|
85
|
+
}
|
|
86
|
+
updateSpinnerMode();
|
|
87
|
+
};
|
|
88
|
+
/** Durable session image blocks, loaded lazily through the attachment
|
|
89
|
+
* store. Projection never reads pixels; the UI decodes on demand. */
|
|
90
|
+
const transcriptImages = (content) => transcriptImagesOf(content, deps.attachments);
|
|
91
|
+
/** V3 deltas are ordered by frame revision and must stay byte-exact.
|
|
92
|
+
* Legacy reconnect/proxy events may instead repeat a cumulative prefix. */
|
|
93
|
+
const appendTextDelta = (row, delta, legacy) => {
|
|
94
|
+
if (delta === '')
|
|
95
|
+
return;
|
|
96
|
+
if (!legacy) {
|
|
97
|
+
row.text += delta;
|
|
98
|
+
touchRow(row);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (lastTextDelta.get(row) === delta)
|
|
102
|
+
return;
|
|
103
|
+
lastTextDelta.set(row, delta);
|
|
104
|
+
if (delta.startsWith(row.text)) {
|
|
105
|
+
row.text = delta;
|
|
106
|
+
touchRow(row);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const maxOverlap = Math.min(row.text.length, delta.length, 4096);
|
|
110
|
+
for (let size = maxOverlap; size > 0; size--) {
|
|
111
|
+
if (row.text.endsWith(delta.slice(0, size))) {
|
|
112
|
+
row.text += delta.slice(size);
|
|
113
|
+
touchRow(row);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
row.text += delta;
|
|
118
|
+
touchRow(row);
|
|
119
|
+
};
|
|
120
|
+
/** The host-plane tools registry (dsh-tools). Resolved once; absent in
|
|
121
|
+
* bare embedders — every presenter call soft-fails to undefined and the
|
|
122
|
+
* card falls back to raw text. */
|
|
123
|
+
const toolsRegistry = deps.tools;
|
|
124
|
+
/** Ask the producing tool how its call should render (diff/terminal/…).
|
|
125
|
+
* Scoped to the live agent so preset-owned tool definitions resolve —
|
|
126
|
+
* the dsh-host-apiproxy presenter pattern. Unknown tool, unparseable
|
|
127
|
+
* args, or a throwing presenter all degrade to the plain text card. */
|
|
128
|
+
const presentCallView = (name, rawArgs) => {
|
|
129
|
+
try {
|
|
130
|
+
const tool = toolsRegistry?.get(name, deps.agent());
|
|
131
|
+
if (tool?.presentCall === undefined)
|
|
132
|
+
return undefined;
|
|
133
|
+
return tool.presentCall(JSON.parse(rawArgs));
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
/** Same for the settled result; `meta` is the tool-private presentation
|
|
140
|
+
* payload the tool attached to its tool/result event (dsh-tool-fs reads
|
|
141
|
+
* its result-time contextual diff back from here). */
|
|
142
|
+
const presentResultView = (name, rawArgs, data) => {
|
|
143
|
+
try {
|
|
144
|
+
// Harness goal/todo tools first: their raw JSON reads as noise in the
|
|
145
|
+
// transcript — fold recognizable shapes into a summary card before the
|
|
146
|
+
// registry gets a chance to (not) know them.
|
|
147
|
+
const local = harnessToolResultView(name, data);
|
|
148
|
+
if (local !== undefined)
|
|
149
|
+
return local;
|
|
150
|
+
const tool = toolsRegistry?.get(name, deps.agent());
|
|
151
|
+
if (tool?.presentResult === undefined)
|
|
152
|
+
return undefined;
|
|
153
|
+
const block = data.message.content[0];
|
|
154
|
+
// oxlint-disable-next-line typescript/no-unnecessary-condition -- durable session data may not match type
|
|
155
|
+
const content = block !== undefined && block.type === 'tool-result' ? block.content : [];
|
|
156
|
+
return tool.presentResult(JSON.parse(rawArgs), {
|
|
157
|
+
content,
|
|
158
|
+
isError: block?.isError === true,
|
|
159
|
+
...(data.meta !== undefined ? { meta: data.meta } : {}),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
// ContentBlockMap is merge-extensible: plugin-added block types are
|
|
167
|
+
// silently skipped (v1 renders text blocks only) — never crashes.
|
|
168
|
+
const textOf = (content) => (content ?? []).map(block => (block.type === 'text' ? block.text : '')).join('').trim();
|
|
169
|
+
/**
|
|
170
|
+
* Transcript-facing text of a user message: the FIRST text block only.
|
|
171
|
+
* `@`-mention attachments (issue #15) ride as later blocks — model-facing
|
|
172
|
+
* only — so joining every block would dump file contents into the bubble,
|
|
173
|
+
* the sticky header, and session titles.
|
|
174
|
+
*/
|
|
175
|
+
const firstTextOf = (content) => (content ?? []).find(block => block.type === 'text')?.text.trim() ?? '';
|
|
176
|
+
const ensureStreaming = (seq) => {
|
|
177
|
+
if (streaming !== undefined)
|
|
178
|
+
return streaming;
|
|
179
|
+
// A reconnect can replay the first delta after the sealed message was
|
|
180
|
+
// already observed. Reuse that durable row instead of opening a second
|
|
181
|
+
// assistant bubble for the same event sequence.
|
|
182
|
+
const existing = seq === undefined
|
|
183
|
+
? undefined
|
|
184
|
+
: [...state.rows].reverse().find(row => row.kind === 'assistant' && row.seq === seq);
|
|
185
|
+
if (existing !== undefined) {
|
|
186
|
+
existing.streaming = true;
|
|
187
|
+
touchRow(existing);
|
|
188
|
+
streaming = existing;
|
|
189
|
+
return existing;
|
|
190
|
+
}
|
|
191
|
+
streaming = { id: deps.rowIds.value, kind: 'assistant', text: '', streaming: true, fresh: true, ...seq !== undefined ? { seq } : {} };
|
|
192
|
+
deps.rowIds.value += 1;
|
|
193
|
+
appendRow(streaming);
|
|
194
|
+
return streaming;
|
|
195
|
+
};
|
|
196
|
+
/** Latest reasoning row keyed by its (turn, step) — lets a resumed
|
|
197
|
+
* mid-step stream REVIVE the row the replay sealed (crash-orphan tail:
|
|
198
|
+
* replay folds the partial row, live continuation chunks would
|
|
199
|
+
* otherwise open a SECOND row for the same step, splitting one
|
|
200
|
+
* thinking block in two). */
|
|
201
|
+
let lastReasoningRow;
|
|
202
|
+
const ensureReasoning = (seq, turn, step) => {
|
|
203
|
+
if (reasoning === undefined) {
|
|
204
|
+
// Same-step revive: the sealed row is this step's thinking — continue
|
|
205
|
+
// it (durationMs carried over via reasoningStart back-dating).
|
|
206
|
+
if (lastReasoningRow !== undefined &&
|
|
207
|
+
turn !== undefined &&
|
|
208
|
+
lastReasoningRow.turn === turn &&
|
|
209
|
+
lastReasoningRow.step === step) {
|
|
210
|
+
reasoning = lastReasoningRow.row;
|
|
211
|
+
reasoning.streaming = true;
|
|
212
|
+
touchRow(reasoning);
|
|
213
|
+
const sealedIdx = sealedReasoning.indexOf(reasoning);
|
|
214
|
+
if (sealedIdx !== -1)
|
|
215
|
+
sealedReasoning.splice(sealedIdx, 1);
|
|
216
|
+
reasoningStart = Date.now() - (reasoning.durationMs ?? 0);
|
|
217
|
+
logForDebugging('thinking: revived sealed reasoning row for same step');
|
|
218
|
+
return reasoning;
|
|
219
|
+
}
|
|
220
|
+
reasoningStart = Date.now();
|
|
221
|
+
reasoning = { id: deps.rowIds.value, kind: 'reasoning', text: '', streaming: true, ...seq !== undefined ? { seq } : {} };
|
|
222
|
+
deps.rowIds.value += 1;
|
|
223
|
+
appendRow(reasoning);
|
|
224
|
+
logForDebugging('thinking: reasoning row open (expanded)');
|
|
225
|
+
}
|
|
226
|
+
if (turn !== undefined && step !== undefined) {
|
|
227
|
+
lastReasoningRow = { row: reasoning, turn, step };
|
|
228
|
+
}
|
|
229
|
+
return reasoning;
|
|
230
|
+
};
|
|
231
|
+
/** Fold the live reasoning preview the moment the model moves PAST
|
|
232
|
+
* thinking — the answer's first text token or a tool call — not at
|
|
233
|
+
* `assistant/message` (end of step). A long reply pushes the thinking
|
|
234
|
+
* block into terminal scrollback long before the message seals, and
|
|
235
|
+
* scrollback rows cannot be repainted (the cursor cannot reach them),
|
|
236
|
+
* so a late fold leaves a stale unfolded preview frozen above the
|
|
237
|
+
* window — the user scrolls up and the thinking looks "not folded".
|
|
238
|
+
* Folding while the block still sits in the live window keeps the
|
|
239
|
+
* shrink inside the diff engine's reachable region. Preview mode only
|
|
240
|
+
* (`full` holds every block open until turn settle by design). */
|
|
241
|
+
const foldLiveReasoning = (where) => {
|
|
242
|
+
if (reasoning === undefined || state.thinkingFold !== 'preview')
|
|
243
|
+
return;
|
|
244
|
+
const duration = Math.max(0, Date.now() - reasoningStart);
|
|
245
|
+
reasoning.durationMs = duration;
|
|
246
|
+
reasoning.streaming = false;
|
|
247
|
+
touchRow(reasoning);
|
|
248
|
+
sealedReasoning.push(reasoning);
|
|
249
|
+
reasoning = undefined;
|
|
250
|
+
logForDebugging(`thinking: folded at ${where} (${duration}ms)`);
|
|
251
|
+
};
|
|
252
|
+
const settleStreaming = () => {
|
|
253
|
+
if (streaming !== undefined) {
|
|
254
|
+
streaming.streaming = false;
|
|
255
|
+
touchRow(streaming);
|
|
256
|
+
}
|
|
257
|
+
streaming = undefined;
|
|
258
|
+
const folded = sealedReasoning.length + (reasoning !== undefined ? 1 : 0);
|
|
259
|
+
for (const row of sealedReasoning) {
|
|
260
|
+
row.streaming = false;
|
|
261
|
+
touchRow(row);
|
|
262
|
+
}
|
|
263
|
+
sealedReasoning.length = 0;
|
|
264
|
+
if (reasoning !== undefined) {
|
|
265
|
+
reasoning.streaming = false;
|
|
266
|
+
reasoning.durationMs = Math.max(0, Date.now() - reasoningStart);
|
|
267
|
+
touchRow(reasoning);
|
|
268
|
+
}
|
|
269
|
+
reasoning = undefined;
|
|
270
|
+
if (folded > 0)
|
|
271
|
+
logForDebugging(`thinking: folded ${folded} reasoning row(s) at turn settle`);
|
|
272
|
+
};
|
|
273
|
+
/** Recompute the spinner phase from live row/tool state. */
|
|
274
|
+
const updateSpinnerMode = () => {
|
|
275
|
+
if (state.activeToolCount > 0) {
|
|
276
|
+
state.spinnerMode = 'tool-use';
|
|
277
|
+
}
|
|
278
|
+
else if (reasoning !== undefined) {
|
|
279
|
+
// Only LIVE reasoning counts — sealed rows stay streaming=true for
|
|
280
|
+
// transcript expansion until turn/end but the model is past thinking.
|
|
281
|
+
state.spinnerMode = 'thinking';
|
|
282
|
+
}
|
|
283
|
+
else if (streaming !== undefined) {
|
|
284
|
+
state.spinnerMode = 'responding';
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
state.spinnerMode = 'requesting';
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
/** Fold one goal mutation into the channel's goal projection. */
|
|
291
|
+
const applyGoalChange = (change) => {
|
|
292
|
+
if (change.operation === 'clear') {
|
|
293
|
+
state.goal = undefined;
|
|
294
|
+
}
|
|
295
|
+
else if (change.goal !== undefined) {
|
|
296
|
+
state.goal = {
|
|
297
|
+
...change.goal,
|
|
298
|
+
roundsStarted: change.roundsStarted ?? state.goal?.roundsStarted ?? 0,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Fold one goal-sourced message into the channel's goal projection.
|
|
304
|
+
* Round-zero goal messages may carry the full durable snapshot (or a clear
|
|
305
|
+
* tombstone) in their source; positive-round messages are admitted
|
|
306
|
+
* continuation prompts that only advance the rounds counter.
|
|
307
|
+
*/
|
|
308
|
+
const applyGoalEvent = (event) => {
|
|
309
|
+
const source = event.data.source;
|
|
310
|
+
if (source.round > 0) {
|
|
311
|
+
// Admitted continuation round — the snapshot itself is unchanged.
|
|
312
|
+
if (state.goal !== undefined) {
|
|
313
|
+
state.goal = {
|
|
314
|
+
...state.goal,
|
|
315
|
+
roundsStarted: Math.max(state.goal.roundsStarted, source.round),
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
const change = source.change;
|
|
321
|
+
// oxlint-disable-next-line typescript/no-unnecessary-condition -- durable replay data may not match the static type
|
|
322
|
+
if (change === undefined || change.kind !== 'goal/change')
|
|
323
|
+
return;
|
|
324
|
+
applyGoalChange(change);
|
|
325
|
+
};
|
|
326
|
+
/** Replay paints settled history without the live smooth-reveal animation. */
|
|
327
|
+
let replaying = false;
|
|
328
|
+
const replayEvents = (events) => {
|
|
329
|
+
// Event sequence numbers restart with a replacement session; reset the
|
|
330
|
+
// idempotency ledger before replay so an old session cannot suppress a
|
|
331
|
+
// legitimate message in the new transcript.
|
|
332
|
+
handledAssistantMessages.clear();
|
|
333
|
+
handledAssistantChunks.clear();
|
|
334
|
+
openStep = undefined;
|
|
335
|
+
activeAttempt = undefined;
|
|
336
|
+
lastStreamRevision = -1;
|
|
337
|
+
assistantRowsByStep.clear();
|
|
338
|
+
lastTextDelta.clear();
|
|
339
|
+
replaying = true;
|
|
340
|
+
try {
|
|
341
|
+
for (const event of prepareReplayEvents(events))
|
|
342
|
+
renderEvent(event);
|
|
343
|
+
}
|
|
344
|
+
finally {
|
|
345
|
+
replaying = false;
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
/**
|
|
349
|
+
* One live stream delta, from a 0.1.5 `agent/assistant-stream` chunk frame
|
|
350
|
+
* or a legacy `assistant/chunk` session event (pre-0.1.5 hosts and raw
|
|
351
|
+
* pre-V3 logs). `seq` exists only on the durable-event path.
|
|
352
|
+
*/
|
|
353
|
+
const renderStreamChunk = (turn, step, chunk, time, seq) => {
|
|
354
|
+
if (chunk.type === 'text-delta') {
|
|
355
|
+
if (chunk.text) {
|
|
356
|
+
// Fold the thinking preview while it is still in the live
|
|
357
|
+
// window (see foldLiveReasoning) — before this text grows the
|
|
358
|
+
// transcript and pushes the block into scrollback.
|
|
359
|
+
foldLiveReasoning('first text token');
|
|
360
|
+
const key = stepKey(turn, step);
|
|
361
|
+
const row = assistantRowsByStep.get(key) ?? ensureStreaming(seq);
|
|
362
|
+
assistantRowsByStep.set(key, row);
|
|
363
|
+
streaming = row;
|
|
364
|
+
row.streaming = true;
|
|
365
|
+
touchRow(row);
|
|
366
|
+
const before = row.text.length;
|
|
367
|
+
appendTextDelta(row, chunk.text, seq !== undefined);
|
|
368
|
+
state.responseChars += Math.max(0, row.text.length - before);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
else if (chunk.type === 'reasoning-delta') {
|
|
372
|
+
if (chunk.text) {
|
|
373
|
+
const row = ensureReasoning(seq, turn, step);
|
|
374
|
+
appendTextDelta(row, chunk.text, seq !== undefined);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
const tps = tpsStep;
|
|
378
|
+
if (tps !== undefined &&
|
|
379
|
+
tps.turn === turn &&
|
|
380
|
+
tps.step === step &&
|
|
381
|
+
isTokenDelta(chunk)) {
|
|
382
|
+
tps.firstTokenTime ??= time;
|
|
383
|
+
tps.outputChars += tokenDeltaChars(chunk);
|
|
384
|
+
const elapsedMs = Math.max(0, time - tps.firstTokenTime);
|
|
385
|
+
if (elapsedMs > 500) {
|
|
386
|
+
const decodeMs = tpsTurnDecodeMs + elapsedMs;
|
|
387
|
+
const outputTokens = tpsTurnDecodeTokens + Math.ceil(tps.outputChars / 4);
|
|
388
|
+
state.tps = outputTokens / (decodeMs / 1000);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
updateSpinnerMode();
|
|
392
|
+
};
|
|
393
|
+
/**
|
|
394
|
+
* Live assistant stream frame (0.1.5+): the transient per-token counterpart
|
|
395
|
+
* of the durable `assistant/message`/`assistant/attempt` settlement. Start
|
|
396
|
+
* frames own the attempt's (turn, step); a reattach rebuilds that pair
|
|
397
|
+
* from the open durable step. Settlement owns the text; an abandoned end
|
|
398
|
+
* must discard provisional rows even when no durable event was written.
|
|
399
|
+
*/
|
|
400
|
+
const renderStreamFrame = (frame) => {
|
|
401
|
+
if (frame.revision <= lastStreamRevision)
|
|
402
|
+
return;
|
|
403
|
+
lastStreamRevision = frame.revision;
|
|
404
|
+
if (frame.type === 'start') {
|
|
405
|
+
if (activeAttempt !== undefined)
|
|
406
|
+
discardAttempt(activeAttempt.turn, activeAttempt.step);
|
|
407
|
+
activeAttempt = { attemptId: frame.attemptId, turn: frame.turn, step: frame.step };
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
if (frame.type === 'end') {
|
|
411
|
+
if (activeAttempt?.attemptId !== frame.attemptId)
|
|
412
|
+
return;
|
|
413
|
+
if (frame.outcome.kind === 'abandoned' || frame.outcome.eventType === 'assistant/attempt') {
|
|
414
|
+
discardAttempt(activeAttempt.turn, activeAttempt.step);
|
|
415
|
+
}
|
|
416
|
+
activeAttempt = undefined;
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
if (activeAttempt === undefined && openStep !== undefined) {
|
|
420
|
+
activeAttempt = { attemptId: frame.attemptId, ...openStep };
|
|
421
|
+
}
|
|
422
|
+
const where = activeAttempt?.attemptId === frame.attemptId ? activeAttempt : undefined;
|
|
423
|
+
if (where === undefined)
|
|
424
|
+
return;
|
|
425
|
+
renderStreamChunk(where.turn, where.step, frame.chunk, frame.time);
|
|
426
|
+
};
|
|
427
|
+
const renderEvent = (event) => {
|
|
428
|
+
// Top-level `goal/change` events are how the goal service actually
|
|
429
|
+
// records durable goal mutations (create/edit/pause/resume/complete/
|
|
430
|
+
// block/clear) — confirmed in production logs. The pinned peer's
|
|
431
|
+
// SessionEvent union predates the type, so admit it structurally: the
|
|
432
|
+
// goal chip and panel stay dark without this fold.
|
|
433
|
+
if (event.type === 'goal/change') {
|
|
434
|
+
applyGoalChange(event.data);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
switch (event.type) {
|
|
438
|
+
case 'user/message': {
|
|
439
|
+
// Compaction checkpoint: `source = { kind: 'plugin', plugin:
|
|
440
|
+
// 'compact' }` (dsh-compact's COMPACT_CHECKPOINT_SOURCE). Render the
|
|
441
|
+
// framed summary after /compact as a Divider title + a summary row
|
|
442
|
+
// that defaults folded (`compact` kind) instead of skipping it like
|
|
443
|
+
// other injected context.
|
|
444
|
+
if (event.data.source.kind === 'plugin' &&
|
|
445
|
+
event.data.source.plugin === 'compact') {
|
|
446
|
+
const summary = textOf(event.data.content);
|
|
447
|
+
appendRow({ id: deps.rowIds.value, kind: 'notice', text: 'Session summary is ready' });
|
|
448
|
+
deps.rowIds.value += 1;
|
|
449
|
+
if (summary) {
|
|
450
|
+
appendRow({ id: deps.rowIds.value, kind: 'compact', text: summary });
|
|
451
|
+
deps.rowIds.value += 1;
|
|
452
|
+
}
|
|
453
|
+
// The surface replace drops the whole pre-compact history: reset
|
|
454
|
+
// the context accounting NOW so the status bar (ctx bar, tokens,
|
|
455
|
+
// context-low warning) drops immediately instead of waiting for
|
|
456
|
+
// the next request's usage event.
|
|
457
|
+
const removed = state.contextSegments.prompt +
|
|
458
|
+
state.contextSegments.assistant +
|
|
459
|
+
state.contextSegments.thinking +
|
|
460
|
+
state.contextSegments.tools;
|
|
461
|
+
const summaryTokens = estimateTokens(summary);
|
|
462
|
+
state.tokens.input = Math.max(0, state.tokens.input - removed) + summaryTokens;
|
|
463
|
+
state.contextSegments = {
|
|
464
|
+
system: state.contextSegments.system,
|
|
465
|
+
prompt: summaryTokens,
|
|
466
|
+
assistant: 0,
|
|
467
|
+
thinking: 0,
|
|
468
|
+
tools: 0,
|
|
469
|
+
};
|
|
470
|
+
state.lastUsage = {
|
|
471
|
+
input: state.contextSegments.system + summaryTokens,
|
|
472
|
+
output: 0,
|
|
473
|
+
cacheRead: 0,
|
|
474
|
+
cacheWrite: 0,
|
|
475
|
+
};
|
|
476
|
+
deps.resetContextWarning();
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
479
|
+
// Same-session goal domain: goal-sourced messages are the round
|
|
480
|
+
// driver's continuation prompts (positive rounds advance the
|
|
481
|
+
// counter); some hosts also inline the durable snapshot in a
|
|
482
|
+
// round-zero source. They are not transcript bubbles — they drive
|
|
483
|
+
// the goal panel's live projection (replayed on resume/rewind like
|
|
484
|
+
// every other event; the snapshot itself arrives as the top-level
|
|
485
|
+
// `goal/change` event admitted above).
|
|
486
|
+
if (event.data.source.kind === 'goal') {
|
|
487
|
+
applyGoalEvent(event);
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
// Injected context (plugin/skill source) is not a human bubble; v1
|
|
491
|
+
// renders direct human prompts only.
|
|
492
|
+
if (event.data.source.kind !== 'user')
|
|
493
|
+
break;
|
|
494
|
+
const text = firstTextOf(event.data.content);
|
|
495
|
+
const images = transcriptImages(event.data.content);
|
|
496
|
+
if (text || images.length > 0) {
|
|
497
|
+
appendRow({
|
|
498
|
+
id: deps.rowIds.value,
|
|
499
|
+
kind: 'user',
|
|
500
|
+
text,
|
|
501
|
+
...(images.length === 0 ? {} : { images }),
|
|
502
|
+
seq: event.seq,
|
|
503
|
+
});
|
|
504
|
+
state.lastUserText = text || t('transcript-image-message', { count: images.length });
|
|
505
|
+
// The context estimate counts everything sent to the model —
|
|
506
|
+
// typed text AND the `@`-mention attachment blocks.
|
|
507
|
+
state.contextSegments.prompt += estimateTokens(textOf(event.data.content));
|
|
508
|
+
deps.rowIds.value += 1;
|
|
509
|
+
}
|
|
510
|
+
break;
|
|
511
|
+
}
|
|
512
|
+
case 'step/start': {
|
|
513
|
+
openStep = { turn: event.data.turn, step: event.data.step };
|
|
514
|
+
if (tpsTurn === event.data.turn) {
|
|
515
|
+
tpsStep = {
|
|
516
|
+
turn: event.data.turn,
|
|
517
|
+
step: event.data.step,
|
|
518
|
+
firstTokenTime: undefined,
|
|
519
|
+
outputChars: 0,
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
case 'assistant/attempt': {
|
|
525
|
+
discardAttempt(event.data.turn, event.data.step);
|
|
526
|
+
break;
|
|
527
|
+
}
|
|
528
|
+
case 'assistant/message': {
|
|
529
|
+
if (handledAssistantMessages.has(event.seq))
|
|
530
|
+
break;
|
|
531
|
+
handledAssistantMessages.add(event.seq);
|
|
532
|
+
// V3 embeds its complete attempt stream; older settlements may omit
|
|
533
|
+
// reasoning that is still durably recorded in assistant/chunk events.
|
|
534
|
+
const canonical = Array.isArray(event.data.stream);
|
|
535
|
+
const text = textOf(event.data.message.content);
|
|
536
|
+
const images = transcriptImages(event.data.message.content);
|
|
537
|
+
const reasoningText = event.data.message.content
|
|
538
|
+
.map(block => (block.type === 'reasoning' ? block.text : ''))
|
|
539
|
+
.join('');
|
|
540
|
+
const settledReasoning = lastReasoningRow !== undefined && lastReasoningRow.turn === event.data.turn && lastReasoningRow.step === event.data.step
|
|
541
|
+
? lastReasoningRow.row : reasoning;
|
|
542
|
+
if (settledReasoning !== undefined) {
|
|
543
|
+
if (reasoningText === '') {
|
|
544
|
+
if (canonical)
|
|
545
|
+
removeRow(settledReasoning);
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
settledReasoning.text = reasoningText;
|
|
549
|
+
settledReasoning.seq ??= event.seq;
|
|
550
|
+
touchRow(settledReasoning);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
else if (reasoningText !== '') {
|
|
554
|
+
// Replays and reattachments may not have seen any reasoning delta.
|
|
555
|
+
// Insert before a live text row to preserve message block order.
|
|
556
|
+
const rebuilt = {
|
|
557
|
+
id: deps.rowIds.value,
|
|
558
|
+
kind: 'reasoning',
|
|
559
|
+
text: reasoningText,
|
|
560
|
+
seq: event.seq,
|
|
561
|
+
};
|
|
562
|
+
deps.rowIds.value += 1;
|
|
563
|
+
const textRow = assistantRowsByStep.get(stepKey(event.data.turn, event.data.step));
|
|
564
|
+
const textIndex = textRow === undefined ? -1 : state.rows.indexOf(textRow);
|
|
565
|
+
if (textIndex === -1)
|
|
566
|
+
appendRow(rebuilt);
|
|
567
|
+
else {
|
|
568
|
+
state.rows.splice(textIndex, 0, rebuilt);
|
|
569
|
+
markChannelReadDirty(state.rows);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
// Reasoning/tool-only steps emit no text: creating an assistant row
|
|
573
|
+
// anyway leaves an empty `●` bullet in the transcript. A pre-existing
|
|
574
|
+
// streaming row always has text (ensureStreaming is only reached on
|
|
575
|
+
// non-empty text deltas), so only create one when text arrives.
|
|
576
|
+
// Key the step→row ledger only when the event carries a durable
|
|
577
|
+
// turn/step; a message without them must never collide onto a
|
|
578
|
+
// previous step's row (a bare `undefined:undefined` key would make
|
|
579
|
+
// every turn/step-less message reuse the FIRST one's assistant row).
|
|
580
|
+
const msgTurn = event.data.turn;
|
|
581
|
+
const msgStep = event.data.step;
|
|
582
|
+
const msgKey = msgTurn !== undefined && msgStep !== undefined
|
|
583
|
+
? stepKey(msgTurn, msgStep)
|
|
584
|
+
: undefined;
|
|
585
|
+
const row = (msgKey !== undefined ? assistantRowsByStep.get(msgKey) : undefined) ?? streaming ??
|
|
586
|
+
(text || images.length > 0
|
|
587
|
+
? ([...state.rows].reverse().find(candidate => candidate.kind === 'assistant' && candidate.seq === event.seq) ?? ensureStreaming(event.seq))
|
|
588
|
+
: undefined);
|
|
589
|
+
if (row !== undefined && canonical && !text && images.length === 0) {
|
|
590
|
+
removeRow(row);
|
|
591
|
+
if (msgKey !== undefined)
|
|
592
|
+
assistantRowsByStep.delete(msgKey);
|
|
593
|
+
}
|
|
594
|
+
else if (row !== undefined) {
|
|
595
|
+
if (msgKey !== undefined)
|
|
596
|
+
assistantRowsByStep.set(msgKey, row);
|
|
597
|
+
row.seq ??= event.seq;
|
|
598
|
+
row.time = event.time;
|
|
599
|
+
if (text || canonical)
|
|
600
|
+
row.text = text;
|
|
601
|
+
row.images = images.length === 0 ? undefined : images;
|
|
602
|
+
row.streaming = false;
|
|
603
|
+
// Live settles keep the smooth-reveal cursor alive (a one-shot
|
|
604
|
+
// non-streaming delivery still paints as a flow); replayed
|
|
605
|
+
// settles must not — the transcript would typewrite on open.
|
|
606
|
+
if (!replaying && text)
|
|
607
|
+
row.fresh = true;
|
|
608
|
+
touchRow(row);
|
|
609
|
+
}
|
|
610
|
+
streaming = undefined;
|
|
611
|
+
if (reasoning !== undefined) {
|
|
612
|
+
// Backstop fold: reasoning whose step ended with no text token
|
|
613
|
+
// and no tool call (foldLiveReasoning handles those earlier —
|
|
614
|
+
// while the block is still in the repaintable live window;
|
|
615
|
+
// here a long reply may already have pushed it into scrollback,
|
|
616
|
+
// where the shrink cannot be repainted). `full` mode
|
|
617
|
+
// (/settings opt-in) keeps the block expanded until turn settle
|
|
618
|
+
// — settleStreaming folds the sealed rows then.
|
|
619
|
+
reasoning.durationMs = Math.max(0, Date.now() - reasoningStart);
|
|
620
|
+
if (state.thinkingFold === 'preview')
|
|
621
|
+
reasoning.streaming = false;
|
|
622
|
+
touchRow(reasoning);
|
|
623
|
+
sealedReasoning.push(reasoning);
|
|
624
|
+
logForDebugging(`thinking: step sealed (${reasoning.durationMs}ms), expanded until turn/end`);
|
|
625
|
+
}
|
|
626
|
+
reasoning = undefined;
|
|
627
|
+
if (activeAttempt !== undefined && activeAttempt.turn === event.data.turn && activeAttempt.step === event.data.step)
|
|
628
|
+
activeAttempt = undefined;
|
|
629
|
+
updateSpinnerMode();
|
|
630
|
+
const usage = event.data.usage;
|
|
631
|
+
if (usage !== undefined) {
|
|
632
|
+
// oxlint-disable-next-line typescript/no-unnecessary-condition -- durable replay data may lack tokens
|
|
633
|
+
state.tokens.input += usage.inputTokens ?? 0;
|
|
634
|
+
// oxlint-disable-next-line typescript/no-unnecessary-condition -- durable replay data may lack tokens
|
|
635
|
+
state.tokens.output += usage.outputTokens ?? 0;
|
|
636
|
+
// Cache split totals feed the session cost estimate (hit-priced
|
|
637
|
+
// input vs. uncached input) — the durable replay may lack them.
|
|
638
|
+
state.tokens.cacheRead += usage.cacheReadTokens ?? 0;
|
|
639
|
+
state.tokens.cacheWrite += usage.cacheWriteTokens ?? 0;
|
|
640
|
+
// Peak/idle bucketing by the request's own time (the durable replay
|
|
641
|
+
// replays historical events, so a resumed session prices each
|
|
642
|
+
// request at the rate window it actually ran in — the session cost
|
|
643
|
+
// estimate never prices the whole session at the current window).
|
|
644
|
+
{
|
|
645
|
+
const bucket = isPeakHour(new Date(event.time))
|
|
646
|
+
? state.tokens.peak
|
|
647
|
+
: state.tokens.idle;
|
|
648
|
+
bucket.input += usage.inputTokens ?? 0;
|
|
649
|
+
bucket.output += usage.outputTokens ?? 0;
|
|
650
|
+
bucket.cacheRead += usage.cacheReadTokens ?? 0;
|
|
651
|
+
bucket.cacheWrite += usage.cacheWriteTokens ?? 0;
|
|
652
|
+
}
|
|
653
|
+
// The most recent request's usage describes the CURRENT context:
|
|
654
|
+
// input (uncached) + cache hits all occupy the window. Cache hits
|
|
655
|
+
// also drive the status-line `cache N` readout.
|
|
656
|
+
state.lastUsage = {
|
|
657
|
+
// oxlint-disable-next-line typescript/no-unnecessary-condition -- durable replay data may lack tokens
|
|
658
|
+
input: usage.inputTokens ?? 0,
|
|
659
|
+
// oxlint-disable-next-line typescript/no-unnecessary-condition -- durable replay data may lack tokens
|
|
660
|
+
output: usage.outputTokens ?? 0,
|
|
661
|
+
cacheRead: usage.cacheReadTokens ?? 0,
|
|
662
|
+
cacheWrite: usage.cacheWriteTokens ?? 0,
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
const tpsMessageStep = tpsStep;
|
|
666
|
+
if (tpsTurn === event.data.turn &&
|
|
667
|
+
tpsMessageStep !== undefined &&
|
|
668
|
+
tpsMessageStep.turn === event.data.turn &&
|
|
669
|
+
tpsMessageStep.step === event.data.step &&
|
|
670
|
+
tpsMessageStep.firstTokenTime !== undefined) {
|
|
671
|
+
const outputTokens = usageOutputTokens(usage)
|
|
672
|
+
?? (tpsMessageStep.outputChars > 0
|
|
673
|
+
? Math.ceil(tpsMessageStep.outputChars / 4)
|
|
674
|
+
: undefined);
|
|
675
|
+
if (outputTokens !== undefined) {
|
|
676
|
+
tpsTurnDecodeMs += Math.max(0, event.time - tpsMessageStep.firstTokenTime);
|
|
677
|
+
tpsTurnDecodeTokens += outputTokens;
|
|
678
|
+
tpsTurnSampled = true;
|
|
679
|
+
if (tpsTurnDecodeMs > 0) {
|
|
680
|
+
state.tps = tpsTurnDecodeTokens / (tpsTurnDecodeMs / 1000);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
if (tpsMessageStep !== undefined &&
|
|
685
|
+
tpsMessageStep.turn === event.data.turn &&
|
|
686
|
+
tpsMessageStep.step === event.data.step) {
|
|
687
|
+
tpsStep = undefined;
|
|
688
|
+
}
|
|
689
|
+
// Context-bar segmentation (pi-nano-context style): assistant text
|
|
690
|
+
// and tool calls in the assistant segment, thinking separately.
|
|
691
|
+
for (const block of event.data.message.content) {
|
|
692
|
+
if (block.type === 'text' && block.text) {
|
|
693
|
+
state.contextSegments.assistant += estimateTokens(block.text);
|
|
694
|
+
}
|
|
695
|
+
else if (block.type === 'reasoning' && block.text) {
|
|
696
|
+
state.contextSegments.thinking += estimateTokens(block.text);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
break;
|
|
700
|
+
}
|
|
701
|
+
case 'tool/call': {
|
|
702
|
+
// The ask-user-question tool renders as the interactive questionnaire
|
|
703
|
+
// panel (DSH user-interaction seam), not as a tool card: the model is
|
|
704
|
+
// parked waiting for the human, so no running card, no active-tool
|
|
705
|
+
// spinner, no args noise in the transcript. The Q&A summary is pushed
|
|
706
|
+
// by the TUI once the batch is answered; tool/result for a call with
|
|
707
|
+
// no card is a no-op below.
|
|
708
|
+
if (event.data.name === 'ask_user_question')
|
|
709
|
+
break;
|
|
710
|
+
// The Task tool's plain card is replaced by the live subagent card
|
|
711
|
+
// (Kimi Code semantics): the delegation itself renders as a subagent
|
|
712
|
+
// row, so the raw args/result card would only duplicate it. The call
|
|
713
|
+
// still runs - only its transcript rendering is suppressed.
|
|
714
|
+
if (isSubagentToolName(event.data.name)) {
|
|
715
|
+
try {
|
|
716
|
+
const args = JSON.parse(event.data.arguments);
|
|
717
|
+
if (typeof args.description === 'string' && args.description)
|
|
718
|
+
deps.pendingTaskDescriptions.push(args.description);
|
|
719
|
+
}
|
|
720
|
+
catch {
|
|
721
|
+
// Unparseable args leave the queue untouched; the card falls back
|
|
722
|
+
// to the provider label.
|
|
723
|
+
}
|
|
724
|
+
break;
|
|
725
|
+
}
|
|
726
|
+
// Reasoning that led to a tool call is done thinking — fold the
|
|
727
|
+
// preview now, before the tool card grows the transcript past it
|
|
728
|
+
// (see foldLiveReasoning).
|
|
729
|
+
foldLiveReasoning('tool call');
|
|
730
|
+
const card = {
|
|
731
|
+
id: deps.rowIds.value,
|
|
732
|
+
kind: 'tool',
|
|
733
|
+
text: '',
|
|
734
|
+
seq: event.seq,
|
|
735
|
+
// Smooth-reveal participation flag: live cards animate their body
|
|
736
|
+
// in; replayed cards (resume/rewind) paint complete.
|
|
737
|
+
fresh: !replaying,
|
|
738
|
+
tool: {
|
|
739
|
+
callId: event.data.callId,
|
|
740
|
+
name: event.data.name,
|
|
741
|
+
argsText: preview(event.data.arguments, ARGS_PREVIEW_LIMIT),
|
|
742
|
+
argsFull: event.data.arguments,
|
|
743
|
+
status: 'running',
|
|
744
|
+
callView: presentCallView(event.data.name, event.data.arguments),
|
|
745
|
+
startedAt: Date.now(),
|
|
746
|
+
},
|
|
747
|
+
};
|
|
748
|
+
deps.rowIds.value += 1;
|
|
749
|
+
toolCards.set(event.data.callId, card);
|
|
750
|
+
appendRow(card);
|
|
751
|
+
state.activeToolCount += 1;
|
|
752
|
+
state.contextSegments.assistant += estimateTokens(`${event.data.name}${event.data.arguments}`);
|
|
753
|
+
updateSpinnerMode();
|
|
754
|
+
break;
|
|
755
|
+
}
|
|
756
|
+
case 'tool/result': {
|
|
757
|
+
const card = toolCards.get(event.data.message.source.callId);
|
|
758
|
+
if (card !== undefined && card.tool !== undefined) {
|
|
759
|
+
const images = transcriptImages(event.data.message.content);
|
|
760
|
+
card.images = images.length === 0 ? undefined : images;
|
|
761
|
+
card.tool.durationMs = Math.max(0, Date.now() - card.tool.startedAt);
|
|
762
|
+
const failure = event.data.error;
|
|
763
|
+
if (failure !== undefined) {
|
|
764
|
+
card.tool.status = 'error';
|
|
765
|
+
const errorText = toolErrorText(event);
|
|
766
|
+
card.tool.errorText = errorText;
|
|
767
|
+
state.contextSegments.tools += estimateTokens(errorText);
|
|
768
|
+
}
|
|
769
|
+
else {
|
|
770
|
+
card.tool.status = 'ok';
|
|
771
|
+
const block = event.data.message.content[0];
|
|
772
|
+
// oxlint-disable-next-line typescript/no-unnecessary-condition -- durable session data may not match type
|
|
773
|
+
const result = block !== undefined && block.type === 'tool-result' ? textOf(block.content) : '';
|
|
774
|
+
card.tool.resultFull = result || undefined;
|
|
775
|
+
card.tool.resultText = result ? preview(result, RESULT_PREVIEW_LIMIT) : undefined;
|
|
776
|
+
// The tool's own settled-state view (applied diff, terminal
|
|
777
|
+
// output, read content…) wins over the raw text body. argsFull
|
|
778
|
+
// pairs the args: live cards are never folded, so it is intact.
|
|
779
|
+
card.tool.resultView = presentResultView(card.tool.name, card.tool.argsFull ?? '', event.data);
|
|
780
|
+
state.contextSegments.tools += estimateTokens(result);
|
|
781
|
+
// A job_output result doubles as the job card's output feed:
|
|
782
|
+
// the registry's read() is consuming and reserved for the
|
|
783
|
+
// owning agent, so the UI mirrors the tail that already streams
|
|
784
|
+
// through the transcript instead of polling the job itself.
|
|
785
|
+
if (card.tool.name === 'job_output' && result !== '') {
|
|
786
|
+
const id = parseJobOutputId(card.tool.argsFull);
|
|
787
|
+
if (id !== undefined)
|
|
788
|
+
deps.jobs.onOutputSeen(id, result, event.time ?? Date.now());
|
|
789
|
+
}
|
|
790
|
+
// A `started background job <id>` ack pairs the job with its
|
|
791
|
+
// tool call: capture the FULL command from the args (the
|
|
792
|
+
// registry label is the friendly description) for the panel.
|
|
793
|
+
const startAck = BACKGROUND_START_ACK.exec(result);
|
|
794
|
+
if (startAck !== null) {
|
|
795
|
+
const command = toolCommandOf(card.tool.argsFull);
|
|
796
|
+
if (command !== undefined)
|
|
797
|
+
deps.jobs.onStarted(startAck[1], command);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
state.activeToolCount = Math.max(0, state.activeToolCount - 1);
|
|
801
|
+
// The card is settled: no later event looks it up by callId, so
|
|
802
|
+
// drop the index entry. The card itself stays in state.rows
|
|
803
|
+
// (bounded by MAX_ROWS + foldRows, which also drops the full
|
|
804
|
+
// args/result payloads of folded cards).
|
|
805
|
+
toolCards.delete(event.data.message.source.callId);
|
|
806
|
+
touchRow(card);
|
|
807
|
+
updateSpinnerMode();
|
|
808
|
+
}
|
|
809
|
+
break;
|
|
810
|
+
}
|
|
811
|
+
case 'step/end': {
|
|
812
|
+
if (openStep !== undefined && openStep.turn === event.data.turn && openStep.step === event.data.step)
|
|
813
|
+
openStep = undefined;
|
|
814
|
+
if (tpsStep !== undefined &&
|
|
815
|
+
tpsStep.turn === event.data.turn &&
|
|
816
|
+
tpsStep.step === event.data.step) {
|
|
817
|
+
tpsStep = undefined;
|
|
818
|
+
}
|
|
819
|
+
break;
|
|
820
|
+
}
|
|
821
|
+
case 'turn/start': {
|
|
822
|
+
deps.inputConvergence.cancelInFlight = false;
|
|
823
|
+
state.cancelPending = false;
|
|
824
|
+
state.working = true;
|
|
825
|
+
state.turnStart = Date.now();
|
|
826
|
+
state.responseChars = 0;
|
|
827
|
+
state.spinnerMode = 'requesting';
|
|
828
|
+
// Keep the prior turn visible until this turn produces a measurable
|
|
829
|
+
// decode span, while starting a fresh weighted step fold.
|
|
830
|
+
tpsBeforeTurn = state.tps;
|
|
831
|
+
tpsTurn = event.data.turn;
|
|
832
|
+
tpsTurnDecodeMs = 0;
|
|
833
|
+
tpsTurnDecodeTokens = 0;
|
|
834
|
+
tpsTurnSampled = false;
|
|
835
|
+
tpsStep = undefined;
|
|
836
|
+
break;
|
|
837
|
+
}
|
|
838
|
+
case 'turn/end': {
|
|
839
|
+
if (activeAttempt !== undefined)
|
|
840
|
+
discardAttempt(activeAttempt.turn, activeAttempt.step);
|
|
841
|
+
openStep = undefined;
|
|
842
|
+
deps.inputConvergence.cancelInFlight = false;
|
|
843
|
+
state.cancelPending = false;
|
|
844
|
+
settleStreaming();
|
|
845
|
+
state.working = false;
|
|
846
|
+
state.activeToolCount = 0;
|
|
847
|
+
if (tpsTurn !== undefined && tpsTurn === event.data.turn) {
|
|
848
|
+
if (tpsTurnSampled && tpsTurnDecodeMs > 0) {
|
|
849
|
+
const turnTps = tpsTurnDecodeTokens / (tpsTurnDecodeMs / 1000);
|
|
850
|
+
state.tps = turnTps;
|
|
851
|
+
state.tpsSamples.push({ tps: turnTps, at: event.time });
|
|
852
|
+
if (state.tpsSamples.length > 500)
|
|
853
|
+
state.tpsSamples.shift();
|
|
854
|
+
}
|
|
855
|
+
else {
|
|
856
|
+
// Do not leave a chars/4 live estimate behind when no completed
|
|
857
|
+
// decode sample exists for this turn.
|
|
858
|
+
state.tps = tpsBeforeTurn;
|
|
859
|
+
}
|
|
860
|
+
tpsTurn = undefined;
|
|
861
|
+
tpsStep = undefined;
|
|
862
|
+
tpsTurnDecodeMs = 0;
|
|
863
|
+
tpsTurnDecodeTokens = 0;
|
|
864
|
+
tpsTurnSampled = false;
|
|
865
|
+
}
|
|
866
|
+
const reason = event.data.reason;
|
|
867
|
+
if (reason.kind === 'completed') {
|
|
868
|
+
deps.checkContextWarning();
|
|
869
|
+
break;
|
|
870
|
+
}
|
|
871
|
+
if (reason.kind === 'aborted' || reason.kind === 'interrupted') {
|
|
872
|
+
// `Agent.cancel()` closes the turn as `aborted`; `interrupted`
|
|
873
|
+
// only appears for crash-orphaned turns. Both user-interruption
|
|
874
|
+
// paths render as a distinct dim row.
|
|
875
|
+
appendRow({
|
|
876
|
+
id: deps.rowIds.value,
|
|
877
|
+
kind: 'interrupt',
|
|
878
|
+
text: t('interrupted-by-user') + t('interrupted-ask-next'),
|
|
879
|
+
});
|
|
880
|
+
deps.rowIds.value += 1;
|
|
881
|
+
break;
|
|
882
|
+
}
|
|
883
|
+
// The notice renders as a single-line Divider title: error.message
|
|
884
|
+
// can carry newlines/control chars, and an embedded \n splits the
|
|
885
|
+
// rule across rows. cleanRenderText is the render-path single-line
|
|
886
|
+
// contract (sessionTree's preview() folds likewise for the tree).
|
|
887
|
+
const detail = reason.kind === 'error' ? cleanRenderText(reason.error.message, NOTICE_CELLS) : '';
|
|
888
|
+
appendRow({ id: deps.rowIds.value, kind: 'notice', text: `turn ${reason.kind}${detail ? ` · ${detail}` : ''}` });
|
|
889
|
+
deps.rowIds.value += 1;
|
|
890
|
+
deps.notify(t('turn-failed', { detail: detail ? ` · ${detail}` : '' }), { color: 'error', timeoutMs: 8000 });
|
|
891
|
+
break;
|
|
892
|
+
}
|
|
893
|
+
case 'request/context':
|
|
894
|
+
// Adapter-advertised context capacity; drives the context-low
|
|
895
|
+
// warning when the route reports one.
|
|
896
|
+
if (event.data.contextWindow !== undefined) {
|
|
897
|
+
state.contextWindow = event.data.contextWindow;
|
|
898
|
+
}
|
|
899
|
+
break;
|
|
900
|
+
case 'system/message': {
|
|
901
|
+
// V3 system prompts are surface nodes, not header fields: the latest
|
|
902
|
+
// node holds the active instructions (an empty render clears them).
|
|
903
|
+
// The context bar's system segment tracks that live text.
|
|
904
|
+
state.contextSegments.system = estimateTokens(textOf(event.data.message.content));
|
|
905
|
+
break;
|
|
906
|
+
}
|
|
907
|
+
case 'request/header': {
|
|
908
|
+
// Reasoning effort readout (status line): the header carries the
|
|
909
|
+
// conversation's call config (provider/model/effort/sampling). The
|
|
910
|
+
// system prompt moved out of the header at V3 (see system/message);
|
|
911
|
+
// pre-V3 logs still carry it, admitted structurally below.
|
|
912
|
+
// oxlint-disable-next-line typescript/no-unnecessary-condition -- durable session data may lack header config
|
|
913
|
+
const effort = event.data.header.config?.reasoningEffort;
|
|
914
|
+
if (typeof effort === 'string') {
|
|
915
|
+
state.reasoningEffort = effort;
|
|
916
|
+
}
|
|
917
|
+
const legacySystem = event.data.header.system;
|
|
918
|
+
if (typeof legacySystem === 'string') {
|
|
919
|
+
state.contextSegments.system = estimateTokens(legacySystem);
|
|
920
|
+
}
|
|
921
|
+
break;
|
|
922
|
+
}
|
|
923
|
+
case 'session/title':
|
|
924
|
+
state.sessionTitle = event.data.title;
|
|
925
|
+
break;
|
|
926
|
+
default:
|
|
927
|
+
// Pre-0.1.5 live streams and raw pre-V3 logs carry per-token chunks
|
|
928
|
+
// as durable session events; 0.1.5 moved live chunks to transient
|
|
929
|
+
// `agent/assistant-stream` frames (renderStreamFrame) and compacts the
|
|
930
|
+
// durable record into `assistant/message.stream`. Match by name so the
|
|
931
|
+
// current union (which no longer lists the type) stays compile-clean.
|
|
932
|
+
if (event.type === 'assistant/chunk') {
|
|
933
|
+
if (handledAssistantChunks.has(event.seq))
|
|
934
|
+
break;
|
|
935
|
+
handledAssistantChunks.add(event.seq);
|
|
936
|
+
const data = event.data;
|
|
937
|
+
renderStreamChunk(data.turn, data.step, data.chunk, event.time, event.seq);
|
|
938
|
+
break;
|
|
939
|
+
}
|
|
940
|
+
// dsh-tool-todo owns this optional module augmentation in alpha.2.
|
|
941
|
+
// Match by name so the TUI remains loadable without that plugin.
|
|
942
|
+
if (event.type === 'todo/write') {
|
|
943
|
+
const todos = todoPanelItems(event.data);
|
|
944
|
+
if (todos !== undefined)
|
|
945
|
+
state.todos = todos;
|
|
946
|
+
break;
|
|
947
|
+
}
|
|
948
|
+
// Logged preset switch (blank sessions only, issue #8): a transcript
|
|
949
|
+
// marker so a replayed log shows which composition produced the
|
|
950
|
+
// turns after it. Not in dsh-session's typed union — matched here by
|
|
951
|
+
// name, like the other plugin-defined events above.
|
|
952
|
+
if (event.type === 'agent-preset/selected') {
|
|
953
|
+
const data = event.data;
|
|
954
|
+
const recordedPreset = typeof data.agentPreset === 'string' ? data.agentPreset : undefined;
|
|
955
|
+
const renamedOfficialPreset = (recordedPreset === 'code' && state.agentPreset === 'ptc') ||
|
|
956
|
+
(recordedPreset === 'ptc' && state.agentPreset === 'code');
|
|
957
|
+
const preset = renamedOfficialPreset && state.agentPreset !== undefined
|
|
958
|
+
? state.agentPreset
|
|
959
|
+
: recordedPreset ?? 'unknown';
|
|
960
|
+
appendRow({
|
|
961
|
+
id: deps.rowIds.value,
|
|
962
|
+
kind: 'notice',
|
|
963
|
+
text: t('agent-preset-switched', { preset }),
|
|
964
|
+
});
|
|
965
|
+
deps.rowIds.value += 1;
|
|
966
|
+
break;
|
|
967
|
+
}
|
|
968
|
+
// `/color` accent (dsh-tui plugin event, replayed on resume/rewind
|
|
969
|
+
// like session/title): last write wins, '' clears to the default.
|
|
970
|
+
if (event.type === 'session/color') {
|
|
971
|
+
const data = event.data;
|
|
972
|
+
state.sessionColor = typeof data.color === 'string' ? data.color : '';
|
|
973
|
+
break;
|
|
974
|
+
}
|
|
975
|
+
// Custom plugin events (tuiRenderers seam): a registered renderer
|
|
976
|
+
// maps the payload to text rows — title as a local row, body as
|
|
977
|
+
// preview-clipped local-output rows, same shape pushLocal uses.
|
|
978
|
+
// Runs on the live stream AND on replay (resume/rewind), so the
|
|
979
|
+
// projection must stay total; the runtime isolates renderer
|
|
980
|
+
// crashes per type.
|
|
981
|
+
if (deps.renderer !== undefined) {
|
|
982
|
+
const rendered = deps.renderer.render(event.type, event.data);
|
|
983
|
+
if (rendered !== undefined) {
|
|
984
|
+
if (rendered.title !== undefined && rendered.title !== '') {
|
|
985
|
+
appendRow({ id: deps.rowIds.value, kind: 'local', text: rendered.title });
|
|
986
|
+
deps.rowIds.value += 1;
|
|
987
|
+
}
|
|
988
|
+
for (const line of rendered.lines) {
|
|
989
|
+
appendRow({
|
|
990
|
+
id: deps.rowIds.value,
|
|
991
|
+
kind: 'local-output',
|
|
992
|
+
text: preview(String(line), LOCAL_OUTPUT_LIMIT),
|
|
993
|
+
});
|
|
994
|
+
deps.rowIds.value += 1;
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
break;
|
|
999
|
+
}
|
|
1000
|
+
};
|
|
1001
|
+
function reset() {
|
|
1002
|
+
streaming = undefined;
|
|
1003
|
+
reasoning = undefined;
|
|
1004
|
+
sealedReasoning.length = 0;
|
|
1005
|
+
lastReasoningRow = undefined;
|
|
1006
|
+
toolCards.clear();
|
|
1007
|
+
handledAssistantMessages.clear();
|
|
1008
|
+
handledAssistantChunks.clear();
|
|
1009
|
+
openStep = undefined;
|
|
1010
|
+
activeAttempt = undefined;
|
|
1011
|
+
lastStreamRevision = -1;
|
|
1012
|
+
assistantRowsByStep.clear();
|
|
1013
|
+
lastTextDelta.clear();
|
|
1014
|
+
tpsTurn = undefined;
|
|
1015
|
+
tpsStep = undefined;
|
|
1016
|
+
tpsTurnDecodeMs = 0;
|
|
1017
|
+
tpsTurnDecodeTokens = 0;
|
|
1018
|
+
tpsTurnSampled = false;
|
|
1019
|
+
}
|
|
1020
|
+
return { reset, replayEvents, renderEvent, renderStreamFrame, settleStreaming, updateSpinnerMode, presentCallView, presentResultView, textOf, firstTextOf };
|
|
1021
|
+
}
|