dsh-plugin-dev-kb 1.0.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 (234) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +56 -0
  3. package/cordis.patch.yml +12 -0
  4. package/kb/INDEX.md +210 -0
  5. package/kb/README.md +69 -0
  6. package/kb/extra/AGENTS.md +75 -0
  7. package/kb/extra/api-gateway.md +164 -0
  8. package/kb/extra/api-gateway.zh.md +164 -0
  9. package/kb/extra/cookbook/adding-a-vendored-package.md +59 -0
  10. package/kb/extra/cookbook/adding-a-vendored-package.zh.md +59 -0
  11. package/kb/extra/cookbook/maintaining-dsh-code-review.md +64 -0
  12. package/kb/extra/cookbook/maintaining-dsh-code-review.zh.md +64 -0
  13. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.md +32 -0
  14. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +32 -0
  15. package/kb/extra/defensive-patterns.md +33 -0
  16. package/kb/extra/defensive-patterns.zh.md +33 -0
  17. package/kb/extra/development.md +171 -0
  18. package/kb/extra/development.zh.md +171 -0
  19. package/kb/extra/event-producer-consumer.md +76 -0
  20. package/kb/extra/event-producer-consumer.zh.md +78 -0
  21. package/kb/extra/glossary.md +45 -0
  22. package/kb/extra/glossary.zh.md +45 -0
  23. package/kb/extra/graph-atlas.md +24 -0
  24. package/kb/extra/graph-atlas.zh.md +26 -0
  25. package/kb/extra/i18n/README.md +60 -0
  26. package/kb/extra/i18n/README.zh.md +60 -0
  27. package/kb/extra/i18n/style-samples.md +87 -0
  28. package/kb/extra/i18n/terminology.md +214 -0
  29. package/kb/extra/i18n/translation-prompt.md +263 -0
  30. package/kb/extra/i18n/translation-rules.md +69 -0
  31. package/kb/extra/i18n/translation-rules.zh.md +69 -0
  32. package/kb/extra/module-graph.md +1641 -0
  33. package/kb/extra/module-graph.zh.md +1643 -0
  34. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.md +113 -0
  35. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +113 -0
  36. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.md +47 -0
  37. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +47 -0
  38. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.md +53 -0
  39. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.zh.md +53 -0
  40. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +55 -0
  41. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +55 -0
  42. package/kb/extra/postmortem/README.md +18 -0
  43. package/kb/extra/postmortem/README.zh.md +18 -0
  44. package/kb/extra/rescope.md +53 -0
  45. package/kb/extra/rescope.zh.md +53 -0
  46. package/kb/extra/subsystems/attachment.md +125 -0
  47. package/kb/extra/subsystems/attachment.zh.md +125 -0
  48. package/kb/extra/subsystems/extensions.md +364 -0
  49. package/kb/extra/subsystems/extensions.zh.md +364 -0
  50. package/kb/extra/subsystems/feedback.md +266 -0
  51. package/kb/extra/subsystems/feedback.zh.md +266 -0
  52. package/kb/extra/testing.md +49 -0
  53. package/kb/extra/testing.zh.md +49 -0
  54. package/kb/extra/web-styling.md +25 -0
  55. package/kb/extra/web-styling.zh.md +25 -0
  56. package/kb/meta/search-index.json +1328 -0
  57. package/kb/meta/site-pages.txt +168 -0
  58. package/kb/meta/source.json +13 -0
  59. package/kb/meta/topics.md +75 -0
  60. package/kb/site/develop/basic/config.md +108 -0
  61. package/kb/site/develop/basic/index.md +146 -0
  62. package/kb/site/develop/basic/publish.md +185 -0
  63. package/kb/site/develop/basic/tool.md +54 -0
  64. package/kb/site/develop/cordis-tutorial/01-first-plugin.md +95 -0
  65. package/kb/site/develop/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
  66. package/kb/site/develop/cordis-tutorial/03-services.md +98 -0
  67. package/kb/site/develop/cordis-tutorial/04-events.md +144 -0
  68. package/kb/site/develop/cordis-tutorial/05-config.md +84 -0
  69. package/kb/site/develop/cordis-tutorial/06-composition-and-hmr.md +113 -0
  70. package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +107 -0
  71. package/kb/site/develop/cordis-tutorial/index.md +62 -0
  72. package/kb/site/develop/framework/events.md +145 -0
  73. package/kb/site/develop/framework/index.md +139 -0
  74. package/kb/site/develop/framework/service.md +152 -0
  75. package/kb/site/develop/practice/index.md +157 -0
  76. package/kb/site/develop/practice/llm-adapter.md +190 -0
  77. package/kb/site/en/develop/basic/config.md +108 -0
  78. package/kb/site/en/develop/basic/index.md +146 -0
  79. package/kb/site/en/develop/basic/publish.md +185 -0
  80. package/kb/site/en/develop/basic/tool.md +54 -0
  81. package/kb/site/en/develop/cordis-tutorial/01-first-plugin.md +95 -0
  82. package/kb/site/en/develop/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
  83. package/kb/site/en/develop/cordis-tutorial/03-services.md +98 -0
  84. package/kb/site/en/develop/cordis-tutorial/04-events.md +144 -0
  85. package/kb/site/en/develop/cordis-tutorial/05-config.md +84 -0
  86. package/kb/site/en/develop/cordis-tutorial/06-composition-and-hmr.md +113 -0
  87. package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +107 -0
  88. package/kb/site/en/develop/cordis-tutorial/index.md +60 -0
  89. package/kb/site/en/develop/framework/events.md +145 -0
  90. package/kb/site/en/develop/framework/index.md +139 -0
  91. package/kb/site/en/develop/framework/service.md +150 -0
  92. package/kb/site/en/develop/practice/index.md +157 -0
  93. package/kb/site/en/develop/practice/llm-adapter.md +190 -0
  94. package/kb/site/en/guide/providers-custom-form.png +0 -0
  95. package/kb/site/en/guide/providers-models-page.png +0 -0
  96. package/kb/site/en/guide/providers.md +100 -0
  97. package/kb/site/en/guide/python-sdk.md +106 -0
  98. package/kb/site/en/guide/quickstart.md +32 -0
  99. package/kb/site/en/index.md +8 -0
  100. package/kb/site/en/reference/agent-lifecycle.md +86 -0
  101. package/kb/site/en/reference/capability-seams.md +475 -0
  102. package/kb/site/en/reference/config-catalog.md +3155 -0
  103. package/kb/site/en/reference/cookbook/adding-a-conversation-node.md +235 -0
  104. package/kb/site/en/reference/cookbook/adding-a-package.md +120 -0
  105. package/kb/site/en/reference/cookbook/adding-a-settings-card.md +102 -0
  106. package/kb/site/en/reference/cookbook/adding-a-tool.md +96 -0
  107. package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +45 -0
  108. package/kb/site/en/reference/cookbook/extension-cookbook.md +131 -0
  109. package/kb/site/en/reference/cordis-api/context.md +368 -0
  110. package/kb/site/en/reference/cordis-api/events.md +211 -0
  111. package/kb/site/en/reference/cordis-api/fiber.md +379 -0
  112. package/kb/site/en/reference/cordis-api/inherited.md +43 -0
  113. package/kb/site/en/reference/cordis-api/registry.md +156 -0
  114. package/kb/site/en/reference/cordis-api/service.md +106 -0
  115. package/kb/site/en/reference/cordis-primer.md +46 -0
  116. package/kb/site/en/reference/index.md +131 -0
  117. package/kb/site/en/reference/persistence-catalog.md +949 -0
  118. package/kb/site/en/reference/subsystems/approval.md +173 -0
  119. package/kb/site/en/reference/subsystems/client-modules.md +121 -0
  120. package/kb/site/en/reference/subsystems/code-runtime.md +194 -0
  121. package/kb/site/en/reference/subsystems/commands.md +190 -0
  122. package/kb/site/en/reference/subsystems/compaction.md +241 -0
  123. package/kb/site/en/reference/subsystems/core.md +1073 -0
  124. package/kb/site/en/reference/subsystems/credentials.md +136 -0
  125. package/kb/site/en/reference/subsystems/filesystem.md +498 -0
  126. package/kb/site/en/reference/subsystems/goal.md +280 -0
  127. package/kb/site/en/reference/subsystems/index.md +58 -0
  128. package/kb/site/en/reference/subsystems/invariants.md +91 -0
  129. package/kb/site/en/reference/subsystems/jobs.md +293 -0
  130. package/kb/site/en/reference/subsystems/llm-streaming.md +920 -0
  131. package/kb/site/en/reference/subsystems/lsp.md +205 -0
  132. package/kb/site/en/reference/subsystems/permission-presets.md +134 -0
  133. package/kb/site/en/reference/subsystems/persistence.md +388 -0
  134. package/kb/site/en/reference/subsystems/plan.md +90 -0
  135. package/kb/site/en/reference/subsystems/sandbox.md +221 -0
  136. package/kb/site/en/reference/subsystems/schedule.md +189 -0
  137. package/kb/site/en/reference/subsystems/scope.md +62 -0
  138. package/kb/site/en/reference/subsystems/session-projection.md +265 -0
  139. package/kb/site/en/reference/subsystems/session-query.md +498 -0
  140. package/kb/site/en/reference/subsystems/session-reference.md +111 -0
  141. package/kb/site/en/reference/subsystems/session-telemetry.md +197 -0
  142. package/kb/site/en/reference/subsystems/session-title.md +207 -0
  143. package/kb/site/en/reference/subsystems/session.md +852 -0
  144. package/kb/site/en/reference/subsystems/settings.md +313 -0
  145. package/kb/site/en/reference/subsystems/shell.md +306 -0
  146. package/kb/site/en/reference/subsystems/skills.md +334 -0
  147. package/kb/site/en/reference/subsystems/spill.md +120 -0
  148. package/kb/site/en/reference/subsystems/storage.md +232 -0
  149. package/kb/site/en/reference/subsystems/subagent.md +737 -0
  150. package/kb/site/en/reference/subsystems/subprocess.md +327 -0
  151. package/kb/site/en/reference/subsystems/system-prompt.md +210 -0
  152. package/kb/site/en/reference/subsystems/terminal.md +187 -0
  153. package/kb/site/en/reference/subsystems/token-meter.md +93 -0
  154. package/kb/site/en/reference/subsystems/tools.md +723 -0
  155. package/kb/site/en/reference/subsystems/typert.md +339 -0
  156. package/kb/site/en/reference/subsystems/user-questions.md +181 -0
  157. package/kb/site/en/reference/subsystems/web-server.md +111 -0
  158. package/kb/site/en/reference/subsystems/web.md +202 -0
  159. package/kb/site/en/reference/subsystems/workflow.md +281 -0
  160. package/kb/site/en/reference/subsystems/workspace.md +231 -0
  161. package/kb/site/en/reference/tool-catalog.md +1877 -0
  162. package/kb/site/en/reference/tool-execution-pipeline.md +66 -0
  163. package/kb/site/guide/providers-custom-form.zh.png +0 -0
  164. package/kb/site/guide/providers-models-page.zh.png +0 -0
  165. package/kb/site/guide/providers.md +100 -0
  166. package/kb/site/guide/python-sdk.md +106 -0
  167. package/kb/site/guide/quickstart.md +32 -0
  168. package/kb/site/index.md +8 -0
  169. package/kb/site/reference/agent-lifecycle.md +86 -0
  170. package/kb/site/reference/capability-seams.md +475 -0
  171. package/kb/site/reference/config-catalog.md +3154 -0
  172. package/kb/site/reference/cookbook/adding-a-conversation-node.md +235 -0
  173. package/kb/site/reference/cookbook/adding-a-package.md +120 -0
  174. package/kb/site/reference/cookbook/adding-a-settings-card.md +102 -0
  175. package/kb/site/reference/cookbook/adding-a-tool.md +98 -0
  176. package/kb/site/reference/cookbook/adding-an-llm-adapter.md +45 -0
  177. package/kb/site/reference/cookbook/extension-cookbook.md +133 -0
  178. package/kb/site/reference/cordis-api/context.md +368 -0
  179. package/kb/site/reference/cordis-api/events.md +211 -0
  180. package/kb/site/reference/cordis-api/fiber.md +379 -0
  181. package/kb/site/reference/cordis-api/inherited.md +43 -0
  182. package/kb/site/reference/cordis-api/registry.md +156 -0
  183. package/kb/site/reference/cordis-api/service.md +106 -0
  184. package/kb/site/reference/cordis-primer.md +52 -0
  185. package/kb/site/reference/index.md +135 -0
  186. package/kb/site/reference/persistence-catalog.md +949 -0
  187. package/kb/site/reference/subsystems/approval.md +173 -0
  188. package/kb/site/reference/subsystems/client-modules.md +121 -0
  189. package/kb/site/reference/subsystems/code-runtime.md +194 -0
  190. package/kb/site/reference/subsystems/commands.md +190 -0
  191. package/kb/site/reference/subsystems/compaction.md +241 -0
  192. package/kb/site/reference/subsystems/core.md +1081 -0
  193. package/kb/site/reference/subsystems/credentials.md +136 -0
  194. package/kb/site/reference/subsystems/filesystem.md +498 -0
  195. package/kb/site/reference/subsystems/goal.md +280 -0
  196. package/kb/site/reference/subsystems/index.md +58 -0
  197. package/kb/site/reference/subsystems/invariants.md +91 -0
  198. package/kb/site/reference/subsystems/jobs.md +293 -0
  199. package/kb/site/reference/subsystems/llm-streaming.md +926 -0
  200. package/kb/site/reference/subsystems/lsp.md +205 -0
  201. package/kb/site/reference/subsystems/permission-presets.md +134 -0
  202. package/kb/site/reference/subsystems/persistence.md +388 -0
  203. package/kb/site/reference/subsystems/plan.md +90 -0
  204. package/kb/site/reference/subsystems/sandbox.md +221 -0
  205. package/kb/site/reference/subsystems/schedule.md +189 -0
  206. package/kb/site/reference/subsystems/scope.md +62 -0
  207. package/kb/site/reference/subsystems/session-projection.md +265 -0
  208. package/kb/site/reference/subsystems/session-query.md +498 -0
  209. package/kb/site/reference/subsystems/session-reference.md +111 -0
  210. package/kb/site/reference/subsystems/session-telemetry.md +197 -0
  211. package/kb/site/reference/subsystems/session-title.md +207 -0
  212. package/kb/site/reference/subsystems/session.md +854 -0
  213. package/kb/site/reference/subsystems/settings.md +313 -0
  214. package/kb/site/reference/subsystems/shell.md +306 -0
  215. package/kb/site/reference/subsystems/skills.md +334 -0
  216. package/kb/site/reference/subsystems/spill.md +120 -0
  217. package/kb/site/reference/subsystems/storage.md +232 -0
  218. package/kb/site/reference/subsystems/subagent.md +739 -0
  219. package/kb/site/reference/subsystems/subprocess.md +327 -0
  220. package/kb/site/reference/subsystems/system-prompt.md +210 -0
  221. package/kb/site/reference/subsystems/terminal.md +187 -0
  222. package/kb/site/reference/subsystems/token-meter.md +93 -0
  223. package/kb/site/reference/subsystems/tools.md +723 -0
  224. package/kb/site/reference/subsystems/typert.md +339 -0
  225. package/kb/site/reference/subsystems/user-questions.md +181 -0
  226. package/kb/site/reference/subsystems/web-server.md +111 -0
  227. package/kb/site/reference/subsystems/web.md +202 -0
  228. package/kb/site/reference/subsystems/workflow.md +281 -0
  229. package/kb/site/reference/subsystems/workspace.md +231 -0
  230. package/kb/site/reference/tool-catalog.md +1880 -0
  231. package/kb/site/reference/tool-execution-pipeline.md +66 -0
  232. package/package.json +40 -0
  233. package/scripts/rebuild-index.mjs +88 -0
  234. package/skills/dsh-plugin-dev-kb.md +66 -0
@@ -0,0 +1,205 @@
1
+ ---
2
+ editSource: "docs/subsystems/lsp.zh.md"
3
+ outline: [2,3]
4
+ ---
5
+
6
+ # LSP 导航
7
+
8
+ LSP seam 是一个[能力 seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-15-lsp-capability-seam.md):它在单一 `ctx.lsp` 服务上公开语义代码导航,并拆分到多个包:Service Definition([dsh-lsp](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/lsp/lsp),`ctx.lsp` + 提供方注册表)、通用 Service Provider([dsh-lsp-stdio](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/lsp/lsp-stdio),经过配置的 stdio 语言服务器宿主)和 Consumer([dsh-tool-lsp](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/lsp/tool-lsp),即 `lsp` 工具 schema)。LSP 是**一项可选能力**,不属于 agent loop(智能体循环)主干,因此其词汇定义在此而非 [core.md](./core.md) 中。更换提供方不会改变模型请求导航的方式。
9
+
10
+ 源文件:[`packages/lsp/lsp/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/lsp/lsp/src/types.ts)
11
+
12
+ ## 操作与坐标
13
+
14
+ seam 与模型恰好公开 4 项语义查询;该联合是闭合的,因此新增一项查询会通过编译强制要求同步修改 seam、提供方和工具。位置与范围采用从零开始的 UTF-16 坐标,与协议一致;面向模型的工具采用从 1 开始的光标约定,并在输入和输出时进行转换。
15
+
16
+ ```ts type-equiv
17
+ /**
18
+ * The four semantic queries the seam and model expose. A closed union: adding an operation is a
19
+ * compile-enforced change across the seam, providers, and the tool. Symbols and call hierarchy are
20
+ * not operations here; they need different schemas.
21
+ */
22
+ type LspOperation = 'goToDefinition' | 'findReferences' | 'goToImplementation' | 'hover'
23
+ ```
24
+
25
+ ```ts type-equiv
26
+ /** A zero-based UTF-16 cursor coordinate, matching the LSP wire convention. */
27
+ interface LspPosition {
28
+ /** Zero-based line. */
29
+ readonly line: number
30
+ /** Zero-based UTF-16 code-unit offset within the line. */
31
+ readonly character: number
32
+ }
33
+ ```
34
+
35
+ ```ts type-equiv
36
+ /** A zero-based UTF-16 half-open range `[start, end)`. */
37
+ interface LspRange {
38
+ readonly start: LspPosition
39
+ readonly end: LspPosition
40
+ }
41
+ ```
42
+
43
+ ## 请求
44
+
45
+ 每个字段都是必填项:`workspaceRoot` 由调用方提供,`languageId` 来自提供方注册而非请求,超时与结果上限由消费方决定。因此没有字段需要由实现提供默认值,也不存在 `resolve()` 步骤。提供方收到调用方请求和派生的 `languageId`;后者只用于同步瞬态文档,从不参与选择。
46
+
47
+ ```ts type-equiv
48
+ /**
49
+ * A caller's normalized query. Every field is required: `workspaceRoot` is caller-supplied,
50
+ * `languageId` comes from the provider registration (not here), and consumers own timeouts and
51
+ * result limits — so no field needs implementation defaulting and there is no `resolve()` step.
52
+ */
53
+ interface LspQueryRequest {
54
+ /** Which semantic query to run. */
55
+ readonly operation: LspOperation
56
+ /** The source file to query (relative to `workspaceRoot` or absolute; the provider canonicalizes). */
57
+ readonly filePath: string
58
+ /** The zero-based UTF-16 cursor position to query at. */
59
+ readonly position: LspPosition
60
+ /** The workspace root the provider resolves against and indexes; required, never defaulted. */
61
+ readonly workspaceRoot: string
62
+ }
63
+ ```
64
+
65
+ ```ts type-equiv
66
+ /**
67
+ * A request as a provider receives it: the caller's {@link LspQueryRequest} plus the `languageId`
68
+ * the seam derived from the provider's extension mapping. The language id only synchronizes the
69
+ * transient document; it does not participate in selection.
70
+ */
71
+ interface LspProviderQuery extends LspQueryRequest {
72
+ /** The LSP language id for `filePath`, from this provider's extension mapping. */
73
+ readonly languageId: string
74
+ }
75
+ ```
76
+
77
+ ## 结果
78
+
79
+ 这是一个闭合的可辨识联合:导航操作规范化为 `locations`,`hover` 规范化为内容或 `null`。消费方使用 `switch` 对 `kind` 做穷尽处理,因此新增分支会使编译失败,直到完成处理。`findReferences` 始终包含声明;提供方在内部强制保证这一点,因此调用方没有对应 flag。`locations` 变体携带 `resolvedWorkspaceUri`,即提供方的规范工作区 `file:` URI。调用方相对化位置 URI 时应使用这一坐标,而不是对可能经过符号链接的请求根目录应用宿主平台路径规则。
80
+
81
+ ```ts type-equiv
82
+ /** One resolved location: a document URI and the range within it. */
83
+ interface LspLocation {
84
+ /** The target document URI (`file:` or otherwise), verbatim from the server. */
85
+ readonly uri: string
86
+ /** The range within the target document. */
87
+ readonly range: LspRange
88
+ }
89
+ ```
90
+
91
+ ```ts type-equiv
92
+ /** Normalized hover content, or `null` for no hover at the position. */
93
+ interface LspHover {
94
+ /** The normalized hover text (markdown or plaintext, provider-joined). */
95
+ readonly contents: string
96
+ /** The range the hover applies to, when the server supplied one. */
97
+ readonly range?: LspRange
98
+ }
99
+ ```
100
+
101
+ ```ts type-equiv
102
+ /**
103
+ * The closed result union. Navigation operations (`goToDefinition`, `findReferences`,
104
+ * `goToImplementation`) normalize to `locations`; `hover` normalizes to content or `null`.
105
+ * Consumers `switch` on `kind` to exhaustiveness so a new arm breaks compilation until handled.
106
+ *
107
+ * The `locations` variant carries `resolvedWorkspaceUri`: the provider's canonical `file:` URI for
108
+ * the request's workspace root. A caller that relativizes location URIs MUST use this, not parse the
109
+ * request's possibly symlinked process path with host-platform rules; the execution platform may
110
+ * differ from the caller's.
111
+ */
112
+ type LspQueryResult =
113
+ | { readonly kind: 'locations'; readonly locations: readonly LspLocation[]; readonly resolvedWorkspaceUri: string }
114
+ | { readonly kind: 'hover'; readonly hover: LspHover | null }
115
+ ```
116
+
117
+ ## 提供方与服务
118
+
119
+ 每个提供方拥有一个稳定的品牌化 `id`,以及一份互斥的、小写且以点开头的扩展名映射。`registerProvider` 会原子预留 id 和每个扩展名:注册无效或冲突时不发布任何内容;其 disposer 会释放所有保留项。每次查询独立选择提供方,且选择与顺序无关;没有匹配项时抛出 `LspError` `LSP_UNAVAILABLE`。该 seam 不公开协议类型、进程或文档控制,也不提供通用 JSON-RPC 逃生口。
120
+
121
+ ```ts type-equiv
122
+ /**
123
+ * A language-server backend registered on `ctx.lsp`. Each provider owns a stable {@link
124
+ * LspProviderId} and an extension-to-language-id map (lowercase, leading-dot keys).
125
+ * `findReferences` always includes declarations — the provider enforces this internally; callers
126
+ * get no flag.
127
+ */
128
+ interface LspProvider {
129
+ /** Stable provider identity, reserved atomically with the extension mappings. */
130
+ readonly id: LspProviderId
131
+ /** Lowercase leading-dot extension → LSP language id (e.g. `{ '.ts': 'typescript' }`). */
132
+ readonly extensionToLanguage: Readonly<Record<string, string>>
133
+ /**
134
+ * Run one query. The seam has already selected this provider and derived `languageId`.
135
+ * @param request - the resolved provider query (caller request + derived language id).
136
+ * @param signal - optional cancellation; the provider stops its own work when it aborts.
137
+ * @returns the normalized, closed-union result.
138
+ */
139
+ query(request: LspProviderQuery, signal?: AbortSignal): Promise<LspQueryResult>
140
+ }
141
+ ```
142
+
143
+ ```ts type-equiv
144
+ /**
145
+ * The LSP capability seam (`ctx.lsp`). Owns provider registration/selection and normalized query
146
+ * execution; exposes exactly the four operations and no protocol escape hatch.
147
+ */
148
+ interface LspService {
149
+ /**
150
+ * Register a provider, atomically reserving its id and every normalized extension. Any conflict
151
+ * or invalid input publishes nothing and throws `LspError`; the returned disposer releases all
152
+ * reservations. Disposed with the calling fiber.
153
+ * @param provider - the backend to register.
154
+ * @returns a synchronous disposer releasing the id and all extension reservations.
155
+ */
156
+ registerProvider(provider: LspProvider): () => void
157
+ /**
158
+ * Select a provider by the file's extension and run one query. Selection is per-query and
159
+ * order-independent; no match throws `LspError` `LSP_UNAVAILABLE`.
160
+ * @param request - the normalized query.
161
+ * @param signal - optional cancellation forwarded to the selected provider.
162
+ * @returns the normalized, closed-union result.
163
+ */
164
+ query(request: LspQueryRequest, signal?: AbortSignal): Promise<LspQueryResult>
165
+ }
166
+ ```
167
+
168
+ `LspProviderId` 是该 seam 的品牌化 id(来自 [dsh-brand](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/util/brand) 的 `Branded<'LspProviderId'>`);`LspError` 扩展 `HarnessError`,提供 `LSP_INVALID_PROVIDER`、`LSP_CONFLICT`、`LSP_UNAVAILABLE`、`LSP_DISPOSED`、`LSP_UNSUPPORTED_OPERATION` 和 `LSP_MALFORMED_RESPONSE` 等稳定错误码,调用方应按错误码路由,而不是解析 `message`。
169
+
170
+ <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
171
+
172
+ <a id="cordis-surface"></a>
173
+
174
+ ## Cordis API
175
+
176
+ 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`) — this section is byte-identical in both language sides of the page. 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).
177
+
178
+ <a id="ctxlsp--lspservice"></a>
179
+
180
+ ### `ctx.lsp` — `LspService`
181
+
182
+ The LSP capability seam (`ctx.lsp`). Owns provider registration/selection and normalized query execution; exposes exactly the four operations and no protocol escape hatch.
183
+
184
+ ```ts cordis-catalog
185
+ /**
186
+ * Register a provider, atomically reserving its id and every normalized extension. Any conflict
187
+ * or invalid input publishes nothing and throws `LspError`; the returned disposer releases all
188
+ * reservations. Disposed with the calling fiber.
189
+ * @param provider - the backend to register.
190
+ * @returns a synchronous disposer releasing the id and all extension reservations.
191
+ */
192
+ registerProvider(provider: LspProvider): () => void
193
+
194
+ /**
195
+ * Select a provider by the file's extension and run one query. Selection is per-query and
196
+ * order-independent; no match throws `LspError` `LSP_UNAVAILABLE`.
197
+ * @param request - the normalized query.
198
+ * @param signal - optional cancellation forwarded to the selected provider.
199
+ * @returns the normalized, closed-union result.
200
+ */
201
+ query(request: LspQueryRequest, signal?: AbortSignal): Promise<LspQueryResult>
202
+ ```
203
+
204
+ Source: [`packages/lsp/lsp/src/types.ts:113`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/lsp/lsp/src/types.ts)
205
+ <!-- END GENERATED cordis-surface -->
@@ -0,0 +1,134 @@
1
+ ---
2
+ editSource: "docs/subsystems/permission-presets.zh.md"
3
+ outline: [2,3]
4
+ ---
5
+
6
+ # 权限预设
7
+
8
+ [dsh-permission-presets](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/interaction/permission-presets) 的权限预设层(`ctx.permissionPresets`,`PermissionPresetService`)把两个相互独立的强制执行 knob,即[沙箱模式](./sandbox.md)(`sandbox/mode`)与[审批策略](./approval.md)(`approval/policy`),捆绑成具名预设,供客户端作为单个权限(Permissions)选择器提供。它是一项可选能力,不属于 agent loop(智能体循环)主干,也不拥有任何强制执行:执行、提示词叙述与回放仍然读取各自 knob的折叠结果,预设切换只记录意图,并通过每个 knob各自的规范 setter 写入。[包 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/permission-presets/README.md) 负责组合状态与限制;[沙箱切换设计](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-06-sandbox.md)负责决策依据。
9
+
10
+ 源码:[`packages/interaction/permission-presets/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/permission-presets/src/index.ts)
11
+
12
+ ## 预设表
13
+
14
+ 预设是一个表键,映射到一个沙箱/审批组合,外加可选的客户端展示信息;默认预设表自带 `workspace-write`(`workspace-write` + `ask`)和 `danger-full-access`(`danger-full-access` + `never`)。
15
+
16
+ ```ts type-equiv
17
+ /** One preset's sandbox/approval bundle and optional client presentation. */
18
+ interface PresetSpec {
19
+ /** The `sandbox/mode` value the preset writes through. */
20
+ sandbox: SandboxMode
21
+ /** The `approval/policy` value the preset writes through. */
22
+ approval: ApprovalPolicy
23
+ /** The display label a client shows for this preset; the raw table key when omitted. */
24
+ name?: string
25
+ /** One user-facing sentence on what the preset means; omitted when not configured. */
26
+ description?: string
27
+ }
28
+ ```
29
+
30
+ ```ts type-equiv
31
+ /** The {@link PermissionPresetService} config: preset table and composition default. */
32
+ interface Config {
33
+ /**
34
+ * The preset table: name → knob bundle. Defaults to `workspace-write`
35
+ * (workspace-write + ask) and `danger-full-access` (danger-full-access +
36
+ * never). The name `custom` is reserved for the derived not-a-preset state.
37
+ */
38
+ presets?: Record<string, PresetSpec>
39
+ /**
40
+ * Default for new sessions. When omitted, the preset matching the composed
41
+ * sandbox and approval defaults is used.
42
+ */
43
+ defaultPreset?: string
44
+ }
45
+ ```
46
+
47
+ 该服务要求一个施加隔离的 `ctx.shell` 执行器和 `ctx.approval`,配置错误在插件加载时即失败:名为 `custom` 的表项会抛出异常(该名称保留给派生的「非预设」状态);在不施加隔离的 bash 执行器(没有 `sandboxMode` 能力事实)之上组合同样抛出异常,因为预设捆绑了一个沙箱模式。
48
+
49
+ ## 当前预设与派生的 `custom`
50
+
51
+ `current(events)` 从 knob 派生实际生效的预设,而不是只看自身事件:它折叠会话的生效沙箱模式(回退到执行器配置的模式)与生效审批策略(先回退到审批服务配置,再回退到 `ask`),优先取仍然匹配的已记录选择,其次取声明顺序中第一个匹配的表项,否则返回 `CUSTOM_PRESET`(`'custom'`)。`custom` 只是派生值:客户端可以把它显示为当前值,但它绝不是切换目标,也绝不出现在事件 payload 中。
52
+
53
+ `names` 按预设表声明顺序列出可切换的预设;`optionOf(name)` 为某个表键(label 回退为该键)或 `custom` 构建客户端渲染的选项,传入其他任何名称都会抛出异常。
54
+
55
+ ```ts type-equiv
56
+ /** The select-option shape a presentation layer advertises for one preset (or for the derived `custom` state). */
57
+ interface PresetOption {
58
+ /** Stable option value: the table key, or `custom`. */
59
+ value: string
60
+ /** The display label. */
61
+ name: string
62
+ /** One user-facing sentence on what the value means; omitted when not configured. */
63
+ description?: string
64
+ }
65
+ ```
66
+
67
+ ## 切换与 `permission/preset` 事件
68
+
69
+ `set(session, name)` 解析预设(未知名称抛出异常),在 `name` 尚不是生效预设时追加一条仅记日志的 `permission/preset` 事件,然后通过各旋钮自己的 setter([dsh-sandbox-policy](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/sandbox/sandbox-policy) 的 `setSandboxMode` 与 [dsh-user-approval](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/interaction/user-approval) 的 `setApprovalPolicy`)写入,且仅当该 knob的生效值发生变化时才写。同一轮次内,选择事件先于旋钮事件出现;重新选择当前生效的预设则什么都不追加。
70
+
71
+ `permission/preset` 是持久、仅记日志的用户意图:它不进入模型 transcript(文本记录),模型可见的后果由 knob 事件经各自消费方承担;它存在是为了在两个预设共享同一个旋钮组合时,让 `current()` 仍能保住用户选择的究竟是哪一个预设;`effectivePermissionPreset(events)` 折叠最后一条,回放不需要任何追赶状态。完整事件声明见[持久化日志事件目录](../persistence-catalog.md);方法签名见生成的[服务目录](#ctxpermissionpresets--permissionpresetservice)。
72
+
73
+ <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
74
+
75
+ <a id="cordis-surface"></a>
76
+
77
+ ## Cordis API
78
+
79
+ 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`) — this section is byte-identical in both language sides of the page. 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).
80
+
81
+ <a id="ctxpermissionpresets--permissionpresetservice"></a>
82
+
83
+ ### `ctx.permissionPresets` — `PermissionPresetService`
84
+
85
+ Owns the deployment's permission presets and their write path. Requires a confining `ctx.shell` executor and `ctx.approval`; unmatched knob values are reported as CUSTOM_PRESET, not an error.
86
+
87
+ ```ts cordis-catalog
88
+ /**
89
+ * Resolve the preset matching the effective knob values. A still-matching
90
+ * last selection wins shared-bundle ties; otherwise the first table match
91
+ * wins, or {@link CUSTOM_PRESET} when no entry matches.
92
+ * @param events - the session's events in log order.
93
+ * @returns the effective preset name, or `custom` when nothing matches.
94
+ */
95
+ current(events: readonly SessionEvent[]): string
96
+
97
+ /**
98
+ * Build the whole select value for one folded knob state: every table
99
+ * option in declaration order, `custom` appended exactly while derived.
100
+ * @param state - the folded knob overrides.
101
+ * @returns the `permissions` projection payload.
102
+ */
103
+ selectFor(state: KnobState): PermissionSelect
104
+
105
+ /**
106
+ * Resolve a preset's knob bundle.
107
+ * @param name - the preset name to resolve.
108
+ * @returns the configured bundle.
109
+ * @throws when `name` is not in the table.
110
+ */
111
+ resolve(name: string): PresetSpec
112
+
113
+ /**
114
+ * Build the client option for a table entry or {@link CUSTOM_PRESET}. A
115
+ * missing label falls back to the table key.
116
+ * @param name - a table key, or `custom`.
117
+ * @returns the option a client renders.
118
+ * @throws when `name` is neither a table key nor `custom`.
119
+ */
120
+ optionOf(name: string): PresetOption
121
+
122
+ /**
123
+ * Record a changed preset, then update each changed knob through its own
124
+ * setter. Selecting the effective preset again appends nothing.
125
+ * @param session - the session the switch belongs to.
126
+ * @param name - the preset to switch to; unknown names throw.
127
+ */
128
+ set(session: Session, name: string): void
129
+ ```
130
+
131
+ Types: [Session](./session.md) · [SessionEvent](./session.md)
132
+
133
+ Source: [`packages/interaction/permission-presets/src/index.ts:159`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/permission-presets/src/index.ts)
134
+ <!-- END GENERATED cordis-surface -->