dsh-plugin-dev-kb 1.5.2 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/README.en.md +31 -9
- package/README.md +42 -14
- package/kb/INDEX.md +3 -3
- package/kb/README.md +9 -4
- package/kb/extra/AGENTS.md +1 -1
- package/kb/extra/cli-help.md +15 -7
- package/kb/extra/cli-help.zh.md +15 -7
- package/kb/extra/cookbook/adding-a-plugin-preview.md +18 -25
- package/kb/extra/cookbook/adding-a-plugin-preview.zh.md +18 -25
- package/kb/extra/cookbook/reviewing-persistence-type-changes.md +1 -1
- package/kb/extra/cookbook/reviewing-persistence-type-changes.zh.md +1 -1
- package/kb/extra/cookbook/reviewing-ui-design.md +166 -0
- package/kb/extra/cookbook/reviewing-ui-design.zh.md +166 -0
- package/kb/extra/deepseek-llm-api-wire-extensions.md +2 -2
- package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +2 -2
- package/kb/extra/defensive-patterns/conversation-and-session.md +2 -2
- package/kb/extra/defensive-patterns/conversation-and-session.zh.md +2 -2
- package/kb/extra/defensive-patterns/general.md +2 -0
- package/kb/extra/defensive-patterns/general.zh.md +2 -0
- package/kb/extra/defensive-patterns/package-surface.md +1 -0
- package/kb/extra/defensive-patterns/package-surface.zh.md +1 -0
- package/kb/extra/defensive-patterns/remote-and-api.md +5 -3
- package/kb/extra/defensive-patterns/remote-and-api.zh.md +5 -3
- package/kb/extra/development.md +16 -9
- package/kb/extra/development.zh.md +16 -9
- package/kb/extra/event-producer-consumer.md +64 -51
- package/kb/extra/event-producer-consumer.zh.md +64 -51
- package/kb/extra/i18n/README.md +2 -0
- package/kb/extra/i18n/README.zh.md +2 -0
- package/kb/extra/module-graph.md +204 -92
- package/kb/extra/module-graph.zh.md +204 -92
- package/kb/extra/persistence-changes/2026-10-13-liveshare-share-viewer-principal.md +60 -0
- package/kb/extra/persistence-changes/2026-10-13-liveshare-share-viewer-principal.zh.md +60 -0
- package/kb/extra/persistence-changes/2026-10-19-session-team-mode.md +48 -0
- package/kb/extra/persistence-changes/2026-10-19-session-team-mode.zh.md +48 -0
- package/kb/extra/persistence-changes/2026-10-22-action-card-status.md +60 -0
- package/kb/extra/persistence-changes/2026-10-22-action-card-status.zh.md +60 -0
- package/kb/extra/persistence-changes/2026-10-25-skill-catalog-incomplete.md +60 -0
- package/kb/extra/persistence-changes/2026-10-25-skill-catalog-incomplete.zh.md +60 -0
- package/kb/extra/persistence-changes/2026-10-27-retry-control-input.md +60 -0
- package/kb/extra/persistence-changes/2026-10-27-retry-control-input.zh.md +60 -0
- package/kb/extra/persistence-changes/2026-10-27-subagent-settlement-attribution.md +60 -0
- package/kb/extra/persistence-changes/2026-10-27-subagent-settlement-attribution.zh.md +60 -0
- package/kb/extra/persistence-changes/2026-11-02-subagent-catalog-names.md +48 -0
- package/kb/extra/persistence-changes/2026-11-02-subagent-catalog-names.zh.md +48 -0
- package/kb/extra/persistence-changes/2026-11-02-team-task-owner-names.md +48 -0
- package/kb/extra/persistence-changes/2026-11-02-team-task-owner-names.zh.md +48 -0
- package/kb/extra/persistence-changes/README.md +2 -0
- package/kb/extra/persistence-changes/README.zh.md +2 -0
- package/kb/extra/persistence-changes/historical-formats/README.md +1 -1
- package/kb/extra/persistence-changes/historical-formats/README.zh.md +1 -1
- package/kb/extra/rescope.md +7 -5
- package/kb/extra/rescope.zh.md +7 -5
- package/kb/extra/subsystems/agent-team.md +38 -75
- package/kb/extra/subsystems/agent-team.zh.md +38 -75
- package/kb/extra/subsystems/attachment.md +36 -13
- package/kb/extra/subsystems/attachment.zh.md +36 -13
- package/kb/extra/subsystems/boot.md +179 -5
- package/kb/extra/subsystems/boot.zh.md +179 -5
- package/kb/extra/subsystems/computer-use.md +78 -0
- package/kb/extra/subsystems/computer-use.zh.md +78 -0
- package/kb/extra/subsystems/deliverables.md +2 -0
- package/kb/extra/subsystems/deliverables.zh.md +2 -0
- package/kb/extra/subsystems/forge.md +1226 -0
- package/kb/extra/subsystems/forge.zh.md +1226 -0
- package/kb/extra/subsystems/liveshare.md +158 -0
- package/kb/extra/subsystems/liveshare.zh.md +158 -0
- package/kb/extra/subsystems/mcp.md +96 -1
- package/kb/extra/subsystems/mcp.zh.md +96 -1
- package/kb/extra/subsystems/worktrees.md +54 -3
- package/kb/extra/subsystems/worktrees.zh.md +54 -3
- package/kb/extra/testing.md +1 -1
- package/kb/extra/testing.zh.md +1 -1
- package/kb/extra/ui-design-review-cases.md +445 -0
- package/kb/extra/ui-design-review-cases.zh.md +445 -0
- package/kb/extra/ui-radius.md +3 -1
- package/kb/extra/ui-radius.zh.md +3 -1
- package/kb/extra/upgrade-guide/v0.2.1-alpha.1/team-direct-inbox/guide.md +1 -1
- package/kb/extra/upgrade-guide/v0.2.1-alpha.1/team-direct-inbox/guide.zh.md +1 -1
- package/kb/extra/upgrade-guide/v0.2.1-alpha.2/cordis-timer-wrappers/guide.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.1-alpha.2/cordis-timer-wrappers/guide.zh.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.1-alpha.2/plugin-manager-view-fields/guide.md +25 -0
- package/kb/extra/upgrade-guide/v0.2.1-alpha.2/plugin-manager-view-fields/guide.zh.md +25 -0
- package/kb/extra/upgrade-guide/v0.2.1-alpha.4/model-switch-compaction/guide.md +30 -0
- package/kb/extra/upgrade-guide/v0.2.1-alpha.4/model-switch-compaction/guide.zh.md +30 -0
- package/kb/extra/upgrade-guide/v0.2.1-alpha.4/session-model-selection/guide.md +28 -0
- package/kb/extra/upgrade-guide/v0.2.1-alpha.4/session-model-selection/guide.zh.md +28 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.1/agent-instructions-chain-budgets/guide.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.1/agent-instructions-chain-budgets/guide.zh.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.1/subagent-control-tools/guide.md +23 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.1/subagent-control-tools/guide.zh.md +23 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/agent-runtime-owner/guide.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/agent-runtime-owner/guide.zh.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/agent-team-subagents/guide.md +31 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/agent-team-subagents/guide.zh.md +31 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/approval-projection-dependency/guide.md +34 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/approval-projection-dependency/guide.zh.md +34 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/auto-review-shutdown/guide.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/auto-review-shutdown/guide.zh.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/auto-review-user-sources/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/auto-review-user-sources/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/conditional-tools/guide.md +25 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/conditional-tools/guide.zh.md +25 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/context-menu-services/guide.md +23 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/context-menu-services/guide.zh.md +23 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/cua-consent-storage/guide.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/cua-consent-storage/guide.zh.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/cua-preset-scope/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/cua-preset-scope/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/cua-relative-coordinates/guide.md +17 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/cua-relative-coordinates/guide.zh.md +17 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/file-drag-callbacks/guide.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/file-drag-callbacks/guide.zh.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/headless-policy-composition/guide.md +27 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/headless-policy-composition/guide.zh.md +27 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/model-badge-package-removal/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/model-badge-package-removal/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/new-session-blank-reuse/guide.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/new-session-blank-reuse/guide.zh.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/node-24/guide.md +17 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/node-24/guide.zh.md +17 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/official-bundle-lists/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/official-bundle-lists/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/persistent-terminal-controls/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/persistent-terminal-controls/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/pi-ai-default-capacities/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/pi-ai-default-capacities/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/pi-ai-model-catalog/guide.md +53 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/pi-ai-model-catalog/guide.zh.md +53 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/pi-ai-protocol-replay/guide.md +30 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/pi-ai-protocol-replay/guide.zh.md +30 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/ptc-script-format/guide.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/ptc-script-format/guide.zh.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/sdk-desktop-context/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/sdk-desktop-context/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/sdk-minimal-checkpoints/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/sdk-minimal-checkpoints/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/session-projection-handles/guide.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/session-projection-handles/guide.zh.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/session-store-writes/guide.md +25 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/session-store-writes/guide.zh.md +25 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/session-team-mode/guide.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/session-team-mode/guide.zh.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/subagent-activation-options/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/subagent-activation-options/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/subagent-service-methods/guide.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/subagent-service-methods/guide.zh.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/subagent-user-controls/guide.md +26 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/subagent-user-controls/guide.zh.md +26 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/tool-executor-plugins/guide.md +35 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/tool-executor-plugins/guide.zh.md +35 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/web-fetch-private-destinations/guide.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/web-fetch-private-destinations/guide.zh.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/webserver-index-peer/guide.md +17 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.2/webserver-index-peer/guide.zh.md +17 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/attachment-read-access/guide.md +23 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/attachment-read-access/guide.zh.md +23 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/computer-use-helper-permissions/guide.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/computer-use-helper-permissions/guide.zh.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/cua-bundle-id-consent/guide.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/cua-bundle-id-consent/guide.zh.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/generated-worktree-names/guide.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/generated-worktree-names/guide.zh.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/inbox-only-agent-wait/guide.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/inbox-only-agent-wait/guide.zh.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/independent-session-forks/guide.md +23 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/independent-session-forks/guide.zh.md +23 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/ptc-caller-cancellation/guide.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/ptc-caller-cancellation/guide.zh.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/session-follow-activation/guide.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/session-follow-activation/guide.zh.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/subagent-runtime-ownership/guide.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/subagent-runtime-ownership/guide.zh.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/team-mode-menu/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/team-mode-menu/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/team-projection/guide.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/team-projection/guide.zh.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/web-file-downloads/guide.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/web-file-downloads/guide.zh.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/web-search-defaults/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.3/web-search-defaults/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.4/model-listing-refresh/guide.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.4/model-listing-refresh/guide.zh.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.4/reasoning-body-props/guide.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.4/reasoning-body-props/guide.zh.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/context-menu-target/guide.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/context-menu-target/guide.zh.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/cordis-loader-entry-trees/guide.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/cordis-loader-entry-trees/guide.zh.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/css-anchored-menus/guide.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/css-anchored-menus/guide.zh.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/cua-source-dev-helper/guide.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/cua-source-dev-helper/guide.zh.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/desktop-stable-channel/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/desktop-stable-channel/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/forge-git-permissions/guide.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/forge-git-permissions/guide.zh.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/forge-worktree-entry/guide.md +29 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/forge-worktree-entry/guide.zh.md +29 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/fs-observation-policy-default-off/guide.md +29 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/fs-observation-policy-default-off/guide.zh.md +29 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/llm-request-purpose-declarations/guide.md +29 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/llm-request-purpose-declarations/guide.zh.md +29 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/pi-ai-request-image-count/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/pi-ai-request-image-count/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/projection-event-frames/guide.md +32 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/projection-event-frames/guide.zh.md +32 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/projection-released-checkpoint/guide.md +30 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/projection-released-checkpoint/guide.zh.md +30 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/projection-snapshot-scope/guide.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/projection-snapshot-scope/guide.zh.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/retained-ptc-timeout/guide.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/retained-ptc-timeout/guide.zh.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/schedule-agent-tools/guide.md +37 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/schedule-agent-tools/guide.zh.md +37 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/schedule-remote-host-tasks/guide.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/schedule-remote-host-tasks/guide.zh.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/sdk-run-commands/guide.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/sdk-run-commands/guide.zh.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/session-header-menu/guide.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/session-header-menu/guide.zh.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/subagent-explicit-reasoning/guide.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/subagent-explicit-reasoning/guide.zh.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/web-search-credential-modes/guide.md +17 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/web-search-credential-modes/guide.zh.md +17 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/web-search-default-provider/guide.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/web-search-default-provider/guide.zh.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.3/chat-process-activity-context/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.3/chat-process-activity-context/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.3/subagent-names/guide.md +29 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.3/subagent-names/guide.zh.md +29 -0
- package/kb/extra/web-styling.md +19 -1
- package/kb/extra/web-styling.zh.md +19 -1
- package/kb/meta/search-index.json +1272 -1098
- package/kb/meta/source.json +8 -4
- package/kb/site/develop/cordis-tutorial/04-events.md +1 -1
- package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +5 -4
- package/kb/site/develop/framework/events.md +1 -1
- package/kb/site/develop/practice/dynamic-cordis.md +1 -1
- package/kb/site/en/develop/cordis-tutorial/04-events.md +1 -1
- package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +5 -4
- package/kb/site/en/develop/framework/events.md +1 -1
- package/kb/site/en/develop/practice/dynamic-cordis.md +1 -1
- package/kb/site/en/guide/network-proxy.md +1 -1
- package/kb/site/en/guide/plugin-market.md +10 -10
- package/kb/site/en/guide/providers.md +5 -1
- package/kb/site/en/guide/python-sdk.md +17 -2
- package/kb/site/en/guide/schedule.md +45 -26
- package/kb/site/en/reference/agent-lifecycle.md +3 -1
- package/kb/site/en/reference/api-gateway.md +4 -4
- package/kb/site/en/reference/capability-seams.md +65 -17
- package/kb/site/en/reference/config-catalog.md +560 -238
- package/kb/site/en/reference/cookbook/adding-a-package.md +4 -2
- package/kb/site/en/reference/cookbook/extension-cookbook.md +1 -1
- package/kb/site/en/reference/cordis-api/context.md +1 -1
- package/kb/site/en/reference/cordis-api/events.md +9 -9
- package/kb/site/en/reference/cordis-api/fiber.md +85 -32
- package/kb/site/en/reference/cordis-api/inherited.md +10 -9
- package/kb/site/en/reference/experimental-persistence-catalog.md +3 -0
- package/kb/site/en/reference/index.md +14 -8
- package/kb/site/en/reference/persistence-catalog.md +532 -246
- package/kb/site/en/reference/subsystems/client-modules.md +19 -11
- package/kb/site/en/reference/subsystems/compaction.md +1 -1
- package/kb/site/en/reference/subsystems/conversation.md +2 -0
- package/kb/site/en/reference/subsystems/core.md +119 -65
- package/kb/site/en/reference/subsystems/filesystem.md +202 -28
- package/kb/site/en/reference/subsystems/index.md +3 -1
- package/kb/site/en/reference/subsystems/llm-streaming.md +92 -4
- package/kb/site/en/reference/subsystems/persistence.md +17 -7
- package/kb/site/en/reference/subsystems/plan.md +4 -4
- package/kb/site/en/reference/subsystems/ptc-runtime.md +12 -5
- package/kb/site/en/reference/subsystems/sandbox.md +11 -4
- package/kb/site/en/reference/subsystems/schedule.md +194 -430
- package/kb/site/en/reference/subsystems/session-projection.md +186 -44
- package/kb/site/en/reference/subsystems/session-reference.md +4 -3
- package/kb/site/en/reference/subsystems/session.md +119 -31
- package/kb/site/en/reference/subsystems/sidebar-right.md +12 -11
- package/kb/site/en/reference/subsystems/skills.md +4 -4
- package/kb/site/en/reference/subsystems/slots.md +30 -3
- package/kb/site/en/reference/subsystems/storage.md +26 -9
- package/kb/site/en/reference/subsystems/subagent.md +119 -102
- package/kb/site/en/reference/subsystems/system-prompt.md +13 -11
- package/kb/site/en/reference/subsystems/token-meter.md +45 -0
- package/kb/site/en/reference/subsystems/tools.md +222 -82
- package/kb/site/en/reference/subsystems/typert.md +21 -11
- package/kb/site/en/reference/subsystems/user-questions.md +22 -6
- package/kb/site/en/reference/subsystems/web-client.md +1 -1
- package/kb/site/en/reference/subsystems/web-server.md +68 -23
- package/kb/site/en/reference/subsystems/web.md +79 -21
- package/kb/site/en/reference/tool-catalog.md +270 -395
- package/kb/site/en/reference/tool-execution-pipeline.md +5 -4
- package/kb/site/guide/network-proxy.md +1 -1
- package/kb/site/guide/plugin-market.md +10 -10
- package/kb/site/guide/providers.md +5 -1
- package/kb/site/guide/python-sdk.md +17 -2
- package/kb/site/guide/schedule.md +45 -26
- package/kb/site/reference/agent-lifecycle.md +3 -1
- package/kb/site/reference/api-gateway.md +4 -4
- package/kb/site/reference/capability-seams.md +65 -17
- package/kb/site/reference/config-catalog.md +560 -238
- package/kb/site/reference/cookbook/adding-a-package.md +4 -2
- package/kb/site/reference/cookbook/extension-cookbook.md +1 -1
- package/kb/site/reference/cordis-api/context.md +1 -1
- package/kb/site/reference/cordis-api/events.md +9 -9
- package/kb/site/reference/cordis-api/fiber.md +87 -32
- package/kb/site/reference/cordis-api/inherited.md +10 -9
- package/kb/site/reference/experimental-persistence-catalog.md +3 -0
- package/kb/site/reference/index.md +14 -8
- package/kb/site/reference/persistence-catalog.md +532 -246
- package/kb/site/reference/subsystems/client-modules.md +19 -11
- package/kb/site/reference/subsystems/compaction.md +1 -1
- package/kb/site/reference/subsystems/conversation.md +4 -0
- package/kb/site/reference/subsystems/core.md +119 -65
- package/kb/site/reference/subsystems/filesystem.md +202 -28
- package/kb/site/reference/subsystems/index.md +3 -1
- package/kb/site/reference/subsystems/llm-streaming.md +92 -4
- package/kb/site/reference/subsystems/persistence.md +17 -7
- package/kb/site/reference/subsystems/plan.md +4 -4
- package/kb/site/reference/subsystems/ptc-runtime.md +12 -5
- package/kb/site/reference/subsystems/sandbox.md +11 -4
- package/kb/site/reference/subsystems/schedule.md +197 -433
- package/kb/site/reference/subsystems/session-projection.md +186 -44
- package/kb/site/reference/subsystems/session-reference.md +4 -3
- package/kb/site/reference/subsystems/session.md +119 -31
- package/kb/site/reference/subsystems/sidebar-right.md +12 -11
- package/kb/site/reference/subsystems/skills.md +4 -4
- package/kb/site/reference/subsystems/slots.md +30 -3
- package/kb/site/reference/subsystems/storage.md +26 -9
- package/kb/site/reference/subsystems/subagent.md +119 -102
- package/kb/site/reference/subsystems/system-prompt.md +13 -11
- package/kb/site/reference/subsystems/token-meter.md +45 -0
- package/kb/site/reference/subsystems/tools.md +222 -82
- package/kb/site/reference/subsystems/typert.md +21 -11
- package/kb/site/reference/subsystems/user-questions.md +22 -6
- package/kb/site/reference/subsystems/web-client.md +1 -1
- package/kb/site/reference/subsystems/web-server.md +68 -23
- package/kb/site/reference/subsystems/web.md +79 -21
- package/kb/site/reference/tool-catalog.md +273 -399
- package/kb/site/reference/tool-execution-pipeline.md +4 -3
- package/lib/index.js +268 -11
- package/lib/kb-search.js +261 -0
- package/lib/kb-version.js +118 -0
- package/package.json +5 -3
- package/scripts/refresh-kb.mjs +153 -0
- package/scripts/selfcheck.mjs +28 -0
- package/scripts/smoke.mjs +77 -0
- package/skills/dsh-plugin-dev-kb.md +8 -7
- package/skills/dsh-plugin-starter.md +65 -0
- package/skills/dsh-upgrade-assistant.md +62 -0
- package/kb/extra/agent-lifecycle.md +0 -91
- package/kb/extra/agent-lifecycle.zh.md +0 -93
- package/kb/extra/api-gateway.md +0 -172
- package/kb/extra/api-gateway.zh.md +0 -178
- package/kb/extra/architecture.md +0 -165
- package/kb/extra/architecture.zh.md +0 -169
- package/kb/extra/capability-seams.md +0 -714
- package/kb/extra/capability-seams.zh.md +0 -716
- package/kb/extra/config-catalog.md +0 -4801
- package/kb/extra/config-catalog.zh.md +0 -4803
- package/kb/extra/cookbook/adding-a-package.md +0 -170
- package/kb/extra/cookbook/adding-a-package.zh.md +0 -170
- package/kb/extra/cookbook/adding-a-settings-card.md +0 -72
- package/kb/extra/cookbook/adding-a-settings-card.zh.md +0 -72
- package/kb/extra/cookbook/adding-a-tool.md +0 -101
- package/kb/extra/cookbook/adding-a-tool.zh.md +0 -103
- package/kb/extra/cookbook/adding-an-llm-adapter.md +0 -43
- package/kb/extra/cookbook/adding-an-llm-adapter.zh.md +0 -43
- package/kb/extra/cookbook/extension-cookbook.md +0 -132
- package/kb/extra/cookbook/extension-cookbook.zh.md +0 -136
- package/kb/extra/cordis-api/context.md +0 -364
- package/kb/extra/cordis-api/context.zh.md +0 -366
- package/kb/extra/cordis-api/events.md +0 -207
- package/kb/extra/cordis-api/events.zh.md +0 -209
- package/kb/extra/cordis-api/fiber.md +0 -375
- package/kb/extra/cordis-api/fiber.zh.md +0 -377
- package/kb/extra/cordis-api/inherited.md +0 -38
- package/kb/extra/cordis-api/registry.md +0 -152
- package/kb/extra/cordis-api/registry.zh.md +0 -154
- package/kb/extra/cordis-api/service.md +0 -102
- package/kb/extra/cordis-api/service.zh.md +0 -104
- package/kb/extra/cordis-tutorial/01-first-plugin.md +0 -95
- package/kb/extra/cordis-tutorial/01-first-plugin.zh.md +0 -95
- package/kb/extra/cordis-tutorial/02-lifecycle-and-effects.md +0 -98
- package/kb/extra/cordis-tutorial/02-lifecycle-and-effects.zh.md +0 -98
- package/kb/extra/cordis-tutorial/03-services.md +0 -98
- package/kb/extra/cordis-tutorial/03-services.zh.md +0 -98
- package/kb/extra/cordis-tutorial/04-events.md +0 -144
- package/kb/extra/cordis-tutorial/04-events.zh.md +0 -144
- package/kb/extra/cordis-tutorial/05-config.md +0 -111
- package/kb/extra/cordis-tutorial/05-config.zh.md +0 -111
- package/kb/extra/cordis-tutorial/06-composition-and-hmr.md +0 -113
- package/kb/extra/cordis-tutorial/06-composition-and-hmr.zh.md +0 -113
- package/kb/extra/cordis-tutorial/07-into-the-harness.md +0 -108
- package/kb/extra/cordis-tutorial/07-into-the-harness.zh.md +0 -108
- package/kb/extra/cordis-tutorial/index.md +0 -60
- package/kb/extra/cordis-tutorial/index.zh.md +0 -62
- package/kb/extra/experimental-persistence-catalog.md +0 -17
- package/kb/extra/experimental-persistence-catalog.zh.md +0 -17
- package/kb/extra/persistence-catalog.md +0 -9140
- package/kb/extra/persistence-catalog.zh.md +0 -9142
- package/kb/extra/subsystems/README.md +0 -76
- package/kb/extra/subsystems/README.zh.md +0 -76
- package/kb/extra/subsystems/approval.md +0 -170
- package/kb/extra/subsystems/approval.zh.md +0 -170
- package/kb/extra/subsystems/client-modules.md +0 -198
- package/kb/extra/subsystems/client-modules.zh.md +0 -198
- package/kb/extra/subsystems/client-resources.md +0 -92
- package/kb/extra/subsystems/client-resources.zh.md +0 -92
- package/kb/extra/subsystems/commands.md +0 -223
- package/kb/extra/subsystems/commands.zh.md +0 -223
- package/kb/extra/subsystems/compaction.md +0 -284
- package/kb/extra/subsystems/compaction.zh.md +0 -284
- package/kb/extra/subsystems/conversation.md +0 -301
- package/kb/extra/subsystems/conversation.zh.md +0 -303
- package/kb/extra/subsystems/core.md +0 -1113
- package/kb/extra/subsystems/core.zh.md +0 -1125
- package/kb/extra/subsystems/credentials.md +0 -493
- package/kb/extra/subsystems/credentials.zh.md +0 -493
- package/kb/extra/subsystems/filesystem.md +0 -530
- package/kb/extra/subsystems/filesystem.zh.md +0 -530
- package/kb/extra/subsystems/goal.md +0 -313
- package/kb/extra/subsystems/goal.zh.md +0 -313
- package/kb/extra/subsystems/jobs.md +0 -554
- package/kb/extra/subsystems/jobs.zh.md +0 -554
- package/kb/extra/subsystems/llm-streaming.md +0 -1196
- package/kb/extra/subsystems/llm-streaming.zh.md +0 -1202
- package/kb/extra/subsystems/lsp.md +0 -202
- package/kb/extra/subsystems/lsp.zh.md +0 -202
- package/kb/extra/subsystems/permission-presets.md +0 -167
- package/kb/extra/subsystems/permission-presets.zh.md +0 -167
- package/kb/extra/subsystems/persistence.md +0 -418
- package/kb/extra/subsystems/persistence.zh.md +0 -418
- package/kb/extra/subsystems/plan.md +0 -87
- package/kb/extra/subsystems/plan.zh.md +0 -87
- package/kb/extra/subsystems/ptc-runtime.md +0 -250
- package/kb/extra/subsystems/ptc-runtime.zh.md +0 -250
- package/kb/extra/subsystems/sandbox.md +0 -221
- package/kb/extra/subsystems/sandbox.zh.md +0 -221
- package/kb/extra/subsystems/schedule.md +0 -550
- package/kb/extra/subsystems/schedule.zh.md +0 -550
- package/kb/extra/subsystems/scope.md +0 -59
- package/kb/extra/subsystems/scope.zh.md +0 -61
- package/kb/extra/subsystems/session-projection.md +0 -356
- package/kb/extra/subsystems/session-projection.zh.md +0 -356
- package/kb/extra/subsystems/session-query.md +0 -511
- package/kb/extra/subsystems/session-query.zh.md +0 -511
- package/kb/extra/subsystems/session-reference.md +0 -224
- package/kb/extra/subsystems/session-reference.zh.md +0 -224
- package/kb/extra/subsystems/session-telemetry.md +0 -212
- package/kb/extra/subsystems/session-telemetry.zh.md +0 -212
- package/kb/extra/subsystems/session-title.md +0 -213
- package/kb/extra/subsystems/session-title.zh.md +0 -213
- package/kb/extra/subsystems/session.md +0 -1339
- package/kb/extra/subsystems/session.zh.md +0 -1343
- package/kb/extra/subsystems/settings.md +0 -155
- package/kb/extra/subsystems/settings.zh.md +0 -155
- package/kb/extra/subsystems/shell.md +0 -314
- package/kb/extra/subsystems/shell.zh.md +0 -314
- package/kb/extra/subsystems/sidebar-right.md +0 -160
- package/kb/extra/subsystems/sidebar-right.zh.md +0 -160
- package/kb/extra/subsystems/skills.md +0 -352
- package/kb/extra/subsystems/skills.zh.md +0 -352
- package/kb/extra/subsystems/slots.md +0 -200
- package/kb/extra/subsystems/slots.zh.md +0 -204
- package/kb/extra/subsystems/spill.md +0 -124
- package/kb/extra/subsystems/spill.zh.md +0 -124
- package/kb/extra/subsystems/storage.md +0 -259
- package/kb/extra/subsystems/storage.zh.md +0 -259
- package/kb/extra/subsystems/subagent.md +0 -686
- package/kb/extra/subsystems/subagent.zh.md +0 -688
- package/kb/extra/subsystems/subprocess.md +0 -321
- package/kb/extra/subsystems/subprocess.zh.md +0 -321
- package/kb/extra/subsystems/system-prompt.md +0 -254
- package/kb/extra/subsystems/system-prompt.zh.md +0 -254
- package/kb/extra/subsystems/terminal.md +0 -184
- package/kb/extra/subsystems/terminal.zh.md +0 -184
- package/kb/extra/subsystems/token-meter.md +0 -106
- package/kb/extra/subsystems/token-meter.zh.md +0 -106
- package/kb/extra/subsystems/tools.md +0 -747
- package/kb/extra/subsystems/tools.zh.md +0 -747
- package/kb/extra/subsystems/typert.md +0 -690
- package/kb/extra/subsystems/typert.zh.md +0 -690
- package/kb/extra/subsystems/user-questions.md +0 -307
- package/kb/extra/subsystems/user-questions.zh.md +0 -307
- package/kb/extra/subsystems/web-client.md +0 -100
- package/kb/extra/subsystems/web-client.zh.md +0 -100
- package/kb/extra/subsystems/web-server.md +0 -302
- package/kb/extra/subsystems/web-server.zh.md +0 -302
- package/kb/extra/subsystems/web.md +0 -206
- package/kb/extra/subsystems/web.zh.md +0 -206
- package/kb/extra/subsystems/workflow.md +0 -278
- package/kb/extra/subsystems/workflow.zh.md +0 -278
- package/kb/extra/subsystems/workspace.md +0 -647
- package/kb/extra/subsystems/workspace.zh.md +0 -647
- package/kb/extra/tool-catalog.md +0 -2824
- package/kb/extra/tool-catalog.zh.md +0 -2832
- package/kb/extra/tool-execution-pipeline.md +0 -65
- package/kb/extra/tool-execution-pipeline.zh.md +0 -67
|
@@ -69,8 +69,10 @@ interface SessionEventMap {
|
|
|
69
69
|
* The rendered system prompt on the model-visible surface. The loop appends
|
|
70
70
|
* the first one as surface node 0 before the step's first `user/message`.
|
|
71
71
|
* A prepared in-history route can append nonempty changes in a continuing
|
|
72
|
-
* series. An incapable route or new series
|
|
73
|
-
*
|
|
72
|
+
* series. An incapable route, or a new series whose effective text differs,
|
|
73
|
+
* normalizes text to the first system node; a series start whose latest
|
|
74
|
+
* surviving node already holds the rendering leaves it in place.
|
|
75
|
+
* Normalization empties nonempty later nodes, then rewrites the head if
|
|
74
76
|
* needed, through logged per-node replacements. An empty rendering always
|
|
75
77
|
* clears all active system nodes, leaving no older instructions model-visible.
|
|
76
78
|
* Empty later nodes are dormant and project to no message; an empty head with
|
|
@@ -582,6 +584,9 @@ declare class Session {
|
|
|
582
584
|
* the log, the append is committed: observer failures are logged and
|
|
583
585
|
* contained per listener, so they do not change the return value or prevent
|
|
584
586
|
* later listeners from observing the same accepted event.
|
|
587
|
+
* Independent Sessions append without notifying store observers. Once a store
|
|
588
|
+
* prepares or enters the instance, writes require a completed creation
|
|
589
|
+
* announcement and remain disabled after removal.
|
|
585
590
|
*
|
|
586
591
|
* @param type - The event type (key of {@link SessionEventMap}).
|
|
587
592
|
* @param data - The event payload; must be JSON-serializable.
|
|
@@ -597,7 +602,9 @@ declare class Session {
|
|
|
597
602
|
* @returns the logged event — its assigned `seq`/`time` plus the SNAPSHOT of
|
|
598
603
|
* `data` that entered the log, so reading `event.data` back sees the logged
|
|
599
604
|
* value, never the caller's still-mutable input.
|
|
600
|
-
* @throws if
|
|
605
|
+
* @throws if a store-owned Session is unentered or its creation announcement
|
|
606
|
+
* has not completed, or if `data` or surface
|
|
607
|
+
* metadata is not losslessly JSON-serializable
|
|
601
608
|
* (BigInt, function, symbol, undefined, negative zero, non-finite number,
|
|
602
609
|
* circular reference, sparse array, or an exotic object such as
|
|
603
610
|
* Map/Set/Date/class instance), or when the candidate violates the
|
|
@@ -682,7 +689,7 @@ Everything else (`turn/*`, `step/*`, `assistant/attempt`, plugin-owned `llm/retr
|
|
|
682
689
|
|
|
683
690
|
`ctx.sessions.create(id, { seed, meta })` is the low-level replay/fork primitive. For ordinary live-session forks, `SessionStore` exposes one policy API:
|
|
684
691
|
|
|
685
|
-
- `fork(source, boundary?, childSessionId?)` accepts a live `Session` object or live `SessionId`, selects source events through the inclusive `SessionSeq` boundary (default: current last event),
|
|
692
|
+
- `fork(source, boundary?, childSessionId?)` accepts a live `Session` object or live `SessionId`, selects source events through the inclusive `SessionSeq` boundary (default: current last event), closes any open tail, then creates an independent live session with deep-cloned seed events, `isSeeded: true`, the exact `inheritedEventCount`, and inherited `cwd`, without `parentSession`.
|
|
686
693
|
|
|
687
694
|
An explicit `boundary` lets callers fork from any stable between-turn position, including a previous `turn/end` or a later standalone log-only event, even if the source has newer events or an open current turn. The API rejects a prefix that ends inside an open turn instead of clipping silently. `dsh-subagent-fork-in-process` keeps its completed-prefix clipping because tool-time delegation usually starts while the parent turn is open; ordinary session branching should make the requested boundary explicit.
|
|
688
695
|
|
|
@@ -707,8 +714,9 @@ interface TurnEndReasonMap {
|
|
|
707
714
|
blocked: { kind: 'blocked' }
|
|
708
715
|
/**
|
|
709
716
|
* The turn failed. `error` is always a structured failure: the `LlmError`
|
|
710
|
-
* facts verbatim, or `{ message: errorChain(error), code
|
|
711
|
-
*
|
|
717
|
+
* facts verbatim, or `{ message: errorChain(error), code }` flattened from
|
|
718
|
+
* any other error, where `code` is `TOOL_ACTIVATION_FAILED` for a failed
|
|
719
|
+
* tool condition and `UNKNOWN` otherwise.
|
|
712
720
|
*/
|
|
713
721
|
error: { kind: 'error'; error: LlmFailure }
|
|
714
722
|
/** At least one step reached its output-token ceiling, even if a plugin continued the turn. */
|
|
@@ -813,6 +821,29 @@ The backends that consume this contract are on [persistence.md](./persistence.md
|
|
|
813
821
|
|
|
814
822
|
The optional `application` selects a registered file handler without changing the system default; `workspacePathApplications({ path })` returns current handlers, names, icons, and default selection after Host path verification.
|
|
815
823
|
|
|
824
|
+
## Session-log upload exclusions
|
|
825
|
+
|
|
826
|
+
`ctx.sessionLogDeepSeek.registerExclusion()` registers a caller-owned predicate over `SessionLogUploadRequest`. Any match omits the log contribution and its acceptance callback before reading Session events. No match preserves normal upload eligibility. The [package README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-log-deepseek/README.md#upload-exclusions) defines failure and disposal behavior.
|
|
827
|
+
|
|
828
|
+
```ts type-equiv
|
|
829
|
+
/** Request identity inspected before preparing a Session-log contribution. */
|
|
830
|
+
interface SessionLogUploadRequest {
|
|
831
|
+
/** Live Session whose canonical log would be contributed. */
|
|
832
|
+
readonly sessionId: SessionId
|
|
833
|
+
/** Auxiliary request classification; absent for ordinary conversation requests. */
|
|
834
|
+
readonly purpose?: string
|
|
835
|
+
}
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
```ts type-equiv
|
|
839
|
+
/**
|
|
840
|
+
* Synchronous, side-effect-free upload exclusion owned by its registering plugin.
|
|
841
|
+
* @param request - request identity; the predicate must not mutate it.
|
|
842
|
+
* @returns `true` to omit the log field and acceptance callback, or `false` to keep checking eligibility.
|
|
843
|
+
*/
|
|
844
|
+
type SessionLogUploadExclusion = (request: SessionLogUploadRequest) => boolean
|
|
845
|
+
```
|
|
846
|
+
|
|
816
847
|
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
|
817
848
|
|
|
818
849
|
<a id="cordis-surface"></a>
|
|
@@ -835,14 +866,6 @@ Host service backing the generated `ctx.remote.session` namespace.
|
|
|
835
866
|
*/
|
|
836
867
|
resolveAgent(sessionId: SessionId): Promise<ApiSessionAgentResult>
|
|
837
868
|
|
|
838
|
-
/**
|
|
839
|
-
* Inspect one attached or persisted Session without activating its Agent.
|
|
840
|
-
* @param sessionId - durable Session identity.
|
|
841
|
-
* @param signal - optional caller cancellation for persistence reads.
|
|
842
|
-
* @returns the current attached state or persisted header and event prefix.
|
|
843
|
-
*/
|
|
844
|
-
inspect( sessionId: SessionId, signal?: AbortSignal, ): Promise<SessionInspection>
|
|
845
|
-
|
|
846
869
|
/**
|
|
847
870
|
* Read all visible Session rows without resuming an Agent.
|
|
848
871
|
* @param _request - reserved empty list request.
|
|
@@ -942,8 +965,8 @@ workspaceDesktop(): { name: string; available: boolean; fileManager: 'finder' |
|
|
|
942
965
|
@Remote('prompt') async prompt(request: SessionPromptRequest, signal: AbortSignal): Promise<SessionPromptValue>
|
|
943
966
|
|
|
944
967
|
/**
|
|
945
|
-
* Read one image
|
|
946
|
-
* @param request -
|
|
968
|
+
* Read one image from the attachment store after gateway authorization.
|
|
969
|
+
* @param request - image reference and gateway permission scope; Session existence is not checked.
|
|
947
970
|
* @returns the durable attachment reference and base64-encoded bytes.
|
|
948
971
|
*/
|
|
949
972
|
@Remote('attachment') attachment(request: SessionAttachmentRequest): Promise<SessionAttachmentValue>
|
|
@@ -964,11 +987,51 @@ workspaceDesktop(): { name: string; available: boolean; fileManager: 'finder' |
|
|
|
964
987
|
|
|
965
988
|
/**
|
|
966
989
|
* Read one cold-safe, message-aligned Session history page.
|
|
967
|
-
* @param request - durable address, backward cursor, and page budget.
|
|
990
|
+
* @param request - durable address, optional fixed cut, backward cursor, and page budget.
|
|
968
991
|
* @param signal - cancellation for persistence reads.
|
|
969
|
-
* @returns one chronological page.
|
|
992
|
+
* @returns one chronological page with its inclusive cursor.
|
|
993
|
+
*/
|
|
994
|
+
@Remote events(request: SessionPageRequest, signal: AbortSignal): Promise<SessionEventsPage>
|
|
995
|
+
|
|
996
|
+
/**
|
|
997
|
+
* Subscribe to Session events without reading a snapshot.
|
|
998
|
+
* @param request - Session address.
|
|
999
|
+
* @param signal - subscription cancellation.
|
|
1000
|
+
* @returns readiness and subsequent events, without a snapshot.
|
|
1001
|
+
*/
|
|
1002
|
+
@Remote({ mode: 'stream' }) observeEvent(request: SessionObserveEventRequest, signal: AbortSignal): AsyncIterable<SessionEventFrame>
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* Subscribe to Session projection changes.
|
|
1006
|
+
* @param request - target Session.
|
|
1007
|
+
* @param signal - subscription cancellation.
|
|
1008
|
+
* @returns readiness followed by one projection change frame per committed event.
|
|
1009
|
+
*/
|
|
1010
|
+
@Remote({ mode: 'stream' }) observeProjections(request: SessionProjectionsRequest, signal: AbortSignal): AsyncIterable<SessionProjectionFrame>
|
|
1011
|
+
|
|
1012
|
+
/**
|
|
1013
|
+
* Read passive Session state.
|
|
1014
|
+
* @param request - target Session.
|
|
1015
|
+
* @param signal - read cancellation.
|
|
1016
|
+
* @returns current passive state.
|
|
1017
|
+
*/
|
|
1018
|
+
@Remote state(request: SessionStateRequest, signal: AbortSignal): Promise<SessionState>
|
|
1019
|
+
|
|
1020
|
+
/**
|
|
1021
|
+
* Subscribe to complete Session state replacements.
|
|
1022
|
+
* @param request - target Session.
|
|
1023
|
+
* @param signal - subscription cancellation.
|
|
1024
|
+
* @returns complete passive state replacements.
|
|
1025
|
+
*/
|
|
1026
|
+
@Remote({ mode: 'stream' }) observeState(request: SessionStateRequest, signal: AbortSignal): AsyncIterable<SessionState>
|
|
1027
|
+
|
|
1028
|
+
/**
|
|
1029
|
+
* Wait for Session quiescence or pending input with bounded assistant output.
|
|
1030
|
+
* @param request - Session, wait bounds and output window.
|
|
1031
|
+
* @param signal - caller cancellation.
|
|
1032
|
+
* @returns stopping state and bounded assistant output.
|
|
970
1033
|
*/
|
|
971
|
-
@Remote
|
|
1034
|
+
@Remote wait(request: SessionWaitRequest, signal: AbortSignal): Promise<SessionWaitValue>
|
|
972
1035
|
|
|
973
1036
|
/**
|
|
974
1037
|
* Follow one Session log from its opening or resume cursor.
|
|
@@ -977,7 +1040,7 @@ workspaceDesktop(): { name: string; available: boolean; fileManager: 'finder' |
|
|
|
977
1040
|
* @returns a complete opening snapshot followed by gap-free durable event
|
|
978
1041
|
* frames and optional cursorless assistant-stream frames.
|
|
979
1042
|
*/
|
|
980
|
-
@Remote({ mode: 'stream'
|
|
1043
|
+
@Remote({ mode: 'stream' }) follow(request: SessionFollowRequest, signal: AbortSignal): AsyncIterable<SessionFollowFrame>
|
|
981
1044
|
|
|
982
1045
|
/**
|
|
983
1046
|
* Read exact projections, returning cached hints only when migration is required.
|
|
@@ -985,7 +1048,7 @@ workspaceDesktop(): { name: string; available: boolean; fileManager: 'finder' |
|
|
|
985
1048
|
* @param signal - cancellation for the Session read.
|
|
986
1049
|
* @returns a sequenced baseline, cached hints when migration is deferred, or null when absent.
|
|
987
1050
|
*/
|
|
988
|
-
@Remote('projections')
|
|
1051
|
+
@Remote('projections') projections(request: SessionProjectionsRequest, signal: AbortSignal): Promise<SessionProjectionsValue>
|
|
989
1052
|
|
|
990
1053
|
/**
|
|
991
1054
|
* Stream a complete live-control baseline followed by replacement frames.
|
|
@@ -995,10 +1058,30 @@ workspaceDesktop(): { name: string; available: boolean; fileManager: 'finder' |
|
|
|
995
1058
|
@Remote({ mode: 'stream' }) async *control(signal: AbortSignal): AsyncIterable<SessionControlFrame>
|
|
996
1059
|
```
|
|
997
1060
|
|
|
998
|
-
Types: [SessionId](./core.md) · [
|
|
1061
|
+
Types: [SessionId](./core.md) · [SessionSearchRequest](./session-query.md)
|
|
999
1062
|
|
|
1000
1063
|
Source: [`packages/api/session-controller/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/session-controller/src/index.ts)
|
|
1001
1064
|
|
|
1065
|
+
<a id="ctxsessionlogdeepseek--sessionlogdeepseekservice"></a>
|
|
1066
|
+
|
|
1067
|
+
### `ctx.sessionLogDeepSeek` — `SessionLogDeepSeekService`
|
|
1068
|
+
|
|
1069
|
+
Incremental Session-log contributor with caller-owned upload exclusions.
|
|
1070
|
+
|
|
1071
|
+
```ts cordis-catalog
|
|
1072
|
+
/**
|
|
1073
|
+
* Exclude matching requests before reading or preparing their log contribution.
|
|
1074
|
+
* Any matching rule suppresses both the field and its acceptance callback. With
|
|
1075
|
+
* no matching rules, normal upload eligibility applies. A throwing rule fails
|
|
1076
|
+
* this contribution; the request-extension registry omits it and reports the error.
|
|
1077
|
+
* @param exclude - synchronous, side-effect-free predicate; `true` skips this upload.
|
|
1078
|
+
* @returns effect disposer that removes this registration when called or when the caller unloads.
|
|
1079
|
+
*/
|
|
1080
|
+
registerExclusion(exclude: SessionLogUploadExclusion): () => Promise<void>
|
|
1081
|
+
```
|
|
1082
|
+
|
|
1083
|
+
Source: [`packages/session/session-log-deepseek/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/session/session-log-deepseek/src/index.ts)
|
|
1084
|
+
|
|
1002
1085
|
<a id="ctxsessions--sessionstore"></a>
|
|
1003
1086
|
|
|
1004
1087
|
### `ctx.sessions` — `SessionStore`
|
|
@@ -1054,7 +1137,7 @@ create(id?: SessionId, options?: CreateSessionOptions): Session
|
|
|
1054
1137
|
* `eventState`, every seed event is either independently owned or any
|
|
1055
1138
|
* shared value is deeply frozen; {@link Session.fromRestore} validates and
|
|
1056
1139
|
* adopts those values without copying or freezing them.
|
|
1057
|
-
* @returns the
|
|
1140
|
+
* @returns the store-owned session, not yet entered and read-only until announced.
|
|
1058
1141
|
* @throws if a session with `id` already exists, metadata is not a plain
|
|
1059
1142
|
* lossless-JSON record with valid scalar fields, or `meta.cwd` is a
|
|
1060
1143
|
* non-absolute path.
|
|
@@ -1062,8 +1145,9 @@ create(id?: SessionId, options?: CreateSessionOptions): Session
|
|
|
1062
1145
|
prepare(id?: SessionId, options?: PrepareSessionOptions): Session
|
|
1063
1146
|
|
|
1064
1147
|
/**
|
|
1065
|
-
* Enter a
|
|
1066
|
-
* append publication hooks and add it to the store.
|
|
1148
|
+
* Enter a session into the store: install the module-private
|
|
1149
|
+
* append publication hooks and add it to the store. Writes remain disabled
|
|
1150
|
+
* until {@link announce} completes successfully. Returns the DETACH
|
|
1067
1151
|
* disposer (hooks + store removal). Does NOT emit `session/created` —
|
|
1068
1152
|
* the caller yields this disposer inside its effect and THEN calls
|
|
1069
1153
|
* {@link announce}, so a throwing `session/created` listener rolls the attach
|
|
@@ -1077,7 +1161,7 @@ prepare(id?: SessionId, options?: PrepareSessionOptions): Session
|
|
|
1077
1161
|
* the two back-to-back so they never trip this, but the public API cannot
|
|
1078
1162
|
* assume that.
|
|
1079
1163
|
*
|
|
1080
|
-
* @param session -
|
|
1164
|
+
* @param session - an unentered session; independent instances become store-owned.
|
|
1081
1165
|
* @returns the detach disposer (publication hooks + store removal). When called from
|
|
1082
1166
|
* a synchronous `session/created` listener, removal and disposal wait until
|
|
1083
1167
|
* that creation dispatch unwinds.
|
|
@@ -1088,7 +1172,9 @@ enter(session: Session): () => void
|
|
|
1088
1172
|
/** Emit `session/created` exactly once for an {@link enter}ed session (with
|
|
1089
1173
|
* the carrier {@link enter} captured). Separate from {@link enter} so the
|
|
1090
1174
|
* caller can yield the detach disposer first (rollback safety — see
|
|
1091
|
-
* {@link enter}).
|
|
1175
|
+
* {@link enter}). The Session remains read-only throughout synchronous
|
|
1176
|
+
* dispatch; successful completion enables appends. A failed announcement
|
|
1177
|
+
* leaves it read-only and cannot be retried.
|
|
1092
1178
|
* @param session - the entered session to announce to listeners.
|
|
1093
1179
|
* @throws if the session is not live or its announcement already began,
|
|
1094
1180
|
* including a reentrant call from a creation listener. */
|
|
@@ -1123,7 +1209,7 @@ get(id: SessionId): Session | undefined
|
|
|
1123
1209
|
list(): Session[]
|
|
1124
1210
|
|
|
1125
1211
|
/**
|
|
1126
|
-
* Create
|
|
1212
|
+
* Create an independent live session from an exact prefix of a live source.
|
|
1127
1213
|
* `boundary` is an inclusive source event seq; omitted means the source's
|
|
1128
1214
|
* current last event. An open tail receives synthetic tool results and
|
|
1129
1215
|
* step/turn closers with the forked cause. Closed steps and turns remain
|
|
@@ -1254,12 +1340,14 @@ Source: [`packages/api/session-controller/src/types.ts`](https://github.com/deep
|
|
|
1254
1340
|
|
|
1255
1341
|
#### `session/created` — emit
|
|
1256
1342
|
|
|
1257
|
-
|
|
1343
|
+
Read-only creation announcement after store entry. New events reject until every synchronous listener has returned successfully. A synchronous throw vetoes creation and rolls back with a paired disposal; detach requested during dispatch is deferred. A returned-promise rejection is logged but cannot retroactively veto this synchronous boundary. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only sessions entered through that agent's context.
|
|
1258
1344
|
|
|
1259
1345
|
```ts cordis-catalog
|
|
1260
1346
|
/**
|
|
1261
|
-
*
|
|
1262
|
-
*
|
|
1347
|
+
* Read-only creation announcement after store entry.
|
|
1348
|
+
* New events reject until every synchronous listener has returned successfully.
|
|
1349
|
+
* A synchronous throw vetoes creation and rolls back with a paired disposal;
|
|
1350
|
+
* detach requested during dispatch is deferred.
|
|
1263
1351
|
* A returned-promise rejection is logged but cannot retroactively veto this
|
|
1264
1352
|
* synchronous boundary.
|
|
1265
1353
|
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners
|
|
@@ -48,7 +48,7 @@ Tab identity is the pair `(kind, address)`: the registry's claim uses the addres
|
|
|
48
48
|
| `canOpen(address)` | Optional synchronous veto of a glob match; it runs on every routing decision. |
|
|
49
49
|
| `title(address)` | The chip's text, captured into the layout record when the tab opens and never rewritten. |
|
|
50
50
|
| `keepMounted` | Optional lazy retention of visited bodies across hiding, Session switches and docking; the owning View holds the Session reference. |
|
|
51
|
-
| `guide` |
|
|
51
|
+
| `guide` | An **array** of entry boxes for the guide page: `[{ id, order, title(), description?(), icon? }, …]` — each entry carries its own `id` (the registry checks entries for duplicates). Picking a box opens the contributing type as a page; omit (or pass an empty array) to stay off the page. ⚠️ Passing a single object throws "entries.map is not a function" (the client entry fails into FAILED → the web boot gate refuses to start) — the 0.2.x live contract is an array; do not use the legacy single-object form. Local fix (2026-11-08, verified on dsh 0.2.1-rc.3; a later upstream `npm run refresh-kb` sync may overwrite this line). |
|
|
52
52
|
|
|
53
53
|
Whole-address patterns match the raw address: picomatch globstar (`**`) excludes standalone `.` and `..` segments even with `dot: true`, which includes dotfiles but does not change that exclusion. Resource-specific code parses addresses; the Host enforces file-read permissions.
|
|
54
54
|
|
|
@@ -79,22 +79,23 @@ export function apply(ctx: Context): void {
|
|
|
79
79
|
|
|
80
80
|
## Navigation: `ctx.sidebarRight`
|
|
81
81
|
|
|
82
|
-
Two opens are the navigation controller, and every way into the column calls one of them: `openResource(address, options?)` for a `dsh-resource://` address — the conversation's file links, a tool row's line reference, a file tree's rows — and `openTab(kind, options?)` for a page — the strip's add control, a guide entry box, or an HTTP(S) link in Assistant Markdown. Both run four steps as one history entry — claim (the registry ranks the resource's types, or the named `kind`'s implementation in force answers); focus a tab already showing the same `(kind, address)`; otherwise seat a new tab; expand the column — and then record the navigation in the Tab domain ([service](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#ctxsidebarright)). Content the user cannot see is not opened, so a collapsed column expands in the same step. `openResource` throws for an address outside `dsh-resource://` or one no type claims; `openTab` throws for a kind nothing registered: both are wiring mistakes, not user errors.
|
|
82
|
+
Two opens are the navigation controller, and every way into the column calls one of them: `openResource(address, options?)` for a `dsh-resource://` address — the conversation's file links, a tool row's line reference, a file tree's rows — and `openTab(kind, options?)` for a page — the strip's add control, a guide entry box, or an HTTP(S) link in Assistant Markdown. Both run four steps as one history entry — claim (the registry ranks the resource's types, or the named `kind`'s implementation in force answers); focus a tab already showing the same `(kind, address)`; otherwise seat a new tab; expand the column — and then record the navigation in the Tab domain ([service](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#ctxsidebarright)). Content the user cannot see is not opened, so a collapsed column expands in the same step, unless the open replaces a floating tab or reveals a tab in a floating panel. A reveal of a tab already on screen makes the pane holding it glow once, for every tab type, and only while its Session is on screen; a reveal that switches tabs or expands the column does not glow. `openResource` throws for an address outside `dsh-resource://` or one no type claims; `openTab` throws for a kind nothing registered: both are wiring mistakes, not user errors.
|
|
83
83
|
|
|
84
84
|
| Option | Meaning |
|
|
85
85
|
|---|---|
|
|
86
86
|
| `paneId` | Land a new tab in this pane; default is the active docked pane (the first docked pane while a floating pane is active). |
|
|
87
|
-
| `replaceTab` |
|
|
87
|
+
| `replaceTab` | New content takes this tab's place and the tab closes in the same step: a docked tab's pane and strip slot, or a floating tab's panel, keeping its pane id and rectangle. A reveal keeps the tab open ([semantics](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#ctxsidebarright)). |
|
|
88
88
|
| `revealIfOpened` | Default `true`: a tab already showing the same `(kind, address)` is focused and handed `params`. `false` opens another tab regardless. |
|
|
89
89
|
| `preferNewPane` | Prefer a new docked pane under the normal pane budget and room rule; fall back to the target pane when it cannot split. Ignored with `replaceTab`. |
|
|
90
|
+
| `destination` (`openResource` only) | `'sidebar'` or `'float'`: settle in the active docked pane (the first docked pane while a floating pane is active) or a new floating panel, ignoring the four options above. A copy already there is revealed; else a copy in the other host moves there with its tab id and body state; else a new tab opens. `'float'` leaves the column's expansion unchanged, for a new tab as for a move ([semantics](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#ctxsidebarright)). |
|
|
90
91
|
| `kind` (`openResource` only) | Name the opening type instead of ranking claims; its implementation in force opens the address, and its `canOpen` still applies. |
|
|
91
92
|
| `params` | Navigation parameters for the body, delivered as `navigation.params`. `openResource` types them by resource type through the merge-extensible `SidebarRightResourceParamsMap` (the text preview declares `{ line?: number }`); `openTab<K>` types them by kind through `SidebarRightTabParamsMap`, `undefined` for a kind that declares none; a body reads `SidebarRightNavigationParams`, the union of both. Values are JSON-shaped by convention and not validated at run time. |
|
|
92
93
|
|
|
93
|
-
Placement
|
|
94
|
+
Placement belongs to the caller, not the tab type. The [files navigator reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-files/README.md#the-navigator) defines its host-owned opening callbacks; the [guide reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#the-guide) defines guide replacement and explicit close.
|
|
94
95
|
|
|
95
|
-
`close(tabId)` closes a tab; `active()` returns the active pane's active tab; `isExpanded()` and `toggleExpanded()` read and flip the column, the flip recorded in the sequence. Reads answer for the no-Session case with `undefined` or `false`; writes need a mounted Session surface and throw without one rather than write into a surface nobody draws.
|
|
96
|
+
`close(tabId)` closes a tab; `hide(tabId)` closes a floating tab or collapses its docked column; `active()` returns the active pane's active tab; `isExpanded()` and `toggleExpanded()` read and flip the column, the flip recorded in the sequence. Reads answer for the no-Session case with `undefined` or `false`; writes need a mounted Session surface and throw without one rather than write into a surface nobody draws.
|
|
96
97
|
|
|
97
|
-
`focus(tabId)` makes a tab its pane's active tab; `split(paneId?)` splits the active docked pane, or the named one, and returns the new pane's id — or `undefined`, recording nothing, when the pane budget or the column's width forbids a split; `float(tabId, rect?)` lifts a tab into a floating pane; `dock(paneId)` returns a floating pane to the docked area. All four run the store's existing actions and record one history entry each; a target that does not exist or is already in the requested state is a no-op, and like `open` they throw without a mounted Session surface. `TabId`, `PaneId`, `TabRecord`, and `FloatRect` are re-exported from the package's `/client` entry so a caller needs no dockkit import.
|
|
98
|
+
`focus(tabId)` makes a tab its pane's active tab; `split(paneId?)` splits the active docked pane, or the named one, and returns the new pane's id — or `undefined`, recording nothing, when the pane budget or the column's width forbids a split; `float(tabId, rect?)` lifts a tab into a floating pane; `dock(paneId)` returns a floating pane to the docked area and expands the column. All four run the store's existing actions and record one history entry each; a target that does not exist or is already in the requested state is a no-op, and like `open` they throw without a mounted Session surface. `TabId`, `PaneId`, `TabRecord`, and `FloatRect` are re-exported from the package's `/client` entry so a caller needs no dockkit import.
|
|
98
99
|
|
|
99
100
|
`focusedTarget(element?)` captures the visible page under live DOM focus, including an embedding iframe; outside or stale sidebar markup yields no target. `commandTarget(element?)` also permits the mounted Session's active dock pane for an open initiated outside the sidebar. A `SidebarRightTarget` captures Session, pane, host, tab occurrence, and navigation revision. `isTargetCurrent(target)` checks that identity before execution, so reopening a record or navigating it invalidates a captured action; it never retargets to another page. See the [controller methods](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/src/client/service.ts) for close and placement outcomes.
|
|
100
101
|
|
|
@@ -110,9 +111,9 @@ The Sidebar declares four extension slots; its document tab declares the additio
|
|
|
110
111
|
| `sidebar.right.tab.menu.item` | list, Session scope | Content-level actions appended after the kit's own layout actions. An item that acts must call the owner's `dismiss()`. |
|
|
111
112
|
| `sidebar.right.tab.document` | keyed by the document implementation's `id`, Session scope | The selected file renderer inside the document tab; the parent owns shared loading and toolbar controls. |
|
|
112
113
|
|
|
113
|
-
A body, title and guide replacement receive the framework-injected `useTabInfo()`. It returns `{ sidebar, panel, tab }`: `sidebar` holds `expanded` and `fullscreen`, `panel.id` names the containing pane
|
|
114
|
+
A body, title and guide replacement receive the framework-injected `useTabInfo()`. It returns `{ sidebar, panel, tab }`: `sidebar` holds `expanded` and `fullscreen`, `panel.id` names the containing pane and the required `panel.isFloating: boolean` distinguishes a floating panel from a docked pane. Both update through the hook when a tab moves, while `tab.id` stays unchanged. `tab` also contains its other record fields plus `visible`, `navigation`, `signal`, and `actions`. All tabs require a foreground Session. Docked bodies also require expansion and selection; docked titles require expansion; foreground floats survive collapse. `signal` aborts when the record disappears or the plugin unloads, not on hiding or Session switching. `tab.actions` provides `openResource`, `openTab`, and `close`, bound to the tab's own Session. Opens return `void` and default to its current docked pane, or the active docked pane when this tab floats; `revealIfOpened` defaults to `true`, and `replaceTab: true` lets new content replace this record in the same history entry; an `openResource` with `destination` passes neither this tab's pane nor this record. Menu entries retain plain `tab` and `dismiss` owner parameters.
|
|
114
115
|
|
|
115
|
-
`navigation.revision` increments on every navigation to the tab whether or not `params` changed, so a body can act on "navigated again" alone; it is `1` for a tab opened by address and `0` for a record nobody opened by address — a seeded guide, or a tab restored by undo. The Tab domain holds one occurrence per open record: a record that appears is pinned in the resource model, so switching tabs unmounts a body without dropping its content; a record that vanishes is aborted and dropped; a record restored by undo is a new occurrence ([Tab domain](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#the-tab-domain)).
|
|
116
|
+
`navigation.revision` increments on every navigation to the tab whether or not `params` changed, so a body can act on "navigated again" alone; it is `1` for a tab opened by address and `0` for a record nobody opened by address — a seeded guide, or a tab restored by reload or undo. The Tab domain holds one occurrence per open record: a record that appears is pinned in the resource model, so switching tabs unmounts a body without dropping its content; a record that vanishes is aborted and dropped; a record restored by undo is a new occurrence ([Tab domain](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#the-tab-domain)).
|
|
116
117
|
|
|
117
118
|
`tab.actions.bindCommands(commands)` contributes `SidebarRightTabCommands`, currently an optional `refresh` callback, for the mounted body. Omitted operations are unavailable; the returned disposer releases that registration without removing a newer body's commands. The tab lifetime also releases them. `tab.refreshShortcut` supplies the effective refresh catalog entry for page controls; it is optional when no entry is available. These fields are declared in the [slot owner types](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/src/client/contract/slots.ts).
|
|
118
119
|
|
|
@@ -145,15 +146,15 @@ The Host `ctx.workspaceFiles` service and generated `workspaceFiles` Remote name
|
|
|
145
146
|
## Shipped types
|
|
146
147
|
|
|
147
148
|
- **`guide`** — `builtin`, opened as `openTab('guide')`. A muted compass sits above one capsule per contributed `guide` entry, in `order`; short lists show registered descriptions, and every missing icon uses the shipped placeholder. Picking a capsule opens the contributing type as a page in the guide tab's place. A pane holds at most one guide tab, and the strip's add control appears only while its pane has none. A new pane receives the registered default page: the sole guide entry directly, or the guide when the entry count is not one ([guide](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#the-guide)).
|
|
148
|
-
- **`text`** — `fallback`, `dsh-resource://file/**`, claiming Session addresses only. Document Preview observes metadata through `useResource<'file'>`, loads content through Remote callbacks, and owns renderer selection, the toolbar, per-tab refresh, scroll, and source navigation; unknown extensions render as plain text ([README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-documentpreview/README.md)).
|
|
149
|
-
- **`files`** — `builtin`, opened as `openTab('files')`. The
|
|
149
|
+
- **`text`** — `fallback`, `dsh-resource://file/**`, claiming Session addresses only. Document Preview observes metadata through `useResource<'file'>`, loads content through Remote callbacks, and owns renderer selection, the toolbar, per-tab refresh, scroll, and source navigation; unknown extensions render as plain text. It directly renders the files plugin's `sidebar.files.navigator` and `sidebar.files.navigator.toggle` Factories in docked and floating panes; unregistered Factories render nothing ([README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-documentpreview/README.md)).
|
|
150
|
+
- **`files`** — `builtin`, opened as `openTab('files')`. The files page and navigator share one workspace tree per pane. [The package reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-files/README.md) owns lazy listings, watches, opening callbacks, and navigation-driven visibility.
|
|
150
151
|
- **`browser`** — multi-instance `builtin`, opened as `openTab('browser', { params: { url? } })`. Chat's [link preference](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-chat/README.md) controls whether Assistant Markdown opens HTTP(S) links here. It accepts public and loopback HTTP(S) targets under the default sandbox, rejects local files in favor of Document Preview, and uses application-known iframe history ([README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-browser/README.md)).
|
|
151
152
|
- **`subagentchat`** — `builtin`, `dsh-resource://subagentchat/session/<child>?parent=<parent>&mode=<mode>`. An explicitly addressed subagent Conversation retained by the resource provider and rendered through the shared Conversation Factory ([README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-subagent/README.md)).
|
|
152
153
|
|
|
153
154
|
<a id="not-built"></a>
|
|
154
155
|
## Not built
|
|
155
156
|
|
|
156
|
-
-
|
|
157
|
+
- Cross-device layout synchronization: layouts are browser-local, with separate saved state per Session ([state](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#state)).
|
|
157
158
|
- A read-only layout snapshot or subscription on `ctx.sidebarRight`: the service exposes operations only, and dockkit's `LayoutState`/`LayoutOp` are internal.
|
|
158
159
|
- A capability-discovery array (`features`) on the service.
|
|
159
160
|
- An `option` priority band for tab types: nothing lists a tab type without letting it claim.
|
|
@@ -78,7 +78,7 @@ The shipped local provider scans roots in rank order:
|
|
|
78
78
|
| 500 | `user-agents` | `<agentsHome>/skills` |
|
|
79
79
|
| 600 | `bundled` | `Config.bundledSkillDir` when configured |
|
|
80
80
|
|
|
81
|
-
The project root is the nearest ancestor containing `.git`; without one, the current cwd is used. When `ctx.fs` is available, the git-root walk probes `.git` through the filesystem service so remote or sandboxed workspaces do not fall back to the host filesystem boundary. The user DSH root skips its `.system` child. The local provider does not synthesize built-in system skills; deployments supply packaged skills through configured bundled roots or dedicated providers.
|
|
81
|
+
The project root is the nearest ancestor containing `.git`; without one, the current cwd is used. When `ctx.fs` is available, the git-root walk probes `.git` through the filesystem service so remote or sandboxed workspaces do not fall back to the host filesystem boundary. The user DSH root skips its `.system` child. The local provider does not synthesize built-in system skills; deployments supply packaged skills through configured bundled roots or dedicated providers. A failed root contributes no candidates, so a lower-priority same-name skill from another root may supply both the catalog description and loaded body until recovery.
|
|
82
82
|
|
|
83
83
|
`dsh-skill-badge` registers one immutable `bundled` candidate at `BUNDLED_SKILL_RANK` and exposes its packaged asset directory through `resourceBase`. The shipped CLI declares the plugin disabled, so enabling its composition row is an explicit opt-in.
|
|
84
84
|
|
|
@@ -131,7 +131,7 @@ interface SkillSummary {
|
|
|
131
131
|
|
|
132
132
|
`ctx.skills.list()` preserves all four policy combinations. `isModelInvocable(skill)` and `isUserInvocable(skill)` read the corresponding required field. A model-only skill sets `{ modelInvocable: true, userInvocable: false }`, a user-only skill sets `{ modelInvocable: false, userInvocable: true }`, and setting both fields to `false` keeps the skill available only through trusted `ctx.skills.get()` callers. The local provider reads the exact kebab-case frontmatter keys `disable-model-invocation` and `user-invocable`, defaults omitted fields to `true`, and projects every parsed skill into this normalized policy.
|
|
133
133
|
|
|
134
|
-
`SkillCatalogSnapshot` distinguishes authoritative absence from transient provider failure or a catalog that kept changing during discovery. `skills` contains the sorted invocation-neutral summaries collected in that observation; `complete` is true only when every registered provider completed without a concurrent catalog revision. Incomplete snapshots are not cached,
|
|
134
|
+
`SkillCatalogSnapshot` distinguishes authoritative absence from transient provider failure or a catalog that kept changing during discovery. `skills` contains the sorted invocation-neutral summaries collected in that observation; `complete` is true only when every registered provider completed without a concurrent catalog revision. Incomplete snapshots are not cached, so the next lookup retries discovery; each consumer decides how to present the partial result.
|
|
135
135
|
|
|
136
136
|
```ts type-equiv
|
|
137
137
|
/** One catalog observation plus whether discovery completed within a stable catalog revision. */
|
|
@@ -230,9 +230,9 @@ interface Config {
|
|
|
230
230
|
|
|
231
231
|
## Session catalog and tool contract
|
|
232
232
|
|
|
233
|
-
`dsh-tool-skill` injects the initial durable user-role `<system-reminder>` at the first `agent/pre-step` of a live session that observes
|
|
233
|
+
`dsh-tool-skill` injects the initial durable user-role `<system-reminder>` at the first `agent/pre-step` of a live session that observes available skills or incomplete discovery. The catalog contains sorted skill `name` and normalized, XML-escaped `description` only; it omits bodies, paths, sources, providers, and routing hints. Discovery forwards the step's abort signal through `SkillLookupOptions`. `catalogDescriptionMaxLength` is the consumer config for the description bound, with default `500` and integer minimum `3`.
|
|
234
234
|
|
|
235
|
-
Before each later model step, the consumer applies exact tool visibility and
|
|
235
|
+
Before each later model step, the consumer applies exact tool visibility and compares the entries and completeness with the newest recognizable visible catalog message in the session log. A changed observation contributes a durable replacement to the pre-step decision; deleting every skill appends an explicit empty replacement. Incomplete discovery publishes the available subset with a warning and optional `incomplete: true` source metadata; absence of that flag means complete. Recovery republishes the catalog even when its entries are unchanged. If compaction hides every historical catalog message, the next observation re-establishes the current catalog; a complete empty view with no prior catalog emits nothing. These catalog messages are session history, not World State.
|
|
236
236
|
|
|
237
237
|
The model-facing `skill({ name })` tool validates the kebab-case name, finds the summary in the invocation-neutral catalog, rejects it before loading unless `isModelInvocable` permits access, then rereads the complete definition for the calling agent cwd and rechecks the policy before returning content. It reports an unresolved skill as unknown or no longer available and returns a tool result containing `<skill_content name="...">`, `<skill_resources>`, and `<skill_instructions>`. `resourceBase` resolves explicitly referenced scripts, references, and assets only as needed; the loaded result does not enumerate a skill directory. Body-only edits therefore change later tool calls without producing catalog messages or rewriting earlier tool results.
|
|
238
238
|
|
|
@@ -14,6 +14,12 @@ This page documents slot ownership, component inputs, extension APIs, and the sh
|
|
|
14
14
|
|
|
15
15
|
The plugin catalog declares `plugins.add.actions`, a root-scoped list for `MenuItemButton` rows after installation in the Add plugin menu. Its owner supplies `onDismiss()` to close the menu before starting an action. The slot follows the owning Plugins page declaration lifetime.
|
|
16
16
|
|
|
17
|
+
The root-scoped lists `sidebar.panellist.actions`, `conversation.session.header.views.actions`, and `sidebar.right.tab.guide.actions` supply the rows of the More menus after the panel rows, the View tabs, and the right-sidebar guide cards. A region draws its More button and menu only while its list has registrations, and passes the customizable entries with their pin state, `onOpen`, `onPinnedChange`, and `onDismiss`. Panel and View entries also carry optional `active` state for the current selection, independently of pin state. The `sidebar.panel.icon` root-scoped factory owns the `sidebar.panellist` list and renders its registered icon by `id`, `size`, and `active` for both sidebar rows and More entries. Each region keeps its own unpinned entry ids in memory; [`ui-entry-customization`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-entry-customization/README.md) registers the shipped rows.
|
|
18
|
+
|
|
19
|
+
[ui-workspace](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-workspace/README.md#understand-the-implementation) documents Session-row extension positions, visibility, and keyboard behavior.
|
|
20
|
+
|
|
21
|
+
[ui-settings](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-settings/README.md#filling-the-settings-slots) documents the settings page and navigation-icon extension points.
|
|
22
|
+
|
|
17
23
|
## Declaration and lifecycle
|
|
18
24
|
|
|
19
25
|
`SlotMap` is the compile-time registry. A package declaration-merges the key, cardinality, scope, owner props, keyed props, and optional slot-level inject face. The runtime declaration is the matching `children` entry on the component that owns the render location.
|
|
@@ -59,11 +65,24 @@ The slot declaration fixes two independent axes.
|
|
|
59
65
|
| cardinality | `list` | Cells are addressed by required `id` and ordered by `order`, then registration order. |
|
|
60
66
|
| cardinality | `keyed` | The owner dispatches an `entryKey`; the matching cell renders with any key-specific props. |
|
|
61
67
|
| cardinality | `chain` | Each entry supplies a pure `select(owner)` function. The first non-null result in priority order renders and receives that result as `matched`; otherwise the owner fallback renders. |
|
|
68
|
+
| cardinality | `hoc` | Entries nest around the owner's `renderSlot(key, owner, { children })` content, lowest outermost; see [Hoc layers](#hoc-layers). |
|
|
62
69
|
| scope | `root` | One root-scoped component and store instance. |
|
|
63
70
|
| scope | `session-maybe` | Inherits the surrounding Provider binding but stays renderable without one; Session values are optional. |
|
|
64
71
|
| scope | `session` | Requires a resolved surrounding Provider binding and receives definite Session values. |
|
|
65
72
|
|
|
66
|
-
`priority` is a shadowing rank for `single`, `list`, and `
|
|
73
|
+
`priority` is a shadowing rank for `single`, `list`, `keyed`, and `hoc` cells and an election order for `chain`. Lower values run or render first. Ordinary additive contributions should choose a fresh list or hoc `id`, or keyed `key`; intentionally reusing a shipped cell replaces its presentation.
|
|
74
|
+
|
|
75
|
+
<a id="hoc-layers"></a>
|
|
76
|
+
|
|
77
|
+
### Hoc layers
|
|
78
|
+
|
|
79
|
+
A hoc entry is a layer addressed by its required `id`. Layers nest by ascending `order`, then `priority`, then registration order, lowest outermost. Each layer receives the same owner props plus the next inner layer as `children`, the owner's content at the innermost, and renders it exactly once; owner props must not use the name `children`. Omitted `children` renders the layers around nothing, and with no live layer the content renders unchanged.
|
|
80
|
+
|
|
81
|
+
- Remounting: adding or removing a layer remounts the content inside it, including a crashed layer leaving the slot; a `session` or `session-maybe` layer also remounts it when its Session binding changes.
|
|
82
|
+
- Errors: a crashed layer renders its `children` and leaves the slot. An error thrown by the wrapped content passes every layer and is reported against none; a layer that wraps its `children` in its own error boundary catches it as an internal wrapper error rather than the original.
|
|
83
|
+
- Layout: the outlet inserts a `display: contents` `[data-slot]` element between the owner and its content, so owner selectors cannot rely on the content being a direct child. A layer must not create a box of its own — for example, use `display: contents` — or the content leaves its parent's layout.
|
|
84
|
+
|
|
85
|
+
The [context-menu plugin](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-context-menu/README.md) contributes `useContextMenu` through `provideRoot`; every scope receives the same plugin-owned trigger factory. Its prop and retained handlers retire when the provider unloads. Its root-scoped keyed `contextMenu.icon` Slot renders business-owned icons from action metadata.
|
|
67
86
|
|
|
68
87
|
## Component inputs
|
|
69
88
|
|
|
@@ -77,6 +96,7 @@ A registered component receives inputs assembled at its binding site. Components
|
|
|
77
96
|
| private data, callbacks, and observable hooks | the registration's `inject` factory | `InjectFace<I>` |
|
|
78
97
|
| localized `t` function | the registration's `locale` namespace | `PropsLocale<N>` |
|
|
79
98
|
| selected chain value | the registration's `select` result | `matched` through `ComposedProps` |
|
|
99
|
+
| wrapped owner content | the `SlotMap` row's `hoc` kind | `children` through `ComposedProps` |
|
|
80
100
|
|
|
81
101
|
`SessionProvider` is also present in `PropsRenderSlots` when an entry declares a `session` or `session-maybe` child. With no `session` prop it inherits the surrounding binding; an explicit `SessionReference` or `undefined` overrides only that subtree. The Provider does not key its whole body. A strict `session` entry remounts when its binding generation changes. A blank `session-maybe` entry adopts its first binding without remounting, then remounts for a later generation or a return to absence.
|
|
82
102
|
|
|
@@ -129,6 +149,7 @@ root [AppFrame]
|
|
|
129
149
|
│ ├─ conversation.session.header.lineage
|
|
130
150
|
│ ├─ conversation.session.header.actions
|
|
131
151
|
│ ├─ conversation.session.header.utilities
|
|
152
|
+
│ ├─ conversation.session.header.views.actions
|
|
132
153
|
│ └─ conversation.session.header.corner
|
|
133
154
|
└─ calls Factory: conversation.content
|
|
134
155
|
|
|
@@ -136,9 +157,13 @@ Factory: conversation.content [ConversationContent]
|
|
|
136
157
|
├─ conversation.session [ConversationSession / DefaultConversationViews]
|
|
137
158
|
│ └─ conversation.view
|
|
138
159
|
│ ├─ id=chat [ChatView]
|
|
160
|
+
│ │ ├─ conversation.chat.text-interaction [list]
|
|
139
161
|
│ │ └─ conversation.chat.flow [ChatFlow]
|
|
140
162
|
│ │ └─ conversation.chat.node [ChatNodeSeat dispatch]
|
|
141
|
-
│ │ ├─ key=user
|
|
163
|
+
│ │ ├─ key=user [UserMessageNodeView]
|
|
164
|
+
│ │ │ ├─ conversation.chat.user.before [chain]
|
|
165
|
+
│ │ │ └─ calls Factory: conversation.chat.user.content
|
|
166
|
+
│ │ ├─ key=steering [UserMessageNodeView]
|
|
142
167
|
│ │ │ └─ calls Factory: conversation.chat.user.content
|
|
143
168
|
│ │ ├─ key=assistant-step [AssistantNodeView / AssistantMarkdown]
|
|
144
169
|
│ │ │ ├─ conversation.chat.message.images [MessageImages]
|
|
@@ -173,6 +198,8 @@ Factory: conversation.content [ConversationContent]
|
|
|
173
198
|
├─ conversation.input.dock
|
|
174
199
|
│ └─ id=queue [QueueDock]
|
|
175
200
|
│ └─ calls Factory: conversation.user.text
|
|
201
|
+
├─ conversation.hero.frame [hoc]
|
|
202
|
+
│ └─ id=pixel-whale [PixelWhale]
|
|
176
203
|
├─ conversation.hero.brand.mark
|
|
177
204
|
├─ conversation.hero.workspace
|
|
178
205
|
│ └─ conversation.hero.workspace.directoryFlow
|
|
@@ -201,4 +228,4 @@ The generated [Client inspect catalog](https://github.com/deepseek-ai/deepseek-h
|
|
|
201
228
|
- Keep business and transport state in their owning Cordis services or Client models. Slot stores hold shared viewing and interaction state only.
|
|
202
229
|
- Keep observable source and snapshot identities stable between changes. Republish through the same source whenever its value changes.
|
|
203
230
|
- Pass JSON-compatible data and callbacks between UI domains. The `hooks` compartment is the sole exception for bare observables; React content travels through slots.
|
|
204
|
-
- Treat `single` and an occupied keyed cell as replacement points. Use list ids or an unoccupied key for additive extensions.
|
|
231
|
+
- Treat `single` and an occupied keyed cell as replacement points. Use fresh list or hoc ids, or an unoccupied key, for additive extensions.
|
|
@@ -48,7 +48,7 @@ interface StorageBackend {
|
|
|
48
48
|
}
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
A backend owns one medium (a file-tree root, a database file) and exposes optional operation groups; `kv` is the only shipped group. `KvFacet.open(descriptor)` opens one named unit — `KvUnitDescriptor` carries the name, current format version, optional compatible
|
|
51
|
+
A backend owns one medium (a file-tree root, a database file) and exposes optional operation groups; `kv` is the only shipped group. `KvFacet.open(descriptor)` opens one named unit — `KvUnitDescriptor` carries the name, current format version, optional compatible versions, table names, and whether a global singleton slot exists — and returns a `KvUnit` with `loadAll`, `putRecord`, `deleteRecord`, `deleteRecords`, `setGlobal`, and `close`. Unit and table names must match `UNIT_NAME_RE` (safe as a file name and as a SQL identifier segment); record keys are opaque strings in the `single` layout and match `[a-zA-Z0-9_-]+` path segments in the `per-record` layout. A unit does not serialize concurrent writes — ordering belongs to the caller — whole-document and row-store calls are atomic on the medium, while a per-record batch interrupted before resolution can be partially applied. Resolved writes are durable; per-record deletions sync directory changes on POSIX. `deleteRecords` applies a whole batch in one call: it resolves once every listed record is absent from the readable state and the backend accepted the batch, and a rejection normally leaves the batch unapplied; a backend that cannot establish or restore the batch's state rejects with `unknown-state`, after which every later operation on that unit rejects with the same error until `close()` releases it (calls after close reject `closed`). A `single`-layout failure after the atomic replacement (a directory-fsync error) can leave the new file on the medium while the caller sees a rejection; close the backend and its domains, then reopen to inspect saved state before retrying. A `single` medium stamped outside the current and declared compatible versions rejects `version-mismatch`; a `per-record` document stamped outside the accepted set reads as absent. A medium that cannot be parsed as the unit rejects `malformed-medium`. [`backend.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/src/backend.ts) is the normative clause-by-clause contract, and the shared conformance suite in [`tests/contract.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/tests/contract.ts) checks the shared clauses against each backend. The [json backend](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-json/README.md) republishes one whole human-readable file per unit atomically; the [sqlite backend](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-sqlite/README.md) stores one document per row in one database for frequently updated data.
|
|
52
52
|
|
|
53
53
|
## Declaring a domain
|
|
54
54
|
|
|
@@ -62,20 +62,20 @@ interface DomainSpec {
|
|
|
62
62
|
/** Current domain format version; reads enforce it according to the selected layout. */
|
|
63
63
|
readonly version: number
|
|
64
64
|
/**
|
|
65
|
-
*
|
|
65
|
+
* Document layout for the backend unit: `single` (the default) stores the
|
|
66
66
|
* whole unit as one document; `per-record` stores each record as its own
|
|
67
67
|
* document, for units whose records are large, sparse, or individually
|
|
68
|
-
* disposable — the projection cache —
|
|
69
|
-
*
|
|
68
|
+
* disposable — the projection cache — with per-record version checks.
|
|
69
|
+
* Row stores retain unit-wide versioning for either layout request.
|
|
70
70
|
*/
|
|
71
71
|
readonly layout?: 'single' | 'per-record'
|
|
72
72
|
/**
|
|
73
73
|
* Older domain versions whose stored records the current record schemas
|
|
74
74
|
* also accept (the declaring owner vouches for that, typically by
|
|
75
|
-
* declaring the fields older records lack as optional).
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
75
|
+
* declaring the fields older records lack as optional). Ordinary reads admit
|
|
76
|
+
* listed versions without restamping saved data; writes stamp {@link version}
|
|
77
|
+
* while leaving untouched records as saved. Current schemas must therefore
|
|
78
|
+
* accept mixed generations even under the current unit stamp.
|
|
79
79
|
*/
|
|
80
80
|
readonly compatibleVersions?: readonly number[]
|
|
81
81
|
/**
|
|
@@ -98,6 +98,23 @@ interface DomainSpec {
|
|
|
98
98
|
|
|
99
99
|
`defineDomain(spec)` pins the spec's literal types and fails loud at the owner's module load, before any medium is touched: a domain or table name outside `UNIT_NAME_RE`, a version that is not a non-negative integer, or a global schema that accepts `null` all throw (`null` is the medium's "never written" sentinel, so a stored nullable global could not round-trip). `domainTable<K, V>(schema)` declares one table with a phantom compile-time key type (typically a [branded id](./core.md#branded-ids)); `descriptorOf(spec)` projects the backend-facing unit descriptor.
|
|
100
100
|
|
|
101
|
+
<a id="domain-versioning"></a>
|
|
102
|
+
## Domain versioning
|
|
103
|
+
|
|
104
|
+
`version` names the current read/write format. `compatibleVersions` lists older versions whose records and global value the owner can decode with its current schemas; only nonnegative integers below `version` are allowed. Without that declaration, reads stay exact-version. Acceptance does not weaken record validation or permit a newer unknown version. Each row's saved fields must determine its meaning unambiguously; a unit stamp cannot distinguish different meanings of identical fields in mixed rows.
|
|
105
|
+
|
|
106
|
+
Ordinary compatible opens and reads do not restamp or normalize saved values. Whole-unit JSON publishes the current stamp and changed data in one atomic file replacement; SQLite commits its first updated unit stamp and mutation in one transaction; batch deletes always use one transaction. Deleting missing records or an empty batch does not advance the stamp. The stamp identifies an accepted format, not completion of value normalization; readers must accept mixed generations. A backend with a unit-wide stamp rejects an unsupported unit version.
|
|
107
|
+
|
|
108
|
+
Serialization failure before publication or successful SQLite rollback preserves the previous data and stamp. An I/O failure after JSON replacement, or a failure of SQLite rollback itself, can leave the saved outcome unknown despite rejection. Stop using and close the backend and its domains, then reopen to inspect saved state before deciding whether to retry. The backend READMEs define these failure cases.
|
|
109
|
+
|
|
110
|
+
JSON's `per-record` layout checks and stamps each document independently; an unsupported document reads as absent. Its existing whole-unit bootstrap is an exception to read-only loading: it copies accepted historical values into current-stamped documents without converting them. An existing declared table directory, even when empty, or a declared global document suppresses bootstrap. SQLite retains unit-wide version checks regardless of the layout request. See the [JSON backend](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-json/README.md) and [SQLite backend](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-sqlite/README.md) for layout and recovery behavior.
|
|
111
|
+
|
|
112
|
+
For a compatible successor, bump `version`, keep all still-readable stamps in `compatibleVersions`, and extend the same schema's decoding/defaults. Consumers normalize values when rewriting selected records; Storage does not assign application record versions. Verify historical and skipped upgrades, mixed values, reads without writes, failure rollback, restart, other-unit isolation, and unknown-version refusal. Table removal and layout changes require their own retention and upgrade policy; a compatible stamp alone does not define either.
|
|
113
|
+
|
|
114
|
+
A v2 unit may contain untouched v1 values. A v3 reader accepting stamp 2 must still decode those values; accepting stamp 1 is also necessary for users who skipped v2 entirely. Removing old decoding requires rewriting and validating every affected record, including those already under a current unit stamp. An incompatible change needs an explicit, recoverable upgrade before opening with the new schema; the storage domain has no value-migration runner.
|
|
115
|
+
|
|
116
|
+
Keep a consistent backup before writing a new format if return to an older reader is required: that reader can refuse the new stamp after the first mutation. Lowering a saved stamp by hand does not reverse value conversion. Domain compatibility does not migrate SQLite's physical schema or JSON envelope formats, and changing a backend route does not transfer stored data. Session-format migrations and SQLite physical-layout versioning have separate owners and do not migrate domain values.
|
|
117
|
+
|
|
101
118
|
## The open domain
|
|
102
119
|
|
|
103
120
|
```ts type-equiv
|
|
@@ -127,7 +144,7 @@ interface Domain<S extends DomainSpec> {
|
|
|
127
144
|
}
|
|
128
145
|
```
|
|
129
146
|
|
|
130
|
-
Reads are synchronous from authoritative in-memory state: `KvTable` exposes `get`/`entries`/`keys`/`size` (snapshot iterators that stay stable while queued writes land), and the global handle's `get()` serves the spec's `initial` until the first `set` materializes the slot on the medium. Every write — `put`, `delete`, `update`, `global.set` — queues on one per-domain chain and reaches backend durability first, then mutates memory, then emits `domain/changed`; a rejected backend write
|
|
147
|
+
Reads are synchronous from authoritative in-memory state: `KvTable` exposes `get`/`entries`/`keys`/`size` (snapshot iterators that stay stable while queued writes land), and the global handle's `get()` serves the spec's `initial` until the first `set` materializes the slot on the medium. Every write — `put`, `delete`, `deleteMany`, `update`, `global.set` — queues on one per-domain chain and reaches backend durability first, then mutates memory, then emits `domain/changed`; a rejected backend write does not publish a domain change; an unknown durable outcome requires reopening before further use of that snapshot; a backend that reports `unknown-state` instead quarantines the domain, and its reads and later writes reject until `close()` releases it. `update(key, fn)` is an atomic read-modify-write at its chain slot (a missing key rejects `missing-key`); `delete` of an absent key resolves `false` with no write and no event. `deleteMany(keys)` removes the present keys as one backend batch in one chain slot, resolves the removed count, and emits one `domain/changed` per removed key; a rejected backend write leaves every record in place and emits nothing; an `unknown-state` rejection quarantines the domain. Returned records are the stored objects themselves, not copies — replace via `put`/`update`, never mutate in place.
|
|
131
148
|
|
|
132
149
|
## The domain facility: `ctx.storageDomain`
|
|
133
150
|
|