dsh-agent-plugins-market 0.9.0 → 0.9.2

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 (358) hide show
  1. package/README.md +64 -154
  2. package/README.zh.md +74 -164
  3. package/assets/dsh-agent-plugins.png +0 -0
  4. package/client/client.js +5371 -1085
  5. package/client/client.js.map +1 -1
  6. package/lib/index.js +2 -257
  7. package/lib/{application → packages/market-bundle/src/application}/catalog.js +207 -41
  8. package/lib/{application → packages/market-bundle/src/application}/details.js +73 -29
  9. package/lib/packages/market-bundle/src/application/extension-inventory.js +408 -0
  10. package/lib/packages/market-bundle/src/application/extension-project.js +64 -0
  11. package/lib/packages/market-bundle/src/application/resource-inventory.js +96 -0
  12. package/lib/packages/market-bundle/src/application/server-config.js +9 -0
  13. package/lib/packages/market-bundle/src/application/suite-queries.js +86 -0
  14. package/lib/packages/market-bundle/src/index.js +372 -0
  15. package/lib/{runtime/host → packages/market-bundle/src/platform}/feedback-tool.js +2 -2
  16. package/lib/{runtime/host → packages/market-bundle/src/platform}/settings-namespace.js +55 -7
  17. package/lib/packages/market-bundle/src/platform/settings-schema.js +25 -0
  18. package/lib/packages/market-bundle/src/routes-extension-presets.js +161 -0
  19. package/lib/packages/market-bundle/src/routes-resources.js +127 -0
  20. package/lib/{routes.js → packages/market-bundle/src/routes.js} +225 -21
  21. package/lib/packages/market-bundle/src/runtime-adapters.js +57 -0
  22. package/lib/packages/market-bundle/src/session-extension.js +337 -0
  23. package/lib/{application → packages/market-catalog/src/application}/catalog-context.js +7 -4
  24. package/lib/{application → packages/market-catalog/src/application}/install-store.js +3 -3
  25. package/lib/{application → packages/market-catalog/src/application}/snapshot-cache.js +100 -11
  26. package/lib/{application → packages/market-catalog/src/application}/source-store.js +24 -11
  27. package/lib/{application → packages/market-catalog/src/application}/state/state-store.js +1 -1
  28. package/lib/{application → packages/market-catalog/src/application}/state/storage-migration.js +1 -1
  29. package/lib/packages/market-catalog/src/index.js +19 -0
  30. package/lib/{catalog → packages/market-catalog/src/scanning}/archive.js +1 -1
  31. package/lib/{catalog → packages/market-catalog/src/scanning}/codex-mcp.js +1 -1
  32. package/lib/{catalog → packages/market-catalog/src/scanning}/component-files.js +2 -2
  33. package/lib/{catalog → packages/market-catalog/src/scanning}/manifests.js +2 -2
  34. package/lib/{catalog → packages/market-catalog/src/scanning}/native-project.js +1 -1
  35. package/lib/{catalog → packages/market-catalog/src/scanning}/paths.js +1 -1
  36. package/lib/{catalog → packages/market-catalog/src/scanning}/plugin-variables.js +21 -1
  37. package/lib/{catalog → packages/market-catalog/src/scanning}/scan-resolvers.js +35 -2
  38. package/lib/{catalog → packages/market-catalog/src/scanning}/skills-parse.js +40 -10
  39. package/lib/{catalog → packages/market-catalog/src/scanning}/validate.js +15 -2
  40. package/lib/packages/market-contracts/src/contracts/extension-presets.js +125 -0
  41. package/lib/{contracts → packages/market-contracts/src/contracts}/market.js +33 -5
  42. package/lib/packages/market-contracts/src/contracts/mcp-overrides.js +2 -0
  43. package/lib/packages/market-contracts/src/contracts/resource-window.js +29 -0
  44. package/lib/packages/market-contracts/src/contracts/settings.js +130 -0
  45. package/lib/packages/market-contracts/src/contracts/surface-toggles.js +29 -0
  46. package/lib/packages/market-contracts/src/contracts/translation.js +28 -0
  47. package/lib/packages/market-contracts/src/index.js +4 -0
  48. package/lib/{model → packages/market-contracts/src/model}/layouts.js +11 -0
  49. package/lib/{application → packages/market-contracts/src/ports}/ports.js +3 -0
  50. package/lib/{application/mcp/mcp-redaction.js → packages/market-contracts/src/redaction.js} +17 -1
  51. package/lib/{application → packages/market-lsp/src/application}/lsp/lsp-direct-config.js +2 -2
  52. package/lib/{application → packages/market-lsp/src/application}/lsp/lsp-server-state.js +1 -1
  53. package/lib/{application → packages/market-lsp/src/application}/lsp/lsp-status.js +20 -3
  54. package/lib/{application → packages/market-lsp/src/application}/lsp/profile-seam.js +1 -1
  55. package/lib/packages/market-lsp/src/application/lsp/validation.js +46 -0
  56. package/lib/{application → packages/market-lsp/src/application}/lsp-service.js +61 -3
  57. package/lib/packages/market-lsp/src/index.js +8 -0
  58. package/lib/{runtime → packages/market-lsp/src/runtime}/lsp/lsp-mounts.js +79 -40
  59. package/lib/{application → packages/market-mcp/src/application}/mcp/mcp-backend.js +0 -16
  60. package/lib/{application → packages/market-mcp/src/application}/mcp/mcp-config.js +104 -21
  61. package/lib/{application → packages/market-mcp/src/application}/mcp/mcp-direct-config.js +12 -4
  62. package/lib/{application → packages/market-mcp/src/application}/mcp/mcp-overrides.js +4 -4
  63. package/lib/{application → packages/market-mcp/src/application}/mcp/mcp-status.js +49 -10
  64. package/lib/packages/market-mcp/src/application/mcp/validation.js +63 -0
  65. package/lib/{application → packages/market-mcp/src/application}/mcp-service.js +111 -91
  66. package/lib/packages/market-mcp/src/index.js +10 -0
  67. package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/bridge.js +12 -9
  68. package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/connection.js +1 -1
  69. package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/oauth.js +1 -1
  70. package/lib/packages/market-mcp/src/runtime/mcp/bridge/tool-ownership.js +26 -0
  71. package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/tools.js +1 -1
  72. package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/mcp-auth-record.js +35 -4
  73. package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/mcp-mounts.js +35 -4
  74. package/lib/packages/market-runtime/src/adapter-contracts.js +1 -0
  75. package/lib/packages/market-runtime/src/application/command-resources.js +74 -0
  76. package/lib/packages/market-runtime/src/application/extension-authorization.js +27 -0
  77. package/lib/packages/market-runtime/src/application/extension-hook-selection.js +56 -0
  78. package/lib/packages/market-runtime/src/application/extension-suite-declarations.js +57 -0
  79. package/lib/packages/market-runtime/src/application/extension-suite-selection.js +84 -0
  80. package/lib/packages/market-runtime/src/application/fs-probe.js +43 -0
  81. package/lib/packages/market-runtime/src/application/panel-resources.js +370 -0
  82. package/lib/{application → packages/market-runtime/src/application}/panels/user-hooks.js +2 -2
  83. package/lib/{application → packages/market-runtime/src/application}/panels/user-store.js +53 -13
  84. package/lib/{application → packages/market-runtime/src/application}/project-agent-roles.js +20 -11
  85. package/lib/packages/market-runtime/src/application/state/extension-presets.js +144 -0
  86. package/lib/packages/market-runtime/src/application/state/resource-favorites.js +90 -0
  87. package/lib/packages/market-runtime/src/application/state/resource-filters.js +2 -0
  88. package/lib/packages/market-runtime/src/application/state/surface-toggles.js +10 -0
  89. package/lib/packages/market-runtime/src/application/state/workspace-policy.js +56 -0
  90. package/lib/packages/market-runtime/src/catalog-port.js +1 -0
  91. package/lib/packages/market-runtime/src/extension-service.js +1 -0
  92. package/lib/packages/market-runtime/src/index.js +31 -0
  93. package/lib/{runtime → packages/market-runtime/src/runtime}/agents/agent-role-router.js +74 -79
  94. package/lib/packages/market-runtime/src/runtime/agents/agent-teams-seat.js +58 -0
  95. package/lib/{runtime → packages/market-runtime/src/runtime}/agents/subagent-catalog.js +89 -21
  96. package/lib/packages/market-runtime/src/runtime/agents/team-coordination.js +51 -0
  97. package/lib/packages/market-runtime/src/runtime/agents/teammate-role-runtime.js +241 -0
  98. package/lib/packages/market-runtime/src/runtime/agents/teammate-role-tool.js +130 -0
  99. package/lib/{runtime → packages/market-runtime/src/runtime}/core/reconcile-scheduler.js +2 -2
  100. package/lib/packages/market-runtime/src/runtime/core/reconciler.js +457 -0
  101. package/lib/packages/market-runtime/src/runtime/host/command-name-allocator.js +168 -0
  102. package/lib/packages/market-runtime/src/runtime/host/extension-progress.js +120 -0
  103. package/lib/packages/market-runtime/src/runtime/host/extension-runtime.js +405 -0
  104. package/lib/packages/market-runtime/src/runtime/host/extension-session-state.js +839 -0
  105. package/lib/packages/market-runtime/src/runtime/host/extension-tool-gates.js +96 -0
  106. package/lib/{runtime → packages/market-runtime/src/runtime}/host/failure-detail.js +1 -1
  107. package/lib/{runtime → packages/market-runtime/src/runtime}/host/host-locale.js +2 -0
  108. package/lib/packages/market-runtime/src/runtime/host/menu-row-identities.js +38 -0
  109. package/lib/packages/market-runtime/src/runtime/host/resource-filter-service.js +81 -0
  110. package/lib/packages/market-runtime/src/runtime/host/scoped-contributors.js +304 -0
  111. package/lib/packages/market-runtime/src/runtime/host/surface-toggle-service.js +15 -0
  112. package/lib/packages/market-runtime/src/runtime/panels/user-commands.js +211 -0
  113. package/lib/{runtime → packages/market-runtime/src/runtime}/panels/user-panels.js +34 -14
  114. package/lib/packages/market-runtime/src/runtime/surfaces/commands-mounts.js +256 -0
  115. package/lib/packages/market-runtime/src/runtime/surfaces/extension-hooks.js +294 -0
  116. package/lib/packages/market-runtime/src/runtime/surfaces/hook-dry-run.js +122 -0
  117. package/lib/{runtime → packages/market-runtime/src/runtime}/surfaces/hooks-mounts.js +1 -1
  118. package/lib/{runtime → packages/market-runtime/src/runtime}/surfaces/project-runtime.js +23 -13
  119. package/lib/packages/market-runtime/src/runtime/surfaces/skills-provider.js +241 -0
  120. package/lib/packages/market-translation/src/application/state/translation-cache.js +122 -0
  121. package/lib/packages/market-translation/src/application/translation/chain.js +99 -0
  122. package/lib/packages/market-translation/src/application/translation/document.js +384 -0
  123. package/lib/packages/market-translation/src/application/translation/localizer.js +642 -0
  124. package/lib/packages/market-translation/src/application/translation/service.js +113 -0
  125. package/lib/packages/market-translation/src/application/translation/unit.js +19 -0
  126. package/lib/packages/market-translation/src/index.js +4 -0
  127. package/lib/packages/market-translation/src/runtime/host/llm-translator.js +278 -0
  128. package/lib/packages/market-translation/src/runtime/host/machine-translator.js +152 -0
  129. package/lib/packages/market-translation/src/runtime/host/text-masking.js +96 -0
  130. package/lib/packages/market-translation/src/runtime/host/translation-providers.js +116 -0
  131. package/lib/types/index.d.ts +2 -130
  132. package/lib/types/{application → packages/market-bundle/src/application}/catalog.d.ts +117 -22
  133. package/lib/types/packages/market-bundle/src/application/details.d.ts +24 -0
  134. package/lib/types/packages/market-bundle/src/application/extension-inventory.d.ts +45 -0
  135. package/lib/types/packages/market-bundle/src/application/extension-project.d.ts +26 -0
  136. package/lib/types/packages/market-bundle/src/application/resource-inventory.d.ts +42 -0
  137. package/lib/types/packages/market-bundle/src/application/server-config.d.ts +9 -0
  138. package/lib/types/packages/market-bundle/src/application/suite-queries.d.ts +84 -0
  139. package/lib/types/packages/market-bundle/src/index.d.ts +125 -0
  140. package/lib/types/{runtime/host → packages/market-bundle/src/platform}/settings-namespace.d.ts +44 -9
  141. package/lib/types/{application/mcp/mcp-backend.d.ts → packages/market-bundle/src/platform/settings-schema.d.ts} +13 -28
  142. package/lib/types/packages/market-bundle/src/routes-extension-presets.d.ts +15 -0
  143. package/lib/types/packages/market-bundle/src/routes-resources.d.ts +17 -0
  144. package/lib/types/packages/market-bundle/src/routes.d.ts +32 -0
  145. package/lib/types/packages/market-bundle/src/runtime-adapters.d.ts +42 -0
  146. package/lib/types/packages/market-bundle/src/session-extension.d.ts +62 -0
  147. package/lib/types/{application → packages/market-catalog/src/application}/catalog-context.d.ts +11 -3
  148. package/lib/types/{application → packages/market-catalog/src/application}/install-store.d.ts +1 -1
  149. package/lib/types/{application → packages/market-catalog/src/application}/regions.d.ts +1 -1
  150. package/lib/types/{application → packages/market-catalog/src/application}/snapshot-cache.d.ts +44 -2
  151. package/lib/types/{application → packages/market-catalog/src/application}/source-store.d.ts +12 -3
  152. package/lib/types/{application → packages/market-catalog/src/application}/state/state-store.d.ts +1 -1
  153. package/lib/types/packages/market-catalog/src/index.d.ts +22 -0
  154. package/lib/types/{catalog → packages/market-catalog/src/scanning}/archive.d.ts +1 -1
  155. package/lib/types/{catalog → packages/market-catalog/src/scanning}/codex-mcp.d.ts +1 -1
  156. package/lib/types/{catalog → packages/market-catalog/src/scanning}/component-files.d.ts +1 -1
  157. package/lib/types/{catalog → packages/market-catalog/src/scanning}/lsp-spec.d.ts +1 -1
  158. package/lib/types/{catalog → packages/market-catalog/src/scanning}/manifests.d.ts +3 -3
  159. package/lib/types/{catalog → packages/market-catalog/src/scanning}/native-project.d.ts +2 -2
  160. package/lib/types/{catalog → packages/market-catalog/src/scanning}/plugin-variables.d.ts +12 -1
  161. package/lib/types/{catalog → packages/market-catalog/src/scanning}/project-config.d.ts +2 -2
  162. package/lib/types/{catalog → packages/market-catalog/src/scanning}/project-hooks.d.ts +2 -2
  163. package/lib/types/{catalog → packages/market-catalog/src/scanning}/scan-pipeline.d.ts +1 -1
  164. package/lib/types/{catalog → packages/market-catalog/src/scanning}/scan-resolvers.d.ts +3 -3
  165. package/lib/types/{catalog → packages/market-catalog/src/scanning}/source-catalog.d.ts +1 -1
  166. package/lib/types/{catalog → packages/market-catalog/src/scanning}/suite-components.d.ts +1 -1
  167. package/lib/types/{catalog → packages/market-catalog/src/scanning}/suite-scanner.d.ts +1 -1
  168. package/lib/types/{catalog → packages/market-catalog/src/scanning}/surfaces.d.ts +1 -1
  169. package/lib/types/{catalog → packages/market-catalog/src/scanning}/validate.d.ts +1 -1
  170. package/lib/types/packages/market-contracts/src/contracts/extension-presets.d.ts +237 -0
  171. package/lib/types/{contracts → packages/market-contracts/src/contracts}/market.d.ts +87 -16
  172. package/lib/types/packages/market-contracts/src/contracts/mcp-overrides.d.ts +39 -0
  173. package/lib/types/{contracts → packages/market-contracts/src/contracts}/mcp-status.d.ts +9 -0
  174. package/lib/types/packages/market-contracts/src/contracts/resource-window.d.ts +70 -0
  175. package/lib/types/packages/market-contracts/src/contracts/settings.d.ts +121 -0
  176. package/lib/types/packages/market-contracts/src/contracts/surface-toggles.d.ts +28 -0
  177. package/lib/types/packages/market-contracts/src/contracts/translation.d.ts +81 -0
  178. package/lib/types/{runtime → packages/market-contracts/src}/host/plugin-message-source.d.ts +1 -1
  179. package/lib/types/packages/market-contracts/src/index.d.ts +5 -0
  180. package/lib/types/{model → packages/market-contracts/src/model}/layouts.d.ts +7 -0
  181. package/lib/types/{model → packages/market-contracts/src/model}/types.d.ts +2 -2
  182. package/lib/types/packages/market-contracts/src/ports/ports.d.ts +183 -0
  183. package/lib/types/{application → packages/market-contracts/src/ports}/queries.d.ts +27 -6
  184. package/lib/types/{application/mcp/mcp-redaction.d.ts → packages/market-contracts/src/redaction.d.ts} +2 -0
  185. package/lib/types/{application → packages/market-lsp/src/application}/lsp/lsp-direct-config.d.ts +1 -1
  186. package/lib/types/{application → packages/market-lsp/src/application}/lsp/lsp-status.d.ts +21 -5
  187. package/lib/types/packages/market-lsp/src/application/lsp/validation.d.ts +8 -0
  188. package/lib/types/{application → packages/market-lsp/src/application}/lsp-service.d.ts +19 -6
  189. package/lib/types/packages/market-lsp/src/index.d.ts +8 -0
  190. package/lib/types/{runtime → packages/market-lsp/src/runtime}/lsp/lsp-mounts.d.ts +26 -6
  191. package/lib/types/packages/market-mcp/src/application/mcp/mcp-backend.d.ts +28 -0
  192. package/lib/types/{application → packages/market-mcp/src/application}/mcp/mcp-bridge-config.d.ts +1 -1
  193. package/lib/types/{application → packages/market-mcp/src/application}/mcp/mcp-config.d.ts +2 -2
  194. package/lib/types/{application → packages/market-mcp/src/application}/mcp/mcp-direct-config.d.ts +6 -1
  195. package/lib/types/{application → packages/market-mcp/src/application}/mcp/mcp-overrides.d.ts +4 -38
  196. package/lib/types/packages/market-mcp/src/application/mcp/mcp-status.d.ts +40 -0
  197. package/lib/types/{application/server-config.d.ts → packages/market-mcp/src/application/mcp/validation.d.ts} +2 -10
  198. package/lib/types/{application → packages/market-mcp/src/application}/mcp-service.d.ts +22 -16
  199. package/lib/types/packages/market-mcp/src/index.d.ts +12 -0
  200. package/lib/types/packages/market-mcp/src/runtime/mcp/bridge/tool-ownership.d.ts +14 -0
  201. package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/mcp-auth-record.d.ts +4 -0
  202. package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/mcp-mounts.d.ts +19 -3
  203. package/lib/types/packages/market-runtime/src/adapter-contracts.d.ts +89 -0
  204. package/lib/types/{application → packages/market-runtime/src/application}/agent-roles.d.ts +2 -0
  205. package/lib/types/packages/market-runtime/src/application/command-resources.d.ts +26 -0
  206. package/lib/types/packages/market-runtime/src/application/extension-authorization.d.ts +12 -0
  207. package/lib/types/packages/market-runtime/src/application/extension-hook-selection.d.ts +23 -0
  208. package/lib/types/packages/market-runtime/src/application/extension-suite-declarations.d.ts +10 -0
  209. package/lib/types/packages/market-runtime/src/application/extension-suite-selection.d.ts +30 -0
  210. package/lib/types/packages/market-runtime/src/application/fs-probe.d.ts +12 -0
  211. package/lib/types/packages/market-runtime/src/application/panel-resources.d.ts +100 -0
  212. package/lib/types/{application → packages/market-runtime/src/application}/panels/user-hooks.d.ts +1 -1
  213. package/lib/types/packages/market-runtime/src/application/project-agent-roles.d.ts +10 -0
  214. package/lib/types/packages/market-runtime/src/application/state/extension-presets.d.ts +24 -0
  215. package/lib/types/packages/market-runtime/src/application/state/resource-favorites.d.ts +9 -0
  216. package/lib/types/packages/market-runtime/src/application/state/resource-filters.d.ts +2 -0
  217. package/lib/types/packages/market-runtime/src/application/state/surface-toggles.d.ts +6 -0
  218. package/lib/types/packages/market-runtime/src/application/state/workspace-policy.d.ts +19 -0
  219. package/lib/types/packages/market-runtime/src/catalog-port.d.ts +30 -0
  220. package/lib/types/packages/market-runtime/src/extension-service.d.ts +14 -0
  221. package/lib/types/packages/market-runtime/src/index.d.ts +41 -0
  222. package/lib/types/{runtime → packages/market-runtime/src/runtime}/agents/agent-role-router.d.ts +66 -31
  223. package/lib/types/packages/market-runtime/src/runtime/agents/agent-teams-seat.d.ts +41 -0
  224. package/lib/types/{runtime → packages/market-runtime/src/runtime}/agents/subagent-catalog.d.ts +34 -2
  225. package/lib/types/packages/market-runtime/src/runtime/agents/team-coordination.d.ts +8 -0
  226. package/lib/types/packages/market-runtime/src/runtime/agents/teammate-role-runtime.d.ts +74 -0
  227. package/lib/types/packages/market-runtime/src/runtime/agents/teammate-role-tool.d.ts +6 -0
  228. package/lib/types/{runtime → packages/market-runtime/src/runtime}/core/reconcile-scheduler.d.ts +5 -2
  229. package/lib/types/packages/market-runtime/src/runtime/core/reconciler.d.ts +141 -0
  230. package/lib/types/packages/market-runtime/src/runtime/host/command-name-allocator.d.ts +132 -0
  231. package/lib/types/packages/market-runtime/src/runtime/host/extension-progress.d.ts +91 -0
  232. package/lib/types/packages/market-runtime/src/runtime/host/extension-runtime.d.ts +77 -0
  233. package/lib/types/packages/market-runtime/src/runtime/host/extension-session-state.d.ts +242 -0
  234. package/lib/types/packages/market-runtime/src/runtime/host/extension-tool-gates.d.ts +38 -0
  235. package/lib/types/{runtime → packages/market-runtime/src/runtime}/host/host-locale.d.ts +1 -1
  236. package/lib/types/packages/market-runtime/src/runtime/host/menu-row-identities.d.ts +50 -0
  237. package/lib/types/{runtime → packages/market-runtime/src/runtime}/host/model-catalog.d.ts +1 -1
  238. package/lib/types/packages/market-runtime/src/runtime/host/resource-filter-service.d.ts +34 -0
  239. package/lib/types/packages/market-runtime/src/runtime/host/scoped-contributors.d.ts +58 -0
  240. package/lib/types/packages/market-runtime/src/runtime/host/surface-toggle-service.d.ts +10 -0
  241. package/lib/types/packages/market-runtime/src/runtime/panels/user-commands.d.ts +74 -0
  242. package/lib/types/{runtime → packages/market-runtime/src/runtime}/panels/user-panels.d.ts +7 -1
  243. package/lib/types/packages/market-runtime/src/runtime/surfaces/commands-mounts.d.ts +81 -0
  244. package/lib/types/packages/market-runtime/src/runtime/surfaces/extension-hooks.d.ts +59 -0
  245. package/lib/types/packages/market-runtime/src/runtime/surfaces/hook-dry-run.d.ts +91 -0
  246. package/lib/types/{runtime → packages/market-runtime/src/runtime}/surfaces/hooks-mounts.d.ts +1 -1
  247. package/lib/types/{runtime → packages/market-runtime/src/runtime}/surfaces/project-runtime.d.ts +8 -5
  248. package/lib/types/packages/market-runtime/src/runtime/surfaces/skills-provider.d.ts +71 -0
  249. package/lib/types/packages/market-translation/src/application/state/translation-cache.d.ts +56 -0
  250. package/lib/types/packages/market-translation/src/application/translation/chain.d.ts +47 -0
  251. package/lib/types/packages/market-translation/src/application/translation/document.d.ts +54 -0
  252. package/lib/types/packages/market-translation/src/application/translation/localizer.d.ts +325 -0
  253. package/lib/types/packages/market-translation/src/application/translation/service.d.ts +89 -0
  254. package/lib/types/packages/market-translation/src/application/translation/unit.d.ts +35 -0
  255. package/lib/types/packages/market-translation/src/index.d.ts +4 -0
  256. package/lib/types/packages/market-translation/src/runtime/host/llm-translator.d.ts +30 -0
  257. package/lib/types/packages/market-translation/src/runtime/host/machine-translator.d.ts +52 -0
  258. package/lib/types/packages/market-translation/src/runtime/host/text-masking.d.ts +42 -0
  259. package/lib/types/packages/market-translation/src/runtime/host/translation-providers.d.ts +42 -0
  260. package/locale/en.json +6 -0
  261. package/locale/zh.json +6 -0
  262. package/package.json +47 -10
  263. package/schemas/README.md +4 -4
  264. package/schemas/agent-plugins/spec.md +2 -2
  265. package/schemas/com.deepseek.harness/spec.md +1 -1
  266. package/schemas/skill-collection/spec.md +10 -2
  267. package/lib/application/panel-resources.js +0 -161
  268. package/lib/application/server-config.js +0 -109
  269. package/lib/contracts/settings.js +0 -63
  270. package/lib/runtime/core/reconciler.js +0 -100
  271. package/lib/runtime/panels/user-commands.js +0 -105
  272. package/lib/runtime/surfaces/commands-mounts.js +0 -186
  273. package/lib/runtime/surfaces/skills-provider.js +0 -160
  274. package/lib/types/application/details.d.ts +0 -7
  275. package/lib/types/application/mcp/mcp-status.d.ts +0 -24
  276. package/lib/types/application/panel-resources.d.ts +0 -28
  277. package/lib/types/application/ports.d.ts +0 -86
  278. package/lib/types/application/project-agent-roles.d.ts +0 -3
  279. package/lib/types/contracts/settings.d.ts +0 -59
  280. package/lib/types/routes.d.ts +0 -16
  281. package/lib/types/runtime/core/reconciler.d.ts +0 -58
  282. package/lib/types/runtime/panels/user-commands.d.ts +0 -27
  283. package/lib/types/runtime/surfaces/commands-mounts.d.ts +0 -48
  284. package/lib/types/runtime/surfaces/skills-provider.d.ts +0 -23
  285. /package/lib/{application → packages/market-catalog/src/application}/deadline.js +0 -0
  286. /package/lib/{application → packages/market-catalog/src/application}/json-file.js +0 -0
  287. /package/lib/{application → packages/market-catalog/src/application}/regions.js +0 -0
  288. /package/lib/{catalog → packages/market-catalog/src/scanning}/fs-probes.js +0 -0
  289. /package/lib/{catalog → packages/market-catalog/src/scanning}/git.js +0 -0
  290. /package/lib/{catalog → packages/market-catalog/src/scanning}/lsp-spec.js +0 -0
  291. /package/lib/{catalog → packages/market-catalog/src/scanning}/project-config.js +0 -0
  292. /package/lib/{catalog → packages/market-catalog/src/scanning}/project-hooks.js +0 -0
  293. /package/lib/{catalog → packages/market-catalog/src/scanning}/scan-pipeline.js +0 -0
  294. /package/lib/{catalog → packages/market-catalog/src/scanning}/source-catalog.js +0 -0
  295. /package/lib/{catalog → packages/market-catalog/src/scanning}/suite-components.js +0 -0
  296. /package/lib/{catalog → packages/market-catalog/src/scanning}/suite-scanner.js +0 -0
  297. /package/lib/{catalog → packages/market-catalog/src/scanning}/surfaces.js +0 -0
  298. /package/lib/{contracts → packages/market-contracts/src/contracts}/lsp-status.js +0 -0
  299. /package/lib/{contracts → packages/market-contracts/src/contracts}/lsp.js +0 -0
  300. /package/lib/{contracts → packages/market-contracts/src/contracts}/mcp-status.js +0 -0
  301. /package/lib/{contracts → packages/market-contracts/src/contracts}/mcp.js +0 -0
  302. /package/lib/{runtime → packages/market-contracts/src}/host/plugin-message-source.js +0 -0
  303. /package/lib/{model → packages/market-contracts/src/model}/command-names.js +0 -0
  304. /package/lib/{model → packages/market-contracts/src/model}/preset-source.js +0 -0
  305. /package/lib/{model → packages/market-contracts/src/model}/types.js +0 -0
  306. /package/lib/{application → packages/market-contracts/src/ports}/queries.js +0 -0
  307. /package/lib/{application → packages/market-mcp/src/application}/mcp/mcp-bridge-config.js +0 -0
  308. /package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/host-contract.js +0 -0
  309. /package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/host-seams.js +0 -0
  310. /package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/plugin-identity.js +0 -0
  311. /package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/projection.js +0 -0
  312. /package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/transport.js +0 -0
  313. /package/lib/{runtime → packages/market-mcp/src/runtime}/mcp/mcp-credentials.js +0 -0
  314. /package/lib/{application → packages/market-runtime/src/application}/agent-roles.js +0 -0
  315. /package/lib/{runtime → packages/market-runtime/src/runtime}/agents/agent-role-names.js +0 -0
  316. /package/lib/{runtime → packages/market-runtime/src/runtime}/core/context.js +0 -0
  317. /package/lib/{runtime → packages/market-runtime/src/runtime}/core/mount-lifecycle.js +0 -0
  318. /package/lib/{runtime → packages/market-runtime/src/runtime}/core/source-auto-update.js +0 -0
  319. /package/lib/{runtime → packages/market-runtime/src/runtime}/core/timer-seat.js +0 -0
  320. /package/lib/{runtime → packages/market-runtime/src/runtime}/host/model-catalog.js +0 -0
  321. /package/lib/{runtime → packages/market-runtime/src/runtime}/host/shell-path.js +0 -0
  322. /package/lib/{runtime → packages/market-runtime/src/runtime}/host/tool-registry-observer.js +0 -0
  323. /package/lib/{runtime → packages/market-runtime/src/runtime}/surfaces/dynamic-context.js +0 -0
  324. /package/lib/types/{runtime/host → packages/market-bundle/src/platform}/feedback-tool.d.ts +0 -0
  325. /package/lib/types/{application → packages/market-catalog/src/application}/deadline.d.ts +0 -0
  326. /package/lib/types/{application → packages/market-catalog/src/application}/json-file.d.ts +0 -0
  327. /package/lib/types/{application → packages/market-catalog/src/application}/state/storage-migration.d.ts +0 -0
  328. /package/lib/types/{catalog → packages/market-catalog/src/scanning}/fs-probes.d.ts +0 -0
  329. /package/lib/types/{catalog → packages/market-catalog/src/scanning}/git.d.ts +0 -0
  330. /package/lib/types/{catalog → packages/market-catalog/src/scanning}/paths.d.ts +0 -0
  331. /package/lib/types/{catalog → packages/market-catalog/src/scanning}/skills-parse.d.ts +0 -0
  332. /package/lib/types/{contracts → packages/market-contracts/src/contracts}/lsp-status.d.ts +0 -0
  333. /package/lib/types/{contracts → packages/market-contracts/src/contracts}/lsp.d.ts +0 -0
  334. /package/lib/types/{contracts → packages/market-contracts/src/contracts}/mcp.d.ts +0 -0
  335. /package/lib/types/{model → packages/market-contracts/src/model}/command-names.d.ts +0 -0
  336. /package/lib/types/{model → packages/market-contracts/src/model}/preset-source.d.ts +0 -0
  337. /package/lib/types/{application → packages/market-lsp/src/application}/lsp/lsp-server-state.d.ts +0 -0
  338. /package/lib/types/{application → packages/market-lsp/src/application}/lsp/profile-seam.d.ts +0 -0
  339. /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/bridge.d.ts +0 -0
  340. /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/connection.d.ts +0 -0
  341. /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/host-contract.d.ts +0 -0
  342. /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/host-seams.d.ts +0 -0
  343. /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/oauth.d.ts +0 -0
  344. /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/plugin-identity.d.ts +0 -0
  345. /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/projection.d.ts +0 -0
  346. /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/tools.d.ts +0 -0
  347. /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/bridge/transport.d.ts +0 -0
  348. /package/lib/types/{runtime → packages/market-mcp/src/runtime}/mcp/mcp-credentials.d.ts +0 -0
  349. /package/lib/types/{application → packages/market-runtime/src/application}/panels/user-store.d.ts +0 -0
  350. /package/lib/types/{runtime → packages/market-runtime/src/runtime}/agents/agent-role-names.d.ts +0 -0
  351. /package/lib/types/{runtime → packages/market-runtime/src/runtime}/core/context.d.ts +0 -0
  352. /package/lib/types/{runtime → packages/market-runtime/src/runtime}/core/mount-lifecycle.d.ts +0 -0
  353. /package/lib/types/{runtime → packages/market-runtime/src/runtime}/core/source-auto-update.d.ts +0 -0
  354. /package/lib/types/{runtime → packages/market-runtime/src/runtime}/core/timer-seat.d.ts +0 -0
  355. /package/lib/types/{runtime → packages/market-runtime/src/runtime}/host/failure-detail.d.ts +0 -0
  356. /package/lib/types/{runtime → packages/market-runtime/src/runtime}/host/shell-path.d.ts +0 -0
  357. /package/lib/types/{runtime → packages/market-runtime/src/runtime}/host/tool-registry-observer.d.ts +0 -0
  358. /package/lib/types/{runtime → packages/market-runtime/src/runtime}/surfaces/dynamic-context.d.ts +0 -0
@@ -0,0 +1,211 @@
1
+ /**
2
+ * User command mounting: every enabled entry of the user commands panel
3
+ * registers as a dsh slash command, so user-authored quick replies behave
4
+ * exactly like suite commands — the body with `$ARGUMENTS` substituted rides
5
+ * one follow-up message on the receiving agent. A nested entry registers
6
+ * under its flattened call name (`git/commit` → `git-commit`) while the panel
7
+ * keeps addressing it by path; when two entries flatten to one call name the
8
+ * later one takes a numeric suffix (`git-commit-1`) and is reported, because a
9
+ * second registration of one name is what makes the host's slash menu drop it.
10
+ * Reconciled on every catalog change, keyed by the entry path.
11
+ * @module runtime/user-commands
12
+ */
13
+ import { createUserMessage } from '@deepseek-ai/dsh-llm';
14
+ import { commandCallName } from '../../../../market-contracts/src/model/command-names.js';
15
+ import { USER_ENTRY_PATH, parseFrontmatterRecord } from '../../application/panels/user-store.js';
16
+ import { pluginMarketSource } from '../../../../market-contracts/src/host/plugin-message-source.js';
17
+ import { CommandNameRegistry, registerWithAllocatedName } from '../host/command-name-allocator.js';
18
+ /** Render a thrown value for a diagnostic, without trusting its string coercion. */
19
+ function messageOf(error) {
20
+ return error instanceof Error ? error.message : String(error);
21
+ }
22
+ /** Register/unregister user-panel commands to match the panel's enabled entries. */
23
+ export class UserCommandMountRegistry {
24
+ ctx;
25
+ store;
26
+ t;
27
+ fingerprints = new Map();
28
+ live = new Map();
29
+ /**
30
+ * The call names this seat holds, and the entry each one was registered for.
31
+ *
32
+ * Occupancy is per layer, which is the unit the host checks: this registry
33
+ * registers into the global layer, so its names must be unique among
34
+ * themselves and against every other registration in that layer.
35
+ */
36
+ names = new CommandNameRegistry();
37
+ registeredName = new Map();
38
+ /** The menu row each live registration produces, with the panel id it translates as. */
39
+ registered = new Map();
40
+ /** Per-workspace entry filter; an absent provider registers everything wanted. */
41
+ entryFilter;
42
+ selectionPolicy;
43
+ registrationPolicy;
44
+ allowDisabled = false;
45
+ constructor(ctx, store, t) {
46
+ this.ctx = ctx;
47
+ this.store = store;
48
+ this.t = t;
49
+ }
50
+ /**
51
+ * Install the per-workspace entry filter read at wanted-row time, keyed by
52
+ * the panel path name the resource window lists (`commands:${entry.name}`).
53
+ */
54
+ setEntryFilter(filter) {
55
+ this.entryFilter = filter;
56
+ }
57
+ /** Gate reconcile and execution by the original panel path name; unset allows all. */
58
+ setSelectionPolicy(callback, registration = callback, options = {}) {
59
+ this.selectionPolicy = callback;
60
+ this.registrationPolicy = registration;
61
+ this.allowDisabled = options.allowDisabled === true;
62
+ }
63
+ /**
64
+ * Sync the live registrations with the panel's enabled entries.
65
+ *
66
+ * A switched-off commands surface reconciles against no entries at all,
67
+ * which unregisters whatever is live — skipping the pass would leave the
68
+ * previous registrations mounted after the switch went off.
69
+ * @param allow - whether the workspace's commands switch is on.
70
+ */
71
+ async reconcile(allow = true) {
72
+ const diagnostics = [];
73
+ const entries = allow ? await this.store.list() : [];
74
+ const wanted = new Map();
75
+ // Keyed by the entry path, not the call name: two entries that flatten to
76
+ // one call name are two commands, and the second gets a suffixed call name
77
+ // rather than replacing the first in the wanted map.
78
+ for (const entry of entries) {
79
+ if (entry.metadata['validationError'] !== undefined)
80
+ continue;
81
+ try {
82
+ parseFrontmatterRecord(entry.rawText);
83
+ }
84
+ catch {
85
+ continue;
86
+ }
87
+ if (entry.disabled && !(this.allowDisabled && this.registrationPolicy?.(entry.name) === true))
88
+ continue;
89
+ if (this.entryFilter?.().allows('commands', `commands:${entry.name}`) === false)
90
+ continue;
91
+ if (this.registrationPolicy?.(entry.name) === false)
92
+ continue;
93
+ if (!USER_ENTRY_PATH.test(entry.name))
94
+ continue;
95
+ wanted.set(entry.name, {
96
+ name: commandCallName(entry.name),
97
+ description: entry.description === '' ? `[${this.t('userCommandSourceLabel')}] ${commandCallName(entry.name)}` : `[${this.t('userCommandSourceLabel')}] ${entry.description}`,
98
+ ...(typeof entry.metadata['argument-hint'] === 'string' && entry.metadata['argument-hint'] !== '' ? { hint: entry.metadata['argument-hint'] } : {}),
99
+ body: entry.content
100
+ });
101
+ }
102
+ for (const [key, disposer] of [...this.live]) {
103
+ if (!wanted.has(key)) {
104
+ disposer();
105
+ this.live.delete(key);
106
+ this.fingerprints.delete(key);
107
+ this.releaseName(key);
108
+ }
109
+ }
110
+ const host = this.ctx;
111
+ const commands = host.commands;
112
+ if (typeof commands?.register !== 'function') {
113
+ if (wanted.size > 0)
114
+ diagnostics.push('ctx.commands is not available in this profile; user commands stay unregistered');
115
+ return diagnostics;
116
+ }
117
+ for (const [key, spec] of wanted) {
118
+ const fingerprint = JSON.stringify(spec);
119
+ if (this.live.has(key) && this.fingerprints.get(key) === fingerprint)
120
+ continue;
121
+ this.live.get(key)?.();
122
+ this.live.delete(key);
123
+ this.fingerprints.delete(key);
124
+ this.releaseName(key);
125
+ const attempt = registerWithAllocatedName(this.names, spec.name, name => commands.register({
126
+ name,
127
+ description: spec.description,
128
+ ...(spec.hint === undefined ? {} : { input: { hint: spec.hint } }),
129
+ handler: invocation => {
130
+ const agent = invocation.agent;
131
+ const send = (body) => {
132
+ if (this.selectionPolicy?.(key) === false)
133
+ return { kind: 'error', text: this.t('commandNotSelected', { command: name }) };
134
+ agent.followup(createUserMessage({
135
+ content: [{ type: 'text', text: body.replaceAll('$ARGUMENTS', invocation.rawInput.trim()) }],
136
+ source: pluginMarketSource()
137
+ }));
138
+ return { kind: 'success', text: this.t('commandAcknowledged', { command: name }) };
139
+ };
140
+ if (!this.selectionPolicy)
141
+ return send(spec.body);
142
+ return (async () => {
143
+ const denied = () => ({ kind: 'error', text: this.t('commandNotSelected', { command: name }) });
144
+ if (this.selectionPolicy?.(key) !== true)
145
+ return denied();
146
+ try {
147
+ const entry = await this.store.get(key);
148
+ if (!entry || entry.metadata['validationError'] !== undefined || (entry.disabled && !this.allowDisabled))
149
+ return denied();
150
+ parseFrontmatterRecord(entry.rawText);
151
+ if (this.selectionPolicy?.(key) !== true)
152
+ return denied();
153
+ return send(entry.content);
154
+ }
155
+ catch {
156
+ return denied();
157
+ }
158
+ })();
159
+ }
160
+ }));
161
+ if (attempt.kind === 'failed') {
162
+ diagnostics.push(`command "${spec.name}": ${messageOf(attempt.error)}`);
163
+ continue;
164
+ }
165
+ this.live.set(key, attempt.disposer);
166
+ this.fingerprints.set(key, fingerprint);
167
+ this.registeredName.set(key, attempt.name);
168
+ // The wanted map is keyed by the entry name the panel lists, which is also
169
+ // the id the panel translated that entry under — one spelling, one cache
170
+ // entry, so the menu shows the text the panel already paid for.
171
+ this.registered.set(key, { name: attempt.name, id: key });
172
+ // The panel addresses the entry by path, so a renamed registration is
173
+ // reported where the entry is listed rather than left to be discovered
174
+ // from the slash menu.
175
+ if (attempt.name !== spec.name) {
176
+ diagnostics.push(`command "${spec.name}": registered as "${attempt.name}" because the call name is already taken`);
177
+ }
178
+ }
179
+ return diagnostics;
180
+ }
181
+ /**
182
+ * Every command this seat currently holds: the call name the menu row carries
183
+ * and the panel identity that owns its translation.
184
+ *
185
+ * The registry is the only place that knows a name allocation suffixed, and a
186
+ * user entry's panel identity is the entry name the panel lists.
187
+ * @returns one row per live registration, in registration-key order.
188
+ */
189
+ registrations() {
190
+ return [...this.registered.values()];
191
+ }
192
+ /** Dispose every registration (plugin teardown). */
193
+ disposeAll() {
194
+ for (const disposer of [...this.live.values()])
195
+ disposer();
196
+ for (const key of [...this.registeredName.keys()])
197
+ this.releaseName(key);
198
+ this.registered.clear();
199
+ this.live.clear();
200
+ this.fingerprints.clear();
201
+ }
202
+ /** Free the call name one unmounted entry held, so a later claim can reuse it. */
203
+ releaseName(key) {
204
+ const name = this.registeredName.get(key);
205
+ if (name === undefined)
206
+ return;
207
+ this.names.forget(name);
208
+ this.registeredName.delete(key);
209
+ this.registered.delete(key);
210
+ }
211
+ }
@@ -30,7 +30,7 @@
30
30
  * @module runtime/user-panels
31
31
  */
32
32
  import { dirname } from 'node:path';
33
- import { skillEntryRejection } from '../../catalog/skills-parse.js';
33
+ import { skillEntryRejection } from '../../../../market-catalog/src/index.js';
34
34
  import { deleteEntryDocument, entryExists, listEntryDocuments, listEntryFiles, readEntryDocument, resolveEntryDocument, SKILL_ENTRY_SHAPES, USER_ENTRY_NAME, USER_ENTRY_PATH, userEntryDir, writeEntryDocument, writeEntryFile } from '../../application/panels/user-store.js';
35
35
  /** The skill-source label user-panel entries carry into the skill registry. */
36
36
  export const USER_PANEL_SKILL_SOURCE = 'user-panel';
@@ -43,9 +43,8 @@ export const USER_PANEL_SKILL_SOURCE = 'user-panel';
43
43
  * (450), so a skill the user wrote by hand wins over one an installed suite
44
44
  * ships under the same name.
45
45
  *
46
- * Switching a skill off is not this provider's job: the panel writes the
47
- * harness's own invocation pair into the document, which every reader of that
48
- * file honors.
46
+ * Global panel switches write the invocation pair into the document. A scoped
47
+ * selection policy overrides only that session and never writes the document.
49
48
  */
50
49
  const USER_PANEL_RANK = 440;
51
50
  /** Throwing CRUD over one panel directory, shared by the three panels. */
@@ -205,15 +204,33 @@ export function isUserSkillEntryName(name) {
205
204
  */
206
205
  export class UserPanelSkillProvider {
207
206
  skills;
207
+ options;
208
208
  name = 'user-panel';
209
- constructor(skills) {
209
+ constructor(skills, options = {}) {
210
210
  this.skills = skills;
211
+ this.options = options;
212
+ }
213
+ invocation(entry) {
214
+ if (!isUserSkillEntryName(entry.name) || entry.metadata['validationError'] !== undefined)
215
+ return undefined;
216
+ if (!this.options.enabled && entry.disabled)
217
+ return undefined;
218
+ const authored = {
219
+ modelInvocable: entry.metadata['disable-model-invocation'] !== true,
220
+ userInvocable: entry.metadata['user-invocable'] !== false
221
+ };
222
+ if (!this.options.enabled)
223
+ return authored;
224
+ if (!this.options.enabled(entry))
225
+ return { modelInvocable: false, userInvocable: false };
226
+ return !authored.modelInvocable && !authored.userInvocable ? { modelInvocable: true, userInvocable: true } : authored;
211
227
  }
212
228
  async list(_options) {
213
229
  const candidates = [];
214
230
  const skills = await this.skills.list();
215
231
  for (const entry of skills) {
216
- if (entry.disabled || !isUserSkillEntryName(entry.name))
232
+ const invocation = this.invocation(entry);
233
+ if (!invocation)
217
234
  continue;
218
235
  candidates.push({
219
236
  // The entry's name is the one its document declares, which is also the
@@ -224,10 +241,7 @@ export class UserPanelSkillProvider {
224
241
  // catalog a suite skill does.
225
242
  description: entry.description === '' ? entry.name : entry.description,
226
243
  ...(typeof entry.metadata['whenToUse'] === 'string' && entry.metadata['whenToUse'] !== '' ? { whenToUse: entry.metadata['whenToUse'] } : {}),
227
- invocation: {
228
- modelInvocable: entry.metadata['disable-model-invocation'] !== true,
229
- userInvocable: entry.metadata['user-invocable'] !== false
230
- },
244
+ invocation,
231
245
  source: USER_PANEL_SKILL_SOURCE,
232
246
  provider: this.name,
233
247
  rank: USER_PANEL_RANK,
@@ -240,15 +254,21 @@ export class UserPanelSkillProvider {
240
254
  }
241
255
  async get(candidate, _options) {
242
256
  const locator = candidate.locator;
243
- const store = this.skills;
244
- const entry = await store.get(locator.name);
245
- if (entry === undefined || entry.disabled)
257
+ if (typeof locator?.name !== 'string' || !isUserSkillEntryName(locator.name))
258
+ return undefined;
259
+ if (this.options.enabled && (candidate.provider !== this.name || candidate.source !== USER_PANEL_SKILL_SOURCE || candidate.name !== locator.name))
260
+ return undefined;
261
+ const entry = await this.skills.get(locator.name);
262
+ if (entry === undefined || (this.options.enabled && (entry.name !== candidate.name || entry.path !== candidate.path)))
263
+ return undefined;
264
+ const invocation = this.invocation(entry);
265
+ if (!invocation || (!invocation.modelInvocable && !invocation.userInvocable))
246
266
  return undefined;
247
267
  return {
248
268
  name: candidate.name,
249
269
  description: candidate.description,
250
270
  ...(typeof entry.metadata['whenToUse'] === 'string' && entry.metadata['whenToUse'] !== '' ? { whenToUse: entry.metadata['whenToUse'] } : {}),
251
- invocation: candidate.invocation,
271
+ invocation: this.options.enabled ? invocation : candidate.invocation,
252
272
  source: candidate.source,
253
273
  provider: this.name,
254
274
  resourceBase: { kind: 'directory', path: this.resourceDirectory(entry) },
@@ -0,0 +1,256 @@
1
+ import { createUserMessage } from '@deepseek-ai/dsh-llm';
2
+ import { qualifiedSuiteId, suiteDataDir } from '../../../../market-catalog/src/index.js';
3
+ import { expandPluginPaths, pluginRootOf } from '../../../../market-catalog/src/index.js';
4
+ import { defaultMarkdownResources, resourceText } from '../../../../market-catalog/src/index.js';
5
+ import { parseCommandResource, readCommands } from '../../application/command-resources.js';
6
+ export { readCommands } from '../../application/command-resources.js';
7
+ import { bindHostLocale } from '../host/host-locale.js';
8
+ import { injectDynamicContext, shellSeamOf } from './dynamic-context.js';
9
+ import { pluginMarketSource } from '../../../../market-contracts/src/host/plugin-message-source.js';
10
+ import { CommandNameRegistry, registerWithAllocatedName } from '../host/command-name-allocator.js';
11
+ import { pluginResourceId } from '../../application/panel-resources.js';
12
+ /** Render a thrown value for a diagnostic, without trusting its string coercion. */
13
+ function messageOf(error) {
14
+ return error instanceof Error ? error.message : String(error);
15
+ }
16
+ export class CommandMountRegistry {
17
+ ctx;
18
+ t;
19
+ dataRoot;
20
+ fingerprints = new Map();
21
+ live = new Map();
22
+ /**
23
+ * The call names this seat holds, and the keys they were registered under.
24
+ *
25
+ * Occupancy is per layer, which is the unit the host checks: this registry
26
+ * instance registers into one layer (an agent's scope on the project path,
27
+ * the global layer on the user path), and a sibling registry in another
28
+ * layer neither sees nor is seen by these names.
29
+ */
30
+ names = new CommandNameRegistry();
31
+ registeredName = new Map();
32
+ /** The menu row each live registration produces, with the panel id it translates as. */
33
+ registered = new Map();
34
+ /** Per-workspace entry filter; an absent provider registers everything wanted. */
35
+ entryFilter;
36
+ selectionPolicy;
37
+ registrationPolicy;
38
+ allowDisabled = false;
39
+ constructor(ctx, t = bindHostLocale(undefined), dataRoot) {
40
+ this.ctx = ctx;
41
+ this.t = t;
42
+ this.dataRoot = dataRoot;
43
+ }
44
+ /**
45
+ * Install the per-workspace entry filter read at wanted-row time. A filtered
46
+ * command never becomes wanted, which unregisters it through the ordinary
47
+ * reconcile pass — the same path a removed command file takes.
48
+ */
49
+ setEntryFilter(filter) {
50
+ this.entryFilter = filter;
51
+ }
52
+ /**
53
+ * Gate reconcile and execution by owning suite and authored resource name,
54
+ * before call-name flattening or collision allocation. Unset allows all.
55
+ */
56
+ setSelectionPolicy(callback, registration = callback, options = {}) {
57
+ this.selectionPolicy = callback;
58
+ this.registrationPolicy = registration;
59
+ this.allowDisabled = options.allowDisabled === true;
60
+ }
61
+ /** The live shell seam, when the profile has one; dynamic context stays literal without it. */
62
+ shell() {
63
+ return shellSeamOf(this.ctx);
64
+ }
65
+ /** Register/unregister suite commands to match the enabled suites exactly. */
66
+ async reconcile(enabledSuites) {
67
+ const diagnostics = [];
68
+ const wanted = new Map();
69
+ /** How many specs already claimed one suite-qualified call name this pass. */
70
+ const occurrences = new Map();
71
+ for (const suite of enabledSuites) {
72
+ const specs = [];
73
+ const resources = suite.activeSurfaces.commands === false ? [] : (suite.resources?.commands ?? (await defaultMarkdownResources(suite.root, 'commands')));
74
+ for (const resource of resources) {
75
+ const includeDisabled = this.allowDisabled && this.registrationPolicy?.(suite, resource.name) === true;
76
+ for (const spec of await readCommands(suite.root, [resource], { includeDisabled }))
77
+ specs.push({ ...spec, resource });
78
+ }
79
+ const suiteRoot = pluginRootOf(suite);
80
+ const suiteData = suiteRoot === undefined || this.dataRoot === undefined ? undefined : suiteDataDir(this.dataRoot, suite.sourceId, suite.id);
81
+ for (const spec of specs) {
82
+ // The registry key is source-qualified: bare suite ids are unique per
83
+ // source only, so two sources' same-named suites would collide.
84
+ const suiteKey = qualifiedSuiteId(suite.sourceId, suite.id);
85
+ // Two files of one suite flatten to one call name (`git/commit` and
86
+ // `git-commit`) and are both real commands, so the key counts them
87
+ // apart and allocation gives the second one a suffix instead of
88
+ // dropping it. The count is per pass, so re-reading the same suite
89
+ // reproduces the same keys.
90
+ const qualified = `${suiteKey}/${spec.name}`;
91
+ const occurrence = occurrences.get(qualified) ?? 0;
92
+ occurrences.set(qualified, occurrence + 1);
93
+ const key = occurrence === 0 ? qualified : `${qualified}#${occurrence}`;
94
+ // The per-workspace resource filter answers by the call name the model
95
+ // types, so the window and the registry agree on what one row names.
96
+ if (this.entryFilter?.().allows('commands', `commands:${spec.name}`) === false)
97
+ continue;
98
+ if (this.registrationPolicy?.(suite, spec.resourceName) === false)
99
+ continue;
100
+ wanted.set(key, {
101
+ ...spec,
102
+ suite,
103
+ suiteId: suiteKey,
104
+ suiteName: suite.manifest.name,
105
+ // Kept apart from the qualified `suiteId` above: the panel id is built
106
+ // from the two raw halves, exactly as the panel builds it.
107
+ sourceId: suite.sourceId,
108
+ rawSuiteId: suite.id,
109
+ ...(suiteRoot === undefined ? {} : { suiteRoot }),
110
+ ...(suiteData === undefined ? {} : { suiteData })
111
+ });
112
+ }
113
+ }
114
+ for (const [key, disposer] of [...this.live]) {
115
+ if (!wanted.has(key)) {
116
+ disposer();
117
+ this.live.delete(key);
118
+ this.fingerprints.delete(key);
119
+ this.releaseName(key);
120
+ }
121
+ }
122
+ const host = this.ctx;
123
+ const commands = host.commands;
124
+ if (typeof commands?.register !== 'function') {
125
+ if (wanted.size > 0)
126
+ diagnostics.push({ suiteId: '', command: '', reason: 'ctx.commands is not available in this profile' });
127
+ return diagnostics;
128
+ }
129
+ for (const [key, { suite, ...spec }] of wanted) {
130
+ const fingerprint = JSON.stringify(spec);
131
+ if (this.live.has(key) && this.fingerprints.get(key) === fingerprint)
132
+ continue;
133
+ this.live.get(key)?.();
134
+ this.live.delete(key);
135
+ this.fingerprints.delete(key);
136
+ this.releaseName(key);
137
+ // A name the layer already holds — a sibling suite flattening to the
138
+ // same call name, a host built-in such as /compact, or a leftover
139
+ // registration — is the one case the host refuses outright, and a
140
+ // refused definition is what the slash menu drops. Allocating the name
141
+ // first turns that collision into a suffix instead of a disappearance.
142
+ const attempt = registerWithAllocatedName(this.names, spec.name, name => commands.register({
143
+ name,
144
+ description: `[${spec.suiteName}] ${spec.description}`,
145
+ ...(spec.hint === undefined ? {} : { input: { hint: spec.hint } }),
146
+ handler: async (invocation) => {
147
+ const agent = invocation.agent;
148
+ const workdir = agent.session?.header?.cwd;
149
+ // The template rides the agent verbatim apart from the placeholders
150
+ // its author wrote: a decorator line naming this plugin or the
151
+ // suite would be text the command author never wrote, and the
152
+ // follow-up's `source` already records provenance.
153
+ let authoredBody = spec.body;
154
+ if (this.selectionPolicy) {
155
+ if (this.selectionPolicy(suite, spec.resourceName) !== true)
156
+ return { kind: 'error', text: this.t('commandNotSelected', { command: name }) };
157
+ try {
158
+ const resource = !this.allowDisabled || spec.resource.file === suite.manifest.path ? spec.resource : { name: spec.resource.name, file: spec.resource.file };
159
+ const fresh = parseCommandResource(resource, await resourceText(resource), { includeDisabled: this.allowDisabled });
160
+ if (!fresh || this.selectionPolicy(suite, spec.resourceName) !== true)
161
+ return { kind: 'error', text: this.t('commandNotSelected', { command: name }) };
162
+ authoredBody = fresh.body;
163
+ }
164
+ catch {
165
+ return { kind: 'error', text: this.t('commandNotSelected', { command: name }) };
166
+ }
167
+ }
168
+ const body = expandPluginPaths(authoredBody, {
169
+ ...(spec.suiteRoot === undefined ? {} : { root: spec.suiteRoot }),
170
+ ...(spec.suiteData === undefined ? {} : { data: spec.suiteData }),
171
+ ...(workdir === undefined ? {} : { projectDir: workdir })
172
+ }).replaceAll('$ARGUMENTS', invocation.rawInput.trim());
173
+ if (this.selectionPolicy?.(suite, spec.resourceName) === false) {
174
+ return { kind: 'error', text: this.t('commandNotSelected', { command: name }) };
175
+ }
176
+ const shell = this.shell();
177
+ if (shell === undefined) {
178
+ agent.followup(createUserMessage({
179
+ content: [{ type: 'text', text: body }],
180
+ source: pluginMarketSource()
181
+ }));
182
+ return { kind: 'success', text: this.t('commandAcknowledged', { command: name }) };
183
+ }
184
+ let text;
185
+ try {
186
+ text = await injectDynamicContext(body, { shell, ...(workdir === undefined ? {} : { workdir }) });
187
+ }
188
+ catch (error) {
189
+ return { kind: 'error', text: error instanceof Error ? error.message : String(error) };
190
+ }
191
+ if (this.selectionPolicy?.(suite, spec.resourceName) === false) {
192
+ return { kind: 'error', text: this.t('commandNotSelected', { command: name }) };
193
+ }
194
+ agent.followup(createUserMessage({
195
+ content: [{ type: 'text', text }],
196
+ source: pluginMarketSource()
197
+ }));
198
+ return { kind: 'success', text: this.t('commandAcknowledged', { command: name }) };
199
+ }
200
+ }));
201
+ if (attempt.kind === 'failed') {
202
+ diagnostics.push({ suiteId: spec.suiteId, command: spec.name, reason: messageOf(attempt.error) });
203
+ continue;
204
+ }
205
+ this.live.set(key, attempt.disposer);
206
+ this.fingerprints.set(key, fingerprint);
207
+ this.registeredName.set(key, attempt.name);
208
+ // The panel addresses this document by the resource name it read plus the
209
+ // suite it belongs to, so the id is built exactly as the panel builds it —
210
+ // same inputs, same string, one shared cache entry.
211
+ this.registered.set(key, { name: attempt.name, id: pluginResourceId(spec.sourceId, spec.rawSuiteId, 'commands', spec.resourceName ?? spec.name) });
212
+ // A renamed command still works, so this is not a failure: it is the
213
+ // one record that the name a user types is not the name the file
214
+ // carries, which nothing else in the status surfaces would show.
215
+ if (attempt.name !== spec.name) {
216
+ diagnostics.push({
217
+ suiteId: spec.suiteId,
218
+ command: attempt.name,
219
+ reason: `registered as "${attempt.name}" because "${spec.name}" is already taken in this command layer`
220
+ });
221
+ }
222
+ }
223
+ return diagnostics;
224
+ }
225
+ /**
226
+ * Every command this layer currently holds: the call name the menu row
227
+ * carries and the panel identity that owns its translation.
228
+ *
229
+ * Two files of one suite can flatten to the same call name, so the
230
+ * registration key (not the name) is what tells those rows apart; each one
231
+ * keeps its own resource name and therefore its own translation id.
232
+ * @returns one row per live registration, in registration-key order.
233
+ */
234
+ registrations() {
235
+ return [...this.registered.values()];
236
+ }
237
+ /** Dispose every registered command; used at plugin teardown. */
238
+ disposeAll() {
239
+ for (const disposer of [...this.live.values()])
240
+ disposer();
241
+ for (const key of [...this.registeredName.keys()])
242
+ this.releaseName(key);
243
+ this.registered.clear();
244
+ this.live.clear();
245
+ this.fingerprints.clear();
246
+ }
247
+ /** Free the call name one unmounted key held, so a later claim can reuse it. */
248
+ releaseName(key) {
249
+ const name = this.registeredName.get(key);
250
+ if (name === undefined)
251
+ return;
252
+ this.names.forget(name);
253
+ this.registeredName.delete(key);
254
+ this.registered.delete(key);
255
+ }
256
+ }