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,534 +1,708 @@
1
- ---
2
- editSource: "docs/subsystems/filesystem.zh.md"
3
- rawMarkdownPath: "reference/subsystems/filesystem.md"
4
- outline: [2,3]
5
- ---
6
-
7
- # 文件系统
8
-
9
- 可选的文件系统能力由四个部分组成:[dsh-fs](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/fs/fs) 拥有 `ctx.fs` 以及带可选守卫的原子文本操作;[dsh-fs-local](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/fs/fs-local) 实现本地磁盘后端;[dsh-fs-observation-policy](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/fs/fs-observation-policy) 记录观测到的存在或缺失状态,并通过事件(而非服务)添加新鲜度规则;[dsh-tool-fs](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/fs/tool-fs) 直接执行面向模型的 read/write/edit 调用并渲染窗口。它位于 agent loop(智能体循环)主干之外;替换后端不会改变策略或工具 schema。
10
-
11
- `dsh-fs-observation-policy` 是可选插件。没有该插件时,`FileSystem` 服务定义、一个提供方和 `dsh-tool-fs` 消费方组成完整且不受约束的文件系统 seam:`write` 无条件创建或覆盖,`edit` 无条件替换字面文本。策略插件通过裁决 `fs/*` waterfall(瀑布式事件)来改变这些操作。移除该插件不会破坏工具,因为工具调用 `ctx.fs` 并分发事件,而不调用策略方法。加载了 `dsh-tool-fs` 的部署也应加载 `dsh-fs-observation-policy`,使默认行为为「先读后写/编辑」。
12
-
13
- 提供方源码:[`packages/fs/fs/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/types.ts) 与 [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)。策略源码:[`packages/fs/fs-observation-policy/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs-observation-policy/src/types.ts)。读取渲染源码:[`packages/fs/tool-fs/src/read-render.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/tool-fs/src/read-render.ts)。
14
-
15
- ## 目标标识与元数据(提供方约定)
16
-
17
- 每个操作首先将用户提供的路径解析为不透明的后端目标。消费方可以显示 `displayPath`,但禁止解析 `targetKey`(一个品牌化的不透明 id),也不得假设它是本地绝对路径。
18
-
19
- 与文件系统共享执行世界的消费方通过提供方获取跨能力坐标,而不是解释该身份:`processPath(target)` 返回子进程可以打开的规范化绝对路径;`processPathFromHostPath(hostPath)` 只在该执行世界共享相应宿主文件时映射其绝对路径;`fileUrl(target)` 返回采用提供方平台语法的 `file:` URI;`contains(parent, child)` 检查规范化身份相等或后代包含关系。
20
-
21
- ```ts type-equiv
22
- /**
23
- * A path resolved by a backend into a stable identity. `resolve()` produces
24
- * this; every other operation takes it.
25
- */
26
- interface FsTarget {
27
- /** Opaque key for stale guards and target lookup. */
28
- targetKey: FsTargetKey
29
- /**
30
- * Path for model/UI-facing output. May be a local absolute path,
31
- * workspace-relative path, or remote URI depending on the backend.
32
- */
33
- displayPath: string
34
- }
35
- ```
36
-
37
- 后端拥有文件版本 token,即 write/edit 所守卫的新鲜度 token。策略插件存储它们以进行陈旧检查;消费方不解释其内容。两个 id 都是品牌化的不透明字符串。
38
-
39
- ```ts type-equiv
40
- /**
41
- * Opaque key for stale guards and target lookup. The local backend uses a
42
- * realpath-like string; a remote backend might use a workspace URI or file id.
43
- * Consumers MUST NOT parse it or assume it is a local absolute path.
44
- */
45
- type FsTargetKey = Branded<'FsTargetKey'>
46
- ```
47
-
48
- ```ts type-equiv
49
- /**
50
- * Opaque file-version token — the freshness token a write/edit guards against.
51
- * The local backend derives it from high-resolution stat identity and freshness
52
- * fields; a remote backend might use a revision id. The policy layer records it
53
- * for stale checks; consumers may display related metadata but MUST NOT
54
- * interpret this token.
55
- */
56
- type FsVersion = Branded<'FsVersion'>
57
- ```
58
-
59
- `stat` 返回元数据(从不返回内容),目标不存在时返回 `undefined`。`type` 让消费方在读取前拒绝目录和特殊文件;`size` 让文本消费方无需通过失败探测即可选择 `readText` 还是 `streamText`。文本消费方在消费 `streamText` 时执行自己的保留量上限。原始字节消费方调用 `readBytes(target, signal, maxBytes)`;其必填的完整内容上限会使已知或读取中发现的超限以 `FS_TOO_LARGE` 失败,不会截断结果或无界缓冲。
60
-
61
- ```ts type-equiv
62
- /**
63
- * Metadata about a target — what {@link FileSystem.stat} returns. Lets the
64
- * policy layer reject directories/special files before reading and choose
65
- * `readText` vs `streamText` from `size` without probing by failure. `version`
66
- * is the freshness token. `undefined` from `stat` means the target is absent.
67
- */
68
- interface FsInfo {
69
- /** Opaque freshness token of the target right now. */
70
- version: FsVersion
71
- /** Whether the target is a regular file, a directory, or something else. */
72
- type: 'file' | 'directory' | 'other'
73
- /** Byte size of a regular file, when the backend can report it. */
74
- size?: number
75
- }
76
- ```
77
-
78
- `lstat` 是路径级、不跟随链接的元数据原语。它接收路径而不是 `FsTarget`,因为 `resolve` 会有意跟随 symlink 以产生稳定标识;需要检查信任边界的消费方可以先调用 `lstat`,在解析前拒绝 `symlink`。
79
-
80
- ```ts type-equiv
81
- /**
82
- * Metadata about a path without following the final path component when it is a
83
- * symbolic link. Unlike {@link FsInfo}, this path-level probe can report
84
- * `symlink` so consumers with trust-boundary rules can reject repository-owned
85
- * links before resolving a target.
86
- */
87
- interface FsPathInfo {
88
- /** Opaque freshness token of the path entry right now. */
89
- version: FsVersion
90
- /** Whether the path entry is a regular file, directory, symlink, or other. */
91
- type: 'file' | 'directory' | 'symlink' | 'other'
92
- /** Byte size of the path entry, when the backend can report it. */
93
- size?: number
94
- }
95
- ```
96
-
97
- `listDir` 按稳定的名称顺序返回直接子条目。每个条目携带子项的 basename、类型、已解析目标,以及后端能报告时的廉价元数据。它禁止读取文件内容,因此 `size` 仅用于普通文件,`version` 来自元数据。已损坏或已消失的子项可以作为 `other` 返回且不带元数据;列出或解析子项元数据时的权限或后端 I/O 失败会以 `FS_PERMISSION_DENIED` 或 `FS_IO_ERROR` 使整个列表操作失败。
98
-
99
- ```ts type-equiv
100
- /**
101
- * One direct child returned by {@link FileSystem.listDir}. Listing returns
102
- * metadata and resolved targets only; it must not read file contents.
103
- */
104
- interface FsDirEntry {
105
- /** Basename of the child inside the listed directory. */
106
- name: string
107
- /** Whether the child is a regular file, a directory, or something else. */
108
- type: 'file' | 'directory' | 'other'
109
- /** Resolved child target for follow-up operations. */
110
- target: FsTarget
111
- /** Opaque freshness token when the backend can report metadata cheaply. */
112
- version?: FsVersion
113
- /** Byte size of a regular file, when the backend can report it. */
114
- size?: number
115
- }
116
- ```
117
-
118
- ## 写入与编辑守卫(提供方约定)
119
-
120
- `writeText` 和 `editText` 的版本守卫都是可选的:省略守卫时执行无条件的裸提供方变更,提供守卫时则执行相应的条件检查。`writeText` 的守卫是 `FsWriteIntent`:`createIfAbsent` 在目标缺失时创建,目标已存在时以 `FS_NOT_OBSERVED` 拒绝;即使目标在提供方初始探测后才出现,也必须拒绝,因为发布操作本身不得替换。`replaceIfVersion` 仅在目标存在且版本匹配时替换,否则报 `FS_STALE_VERSION`。省略 `expected` 则无条件创建或覆盖。联合类型本身只包含两种有守卫的意图;「无守卫」通过省略表达,因此 write 和 edit 都使用同一个可选的 `expected` 字段。
121
-
122
- ```ts type-equiv
123
- /**
124
- * Guarded write intent. `createIfAbsent` rejects an existing target with
125
- * `FS_NOT_OBSERVED`; `replaceIfVersion` rejects absence or mismatch with
126
- * `FS_STALE_VERSION`. Omitting the intent from `writeText` means unconditional
127
- * create-or-overwrite, not a third union arm.
128
- */
129
- type FsWriteIntent =
130
- | { kind: 'createIfAbsent' }
131
- | { kind: 'replaceIfVersion'; version: FsVersion }
132
- ```
133
-
134
- ```ts type-equiv
135
- /** Outcome of a full-file write. */
136
- interface FsWriteOutcome {
137
- /** Whether the write created a new file or replaced an existing one. */
138
- operation: 'create' | 'update'
139
- /** Opaque version of the file after the write. */
140
- version: FsVersion
141
- /**
142
- * The file's content BEFORE the write, or `null` when the file did not exist
143
- * (a create) or the backend declined a contextual basis (for example, a
144
- * binary/non-UTF-8 prior file or either overwrite side reaching its exclusive limit).
145
- * LF-normalized storage text (the diff basis), never a diff — a consumer
146
- * computes the result-time contextual diff from `before`/`after` when
147
- * `before` is present, else falls back to a whole-file diff.
148
- */
149
- before: string | null
150
- /** The file's content AFTER the write, LF-normalized to share `before`'s diff basis. */
151
- after: string
152
- }
153
- ```
154
-
155
- `editText` 是提供方级别的变更操作,而非在别处组合的 `read` 加 `write`。带守卫时,它在字面匹配之前先验证预期版本(因此对陈旧内容的编辑报 `FS_STALE_VERSION`,而非对更新内容的匹配失败);不带守卫时,它编辑当前内容。无论哪种路径,它都应用替换并原子写入——将匹配、行尾处理、陈旧检查和原子替换保持在一个变更临界区内——目标缺失时两条路径都报 `FS_STALE_VERSION`。
156
-
157
- ```ts type-equiv
158
- /** A literal-replacement edit request. */
159
- interface FsEditRequest {
160
- /** Literal non-empty text to replace. Must match exactly (after line-ending normalization). */
161
- oldString: string
162
- /** Literal replacement text. An empty string deletes the matched text. */
163
- newString: string
164
- /** Replace every match instead of requiring exactly one. */
165
- replaceAll: boolean
166
- }
167
- ```
168
-
169
- ```ts type-equiv
170
- /** Outcome of a literal edit. */
171
- interface FsEditOutcome {
172
- /** Opaque version of the file after the edit. */
173
- version: FsVersion
174
- /**
175
- * The file's content BEFORE the edit. Raw storage text (LF-normalized by the
176
- * backend), never a diff — a consumer computes the result-time contextual diff
177
- * (the applied hunk with context) from `before`/`after`.
178
- */
179
- before: string
180
- /** The file's content AFTER the edit. */
181
- after: string
182
- }
183
- ```
184
-
185
- ## fs 策略事件(提供方约定词汇)
186
-
187
- `dsh-fs` 拥有三个事件,由工具分发、策略插件监听,使事件发出方(`dsh-tool-fs`)与监听方(`dsh-fs-observation-policy`)共享词汇,而事件发出方无需依赖策略插件。它们只携带 `dsh-fs` 词汇加一个不透明的 `object` actor,不含面向模型的概念,也不含 agent/会话所有者结构。
188
-
189
- `fs/write-intent` 与 `fs/edit-intent` 是**单槽决策 waterfall**:工具分发时附带一个默认 thunk(返回 `undefined`,即裸提供方),监听方完全决策而不调用 `next()`。该 slot 按注册顺序先到先得——由策略插件占据是部署约定,而非强制不变式。`fs/observed` 是一个即发即弃的记录事件,携带 `FsObservation`:存在于某个版本,或确认缺失。该事件通过普通 `ctx.emit` 分发;其监听方必须是同步的、仅产生副作用,因为工具不会捕获该 emit 抛出的异常——抛出异常的监听方可能取代读取操作原本待返回的错误,或使工具在变更已经成功后返回 `isError` 结果。下方生成的 [cordis surface](#cordis-surface) 展示确切签名。
190
-
191
- ```ts type-equiv
192
- /**
193
- * One authoritative observation of a target. A present observation carries the
194
- * version used by guarded replacement; an absent observation authorizes only a
195
- * guarded create, never an edit.
196
- */
197
- type FsObservation =
198
- | { readonly kind: 'present'; readonly version: FsVersion }
199
- | { readonly kind: 'absent' }
200
- ```
201
-
202
- ## 执行上下文(策略插件)
203
-
204
- 策略插件只需要足够的执行上下文,通过收窄 `fs/*` 事件携带的不透明 `object` actor 来推导观测状态的所有者。`ToolExecution` 包含必需的字段,因此 `dsh-tool-fs` 将其执行对象作为 actor 直接传递,而无需让 `dsh-fs-observation-policy` 导入工具、agent 或会话包。
205
-
206
- ```ts type-equiv
207
- /**
208
- * Minimal structural view of a tool execution the policy plugin needs to derive
209
- * an observed-state owner. `@deepseek-ai/dsh-tools`' `ToolExecution` contains
210
- * these fields, so the tool passes its `exec` straight through as the opaque
211
- * `object` actor on the `fs/*` events; this plugin narrows that actor to
212
- * `FsObservationActor` without importing `dsh-tools`, `dsh-agent`, or `dsh-session`.
213
- *
214
- * The owner is `agent.session` when present. It is treated as an opaque object
215
- * identity (a `WeakMap` key); this package never reads any of its fields.
216
- */
217
- interface FsObservationActor {
218
- /** The agent on whose behalf the call runs, when there is one. */
219
- agent?: {
220
- /** The session that owns observed-file state, used as an opaque key. */
221
- session?: object
222
- }
223
- }
224
- ```
225
-
226
- ## 读取结果(消费方 / 读取渲染)
227
-
228
- 文本读取受行窗口、字节上限和后端限制约束。达到字节上限后,扫描仍会继续,但不再保留更多行,因此 `totalLines` 仍为精确值。面向模型的 `read` 工具渲染的结果纯粹是展示性的;不存在 `full`/`partial` 视图区分——授权基于新鲜度(工具发出表示目标存在的 `fs/observed` 事件,并直接携带 stat 的版本),因此任何窗口化读取在文件未变时都能授权后续的 write/edit。元数据未命中时,工具会在返回 `FS_NOT_FOUND` 前 emit 缺失观测,使后续带守卫的写入可以重新创建外部删除的目标,但不会授权 edit。拥有读取操作的执行器 `dsh-tool-fs` 实现读取窗口化并构造该结果;策略插件不执行这些操作。
229
-
230
- ```ts type-equiv
231
- /** Outcome of a bounded text read — what {@link formatReadOutput} renders. */
232
- interface FileReadOutcome {
233
- /** 1-based first line requested. */
234
- offset: number
235
- /** Returned lines, already numbered. */
236
- lines: FileTextLine[]
237
- /** Exact total line count in the file. */
238
- totalLines: number
239
- /** Whether selected output hit the byte cap. */
240
- truncatedByBytes?: true
241
- }
242
- ```
243
-
244
- ## 已观测文件状态(策略插件)
245
-
246
- 已观测状态是 `dsh-fs-observation-policy` 插件内部持有的 `WeakMap<owner, Map<targetKey, FsObservation>>`。映射中没有条目表示未见;`{ kind: 'absent' }` 表示 `read` 的元数据未命中,或 `str_replace_editor` 的 `view`、`str_replace`、`insert` 命令发生元数据未命中,从而确认缺失;`{ kind: 'present', version }` 表示 read、write 或 edit 观测到该版本。写入决策把未见和缺失映射到 `createIfAbsent`,把存在映射到 `replaceIfVersion`;编辑决策把未见映射到 `FS_NOT_OBSERVED`,把缺失映射到 `FS_NOT_FOUND`,把存在映射到其版本守卫。所有者从事件 actor 推导(通常是 `exec.agent.session`),被视为不透明且从不读取。dispose(资源释放)时丢弃全部数据(HMR(热模块替换)安全),策略不执行任何文件系统 I/O。
247
-
248
- ## 错误分类体系(提供方约定)
249
-
250
- 文件系统故障使用稳定的 `FsErrorCode` 字符串,由 `FsError`(`HarnessError`)携带。工具注册表在错误结果上保留 `{ name, code }`,使重试、权限和 UI 层可以按 code 分支而无需解析文本。
251
-
252
- ```ts type-equiv
253
- /**
254
- * Stable, machine-routable codes for filesystem failures. Carried on
255
- * {@link FsError}; the tool registry exposes `{ name, code }` on `isError`
256
- * results so retry/permission/UI layers can branch without parsing messages.
257
- */
258
- type FsErrorCode =
259
- | 'FS_NOT_FOUND'
260
- | 'FS_NOT_DIRECTORY'
261
- | 'FS_NOT_TEXT'
262
- | 'FS_NOT_REGULAR_FILE'
263
- | 'FS_TOO_LARGE'
264
- | 'FS_PERMISSION_DENIED'
265
- | 'FS_SANDBOX_DENIED'
266
- | 'FS_IO_ERROR'
267
- | 'FS_STALE_VERSION'
268
- | 'FS_NOT_OBSERVED'
269
- | 'FS_AMBIGUOUS_EDIT'
270
- | 'FS_EDIT_NOT_FOUND'
271
- | 'FS_ABORTED'
272
- ```
273
-
274
- 目录列表使用 `FS_NOT_DIRECTORY`、`FS_PERMISSION_DENIED` 与 `FS_IO_ERROR` 区分已存在但并非目录的目标、被拒绝的列表操作和意外的后端 I/O 失败。`FS_SANDBOX_DENIED` 是强制执行沙箱的后端(`dsh-fs-sandbox`)所作的策略拒绝——模式边界拒绝了写入/编辑——与 `FS_PERMISSION_DENIED`(宿主内核拒绝)不同。`FS_NOT_OBSERVED` 表示策略插件没有此所有者的先前观测记录(或 `createIfAbsent` 遇到了现有文件)。`FS_NOT_FOUND` 也表示策略因确认缺失而拒绝 edit。`FS_STALE_VERSION` 表示后端版本不再与观测到的版本匹配(或提供方本身收到针对缺失目标的 edit)。新鲜度授权没有部分/完整之分,因此不存在 `FS_PARTIAL_OBSERVATION`。
275
-
276
- ## 文件 IO 不设超时
277
-
278
- `read`/`write`/`edit` **不**接受 `timeoutMs`,提供方约定也不设置截止时间——不同于 bash 与 web(它们消费 [`@deepseek-ai/dsh-timeout`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/util/timeout/README.zh.md))以及 subprocess 支撑的 `glob`/`grep`(其声明的 `timeoutMs` 由 `@deepseek-ai/dsh-tool-call-timeout-policy` 强制执行):那些是进程支撑的,截止时间可以真正终止工作。本地系统调用至多是尽力中止——超时无法迫使进行中的 `fsync`/`rename` 停下,因此这里的 `timeoutMs` 会成为 seam 无法强制执行的截止时间,而且恰好落在「显式优于隐式」禁止隐式默认值的位置。取消仍通过工具执行 signal 传播,在系统调用边界尽力中止。
279
-
280
- ## 服务与插件
281
-
282
- `FileSystem`(`ctx.fs`,abstract)拥有提供方原语:`resolve`、`processPath`、`processPathFromHostPath`、`fileUrl`、`contains`、`stat`、`lstat`、`readText`、`streamText`、`readBytes`、`listDir`、`writeText` 与 `editText`。`dsh-fs-observation-policy` **不注册服务**。它通过 `fs/*` 事件门禁添加策略,根据未见、缺失或存在状态对写入与编辑意图 waterfall 作出决策,并记录 `FsObservation` 值。执行器是 `dsh-tool-fs`:它通过 `ctx.fs` 读取、写入或编辑,分发 waterfall,并 emit 记录事件。下方生成的 [`ctx.fs` 小节](#ctxfs--filesystem-abstract-seam) 展示确切的 `ctx.fs` 签名。
283
-
284
- <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
285
-
286
- <a id="cordis-surface"></a>
287
-
288
- ## Cordis API
289
-
290
- 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).
291
-
292
- <a id="ctxfs--filesystem-abstract-seam"></a>
293
-
294
- ### `ctx.fs` — `FileSystem` (abstract seam)
295
-
296
- Abstract filesystem provider. Targets must preserve identity across aliases; reads expose regular UTF-8 text or typed errors, listings are stable and content-free, and mutations are atomic. Optional guards add stale protection without changing the unguarded provider contract.
297
-
298
- ```ts cordis-catalog
299
- /**
300
- * Observe one file or a directory's direct entries in this provider's execution world.
301
- * @param target - resolved file or directory, including an absent path to observe for creation.
302
- * @param changed - invalidation callback; errors can be reported during or after initialization.
303
- * @param signal - cancels watcher initialization; the caller closes an initialized watcher.
304
- * @returns a promise resolving once observation is active, with an asynchronous close function.
305
- * @throws when the provider does not support watching or cannot initialize the watcher.
306
- */
307
- watch(target: FsTarget, changed: (error?: Error) => void, signal: AbortSignal): Promise<() => Promise<void>>
308
-
309
- /**
310
- * Resolve a model/plugin-supplied path into a stable {@link FsTarget}. May perform I/O (a
311
- * remote/sandboxed backend may need a round-trip to map a path to a stable identity), hence
312
- * async even though the local backend only normalizes + realpaths.
313
- *
314
- * @param path - the path to resolve; relative paths resolve against `opts.cwd`.
315
- * @param opts - optional cwd override and cancellation signal.
316
- * @returns the stable target; the same file yields the same `targetKey`.
317
- */
318
- abstract resolve(path: string, opts?: { cwd?: string; signal?: AbortSignal }): Promise<FsTarget>
319
-
320
- /**
321
- * Return the canonical absolute path a subprocess in this filesystem's
322
- * execution world can open. The path is deliberately separate from
323
- * {@link FsTarget.targetKey}: consumers may pass this value to another OS
324
- * capability, but must continue treating the target key as opaque.
325
- * @param target - the resolved target whose process path is required.
326
- * @returns an absolute path in the backend's execution world.
327
- */
328
- abstract processPath(target: FsTarget): string
329
-
330
- /**
331
- * Map an absolute path from the harness host into this filesystem's
332
- * execution world when both paths identify the same file. The base provider
333
- * exposes no mapping; host-backed or explicitly shared backends override it.
334
- * @param hostPath - absolute path in the harness host filesystem.
335
- * @returns the process path for the same file, or undefined when this
336
- * execution world cannot read that host file.
337
- */
338
- processPathFromHostPath(hostPath: string): string | undefined
339
-
340
- /**
341
- * Return the canonical `file:` URI for a target in this filesystem's
342
- * execution world. Backends own URI encoding because the host platform may
343
- * differ from the execution platform.
344
- * @param target - the resolved target to encode.
345
- * @returns the target's canonical file URI.
346
- */
347
- abstract fileUrl(target: FsTarget): string
348
-
349
- /**
350
- * Test canonical containment without exposing or parsing backend target
351
- * keys. Both targets must come from this provider.
352
- * @param parent - canonical directory target.
353
- * @param child - canonical candidate target.
354
- * @returns true when `child` is `parent` or a descendant of it.
355
- */
356
- abstract contains(parent: FsTarget, child: FsTarget): boolean
357
-
358
- /**
359
- * Return target metadata, or `undefined` when the target does not exist.
360
- * @param target - the resolved target to stat.
361
- * @param signal - aborts the metadata round-trip.
362
- * @returns metadata only, never content; undefined for an absent target.
363
- */
364
- abstract stat(target: FsTarget, signal?: AbortSignal): Promise<FsInfo | undefined>
365
-
366
- /**
367
- * Return path metadata without following the final path component when it is a
368
- * symbolic link. This is intentionally path-shaped, not target-shaped:
369
- * {@link resolve} follows symlinks to produce the stable identity used by
370
- * normal reads/writes, while `lstat` lets a consumer reject the path itself
371
- * before that follow happens.
372
- *
373
- * `opts.cwd` follows {@link resolve}'s cwd rules. `undefined` means the path is
374
- * absent.
375
- * @param path - the path to inspect; relative paths resolve against `opts.cwd`.
376
- * @param opts - `cwd` overrides the backend's default base for relative paths.
377
- * @param signal - aborts the metadata round-trip.
378
- * @returns metadata only, never content; undefined for an absent path.
379
- */
380
- abstract lstat(path: string, opts?: { cwd?: string }, signal?: AbortSignal): Promise<FsPathInfo | undefined>
381
-
382
- /**
383
- * Read the whole regular text file as a single decoded string.
384
- * @param target - the resolved target to read.
385
- * @param signal - aborts the read.
386
- * @returns the full decoded UTF-8 content.
387
- */
388
- abstract readText(target: FsTarget, signal?: AbortSignal): Promise<string>
389
-
390
- /**
391
- * Stream the whole regular text file as decoded text chunks (same text
392
- * semantics as {@link readText}, for large files). The backend owns
393
- * cross-chunk UTF-8 decoding and binary rejection so the policy layer never
394
- * touches raw bytes.
395
- * @param target - the resolved target to read.
396
- * @param signal - aborts the stream, including between chunks.
397
- * @returns the chunk iterable, decoded and validated like {@link readText}.
398
- */
399
- abstract streamText(target: FsTarget, signal?: AbortSignal): Promise<AsyncIterable<string>>
400
-
401
- /**
402
- * Read the whole regular file as raw bytes with no decoding or binary
403
- * rejection. The bound lives at this seam so a backend can never buffer an
404
- * unbounded file: a target known or discovered to exceed `maxBytes` fails
405
- * with `FS_TOO_LARGE` instead of returning a truncated result.
406
- * @param target - the resolved target to read.
407
- * @param signal - aborts the read.
408
- * @param maxBytes - inclusive byte cap on the complete content.
409
- * @returns the full raw content, at most `maxBytes` long.
410
- */
411
- abstract readBytes(target: FsTarget, signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array>
412
-
413
- /**
414
- * Read one byte window of the regular file as raw bytes with no decoding or
415
- * binary rejection: the bytes at `[offset, offset + length)`, shorter when
416
- * the file ends inside the window and empty when `offset` lies at or past
417
- * its end. The window is the bound here, not the file: a backend transfers
418
- * at most `length` bytes of content beyond the prefix it skips to reach
419
- * `offset` and never buffers the whole file, so the caller's cap on `length`
420
- * is the guard against unbounded buffering.
421
- * @param target - the resolved target to read.
422
- * @param range - `offset`, the 0-based first byte, and `length`, the largest byte count; both non-negative integers.
423
- * @param signal - aborts the read.
424
- * @returns the window's bytes, at most `length` long.
425
- */
426
- abstract readByteRange(target: FsTarget, range: { offset: number; length: number }, signal?: AbortSignal): Promise<Uint8Array>
427
-
428
- /**
429
- * List direct children of a directory in stable name order. Returns resolved
430
- * child targets plus cheap metadata only; never reads file contents.
431
- * @param target - the resolved directory target.
432
- * @param signal - aborts the listing.
433
- * @returns one entry per direct child, in stable name order.
434
- */
435
- abstract listDir(target: FsTarget, signal?: AbortSignal): Promise<FsDirEntry[]>
436
-
437
- /**
438
- * Atomically create or replace UTF-8 text. `expected` guards intent and
439
- * staleness; omission allows unconditional overwrite.
440
- * @param target - the resolved target to write.
441
- * @param content - the full new file content.
442
- * @param expected - the write intent guarding the write; omit for unconditional.
443
- * @param signal - aborts before atomic publication takes effect.
444
- * @param sandboxPolicy - the per-call mode and workspace root this write
445
- * runs under; a sandboxing backend fences the write by it, the bare backend
446
- * ignores it. Omit to leave the backend its own default.
447
- * @returns the outcome, including the version the write produced.
448
- */
449
- abstract writeText( target: FsTarget, content: string, expected?: FsWriteIntent, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy, ): Promise<FsWriteOutcome>
450
-
451
- /**
452
- * Atomically edit literal text. When supplied, the version guard is checked
453
- * before matching so stale content reports `FS_STALE_VERSION`; omission edits
454
- * the current content without a freshness precondition.
455
- * @param target - the resolved target to edit.
456
- * @param edit - the literal search/replace request.
457
- * @param expected - the version guard; omit for an unconditional edit.
458
- * @param signal - aborts before atomic publication takes effect.
459
- * @param sandboxPolicy - the per-call mode and workspace root this edit runs
460
- * under; a sandboxing backend fences the edit by it, the bare backend
461
- * ignores it. Omit to leave the backend its own default.
462
- * @returns the outcome, including the version the edit produced.
463
- */
464
- abstract editText( target: FsTarget, edit: FsEditRequest, expected?: { version: FsVersion }, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy, ): Promise<FsEditOutcome>
465
- ```
466
-
467
- Types: [SandboxExecutionPolicy](./sandbox.md)
468
-
469
- Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
470
-
471
- <a id="fs-events"></a>
472
-
473
- ### `fs/*` events
474
-
475
- <a id="fsedit-intent--waterfall"></a>
476
-
477
- #### `fs/edit-intent` — waterfall
478
-
479
- Single-slot decision for the next FileSystem.editText. Calling `next()` yields an unconditional edit; the first returned guard wins.
480
-
481
- ```ts cordis-catalog
482
- /**
483
- * Single-slot decision for the next {@link FileSystem.editText}. Calling
484
- * `next()` yields an unconditional edit; the first returned guard wins.
485
- * @param target - the resolved target about to be edited.
486
- * @param actor - the opaque tool-execution context the decider keys off.
487
- * @mode waterfall
488
- */
489
- 'fs/edit-intent'(target: FsTarget, actor: object | undefined, next: () => { version: FsVersion } | undefined | Promise<{ version: FsVersion } | undefined>): Promise<{ version: FsVersion } | undefined>
490
- ```
491
-
492
- Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
493
-
494
- <a id="fsobserved--emit"></a>
495
-
496
- #### `fs/observed` — emit
497
-
498
- Record an authoritative positive or negative observation. Listeners must be synchronous recorders: throws fail the tool call and returned promises are not awaited.
499
-
500
- ```ts cordis-catalog
501
- /**
502
- * Record an authoritative positive or negative observation. Listeners must
503
- * be synchronous recorders: throws fail the tool call and returned promises
504
- * are not awaited.
505
- * @param target - the target whose presence or absence was observed.
506
- * @param observation - present with its version, or confirmed absent.
507
- * @param actor - the observing tool-execution context; undefined records nothing useful.
508
- * @mode emit
509
- */
510
- 'fs/observed'(target: FsTarget, observation: FsObservation, actor: object | undefined): void
511
- ```
512
-
513
- Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
514
-
515
- <a id="fswrite-intent--waterfall"></a>
516
-
517
- #### `fs/write-intent` — waterfall
518
-
519
- Single-slot decision for the next FileSystem.writeText. Calling `next()` yields the bare provider's unconditional write; the first listener that returns an intent owns the decision rather than composing with peers.
520
-
521
- ```ts cordis-catalog
522
- /**
523
- * Single-slot decision for the next {@link FileSystem.writeText}. Calling
524
- * `next()` yields the bare provider's unconditional write; the first listener
525
- * that returns an intent owns the decision rather than composing with peers.
526
- * @param target - the resolved target about to be written.
527
- * @param actor - the opaque tool-execution context the decider keys off.
528
- * @mode waterfall
529
- */
530
- 'fs/write-intent'(target: FsTarget, actor: object | undefined, next: () => FsWriteIntent | undefined | Promise<FsWriteIntent | undefined>): Promise<FsWriteIntent | undefined>
531
- ```
532
-
533
- Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
534
- <!-- END GENERATED cordis-surface -->
1
+ ---
2
+ editSource: "docs/subsystems/filesystem.zh.md"
3
+ rawMarkdownPath: "reference/subsystems/filesystem.md"
4
+ outline: [2,3]
5
+ ---
6
+
7
+ # 文件系统
8
+
9
+ 可选的文件系统能力由以下角色组成:[dsh-fs](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/fs/fs) 拥有 `ctx.fs` 和受防护的文件变更操作;[dsh-fs-local](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/fs/fs-local) 实现本地磁盘后端;[dsh-fs-observation-policy](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/fs/fs-observation-policy) 记录观测到的存在或缺失状态,并通过事件(而非服务)添加新鲜度规则;[dsh-tool-fs](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/fs/tool-fs) 直接执行面向模型的 read/write/edit 调用并渲染窗口。它位于 agent loop(智能体循环)主干之外;替换后端不会改变策略或工具 schema。纯库 [dsh-fs-patch](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs-patch/README.zh.md) 提供补丁解析与文本应用。
10
+
11
+ `dsh-fs-observation-policy` 是可选插件。没有该插件时,`FileSystem` 服务定义、一个提供方和 `dsh-tool-fs` 消费方组成完整且不受约束的文件系统 seam:`write` 无条件创建或覆盖,`edit` 无条件替换字面文本。策略插件通过裁决 `fs/*` waterfall(瀑布式事件)来改变这些操作。移除该插件不会破坏工具,因为工具调用 `ctx.fs` 并分发事件,而不调用策略方法。随发行版交付的组合不启用它:`dsh-base` 中的 `fs-observation-policy` 行写着 `disabled: true`,需要「先读后写/编辑」的部署把该行改为 `disabled: false`。
12
+
13
+ 提供方源码:[`packages/fs/fs/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/types.ts) 与 [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)。策略源码:[`packages/fs/fs-observation-policy/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs-observation-policy/src/types.ts)。读取渲染源码:[`packages/fs/tool-fs/src/read-render.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/tool-fs/src/read-render.ts)。
14
+
15
+ ## 目标标识与元数据(提供方约定)
16
+
17
+ 每个操作首先将用户提供的路径解析为不透明的后端目标。消费方可以显示 `displayPath`,但禁止解析 `targetKey`(一个品牌化的不透明 id),也不得假设它是本地绝对路径。
18
+
19
+ 与文件系统共享执行世界的消费方通过提供方获取跨能力坐标,而不是解释该身份:`processPath(target)` 返回子进程可以打开的规范化绝对路径;`processPathFromHostPath(hostPath)` 只在该执行世界共享相应宿主文件时映射其绝对路径;`fileUrl(target)` 返回采用提供方平台语法的 `file:` URI;`contains(parent, child)` 检查规范化身份相等或后代包含关系。
20
+
21
+ ```ts type-equiv
22
+ /**
23
+ * A path resolved by a backend into a stable identity. `resolve()` produces
24
+ * this; every other operation takes it.
25
+ */
26
+ interface FsTarget {
27
+ /** Opaque key for stale guards and target lookup. */
28
+ targetKey: FsTargetKey
29
+ /**
30
+ * Path for model/UI-facing output. May be a local absolute path,
31
+ * workspace-relative path, or remote URI depending on the backend.
32
+ */
33
+ displayPath: string
34
+ }
35
+ ```
36
+
37
+ 后端拥有文件版本 token,即变更所守卫的新鲜度 token。策略插件存储它们以进行陈旧检查;消费方不解释其内容。两个 id 都是品牌化的不透明字符串。
38
+
39
+ ```ts type-equiv
40
+ /**
41
+ * Opaque key for stale guards and target lookup. The local backend uses a
42
+ * realpath-like string; a remote backend might use a workspace URI or file id.
43
+ * Consumers MUST NOT parse it or assume it is a local absolute path.
44
+ */
45
+ type FsTargetKey = Branded<'FsTargetKey'>
46
+ ```
47
+
48
+ ```ts type-equiv
49
+ /**
50
+ * Opaque file-version token — the freshness token a write/edit guards against.
51
+ * The local backend derives it from high-resolution stat identity and freshness
52
+ * fields; a remote backend might use a revision id. The policy layer records it
53
+ * for stale checks; consumers may display related metadata but MUST NOT
54
+ * interpret this token.
55
+ */
56
+ type FsVersion = Branded<'FsVersion'>
57
+ ```
58
+
59
+ `stat` 返回元数据(从不返回内容),目标不存在时返回 `undefined`。`type` 让消费方在读取前拒绝目录和特殊文件;`size` 让文本消费方无需通过失败探测即可选择 `readText` 还是 `streamText`。文本消费方在消费 `streamText` 时执行自己的保留量上限。原始字节消费方调用 `readBytes(target, signal, maxBytes)`;其必填的完整内容上限会使已知或读取中发现的超限以 `FS_TOO_LARGE` 失败,不会截断结果或无界缓冲。
60
+
61
+ ```ts type-equiv
62
+ /**
63
+ * Metadata about a target — what {@link FileSystem.stat} returns. Lets the
64
+ * policy layer reject directories/special files before reading and choose
65
+ * `readText` vs `streamText` from `size` without probing by failure. `version`
66
+ * is the freshness token. `undefined` from `stat` means the target is absent.
67
+ */
68
+ interface FsInfo {
69
+ /** Opaque freshness token of the target right now. */
70
+ version: FsVersion
71
+ /** Whether the target is a regular file, a directory, or something else. */
72
+ type: 'file' | 'directory' | 'other'
73
+ /** Byte size of a regular file, when the backend can report it. */
74
+ size?: number
75
+ }
76
+ ```
77
+
78
+ `lstat` 是路径级、不跟随链接的元数据原语。它接收路径而不是 `FsTarget`,因为 `resolve` 会有意跟随 symlink 以产生稳定标识;需要检查信任边界的消费方可以先调用 `lstat`,在解析前拒绝 `symlink`。
79
+
80
+ ```ts type-equiv
81
+ /**
82
+ * Metadata about a path without following the final path component when it is a
83
+ * symbolic link. Unlike {@link FsInfo}, this path-level probe can report
84
+ * `symlink` so consumers with trust-boundary rules can reject repository-owned
85
+ * links before resolving a target.
86
+ */
87
+ interface FsPathInfo {
88
+ /** Opaque freshness token of the path entry right now. */
89
+ version: FsVersion
90
+ /** Whether the path entry is a regular file, directory, symlink, or other. */
91
+ type: 'file' | 'directory' | 'symlink' | 'other'
92
+ /** Byte size of the path entry, when the backend can report it. */
93
+ size?: number
94
+ }
95
+ ```
96
+
97
+ `listDir` 按稳定的名称顺序返回直接子条目。每个条目携带子项的 basename、类型、已解析目标,以及后端能报告时的廉价元数据。它禁止读取文件内容,因此 `size` 仅用于普通文件,`version` 来自元数据。已损坏或已消失的子项可以作为 `other` 返回且不带元数据;列出或解析子项元数据时的权限或后端 I/O 失败会以 `FS_PERMISSION_DENIED` 或 `FS_IO_ERROR` 使整个列表操作失败。
98
+
99
+ ```ts type-equiv
100
+ /**
101
+ * One direct child returned by {@link FileSystem.listDir}. Listing returns
102
+ * metadata and resolved targets only; it must not read file contents.
103
+ */
104
+ interface FsDirEntry {
105
+ /** Basename of the child inside the listed directory. */
106
+ name: string
107
+ /** Whether the child is a regular file, a directory, or something else. */
108
+ type: 'file' | 'directory' | 'other'
109
+ /** Resolved child target for follow-up operations. */
110
+ target: FsTarget
111
+ /** Opaque freshness token when the backend can report metadata cheaply. */
112
+ version?: FsVersion
113
+ /** Byte size of a regular file, when the backend can report it. */
114
+ size?: number
115
+ }
116
+ ```
117
+
118
+ <a id="patch-syntax-records"></a>
119
+ ## 补丁语法记录
120
+
121
+ [dsh-fs-patch](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs-patch/README.zh.md) 将完整补丁文本解析为可序列化的操作,路径保持为未解析的字符串;`applyHunks` 将 hunk 应用于调用方提供的 LF 规范化文本,返回完整新文本或结构化匹配失败。固定的解析与匹配规则由包 README 维护。
122
+
123
+ ```ts type-equiv
124
+ /** One contiguous update. */
125
+ interface PatchHunk {
126
+ /** One-based input line containing the marker or first implicit hunk line. */
127
+ lineNumber: number
128
+ /** Text following `@@ `, used as a search anchor by the text matcher. */
129
+ context?: string
130
+ /** Context and removed lines, without patch prefixes or line endings. */
131
+ oldLines: string[]
132
+ /** Context and added lines, without patch prefixes or line endings. */
133
+ newLines: string[]
134
+ /** Whether `*** End of File` follows this hunk. */
135
+ isEndOfFile: boolean
136
+ }
137
+
138
+ ```
139
+
140
+ ```ts type-equiv
141
+ /** Ordered file operation; a move is an update with a destination path. */
142
+ type PatchOperation =
143
+ | {
144
+ kind: 'add'
145
+ path: string
146
+ lineNumber: number
147
+ /** Added lines joined with LF, including a final LF for every added line. */
148
+ content: string
149
+ }
150
+ | {
151
+ kind: 'delete'
152
+ path: string
153
+ lineNumber: number
154
+ }
155
+ | {
156
+ kind: 'update'
157
+ path: string
158
+ lineNumber: number
159
+ moveTo?: string
160
+ hunks: PatchHunk[]
161
+ }
162
+ ```
163
+
164
+ ```ts type-equiv
165
+ /** The first hunk whose anchor or old lines could not be located in the original text. */
166
+ interface HunkApplyFailure {
167
+ /** One-based line of the failing hunk in the patch input. */
168
+ hunkLineNumber: number
169
+ /** The failed anchor or old-content search. */
170
+ stage: 'context' | 'oldLines'
171
+ /** Zero-based sequential search cursor; EOF searches override it with the tail candidate. */
172
+ searchStart: number
173
+ /** Original anchor or old lines, including any trailing empty line retried without its sentinel. */
174
+ pattern: string[]
175
+ }
176
+
177
+ ```
178
+
179
+ ```ts type-equiv
180
+ /** Complete new text or a match failure; failures contain no partially updated text. */
181
+ type ApplyHunksResult =
182
+ | { ok: true; after: string }
183
+ | { ok: false; failure: HunkApplyFailure }
184
+ ```
185
+
186
+ ## 写入与编辑守卫(提供方约定)
187
+
188
+ 相同的可选防护规则也覆盖补丁、删除和移动。提供方不记录观察;调用方分派意图并记录已完成的结果。
189
+
190
+ | 操作 | 意图 | 成功观察 |
191
+ |---|---|---|
192
+ | `patchText` | `fs/edit-intent` | 目标存在于返回的版本。 |
193
+ | `deleteFile` | `fs/delete-intent` | 源缺失。 |
194
+ | `moveFile` 源 | `fs/edit-intent` | 仅在 `sourceDeleted` 为 true 时记录源缺失。 |
195
+ | `moveFile` 目标 | `fs/write-intent` | 目标存在于 `destination.version`。 |
196
+
197
+ 补丁、删除和移动的源必须是普通文件;源缺失或版本陈旧报告 `FS_STALE_VERSION`。补丁在变更锁内对 LF 规范化文本匹配,不匹配报告 `FS_PATCH_MISMATCH`,包含补丁 hunk 行号与阶段。移动以 `FS_SAME_TARGET` 拒绝相同目标 key,对目标使用写入防护,并保留源的行尾风格与模式。删除、移动源和被覆盖目标的基线是有界、可空的 LF 文本。移动是两个效果:目标可能已发布而源删除失败。本地移动在暂存目标前检查取消;随后提供方完成两端效果并报告结果。
198
+
199
+ 目标已跟随符号链接,因此拒绝符号链接源的调用方在 `resolve` 前用 `lstat` 检查路径。
200
+
201
+ ```ts type-equiv
202
+ /** Outcome of a guarded delete; the bounded basis follows FsWriteOutcome.before. */
203
+ interface FsDeleteOutcome {
204
+ /** LF-normalized removed content, or null for an unavailable, binary, or over-limit basis. */
205
+ before: string | null
206
+ }
207
+ ```
208
+
209
+ ```ts type-equiv
210
+ /** Serializable failure after a move has published its destination but retained its source. */
211
+ interface FsMoveSourceFailure {
212
+ /** Filesystem failure code for source removal. */
213
+ code: FsErrorCode
214
+ /** Diagnostic identifying the source and the failed removal. */
215
+ message: string
216
+ }
217
+ ```
218
+
219
+ ```ts type-equiv
220
+ /** Published destination and removal status; sourceBefore is the bounded LF source basis captured under the move lock. */
221
+ type FsMoveOutcome =
222
+ | { sourceBefore: string | null; destination: FsWriteOutcome; sourceDeleted: true }
223
+ | { sourceBefore: string | null; destination: FsWriteOutcome; sourceDeleted: false; sourceFailure: FsMoveSourceFailure }
224
+ ```
225
+
226
+ `writeText` 和 `editText` 的版本守卫都是可选的:省略守卫时执行无条件的裸提供方变更,提供守卫时则执行相应的条件检查。`writeText` 的守卫是 `FsWriteIntent`:`createIfAbsent` 在目标缺失时创建,目标已存在时以 `FS_NOT_OBSERVED` 拒绝;即使目标在提供方初始探测后才出现,也必须拒绝,因为发布操作本身不得替换。`replaceIfVersion` 仅在目标存在且版本匹配时替换,否则报 `FS_STALE_VERSION`。省略 `expected` 则无条件创建或覆盖。联合类型本身只包含两种有守卫的意图;「无守卫」通过省略表达,因此 write 和 edit 都使用同一个可选的 `expected` 字段。
227
+
228
+ ```ts type-equiv
229
+ /**
230
+ * Guarded write intent. `createIfAbsent` rejects an existing target with
231
+ * `FS_NOT_OBSERVED`; `replaceIfVersion` rejects absence or mismatch with
232
+ * `FS_STALE_VERSION`. Omitting the intent from `writeText` means unconditional
233
+ * create-or-overwrite, not a third union arm.
234
+ */
235
+ type FsWriteIntent =
236
+ | { kind: 'createIfAbsent' }
237
+ | { kind: 'replaceIfVersion'; version: FsVersion }
238
+ ```
239
+
240
+ ```ts type-equiv
241
+ /** Outcome of a full-file write. */
242
+ interface FsWriteOutcome {
243
+ /** Whether the write created a new file or replaced an existing one. */
244
+ operation: 'create' | 'update'
245
+ /** Opaque version of the file after the write. */
246
+ version: FsVersion
247
+ /**
248
+ * The file's content BEFORE the write, or `null` when the file did not exist
249
+ * (a create) or the backend declined a contextual basis (for example, a
250
+ * binary/non-UTF-8 prior file or either overwrite side reaching its exclusive limit).
251
+ * LF-normalized storage text (the diff basis), never a diff — a consumer
252
+ * computes the result-time contextual diff from `before`/`after` when
253
+ * `before` is present, else falls back to a whole-file diff.
254
+ */
255
+ before: string | null
256
+ /** The file's content AFTER the write, LF-normalized to share `before`'s diff basis. */
257
+ after: string
258
+ }
259
+ ```
260
+
261
+ `editText` 是提供方级别的变更操作,而非在别处组合的 `read` 加 `write`。带守卫时,它在字面匹配之前先验证预期版本(因此对陈旧内容的编辑报 `FS_STALE_VERSION`,而非对更新内容的匹配失败);不带守卫时,它编辑当前内容。无论哪种路径,它都应用替换并原子写入——将匹配、行尾处理、陈旧检查和原子替换保持在一个变更临界区内——目标缺失时两条路径都报 `FS_STALE_VERSION`。
262
+
263
+ ```ts type-equiv
264
+ /** A literal-replacement edit request. */
265
+ interface FsEditRequest {
266
+ /** Literal non-empty text to replace. Must match exactly (after line-ending normalization). */
267
+ oldString: string
268
+ /** Literal replacement text. An empty string deletes the matched text. */
269
+ newString: string
270
+ /** Replace every match instead of requiring exactly one. */
271
+ replaceAll: boolean
272
+ }
273
+ ```
274
+
275
+ ```ts type-equiv
276
+ /** Outcome of a literal edit. */
277
+ interface FsEditOutcome {
278
+ /** Opaque version of the file after the edit. */
279
+ version: FsVersion
280
+ /**
281
+ * The file's content BEFORE the edit. Raw storage text (LF-normalized by the
282
+ * backend), never a diff — a consumer computes the result-time contextual diff
283
+ * (the applied hunk with context) from `before`/`after`.
284
+ */
285
+ before: string
286
+ /** The file's content AFTER the edit. */
287
+ after: string
288
+ }
289
+ ```
290
+
291
+ ## fs 策略事件(提供方约定词汇)
292
+
293
+ `dsh-fs` 为变更消费方与观察策略定义四个事件。消费方在操作前分发意图,并记录已完成的效果,无需依赖策略插件。它们只携带 `dsh-fs` 词汇加一个不透明的 `object` actor,不含面向模型的概念,也不含 agent/会话所有者结构。
294
+
295
+ `fs/write-intent`、`fs/edit-intent` 与 `fs/delete-intent` 是**单槽决策 waterfall**:工具分发时附带一个默认 thunk(返回 `undefined`,即裸提供方),监听方完全决策而不调用 `next()`。该 slot 按注册顺序先到先得——由策略插件占据是部署约定,而非强制不变式。`fs/observed` 是一个即发即弃的记录事件,携带 `FsObservation`:存在于某个版本,或确认缺失。该事件通过普通 `ctx.emit` 分发;其监听方必须是同步的、仅产生副作用,因为工具不会捕获该 emit 抛出的异常——抛出异常的监听方可能取代读取操作原本待返回的错误,或使工具在变更已经成功后返回 `isError` 结果。下方生成的 [cordis surface](#cordis-surface) 展示确切签名。
296
+
297
+ ```ts type-equiv
298
+ /**
299
+ * One authoritative observation of a target. A present observation carries the
300
+ * version used by guarded replacement; an absent observation authorizes only a
301
+ * guarded create, never an edit.
302
+ */
303
+ type FsObservation =
304
+ | { readonly kind: 'present'; readonly version: FsVersion }
305
+ | { readonly kind: 'absent' }
306
+ ```
307
+
308
+ ## 执行上下文(策略插件)
309
+
310
+ 策略插件只需要足够的执行上下文,通过收窄 `fs/*` 事件携带的不透明 `object` actor 来推导观测状态的所有者。`ToolExecution` 包含必需的字段,因此 `dsh-tool-fs` 将其执行对象作为 actor 直接传递,而无需让 `dsh-fs-observation-policy` 导入工具、agent 或会话包。
311
+
312
+ ```ts type-equiv
313
+ /**
314
+ * Minimal structural view of a tool execution the policy plugin needs to derive
315
+ * an observed-state owner. `@deepseek-ai/dsh-tools`' `ToolExecution` contains
316
+ * these fields, so the tool passes its `exec` straight through as the opaque
317
+ * `object` actor on the `fs/*` events; this plugin narrows that actor to
318
+ * `FsObservationActor` without importing `dsh-tools`, `dsh-agent`, or `dsh-session`.
319
+ *
320
+ * The owner is `agent.session` when present. It is treated as an opaque object
321
+ * identity (a `WeakMap` key); this package never reads any of its fields.
322
+ */
323
+ interface FsObservationActor {
324
+ /** The agent on whose behalf the call runs, when there is one. */
325
+ agent?: {
326
+ /** The session that owns observed-file state, used as an opaque key. */
327
+ session?: object
328
+ }
329
+ }
330
+ ```
331
+
332
+ ## 读取结果(消费方 / 读取渲染)
333
+
334
+ 文本读取受行窗口、字节上限和后端限制约束。达到字节上限后,扫描仍会继续,但不再保留更多行,因此 `totalLines` 仍为精确值。面向模型的 `read` 工具渲染的结果纯粹是展示性的;不存在 `full`/`partial` 视图区分——授权基于新鲜度(工具发出表示目标存在的 `fs/observed` 事件,并直接携带 stat 的版本),因此任何窗口化读取在文件未变时都能授权后续的 write/edit。元数据未命中时,工具会在返回 `FS_NOT_FOUND` 前 emit 缺失观测,使后续带守卫的写入可以重新创建外部删除的目标,但不会授权 edit。拥有读取操作的执行器 `dsh-tool-fs` 实现读取窗口化并构造该结果;策略插件不执行这些操作。
335
+
336
+ ```ts type-equiv
337
+ /** Outcome of a bounded text read — what {@link formatReadOutput} renders. */
338
+ interface FileReadOutcome {
339
+ /** 1-based first line requested. */
340
+ offset: number
341
+ /** Returned lines, already numbered. */
342
+ lines: FileTextLine[]
343
+ /** Exact total line count in the file. */
344
+ totalLines: number
345
+ /** Whether selected output hit the byte cap. */
346
+ truncatedByBytes?: true
347
+ }
348
+ ```
349
+
350
+ ## 已观测文件状态(策略插件)
351
+
352
+ 已观测状态是 `dsh-fs-observation-policy` 插件内部持有的 `WeakMap<owner, Map<targetKey, FsObservation>>`。映射中没有条目表示未见;`{ kind: 'absent' }` 表示 `read` 的元数据未命中,或 `str_replace_editor` 的 `view`、`str_replace`、`insert` 命令发生元数据未命中,从而确认缺失;`{ kind: 'present', version }` 表示 read、write 或 edit 观测到该版本。写入决策把未见和缺失映射到 `createIfAbsent`,把存在映射到 `replaceIfVersion`;编辑/删除决策把未见映射到 `FS_NOT_OBSERVED`,把缺失映射到 `FS_NOT_FOUND`,把存在映射到其版本守卫。所有者从事件 actor 推导(通常是 `exec.agent.session`),被视为不透明且从不读取。dispose(资源释放)时丢弃全部数据(HMR(热模块替换)安全),策略不执行任何文件系统 I/O。
353
+
354
+ ## 补丁执行(消费方)
355
+
356
+ 内部 [tool-fs 补丁执行器](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/tool-fs/README.zh.md#understand-the-implementation) 在预检时分发意图决策而不发出观察、模拟前序操作,并在每次提交时重新取得防护。沙箱围栏与 `write`、`edit` 一样由提供方在提交时判断。提供方结果决定记录哪些效果;执行器细节与失败保证由包 README 维护。
357
+
358
+ | 操作 | 首次使用目标的预检意图 | 提交意图 | 成功观察 |
359
+ |---|---|---|---|
360
+ | add | `fs/write-intent` | `fs/write-intent` | 目标 present(version) |
361
+ | update | `fs/edit-intent` | `fs/edit-intent` | 目标 present(version) |
362
+ | delete | `fs/delete-intent` | `fs/delete-intent` | 目标 absent |
363
+ | move | 源 `fs/edit-intent`;目标 `fs/write-intent` | 重新分发同一组意图 | 目标 present(version);仅在源删除成功时记录 absent |
364
+
365
+ `apply_patch` 工具返回严格的提交值,包含各操作诊断及用于渲染的完整文本变更输入;持久化元数据只保留基于提供方有界基线的 diff hunk 与停止标志。语法和预检拒绝为 `isError: true`;停止的提交报告仍为 `isError: false`,确保已知部分 diff 进入 Session 展示,但被取消的调用与其他工具一样收到工具注册表的中止结果。[工具 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/tool-fs/README.zh.md#use-this-package) 维护格式与恢复规则。
366
+
367
+ ## 错误分类体系(提供方约定)
368
+
369
+ 文件系统故障使用稳定的 `FsErrorCode` 字符串,由 `FsError`(`HarnessError`)携带。工具注册表在错误结果上保留 `{ name, code }`,使重试、权限和 UI 层可以按 code 分支而无需解析文本。
370
+
371
+ `FS_PATCH_MISMATCH` 表示 hunk 在提供方提交阶段未匹配;消息标明补丁行号与失败的搜索阶段。`FS_SAME_TARGET` 表示移动源与目标共享已解析身份。删除意图遵循编辑意图:未见为 `FS_NOT_OBSERVED`,观察到缺失为 `FS_NOT_FOUND`,存在状态提供版本。提供方收到缺失的补丁/删除/移动源时,即使没有防护也使用 `FS_STALE_VERSION`。
372
+
373
+ ```ts
374
+ import { FS_ERROR_CODES } from '@deepseek-ai/dsh-fs'
375
+ ```
376
+
377
+ ```ts type-equiv
378
+ /** One machine-routable filesystem failure code from FS_ERROR_CODES. */
379
+ type FsErrorCode = typeof FS_ERROR_CODES[number]
380
+ ```
381
+
382
+ 目录列表使用 `FS_NOT_DIRECTORY`、`FS_PERMISSION_DENIED` 与 `FS_IO_ERROR` 区分已存在但并非目录的目标、被拒绝的列表操作和意外的后端 I/O 失败。`FS_SANDBOX_DENIED` 是强制执行沙箱的后端(`dsh-fs-sandbox`)所作的策略拒绝——模式边界拒绝了变更——与 `FS_PERMISSION_DENIED`(宿主内核拒绝)不同。`FS_NOT_OBSERVED` 表示策略插件没有此所有者的先前观测记录(或 `createIfAbsent` 遇到了现有文件)。`FS_NOT_FOUND` 也表示策略因确认缺失而拒绝 edit。`FS_STALE_VERSION` 表示后端版本不再与观测到的版本匹配(或提供方本身收到针对缺失目标的 edit)。新鲜度授权没有部分/完整之分,因此不存在 `FS_PARTIAL_OBSERVATION`。`FS_ALREADY_EXISTS` 表示仅创建的工具命令遇到了已存在的目标;调用方应换一个路径或编辑现有文件。`dsh-fs-local` 与 `dsh-fs-sandbox` 的包含性检查用 `dsh-fs` 的函数 `fsErrorFromErrno` 分类解析、元数据、读取与目录列表中的 errno 失败:`ENOENT` 与 `ENOTDIR` 报告 `FS_NOT_FOUND`,`EACCES` 与 `EPERM` 报告 `FS_PERMISSION_DENIED`,`EISDIR` 报告 `FS_NOT_REGULAR_FILE`,其他 errno 报告 `FS_IO_ERROR`,均以 Node 错误为 `cause`。
383
+
384
+ ## 文件 IO 不设超时
385
+
386
+ `read`/`write`/`edit` **不**接受 `timeoutMs`,提供方约定也不设置截止时间——不同于 bash 与 web(它们消费 [`@deepseek-ai/dsh-timeout`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/util/timeout/README.zh.md))以及 subprocess 支撑的 `glob`/`grep`(其声明的 `timeoutMs` 由 `@deepseek-ai/dsh-tool-call-timeout-policy` 强制执行):那些是进程支撑的,截止时间可以真正终止工作。本地系统调用至多是尽力中止——超时无法迫使进行中的 `fsync`/`rename` 停下,因此这里的 `timeoutMs` 会成为 seam 无法强制执行的截止时间,而且恰好落在「显式优于隐式」禁止隐式默认值的位置。取消仍通过工具执行 signal 传播,在系统调用边界尽力中止。
387
+
388
+ ## 服务与插件
389
+
390
+ `FileSystem`(`ctx.fs`,abstract)拥有提供方原语:`resolve`、`processPath`、`processPathFromHostPath`、`fileUrl`、`contains`、`stat`、`lstat`、`readText`、`streamText`、`readBytes`、`listDir`、`writeText`、`editText`、`patchText`、`deleteFile` 与 `moveFile`。`dsh-fs-observation-policy` **不注册服务**。它通过 `fs/*` 事件门禁添加策略,根据未见、缺失或存在状态对写入、编辑与删除意图 waterfall 作出决策,并记录 `FsObservation` 值。执行器是 `dsh-tool-fs`:它通过 `ctx.fs` 读取、写入或编辑,分发 waterfall,并 emit 记录事件。下方生成的 [`ctx.fs` 小节](#ctxfs--filesystem-abstract-seam) 展示确切的 `ctx.fs` 签名。
391
+
392
+ <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
393
+
394
+ <a id="cordis-surface"></a>
395
+
396
+ ## Cordis API
397
+
398
+ 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).
399
+
400
+ <a id="ctxfs--filesystem-abstract-seam"></a>
401
+
402
+ ### `ctx.fs` — `FileSystem` (abstract seam)
403
+
404
+ Abstract filesystem provider. Targets must preserve identity across aliases; reads expose regular UTF-8 text or typed errors, listings are stable and content-free, and single-file publication is atomic. Moves can retain their source after publishing the destination. Optional guards add stale protection without changing the unguarded provider contract.
405
+
406
+ ```ts cordis-catalog
407
+ /**
408
+ * Observe one file or a directory's direct entries in this provider's execution world.
409
+ * @param target - resolved file or directory, including an absent path to observe for creation.
410
+ * @param changed - invalidation callback; errors can be reported during or after initialization.
411
+ * @param signal - cancels watcher initialization; the caller closes an initialized watcher.
412
+ * @returns a promise resolving once observation is active, with an asynchronous close function.
413
+ * @throws when the provider does not support watching or cannot initialize the watcher.
414
+ */
415
+ watch(target: FsTarget, changed: (error?: Error) => void, signal: AbortSignal): Promise<() => Promise<void>>
416
+
417
+ /**
418
+ * Resolve a model/plugin-supplied path into a stable {@link FsTarget}. May perform I/O (a
419
+ * remote/sandboxed backend may need a round-trip to map a path to a stable identity), hence
420
+ * async even though the local backend only normalizes + realpaths.
421
+ *
422
+ * @param path - the path to resolve; relative paths resolve against `opts.cwd`.
423
+ * @param opts - optional cwd override and cancellation signal.
424
+ * @returns the stable target; the same file yields the same `targetKey`.
425
+ */
426
+ abstract resolve(path: string, opts?: { cwd?: string; signal?: AbortSignal }): Promise<FsTarget>
427
+
428
+ /**
429
+ * Return the canonical absolute path a subprocess in this filesystem's
430
+ * execution world can open. The path is deliberately separate from
431
+ * {@link FsTarget.targetKey}: consumers may pass this value to another OS
432
+ * capability, but must continue treating the target key as opaque.
433
+ * @param target - the resolved target whose process path is required.
434
+ * @returns an absolute path in the backend's execution world.
435
+ */
436
+ abstract processPath(target: FsTarget): string
437
+
438
+ /**
439
+ * Map an absolute path from the harness host into this filesystem's
440
+ * execution world when both paths identify the same file. The base provider
441
+ * exposes no mapping; host-backed or explicitly shared backends override it.
442
+ * @param hostPath - absolute path in the harness host filesystem.
443
+ * @returns the process path for the same file, or undefined when this
444
+ * execution world cannot read that host file.
445
+ */
446
+ processPathFromHostPath(hostPath: string): string | undefined
447
+
448
+ /**
449
+ * Return the canonical `file:` URI for a target in this filesystem's
450
+ * execution world. Backends own URI encoding because the host platform may
451
+ * differ from the execution platform.
452
+ * @param target - the resolved target to encode.
453
+ * @returns the target's canonical file URI.
454
+ */
455
+ abstract fileUrl(target: FsTarget): string
456
+
457
+ /**
458
+ * Test canonical containment without exposing or parsing backend target
459
+ * keys. Both targets must come from this provider.
460
+ * @param parent - canonical directory target.
461
+ * @param child - canonical candidate target.
462
+ * @returns true when `child` is `parent` or a descendant of it.
463
+ */
464
+ abstract contains(parent: FsTarget, child: FsTarget): boolean
465
+
466
+ /**
467
+ * Return target metadata, or `undefined` when the target does not exist.
468
+ * @param target - the resolved target to stat.
469
+ * @param signal - aborts the metadata round-trip.
470
+ * @returns metadata only, never content; undefined for an absent target.
471
+ */
472
+ abstract stat(target: FsTarget, signal?: AbortSignal): Promise<FsInfo | undefined>
473
+
474
+ /**
475
+ * Return path metadata without following the final path component when it is a
476
+ * symbolic link. This is intentionally path-shaped, not target-shaped:
477
+ * {@link resolve} follows symlinks to produce the stable identity used by
478
+ * normal reads/writes, while `lstat` lets a consumer reject the path itself
479
+ * before that follow happens.
480
+ *
481
+ * `opts.cwd` follows {@link resolve}'s cwd rules. `undefined` means the path is
482
+ * absent.
483
+ * @param path - the path to inspect; relative paths resolve against `opts.cwd`.
484
+ * @param opts - `cwd` overrides the backend's default base for relative paths.
485
+ * @param signal - aborts the metadata round-trip.
486
+ * @returns metadata only, never content; undefined for an absent path.
487
+ */
488
+ abstract lstat(path: string, opts?: { cwd?: string }, signal?: AbortSignal): Promise<FsPathInfo | undefined>
489
+
490
+ /**
491
+ * Read the whole regular text file as a single decoded string.
492
+ * @param target - the resolved target to read.
493
+ * @param signal - aborts the read.
494
+ * @returns the full decoded UTF-8 content.
495
+ */
496
+ abstract readText(target: FsTarget, signal?: AbortSignal): Promise<string>
497
+
498
+ /**
499
+ * Stream the whole regular text file as decoded text chunks (same text
500
+ * semantics as {@link readText}, for large files). The backend owns
501
+ * cross-chunk UTF-8 decoding and binary rejection so the policy layer never
502
+ * touches raw bytes.
503
+ * @param target - the resolved target to read.
504
+ * @param signal - aborts the stream, including between chunks.
505
+ * @returns the chunk iterable, decoded and validated like {@link readText}.
506
+ */
507
+ abstract streamText(target: FsTarget, signal?: AbortSignal): Promise<AsyncIterable<string>>
508
+
509
+ /**
510
+ * Read the whole regular file as raw bytes with no decoding or binary
511
+ * rejection. The bound lives at this seam so a backend can never buffer an
512
+ * unbounded file: a target known or discovered to exceed `maxBytes` fails
513
+ * with `FS_TOO_LARGE` instead of returning a truncated result.
514
+ * @param target - the resolved target to read.
515
+ * @param signal - aborts the read.
516
+ * @param maxBytes - inclusive byte cap on the complete content.
517
+ * @returns the full raw content, at most `maxBytes` long.
518
+ */
519
+ abstract readBytes(target: FsTarget, signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array>
520
+
521
+ /**
522
+ * Read one byte window of the regular file as raw bytes with no decoding or
523
+ * binary rejection: the bytes at `[offset, offset + length)`, shorter when
524
+ * the file ends inside the window and empty when `offset` lies at or past
525
+ * its end. The window is the bound here, not the file: a backend transfers
526
+ * at most `length` bytes of content beyond the prefix it skips to reach
527
+ * `offset` and never buffers the whole file, so the caller's cap on `length`
528
+ * is the guard against unbounded buffering.
529
+ * @param target - the resolved target to read.
530
+ * @param range - `offset`, the 0-based first byte, and `length`, the largest byte count; both non-negative integers.
531
+ * @param signal - aborts the read.
532
+ * @returns the window's bytes, at most `length` long.
533
+ */
534
+ abstract readByteRange(target: FsTarget, range: { offset: number; length: number }, signal?: AbortSignal): Promise<Uint8Array>
535
+
536
+ /**
537
+ * List direct children of a directory in stable name order. Returns resolved
538
+ * child targets plus cheap metadata only; never reads file contents.
539
+ * @param target - the resolved directory target.
540
+ * @param signal - aborts the listing.
541
+ * @returns one entry per direct child, in stable name order.
542
+ */
543
+ abstract listDir(target: FsTarget, signal?: AbortSignal): Promise<FsDirEntry[]>
544
+
545
+ /**
546
+ * Atomically create or replace UTF-8 text. `expected` guards intent and
547
+ * staleness; omission allows unconditional overwrite.
548
+ * @param target - the resolved target to write.
549
+ * @param content - the full new file content.
550
+ * @param expected - the write intent guarding the write; omit for unconditional.
551
+ * @param signal - aborts before atomic publication takes effect.
552
+ * @param sandboxPolicy - the per-call mode and workspace root this write
553
+ * runs under; a sandboxing backend fences the write by it, the bare backend
554
+ * ignores it. Omit to leave the backend its own default.
555
+ * @returns the outcome, including the version the write produced.
556
+ */
557
+ abstract writeText( target: FsTarget, content: string, expected?: FsWriteIntent, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy, ): Promise<FsWriteOutcome>
558
+
559
+ /**
560
+ * Atomically edit literal text. When supplied, the version guard is checked
561
+ * before matching so stale content reports `FS_STALE_VERSION`; omission edits
562
+ * the current content without a freshness precondition.
563
+ * @param target - the resolved target to edit.
564
+ * @param edit - the literal search/replace request.
565
+ * @param expected - the version guard; omit for an unconditional edit.
566
+ * @param signal - aborts before atomic publication takes effect.
567
+ * @param sandboxPolicy - the per-call mode and workspace root this edit runs
568
+ * under; a sandboxing backend fences the edit by it, the bare backend
569
+ * ignores it. Omit to leave the backend its own default.
570
+ * @returns the outcome, including the version the edit produced.
571
+ */
572
+ abstract editText( target: FsTarget, edit: FsEditRequest, expected?: { version: FsVersion }, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy, ): Promise<FsEditOutcome>
573
+
574
+ /**
575
+ * Atomically apply parsed hunks to the LF-normalized text and restore the
576
+ * stored line-ending style. A missing or stale target reports
577
+ * `FS_STALE_VERSION`; an unmatched hunk reports `FS_PATCH_MISMATCH`.
578
+ * @param target - the resolved regular file to patch.
579
+ * @param hunks - ordered hunks from `parsePatch`.
580
+ * @param expected - the version guard; omit for an unconditional patch.
581
+ * @param signal - aborts before atomic publication takes effect.
582
+ * @param sandboxPolicy - the per-call mode and workspace root this patch runs
583
+ * under; a sandboxing backend fences the patch by it, the bare backend
584
+ * ignores it. Omit to leave the backend its own default.
585
+ * @returns the outcome, including the version the patch produced.
586
+ */
587
+ abstract patchText( target: FsTarget, hunks: readonly PatchHunk[], expected?: { version: FsVersion }, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy, ): Promise<FsEditOutcome>
588
+
589
+ /**
590
+ * Remove a regular file. A missing or stale target reports `FS_STALE_VERSION`;
591
+ * a directory or other non-file reports `FS_NOT_REGULAR_FILE`. Resolution has
592
+ * already followed symlinks, so the target is the real file.
593
+ * @param target - the resolved file to remove.
594
+ * @param expected - the version guard; omit for an unconditional removal.
595
+ * @param signal - aborts before removal.
596
+ * @param sandboxPolicy - the per-call mode and workspace root this removal
597
+ * runs under; a sandboxing backend fences it, the bare backend ignores it.
598
+ * Omit to leave the backend its own default.
599
+ * @returns the bounded LF-normalized removed text, or null when no basis is available.
600
+ */
601
+ abstract deleteFile( target: FsTarget, expected?: { version: FsVersion }, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy, ): Promise<FsDeleteOutcome>
602
+
603
+ /**
604
+ * Publish the source text, optionally patched, at the destination, then remove
605
+ * the source. Both targets stay locked in canonical order. Identical targets
606
+ * report `FS_SAME_TARGET`; the source guard follows `patchText` and the
607
+ * destination guard follows `writeText`. The two effects are separate: a
608
+ * published destination with a retained source is a final outcome reported
609
+ * through `sourceDeleted: false`.
610
+ * @param source - the resolved regular source; its line-ending style and mode carry over.
611
+ * @param destination - the resolved destination within the same provider.
612
+ * @param options - optional hunks and the source/destination guards; an omitted guard is unconditional.
613
+ * @param signal - checked before destination staging; the commit then completes both effects.
614
+ * @param sandboxPolicy - the per-call mode and workspace root both paths run
615
+ * under; a sandboxing backend fences them, the bare backend ignores it.
616
+ * Omit to leave the backend its own default.
617
+ * @returns the bounded LF source basis, the destination outcome, and the source-removal status.
618
+ */
619
+ abstract moveFile( source: FsTarget, destination: FsTarget, options: { hunks?: readonly PatchHunk[] expectedSource?: { version: FsVersion } expectedDestination?: FsWriteIntent }, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy, ): Promise<FsMoveOutcome>
620
+ ```
621
+
622
+ Types: [SandboxExecutionPolicy](./sandbox.md)
623
+
624
+ Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
625
+
626
+ <a id="fs-events"></a>
627
+
628
+ ### `fs/*` events
629
+
630
+ <a id="fsdelete-intent--waterfall"></a>
631
+
632
+ #### `fs/delete-intent` — waterfall
633
+
634
+ Single-slot decision for FileSystem.deleteFile; the first returned guard wins. Calling next() delegates to an unconditional deletion.
635
+
636
+ ```ts cordis-catalog
637
+ /**
638
+ * Single-slot decision for FileSystem.deleteFile; the first returned guard wins.
639
+ * Calling next() delegates to an unconditional deletion.
640
+ * @param target - the resolved source about to be removed.
641
+ * @param actor - the opaque tool-execution context used to select observed state.
642
+ * @mode waterfall
643
+ */
644
+ 'fs/delete-intent'(target: FsTarget, actor: object | undefined, next: () => { version: FsVersion } | undefined | Promise<{ version: FsVersion } | undefined>): Promise<{ version: FsVersion } | undefined>
645
+ ```
646
+
647
+ Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
648
+
649
+ <a id="fsedit-intent--waterfall"></a>
650
+
651
+ #### `fs/edit-intent` — waterfall
652
+
653
+ Single-slot decision for the next FileSystem.editText. Calling `next()` yields an unconditional edit; the first returned guard wins.
654
+
655
+ ```ts cordis-catalog
656
+ /**
657
+ * Single-slot decision for the next {@link FileSystem.editText}. Calling
658
+ * `next()` yields an unconditional edit; the first returned guard wins.
659
+ * @param target - the resolved target about to be edited.
660
+ * @param actor - the opaque tool-execution context the decider keys off.
661
+ * @mode waterfall
662
+ */
663
+ 'fs/edit-intent'(target: FsTarget, actor: object | undefined, next: () => { version: FsVersion } | undefined | Promise<{ version: FsVersion } | undefined>): Promise<{ version: FsVersion } | undefined>
664
+ ```
665
+
666
+ Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
667
+
668
+ <a id="fsobserved--emit"></a>
669
+
670
+ #### `fs/observed` — emit
671
+
672
+ Record an authoritative positive or negative observation. Listeners must be synchronous recorders: throws fail the tool call and returned promises are not awaited.
673
+
674
+ ```ts cordis-catalog
675
+ /**
676
+ * Record an authoritative positive or negative observation. Listeners must
677
+ * be synchronous recorders: throws fail the tool call and returned promises
678
+ * are not awaited.
679
+ * @param target - the target whose presence or absence was observed.
680
+ * @param observation - present with its version, or confirmed absent.
681
+ * @param actor - the observing tool-execution context; undefined records nothing useful.
682
+ * @mode emit
683
+ */
684
+ 'fs/observed'(target: FsTarget, observation: FsObservation, actor: object | undefined): void
685
+ ```
686
+
687
+ Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
688
+
689
+ <a id="fswrite-intent--waterfall"></a>
690
+
691
+ #### `fs/write-intent` — waterfall
692
+
693
+ Single-slot decision for the next FileSystem.writeText. Calling `next()` yields the bare provider's unconditional write; the first listener that returns an intent owns the decision rather than composing with peers.
694
+
695
+ ```ts cordis-catalog
696
+ /**
697
+ * Single-slot decision for the next {@link FileSystem.writeText}. Calling
698
+ * `next()` yields the bare provider's unconditional write; the first listener
699
+ * that returns an intent owns the decision rather than composing with peers.
700
+ * @param target - the resolved target about to be written.
701
+ * @param actor - the opaque tool-execution context the decider keys off.
702
+ * @mode waterfall
703
+ */
704
+ 'fs/write-intent'(target: FsTarget, actor: object | undefined, next: () => FsWriteIntent | undefined | Promise<FsWriteIntent | undefined>): Promise<FsWriteIntent | undefined>
705
+ ```
706
+
707
+ Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
708
+ <!-- END GENERATED cordis-surface -->