dsh-plugin-guide 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE.md +26 -0
  3. package/README.es.md +139 -0
  4. package/README.hi.md +138 -0
  5. package/README.md +165 -0
  6. package/README.pt.md +139 -0
  7. package/README.zh-CN.md +164 -0
  8. package/SKILL.md +69 -0
  9. package/cordis.patch.yml +4 -0
  10. package/guide/links.md +92 -0
  11. package/guide/plugin-dev-guide.md +429 -0
  12. package/guide/quick-reference.es.md +176 -0
  13. package/guide/quick-reference.hi.md +176 -0
  14. package/guide/quick-reference.md +176 -0
  15. package/guide/quick-reference.pt.md +176 -0
  16. package/guide/quick-reference.zh-CN.md +175 -0
  17. package/index.js +58 -0
  18. package/package.json +83 -0
  19. package/references/community-ecosystem.md +201 -0
  20. package/references/community-repo-deep-dive.md +695 -0
  21. package/references/cordis-paper-and-community.md +326 -0
  22. package/references/harness-repo.md +654 -0
  23. package/references/official-docs/AGENTS.md +149 -0
  24. package/references/official-docs/BENCHMARK.md +3 -0
  25. package/references/official-docs/CLAUDE.md +1 -0
  26. package/references/official-docs/CONTRIBUTING.i18n.yaml +6 -0
  27. package/references/official-docs/CONTRIBUTING.md +23 -0
  28. package/references/official-docs/CONTRIBUTING.zh.md +23 -0
  29. package/references/official-docs/LICENSE +21 -0
  30. package/references/official-docs/README.i18n.yaml +6 -0
  31. package/references/official-docs/README.md +35 -0
  32. package/references/official-docs/README.zh.md +74 -0
  33. package/references/official-docs/SNAPSHOT.md +16 -0
  34. package/references/official-docs/THIRD_PARTY_NOTICES.md +192 -0
  35. package/references/official-docs/docs/AGENTS.md +75 -0
  36. package/references/official-docs/docs/agent-lifecycle.i18n.yaml +6 -0
  37. package/references/official-docs/docs/agent-lifecycle.md +82 -0
  38. package/references/official-docs/docs/agent-lifecycle.zh.md +84 -0
  39. package/references/official-docs/docs/api-gateway.i18n.yaml +6 -0
  40. package/references/official-docs/docs/api-gateway.md +164 -0
  41. package/references/official-docs/docs/api-gateway.zh.md +164 -0
  42. package/references/official-docs/docs/architecture.i18n.yaml +6 -0
  43. package/references/official-docs/docs/architecture.md +129 -0
  44. package/references/official-docs/docs/architecture.zh.md +133 -0
  45. package/references/official-docs/docs/capability-seams.i18n.yaml +6 -0
  46. package/references/official-docs/docs/capability-seams.md +471 -0
  47. package/references/official-docs/docs/capability-seams.zh.md +473 -0
  48. package/references/official-docs/docs/config-catalog.i18n.yaml +6 -0
  49. package/references/official-docs/docs/config-catalog.md +3151 -0
  50. package/references/official-docs/docs/config-catalog.zh.md +3152 -0
  51. package/references/official-docs/docs/cookbook/adding-a-conversation-node.i18n.yaml +6 -0
  52. package/references/official-docs/docs/cookbook/adding-a-conversation-node.md +233 -0
  53. package/references/official-docs/docs/cookbook/adding-a-conversation-node.zh.md +233 -0
  54. package/references/official-docs/docs/cookbook/adding-a-package.i18n.yaml +6 -0
  55. package/references/official-docs/docs/cookbook/adding-a-package.md +118 -0
  56. package/references/official-docs/docs/cookbook/adding-a-package.zh.md +118 -0
  57. package/references/official-docs/docs/cookbook/adding-a-tool.i18n.yaml +6 -0
  58. package/references/official-docs/docs/cookbook/adding-a-tool.md +94 -0
  59. package/references/official-docs/docs/cookbook/adding-a-tool.zh.md +96 -0
  60. package/references/official-docs/docs/cookbook/adding-a-vendored-package.i18n.yaml +6 -0
  61. package/references/official-docs/docs/cookbook/adding-a-vendored-package.md +59 -0
  62. package/references/official-docs/docs/cookbook/adding-a-vendored-package.zh.md +59 -0
  63. package/references/official-docs/docs/cookbook/adding-an-llm-adapter.i18n.yaml +6 -0
  64. package/references/official-docs/docs/cookbook/adding-an-llm-adapter.md +43 -0
  65. package/references/official-docs/docs/cookbook/adding-an-llm-adapter.zh.md +43 -0
  66. package/references/official-docs/docs/cookbook/extension-cookbook.i18n.yaml +6 -0
  67. package/references/official-docs/docs/cookbook/extension-cookbook.md +129 -0
  68. package/references/official-docs/docs/cookbook/extension-cookbook.zh.md +131 -0
  69. package/references/official-docs/docs/cookbook/maintaining-dsh-code-review.i18n.yaml +6 -0
  70. package/references/official-docs/docs/cookbook/maintaining-dsh-code-review.md +64 -0
  71. package/references/official-docs/docs/cookbook/maintaining-dsh-code-review.zh.md +64 -0
  72. package/references/official-docs/docs/cookbook/responding-to-pr-review-on-a-stack.i18n.yaml +6 -0
  73. package/references/official-docs/docs/cookbook/responding-to-pr-review-on-a-stack.md +32 -0
  74. package/references/official-docs/docs/cookbook/responding-to-pr-review-on-a-stack.zh.md +32 -0
  75. package/references/official-docs/docs/cordis-api/context.i18n.yaml +6 -0
  76. package/references/official-docs/docs/cordis-api/context.md +364 -0
  77. package/references/official-docs/docs/cordis-api/context.zh.md +366 -0
  78. package/references/official-docs/docs/cordis-api/events.i18n.yaml +6 -0
  79. package/references/official-docs/docs/cordis-api/events.md +207 -0
  80. package/references/official-docs/docs/cordis-api/events.zh.md +209 -0
  81. package/references/official-docs/docs/cordis-api/fiber.i18n.yaml +6 -0
  82. package/references/official-docs/docs/cordis-api/fiber.md +375 -0
  83. package/references/official-docs/docs/cordis-api/fiber.zh.md +377 -0
  84. package/references/official-docs/docs/cordis-api/inherited.md +39 -0
  85. package/references/official-docs/docs/cordis-api/registry.i18n.yaml +6 -0
  86. package/references/official-docs/docs/cordis-api/registry.md +152 -0
  87. package/references/official-docs/docs/cordis-api/registry.zh.md +154 -0
  88. package/references/official-docs/docs/cordis-api/service.i18n.yaml +6 -0
  89. package/references/official-docs/docs/cordis-api/service.md +102 -0
  90. package/references/official-docs/docs/cordis-api/service.zh.md +104 -0
  91. package/references/official-docs/docs/cordis-primer.i18n.yaml +6 -0
  92. package/references/official-docs/docs/cordis-primer.md +44 -0
  93. package/references/official-docs/docs/cordis-primer.zh.md +50 -0
  94. package/references/official-docs/docs/cordis-tutorial/01-first-plugin.i18n.yaml +6 -0
  95. package/references/official-docs/docs/cordis-tutorial/01-first-plugin.md +95 -0
  96. package/references/official-docs/docs/cordis-tutorial/01-first-plugin.zh.md +95 -0
  97. package/references/official-docs/docs/cordis-tutorial/02-lifecycle-and-effects.i18n.yaml +6 -0
  98. package/references/official-docs/docs/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
  99. package/references/official-docs/docs/cordis-tutorial/02-lifecycle-and-effects.zh.md +98 -0
  100. package/references/official-docs/docs/cordis-tutorial/03-services.i18n.yaml +6 -0
  101. package/references/official-docs/docs/cordis-tutorial/03-services.md +98 -0
  102. package/references/official-docs/docs/cordis-tutorial/03-services.zh.md +98 -0
  103. package/references/official-docs/docs/cordis-tutorial/04-events.i18n.yaml +6 -0
  104. package/references/official-docs/docs/cordis-tutorial/04-events.md +144 -0
  105. package/references/official-docs/docs/cordis-tutorial/04-events.zh.md +144 -0
  106. package/references/official-docs/docs/cordis-tutorial/05-config.i18n.yaml +6 -0
  107. package/references/official-docs/docs/cordis-tutorial/05-config.md +84 -0
  108. package/references/official-docs/docs/cordis-tutorial/05-config.zh.md +84 -0
  109. package/references/official-docs/docs/cordis-tutorial/06-composition-and-hmr.i18n.yaml +6 -0
  110. package/references/official-docs/docs/cordis-tutorial/06-composition-and-hmr.md +113 -0
  111. package/references/official-docs/docs/cordis-tutorial/06-composition-and-hmr.zh.md +113 -0
  112. package/references/official-docs/docs/cordis-tutorial/07-into-the-harness.i18n.yaml +6 -0
  113. package/references/official-docs/docs/cordis-tutorial/07-into-the-harness.md +107 -0
  114. package/references/official-docs/docs/cordis-tutorial/07-into-the-harness.zh.md +107 -0
  115. package/references/official-docs/docs/cordis-tutorial/index.i18n.yaml +6 -0
  116. package/references/official-docs/docs/cordis-tutorial/index.md +60 -0
  117. package/references/official-docs/docs/cordis-tutorial/index.zh.md +62 -0
  118. package/references/official-docs/docs/defensive-patterns.i18n.yaml +6 -0
  119. package/references/official-docs/docs/defensive-patterns.md +33 -0
  120. package/references/official-docs/docs/defensive-patterns.zh.md +33 -0
  121. package/references/official-docs/docs/development.i18n.yaml +6 -0
  122. package/references/official-docs/docs/development.md +171 -0
  123. package/references/official-docs/docs/development.zh.md +171 -0
  124. package/references/official-docs/docs/event-producer-consumer.i18n.yaml +6 -0
  125. package/references/official-docs/docs/event-producer-consumer.md +76 -0
  126. package/references/official-docs/docs/event-producer-consumer.zh.md +78 -0
  127. package/references/official-docs/docs/glossary.i18n.yaml +6 -0
  128. package/references/official-docs/docs/glossary.md +45 -0
  129. package/references/official-docs/docs/glossary.zh.md +45 -0
  130. package/references/official-docs/docs/graph-atlas.i18n.yaml +6 -0
  131. package/references/official-docs/docs/graph-atlas.md +24 -0
  132. package/references/official-docs/docs/graph-atlas.zh.md +26 -0
  133. package/references/official-docs/docs/i18n/README.i18n.yaml +6 -0
  134. package/references/official-docs/docs/i18n/README.md +60 -0
  135. package/references/official-docs/docs/i18n/README.zh.md +60 -0
  136. package/references/official-docs/docs/i18n/style-samples.md +87 -0
  137. package/references/official-docs/docs/i18n/terminology.md +214 -0
  138. package/references/official-docs/docs/i18n/translation-prompt.md +263 -0
  139. package/references/official-docs/docs/i18n/translation-rules.i18n.yaml +6 -0
  140. package/references/official-docs/docs/i18n/translation-rules.md +69 -0
  141. package/references/official-docs/docs/i18n/translation-rules.zh.md +69 -0
  142. package/references/official-docs/docs/module-graph.i18n.yaml +6 -0
  143. package/references/official-docs/docs/module-graph.md +1638 -0
  144. package/references/official-docs/docs/module-graph.zh.md +1640 -0
  145. package/references/official-docs/docs/persistence-catalog.i18n.yaml +6 -0
  146. package/references/official-docs/docs/persistence-catalog.md +944 -0
  147. package/references/official-docs/docs/persistence-catalog.zh.md +946 -0
  148. package/references/official-docs/docs/postmortem/0001-acp-default-export-drops-inject.i18n.yaml +6 -0
  149. package/references/official-docs/docs/postmortem/0001-acp-default-export-drops-inject.md +113 -0
  150. package/references/official-docs/docs/postmortem/0001-acp-default-export-drops-inject.zh.md +113 -0
  151. package/references/official-docs/docs/postmortem/0002-js-expression-disabled-filesystem-tools.i18n.yaml +6 -0
  152. package/references/official-docs/docs/postmortem/0002-js-expression-disabled-filesystem-tools.md +47 -0
  153. package/references/official-docs/docs/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +47 -0
  154. package/references/official-docs/docs/postmortem/0003-web-agent-gui-feedback-loop.i18n.yaml +6 -0
  155. package/references/official-docs/docs/postmortem/0003-web-agent-gui-feedback-loop.md +53 -0
  156. package/references/official-docs/docs/postmortem/0003-web-agent-gui-feedback-loop.zh.md +53 -0
  157. package/references/official-docs/docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.i18n.yaml +6 -0
  158. package/references/official-docs/docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +55 -0
  159. package/references/official-docs/docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +55 -0
  160. package/references/official-docs/docs/postmortem/README.i18n.yaml +6 -0
  161. package/references/official-docs/docs/postmortem/README.md +18 -0
  162. package/references/official-docs/docs/postmortem/README.zh.md +18 -0
  163. package/references/official-docs/docs/rescope.i18n.yaml +6 -0
  164. package/references/official-docs/docs/rescope.md +53 -0
  165. package/references/official-docs/docs/rescope.zh.md +53 -0
  166. package/references/official-docs/docs/subsystems/README.i18n.yaml +6 -0
  167. package/references/official-docs/docs/subsystems/README.md +55 -0
  168. package/references/official-docs/docs/subsystems/README.zh.md +55 -0
  169. package/references/official-docs/docs/subsystems/approval.i18n.yaml +6 -0
  170. package/references/official-docs/docs/subsystems/approval.md +170 -0
  171. package/references/official-docs/docs/subsystems/approval.zh.md +170 -0
  172. package/references/official-docs/docs/subsystems/attachment.i18n.yaml +6 -0
  173. package/references/official-docs/docs/subsystems/attachment.md +115 -0
  174. package/references/official-docs/docs/subsystems/attachment.zh.md +115 -0
  175. package/references/official-docs/docs/subsystems/client-modules.i18n.yaml +6 -0
  176. package/references/official-docs/docs/subsystems/client-modules.md +118 -0
  177. package/references/official-docs/docs/subsystems/client-modules.zh.md +118 -0
  178. package/references/official-docs/docs/subsystems/code-runtime.i18n.yaml +6 -0
  179. package/references/official-docs/docs/subsystems/code-runtime.md +191 -0
  180. package/references/official-docs/docs/subsystems/code-runtime.zh.md +191 -0
  181. package/references/official-docs/docs/subsystems/commands.i18n.yaml +6 -0
  182. package/references/official-docs/docs/subsystems/commands.md +187 -0
  183. package/references/official-docs/docs/subsystems/commands.zh.md +187 -0
  184. package/references/official-docs/docs/subsystems/compaction.i18n.yaml +6 -0
  185. package/references/official-docs/docs/subsystems/compaction.md +238 -0
  186. package/references/official-docs/docs/subsystems/compaction.zh.md +238 -0
  187. package/references/official-docs/docs/subsystems/core.i18n.yaml +6 -0
  188. package/references/official-docs/docs/subsystems/core.md +1070 -0
  189. package/references/official-docs/docs/subsystems/core.zh.md +1078 -0
  190. package/references/official-docs/docs/subsystems/credentials.i18n.yaml +6 -0
  191. package/references/official-docs/docs/subsystems/credentials.md +133 -0
  192. package/references/official-docs/docs/subsystems/credentials.zh.md +133 -0
  193. package/references/official-docs/docs/subsystems/extensions.i18n.yaml +6 -0
  194. package/references/official-docs/docs/subsystems/extensions.md +364 -0
  195. package/references/official-docs/docs/subsystems/extensions.zh.md +364 -0
  196. package/references/official-docs/docs/subsystems/feedback.i18n.yaml +6 -0
  197. package/references/official-docs/docs/subsystems/feedback.md +266 -0
  198. package/references/official-docs/docs/subsystems/feedback.zh.md +266 -0
  199. package/references/official-docs/docs/subsystems/filesystem.i18n.yaml +6 -0
  200. package/references/official-docs/docs/subsystems/filesystem.md +495 -0
  201. package/references/official-docs/docs/subsystems/filesystem.zh.md +495 -0
  202. package/references/official-docs/docs/subsystems/goal.i18n.yaml +6 -0
  203. package/references/official-docs/docs/subsystems/goal.md +277 -0
  204. package/references/official-docs/docs/subsystems/goal.zh.md +277 -0
  205. package/references/official-docs/docs/subsystems/invariants.i18n.yaml +6 -0
  206. package/references/official-docs/docs/subsystems/invariants.md +88 -0
  207. package/references/official-docs/docs/subsystems/invariants.zh.md +88 -0
  208. package/references/official-docs/docs/subsystems/jobs.i18n.yaml +6 -0
  209. package/references/official-docs/docs/subsystems/jobs.md +290 -0
  210. package/references/official-docs/docs/subsystems/jobs.zh.md +290 -0
  211. package/references/official-docs/docs/subsystems/llm-streaming.i18n.yaml +6 -0
  212. package/references/official-docs/docs/subsystems/llm-streaming.md +888 -0
  213. package/references/official-docs/docs/subsystems/llm-streaming.zh.md +894 -0
  214. package/references/official-docs/docs/subsystems/lsp.i18n.yaml +6 -0
  215. package/references/official-docs/docs/subsystems/lsp.md +202 -0
  216. package/references/official-docs/docs/subsystems/lsp.zh.md +202 -0
  217. package/references/official-docs/docs/subsystems/permission-presets.i18n.yaml +6 -0
  218. package/references/official-docs/docs/subsystems/permission-presets.md +131 -0
  219. package/references/official-docs/docs/subsystems/permission-presets.zh.md +131 -0
  220. package/references/official-docs/docs/subsystems/persistence.i18n.yaml +6 -0
  221. package/references/official-docs/docs/subsystems/persistence.md +385 -0
  222. package/references/official-docs/docs/subsystems/persistence.zh.md +385 -0
  223. package/references/official-docs/docs/subsystems/plan.i18n.yaml +6 -0
  224. package/references/official-docs/docs/subsystems/plan.md +87 -0
  225. package/references/official-docs/docs/subsystems/plan.zh.md +87 -0
  226. package/references/official-docs/docs/subsystems/sandbox.i18n.yaml +6 -0
  227. package/references/official-docs/docs/subsystems/sandbox.md +218 -0
  228. package/references/official-docs/docs/subsystems/sandbox.zh.md +218 -0
  229. package/references/official-docs/docs/subsystems/schedule.i18n.yaml +6 -0
  230. package/references/official-docs/docs/subsystems/schedule.md +186 -0
  231. package/references/official-docs/docs/subsystems/schedule.zh.md +186 -0
  232. package/references/official-docs/docs/subsystems/scope.i18n.yaml +6 -0
  233. package/references/official-docs/docs/subsystems/scope.md +59 -0
  234. package/references/official-docs/docs/subsystems/scope.zh.md +59 -0
  235. package/references/official-docs/docs/subsystems/session-projection.i18n.yaml +6 -0
  236. package/references/official-docs/docs/subsystems/session-projection.md +262 -0
  237. package/references/official-docs/docs/subsystems/session-projection.zh.md +262 -0
  238. package/references/official-docs/docs/subsystems/session-query.i18n.yaml +6 -0
  239. package/references/official-docs/docs/subsystems/session-query.md +495 -0
  240. package/references/official-docs/docs/subsystems/session-query.zh.md +495 -0
  241. package/references/official-docs/docs/subsystems/session-reference.i18n.yaml +6 -0
  242. package/references/official-docs/docs/subsystems/session-reference.md +108 -0
  243. package/references/official-docs/docs/subsystems/session-reference.zh.md +108 -0
  244. package/references/official-docs/docs/subsystems/session-telemetry.i18n.yaml +6 -0
  245. package/references/official-docs/docs/subsystems/session-telemetry.md +194 -0
  246. package/references/official-docs/docs/subsystems/session-telemetry.zh.md +194 -0
  247. package/references/official-docs/docs/subsystems/session-title.i18n.yaml +6 -0
  248. package/references/official-docs/docs/subsystems/session-title.md +204 -0
  249. package/references/official-docs/docs/subsystems/session-title.zh.md +204 -0
  250. package/references/official-docs/docs/subsystems/session.i18n.yaml +6 -0
  251. package/references/official-docs/docs/subsystems/session.md +849 -0
  252. package/references/official-docs/docs/subsystems/session.zh.md +851 -0
  253. package/references/official-docs/docs/subsystems/settings.i18n.yaml +6 -0
  254. package/references/official-docs/docs/subsystems/settings.md +310 -0
  255. package/references/official-docs/docs/subsystems/settings.zh.md +310 -0
  256. package/references/official-docs/docs/subsystems/shell.i18n.yaml +6 -0
  257. package/references/official-docs/docs/subsystems/shell.md +303 -0
  258. package/references/official-docs/docs/subsystems/shell.zh.md +303 -0
  259. package/references/official-docs/docs/subsystems/skills.i18n.yaml +6 -0
  260. package/references/official-docs/docs/subsystems/skills.md +331 -0
  261. package/references/official-docs/docs/subsystems/skills.zh.md +331 -0
  262. package/references/official-docs/docs/subsystems/spill.i18n.yaml +6 -0
  263. package/references/official-docs/docs/subsystems/spill.md +117 -0
  264. package/references/official-docs/docs/subsystems/spill.zh.md +117 -0
  265. package/references/official-docs/docs/subsystems/storage.i18n.yaml +6 -0
  266. package/references/official-docs/docs/subsystems/storage.md +229 -0
  267. package/references/official-docs/docs/subsystems/storage.zh.md +229 -0
  268. package/references/official-docs/docs/subsystems/subagent.i18n.yaml +6 -0
  269. package/references/official-docs/docs/subsystems/subagent.md +734 -0
  270. package/references/official-docs/docs/subsystems/subagent.zh.md +736 -0
  271. package/references/official-docs/docs/subsystems/subprocess.i18n.yaml +6 -0
  272. package/references/official-docs/docs/subsystems/subprocess.md +324 -0
  273. package/references/official-docs/docs/subsystems/subprocess.zh.md +324 -0
  274. package/references/official-docs/docs/subsystems/system-prompt.i18n.yaml +6 -0
  275. package/references/official-docs/docs/subsystems/system-prompt.md +207 -0
  276. package/references/official-docs/docs/subsystems/system-prompt.zh.md +207 -0
  277. package/references/official-docs/docs/subsystems/terminal.i18n.yaml +6 -0
  278. package/references/official-docs/docs/subsystems/terminal.md +184 -0
  279. package/references/official-docs/docs/subsystems/terminal.zh.md +184 -0
  280. package/references/official-docs/docs/subsystems/token-meter.i18n.yaml +6 -0
  281. package/references/official-docs/docs/subsystems/token-meter.md +90 -0
  282. package/references/official-docs/docs/subsystems/token-meter.zh.md +90 -0
  283. package/references/official-docs/docs/subsystems/tools.i18n.yaml +6 -0
  284. package/references/official-docs/docs/subsystems/tools.md +720 -0
  285. package/references/official-docs/docs/subsystems/tools.zh.md +720 -0
  286. package/references/official-docs/docs/subsystems/typert.i18n.yaml +6 -0
  287. package/references/official-docs/docs/subsystems/typert.md +336 -0
  288. package/references/official-docs/docs/subsystems/typert.zh.md +336 -0
  289. package/references/official-docs/docs/subsystems/user-questions.i18n.yaml +6 -0
  290. package/references/official-docs/docs/subsystems/user-questions.md +178 -0
  291. package/references/official-docs/docs/subsystems/user-questions.zh.md +178 -0
  292. package/references/official-docs/docs/subsystems/web-server.i18n.yaml +6 -0
  293. package/references/official-docs/docs/subsystems/web-server.md +108 -0
  294. package/references/official-docs/docs/subsystems/web-server.zh.md +108 -0
  295. package/references/official-docs/docs/subsystems/web.i18n.yaml +6 -0
  296. package/references/official-docs/docs/subsystems/web.md +199 -0
  297. package/references/official-docs/docs/subsystems/web.zh.md +199 -0
  298. package/references/official-docs/docs/subsystems/workflow.i18n.yaml +6 -0
  299. package/references/official-docs/docs/subsystems/workflow.md +278 -0
  300. package/references/official-docs/docs/subsystems/workflow.zh.md +278 -0
  301. package/references/official-docs/docs/subsystems/workspace.i18n.yaml +6 -0
  302. package/references/official-docs/docs/subsystems/workspace.md +228 -0
  303. package/references/official-docs/docs/subsystems/workspace.zh.md +228 -0
  304. package/references/official-docs/docs/testing.i18n.yaml +6 -0
  305. package/references/official-docs/docs/testing.md +49 -0
  306. package/references/official-docs/docs/testing.zh.md +49 -0
  307. package/references/official-docs/docs/tool-catalog.i18n.yaml +6 -0
  308. package/references/official-docs/docs/tool-catalog.md +1873 -0
  309. package/references/official-docs/docs/tool-catalog.zh.md +1878 -0
  310. package/references/official-docs/docs/tool-execution-pipeline.i18n.yaml +6 -0
  311. package/references/official-docs/docs/tool-execution-pipeline.md +62 -0
  312. package/references/official-docs/docs/tool-execution-pipeline.zh.md +64 -0
  313. package/references/official-docs/docs/user/develop/basic/config.i18n.yaml +6 -0
  314. package/references/official-docs/docs/user/develop/basic/config.md +106 -0
  315. package/references/official-docs/docs/user/develop/basic/config.zh.md +106 -0
  316. package/references/official-docs/docs/user/develop/basic/index.i18n.yaml +6 -0
  317. package/references/official-docs/docs/user/develop/basic/index.md +144 -0
  318. package/references/official-docs/docs/user/develop/basic/index.zh.md +144 -0
  319. package/references/official-docs/docs/user/develop/basic/publish.i18n.yaml +6 -0
  320. package/references/official-docs/docs/user/develop/basic/publish.md +183 -0
  321. package/references/official-docs/docs/user/develop/basic/publish.zh.md +183 -0
  322. package/references/official-docs/docs/user/develop/basic/tool.i18n.yaml +6 -0
  323. package/references/official-docs/docs/user/develop/basic/tool.md +52 -0
  324. package/references/official-docs/docs/user/develop/basic/tool.zh.md +52 -0
  325. package/references/official-docs/docs/user/develop/framework/events.i18n.yaml +6 -0
  326. package/references/official-docs/docs/user/develop/framework/events.md +143 -0
  327. package/references/official-docs/docs/user/develop/framework/events.zh.md +143 -0
  328. package/references/official-docs/docs/user/develop/framework/index.i18n.yaml +6 -0
  329. package/references/official-docs/docs/user/develop/framework/index.md +137 -0
  330. package/references/official-docs/docs/user/develop/framework/index.zh.md +137 -0
  331. package/references/official-docs/docs/user/develop/framework/service.i18n.yaml +6 -0
  332. package/references/official-docs/docs/user/develop/framework/service.md +148 -0
  333. package/references/official-docs/docs/user/develop/framework/service.zh.md +150 -0
  334. package/references/official-docs/docs/user/develop/practice/index.i18n.yaml +6 -0
  335. package/references/official-docs/docs/user/develop/practice/index.md +155 -0
  336. package/references/official-docs/docs/user/develop/practice/index.zh.md +155 -0
  337. package/references/official-docs/docs/user/develop/practice/llm-adapter.i18n.yaml +6 -0
  338. package/references/official-docs/docs/user/develop/practice/llm-adapter.md +188 -0
  339. package/references/official-docs/docs/user/develop/practice/llm-adapter.zh.md +188 -0
  340. package/references/official-docs/docs/user/guide/index.i18n.yaml +6 -0
  341. package/references/official-docs/docs/user/guide/index.md +30 -0
  342. package/references/official-docs/docs/user/guide/index.zh.md +30 -0
  343. package/references/official-docs/docs/user/guide/providers-custom-form.png +0 -0
  344. package/references/official-docs/docs/user/guide/providers-custom-form.zh.png +0 -0
  345. package/references/official-docs/docs/user/guide/providers-models-page.png +0 -0
  346. package/references/official-docs/docs/user/guide/providers-models-page.zh.png +0 -0
  347. package/references/official-docs/docs/user/guide/providers.i18n.yaml +6 -0
  348. package/references/official-docs/docs/user/guide/providers.md +98 -0
  349. package/references/official-docs/docs/user/guide/providers.zh.md +98 -0
  350. package/references/official-docs/docs/user/guide/python-sdk.i18n.yaml +6 -0
  351. package/references/official-docs/docs/user/guide/python-sdk.md +104 -0
  352. package/references/official-docs/docs/user/guide/python-sdk.zh.md +104 -0
  353. package/references/official-docs/docs/user/index.i18n.yaml +6 -0
  354. package/references/official-docs/docs/user/index.md +11 -0
  355. package/references/official-docs/docs/user/index.zh.md +11 -0
  356. package/references/official-docs/docs/web-styling.i18n.yaml +6 -0
  357. package/references/official-docs/docs/web-styling.md +25 -0
  358. package/references/official-docs/docs/web-styling.zh.md +25 -0
  359. package/references/official-docs/examples/AGENTS.md +20 -0
  360. package/references/official-docs/packages/AGENTS.md +27 -0
  361. package/references/official-docs/packages/README.md +69 -0
  362. package/references/official-docs/vendor/README.md +60 -0
  363. package/references/official-docs/website-docs.ts +524 -0
  364. package/references/sources.md +137 -0
  365. package/references/upstream-cordis.md +594 -0
  366. package/references/website-pages.md +668 -0
  367. package/scripts/archive-discussions.ps1 +154 -0
  368. package/scripts/download-community-articles.ps1 +188 -0
  369. package/scripts/download-community-repos.ps1 +232 -0
  370. package/scripts/download-sources.ps1 +195 -0
  371. package/scripts/gen-topic-snapshot.ps1 +91 -0
  372. package/scripts/install-skill.ps1 +63 -0
  373. package/scripts/sync-official-docs.ps1 +130 -0
  374. package/scripts/verify-kit.ps1 +191 -0
@@ -0,0 +1,654 @@
1
+ # DeepSeek Harness 仓库文档调研
2
+
3
+ > 调研对象:本地完整 checkout `D:\deepseek-harness`(只读)+ 公开仓库 `https://github.com/deepseek-ai/deepseek-harness`。
4
+ > 结论来源以本地仓库文档为准;每条事实标注具体文件路径或 URL。本地 checkout 未覆盖或无法核实的内容标注 `[unverified]`。
5
+
6
+ DeepSeek Harness(DSH)是一个**基于 vendored Cordis 框架的插件式 agent harness**,公开宣传语为 **"Everything is a Plugin"(一切都是插件)**(见 GitHub 仓库标题 `deepseek-ai/deepseek-harness: DeepSeek Harness: Everything is a Plugin.`)。模型适配器、工具注册表、会话日志、甚至 agent loop 本身都是插件,因此每一部分都能从配置替换。
7
+
8
+ ---
9
+
10
+ ## 1. 整体架构:一切皆插件
11
+
12
+ ### 1.1 核心主张
13
+
14
+ `docs/architecture.md` §Cordis 开门见山:
15
+
16
+ > [Cordis](official-docs/docs/cordis-primer.md) is the framework under dsh: plugins contribute services, typed events, and reversible effects to a shared context. Every part of the product is a plugin, including the model adapter, the tool registry, the session log, and the agent loop itself, so every part is replaceable from configuration.
17
+
18
+ > There is no privileged core to patch: you extend dsh by mounting a plugin beside the others, and registrations are effects that unwind when their plugin unloads.
19
+
20
+ 来源:`D:\deepseek-harness\docs\architecture.md`(L11–L13)。
21
+
22
+ ### 1.2 框架层:vendored Cordis
23
+
24
+ Cordis 框架以**源码 vendored(拷贝)**方式进入 monorepo,而非 npm 依赖,目的是让 harness 完全拥有自己的框架层(可审计、可补丁、可固定版本)。所有 vendored 包被重命名为 `@deepseek-ai` scope(`cordis` → `@deepseek-ai/cordis`,`@cordisjs/plugin-<x>` → `@deepseek-ai/cordis-plugin-<x>`)。
25
+
26
+ 来源:`D:\deepseek-harness\vendor\README.md`(L1–L7)。
27
+
28
+ vendored 清单(`vendor/README.md` §Manifest,L13–L24):
29
+
30
+ | 目录 | npm 名 | 上游名 | 版本 | 上游仓库 |
31
+ |---|---|---|---|---|
32
+ | `cosmokit/` | `@deepseek-ai/cosmokit` | cosmokit | 1.8.1 | github.com/deepseek-harness/cosmokit |
33
+ | `schemastery/` | `@deepseek-ai/schemastery` | schemastery | 3.18.0 | github.com/deepseek-harness/schemastery |
34
+ | `cordis/` | `@deepseek-ai/cordis` | cordis | 4.0.0-rc.7 | github.com/cordiverse/cordis |
35
+ | `loader/` | `@deepseek-ai/cordis-plugin-loader` | @cordisjs/plugin-loader | 1.0.0-rc.5 | github.com/cordiverse/cordis |
36
+ | `include/` | `@deepseek-ai/cordis-plugin-include` | @cordisjs/plugin-include | 1.0.4 | github.com/deepseek-harness/cordis |
37
+ | `group/` | `@deepseek-ai/cordis-plugin-group` | @cordisjs/plugin-group | 1.0.0 | github.com/deepseek-harness/cordis |
38
+ | `timer/` | `@deepseek-ai/cordis-plugin-timer` | @cordisjs/plugin-timer | 1.1.2 | github.com/deepseek-harness/cordis |
39
+ | `hmr/` | `@deepseek-ai/cordis-plugin-hmr` | @cordisjs/plugin-hmr | 1.0.15 | github.com/deepseek-harness/cordis |
40
+ | `logger-console/` | `@deepseek-ai/cordis-plugin-logger-console` | @cordisjs/plugin-logger-console | 1.0.0 | github.com/deepseek-harness/cordis |
41
+
42
+ (08-14 核查:`deepseek-harness/cordis` 已 404,`deepseek-harness` org 的 fork 仓库不再公开可访问;其源码以 harness 仓库 `vendor/` 内的 vendored 副本为准。)
43
+
44
+ `vendor/README.md` 还记录了一份 exhaustive 的**本地修改日志(18 条)**,其中对插件作者最重要的是:
45
+ - `cordis/src/fiber.ts` lifecycle hardening(effect 创建在 owner 处于 `UNLOADING` 时被拒绝;`PENDING`/`LOADING` 时合法)(L38,条目 6)。
46
+ - Loader/Include 事务化配置调和、`!!js` 延迟解析(L40 条目 8、L47 条目 15)。
47
+ - `include` 的 `applyEntryPatches(data, patches, warn)` 与 `entryListSchema` 被导出,供 `dsh --dump-config` 精确重放 patch 算法(L43 条目 11)。
48
+ - `disabled` 字段插值(L50 条目 18)。
49
+
50
+ ### 1.3 仓库布局
51
+
52
+ 根 `AGENTS.md` §Repository layout(工作区 `D:\deepseek-harness\Project\Plugins` 之外只读)给出了完整布局。要点:
53
+
54
+ ```
55
+ vendor/ Vendored Cordis 源码
56
+ packages/ @deepseek-ai/dsh-<pkg> workspaces,位于 packages/<group>/<pkg>/
57
+ core/ session, system-prompt, tools, agent, agent-loop(产品 API 主干)
58
+ api/ 远程 BFF 组装 + Typert RPC 网关
59
+ typert/ 类型图生成器/加载器/运行时注册表
60
+ llm/ LLM 能力:Service Definition/Consumer + DeepSeek providers
61
+ shell/ bash 能力:Service Definition + local/pwsh providers + shell Consumers
62
+ subprocess/ subprocess 能力 + local 进程树 provider
63
+ fs/ filesystem 能力 + policy
64
+ lsp/ language-server 能力
65
+ skill/ skill provider registry + local 实现 + catalog/loader tool
66
+ web/ web 能力:Service Definition + search/fetch providers + tool Consumer
67
+ compaction/ compaction 能力 + basic provider
68
+ context/ 请求上下文插件
69
+ subagent/ subagent 能力 + providers + delegation Consumers
70
+ bundle/ 可安装的 dsh --profile patch-layer 包(base/web-app/headless)
71
+ workflow/ workflow 能力 + worker-thread provider + tool Consumer
72
+ todo/ todo_write tool
73
+ plan/ plan mode(logged state)
74
+ preset/ 从 preset cordis.yml 做每会话 agent 组装
75
+ guard/ loop-hygiene + tool-timeout 插件
76
+ self-modification/ agent 检查/挂载自己的插件
77
+ hooks/ Claude Code/Codex hook 桥 + wire 协议库
78
+ session/ 持久会话数据:persistence/projection/titles/telemetry
79
+ identity/ 匿名身份
80
+ settings/ 用户设置能力 + file provider
81
+ credentials/ credential-reference 能力 + env/.env provider
82
+ acp/ automation-only Agent Client Protocol server
83
+ interaction/ approval/interaction 能力、permission、commands、ask-user
84
+ boot/ 共享 app-bin glue
85
+ sdk/ JSON-RPC 协议、server、TypeScript client
86
+ examples/ demo bundles(agent-spine + CLI/ACP/JSON-RPC bins)
87
+ support/ dev/test 基础设施
88
+ util/ 零依赖工具
89
+ python/ Python SDK + bundled runtime(见 python/README.md)
90
+ native/ @deepseek-ai/node-addon-landlock-run 源码来源(见 native/README.md)
91
+ examples/ 可运行的 cordis.yml leaves(挂载在 packages/examples bundles 上)
92
+ .agents/ Agent workflows 与 Agent Notes(notes/)
93
+ docs/ architecture、generated catalogs、postmortems、cookbook
94
+ scripts/ 仓库门禁与生成器
95
+ website/ VitePress 投影选中的双语 docs/ 源
96
+ ```
97
+
98
+ 来源:`D:\deepseek-harness\AGENTS.md` §Repository layout(也见 `D:\deepseek-harness\CLAUDE.md` 的 symlink 说明:`CLAUDE.md` 是 `AGENTS.md` 的软链接)。
99
+
100
+ ### 1.4 用户插件放在哪里
101
+
102
+ 三类"叶子"(leaf)都在 `examples/` 下,是**可运行的 Cordis 组装**,不是 build target:
103
+
104
+ - `examples/headless-agent/` — 一次性 headless coding agent(挂 `@deepseek-ai/dsh-agent-spine-demo`)
105
+ - `examples/acp-agent/` — ACP 自动化 server(挂 `@deepseek-ai/dsh-acp-demo`)
106
+ - `examples/jsonrpc-agent/` — JSON-RPC(挂 `@deepseek-ai/dsh-sdk-jsonrpc-demo`)
107
+ - `examples/mcp-memory/`、`examples/web-cordis/`、`examples/web-schedule/` — 其它演示叶子
108
+
109
+ 来源:`D:\deepseek-harness\docs\cookbook\extension-cookbook.md` §Runnable wirings(L91–L93)、`D:\deepseek-harness\examples\AGENTS.md`。
110
+
111
+ `examples/AGENTS.md`(L1–L5)规定:
112
+ - `examples/` 是一个 workspace 成员,是**可运行/测试 Cordis 配置的模块解析根**,不是 build target。
113
+ - `examples/package.json` 声明这些配置加载的包;每个 leaf 自己的 `package.json` 只是元数据。
114
+ - 可复用逻辑抽到 `packages/`(那里有 per-file coverage 和 README 门禁);examples 只保留 `cordis.yml` 布线、demo 产物、e2e/snapshot 场景。
115
+
116
+ **用户自建插件**的推荐路径见 `docs/user/develop/basic/` 教程序列:`index.md`(第一个插件)→ `tool.md`(建工具)→ `config.md`(配置)→ `publish.md`(打包成 bundle 安装进 profile)。用户本地插件通过 `--patch ./scratch-plugin/cordis.yml` overlay 挂载(`docs/user/develop/basic/tool.md` L43 的 `pnpm dsh web --patch ./scratch-plugin/cordis.yml`)。
117
+
118
+ ### 1.5 Profiles 与 bundles
119
+
120
+ `docs/architecture.md` §Profiles and bundles(L15–L37)是权威定义:
121
+
122
+ - **profile**:命名组装,存于 Harness home(`$DSH_HOME/profiles/<name>`)。它列出自己堆叠的 bundles、持有的 out-of-tree 插件,以及用户自己的 `cordis.patch.yml`。`web` 与 `headless` 是内置模板。
123
+ - **bundle**:Cordis 配置行及其挂载代码的**分发格式**;它插入的内容能被其上方的层继续 patch。
124
+ - 两者都在自己的 `package.json` 里通过 `dsh` 字段自声明:`dsh.profile` 列出 profile 的 bundles,`dsh.bundle` 指向 bundle 的 patch 文件。
125
+
126
+ 内置 bundle(`docs/architecture.md` L25):
127
+ - [`dsh-base`](../packages/bundle/base/README.md) — 每个 profile 的第一层:模型适配器、工具、持久化、sandbox/approval 策略、settings、credentials、telemetry。
128
+ - [`dsh-web-app`](../packages/bundle/web-app/README.md) — 加浏览器应用。
129
+ - [`dsh-headless`](../packages/bundle/headless/README.md) — 加一次性 runner(无 server)。
130
+
131
+ **层应用顺序**(`docs/architecture.md` L27):每个 profile 按列出顺序的 bundle → profile 的 `cordis.patch.yml` → home 级 `$DSH_HOME/cordis.patch.yml` → 每个 `--patch` overlay。patch 按 `id` 定位一行并**整体替换其 config**,或插入新行。
132
+
133
+ 查看实际启动树:`dsh --profile web --dump-config`(L33)。
134
+
135
+ `docs/user/develop/basic/publish.md` 用可运行例子补齐了两个 manifest 的具体形状:
136
+
137
+ bundle manifest(`dsh.bundle`):
138
+ ```json
139
+ { "name": "dsh-hello-plugin", "version": "0.1.0", "type": "module",
140
+ "main": "index.js", "files": ["index.js", "cordis.patch.yml"],
141
+ "dsh": { "bundle": { "patch": "./cordis.patch.yml" } } }
142
+ ```
143
+ profile manifest(`dsh.profile`):
144
+ ```json
145
+ { "name": "dsh-profile-demo", "private": true,
146
+ "dependencies": { "dsh-hello-plugin": "link:/path/to/hello-plugin" },
147
+ "dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "dsh-hello-plugin"] } } }
148
+ ```
149
+
150
+ 关键语义(`publish.md` L112–L128):层顺序 = ①profile `dsh.profile.bundles` 列表顺序(`@deepseek-ai/dsh-base` 第一)→ ②profile 自身 `cordis.patch.yml` → ③home 级 `$DSH_HOME/cordis.patch.yml` → ④每个 `--patch <path>`(按 argv 顺序)。**靠后的层按行取胜;patch 替换整行 config 而非深合并 key**。安装命令 `dsh plugin --profile <name> add <package>` 转发给 pnpm(L77–L101)。
151
+
152
+ ### 1.6 核心包(`ctx` 键)
153
+
154
+ `docs/architecture.md` §Core packages(L43–L51):
155
+
156
+ | Package | Owns | `ctx` key |
157
+ |---|---|---|
158
+ | `core/session` | append-only `SessionEvent` log + 内存 store | `ctx.sessions` |
159
+ | `core/system-prompt` | prompt-section 与 tool-schema 组装 | `ctx.systemPrompt` |
160
+ | `core/tools` | scoped tool registry + guarded 执行管线 | `ctx.tools` |
161
+ | `core/agent` | `Agent` 接口、live registry、`agent/*` events | `ctx.agents` |
162
+ | `core/agent-loop` | 实现该接口的默认 driver | `ctx.agentLoop` |
163
+ | `core/scope` | per-agent scoped-registration primitive | library,无 key |
164
+ | `llm/llm` | message/stream 词汇 + adapter seam | `ctx.llm` |
165
+
166
+ 完整的能力 seam / 服务图(每个 `ctx.<key>` 的 role=seam/core/bundle、owner 包、实现包、直接消费者)由生成器生成在 `docs/capability-seams.md`(含 mermaid 图 + 表格,L1–L471)。它把服务分三类:**core spine service**(如 `ctx.sessions`/`ctx.tools`)、**swappable capability seam**(如 `ctx.shell`/`ctx.fs`/`ctx.subprocess`/`ctx.llm`/`ctx.skills`)、**bundle/composition point**(如 `ctx.agentLoop`)。
167
+
168
+ ---
169
+
170
+ ## 2. 插件契约(plugin contract)
171
+
172
+ ### 2.1 三种插件形态
173
+
174
+ `docs/cordis-tutorial/01-first-plugin.md`(L53–L77)+ `docs/cordis-primer.md`:
175
+
176
+ 1. **函数插件**(最常见):module 导出 `apply(ctx)`,可选 `inject`/`Config`/`name`。
177
+ 2. **对象插件**:导出含 `apply(ctx)` 方法的对象。
178
+ 3. **类插件**:`Service` 子类(`class MyService extends Service { constructor(ctx){ super(ctx,'key') } }`)。
179
+
180
+ `packages/AGENTS.md` §Plugin exports(L5)约定:
181
+ > service packages default-export their service class; function plugins named-export `name` / `inject` / `Config` / `apply` and have no default export.
182
+
183
+ **混合两种形式会让 Loader 丢弃函数插件的 namespace**(postmortem `docs/postmortem/0001-acp-default-export-drops-inject.md`)。
184
+
185
+ `01-first-plugin.md` 关键事实:
186
+ - `apply` 抛错 = loud failure(进程崩),不是跳过条目(L81–L89)。
187
+ - module 无法解析(拼错路径/包名)时通过 Cordis logger service 报告而非崩进程,boot 时可能被吞(L91)。
188
+ - `name` 导出是可选的诊断标签。
189
+
190
+ ### 2.2 注册即 effect,disposer 语义
191
+
192
+ `docs/cordis-tutorial/02-lifecycle-and-effects.md` 是权威:
193
+
194
+ - 插件可因配置编辑、HMR、显式 dispose、或**失去 required service** 而卸载。通过 Cordis API 做的注册是 effect,卸载时自动撤销;Cordis 不管的资源须用 `ctx.effect()` 包裹并返回 disposer(L5)。
195
+ - `ctx.effect(() => { ...; return () => cleanup() })` — effect body 在加载时运行,disposer 在卸载时运行(L65)。
196
+ - **已经是 effect 的内建 API**(L84–L92):`ctx.on(event, listener)`(卸载时移除 listener)、`ctx.plugin(child)`(随父卸载)、service 注册、harness registry 的 `register()`(返回的 disposer 自动挂到调用插件)。
197
+ - disposer **按注册逆序启动,但多个 async disposer 并发运行**;若 teardown 必须有序,放进一个 disposer 内依次 await(L94)。
198
+ - `ctx.plugin(heartbeat)` 返回 **fiber**(一个已加载插件实例的运行时句柄);`fiber.dispose()` resolve 于所有清理(含 async disposer)完成后,并递归卸载子插件(L62–L66)。
199
+
200
+ **Fiber 状态机**(L68–L82):
201
+ ```
202
+ PENDING → LOADING → ACTIVE → UNLOADING → DISPOSED
203
+ ↘ FAILED
204
+ ```
205
+ - `PENDING`:已声明,但 required service 尚不可用。
206
+ - `LOADING/ACTIVE`:`apply` 运行中 / 已完成。
207
+ - `FAILED`:`apply` 或 config 校验抛错。
208
+ - `UNLOADING/DISPOSED`:disposers 运行中 / 全部拆除。
209
+
210
+ `docs/cordis-primer.md` §Practical Rules(L44):每个注册都应有 disposer(`ctx.effect()` 返回一个,或用 Cordis helper);teardown 顺序相关时放进一个 effect。
211
+
212
+ ### 2.3 Service:注入依赖与声明合并
213
+
214
+ `docs/cordis-tutorial/03-services.md` + `docs/user/develop/framework/service.md`:
215
+
216
+ - **提供 service**:`super(ctx, 'greeter')` 在运行时把实例注册到 `ctx.greeter`;注册本身是 effect(卸载 provider 即移除 service)。编译期靠 TypeScript **declaration merging**:
217
+ ```ts
218
+ declare module '@deepseek-ai/cordis' {
219
+ interface Context { greeter: GreeterService }
220
+ }
221
+ ```
222
+ (`03-services.md` L14–L18、L39–L40)。不写这段,运行时仍工作,但消费者失去类型安全。
223
+
224
+ - **消费 service**:`export const inject = ['greeter']`。Cordis 让插件停在 `PENDING` 直到所有 listed service 存在,`apply` 内 `ctx.greeter` 保证就绪。**加载顺序由依赖而非文件顺序决定**(`03-services.md` L59)。
225
+
226
+ - **依赖在加载后仍被追踪**:required service 消失(provider 卸载/hot-replace)→ 依赖插件也卸载,service 回来后再加载(L76–L78)。这就是配置里换 provider 能工作的原因。
227
+
228
+ - **可选依赖**:不加 `inject`,用 `ctx.get('greeter')` 在使用点探测(返回 `undefined` 时插件仍运行)(L80–L90)。`packages/AGENTS.md` L6 强调:`ctx.get(name)` 读全局 service store,`ctx.<name>` property proxy 是拓扑敏感的,只用于 declared injection。
229
+
230
+ - `Service` 子类自身就是插件(类形态),`ctx.plugin(GreeterService)` 像普通插件一样挂载。
231
+
232
+ - service 名是**每应用一个扁平命名空间**;自建服务要加前缀(harness 已占用 `tools`/`llm` 等 plain names)(`03-services.md` L92–L94)。
233
+
234
+ ### 2.4 Typed events + declaration merging + dispatch modes
235
+
236
+ `docs/cordis-tutorial/04-events.md` + `docs/cordis-primer.md` §Dispatch Modes:
237
+
238
+ **声明**(`04-events.md` L14–L21):
239
+ ```ts
240
+ declare module '@deepseek-ai/cordis' {
241
+ interface Context { stats: StatsService }
242
+ interface Events { 'stats/report'(name: string, count: number): void }
243
+ }
244
+ ```
245
+ `interface Events` 合并是 event 系统的类型安全机制;`namespace/action` 命名约定让扁平 event 命名空间可读。
246
+
247
+ **五个 dispatch mode**(`04-events.md` L84–L91;`cordis-primer.md` L19–L24 的表格):
248
+
249
+ | Mode | 调用 | 语义 | Awaited? | 有返回值? |
250
+ |---|---|---|---|---|
251
+ | `emit` | `ctx.emit(name, ...args)` | 同步广播;返回值/ promise 不 await 不收集 | No | No |
252
+ | `parallel` | `await ctx.parallel(...)` | 全部并发执行,一起 await | Yes | No |
253
+ | `serial` | `await ctx.serial(...)` | 顺序 await;首个非 null/false/undefined 返回值胜出并停 | Yes | Yes |
254
+ | `bail` | `ctx.bail(...)` | serial 的同步版 | No | Yes |
255
+ | `waterfall` | `ctx.waterfall(name, ...args, next)` | around-middleware | No | Yes |
256
+
257
+ **dispatch mode 是 event 公共契约的一部分**。harness 新 event 用 `@mode` 标签文档化,供生成 catalog 检查声明与 dispatch 点一致(`cordis-primer.md` L26)。
258
+
259
+ **Waterfall 语义**(`cordis-primer.md` L28–L34、`04-events.md` L94–L140):listener 收到 `(...args, next)`。调用 `next()` 把(可能被包装的)结果委派给下一个服务;不调用就短路(veto)。值通过 `next()` 的返回值传播。**只观察/注解的 waterfall listener 必须调用 `next()`**;返回而不调用是刻意的短路。忘掉 `next()` 会静默吞掉下游默认行为。`prepend: true` 只在 listener 必须跑在普通注册之前时用。
260
+
261
+ harness 的 waterfall 例子:`agent/request`、`approval/request`、`tools/pre-execute`、`tools/execute`、`tools/post-execute`。
262
+
263
+ ### 2.5 Capability seam:Service Definition / Provider / Consumer
264
+
265
+ `docs/glossary.md` §capability-seam(L7–L9)定义:
266
+
267
+ - **seam** — 一个 *swappable capability*,含三个角色:一个 **Service Definition**(拥有 `ctx.<key>` 和词汇类型的 Cordis `Service` — 抽象类如 `ShellExecutor`,或具体 registry 如 `WebRuntime`,**绝不是 TypeScript `interface`**)、一个或多个 **Service Provider**、一个或多个注入该 service 的 **Consumer**。
268
+ - 权威例子(`glossary.md` L9、`docs/user/develop/practice/index.md` §Bash example):`packages/shell` — `dsh-shell`(Service Definition)、`dsh-bash-local`/`dsh-bash-sandbox`(providers)、`dsh-tool-bash`(Consumer)。
269
+ - 角色通常在独立演化时分属独立包,但一个包可拥有多个角色(`dsh-llm` 同时拥有 Service Definition 与 Consumer)。
270
+ - **seam 是完整能力,绝不是单一角色**;称呼构成部分时用角色/类/service/contract/extension point 词。
271
+
272
+ `docs/architecture.md` §Capability seams(L98–L102):一个 provider 替换就能改变整个产品——filesystem 与 subprocess providers 共享同一个 execution world,指向远程 sandbox 可让 Bash、PTY、LSP 一起迁移,无需 provider 分支。
273
+
274
+ 三包拓扑的落地模板是 `docs/cookbook/adding-a-package.md` §3 Decide the package topology 的"Name the role that exists"(L45–L71),给出一张角色命名词表(`Controller`/`Store`/`Directory`/`Presenter`/`Registry`/`Runtime`/`Resolver`/`Binder`/`Engine`/`Policy`/`Executor`/`Gateway`/`Provider`/`Backend`/`Handle`/`Config`/`Service`),并规定:
275
+ - 单数 `ctx` key 用于一个 engine/runtime/policy/controller/resolver/store/current config;复数 key 用于 registry 或拥有多个命名成员的服务。类角色与 key 数必须一致。
276
+ - 不要用一个 Cordis `Context` key 承载互不兼容的 host/client 声明(declaration merging 两边都会看到)。
277
+ - `SDK` 只用于 JSON-RPC client/server 协议;产品拼写是 `Typert`(不是 `TypeRT`/`typeRT`)。
278
+
279
+ ### 2.6 Config schema(Schemastery / Standard Schema)
280
+
281
+ `docs/cordis-tutorial/05-config.md` + `docs/user/develop/basic/config.md`:
282
+
283
+ - 导出同名 `Config` 接口 + Schemastery schema:
284
+ ```ts
285
+ export interface Config { greeting: string; targets: string[] }
286
+ export const Config: Schema<Config> = Schema.object({
287
+ greeting: Schema.string().default('Hello'),
288
+ targets: Schema.array(String).default(['world']),
289
+ })
290
+ export function apply(ctx: Context, config: Config) { ... }
291
+ ```
292
+ (`05-config.md` L11–L31)。
293
+ - 本仓库用 **Schemastery**(vendored `@deepseek-ai/schemastery` 3.18.0)做 schema;Cordis 本身接受任何 [Standard Schema](https://standardschema.dev/) validator,**导出普通对象作为 `Config` 不行**(`05-config.md` L34、`config.md` L45)。
294
+ - 校验在加载时运行;无效配置 `ValidationError` 使 fiber 进 `FAILED`(`05-config.md` L63–L68)。default 会填充,`apply` 收到完整、已验证的 config。
295
+ - schema 可表达的更严格校验:`Schema.string().required()`、`Schema.union(['fast','accurate']).default('fast')`(`config.md` L51–L72)。
296
+ - **原则**(`config.md` §Design principles、`AGENTS.md` §Conventions):不要硬编码 tunable——**两个部署可能想设不同值的东西都必须是 config 字段**(检验标准:`cordis.yml` 能否不改代码就改它);self-contained 约束写进 schema 让它在加载时 fail loud;引用 service/注册资源的约束用 dependency injection。
297
+ - HMR:配置编辑会 hot-replace 插件(卸载旧实例、加载新实例),因注册是 effect 而不会残留旧注册(`config.md` L98–L100)。
298
+
299
+ ### 2.7 `!!js` 配置、`disabled`、overlays
300
+
301
+ `docs/cordis-primer.md` §Loader Configuration(L36–L38)+ `05-config.md` §Computed config values(L70–L80):
302
+
303
+ - `!!js` tag 只允许在 `config` 内、以及 entry 的 `disabled` 字段里(**是 `!!js` 不是 `!js`**,见根 `AGENTS.md` §Secrets/.env)。
304
+ - `disabled: !!js ...` 在每次 mount 决策时针对 loader context 求值(本仓库扩展),可让行按平台/环境自门控。
305
+ - 其它 metadata(`name`/`id`/`inject`/…)保持静态,表达式在那里只是 truthy 数据。
306
+ - `@deepseek-ai/cordis-plugin-include` 把 `!!js` 解析成表达式节点;Loader 在 declared injections 激活后、针对该插件 context(`ctx.serviceName`)插值 entry 的 `config`,在每次 mount 决策时插值 `disabled`;Include 保留嵌套行表达式直到目标激活;其余 metadata 保持字面量。
307
+ - 环境选择插件时用 **overlays**。
308
+
309
+ 真实例子(`packages/bundle/base/cordis.patch.yml`):
310
+ - `bash-sandbox`: `disabled: !!js process.platform === 'win32'`(L180)
311
+ - `sandbox-policy.config.mode`: `!!js process.env.DSH_PERMISSION_MODE ?? 'workspace-write'`(L175)
312
+ - `session-telemetry-otel.config.mode`: `!!js process.env.DSH_TELEMETRY_MODE || 'DISABLED'`(L151)
313
+ - `session-persistence-jsonl.config.root`: `!!js dshHomePath('sessions')`(L101)
314
+
315
+ ### 2.8 `verify-cordis-config` 强制门禁
316
+
317
+ `scripts/verify-cordis-config.ts`(L1–L497)是 `doc-sync` 的一部分,强制以下约束(`AGENTS.md` §Conventions 也引用:"Raw/Web `cordis.yml` bare plugins must appear in their resolver manifest's `dependencies`; `verify-cordis-config` enforces it"):
318
+
319
+ 1. **metadata 插值约束**(`metadataFields = ['id','name','group','inject','intercept','isolate']`,L41;`metadataExpressionErrors` L431–L453):`disabled` 是唯一可插值的 metadata 字段——它的 `!!js` 表达式节点合法且必须可解析(用 `new Function` 只编译不执行,L462–L472),嵌套在它下面的表达式是 truthy 数据;**其余每个 metadata 字段必须完全静态**,出现 `!!js` 报 `!!js is not interpolated here`。
320
+ 2. **依赖解析**(`missingPluginDependencies` L342–L364):每个裸插件 specifier 的包名必须出现在对应 resolver manifest(`examples/package.json`、`apps/cli/package.json` 或某个 bundle manifest)的 `dependencies` 中。
321
+ 3. **source plane 解析**(`validateSourcePlaneResolution` L300–L340):本地 workspace 包的每个 specifier 必须通过 `tsconfig.base.json` 的 `paths` 解析到 `.ts`/`.tsx` 源文件,否则 tsx source launch 在干净 checkout 会失败。
322
+ 4. **preset 平面分离**(`validatePresetPlaneSeparation` L147–L171):shipped agent preset 不得重复 host composition 仍在运行的行(一行属于恰好一个 plane)。
323
+ 5. **client halves 声明**(`validateClientHalvesDeclared` L115–L128):`packages/client` 包导出 `./client` 就必须声明 `dsh.client`(反之亦然)。
324
+ 6. 目录选择器 chooser 的隐式 backend/surface 包依赖也强制解析(L44–L58)。
325
+
326
+ 配套 spec:`scripts/verify-cordis-config.spec.ts`。
327
+
328
+ ### 2.9 Group / isolate(服务隔离)
329
+
330
+ `docs/cordis-tutorial/06-composition-and-hmr.md` L21 + `docs/user/develop/framework/service.md` §Service isolation(L111–L139):
331
+
332
+ - `id` 给 entry 稳定身份(loader 借此区分"编辑已有条目"vs"删了再加")。
333
+ - `disabled: true` 卸载插件但保留条目。
334
+ - **Groups** 把子列表嵌套为一单元加载/卸载;**`isolate`** 给 group 自己的 service 名实例——两个 group 各见不同配置的 `shell` provider 互不影响。
335
+ - 例子(`service.md` L115–L137)用 `@deepseek-ai/cordis-plugin-group` + `isolate: { shell: true }` + `config:` 子列表。
336
+ - 没有 `id` 的 entry 每次读取都生成 id,配置文件一改就算 removed-plus-added 并 remount(`06` L59)。
337
+
338
+ ---
339
+
340
+ ## 3. 插件生命周期与扩展点
341
+
342
+ ### 3.1 Agent loop 与 turn flow
343
+
344
+ `docs/architecture.md` §Turn flow(L63–L90)给出 step/turn 定义与流程:
345
+
346
+ - **step** = 一次模型请求 + 它调用的工具。**turn** = 零或多个 step。
347
+ - 流程(L67–L82):
348
+ ```
349
+ turn/start
350
+ claim next-step input plus one queued message
351
+ assemble prompt sections + tool schemas
352
+ -> agent/pre-step reject | enter(messages)
353
+ reject, or a first enter rewritten empty -> close the turn with no step
354
+ step/start
355
+ append entered messages as user/message
356
+ derive model history from the log
357
+ agent/request -> llm/stream -> assistant/chunk* -> assistant/message
358
+ tool/call* -> tools/pre-execute -> tools/execute -> tools/post-execute -> tool/result*
359
+ step/end
360
+ tools owe another request, or next-step input arrived -> claim -> next step
361
+ -> agent/turn-stopping
362
+ turn/end
363
+ ```
364
+ - `turn/*`、`step/*`、`user/message`、`assistant/*`、`tool/*` 是**持久 session event**;其余是三个域里的 live 扩展点。`agent/pre-step`、`agent/request`、`llm/stream`、三个 `tools/*` 事件是 waterfall(listener 必须调 `next()`);`agent/turn-stopping` 是 serial 且无 `next()`(L84)。
365
+
366
+ ### 3.2 扩展点地图(新行为放哪)
367
+
368
+ `docs/architecture.md` §Where new behavior goes(L104–L127)给了"目标 → 机制"表,例如:
369
+
370
+ | 目标 | 机制 |
371
+ |---|---|
372
+ | 加模型 provider | 在 `ctx.llm` 注册 adapter |
373
+ | 加模型能力 | 在 `ctx.tools` 注册;schema 自动进入 prompt 组装 |
374
+ | 给单会话不同能力集 | 组合 agent preset;那里的 service 行需要 `isolate` realm |
375
+ | 加 shell 执行 | 注册 `ctx.shell` backend;local 经 `ctx.subprocess` spawn |
376
+ | 加人命令 | 注册 `ctx.commands`;不经模型 turn 分发 |
377
+ | 加后台工作 | 注册 `ctx.jobs`;`job_*` tools 收集/停止 |
378
+ | 拦截请求/工具/turn | 用 `agent/*` 或 `tools/*` event |
379
+ | 加模型上下文 | 调 `agent.inject()`;落在下一次 admitted request |
380
+ | 加持久会话状态 | 扩展 `SessionEventMap`;从 log 渲染/replay |
381
+ | 同一会话目标 | 用 `ctx.goals`;经 `agent/*` 继续 |
382
+ | fork 会话 | `ctx.sessions.fork(source, boundary?, childSessionId?)` |
383
+ | 把注册限定到一个 agent | 用该 agent 的 `agent.ctx` |
384
+
385
+ `docs/cookbook/extension-cookbook.md` §The feature → mechanism map(L95–L129)把每个产品 feature 映射到 listener,并给出五种插件骨架示例代码:
386
+ 1. **A tool plugin**(`ctx.tools.register(defineTool(...))`)
387
+ 2. **A hook plugin (permission-gate)**(`ctx.on('tools/pre-execute', async (exec, next) => { if(!isAllowed) return {kind:'deny', reason}; return next() })`,返回 `PreToolDecision`)
388
+ 3. **A UI plugin**(监听 `session/event` 渲染 `assistant/chunk`,用 `agent.followup()`/`agent.steer()` 回输)
389
+ 4. **An external protocol driver**(adapt wire peer 到 `ctx.agents`,`AgentHandle.dispose()` 达 quiescence;`packages/acp/acp` 是 worked example)
390
+ 5. **Runnable wirings**(`examples/*/cordis.yml`)
391
+
392
+ ### 3.3 Tool 注册配方(cookbook: adding-a-tool.md)
393
+
394
+ `docs/cookbook/adding-a-tool.md` 是**模型可见工具契约的权威参考**。最小形态(L9–L38):
395
+
396
+ ```ts
397
+ import { defineTool } from '@deepseek-ai/dsh-tools'
398
+ export const name = 'my-tool'
399
+ export const inject = ['tools']
400
+ export function apply(ctx: Context) {
401
+ ctx.tools.register(defineTool({
402
+ name: 'read_file',
403
+ description: 'Read a file from disk.',
404
+ parameters: {
405
+ path: { type: 'string', required: true, description: 'Absolute path' },
406
+ limit: { type: 'number' },
407
+ },
408
+ output: {
409
+ schema: { type: 'string' },
410
+ render: (_args, value) => [{ type: 'text', text: value }],
411
+ },
412
+ async execute(args, exec) {
413
+ return readFile(args.path, { encoding: 'utf8', signal: exec.signal })
414
+ },
415
+ }))
416
+ }
417
+ ```
418
+
419
+ `execute()` 契约要点(L40–L56):
420
+ - **args 已为你校验**:`defineTool` 在 `execute` 前用 `ParameterSchemaSpec` 校验 model 生成的 `arguments`(类型、required key、literal 约束、exact-one union、嵌套值)。`args` 匹配 `InferArgs`。仍需手查 DSL 不表达的约束(非空字符串、正数、跨字段)。
421
+ - **注册借用你的 readonly definition**:不 mutate schema/替换 callback;热换工具 = dispose owning effect 再注册新实例。
422
+ - **执行身份受保护**:registry 一次性递归 materialize 无损 JSON arguments、在策略开始前 freeze、分配不透明 `exec.token`;`callId`/`name`/`arguments`/`agent`/`token`/必需 caller-owned `signal`/可选 `parent` 在 dispatch 中不可变。
423
+ - **声明并返回一个 canonical JSON 值**:`output.schema` 用 `ValueSchemaSpec`(object/array/scalar/null root);`execute` 只返回推断值,registry 快照/校验/freeze 后交给 `output.render(args, value)`。
424
+ - **throw 或返回无效值 = `isError`**。throw 用于基础设施失败。
425
+ - **遵守 `exec.signal`**(取消在途工作)。
426
+ - 可选 `output.presentationMeta(args, value)` 派生可回放的 JSON(持久到 `tool/result`)。
427
+ - 可选 `exec.agent` 用于异步通知:`agent.inject({ content, source: { kind: 'plugin', plugin: '<name>' } })` 是下一次请求看到的持久上下文,不是唤醒(idle agent 保持 idle)。
428
+ - 后台工作:`run_in_background` 用 producer config 门控,经 `ctx.jobs.start({ kind, label, owner: exec.agent, run })` 注册。
429
+
430
+ **执行策略与观察**(L57–L59):`tools/pre-execute`(可扩展 allow/deny/ask)、`ctx.tools.guard()`(最终单调 deny)、`tools/execute`(包裹 dispatch 加 deadline/retry/metrics)、`tools/post-execute`(替换呈现/值、block、附加上下文)、`tools/result`(观察不可变最终结果)。
431
+
432
+ **Code Mode 免费获得工具**(L61–L65):每个可见注册工具可作为 `await tools.<name>(args)`;生成的 `ToolArgsMap`/`ToolOutputMap` 从同一 schema 推导精确类型;失败 reject 真实 `ToolCallError`(只暴露 `name`/`toolName`/`message`)。
433
+
434
+ **UI 呈现**(L67–L90):`output.render` 是模型内容;UI card 由纯函数 `presentCall`/`presentResult` 声明,返回 `card`-tagged render intent(`generic`/`terminal`/`diff`/`search`/`read`/`web`)。硬规则:**纯度**(live streaming 与 REPLAY 都要跑,必须只是 `args`(+result) 的纯函数,无 I/O/session state/clock/random);UI-only 格式不进 model result;`defineTool` 对显示路径软校验(malformed args 返回 `undefined` 走 generic fallback 而非 throw)。
435
+
436
+ `packages/core/tools/README.md` 给出 `ctx.tools` 服务(`ToolRuntime`)的完整 API:`register`/`presentAs`/`restrict`/`get`/`schemas`/`guard`/`execute`/`executionMode`,以及 config `mode: native | code | both`、`defineTool` schema DSL(`ParameterSchemaSpec`/`ValueSchemaSpec`、`oneOf`、`additionalProperties`)、Code Mode 的 `run_code` 保留 transport、并行执行、`ToolDefinition`/`ToolExecution`/`PreToolDecision`/`PostToolDecision`/`ToolGuard` 等关键类型(L1–L198)。
437
+
438
+ ### 3.4 Skill 插件机制(packages/skill)
439
+
440
+ `packages/skill/skill/README.md` 定义 `ctx.skills`(`SkillRegistry`):
441
+
442
+ - **纯 agent skill provider registry**,不知道 skill 来自本地文件/插件数据/HTTP(`registerProvider` 注册来源)。shipped local 实现是 `@deepseek-ai/dsh-skill-filesystem`。
443
+ - host+per-scope 分层,套在 `@deepseek-ai/dsh-scope` 上:注册落到调用 context 的 scope layer;读取合并 global layer + viewing scope chain,最近层同名胜出。
444
+ - 公共 API:`registerProvider(create)`、`snapshot({cwd,signal,scope})`、`list(...)`、`get(name,...)`、`register(skill)`(runtime embedded skill,rank 250)。
445
+ - 事件 `skills/change`(unfiltered invalidation notification,不带 catalog,消费者自己 `snapshot()` 重取)。
446
+ - config `collectCacheMaxEntries`(默认 128)。
447
+ - **Invocation policy**:`SkillSummary.invocation` 是必需 typed policy(`modelInvocable`/`userInvocable` 两个独立布尔,四种组合)。
448
+ - `renderSkillContent(skill)` 渲染 canonical `<skill_content>` block(`dsh-tool-skill` 与用户显式注入共用同一形状)。
449
+ - 消费者边界:registry 不渲染模型引导也不注册工具;`@deepseek-ai/dsh-tool-skill` 消费 `ctx.skills`(durable session catalogs + `skill` tool)。
450
+
451
+ skill 目录结构:`packages/skill/` 下有 `skill`(registry/Service Definition)、`skill-filesystem`(本地 provider)、`skill-badge`(provider,默认 `disabled: true`)、`tool-skill`(Consumer)。
452
+
453
+ `capability-seams.md` 对应行:`ctx.skills` = seam,owner `skill`,实现 `skill-badge`/`skill-filesystem`,消费者 `tool-skill`。
454
+
455
+ ### 3.5 Bundle / profile 系统 + preset
456
+
457
+ - **bundle**(`packages/bundle/README.md`):`packages/bundle/base/`(patch only,第一层)、`web-app/`(web patch + runtime glue)、`headless/`(挂 `headless-runner`)。`packages/bundle/base/cordis.patch.yml`(L1–L451)是实际的第一层 patch,列出全部 base 行(`llm`、`session`、`typert*`、`agent`、`agent-loop`、`tools`、`system-prompt`、`fs-sandbox`、`llm-deepseek`、`skill*`、`subagent*`、`workflow*`、`tool-*`、`plan-mode`、`goal*` 等),是看真实配置行形状的最佳示例。
458
+ - **profile**:`dsh.profile.bundles` 列表;`web`/`headless` 模板。
459
+ - **preset**(`packages/preset/agent-presets/README.md`):一个 **preset** 是持有一份 `agent.cordis.yml` 的目录;roster 在每进程**只挂载一次**到一个 standing scope,每个命名它的会话通过 `dsh-scope` 的 parent chain 让 agent scope key 父级化到该 mount。视图解析 `agent → preset → global`(近者遮蔽远者)。
460
+ - Service `AgentPresets`(`ctx.agentPresets`)API:`defaultId`/`list()`/`resolve(id?)`/`mount(agentCtx,id?)`/`composeFrom(agentCtx,parentCtx)`/`composedPreset`/`recompose`/`standingKeyFor`/`roots`/`authorable`/`read`/`copy`/`remove`。
461
+ - `mount()` 唯一受支持调用点是 agent factory 的 `setup(agentCtx)` hook。
462
+ - preset 行解析:**包名从 host composition 解析**(本地 preset 在用户 home 下,Node 向上走 `node_modules` 找不到 harness);相对路径从 preset 自身目录解析;绝对路径转 `file:` URL。
463
+ - 显示元数据在可选 `preset.yml`(`name`/`description`)。
464
+ - config:`default`(必填)、`roots`(默认 `[]`)、`includeUserRoot`(默认 `true`,追加 `<dshHome>/.agent-presets`)。
465
+ - mount 拒绝三类:unscoped target、never-usable row、publishes-into-root-realm row(service 要放 `isolate` realm)。
466
+ - preset 文件是 input,不是持久化目标(mounted subtree 覆盖 `write()` 为 no-op)。
467
+ - 切换 = `agent-preset/selected` session event(model-visible ⟺ logged 规则)。
468
+
469
+ ---
470
+
471
+ ## 4. 插件作者必须满足的约定与门禁
472
+
473
+ 根 `AGENTS.md` §Conventions + §Commands + `packages/AGENTS.md` + `docs/testing.md` + `docs/development.md` 是权威来源。
474
+
475
+ ### 4.1 包命名与 manifest 不变式
476
+
477
+ - 每个 npm 包是 `@deepseek-ai/dsh-<name>`;vendored 包 rescope(映射在 `docs/rescope.md`)且 `private: true`。`@deepseek-ai/cordis` 是每个 harness 包的 peerDependency(+ dev)。
478
+ - `packages/AGENTS.md` §Adding a package(`docs/cookbook/adding-a-package.md` L25)的 `package.json` 不变式(`pnpm run constraints` / `scripts/check-workspace-constraints.ts` 强制):`private: true`、`version` 匹配 root、`type: module`、`main: "lib/index.js"`、`types: "lib/types/index.d.ts"`、`exports["."].types: "./lib/types/index.d.ts"`、`exports["."].default: "./lib/index.js"`、`@deepseek-ai/cordis` 同时在 peerDependencies 和 devDependencies(同 range)、每个 dsh peer dep 镜像进 devDependencies、`@deepseek-ai/schemastery` 进 `dependencies`(运行时 validator)、`files` 列表精确为 `lib/index.js`、`lib/invariant.js`、`lib/types/**/*.d.ts` + 包特定 runtime 产物。
479
+ - 包内相对 import 用显式 `.ts` 说明符(`export * from './types.ts'`),编译期改写为 `.js`,声明保留 `.ts`,NodeNext 消费者能解析到 sibling `.d.ts`。
480
+
481
+ ### 4.2 ESM 与 source/artifact 平面
482
+
483
+ - **ESM everywhere**(`"type": "module"`)。跨包用包名,包内相对 import 用 `.ts`。
484
+ - 配置子进程跑 built `lib/`(plain Node);source 回归用声明的 launcher。`dsh` CLI source launch 经 tsx 的 ESM-only hook(`node --import tsx/esm`);它触及的模块必须保持 ESM(无 CJS-only exports)。
485
+ - **Source plane vs artifact plane,永不混用**:静态门禁和测试经 tsconfig `paths` 把 workspace import 解析到 `src`,在干净树上通过;消费 built `lib/` 的门禁要显式声明该依赖(`docs/development.md` §TypeScript project layout)。
486
+
487
+ ### 4.3 类型安全与文档门禁
488
+
489
+ - `strict: true` + `noImplicitAny`;每个残留 `any` 解释为何无法收窄。
490
+ - 每个 module/export 有简洁 JSDoc(`@param`/`@returns`),由 `verify-export-jsdoc` 强制。
491
+ - typed events 用 declaration merging + merge-extensible maps;event JSDoc 需 `@mode` 和 payload `@param`;scoped keys 缺 payload 需 `@dshScopeScan unsupported`。
492
+ - `SessionEventMap` 成员默认 required-on-read;不认其类型的 build 拒绝该 log,除非 event 带 envelope 的 `ignorable: true`;只有结构格式变更才 bump `SESSION_FORMAT_VERSION`。
493
+ - switch 用 discriminant tags:closed union 结尾 `assertNever`;merge-extensible union 走文档化 default。
494
+ - opaque 跨边界 id 用 branded(`Branded<B>` from `dsh-brand`),从不裸 `string`。
495
+ - 每个包拥有 `./invariant`(注册 manifest 名;检查 event/data 关系或给空 installer 一个包特定 `No runtime invariant:` 理由),由 `verify-package-invariants` 强制(`packages/AGENTS.md` L18)。
496
+ - package README 的 Model Experience 格式(canonical Model Experience format,`docs/cookbook/adding-a-package.md` §4)+ `Known Limitations and Deferred Work` 段落由 `verify-package-readme-model-experience.ts` / `verify-package-readme-limitations.ts` 门禁。
497
+
498
+ ### 4.4 双语文档
499
+
500
+ - 人类文档须中英双语,`.zh.md` 配对;契约在 `docs/i18n/README.md`(pairing contract)。routine 双语工作按 `docs/AGENTS.md`;`dsh-translate-docs` 只在用户显式调用时运行。
501
+ - 文档分层(tier taxonomy,`docs/AGENTS.md` L15–L34):一个事实一个 home。生成的英文源(`cordis-surface` 区域、`tool-catalog`、`config-catalog`、`persistence-catalog`、`module-graph`)从源生成且 freshness-gated;中文对照经 pairing workflow。
502
+ - `doc-sync` 聚合所有文档门禁:`verify-md-links`(死链/死锚点)、`verify-type-equiv`(`ts type-equiv`/`ts public-api` 粘贴不漂移)、`verify-doc-budgets`(词数上限)、`verify-agent-note-format`、`verify-archived-agent-notes`、`verify-config-catalog`、`doc-typecheck`(fenced `ts` block 必须编译)等。leaf 列表在 `scripts/run-gates.ts`。
503
+
504
+ ### 4.5 测试与快照门禁
505
+
506
+ `docs/testing.md` 分层:
507
+ - **Unit**(`pnpm run test`):vitest。每个 registry 要有 HMR-safety 测试(dispose contributing fiber,断言清理)。
508
+ - **Coverage gate**(`pnpm run test:coverage`):CI 覆盖门禁 = `packages/*/*/src` 每文件 100%(`test:coverage` 而非 `test` 是门禁)。
509
+ - **Real-API e2e**(`pnpm run test:e2e`):with-key;无 key 自跳过。
510
+ - **Snapshot**(`pnpm run test:snapshot`):keyless 期望输出覆盖外部行为(transport contract + presentation;持久 log pin assembled backend behavior)。ACP boots 真实 automation-server example,replay 录制 session,diff normalized JSON-RPC + 重持久化 log。record 用 `pnpm run test:snapshot:record`。
511
+ - **Web browser snapshot**(`pnpm run test:web`;Linux PR gate)。
512
+
513
+ 关键政策(`testing.md` L33、L47–L49):**product-visible 插件要求 non-unit REAL-composition 测试**(手搭 `ctx.plugin(...)` 套件不够,须 boot 测试专用 `cordis.yml` 经 Loader 和 app/process)。**每个非平凡 model-/protocol-/human-visible 变更在同一 PR 里通过可运行 example 的 snapshot suite 增/改一个 keyless scenario**;包测试、e2e-only 断言、mock-only fixture 不能替代 assembled application transcript。
514
+
515
+ `examples/AGENTS.md` §E2E smokes:每个 example 都要有 keyless(boot 真实 cordis.yml 经 Loader)和 with-key(真实模型 prompt)两个 smoke。
516
+
517
+ ### 4.6 其它门禁与命令
518
+
519
+ `AGENTS.md` §Commands + `docs/development.md`:
520
+ ```sh
521
+ pnpm install # node ^22.19 || >=24(pnpm@11.7.0 pinned)
522
+ pnpm run clean
523
+ pnpm run test # vitest unit
524
+ pnpm run test:coverage # CI coverage gate:packages/*/*/src 每文件 100%
525
+ pnpm run test:e2e # real-API;无 DEEPSEEK_API_KEY 自跳过
526
+ pnpm run test:snapshot # keyless ACP/headless replay
527
+ pnpm run test:snapshot:record
528
+ pnpm run typecheck # strict;Host lib phase 先于 Client
529
+ pnpm run lint # oxlint
530
+ pnpm run duplication # 跨文件 TS clone 检测
531
+ pnpm run build # tsc 出 lib/types,tsdown 打包 runtime
532
+ pnpm run hygiene # knip + publint + workspace constraints + NodeNext consumer check
533
+ pnpm run check:windows-wine # 仅诊断已知 Windows 失败(需 wine)
534
+ pnpm run doc-sync # 所有文档门禁
535
+ pnpm run website:build # VitePress build(兼死链检查)
536
+ pnpm dsh --profile headless "task" # 从源跑一任务(需 key)
537
+ ```
538
+
539
+ `pnpm run hygiene` 含 `publint`(验证 package entrypoint 对 built `lib/*.js`)+ `verify-node-next-types`(对临时 NodeNext consumer 验证 built declarations)——需要先 `pnpm run build`。
540
+
541
+ ### 4.7 仓库级约定(作者必须遵守的行为规则)
542
+
543
+ 根 `AGENTS.md` §Conventions 的 standing rules(与插件开发直接相关者):
544
+
545
+ - **Registrations are effects**:每个贡献经 `ctx.effect()`/`ctx.on()`;registry 的 `register()` 返回 disposer。
546
+ - **Model-visible ⟺ logged**:任何到达模型请求的东西必须能从 session log 重建;新的 model-visible input 需要新 session event。
547
+ - **Plugins, not loop changes**:新行为放在文档化扩展点上;改 `agent-loop` 需更新 `docs/architecture.md`。
548
+ - **A capability seam 由 Service Definition / Service Provider / Consumer 组成**;完整,绝不一角色;只在角色独立演化时拆分。
549
+ - **No hardcoded tunables in plugins**:部署差异是 validated `Config` 字段,可从 cordis.yml 改;`DEFAULT_*` 常量或 test hook 不算可配置性。
550
+ - **Misconfiguration fails loud**:load 时 self-contained 就 load 时失败,否则最早可解析点失败;绝不静默跳过缺失 referent。
551
+ - **Explicit > implicit at package boundaries**:defaulting 是 owning 实现里的显式 `resolve(request): Spec` 步骤,不是 `run()` 里隐藏的 `?? default`(`dsh-shell` 的 request/spec 拆分是模板)。
552
+ - **Waterfall listeners MUST call `next()`**。
553
+ - **Trust TypeScript at typed same-process boundaries**:只在 parser/config、queued、model/tool JSON、durable/file、worker、process、wire 边界做运行时校验。
554
+ - **一个 async 操作 = 一个 lifecycle controller 或 transaction**。
555
+ - **非平凡变更必须同 PR 加 Agent Note**(`.agents/notes/README.md` §When to write one;`docs/AGENTS.md` L39)。
556
+ - TODO markers:`FIXME`/`TODO`/`XXX` 按紧急度。
557
+ - 文件以恰好一个 trailing newline 结尾(`git diff --cached --check` 在 pre-commit 门禁)。
558
+
559
+ Agent Notes 的生命周期/分类/格式见 `.agents/notes/README.md`:路径 `{lifecycle}/{class}/yyyy-mm-dd-topic-title.md`,lifecycle ∈ `proposed`/`implemented`/`rejected`(+ frozen `archived/{class}/`),class ∈ `feature`/`bug-fix`/`simplification`/`architecture`/`process`/`testing`;头部三行固定 `# Agent Note: <title>` + 空行 + `Status: <status>`;强制 `## Alternatives considered`。
560
+
561
+ ---
562
+
563
+ ## 5. 每个事实的路径/URL 索引(摘要)
564
+
565
+ 本地 checkout 权威文件(全部已 `read` 核实):
566
+
567
+ | 事实 | 文件 |
568
+ |---|---|
569
+ | 整体架构 / 一切皆插件 / profile+bundle / 扩展点地图 | `D:\deepseek-harness\docs\architecture.md` |
570
+ | 术语:capability-seam、agent-scope、goal、human command、loop hierarchy、Ralph | `D:\deepseek-harness\docs\glossary.md` |
571
+ | Cordis 五思想 / dispatch modes / waterfall / loader config | `D:\deepseek-harness\docs\cordis-primer.md` |
572
+ | 插件三形态 / 生命周期 / effect / fiber 状态机 / service / events / config / HMR | `D:\deepseek-harness\docs\cordis-tutorial\01~07-*.md` |
573
+ | Cordis 核心 API + inherited tier | `D:\deepseek-harness\docs\cordis-api\{context,events,fiber,service,registry,inherited}.md` |
574
+ | 工具契约(defineTool/execute/output/UI card) | `D:\deepseek-harness\docs\cookbook\adding-a-tool.md` |
575
+ | 加包 checklist / 命名词表 / package README 格式 | `D:\deepseek-harness\docs\cookbook\adding-a-package.md` |
576
+ | 扩展插件骨架 / feature→mechanism map | `D:\deepseek-harness\docs\cookbook\extension-cookbook.md` |
577
+ | LLM adapter 契约 | `D:\deepseek-harness\docs\cookbook\adding-an-llm-adapter.md` |
578
+ | vendored 包 manifest + 本地修改日志 + sync 程序 | `D:\deepseek-harness\vendor\README.md` |
579
+ | Agent Notes 布局/分类/格式 | `D:\deepseek-harness\.agents\notes\README.md` |
580
+ | 包级规则 | `D:\deepseek-harness\packages\AGENTS.md` |
581
+ | examples 规则 | `D:\deepseek-harness\examples\AGENTS.md` |
582
+ | 能力 seam 图 + 服务表 | `D:\deepseek-harness\docs\capability-seams.md` |
583
+ | 配置目录(每包 config 声明) | `D:\deepseek-harness\docs\config-catalog.md`(generated,3151 行) |
584
+ | 测试政策 / snapshot / coverage | `D:\deepseek-harness\docs\testing.md` |
585
+ | 开发指南 / TS project layout / CI | `D:\deepseek-harness\docs\development.md` |
586
+ | 文档标准 / tier taxonomy / 双语 | `D:\deepseek-harness\docs\AGENTS.md` |
587
+ | `ctx.tools` 服务 + Code Mode + 并行 | `D:\deepseek-harness\packages\core\tools\README.md` |
588
+ | `ctx.skills` 服务 | `D:\deepseek-harness\packages\skill\skill\README.md` |
589
+ | `ctx.agentPresets` 服务 | `D:\deepseek-harness\packages\preset\agent-presets\README.md` |
590
+ | bundle 包 | `D:\deepseek-harness\packages\bundle\README.md` + `packages\bundle\{base,web-app,headless}\cordis.patch.yml` |
591
+ | base 层实际配置行 | `D:\deepseek-harness\packages\bundle\base\cordis.patch.yml` |
592
+ | headless 示例组装 | `D:\deepseek-harness\examples\headless-agent\cordis.yml` |
593
+ | 用户教程(建插件/工具/配置/发布) | `D:\deepseek-harness\docs\user\develop\basic\{index,tool,config,publish}.md` |
594
+ | 框架教程(service/events/三角色能力) | `D:\deepseek-harness\docs\user\develop\framework\{service,events}.md` + `docs\user\develop\practice\index.md` |
595
+ | `verify-cordis-config` 强制门禁 | `D:\deepseek-harness\scripts\verify-cordis-config.ts` + `scripts\verify-cordis-config.spec.ts` |
596
+ | 根约定 + 命令 | `D:\deepseek-harness\AGENTS.md`(`CLAUDE.md` 是软链接) |
597
+
598
+ 公开仓库 URL(经 web_search 核实存在):
599
+
600
+ - 仓库首页:https://github.com/deepseek-ai/deepseek-harness (标题 "DeepSeek Harness: Everything is a Plugin.")
601
+ - README:https://github.com/deepseek-ai/deepseek-harness/blob/master/README.md 与 `README.zh.md`
602
+ - 架构文档:https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/architecture.md (及 `.zh.md`)
603
+ - 配置目录:https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/config-catalog.md
604
+ - 发布教程:https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/user/develop/basic/publish.md
605
+ - Cordis primer:https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/cordis-primer.md
606
+ - 能力 seam:https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/glossary.md
607
+ - npm 包示例:https://www.npmjs.com/package/@deepseek-ai/dsh-settings-file
608
+
609
+ > 公开仓库 master 分支的文档结构与本地 checkout 一致(architecture.md、config-catalog.md、cordis-primer.md、glossary.md、publish.md 等在 master 均可访问)。公开 issues/discussions 中"专门讨论插件开发契约"的**独立线程内容未在本次检索中抓到**——本次 web_search 返回的源主要是文档镜像(README/docs/cookbook/cordis-tutorial),因此"公开 issue/discussion 里的额外插件开发约定"视为 `[unverified]`;其余所有事实均已本地读档核实。
610
+
611
+ ---
612
+
613
+ ## 全部来源
614
+
615
+ **本地(只读 checkout `D:\deepseek-harness`,全部 `read` 核实):**
616
+ 1. `docs/architecture.md`
617
+ 2. `docs/glossary.md`
618
+ 3. `docs/cordis-primer.md`
619
+ 4. `docs/cordis-tutorial/01-first-plugin.md` ~ `07-into-the-harness.md`
620
+ 5. `docs/cookbook/adding-a-tool.md`
621
+ 6. `docs/cookbook/adding-a-package.md`
622
+ 7. `docs/cookbook/extension-cookbook.md`
623
+ 8. `docs/cookbook/adding-an-llm-adapter.md`
624
+ 9. `docs/capability-seams.md`
625
+ 10. `docs/config-catalog.md`
626
+ 11. `docs/testing.md`
627
+ 12. `docs/development.md`
628
+ 13. `docs/AGENTS.md`
629
+ 14. `docs/user/develop/basic/{index,tool,config,publish}.md`
630
+ 15. `docs/user/develop/framework/{service,events}.md`
631
+ 16. `docs/user/develop/practice/index.md`
632
+ 17. `packages/AGENTS.md`
633
+ 18. `examples/AGENTS.md`
634
+ 19. `vendor/README.md`
635
+ 20. `.agents/notes/README.md`
636
+ 21. `packages/bundle/README.md` + `packages/bundle/base/cordis.patch.yml` + `packages/bundle/{web-app,headless}/cordis.patch.yml`
637
+ 22. `packages/skill/skill/README.md`
638
+ 23. `packages/preset/agent-presets/README.md`
639
+ 24. `packages/core/tools/README.md`
640
+ 25. `examples/headless-agent/cordis.yml`
641
+ 26. `scripts/verify-cordis-config.ts` + `scripts/verify-cordis-config.spec.ts`
642
+ 27. 根 `AGENTS.md` / `CLAUDE.md`
643
+
644
+ **Web(web_search):**
645
+ - https://github.com/deepseek-ai/deepseek-harness
646
+ - https://github.com/deepseek-ai/deepseek-harness/blob/master/README.md
647
+ - https://github.com/deepseek-ai/deepseek-harness/blob/master/README.zh.md
648
+ - https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/architecture.md
649
+ - https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/config-catalog.md
650
+ - https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/user/develop/basic/publish.md
651
+ - https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/cordis-primer.md
652
+ - https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/glossary.md
653
+ - https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/capability-seams.md
654
+ - https://www.npmjs.com/package/@deepseek-ai/dsh-settings-file