@ai-agent-forge/agent-forge 0.86.7 → 0.88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (717) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +10 -11
  3. package/dist/artifacts/artifact-store.d.ts.map +1 -1
  4. package/dist/artifacts/artifact-store.js +9 -5
  5. package/dist/artifacts/artifact-store.js.map +1 -1
  6. package/dist/bundle/.build-manifest.json +430 -413
  7. package/dist/bundle/chunks/{chunk-A7GUOX2H.js → chunk-6ZKDNZHA.js} +5 -1
  8. package/dist/bundle/chunks/chunk-HLJEVRWP.js +13 -0
  9. package/dist/bundle/chunks/chunk-YGHQME4V.js +1456 -0
  10. package/dist/bundle/chunks/image-resize-worker.js +12 -1
  11. package/dist/bundle/chunks/{virtual-modules-3IZ4MYSQ.js → virtual-modules-KZ5DRH7Q.js} +1 -1
  12. package/dist/bundle/cli.js +1 -1
  13. package/dist/bundle/client.js +1 -1
  14. package/dist/bundle/index.js +2 -2
  15. package/dist/bundle/rpc-entry.js +1 -1
  16. package/dist/cli/args.d.ts.map +1 -1
  17. package/dist/cli/args.js +231 -185
  18. package/dist/cli/args.js.map +1 -1
  19. package/dist/cli/auth-check.d.ts.map +1 -1
  20. package/dist/cli/auth-check.js +17 -4
  21. package/dist/cli/auth-check.js.map +1 -1
  22. package/dist/cli/auth-command.d.ts.map +1 -1
  23. package/dist/cli/auth-command.js +15 -9
  24. package/dist/cli/auth-command.js.map +1 -1
  25. package/dist/cli/credential-print.d.ts.map +1 -1
  26. package/dist/cli/credential-print.js +14 -7
  27. package/dist/cli/credential-print.js.map +1 -1
  28. package/dist/cli/experimental/command.d.ts.map +1 -1
  29. package/dist/cli/experimental/command.js +6 -5
  30. package/dist/cli/experimental/command.js.map +1 -1
  31. package/dist/cli/list-models.d.ts.map +1 -1
  32. package/dist/cli/list-models.js +9 -8
  33. package/dist/cli/list-models.js.map +1 -1
  34. package/dist/cli/plugin-manager-controller.d.ts.map +1 -1
  35. package/dist/cli/plugin-manager-controller.js +2 -1
  36. package/dist/cli/plugin-manager-controller.js.map +1 -1
  37. package/dist/cli/serve.d.ts.map +1 -1
  38. package/dist/cli/serve.js +8 -5
  39. package/dist/cli/serve.js.map +1 -1
  40. package/dist/client/remote-session.d.ts.map +1 -1
  41. package/dist/client/remote-session.js +16 -9
  42. package/dist/client/remote-session.js.map +1 -1
  43. package/dist/config.d.ts.map +1 -1
  44. package/dist/config.js +5 -3
  45. package/dist/config.js.map +1 -1
  46. package/dist/core/agent-capability-contract.d.ts +0 -7
  47. package/dist/core/agent-capability-contract.d.ts.map +1 -1
  48. package/dist/core/agent-capability-contract.js +72 -68
  49. package/dist/core/agent-capability-contract.js.map +1 -1
  50. package/dist/core/agent-session-bash.d.ts.map +1 -1
  51. package/dist/core/agent-session-bash.js +5 -4
  52. package/dist/core/agent-session-bash.js.map +1 -1
  53. package/dist/core/agent-session-compaction.d.ts +6 -10
  54. package/dist/core/agent-session-compaction.d.ts.map +1 -1
  55. package/dist/core/agent-session-compaction.js +35 -133
  56. package/dist/core/agent-session-compaction.js.map +1 -1
  57. package/dist/core/agent-session-context.d.ts.map +1 -1
  58. package/dist/core/agent-session-context.js +18 -13
  59. package/dist/core/agent-session-context.js.map +1 -1
  60. package/dist/core/agent-session-internal.d.ts +0 -6
  61. package/dist/core/agent-session-internal.d.ts.map +1 -1
  62. package/dist/core/agent-session-internal.js.map +1 -1
  63. package/dist/core/agent-session-model.d.ts.map +1 -1
  64. package/dist/core/agent-session-model.js +2 -1
  65. package/dist/core/agent-session-model.js.map +1 -1
  66. package/dist/core/agent-session-retry.d.ts.map +1 -1
  67. package/dist/core/agent-session-retry.js +3 -3
  68. package/dist/core/agent-session-retry.js.map +1 -1
  69. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  70. package/dist/core/agent-session-runtime.js +7 -6
  71. package/dist/core/agent-session-runtime.js.map +1 -1
  72. package/dist/core/agent-session-services.d.ts +1 -1
  73. package/dist/core/agent-session-services.d.ts.map +1 -1
  74. package/dist/core/agent-session-services.js.map +1 -1
  75. package/dist/core/agent-session-tools.d.ts.map +1 -1
  76. package/dist/core/agent-session-tools.js +3 -2
  77. package/dist/core/agent-session-tools.js.map +1 -1
  78. package/dist/core/agent-session.d.ts +40 -22
  79. package/dist/core/agent-session.d.ts.map +1 -1
  80. package/dist/core/agent-session.js +147 -67
  81. package/dist/core/agent-session.js.map +1 -1
  82. package/dist/core/auth-guidance.d.ts.map +1 -1
  83. package/dist/core/auth-guidance.js +11 -5
  84. package/dist/core/auth-guidance.js.map +1 -1
  85. package/dist/core/auth-storage.d.ts.map +1 -1
  86. package/dist/core/auth-storage.js +9 -6
  87. package/dist/core/auth-storage.js.map +1 -1
  88. package/dist/core/compaction/compaction.d.ts.map +1 -1
  89. package/dist/core/compaction/compaction.js +2 -1
  90. package/dist/core/compaction/compaction.js.map +1 -1
  91. package/dist/core/embedded-sdk.d.ts.map +1 -1
  92. package/dist/core/embedded-sdk.js +10 -6
  93. package/dist/core/embedded-sdk.js.map +1 -1
  94. package/dist/core/export-html/index.d.ts.map +1 -1
  95. package/dist/core/export-html/index.js +9 -4
  96. package/dist/core/export-html/index.js.map +1 -1
  97. package/dist/core/extensions/agent-composition.d.ts.map +1 -1
  98. package/dist/core/extensions/agent-composition.js +26 -19
  99. package/dist/core/extensions/agent-composition.js.map +1 -1
  100. package/dist/core/extensions/bootstrap-agent-loop.d.ts.map +1 -1
  101. package/dist/core/extensions/bootstrap-agent-loop.js +3 -2
  102. package/dist/core/extensions/bootstrap-agent-loop.js.map +1 -1
  103. package/dist/core/extensions/bootstrap-compaction-policy.d.ts.map +1 -1
  104. package/dist/core/extensions/bootstrap-compaction-policy.js +0 -34
  105. package/dist/core/extensions/bootstrap-compaction-policy.js.map +1 -1
  106. package/dist/core/extensions/bootstrap-lifecycle.d.ts.map +1 -1
  107. package/dist/core/extensions/bootstrap-lifecycle.js +20 -17
  108. package/dist/core/extensions/bootstrap-lifecycle.js.map +1 -1
  109. package/dist/core/extensions/bootstrap-overflow-policy.d.ts.map +1 -1
  110. package/dist/core/extensions/bootstrap-overflow-policy.js +2 -1
  111. package/dist/core/extensions/bootstrap-overflow-policy.js.map +1 -1
  112. package/dist/core/extensions/bootstrap-retry-policy.d.ts.map +1 -1
  113. package/dist/core/extensions/bootstrap-retry-policy.js +4 -3
  114. package/dist/core/extensions/bootstrap-retry-policy.js.map +1 -1
  115. package/dist/core/extensions/bootstrap-skills.d.ts.map +1 -1
  116. package/dist/core/extensions/bootstrap-skills.js +7 -6
  117. package/dist/core/extensions/bootstrap-skills.js.map +1 -1
  118. package/dist/core/extensions/bootstrap-tools.d.ts.map +1 -1
  119. package/dist/core/extensions/bootstrap-tools.js +2 -1
  120. package/dist/core/extensions/bootstrap-tools.js.map +1 -1
  121. package/dist/core/extensions/capability-plugin.d.ts.map +1 -1
  122. package/dist/core/extensions/capability-plugin.js +37 -13
  123. package/dist/core/extensions/capability-plugin.js.map +1 -1
  124. package/dist/core/extensions/capability-runtime-events.d.ts.map +1 -1
  125. package/dist/core/extensions/capability-runtime-events.js +17 -13
  126. package/dist/core/extensions/capability-runtime-events.js.map +1 -1
  127. package/dist/core/extensions/capability-runtime-guards.d.ts.map +1 -1
  128. package/dist/core/extensions/capability-runtime-guards.js +16 -15
  129. package/dist/core/extensions/capability-runtime-guards.js.map +1 -1
  130. package/dist/core/extensions/capability-runtime-manifest.d.ts.map +1 -1
  131. package/dist/core/extensions/capability-runtime-manifest.js +52 -30
  132. package/dist/core/extensions/capability-runtime-manifest.js.map +1 -1
  133. package/dist/core/extensions/capability-runtime-validation.d.ts.map +1 -1
  134. package/dist/core/extensions/capability-runtime-validation.js +66 -65
  135. package/dist/core/extensions/capability-runtime-validation.js.map +1 -1
  136. package/dist/core/extensions/capability-runtime.d.ts.map +1 -1
  137. package/dist/core/extensions/capability-runtime.js +147 -127
  138. package/dist/core/extensions/capability-runtime.js.map +1 -1
  139. package/dist/core/extensions/compaction-memory-failure-mode.d.ts.map +1 -1
  140. package/dist/core/extensions/compaction-memory-failure-mode.js +3 -2
  141. package/dist/core/extensions/compaction-memory-failure-mode.js.map +1 -1
  142. package/dist/core/extensions/context-strategy-binding.d.ts.map +1 -1
  143. package/dist/core/extensions/context-strategy-binding.js +7 -4
  144. package/dist/core/extensions/context-strategy-binding.js.map +1 -1
  145. package/dist/core/extensions/lifecycle-catalog.d.ts.map +1 -1
  146. package/dist/core/extensions/lifecycle-catalog.js +290 -279
  147. package/dist/core/extensions/lifecycle-catalog.js.map +1 -1
  148. package/dist/core/extensions/lifecycle-delivery-queue.d.ts.map +1 -1
  149. package/dist/core/extensions/lifecycle-delivery-queue.js +3 -2
  150. package/dist/core/extensions/lifecycle-delivery-queue.js.map +1 -1
  151. package/dist/core/extensions/provider-failover.d.ts +7 -3
  152. package/dist/core/extensions/provider-failover.d.ts.map +1 -1
  153. package/dist/core/extensions/provider-failover.js +9 -8
  154. package/dist/core/extensions/provider-failover.js.map +1 -1
  155. package/dist/core/facade/coding-agent-facade.d.ts +6 -6
  156. package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
  157. package/dist/core/facade/coding-agent-facade.js +2 -3
  158. package/dist/core/facade/coding-agent-facade.js.map +1 -1
  159. package/dist/core/http-dispatcher.d.ts.map +1 -1
  160. package/dist/core/http-dispatcher.js +2 -1
  161. package/dist/core/http-dispatcher.js.map +1 -1
  162. package/dist/core/i18n/index.d.ts +14 -0
  163. package/dist/core/i18n/index.d.ts.map +1 -0
  164. package/dist/core/i18n/index.js +67 -0
  165. package/dist/core/i18n/index.js.map +1 -0
  166. package/dist/core/i18n/locales/en/example.d.ts +7 -0
  167. package/dist/core/i18n/locales/en/example.d.ts.map +1 -0
  168. package/dist/core/i18n/locales/en/example.js +7 -0
  169. package/dist/core/i18n/locales/en/example.js.map +1 -0
  170. package/dist/core/i18n/locales/zh-cn/cli.d.ts +8 -0
  171. package/dist/core/i18n/locales/zh-cn/cli.d.ts.map +1 -0
  172. package/dist/core/i18n/locales/zh-cn/cli.js +229 -0
  173. package/dist/core/i18n/locales/zh-cn/cli.js.map +1 -0
  174. package/dist/core/i18n/locales/zh-cn/common.d.ts +6 -0
  175. package/dist/core/i18n/locales/zh-cn/common.d.ts.map +1 -0
  176. package/dist/core/i18n/locales/zh-cn/common.js +6 -0
  177. package/dist/core/i18n/locales/zh-cn/common.js.map +1 -0
  178. package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts +13 -0
  179. package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts.map +1 -0
  180. package/dist/core/i18n/locales/zh-cn/core-contract-core.js +173 -0
  181. package/dist/core/i18n/locales/zh-cn/core-contract-core.js.map +1 -0
  182. package/dist/core/i18n/locales/zh-cn/core-contract-extensions.d.ts +12 -0
  183. package/dist/core/i18n/locales/zh-cn/core-contract-extensions.d.ts.map +1 -0
  184. package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js +582 -0
  185. package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js.map +1 -0
  186. package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts +9 -0
  187. package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts.map +1 -0
  188. package/dist/core/i18n/locales/zh-cn/core-contract-final.js +55 -0
  189. package/dist/core/i18n/locales/zh-cn/core-contract-final.js.map +1 -0
  190. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts +11 -0
  191. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts.map +1 -0
  192. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js +455 -0
  193. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js.map +1 -0
  194. package/dist/core/i18n/locales/zh-cn/core-errors.d.ts +9 -0
  195. package/dist/core/i18n/locales/zh-cn/core-errors.d.ts.map +1 -0
  196. package/dist/core/i18n/locales/zh-cn/core-errors.js +191 -0
  197. package/dist/core/i18n/locales/zh-cn/core-errors.js.map +1 -0
  198. package/dist/core/i18n/locales/zh-cn/example.d.ts +7 -0
  199. package/dist/core/i18n/locales/zh-cn/example.d.ts.map +1 -0
  200. package/dist/core/i18n/locales/zh-cn/example.js +10 -0
  201. package/dist/core/i18n/locales/zh-cn/example.js.map +1 -0
  202. package/dist/core/i18n/locales/zh-cn/index.d.ts +2 -0
  203. package/dist/core/i18n/locales/zh-cn/index.d.ts.map +1 -0
  204. package/dist/core/i18n/locales/zh-cn/index.js +41 -0
  205. package/dist/core/i18n/locales/zh-cn/index.js.map +1 -0
  206. package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts +10 -0
  207. package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts.map +1 -0
  208. package/dist/core/i18n/locales/zh-cn/interactive-mode.js +267 -0
  209. package/dist/core/i18n/locales/zh-cn/interactive-mode.js.map +1 -0
  210. package/dist/core/i18n/locales/zh-cn/keybindings.d.ts +11 -0
  211. package/dist/core/i18n/locales/zh-cn/keybindings.d.ts.map +1 -0
  212. package/dist/core/i18n/locales/zh-cn/keybindings.js +67 -0
  213. package/dist/core/i18n/locales/zh-cn/keybindings.js.map +1 -0
  214. package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts +7 -0
  215. package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts.map +1 -0
  216. package/dist/core/i18n/locales/zh-cn/slash-commands.js +39 -0
  217. package/dist/core/i18n/locales/zh-cn/slash-commands.js.map +1 -0
  218. package/dist/core/i18n/locales/zh-cn/tui-builtin.d.ts +10 -0
  219. package/dist/core/i18n/locales/zh-cn/tui-builtin.d.ts.map +1 -0
  220. package/dist/core/i18n/locales/zh-cn/tui-builtin.js +15 -0
  221. package/dist/core/i18n/locales/zh-cn/tui-builtin.js.map +1 -0
  222. package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts +13 -0
  223. package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts.map +1 -0
  224. package/dist/core/i18n/locales/zh-cn/tui-components-misc.js +102 -0
  225. package/dist/core/i18n/locales/zh-cn/tui-components-misc.js.map +1 -0
  226. package/dist/core/i18n/locales/zh-cn/tui-components-selectors.d.ts +12 -0
  227. package/dist/core/i18n/locales/zh-cn/tui-components-selectors.d.ts.map +1 -0
  228. package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js +286 -0
  229. package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js.map +1 -0
  230. package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.d.ts +9 -0
  231. package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.d.ts.map +1 -0
  232. package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.js +79 -0
  233. package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.js.map +1 -0
  234. package/dist/core/i18n/locales/zh-cn/tui-self-owned.d.ts +8 -0
  235. package/dist/core/i18n/locales/zh-cn/tui-self-owned.d.ts.map +1 -0
  236. package/dist/core/i18n/locales/zh-cn/tui-self-owned.js +72 -0
  237. package/dist/core/i18n/locales/zh-cn/tui-self-owned.js.map +1 -0
  238. package/dist/core/keybindings.d.ts +15 -0
  239. package/dist/core/keybindings.d.ts.map +1 -1
  240. package/dist/core/keybindings.js +18 -0
  241. package/dist/core/keybindings.js.map +1 -1
  242. package/dist/core/logger.d.ts.map +1 -1
  243. package/dist/core/logger.js +5 -1
  244. package/dist/core/logger.js.map +1 -1
  245. package/dist/core/model-config.d.ts +0 -1
  246. package/dist/core/model-config.d.ts.map +1 -1
  247. package/dist/core/model-config.js +9 -1
  248. package/dist/core/model-config.js.map +1 -1
  249. package/dist/core/model-registry.d.ts.map +1 -1
  250. package/dist/core/model-registry.js +2 -1
  251. package/dist/core/model-registry.js.map +1 -1
  252. package/dist/core/model-runtime.d.ts.map +1 -1
  253. package/dist/core/model-runtime.js +11 -7
  254. package/dist/core/model-runtime.js.map +1 -1
  255. package/dist/core/package-install-host.d.ts.map +1 -1
  256. package/dist/core/package-install-host.js +4 -3
  257. package/dist/core/package-install-host.js.map +1 -1
  258. package/dist/core/package-manager.d.ts.map +1 -1
  259. package/dist/core/package-manager.js +15 -10
  260. package/dist/core/package-manager.js.map +1 -1
  261. package/dist/core/package-resource-collection.d.ts.map +1 -1
  262. package/dist/core/package-resource-collection.js +2 -1
  263. package/dist/core/package-resource-collection.js.map +1 -1
  264. package/dist/core/package-source.d.ts.map +1 -1
  265. package/dist/core/package-source.js +3 -2
  266. package/dist/core/package-source.js.map +1 -1
  267. package/dist/core/provider-composer.d.ts +2 -2
  268. package/dist/core/provider-composer.d.ts.map +1 -1
  269. package/dist/core/provider-composer.js +29 -21
  270. package/dist/core/provider-composer.js.map +1 -1
  271. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  272. package/dist/core/remote-catalog-provider.js +6 -2
  273. package/dist/core/remote-catalog-provider.js.map +1 -1
  274. package/dist/core/resolve-config-value.d.ts.map +1 -1
  275. package/dist/core/resolve-config-value.js +15 -5
  276. package/dist/core/resolve-config-value.js.map +1 -1
  277. package/dist/core/sdk.d.ts +27 -5
  278. package/dist/core/sdk.d.ts.map +1 -1
  279. package/dist/core/sdk.js +80 -55
  280. package/dist/core/sdk.js.map +1 -1
  281. package/dist/core/session-cwd.d.ts.map +1 -1
  282. package/dist/core/session-cwd.js +5 -2
  283. package/dist/core/session-cwd.js.map +1 -1
  284. package/dist/core/session-export.d.ts.map +1 -1
  285. package/dist/core/session-export.js +2 -1
  286. package/dist/core/session-export.js.map +1 -1
  287. package/dist/core/session-manager.d.ts.map +1 -1
  288. package/dist/core/session-manager.js +39 -29
  289. package/dist/core/session-manager.js.map +1 -1
  290. package/dist/core/session-storage.d.ts.map +1 -1
  291. package/dist/core/session-storage.js +3 -3
  292. package/dist/core/session-storage.js.map +1 -1
  293. package/dist/core/settings-manager.d.ts +20 -20
  294. package/dist/core/settings-manager.d.ts.map +1 -1
  295. package/dist/core/settings-manager.js +47 -59
  296. package/dist/core/settings-manager.js.map +1 -1
  297. package/dist/core/slash-commands.d.ts.map +1 -1
  298. package/dist/core/slash-commands.js +53 -32
  299. package/dist/core/slash-commands.js.map +1 -1
  300. package/dist/core/system-prompt.d.ts.map +1 -1
  301. package/dist/core/system-prompt.js +25 -2
  302. package/dist/core/system-prompt.js.map +1 -1
  303. package/dist/core/tools/bash.d.ts.map +1 -1
  304. package/dist/core/tools/bash.js +11 -7
  305. package/dist/core/tools/bash.js.map +1 -1
  306. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  307. package/dist/core/tools/edit-diff.js +9 -4
  308. package/dist/core/tools/edit-diff.js.map +1 -1
  309. package/dist/core/tools/edit.d.ts.map +1 -1
  310. package/dist/core/tools/edit.js +4 -3
  311. package/dist/core/tools/edit.js.map +1 -1
  312. package/dist/core/tools/index.d.ts.map +1 -1
  313. package/dist/core/tools/index.js +3 -2
  314. package/dist/core/tools/index.js.map +1 -1
  315. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  316. package/dist/core/tools/output-accumulator.js +2 -1
  317. package/dist/core/tools/output-accumulator.js.map +1 -1
  318. package/dist/core/tools/read.d.ts.map +1 -1
  319. package/dist/core/tools/read.js +6 -2
  320. package/dist/core/tools/read.js.map +1 -1
  321. package/dist/core/tools/write.d.ts.map +1 -1
  322. package/dist/core/tools/write.js +2 -1
  323. package/dist/core/tools/write.js.map +1 -1
  324. package/dist/durable/durable-service.d.ts.map +1 -1
  325. package/dist/durable/durable-service.js +25 -18
  326. package/dist/durable/durable-service.js.map +1 -1
  327. package/dist/host/checkpoint-commit.d.ts.map +1 -1
  328. package/dist/host/checkpoint-commit.js +2 -1
  329. package/dist/host/checkpoint-commit.js.map +1 -1
  330. package/dist/host/manual-compaction.d.ts.map +1 -1
  331. package/dist/host/manual-compaction.js +2 -1
  332. package/dist/host/manual-compaction.js.map +1 -1
  333. package/dist/host/output-projection.d.ts +0 -13
  334. package/dist/host/output-projection.d.ts.map +1 -1
  335. package/dist/host/output-projection.js +16 -2
  336. package/dist/host/output-projection.js.map +1 -1
  337. package/dist/host/summary-retry.d.ts.map +1 -1
  338. package/dist/host/summary-retry.js +3 -2
  339. package/dist/host/summary-retry.js.map +1 -1
  340. package/dist/main.d.ts.map +1 -1
  341. package/dist/main.js +97 -60
  342. package/dist/main.js.map +1 -1
  343. package/dist/modes/interactive/components/agents-view.d.ts.map +1 -1
  344. package/dist/modes/interactive/components/agents-view.js +18 -15
  345. package/dist/modes/interactive/components/agents-view.js.map +1 -1
  346. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  347. package/dist/modes/interactive/components/assistant-message.js +6 -5
  348. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  349. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  350. package/dist/modes/interactive/components/bash-execution.js +12 -7
  351. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  352. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  353. package/dist/modes/interactive/components/bordered-loader.js +2 -1
  354. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  355. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  356. package/dist/modes/interactive/components/branch-summary-message.js +6 -5
  357. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  358. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  359. package/dist/modes/interactive/components/compaction-summary-message.js +9 -5
  360. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  361. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  362. package/dist/modes/interactive/components/config-selector.js +18 -15
  363. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  364. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  365. package/dist/modes/interactive/components/custom-entry.js +2 -1
  366. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  367. package/dist/modes/interactive/components/dialog-editor.d.ts.map +1 -1
  368. package/dist/modes/interactive/components/dialog-editor.js +5 -4
  369. package/dist/modes/interactive/components/dialog-editor.js.map +1 -1
  370. package/dist/modes/interactive/components/dialog-input.d.ts.map +1 -1
  371. package/dist/modes/interactive/components/dialog-input.js +2 -1
  372. package/dist/modes/interactive/components/dialog-input.js.map +1 -1
  373. package/dist/modes/interactive/components/dialog-selector.d.ts.map +1 -1
  374. package/dist/modes/interactive/components/dialog-selector.js +4 -3
  375. package/dist/modes/interactive/components/dialog-selector.js.map +1 -1
  376. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  377. package/dist/modes/interactive/components/first-time-setup.js +11 -10
  378. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  379. package/dist/modes/interactive/components/footer.d.ts +0 -2
  380. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  381. package/dist/modes/interactive/components/footer.js +8 -10
  382. package/dist/modes/interactive/components/footer.js.map +1 -1
  383. package/dist/modes/interactive/components/index.d.ts +1 -0
  384. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  385. package/dist/modes/interactive/components/index.js +1 -0
  386. package/dist/modes/interactive/components/index.js.map +1 -1
  387. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  388. package/dist/modes/interactive/components/keybinding-hints.js +3 -2
  389. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  390. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  391. package/dist/modes/interactive/components/login-dialog.js +12 -11
  392. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  393. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
  394. package/dist/modes/interactive/components/mermaid.js +6 -2
  395. package/dist/modes/interactive/components/mermaid.js.map +1 -1
  396. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  397. package/dist/modes/interactive/components/model-selector.js +28 -16
  398. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  399. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  400. package/dist/modes/interactive/components/oauth-selector.js +10 -9
  401. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  402. package/dist/modes/interactive/components/plugin-manager-entry.d.ts.map +1 -1
  403. package/dist/modes/interactive/components/plugin-manager-entry.js +22 -13
  404. package/dist/modes/interactive/components/plugin-manager-entry.js.map +1 -1
  405. package/dist/modes/interactive/components/plugin-selection-entry.d.ts.map +1 -1
  406. package/dist/modes/interactive/components/plugin-selection-entry.js +27 -12
  407. package/dist/modes/interactive/components/plugin-selection-entry.js.map +1 -1
  408. package/dist/modes/interactive/components/queue-manager-selector.d.ts +60 -0
  409. package/dist/modes/interactive/components/queue-manager-selector.d.ts.map +1 -0
  410. package/dist/modes/interactive/components/queue-manager-selector.js +166 -0
  411. package/dist/modes/interactive/components/queue-manager-selector.js.map +1 -0
  412. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  413. package/dist/modes/interactive/components/scoped-models-selector.js +16 -14
  414. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  415. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  416. package/dist/modes/interactive/components/session-selector.js +43 -31
  417. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  418. package/dist/modes/interactive/components/settings-selector.d.ts +4 -6
  419. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  420. package/dist/modes/interactive/components/settings-selector.js +115 -120
  421. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  422. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
  423. package/dist/modes/interactive/components/settings-submenu.js +5 -4
  424. package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
  425. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  426. package/dist/modes/interactive/components/show-images-selector.js +3 -2
  427. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  428. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  429. package/dist/modes/interactive/components/skill-invocation-message.js +4 -3
  430. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  431. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  432. package/dist/modes/interactive/components/status-indicator.js +14 -5
  433. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  434. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  435. package/dist/modes/interactive/components/theme-selector.js +2 -1
  436. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  437. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  438. package/dist/modes/interactive/components/thinking-selector.js +11 -4
  439. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  440. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  441. package/dist/modes/interactive/components/tool-execution.js +8 -3
  442. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  443. package/dist/modes/interactive/components/tree-list.d.ts.map +1 -1
  444. package/dist/modes/interactive/components/tree-list.js +7 -6
  445. package/dist/modes/interactive/components/tree-list.js.map +1 -1
  446. package/dist/modes/interactive/components/tree-render.d.ts.map +1 -1
  447. package/dist/modes/interactive/components/tree-render.js +28 -23
  448. package/dist/modes/interactive/components/tree-render.js.map +1 -1
  449. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  450. package/dist/modes/interactive/components/tree-selector.js +9 -7
  451. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  452. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  453. package/dist/modes/interactive/components/user-message-selector.js +5 -4
  454. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  455. package/dist/modes/interactive/components/workflow-view.d.ts.map +1 -1
  456. package/dist/modes/interactive/components/workflow-view.js +36 -21
  457. package/dist/modes/interactive/components/workflow-view.js.map +1 -1
  458. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  459. package/dist/modes/interactive/external-editor.js +2 -1
  460. package/dist/modes/interactive/external-editor.js.map +1 -1
  461. package/dist/modes/interactive/interactive-auth.d.ts.map +1 -1
  462. package/dist/modes/interactive/interactive-auth.js +71 -40
  463. package/dist/modes/interactive/interactive-auth.js.map +1 -1
  464. package/dist/modes/interactive/interactive-commands.d.ts +1 -0
  465. package/dist/modes/interactive/interactive-commands.d.ts.map +1 -1
  466. package/dist/modes/interactive/interactive-commands.js +3 -0
  467. package/dist/modes/interactive/interactive-commands.js.map +1 -1
  468. package/dist/modes/interactive/interactive-dialog-ui.d.ts.map +1 -1
  469. package/dist/modes/interactive/interactive-dialog-ui.js +5 -5
  470. package/dist/modes/interactive/interactive-dialog-ui.js.map +1 -1
  471. package/dist/modes/interactive/interactive-format.d.ts.map +1 -1
  472. package/dist/modes/interactive/interactive-format.js +34 -18
  473. package/dist/modes/interactive/interactive-format.js.map +1 -1
  474. package/dist/modes/interactive/interactive-helpers.d.ts.map +1 -1
  475. package/dist/modes/interactive/interactive-helpers.js +7 -2
  476. package/dist/modes/interactive/interactive-helpers.js.map +1 -1
  477. package/dist/modes/interactive/interactive-mode.d.ts +4 -2
  478. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  479. package/dist/modes/interactive/interactive-mode.js +350 -279
  480. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  481. package/dist/modes/interactive/interactive-selectors.d.ts +9 -0
  482. package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
  483. package/dist/modes/interactive/interactive-selectors.js +79 -25
  484. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  485. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  486. package/dist/modes/interactive/theme/theme-controller.js +5 -1
  487. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  488. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  489. package/dist/modes/interactive/theme/theme.js +26 -23
  490. package/dist/modes/interactive/theme/theme.js.map +1 -1
  491. package/dist/modes/json-event.d.ts.map +1 -1
  492. package/dist/modes/json-event.js +3 -2
  493. package/dist/modes/json-event.js.map +1 -1
  494. package/dist/modes/print-mode.d.ts.map +1 -1
  495. package/dist/modes/print-mode.js +3 -2
  496. package/dist/modes/print-mode.js.map +1 -1
  497. package/dist/modes/rpc/rpc-client.d.ts +0 -8
  498. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  499. package/dist/modes/rpc/rpc-client.js +3 -14
  500. package/dist/modes/rpc/rpc-client.js.map +1 -1
  501. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  502. package/dist/modes/rpc/rpc-mode.js +0 -9
  503. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  504. package/dist/modes/rpc/rpc-types.d.ts +0 -19
  505. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  506. package/dist/modes/rpc/rpc-types.js.map +1 -1
  507. package/dist/package-manager-cli.d.ts.map +1 -1
  508. package/dist/package-manager-cli.js +28 -13
  509. package/dist/package-manager-cli.js.map +1 -1
  510. package/dist/plugins/ecosystem/catalog.d.ts.map +1 -1
  511. package/dist/plugins/ecosystem/catalog.js +3 -2
  512. package/dist/plugins/ecosystem/catalog.js.map +1 -1
  513. package/dist/plugins/ecosystem/cli.d.ts.map +1 -1
  514. package/dist/plugins/ecosystem/cli.js +2 -1
  515. package/dist/plugins/ecosystem/cli.js.map +1 -1
  516. package/dist/plugins/ecosystem/default-plugin-market.d.ts.map +1 -1
  517. package/dist/plugins/ecosystem/default-plugin-market.js +3 -2
  518. package/dist/plugins/ecosystem/default-plugin-market.js.map +1 -1
  519. package/dist/plugins/ecosystem/distribution.d.ts.map +1 -1
  520. package/dist/plugins/ecosystem/distribution.js +2 -1
  521. package/dist/plugins/ecosystem/distribution.js.map +1 -1
  522. package/dist/plugins/ecosystem/installer.d.ts.map +1 -1
  523. package/dist/plugins/ecosystem/installer.js +3 -2
  524. package/dist/plugins/ecosystem/installer.js.map +1 -1
  525. package/dist/plugins/ecosystem/node-disk-registry-source.d.ts.map +1 -1
  526. package/dist/plugins/ecosystem/node-disk-registry-source.js +20 -17
  527. package/dist/plugins/ecosystem/node-disk-registry-source.js.map +1 -1
  528. package/dist/plugins/ecosystem/node-distribution-host.d.ts.map +1 -1
  529. package/dist/plugins/ecosystem/node-distribution-host.js +35 -34
  530. package/dist/plugins/ecosystem/node-distribution-host.js.map +1 -1
  531. package/dist/plugins/ecosystem/node-npm-registry-source.d.ts.map +1 -1
  532. package/dist/plugins/ecosystem/node-npm-registry-source.js +35 -34
  533. package/dist/plugins/ecosystem/node-npm-registry-source.js.map +1 -1
  534. package/dist/plugins/ecosystem/node-package-install-host.d.ts.map +1 -1
  535. package/dist/plugins/ecosystem/node-package-install-host.js +9 -8
  536. package/dist/plugins/ecosystem/node-package-install-host.js.map +1 -1
  537. package/dist/plugins/ecosystem/node-package-install-persistence.d.ts.map +1 -1
  538. package/dist/plugins/ecosystem/node-package-install-persistence.js +4 -3
  539. package/dist/plugins/ecosystem/node-package-install-persistence.js.map +1 -1
  540. package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts +9 -2
  541. package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts.map +1 -1
  542. package/dist/plugins/ecosystem/node-plugin-bootstrap.js +44 -5
  543. package/dist/plugins/ecosystem/node-plugin-bootstrap.js.map +1 -1
  544. package/dist/plugins/ecosystem/node-plugin-trust-root.d.ts.map +1 -1
  545. package/dist/plugins/ecosystem/node-plugin-trust-root.js +10 -9
  546. package/dist/plugins/ecosystem/node-plugin-trust-root.js.map +1 -1
  547. package/dist/plugins/ecosystem/node-registry-source.d.ts.map +1 -1
  548. package/dist/plugins/ecosystem/node-registry-source.js +31 -30
  549. package/dist/plugins/ecosystem/node-registry-source.js.map +1 -1
  550. package/dist/plugins/ecosystem/node-release-package-source.d.ts.map +1 -1
  551. package/dist/plugins/ecosystem/node-release-package-source.js +30 -29
  552. package/dist/plugins/ecosystem/node-release-package-source.js.map +1 -1
  553. package/dist/plugins/ecosystem/node-tar-writer.d.ts.map +1 -1
  554. package/dist/plugins/ecosystem/node-tar-writer.js +11 -10
  555. package/dist/plugins/ecosystem/node-tar-writer.js.map +1 -1
  556. package/dist/plugins/ecosystem/node-url-package-source.d.ts.map +1 -1
  557. package/dist/plugins/ecosystem/node-url-package-source.js +21 -20
  558. package/dist/plugins/ecosystem/node-url-package-source.js.map +1 -1
  559. package/dist/plugins/ecosystem/plugin-acquisition.d.ts.map +1 -1
  560. package/dist/plugins/ecosystem/plugin-acquisition.js +3 -2
  561. package/dist/plugins/ecosystem/plugin-acquisition.js.map +1 -1
  562. package/dist/plugins/ecosystem/plugin-bootstrap.d.ts +9 -1
  563. package/dist/plugins/ecosystem/plugin-bootstrap.d.ts.map +1 -1
  564. package/dist/plugins/ecosystem/plugin-bootstrap.js +5 -0
  565. package/dist/plugins/ecosystem/plugin-bootstrap.js.map +1 -1
  566. package/dist/plugins/ecosystem/registry-cli-adapter.d.ts.map +1 -1
  567. package/dist/plugins/ecosystem/registry-cli-adapter.js +2 -1
  568. package/dist/plugins/ecosystem/registry-cli-adapter.js.map +1 -1
  569. package/dist/plugins/ecosystem/registry.d.ts.map +1 -1
  570. package/dist/plugins/ecosystem/registry.js +35 -32
  571. package/dist/plugins/ecosystem/registry.js.map +1 -1
  572. package/dist/plugins/ecosystem/resolver.d.ts.map +1 -1
  573. package/dist/plugins/ecosystem/resolver.js +3 -2
  574. package/dist/plugins/ecosystem/resolver.js.map +1 -1
  575. package/dist/plugins/ecosystem/selection-store.d.ts.map +1 -1
  576. package/dist/plugins/ecosystem/selection-store.js +11 -10
  577. package/dist/plugins/ecosystem/selection-store.js.map +1 -1
  578. package/dist/plugins/ecosystem/selection.d.ts.map +1 -1
  579. package/dist/plugins/ecosystem/selection.js +8 -7
  580. package/dist/plugins/ecosystem/selection.js.map +1 -1
  581. package/dist/plugins/ecosystem/state.d.ts.map +1 -1
  582. package/dist/plugins/ecosystem/state.js +24 -23
  583. package/dist/plugins/ecosystem/state.js.map +1 -1
  584. package/dist/plugins/ecosystem/updates.d.ts.map +1 -1
  585. package/dist/plugins/ecosystem/updates.js +5 -4
  586. package/dist/plugins/ecosystem/updates.js.map +1 -1
  587. package/dist/plugins/mcp-http.d.ts +0 -17
  588. package/dist/plugins/mcp-http.d.ts.map +1 -1
  589. package/dist/plugins/mcp-http.js +30 -7
  590. package/dist/plugins/mcp-http.js.map +1 -1
  591. package/dist/plugins/plugin-supervisor.d.ts.map +1 -1
  592. package/dist/plugins/plugin-supervisor.js +19 -1
  593. package/dist/plugins/plugin-supervisor.js.map +1 -1
  594. package/dist/profile/first-roles.d.ts.map +1 -1
  595. package/dist/profile/first-roles.js +10 -1
  596. package/dist/profile/first-roles.js.map +1 -1
  597. package/dist/profile/goal-plugin.d.ts.map +1 -1
  598. package/dist/profile/goal-plugin.js +24 -5
  599. package/dist/profile/goal-plugin.js.map +1 -1
  600. package/dist/profile/identity.d.ts.map +1 -1
  601. package/dist/profile/identity.js +7 -6
  602. package/dist/profile/identity.js.map +1 -1
  603. package/dist/profile/lock.d.ts.map +1 -1
  604. package/dist/profile/lock.js +15 -1
  605. package/dist/profile/lock.js.map +1 -1
  606. package/dist/profile/plan-plugin.d.ts.map +1 -1
  607. package/dist/profile/plan-plugin.js +26 -13
  608. package/dist/profile/plan-plugin.js.map +1 -1
  609. package/dist/profile/plugin-profiles.d.ts.map +1 -1
  610. package/dist/profile/plugin-profiles.js +2 -1
  611. package/dist/profile/plugin-profiles.js.map +1 -1
  612. package/dist/profile/policy-manifest.d.ts.map +1 -1
  613. package/dist/profile/policy-manifest.js +5 -4
  614. package/dist/profile/policy-manifest.js.map +1 -1
  615. package/dist/profile/profile-registry.d.ts +0 -12
  616. package/dist/profile/profile-registry.d.ts.map +1 -1
  617. package/dist/profile/profile-registry.js +14 -1
  618. package/dist/profile/profile-registry.js.map +1 -1
  619. package/dist/profile/role-catalog.d.ts +0 -1
  620. package/dist/profile/role-catalog.d.ts.map +1 -1
  621. package/dist/profile/role-catalog.js +17 -15
  622. package/dist/profile/role-catalog.js.map +1 -1
  623. package/dist/profile/role-orchestrator.d.ts.map +1 -1
  624. package/dist/profile/role-orchestrator.js +8 -7
  625. package/dist/profile/role-orchestrator.js.map +1 -1
  626. package/dist/profile/role-runner.d.ts.map +1 -1
  627. package/dist/profile/role-runner.js +3 -2
  628. package/dist/profile/role-runner.js.map +1 -1
  629. package/dist/profile/root-facade.d.ts.map +1 -1
  630. package/dist/profile/root-facade.js +2 -1
  631. package/dist/profile/root-facade.js.map +1 -1
  632. package/dist/profile/skill-discovery-wiring.d.ts.map +1 -1
  633. package/dist/profile/skill-discovery-wiring.js +7 -2
  634. package/dist/profile/skill-discovery-wiring.js.map +1 -1
  635. package/dist/profile/state-store.d.ts.map +1 -1
  636. package/dist/profile/state-store.js +13 -9
  637. package/dist/profile/state-store.js.map +1 -1
  638. package/dist/profile/todo-plugin.d.ts.map +1 -1
  639. package/dist/profile/todo-plugin.js +9 -4
  640. package/dist/profile/todo-plugin.js.map +1 -1
  641. package/dist/profiles/builtin-suites.d.ts +13 -6
  642. package/dist/profiles/builtin-suites.d.ts.map +1 -1
  643. package/dist/profiles/builtin-suites.js +15 -6
  644. package/dist/profiles/builtin-suites.js.map +1 -1
  645. package/dist/profiles/suite-loader.d.ts +25 -1
  646. package/dist/profiles/suite-loader.d.ts.map +1 -1
  647. package/dist/profiles/suite-loader.js +34 -9
  648. package/dist/profiles/suite-loader.js.map +1 -1
  649. package/dist/remote/server-entry.d.ts.map +1 -1
  650. package/dist/remote/server-entry.js +3 -2
  651. package/dist/remote/server-entry.js.map +1 -1
  652. package/dist/remote/session-source.d.ts.map +1 -1
  653. package/dist/remote/session-source.js +8 -4
  654. package/dist/remote/session-source.js.map +1 -1
  655. package/dist/share/session-share.d.ts.map +1 -1
  656. package/dist/share/session-share.js +14 -2
  657. package/dist/share/session-share.js.map +1 -1
  658. package/dist/testing/plugin-testkit.d.ts.map +1 -1
  659. package/dist/testing/plugin-testkit.js +4 -3
  660. package/dist/testing/plugin-testkit.js.map +1 -1
  661. package/dist/testing/runtime-delivery-queue.d.ts.map +1 -1
  662. package/dist/testing/runtime-delivery-queue.js +2 -1
  663. package/dist/testing/runtime-delivery-queue.js.map +1 -1
  664. package/dist/testing/session-plugin-testkit.d.ts.map +1 -1
  665. package/dist/testing/session-plugin-testkit.js +10 -7
  666. package/dist/testing/session-plugin-testkit.js.map +1 -1
  667. package/dist/utils/ansi.d.ts.map +1 -1
  668. package/dist/utils/ansi.js +2 -1
  669. package/dist/utils/ansi.js.map +1 -1
  670. package/dist/utils/clipboard.d.ts.map +1 -1
  671. package/dist/utils/clipboard.js +7 -6
  672. package/dist/utils/clipboard.js.map +1 -1
  673. package/dist/utils/image-resize-worker.d.ts.map +1 -1
  674. package/dist/utils/image-resize-worker.js +3 -2
  675. package/dist/utils/image-resize-worker.js.map +1 -1
  676. package/dist/utils/photon.d.ts +2 -2
  677. package/dist/utils/photon.d.ts.map +1 -1
  678. package/dist/utils/photon.js +2 -2
  679. package/dist/utils/photon.js.map +1 -1
  680. package/dist/utils/shell.d.ts.map +1 -1
  681. package/dist/utils/shell.js +9 -8
  682. package/dist/utils/shell.js.map +1 -1
  683. package/dist/utils/tools-manager.d.ts.map +1 -1
  684. package/dist/utils/tools-manager.js +23 -13
  685. package/dist/utils/tools-manager.js.map +1 -1
  686. package/dist/utils/version-check.d.ts.map +1 -1
  687. package/dist/utils/version-check.js +5 -1
  688. package/dist/utils/version-check.js.map +1 -1
  689. package/docs/compaction.md +1 -3
  690. package/docs/docs.json +4 -0
  691. package/docs/index.md +1 -0
  692. package/docs/keybindings.md +3 -0
  693. package/docs/mcp.md +103 -0
  694. package/docs/models.md +14 -22
  695. package/docs/providers.md +0 -1
  696. package/docs/quickstart.md +1 -1
  697. package/docs/rpc.md +1 -26
  698. package/docs/sdk.md +4 -6
  699. package/docs/settings.md +10 -12
  700. package/docs/skills.md +1 -9
  701. package/docs/terminal-setup.md +2 -3
  702. package/docs/usage.md +7 -6
  703. package/examples/extensions/with-deps/package-lock.json +2 -2
  704. package/examples/extensions/with-deps/package.json +1 -1
  705. package/examples/extensions/with-deps/plugin.json +1 -1
  706. package/examples/sdk/10-settings.ts +2 -4
  707. package/examples/sdk/12-full-control.ts +1 -2
  708. package/package.json +1 -3
  709. package/dist/bundle/chunks/chunk-EALJ5DDX.js +0 -1452
  710. package/dist/core/extensions/microcompact.d.ts +0 -80
  711. package/dist/core/extensions/microcompact.d.ts.map +0 -1
  712. package/dist/core/extensions/microcompact.js +0 -134
  713. package/dist/core/extensions/microcompact.js.map +0 -1
  714. package/dist/server/create-harness.d.ts +0 -26
  715. package/dist/server/create-harness.d.ts.map +0 -1
  716. package/dist/server/create-harness.js +0 -106
  717. package/dist/server/create-harness.js.map +0 -1
@@ -1,3 +1,4 @@
1
+ import { t } from "../../core/i18n/index.js";
1
2
  import { buildPluginCatalogV1 } from "./catalog.js";
2
3
  /** Version of the user-owned, host-independent plugin selection snapshot. */
3
4
  export const PLUGIN_SELECTION_VERSION_V1 = 1;
@@ -15,10 +16,10 @@ export class PluginSelectionErrorV1 extends Error {
15
16
  }
16
17
  function validateId(value, label) {
17
18
  if (typeof value !== "string" || value.trim().length === 0) {
18
- throw new PluginSelectionErrorV1(label === "profileId" ? "invalid_profile_id" : "invalid_plugin_id", `${label} must be a non-empty string`, typeof value === "string" ? value : undefined);
19
+ throw new PluginSelectionErrorV1(label === "profileId" ? "invalid_profile_id" : "invalid_plugin_id", t("{label} must be a non-empty string", { label }), typeof value === "string" ? value : undefined);
19
20
  }
20
21
  if (value.length > MAX_PLUGIN_SELECTION_ID_CHARS_V1) {
21
- throw new PluginSelectionErrorV1(label === "profileId" ? "profile_id_too_long" : "plugin_id_too_long", `${label} must be at most ${MAX_PLUGIN_SELECTION_ID_CHARS_V1} characters`, value);
22
+ throw new PluginSelectionErrorV1(label === "profileId" ? "profile_id_too_long" : "plugin_id_too_long", t("{label} must be at most {max} characters", { label, max: MAX_PLUGIN_SELECTION_ID_CHARS_V1 }), value);
22
23
  }
23
24
  return value;
24
25
  }
@@ -26,14 +27,14 @@ function normalizeIds(ids, label) {
26
27
  if (ids === undefined)
27
28
  return [];
28
29
  if (!Array.isArray(ids) || ids.length > MAX_PLUGIN_SELECTION_IDS_V1) {
29
- throw new PluginSelectionErrorV1("too_many_plugin_ids", `${label} must contain at most ${MAX_PLUGIN_SELECTION_IDS_V1} plugin IDs`);
30
+ throw new PluginSelectionErrorV1("too_many_plugin_ids", t("{label} must contain at most {max} plugin IDs", { label, max: MAX_PLUGIN_SELECTION_IDS_V1 }));
30
31
  }
31
32
  const seen = new Set();
32
33
  const normalized = [];
33
34
  for (const candidate of ids) {
34
35
  const id = validateId(candidate, "pluginId");
35
36
  if (seen.has(id)) {
36
- throw new PluginSelectionErrorV1("duplicate_plugin_id", `${label} contains duplicate plugin ID: ${id}`, id);
37
+ throw new PluginSelectionErrorV1("duplicate_plugin_id", t("{label} contains duplicate plugin ID: {id}", { label, id }), id);
37
38
  }
38
39
  seen.add(id);
39
40
  normalized.push(id);
@@ -44,7 +45,7 @@ function normalizeIds(ids, label) {
44
45
  function assertKnownIds(ids, knownIds) {
45
46
  for (const id of ids) {
46
47
  if (!knownIds.has(id)) {
47
- throw new PluginSelectionErrorV1("unknown_plugin_id", `Selection references unknown plugin ID: ${id}`, id);
48
+ throw new PluginSelectionErrorV1("unknown_plugin_id", t("Selection references unknown plugin ID: {id}", { id }), id);
48
49
  }
49
50
  }
50
51
  }
@@ -70,7 +71,7 @@ export function resolvePluginSelectionV1(input) {
70
71
  const knownIds = new Set(input.manifests.map((manifest) => manifest.id));
71
72
  const provisional = createPluginSelectionV1(input.selection);
72
73
  if (input.selection.selectedPluginIds === undefined && knownIds.size > MAX_PLUGIN_SELECTION_IDS_V1) {
73
- throw new PluginSelectionErrorV1("too_many_plugin_ids", `discovered plugin IDs exceed the selection limit of ${MAX_PLUGIN_SELECTION_IDS_V1}`);
74
+ throw new PluginSelectionErrorV1("too_many_plugin_ids", t("discovered plugin IDs exceed the selection limit of {limit}", { limit: MAX_PLUGIN_SELECTION_IDS_V1 }));
74
75
  }
75
76
  const selectedPluginIds = input.selection.selectedPluginIds === undefined
76
77
  ? Object.freeze([...knownIds].sort((a, b) => a.localeCompare(b)))
@@ -101,7 +102,7 @@ export function resolvePluginSelectionV1(input) {
101
102
  const selectedEntryIds = new Set(selectedCatalog.entries.map((entry) => entry.pluginId));
102
103
  const omitted = selection.selectedPluginIds.find((id) => !selectedEntryIds.has(id));
103
104
  if (omitted !== undefined) {
104
- throw new PluginSelectionErrorV1("catalog_truncated", `Catalog truncation omitted selected plugin ID: ${omitted}`, omitted);
105
+ throw new PluginSelectionErrorV1("catalog_truncated", t("Catalog truncation omitted selected plugin ID: {id}", { id: omitted }), omitted);
105
106
  }
106
107
  }
107
108
  const entries = Object.freeze(selectedCatalog.entries);
@@ -1 +1 @@
1
- {"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/selection.ts"],"names":[],"mappings":"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","sourcesContent":["import { buildPluginCatalogV1, type PluginCatalogEntryV1, type PluginCatalogSnapshotV1 } from \"./catalog.ts\";\nimport type { CapabilityRefV1, HostFactsV1, PluginDiagnosticV1, PluginManifestV1 } from \"./types.ts\";\n\n/** Version of the user-owned, host-independent plugin selection snapshot. */\nexport const PLUGIN_SELECTION_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_SELECTION_ID_CHARS_V1 = 128;\nexport const MAX_PLUGIN_SELECTION_IDS_V1 = 128;\n\nexport interface PluginSelectionV1 {\n\treadonly version: typeof PLUGIN_SELECTION_VERSION_V1;\n\treadonly profileId: string;\n\treadonly selectedPluginIds: readonly string[];\n\treadonly disabledPluginIds: readonly string[];\n}\n\nexport type PluginSelectionErrorCodeV1 =\n\t| \"invalid_profile_id\"\n\t| \"profile_id_too_long\"\n\t| \"invalid_plugin_id\"\n\t| \"plugin_id_too_long\"\n\t| \"too_many_plugin_ids\"\n\t| \"duplicate_plugin_id\"\n\t| \"unknown_plugin_id\"\n\t| \"catalog_truncated\";\n\nexport class PluginSelectionErrorV1 extends Error {\n\treadonly code: PluginSelectionErrorCodeV1;\n\treadonly pluginId?: string;\n\n\tconstructor(code: PluginSelectionErrorCodeV1, message: string, pluginId?: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PluginSelectionErrorV1\";\n\t\tthis.code = code;\n\t\tthis.pluginId = pluginId;\n\t}\n}\n\n/**\n * A pure catalog projection for a user selection. It never downloads,\n * writes, installs, activates, or mutates a plugin. The host owns those\n * operations through the separate installer contract.\n */\nexport interface PluginSelectionResolutionV1 {\n\treadonly selection: PluginSelectionV1;\n\t/** The bounded catalog of every discovered manifest. */\n\treadonly catalog: PluginCatalogSnapshotV1;\n\t/** Entries requested by the selection, in catalog order. */\n\treadonly entries: readonly PluginCatalogEntryV1[];\n\treadonly diagnostics: readonly PluginDiagnosticV1[];\n}\n\nexport interface PluginSelectionInputV1 {\n\treadonly profileId: string;\n\t/** Omitted means all discovered plugin IDs; [] means no plugin. */\n\treadonly selectedPluginIds?: readonly string[];\n\treadonly disabledPluginIds?: readonly string[];\n}\n\nfunction validateId(value: unknown, label: \"profileId\" | \"pluginId\"): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\tthrow new PluginSelectionErrorV1(\n\t\t\tlabel === \"profileId\" ? \"invalid_profile_id\" : \"invalid_plugin_id\",\n\t\t\t`${label} must be a non-empty string`,\n\t\t\ttypeof value === \"string\" ? value : undefined,\n\t\t);\n\t}\n\tif (value.length > MAX_PLUGIN_SELECTION_ID_CHARS_V1) {\n\t\tthrow new PluginSelectionErrorV1(\n\t\t\tlabel === \"profileId\" ? \"profile_id_too_long\" : \"plugin_id_too_long\",\n\t\t\t`${label} must be at most ${MAX_PLUGIN_SELECTION_ID_CHARS_V1} characters`,\n\t\t\tvalue,\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction normalizeIds(\n\tids: readonly string[] | undefined,\n\tlabel: \"selectedPluginIds\" | \"disabledPluginIds\",\n): readonly string[] {\n\tif (ids === undefined) return [];\n\tif (!Array.isArray(ids) || ids.length > MAX_PLUGIN_SELECTION_IDS_V1) {\n\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\"too_many_plugin_ids\",\n\t\t\t`${label} must contain at most ${MAX_PLUGIN_SELECTION_IDS_V1} plugin IDs`,\n\t\t);\n\t}\n\tconst seen = new Set<string>();\n\tconst normalized: string[] = [];\n\tfor (const candidate of ids) {\n\t\tconst id = validateId(candidate, \"pluginId\");\n\t\tif (seen.has(id)) {\n\t\t\tthrow new PluginSelectionErrorV1(\"duplicate_plugin_id\", `${label} contains duplicate plugin ID: ${id}`, id);\n\t\t}\n\t\tseen.add(id);\n\t\tnormalized.push(id);\n\t}\n\tnormalized.sort((left, right) => left.localeCompare(right));\n\treturn Object.freeze(normalized);\n}\n\nfunction assertKnownIds(ids: readonly string[], knownIds: ReadonlySet<string>): void {\n\tfor (const id of ids) {\n\t\tif (!knownIds.has(id)) {\n\t\t\tthrow new PluginSelectionErrorV1(\"unknown_plugin_id\", `Selection references unknown plugin ID: ${id}`, id);\n\t\t}\n\t}\n}\n\n/** Validate and freeze a selection without resolving or touching a host. */\nexport function createPluginSelectionV1(input: PluginSelectionInputV1): PluginSelectionV1 {\n\tconst profileId = validateId(input.profileId, \"profileId\");\n\tconst selectedPluginIds = normalizeIds(input.selectedPluginIds, \"selectedPluginIds\");\n\tconst disabledPluginIds = normalizeIds(input.disabledPluginIds, \"disabledPluginIds\");\n\treturn Object.freeze({\n\t\tversion: PLUGIN_SELECTION_VERSION_V1,\n\t\tprofileId,\n\t\tselectedPluginIds,\n\t\tdisabledPluginIds,\n\t});\n}\n\n/**\n * Resolve a selection to bounded catalog entries and diagnostics. This is a\n * read-only planning operation; it does not imply that any plugin is enabled.\n */\nexport function resolvePluginSelectionV1(input: {\n\treadonly selection: PluginSelectionInputV1;\n\treadonly manifests: readonly PluginManifestV1[];\n\treadonly host: HostFactsV1;\n\treadonly required?: boolean;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\treadonly maxEntries?: number;\n}): PluginSelectionResolutionV1 {\n\tfor (const manifest of input.manifests) validateId(manifest.id, \"pluginId\");\n\tconst knownIds = new Set(input.manifests.map((manifest) => manifest.id));\n\tconst provisional = createPluginSelectionV1(input.selection);\n\tif (input.selection.selectedPluginIds === undefined && knownIds.size > MAX_PLUGIN_SELECTION_IDS_V1) {\n\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\"too_many_plugin_ids\",\n\t\t\t`discovered plugin IDs exceed the selection limit of ${MAX_PLUGIN_SELECTION_IDS_V1}`,\n\t\t);\n\t}\n\tconst selectedPluginIds =\n\t\tinput.selection.selectedPluginIds === undefined\n\t\t\t? Object.freeze([...knownIds].sort((a, b) => a.localeCompare(b)))\n\t\t\t: provisional.selectedPluginIds;\n\tconst selection = Object.freeze({ ...provisional, selectedPluginIds });\n\tassertKnownIds(selection.selectedPluginIds, knownIds);\n\tassertKnownIds(selection.disabledPluginIds, knownIds);\n\tconst catalog = buildPluginCatalogV1({\n\t\tmanifests: input.manifests,\n\t\thost: input.host,\n\t\trequired: input.required,\n\t\tdisabledPluginIds: selection.disabledPluginIds,\n\t\tavailableCapabilities: input.availableCapabilities,\n\t\tmaxEntries: input.maxEntries,\n\t});\n\tconst selected = new Set(selection.selectedPluginIds);\n\t// Resolve selected manifests separately so a bounded/truncated all-manifest\n\t// catalog cannot silently hide an explicitly selected plugin.\n\tconst selectedCatalog = buildPluginCatalogV1({\n\t\tmanifests: input.manifests.filter((manifest) => selected.has(manifest.id)),\n\t\thost: input.host,\n\t\trequired: input.required,\n\t\tdisabledPluginIds: selection.disabledPluginIds,\n\t\tavailableCapabilities: input.availableCapabilities,\n\t\tmaxEntries: Math.max(input.maxEntries ?? MAX_PLUGIN_SELECTION_IDS_V1, selection.selectedPluginIds.length),\n\t});\n\tif (selectedCatalog.truncated) {\n\t\tconst selectedEntryIds = new Set(selectedCatalog.entries.map((entry) => entry.pluginId));\n\t\tconst omitted = selection.selectedPluginIds.find((id) => !selectedEntryIds.has(id));\n\t\tif (omitted !== undefined) {\n\t\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\t\"catalog_truncated\",\n\t\t\t\t`Catalog truncation omitted selected plugin ID: ${omitted}`,\n\t\t\t\tomitted,\n\t\t\t);\n\t\t}\n\t}\n\tconst entries = Object.freeze(selectedCatalog.entries);\n\tconst diagnostics = Object.freeze(entries.flatMap((entry) => entry.resolution.diagnostics));\n\treturn Object.freeze({ selection, catalog, entries, diagnostics });\n}\n\n/** Serialize only the stable selection data; no manifest, host, or payload is included. */\nexport function serializePluginSelectionV1(selection: PluginSelectionV1): string {\n\tconst normalized = createPluginSelectionV1(selection);\n\treturn JSON.stringify(normalized);\n}\n"]}
1
+ {"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/selection.ts"],"names":[],"mappings":"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","sourcesContent":["import { t } from \"../../core/i18n/index.ts\";\nimport { buildPluginCatalogV1, type PluginCatalogEntryV1, type PluginCatalogSnapshotV1 } from \"./catalog.ts\";\nimport type { CapabilityRefV1, HostFactsV1, PluginDiagnosticV1, PluginManifestV1 } from \"./types.ts\";\n\n/** Version of the user-owned, host-independent plugin selection snapshot. */\nexport const PLUGIN_SELECTION_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_SELECTION_ID_CHARS_V1 = 128;\nexport const MAX_PLUGIN_SELECTION_IDS_V1 = 128;\n\nexport interface PluginSelectionV1 {\n\treadonly version: typeof PLUGIN_SELECTION_VERSION_V1;\n\treadonly profileId: string;\n\treadonly selectedPluginIds: readonly string[];\n\treadonly disabledPluginIds: readonly string[];\n}\n\nexport type PluginSelectionErrorCodeV1 =\n\t| \"invalid_profile_id\"\n\t| \"profile_id_too_long\"\n\t| \"invalid_plugin_id\"\n\t| \"plugin_id_too_long\"\n\t| \"too_many_plugin_ids\"\n\t| \"duplicate_plugin_id\"\n\t| \"unknown_plugin_id\"\n\t| \"catalog_truncated\";\n\nexport class PluginSelectionErrorV1 extends Error {\n\treadonly code: PluginSelectionErrorCodeV1;\n\treadonly pluginId?: string;\n\n\tconstructor(code: PluginSelectionErrorCodeV1, message: string, pluginId?: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PluginSelectionErrorV1\";\n\t\tthis.code = code;\n\t\tthis.pluginId = pluginId;\n\t}\n}\n\n/**\n * A pure catalog projection for a user selection. It never downloads,\n * writes, installs, activates, or mutates a plugin. The host owns those\n * operations through the separate installer contract.\n */\nexport interface PluginSelectionResolutionV1 {\n\treadonly selection: PluginSelectionV1;\n\t/** The bounded catalog of every discovered manifest. */\n\treadonly catalog: PluginCatalogSnapshotV1;\n\t/** Entries requested by the selection, in catalog order. */\n\treadonly entries: readonly PluginCatalogEntryV1[];\n\treadonly diagnostics: readonly PluginDiagnosticV1[];\n}\n\nexport interface PluginSelectionInputV1 {\n\treadonly profileId: string;\n\t/** Omitted means all discovered plugin IDs; [] means no plugin. */\n\treadonly selectedPluginIds?: readonly string[];\n\treadonly disabledPluginIds?: readonly string[];\n}\n\nfunction validateId(value: unknown, label: \"profileId\" | \"pluginId\"): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\tthrow new PluginSelectionErrorV1(\n\t\t\tlabel === \"profileId\" ? \"invalid_profile_id\" : \"invalid_plugin_id\",\n\t\t\tt(\"{label} must be a non-empty string\", { label }),\n\t\t\ttypeof value === \"string\" ? value : undefined,\n\t\t);\n\t}\n\tif (value.length > MAX_PLUGIN_SELECTION_ID_CHARS_V1) {\n\t\tthrow new PluginSelectionErrorV1(\n\t\t\tlabel === \"profileId\" ? \"profile_id_too_long\" : \"plugin_id_too_long\",\n\t\t\tt(\"{label} must be at most {max} characters\", { label, max: MAX_PLUGIN_SELECTION_ID_CHARS_V1 }),\n\t\t\tvalue,\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction normalizeIds(\n\tids: readonly string[] | undefined,\n\tlabel: \"selectedPluginIds\" | \"disabledPluginIds\",\n): readonly string[] {\n\tif (ids === undefined) return [];\n\tif (!Array.isArray(ids) || ids.length > MAX_PLUGIN_SELECTION_IDS_V1) {\n\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\"too_many_plugin_ids\",\n\t\t\tt(\"{label} must contain at most {max} plugin IDs\", { label, max: MAX_PLUGIN_SELECTION_IDS_V1 }),\n\t\t);\n\t}\n\tconst seen = new Set<string>();\n\tconst normalized: string[] = [];\n\tfor (const candidate of ids) {\n\t\tconst id = validateId(candidate, \"pluginId\");\n\t\tif (seen.has(id)) {\n\t\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\t\"duplicate_plugin_id\",\n\t\t\t\tt(\"{label} contains duplicate plugin ID: {id}\", { label, id }),\n\t\t\t\tid,\n\t\t\t);\n\t\t}\n\t\tseen.add(id);\n\t\tnormalized.push(id);\n\t}\n\tnormalized.sort((left, right) => left.localeCompare(right));\n\treturn Object.freeze(normalized);\n}\n\nfunction assertKnownIds(ids: readonly string[], knownIds: ReadonlySet<string>): void {\n\tfor (const id of ids) {\n\t\tif (!knownIds.has(id)) {\n\t\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\t\"unknown_plugin_id\",\n\t\t\t\tt(\"Selection references unknown plugin ID: {id}\", { id }),\n\t\t\t\tid,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/** Validate and freeze a selection without resolving or touching a host. */\nexport function createPluginSelectionV1(input: PluginSelectionInputV1): PluginSelectionV1 {\n\tconst profileId = validateId(input.profileId, \"profileId\");\n\tconst selectedPluginIds = normalizeIds(input.selectedPluginIds, \"selectedPluginIds\");\n\tconst disabledPluginIds = normalizeIds(input.disabledPluginIds, \"disabledPluginIds\");\n\treturn Object.freeze({\n\t\tversion: PLUGIN_SELECTION_VERSION_V1,\n\t\tprofileId,\n\t\tselectedPluginIds,\n\t\tdisabledPluginIds,\n\t});\n}\n\n/**\n * Resolve a selection to bounded catalog entries and diagnostics. This is a\n * read-only planning operation; it does not imply that any plugin is enabled.\n */\nexport function resolvePluginSelectionV1(input: {\n\treadonly selection: PluginSelectionInputV1;\n\treadonly manifests: readonly PluginManifestV1[];\n\treadonly host: HostFactsV1;\n\treadonly required?: boolean;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\treadonly maxEntries?: number;\n}): PluginSelectionResolutionV1 {\n\tfor (const manifest of input.manifests) validateId(manifest.id, \"pluginId\");\n\tconst knownIds = new Set(input.manifests.map((manifest) => manifest.id));\n\tconst provisional = createPluginSelectionV1(input.selection);\n\tif (input.selection.selectedPluginIds === undefined && knownIds.size > MAX_PLUGIN_SELECTION_IDS_V1) {\n\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\"too_many_plugin_ids\",\n\t\t\tt(\"discovered plugin IDs exceed the selection limit of {limit}\", { limit: MAX_PLUGIN_SELECTION_IDS_V1 }),\n\t\t);\n\t}\n\tconst selectedPluginIds =\n\t\tinput.selection.selectedPluginIds === undefined\n\t\t\t? Object.freeze([...knownIds].sort((a, b) => a.localeCompare(b)))\n\t\t\t: provisional.selectedPluginIds;\n\tconst selection = Object.freeze({ ...provisional, selectedPluginIds });\n\tassertKnownIds(selection.selectedPluginIds, knownIds);\n\tassertKnownIds(selection.disabledPluginIds, knownIds);\n\tconst catalog = buildPluginCatalogV1({\n\t\tmanifests: input.manifests,\n\t\thost: input.host,\n\t\trequired: input.required,\n\t\tdisabledPluginIds: selection.disabledPluginIds,\n\t\tavailableCapabilities: input.availableCapabilities,\n\t\tmaxEntries: input.maxEntries,\n\t});\n\tconst selected = new Set(selection.selectedPluginIds);\n\t// Resolve selected manifests separately so a bounded/truncated all-manifest\n\t// catalog cannot silently hide an explicitly selected plugin.\n\tconst selectedCatalog = buildPluginCatalogV1({\n\t\tmanifests: input.manifests.filter((manifest) => selected.has(manifest.id)),\n\t\thost: input.host,\n\t\trequired: input.required,\n\t\tdisabledPluginIds: selection.disabledPluginIds,\n\t\tavailableCapabilities: input.availableCapabilities,\n\t\tmaxEntries: Math.max(input.maxEntries ?? MAX_PLUGIN_SELECTION_IDS_V1, selection.selectedPluginIds.length),\n\t});\n\tif (selectedCatalog.truncated) {\n\t\tconst selectedEntryIds = new Set(selectedCatalog.entries.map((entry) => entry.pluginId));\n\t\tconst omitted = selection.selectedPluginIds.find((id) => !selectedEntryIds.has(id));\n\t\tif (omitted !== undefined) {\n\t\t\tthrow new PluginSelectionErrorV1(\n\t\t\t\t\"catalog_truncated\",\n\t\t\t\tt(\"Catalog truncation omitted selected plugin ID: {id}\", { id: omitted }),\n\t\t\t\tomitted,\n\t\t\t);\n\t\t}\n\t}\n\tconst entries = Object.freeze(selectedCatalog.entries);\n\tconst diagnostics = Object.freeze(entries.flatMap((entry) => entry.resolution.diagnostics));\n\treturn Object.freeze({ selection, catalog, entries, diagnostics });\n}\n\n/** Serialize only the stable selection data; no manifest, host, or payload is included. */\nexport function serializePluginSelectionV1(selection: PluginSelectionV1): string {\n\tconst normalized = createPluginSelectionV1(selection);\n\treturn JSON.stringify(normalized);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/state.ts"],"names":[],"mappings":"AAIA,OAAO,EAGN,KAAK,oBAAoB,EACzB,MAAM,gBAAgB,CAAC;AAExB,eAAO,MAAM,gCAAgC,GAAa,CAAC;AAC3D,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,eAAO,MAAM,gCAAgC,OAAO,CAAC;AACrD,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,eAAO,MAAM,0CAA0C,OAAO,CAAC;AAC/D,iGAAiG;AACjG,eAAO,MAAM,gCAAgC,MAAM,CAAC;AAEpD,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,CAAC;AACtD,MAAM,MAAM,sBAAsB,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAEnE,qFAAqF;AACrF,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,qEAAqE;IACrE,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,gFAAgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE;QACf,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;QACnC,kEAAkE;QAClE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAC1B,QAAQ,CAAC,SAAS,EAAE,sBAAsB,CAAC;KAC3C,CAAC;CACF;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,OAAO,EAAE,OAAO,gCAAgC,CAAC;IAC1D,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACjD;AAED,MAAM,MAAM,2BAA2B,GACpC,cAAc,GACd,cAAc,GACd,gBAAgB,GAChB,oBAAoB,GACpB,kBAAkB,GAClB,0BAA0B,GAC1B,WAAW,CAAC;AAEf,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,IAAI,EAAE,2BAA2B,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,uBAAuB,GAChC;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAA;CAAE,GACnE;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAA;CAAE,GACxE;IACA,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,SAAS,uBAAuB,EAAE,CAAC;CACxD,GACD;IACA,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,SAAS,uBAAuB,EAAE,CAAC;CACxD,CAAC;AAEL,MAAM,MAAM,2BAA2B,GACpC;IACA,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CACzB,GACD;IACA,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,SAAS,uBAAuB,EAAE,CAAC;CACxD,GACD;IACA,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,SAAS,uBAAuB,EAAE,CAAC;CACxD,CAAC;AAEL,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,yBAAyB;IACzC,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,UAAU,CAAC,EAAE,uBAAuB,CAAC;CAC9C;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACjG,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;QACxB,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;QAC5C,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;QACnC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAC1B,mEAAmE;QACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;KAC9B,KAAK,OAAO,CAAC,2BAA2B,CAAC,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;QACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;QACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;KAC9B,KAAK,OAAO,CAAC,2BAA2B,CAAC,CAAC;CAC3C;AA8MD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,kBAAkB,CA0I/F","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, resolve } from \"node:path\";\n\nimport {\n\tDEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,\n\tMAX_PLUGIN_SCOPE_REF_CHARS_V1,\n\ttype PluginInstallationV1,\n} from \"./installer.ts\";\n\nexport const PLUGIN_STATE_SNAPSHOT_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_STATE_RECORDS_V1 = 256;\nexport const MAX_PLUGIN_STATE_STRING_CHARS_V1 = 4096;\nexport const MAX_PLUGIN_STATE_ID_CHARS_V1 = 256;\nexport const MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1 = 2048;\n/** Optional acquisition source label (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`). */\nexport const MAX_PLUGIN_STATE_SOURCE_CHARS_V1 = 128;\n\nexport type PluginStateScopeV1 = \"global\" | \"project\";\nexport type PluginStateLifecycleV1 = PluginInstallationV1[\"state\"];\n\n/** Persisted identity, enablement, scope, and recoverable installation lifecycle. */\nexport interface PluginStateRecordV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly manifestDigest: string;\n\t/** Opaque host handle. It must never be a local path or file URI. */\n\treadonly installationRef: string;\n\t/** Optional acquisition source label; absent on records written before S1-b. */\n\treadonly source?: string;\n\treadonly state: {\n\t\treadonly scope: PluginStateScopeV1;\n\t\t/** Opaque concrete installation namespace; never a local path. */\n\t\treadonly scopeRef: string;\n\t\treadonly enabled: boolean;\n\t\treadonly lifecycle: PluginStateLifecycleV1;\n\t};\n}\n\nexport interface PluginStateSnapshotV1 {\n\treadonly version: typeof PLUGIN_STATE_SNAPSHOT_VERSION_V1;\n\treadonly records: readonly PluginStateRecordV1[];\n}\n\nexport type PluginStateDiagnosticCodeV1 =\n\t| \"invalid_path\"\n\t| \"invalid_json\"\n\t| \"invalid_schema\"\n\t| \"duplicate_identity\"\n\t| \"too_many_records\"\n\t| \"invalid_installation_ref\"\n\t| \"cancelled\";\n\nexport interface PluginStateDiagnosticV1 {\n\treadonly code: PluginStateDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly identity?: string;\n}\n\nexport type PluginStateReadResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| { readonly status: \"missing\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport type PluginStateMutationResultV1 =\n\t| {\n\t\t\treadonly status: \"ok\";\n\t\t\treadonly snapshot: PluginStateSnapshotV1;\n\t\t\treadonly changed: boolean;\n\t }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport interface PluginStateFileSystemV1 {\n\treadonly readFile: (path: string) => Promise<string>;\n\treadonly mkdir: (path: string) => Promise<void>;\n\treadonly writeFile: (path: string, data: string) => Promise<void>;\n\treadonly rename: (oldPath: string, newPath: string) => Promise<void>;\n\treadonly unlink: (path: string) => Promise<void>;\n}\n\nexport interface PluginStateStoreOptionsV1 {\n\t/** Absolute path to the host-owned plugin-state.json file. */\n\treadonly filePath: string;\n\t/** Injectable filesystem for deterministic tests and alternate hosts. */\n\treadonly fileSystem?: PluginStateFileSystemV1;\n}\n\nexport interface PluginStateStoreV1 {\n\treadonly read: (options?: { readonly signal?: AbortSignal }) => Promise<PluginStateReadResultV1>;\n\treadonly upsert: (input: {\n\t\treadonly installation: PluginInstallationV1;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly enabled: boolean;\n\t\t/** Optional acquisition source label persisted with the record. */\n\t\treadonly source?: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n\treadonly remove: (input: {\n\t\treadonly pluginId: string;\n\t\treadonly pluginVersion: string;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly scopeRef: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n}\n\nconst EMPTY_SNAPSHOT: PluginStateSnapshotV1 = Object.freeze({\n\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\trecords: Object.freeze([]),\n});\n\nfunction diagnostic(code: PluginStateDiagnosticCodeV1, message: string, identity?: string): PluginStateDiagnosticV1 {\n\treturn Object.freeze(identity === undefined ? { code, message } : { code, message, identity });\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn error instanceof Error && (error.name === \"AbortError\" || error.name === \"AbortSignalError\");\n}\n\nfunction isMissingError(error: unknown): boolean {\n\tif (typeof error !== \"object\" || error === null) return false;\n\treturn \"code\" in error && (error as { readonly code?: unknown }).code === \"ENOENT\";\n}\n\nfunction validateFilePath(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_STRING_CHARS_V1)\n\t\tthrow new Error(\"invalid plugin state file path\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid plugin state file path\");\n\tif (/^file:/iu.test(value) || (/^[a-z][a-z\\d+.-]*:/iu.test(value) && !/^[a-z]:[\\\\/]/iu.test(value)))\n\t\tthrow new Error(\"invalid plugin state file path\");\n\tconst normalized = isAbsolute(value) ? value : resolve(value);\n\tif (basename(normalized).length === 0 || basename(normalized) === \".\" || basename(normalized) === \"..\")\n\t\tthrow new Error(\"invalid plugin state file path\");\n\treturn normalized;\n}\n\nfunction validateOpaqueInstallationRef(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1)\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid installation reference\");\n\treturn value;\n}\n\nfunction validateScopeRef(scope: PluginStateScopeV1, value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_SCOPE_REF_CHARS_V1)\n\t\tthrow new Error(\"invalid plugin scope reference\");\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(\"invalid plugin scope reference\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid plugin scope reference\");\n\tif (scope === \"global\" && value !== DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1)\n\t\tthrow new Error(\"invalid plugin scope reference\");\n\treturn value;\n}\n\nfunction validateString(value: unknown, label: string, max = MAX_PLUGIN_STATE_STRING_CHARS_V1): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0 || value.length > max || /[\\u0000-\\u001f]/u.test(value))\n\t\tthrow new Error(`${label} is invalid`);\n\treturn value;\n}\n\n/** Acquisition source labels (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`, `github:<owner>/<repo>@<tag|latest>`). */\nfunction validateSourceLabel(value: unknown): string {\n\tif (\n\t\ttypeof value !== \"string\" ||\n\t\tvalue.length === 0 ||\n\t\tvalue.length > MAX_PLUGIN_STATE_SOURCE_CHARS_V1 ||\n\t\t!/^[a-z][a-z0-9.:[\\]_/@-]*$/u.test(value)\n\t)\n\t\tthrow new Error(\"record source label is invalid\");\n\treturn value;\n}\n\nfunction identityOf(record: PluginStateRecordV1): string {\n\treturn `${record.state.scope}:${record.state.scopeRef}:${record.pluginId}@${record.pluginVersion}`;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasExactKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n\tconst expected = new Set(keys);\n\treturn Object.keys(value).length === expected.size && Object.keys(value).every((key) => expected.has(key));\n}\n\nfunction validateRecord(value: unknown): PluginStateRecordV1 {\n\tconst requiredKeys = [\"pluginId\", \"pluginVersion\", \"manifestDigest\", \"installationRef\", \"state\"];\n\tconst allowedKeys = new Set([...requiredKeys, \"source\"]);\n\tif (!isObject(value) || Object.keys(value).some((key) => !allowedKeys.has(key)))\n\t\tthrow new Error(\"record schema is invalid\");\n\tfor (const key of requiredKeys) if (!(key in value)) throw new Error(\"record schema is invalid\");\n\tconst pluginId = validateString(value.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(value.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(value.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(value.installationRef);\n\tconst source = value.source === undefined ? undefined : validateSourceLabel(value.source);\n\tif (!isObject(value.state) || !hasExactKeys(value.state, [\"scope\", \"scopeRef\", \"enabled\", \"lifecycle\"]))\n\t\tthrow new Error(\"state schema is invalid\");\n\tif (value.state.scope !== \"global\" && value.state.scope !== \"project\") throw new Error(\"state scope is invalid\");\n\tconst scopeRef = validateScopeRef(value.state.scope, value.state.scopeRef);\n\tif (typeof value.state.enabled !== \"boolean\") throw new Error(\"state enabled flag is invalid\");\n\tif (\n\t\tvalue.state.lifecycle !== \"installed\" &&\n\t\tvalue.state.lifecycle !== \"active\" &&\n\t\tvalue.state.lifecycle !== \"retained\"\n\t)\n\t\tthrow new Error(\"state lifecycle is invalid\");\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(source === undefined ? {} : { source }),\n\t\tstate: Object.freeze({\n\t\t\tscope: value.state.scope,\n\t\t\tscopeRef,\n\t\t\tenabled: value.state.enabled,\n\t\t\tlifecycle: value.state.lifecycle,\n\t\t}),\n\t});\n}\n\nfunction validateSnapshot(value: unknown): PluginStateSnapshotV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"version\", \"records\"])) throw new Error(\"snapshot schema is invalid\");\n\tif (value.version !== PLUGIN_STATE_SNAPSHOT_VERSION_V1) throw new Error(\"snapshot version is unsupported\");\n\tif (!Array.isArray(value.records)) throw new Error(\"records must be an array\");\n\tif (value.records.length > MAX_PLUGIN_STATE_RECORDS_V1) throw new Error(\"too many plugin state records\");\n\tconst records = value.records.map(validateRecord);\n\tconst identities = new Set<string>();\n\tfor (const record of records) {\n\t\tconst identity = identityOf(record);\n\t\tif (identities.has(identity)) throw new Error(`duplicate identity: ${identity}`);\n\t\tidentities.add(identity);\n\t}\n\trecords.sort((left, right) => identityOf(left).localeCompare(identityOf(right)));\n\treturn Object.freeze({\n\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\trecords: Object.freeze(records),\n\t});\n}\n\nfunction invalidFromError(error: unknown): PluginStateDiagnosticV1 {\n\tconst message = error instanceof Error ? error.message : \"plugin state schema is invalid\";\n\tconst duplicatePrefix = \"duplicate identity: \";\n\tif (message.startsWith(duplicatePrefix))\n\t\treturn diagnostic(\"duplicate_identity\", message, message.slice(duplicatePrefix.length));\n\tif (message === \"too many plugin state records\") return diagnostic(\"too_many_records\", message);\n\tif (message === \"invalid installation reference\") return diagnostic(\"invalid_installation_ref\", message);\n\treturn diagnostic(\"invalid_schema\", message);\n}\n\nfunction defaultFileSystem(): PluginStateFileSystemV1 {\n\treturn {\n\t\treadFile: async (path) => await readFile(path, \"utf8\"),\n\t\tmkdir: async (path) => {\n\t\t\tawait mkdir(path, { recursive: true });\n\t\t},\n\t\twriteFile: async (path, data) => {\n\t\t\tawait writeFile(path, data, \"utf8\");\n\t\t},\n\t\trename,\n\t\tunlink,\n\t};\n}\n\nfunction cancelledResult(): {\n\treadonly status: \"cancelled\";\n\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n} {\n\treturn Object.freeze({\n\t\tstatus: \"cancelled\",\n\t\tdiagnostics: Object.freeze([diagnostic(\"cancelled\", \"Plugin state operation was cancelled\")]),\n\t});\n}\n\nfunction sortRecords(records: readonly PluginStateRecordV1[]): readonly PluginStateRecordV1[] {\n\treturn Object.freeze([...records].sort((left, right) => identityOf(left).localeCompare(identityOf(right))));\n}\n\nfunction makeRecord(\n\tinstallation: PluginInstallationV1,\n\tscope: PluginStateScopeV1,\n\tenabled: boolean,\n\tsource?: string,\n): PluginStateRecordV1 {\n\tif (installation.version !== 1) throw new Error(\"plugin installation handle is invalid\");\n\tconst pluginId = validateString(installation.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(installation.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(installation.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(installation.installationRef);\n\tif (scope !== \"global\" && scope !== \"project\") throw new Error(\"state scope is invalid\");\n\tif (installation.scope !== scope) throw new Error(\"installation scope does not match state scope\");\n\tconst scopeRef = validateScopeRef(\n\t\tscope,\n\t\tscope === \"global\" ? (installation.scopeRef ?? DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1) : installation.scopeRef,\n\t);\n\tif (typeof enabled !== \"boolean\") throw new Error(\"state enabled flag is invalid\");\n\tconst sourceLabel = source === undefined ? undefined : validateSourceLabel(source);\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(sourceLabel === undefined ? {} : { source: sourceLabel }),\n\t\tstate: Object.freeze({ scope, scopeRef, enabled, lifecycle: installation.state }),\n\t});\n}\n\nexport function createPluginStateStoreV1(options: PluginStateStoreOptionsV1): PluginStateStoreV1 {\n\tconst filePath = validateFilePath(options.filePath);\n\tconst fileSystem = options.fileSystem ?? defaultFileSystem();\n\n\tasync function read(signal?: AbortSignal): Promise<PluginStateReadResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = await fileSystem.readFile(filePath);\n\t\t} catch (error) {\n\t\t\tif (isMissingError(error)) return Object.freeze({ status: \"missing\", snapshot: EMPTY_SNAPSHOT });\n\t\t\tif (isAbortError(error) || signal?.aborted) return cancelledResult();\n\t\t\tthrow error;\n\t\t}\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(content) as unknown;\n\t\t} catch {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"invalid_json\", \"plugin state JSON is invalid\")]),\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"ok\",\n\t\t\t\tsnapshot: validateSnapshot(parsed),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t});\n\t\t}\n\t}\n\n\tasync function write(snapshot: PluginStateSnapshotV1, signal?: AbortSignal): Promise<PluginStateMutationResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tconst parent = dirname(filePath);\n\t\tconst temporaryPath = join(parent, `.${basename(filePath)}.${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait fileSystem.mkdir(parent);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.writeFile(temporaryPath, `${JSON.stringify(snapshot)}\\n`);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.rename(temporaryPath, filePath);\n\t\t\treturn Object.freeze({ status: \"ok\", snapshot, changed: true });\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tawait fileSystem.unlink(temporaryPath);\n\t\t\t} catch {\n\t\t\t\t// Cleanup must not replace the original write/rename error.\n\t\t\t}\n\t\t}\n\t}\n\n\t// Serialize mutations made through one store instance so concurrent CLI/UI\n\t// actions cannot lose each other's read-modify-write updates.\n\tlet mutationTail: Promise<void> = Promise.resolve();\n\tfunction enqueueMutation<T>(operation: () => Promise<T>): Promise<T> {\n\t\tconst result = mutationTail.then(operation, operation);\n\t\tmutationTail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\treturn {\n\t\tread: async ({ signal } = {}) => await read(signal),\n\t\tupsert: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet record: PluginStateRecordV1;\n\t\t\t\ttry {\n\t\t\t\t\trecord = makeRecord(input.installation, input.scope, input.enabled, input.source);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst records = current.snapshot.records.filter(\n\t\t\t\t\t(candidate) => identityOf(candidate) !== identityOf(record),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\trecords.length >= MAX_PLUGIN_STATE_RECORDS_V1 &&\n\t\t\t\t\t!current.snapshot.records.some((candidate) => identityOf(candidate) === identityOf(record))\n\t\t\t\t)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"too_many_records\", \"too many plugin state records\")]),\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords([...records, record]),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t\tremove: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet pluginId: string;\n\t\t\t\tlet pluginVersion: string;\n\t\t\t\tlet scope: PluginStateScopeV1;\n\t\t\t\tlet scopeRef: string;\n\t\t\t\ttry {\n\t\t\t\t\tpluginId = validateString(input.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tpluginVersion = validateString(input.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tif (input.scope !== \"global\" && input.scope !== \"project\") throw new Error(\"state scope is invalid\");\n\t\t\t\t\tscope = input.scope;\n\t\t\t\t\tscopeRef = validateScopeRef(scope, input.scopeRef);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst identity = `${scope}:${scopeRef}:${pluginId}@${pluginVersion}`;\n\t\t\t\tconst records = current.snapshot.records.filter((candidate) => identityOf(candidate) !== identity);\n\t\t\t\tif (records.length === current.snapshot.records.length)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"ok\",\n\t\t\t\t\t\tsnapshot: current.snapshot,\n\t\t\t\t\t\tchanged: false,\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords(records),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t};\n}\n"]}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/state.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, resolve } from \"node:path\";\n\nimport { t } from \"../../core/i18n/index.ts\";\nimport {\n\tDEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,\n\tMAX_PLUGIN_SCOPE_REF_CHARS_V1,\n\ttype PluginInstallationV1,\n} from \"./installer.ts\";\n\nexport const PLUGIN_STATE_SNAPSHOT_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_STATE_RECORDS_V1 = 256;\nexport const MAX_PLUGIN_STATE_STRING_CHARS_V1 = 4096;\nexport const MAX_PLUGIN_STATE_ID_CHARS_V1 = 256;\nexport const MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1 = 2048;\n/** Optional acquisition source label (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`). */\nexport const MAX_PLUGIN_STATE_SOURCE_CHARS_V1 = 128;\n\nexport type PluginStateScopeV1 = \"global\" | \"project\";\nexport type PluginStateLifecycleV1 = PluginInstallationV1[\"state\"];\n\n/** Persisted identity, enablement, scope, and recoverable installation lifecycle. */\nexport interface PluginStateRecordV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly manifestDigest: string;\n\t/** Opaque host handle. It must never be a local path or file URI. */\n\treadonly installationRef: string;\n\t/** Optional acquisition source label; absent on records written before S1-b. */\n\treadonly source?: string;\n\treadonly state: {\n\t\treadonly scope: PluginStateScopeV1;\n\t\t/** Opaque concrete installation namespace; never a local path. */\n\t\treadonly scopeRef: string;\n\t\treadonly enabled: boolean;\n\t\treadonly lifecycle: PluginStateLifecycleV1;\n\t};\n}\n\nexport interface PluginStateSnapshotV1 {\n\treadonly version: typeof PLUGIN_STATE_SNAPSHOT_VERSION_V1;\n\treadonly records: readonly PluginStateRecordV1[];\n}\n\nexport type PluginStateDiagnosticCodeV1 =\n\t| \"invalid_path\"\n\t| \"invalid_json\"\n\t| \"invalid_schema\"\n\t| \"duplicate_identity\"\n\t| \"too_many_records\"\n\t| \"invalid_installation_ref\"\n\t| \"cancelled\";\n\nexport interface PluginStateDiagnosticV1 {\n\treadonly code: PluginStateDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly identity?: string;\n}\n\nexport type PluginStateReadResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| { readonly status: \"missing\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport type PluginStateMutationResultV1 =\n\t| {\n\t\t\treadonly status: \"ok\";\n\t\t\treadonly snapshot: PluginStateSnapshotV1;\n\t\t\treadonly changed: boolean;\n\t }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport interface PluginStateFileSystemV1 {\n\treadonly readFile: (path: string) => Promise<string>;\n\treadonly mkdir: (path: string) => Promise<void>;\n\treadonly writeFile: (path: string, data: string) => Promise<void>;\n\treadonly rename: (oldPath: string, newPath: string) => Promise<void>;\n\treadonly unlink: (path: string) => Promise<void>;\n}\n\nexport interface PluginStateStoreOptionsV1 {\n\t/** Absolute path to the host-owned plugin-state.json file. */\n\treadonly filePath: string;\n\t/** Injectable filesystem for deterministic tests and alternate hosts. */\n\treadonly fileSystem?: PluginStateFileSystemV1;\n}\n\nexport interface PluginStateStoreV1 {\n\treadonly read: (options?: { readonly signal?: AbortSignal }) => Promise<PluginStateReadResultV1>;\n\treadonly upsert: (input: {\n\t\treadonly installation: PluginInstallationV1;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly enabled: boolean;\n\t\t/** Optional acquisition source label persisted with the record. */\n\t\treadonly source?: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n\treadonly remove: (input: {\n\t\treadonly pluginId: string;\n\t\treadonly pluginVersion: string;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly scopeRef: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n}\n\nconst EMPTY_SNAPSHOT: PluginStateSnapshotV1 = Object.freeze({\n\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\trecords: Object.freeze([]),\n});\n\nfunction diagnostic(code: PluginStateDiagnosticCodeV1, message: string, identity?: string): PluginStateDiagnosticV1 {\n\treturn Object.freeze(identity === undefined ? { code, message } : { code, message, identity });\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn error instanceof Error && (error.name === \"AbortError\" || error.name === \"AbortSignalError\");\n}\n\nfunction isMissingError(error: unknown): boolean {\n\tif (typeof error !== \"object\" || error === null) return false;\n\treturn \"code\" in error && (error as { readonly code?: unknown }).code === \"ENOENT\";\n}\n\nfunction validateFilePath(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_STRING_CHARS_V1)\n\t\tthrow new Error(t(\"invalid plugin state file path\"));\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(t(\"invalid plugin state file path\"));\n\tif (/^file:/iu.test(value) || (/^[a-z][a-z\\d+.-]*:/iu.test(value) && !/^[a-z]:[\\\\/]/iu.test(value)))\n\t\tthrow new Error(t(\"invalid plugin state file path\"));\n\tconst normalized = isAbsolute(value) ? value : resolve(value);\n\tif (basename(normalized).length === 0 || basename(normalized) === \".\" || basename(normalized) === \"..\")\n\t\tthrow new Error(t(\"invalid plugin state file path\"));\n\treturn normalized;\n}\n\nfunction validateOpaqueInstallationRef(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1)\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid installation reference\");\n\treturn value;\n}\n\nfunction validateScopeRef(scope: PluginStateScopeV1, value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_SCOPE_REF_CHARS_V1)\n\t\tthrow new Error(t(\"invalid plugin scope reference\"));\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(t(\"invalid plugin scope reference\"));\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(t(\"invalid plugin scope reference\"));\n\tif (scope === \"global\" && value !== DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1)\n\t\tthrow new Error(t(\"invalid plugin scope reference\"));\n\treturn value;\n}\n\nfunction validateString(value: unknown, label: string, max = MAX_PLUGIN_STATE_STRING_CHARS_V1): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0 || value.length > max || /[\\u0000-\\u001f]/u.test(value))\n\t\tthrow new Error(t(\"{label} is invalid\", { label }));\n\treturn value;\n}\n\n/** Acquisition source labels (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`, `github:<owner>/<repo>@<tag|latest>`). */\nfunction validateSourceLabel(value: unknown): string {\n\tif (\n\t\ttypeof value !== \"string\" ||\n\t\tvalue.length === 0 ||\n\t\tvalue.length > MAX_PLUGIN_STATE_SOURCE_CHARS_V1 ||\n\t\t!/^[a-z][a-z0-9.:[\\]_/@-]*$/u.test(value)\n\t)\n\t\tthrow new Error(t(\"record source label is invalid\"));\n\treturn value;\n}\n\nfunction identityOf(record: PluginStateRecordV1): string {\n\treturn `${record.state.scope}:${record.state.scopeRef}:${record.pluginId}@${record.pluginVersion}`;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasExactKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n\tconst expected = new Set(keys);\n\treturn Object.keys(value).length === expected.size && Object.keys(value).every((key) => expected.has(key));\n}\n\nfunction validateRecord(value: unknown): PluginStateRecordV1 {\n\tconst requiredKeys = [\"pluginId\", \"pluginVersion\", \"manifestDigest\", \"installationRef\", \"state\"];\n\tconst allowedKeys = new Set([...requiredKeys, \"source\"]);\n\tif (!isObject(value) || Object.keys(value).some((key) => !allowedKeys.has(key)))\n\t\tthrow new Error(t(\"record schema is invalid\"));\n\tfor (const key of requiredKeys) if (!(key in value)) throw new Error(t(\"record schema is invalid\"));\n\tconst pluginId = validateString(value.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(value.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(value.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(value.installationRef);\n\tconst source = value.source === undefined ? undefined : validateSourceLabel(value.source);\n\tif (!isObject(value.state) || !hasExactKeys(value.state, [\"scope\", \"scopeRef\", \"enabled\", \"lifecycle\"]))\n\t\tthrow new Error(t(\"state schema is invalid\"));\n\tif (value.state.scope !== \"global\" && value.state.scope !== \"project\") throw new Error(t(\"state scope is invalid\"));\n\tconst scopeRef = validateScopeRef(value.state.scope, value.state.scopeRef);\n\tif (typeof value.state.enabled !== \"boolean\") throw new Error(t(\"state enabled flag is invalid\"));\n\tif (\n\t\tvalue.state.lifecycle !== \"installed\" &&\n\t\tvalue.state.lifecycle !== \"active\" &&\n\t\tvalue.state.lifecycle !== \"retained\"\n\t)\n\t\tthrow new Error(t(\"state lifecycle is invalid\"));\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(source === undefined ? {} : { source }),\n\t\tstate: Object.freeze({\n\t\t\tscope: value.state.scope,\n\t\t\tscopeRef,\n\t\t\tenabled: value.state.enabled,\n\t\t\tlifecycle: value.state.lifecycle,\n\t\t}),\n\t});\n}\n\nfunction validateSnapshot(value: unknown): PluginStateSnapshotV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"version\", \"records\"]))\n\t\tthrow new Error(t(\"snapshot schema is invalid\"));\n\tif (value.version !== PLUGIN_STATE_SNAPSHOT_VERSION_V1) throw new Error(t(\"snapshot version is unsupported\"));\n\tif (!Array.isArray(value.records)) throw new Error(t(\"records must be an array\"));\n\tif (value.records.length > MAX_PLUGIN_STATE_RECORDS_V1) throw new Error(\"too many plugin state records\");\n\tconst records = value.records.map(validateRecord);\n\tconst identities = new Set<string>();\n\tfor (const record of records) {\n\t\tconst identity = identityOf(record);\n\t\tif (identities.has(identity)) throw new Error(`duplicate identity: ${identity}`);\n\t\tidentities.add(identity);\n\t}\n\trecords.sort((left, right) => identityOf(left).localeCompare(identityOf(right)));\n\treturn Object.freeze({\n\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\trecords: Object.freeze(records),\n\t});\n}\n\nfunction invalidFromError(error: unknown): PluginStateDiagnosticV1 {\n\tconst message = error instanceof Error ? error.message : \"plugin state schema is invalid\";\n\tconst duplicatePrefix = \"duplicate identity: \";\n\tif (message.startsWith(duplicatePrefix))\n\t\treturn diagnostic(\"duplicate_identity\", message, message.slice(duplicatePrefix.length));\n\tif (message === \"too many plugin state records\") return diagnostic(\"too_many_records\", message);\n\tif (message === \"invalid installation reference\") return diagnostic(\"invalid_installation_ref\", message);\n\treturn diagnostic(\"invalid_schema\", message);\n}\n\nfunction defaultFileSystem(): PluginStateFileSystemV1 {\n\treturn {\n\t\treadFile: async (path) => await readFile(path, \"utf8\"),\n\t\tmkdir: async (path) => {\n\t\t\tawait mkdir(path, { recursive: true });\n\t\t},\n\t\twriteFile: async (path, data) => {\n\t\t\tawait writeFile(path, data, \"utf8\");\n\t\t},\n\t\trename,\n\t\tunlink,\n\t};\n}\n\nfunction cancelledResult(): {\n\treadonly status: \"cancelled\";\n\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n} {\n\treturn Object.freeze({\n\t\tstatus: \"cancelled\",\n\t\tdiagnostics: Object.freeze([diagnostic(\"cancelled\", \"Plugin state operation was cancelled\")]),\n\t});\n}\n\nfunction sortRecords(records: readonly PluginStateRecordV1[]): readonly PluginStateRecordV1[] {\n\treturn Object.freeze([...records].sort((left, right) => identityOf(left).localeCompare(identityOf(right))));\n}\n\nfunction makeRecord(\n\tinstallation: PluginInstallationV1,\n\tscope: PluginStateScopeV1,\n\tenabled: boolean,\n\tsource?: string,\n): PluginStateRecordV1 {\n\tif (installation.version !== 1) throw new Error(\"plugin installation handle is invalid\");\n\tconst pluginId = validateString(installation.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(installation.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(installation.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(installation.installationRef);\n\tif (scope !== \"global\" && scope !== \"project\") throw new Error(t(\"state scope is invalid\"));\n\tif (installation.scope !== scope) throw new Error(t(\"installation scope does not match state scope\"));\n\tconst scopeRef = validateScopeRef(\n\t\tscope,\n\t\tscope === \"global\" ? (installation.scopeRef ?? DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1) : installation.scopeRef,\n\t);\n\tif (typeof enabled !== \"boolean\") throw new Error(t(\"state enabled flag is invalid\"));\n\tconst sourceLabel = source === undefined ? undefined : validateSourceLabel(source);\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(sourceLabel === undefined ? {} : { source: sourceLabel }),\n\t\tstate: Object.freeze({ scope, scopeRef, enabled, lifecycle: installation.state }),\n\t});\n}\n\nexport function createPluginStateStoreV1(options: PluginStateStoreOptionsV1): PluginStateStoreV1 {\n\tconst filePath = validateFilePath(options.filePath);\n\tconst fileSystem = options.fileSystem ?? defaultFileSystem();\n\n\tasync function read(signal?: AbortSignal): Promise<PluginStateReadResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = await fileSystem.readFile(filePath);\n\t\t} catch (error) {\n\t\t\tif (isMissingError(error)) return Object.freeze({ status: \"missing\", snapshot: EMPTY_SNAPSHOT });\n\t\t\tif (isAbortError(error) || signal?.aborted) return cancelledResult();\n\t\t\tthrow error;\n\t\t}\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(content) as unknown;\n\t\t} catch {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"invalid_json\", \"plugin state JSON is invalid\")]),\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"ok\",\n\t\t\t\tsnapshot: validateSnapshot(parsed),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t});\n\t\t}\n\t}\n\n\tasync function write(snapshot: PluginStateSnapshotV1, signal?: AbortSignal): Promise<PluginStateMutationResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tconst parent = dirname(filePath);\n\t\tconst temporaryPath = join(parent, `.${basename(filePath)}.${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait fileSystem.mkdir(parent);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.writeFile(temporaryPath, `${JSON.stringify(snapshot)}\\n`);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.rename(temporaryPath, filePath);\n\t\t\treturn Object.freeze({ status: \"ok\", snapshot, changed: true });\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tawait fileSystem.unlink(temporaryPath);\n\t\t\t} catch {\n\t\t\t\t// Cleanup must not replace the original write/rename error.\n\t\t\t}\n\t\t}\n\t}\n\n\t// Serialize mutations made through one store instance so concurrent CLI/UI\n\t// actions cannot lose each other's read-modify-write updates.\n\tlet mutationTail: Promise<void> = Promise.resolve();\n\tfunction enqueueMutation<T>(operation: () => Promise<T>): Promise<T> {\n\t\tconst result = mutationTail.then(operation, operation);\n\t\tmutationTail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\treturn {\n\t\tread: async ({ signal } = {}) => await read(signal),\n\t\tupsert: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet record: PluginStateRecordV1;\n\t\t\t\ttry {\n\t\t\t\t\trecord = makeRecord(input.installation, input.scope, input.enabled, input.source);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst records = current.snapshot.records.filter(\n\t\t\t\t\t(candidate) => identityOf(candidate) !== identityOf(record),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\trecords.length >= MAX_PLUGIN_STATE_RECORDS_V1 &&\n\t\t\t\t\t!current.snapshot.records.some((candidate) => identityOf(candidate) === identityOf(record))\n\t\t\t\t)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"too_many_records\", \"too many plugin state records\")]),\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords([...records, record]),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t\tremove: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet pluginId: string;\n\t\t\t\tlet pluginVersion: string;\n\t\t\t\tlet scope: PluginStateScopeV1;\n\t\t\t\tlet scopeRef: string;\n\t\t\t\ttry {\n\t\t\t\t\tpluginId = validateString(input.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tpluginVersion = validateString(input.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tif (input.scope !== \"global\" && input.scope !== \"project\") throw new Error(t(\"state scope is invalid\"));\n\t\t\t\t\tscope = input.scope;\n\t\t\t\t\tscopeRef = validateScopeRef(scope, input.scopeRef);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst identity = `${scope}:${scopeRef}:${pluginId}@${pluginVersion}`;\n\t\t\t\tconst records = current.snapshot.records.filter((candidate) => identityOf(candidate) !== identity);\n\t\t\t\tif (records.length === current.snapshot.records.length)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"ok\",\n\t\t\t\t\t\tsnapshot: current.snapshot,\n\t\t\t\t\t\tchanged: false,\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords(records),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t};\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises";
3
3
  import { basename, dirname, isAbsolute, join, resolve } from "node:path";
4
+ import { t } from "../../core/i18n/index.js";
4
5
  import { DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1, MAX_PLUGIN_SCOPE_REF_CHARS_V1, } from "./installer.js";
5
6
  export const PLUGIN_STATE_SNAPSHOT_VERSION_V1 = 1;
6
7
  export const MAX_PLUGIN_STATE_RECORDS_V1 = 256;
@@ -26,14 +27,14 @@ function isMissingError(error) {
26
27
  }
27
28
  function validateFilePath(value) {
28
29
  if (typeof value !== "string" || value.trim() === "" || value.length > MAX_PLUGIN_STATE_STRING_CHARS_V1)
29
- throw new Error("invalid plugin state file path");
30
+ throw new Error(t("invalid plugin state file path"));
30
31
  if (value.includes("\0") || /[\u0000-\u001f]/u.test(value))
31
- throw new Error("invalid plugin state file path");
32
+ throw new Error(t("invalid plugin state file path"));
32
33
  if (/^file:/iu.test(value) || (/^[a-z][a-z\d+.-]*:/iu.test(value) && !/^[a-z]:[\\/]/iu.test(value)))
33
- throw new Error("invalid plugin state file path");
34
+ throw new Error(t("invalid plugin state file path"));
34
35
  const normalized = isAbsolute(value) ? value : resolve(value);
35
36
  if (basename(normalized).length === 0 || basename(normalized) === "." || basename(normalized) === "..")
36
- throw new Error("invalid plugin state file path");
37
+ throw new Error(t("invalid plugin state file path"));
37
38
  return normalized;
38
39
  }
39
40
  function validateOpaqueInstallationRef(value) {
@@ -47,18 +48,18 @@ function validateOpaqueInstallationRef(value) {
47
48
  }
48
49
  function validateScopeRef(scope, value) {
49
50
  if (typeof value !== "string" || value.trim() === "" || value.length > MAX_PLUGIN_SCOPE_REF_CHARS_V1)
50
- throw new Error("invalid plugin scope reference");
51
+ throw new Error(t("invalid plugin scope reference"));
51
52
  if (/^(?:file:|[a-zA-Z]:[\\/]|[\\/]{1,2}|\\\\)/u.test(value) || /\s/u.test(value))
52
- throw new Error("invalid plugin scope reference");
53
+ throw new Error(t("invalid plugin scope reference"));
53
54
  if (value.includes("\0") || /[\u0000-\u001f]/u.test(value))
54
- throw new Error("invalid plugin scope reference");
55
+ throw new Error(t("invalid plugin scope reference"));
55
56
  if (scope === "global" && value !== DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1)
56
- throw new Error("invalid plugin scope reference");
57
+ throw new Error(t("invalid plugin scope reference"));
57
58
  return value;
58
59
  }
59
60
  function validateString(value, label, max = MAX_PLUGIN_STATE_STRING_CHARS_V1) {
60
61
  if (typeof value !== "string" || value.trim().length === 0 || value.length > max || /[\u0000-\u001f]/u.test(value))
61
- throw new Error(`${label} is invalid`);
62
+ throw new Error(t("{label} is invalid", { label }));
62
63
  return value;
63
64
  }
64
65
  /** Acquisition source labels (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`, `github:<owner>/<repo>@<tag|latest>`). */
@@ -67,7 +68,7 @@ function validateSourceLabel(value) {
67
68
  value.length === 0 ||
68
69
  value.length > MAX_PLUGIN_STATE_SOURCE_CHARS_V1 ||
69
70
  !/^[a-z][a-z0-9.:[\]_/@-]*$/u.test(value))
70
- throw new Error("record source label is invalid");
71
+ throw new Error(t("record source label is invalid"));
71
72
  return value;
72
73
  }
73
74
  function identityOf(record) {
@@ -84,26 +85,26 @@ function validateRecord(value) {
84
85
  const requiredKeys = ["pluginId", "pluginVersion", "manifestDigest", "installationRef", "state"];
85
86
  const allowedKeys = new Set([...requiredKeys, "source"]);
86
87
  if (!isObject(value) || Object.keys(value).some((key) => !allowedKeys.has(key)))
87
- throw new Error("record schema is invalid");
88
+ throw new Error(t("record schema is invalid"));
88
89
  for (const key of requiredKeys)
89
90
  if (!(key in value))
90
- throw new Error("record schema is invalid");
91
+ throw new Error(t("record schema is invalid"));
91
92
  const pluginId = validateString(value.pluginId, "pluginId", MAX_PLUGIN_STATE_ID_CHARS_V1);
92
93
  const pluginVersion = validateString(value.pluginVersion, "pluginVersion", MAX_PLUGIN_STATE_ID_CHARS_V1);
93
94
  const manifestDigest = validateString(value.manifestDigest, "manifestDigest");
94
95
  const installationRef = validateOpaqueInstallationRef(value.installationRef);
95
96
  const source = value.source === undefined ? undefined : validateSourceLabel(value.source);
96
97
  if (!isObject(value.state) || !hasExactKeys(value.state, ["scope", "scopeRef", "enabled", "lifecycle"]))
97
- throw new Error("state schema is invalid");
98
+ throw new Error(t("state schema is invalid"));
98
99
  if (value.state.scope !== "global" && value.state.scope !== "project")
99
- throw new Error("state scope is invalid");
100
+ throw new Error(t("state scope is invalid"));
100
101
  const scopeRef = validateScopeRef(value.state.scope, value.state.scopeRef);
101
102
  if (typeof value.state.enabled !== "boolean")
102
- throw new Error("state enabled flag is invalid");
103
+ throw new Error(t("state enabled flag is invalid"));
103
104
  if (value.state.lifecycle !== "installed" &&
104
105
  value.state.lifecycle !== "active" &&
105
106
  value.state.lifecycle !== "retained")
106
- throw new Error("state lifecycle is invalid");
107
+ throw new Error(t("state lifecycle is invalid"));
107
108
  return Object.freeze({
108
109
  pluginId,
109
110
  pluginVersion,
@@ -120,11 +121,11 @@ function validateRecord(value) {
120
121
  }
121
122
  function validateSnapshot(value) {
122
123
  if (!isObject(value) || !hasExactKeys(value, ["version", "records"]))
123
- throw new Error("snapshot schema is invalid");
124
+ throw new Error(t("snapshot schema is invalid"));
124
125
  if (value.version !== PLUGIN_STATE_SNAPSHOT_VERSION_V1)
125
- throw new Error("snapshot version is unsupported");
126
+ throw new Error(t("snapshot version is unsupported"));
126
127
  if (!Array.isArray(value.records))
127
- throw new Error("records must be an array");
128
+ throw new Error(t("records must be an array"));
128
129
  if (value.records.length > MAX_PLUGIN_STATE_RECORDS_V1)
129
130
  throw new Error("too many plugin state records");
130
131
  const records = value.records.map(validateRecord);
@@ -182,12 +183,12 @@ function makeRecord(installation, scope, enabled, source) {
182
183
  const manifestDigest = validateString(installation.manifestDigest, "manifestDigest");
183
184
  const installationRef = validateOpaqueInstallationRef(installation.installationRef);
184
185
  if (scope !== "global" && scope !== "project")
185
- throw new Error("state scope is invalid");
186
+ throw new Error(t("state scope is invalid"));
186
187
  if (installation.scope !== scope)
187
- throw new Error("installation scope does not match state scope");
188
+ throw new Error(t("installation scope does not match state scope"));
188
189
  const scopeRef = validateScopeRef(scope, scope === "global" ? (installation.scopeRef ?? DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1) : installation.scopeRef);
189
190
  if (typeof enabled !== "boolean")
190
- throw new Error("state enabled flag is invalid");
191
+ throw new Error(t("state enabled flag is invalid"));
191
192
  const sourceLabel = source === undefined ? undefined : validateSourceLabel(source);
192
193
  return Object.freeze({
193
194
  pluginId,
@@ -312,7 +313,7 @@ export function createPluginStateStoreV1(options) {
312
313
  pluginId = validateString(input.pluginId, "pluginId", MAX_PLUGIN_STATE_ID_CHARS_V1);
313
314
  pluginVersion = validateString(input.pluginVersion, "pluginVersion", MAX_PLUGIN_STATE_ID_CHARS_V1);
314
315
  if (input.scope !== "global" && input.scope !== "project")
315
- throw new Error("state scope is invalid");
316
+ throw new Error(t("state scope is invalid"));
316
317
  scope = input.scope;
317
318
  scopeRef = validateScopeRef(scope, input.scopeRef);
318
319
  }
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/state.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, resolve } from \"node:path\";\n\nimport {\n\tDEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,\n\tMAX_PLUGIN_SCOPE_REF_CHARS_V1,\n\ttype PluginInstallationV1,\n} from \"./installer.ts\";\n\nexport const PLUGIN_STATE_SNAPSHOT_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_STATE_RECORDS_V1 = 256;\nexport const MAX_PLUGIN_STATE_STRING_CHARS_V1 = 4096;\nexport const MAX_PLUGIN_STATE_ID_CHARS_V1 = 256;\nexport const MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1 = 2048;\n/** Optional acquisition source label (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`). */\nexport const MAX_PLUGIN_STATE_SOURCE_CHARS_V1 = 128;\n\nexport type PluginStateScopeV1 = \"global\" | \"project\";\nexport type PluginStateLifecycleV1 = PluginInstallationV1[\"state\"];\n\n/** Persisted identity, enablement, scope, and recoverable installation lifecycle. */\nexport interface PluginStateRecordV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly manifestDigest: string;\n\t/** Opaque host handle. It must never be a local path or file URI. */\n\treadonly installationRef: string;\n\t/** Optional acquisition source label; absent on records written before S1-b. */\n\treadonly source?: string;\n\treadonly state: {\n\t\treadonly scope: PluginStateScopeV1;\n\t\t/** Opaque concrete installation namespace; never a local path. */\n\t\treadonly scopeRef: string;\n\t\treadonly enabled: boolean;\n\t\treadonly lifecycle: PluginStateLifecycleV1;\n\t};\n}\n\nexport interface PluginStateSnapshotV1 {\n\treadonly version: typeof PLUGIN_STATE_SNAPSHOT_VERSION_V1;\n\treadonly records: readonly PluginStateRecordV1[];\n}\n\nexport type PluginStateDiagnosticCodeV1 =\n\t| \"invalid_path\"\n\t| \"invalid_json\"\n\t| \"invalid_schema\"\n\t| \"duplicate_identity\"\n\t| \"too_many_records\"\n\t| \"invalid_installation_ref\"\n\t| \"cancelled\";\n\nexport interface PluginStateDiagnosticV1 {\n\treadonly code: PluginStateDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly identity?: string;\n}\n\nexport type PluginStateReadResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| { readonly status: \"missing\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport type PluginStateMutationResultV1 =\n\t| {\n\t\t\treadonly status: \"ok\";\n\t\t\treadonly snapshot: PluginStateSnapshotV1;\n\t\t\treadonly changed: boolean;\n\t }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport interface PluginStateFileSystemV1 {\n\treadonly readFile: (path: string) => Promise<string>;\n\treadonly mkdir: (path: string) => Promise<void>;\n\treadonly writeFile: (path: string, data: string) => Promise<void>;\n\treadonly rename: (oldPath: string, newPath: string) => Promise<void>;\n\treadonly unlink: (path: string) => Promise<void>;\n}\n\nexport interface PluginStateStoreOptionsV1 {\n\t/** Absolute path to the host-owned plugin-state.json file. */\n\treadonly filePath: string;\n\t/** Injectable filesystem for deterministic tests and alternate hosts. */\n\treadonly fileSystem?: PluginStateFileSystemV1;\n}\n\nexport interface PluginStateStoreV1 {\n\treadonly read: (options?: { readonly signal?: AbortSignal }) => Promise<PluginStateReadResultV1>;\n\treadonly upsert: (input: {\n\t\treadonly installation: PluginInstallationV1;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly enabled: boolean;\n\t\t/** Optional acquisition source label persisted with the record. */\n\t\treadonly source?: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n\treadonly remove: (input: {\n\t\treadonly pluginId: string;\n\t\treadonly pluginVersion: string;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly scopeRef: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n}\n\nconst EMPTY_SNAPSHOT: PluginStateSnapshotV1 = Object.freeze({\n\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\trecords: Object.freeze([]),\n});\n\nfunction diagnostic(code: PluginStateDiagnosticCodeV1, message: string, identity?: string): PluginStateDiagnosticV1 {\n\treturn Object.freeze(identity === undefined ? { code, message } : { code, message, identity });\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn error instanceof Error && (error.name === \"AbortError\" || error.name === \"AbortSignalError\");\n}\n\nfunction isMissingError(error: unknown): boolean {\n\tif (typeof error !== \"object\" || error === null) return false;\n\treturn \"code\" in error && (error as { readonly code?: unknown }).code === \"ENOENT\";\n}\n\nfunction validateFilePath(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_STRING_CHARS_V1)\n\t\tthrow new Error(\"invalid plugin state file path\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid plugin state file path\");\n\tif (/^file:/iu.test(value) || (/^[a-z][a-z\\d+.-]*:/iu.test(value) && !/^[a-z]:[\\\\/]/iu.test(value)))\n\t\tthrow new Error(\"invalid plugin state file path\");\n\tconst normalized = isAbsolute(value) ? value : resolve(value);\n\tif (basename(normalized).length === 0 || basename(normalized) === \".\" || basename(normalized) === \"..\")\n\t\tthrow new Error(\"invalid plugin state file path\");\n\treturn normalized;\n}\n\nfunction validateOpaqueInstallationRef(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1)\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid installation reference\");\n\treturn value;\n}\n\nfunction validateScopeRef(scope: PluginStateScopeV1, value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_SCOPE_REF_CHARS_V1)\n\t\tthrow new Error(\"invalid plugin scope reference\");\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(\"invalid plugin scope reference\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid plugin scope reference\");\n\tif (scope === \"global\" && value !== DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1)\n\t\tthrow new Error(\"invalid plugin scope reference\");\n\treturn value;\n}\n\nfunction validateString(value: unknown, label: string, max = MAX_PLUGIN_STATE_STRING_CHARS_V1): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0 || value.length > max || /[\\u0000-\\u001f]/u.test(value))\n\t\tthrow new Error(`${label} is invalid`);\n\treturn value;\n}\n\n/** Acquisition source labels (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`, `github:<owner>/<repo>@<tag|latest>`). */\nfunction validateSourceLabel(value: unknown): string {\n\tif (\n\t\ttypeof value !== \"string\" ||\n\t\tvalue.length === 0 ||\n\t\tvalue.length > MAX_PLUGIN_STATE_SOURCE_CHARS_V1 ||\n\t\t!/^[a-z][a-z0-9.:[\\]_/@-]*$/u.test(value)\n\t)\n\t\tthrow new Error(\"record source label is invalid\");\n\treturn value;\n}\n\nfunction identityOf(record: PluginStateRecordV1): string {\n\treturn `${record.state.scope}:${record.state.scopeRef}:${record.pluginId}@${record.pluginVersion}`;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasExactKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n\tconst expected = new Set(keys);\n\treturn Object.keys(value).length === expected.size && Object.keys(value).every((key) => expected.has(key));\n}\n\nfunction validateRecord(value: unknown): PluginStateRecordV1 {\n\tconst requiredKeys = [\"pluginId\", \"pluginVersion\", \"manifestDigest\", \"installationRef\", \"state\"];\n\tconst allowedKeys = new Set([...requiredKeys, \"source\"]);\n\tif (!isObject(value) || Object.keys(value).some((key) => !allowedKeys.has(key)))\n\t\tthrow new Error(\"record schema is invalid\");\n\tfor (const key of requiredKeys) if (!(key in value)) throw new Error(\"record schema is invalid\");\n\tconst pluginId = validateString(value.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(value.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(value.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(value.installationRef);\n\tconst source = value.source === undefined ? undefined : validateSourceLabel(value.source);\n\tif (!isObject(value.state) || !hasExactKeys(value.state, [\"scope\", \"scopeRef\", \"enabled\", \"lifecycle\"]))\n\t\tthrow new Error(\"state schema is invalid\");\n\tif (value.state.scope !== \"global\" && value.state.scope !== \"project\") throw new Error(\"state scope is invalid\");\n\tconst scopeRef = validateScopeRef(value.state.scope, value.state.scopeRef);\n\tif (typeof value.state.enabled !== \"boolean\") throw new Error(\"state enabled flag is invalid\");\n\tif (\n\t\tvalue.state.lifecycle !== \"installed\" &&\n\t\tvalue.state.lifecycle !== \"active\" &&\n\t\tvalue.state.lifecycle !== \"retained\"\n\t)\n\t\tthrow new Error(\"state lifecycle is invalid\");\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(source === undefined ? {} : { source }),\n\t\tstate: Object.freeze({\n\t\t\tscope: value.state.scope,\n\t\t\tscopeRef,\n\t\t\tenabled: value.state.enabled,\n\t\t\tlifecycle: value.state.lifecycle,\n\t\t}),\n\t});\n}\n\nfunction validateSnapshot(value: unknown): PluginStateSnapshotV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"version\", \"records\"])) throw new Error(\"snapshot schema is invalid\");\n\tif (value.version !== PLUGIN_STATE_SNAPSHOT_VERSION_V1) throw new Error(\"snapshot version is unsupported\");\n\tif (!Array.isArray(value.records)) throw new Error(\"records must be an array\");\n\tif (value.records.length > MAX_PLUGIN_STATE_RECORDS_V1) throw new Error(\"too many plugin state records\");\n\tconst records = value.records.map(validateRecord);\n\tconst identities = new Set<string>();\n\tfor (const record of records) {\n\t\tconst identity = identityOf(record);\n\t\tif (identities.has(identity)) throw new Error(`duplicate identity: ${identity}`);\n\t\tidentities.add(identity);\n\t}\n\trecords.sort((left, right) => identityOf(left).localeCompare(identityOf(right)));\n\treturn Object.freeze({\n\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\trecords: Object.freeze(records),\n\t});\n}\n\nfunction invalidFromError(error: unknown): PluginStateDiagnosticV1 {\n\tconst message = error instanceof Error ? error.message : \"plugin state schema is invalid\";\n\tconst duplicatePrefix = \"duplicate identity: \";\n\tif (message.startsWith(duplicatePrefix))\n\t\treturn diagnostic(\"duplicate_identity\", message, message.slice(duplicatePrefix.length));\n\tif (message === \"too many plugin state records\") return diagnostic(\"too_many_records\", message);\n\tif (message === \"invalid installation reference\") return diagnostic(\"invalid_installation_ref\", message);\n\treturn diagnostic(\"invalid_schema\", message);\n}\n\nfunction defaultFileSystem(): PluginStateFileSystemV1 {\n\treturn {\n\t\treadFile: async (path) => await readFile(path, \"utf8\"),\n\t\tmkdir: async (path) => {\n\t\t\tawait mkdir(path, { recursive: true });\n\t\t},\n\t\twriteFile: async (path, data) => {\n\t\t\tawait writeFile(path, data, \"utf8\");\n\t\t},\n\t\trename,\n\t\tunlink,\n\t};\n}\n\nfunction cancelledResult(): {\n\treadonly status: \"cancelled\";\n\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n} {\n\treturn Object.freeze({\n\t\tstatus: \"cancelled\",\n\t\tdiagnostics: Object.freeze([diagnostic(\"cancelled\", \"Plugin state operation was cancelled\")]),\n\t});\n}\n\nfunction sortRecords(records: readonly PluginStateRecordV1[]): readonly PluginStateRecordV1[] {\n\treturn Object.freeze([...records].sort((left, right) => identityOf(left).localeCompare(identityOf(right))));\n}\n\nfunction makeRecord(\n\tinstallation: PluginInstallationV1,\n\tscope: PluginStateScopeV1,\n\tenabled: boolean,\n\tsource?: string,\n): PluginStateRecordV1 {\n\tif (installation.version !== 1) throw new Error(\"plugin installation handle is invalid\");\n\tconst pluginId = validateString(installation.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(installation.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(installation.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(installation.installationRef);\n\tif (scope !== \"global\" && scope !== \"project\") throw new Error(\"state scope is invalid\");\n\tif (installation.scope !== scope) throw new Error(\"installation scope does not match state scope\");\n\tconst scopeRef = validateScopeRef(\n\t\tscope,\n\t\tscope === \"global\" ? (installation.scopeRef ?? DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1) : installation.scopeRef,\n\t);\n\tif (typeof enabled !== \"boolean\") throw new Error(\"state enabled flag is invalid\");\n\tconst sourceLabel = source === undefined ? undefined : validateSourceLabel(source);\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(sourceLabel === undefined ? {} : { source: sourceLabel }),\n\t\tstate: Object.freeze({ scope, scopeRef, enabled, lifecycle: installation.state }),\n\t});\n}\n\nexport function createPluginStateStoreV1(options: PluginStateStoreOptionsV1): PluginStateStoreV1 {\n\tconst filePath = validateFilePath(options.filePath);\n\tconst fileSystem = options.fileSystem ?? defaultFileSystem();\n\n\tasync function read(signal?: AbortSignal): Promise<PluginStateReadResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = await fileSystem.readFile(filePath);\n\t\t} catch (error) {\n\t\t\tif (isMissingError(error)) return Object.freeze({ status: \"missing\", snapshot: EMPTY_SNAPSHOT });\n\t\t\tif (isAbortError(error) || signal?.aborted) return cancelledResult();\n\t\t\tthrow error;\n\t\t}\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(content) as unknown;\n\t\t} catch {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"invalid_json\", \"plugin state JSON is invalid\")]),\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"ok\",\n\t\t\t\tsnapshot: validateSnapshot(parsed),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t});\n\t\t}\n\t}\n\n\tasync function write(snapshot: PluginStateSnapshotV1, signal?: AbortSignal): Promise<PluginStateMutationResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tconst parent = dirname(filePath);\n\t\tconst temporaryPath = join(parent, `.${basename(filePath)}.${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait fileSystem.mkdir(parent);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.writeFile(temporaryPath, `${JSON.stringify(snapshot)}\\n`);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.rename(temporaryPath, filePath);\n\t\t\treturn Object.freeze({ status: \"ok\", snapshot, changed: true });\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tawait fileSystem.unlink(temporaryPath);\n\t\t\t} catch {\n\t\t\t\t// Cleanup must not replace the original write/rename error.\n\t\t\t}\n\t\t}\n\t}\n\n\t// Serialize mutations made through one store instance so concurrent CLI/UI\n\t// actions cannot lose each other's read-modify-write updates.\n\tlet mutationTail: Promise<void> = Promise.resolve();\n\tfunction enqueueMutation<T>(operation: () => Promise<T>): Promise<T> {\n\t\tconst result = mutationTail.then(operation, operation);\n\t\tmutationTail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\treturn {\n\t\tread: async ({ signal } = {}) => await read(signal),\n\t\tupsert: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet record: PluginStateRecordV1;\n\t\t\t\ttry {\n\t\t\t\t\trecord = makeRecord(input.installation, input.scope, input.enabled, input.source);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst records = current.snapshot.records.filter(\n\t\t\t\t\t(candidate) => identityOf(candidate) !== identityOf(record),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\trecords.length >= MAX_PLUGIN_STATE_RECORDS_V1 &&\n\t\t\t\t\t!current.snapshot.records.some((candidate) => identityOf(candidate) === identityOf(record))\n\t\t\t\t)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"too_many_records\", \"too many plugin state records\")]),\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords([...records, record]),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t\tremove: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet pluginId: string;\n\t\t\t\tlet pluginVersion: string;\n\t\t\t\tlet scope: PluginStateScopeV1;\n\t\t\t\tlet scopeRef: string;\n\t\t\t\ttry {\n\t\t\t\t\tpluginId = validateString(input.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tpluginVersion = validateString(input.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tif (input.scope !== \"global\" && input.scope !== \"project\") throw new Error(\"state scope is invalid\");\n\t\t\t\t\tscope = input.scope;\n\t\t\t\t\tscopeRef = validateScopeRef(scope, input.scopeRef);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst identity = `${scope}:${scopeRef}:${pluginId}@${pluginVersion}`;\n\t\t\t\tconst records = current.snapshot.records.filter((candidate) => identityOf(candidate) !== identity);\n\t\t\t\tif (records.length === current.snapshot.records.length)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"ok\",\n\t\t\t\t\t\tsnapshot: current.snapshot,\n\t\t\t\t\t\tchanged: false,\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords(records),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t};\n}\n"]}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/state.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, resolve } from \"node:path\";\n\nimport { t } from \"../../core/i18n/index.ts\";\nimport {\n\tDEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,\n\tMAX_PLUGIN_SCOPE_REF_CHARS_V1,\n\ttype PluginInstallationV1,\n} from \"./installer.ts\";\n\nexport const PLUGIN_STATE_SNAPSHOT_VERSION_V1 = 1 as const;\nexport const MAX_PLUGIN_STATE_RECORDS_V1 = 256;\nexport const MAX_PLUGIN_STATE_STRING_CHARS_V1 = 4096;\nexport const MAX_PLUGIN_STATE_ID_CHARS_V1 = 256;\nexport const MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1 = 2048;\n/** Optional acquisition source label (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`). */\nexport const MAX_PLUGIN_STATE_SOURCE_CHARS_V1 = 128;\n\nexport type PluginStateScopeV1 = \"global\" | \"project\";\nexport type PluginStateLifecycleV1 = PluginInstallationV1[\"state\"];\n\n/** Persisted identity, enablement, scope, and recoverable installation lifecycle. */\nexport interface PluginStateRecordV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly manifestDigest: string;\n\t/** Opaque host handle. It must never be a local path or file URI. */\n\treadonly installationRef: string;\n\t/** Optional acquisition source label; absent on records written before S1-b. */\n\treadonly source?: string;\n\treadonly state: {\n\t\treadonly scope: PluginStateScopeV1;\n\t\t/** Opaque concrete installation namespace; never a local path. */\n\t\treadonly scopeRef: string;\n\t\treadonly enabled: boolean;\n\t\treadonly lifecycle: PluginStateLifecycleV1;\n\t};\n}\n\nexport interface PluginStateSnapshotV1 {\n\treadonly version: typeof PLUGIN_STATE_SNAPSHOT_VERSION_V1;\n\treadonly records: readonly PluginStateRecordV1[];\n}\n\nexport type PluginStateDiagnosticCodeV1 =\n\t| \"invalid_path\"\n\t| \"invalid_json\"\n\t| \"invalid_schema\"\n\t| \"duplicate_identity\"\n\t| \"too_many_records\"\n\t| \"invalid_installation_ref\"\n\t| \"cancelled\";\n\nexport interface PluginStateDiagnosticV1 {\n\treadonly code: PluginStateDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly identity?: string;\n}\n\nexport type PluginStateReadResultV1 =\n\t| { readonly status: \"ok\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| { readonly status: \"missing\"; readonly snapshot: PluginStateSnapshotV1 }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport type PluginStateMutationResultV1 =\n\t| {\n\t\t\treadonly status: \"ok\";\n\t\t\treadonly snapshot: PluginStateSnapshotV1;\n\t\t\treadonly changed: boolean;\n\t }\n\t| {\n\t\t\treadonly status: \"invalid\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t }\n\t| {\n\t\t\treadonly status: \"cancelled\";\n\t\t\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n\t };\n\nexport interface PluginStateFileSystemV1 {\n\treadonly readFile: (path: string) => Promise<string>;\n\treadonly mkdir: (path: string) => Promise<void>;\n\treadonly writeFile: (path: string, data: string) => Promise<void>;\n\treadonly rename: (oldPath: string, newPath: string) => Promise<void>;\n\treadonly unlink: (path: string) => Promise<void>;\n}\n\nexport interface PluginStateStoreOptionsV1 {\n\t/** Absolute path to the host-owned plugin-state.json file. */\n\treadonly filePath: string;\n\t/** Injectable filesystem for deterministic tests and alternate hosts. */\n\treadonly fileSystem?: PluginStateFileSystemV1;\n}\n\nexport interface PluginStateStoreV1 {\n\treadonly read: (options?: { readonly signal?: AbortSignal }) => Promise<PluginStateReadResultV1>;\n\treadonly upsert: (input: {\n\t\treadonly installation: PluginInstallationV1;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly enabled: boolean;\n\t\t/** Optional acquisition source label persisted with the record. */\n\t\treadonly source?: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n\treadonly remove: (input: {\n\t\treadonly pluginId: string;\n\t\treadonly pluginVersion: string;\n\t\treadonly scope: PluginStateScopeV1;\n\t\treadonly scopeRef: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<PluginStateMutationResultV1>;\n}\n\nconst EMPTY_SNAPSHOT: PluginStateSnapshotV1 = Object.freeze({\n\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\trecords: Object.freeze([]),\n});\n\nfunction diagnostic(code: PluginStateDiagnosticCodeV1, message: string, identity?: string): PluginStateDiagnosticV1 {\n\treturn Object.freeze(identity === undefined ? { code, message } : { code, message, identity });\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn error instanceof Error && (error.name === \"AbortError\" || error.name === \"AbortSignalError\");\n}\n\nfunction isMissingError(error: unknown): boolean {\n\tif (typeof error !== \"object\" || error === null) return false;\n\treturn \"code\" in error && (error as { readonly code?: unknown }).code === \"ENOENT\";\n}\n\nfunction validateFilePath(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_STRING_CHARS_V1)\n\t\tthrow new Error(t(\"invalid plugin state file path\"));\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(t(\"invalid plugin state file path\"));\n\tif (/^file:/iu.test(value) || (/^[a-z][a-z\\d+.-]*:/iu.test(value) && !/^[a-z]:[\\\\/]/iu.test(value)))\n\t\tthrow new Error(t(\"invalid plugin state file path\"));\n\tconst normalized = isAbsolute(value) ? value : resolve(value);\n\tif (basename(normalized).length === 0 || basename(normalized) === \".\" || basename(normalized) === \"..\")\n\t\tthrow new Error(t(\"invalid plugin state file path\"));\n\treturn normalized;\n}\n\nfunction validateOpaqueInstallationRef(value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_STATE_INSTALLATION_REF_CHARS_V1)\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(\"invalid installation reference\");\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(\"invalid installation reference\");\n\treturn value;\n}\n\nfunction validateScopeRef(scope: PluginStateScopeV1, value: unknown): string {\n\tif (typeof value !== \"string\" || value.trim() === \"\" || value.length > MAX_PLUGIN_SCOPE_REF_CHARS_V1)\n\t\tthrow new Error(t(\"invalid plugin scope reference\"));\n\tif (/^(?:file:|[a-zA-Z]:[\\\\/]|[\\\\/]{1,2}|\\\\\\\\)/u.test(value) || /\\s/u.test(value))\n\t\tthrow new Error(t(\"invalid plugin scope reference\"));\n\tif (value.includes(\"\\0\") || /[\\u0000-\\u001f]/u.test(value)) throw new Error(t(\"invalid plugin scope reference\"));\n\tif (scope === \"global\" && value !== DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1)\n\t\tthrow new Error(t(\"invalid plugin scope reference\"));\n\treturn value;\n}\n\nfunction validateString(value: unknown, label: string, max = MAX_PLUGIN_STATE_STRING_CHARS_V1): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0 || value.length > max || /[\\u0000-\\u001f]/u.test(value))\n\t\tthrow new Error(t(\"{label} is invalid\", { label }));\n\treturn value;\n}\n\n/** Acquisition source labels (`npm:<host>`, `url:<host>`, `local:dir`, `local:file`, `github:<owner>/<repo>@<tag|latest>`). */\nfunction validateSourceLabel(value: unknown): string {\n\tif (\n\t\ttypeof value !== \"string\" ||\n\t\tvalue.length === 0 ||\n\t\tvalue.length > MAX_PLUGIN_STATE_SOURCE_CHARS_V1 ||\n\t\t!/^[a-z][a-z0-9.:[\\]_/@-]*$/u.test(value)\n\t)\n\t\tthrow new Error(t(\"record source label is invalid\"));\n\treturn value;\n}\n\nfunction identityOf(record: PluginStateRecordV1): string {\n\treturn `${record.state.scope}:${record.state.scopeRef}:${record.pluginId}@${record.pluginVersion}`;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasExactKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n\tconst expected = new Set(keys);\n\treturn Object.keys(value).length === expected.size && Object.keys(value).every((key) => expected.has(key));\n}\n\nfunction validateRecord(value: unknown): PluginStateRecordV1 {\n\tconst requiredKeys = [\"pluginId\", \"pluginVersion\", \"manifestDigest\", \"installationRef\", \"state\"];\n\tconst allowedKeys = new Set([...requiredKeys, \"source\"]);\n\tif (!isObject(value) || Object.keys(value).some((key) => !allowedKeys.has(key)))\n\t\tthrow new Error(t(\"record schema is invalid\"));\n\tfor (const key of requiredKeys) if (!(key in value)) throw new Error(t(\"record schema is invalid\"));\n\tconst pluginId = validateString(value.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(value.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(value.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(value.installationRef);\n\tconst source = value.source === undefined ? undefined : validateSourceLabel(value.source);\n\tif (!isObject(value.state) || !hasExactKeys(value.state, [\"scope\", \"scopeRef\", \"enabled\", \"lifecycle\"]))\n\t\tthrow new Error(t(\"state schema is invalid\"));\n\tif (value.state.scope !== \"global\" && value.state.scope !== \"project\") throw new Error(t(\"state scope is invalid\"));\n\tconst scopeRef = validateScopeRef(value.state.scope, value.state.scopeRef);\n\tif (typeof value.state.enabled !== \"boolean\") throw new Error(t(\"state enabled flag is invalid\"));\n\tif (\n\t\tvalue.state.lifecycle !== \"installed\" &&\n\t\tvalue.state.lifecycle !== \"active\" &&\n\t\tvalue.state.lifecycle !== \"retained\"\n\t)\n\t\tthrow new Error(t(\"state lifecycle is invalid\"));\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(source === undefined ? {} : { source }),\n\t\tstate: Object.freeze({\n\t\t\tscope: value.state.scope,\n\t\t\tscopeRef,\n\t\t\tenabled: value.state.enabled,\n\t\t\tlifecycle: value.state.lifecycle,\n\t\t}),\n\t});\n}\n\nfunction validateSnapshot(value: unknown): PluginStateSnapshotV1 {\n\tif (!isObject(value) || !hasExactKeys(value, [\"version\", \"records\"]))\n\t\tthrow new Error(t(\"snapshot schema is invalid\"));\n\tif (value.version !== PLUGIN_STATE_SNAPSHOT_VERSION_V1) throw new Error(t(\"snapshot version is unsupported\"));\n\tif (!Array.isArray(value.records)) throw new Error(t(\"records must be an array\"));\n\tif (value.records.length > MAX_PLUGIN_STATE_RECORDS_V1) throw new Error(\"too many plugin state records\");\n\tconst records = value.records.map(validateRecord);\n\tconst identities = new Set<string>();\n\tfor (const record of records) {\n\t\tconst identity = identityOf(record);\n\t\tif (identities.has(identity)) throw new Error(`duplicate identity: ${identity}`);\n\t\tidentities.add(identity);\n\t}\n\trecords.sort((left, right) => identityOf(left).localeCompare(identityOf(right)));\n\treturn Object.freeze({\n\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\trecords: Object.freeze(records),\n\t});\n}\n\nfunction invalidFromError(error: unknown): PluginStateDiagnosticV1 {\n\tconst message = error instanceof Error ? error.message : \"plugin state schema is invalid\";\n\tconst duplicatePrefix = \"duplicate identity: \";\n\tif (message.startsWith(duplicatePrefix))\n\t\treturn diagnostic(\"duplicate_identity\", message, message.slice(duplicatePrefix.length));\n\tif (message === \"too many plugin state records\") return diagnostic(\"too_many_records\", message);\n\tif (message === \"invalid installation reference\") return diagnostic(\"invalid_installation_ref\", message);\n\treturn diagnostic(\"invalid_schema\", message);\n}\n\nfunction defaultFileSystem(): PluginStateFileSystemV1 {\n\treturn {\n\t\treadFile: async (path) => await readFile(path, \"utf8\"),\n\t\tmkdir: async (path) => {\n\t\t\tawait mkdir(path, { recursive: true });\n\t\t},\n\t\twriteFile: async (path, data) => {\n\t\t\tawait writeFile(path, data, \"utf8\");\n\t\t},\n\t\trename,\n\t\tunlink,\n\t};\n}\n\nfunction cancelledResult(): {\n\treadonly status: \"cancelled\";\n\treadonly diagnostics: readonly PluginStateDiagnosticV1[];\n} {\n\treturn Object.freeze({\n\t\tstatus: \"cancelled\",\n\t\tdiagnostics: Object.freeze([diagnostic(\"cancelled\", \"Plugin state operation was cancelled\")]),\n\t});\n}\n\nfunction sortRecords(records: readonly PluginStateRecordV1[]): readonly PluginStateRecordV1[] {\n\treturn Object.freeze([...records].sort((left, right) => identityOf(left).localeCompare(identityOf(right))));\n}\n\nfunction makeRecord(\n\tinstallation: PluginInstallationV1,\n\tscope: PluginStateScopeV1,\n\tenabled: boolean,\n\tsource?: string,\n): PluginStateRecordV1 {\n\tif (installation.version !== 1) throw new Error(\"plugin installation handle is invalid\");\n\tconst pluginId = validateString(installation.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst pluginVersion = validateString(installation.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\tconst manifestDigest = validateString(installation.manifestDigest, \"manifestDigest\");\n\tconst installationRef = validateOpaqueInstallationRef(installation.installationRef);\n\tif (scope !== \"global\" && scope !== \"project\") throw new Error(t(\"state scope is invalid\"));\n\tif (installation.scope !== scope) throw new Error(t(\"installation scope does not match state scope\"));\n\tconst scopeRef = validateScopeRef(\n\t\tscope,\n\t\tscope === \"global\" ? (installation.scopeRef ?? DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1) : installation.scopeRef,\n\t);\n\tif (typeof enabled !== \"boolean\") throw new Error(t(\"state enabled flag is invalid\"));\n\tconst sourceLabel = source === undefined ? undefined : validateSourceLabel(source);\n\treturn Object.freeze({\n\t\tpluginId,\n\t\tpluginVersion,\n\t\tmanifestDigest,\n\t\tinstallationRef,\n\t\t...(sourceLabel === undefined ? {} : { source: sourceLabel }),\n\t\tstate: Object.freeze({ scope, scopeRef, enabled, lifecycle: installation.state }),\n\t});\n}\n\nexport function createPluginStateStoreV1(options: PluginStateStoreOptionsV1): PluginStateStoreV1 {\n\tconst filePath = validateFilePath(options.filePath);\n\tconst fileSystem = options.fileSystem ?? defaultFileSystem();\n\n\tasync function read(signal?: AbortSignal): Promise<PluginStateReadResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = await fileSystem.readFile(filePath);\n\t\t} catch (error) {\n\t\t\tif (isMissingError(error)) return Object.freeze({ status: \"missing\", snapshot: EMPTY_SNAPSHOT });\n\t\t\tif (isAbortError(error) || signal?.aborted) return cancelledResult();\n\t\t\tthrow error;\n\t\t}\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(content) as unknown;\n\t\t} catch {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"invalid_json\", \"plugin state JSON is invalid\")]),\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"ok\",\n\t\t\t\tsnapshot: validateSnapshot(parsed),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn Object.freeze({\n\t\t\t\tstatus: \"invalid\",\n\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t});\n\t\t}\n\t}\n\n\tasync function write(snapshot: PluginStateSnapshotV1, signal?: AbortSignal): Promise<PluginStateMutationResultV1> {\n\t\tif (signal?.aborted) return cancelledResult();\n\t\tconst parent = dirname(filePath);\n\t\tconst temporaryPath = join(parent, `.${basename(filePath)}.${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait fileSystem.mkdir(parent);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.writeFile(temporaryPath, `${JSON.stringify(snapshot)}\\n`);\n\t\t\tif (signal?.aborted) return cancelledResult();\n\t\t\tawait fileSystem.rename(temporaryPath, filePath);\n\t\t\treturn Object.freeze({ status: \"ok\", snapshot, changed: true });\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tawait fileSystem.unlink(temporaryPath);\n\t\t\t} catch {\n\t\t\t\t// Cleanup must not replace the original write/rename error.\n\t\t\t}\n\t\t}\n\t}\n\n\t// Serialize mutations made through one store instance so concurrent CLI/UI\n\t// actions cannot lose each other's read-modify-write updates.\n\tlet mutationTail: Promise<void> = Promise.resolve();\n\tfunction enqueueMutation<T>(operation: () => Promise<T>): Promise<T> {\n\t\tconst result = mutationTail.then(operation, operation);\n\t\tmutationTail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\treturn {\n\t\tread: async ({ signal } = {}) => await read(signal),\n\t\tupsert: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet record: PluginStateRecordV1;\n\t\t\t\ttry {\n\t\t\t\t\trecord = makeRecord(input.installation, input.scope, input.enabled, input.source);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst records = current.snapshot.records.filter(\n\t\t\t\t\t(candidate) => identityOf(candidate) !== identityOf(record),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\trecords.length >= MAX_PLUGIN_STATE_RECORDS_V1 &&\n\t\t\t\t\t!current.snapshot.records.some((candidate) => identityOf(candidate) === identityOf(record))\n\t\t\t\t)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([diagnostic(\"too_many_records\", \"too many plugin state records\")]),\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords([...records, record]),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t\tremove: (input) =>\n\t\t\tenqueueMutation(async () => {\n\t\t\t\tlet pluginId: string;\n\t\t\t\tlet pluginVersion: string;\n\t\t\t\tlet scope: PluginStateScopeV1;\n\t\t\t\tlet scopeRef: string;\n\t\t\t\ttry {\n\t\t\t\t\tpluginId = validateString(input.pluginId, \"pluginId\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tpluginVersion = validateString(input.pluginVersion, \"pluginVersion\", MAX_PLUGIN_STATE_ID_CHARS_V1);\n\t\t\t\t\tif (input.scope !== \"global\" && input.scope !== \"project\") throw new Error(t(\"state scope is invalid\"));\n\t\t\t\t\tscope = input.scope;\n\t\t\t\t\tscopeRef = validateScopeRef(scope, input.scopeRef);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"invalid\",\n\t\t\t\t\t\tdiagnostics: Object.freeze([invalidFromError(error)]),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst current = await read(input.signal);\n\t\t\t\tif (current.status !== \"ok\" && current.status !== \"missing\") return current;\n\t\t\t\tif (input.signal?.aborted) return cancelledResult();\n\t\t\t\tconst identity = `${scope}:${scopeRef}:${pluginId}@${pluginVersion}`;\n\t\t\t\tconst records = current.snapshot.records.filter((candidate) => identityOf(candidate) !== identity);\n\t\t\t\tif (records.length === current.snapshot.records.length)\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\tstatus: \"ok\",\n\t\t\t\t\t\tsnapshot: current.snapshot,\n\t\t\t\t\t\tchanged: false,\n\t\t\t\t\t});\n\t\t\t\tconst snapshot = Object.freeze({\n\t\t\t\t\tversion: PLUGIN_STATE_SNAPSHOT_VERSION_V1,\n\t\t\t\t\trecords: sortRecords(records),\n\t\t\t\t});\n\t\t\t\treturn await write(snapshot, input.signal);\n\t\t\t}),\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"updates.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/updates.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,MAAM,YAAY,CAAC;AAcpB,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAEzE;AAoCD,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IAC1C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB,GAAG,oBAAoB,CAUvB;AAED,MAAM,MAAM,oBAAoB,GAC7B;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,GACtE;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnG,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC3C,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5D,QAAQ,CAAC,QAAQ,CAAC,EAAE,sBAAsB,CAAC;CAC3C,GAAG,oBAAoB,CAsEvB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,oBAAoB,GAAG,oBAAoB,CAGzF;AAED,6EAA6E;AAC7E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;CACxC,GAAG,oBAAoB,CAMvB","sourcesContent":["import { VERSION } from \"../../config.ts\";\nimport { stableJsonDigest } from \"../../profile/identity.ts\";\nimport { resolvePluginCompatibilityV1 } from \"./resolver.ts\";\nimport type {\n\tCapabilityRefV1,\n\tHostFactsV1,\n\tPluginManifestV1,\n\tPluginSourceVerifierV1,\n\tPluginUpdateRecordV1,\n} from \"./types.ts\";\n\nfunction manifestPayload(manifest: PluginManifestV1): Record<string, unknown> {\n\treturn {\n\t\tid: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\tapiVersion: manifest.apiVersion,\n\t\t...(manifest.capabilityRefs === undefined ? {} : { capabilityRefs: manifest.capabilityRefs }),\n\t\t...(manifest.requires === undefined ? {} : { requires: manifest.requires }),\n\t\t...(manifest.platform === undefined ? {} : { platform: manifest.platform }),\n\t\ttestOnly: manifest.testOnly ?? false,\n\t};\n}\n\nexport function pluginManifestDigestV1(manifest: PluginManifestV1): string {\n\treturn stableJsonDigest(manifestPayload(manifest) as Parameters<typeof stableJsonDigest>[0]);\n}\n\nfunction snapshotManifest(manifest: PluginManifestV1): PluginManifestV1 {\n\tconst capabilityRefs = manifest.capabilityRefs?.map((ref) => Object.freeze({ ...ref }));\n\tconst requires = manifest.requires?.map((requirement) => Object.freeze({ ...requirement }));\n\tconst platform = manifest.platform;\n\tconst runtime = platform?.runtime?.map((constraint) => Object.freeze({ ...constraint }));\n\tconst adapters = platform?.adapters?.map((adapter) =>\n\t\tObject.freeze({\n\t\t\t...adapter,\n\t\t\tos: Object.freeze([...adapter.os]),\n\t\t\t...(adapter.arch === undefined ? {} : { arch: Object.freeze([...adapter.arch]) }),\n\t\t\t...(adapter.hostFeatures === undefined ? {} : { hostFeatures: Object.freeze([...adapter.hostFeatures]) }),\n\t\t}),\n\t);\n\tconst platformSnapshot =\n\t\tplatform === undefined\n\t\t\t? undefined\n\t\t\t: Object.freeze({\n\t\t\t\t\t...platform,\n\t\t\t\t\tos: Object.freeze([...platform.os]),\n\t\t\t\t\t...(platform.arch === undefined ? {} : { arch: Object.freeze([...platform.arch]) }),\n\t\t\t\t\t...(runtime === undefined ? {} : { runtime: Object.freeze(runtime) }),\n\t\t\t\t\t...(platform.hostFeatures === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { hostFeatures: Object.freeze([...platform.hostFeatures]) }),\n\t\t\t\t\t...(adapters === undefined ? {} : { adapters: Object.freeze(adapters) }),\n\t\t\t\t});\n\treturn Object.freeze({\n\t\t...manifest,\n\t\t...(capabilityRefs === undefined ? {} : { capabilityRefs: Object.freeze(capabilityRefs) }),\n\t\t...(requires === undefined ? {} : { requires: Object.freeze(requires) }),\n\t\t...(platformSnapshot === undefined ? {} : { platform: platformSnapshot }),\n\t});\n}\n\n/** Create an immutable staged update; activation is a separate explicit transition. */\nexport function stagePluginUpdateV1(input: {\n\treadonly manifest: PluginManifestV1;\n\treadonly source: string;\n}): PluginUpdateRecordV1 {\n\tif (input.source.trim().length === 0) throw new Error(\"update source must be a non-empty string\");\n\treturn Object.freeze({\n\t\tpluginId: input.manifest.id,\n\t\tpluginVersion: input.manifest.pluginVersion,\n\t\tsource: input.source,\n\t\tmanifest: snapshotManifest(input.manifest),\n\t\tmanifestDigest: pluginManifestDigestV1(input.manifest),\n\t\tstate: \"staged\",\n\t});\n}\n\nexport type UpdateVerificationV1 =\n\t| { readonly status: \"verified\"; readonly record: PluginUpdateRecordV1 }\n\t| { readonly status: \"rejected\"; readonly record: PluginUpdateRecordV1; readonly reason: string };\n\n/** Verify digest and host compatibility without applying any policy or side effect. */\nexport function verifyPluginUpdateV1(input: {\n\treadonly record: PluginUpdateRecordV1;\n\treadonly host: HostFactsV1;\n\treadonly expectedDigest?: string;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\treadonly verifier?: PluginSourceVerifierV1;\n}): UpdateVerificationV1 {\n\tconst actualDigest = pluginManifestDigestV1(input.record.manifest);\n\tif (input.record.state !== \"staged\") {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: `Update must be staged before verification: ${input.record.state}`,\n\t\t};\n\t}\n\tif (input.record.pluginId !== input.record.manifest.id) {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: \"Update record plugin ID does not match embedded manifest\",\n\t\t};\n\t}\n\tif (input.record.pluginVersion !== input.record.manifest.pluginVersion) {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: \"Update record plugin version does not match embedded manifest\",\n\t\t};\n\t}\n\tif (input.record.manifestDigest !== actualDigest) {\n\t\treturn { status: \"rejected\", record: input.record, reason: \"Staged manifest digest drifted\" };\n\t}\n\tif (input.expectedDigest !== undefined && input.expectedDigest !== actualDigest) {\n\t\treturn { status: \"rejected\", record: input.record, reason: \"Manifest digest does not match expectation\" };\n\t}\n\tconst resolution = resolvePluginCompatibilityV1({\n\t\tmanifest: input.record.manifest,\n\t\thost: input.host,\n\t\trequired: true,\n\t\tavailableCapabilities: input.availableCapabilities,\n\t\t// D-073: update verification enforces the declared host version range;\n\t\t// previously this path skipped the check entirely.\n\t\thostVersion: VERSION,\n\t});\n\tif (resolution.status !== \"installed-ready\") {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: `Plugin is not ready on host: ${resolution.status}`,\n\t\t};\n\t}\n\tif (input.verifier !== undefined) {\n\t\ttry {\n\t\t\tconst sourceVerification = input.verifier({\n\t\t\t\tpluginId: input.record.pluginId,\n\t\t\t\tpluginVersion: input.record.pluginVersion,\n\t\t\t\tsource: input.record.source,\n\t\t\t\tmanifestDigest: actualDigest,\n\t\t\t});\n\t\t\tif (sourceVerification.status !== \"accepted\") {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"rejected\",\n\t\t\t\t\trecord: input.record,\n\t\t\t\t\treason: \"Plugin source was rejected by the configured verifier\",\n\t\t\t\t};\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tstatus: \"rejected\",\n\t\t\t\trecord: input.record,\n\t\t\t\treason: \"Plugin source verifier failed\",\n\t\t\t};\n\t\t}\n\t}\n\tconst record = Object.freeze({ ...input.record, state: \"verified\" as const });\n\treturn { status: \"verified\", record };\n}\n\nexport function activatePluginUpdateV1(record: PluginUpdateRecordV1): PluginUpdateRecordV1 {\n\tif (record.state !== \"verified\") throw new Error(`Only a verified update can become active: ${record.pluginId}`);\n\treturn Object.freeze({ ...record, state: \"active\" as const });\n}\n\n/** Preserve the old record and return it as active after a failed update. */\nexport function rollbackPluginUpdateV1(input: {\n\treadonly failed: PluginUpdateRecordV1;\n\treadonly previous: PluginUpdateRecordV1;\n}): PluginUpdateRecordV1 {\n\tif (input.previous.pluginId !== input.failed.pluginId) {\n\t\tthrow new Error(\"Cannot rollback updates for different plugins\");\n\t}\n\tif (input.previous.state !== \"active\") throw new Error(\"Rollback target must be active\");\n\treturn Object.freeze({ ...input.previous, state: \"active\" as const });\n}\n"]}
1
+ {"version":3,"file":"updates.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/updates.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACX,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,MAAM,YAAY,CAAC;AAcpB,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAEzE;AAoCD,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IAC1C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB,GAAG,oBAAoB,CAUvB;AAED,MAAM,MAAM,oBAAoB,GAC7B;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,GACtE;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnG,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC3C,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5D,QAAQ,CAAC,QAAQ,CAAC,EAAE,sBAAsB,CAAC;CAC3C,GAAG,oBAAoB,CAsEvB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,oBAAoB,GAAG,oBAAoB,CAIzF;AAED,6EAA6E;AAC7E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;CACxC,GAAG,oBAAoB,CAMvB","sourcesContent":["import { VERSION } from \"../../config.ts\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport { stableJsonDigest } from \"../../profile/identity.ts\";\nimport { resolvePluginCompatibilityV1 } from \"./resolver.ts\";\nimport type {\n\tCapabilityRefV1,\n\tHostFactsV1,\n\tPluginManifestV1,\n\tPluginSourceVerifierV1,\n\tPluginUpdateRecordV1,\n} from \"./types.ts\";\n\nfunction manifestPayload(manifest: PluginManifestV1): Record<string, unknown> {\n\treturn {\n\t\tid: manifest.id,\n\t\tpluginVersion: manifest.pluginVersion,\n\t\tapiVersion: manifest.apiVersion,\n\t\t...(manifest.capabilityRefs === undefined ? {} : { capabilityRefs: manifest.capabilityRefs }),\n\t\t...(manifest.requires === undefined ? {} : { requires: manifest.requires }),\n\t\t...(manifest.platform === undefined ? {} : { platform: manifest.platform }),\n\t\ttestOnly: manifest.testOnly ?? false,\n\t};\n}\n\nexport function pluginManifestDigestV1(manifest: PluginManifestV1): string {\n\treturn stableJsonDigest(manifestPayload(manifest) as Parameters<typeof stableJsonDigest>[0]);\n}\n\nfunction snapshotManifest(manifest: PluginManifestV1): PluginManifestV1 {\n\tconst capabilityRefs = manifest.capabilityRefs?.map((ref) => Object.freeze({ ...ref }));\n\tconst requires = manifest.requires?.map((requirement) => Object.freeze({ ...requirement }));\n\tconst platform = manifest.platform;\n\tconst runtime = platform?.runtime?.map((constraint) => Object.freeze({ ...constraint }));\n\tconst adapters = platform?.adapters?.map((adapter) =>\n\t\tObject.freeze({\n\t\t\t...adapter,\n\t\t\tos: Object.freeze([...adapter.os]),\n\t\t\t...(adapter.arch === undefined ? {} : { arch: Object.freeze([...adapter.arch]) }),\n\t\t\t...(adapter.hostFeatures === undefined ? {} : { hostFeatures: Object.freeze([...adapter.hostFeatures]) }),\n\t\t}),\n\t);\n\tconst platformSnapshot =\n\t\tplatform === undefined\n\t\t\t? undefined\n\t\t\t: Object.freeze({\n\t\t\t\t\t...platform,\n\t\t\t\t\tos: Object.freeze([...platform.os]),\n\t\t\t\t\t...(platform.arch === undefined ? {} : { arch: Object.freeze([...platform.arch]) }),\n\t\t\t\t\t...(runtime === undefined ? {} : { runtime: Object.freeze(runtime) }),\n\t\t\t\t\t...(platform.hostFeatures === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { hostFeatures: Object.freeze([...platform.hostFeatures]) }),\n\t\t\t\t\t...(adapters === undefined ? {} : { adapters: Object.freeze(adapters) }),\n\t\t\t\t});\n\treturn Object.freeze({\n\t\t...manifest,\n\t\t...(capabilityRefs === undefined ? {} : { capabilityRefs: Object.freeze(capabilityRefs) }),\n\t\t...(requires === undefined ? {} : { requires: Object.freeze(requires) }),\n\t\t...(platformSnapshot === undefined ? {} : { platform: platformSnapshot }),\n\t});\n}\n\n/** Create an immutable staged update; activation is a separate explicit transition. */\nexport function stagePluginUpdateV1(input: {\n\treadonly manifest: PluginManifestV1;\n\treadonly source: string;\n}): PluginUpdateRecordV1 {\n\tif (input.source.trim().length === 0) throw new Error(t(\"update source must be a non-empty string\"));\n\treturn Object.freeze({\n\t\tpluginId: input.manifest.id,\n\t\tpluginVersion: input.manifest.pluginVersion,\n\t\tsource: input.source,\n\t\tmanifest: snapshotManifest(input.manifest),\n\t\tmanifestDigest: pluginManifestDigestV1(input.manifest),\n\t\tstate: \"staged\",\n\t});\n}\n\nexport type UpdateVerificationV1 =\n\t| { readonly status: \"verified\"; readonly record: PluginUpdateRecordV1 }\n\t| { readonly status: \"rejected\"; readonly record: PluginUpdateRecordV1; readonly reason: string };\n\n/** Verify digest and host compatibility without applying any policy or side effect. */\nexport function verifyPluginUpdateV1(input: {\n\treadonly record: PluginUpdateRecordV1;\n\treadonly host: HostFactsV1;\n\treadonly expectedDigest?: string;\n\treadonly availableCapabilities?: readonly CapabilityRefV1[];\n\treadonly verifier?: PluginSourceVerifierV1;\n}): UpdateVerificationV1 {\n\tconst actualDigest = pluginManifestDigestV1(input.record.manifest);\n\tif (input.record.state !== \"staged\") {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: `Update must be staged before verification: ${input.record.state}`,\n\t\t};\n\t}\n\tif (input.record.pluginId !== input.record.manifest.id) {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: \"Update record plugin ID does not match embedded manifest\",\n\t\t};\n\t}\n\tif (input.record.pluginVersion !== input.record.manifest.pluginVersion) {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: \"Update record plugin version does not match embedded manifest\",\n\t\t};\n\t}\n\tif (input.record.manifestDigest !== actualDigest) {\n\t\treturn { status: \"rejected\", record: input.record, reason: \"Staged manifest digest drifted\" };\n\t}\n\tif (input.expectedDigest !== undefined && input.expectedDigest !== actualDigest) {\n\t\treturn { status: \"rejected\", record: input.record, reason: \"Manifest digest does not match expectation\" };\n\t}\n\tconst resolution = resolvePluginCompatibilityV1({\n\t\tmanifest: input.record.manifest,\n\t\thost: input.host,\n\t\trequired: true,\n\t\tavailableCapabilities: input.availableCapabilities,\n\t\t// D-073: update verification enforces the declared host version range;\n\t\t// previously this path skipped the check entirely.\n\t\thostVersion: VERSION,\n\t});\n\tif (resolution.status !== \"installed-ready\") {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\trecord: input.record,\n\t\t\treason: `Plugin is not ready on host: ${resolution.status}`,\n\t\t};\n\t}\n\tif (input.verifier !== undefined) {\n\t\ttry {\n\t\t\tconst sourceVerification = input.verifier({\n\t\t\t\tpluginId: input.record.pluginId,\n\t\t\t\tpluginVersion: input.record.pluginVersion,\n\t\t\t\tsource: input.record.source,\n\t\t\t\tmanifestDigest: actualDigest,\n\t\t\t});\n\t\t\tif (sourceVerification.status !== \"accepted\") {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"rejected\",\n\t\t\t\t\trecord: input.record,\n\t\t\t\t\treason: \"Plugin source was rejected by the configured verifier\",\n\t\t\t\t};\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tstatus: \"rejected\",\n\t\t\t\trecord: input.record,\n\t\t\t\treason: \"Plugin source verifier failed\",\n\t\t\t};\n\t\t}\n\t}\n\tconst record = Object.freeze({ ...input.record, state: \"verified\" as const });\n\treturn { status: \"verified\", record };\n}\n\nexport function activatePluginUpdateV1(record: PluginUpdateRecordV1): PluginUpdateRecordV1 {\n\tif (record.state !== \"verified\")\n\t\tthrow new Error(t(\"Only a verified update can become active: {pluginId}\", { pluginId: record.pluginId }));\n\treturn Object.freeze({ ...record, state: \"active\" as const });\n}\n\n/** Preserve the old record and return it as active after a failed update. */\nexport function rollbackPluginUpdateV1(input: {\n\treadonly failed: PluginUpdateRecordV1;\n\treadonly previous: PluginUpdateRecordV1;\n}): PluginUpdateRecordV1 {\n\tif (input.previous.pluginId !== input.failed.pluginId) {\n\t\tthrow new Error(t(\"Cannot rollback updates for different plugins\"));\n\t}\n\tif (input.previous.state !== \"active\") throw new Error(t(\"Rollback target must be active\"));\n\treturn Object.freeze({ ...input.previous, state: \"active\" as const });\n}\n"]}