@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
  const NODE_HTTP_PLUGIN_REGISTRY_SOURCE_VERSION_V1 = 1;
2
3
  const DEFAULT_TIMEOUT_MS_V1 = 15_000;
3
4
  const MAX_TIMEOUT_MS_V1 = 120_000;
@@ -18,7 +19,7 @@ export class NodeHttpPluginRegistrySourceErrorV1 extends Error {
18
19
  function boundedPositive(value, fallback, maximum, label) {
19
20
  const result = value ?? fallback;
20
21
  if (!Number.isSafeInteger(result) || result <= 0 || result > maximum) {
21
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", `${label} must be a positive integer at most ${maximum}`);
22
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", t("{label} must be a positive integer at most {maximum}", { label, maximum }));
22
23
  }
23
24
  return result;
24
25
  }
@@ -28,13 +29,13 @@ function allowedOrigin(value) {
28
29
  parsed = new URL(value);
29
30
  }
30
31
  catch {
31
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", "Allowed registry origin is invalid");
32
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", t("Allowed registry origin is invalid"));
32
33
  }
33
34
  if ((parsed.protocol !== "http:" && parsed.protocol !== "https:") || parsed.username || parsed.password) {
34
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", "Allowed registry origin must be an http(s) origin without credentials");
35
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", t("Allowed registry origin must be an http(s) origin without credentials"));
35
36
  }
36
37
  if (parsed.pathname !== "/" || parsed.search !== "" || parsed.hash !== "") {
37
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", "Allowed registry origin must not include a path, query, or fragment");
38
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", t("Allowed registry origin must not include a path, query, or fragment"));
38
39
  }
39
40
  return parsed.origin;
40
41
  }
@@ -44,16 +45,16 @@ function endpointUrl(value, origins) {
44
45
  parsed = new URL(value);
45
46
  }
46
47
  catch {
47
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", "Plugin registry URL is invalid");
48
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", t("Plugin registry URL is invalid"));
48
49
  }
49
50
  if ((parsed.protocol !== "http:" && parsed.protocol !== "https:") || parsed.username || parsed.password) {
50
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", "Plugin registry URL must use http(s) without credentials");
51
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", t("Plugin registry URL must use http(s) without credentials"));
51
52
  }
52
53
  if (parsed.search !== "" || parsed.hash !== "") {
53
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", "Plugin registry URL must not include a query or fragment");
54
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", t("Plugin registry URL must not include a query or fragment"));
54
55
  }
55
56
  if (!origins.has(parsed.origin)) {
56
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", "Plugin registry origin is not allowed");
57
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", t("Plugin registry origin is not allowed"));
57
58
  }
58
59
  return parsed;
59
60
  }
@@ -62,11 +63,11 @@ function responseLength(response) {
62
63
  if (raw === null)
63
64
  return undefined;
64
65
  if (!/^\d+$/u.test(raw)) {
65
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", "Plugin registry response length is invalid");
66
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", t("Plugin registry response length is invalid"));
66
67
  }
67
68
  const value = Number(raw);
68
69
  if (!Number.isSafeInteger(value)) {
69
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", "Plugin registry response length is invalid");
70
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", t("Plugin registry response length is invalid"));
70
71
  }
71
72
  return value;
72
73
  }
@@ -132,7 +133,7 @@ function discardResponseBody(response) {
132
133
  }
133
134
  async function readBody(response, maxBytes, signal) {
134
135
  if (response.body === null) {
135
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", "Plugin registry response has no body");
136
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", t("Plugin registry response has no body"));
136
137
  }
137
138
  const reader = response.body.getReader();
138
139
  const chunks = [];
@@ -140,13 +141,13 @@ async function readBody(response, maxBytes, signal) {
140
141
  try {
141
142
  for (;;) {
142
143
  if (signal.aborted)
143
- throw new DOMException("aborted", "AbortError");
144
+ throw new DOMException(t("aborted"), "AbortError");
144
145
  const item = await awaitBeforeAbort(reader.read(), signal);
145
146
  if (item.done)
146
147
  break;
147
148
  total += item.value.byteLength;
148
149
  if (total > maxBytes) {
149
- throw new NodeHttpPluginRegistrySourceErrorV1("response_too_large", "Plugin registry response exceeds the configured size limit");
150
+ throw new NodeHttpPluginRegistrySourceErrorV1("response_too_large", t("Plugin registry response exceeds the configured size limit"));
150
151
  }
151
152
  chunks.push(item.value);
152
153
  }
@@ -168,16 +169,16 @@ function parseDocument(bytes) {
168
169
  value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
169
170
  }
170
171
  catch {
171
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", "Plugin registry response is not valid JSON");
172
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", t("Plugin registry response is not valid JSON"));
172
173
  }
173
174
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
174
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", "Plugin registry document is invalid");
175
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", t("Plugin registry document is invalid"));
175
176
  }
176
177
  const document = value;
177
178
  if (Object.keys(document).some((key) => key !== "version" && key !== "entries") ||
178
179
  document.version !== 1 ||
179
180
  !Array.isArray(document.entries)) {
180
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", "Plugin registry document is invalid");
181
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", t("Plugin registry document is invalid"));
181
182
  }
182
183
  return document.entries;
183
184
  }
@@ -195,9 +196,9 @@ function sanitizedSourceError(error) {
195
196
  code !== "request_timed_out" &&
196
197
  code !== "invalid_response" &&
197
198
  code !== "response_too_large") {
198
- return new NodeHttpPluginRegistrySourceErrorV1("request_failed", "Plugin registry request failed");
199
+ return new NodeHttpPluginRegistrySourceErrorV1("request_failed", t("Plugin registry request failed"));
199
200
  }
200
- return new NodeHttpPluginRegistrySourceErrorV1(code, "Plugin registry request failed");
201
+ return new NodeHttpPluginRegistrySourceErrorV1(code, t("Plugin registry request failed"));
201
202
  }
202
203
  /**
203
204
  * Creates a bounded, allowlisted HTTP registry reader. It only transports
@@ -207,10 +208,10 @@ function sanitizedSourceError(error) {
207
208
  export function createNodeHttpPluginRegistrySourceV1(options) {
208
209
  const transport = options.fetch ?? globalThis.fetch;
209
210
  if (typeof transport !== "function") {
210
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", "Node fetch is unavailable");
211
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", t("Node fetch is unavailable"));
211
212
  }
212
213
  if (!Array.isArray(options.allowedOrigins) || options.allowedOrigins.length === 0) {
213
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", "At least one allowed registry origin is required");
214
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", t("At least one allowed registry origin is required"));
214
215
  }
215
216
  const origins = new Set(options.allowedOrigins.map(allowedOrigin));
216
217
  const endpoint = endpointUrl(options.url, origins);
@@ -218,7 +219,7 @@ export function createNodeHttpPluginRegistrySourceV1(options) {
218
219
  const maxResponseBytes = boundedPositive(options.maxResponseBytes, DEFAULT_MAX_RESPONSE_BYTES_V1, MAX_RESPONSE_BYTES_V1, "maxResponseBytes");
219
220
  const userAgent = options.userAgent ?? "agent-forge-plugin-registry/1";
220
221
  if (userAgent.length === 0 || userAgent.length > 256 || /[\r\n]/u.test(userAgent)) {
221
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", "userAgent is invalid");
222
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_configuration", t("userAgent is invalid"));
222
223
  }
223
224
  const source = endpoint.origin + endpoint.pathname;
224
225
  return {
@@ -226,14 +227,14 @@ export function createNodeHttpPluginRegistrySourceV1(options) {
226
227
  source,
227
228
  list: async ({ signal } = {}) => {
228
229
  if (isCallerCancelled(signal)) {
229
- throw new NodeHttpPluginRegistrySourceErrorV1("cancelled", "Plugin registry request was cancelled");
230
+ throw new NodeHttpPluginRegistrySourceErrorV1("cancelled", t("Plugin registry request was cancelled"));
230
231
  }
231
232
  const request = requestController(signal, timeoutMs);
232
233
  let response;
233
234
  try {
234
235
  const transportResponse = Promise.resolve().then(() => {
235
236
  if (request.signal.aborted)
236
- throw new DOMException("aborted", "AbortError");
237
+ throw new DOMException(t("aborted"), "AbortError");
237
238
  return transport(endpoint.toString(), {
238
239
  method: "GET",
239
240
  headers: {
@@ -251,30 +252,30 @@ export function createNodeHttpPluginRegistrySourceV1(options) {
251
252
  const receivedResponse = await awaitBeforeAbort(transportResponse, request.signal);
252
253
  response = receivedResponse;
253
254
  if (receivedResponse.status < 200 || receivedResponse.status >= 300) {
254
- throw new NodeHttpPluginRegistrySourceErrorV1("request_failed", "Plugin registry request did not succeed");
255
+ throw new NodeHttpPluginRegistrySourceErrorV1("request_failed", t("Plugin registry request did not succeed"));
255
256
  }
256
257
  if (!isJsonResponse(receivedResponse)) {
257
- throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", "Plugin registry response must be JSON");
258
+ throw new NodeHttpPluginRegistrySourceErrorV1("invalid_response", t("Plugin registry response must be JSON"));
258
259
  }
259
260
  const length = responseLength(receivedResponse);
260
261
  if (length !== undefined && length > maxResponseBytes) {
261
- throw new NodeHttpPluginRegistrySourceErrorV1("response_too_large", "Plugin registry response exceeds the configured size limit");
262
+ throw new NodeHttpPluginRegistrySourceErrorV1("response_too_large", t("Plugin registry response exceeds the configured size limit"));
262
263
  }
263
264
  return parseDocument(await readBody(receivedResponse, maxResponseBytes, request.signal));
264
265
  }
265
266
  catch (error) {
266
267
  if (isCallerCancelled(signal)) {
267
- throw new NodeHttpPluginRegistrySourceErrorV1("cancelled", "Plugin registry request was cancelled");
268
+ throw new NodeHttpPluginRegistrySourceErrorV1("cancelled", t("Plugin registry request was cancelled"));
268
269
  }
269
270
  if (request.timedOut()) {
270
- throw new NodeHttpPluginRegistrySourceErrorV1("request_timed_out", "Plugin registry request timed out");
271
+ throw new NodeHttpPluginRegistrySourceErrorV1("request_timed_out", t("Plugin registry request timed out"));
271
272
  }
272
273
  if (error instanceof NodeHttpPluginRegistrySourceErrorV1)
273
274
  throw sanitizedSourceError(error);
274
275
  if (isAbortLike(error)) {
275
- throw new NodeHttpPluginRegistrySourceErrorV1("cancelled", "Plugin registry request was cancelled");
276
+ throw new NodeHttpPluginRegistrySourceErrorV1("cancelled", t("Plugin registry request was cancelled"));
276
277
  }
277
- throw new NodeHttpPluginRegistrySourceErrorV1("request_failed", "Plugin registry request failed");
278
+ throw new NodeHttpPluginRegistrySourceErrorV1("request_failed", t("Plugin registry request failed"));
278
279
  }
279
280
  finally {
280
281
  request.cleanup();
@@ -1 +1 @@
1
- {"version":3,"file":"node-registry-source.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/node-registry-source.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PluginRegistryManifestEnvelopeV1, PluginRegistrySourceV1 } from \"./registry.ts\";\n\nconst NODE_HTTP_PLUGIN_REGISTRY_SOURCE_VERSION_V1 = 1 as const;\nconst DEFAULT_TIMEOUT_MS_V1 = 15_000;\nconst MAX_TIMEOUT_MS_V1 = 120_000;\nconst DEFAULT_MAX_RESPONSE_BYTES_V1 = 4 * 1024 * 1024;\nconst MAX_RESPONSE_BYTES_V1 = 8 * 1024 * 1024;\n\nexport type NodeHttpPluginRegistrySourceErrorCodeV1 =\n\t| \"cancelled\"\n\t| \"invalid_configuration\"\n\t| \"request_failed\"\n\t| \"request_timed_out\"\n\t| \"invalid_response\"\n\t| \"response_too_large\";\n\n/**\n * Deliberately does not retain transport exceptions or response bodies: callers\n * must not turn registry diagnostics into a credential or path disclosure.\n */\nexport class NodeHttpPluginRegistrySourceErrorV1 extends Error {\n\treadonly code: NodeHttpPluginRegistrySourceErrorCodeV1;\n\n\tconstructor(code: NodeHttpPluginRegistrySourceErrorCodeV1, message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"NodeHttpPluginRegistrySourceErrorV1\";\n\t\tthis.code = code;\n\t}\n}\n\nexport interface NodeHttpPluginRegistrySourceOptionsV1 {\n\t/** Absolute endpoint returning the versioned JSON registry document. */\n\treadonly url: string | URL;\n\t/** Exact http(s) origins the host has intentionally allowed. */\n\treadonly allowedOrigins: readonly string[];\n\t/** Real fetch or deterministic test replacement. */\n\treadonly fetch?: typeof globalThis.fetch;\n\treadonly requestTimeoutMs?: number;\n\treadonly maxResponseBytes?: number;\n\treadonly userAgent?: string;\n}\n\nexport interface NodeHttpPluginRegistrySourceV1 extends PluginRegistrySourceV1 {\n\treadonly version: typeof NODE_HTTP_PLUGIN_REGISTRY_SOURCE_VERSION_V1;\n\t/** Sanitized endpoint identity: never contains credentials, query, or fragment. */\n\treadonly source: string;\n}\n\ninterface RegistryDocumentV1 {\n\treadonly version: 1;\n\treadonly entries: readonly PluginRegistryManifestEnvelopeV1[];\n}\n\nfunction boundedPositive(value: number | undefined, fallback: number, maximum: number, label: string): number {\n\tconst result = value ?? fallback;\n\tif (!Number.isSafeInteger(result) || result <= 0 || result > maximum) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\t`${label} must be a positive integer at most ${maximum}`,\n\t\t);\n\t}\n\treturn result;\n}\n\nfunction allowedOrigin(value: string): string {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(value);\n\t} catch {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_configuration\", \"Allowed registry origin is invalid\");\n\t}\n\tif ((parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") || parsed.username || parsed.password) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\t\"Allowed registry origin must be an http(s) origin without credentials\",\n\t\t);\n\t}\n\tif (parsed.pathname !== \"/\" || parsed.search !== \"\" || parsed.hash !== \"\") {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\t\"Allowed registry origin must not include a path, query, or fragment\",\n\t\t);\n\t}\n\treturn parsed.origin;\n}\n\nfunction endpointUrl(value: string | URL, origins: ReadonlySet<string>): URL {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(value);\n\t} catch {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_configuration\", \"Plugin registry URL is invalid\");\n\t}\n\tif ((parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") || parsed.username || parsed.password) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\t\"Plugin registry URL must use http(s) without credentials\",\n\t\t);\n\t}\n\tif (parsed.search !== \"\" || parsed.hash !== \"\") {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\t\"Plugin registry URL must not include a query or fragment\",\n\t\t);\n\t}\n\tif (!origins.has(parsed.origin)) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_configuration\", \"Plugin registry origin is not allowed\");\n\t}\n\treturn parsed;\n}\n\nfunction responseLength(response: Response): number | undefined {\n\tconst raw = response.headers.get(\"content-length\");\n\tif (raw === null) return undefined;\n\tif (!/^\\d+$/u.test(raw)) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_response\", \"Plugin registry response length is invalid\");\n\t}\n\tconst value = Number(raw);\n\tif (!Number.isSafeInteger(value)) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_response\", \"Plugin registry response length is invalid\");\n\t}\n\treturn value;\n}\n\nfunction isJsonResponse(response: Response): boolean {\n\tconst contentType = response.headers.get(\"content-type\");\n\tif (contentType === null) return false;\n\tconst mediaType = contentType.split(\";\", 1)[0]?.trim().toLowerCase();\n\treturn mediaType === \"application/json\" || mediaType === \"application/vnd.agent-forge.plugin-registry+json\";\n}\n\nfunction requestController(\n\tparent: AbortSignal | undefined,\n\ttimeoutMs: number,\n): {\n\treadonly signal: AbortSignal;\n\treadonly timedOut: () => boolean;\n\treadonly cleanup: () => void;\n} {\n\tconst controller = new AbortController();\n\tlet timedOut = false;\n\tconst abort = () => controller.abort(parent?.reason);\n\tif (parent?.aborted === true) abort();\n\telse parent?.addEventListener(\"abort\", abort, { once: true });\n\tconst timeout = setTimeout(() => {\n\t\ttimedOut = true;\n\t\tcontroller.abort();\n\t}, timeoutMs);\n\treturn {\n\t\tsignal: controller.signal,\n\t\ttimedOut: () => timedOut,\n\t\tcleanup: () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tparent?.removeEventListener(\"abort\", abort);\n\t\t},\n\t};\n}\n\nfunction abortPromise(signal: AbortSignal): { readonly promise: Promise<never>; readonly cleanup: () => void } {\n\tlet rejectAbort: (() => void) | undefined;\n\tconst promise = new Promise<never>((_resolve, reject) => {\n\t\trejectAbort = () => reject(new DOMException(\"aborted\", \"AbortError\"));\n\t\tif (signal.aborted) rejectAbort();\n\t\telse signal.addEventListener(\"abort\", rejectAbort, { once: true });\n\t});\n\treturn {\n\t\tpromise,\n\t\tcleanup: () => {\n\t\t\tif (rejectAbort !== undefined) signal.removeEventListener(\"abort\", rejectAbort);\n\t\t},\n\t};\n}\n\nasync function awaitBeforeAbort<T>(operation: Promise<T>, signal: AbortSignal): Promise<T> {\n\tconst abort = abortPromise(signal);\n\ttry {\n\t\treturn await Promise.race([operation, abort.promise]);\n\t} finally {\n\t\tabort.cleanup();\n\t}\n}\n\nfunction discardResponseBody(response: Response | undefined): void {\n\tconst responseBody = response?.body;\n\tif (responseBody !== undefined && responseBody !== null) {\n\t\tvoid responseBody.cancel().catch(() => undefined);\n\t}\n}\n\nasync function readBody(response: Response, maxBytes: number, signal: AbortSignal): Promise<Uint8Array> {\n\tif (response.body === null) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_response\", \"Plugin registry response has no body\");\n\t}\n\tconst reader = response.body.getReader();\n\tconst chunks: Uint8Array[] = [];\n\tlet total = 0;\n\ttry {\n\t\tfor (;;) {\n\t\t\tif (signal.aborted) throw new DOMException(\"aborted\", \"AbortError\");\n\t\t\tconst item = await awaitBeforeAbort(reader.read(), signal);\n\t\t\tif (item.done) break;\n\t\t\ttotal += item.value.byteLength;\n\t\t\tif (total > maxBytes) {\n\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\t\t\"response_too_large\",\n\t\t\t\t\t\"Plugin registry response exceeds the configured size limit\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tchunks.push(item.value);\n\t\t}\n\t} finally {\n\t\treader.releaseLock();\n\t}\n\tconst bytes = new Uint8Array(total);\n\tlet offset = 0;\n\tfor (const chunk of chunks) {\n\t\tbytes.set(chunk, offset);\n\t\toffset += chunk.byteLength;\n\t}\n\treturn bytes;\n}\n\nfunction parseDocument(bytes: Uint8Array): readonly PluginRegistryManifestEnvelopeV1[] {\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes));\n\t} catch {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_response\", \"Plugin registry response is not valid JSON\");\n\t}\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_response\", \"Plugin registry document is invalid\");\n\t}\n\tconst document = value as Record<string, unknown>;\n\tif (\n\t\tObject.keys(document).some((key) => key !== \"version\" && key !== \"entries\") ||\n\t\tdocument.version !== 1 ||\n\t\t!Array.isArray(document.entries)\n\t) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_response\", \"Plugin registry document is invalid\");\n\t}\n\treturn document.entries as unknown as RegistryDocumentV1[\"entries\"];\n}\n\nfunction isAbortLike(error: unknown): boolean {\n\treturn error instanceof DOMException && error.name === \"AbortError\";\n}\n\nfunction isCallerCancelled(signal: AbortSignal | undefined): boolean {\n\treturn signal?.aborted === true;\n}\n\nfunction sanitizedSourceError(error: NodeHttpPluginRegistrySourceErrorV1): NodeHttpPluginRegistrySourceErrorV1 {\n\tconst code: unknown = error.code;\n\tif (\n\t\tcode !== \"cancelled\" &&\n\t\tcode !== \"invalid_configuration\" &&\n\t\tcode !== \"request_failed\" &&\n\t\tcode !== \"request_timed_out\" &&\n\t\tcode !== \"invalid_response\" &&\n\t\tcode !== \"response_too_large\"\n\t) {\n\t\treturn new NodeHttpPluginRegistrySourceErrorV1(\"request_failed\", \"Plugin registry request failed\");\n\t}\n\treturn new NodeHttpPluginRegistrySourceErrorV1(code, \"Plugin registry request failed\");\n}\n\n/**\n * Creates a bounded, allowlisted HTTP registry reader. It only transports\n * metadata to the existing registry verifier; package bytes, trust decisions,\n * and installation remain separate host-owned capabilities.\n */\nexport function createNodeHttpPluginRegistrySourceV1(\n\toptions: NodeHttpPluginRegistrySourceOptionsV1,\n): NodeHttpPluginRegistrySourceV1 {\n\tconst transport = options.fetch ?? globalThis.fetch;\n\tif (typeof transport !== \"function\") {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_configuration\", \"Node fetch is unavailable\");\n\t}\n\tif (!Array.isArray(options.allowedOrigins) || options.allowedOrigins.length === 0) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\t\"At least one allowed registry origin is required\",\n\t\t);\n\t}\n\tconst origins = new Set(options.allowedOrigins.map(allowedOrigin));\n\tconst endpoint = endpointUrl(options.url, origins);\n\tconst timeoutMs = boundedPositive(\n\t\toptions.requestTimeoutMs,\n\t\tDEFAULT_TIMEOUT_MS_V1,\n\t\tMAX_TIMEOUT_MS_V1,\n\t\t\"requestTimeoutMs\",\n\t);\n\tconst maxResponseBytes = boundedPositive(\n\t\toptions.maxResponseBytes,\n\t\tDEFAULT_MAX_RESPONSE_BYTES_V1,\n\t\tMAX_RESPONSE_BYTES_V1,\n\t\t\"maxResponseBytes\",\n\t);\n\tconst userAgent = options.userAgent ?? \"agent-forge-plugin-registry/1\";\n\tif (userAgent.length === 0 || userAgent.length > 256 || /[\\r\\n]/u.test(userAgent)) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_configuration\", \"userAgent is invalid\");\n\t}\n\tconst source = endpoint.origin + endpoint.pathname;\n\n\treturn {\n\t\tversion: NODE_HTTP_PLUGIN_REGISTRY_SOURCE_VERSION_V1,\n\t\tsource,\n\t\tlist: async ({ signal } = {}) => {\n\t\t\tif (isCallerCancelled(signal)) {\n\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"cancelled\", \"Plugin registry request was cancelled\");\n\t\t\t}\n\t\t\tconst request = requestController(signal, timeoutMs);\n\t\t\tlet response: Response | undefined;\n\t\t\ttry {\n\t\t\t\tconst transportResponse = Promise.resolve().then(() => {\n\t\t\t\t\tif (request.signal.aborted) throw new DOMException(\"aborted\", \"AbortError\");\n\t\t\t\t\treturn transport(endpoint.toString(), {\n\t\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\taccept: \"application/vnd.agent-forge.plugin-registry+json, application/json\",\n\t\t\t\t\t\t\t\"user-agent\": userAgent,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tredirect: \"error\",\n\t\t\t\t\t\tsignal: request.signal,\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t\tvoid transportResponse.then(\n\t\t\t\t\t(lateResponse) => {\n\t\t\t\t\t\tif (request.signal.aborted) discardResponseBody(lateResponse);\n\t\t\t\t\t},\n\t\t\t\t\t() => undefined,\n\t\t\t\t);\n\t\t\t\tconst receivedResponse = await awaitBeforeAbort(transportResponse, request.signal);\n\t\t\t\tresponse = receivedResponse;\n\t\t\t\tif (receivedResponse.status < 200 || receivedResponse.status >= 300) {\n\t\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\t\t\t\"request_failed\",\n\t\t\t\t\t\t\"Plugin registry request did not succeed\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!isJsonResponse(receivedResponse)) {\n\t\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\t\t\t\"invalid_response\",\n\t\t\t\t\t\t\"Plugin registry response must be JSON\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst length = responseLength(receivedResponse);\n\t\t\t\tif (length !== undefined && length > maxResponseBytes) {\n\t\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\t\t\t\"response_too_large\",\n\t\t\t\t\t\t\"Plugin registry response exceeds the configured size limit\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn parseDocument(await readBody(receivedResponse, maxResponseBytes, request.signal));\n\t\t\t} catch (error) {\n\t\t\t\tif (isCallerCancelled(signal)) {\n\t\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"cancelled\", \"Plugin registry request was cancelled\");\n\t\t\t\t}\n\t\t\t\tif (request.timedOut()) {\n\t\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"request_timed_out\", \"Plugin registry request timed out\");\n\t\t\t\t}\n\t\t\t\tif (error instanceof NodeHttpPluginRegistrySourceErrorV1) throw sanitizedSourceError(error);\n\t\t\t\tif (isAbortLike(error)) {\n\t\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"cancelled\", \"Plugin registry request was cancelled\");\n\t\t\t\t}\n\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"request_failed\", \"Plugin registry request failed\");\n\t\t\t} finally {\n\t\t\t\trequest.cleanup();\n\t\t\t\tdiscardResponseBody(response);\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"node-registry-source.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/node-registry-source.ts"],"names":[],"mappings":"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","sourcesContent":["import { t } from \"../../core/i18n/index.ts\";\nimport type { PluginRegistryManifestEnvelopeV1, PluginRegistrySourceV1 } from \"./registry.ts\";\n\nconst NODE_HTTP_PLUGIN_REGISTRY_SOURCE_VERSION_V1 = 1 as const;\nconst DEFAULT_TIMEOUT_MS_V1 = 15_000;\nconst MAX_TIMEOUT_MS_V1 = 120_000;\nconst DEFAULT_MAX_RESPONSE_BYTES_V1 = 4 * 1024 * 1024;\nconst MAX_RESPONSE_BYTES_V1 = 8 * 1024 * 1024;\n\nexport type NodeHttpPluginRegistrySourceErrorCodeV1 =\n\t| \"cancelled\"\n\t| \"invalid_configuration\"\n\t| \"request_failed\"\n\t| \"request_timed_out\"\n\t| \"invalid_response\"\n\t| \"response_too_large\";\n\n/**\n * Deliberately does not retain transport exceptions or response bodies: callers\n * must not turn registry diagnostics into a credential or path disclosure.\n */\nexport class NodeHttpPluginRegistrySourceErrorV1 extends Error {\n\treadonly code: NodeHttpPluginRegistrySourceErrorCodeV1;\n\n\tconstructor(code: NodeHttpPluginRegistrySourceErrorCodeV1, message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"NodeHttpPluginRegistrySourceErrorV1\";\n\t\tthis.code = code;\n\t}\n}\n\nexport interface NodeHttpPluginRegistrySourceOptionsV1 {\n\t/** Absolute endpoint returning the versioned JSON registry document. */\n\treadonly url: string | URL;\n\t/** Exact http(s) origins the host has intentionally allowed. */\n\treadonly allowedOrigins: readonly string[];\n\t/** Real fetch or deterministic test replacement. */\n\treadonly fetch?: typeof globalThis.fetch;\n\treadonly requestTimeoutMs?: number;\n\treadonly maxResponseBytes?: number;\n\treadonly userAgent?: string;\n}\n\nexport interface NodeHttpPluginRegistrySourceV1 extends PluginRegistrySourceV1 {\n\treadonly version: typeof NODE_HTTP_PLUGIN_REGISTRY_SOURCE_VERSION_V1;\n\t/** Sanitized endpoint identity: never contains credentials, query, or fragment. */\n\treadonly source: string;\n}\n\ninterface RegistryDocumentV1 {\n\treadonly version: 1;\n\treadonly entries: readonly PluginRegistryManifestEnvelopeV1[];\n}\n\nfunction boundedPositive(value: number | undefined, fallback: number, maximum: number, label: string): number {\n\tconst result = value ?? fallback;\n\tif (!Number.isSafeInteger(result) || result <= 0 || result > maximum) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\tt(\"{label} must be a positive integer at most {maximum}\", { label, maximum }),\n\t\t);\n\t}\n\treturn result;\n}\n\nfunction allowedOrigin(value: string): string {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(value);\n\t} catch {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_configuration\", t(\"Allowed registry origin is invalid\"));\n\t}\n\tif ((parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") || parsed.username || parsed.password) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\tt(\"Allowed registry origin must be an http(s) origin without credentials\"),\n\t\t);\n\t}\n\tif (parsed.pathname !== \"/\" || parsed.search !== \"\" || parsed.hash !== \"\") {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\tt(\"Allowed registry origin must not include a path, query, or fragment\"),\n\t\t);\n\t}\n\treturn parsed.origin;\n}\n\nfunction endpointUrl(value: string | URL, origins: ReadonlySet<string>): URL {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(value);\n\t} catch {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_configuration\", t(\"Plugin registry URL is invalid\"));\n\t}\n\tif ((parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") || parsed.username || parsed.password) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\tt(\"Plugin registry URL must use http(s) without credentials\"),\n\t\t);\n\t}\n\tif (parsed.search !== \"\" || parsed.hash !== \"\") {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\tt(\"Plugin registry URL must not include a query or fragment\"),\n\t\t);\n\t}\n\tif (!origins.has(parsed.origin)) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\tt(\"Plugin registry origin is not allowed\"),\n\t\t);\n\t}\n\treturn parsed;\n}\n\nfunction responseLength(response: Response): number | undefined {\n\tconst raw = response.headers.get(\"content-length\");\n\tif (raw === null) return undefined;\n\tif (!/^\\d+$/u.test(raw)) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_response\",\n\t\t\tt(\"Plugin registry response length is invalid\"),\n\t\t);\n\t}\n\tconst value = Number(raw);\n\tif (!Number.isSafeInteger(value)) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_response\",\n\t\t\tt(\"Plugin registry response length is invalid\"),\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction isJsonResponse(response: Response): boolean {\n\tconst contentType = response.headers.get(\"content-type\");\n\tif (contentType === null) return false;\n\tconst mediaType = contentType.split(\";\", 1)[0]?.trim().toLowerCase();\n\treturn mediaType === \"application/json\" || mediaType === \"application/vnd.agent-forge.plugin-registry+json\";\n}\n\nfunction requestController(\n\tparent: AbortSignal | undefined,\n\ttimeoutMs: number,\n): {\n\treadonly signal: AbortSignal;\n\treadonly timedOut: () => boolean;\n\treadonly cleanup: () => void;\n} {\n\tconst controller = new AbortController();\n\tlet timedOut = false;\n\tconst abort = () => controller.abort(parent?.reason);\n\tif (parent?.aborted === true) abort();\n\telse parent?.addEventListener(\"abort\", abort, { once: true });\n\tconst timeout = setTimeout(() => {\n\t\ttimedOut = true;\n\t\tcontroller.abort();\n\t}, timeoutMs);\n\treturn {\n\t\tsignal: controller.signal,\n\t\ttimedOut: () => timedOut,\n\t\tcleanup: () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tparent?.removeEventListener(\"abort\", abort);\n\t\t},\n\t};\n}\n\nfunction abortPromise(signal: AbortSignal): { readonly promise: Promise<never>; readonly cleanup: () => void } {\n\tlet rejectAbort: (() => void) | undefined;\n\tconst promise = new Promise<never>((_resolve, reject) => {\n\t\trejectAbort = () => reject(new DOMException(\"aborted\", \"AbortError\"));\n\t\tif (signal.aborted) rejectAbort();\n\t\telse signal.addEventListener(\"abort\", rejectAbort, { once: true });\n\t});\n\treturn {\n\t\tpromise,\n\t\tcleanup: () => {\n\t\t\tif (rejectAbort !== undefined) signal.removeEventListener(\"abort\", rejectAbort);\n\t\t},\n\t};\n}\n\nasync function awaitBeforeAbort<T>(operation: Promise<T>, signal: AbortSignal): Promise<T> {\n\tconst abort = abortPromise(signal);\n\ttry {\n\t\treturn await Promise.race([operation, abort.promise]);\n\t} finally {\n\t\tabort.cleanup();\n\t}\n}\n\nfunction discardResponseBody(response: Response | undefined): void {\n\tconst responseBody = response?.body;\n\tif (responseBody !== undefined && responseBody !== null) {\n\t\tvoid responseBody.cancel().catch(() => undefined);\n\t}\n}\n\nasync function readBody(response: Response, maxBytes: number, signal: AbortSignal): Promise<Uint8Array> {\n\tif (response.body === null) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_response\", t(\"Plugin registry response has no body\"));\n\t}\n\tconst reader = response.body.getReader();\n\tconst chunks: Uint8Array[] = [];\n\tlet total = 0;\n\ttry {\n\t\tfor (;;) {\n\t\t\tif (signal.aborted) throw new DOMException(t(\"aborted\"), \"AbortError\");\n\t\t\tconst item = await awaitBeforeAbort(reader.read(), signal);\n\t\t\tif (item.done) break;\n\t\t\ttotal += item.value.byteLength;\n\t\t\tif (total > maxBytes) {\n\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\t\t\"response_too_large\",\n\t\t\t\t\tt(\"Plugin registry response exceeds the configured size limit\"),\n\t\t\t\t);\n\t\t\t}\n\t\t\tchunks.push(item.value);\n\t\t}\n\t} finally {\n\t\treader.releaseLock();\n\t}\n\tconst bytes = new Uint8Array(total);\n\tlet offset = 0;\n\tfor (const chunk of chunks) {\n\t\tbytes.set(chunk, offset);\n\t\toffset += chunk.byteLength;\n\t}\n\treturn bytes;\n}\n\nfunction parseDocument(bytes: Uint8Array): readonly PluginRegistryManifestEnvelopeV1[] {\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes));\n\t} catch {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_response\",\n\t\t\tt(\"Plugin registry response is not valid JSON\"),\n\t\t);\n\t}\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_response\", t(\"Plugin registry document is invalid\"));\n\t}\n\tconst document = value as Record<string, unknown>;\n\tif (\n\t\tObject.keys(document).some((key) => key !== \"version\" && key !== \"entries\") ||\n\t\tdocument.version !== 1 ||\n\t\t!Array.isArray(document.entries)\n\t) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_response\", t(\"Plugin registry document is invalid\"));\n\t}\n\treturn document.entries as unknown as RegistryDocumentV1[\"entries\"];\n}\n\nfunction isAbortLike(error: unknown): boolean {\n\treturn error instanceof DOMException && error.name === \"AbortError\";\n}\n\nfunction isCallerCancelled(signal: AbortSignal | undefined): boolean {\n\treturn signal?.aborted === true;\n}\n\nfunction sanitizedSourceError(error: NodeHttpPluginRegistrySourceErrorV1): NodeHttpPluginRegistrySourceErrorV1 {\n\tconst code: unknown = error.code;\n\tif (\n\t\tcode !== \"cancelled\" &&\n\t\tcode !== \"invalid_configuration\" &&\n\t\tcode !== \"request_failed\" &&\n\t\tcode !== \"request_timed_out\" &&\n\t\tcode !== \"invalid_response\" &&\n\t\tcode !== \"response_too_large\"\n\t) {\n\t\treturn new NodeHttpPluginRegistrySourceErrorV1(\"request_failed\", t(\"Plugin registry request failed\"));\n\t}\n\treturn new NodeHttpPluginRegistrySourceErrorV1(code, t(\"Plugin registry request failed\"));\n}\n\n/**\n * Creates a bounded, allowlisted HTTP registry reader. It only transports\n * metadata to the existing registry verifier; package bytes, trust decisions,\n * and installation remain separate host-owned capabilities.\n */\nexport function createNodeHttpPluginRegistrySourceV1(\n\toptions: NodeHttpPluginRegistrySourceOptionsV1,\n): NodeHttpPluginRegistrySourceV1 {\n\tconst transport = options.fetch ?? globalThis.fetch;\n\tif (typeof transport !== \"function\") {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_configuration\", t(\"Node fetch is unavailable\"));\n\t}\n\tif (!Array.isArray(options.allowedOrigins) || options.allowedOrigins.length === 0) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\tt(\"At least one allowed registry origin is required\"),\n\t\t);\n\t}\n\tconst origins = new Set(options.allowedOrigins.map(allowedOrigin));\n\tconst endpoint = endpointUrl(options.url, origins);\n\tconst timeoutMs = boundedPositive(\n\t\toptions.requestTimeoutMs,\n\t\tDEFAULT_TIMEOUT_MS_V1,\n\t\tMAX_TIMEOUT_MS_V1,\n\t\t\"requestTimeoutMs\",\n\t);\n\tconst maxResponseBytes = boundedPositive(\n\t\toptions.maxResponseBytes,\n\t\tDEFAULT_MAX_RESPONSE_BYTES_V1,\n\t\tMAX_RESPONSE_BYTES_V1,\n\t\t\"maxResponseBytes\",\n\t);\n\tconst userAgent = options.userAgent ?? \"agent-forge-plugin-registry/1\";\n\tif (userAgent.length === 0 || userAgent.length > 256 || /[\\r\\n]/u.test(userAgent)) {\n\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"invalid_configuration\", t(\"userAgent is invalid\"));\n\t}\n\tconst source = endpoint.origin + endpoint.pathname;\n\n\treturn {\n\t\tversion: NODE_HTTP_PLUGIN_REGISTRY_SOURCE_VERSION_V1,\n\t\tsource,\n\t\tlist: async ({ signal } = {}) => {\n\t\t\tif (isCallerCancelled(signal)) {\n\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"cancelled\", t(\"Plugin registry request was cancelled\"));\n\t\t\t}\n\t\t\tconst request = requestController(signal, timeoutMs);\n\t\t\tlet response: Response | undefined;\n\t\t\ttry {\n\t\t\t\tconst transportResponse = Promise.resolve().then(() => {\n\t\t\t\t\tif (request.signal.aborted) throw new DOMException(t(\"aborted\"), \"AbortError\");\n\t\t\t\t\treturn transport(endpoint.toString(), {\n\t\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\taccept: \"application/vnd.agent-forge.plugin-registry+json, application/json\",\n\t\t\t\t\t\t\t\"user-agent\": userAgent,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tredirect: \"error\",\n\t\t\t\t\t\tsignal: request.signal,\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t\tvoid transportResponse.then(\n\t\t\t\t\t(lateResponse) => {\n\t\t\t\t\t\tif (request.signal.aborted) discardResponseBody(lateResponse);\n\t\t\t\t\t},\n\t\t\t\t\t() => undefined,\n\t\t\t\t);\n\t\t\t\tconst receivedResponse = await awaitBeforeAbort(transportResponse, request.signal);\n\t\t\t\tresponse = receivedResponse;\n\t\t\t\tif (receivedResponse.status < 200 || receivedResponse.status >= 300) {\n\t\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\t\t\t\"request_failed\",\n\t\t\t\t\t\tt(\"Plugin registry request did not succeed\"),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!isJsonResponse(receivedResponse)) {\n\t\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\t\t\t\"invalid_response\",\n\t\t\t\t\t\tt(\"Plugin registry response must be JSON\"),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst length = responseLength(receivedResponse);\n\t\t\t\tif (length !== undefined && length > maxResponseBytes) {\n\t\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\t\t\t\"response_too_large\",\n\t\t\t\t\t\tt(\"Plugin registry response exceeds the configured size limit\"),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn parseDocument(await readBody(receivedResponse, maxResponseBytes, request.signal));\n\t\t\t} catch (error) {\n\t\t\t\tif (isCallerCancelled(signal)) {\n\t\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"cancelled\", t(\"Plugin registry request was cancelled\"));\n\t\t\t\t}\n\t\t\t\tif (request.timedOut()) {\n\t\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\n\t\t\t\t\t\t\"request_timed_out\",\n\t\t\t\t\t\tt(\"Plugin registry request timed out\"),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (error instanceof NodeHttpPluginRegistrySourceErrorV1) throw sanitizedSourceError(error);\n\t\t\t\tif (isAbortLike(error)) {\n\t\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"cancelled\", t(\"Plugin registry request was cancelled\"));\n\t\t\t\t}\n\t\t\t\tthrow new NodeHttpPluginRegistrySourceErrorV1(\"request_failed\", t(\"Plugin registry request failed\"));\n\t\t\t} finally {\n\t\t\t\trequest.cleanup();\n\t\t\t\tdiscardResponseBody(response);\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"node-release-package-source.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/node-release-package-source.ts"],"names":[],"mappings":"AA8BA,MAAM,MAAM,mCAAmC,GAC5C,WAAW,GACX,uBAAuB,GACvB,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,GAClB,oBAAoB,GACpB,mBAAmB,GACnB,yBAAyB,GACzB,yBAAyB,GACzB,cAAc,CAAC;AAElB,qBAAa,+BAAgC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,EAAE,mCAAmC,CAAC;IACnD,6FAA6F;IAC7F,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAEpC,YACC,IAAI,EAAE,mCAAmC,EACzC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAAE,EAMjD;CACD;AAED,MAAM,WAAW,iCAAiC;IACjD,4EAA4E;IAC5E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,6EAA6E;IAC7E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACzC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,iBAAiB,GAAG,kBAAkB,CAAC;IAC3D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE;QACtC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;QAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;QACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;KAC9B,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC;CAC1C;AAwND,sDAAsD;AACtD,wBAAgB,gCAAgC,CAC/C,OAAO,GAAE,iCAAsC,GAC7C,0BAA0B,CAsJ5B","sourcesContent":["import { downloadNodeUrlPackageV1 } from \"./node-url-package-source.ts\";\n\n/**\n * GitHub/Gitee release plugin package source (design\n * `插件独立分发与启动装配设计.md` §4.6 \"GitHub\"/\"Gitee\" rows). Two-step\n * protocol: resolve one release through the repo's release API — the exact\n * tag endpoint when a tag is given, otherwise the first non-draft entry of\n * the first releases page in API order (no client-side sorting) — then pick\n * the release's single `.zip`/`.tgz` asset and download it with the same\n * bounded http(s) semantics as custom URL packages (redirect-per-hop, budget,\n * timeout, optional strong sha256). Zero or multiple matching assets are\n * explicit structured errors listing the asset names; nothing is guessed.\n * Authentication is optional: GitHub uses an `Authorization: Bearer` header,\n * Gitee an `access_token` query parameter. Anonymous rate limits (403/429\n * with `X-RateLimit-Remaining: 0`, or any 429) surface as `rate_limited`\n * carrying the advertised `X-RateLimit-Reset` epoch; there is no retry.\n */\n\nconst DEFAULT_GITHUB_API_ORIGIN_V1 = \"https://api.github.com\";\nconst DEFAULT_GITEE_API_ORIGIN_V1 = \"https://gitee.com/api/v5\";\nconst DEFAULT_TIMEOUT_MS_V1 = 15_000;\nconst MAX_TIMEOUT_MS_V1 = 120_000;\nconst DEFAULT_MAX_RESPONSE_BYTES_V1 = 8 * 1024 * 1024;\nconst MAX_RESPONSE_BYTES_V1 = 16 * 1024 * 1024;\nconst DEFAULT_MAX_ASSET_BYTES_V1 = 128 * 1024 * 1024;\nconst MAX_ASSET_BYTES_V1 = 512 * 1024 * 1024;\nconst DEFAULT_REDIRECTS_V1 = 3;\nconst MAX_REDIRECTS_V1 = 5;\nconst REDIRECT_STATUS = new Set([301, 302, 303, 307, 308]);\n\nexport type NodeReleasePackageSourceErrorCodeV1 =\n\t| \"cancelled\"\n\t| \"invalid_configuration\"\n\t| \"request_failed\"\n\t| \"request_timed_out\"\n\t| \"invalid_response\"\n\t| \"response_too_large\"\n\t| \"release_not_found\"\n\t| \"release_asset_not_found\"\n\t| \"release_asset_ambiguous\"\n\t| \"rate_limited\";\n\nexport class NodeReleasePackageSourceErrorV1 extends Error {\n\treadonly code: NodeReleasePackageSourceErrorCodeV1;\n\t/** Unix epoch seconds advertised by `X-RateLimit-Reset`; present only for `rate_limited`. */\n\treadonly resetEpochSeconds?: number;\n\n\tconstructor(\n\t\tcode: NodeReleasePackageSourceErrorCodeV1,\n\t\tmessage: string,\n\t\toptions?: { readonly resetEpochSeconds?: number },\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"NodeReleasePackageSourceErrorV1\";\n\t\tthis.code = code;\n\t\tif (options?.resetEpochSeconds !== undefined) this.resetEpochSeconds = options.resetEpochSeconds;\n\t}\n}\n\nexport interface NodeReleasePackageSourceOptionsV1 {\n\t/** Bare http(s) GitHub API origin; defaults to `https://api.github.com`. */\n\treadonly githubApiOrigin?: string;\n\t/** Bare http(s) Gitee API origin; defaults to `https://gitee.com/api/v5`. */\n\treadonly giteeApiOrigin?: string;\n\t/** Optional GitHub API token sent as a bearer header. */\n\treadonly githubToken?: string;\n\t/** Optional Gitee API token sent as an `access_token` query parameter. */\n\treadonly giteeToken?: string;\n\t/** Real fetch or a deterministic test replacement. */\n\treadonly fetch?: typeof globalThis.fetch;\n\treadonly requestTimeoutMs?: number;\n\treadonly maxResponseBytes?: number;\n\treadonly maxAssetBytes?: number;\n\treadonly maxRedirects?: number;\n\treadonly userAgent?: string;\n}\n\nexport interface NodeReleaseAssetDownloadV1 {\n\treadonly bytes: Uint8Array;\n\treadonly mediaType: \"application/zip\" | \"application/gzip\";\n\treadonly sha256Hex: string;\n\t/** `github:<owner>/<repo>@<tag|latest>` or the `gitee:` equivalent. */\n\treadonly sourceLabel: string;\n}\n\nexport interface NodeReleasePackageSourceV1 {\n\treadonly version: 1;\n\treadonly downloadReleaseAsset: (input: {\n\t\treadonly kind: \"github\" | \"gitee\";\n\t\treadonly owner: string;\n\t\treadonly repo: string;\n\t\treadonly tag?: string;\n\t\treadonly expectedDigestHex?: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<NodeReleaseAssetDownloadV1>;\n}\n\ninterface ReleaseAssetShapeV1 {\n\treadonly name?: unknown;\n\treadonly browser_download_url?: unknown;\n}\n\ninterface ReleaseShapeV1 {\n\treadonly draft?: unknown;\n\treadonly assets?: unknown;\n}\n\nfunction boundedPositive(value: number | undefined, fallback: number, maximum: number, label: string): number {\n\tconst result = value ?? fallback;\n\tif (!Number.isSafeInteger(result) || result <= 0 || result > maximum)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\t`${label} must be a positive integer at most ${maximum}`,\n\t\t);\n\treturn result;\n}\n\nfunction boundedToken(value: string | undefined, label: string): string | undefined {\n\tif (value === undefined) return undefined;\n\tif (value.length === 0 || value.length > 4096 || /[\\r\\n\\s]/u.test(value))\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_configuration\", `${label} is invalid`);\n\treturn value;\n}\n\nfunction apiOrigin(value: string, label: string): { readonly origin: string; readonly pathPrefix: string } {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(value);\n\t} catch {\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_configuration\", `${label} is invalid`);\n\t}\n\tif (\n\t\t(parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") ||\n\t\tparsed.username !== \"\" ||\n\t\tparsed.password !== \"\"\n\t)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\t`${label} must be http(s) without credentials`,\n\t\t);\n\tif (parsed.search !== \"\" || parsed.hash !== \"\")\n\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\t`${label} must not include a query or fragment`,\n\t\t);\n\t// The Gitee default origin carries the `/api/v5` path prefix. The prefix is\n\t// kept as a plain string because a URL normalizes an empty pathname back\n\t// to \"/\", which would reintroduce a double slash when joining endpoints.\n\tconst trimmed = parsed.pathname.replace(/\\/+$/u, \"\");\n\treturn { origin: parsed.origin, pathPrefix: trimmed === \"\" || trimmed === \"/\" ? \"\" : trimmed.replace(/^\\//u, \"\") };\n}\n\nfunction jsonBytes(value: Uint8Array): unknown {\n\ttry {\n\t\treturn JSON.parse(new TextDecoder(\"utf-8\", { fatal: true }).decode(value));\n\t} catch {\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", \"release API response is not valid JSON\");\n\t}\n}\n\nfunction parseReleaseList(bytes: Uint8Array): readonly ReleaseShapeV1[] {\n\tconst value = jsonBytes(bytes);\n\tif (!Array.isArray(value))\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", \"release API response is not a release list\");\n\treturn value as readonly ReleaseShapeV1[];\n}\n\nfunction parseReleaseObject(bytes: Uint8Array): ReleaseShapeV1 {\n\tconst value = jsonBytes(bytes);\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value))\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", \"release API response is not a release object\");\n\treturn value as ReleaseShapeV1;\n}\n\n/** First non-draft entry in API order; the array itself is the ordering contract. */\nfunction firstPublishedRelease(releases: readonly ReleaseShapeV1[]): ReleaseShapeV1 {\n\tconst published = releases.find((release) => release.draft !== true);\n\tif (published === undefined)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"release_not_found\", \"repo has no published release\");\n\treturn published;\n}\n\ninterface ReleaseAssetNameV1 {\n\treadonly name: string;\n\treadonly url: unknown;\n}\n\n/** Assets with a usable name; entries without a string name are ignored as API noise. */\nfunction namedAssets(release: ReleaseShapeV1): readonly ReleaseAssetNameV1[] {\n\tif (release.assets === undefined) return [];\n\tif (!Array.isArray(release.assets))\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", \"release assets are invalid\");\n\tconst entries: ReleaseAssetNameV1[] = [];\n\tfor (const asset of release.assets) {\n\t\tif (typeof asset !== \"object\" || asset === null) continue;\n\t\tconst shape = asset as ReleaseAssetShapeV1;\n\t\tif (typeof shape.name !== \"string\" || shape.name.length === 0) continue;\n\t\tentries.push({ name: shape.name, url: shape.browser_download_url });\n\t}\n\treturn entries;\n}\n\nfunction isPackageAssetName(name: string): boolean {\n\tconst value = name.toLowerCase();\n\treturn value.endsWith(\".zip\") || value.endsWith(\".tgz\");\n}\n\n/** Select the release's single `.zip`/`.tgz` asset and return its download URL. */\nfunction selectPackageAssetUrl(release: ReleaseShapeV1): string {\n\tconst assets = namedAssets(release);\n\tconst candidates = assets.filter((asset) => isPackageAssetName(asset.name));\n\tconst assetNames = assets.map((asset) => asset.name).join(\", \");\n\tif (candidates.length === 0)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\"release_asset_not_found\",\n\t\t\tassetNames.length === 0 ? \"release has no assets\" : `assets: ${assetNames}`,\n\t\t);\n\tif (candidates.length > 1)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\"release_asset_ambiguous\",\n\t\t\t`candidates: ${candidates.map((asset) => asset.name).join(\", \")}`,\n\t\t);\n\tconst chosen = candidates[0]!;\n\tif (typeof chosen.url !== \"string\" || chosen.url.length === 0)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", \"release asset has no download URL\");\n\treturn chosen.url;\n}\n\nfunction isAbortLike(error: unknown): boolean {\n\treturn error instanceof Error && (error.name === \"AbortError\" || error.name === \"AbortSignalError\");\n}\n\ninterface RequestSignal {\n\treadonly signal: AbortSignal;\n\treadonly timedOut: () => boolean;\n\treadonly cleanup: () => void;\n}\n\nfunction requestSignal(parent: AbortSignal | undefined, timeoutMs: number): RequestSignal {\n\tconst controller = new AbortController();\n\tlet timedOut = false;\n\tconst abort = () => controller.abort(parent?.reason);\n\tif (parent?.aborted === true) abort();\n\telse parent?.addEventListener(\"abort\", abort, { once: true });\n\tconst timeout = setTimeout(() => {\n\t\ttimedOut = true;\n\t\tcontroller.abort();\n\t}, timeoutMs);\n\treturn {\n\t\tsignal: controller.signal,\n\t\ttimedOut: () => timedOut,\n\t\tcleanup: () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tparent?.removeEventListener(\"abort\", abort);\n\t\t},\n\t};\n}\n\nfunction isJsonResponse(response: Response): boolean {\n\tconst contentType = response.headers.get(\"content-type\");\n\tif (contentType === null) return false;\n\tconst mediaType = contentType.split(\";\", 1)[0]?.trim().toLowerCase();\n\treturn mediaType === \"application/json\" || mediaType === \"application/vnd.github+json\";\n}\n\n/**\n * Rate-limit verdict for 403/429 responses: any 429, and a 403 whose\n * `X-RateLimit-Remaining` is exactly `0`. The reset epoch is passed through\n * verbatim when present and integer-like; absent headers stay absent.\n */\nfunction rateLimitState(response: Response): { readonly limited: boolean; readonly resetEpochSeconds?: number } {\n\tconst limited =\n\t\tresponse.status === 429 || (response.status === 403 && response.headers.get(\"x-ratelimit-remaining\") === \"0\");\n\tif (!limited) return { limited: false };\n\tconst reset = response.headers.get(\"x-ratelimit-reset\");\n\tconst resetValue = reset === null ? Number.NaN : Number.parseInt(reset, 10);\n\tif (!Number.isSafeInteger(resetValue) || resetValue < 0) return { limited: true };\n\treturn { limited: true, resetEpochSeconds: resetValue };\n}\n\nasync function readBody(response: Response, maxBytes: number, signal: AbortSignal): Promise<Uint8Array> {\n\tif (response.body === null)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", \"release API response has no body\");\n\tconst reader = response.body.getReader();\n\tconst chunks: Uint8Array[] = [];\n\tlet total = 0;\n\ttry {\n\t\tfor (;;) {\n\t\t\tif (signal.aborted) throw new DOMException(\"aborted\", \"AbortError\");\n\t\t\tconst item = await reader.read();\n\t\t\tif (item.done) break;\n\t\t\ttotal += item.value.byteLength;\n\t\t\tif (total > maxBytes)\n\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\t\t\"response_too_large\",\n\t\t\t\t\t\"release API response exceeds the configured size limit\",\n\t\t\t\t);\n\t\t\tchunks.push(item.value);\n\t\t}\n\t} finally {\n\t\treader.releaseLock();\n\t}\n\tconst bytes = new Uint8Array(total);\n\tlet offset = 0;\n\tfor (const chunk of chunks) {\n\t\tbytes.set(chunk, offset);\n\t\toffset += chunk.byteLength;\n\t}\n\treturn bytes;\n}\n\n/** Create the bounded GitHub/Gitee release reader. */\nexport function createNodeReleasePackageSourceV1(\n\toptions: NodeReleasePackageSourceOptionsV1 = {},\n): NodeReleasePackageSourceV1 {\n\tconst transport = options.fetch ?? globalThis.fetch;\n\tif (typeof transport !== \"function\")\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_configuration\", \"Node fetch is unavailable\");\n\tconst githubOrigin = apiOrigin(options.githubApiOrigin ?? DEFAULT_GITHUB_API_ORIGIN_V1, \"githubApiOrigin\");\n\tconst giteeOrigin = apiOrigin(options.giteeApiOrigin ?? DEFAULT_GITEE_API_ORIGIN_V1, \"giteeApiOrigin\");\n\tconst githubToken = boundedToken(options.githubToken, \"githubToken\");\n\tconst giteeToken = boundedToken(options.giteeToken, \"giteeToken\");\n\tconst timeoutMs = boundedPositive(\n\t\toptions.requestTimeoutMs,\n\t\tDEFAULT_TIMEOUT_MS_V1,\n\t\tMAX_TIMEOUT_MS_V1,\n\t\t\"requestTimeoutMs\",\n\t);\n\tconst maxResponseBytes = boundedPositive(\n\t\toptions.maxResponseBytes,\n\t\tDEFAULT_MAX_RESPONSE_BYTES_V1,\n\t\tMAX_RESPONSE_BYTES_V1,\n\t\t\"maxResponseBytes\",\n\t);\n\tconst maxAssetBytes = boundedPositive(\n\t\toptions.maxAssetBytes,\n\t\tDEFAULT_MAX_ASSET_BYTES_V1,\n\t\tMAX_ASSET_BYTES_V1,\n\t\t\"maxAssetBytes\",\n\t);\n\tconst maxRedirects = options.maxRedirects ?? DEFAULT_REDIRECTS_V1;\n\tif (!Number.isSafeInteger(maxRedirects) || maxRedirects < 0 || maxRedirects > MAX_REDIRECTS_V1)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\t`maxRedirects must be an integer between 0 and ${MAX_REDIRECTS_V1}`,\n\t\t);\n\tconst userAgent = options.userAgent ?? \"agent-forge-plugin-release/1\";\n\tif (userAgent.length === 0 || userAgent.length > 256 || /[\\r\\n]/u.test(userAgent))\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_configuration\", \"userAgent is invalid\");\n\n\tconst fetchReleaseJson = async (\n\t\turl: URL,\n\t\theaders: Readonly<Record<string, string>>,\n\t\tparentSignal: AbortSignal | undefined,\n\t): Promise<Uint8Array> => {\n\t\tlet current = url;\n\t\tfor (let redirect = 0; ; redirect += 1) {\n\t\t\tconst request = requestSignal(parentSignal, timeoutMs);\n\t\t\tlet response: Response;\n\t\t\ttry {\n\t\t\t\tresponse = await transport(current.toString(), {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\theaders: { accept: \"application/json\", \"user-agent\": userAgent, ...headers },\n\t\t\t\t\tredirect: \"manual\",\n\t\t\t\t\tsignal: request.signal,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\trequest.cleanup();\n\t\t\t\tif (request.timedOut())\n\t\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"request_timed_out\", \"release API request timed out\");\n\t\t\t\tif (isAbortLike(error))\n\t\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"cancelled\", \"release API request was cancelled\");\n\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"request_failed\", \"release API request failed\");\n\t\t\t}\n\t\t\tif (!REDIRECT_STATUS.has(response.status)) {\n\t\t\t\ttry {\n\t\t\t\t\tif (response.status === 404)\n\t\t\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"release_not_found\", \"repo or release was not found\");\n\t\t\t\t\tconst limit = rateLimitState(response);\n\t\t\t\t\tif (limit.limited) {\n\t\t\t\t\t\tconst message =\n\t\t\t\t\t\t\tlimit.resetEpochSeconds === undefined\n\t\t\t\t\t\t\t\t? \"rate limit was exceeded\"\n\t\t\t\t\t\t\t\t: `rate limit resets at ${new Date(limit.resetEpochSeconds * 1000).toISOString()}`;\n\t\t\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"rate_limited\", message, {\n\t\t\t\t\t\t\t...(limit.resetEpochSeconds === undefined ? {} : { resetEpochSeconds: limit.resetEpochSeconds }),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (response.status < 200 || response.status >= 300)\n\t\t\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"request_failed\", \"release API request did not succeed\");\n\t\t\t\t\tif (!isJsonResponse(response))\n\t\t\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", \"release API response must be JSON\");\n\t\t\t\t\tconst bytes = await readBody(response, maxResponseBytes, request.signal);\n\t\t\t\t\treturn bytes;\n\t\t\t\t} finally {\n\t\t\t\t\tawait response.body?.cancel().catch(() => undefined);\n\t\t\t\t\trequest.cleanup();\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst location = response.headers.get(\"location\");\n\t\t\tawait response.body?.cancel().catch(() => undefined);\n\t\t\trequest.cleanup();\n\t\t\tif (location === null || redirect >= maxRedirects)\n\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"request_failed\", \"release API redirect limit exceeded\");\n\t\t\tlet next: URL;\n\t\t\ttry {\n\t\t\t\tnext = new URL(location, current);\n\t\t\t} catch {\n\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", \"release API redirect target is invalid\");\n\t\t\t}\n\t\t\tif ((next.protocol !== \"http:\" && next.protocol !== \"https:\") || next.username !== \"\" || next.password !== \"\")\n\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", \"release API redirect must stay http(s)\");\n\t\t\tcurrent = next;\n\t\t}\n\t};\n\n\tconst downloadReleaseAsset: NodeReleasePackageSourceV1[\"downloadReleaseAsset\"] = async (input) => {\n\t\tif (input.signal?.aborted === true)\n\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"cancelled\", \"release asset download was cancelled\");\n\t\tconst sourceLabel = `${input.kind}:${input.owner}/${input.repo}@${input.tag ?? \"latest\"}`;\n\t\tconst base = input.kind === \"github\" ? githubOrigin : giteeOrigin;\n\t\tconst segments = [\n\t\t\tbase.pathPrefix === \"\" ? undefined : base.pathPrefix,\n\t\t\t\"repos\",\n\t\t\tencodeURIComponent(input.owner),\n\t\t\tencodeURIComponent(input.repo),\n\t\t\t\"releases\",\n\t\t\t...(input.tag === undefined ? [] : [\"tags\", encodeURIComponent(input.tag)]),\n\t\t].filter((segment): segment is string => segment !== undefined);\n\t\tconst endpoint = new URL(`${base.origin}/${segments.join(\"/\")}`);\n\t\tconst headers: Readonly<Record<string, string>> =\n\t\t\tinput.kind === \"github\"\n\t\t\t\t? {\n\t\t\t\t\t\t\"x-github-api-version\": \"2022-11-28\",\n\t\t\t\t\t\t...(githubToken === undefined ? {} : { authorization: `Bearer ${githubToken}` }),\n\t\t\t\t\t}\n\t\t\t\t: {};\n\t\tif (input.kind === \"gitee\" && giteeToken !== undefined) endpoint.searchParams.set(\"access_token\", giteeToken);\n\t\tconst payload = await fetchReleaseJson(endpoint, headers, input.signal);\n\t\tconst release =\n\t\t\tinput.tag === undefined ? firstPublishedRelease(parseReleaseList(payload)) : parseReleaseObject(payload);\n\t\tconst assetUrl = selectPackageAssetUrl(release);\n\t\tconst download = await downloadNodeUrlPackageV1(\n\t\t\t{\n\t\t\t\t...(options.fetch === undefined ? {} : { fetch: options.fetch }),\n\t\t\t\trequestTimeoutMs: timeoutMs,\n\t\t\t\tmaxPackageBytes: maxAssetBytes,\n\t\t\t\tuserAgent,\n\t\t\t},\n\t\t\t{\n\t\t\t\turl: assetUrl,\n\t\t\t\t...(input.expectedDigestHex === undefined ? {} : { expectedDigestHex: input.expectedDigestHex }),\n\t\t\t\tsignal: input.signal,\n\t\t\t},\n\t\t);\n\t\treturn {\n\t\t\tbytes: download.bytes,\n\t\t\tmediaType: download.mediaType,\n\t\t\tsha256Hex: download.digestHex,\n\t\t\tsourceLabel,\n\t\t};\n\t};\n\n\treturn { version: 1, downloadReleaseAsset };\n}\n"]}
1
+ {"version":3,"file":"node-release-package-source.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/node-release-package-source.ts"],"names":[],"mappings":"AA+BA,MAAM,MAAM,mCAAmC,GAC5C,WAAW,GACX,uBAAuB,GACvB,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,GAClB,oBAAoB,GACpB,mBAAmB,GACnB,yBAAyB,GACzB,yBAAyB,GACzB,cAAc,CAAC;AAElB,qBAAa,+BAAgC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,EAAE,mCAAmC,CAAC;IACnD,6FAA6F;IAC7F,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAEpC,YACC,IAAI,EAAE,mCAAmC,EACzC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAAE,EAMjD;CACD;AAED,MAAM,WAAW,iCAAiC;IACjD,4EAA4E;IAC5E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,6EAA6E;IAC7E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACzC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,iBAAiB,GAAG,kBAAkB,CAAC;IAC3D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE;QACtC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;QAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;QACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;KAC9B,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC;CAC1C;AAwND,sDAAsD;AACtD,wBAAgB,gCAAgC,CAC/C,OAAO,GAAE,iCAAsC,GAC7C,0BAA0B,CAsJ5B","sourcesContent":["import { t } from \"../../core/i18n/index.ts\";\nimport { downloadNodeUrlPackageV1 } from \"./node-url-package-source.ts\";\n\n/**\n * GitHub/Gitee release plugin package source (design\n * `插件独立分发与启动装配设计.md` §4.6 \"GitHub\"/\"Gitee\" rows). Two-step\n * protocol: resolve one release through the repo's release API — the exact\n * tag endpoint when a tag is given, otherwise the first non-draft entry of\n * the first releases page in API order (no client-side sorting) — then pick\n * the release's single `.zip`/`.tgz` asset and download it with the same\n * bounded http(s) semantics as custom URL packages (redirect-per-hop, budget,\n * timeout, optional strong sha256). Zero or multiple matching assets are\n * explicit structured errors listing the asset names; nothing is guessed.\n * Authentication is optional: GitHub uses an `Authorization: Bearer` header,\n * Gitee an `access_token` query parameter. Anonymous rate limits (403/429\n * with `X-RateLimit-Remaining: 0`, or any 429) surface as `rate_limited`\n * carrying the advertised `X-RateLimit-Reset` epoch; there is no retry.\n */\n\nconst DEFAULT_GITHUB_API_ORIGIN_V1 = \"https://api.github.com\";\nconst DEFAULT_GITEE_API_ORIGIN_V1 = \"https://gitee.com/api/v5\";\nconst DEFAULT_TIMEOUT_MS_V1 = 15_000;\nconst MAX_TIMEOUT_MS_V1 = 120_000;\nconst DEFAULT_MAX_RESPONSE_BYTES_V1 = 8 * 1024 * 1024;\nconst MAX_RESPONSE_BYTES_V1 = 16 * 1024 * 1024;\nconst DEFAULT_MAX_ASSET_BYTES_V1 = 128 * 1024 * 1024;\nconst MAX_ASSET_BYTES_V1 = 512 * 1024 * 1024;\nconst DEFAULT_REDIRECTS_V1 = 3;\nconst MAX_REDIRECTS_V1 = 5;\nconst REDIRECT_STATUS = new Set([301, 302, 303, 307, 308]);\n\nexport type NodeReleasePackageSourceErrorCodeV1 =\n\t| \"cancelled\"\n\t| \"invalid_configuration\"\n\t| \"request_failed\"\n\t| \"request_timed_out\"\n\t| \"invalid_response\"\n\t| \"response_too_large\"\n\t| \"release_not_found\"\n\t| \"release_asset_not_found\"\n\t| \"release_asset_ambiguous\"\n\t| \"rate_limited\";\n\nexport class NodeReleasePackageSourceErrorV1 extends Error {\n\treadonly code: NodeReleasePackageSourceErrorCodeV1;\n\t/** Unix epoch seconds advertised by `X-RateLimit-Reset`; present only for `rate_limited`. */\n\treadonly resetEpochSeconds?: number;\n\n\tconstructor(\n\t\tcode: NodeReleasePackageSourceErrorCodeV1,\n\t\tmessage: string,\n\t\toptions?: { readonly resetEpochSeconds?: number },\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"NodeReleasePackageSourceErrorV1\";\n\t\tthis.code = code;\n\t\tif (options?.resetEpochSeconds !== undefined) this.resetEpochSeconds = options.resetEpochSeconds;\n\t}\n}\n\nexport interface NodeReleasePackageSourceOptionsV1 {\n\t/** Bare http(s) GitHub API origin; defaults to `https://api.github.com`. */\n\treadonly githubApiOrigin?: string;\n\t/** Bare http(s) Gitee API origin; defaults to `https://gitee.com/api/v5`. */\n\treadonly giteeApiOrigin?: string;\n\t/** Optional GitHub API token sent as a bearer header. */\n\treadonly githubToken?: string;\n\t/** Optional Gitee API token sent as an `access_token` query parameter. */\n\treadonly giteeToken?: string;\n\t/** Real fetch or a deterministic test replacement. */\n\treadonly fetch?: typeof globalThis.fetch;\n\treadonly requestTimeoutMs?: number;\n\treadonly maxResponseBytes?: number;\n\treadonly maxAssetBytes?: number;\n\treadonly maxRedirects?: number;\n\treadonly userAgent?: string;\n}\n\nexport interface NodeReleaseAssetDownloadV1 {\n\treadonly bytes: Uint8Array;\n\treadonly mediaType: \"application/zip\" | \"application/gzip\";\n\treadonly sha256Hex: string;\n\t/** `github:<owner>/<repo>@<tag|latest>` or the `gitee:` equivalent. */\n\treadonly sourceLabel: string;\n}\n\nexport interface NodeReleasePackageSourceV1 {\n\treadonly version: 1;\n\treadonly downloadReleaseAsset: (input: {\n\t\treadonly kind: \"github\" | \"gitee\";\n\t\treadonly owner: string;\n\t\treadonly repo: string;\n\t\treadonly tag?: string;\n\t\treadonly expectedDigestHex?: string;\n\t\treadonly signal?: AbortSignal;\n\t}) => Promise<NodeReleaseAssetDownloadV1>;\n}\n\ninterface ReleaseAssetShapeV1 {\n\treadonly name?: unknown;\n\treadonly browser_download_url?: unknown;\n}\n\ninterface ReleaseShapeV1 {\n\treadonly draft?: unknown;\n\treadonly assets?: unknown;\n}\n\nfunction boundedPositive(value: number | undefined, fallback: number, maximum: number, label: string): number {\n\tconst result = value ?? fallback;\n\tif (!Number.isSafeInteger(result) || result <= 0 || result > maximum)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\tt(\"{label} must be a positive integer at most {maximum}\", { label, maximum }),\n\t\t);\n\treturn result;\n}\n\nfunction boundedToken(value: string | undefined, label: string): string | undefined {\n\tif (value === undefined) return undefined;\n\tif (value.length === 0 || value.length > 4096 || /[\\r\\n\\s]/u.test(value))\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_configuration\", t(\"{label} is invalid\", { label }));\n\treturn value;\n}\n\nfunction apiOrigin(value: string, label: string): { readonly origin: string; readonly pathPrefix: string } {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(value);\n\t} catch {\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_configuration\", t(\"{label} is invalid\", { label }));\n\t}\n\tif (\n\t\t(parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") ||\n\t\tparsed.username !== \"\" ||\n\t\tparsed.password !== \"\"\n\t)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\tt(\"{label} must be http(s) without credentials\", { label }),\n\t\t);\n\tif (parsed.search !== \"\" || parsed.hash !== \"\")\n\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\tt(\"{label} must not include a query or fragment\", { label }),\n\t\t);\n\t// The Gitee default origin carries the `/api/v5` path prefix. The prefix is\n\t// kept as a plain string because a URL normalizes an empty pathname back\n\t// to \"/\", which would reintroduce a double slash when joining endpoints.\n\tconst trimmed = parsed.pathname.replace(/\\/+$/u, \"\");\n\treturn { origin: parsed.origin, pathPrefix: trimmed === \"\" || trimmed === \"/\" ? \"\" : trimmed.replace(/^\\//u, \"\") };\n}\n\nfunction jsonBytes(value: Uint8Array): unknown {\n\ttry {\n\t\treturn JSON.parse(new TextDecoder(\"utf-8\", { fatal: true }).decode(value));\n\t} catch {\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", t(\"release API response is not valid JSON\"));\n\t}\n}\n\nfunction parseReleaseList(bytes: Uint8Array): readonly ReleaseShapeV1[] {\n\tconst value = jsonBytes(bytes);\n\tif (!Array.isArray(value))\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", t(\"release API response is not a release list\"));\n\treturn value as readonly ReleaseShapeV1[];\n}\n\nfunction parseReleaseObject(bytes: Uint8Array): ReleaseShapeV1 {\n\tconst value = jsonBytes(bytes);\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value))\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", t(\"release API response is not a release object\"));\n\treturn value as ReleaseShapeV1;\n}\n\n/** First non-draft entry in API order; the array itself is the ordering contract. */\nfunction firstPublishedRelease(releases: readonly ReleaseShapeV1[]): ReleaseShapeV1 {\n\tconst published = releases.find((release) => release.draft !== true);\n\tif (published === undefined)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"release_not_found\", t(\"repo has no published release\"));\n\treturn published;\n}\n\ninterface ReleaseAssetNameV1 {\n\treadonly name: string;\n\treadonly url: unknown;\n}\n\n/** Assets with a usable name; entries without a string name are ignored as API noise. */\nfunction namedAssets(release: ReleaseShapeV1): readonly ReleaseAssetNameV1[] {\n\tif (release.assets === undefined) return [];\n\tif (!Array.isArray(release.assets))\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", t(\"release assets are invalid\"));\n\tconst entries: ReleaseAssetNameV1[] = [];\n\tfor (const asset of release.assets) {\n\t\tif (typeof asset !== \"object\" || asset === null) continue;\n\t\tconst shape = asset as ReleaseAssetShapeV1;\n\t\tif (typeof shape.name !== \"string\" || shape.name.length === 0) continue;\n\t\tentries.push({ name: shape.name, url: shape.browser_download_url });\n\t}\n\treturn entries;\n}\n\nfunction isPackageAssetName(name: string): boolean {\n\tconst value = name.toLowerCase();\n\treturn value.endsWith(\".zip\") || value.endsWith(\".tgz\");\n}\n\n/** Select the release's single `.zip`/`.tgz` asset and return its download URL. */\nfunction selectPackageAssetUrl(release: ReleaseShapeV1): string {\n\tconst assets = namedAssets(release);\n\tconst candidates = assets.filter((asset) => isPackageAssetName(asset.name));\n\tconst assetNames = assets.map((asset) => asset.name).join(\", \");\n\tif (candidates.length === 0)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\"release_asset_not_found\",\n\t\t\tassetNames.length === 0 ? t(\"release has no assets\") : t(\"assets: {names}\", { names: assetNames }),\n\t\t);\n\tif (candidates.length > 1)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\"release_asset_ambiguous\",\n\t\t\tt(\"candidates: {names}\", { names: candidates.map((asset) => asset.name).join(\", \") }),\n\t\t);\n\tconst chosen = candidates[0]!;\n\tif (typeof chosen.url !== \"string\" || chosen.url.length === 0)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", t(\"release asset has no download URL\"));\n\treturn chosen.url;\n}\n\nfunction isAbortLike(error: unknown): boolean {\n\treturn error instanceof Error && (error.name === \"AbortError\" || error.name === \"AbortSignalError\");\n}\n\ninterface RequestSignal {\n\treadonly signal: AbortSignal;\n\treadonly timedOut: () => boolean;\n\treadonly cleanup: () => void;\n}\n\nfunction requestSignal(parent: AbortSignal | undefined, timeoutMs: number): RequestSignal {\n\tconst controller = new AbortController();\n\tlet timedOut = false;\n\tconst abort = () => controller.abort(parent?.reason);\n\tif (parent?.aborted === true) abort();\n\telse parent?.addEventListener(\"abort\", abort, { once: true });\n\tconst timeout = setTimeout(() => {\n\t\ttimedOut = true;\n\t\tcontroller.abort();\n\t}, timeoutMs);\n\treturn {\n\t\tsignal: controller.signal,\n\t\ttimedOut: () => timedOut,\n\t\tcleanup: () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tparent?.removeEventListener(\"abort\", abort);\n\t\t},\n\t};\n}\n\nfunction isJsonResponse(response: Response): boolean {\n\tconst contentType = response.headers.get(\"content-type\");\n\tif (contentType === null) return false;\n\tconst mediaType = contentType.split(\";\", 1)[0]?.trim().toLowerCase();\n\treturn mediaType === \"application/json\" || mediaType === \"application/vnd.github+json\";\n}\n\n/**\n * Rate-limit verdict for 403/429 responses: any 429, and a 403 whose\n * `X-RateLimit-Remaining` is exactly `0`. The reset epoch is passed through\n * verbatim when present and integer-like; absent headers stay absent.\n */\nfunction rateLimitState(response: Response): { readonly limited: boolean; readonly resetEpochSeconds?: number } {\n\tconst limited =\n\t\tresponse.status === 429 || (response.status === 403 && response.headers.get(\"x-ratelimit-remaining\") === \"0\");\n\tif (!limited) return { limited: false };\n\tconst reset = response.headers.get(\"x-ratelimit-reset\");\n\tconst resetValue = reset === null ? Number.NaN : Number.parseInt(reset, 10);\n\tif (!Number.isSafeInteger(resetValue) || resetValue < 0) return { limited: true };\n\treturn { limited: true, resetEpochSeconds: resetValue };\n}\n\nasync function readBody(response: Response, maxBytes: number, signal: AbortSignal): Promise<Uint8Array> {\n\tif (response.body === null)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", t(\"release API response has no body\"));\n\tconst reader = response.body.getReader();\n\tconst chunks: Uint8Array[] = [];\n\tlet total = 0;\n\ttry {\n\t\tfor (;;) {\n\t\t\tif (signal.aborted) throw new DOMException(t(\"aborted\"), \"AbortError\");\n\t\t\tconst item = await reader.read();\n\t\t\tif (item.done) break;\n\t\t\ttotal += item.value.byteLength;\n\t\t\tif (total > maxBytes)\n\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\t\t\"response_too_large\",\n\t\t\t\t\tt(\"release API response exceeds the configured size limit\"),\n\t\t\t\t);\n\t\t\tchunks.push(item.value);\n\t\t}\n\t} finally {\n\t\treader.releaseLock();\n\t}\n\tconst bytes = new Uint8Array(total);\n\tlet offset = 0;\n\tfor (const chunk of chunks) {\n\t\tbytes.set(chunk, offset);\n\t\toffset += chunk.byteLength;\n\t}\n\treturn bytes;\n}\n\n/** Create the bounded GitHub/Gitee release reader. */\nexport function createNodeReleasePackageSourceV1(\n\toptions: NodeReleasePackageSourceOptionsV1 = {},\n): NodeReleasePackageSourceV1 {\n\tconst transport = options.fetch ?? globalThis.fetch;\n\tif (typeof transport !== \"function\")\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_configuration\", t(\"Node fetch is unavailable\"));\n\tconst githubOrigin = apiOrigin(options.githubApiOrigin ?? DEFAULT_GITHUB_API_ORIGIN_V1, \"githubApiOrigin\");\n\tconst giteeOrigin = apiOrigin(options.giteeApiOrigin ?? DEFAULT_GITEE_API_ORIGIN_V1, \"giteeApiOrigin\");\n\tconst githubToken = boundedToken(options.githubToken, \"githubToken\");\n\tconst giteeToken = boundedToken(options.giteeToken, \"giteeToken\");\n\tconst timeoutMs = boundedPositive(\n\t\toptions.requestTimeoutMs,\n\t\tDEFAULT_TIMEOUT_MS_V1,\n\t\tMAX_TIMEOUT_MS_V1,\n\t\t\"requestTimeoutMs\",\n\t);\n\tconst maxResponseBytes = boundedPositive(\n\t\toptions.maxResponseBytes,\n\t\tDEFAULT_MAX_RESPONSE_BYTES_V1,\n\t\tMAX_RESPONSE_BYTES_V1,\n\t\t\"maxResponseBytes\",\n\t);\n\tconst maxAssetBytes = boundedPositive(\n\t\toptions.maxAssetBytes,\n\t\tDEFAULT_MAX_ASSET_BYTES_V1,\n\t\tMAX_ASSET_BYTES_V1,\n\t\t\"maxAssetBytes\",\n\t);\n\tconst maxRedirects = options.maxRedirects ?? DEFAULT_REDIRECTS_V1;\n\tif (!Number.isSafeInteger(maxRedirects) || maxRedirects < 0 || maxRedirects > MAX_REDIRECTS_V1)\n\t\tthrow new NodeReleasePackageSourceErrorV1(\n\t\t\t\"invalid_configuration\",\n\t\t\tt(\"maxRedirects must be an integer between 0 and {max}\", { max: MAX_REDIRECTS_V1 }),\n\t\t);\n\tconst userAgent = options.userAgent ?? \"agent-forge-plugin-release/1\";\n\tif (userAgent.length === 0 || userAgent.length > 256 || /[\\r\\n]/u.test(userAgent))\n\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_configuration\", t(\"userAgent is invalid\"));\n\n\tconst fetchReleaseJson = async (\n\t\turl: URL,\n\t\theaders: Readonly<Record<string, string>>,\n\t\tparentSignal: AbortSignal | undefined,\n\t): Promise<Uint8Array> => {\n\t\tlet current = url;\n\t\tfor (let redirect = 0; ; redirect += 1) {\n\t\t\tconst request = requestSignal(parentSignal, timeoutMs);\n\t\t\tlet response: Response;\n\t\t\ttry {\n\t\t\t\tresponse = await transport(current.toString(), {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\theaders: { accept: \"application/json\", \"user-agent\": userAgent, ...headers },\n\t\t\t\t\tredirect: \"manual\",\n\t\t\t\t\tsignal: request.signal,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\trequest.cleanup();\n\t\t\t\tif (request.timedOut())\n\t\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"request_timed_out\", t(\"release API request timed out\"));\n\t\t\t\tif (isAbortLike(error))\n\t\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"cancelled\", t(\"release API request was cancelled\"));\n\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"request_failed\", t(\"release API request failed\"));\n\t\t\t}\n\t\t\tif (!REDIRECT_STATUS.has(response.status)) {\n\t\t\t\ttry {\n\t\t\t\t\tif (response.status === 404)\n\t\t\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"release_not_found\", t(\"repo or release was not found\"));\n\t\t\t\t\tconst limit = rateLimitState(response);\n\t\t\t\t\tif (limit.limited) {\n\t\t\t\t\t\tconst message =\n\t\t\t\t\t\t\tlimit.resetEpochSeconds === undefined\n\t\t\t\t\t\t\t\t? \"rate limit was exceeded\"\n\t\t\t\t\t\t\t\t: `rate limit resets at ${new Date(limit.resetEpochSeconds * 1000).toISOString()}`;\n\t\t\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"rate_limited\", message, {\n\t\t\t\t\t\t\t...(limit.resetEpochSeconds === undefined ? {} : { resetEpochSeconds: limit.resetEpochSeconds }),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (response.status < 200 || response.status >= 300)\n\t\t\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"request_failed\", t(\"release API request did not succeed\"));\n\t\t\t\t\tif (!isJsonResponse(response))\n\t\t\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", t(\"release API response must be JSON\"));\n\t\t\t\t\tconst bytes = await readBody(response, maxResponseBytes, request.signal);\n\t\t\t\t\treturn bytes;\n\t\t\t\t} finally {\n\t\t\t\t\tawait response.body?.cancel().catch(() => undefined);\n\t\t\t\t\trequest.cleanup();\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst location = response.headers.get(\"location\");\n\t\t\tawait response.body?.cancel().catch(() => undefined);\n\t\t\trequest.cleanup();\n\t\t\tif (location === null || redirect >= maxRedirects)\n\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"request_failed\", t(\"release API redirect limit exceeded\"));\n\t\t\tlet next: URL;\n\t\t\ttry {\n\t\t\t\tnext = new URL(location, current);\n\t\t\t} catch {\n\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", t(\"release API redirect target is invalid\"));\n\t\t\t}\n\t\t\tif ((next.protocol !== \"http:\" && next.protocol !== \"https:\") || next.username !== \"\" || next.password !== \"\")\n\t\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"invalid_response\", t(\"release API redirect must stay http(s)\"));\n\t\t\tcurrent = next;\n\t\t}\n\t};\n\n\tconst downloadReleaseAsset: NodeReleasePackageSourceV1[\"downloadReleaseAsset\"] = async (input) => {\n\t\tif (input.signal?.aborted === true)\n\t\t\tthrow new NodeReleasePackageSourceErrorV1(\"cancelled\", t(\"release asset download was cancelled\"));\n\t\tconst sourceLabel = `${input.kind}:${input.owner}/${input.repo}@${input.tag ?? \"latest\"}`;\n\t\tconst base = input.kind === \"github\" ? githubOrigin : giteeOrigin;\n\t\tconst segments = [\n\t\t\tbase.pathPrefix === \"\" ? undefined : base.pathPrefix,\n\t\t\t\"repos\",\n\t\t\tencodeURIComponent(input.owner),\n\t\t\tencodeURIComponent(input.repo),\n\t\t\t\"releases\",\n\t\t\t...(input.tag === undefined ? [] : [\"tags\", encodeURIComponent(input.tag)]),\n\t\t].filter((segment): segment is string => segment !== undefined);\n\t\tconst endpoint = new URL(`${base.origin}/${segments.join(\"/\")}`);\n\t\tconst headers: Readonly<Record<string, string>> =\n\t\t\tinput.kind === \"github\"\n\t\t\t\t? {\n\t\t\t\t\t\t\"x-github-api-version\": \"2022-11-28\",\n\t\t\t\t\t\t...(githubToken === undefined ? {} : { authorization: `Bearer ${githubToken}` }),\n\t\t\t\t\t}\n\t\t\t\t: {};\n\t\tif (input.kind === \"gitee\" && giteeToken !== undefined) endpoint.searchParams.set(\"access_token\", giteeToken);\n\t\tconst payload = await fetchReleaseJson(endpoint, headers, input.signal);\n\t\tconst release =\n\t\t\tinput.tag === undefined ? firstPublishedRelease(parseReleaseList(payload)) : parseReleaseObject(payload);\n\t\tconst assetUrl = selectPackageAssetUrl(release);\n\t\tconst download = await downloadNodeUrlPackageV1(\n\t\t\t{\n\t\t\t\t...(options.fetch === undefined ? {} : { fetch: options.fetch }),\n\t\t\t\trequestTimeoutMs: timeoutMs,\n\t\t\t\tmaxPackageBytes: maxAssetBytes,\n\t\t\t\tuserAgent,\n\t\t\t},\n\t\t\t{\n\t\t\t\turl: assetUrl,\n\t\t\t\t...(input.expectedDigestHex === undefined ? {} : { expectedDigestHex: input.expectedDigestHex }),\n\t\t\t\tsignal: input.signal,\n\t\t\t},\n\t\t);\n\t\treturn {\n\t\t\tbytes: download.bytes,\n\t\t\tmediaType: download.mediaType,\n\t\t\tsha256Hex: download.digestHex,\n\t\t\tsourceLabel,\n\t\t};\n\t};\n\n\treturn { version: 1, downloadReleaseAsset };\n}\n"]}