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
@@ -1,12 +1,12 @@
1
1
  /** Suite detail and preview projections owned by the application layer. */
2
2
  import { readFile, stat } from 'node:fs/promises';
3
3
  import { parse as parseYaml } from 'yaml';
4
- import { discoverLspEntries } from '../catalog/surfaces.js';
5
- import { defaultMarkdownResources, resourceText } from '../catalog/component-files.js';
6
- import { credentialRefsInServer } from './mcp/mcp-config.js';
7
- import { redactMcpConfig, redactMcpOverrides } from './mcp/mcp-redaction.js';
8
- import { applyOverride } from './mcp/mcp-overrides.js';
9
- import { effectiveSurfaces } from '../model/types.js';
4
+ import { discoverLspEntries } from '../../../market-catalog/src/index.js';
5
+ import { defaultMarkdownResources, resourceText } from '../../../market-catalog/src/index.js';
6
+ import { credentialRefsInServer } from '../../../market-mcp/src/index.js';
7
+ import { redactMcpConfig, redactMcpOverrides } from '../../../market-contracts/src/redaction.js';
8
+ import { applyOverride } from '../../../market-mcp/src/index.js';
9
+ import { effectiveSurfaces } from '../../../market-contracts/src/model/types.js';
10
10
  /** The checkout's last modification, or null when the path cannot be read. */
11
11
  async function rootModifiedAt(root) {
12
12
  try {
@@ -60,53 +60,97 @@ export async function buildSuiteDetail(suite, installed, diagnostics, mcpOverrid
60
60
  : { count: 0, entries: [] }
61
61
  : normalizedHookPreviews(suite.hooks)
62
62
  : { count: 0, entries: [] },
63
- commands: remoteUrl === undefined ? await markdownPreviews(suite.resources?.commands ?? (await defaultMarkdownResources(suite.root, 'commands'))) : [],
64
- agents: remoteUrl === undefined ? await markdownPreviews(suite.resources?.agents ?? (await defaultMarkdownResources(suite.root, 'agents'))) : [],
63
+ commands: remoteUrl === undefined ? await documentMetas(suite.resources?.commands ?? (await defaultMarkdownResources(suite.root, 'commands'))) : [],
64
+ agents: remoteUrl === undefined ? await documentMetas(suite.resources?.agents ?? (await defaultMarkdownResources(suite.root, 'agents'))) : [],
65
65
  lsp: remoteUrl === undefined ? await lspDetail(suite) : { servers: [], raw: [] },
66
66
  errors: suite.errors,
67
67
  mcpErrors: diagnostics.filter(diagnostic => diagnostic.suiteId === suite.id).map(diagnostic => `${diagnostic.serverKey}: ${diagnostic.reason}`)
68
68
  };
69
69
  }
70
- /** Read one skill body from a normalized suite. */
71
- export async function readSkillContent(suite, skillName) {
70
+ /**
71
+ * Read one skill's authored text from a normalized suite.
72
+ *
73
+ * A skill's file is resolved by the scan; commands and agents resolve theirs
74
+ * through the suite's own resource list ({@link readSuiteDocument}). A skill a
75
+ * suite does not carry is a miss, not a lookup.
76
+ */
77
+ async function readSkillText(suite, skillName) {
72
78
  const skill = suite.skills.find(entry => entry.name === skillName);
73
79
  if (skill === undefined)
74
80
  throw new Error(`skill "${skillName}" not found in suite "${suite.id}"`);
75
- let content;
76
81
  try {
77
- content = await readFile(skill.file, 'utf8');
82
+ return await readFile(skill.file, 'utf8');
78
83
  }
79
84
  catch (error) {
80
85
  throw new Error(`skill file unreadable: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
81
86
  }
82
- return { name: skill.name, description: skill.description, content, path: skill.file };
83
87
  }
88
+ /**
89
+ * Read one of a suite's document surfaces — a skill, a command, or an agent —
90
+ * by the identity the market detail page addresses it with.
91
+ *
92
+ * This is the only body the market ever serves. The detail payload carries a
93
+ * document's name and description so its row can render, and the text arrives
94
+ * here when a reader opens that row, whole and uncut.
95
+ *
96
+ * The suite's own scanned resource list is the only source of a path: the
97
+ * caller names a document, never a path, and a name the scan did not produce is
98
+ * a miss rather than a lookup. Commands and agents read the same resource the
99
+ * scan that built the detail payload found, so a document read here is the
100
+ * document that payload named — re-read rather than taken from the request.
101
+ * @param suite - the normalized suite the document belongs to.
102
+ * @param kind - which of the three document surfaces the name belongs to.
103
+ * @param name - the document's name inside that surface.
104
+ * @returns the document's text exactly as authored.
105
+ */
106
+ export async function readSuiteDocument(suite, kind, name) {
107
+ if (kind === 'skills')
108
+ return readSkillText(suite, name);
109
+ const resources = suite.resources?.[kind] ?? (await defaultMarkdownResources(suite.root, kind));
110
+ const resource = resources.find(entry => entry.name === name);
111
+ if (resource === undefined)
112
+ throw new Error(`no ${kind} document named "${name}" in suite "${suite.id}"`);
113
+ return resourceText(resource);
114
+ }
115
+ /**
116
+ * A capped preview of a file whose bytes still travel inside the detail
117
+ * payload — the directory-style LSP definition files, and nothing else. The
118
+ * cap is written into the text it produces, so a reader who gets one never
119
+ * mistakes a cut document for a whole one.
120
+ */
84
121
  async function readPreview(path, capBytes = 64 * 1024) {
85
122
  const text = await readFile(path, 'utf8');
86
123
  return text.length > capBytes ? `${text.slice(0, capBytes)}\n… (truncated)` : text;
87
124
  }
88
- async function markdownPreviews(resources) {
89
- const previews = [];
125
+ /**
126
+ * One document's identity as the suite detail payload carries it: the name its
127
+ * row shows and the description its frontmatter declares. The body is not part
128
+ * of the payload — it is read on demand, by the document route, when a reader
129
+ * opens the row.
130
+ */
131
+ async function documentMetas(resources) {
132
+ const metas = [];
90
133
  for (const resource of resources) {
91
134
  try {
92
- const content = (await resourceText(resource)).slice(0, 64 * 1024);
93
- const frontmatter = /^---\r?\n([\s\S]*?)\r?\n---/.exec(content)?.[1];
94
- let description;
95
- if (frontmatter !== undefined) {
96
- const yaml = parseYaml(frontmatter);
97
- if (typeof yaml === 'object' && yaml !== null) {
98
- const desc = yaml['description'];
99
- if (typeof desc === 'string')
100
- description = desc;
101
- }
102
- }
103
- previews.push({ name: resource.name, ...(description === undefined ? {} : { description }), content });
135
+ const description = frontmatterDescription(await resourceText(resource));
136
+ metas.push({ name: resource.name, ...(description === undefined ? {} : { description }) });
104
137
  }
105
138
  catch {
106
- // Unreadable preview files are omitted from the detail response.
139
+ // Unreadable document files are omitted from the detail response.
107
140
  }
108
141
  }
109
- return previews;
142
+ return metas;
143
+ }
144
+ /** The `description` a document's YAML frontmatter declares, when it declares one. */
145
+ function frontmatterDescription(text) {
146
+ const frontmatter = /^---\r?\n([\s\S]*?)\r?\n---/.exec(text)?.[1];
147
+ if (frontmatter === undefined)
148
+ return undefined;
149
+ const yaml = parseYaml(frontmatter);
150
+ if (typeof yaml !== 'object' || yaml === null)
151
+ return undefined;
152
+ const description = yaml['description'];
153
+ return typeof description === 'string' ? description : undefined;
110
154
  }
111
155
  function normalizedHookPreviews(hooks) {
112
156
  const entries = Object.entries(hooks.events).flatMap(([event, groups]) => groups.flatMap(group => group.hooks.map(hook => ({ event, ...(group.matcher === undefined ? {} : { matcher: group.matcher }), command: hook.command }))));
@@ -0,0 +1,408 @@
1
+ /** Extension inventory reuses catalog/panel status queries and preserves their full-detail identities. */
2
+ import { basename } from 'node:path';
3
+ import { HOOK_EVENT_HOST_SUPPORT, hookResourceId } from '../../../market-contracts/src/contracts/extension-presets.js';
4
+ import { SUITE_SURFACE_KEYS } from '../../../market-contracts/src/model/types.js';
5
+ import { USER_MCP_SOURCE, USER_MCP_SUITE } from '../../../market-mcp/src/index.js';
6
+ import { qualifiedSuiteId } from '../../../market-catalog/src/index.js';
7
+ import { deriveServerName } from '../../../market-mcp/src/index.js';
8
+ import { USER_HOOKS_SOURCE, USER_HOOKS_SUITE, exposesIndividualHooks } from '../../../market-runtime/src/index.js';
9
+ import { DIRECT_LSP_SUITE_ID } from '../../../market-lsp/src/index.js';
10
+ /** User-owned configuration is not a market offering. Its direct MCP servers have no suite parent. */
11
+ const isOwnedSentinel = (sourceId, id) => (sourceId === USER_MCP_SOURCE && id === USER_MCP_SUITE) || (sourceId === USER_HOOKS_SOURCE && id === USER_HOOKS_SUITE);
12
+ /** Classification does not change the identifiers used by existing preset and session records. */
13
+ function localConfiguration(suite) {
14
+ if (suite.sourceId === USER_HOOKS_SOURCE && suite.id === USER_HOOKS_SUITE)
15
+ return { configuration: 'user-hooks', name: 'User Hooks' };
16
+ if (suite.dimension === 'project')
17
+ return { configuration: 'project', name: suite.sourceId === 'native' ? basename(suite.root) : suite.manifest.name };
18
+ return undefined;
19
+ }
20
+ /** Suite panel ids are JSON tuples, not display names or flattened command identifiers. */
21
+ export function suiteResourceOwner(entry) {
22
+ if (entry.origin !== 'plugin' || entry.id === undefined)
23
+ return undefined;
24
+ try {
25
+ const value = JSON.parse(entry.id);
26
+ if (Array.isArray(value) && value.length === 4 && typeof value[0] === 'string' && typeof value[1] === 'string') {
27
+ return 'market:' + value[0] + '/' + value[1];
28
+ }
29
+ }
30
+ catch {
31
+ /* Invalid provenance remains unavailable instead of guessing its owner. */
32
+ }
33
+ return undefined;
34
+ }
35
+ /**
36
+ * The composed global switch for one panel entry.
37
+ *
38
+ * Only a candidate's validated declaration can say whether an entry the panel
39
+ * reports as off is an ordinary disabled consumer (selectable per session) or an
40
+ * invalid one (not selectable at all). Without a candidate the panel's own verdict
41
+ * is the whole answer, which is the legacy behaviour.
42
+ */
43
+ function candidateEntryVerdict(candidate, kind, name, panelDisabled) {
44
+ // An ordinary disabled consumer stays selectable per session; a surface that failed
45
+ // validation, or an entry the declaration does not actually carry, does not.
46
+ const selectable = candidate.validSurfaces[kind] === true && declaresResource(candidate, kind, name);
47
+ // The panel's own flag cannot stand in for the parent switch: it reports one entry's
48
+ // combined state, so a suite that is off globally must be composed in explicitly or
49
+ // its entries would read as globally enabled.
50
+ return { available: selectable, globalEnabled: selectable && globalSurfaceEnabled(candidate, kind) && !panelDisabled };
51
+ }
52
+ /** The composed global switch for one surface of one candidate suite. */
53
+ function globalSurfaceEnabled(candidate, kind) {
54
+ const { suite, validSurfaces } = candidate;
55
+ return suite.enabled && validSurfaces[kind] === true && suite.activeSurfaces?.[kind] === true;
56
+ }
57
+ /**
58
+ * A candidate is displayable while any surface or its system prompt validated; a
59
+ * candidate the parser rejected contributes nothing to select.
60
+ */
61
+ function candidateAvailable(candidate) {
62
+ const { suite, validSurfaces } = candidate;
63
+ return SUITE_SURFACE_KEYS.some(key => validSurfaces[key] === true) || (suite.systemPrompt !== undefined && suite.systemPrompt !== '');
64
+ }
65
+ /** Whether the validated declaration really carries the entry the panel reported. */
66
+ function declaresResource(candidate, kind, name) {
67
+ return kind === 'skills' ? candidate.suite.skills.some(skill => skill.name === name) : (candidate.suite.resources?.[kind] ?? []).some(resource => resource.name === name);
68
+ }
69
+ export async function readExtensionInventory(ports, options = {}) {
70
+ // A caller outside the type system could still name candidates without the override
71
+ // data. Absence there would read as "enabled", so it is refused rather than guessed.
72
+ if (options.candidates !== undefined && (options.mcpOverrides === undefined || options.lspDisabledIds === undefined))
73
+ throw new Error('extension-inventory-override-data-required');
74
+ const [overview, mcp, lsp, skills, commands, agents] = await Promise.all([
75
+ ports.catalog.overview(),
76
+ ports.catalog.mcpStatus(),
77
+ ports.catalog.lspStatus(),
78
+ ports.panels.skills.list(true),
79
+ ports.panels.commands.list(true),
80
+ ports.panels.agents.list(true)
81
+ ]);
82
+ const rows = [];
83
+ for (const suite of overview.suites) {
84
+ if (!suite.installed || suite.dimension !== 'user')
85
+ continue;
86
+ rows.push({
87
+ id: 'market:' + suite.sourceId + '/' + suite.suiteId,
88
+ face: 'market',
89
+ name: suite.name,
90
+ source: suite.sourceId,
91
+ description: suite.description,
92
+ ...(suite.translatedDescription === undefined ? {} : { translatedDescription: suite.translatedDescription }),
93
+ ...(suite.version === undefined ? {} : { version: suite.version }),
94
+ available: suite.enabled !== false,
95
+ counts: SUITE_SURFACE_KEYS.filter(key => suite.surfaces[key] > 0).map(key => ({ label: key, count: suite.surfaces[key] })),
96
+ detail: { kind: 'suite', sourceId: suite.sourceId, suiteId: suite.suiteId }
97
+ });
98
+ }
99
+ const candidates = options.candidates ?? [];
100
+ const candidateOwners = new Map(candidates.map(candidate => ['market:' + candidate.suite.sourceId + '/' + candidate.suite.id, candidate]));
101
+ const rowById = new Map(rows.map(row => [row.id, row]));
102
+ for (const candidate of candidates) {
103
+ const { suite } = candidate;
104
+ // Direct MCP entries have no parent, and the user hooks configuration has no
105
+ // card anywhere: neither publishes a market row. The hooks suite's rows stay
106
+ // on the Hooks face, where its grant is derived from the selected hooks
107
+ // themselves instead of from a parent id no preset carries.
108
+ if (isOwnedSentinel(suite.sourceId, suite.id))
109
+ continue;
110
+ const owner = 'market:' + suite.sourceId + '/' + suite.id;
111
+ const usable = candidateAvailable(candidate);
112
+ const globalEnabled = usable && suite.enabled && SUITE_SURFACE_KEYS.some(key => globalSurfaceEnabled(candidate, key));
113
+ // One suite is one row. The overview row stays the display authority — its name and
114
+ // description carry the panel's translation — while the validated declaration
115
+ // supplies availability and the switch.
116
+ const existing = rowById.get(owner);
117
+ if (existing !== undefined) {
118
+ existing.available = usable;
119
+ existing.globalEnabled = globalEnabled;
120
+ Object.assign(existing, localConfiguration(suite));
121
+ continue;
122
+ }
123
+ // A project suite the overview never listed still needs its row.
124
+ const row = {
125
+ id: owner,
126
+ face: 'market',
127
+ name: suite.manifest.name,
128
+ ...localConfiguration(suite),
129
+ source: suite.sourceId,
130
+ description: suite.manifest.description,
131
+ available: usable,
132
+ globalEnabled,
133
+ counts: SUITE_SURFACE_KEYS.filter(key => suite.surfaces[key] > 0).map(key => ({ label: key, count: suite.surfaces[key] })),
134
+ detail: { kind: 'suite', sourceId: suite.sourceId, suiteId: suite.id, ...(options.sessionId === undefined ? {} : { sessionId: options.sessionId }) }
135
+ };
136
+ rows.push(row);
137
+ rowById.set(owner, row);
138
+ }
139
+ for (const suite of options.projectSuites ?? []) {
140
+ const owner = 'market:' + suite.sourceId + '/' + suite.id;
141
+ // Candidate validation already owns this resource; legacy discovery cannot append or override it.
142
+ if (rowById.has(owner))
143
+ continue;
144
+ // The user hooks configuration has no card on any face; its hook rows come
145
+ // from the hook loop below and its grant is derived from them.
146
+ if (isOwnedSentinel(suite.sourceId, suite.id))
147
+ continue;
148
+ const row = {
149
+ id: owner,
150
+ face: 'market',
151
+ name: suite.manifest.name,
152
+ ...localConfiguration(suite),
153
+ source: suite.sourceId,
154
+ available: suite.enabled,
155
+ description: suite.manifest.description,
156
+ counts: SUITE_SURFACE_KEYS.filter(key => suite.surfaces[key] > 0).map(key => ({ label: key, count: suite.surfaces[key] })),
157
+ detail: { kind: 'suite', sourceId: suite.sourceId, suiteId: suite.id, ...(options.sessionId === undefined ? {} : { sessionId: options.sessionId }) }
158
+ };
159
+ rows.push(row);
160
+ rowById.set(owner, row);
161
+ }
162
+ const projectOwners = new Set((options.projectSuites ?? []).map(suite => 'market:' + suite.sourceId + '/' + suite.id));
163
+ const address = (owner) => (owner !== undefined && projectOwners.has(owner) && options.sessionId !== undefined ? { sessionId: options.sessionId } : {});
164
+ const parents = new Map(rows.map(row => [row.id, row.available]));
165
+ // The user's own hook declarations are configuration rows, not suite children:
166
+ // one row per declared command hook, grouped by event, carrying the host's
167
+ // support verdict for that event. A supported event's rows select like any
168
+ // other resource; a partial or registered-only event's rows stay read-only
169
+ // with the reason, so the Hooks tab registers the declaration without
170
+ // pretending the host runs it.
171
+ for (const suite of options.hookSuites ?? options.projectSuites ?? []) {
172
+ if (suite.hooks === undefined)
173
+ continue;
174
+ const provenance = suite.sourceId === USER_HOOKS_SOURCE && suite.id === USER_HOOKS_SUITE ? 'user-hooks' : suite.manifest.name;
175
+ // The rule is the suite's, not the caller's: an installed suite publishes no
176
+ // per-hook switch, so every row of its declaration follows the parent
177
+ // grant, while project and @user-hooks declarations stay individually
178
+ // addressable. Both reads carry the same verdict.
179
+ const followsSuite = !exposesIndividualHooks(suite);
180
+ const supportedEvents = suite.hooks.events;
181
+ for (const [event, groups] of Object.entries(supportedEvents)) {
182
+ const support = HOOK_EVENT_HOST_SUPPORT[event] ?? 'registered-only';
183
+ const selectable = support === 'supported';
184
+ let index = 0;
185
+ for (const group of groups) {
186
+ for (const hook of group.hooks) {
187
+ // The position is the identity the row was published under, so it is
188
+ // read before the counter moves rather than inside the id expression.
189
+ const hookIndex = index;
190
+ index += 1;
191
+ rows.push({
192
+ id: hookResourceId(suite.sourceId, suite.id, event, hookIndex),
193
+ face: 'hooks',
194
+ name: hook.command,
195
+ source: group.matcher === undefined || group.matcher === '*' ? provenance : provenance + ' · ' + group.matcher,
196
+ description: event,
197
+ suiteResourceId: 'market:' + suite.sourceId + '/' + suite.id,
198
+ ...(selectable
199
+ ? { available: true, globalEnabled: true }
200
+ : { available: false, control: 'global-only', unavailableReason: support === 'supported-partial' ? 'hook-event-partial' : 'hook-event-unsupported' }),
201
+ ...(followsSuite ? { followsSuite: true } : {}),
202
+ // The detail a row opens is the hook itself, not the suite behind it:
203
+ // every field the surface shows comes from this scanned declaration.
204
+ detail: {
205
+ kind: 'hook',
206
+ sourceId: suite.sourceId,
207
+ suiteId: suite.id,
208
+ event,
209
+ hookIndex,
210
+ command: hook.command,
211
+ ...(group.matcher === undefined ? {} : { matcher: group.matcher }),
212
+ ...(hook.timeout === undefined ? {} : { timeoutSec: hook.timeout }),
213
+ provenance,
214
+ support,
215
+ ...(options.sessionId === undefined ? {} : { sessionId: options.sessionId })
216
+ }
217
+ });
218
+ }
219
+ }
220
+ }
221
+ // Declarations the catalog validator rejected (Notification, SessionEnd,
222
+ // PreCompact and anything else the host cannot run) exist only as
223
+ // diagnostics on the suite. Each names its event, so one read-only row per
224
+ // diagnostic registers the declaration in the Hooks tab instead of letting
225
+ // it disappear into the suite detail's error list.
226
+ for (const error of suite.errors) {
227
+ const event = /^\S+ unsupported hook event (\S+)$/.exec(error)?.[1];
228
+ if (event === undefined)
229
+ continue;
230
+ const support = HOOK_EVENT_HOST_SUPPORT[event] ?? 'registered-only';
231
+ rows.push({
232
+ id: 'hooks:' + suite.sourceId + '/' + suite.id + '/' + event + '/declared',
233
+ face: 'hooks',
234
+ name: event,
235
+ source: provenance,
236
+ description: event,
237
+ available: false,
238
+ control: 'global-only',
239
+ unavailableReason: support === 'supported-partial' ? 'hook-event-partial' : 'hook-event-unsupported',
240
+ ...(followsSuite ? { followsSuite: true } : {}),
241
+ // A rejected declaration has no admitted hook, so the detail carries the
242
+ // event and the validator's own words instead of a command or position.
243
+ detail: {
244
+ kind: 'hook',
245
+ sourceId: suite.sourceId,
246
+ suiteId: suite.id,
247
+ event,
248
+ provenance,
249
+ support,
250
+ diagnostic: error,
251
+ ...(options.sessionId === undefined ? {} : { sessionId: options.sessionId })
252
+ }
253
+ });
254
+ }
255
+ }
256
+ for (const [face, entries] of [
257
+ ['skills', skills],
258
+ ['commands', commands],
259
+ ['agents', agents]
260
+ ]) {
261
+ for (const entry of entries) {
262
+ const owner = suiteResourceOwner(entry);
263
+ const identity = entry.id ?? entry.name;
264
+ rows.push({
265
+ id: face + ':' + identity,
266
+ face,
267
+ name: entry.name,
268
+ // Both texts travel: the panel renders the translated one until the
269
+ // reader flips the shared view, which needs the authored text too.
270
+ description: entry.description,
271
+ ...(entry.translatedDescription === undefined ? {} : { translatedDescription: entry.translatedDescription }),
272
+ source: entry.suiteName ?? 'user',
273
+ ...(owner === undefined ? {} : { suiteResourceId: owner }),
274
+ ...(face === 'skills' && entry.origin === 'user'
275
+ ? { globalEnabled: !entry.disabled, available: entry.metadata['validationError'] === undefined }
276
+ : candidateOwners.has(owner ?? '')
277
+ ? candidateEntryVerdict(candidateOwners.get(owner), face, entry.name, entry.disabled)
278
+ : // A native (user-origin) entry the user switched off is an ordinary disabled
279
+ // consumer: a preset may name it. A document that failed to parse is not
280
+ // selectable, whatever a preset says, and `metadata.validationError` is the
281
+ // panel's own evidence for that.
282
+ entry.origin === 'user'
283
+ ? { available: entry.metadata['validationError'] === undefined, globalEnabled: !entry.disabled && entry.metadata['validationError'] === undefined }
284
+ : { available: !entry.disabled && owner !== undefined && parents.get(owner) === true }),
285
+ detail: { kind: 'panel', panel: face, entryId: identity, ...address(owner) }
286
+ });
287
+ }
288
+ }
289
+ for (const entry of mcp.entries) {
290
+ const owner = entry.suiteId === undefined || entry.suiteId === USER_MCP_SOURCE + '/' + USER_MCP_SUITE ? undefined : 'market:' + entry.suiteId;
291
+ const row = {
292
+ id: 'mcp:' + entry.id,
293
+ face: 'mcp',
294
+ name: entry.name,
295
+ source: entry.source ?? 'direct',
296
+ description: entry.transport,
297
+ ...((entry.kind === 'direct' && entry.managed !== true) || options.mcpSessionControl === false
298
+ ? { control: 'global-only', unavailableReason: entry.kind === 'direct' && entry.managed !== true ? 'direct-mcp-uncontrolled' : 'host-mcp-uncontrolled' }
299
+ : {}),
300
+ ...(owner === undefined ? {} : { suiteResourceId: owner }),
301
+ available: entry.state !== 'disabled' && entry.state !== 'foreign' && entry.state !== 'orphaned' && (owner === undefined || parents.get(owner) === true),
302
+ detail: { kind: 'mcp', entryId: entry.id, ...address(owner) }
303
+ };
304
+ rows.push(row);
305
+ // Registered so a candidate corrects this row in place instead of adding another.
306
+ rowById.set(row.id, row);
307
+ }
308
+ for (const entry of lsp.entries) {
309
+ const owner = entry.kind === 'direct' ? undefined : 'market:' + entry.suiteId;
310
+ const row = {
311
+ id: 'lsp:' + entry.id,
312
+ face: 'lsp',
313
+ name: entry.serverKey,
314
+ source: entry.kind === 'direct' ? 'direct' : entry.suiteName,
315
+ description: entry.command,
316
+ ...(owner === undefined ? {} : { suiteResourceId: owner }),
317
+ // Only candidate mode can say a disabled direct server is still nameable, because
318
+ // only then does the caller supply the disabled-id switch. Legacy mode has no such
319
+ // evidence, so it keeps the original rule exactly: a disabled row is unavailable.
320
+ available: entry.kind === 'direct'
321
+ ? options.candidates === undefined
322
+ ? entry.state !== 'disabled'
323
+ : entry.state !== 'failed' && entry.state !== 'conflict' && entry.state !== 'host-missing'
324
+ : entry.state !== 'disabled' && parents.get(owner) === true,
325
+ ...(entry.kind !== 'direct'
326
+ ? { globalEnabled: entry.state !== 'disabled' }
327
+ : options.candidates === undefined || options.lspDisabledIds === undefined
328
+ ? {}
329
+ : { globalEnabled: !options.lspDisabledIds.has(entry.id) }),
330
+ detail: { kind: 'lsp', entryId: entry.id, ...address(owner) }
331
+ };
332
+ rows.push(row);
333
+ rowById.set(row.id, row);
334
+ }
335
+ // Rows for declarations the status layer omits, because it only reports installed
336
+ // and globally enabled suites. These are exactly the entries a preset still has to
337
+ // be able to name, and they are synthesized from the validated declaration rather
338
+ // than inferred from the absence of a status row.
339
+ for (const candidate of candidates) {
340
+ const { suite } = candidate;
341
+ const suiteKey = qualifiedSuiteId(suite.sourceId, suite.id);
342
+ // A user-owned sentinel's server is a direct resource: it has no suite parent to
343
+ // gate it, exactly as the status layer reports the same server.
344
+ const owner = isOwnedSentinel(suite.sourceId, suite.id) ? undefined : 'market:' + suite.sourceId + '/' + suite.id;
345
+ const ownerAvailable = owner === undefined || parents.get(owner) === true;
346
+ // Overrides are keyed by the source-qualified suite key the MCP layer itself uses,
347
+ // not by the resource id a preset names.
348
+ const overrides = options.mcpOverrides?.get(suiteKey);
349
+ for (const [serverKey, server] of Object.entries(suite.mcp?.servers ?? {})) {
350
+ const rowId = 'plugin:' + suiteKey + '/' + serverKey;
351
+ const override = overrides?.[serverKey];
352
+ const selectable = ownerAvailable && candidate.validSurfaces.mcp === true;
353
+ const globalEnabled = override?.enabled === false ? false : globalSurfaceEnabled(candidate, 'mcp');
354
+ // The status layer reports the row for an enabled suite and updates it in place;
355
+ // a row it omitted (a disabled suite) is synthesized from the declaration. Either
356
+ // way a status row that exists is corrected, never duplicated.
357
+ const existing = rowById.get('mcp:' + rowId);
358
+ if (existing !== undefined) {
359
+ existing.available = selectable;
360
+ existing.globalEnabled = globalEnabled;
361
+ continue;
362
+ }
363
+ const hostBackend = options.mcpSessionControl === false;
364
+ rows.push({
365
+ id: 'mcp:' + rowId,
366
+ face: 'mcp',
367
+ name: deriveServerName(suite, serverKey),
368
+ source: suite.manifest.name,
369
+ description: server.type,
370
+ ...(hostBackend ? { control: 'global-only', unavailableReason: 'host-mcp-uncontrolled' } : {}),
371
+ suiteResourceId: owner,
372
+ available: selectable,
373
+ globalEnabled,
374
+ detail: { kind: 'mcp', entryId: rowId, ...(options.sessionId === undefined ? {} : { sessionId: options.sessionId }) }
375
+ });
376
+ }
377
+ for (const spec of Object.values(suite.lsp?.servers ?? {})) {
378
+ const rowId = suiteKey + '/' + spec.key;
379
+ if (suiteKey === DIRECT_LSP_SUITE_ID)
380
+ continue;
381
+ // A project suite's LSP declaration is never enableable, whatever the preset says.
382
+ const valid = candidate.validSurfaces.lsp === true;
383
+ const selectable = ownerAvailable && valid;
384
+ const globalEnabled = valid && suite.enabled && suite.activeSurfaces?.lsp === true && options.lspDisabledIds?.has(rowId) !== true;
385
+ const existing = rowById.get('lsp:' + rowId);
386
+ if (existing !== undefined) {
387
+ existing.available = selectable;
388
+ existing.globalEnabled = globalEnabled;
389
+ continue;
390
+ }
391
+ const row = {
392
+ id: 'lsp:' + rowId,
393
+ face: 'lsp',
394
+ name: spec.key,
395
+ source: suite.manifest.name,
396
+ description: spec.command,
397
+ suiteResourceId: owner,
398
+ available: selectable,
399
+ globalEnabled,
400
+ detail: { kind: 'lsp', entryId: rowId, ...(options.sessionId === undefined ? {} : { sessionId: options.sessionId }) }
401
+ };
402
+ rows.push(row);
403
+ rowById.set(row.id, row);
404
+ }
405
+ }
406
+ return rows;
407
+ }
408
+ export { extensionResourceEnabled } from '../../../market-runtime/src/index.js';
@@ -0,0 +1,64 @@
1
+ import { createPanelResources } from '../../../market-runtime/src/index.js';
2
+ import { buildMcpStatus } from '../../../market-mcp/src/index.js';
3
+ import { buildLspStatus } from '../../../market-lsp/src/index.js';
4
+ import { buildSuiteDetail } from './details.js';
5
+ import { USER_HOOKS_SOURCE, USER_HOOKS_SUITE, loadUserHooksSuite } from '../../../market-runtime/src/index.js';
6
+ export function createProjectExtensionResources(catalog, users, cwd) {
7
+ const panels = createPanelResources(catalog, users, cwd);
8
+ const suites = async () => (await catalog.readProjectCatalog(cwd)).suites;
9
+ return {
10
+ panels,
11
+ suites,
12
+ async suiteDetail(sourceId, suiteId) {
13
+ // The user-hooks synthetic suite is a configuration row, not an install:
14
+ // `enabledUserSuites` carries it only while it declares events, so the
15
+ // detail reads the always-built suite and shows its diagnostics when the
16
+ // configuration is empty or malformed instead of a 404.
17
+ if (sourceId === USER_HOOKS_SOURCE && suiteId === USER_HOOKS_SUITE) {
18
+ const hooks = await loadUserHooksSuite(catalog.agentsRoot);
19
+ // The suite declares hooks only; an explicit empty resource list keeps the
20
+ // detail from discovering the shared Agent layout root's commands and
21
+ // agents directories as if they were this configuration's surfaces.
22
+ return buildSuiteDetail({ ...hooks, resources: { commands: [], agents: [] } }, undefined, [], undefined);
23
+ }
24
+ const suite = (await suites()).find(row => row.sourceId === sourceId && row.id === suiteId) ??
25
+ (await catalog.enabledUserSuites()).find(row => row.sourceId === sourceId && row.id === suiteId && row.sourceId === '@user-hooks');
26
+ if (!suite)
27
+ throw new Error('project suite not found');
28
+ return buildSuiteDetail(suite, undefined, [], undefined);
29
+ },
30
+ /**
31
+ * One document of this workspace's suite, on any of the three surfaces.
32
+ *
33
+ * The lookup stays in Catalog — one reader for skills, commands and agents — and
34
+ * the project cwd only selects which snapshot answers. Re-scanning here would
35
+ * duplicate the catalog's own identity handling.
36
+ */
37
+ async suiteDocument(sourceId, suiteId, kind, name) {
38
+ return catalog.suiteDocument(sourceId, suiteId, kind, name, cwd);
39
+ },
40
+ /** The same document's translation, answered from this workspace's snapshot. */
41
+ async suiteDocumentTranslation(sourceId, suiteId, kind, name, retry = false) {
42
+ return catalog.suiteDocumentTranslation(sourceId, suiteId, kind, name, retry, cwd);
43
+ },
44
+ async mcpStatus(diagnostics = [], observed = []) {
45
+ const declared = (await suites()).map(suite => ({ ...suite, installedAt: suite.installedAt ?? 'project' }));
46
+ return buildMcpStatus(declared, diagnostics, observed, await catalog.allMcpOverrides(declared));
47
+ },
48
+ async lspStatus() {
49
+ const declared = (await suites()).map(suite => ({ ...suite, installedAt: suite.installedAt ?? 'project' }));
50
+ return buildLspStatus(declared, {
51
+ hasLiveMounts: () => false,
52
+ // Same shape the mount registry records: one row per suite, keyed by suite id,
53
+ // with the suite's declared server keys joined as the registry joins them.
54
+ diagnosticsSnapshot: () => new Map(declared.flatMap(suite => {
55
+ const servers = suite.lsp?.servers;
56
+ if (servers === undefined)
57
+ return [];
58
+ const suiteId = suite.sourceId + '/' + suite.id;
59
+ return [[suiteId, { suiteId, serverKey: Object.keys(servers).join(','), code: 'mount-failed', reason: 'project-lsp-unsupported' }]];
60
+ }))
61
+ });
62
+ }
63
+ };
64
+ }