dsh-plugin-dev-kb 1.6.0 → 1.8.1

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.
Files changed (622) hide show
  1. package/CHANGELOG.md +186 -141
  2. package/README.en.md +172 -155
  3. package/README.md +183 -163
  4. package/kb/INDEX.md +236 -234
  5. package/kb/README.md +88 -83
  6. package/kb/extra/AGENTS.md +77 -77
  7. package/kb/extra/cli-help.md +15 -7
  8. package/kb/extra/cli-help.zh.md +15 -7
  9. package/kb/extra/cookbook/adding-a-plugin-preview.md +18 -25
  10. package/kb/extra/cookbook/adding-a-plugin-preview.zh.md +18 -25
  11. package/kb/extra/cookbook/reviewing-persistence-type-changes.md +1 -1
  12. package/kb/extra/cookbook/reviewing-persistence-type-changes.zh.md +1 -1
  13. package/kb/extra/cookbook/reviewing-ui-design.md +166 -0
  14. package/kb/extra/cookbook/reviewing-ui-design.zh.md +166 -0
  15. package/kb/extra/deepseek-llm-api-wire-extensions.md +162 -162
  16. package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +162 -162
  17. package/kb/extra/defensive-patterns/conversation-and-session.md +2 -2
  18. package/kb/extra/defensive-patterns/conversation-and-session.zh.md +2 -2
  19. package/kb/extra/defensive-patterns/general.md +2 -0
  20. package/kb/extra/defensive-patterns/general.zh.md +2 -0
  21. package/kb/extra/defensive-patterns/package-surface.md +233 -231
  22. package/kb/extra/defensive-patterns/package-surface.zh.md +233 -231
  23. package/kb/extra/defensive-patterns/remote-and-api.md +117 -115
  24. package/kb/extra/defensive-patterns/remote-and-api.zh.md +117 -115
  25. package/kb/extra/development.md +221 -214
  26. package/kb/extra/development.zh.md +228 -221
  27. package/kb/extra/event-producer-consumer.md +133 -110
  28. package/kb/extra/event-producer-consumer.zh.md +135 -112
  29. package/kb/extra/i18n/README.md +2 -0
  30. package/kb/extra/i18n/README.zh.md +2 -0
  31. package/kb/extra/module-graph.md +1961 -1776
  32. package/kb/extra/module-graph.zh.md +1963 -1778
  33. package/kb/extra/persistence-changes/2026-10-13-liveshare-share-viewer-principal.md +60 -0
  34. package/kb/extra/persistence-changes/2026-10-13-liveshare-share-viewer-principal.zh.md +60 -0
  35. package/kb/extra/persistence-changes/2026-10-19-session-team-mode.md +48 -0
  36. package/kb/extra/persistence-changes/2026-10-19-session-team-mode.zh.md +48 -0
  37. package/kb/extra/persistence-changes/2026-10-22-action-card-status.md +60 -0
  38. package/kb/extra/persistence-changes/2026-10-22-action-card-status.zh.md +60 -0
  39. package/kb/extra/persistence-changes/2026-10-25-skill-catalog-incomplete.md +60 -0
  40. package/kb/extra/persistence-changes/2026-10-25-skill-catalog-incomplete.zh.md +60 -0
  41. package/kb/extra/persistence-changes/2026-10-27-retry-control-input.md +60 -0
  42. package/kb/extra/persistence-changes/2026-10-27-retry-control-input.zh.md +60 -0
  43. package/kb/extra/persistence-changes/2026-10-27-subagent-settlement-attribution.md +60 -0
  44. package/kb/extra/persistence-changes/2026-10-27-subagent-settlement-attribution.zh.md +60 -0
  45. package/kb/extra/persistence-changes/2026-11-02-subagent-catalog-names.md +48 -0
  46. package/kb/extra/persistence-changes/2026-11-02-subagent-catalog-names.zh.md +48 -0
  47. package/kb/extra/persistence-changes/2026-11-02-team-task-owner-names.md +48 -0
  48. package/kb/extra/persistence-changes/2026-11-02-team-task-owner-names.zh.md +48 -0
  49. package/kb/extra/persistence-changes/2026-11-05-timeline-priority-notice.md +60 -0
  50. package/kb/extra/persistence-changes/2026-11-05-timeline-priority-notice.zh.md +60 -0
  51. package/kb/extra/persistence-changes/README.md +92 -90
  52. package/kb/extra/persistence-changes/README.zh.md +92 -90
  53. package/kb/extra/persistence-changes/historical-formats/README.md +75 -75
  54. package/kb/extra/persistence-changes/historical-formats/README.zh.md +75 -75
  55. package/kb/extra/persistence-changes/releases/README.md +103 -103
  56. package/kb/extra/persistence-changes/releases/README.zh.md +103 -103
  57. package/kb/extra/rescope.md +55 -53
  58. package/kb/extra/rescope.zh.md +55 -53
  59. package/kb/extra/subsystems/agent-team.md +38 -75
  60. package/kb/extra/subsystems/agent-team.zh.md +38 -75
  61. package/kb/extra/subsystems/attachment.md +36 -13
  62. package/kb/extra/subsystems/attachment.zh.md +36 -13
  63. package/kb/extra/subsystems/boot.md +631 -447
  64. package/kb/extra/subsystems/boot.zh.md +631 -447
  65. package/kb/extra/subsystems/computer-use.md +179 -59
  66. package/kb/extra/subsystems/computer-use.zh.md +179 -59
  67. package/kb/extra/subsystems/deliverables.md +2 -0
  68. package/kb/extra/subsystems/deliverables.zh.md +2 -0
  69. package/kb/extra/subsystems/extensions.md +387 -384
  70. package/kb/extra/subsystems/extensions.zh.md +387 -384
  71. package/kb/extra/subsystems/feedback.md +418 -400
  72. package/kb/extra/subsystems/feedback.zh.md +418 -400
  73. package/kb/extra/subsystems/forge.md +2169 -0
  74. package/kb/extra/subsystems/forge.zh.md +2171 -0
  75. package/kb/extra/subsystems/liveshare.md +167 -0
  76. package/kb/extra/subsystems/liveshare.zh.md +167 -0
  77. package/kb/extra/subsystems/mcp.md +237 -139
  78. package/kb/extra/subsystems/mcp.zh.md +237 -139
  79. package/kb/extra/subsystems/office-kit.md +122 -0
  80. package/kb/extra/subsystems/office-kit.zh.md +122 -0
  81. package/kb/extra/subsystems/working-directory.md +95 -64
  82. package/kb/extra/subsystems/working-directory.zh.md +95 -64
  83. package/kb/extra/subsystems/worktrees.md +187 -76
  84. package/kb/extra/subsystems/worktrees.zh.md +187 -76
  85. package/kb/extra/testing.md +1 -1
  86. package/kb/extra/testing.zh.md +1 -1
  87. package/kb/extra/ui-design-review-cases.md +445 -0
  88. package/kb/extra/ui-design-review-cases.zh.md +445 -0
  89. package/kb/extra/ui-radius.md +3 -1
  90. package/kb/extra/ui-radius.zh.md +3 -1
  91. package/kb/extra/upgrade-guide/v0.2.1-alpha.1/python-ptc-sandbox/guide.md +21 -21
  92. package/kb/extra/upgrade-guide/v0.2.1-alpha.1/python-ptc-sandbox/guide.zh.md +21 -21
  93. package/kb/extra/upgrade-guide/v0.2.1-alpha.1/team-direct-inbox/guide.md +1 -1
  94. package/kb/extra/upgrade-guide/v0.2.1-alpha.1/team-direct-inbox/guide.zh.md +1 -1
  95. package/kb/extra/upgrade-guide/v0.2.1-alpha.2/cordis-timer-wrappers/guide.md +24 -0
  96. package/kb/extra/upgrade-guide/v0.2.1-alpha.2/cordis-timer-wrappers/guide.zh.md +24 -0
  97. package/kb/extra/upgrade-guide/v0.2.1-alpha.2/plugin-manager-view-fields/guide.md +25 -0
  98. package/kb/extra/upgrade-guide/v0.2.1-alpha.2/plugin-manager-view-fields/guide.zh.md +25 -0
  99. package/kb/extra/upgrade-guide/v0.2.1-alpha.4/model-switch-compaction/guide.md +30 -0
  100. package/kb/extra/upgrade-guide/v0.2.1-alpha.4/model-switch-compaction/guide.zh.md +30 -0
  101. package/kb/extra/upgrade-guide/v0.2.1-alpha.4/session-model-selection/guide.md +28 -0
  102. package/kb/extra/upgrade-guide/v0.2.1-alpha.4/session-model-selection/guide.zh.md +28 -0
  103. package/kb/extra/upgrade-guide/v0.2.1-rc.1/agent-instructions-chain-budgets/guide.md +24 -0
  104. package/kb/extra/upgrade-guide/v0.2.1-rc.1/agent-instructions-chain-budgets/guide.zh.md +24 -0
  105. package/kb/extra/upgrade-guide/v0.2.1-rc.1/subagent-control-tools/guide.md +23 -0
  106. package/kb/extra/upgrade-guide/v0.2.1-rc.1/subagent-control-tools/guide.zh.md +23 -0
  107. package/kb/extra/upgrade-guide/v0.2.1-rc.2/agent-runtime-owner/guide.md +20 -0
  108. package/kb/extra/upgrade-guide/v0.2.1-rc.2/agent-runtime-owner/guide.zh.md +20 -0
  109. package/kb/extra/upgrade-guide/v0.2.1-rc.2/agent-team-subagents/guide.md +31 -0
  110. package/kb/extra/upgrade-guide/v0.2.1-rc.2/agent-team-subagents/guide.zh.md +31 -0
  111. package/kb/extra/upgrade-guide/v0.2.1-rc.2/approval-projection-dependency/guide.md +34 -0
  112. package/kb/extra/upgrade-guide/v0.2.1-rc.2/approval-projection-dependency/guide.zh.md +34 -0
  113. package/kb/extra/upgrade-guide/v0.2.1-rc.2/auto-review-shutdown/guide.md +20 -0
  114. package/kb/extra/upgrade-guide/v0.2.1-rc.2/auto-review-shutdown/guide.zh.md +20 -0
  115. package/kb/extra/upgrade-guide/v0.2.1-rc.2/auto-review-user-sources/guide.md +18 -0
  116. package/kb/extra/upgrade-guide/v0.2.1-rc.2/auto-review-user-sources/guide.zh.md +18 -0
  117. package/kb/extra/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.md +18 -0
  118. package/kb/extra/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.zh.md +18 -0
  119. package/kb/extra/upgrade-guide/v0.2.1-rc.2/conditional-tools/guide.md +25 -0
  120. package/kb/extra/upgrade-guide/v0.2.1-rc.2/conditional-tools/guide.zh.md +25 -0
  121. package/kb/extra/upgrade-guide/v0.2.1-rc.2/context-menu-services/guide.md +23 -0
  122. package/kb/extra/upgrade-guide/v0.2.1-rc.2/context-menu-services/guide.zh.md +23 -0
  123. package/kb/extra/upgrade-guide/v0.2.1-rc.2/cua-consent-storage/guide.md +22 -0
  124. package/kb/extra/upgrade-guide/v0.2.1-rc.2/cua-consent-storage/guide.zh.md +22 -0
  125. package/kb/extra/upgrade-guide/v0.2.1-rc.2/cua-preset-scope/guide.md +18 -0
  126. package/kb/extra/upgrade-guide/v0.2.1-rc.2/cua-preset-scope/guide.zh.md +18 -0
  127. package/kb/extra/upgrade-guide/v0.2.1-rc.2/cua-relative-coordinates/guide.md +17 -0
  128. package/kb/extra/upgrade-guide/v0.2.1-rc.2/cua-relative-coordinates/guide.zh.md +17 -0
  129. package/kb/extra/upgrade-guide/v0.2.1-rc.2/file-drag-callbacks/guide.md +19 -0
  130. package/kb/extra/upgrade-guide/v0.2.1-rc.2/file-drag-callbacks/guide.zh.md +19 -0
  131. package/kb/extra/upgrade-guide/v0.2.1-rc.2/headless-policy-composition/guide.md +27 -0
  132. package/kb/extra/upgrade-guide/v0.2.1-rc.2/headless-policy-composition/guide.zh.md +27 -0
  133. package/kb/extra/upgrade-guide/v0.2.1-rc.2/model-badge-package-removal/guide.md +18 -0
  134. package/kb/extra/upgrade-guide/v0.2.1-rc.2/model-badge-package-removal/guide.zh.md +18 -0
  135. package/kb/extra/upgrade-guide/v0.2.1-rc.2/new-session-blank-reuse/guide.md +22 -0
  136. package/kb/extra/upgrade-guide/v0.2.1-rc.2/new-session-blank-reuse/guide.zh.md +22 -0
  137. package/kb/extra/upgrade-guide/v0.2.1-rc.2/node-24/guide.md +17 -0
  138. package/kb/extra/upgrade-guide/v0.2.1-rc.2/node-24/guide.zh.md +17 -0
  139. package/kb/extra/upgrade-guide/v0.2.1-rc.2/official-bundle-lists/guide.md +18 -0
  140. package/kb/extra/upgrade-guide/v0.2.1-rc.2/official-bundle-lists/guide.zh.md +18 -0
  141. package/kb/extra/upgrade-guide/v0.2.1-rc.2/persistent-terminal-controls/guide.md +18 -0
  142. package/kb/extra/upgrade-guide/v0.2.1-rc.2/persistent-terminal-controls/guide.zh.md +18 -0
  143. package/kb/extra/upgrade-guide/v0.2.1-rc.2/pi-ai-default-capacities/guide.md +18 -0
  144. package/kb/extra/upgrade-guide/v0.2.1-rc.2/pi-ai-default-capacities/guide.zh.md +18 -0
  145. package/kb/extra/upgrade-guide/v0.2.1-rc.2/pi-ai-model-catalog/guide.md +53 -0
  146. package/kb/extra/upgrade-guide/v0.2.1-rc.2/pi-ai-model-catalog/guide.zh.md +53 -0
  147. package/kb/extra/upgrade-guide/v0.2.1-rc.2/pi-ai-protocol-replay/guide.md +30 -0
  148. package/kb/extra/upgrade-guide/v0.2.1-rc.2/pi-ai-protocol-replay/guide.zh.md +30 -0
  149. package/kb/extra/upgrade-guide/v0.2.1-rc.2/ptc-script-format/guide.md +20 -0
  150. package/kb/extra/upgrade-guide/v0.2.1-rc.2/ptc-script-format/guide.zh.md +20 -0
  151. package/kb/extra/upgrade-guide/v0.2.1-rc.2/sdk-desktop-context/guide.md +18 -0
  152. package/kb/extra/upgrade-guide/v0.2.1-rc.2/sdk-desktop-context/guide.zh.md +18 -0
  153. package/kb/extra/upgrade-guide/v0.2.1-rc.2/sdk-minimal-checkpoints/guide.md +18 -0
  154. package/kb/extra/upgrade-guide/v0.2.1-rc.2/sdk-minimal-checkpoints/guide.zh.md +18 -0
  155. package/kb/extra/upgrade-guide/v0.2.1-rc.2/session-projection-handles/guide.md +24 -0
  156. package/kb/extra/upgrade-guide/v0.2.1-rc.2/session-projection-handles/guide.zh.md +24 -0
  157. package/kb/extra/upgrade-guide/v0.2.1-rc.2/session-store-writes/guide.md +25 -0
  158. package/kb/extra/upgrade-guide/v0.2.1-rc.2/session-store-writes/guide.zh.md +25 -0
  159. package/kb/extra/upgrade-guide/v0.2.1-rc.2/session-team-mode/guide.md +22 -0
  160. package/kb/extra/upgrade-guide/v0.2.1-rc.2/session-team-mode/guide.zh.md +22 -0
  161. package/kb/extra/upgrade-guide/v0.2.1-rc.2/subagent-activation-options/guide.md +18 -0
  162. package/kb/extra/upgrade-guide/v0.2.1-rc.2/subagent-activation-options/guide.zh.md +18 -0
  163. package/kb/extra/upgrade-guide/v0.2.1-rc.2/subagent-service-methods/guide.md +19 -0
  164. package/kb/extra/upgrade-guide/v0.2.1-rc.2/subagent-service-methods/guide.zh.md +19 -0
  165. package/kb/extra/upgrade-guide/v0.2.1-rc.2/subagent-user-controls/guide.md +26 -0
  166. package/kb/extra/upgrade-guide/v0.2.1-rc.2/subagent-user-controls/guide.zh.md +26 -0
  167. package/kb/extra/upgrade-guide/v0.2.1-rc.2/tool-executor-plugins/guide.md +35 -0
  168. package/kb/extra/upgrade-guide/v0.2.1-rc.2/tool-executor-plugins/guide.zh.md +35 -0
  169. package/kb/extra/upgrade-guide/v0.2.1-rc.2/web-fetch-private-destinations/guide.md +21 -0
  170. package/kb/extra/upgrade-guide/v0.2.1-rc.2/web-fetch-private-destinations/guide.zh.md +21 -0
  171. package/kb/extra/upgrade-guide/v0.2.1-rc.2/webserver-index-peer/guide.md +17 -0
  172. package/kb/extra/upgrade-guide/v0.2.1-rc.2/webserver-index-peer/guide.zh.md +17 -0
  173. package/kb/extra/upgrade-guide/v0.2.1-rc.3/attachment-read-access/guide.md +23 -0
  174. package/kb/extra/upgrade-guide/v0.2.1-rc.3/attachment-read-access/guide.zh.md +23 -0
  175. package/kb/extra/upgrade-guide/v0.2.1-rc.3/computer-use-helper-permissions/guide.md +21 -0
  176. package/kb/extra/upgrade-guide/v0.2.1-rc.3/computer-use-helper-permissions/guide.zh.md +21 -0
  177. package/kb/extra/upgrade-guide/v0.2.1-rc.3/cua-bundle-id-consent/guide.md +20 -0
  178. package/kb/extra/upgrade-guide/v0.2.1-rc.3/cua-bundle-id-consent/guide.zh.md +20 -0
  179. package/kb/extra/upgrade-guide/v0.2.1-rc.3/generated-worktree-names/guide.md +20 -0
  180. package/kb/extra/upgrade-guide/v0.2.1-rc.3/generated-worktree-names/guide.zh.md +20 -0
  181. package/kb/extra/upgrade-guide/v0.2.1-rc.3/inbox-only-agent-wait/guide.md +19 -0
  182. package/kb/extra/upgrade-guide/v0.2.1-rc.3/inbox-only-agent-wait/guide.zh.md +19 -0
  183. package/kb/extra/upgrade-guide/v0.2.1-rc.3/independent-session-forks/guide.md +23 -0
  184. package/kb/extra/upgrade-guide/v0.2.1-rc.3/independent-session-forks/guide.zh.md +23 -0
  185. package/kb/extra/upgrade-guide/v0.2.1-rc.3/ptc-caller-cancellation/guide.md +20 -0
  186. package/kb/extra/upgrade-guide/v0.2.1-rc.3/ptc-caller-cancellation/guide.zh.md +20 -0
  187. package/kb/extra/upgrade-guide/v0.2.1-rc.3/session-follow-activation/guide.md +21 -0
  188. package/kb/extra/upgrade-guide/v0.2.1-rc.3/session-follow-activation/guide.zh.md +21 -0
  189. package/kb/extra/upgrade-guide/v0.2.1-rc.3/subagent-runtime-ownership/guide.md +21 -0
  190. package/kb/extra/upgrade-guide/v0.2.1-rc.3/subagent-runtime-ownership/guide.zh.md +21 -0
  191. package/kb/extra/upgrade-guide/v0.2.1-rc.3/team-mode-menu/guide.md +18 -0
  192. package/kb/extra/upgrade-guide/v0.2.1-rc.3/team-mode-menu/guide.zh.md +18 -0
  193. package/kb/extra/upgrade-guide/v0.2.1-rc.3/team-projection/guide.md +20 -0
  194. package/kb/extra/upgrade-guide/v0.2.1-rc.3/team-projection/guide.zh.md +20 -0
  195. package/kb/extra/upgrade-guide/v0.2.1-rc.3/web-file-downloads/guide.md +19 -0
  196. package/kb/extra/upgrade-guide/v0.2.1-rc.3/web-file-downloads/guide.zh.md +19 -0
  197. package/kb/extra/upgrade-guide/v0.2.1-rc.3/web-search-defaults/guide.md +18 -0
  198. package/kb/extra/upgrade-guide/v0.2.1-rc.3/web-search-defaults/guide.zh.md +18 -0
  199. package/kb/extra/upgrade-guide/v0.2.1-rc.4/model-listing-refresh/guide.md +22 -0
  200. package/kb/extra/upgrade-guide/v0.2.1-rc.4/model-listing-refresh/guide.zh.md +22 -0
  201. package/kb/extra/upgrade-guide/v0.2.1-rc.4/reasoning-body-props/guide.md +20 -0
  202. package/kb/extra/upgrade-guide/v0.2.1-rc.4/reasoning-body-props/guide.zh.md +20 -0
  203. package/kb/extra/upgrade-guide/v0.2.1-rc.4/sandbox-unsupported-policy-error/guide.md +18 -0
  204. package/kb/extra/upgrade-guide/v0.2.1-rc.4/sandbox-unsupported-policy-error/guide.zh.md +18 -0
  205. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/context-menu-target/guide.md +19 -0
  206. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/context-menu-target/guide.zh.md +19 -0
  207. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/cordis-loader-entry-trees/guide.md +24 -0
  208. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/cordis-loader-entry-trees/guide.zh.md +24 -0
  209. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/css-anchored-menus/guide.md +21 -0
  210. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/css-anchored-menus/guide.zh.md +21 -0
  211. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/cua-source-dev-helper/guide.md +19 -0
  212. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/cua-source-dev-helper/guide.zh.md +19 -0
  213. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/desktop-stable-channel/guide.md +18 -0
  214. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/desktop-stable-channel/guide.zh.md +18 -0
  215. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/forge-git-permissions/guide.md +21 -0
  216. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/forge-git-permissions/guide.zh.md +21 -0
  217. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/forge-worktree-entry/guide.md +29 -0
  218. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/forge-worktree-entry/guide.zh.md +29 -0
  219. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/fs-observation-policy-default-off/guide.md +29 -0
  220. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/fs-observation-policy-default-off/guide.zh.md +29 -0
  221. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/llm-error-builtin-codes/guide.md +18 -0
  222. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/llm-error-builtin-codes/guide.zh.md +18 -0
  223. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/llm-request-purpose-declarations/guide.md +29 -0
  224. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/llm-request-purpose-declarations/guide.zh.md +29 -0
  225. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/pi-ai-request-image-count/guide.md +18 -0
  226. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/pi-ai-request-image-count/guide.zh.md +18 -0
  227. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/projection-event-frames/guide.md +32 -0
  228. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/projection-event-frames/guide.zh.md +32 -0
  229. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/projection-released-checkpoint/guide.md +30 -0
  230. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/projection-released-checkpoint/guide.zh.md +30 -0
  231. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/projection-snapshot-scope/guide.md +19 -0
  232. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/projection-snapshot-scope/guide.zh.md +19 -0
  233. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/retained-ptc-timeout/guide.md +21 -0
  234. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/retained-ptc-timeout/guide.zh.md +21 -0
  235. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/schedule-agent-tools/guide.md +37 -0
  236. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/schedule-agent-tools/guide.zh.md +37 -0
  237. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/schedule-remote-host-tasks/guide.md +22 -0
  238. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/schedule-remote-host-tasks/guide.zh.md +22 -0
  239. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/sdk-run-commands/guide.md +24 -0
  240. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/sdk-run-commands/guide.zh.md +24 -0
  241. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/session-header-menu/guide.md +20 -0
  242. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/session-header-menu/guide.zh.md +20 -0
  243. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/subagent-explicit-reasoning/guide.md +20 -0
  244. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/subagent-explicit-reasoning/guide.zh.md +20 -0
  245. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/web-search-credential-modes/guide.md +17 -0
  246. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/web-search-credential-modes/guide.zh.md +17 -0
  247. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/web-search-default-provider/guide.md +19 -0
  248. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/web-search-default-provider/guide.zh.md +19 -0
  249. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/chat-process-activity-context/guide.md +18 -0
  250. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/chat-process-activity-context/guide.zh.md +18 -0
  251. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-kit-package/guide.md +34 -0
  252. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-kit-package/guide.zh.md +34 -0
  253. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-operation-tools/guide.md +49 -0
  254. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-operation-tools/guide.zh.md +49 -0
  255. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-skill-resources/guide.md +36 -0
  256. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-skill-resources/guide.zh.md +36 -0
  257. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/subagent-names/guide.md +29 -0
  258. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/subagent-names/guide.zh.md +29 -0
  259. package/kb/extra/upgrade-guide/v0.2.2-rc.1/account-notification-fields/guide.md +26 -0
  260. package/kb/extra/upgrade-guide/v0.2.2-rc.1/account-notification-fields/guide.zh.md +26 -0
  261. package/kb/extra/upgrade-guide/v0.2.2-rc.1/account-remote-provider/guide.md +22 -0
  262. package/kb/extra/upgrade-guide/v0.2.2-rc.1/account-remote-provider/guide.zh.md +22 -0
  263. package/kb/extra/upgrade-guide/v0.2.2-rc.1/archive-worktrees/guide.md +21 -0
  264. package/kb/extra/upgrade-guide/v0.2.2-rc.1/archive-worktrees/guide.zh.md +21 -0
  265. package/kb/extra/upgrade-guide/v0.2.2-rc.1/attachment-error-codes/guide.md +23 -0
  266. package/kb/extra/upgrade-guide/v0.2.2-rc.1/attachment-error-codes/guide.zh.md +23 -0
  267. package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-ax-read-limits/guide.md +20 -0
  268. package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-ax-read-limits/guide.zh.md +20 -0
  269. package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-hover-ax-only/guide.md +18 -0
  270. package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-hover-ax-only/guide.zh.md +18 -0
  271. package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-native-platform/guide.md +23 -0
  272. package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-native-platform/guide.zh.md +23 -0
  273. package/kb/extra/upgrade-guide/v0.2.2-rc.1/dsh-doc-skill/guide.md +35 -0
  274. package/kb/extra/upgrade-guide/v0.2.2-rc.1/dsh-doc-skill/guide.zh.md +35 -0
  275. package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-change-request-overview/guide.md +26 -0
  276. package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-change-request-overview/guide.zh.md +26 -0
  277. package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-pinned-diff/guide.md +26 -0
  278. package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-pinned-diff/guide.zh.md +26 -0
  279. package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-review-reads/guide.md +19 -0
  280. package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-review-reads/guide.zh.md +19 -0
  281. package/kb/extra/upgrade-guide/v0.2.2-rc.1/package-export-cleanup/guide.md +26 -0
  282. package/kb/extra/upgrade-guide/v0.2.2-rc.1/package-export-cleanup/guide.zh.md +26 -0
  283. package/kb/extra/upgrade-guide/v0.2.2-rc.1/plugin-update-method/guide.md +22 -0
  284. package/kb/extra/upgrade-guide/v0.2.2-rc.1/plugin-update-method/guide.zh.md +22 -0
  285. package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-bootstrap-protocol/guide.md +25 -0
  286. package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-bootstrap-protocol/guide.zh.md +25 -0
  287. package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-inspect-output/guide.md +48 -0
  288. package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-inspect-output/guide.zh.md +48 -0
  289. package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-scoped-repl-default/guide.md +45 -0
  290. package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-scoped-repl-default/guide.zh.md +45 -0
  291. package/kb/extra/upgrade-guide/v0.2.2-rc.1/runtime-context-reminders/guide.md +19 -0
  292. package/kb/extra/upgrade-guide/v0.2.2-rc.1/runtime-context-reminders/guide.zh.md +19 -0
  293. package/kb/extra/upgrade-guide/v0.2.2-rc.1/session-append-overloads/guide.md +17 -0
  294. package/kb/extra/upgrade-guide/v0.2.2-rc.1/session-append-overloads/guide.zh.md +17 -0
  295. package/kb/extra/upgrade-guide/v0.2.2-rc.1/subagent-interrupt-default/guide.md +27 -0
  296. package/kb/extra/upgrade-guide/v0.2.2-rc.1/subagent-interrupt-default/guide.zh.md +27 -0
  297. package/kb/extra/upgrade-guide/v0.2.2-rc.1/terminal-backend-cleanup-error/guide.md +20 -0
  298. package/kb/extra/upgrade-guide/v0.2.2-rc.1/terminal-backend-cleanup-error/guide.zh.md +20 -0
  299. package/kb/extra/upgrade-guide/v0.2.2-rc.1/terminal-bundle-sidebar-backend/guide.md +19 -0
  300. package/kb/extra/upgrade-guide/v0.2.2-rc.1/terminal-bundle-sidebar-backend/guide.zh.md +19 -0
  301. package/kb/extra/upgrade-guide/v0.2.2-rc.1/web-fetch-transport-error-codes/guide.md +18 -0
  302. package/kb/extra/upgrade-guide/v0.2.2-rc.1/web-fetch-transport-error-codes/guide.zh.md +18 -0
  303. package/kb/extra/upgrade-guide/v0.2.2-rc.1/web-search-billing/guide.md +41 -0
  304. package/kb/extra/upgrade-guide/v0.2.2-rc.1/web-search-billing/guide.zh.md +41 -0
  305. package/kb/extra/upgrade-guide/v0.2.2-rc.1/window-drag-regions/guide.md +21 -0
  306. package/kb/extra/upgrade-guide/v0.2.2-rc.1/window-drag-regions/guide.zh.md +21 -0
  307. package/kb/extra/upgrade-guide/v0.2.2-rc.2/client-module-metadata/guide.md +29 -0
  308. package/kb/extra/upgrade-guide/v0.2.2-rc.2/client-module-metadata/guide.zh.md +29 -0
  309. package/kb/extra/upgrade-guide/v0.2.2-rc.2/connection-page-peer/guide.md +25 -0
  310. package/kb/extra/upgrade-guide/v0.2.2-rc.2/connection-page-peer/guide.zh.md +25 -0
  311. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cordis-root-and-intercept-metadata/guide.md +31 -0
  312. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cordis-root-and-intercept-metadata/guide.zh.md +31 -0
  313. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-agents-without-preset/guide.md +24 -0
  314. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-agents-without-preset/guide.zh.md +24 -0
  315. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-macos-provider/guide.md +24 -0
  316. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-macos-provider/guide.zh.md +24 -0
  317. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-partial-observations/guide.md +19 -0
  318. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-partial-observations/guide.zh.md +19 -0
  319. package/kb/extra/upgrade-guide/v0.2.2-rc.2/deepseek-files-timeout/guide.md +15 -0
  320. package/kb/extra/upgrade-guide/v0.2.2-rc.2/deepseek-files-timeout/guide.zh.md +15 -0
  321. package/kb/extra/upgrade-guide/v0.2.2-rc.2/experimental-tool-error-codes/guide.md +28 -0
  322. package/kb/extra/upgrade-guide/v0.2.2-rc.2/experimental-tool-error-codes/guide.zh.md +28 -0
  323. package/kb/extra/upgrade-guide/v0.2.2-rc.2/package-export-cleanup/guide.md +36 -0
  324. package/kb/extra/upgrade-guide/v0.2.2-rc.2/package-export-cleanup/guide.zh.md +36 -0
  325. package/kb/extra/upgrade-guide/v0.2.2-rc.2/python-ptc-removal/guide.md +22 -0
  326. package/kb/extra/upgrade-guide/v0.2.2-rc.2/python-ptc-removal/guide.zh.md +22 -0
  327. package/kb/extra/upgrade-guide/v0.2.2-rc.2/session-status-package/guide.md +31 -0
  328. package/kb/extra/upgrade-guide/v0.2.2-rc.2/session-status-package/guide.zh.md +31 -0
  329. package/kb/extra/upgrade-guide/v0.2.2-rc.2/shared-search-filter/guide.md +18 -0
  330. package/kb/extra/upgrade-guide/v0.2.2-rc.2/shared-search-filter/guide.zh.md +18 -0
  331. package/kb/extra/upgrade-guide/v0.2.2-rc.2/shell-fs-tool-error-codes/guide.md +30 -0
  332. package/kb/extra/upgrade-guide/v0.2.2-rc.2/shell-fs-tool-error-codes/guide.zh.md +30 -0
  333. package/kb/extra/web-styling.md +57 -39
  334. package/kb/extra/web-styling.zh.md +57 -39
  335. package/kb/meta/search-index.json +4508 -3806
  336. package/kb/meta/source.json +18 -14
  337. package/kb/site/develop/cordis-tutorial/04-events.md +1 -1
  338. package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +5 -4
  339. package/kb/site/develop/framework/events.md +1 -1
  340. package/kb/site/develop/practice/dynamic-cordis.md +1 -1
  341. package/kb/site/develop/practice/llm-adapter.md +192 -192
  342. package/kb/site/en/develop/cordis-tutorial/04-events.md +1 -1
  343. package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +5 -4
  344. package/kb/site/en/develop/framework/events.md +1 -1
  345. package/kb/site/en/develop/practice/dynamic-cordis.md +1 -1
  346. package/kb/site/en/develop/practice/llm-adapter.md +192 -192
  347. package/kb/site/en/guide/desktop-uninstall-cleanup.md +63 -0
  348. package/kb/site/en/guide/network-proxy.md +1 -1
  349. package/kb/site/en/guide/plugin-market.md +153 -151
  350. package/kb/site/en/guide/providers.md +234 -230
  351. package/kb/site/en/guide/python-sdk.md +17 -2
  352. package/kb/site/en/guide/quickstart.md +35 -34
  353. package/kb/site/en/guide/schedule.md +45 -26
  354. package/kb/site/en/reference/agent-lifecycle.md +3 -1
  355. package/kb/site/en/reference/api-gateway.md +4 -4
  356. package/kb/site/en/reference/capability-seams.md +789 -719
  357. package/kb/site/en/reference/config-catalog.md +5432 -4806
  358. package/kb/site/en/reference/cookbook/adding-a-package.md +175 -173
  359. package/kb/site/en/reference/cookbook/adding-a-tool.md +105 -104
  360. package/kb/site/en/reference/cookbook/extension-cookbook.md +178 -135
  361. package/kb/site/en/reference/cordis-api/context.md +373 -369
  362. package/kb/site/en/reference/cordis-api/events.md +9 -9
  363. package/kb/site/en/reference/cordis-api/fiber.md +457 -380
  364. package/kb/site/en/reference/cordis-api/inherited.md +44 -43
  365. package/kb/site/en/reference/cordis-api/service.md +118 -107
  366. package/kb/site/en/reference/experimental-persistence-catalog.md +36 -20
  367. package/kb/site/en/reference/index.md +174 -168
  368. package/kb/site/en/reference/persistence-catalog.md +9453 -9146
  369. package/kb/site/en/reference/subsystems/client-modules.md +19 -11
  370. package/kb/site/en/reference/subsystems/compaction.md +288 -288
  371. package/kb/site/en/reference/subsystems/conversation.md +2 -0
  372. package/kb/site/en/reference/subsystems/core.md +1172 -1117
  373. package/kb/site/en/reference/subsystems/credentials.md +526 -497
  374. package/kb/site/en/reference/subsystems/filesystem.md +708 -534
  375. package/kb/site/en/reference/subsystems/index.md +82 -80
  376. package/kb/site/en/reference/subsystems/llm-streaming.md +1290 -1200
  377. package/kb/site/en/reference/subsystems/lsp.md +230 -206
  378. package/kb/site/en/reference/subsystems/persistence.md +451 -422
  379. package/kb/site/en/reference/subsystems/plan.md +91 -91
  380. package/kb/site/en/reference/subsystems/ptc-runtime.md +295 -254
  381. package/kb/site/en/reference/subsystems/sandbox.md +250 -225
  382. package/kb/site/en/reference/subsystems/schedule.md +194 -430
  383. package/kb/site/en/reference/subsystems/session-projection.md +186 -44
  384. package/kb/site/en/reference/subsystems/session-query.md +525 -515
  385. package/kb/site/en/reference/subsystems/session-reference.md +231 -228
  386. package/kb/site/en/reference/subsystems/session.md +1478 -1343
  387. package/kb/site/en/reference/subsystems/sidebar-right.md +165 -164
  388. package/kb/site/en/reference/subsystems/skills.md +356 -356
  389. package/kb/site/en/reference/subsystems/slots.md +235 -204
  390. package/kb/site/en/reference/subsystems/storage.md +26 -9
  391. package/kb/site/en/reference/subsystems/subagent.md +119 -102
  392. package/kb/site/en/reference/subsystems/system-prompt.md +13 -11
  393. package/kb/site/en/reference/subsystems/terminal.md +188 -188
  394. package/kb/site/en/reference/subsystems/token-meter.md +45 -0
  395. package/kb/site/en/reference/subsystems/tools.md +902 -751
  396. package/kb/site/en/reference/subsystems/typert.md +21 -11
  397. package/kb/site/en/reference/subsystems/user-questions.md +330 -311
  398. package/kb/site/en/reference/subsystems/web-client.md +161 -104
  399. package/kb/site/en/reference/subsystems/web-server.md +434 -306
  400. package/kb/site/en/reference/subsystems/web.md +268 -210
  401. package/kb/site/en/reference/subsystems/workflow.md +287 -282
  402. package/kb/site/en/reference/subsystems/workspace.md +743 -651
  403. package/kb/site/en/reference/tool-catalog.md +2867 -2829
  404. package/kb/site/en/reference/tool-execution-pipeline.md +5 -4
  405. package/kb/site/guide/desktop-uninstall-cleanup.md +63 -0
  406. package/kb/site/guide/network-proxy.md +1 -1
  407. package/kb/site/guide/plugin-market.md +153 -151
  408. package/kb/site/guide/providers.md +234 -230
  409. package/kb/site/guide/python-sdk.md +17 -2
  410. package/kb/site/guide/quickstart.md +35 -34
  411. package/kb/site/guide/schedule.md +45 -26
  412. package/kb/site/reference/agent-lifecycle.md +3 -1
  413. package/kb/site/reference/api-gateway.md +4 -4
  414. package/kb/site/reference/capability-seams.md +789 -719
  415. package/kb/site/reference/config-catalog.md +5432 -4806
  416. package/kb/site/reference/cookbook/adding-a-package.md +175 -173
  417. package/kb/site/reference/cookbook/adding-a-tool.md +107 -106
  418. package/kb/site/reference/cookbook/extension-cookbook.md +182 -139
  419. package/kb/site/reference/cordis-api/context.md +373 -369
  420. package/kb/site/reference/cordis-api/events.md +9 -9
  421. package/kb/site/reference/cordis-api/fiber.md +459 -380
  422. package/kb/site/reference/cordis-api/inherited.md +44 -43
  423. package/kb/site/reference/cordis-api/service.md +118 -107
  424. package/kb/site/reference/experimental-persistence-catalog.md +36 -20
  425. package/kb/site/reference/index.md +178 -172
  426. package/kb/site/reference/persistence-catalog.md +9453 -9146
  427. package/kb/site/reference/subsystems/client-modules.md +19 -11
  428. package/kb/site/reference/subsystems/compaction.md +288 -288
  429. package/kb/site/reference/subsystems/conversation.md +4 -0
  430. package/kb/site/reference/subsystems/core.md +1184 -1129
  431. package/kb/site/reference/subsystems/credentials.md +526 -497
  432. package/kb/site/reference/subsystems/filesystem.md +708 -534
  433. package/kb/site/reference/subsystems/index.md +82 -80
  434. package/kb/site/reference/subsystems/llm-streaming.md +1296 -1206
  435. package/kb/site/reference/subsystems/lsp.md +230 -206
  436. package/kb/site/reference/subsystems/persistence.md +451 -422
  437. package/kb/site/reference/subsystems/plan.md +91 -91
  438. package/kb/site/reference/subsystems/ptc-runtime.md +295 -254
  439. package/kb/site/reference/subsystems/sandbox.md +250 -225
  440. package/kb/site/reference/subsystems/schedule.md +197 -433
  441. package/kb/site/reference/subsystems/session-projection.md +186 -44
  442. package/kb/site/reference/subsystems/session-query.md +525 -515
  443. package/kb/site/reference/subsystems/session-reference.md +231 -228
  444. package/kb/site/reference/subsystems/session.md +1482 -1347
  445. package/kb/site/reference/subsystems/sidebar-right.md +165 -164
  446. package/kb/site/reference/subsystems/skills.md +356 -356
  447. package/kb/site/reference/subsystems/slots.md +239 -208
  448. package/kb/site/reference/subsystems/storage.md +26 -9
  449. package/kb/site/reference/subsystems/subagent.md +119 -102
  450. package/kb/site/reference/subsystems/system-prompt.md +13 -11
  451. package/kb/site/reference/subsystems/terminal.md +188 -188
  452. package/kb/site/reference/subsystems/token-meter.md +45 -0
  453. package/kb/site/reference/subsystems/tools.md +902 -751
  454. package/kb/site/reference/subsystems/typert.md +21 -11
  455. package/kb/site/reference/subsystems/user-questions.md +330 -311
  456. package/kb/site/reference/subsystems/web-client.md +161 -104
  457. package/kb/site/reference/subsystems/web-server.md +434 -306
  458. package/kb/site/reference/subsystems/web.md +268 -210
  459. package/kb/site/reference/subsystems/workflow.md +287 -282
  460. package/kb/site/reference/subsystems/workspace.md +743 -651
  461. package/kb/site/reference/tool-catalog.md +2872 -2835
  462. package/kb/site/reference/tool-execution-pipeline.md +4 -3
  463. package/lib/index.js +359 -244
  464. package/lib/kb-version.js +118 -0
  465. package/package.json +68 -66
  466. package/scripts/refresh-kb.mjs +153 -0
  467. package/scripts/selfcheck.mjs +18 -0
  468. package/scripts/smoke.mjs +77 -0
  469. package/skills/dsh-plugin-dev-kb.md +71 -69
  470. package/skills/dsh-plugin-starter.md +65 -0
  471. package/skills/dsh-upgrade-assistant.md +62 -0
  472. package/kb/extra/agent-lifecycle.md +0 -91
  473. package/kb/extra/agent-lifecycle.zh.md +0 -93
  474. package/kb/extra/api-gateway.md +0 -172
  475. package/kb/extra/api-gateway.zh.md +0 -178
  476. package/kb/extra/architecture.md +0 -165
  477. package/kb/extra/architecture.zh.md +0 -169
  478. package/kb/extra/capability-seams.md +0 -714
  479. package/kb/extra/capability-seams.zh.md +0 -716
  480. package/kb/extra/config-catalog.md +0 -4801
  481. package/kb/extra/config-catalog.zh.md +0 -4803
  482. package/kb/extra/cookbook/adding-a-package.md +0 -170
  483. package/kb/extra/cookbook/adding-a-package.zh.md +0 -170
  484. package/kb/extra/cookbook/adding-a-settings-card.md +0 -72
  485. package/kb/extra/cookbook/adding-a-settings-card.zh.md +0 -72
  486. package/kb/extra/cookbook/adding-a-tool.md +0 -101
  487. package/kb/extra/cookbook/adding-a-tool.zh.md +0 -103
  488. package/kb/extra/cookbook/adding-an-llm-adapter.md +0 -43
  489. package/kb/extra/cookbook/adding-an-llm-adapter.zh.md +0 -43
  490. package/kb/extra/cookbook/extension-cookbook.md +0 -132
  491. package/kb/extra/cookbook/extension-cookbook.zh.md +0 -136
  492. package/kb/extra/cordis-api/context.md +0 -364
  493. package/kb/extra/cordis-api/context.zh.md +0 -366
  494. package/kb/extra/cordis-api/events.md +0 -207
  495. package/kb/extra/cordis-api/events.zh.md +0 -209
  496. package/kb/extra/cordis-api/fiber.md +0 -375
  497. package/kb/extra/cordis-api/fiber.zh.md +0 -377
  498. package/kb/extra/cordis-api/inherited.md +0 -38
  499. package/kb/extra/cordis-api/registry.md +0 -152
  500. package/kb/extra/cordis-api/registry.zh.md +0 -154
  501. package/kb/extra/cordis-api/service.md +0 -102
  502. package/kb/extra/cordis-api/service.zh.md +0 -104
  503. package/kb/extra/cordis-tutorial/01-first-plugin.md +0 -95
  504. package/kb/extra/cordis-tutorial/01-first-plugin.zh.md +0 -95
  505. package/kb/extra/cordis-tutorial/02-lifecycle-and-effects.md +0 -98
  506. package/kb/extra/cordis-tutorial/02-lifecycle-and-effects.zh.md +0 -98
  507. package/kb/extra/cordis-tutorial/03-services.md +0 -98
  508. package/kb/extra/cordis-tutorial/03-services.zh.md +0 -98
  509. package/kb/extra/cordis-tutorial/04-events.md +0 -144
  510. package/kb/extra/cordis-tutorial/04-events.zh.md +0 -144
  511. package/kb/extra/cordis-tutorial/05-config.md +0 -111
  512. package/kb/extra/cordis-tutorial/05-config.zh.md +0 -111
  513. package/kb/extra/cordis-tutorial/06-composition-and-hmr.md +0 -113
  514. package/kb/extra/cordis-tutorial/06-composition-and-hmr.zh.md +0 -113
  515. package/kb/extra/cordis-tutorial/07-into-the-harness.md +0 -108
  516. package/kb/extra/cordis-tutorial/07-into-the-harness.zh.md +0 -108
  517. package/kb/extra/cordis-tutorial/index.md +0 -60
  518. package/kb/extra/cordis-tutorial/index.zh.md +0 -62
  519. package/kb/extra/experimental-persistence-catalog.md +0 -17
  520. package/kb/extra/experimental-persistence-catalog.zh.md +0 -17
  521. package/kb/extra/persistence-catalog.md +0 -9140
  522. package/kb/extra/persistence-catalog.zh.md +0 -9142
  523. package/kb/extra/subsystems/README.md +0 -76
  524. package/kb/extra/subsystems/README.zh.md +0 -76
  525. package/kb/extra/subsystems/approval.md +0 -170
  526. package/kb/extra/subsystems/approval.zh.md +0 -170
  527. package/kb/extra/subsystems/client-modules.md +0 -198
  528. package/kb/extra/subsystems/client-modules.zh.md +0 -198
  529. package/kb/extra/subsystems/client-resources.md +0 -92
  530. package/kb/extra/subsystems/client-resources.zh.md +0 -92
  531. package/kb/extra/subsystems/commands.md +0 -223
  532. package/kb/extra/subsystems/commands.zh.md +0 -223
  533. package/kb/extra/subsystems/compaction.md +0 -284
  534. package/kb/extra/subsystems/compaction.zh.md +0 -284
  535. package/kb/extra/subsystems/conversation.md +0 -301
  536. package/kb/extra/subsystems/conversation.zh.md +0 -303
  537. package/kb/extra/subsystems/core.md +0 -1113
  538. package/kb/extra/subsystems/core.zh.md +0 -1125
  539. package/kb/extra/subsystems/credentials.md +0 -493
  540. package/kb/extra/subsystems/credentials.zh.md +0 -493
  541. package/kb/extra/subsystems/filesystem.md +0 -530
  542. package/kb/extra/subsystems/filesystem.zh.md +0 -530
  543. package/kb/extra/subsystems/goal.md +0 -313
  544. package/kb/extra/subsystems/goal.zh.md +0 -313
  545. package/kb/extra/subsystems/jobs.md +0 -554
  546. package/kb/extra/subsystems/jobs.zh.md +0 -554
  547. package/kb/extra/subsystems/llm-streaming.md +0 -1196
  548. package/kb/extra/subsystems/llm-streaming.zh.md +0 -1202
  549. package/kb/extra/subsystems/lsp.md +0 -202
  550. package/kb/extra/subsystems/lsp.zh.md +0 -202
  551. package/kb/extra/subsystems/office-to-pdf.md +0 -87
  552. package/kb/extra/subsystems/office-to-pdf.zh.md +0 -87
  553. package/kb/extra/subsystems/permission-presets.md +0 -167
  554. package/kb/extra/subsystems/permission-presets.zh.md +0 -167
  555. package/kb/extra/subsystems/persistence.md +0 -418
  556. package/kb/extra/subsystems/persistence.zh.md +0 -418
  557. package/kb/extra/subsystems/plan.md +0 -87
  558. package/kb/extra/subsystems/plan.zh.md +0 -87
  559. package/kb/extra/subsystems/ptc-runtime.md +0 -250
  560. package/kb/extra/subsystems/ptc-runtime.zh.md +0 -250
  561. package/kb/extra/subsystems/sandbox.md +0 -221
  562. package/kb/extra/subsystems/sandbox.zh.md +0 -221
  563. package/kb/extra/subsystems/schedule.md +0 -550
  564. package/kb/extra/subsystems/schedule.zh.md +0 -550
  565. package/kb/extra/subsystems/scope.md +0 -59
  566. package/kb/extra/subsystems/scope.zh.md +0 -61
  567. package/kb/extra/subsystems/session-projection.md +0 -356
  568. package/kb/extra/subsystems/session-projection.zh.md +0 -356
  569. package/kb/extra/subsystems/session-query.md +0 -511
  570. package/kb/extra/subsystems/session-query.zh.md +0 -511
  571. package/kb/extra/subsystems/session-reference.md +0 -224
  572. package/kb/extra/subsystems/session-reference.zh.md +0 -224
  573. package/kb/extra/subsystems/session-telemetry.md +0 -212
  574. package/kb/extra/subsystems/session-telemetry.zh.md +0 -212
  575. package/kb/extra/subsystems/session-title.md +0 -213
  576. package/kb/extra/subsystems/session-title.zh.md +0 -213
  577. package/kb/extra/subsystems/session.md +0 -1339
  578. package/kb/extra/subsystems/session.zh.md +0 -1343
  579. package/kb/extra/subsystems/settings.md +0 -155
  580. package/kb/extra/subsystems/settings.zh.md +0 -155
  581. package/kb/extra/subsystems/shell.md +0 -314
  582. package/kb/extra/subsystems/shell.zh.md +0 -314
  583. package/kb/extra/subsystems/sidebar-right.md +0 -160
  584. package/kb/extra/subsystems/sidebar-right.zh.md +0 -160
  585. package/kb/extra/subsystems/skills.md +0 -352
  586. package/kb/extra/subsystems/skills.zh.md +0 -352
  587. package/kb/extra/subsystems/slots.md +0 -200
  588. package/kb/extra/subsystems/slots.zh.md +0 -204
  589. package/kb/extra/subsystems/spill.md +0 -124
  590. package/kb/extra/subsystems/spill.zh.md +0 -124
  591. package/kb/extra/subsystems/storage.md +0 -259
  592. package/kb/extra/subsystems/storage.zh.md +0 -259
  593. package/kb/extra/subsystems/subagent.md +0 -686
  594. package/kb/extra/subsystems/subagent.zh.md +0 -688
  595. package/kb/extra/subsystems/subprocess.md +0 -321
  596. package/kb/extra/subsystems/subprocess.zh.md +0 -321
  597. package/kb/extra/subsystems/system-prompt.md +0 -254
  598. package/kb/extra/subsystems/system-prompt.zh.md +0 -254
  599. package/kb/extra/subsystems/terminal.md +0 -184
  600. package/kb/extra/subsystems/terminal.zh.md +0 -184
  601. package/kb/extra/subsystems/token-meter.md +0 -106
  602. package/kb/extra/subsystems/token-meter.zh.md +0 -106
  603. package/kb/extra/subsystems/tools.md +0 -747
  604. package/kb/extra/subsystems/tools.zh.md +0 -747
  605. package/kb/extra/subsystems/typert.md +0 -690
  606. package/kb/extra/subsystems/typert.zh.md +0 -690
  607. package/kb/extra/subsystems/user-questions.md +0 -307
  608. package/kb/extra/subsystems/user-questions.zh.md +0 -307
  609. package/kb/extra/subsystems/web-client.md +0 -100
  610. package/kb/extra/subsystems/web-client.zh.md +0 -100
  611. package/kb/extra/subsystems/web-server.md +0 -302
  612. package/kb/extra/subsystems/web-server.zh.md +0 -302
  613. package/kb/extra/subsystems/web.md +0 -206
  614. package/kb/extra/subsystems/web.zh.md +0 -206
  615. package/kb/extra/subsystems/workflow.md +0 -278
  616. package/kb/extra/subsystems/workflow.zh.md +0 -278
  617. package/kb/extra/subsystems/workspace.md +0 -647
  618. package/kb/extra/subsystems/workspace.zh.md +0 -647
  619. package/kb/extra/tool-catalog.md +0 -2824
  620. package/kb/extra/tool-catalog.zh.md +0 -2832
  621. package/kb/extra/tool-execution-pipeline.md +0 -65
  622. package/kb/extra/tool-execution-pipeline.zh.md +0 -67
@@ -1,651 +1,743 @@
1
- ---
2
- editSource: "docs/subsystems/workspace.zh.md"
3
- rawMarkdownPath: "reference/subsystems/workspace.md"
4
- outline: [2,3]
5
- ---
6
-
7
- # 工作区
8
-
9
- 工作区(workspace)是用户工作目录的持久记录:一个建立在规范路径之上的稳定 id、一个显示标题,以及归属于它的会话的有序账本。该子系统是单个包(package)([dsh-workspace](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/workspace/workspace),`ctx.workspaceRegistry`)——一项宿主侧可选能力,不属于 agent loop(智能体循环)主干,并且对模型不可见(没有工具、没有提示词文本、没有会话事件)。它通过[存储领域数据形式](./storage.md)存储自己的记录,并对照 [`SessionHeader.cwd`](./persistence.md#sessionheader--metadata-beside-the-log) 校验会话成员资格,因此 `storageDomain` 与 `sessionPersistence` 是必需的启动依赖:持久化这一依赖不可用时,插件保持 pending,而不是把这种不可用误当作空历史。设计记录:[领域 KV 存储 Agent Note(agent 决策记录)](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.zh.md);引导与 GUI 顺序:[Workspace UI 产品流程 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/archived/feature/2026-07-25-workspace-ui-product-flow.md)。
10
-
11
- 源码:[`packages/workspace/workspace/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/src/types.ts)
12
-
13
- ## 标识
14
-
15
- ```ts type-equiv
16
- /**
17
- * Identifies one workspace record. A generated uuid, never the path: path
18
- * normalization rewrites paths, and a reference anchor must stay stable.
19
- */
20
- type WorkspaceId = Branded<'WorkspaceId'>
21
- ```
22
-
23
- `WorkspaceId` 是[品牌化 id](./core.md#branded-ids)。路径标识与之分离:`realpathNormalize`(`fs.realpath`;尾部斜杠、`..` 与符号链接全部解析)是唯一的一套唯一性规范——工作区路径以规范化形式存储,唯一性即规范路径的字符串相等(指向已被拥有目录的符号链接会与之冲突),attach 时的会话 cwd 检查也走同一套规范。
24
-
25
- ## 工作区实体
26
-
27
- 消费方只看到 `Workspace` 接口;实现保持包内私有。
28
-
29
- ```ts type-equiv
30
- /**
31
- * One workspace: a stable id over an existing directory, a display title, and
32
- * an ordered candidate account of sessions. Membership validates header cwd
33
- * against the workspace path, but preserves an existing account when its
34
- * fully qualified cwd is missing. Consumers only see this interface; the
35
- * implementation stays private.
36
- */
37
- interface Workspace {
38
- /** Stable record id (generated uuid). */
39
- readonly id: WorkspaceId
40
-
41
- /**
42
- * Canonical directory path: the `fs.realpath` of the path given at create
43
- * time (trailing slashes, `..`, and symlinks all resolved). Never rewritten
44
- * afterwards, even when the directory disappears (see {@link status}).
45
- */
46
- readonly path: string
47
-
48
- /** Display title. Defaults to the final path segment, or a filesystem root's own spelling; duplicates are allowed. */
49
- readonly title: string
50
-
51
- /** ISO-8601 creation instant, stamped at create and never rewritten. */
52
- readonly createdAt: string
53
-
54
- /** ISO-8601 instant of the last durable mutation (create counts as one). */
55
- readonly updatedAt: string
56
-
57
- /**
58
- * Header-validated sessions in manually owned order: a new session is
59
- * prepended at attach, explicit reordering goes through
60
- * `insertSessionBefore`, and activity never reorders. The durable candidate
61
- * account is filtered synchronously: missing headers, invalid cwd values,
62
- * and canonical cwd mismatches are never returned. A fully qualified cwd
63
- * whose realpath or directory stat fails with ENOENT preserves an existing
64
- * candidate, including a dangling symlink; other filesystem failures do not.
65
- * A subsequent mutation prunes filtered candidates, not missing-directory
66
- * candidates. This does not admit new sessions or recreate directories.
67
- */
68
- readonly sessionIds: readonly SessionId[]
69
-
70
- /**
71
- * Replace the display title durably.
72
- * @param title - New title; any string, duplicates across workspaces allowed.
73
- * @returns resolution after durability.
74
- */
75
- setTitle(title: string): Promise<void>
76
-
77
- /**
78
- * Prepend a session to this workspace's candidate account. An already
79
- * accounted id resolves without writing, aside from the durable
80
- * filtered-candidate prune every accepted mutation performs. A new id's
81
- * live or persisted
82
- * header cwd must resolve to an existing directory equal to {@link path};
83
- * unknown ids, missing or invalid cwd values, and mismatches reject without
84
- * writing.
85
- * @param sessionId - The session to record.
86
- * @returns resolution after durability.
87
- */
88
- attachSession(sessionId: SessionId): Promise<void>
89
-
90
- /**
91
- * Move an accounted session within the manual order, DOM-insertBefore-like:
92
- * with an anchor the session lands before it, without one it appends to the
93
- * end. Only the moved id changes position. A session or anchor absent from
94
- * the account rejects without writing; a move to the current position
95
- * resolves without writing, aside from the durable filtered-candidate
96
- * prune every accepted mutation performs; decided on the domain write
97
- * chain.
98
- * @param sessionId - The accounted session to move.
99
- * @param beforeSessionId - Accounted anchor to insert before; omitted appends.
100
- * @returns resolution after durability.
101
- */
102
- insertSessionBefore(sessionId: SessionId, beforeSessionId?: SessionId): Promise<void>
103
-
104
- /**
105
- * Remove a session from this workspace's account. Idempotent: an id not on
106
- * the account resolves without writing, aside from the durable
107
- * filtered-candidate prune every accepted mutation performs; decided on
108
- * the domain write chain like attach. Never touches the session's own stored log.
109
- * @param sessionId - The session to remove.
110
- * @returns resolution after durability.
111
- */
112
- detachSession(sessionId: SessionId): Promise<void>
113
-
114
- /**
115
- * Live directory check, uncached: whether {@link path} currently exists and
116
- * is a directory. A missing directory never mutates the record — the
117
- * directory may only be temporarily moved.
118
- * @returns `'ok'` when the directory exists, `'missing-dir'` otherwise.
119
- */
120
- status(): Promise<'ok' | 'missing-dir'>
121
- }
122
- ```
123
-
124
- 所有权的真源是记录中有序的 `sessionIds`,绝不从会话 cwd 派生。成员资格将记录的 header cwd 与工作区路径校验;已有候选的完全限定 cwd 在路径解析或目录 stat 时返回 `ENOENT`,仍保留其归属。这会保留目录缺失或符号链接失效时的记账关系,但不会接纳新会话。失败的写入会拒绝(`insertSessionBefore` 的账本错误以 `WorkspaceMoveInvalidError` 拒绝,存储失败以普通错误拒绝);每次被接受的变更都盖上 `updatedAt` 时间戳,并持久修剪不再通过成员资格检查的候选项。
125
-
126
- ## 注册表:`ctx.workspaceRegistry`
127
-
128
- `WorkspaceRegistry`([签名](#ctxworkspaceregistry--workspaceregistry))拥有注册与解析。`create(path, title?)` 要求完全限定路径并将其规范化,拒绝不存在的路径(原样传出原始 `ENOENT`)或非目录;当规范路径已被拥有时原样返回既有实体;否则创建一条标题为 `title ?? defaultWorkspaceTitle(path)` 的记录并前插到持久的注册表顺序中(不同规范路径可以共享同一显示标题,没有最终路径段时使用根路径拼写)。`get(id)` 与有序的 `list()` 是同步缓存读取;`resolveByPath(path)` 应用同一套完全限定 realpath 规范但不创建。`delete(id)` 只移除注册记录、顺序条目和会话账本——目录、用户文件、实时会话和已持久化日志一概不动,因此这些会话变为 Ungrouped([参考](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/README.zh.md));未知 id 返回 `false`。create 与 delete 会在其两次写入(记录 + 顺序)可能分叉之前先持久写入一个待定变更标记;启动时恰好解决被标记的那次变更——通过删除被标记的表行:这会补完被中断的 delete,并回滚被中断的 create(注册可以重建,因此回滚是安全方向)——而没有标记的顺序/表不一致则作为损坏大声失败。
129
-
130
- 会话的 cwd 在创建时由创建者赋予,而不是由本注册表赋予——API 网关从所选工作区的 `path` 解析新会话的 cwd(回退到显式或默认 cwd),先创建会话使 cwd 落入其不可变的 [`SessionHeader`](./persistence.md#sessionheader--metadata-beside-the-log),再调用 `attachSession`,后者会把已存储的 header cwd 与工作区路径重新校验一遍。首次成功启动时,注册表仅凭已持久化的 header(`id`、`cwd`、`createdAt`——绝不读事件正文)引导历史:把规范 cwd 有效的会话按目录分组为工作区,最新的排在最前;「已初始化」标记最后写入,因此被中断的引导可以安全续跑。引导只发生这一次:没有 cwd 的历史遗留会话保持 Ungrouped,此后创建的会话只能通过 `attachSession` 加入工作区。
131
-
132
- ## 默认工作区初始化
133
-
134
- 控制器的 `initializeDefault` 不接受请求参数:它拥有固定目录名 `default-workspace`,解析 Documents 位置,并请求注册表执行一次初始化。注册表接收目录解析器,以所请求目录(而非规范路径)的最后一段作为初始标题,并将登记与持久化身份一起提交。语言不会传到 Host——浏览器消费方通过控制器的 `workspaceDisplayTitle` 为仍保留该自动标题的工作区加标签,因此只有屏幕上的名称跟随读者语言。[首次使用行为与配置](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-controller/README.zh.md#first-use-workspace)说明复用和失败处理。
135
-
136
- ## 会话置顶
137
-
138
- 控制器的[传输类型](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-controller/src/types.ts)定义了 `WorkspacePinSessionRequest` 和 `WorkspaceUnpinSessionRequest`,两者都携带一个 `sessionId`。两个操作都返回 `WorkspacePinValue`:完整的会话 id 数组 `pinnedSessionIds`,最近置顶的会话排在前面。置顶要求会话已知且未归档;对未置顶的 id 取消置顶会成功,且不改变集合。归档在同一次持久化写入中移除该会话的置顶,取消归档不会恢复置顶。
139
-
140
- ## 归档准入
141
-
142
- 归档是一个注册表全局的持久化集合,注册表拒绝把正在运行的工作藏在它后面。这条规则是本包声明并派发的两个宿主事件之上的能力接缝([事件](#workspace-events)):`workspace/session-activity`(waterfall)向已组合的提供方询问某会话还有什么在跑,`workspace/session-stop`(parallel)请它们停止这些工作。每个提供方像任何监听器一样在根上注册,因此本包不认识 agent、job 或 schedule 的词汇;各族是一个可合并扩展的 map 的键。
143
-
144
- ```ts type-equiv
145
- /**
146
- * Activity families a `workspace/session-activity` listener may report. This
147
- * package declares none: each provider merges its own key from a module both
148
- * its Host and Client faces import, so a consumer that renders the families
149
- * sees exactly the keys its program compiled and falls through to a generic
150
- * description for any other. The shipped providers merge `turn` (the Agent
151
- * registry), `job` (the job registry seam), `subagent` (the Subagent
152
- * runtime), and `schedule` (the Schedule plugin).
153
- */
154
- interface SessionActivityKindMap {}
155
- ```
156
-
157
- `SessionActivityKind` 即 `keyof SessionActivityKindMap`,因此一个没有编译任何提供方的程序看不到任何键。随附的键放在各自 client 可导入的类型模块里:`turn` 在 Agent 注册表的 `types.ts`,`job` 在任务注册表接缝的 `view.ts`,`subagent` 在 Subagent runtime 的 `control-types.ts`,`schedule` 在 Schedule 插件的 `types.ts`;渲染各族的消费方为其分支导入这些模块,并为其他任何键保留一条通用文案。提供方通过把自己的 `SessionActivity` 条目前置到 `next()` 的结果来回答 waterfall;注册表最内层的回调返回空列表,因此没有提供方的组合可自由归档。
158
-
159
- ```ts type-equiv
160
- /**
161
- * One reason a session counts as active for archive admission. Families with
162
- * per-item identity list their items so a caller can name what must stop.
163
- */
164
- interface SessionActivity {
165
- readonly kind: SessionActivityKind
166
- /** Active items of the family; absent for a family without per-item identity (`turn`). */
167
- readonly items?: readonly SessionActivityItem[]
168
- }
169
- ```
170
-
171
- `SessionActivityItem` 携带各族自己的 `id`(会话、任务或提醒 id)和可选的展示 `label`。`archiveSession(sessionId)` 在存在性检查之后只询问 waterfall 一次,对非空答案以 `WorkspaceActiveSessionError`(`sessionId`、`activity`)拒绝且不写入;控制器把它映射为 `workspace/session-active` 错误,其 details 携带同样的两个字段。`archiveSession(sessionId, { stopActivity: true })`——`ArchiveSessionOptions` 的这个字段由传输请求以 `stopActivity` 暴露——跳过检查、先写入归档、再派发 `workspace/session-stop`;提供方抛错只记日志,归档保留,被停止的工作从不等待收敛。已归档的 id 既不询问也不停止。随附的提供方、它们停止什么,以及让已归档会话不跑模型步的 `agent/pre-step` 门禁,记录在[注册表包](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/README.zh.md#api-behavior);决策记录见 [archive-stops-running-work Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.zh.md)。
172
-
173
- ## 消费方
174
-
175
- [`dsh-workspace-controller`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/api/workspace-controller) 经 `ctx.workspaceRegistry` 向 GUI 客户端提供工作区 CRUD,[`dsh-session-controller`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/api/session-controller) 执行上文「先建会话再 attach」的流程。[dsh-agent-instructions](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/context/agent-instructions) 尽管名字如此,却**不是**消费方:它在 agent 自己的 cwd 下发现 AGENTS.md 风格的指令文件,从不触碰 `ctx.workspaceRegistry`——两者共用的这个词指的是用户的工作目录,而非本注册表的实体。
176
-
177
- <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
178
-
179
- <a id="cordis-surface"></a>
180
-
181
- ## Cordis API
182
-
183
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
184
-
185
- <a id="ctxdirectorypicker--directorypicker-abstract-seam"></a>
186
-
187
- ### `ctx.directoryPicker` — `DirectoryPicker` (abstract seam)
188
-
189
- Abstract directory-picking service. Subclass, implement `capability()`, and load the subclass as a plugin — it registers as `ctx.directoryPicker` (one implementation per context; loading a second throws, cordis' standard duplicate-service behavior). The capability object must be stable for the service lifetime: consumers may capture it across calls.
190
-
191
- ```ts cordis-catalog
192
- /**
193
- * The backend's interaction capability.
194
- * @returns the discriminated capability consumers switch on.
195
- */
196
- abstract capability(): DirectoryPickerCapability
197
- ```
198
-
199
- Source: [`packages/host/directory-picker/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/directory-picker/src/index.ts)
200
-
201
- <a id="ctxdirectorypickercontroller--directorypickercontroller"></a>
202
-
203
- ### `ctx.directoryPickerController` — `DirectoryPickerController`
204
-
205
- Host service backing the generated `ctx.remote.directoryPicker` namespace. The seam it exports is abstract and therefore never a Loader entry of its own, so this controller carries the wire verbs: one composed backend serves either the native chooser or the browse primitives, and a verb the composition cannot serve is refused rather than approximated.
206
-
207
- ```ts cordis-catalog
208
- /**
209
- * Open the host's OS chooser for a Remote caller.
210
- * @param signal - caller lifetime; abort terminates the chooser.
211
- * @returns the chosen absolute path, or null when the operator cancels.
212
- */
213
- @Remote('pick') async pick(signal: AbortSignal): Promise<string | null>
214
-
215
- /**
216
- * List one directory level for a Remote caller's in-app browser.
217
- * @param path - absolute directory to list; absent lists the home directory.
218
- * @param signal - caller lifetime; abort stops the backend's scan instead of
219
- * letting it outlive a disconnected caller.
220
- * @returns the level's listing with its ancestry.
221
- */
222
- @Remote('list') async list(path: string | undefined, signal: AbortSignal): Promise<DirectoryListing>
223
-
224
- /**
225
- * Create one child directory for a Remote caller's in-app browser.
226
- * @param path - absolute existing parent directory.
227
- * @param name - single non-blank path segment.
228
- * @returns the created directory's absolute path.
229
- */
230
- @Remote('createDirectory') async createDirectory(path: string, name: string): Promise<string>
231
- ```
232
-
233
- Source: [`packages/api/workspace-controller/src/directory-picker.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-controller/src/directory-picker.ts)
234
-
235
- <a id="ctxterminalcontroller--terminalcontroller"></a>
236
-
237
- ### `ctx.terminalController` — `TerminalController`
238
-
239
- Typed Remote control of transient Session-owned terminal processes.
240
-
241
- ```ts cordis-catalog
242
- /**
243
- * Read the Session's current directory and terminal limits without filesystem validation or shell lookup.
244
- * @param agent - Session owner supplied by the Gateway.
245
- * @param signal - request cancellation.
246
- * @returns the logged current directory and terminal limits; retained terminals keep their own process directories.
247
- */
248
- @Remote environment(agent: Agent, signal: AbortSignal): TerminalEnvironment
249
-
250
- /**
251
- * Discover installed shells in the Session's execution environment.
252
- * @param agent - Session owner supplied by the Gateway.
253
- * @param signal - request cancellation.
254
- * @returns verified profiles, with the configured or system default first.
255
- */
256
- @Remote shells(agent: Agent, signal: AbortSignal): Promise<TerminalShell[]>
257
-
258
- /**
259
- * List retained terminals without resolving or activating an Agent.
260
- * @param sessionId - displayed Session identity, including offline history.
261
- * @returns terminals retained for this Host lifetime.
262
- */
263
- @Remote list(sessionId: SessionId): WebTerminalInfo[]
264
-
265
- /**
266
- * Allocate a user shell once for a caller-generated identity, without Agent sandbox or approval restrictions.
267
- * @param agent - Session owner supplied by the Gateway.
268
- * @param request - initial dimensions and idempotency identity.
269
- * @param signal - allocation cancellation; committed terminals survive disconnection.
270
- * @returns the existing or newly committed terminal.
271
- */
272
- @Remote async create(agent: Agent, request: TerminalCreateRequest, signal: AbortSignal): Promise<WebTerminalInfo>
273
-
274
- /**
275
- * Retain an existing terminal for a window without activating its Agent or taking input control.
276
- * @param sessionId - owning Session identity, including an inactive saved layout.
277
- * @param id - retained Host terminal identity.
278
- * @param signal - physical Remote stream cancellation.
279
- * @returns a hold acknowledgement followed by an open lifetime stream.
280
- */
281
- @Remote({ mode: 'stream' }) retain(sessionId: SessionId, id: WebTerminalId, signal: AbortSignal): AsyncIterable<TerminalRetentionFrame>
282
-
283
- /**
284
- * Attach terminal input and output to one physical Remote stream.
285
- * @param agent - Session owner supplied by the Gateway.
286
- * @param id - terminal identity.
287
- * @param signal - attachment cancellation; the process remains alive and input is never replayed.
288
- * @returns screen recovery, output, writable state and provider-acceptance acknowledgements.
289
- */
290
- @Remote({ mode: 'stream' }) attach(agent: Agent, id: WebTerminalId, signal: AbortSignal): RemoteStream<TerminalFrame, TerminalInput>
291
-
292
- /**
293
- * Rename a terminal without changing its shell.
294
- * @param agent - Session owner supplied by the Gateway.
295
- * @param id - terminal identity.
296
- * @param title - nonempty display title, at most 120 characters.
297
- */
298
- @Remote rename(agent: Agent, id: WebTerminalId, title: string): void
299
-
300
- /**
301
- * Close an identity to future creation and kill its process range; repeated closes succeed.
302
- * @param agent - Session owner supplied by the Gateway.
303
- * @param id - terminal identity.
304
- * @returns after provider cleanup succeeds. A failure retains the terminal for retry.
305
- */
306
- @Remote async close(agent: Agent, id: WebTerminalId): Promise<void>
307
- ```
308
-
309
- Types: [Agent](./core.md) · [RemoteStream](./typert.md) · [SessionId](./core.md)
310
-
311
- Source: [`packages/api/terminal-controller/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/terminal-controller/src/index.ts)
312
-
313
- <a id="ctxworkspacecontroller--workspacecontroller"></a>
314
-
315
- ### `ctx.workspaceController` — `WorkspaceController`
316
-
317
- Host service backing the generated `ctx.remote.workspace` namespace.
318
-
319
- ```ts cordis-catalog
320
- /**
321
- * Create or idempotently resolve one Workspace over an existing directory.
322
- * @param request - directory path to register.
323
- * @returns the Workspace and whether this call created it.
324
- */
325
- @Remote('create') create(request: WorkspaceCreateRequest): Promise<WorkspaceCreateValue>
326
-
327
- /**
328
- * Initialize or reuse the default Workspace during first-use startup. The
329
- * directory name is fixed, so the Host never renames or relocates an
330
- * existing default; its initial title is that same name, which browser
331
- * consumers label in the reader's language.
332
- * @param signal - caller lifetime; cancels native directory lookup.
333
- * @returns the durable Workspace, or undefined when first-use initialization is ineligible; creates no Session or message.
334
- */
335
- @Remote('initializeDefault') async initializeDefault(signal: AbortSignal): Promise<WorkspaceValue | undefined>
336
-
337
- /**
338
- * Rename one Workspace to a unique non-blank title.
339
- * @param request - Workspace identity and proposed title.
340
- * @returns the updated Workspace projection.
341
- */
342
- @Remote('rename') rename(request: WorkspaceRenameRequest): Promise<WorkspaceValue>
343
-
344
- /**
345
- * Remove one Workspace registration while retaining files and Sessions.
346
- * @param request - Workspace identity to remove.
347
- * @returns deletion confirmation.
348
- */
349
- @Remote('delete') delete(request: WorkspaceDeleteRequest): Promise<WorkspaceDeleteValue>
350
-
351
- /**
352
- * Move one Workspace within the registry display order.
353
- * @param request - moved Workspace and optional anchor.
354
- * @returns the complete resulting Workspace order.
355
- */
356
- @Remote('insertBefore') insertBefore(request: WorkspaceInsertBeforeRequest): Promise<WorkspaceOrderValue>
357
-
358
- /**
359
- * Move one accounted Session within a Workspace.
360
- * @param request - Workspace, Session, and optional anchor identities.
361
- * @returns the updated Workspace projection.
362
- */
363
- @Remote('insertSessionBefore') insertSessionBefore(request: WorkspaceInsertSessionBeforeRequest): Promise<WorkspaceValue>
364
-
365
- /**
366
- * Hide one known Session from Workspace grouping surfaces.
367
- * @param request - Session identity to archive.
368
- * @returns the complete resulting archive set.
369
- */
370
- @Remote('archiveSession') archiveSession(request: WorkspaceArchiveSessionRequest): Promise<WorkspaceArchiveValue>
371
-
372
- /**
373
- * Restore one archived Session to Workspace grouping surfaces.
374
- * @param request - Session identity to unarchive.
375
- * @returns the complete resulting archive set.
376
- */
377
- @Remote('unarchiveSession') unarchiveSession(request: WorkspaceUnarchiveSessionRequest): Promise<WorkspaceArchiveValue>
378
-
379
- /**
380
- * Surface one known unarchived Session ahead of unpinned Sessions.
381
- * @param request - Session identity to pin.
382
- * @returns the complete resulting pin set, most recently pinned first.
383
- */
384
- @Remote('pinSession') pinSession(request: WorkspacePinSessionRequest): Promise<WorkspacePinValue>
385
-
386
- /**
387
- * Remove one Session's pin without changing its saved Session order.
388
- * @param request - Session identity to unpin.
389
- * @returns the complete resulting pin set, most recently pinned first.
390
- */
391
- @Remote('unpinSession') unpinSession(request: WorkspaceUnpinSessionRequest): Promise<WorkspacePinValue>
392
-
393
- /**
394
- * Stream a complete Workspace baseline followed by ordered increments. A
395
- * non-owner receives only the Workspaces and Sessions `allows()` admits.
396
- * When a delivered Workspace is no longer admitted at its next change or
397
- * the next order change, the stream sends a `replace` frame with the
398
- * complete filtered state instead of a `remove`, because a Client never
399
- * resurrects a removed Workspace; a `remove` frame reports a deletion and
400
- * reaches only a Client that received that Workspace.
401
- * @param signal - generation cancellation.
402
- * @returns baseline followed by ordered Workspace increments.
403
- */
404
- @Remote({ mode: 'stream' }) async *follow(signal: AbortSignal): AsyncIterable<WorkspaceFollowFrame>
405
- ```
406
-
407
- Source: [`packages/api/workspace-controller/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-controller/src/index.ts)
408
-
409
- <a id="ctxworkspacefiles--workspacefiles"></a>
410
-
411
- ### `ctx.workspaceFiles` — `WorkspaceFiles`
412
-
413
- Host Remote file reads and workspace directory observations over the composed filesystem.
414
-
415
- ```ts cordis-catalog
416
- /**
417
- * Read one page of lines from a UTF-8 file readable by the filesystem backend.
418
- * @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
419
- * @param path - absolute path or path relative to the workspace root; files outside it are allowed.
420
- * @param range - the line window; omitted fields take the page defaults.
421
- * @param signal - caller cancellation.
422
- * @returns the page, the file's version at the stat before it, and whether it reaches the last line.
423
- */
424
- @Remote async read( workspaceFileScope: WorkspaceFileScope, path: string, range: WorkspaceFileRange, signal: AbortSignal, ): Promise<WorkspaceFileText>
425
-
426
- /**
427
- * Read a complete regular file or one byte range without text decoding.
428
- * @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
429
- * @param path - target path, absolute or workspace-relative; relative to the base file's directory when provided.
430
- * @param options - optional base file and range; without a range the complete-file cap applies.
431
- * @param signal - caller cancellation.
432
- * @returns native bytes with the file's version and size at the preceding stat, byte offset, and EOF marker.
433
- */
434
- @Remote async readBytes( workspaceFileScope: WorkspaceFileScope, path: string, options: WorkspaceByteReadOptions, signal: AbortSignal, ): Promise<WorkspaceFileBytes>
435
-
436
- /**
437
- * Report one regular file's identity, version, and size without its content.
438
- * @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
439
- * @param path - absolute path or path relative to the workspace root; files outside it are allowed.
440
- * @param signal - caller cancellation.
441
- * @returns the file's absolute path, current version, and byte size.
442
- */
443
- @Remote async stat(workspaceFileScope: WorkspaceFileScope, path: string, signal: AbortSignal): Promise<WorkspaceFileStat>
444
-
445
- /**
446
- * List the direct children of one directory inside the Session's workspace.
447
- * @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
448
- * @param path - workspace path, absolute or relative to the workspace root.
449
- * @param signal - caller cancellation.
450
- * @returns the directory's children in the backend's stable name order, bounded by the entry cap.
451
- */
452
- @Remote async list(workspaceFileScope: WorkspaceFileScope, path: string, signal: AbortSignal): Promise<WorkspaceDirectoryListing>
453
-
454
- /**
455
- * Watch one file or a directory's direct entries in the Session's filesystem.
456
- * Files use the backend's read authority; directories remain workspace-scoped.
457
- * @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
458
- * @param path - target path; the Host determines its type and confines directories to the workspace.
459
- * @param signal - generation cancellation.
460
- * @returns `ready` once the target watch is active, then current metadata for queued and live invalidations.
461
- * @throws RemoteError when watching is unavailable or a directory is outside the workspace.
462
- */
463
- @Remote({ mode: 'stream' }) changes(workspaceFileScope: WorkspaceFileScope, path: string, signal: AbortSignal): AsyncIterable<WorkspaceFileWatchFrame>
464
- ```
465
-
466
- Source: [`packages/api/workspace-files/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-files/src/index.ts)
467
-
468
- <a id="ctxworkspaceregistry--workspaceregistry"></a>
469
-
470
- ### `ctx.workspaceRegistry` — `WorkspaceRegistry`
471
-
472
- Durable workspace registry. Startup waits for `sessionPersistence`, builds one canonical-cwd header index, and completes the one-time history bootstrap before the service becomes active. The persistence dependency is mandatory so an unavailable peer can never be mistaken for an empty history and commit the initialized marker.
473
-
474
- ```ts cordis-catalog
475
- /**
476
- * Create or reuse a workspace for an existing directory. The fully qualified
477
- * path is canonicalized through `fs.realpath`; a relative, nonexistent, or
478
- * non-directory path rejects. Repeated calls for the same canonical path
479
- * return the existing entity without changing its title.
480
- * A newly created workspace is prepended to the durable registry order.
481
- * Different canonical paths may share a display title.
482
- * @param path - Existing directory to own, in a fully qualified path spelling.
483
- * @param title - Display title used only when a new record is created.
484
- * @returns the existing or newly durable workspace.
485
- */
486
- async create(path: string, title?: string): Promise<Workspace>
487
-
488
- /**
489
- * Initialize the default Workspace only while both the registry and Session
490
- * history are empty. Repeated requests reuse its durable identity; deleting
491
- * that registration permanently disables automatic creation.
492
- * @param resolveDirectory - resolve the absolute directory; called only for
493
- * eligible creation, inside the registry mutation queue. Missing directories
494
- * are created recursively before registration, and the initial title is the
495
- * requested directory's own final segment — not the canonical one, so a
496
- * symlink at that path does not retitle the Workspace after its target.
497
- * After resolution, caller cancellation does not roll back creation or registration.
498
- * @returns the initialized Workspace, or undefined when automatic creation is ineligible.
499
- */
500
- initializeDefault(resolveDirectory: () => Promise<string>): Promise<Workspace | undefined>
501
-
502
- /**
503
- * Look up a workspace by id.
504
- * @param id - Workspace id.
505
- * @returns the workspace, or `undefined` when unknown.
506
- */
507
- get(id: WorkspaceId): Workspace | undefined
508
-
509
- /**
510
- * Synchronous workspace projection in durable registry order. Every
511
- * entity's `sessionIds` getter is already filtered by the startup/live
512
- * canonical-cwd header index; this method performs no persistence reads.
513
- * @returns a fresh ordered array of workspace entities.
514
- */
515
- list(): Workspace[]
516
-
517
- /**
518
- * Delete one workspace registration while retaining its directory and every
519
- * session log. The durable order is updated before the table deletion; a
520
- * failed table write restores the prior order and keeps the entity
521
- * published. Unknown ids are an idempotent no-op for domain callers.
522
- * @param id - Workspace registration to remove.
523
- * @returns `true` when a record was deleted, `false` when it was unknown.
524
- */
525
- delete(id: WorkspaceId): Promise<boolean>
526
-
527
- /**
528
- * Move one workspace within the durable display order, DOM-insertBefore-like.
529
- * With an anchor it lands before that workspace; without one it appends.
530
- * @param id - Workspace to move.
531
- * @param beforeId - Workspace anchor; omitted appends.
532
- * @returns the complete committed workspace order.
533
- */
534
- insertBefore(id: WorkspaceId, beforeId?: WorkspaceId): Promise<readonly WorkspaceId[]>
535
-
536
- /**
537
- * Archive one session durably. The session must exist (live or in session
538
- * persistence); its workspace accounting — or lack of one — is irrelevant.
539
- * Without `stopActivity` the session must also be inactive: the
540
- * `workspace/session-activity` waterfall is asked once, and any reported
541
- * activity rejects with {@link WorkspaceActiveSessionError} before anything
542
- * is written. With `stopActivity` the archive is written without an
543
- * activity check, and the `workspace/session-stop` providers are then asked
544
- * to stop the session's work: the durable archive set is what a provider's
545
- * `agent/pre-step` gate reads, so every wake the stops induce is already
546
- * blocked. Archiving drops the session's pin in the same durable write
547
- * (pinning and archival are mutually exclusive). An already archived id
548
- * resolves without writing, asking, or stopping.
549
- * @param sessionId - The session to archive.
550
- * @param options - Whether running work is stopped instead of refusing.
551
- * @returns resolution after durability and, with `stopActivity`, after every stop request was issued.
552
- */
553
- archiveSession(sessionId: SessionId, options: ArchiveSessionOptions = {}): Promise<void>
554
-
555
- /**
556
- * Unarchive one session durably by dropping it from the registry-global
557
- * archive set; the accounting slot was never touched, so the session
558
- * returns to its recorded position. Unarchiving runs no session-existence
559
- * check because removing an id cannot introduce an unknown one, so an
560
- * entry whose session is gone still resolves. An id that is not archived
561
- * resolves without writing.
562
- * @param sessionId - The session to unarchive.
563
- * @returns resolution after durability.
564
- */
565
- unarchiveSession(sessionId: SessionId): Promise<void>
566
-
567
- /**
568
- * Pin one session durably, prepending it to the registry-global pin set.
569
- * The session must exist (live or in session persistence) and must not be
570
- * archived. An already pinned id resolves without writing or reordering.
571
- * @param sessionId - The session to pin.
572
- * @returns resolution after durability.
573
- */
574
- pinSession(sessionId: SessionId): Promise<void>
575
-
576
- /**
577
- * Unpin one session durably by dropping it from the registry-global pin
578
- * set. Unpinning runs no session-existence check because removing an id
579
- * cannot introduce an unknown one, so an entry whose session is gone still
580
- * resolves. An id that is not pinned resolves without writing.
581
- * @param sessionId - The session to unpin.
582
- * @returns resolution after durability.
583
- */
584
- unpinSession(sessionId: SessionId): Promise<void>
585
-
586
- /**
587
- * Resolve by canonical directory path without creating or mutating a
588
- * workspace. A missing path rejects during `realpath`; an existing unowned
589
- * directory returns `undefined`.
590
- * @param path - Existing directory path in a fully qualified spelling.
591
- * @returns the workspace owning the canonical path, when one exists.
592
- */
593
- async resolveByPath(path: string): Promise<Workspace | undefined>
594
- ```
595
-
596
- Types: [SessionId](./core.md)
597
-
598
- Source: [`packages/workspace/workspace/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/src/index.ts)
599
-
600
- <a id="workspace-events"></a>
601
-
602
- ### `workspace/*` events
603
-
604
- <a id="workspacesession-activity--waterfall"></a>
605
-
606
- #### `workspace/session-activity` — waterfall
607
-
608
- Ask the composed providers what still runs for a session before it is archived. A listener prepends its own SessionActivity entries to the result of `next()`; the registry's innermost callback returns an empty list, so a composition without providers archives freely. Any non-empty result refuses the archive without a write.
609
-
610
- ```ts cordis-catalog
611
- /**
612
- * Ask the composed providers what still runs for a session before it is
613
- * archived. A listener prepends its own {@link SessionActivity} entries to
614
- * the result of `next()`; the registry's innermost callback returns an
615
- * empty list, so a composition without providers archives freely. Any
616
- * non-empty result refuses the archive without a write.
617
- * @param request - the session about to be archived.
618
- * @param next - delegate to the remaining providers.
619
- * @mode waterfall
620
- */
621
- 'workspace/session-activity'( request: SessionActivityRequest, next: () => Promise<readonly SessionActivity[]>, ): Promise<readonly SessionActivity[]>
622
- ```
623
-
624
- Source: [`packages/workspace/workspace/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/src/index.ts)
625
-
626
- <a id="workspacesession-stop--parallel"></a>
627
-
628
- #### `workspace/session-stop` — parallel
629
-
630
- Stop a session's running work because the caller archived it with `stopActivity`; the archive set is durable when this dispatches. Each provider stops its own families — cancelling a turn, its subagent descendants, owned jobs, or active schedules — through the same cancel paths the user's own stop actions use, so the session log ends every open turn regularly and a later unarchive can continue the conversation. Listeners issue their stop requests without waiting for running work to settle; a listener may await its own durability barrier. A rejection is logged by the registry and does not undo the archive.
631
-
632
- ```ts cordis-catalog
633
- /**
634
- * Stop a session's running work because the caller archived it with
635
- * `stopActivity`; the archive set is durable when this dispatches. Each
636
- * provider stops its own families — cancelling a turn, its subagent
637
- * descendants, owned jobs, or active schedules — through the same cancel
638
- * paths the user's own stop actions use, so the session log ends every
639
- * open turn regularly and a later unarchive can continue the
640
- * conversation. Listeners issue their stop requests without waiting for
641
- * running work to settle; a listener may await its own durability
642
- * barrier. A rejection is logged by the registry and does not undo the
643
- * archive.
644
- * @param request - the session being archived.
645
- * @mode parallel
646
- */
647
- 'workspace/session-stop'(request: SessionActivityRequest): Promise<void> | void
648
- ```
649
-
650
- Source: [`packages/workspace/workspace/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/src/index.ts)
651
- <!-- END GENERATED cordis-surface -->
1
+ ---
2
+ editSource: "docs/subsystems/workspace.zh.md"
3
+ rawMarkdownPath: "reference/subsystems/workspace.md"
4
+ outline: [2,3]
5
+ ---
6
+
7
+ # 工作区
8
+
9
+ 工作区(workspace)是用户工作目录的持久记录:一个建立在规范路径之上的稳定 id、一个显示标题,以及归属于它的会话的有序账本。该子系统是单个包(package)([dsh-workspace](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/workspace/workspace),`ctx.workspaceRegistry`)——一项宿主侧可选能力,不属于 agent loop(智能体循环)主干,并且对模型不可见(没有工具、没有提示词文本、没有会话事件)。它通过[存储领域数据形式](./storage.md)存储自己的记录,并对照 [`SessionHeader.cwd`](./persistence.md#sessionheader--metadata-beside-the-log) 校验会话成员资格,因此 `storageDomain` 与 `sessionPersistence` 是必需的启动依赖:持久化这一依赖不可用时,插件保持 pending,而不是把这种不可用误当作空历史。设计记录:[领域 KV 存储 Agent Note(agent 决策记录)](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.zh.md);引导与 GUI 顺序:[Workspace UI 产品流程 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/archived/feature/2026-07-25-workspace-ui-product-flow.md)。
10
+
11
+ 源码:[`packages/workspace/workspace/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/src/types.ts)
12
+
13
+ ## 标识
14
+
15
+ ```ts type-equiv
16
+ /**
17
+ * Identifies one workspace record. A generated uuid, never the path: path
18
+ * normalization rewrites paths, and a reference anchor must stay stable.
19
+ */
20
+ type WorkspaceId = Branded<'WorkspaceId'>
21
+ ```
22
+
23
+ `WorkspaceId` 是[品牌化 id](./core.md#branded-ids)。路径标识与之分离:`realpathNormalize`(`fs.realpath`;尾部斜杠、`..` 与符号链接全部解析)是唯一的一套唯一性规范——工作区路径以规范化形式存储,唯一性即规范路径的字符串相等(指向已被拥有目录的符号链接会与之冲突),attach 时的会话 cwd 检查也走同一套规范。
24
+
25
+ ## 工作区实体
26
+
27
+ 消费方只看到 `Workspace` 接口;实现保持包内私有。
28
+
29
+ ```ts type-equiv
30
+ /**
31
+ * One workspace: a stable id over an existing directory, a display title, and
32
+ * an ordered candidate account of sessions. Membership validates header cwd
33
+ * against the workspace path, but preserves an existing account when its
34
+ * fully qualified cwd is missing. Consumers only see this interface; the
35
+ * implementation stays private.
36
+ */
37
+ interface Workspace {
38
+ /** Stable record id (generated uuid). */
39
+ readonly id: WorkspaceId
40
+
41
+ /**
42
+ * Canonical directory path: the `fs.realpath` of the path given at create
43
+ * time (trailing slashes, `..`, and symlinks all resolved). Never rewritten
44
+ * afterwards, even when the directory disappears (see {@link status}).
45
+ */
46
+ readonly path: string
47
+
48
+ /** Display title. Defaults to the final path segment, or a filesystem root's own spelling; duplicates are allowed. */
49
+ readonly title: string
50
+
51
+ /** ISO-8601 creation instant, stamped at create and never rewritten. */
52
+ readonly createdAt: string
53
+
54
+ /** ISO-8601 instant of the last durable mutation (create counts as one). */
55
+ readonly updatedAt: string
56
+
57
+ /**
58
+ * Header-validated sessions in manually owned order: a new session is
59
+ * prepended at attach, explicit reordering goes through
60
+ * `insertSessionBefore`, and activity never reorders. The durable candidate
61
+ * account is filtered synchronously: missing headers, invalid cwd values,
62
+ * and canonical cwd mismatches are never returned. A fully qualified cwd
63
+ * whose realpath or directory stat fails with ENOENT preserves an existing
64
+ * candidate, including a dangling symlink; other filesystem failures do not.
65
+ * A subsequent mutation prunes filtered candidates, not missing-directory
66
+ * candidates. This does not admit new sessions or recreate directories.
67
+ */
68
+ readonly sessionIds: readonly SessionId[]
69
+
70
+ /**
71
+ * Replace the display title durably.
72
+ * @param title - New title; any string, duplicates across workspaces allowed.
73
+ * @returns resolution after durability.
74
+ */
75
+ setTitle(title: string): Promise<void>
76
+
77
+ /**
78
+ * Prepend a session to this workspace's candidate account. An already
79
+ * accounted id resolves without writing, aside from the durable
80
+ * filtered-candidate prune every accepted mutation performs. A new id's
81
+ * live or persisted
82
+ * header cwd must resolve to an existing directory equal to {@link path};
83
+ * unknown ids, missing or invalid cwd values, and mismatches reject without
84
+ * writing.
85
+ * @param sessionId - The session to record.
86
+ * @returns resolution after durability.
87
+ */
88
+ attachSession(sessionId: SessionId): Promise<void>
89
+
90
+ /**
91
+ * Move an accounted session within the manual order, DOM-insertBefore-like:
92
+ * with an anchor the session lands before it, without one it appends to the
93
+ * end. Only the moved id changes position. A session or anchor absent from
94
+ * the account rejects without writing; a move to the current position
95
+ * resolves without writing, aside from the durable filtered-candidate
96
+ * prune every accepted mutation performs; decided on the domain write
97
+ * chain.
98
+ * @param sessionId - The accounted session to move.
99
+ * @param beforeSessionId - Accounted anchor to insert before; omitted appends.
100
+ * @returns resolution after durability.
101
+ */
102
+ insertSessionBefore(sessionId: SessionId, beforeSessionId?: SessionId): Promise<void>
103
+
104
+ /**
105
+ * Remove a session from this workspace's account. Idempotent: an id not on
106
+ * the account resolves without writing, aside from the durable
107
+ * filtered-candidate prune every accepted mutation performs; decided on
108
+ * the domain write chain like attach. Never touches the session's own stored log.
109
+ * @param sessionId - The session to remove.
110
+ * @returns resolution after durability.
111
+ */
112
+ detachSession(sessionId: SessionId): Promise<void>
113
+
114
+ /**
115
+ * Live directory check, uncached: whether {@link path} currently exists and
116
+ * is a directory. A missing directory never mutates the record — the
117
+ * directory may only be temporarily moved.
118
+ * @returns `'ok'` when the directory exists, `'missing-dir'` otherwise.
119
+ */
120
+ status(): Promise<'ok' | 'missing-dir'>
121
+ }
122
+ ```
123
+
124
+ 所有权的真源是记录中有序的 `sessionIds`,绝不从会话 cwd 派生。成员资格将记录的 header cwd 与工作区路径校验;已有候选的完全限定 cwd 在路径解析或目录 stat 时返回 `ENOENT`,仍保留其归属。这会保留目录缺失或符号链接失效时的记账关系,但不会接纳新会话。失败的写入会拒绝(`insertSessionBefore` 的账本错误以 `WorkspaceMoveInvalidError` 拒绝,存储失败以普通错误拒绝);每次被接受的变更都盖上 `updatedAt` 时间戳,并持久修剪不再通过成员资格检查的候选项。
125
+
126
+ ## 注册表:`ctx.workspaceRegistry`
127
+
128
+ `WorkspaceRegistry`([签名](#ctxworkspaceregistry--workspaceregistry))拥有注册与解析。`create(path, title?)` 要求完全限定路径并将其规范化,拒绝不存在的路径(原样传出原始 `ENOENT`)或非目录;当规范路径已被拥有时原样返回既有实体;否则创建一条标题为 `title ?? defaultWorkspaceTitle(path)` 的记录并前插到持久的注册表顺序中(不同规范路径可以共享同一显示标题,没有最终路径段时使用根路径拼写)。`get(id)` 与有序的 `list()` 是同步缓存读取;`resolveByPath(path)` 应用同一套完全限定 realpath 规范但不创建。`delete(id)` 只移除注册记录、顺序条目和会话账本——目录、用户文件、实时会话和已持久化日志一概不动,因此这些会话变为 Ungrouped([参考](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/README.zh.md));未知 id 返回 `false`。create 与 delete 会在其两次写入(记录 + 顺序)可能分叉之前先持久写入一个待定变更标记;启动时恰好解决被标记的那次变更——通过删除被标记的表行:这会补完被中断的 delete,并回滚被中断的 create(注册可以重建,因此回滚是安全方向)——而没有标记的顺序/表不一致则作为损坏大声失败。
129
+
130
+ 会话的 cwd 在创建时由创建者赋予,而不是由本注册表赋予——API 网关从所选工作区的 `path` 解析新会话的 cwd(回退到显式或默认 cwd),先创建会话使 cwd 落入其不可变的 [`SessionHeader`](./persistence.md#sessionheader--metadata-beside-the-log),再调用 `attachSession`,后者会把已存储的 header cwd 与工作区路径重新校验一遍。首次成功启动时,注册表仅凭已持久化的 header(`id`、`cwd`、`createdAt`——绝不读事件正文)引导历史:把规范 cwd 有效的会话按目录分组为工作区,最新的排在最前;「已初始化」标记最后写入,因此被中断的引导可以安全续跑。引导只发生这一次:没有 cwd 的历史遗留会话保持 Ungrouped,此后创建的会话只能通过 `attachSession` 加入工作区。
131
+
132
+ ## 默认工作区初始化
133
+
134
+ 控制器的 `initializeDefault` 不接受请求参数:它拥有固定目录名 `default-workspace`,解析 Documents 位置,并请求注册表执行一次初始化。注册表接收目录解析器,以所请求目录(而非规范路径)的最后一段作为初始标题,并将登记与持久化身份一起提交。语言不会传到 Host——浏览器消费方通过控制器的 `workspaceDisplayTitle` 为仍保留该自动标题的工作区加标签,因此只有屏幕上的名称跟随读者语言。[首次使用行为与配置](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-controller/README.zh.md#first-use-workspace)说明复用和失败处理。
135
+
136
+ ## 会话置顶
137
+
138
+ 控制器的[传输类型](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-controller/src/types.ts)定义了 `WorkspacePinSessionRequest` 和 `WorkspaceUnpinSessionRequest`,两者都携带一个 `sessionId`。两个操作都返回 `WorkspacePinValue`:完整的会话 id 数组 `pinnedSessionIds`,最近置顶的会话排在前面。置顶要求会话已知且未归档;对未置顶的 id 取消置顶会成功,且不改变集合。归档在同一次持久化写入中移除该会话的置顶,取消归档不会恢复置顶。
139
+
140
+ ## 归档准入
141
+
142
+ 归档是一个注册表全局的持久化集合,注册表拒绝把正在运行的工作藏在它后面。这条规则是本包声明并派发的两个宿主事件之上的能力接缝([事件](#workspace-events)):`workspace/session-activity`(waterfall)向已组合的提供方询问某会话还有什么在跑,`workspace/session-stop`(parallel)请它们停止这些工作。每个提供方像任何监听器一样在根上注册,因此本包不认识 agent、job 或 schedule 的词汇;各族是一个可合并扩展的 map 的键。
143
+
144
+ ```ts type-equiv
145
+ /**
146
+ * Activity families a `workspace/session-activity` listener may report. This
147
+ * package declares none: each provider merges its own key from a module both
148
+ * its Host and Client faces import, so a consumer that renders the families
149
+ * sees exactly the keys its program compiled and falls through to a generic
150
+ * description for any other. The shipped providers merge `turn` (the Agent
151
+ * registry), `job` (the job registry seam), `subagent` (the Subagent
152
+ * runtime), and `schedule` (the Schedule plugin).
153
+ */
154
+ interface SessionActivityKindMap {}
155
+ ```
156
+
157
+ `SessionActivityKind` 即 `keyof SessionActivityKindMap`,因此一个没有编译任何提供方的程序看不到任何键。随附的键放在各自 client 可导入的类型模块里:`turn` 在 Agent 注册表的 `types.ts`,`job` 在任务注册表接缝的 `view.ts`,`subagent` 在 Subagent runtime 的 `control-types.ts`,`schedule` 在 Schedule 插件的 `types.ts`;渲染各族的消费方为其分支导入这些模块,并为其他任何键保留一条通用文案。提供方通过把自己的 `SessionActivity` 条目前置到 `next()` 的结果来回答 waterfall;注册表最内层的回调返回空列表,因此没有提供方的组合可自由归档。
158
+
159
+ ```ts type-equiv
160
+ /**
161
+ * One reason a session counts as active for archive admission. Families with
162
+ * per-item identity list their items so a caller can name what must stop.
163
+ */
164
+ interface SessionActivity {
165
+ readonly kind: SessionActivityKind
166
+ /** Active items of the family; absent for a family without per-item identity (`turn`). */
167
+ readonly items?: readonly SessionActivityItem[]
168
+ }
169
+ ```
170
+
171
+ `SessionActivityItem` 携带各族自己的 `id`(会话、任务或提醒 id)和可选的展示 `label`。`archiveSession(sessionId)` 在存在性检查之后只询问 waterfall 一次,对非空答案以 `WorkspaceActiveSessionError`(`sessionId`、`activity`)拒绝且不写入;控制器把它映射为 `workspace/session-active` 错误,其 details 携带同样的两个字段。`archiveSession(sessionId, { stopActivity: true })`——`ArchiveSessionOptions` 的这个字段由传输请求以 `stopActivity` 暴露——跳过检查、先写入归档、再派发 `workspace/session-stop`;提供方抛错只记日志,归档保留,被停止的工作从不等待收敛。已归档的 id 既不询问也不停止。随附的提供方、它们停止什么,以及让已归档会话不跑模型步的 `agent/pre-step` 门禁,记录在[注册表包](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/README.zh.md#api-behavior);决策记录见 [archive-stops-running-work Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-09-21-archive-stops-running-session-work.zh.md)。
172
+
173
+ ## 消费方
174
+
175
+ [`dsh-workspace-controller`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/api/workspace-controller) 经 `ctx.workspaceRegistry` 向 GUI 客户端提供工作区 CRUD,[`dsh-session-controller`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/api/session-controller) 执行上文「先建会话再 attach」的流程。[dsh-agent-instructions](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/context/agent-instructions) 尽管名字如此,却**不是**消费方:它在 agent 自己的 cwd 下发现 AGENTS.md 风格的指令文件,从不触碰 `ctx.workspaceRegistry`——两者共用的这个词指的是用户的工作目录,而非本注册表的实体。
176
+
177
+ <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
178
+
179
+ <a id="cordis-surface"></a>
180
+
181
+ ## Cordis API
182
+
183
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
184
+
185
+ <a id="ctxdirectorypicker--directorypicker-abstract-seam"></a>
186
+
187
+ ### `ctx.directoryPicker` — `DirectoryPicker` (abstract seam)
188
+
189
+ Abstract directory-picking service. Subclass, implement `capability()`, and load the subclass as a plugin — it registers as `ctx.directoryPicker` (one implementation per context; loading a second throws, cordis' standard duplicate-service behavior). The capability object must be stable for the service lifetime: consumers may capture it across calls.
190
+
191
+ ```ts cordis-catalog
192
+ /**
193
+ * The backend's interaction capability.
194
+ * @returns the discriminated capability consumers switch on.
195
+ */
196
+ abstract capability(): DirectoryPickerCapability
197
+ ```
198
+
199
+ Source: [`packages/host/directory-picker/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/directory-picker/src/index.ts)
200
+
201
+ <a id="ctxdirectorypickercontroller--directorypickercontroller"></a>
202
+
203
+ ### `ctx.directoryPickerController` — `DirectoryPickerController`
204
+
205
+ Host service backing the generated `ctx.remote.directoryPicker` namespace. The seam it exports is abstract and therefore never a Loader entry of its own, so this controller carries the wire verbs: one composed backend serves either the native chooser or the browse primitives, and a verb the composition cannot serve is refused rather than approximated.
206
+
207
+ ```ts cordis-catalog
208
+ /**
209
+ * Open the host's OS chooser for a Remote caller.
210
+ * @param signal - caller lifetime; abort terminates the chooser.
211
+ * @returns the chosen absolute path, or null when the operator cancels.
212
+ */
213
+ @Remote('pick') async pick(signal: AbortSignal): Promise<string | null>
214
+
215
+ /**
216
+ * List one directory level for a Remote caller's in-app browser.
217
+ * @param path - absolute directory to list; absent lists the home directory.
218
+ * @param signal - caller lifetime; abort stops the backend's scan instead of
219
+ * letting it outlive a disconnected caller.
220
+ * @returns the level's listing with its ancestry.
221
+ */
222
+ @Remote('list') async list(path: string | undefined, signal: AbortSignal): Promise<DirectoryListing>
223
+
224
+ /**
225
+ * Create one child directory for a Remote caller's in-app browser.
226
+ * @param path - absolute existing parent directory.
227
+ * @param name - single non-blank path segment.
228
+ * @returns the created directory's absolute path.
229
+ */
230
+ @Remote('createDirectory') async createDirectory(path: string, name: string): Promise<string>
231
+ ```
232
+
233
+ Source: [`packages/api/workspace-controller/src/directory-picker.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-controller/src/directory-picker.ts)
234
+
235
+ <a id="ctxterminalcontroller--terminalcontroller"></a>
236
+
237
+ ### `ctx.terminalController` — `TerminalController`
238
+
239
+ Typed Remote control of transient Session-owned terminal processes.
240
+
241
+ ```ts cordis-catalog
242
+ /**
243
+ * Read the Session's current directory and terminal limits without filesystem validation or shell lookup.
244
+ * @param agent - Session owner supplied by the Gateway.
245
+ * @param signal - request cancellation.
246
+ * @returns the logged current directory and terminal limits; retained terminals keep their own process directories.
247
+ */
248
+ @Remote environment(agent: Agent, signal: AbortSignal): TerminalEnvironment
249
+
250
+ /**
251
+ * Discover installed shells in the Session's execution environment.
252
+ * @param agent - Session owner supplied by the Gateway.
253
+ * @param signal - request cancellation.
254
+ * @returns verified profiles, with the configured or system default first.
255
+ */
256
+ @Remote shells(agent: Agent, signal: AbortSignal): Promise<TerminalShell[]>
257
+
258
+ /**
259
+ * List retained terminals without resolving or activating an Agent.
260
+ * @param sessionId - displayed Session identity, including offline history.
261
+ * @returns terminals retained for this Host lifetime.
262
+ */
263
+ @Remote list(sessionId: SessionId): WebTerminalInfo[]
264
+
265
+ /**
266
+ * Allocate a user shell once for a caller-generated identity, without Agent sandbox or approval restrictions.
267
+ * @param agent - Session owner supplied by the Gateway.
268
+ * @param request - initial dimensions and idempotency identity.
269
+ * @param signal - allocation cancellation; committed terminals survive disconnection.
270
+ * @returns the existing or newly committed terminal.
271
+ */
272
+ @Remote async create(agent: Agent, request: TerminalCreateRequest, signal: AbortSignal): Promise<WebTerminalInfo>
273
+
274
+ /**
275
+ * Open a terminal for the Session's Agent under a caller-resolved sandbox policy; it appears in every
276
+ * window that watches the Session and passes to the person on the person's first typed input.
277
+ * @param agent - Session owner whose Agent requests the terminal.
278
+ * @param request - title, directory, dimensions, sandbox policy and shell preference.
279
+ * @param signal - allocation cancellation; a committed terminal outlives it.
280
+ * @returns the Agent's handle for the committed terminal.
281
+ * @throws RemoteError `terminal/limit-reached` when the Session or Agent terminal limit is reached.
282
+ * @throws Error when the title is blank or longer than 120 characters.
283
+ */
284
+ async openForAgent(agent: Agent, request: AgentTerminalRequest, signal: AbortSignal): Promise<AgentTerminal>
285
+
286
+ /**
287
+ * Render a page of any terminal in the Agent's Session, including terminals the person opened.
288
+ * @param agent - Session owner.
289
+ * @param id - terminal identity.
290
+ * @param request - page position and byte bound.
291
+ * @returns rendered screen text, including output received before the call.
292
+ * @throws RemoteError `terminal/unavailable` when the terminal is missing or closes before the screen is read.
293
+ */
294
+ readScreen(agent: Agent, id: WebTerminalId, request: TerminalScreenRequest): Promise<TerminalScreenPage>
295
+
296
+ /**
297
+ * Observe whether a Session terminal's shell is running a command.
298
+ * @param agent - Session owner.
299
+ * @param id - terminal identity.
300
+ * @returns idle, busy, or unknown for unsupported shells and sandboxed launches.
301
+ */
302
+ inspectActivity(agent: Agent, id: WebTerminalId): Promise<'idle' | 'busy' | 'unknown'>
303
+
304
+ /**
305
+ * Stream the Session's retained terminals as whole sets, without resolving or activating an Agent.
306
+ * @param sessionId - watched Session identity.
307
+ * @param signal - stream cancellation.
308
+ * @returns the current set, then a new set after creation, removal or any published state change.
309
+ */
310
+ @Remote({ mode: 'stream' }) async *watch(sessionId: SessionId, signal: AbortSignal): AsyncIterable<WebTerminalInfo[]>
311
+
312
+ /**
313
+ * Retain an existing terminal for a window without activating its Agent or taking input control.
314
+ * @param sessionId - owning Session identity, including an inactive saved layout.
315
+ * @param id - retained Host terminal identity.
316
+ * @param signal - physical Remote stream cancellation.
317
+ * @returns a hold acknowledgement followed by an open lifetime stream.
318
+ */
319
+ @Remote({ mode: 'stream' }) retain(sessionId: SessionId, id: WebTerminalId, signal: AbortSignal): AsyncIterable<TerminalRetentionFrame>
320
+
321
+ /**
322
+ * Attach terminal input and output to one physical Remote stream.
323
+ * @param agent - Session owner supplied by the Gateway.
324
+ * @param id - terminal identity.
325
+ * @param signal - attachment cancellation; the process remains alive and input is never replayed.
326
+ * @returns screen recovery, output, writable state and provider-acceptance acknowledgements.
327
+ */
328
+ @Remote({ mode: 'stream' }) attach(agent: Agent, id: WebTerminalId, signal: AbortSignal): RemoteStream<TerminalFrame, TerminalInput>
329
+
330
+ /**
331
+ * Rename a terminal without changing its shell.
332
+ * @param agent - Session owner supplied by the Gateway.
333
+ * @param id - terminal identity.
334
+ * @param title - nonempty display title, at most 120 characters.
335
+ */
336
+ @Remote rename(agent: Agent, id: WebTerminalId, title: string): void
337
+
338
+ /**
339
+ * Close an identity to future creation and kill its process range; repeated closes succeed.
340
+ * @param agent - Session owner supplied by the Gateway.
341
+ * @param id - terminal identity.
342
+ * @returns after provider cleanup succeeds. A failure retains the terminal for retry.
343
+ */
344
+ @Remote async close(agent: Agent, id: WebTerminalId): Promise<void>
345
+ ```
346
+
347
+ Types: [Agent](./core.md) · [RemoteStream](./typert.md) · [SessionId](./core.md)
348
+
349
+ Source: [`packages/api/terminal-controller/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/terminal-controller/src/index.ts)
350
+
351
+ <a id="ctxworkspacecontroller--workspacecontroller"></a>
352
+
353
+ ### `ctx.workspaceController` — `WorkspaceController`
354
+
355
+ Host service backing the generated `ctx.remote.workspace` namespace.
356
+
357
+ ```ts cordis-catalog
358
+ /**
359
+ * Create or idempotently resolve one Workspace over an existing directory.
360
+ * @param request - directory path to register.
361
+ * @returns the Workspace and whether this call created it.
362
+ */
363
+ @Remote('create') create(request: WorkspaceCreateRequest): Promise<WorkspaceCreateValue>
364
+
365
+ /**
366
+ * Initialize or reuse the default Workspace during first-use startup. The
367
+ * directory name is fixed, so the Host never renames or relocates an
368
+ * existing default; its initial title is that same name, which browser
369
+ * consumers label in the reader's language.
370
+ * @param signal - caller lifetime; cancels native directory lookup.
371
+ * @returns the durable Workspace, or undefined when first-use initialization is ineligible; creates no Session or message.
372
+ */
373
+ @Remote('initializeDefault') async initializeDefault(signal: AbortSignal): Promise<WorkspaceValue | undefined>
374
+
375
+ /**
376
+ * Rename one Workspace to a unique non-blank title.
377
+ * @param request - Workspace identity and proposed title.
378
+ * @returns the updated Workspace projection.
379
+ */
380
+ @Remote('rename') rename(request: WorkspaceRenameRequest): Promise<WorkspaceValue>
381
+
382
+ /**
383
+ * Remove one Workspace registration while retaining files and Sessions.
384
+ * @param request - Workspace identity to remove.
385
+ * @returns deletion confirmation.
386
+ */
387
+ @Remote('delete') delete(request: WorkspaceDeleteRequest): Promise<WorkspaceDeleteValue>
388
+
389
+ /**
390
+ * Move one Workspace within the registry display order.
391
+ * @param request - moved Workspace and optional anchor.
392
+ * @returns the complete resulting Workspace order.
393
+ */
394
+ @Remote('insertBefore') insertBefore(request: WorkspaceInsertBeforeRequest): Promise<WorkspaceOrderValue>
395
+
396
+ /**
397
+ * Move one accounted Session within a Workspace.
398
+ * @param request - Workspace, Session, and optional anchor identities.
399
+ * @returns the updated Workspace projection.
400
+ */
401
+ @Remote('insertSessionBefore') insertSessionBefore(request: WorkspaceInsertSessionBeforeRequest): Promise<WorkspaceValue>
402
+
403
+ /**
404
+ * Hide one known Session from Workspace grouping surfaces.
405
+ * @param request - Session identity to archive.
406
+ * @returns the complete resulting archive set.
407
+ */
408
+ @Remote('archiveSession') archiveSession(request: WorkspaceArchiveSessionRequest): Promise<WorkspaceArchiveValue>
409
+
410
+ /**
411
+ * Restore one archived Session to Workspace grouping surfaces.
412
+ * @param request - Session identity to unarchive.
413
+ * @returns the complete resulting archive set.
414
+ */
415
+ @Remote('unarchiveSession') unarchiveSession(request: WorkspaceUnarchiveSessionRequest): Promise<WorkspaceArchiveValue>
416
+
417
+ /**
418
+ * Surface one known unarchived Session ahead of unpinned Sessions.
419
+ * @param request - Session identity to pin.
420
+ * @returns the complete resulting pin set, most recently pinned first.
421
+ */
422
+ @Remote('pinSession') pinSession(request: WorkspacePinSessionRequest): Promise<WorkspacePinValue>
423
+
424
+ /**
425
+ * Remove one Session's pin without changing its saved Session order.
426
+ * @param request - Session identity to unpin.
427
+ * @returns the complete resulting pin set, most recently pinned first.
428
+ */
429
+ @Remote('unpinSession') unpinSession(request: WorkspaceUnpinSessionRequest): Promise<WorkspacePinValue>
430
+
431
+ /**
432
+ * Stream a complete Workspace baseline followed by ordered increments. A
433
+ * non-owner receives only the Workspaces and Sessions `allows()` admits.
434
+ * When a delivered Workspace is no longer admitted at its next change or
435
+ * the next order change, the stream sends a `replace` frame with the
436
+ * complete filtered state instead of a `remove`, because a Client never
437
+ * resurrects a removed Workspace; a `remove` frame reports a deletion and
438
+ * reaches only a Client that received that Workspace.
439
+ * @param signal - generation cancellation.
440
+ * @returns baseline followed by ordered Workspace increments.
441
+ */
442
+ @Remote({ mode: 'stream' }) async *follow(signal: AbortSignal): AsyncIterable<WorkspaceFollowFrame>
443
+ ```
444
+
445
+ Source: [`packages/api/workspace-controller/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-controller/src/index.ts)
446
+
447
+ <a id="ctxworkspacefiles--workspacefiles"></a>
448
+
449
+ ### `ctx.workspaceFiles` — `WorkspaceFiles`
450
+
451
+ Host Remote file reads and workspace directory observations over the composed filesystem.
452
+
453
+ ```ts cordis-catalog
454
+ /**
455
+ * Read one page of lines from a UTF-8 file readable by the filesystem backend.
456
+ * @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
457
+ * @param path - absolute path or path relative to the workspace root; files outside it are allowed.
458
+ * @param range - the line window; omitted fields take the page defaults.
459
+ * @param signal - caller cancellation.
460
+ * @returns the page, the file's version at the stat before it, and whether it reaches the last line.
461
+ */
462
+ @Remote async read( workspaceFileScope: WorkspaceFileScope, path: string, range: WorkspaceFileRange, signal: AbortSignal, ): Promise<WorkspaceFileText>
463
+
464
+ /**
465
+ * Read a complete regular file or one byte range without text decoding.
466
+ * @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
467
+ * @param path - target path, absolute or workspace-relative; relative to the base file's directory when provided.
468
+ * @param options - optional base file and range; without a range the complete-file cap applies.
469
+ * @param signal - caller cancellation.
470
+ * @returns native bytes with the file's version and size at the preceding stat, byte offset, and EOF marker.
471
+ */
472
+ @Remote async readBytes( workspaceFileScope: WorkspaceFileScope, path: string, options: WorkspaceByteReadOptions, signal: AbortSignal, ): Promise<WorkspaceFileBytes>
473
+
474
+ /**
475
+ * Report one regular file's identity, version, and size without its content.
476
+ * @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
477
+ * @param path - absolute path or path relative to the workspace root; files outside it are allowed.
478
+ * @param signal - caller cancellation.
479
+ * @returns the file's absolute path, current version, and byte size.
480
+ */
481
+ @Remote async stat(workspaceFileScope: WorkspaceFileScope, path: string, signal: AbortSignal): Promise<WorkspaceFileStat>
482
+
483
+ /**
484
+ * List the direct children of one directory inside the Session's workspace.
485
+ * @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
486
+ * @param path - workspace path, absolute or relative to the workspace root.
487
+ * @param signal - caller cancellation.
488
+ * @returns the directory's children in the backend's stable name order, bounded by the entry cap.
489
+ */
490
+ @Remote async list(workspaceFileScope: WorkspaceFileScope, path: string, signal: AbortSignal): Promise<WorkspaceDirectoryListing>
491
+
492
+ /**
493
+ * Search files and their inferred ancestor directories with packaged ripgrep.
494
+ * Native ignore rules apply unless disabled; VCS metadata, symlinks and empty
495
+ * directories are absent. Within the bounded set of listed files, matches
496
+ * sort by depth, then workspace-relative path.
497
+ * @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
498
+ * @param request - the query, literal exclusions, and hidden/ignore switches.
499
+ * @param signal - caller cancellation, forwarded to the subprocess; rejection preserves its reason.
500
+ * @returns matches capped by search.maxResults; incomplete marks excess rg files or exit 2.
501
+ * @throws RemoteError `gateway/bad-request`: the query is blank.
502
+ * @throws RemoteError `workspace-file/not-found`: the workspace root does not exist.
503
+ * @throws RemoteError `workspace-file/not-directory`: the workspace root is not a directory.
504
+ * @throws RemoteError `workspace-file/search-failed`: subprocess is missing, rg cannot launch or execute, or the search times out.
505
+ */
506
+ @Remote async search( workspaceFileScope: WorkspaceFileScope, request: WorkspaceFileSearchRequest, signal: AbortSignal, ): Promise<WorkspaceFileSearchResult>
507
+
508
+ /**
509
+ * Watch one file or a directory's direct entries in the Session's filesystem.
510
+ * Files use the backend's read authority; directories remain workspace-scoped.
511
+ * @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
512
+ * @param path - target path; the Host determines its type and confines directories to the workspace.
513
+ * @param signal - generation cancellation.
514
+ * @returns `ready` once the target watch is active, then current metadata for queued and live invalidations.
515
+ * @throws RemoteError when watching is unavailable or a directory is outside the workspace.
516
+ */
517
+ @Remote({ mode: 'stream' }) changes(workspaceFileScope: WorkspaceFileScope, path: string, signal: AbortSignal): AsyncIterable<WorkspaceFileWatchFrame>
518
+ ```
519
+
520
+ Source: [`packages/api/workspace-files/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-files/src/index.ts)
521
+
522
+ <a id="ctxworkspaceregistry--workspaceregistry"></a>
523
+
524
+ ### `ctx.workspaceRegistry` — `WorkspaceRegistry`
525
+
526
+ Durable workspace registry. Startup waits for `sessionPersistence`, builds one canonical-cwd header index, and completes the one-time history bootstrap before the service becomes active. The persistence dependency is mandatory so an unavailable peer can never be mistaken for an empty history and commit the initialized marker.
527
+
528
+ ```ts cordis-catalog
529
+ /**
530
+ * Create or reuse a workspace for an existing directory. The fully qualified
531
+ * path is canonicalized through `fs.realpath`; a relative, nonexistent, or
532
+ * non-directory path rejects. Repeated calls for the same canonical path
533
+ * return the existing entity without changing its title.
534
+ * A newly created workspace is prepended to the durable registry order.
535
+ * Different canonical paths may share a display title.
536
+ * @param path - Existing directory to own, in a fully qualified path spelling.
537
+ * @param title - Display title used only when a new record is created.
538
+ * @returns the existing or newly durable workspace.
539
+ */
540
+ async create(path: string, title?: string): Promise<Workspace>
541
+
542
+ /**
543
+ * Initialize the default Workspace only while both the registry and Session
544
+ * history are empty. Repeated requests reuse its durable identity; deleting
545
+ * that registration permanently disables automatic creation.
546
+ * @param resolveDirectory - resolve the absolute directory; called only for
547
+ * eligible creation, inside the registry mutation queue. Missing directories
548
+ * are created recursively before registration, and the initial title is the
549
+ * requested directory's own final segment — not the canonical one, so a
550
+ * symlink at that path does not retitle the Workspace after its target.
551
+ * After resolution, caller cancellation does not roll back creation or registration.
552
+ * @returns the initialized Workspace, or undefined when automatic creation is ineligible.
553
+ */
554
+ initializeDefault(resolveDirectory: () => Promise<string>): Promise<Workspace | undefined>
555
+
556
+ /**
557
+ * Look up a workspace by id.
558
+ * @param id - Workspace id.
559
+ * @returns the workspace, or `undefined` when unknown.
560
+ */
561
+ get(id: WorkspaceId): Workspace | undefined
562
+
563
+ /**
564
+ * Synchronous workspace projection in durable registry order. Every
565
+ * entity's `sessionIds` getter is already filtered by the startup/live
566
+ * canonical-cwd header index; this method performs no persistence reads.
567
+ * @returns a fresh ordered array of workspace entities.
568
+ */
569
+ list(): Workspace[]
570
+
571
+ /**
572
+ * Delete one workspace registration while retaining its directory and every
573
+ * session log. The durable order is updated before the table deletion; a
574
+ * failed table write restores the prior order and keeps the entity
575
+ * published. Unknown ids are an idempotent no-op for domain callers.
576
+ * @param id - Workspace registration to remove.
577
+ * @returns `true` when a record was deleted, `false` when it was unknown.
578
+ */
579
+ delete(id: WorkspaceId): Promise<boolean>
580
+
581
+ /**
582
+ * Move one workspace within the durable display order, DOM-insertBefore-like.
583
+ * With an anchor it lands before that workspace; without one it appends.
584
+ * @param id - Workspace to move.
585
+ * @param beforeId - Workspace anchor; omitted appends.
586
+ * @returns the complete committed workspace order.
587
+ */
588
+ insertBefore(id: WorkspaceId, beforeId?: WorkspaceId): Promise<readonly WorkspaceId[]>
589
+
590
+ /**
591
+ * Archive one session durably. The session must exist (live or in session
592
+ * persistence); its workspace accounting — or lack of one — is irrelevant.
593
+ * Without `stopActivity` the session must also be inactive: the
594
+ * `workspace/session-activity` waterfall is asked once, and any reported
595
+ * activity rejects with {@link WorkspaceActiveSessionError} before anything
596
+ * is written. With `stopActivity` the archive is written without an
597
+ * activity check, and the `workspace/session-stop` providers are then asked
598
+ * to stop the session's work: the durable archive set is what a provider's
599
+ * `agent/pre-step` gate reads, so every wake the stops induce is already
600
+ * blocked. Archiving drops the session's pin in the same durable write
601
+ * (pinning and archival are mutually exclusive). An already archived id
602
+ * resolves without writing, asking, or stopping.
603
+ * @param sessionId - The session to archive.
604
+ * @param options - Whether running work is stopped instead of refusing.
605
+ * @returns resolution after durability, any stop requests, and follow-up admission.
606
+ */
607
+ archiveSession(sessionId: SessionId, options: ArchiveSessionOptions = {}): Promise<void>
608
+
609
+ /**
610
+ * Unarchive one session durably by dropping it from the registry-global
611
+ * archive set; the accounting slot was never touched, so the session
612
+ * returns to its recorded position. Unarchiving runs no session-existence
613
+ * check because removing an id cannot introduce an unknown one, so an
614
+ * entry whose session is gone still resolves. An id that is not archived
615
+ * resolves without writing.
616
+ * @param sessionId - The session to unarchive.
617
+ * @returns resolution after durability.
618
+ */
619
+ unarchiveSession(sessionId: SessionId): Promise<void>
620
+
621
+ /**
622
+ * Pin one session durably, prepending it to the registry-global pin set.
623
+ * The session must exist (live or in session persistence) and must not be
624
+ * archived. An already pinned id resolves without writing or reordering.
625
+ * @param sessionId - The session to pin.
626
+ * @returns resolution after durability.
627
+ */
628
+ pinSession(sessionId: SessionId): Promise<void>
629
+
630
+ /**
631
+ * Unpin one session durably by dropping it from the registry-global pin
632
+ * set. Unpinning runs no session-existence check because removing an id
633
+ * cannot introduce an unknown one, so an entry whose session is gone still
634
+ * resolves. An id that is not pinned resolves without writing.
635
+ * @param sessionId - The session to unpin.
636
+ * @returns resolution after durability.
637
+ */
638
+ unpinSession(sessionId: SessionId): Promise<void>
639
+
640
+ /**
641
+ * Resolve by canonical directory path without creating or mutating a
642
+ * workspace. A missing path rejects during `realpath`; an existing unowned
643
+ * directory returns `undefined`.
644
+ * @param path - Existing directory path in a fully qualified spelling.
645
+ * @returns the workspace owning the canonical path, when one exists.
646
+ */
647
+ async resolveByPath(path: string): Promise<Workspace | undefined>
648
+ ```
649
+
650
+ Types: [SessionId](./core.md)
651
+
652
+ Source: [`packages/workspace/workspace/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/src/index.ts)
653
+
654
+ <a id="workspace-events"></a>
655
+
656
+ ### `workspace/*` events
657
+
658
+ <a id="workspacesession-activity--waterfall"></a>
659
+
660
+ #### `workspace/session-activity` — waterfall
661
+
662
+ Ask the composed providers what still runs for a session before it is archived. A listener prepends its own SessionActivity entries to the result of `next()`; the registry's innermost callback returns an empty list, so a composition without providers archives freely. Any non-empty result refuses the archive without a write.
663
+
664
+ ```ts cordis-catalog
665
+ /**
666
+ * Ask the composed providers what still runs for a session before it is
667
+ * archived. A listener prepends its own {@link SessionActivity} entries to
668
+ * the result of `next()`; the registry's innermost callback returns an
669
+ * empty list, so a composition without providers archives freely. Any
670
+ * non-empty result refuses the archive without a write.
671
+ * @param request - the session about to be archived.
672
+ * @param next - delegate to the remaining providers.
673
+ * @mode waterfall
674
+ */
675
+ 'workspace/session-activity'( request: SessionActivityRequest, next: () => Promise<readonly SessionActivity[]>, ): Promise<readonly SessionActivity[]>
676
+ ```
677
+
678
+ Source: [`packages/workspace/workspace/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/src/index.ts)
679
+
680
+ <a id="workspacesession-archived--parallel"></a>
681
+
682
+ #### `workspace/session-archived` — parallel
683
+
684
+ Admit optional follow-up work after durable archival and any stop requests. Dispatched inside the registry's write queue: a listener registers its work and returns, and runs the work and any unbounded I/O afterwards. Listener failures are logged without undoing archival. Listeners own and drain their background work.
685
+
686
+ ```ts cordis-catalog
687
+ /**
688
+ * Admit optional follow-up work after durable archival and any stop requests.
689
+ * Dispatched inside the registry's write queue: a listener registers its work
690
+ * and returns, and runs the work and any unbounded I/O afterwards. Listener
691
+ * failures are logged without undoing archival. Listeners own and drain their background work.
692
+ * @param request - newly archived Session; repeated archive requests do not dispatch.
693
+ * @mode parallel
694
+ */
695
+ 'workspace/session-archived'(request: SessionActivityRequest): Promise<void> | void
696
+ ```
697
+
698
+ Source: [`packages/workspace/workspace/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/src/index.ts)
699
+
700
+ <a id="workspacesession-stop--parallel"></a>
701
+
702
+ #### `workspace/session-stop` — parallel
703
+
704
+ Stop a session's running work because the caller archived it with `stopActivity`; the archive set is durable when this dispatches. Each provider stops its own families — cancelling a turn, its subagent descendants, owned jobs, or active schedules — through the same cancel paths the user's own stop actions use, so the session log ends every open turn regularly and a later unarchive can continue the conversation. Listeners issue their stop requests without waiting for running work to settle; a listener may await its own durability barrier. A rejection is logged by the registry and does not undo the archive.
705
+
706
+ ```ts cordis-catalog
707
+ /**
708
+ * Stop a session's running work because the caller archived it with
709
+ * `stopActivity`; the archive set is durable when this dispatches. Each
710
+ * provider stops its own families — cancelling a turn, its subagent
711
+ * descendants, owned jobs, or active schedules — through the same cancel
712
+ * paths the user's own stop actions use, so the session log ends every
713
+ * open turn regularly and a later unarchive can continue the
714
+ * conversation. Listeners issue their stop requests without waiting for
715
+ * running work to settle; a listener may await its own durability
716
+ * barrier. A rejection is logged by the registry and does not undo the
717
+ * archive.
718
+ * @param request - the session being archived.
719
+ * @mode parallel
720
+ */
721
+ 'workspace/session-stop'(request: SessionActivityRequest): Promise<void> | void
722
+ ```
723
+
724
+ Source: [`packages/workspace/workspace/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/src/index.ts)
725
+
726
+ <a id="workspacesession-unarchiving--parallel"></a>
727
+
728
+ #### `workspace/session-unarchiving` — parallel
729
+
730
+ Cancel or settle archive follow-up work before making a Session available again. A rejection retains the archived state.
731
+
732
+ ```ts cordis-catalog
733
+ /**
734
+ * Cancel or settle archive follow-up work before making a Session available again.
735
+ * A rejection retains the archived state.
736
+ * @param request - Session about to leave the archive set.
737
+ * @mode parallel
738
+ */
739
+ 'workspace/session-unarchiving'(request: SessionActivityRequest): Promise<void> | void
740
+ ```
741
+
742
+ Source: [`packages/workspace/workspace/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/workspace/workspace/src/index.ts)
743
+ <!-- END GENERATED cordis-surface -->