@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 +1 @@
1
- {"version":3,"file":"root-facade.js","sourceRoot":"","sources":["../../src/profile/root-facade.ts"],"names":[],"mappings":"AA0BA,MAAM,UAAU,qBAAqB,CAA4B,OAOhE,EAAsC;IACtC,MAAM,YAAY,GAAG,OAAO,CAAC,gBAAgB,IAAI,uBAAuB,CAAC;IACzE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,CAAC;IAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC;QAC7C,EAAE,EAAE,YAAY;QAChB,OAAO,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC;QACjC,IAAI,EAAE,uBAAuB;QAC7B,GAAG,EAAE,CAAC,KAAa,EAAE,OAA0C,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC;KAC/F,CAAC,CAAC;IACH,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,OAAO;QACN,YAAY;QACZ,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE;YAChC,8DAA8D;YAC9D,IAAI,YAAY,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;YAC1D,CAAC;YACD,YAAY,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC;gBACJ,qEAAqE;gBACrE,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,CAAkB,UAAU,CAAC,CAAC;gBACzE,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;gBAC3D,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACJ,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;oBAC7E,MAAM,SAAS,CAAC,MAAM,CAAC;oBACvB,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;oBAC7C,OAAO;wBACN,MAAM,EAAE,cAAc,CAAC,MAAM;wBAC7B,GAAG,CAAC,cAAc,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACjF,GAAG,CAAC,cAAc,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACjF,QAAQ,EAAE,cAAc,CAAC,QAAQ;wBACjC,UAAU,EAAE,QAAQ,CAAC,EAAE;wBACvB,OAAO;qBACP,CAAC;gBACH,CAAC;wBAAS,CAAC;oBACV,IAAI,KAAK,CAAC,QAAQ,EAAE;wBAAE,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC7C,CAAC;YACF,CAAC;oBAAS,CAAC;gBACV,YAAY,GAAG,KAAK,CAAC;YACtB,CAAC;QAAA,CACD;KACD,CAAC;AAAA,CACF","sourcesContent":["/**\n * Root-agent-controller facade adapter (2.1a).\n *\n * Proves the default root can be created and run through the public facade:\n * the adapter defines (or reuses) a `root-agent-controller` definition on the\n * composition and runs each turn on a fresh instance with the controller\n * lease acquired and released through the public API — no private main-loop\n * access. The TUI keeps its transitional path until 2.1c.\n */\nimport type { AgentCompositionAPI } from \"../core/extensions/public-api.ts\";\n\nexport interface RootAgentFacadeTurnResultV1<TResult> {\n\treadonly status: \"succeeded\" | \"failed\" | \"cancelled\" | \"disposed\";\n\treadonly output?: TResult;\n\treadonly revision: number;\n\treadonly error?: Error;\n\treadonly instanceId: string;\n\treadonly leaseId: string;\n}\n\nexport interface RootAgentFacadeV1<TInput = unknown, TResult = unknown> {\n\treadonly definitionId: string;\n\t/** Runs one minimal turn: create instance → acquire controller lease → run → release. */\n\trunTurn(input: TInput, options?: { readonly signal?: AbortSignal }): Promise<RootAgentFacadeTurnResultV1<TResult>>;\n}\n\nexport function createRootAgentFacade<TInput, TResult = unknown>(options: {\n\treadonly composition: AgentCompositionAPI;\n\treadonly rootDefinitionId?: string;\n\treadonly rootVersion?: number;\n\treadonly owner?: string;\n\t/** The root turn implementation (deterministic in tests). */\n\treadonly run: (input: TInput, context: { readonly signal?: AbortSignal }) => Promise<TResult> | TResult;\n}): RootAgentFacadeV1<TInput, TResult> {\n\tconst definitionId = options.rootDefinitionId ?? \"root-agent-controller\";\n\tconst owner = options.owner ?? \"root-facade\";\n\tconst definition = options.composition.define({\n\t\tid: definitionId,\n\t\tversion: options.rootVersion ?? 1,\n\t\trole: \"root-agent-controller\",\n\t\trun: (input: TInput, context: { readonly signal?: AbortSignal }) => options.run(input, context),\n\t});\n\tlet turnInFlight = false;\n\n\treturn {\n\t\tdefinitionId,\n\t\tasync runTurn(input, runOptions) {\n\t\t\t// Single-controller rule: one turn at a time per root facade.\n\t\t\tif (turnInFlight) {\n\t\t\t\tthrow new Error(\"Root facade is already running a turn\");\n\t\t\t}\n\t\t\tturnInFlight = true;\n\t\t\ttry {\n\t\t\t\t// A composition instance is single-run; every turn gets a fresh one.\n\t\t\t\tconst instance = options.composition.create<TInput, TResult>(definition);\n\t\t\t\tconst lease = await instance.acquireControllerLease(owner);\n\t\t\t\tconst leaseId = lease.id;\n\t\t\t\ttry {\n\t\t\t\t\tconst operation = instance.run(input, { lease, signal: runOptions?.signal });\n\t\t\t\t\tawait operation.result;\n\t\t\t\t\tconst instanceResult = await instance.wait();\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: instanceResult.status,\n\t\t\t\t\t\t...(instanceResult.output !== undefined ? { output: instanceResult.output } : {}),\n\t\t\t\t\t\t...(instanceResult.error instanceof Error ? { error: instanceResult.error } : {}),\n\t\t\t\t\t\trevision: instanceResult.revision,\n\t\t\t\t\t\tinstanceId: instance.id,\n\t\t\t\t\t\tleaseId,\n\t\t\t\t\t};\n\t\t\t\t} finally {\n\t\t\t\t\tif (lease.isActive()) await lease.release();\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tturnInFlight = false;\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"root-facade.js","sourceRoot":"","sources":["../../src/profile/root-facade.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,CAAC,EAAE,MAAM,uBAAuB,CAAC;AAiB1C,MAAM,UAAU,qBAAqB,CAA4B,OAOhE,EAAsC;IACtC,MAAM,YAAY,GAAG,OAAO,CAAC,gBAAgB,IAAI,uBAAuB,CAAC;IACzE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,CAAC;IAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC;QAC7C,EAAE,EAAE,YAAY;QAChB,OAAO,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC;QACjC,IAAI,EAAE,uBAAuB;QAC7B,GAAG,EAAE,CAAC,KAAa,EAAE,OAA0C,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC;KAC/F,CAAC,CAAC;IACH,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,OAAO;QACN,YAAY;QACZ,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE;YAChC,8DAA8D;YAC9D,IAAI,YAAY,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC;YAC7D,CAAC;YACD,YAAY,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC;gBACJ,qEAAqE;gBACrE,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,CAAkB,UAAU,CAAC,CAAC;gBACzE,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;gBAC3D,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACJ,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;oBAC7E,MAAM,SAAS,CAAC,MAAM,CAAC;oBACvB,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;oBAC7C,OAAO;wBACN,MAAM,EAAE,cAAc,CAAC,MAAM;wBAC7B,GAAG,CAAC,cAAc,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACjF,GAAG,CAAC,cAAc,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACjF,QAAQ,EAAE,cAAc,CAAC,QAAQ;wBACjC,UAAU,EAAE,QAAQ,CAAC,EAAE;wBACvB,OAAO;qBACP,CAAC;gBACH,CAAC;wBAAS,CAAC;oBACV,IAAI,KAAK,CAAC,QAAQ,EAAE;wBAAE,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC7C,CAAC;YACF,CAAC;oBAAS,CAAC;gBACV,YAAY,GAAG,KAAK,CAAC;YACtB,CAAC;QAAA,CACD;KACD,CAAC;AAAA,CACF","sourcesContent":["/**\n * Root-agent-controller facade adapter (2.1a).\n *\n * Proves the default root can be created and run through the public facade:\n * the adapter defines (or reuses) a `root-agent-controller` definition on the\n * composition and runs each turn on a fresh instance with the controller\n * lease acquired and released through the public API — no private main-loop\n * access. The TUI keeps its transitional path until 2.1c.\n */\nimport type { AgentCompositionAPI } from \"../core/extensions/public-api.ts\";\nimport { t } from \"../core/i18n/index.ts\";\n\nexport interface RootAgentFacadeTurnResultV1<TResult> {\n\treadonly status: \"succeeded\" | \"failed\" | \"cancelled\" | \"disposed\";\n\treadonly output?: TResult;\n\treadonly revision: number;\n\treadonly error?: Error;\n\treadonly instanceId: string;\n\treadonly leaseId: string;\n}\n\nexport interface RootAgentFacadeV1<TInput = unknown, TResult = unknown> {\n\treadonly definitionId: string;\n\t/** Runs one minimal turn: create instance → acquire controller lease → run → release. */\n\trunTurn(input: TInput, options?: { readonly signal?: AbortSignal }): Promise<RootAgentFacadeTurnResultV1<TResult>>;\n}\n\nexport function createRootAgentFacade<TInput, TResult = unknown>(options: {\n\treadonly composition: AgentCompositionAPI;\n\treadonly rootDefinitionId?: string;\n\treadonly rootVersion?: number;\n\treadonly owner?: string;\n\t/** The root turn implementation (deterministic in tests). */\n\treadonly run: (input: TInput, context: { readonly signal?: AbortSignal }) => Promise<TResult> | TResult;\n}): RootAgentFacadeV1<TInput, TResult> {\n\tconst definitionId = options.rootDefinitionId ?? \"root-agent-controller\";\n\tconst owner = options.owner ?? \"root-facade\";\n\tconst definition = options.composition.define({\n\t\tid: definitionId,\n\t\tversion: options.rootVersion ?? 1,\n\t\trole: \"root-agent-controller\",\n\t\trun: (input: TInput, context: { readonly signal?: AbortSignal }) => options.run(input, context),\n\t});\n\tlet turnInFlight = false;\n\n\treturn {\n\t\tdefinitionId,\n\t\tasync runTurn(input, runOptions) {\n\t\t\t// Single-controller rule: one turn at a time per root facade.\n\t\t\tif (turnInFlight) {\n\t\t\t\tthrow new Error(t(\"Root facade is already running a turn\"));\n\t\t\t}\n\t\t\tturnInFlight = true;\n\t\t\ttry {\n\t\t\t\t// A composition instance is single-run; every turn gets a fresh one.\n\t\t\t\tconst instance = options.composition.create<TInput, TResult>(definition);\n\t\t\t\tconst lease = await instance.acquireControllerLease(owner);\n\t\t\t\tconst leaseId = lease.id;\n\t\t\t\ttry {\n\t\t\t\t\tconst operation = instance.run(input, { lease, signal: runOptions?.signal });\n\t\t\t\t\tawait operation.result;\n\t\t\t\t\tconst instanceResult = await instance.wait();\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: instanceResult.status,\n\t\t\t\t\t\t...(instanceResult.output !== undefined ? { output: instanceResult.output } : {}),\n\t\t\t\t\t\t...(instanceResult.error instanceof Error ? { error: instanceResult.error } : {}),\n\t\t\t\t\t\trevision: instanceResult.revision,\n\t\t\t\t\t\tinstanceId: instance.id,\n\t\t\t\t\t\tleaseId,\n\t\t\t\t\t};\n\t\t\t\t} finally {\n\t\t\t\t\tif (lease.isActive()) await lease.release();\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tturnInFlight = false;\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"skill-discovery-wiring.d.ts","sourceRoot":"","sources":["../../src/profile/skill-discovery-wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAIxE,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,KAAK,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,SAAS;QAC/B,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;QAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KACzB,EAAE,CAAC;CACJ;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACvC,aAAa,CAAC,KAAK,EAAE;QACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,KAAK,EAAE,SAAS;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACpF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;KAC3B,GAAG,gBAAgB,CAAC;IACrB,0BAA0B,CAAC,KAAK,EAAE;QACjC,QAAQ,CAAC,qBAAqB,EAAE,SAAS;YAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC7F,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;KAC7C,GAAG;QAAE,QAAQ,CAAC,SAAS,EAAE,SAAS,0BAA0B,EAAE,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAA;KAAE,CAAC;CAC9G;AAED,wBAAgB,0BAA0B,IAAI,iBAAiB,CAgE9D","sourcesContent":["/**\n * Skill/MCP discovery wiring (4.4) — turns discovered Skill and MCP tool\n * capabilities into profile-assembly inputs, with all four failure modes\n * explicit BEFORE a session exists: missing dependencies, version conflicts\n * between sources, disabled items, and replacements.\n *\n * Each registered item (a Skill or an MCP server) contributes capability\n * declarations; MCP tools derive capability ids `mcp:<serverId>:<toolName>`.\n * Two enabled items declaring the SAME capability id with DIFFERENT\n * versions is a structured version conflict; identical versions dedupe.\n * Disabled items contribute nothing (replacement = disable + register).\n * Resolution reuses the 2.5a exact-version wiring — no kernel special\n * cases. Implementation lives entirely in profile/assembly land.\n */\n\nimport type { ProfileDependencyWiringV1 } from \"./dependency-wiring.ts\";\nimport { wireProfileDependencies } from \"./dependency-wiring.ts\";\nimport type { ResolvedPluginManifestV1 } from \"./identity.ts\";\n\nexport type DiscoverySourceKindV1 = \"skill\" | \"mcp\";\n\nexport interface DiscoveredItemV1 {\n\treadonly sourceKind: DiscoverySourceKindV1;\n\treadonly itemId: string;\n\treadonly version: string;\n\treadonly capabilities: readonly { readonly id: string; readonly version: number }[];\n\treadonly enabled: boolean;\n}\n\nexport interface DiscoveryVersionConflictV1 {\n\treadonly capabilityId: string;\n\treadonly declarations: readonly {\n\t\treadonly sourceKind: DiscoverySourceKindV1;\n\t\treadonly itemId: string;\n\t\treadonly version: number;\n\t}[];\n}\n\nexport interface DiscoveryWiringV1 {\n\tregister(item: DiscoveredItemV1): void;\n\tderiveMcpItem(input: {\n\t\treadonly serverId: string;\n\t\treadonly version: string;\n\t\treadonly tools: readonly { readonly name: string; readonly description?: string }[];\n\t\treadonly enabled?: boolean;\n\t}): DiscoveredItemV1;\n\twireDiscoveredDependencies(input: {\n\t\treadonly availableCapabilities: readonly { readonly id: string; readonly version: number }[];\n\t\treadonly disabledItemIds?: readonly string[];\n\t}): { readonly conflicts: readonly DiscoveryVersionConflictV1[]; readonly wiring: ProfileDependencyWiringV1 };\n}\n\nexport function createSkillDiscoveryWiring(): DiscoveryWiringV1 {\n\tconst items = new Map<string, DiscoveredItemV1>();\n\tconst keyOf = (item: DiscoveredItemV1): string => `${item.sourceKind}:${item.itemId}`;\n\n\treturn {\n\t\tregister(item) {\n\t\t\tif (item.itemId.trim().length === 0) throw new Error(\"Discovered item id must be a non-empty string\");\n\t\t\tconst existing = items.get(keyOf(item));\n\t\t\tif (existing && existing.version !== item.version) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Item ${keyOf(item)} re-registered with a different version (${existing.version} -> ${item.version})`,\n\t\t\t\t);\n\t\t\t}\n\t\t\titems.set(keyOf(item), { ...item, capabilities: [...item.capabilities] });\n\t\t},\n\t\tderiveMcpItem({ serverId, version, tools, enabled = true }) {\n\t\t\treturn {\n\t\t\t\tsourceKind: \"mcp\",\n\t\t\t\titemId: serverId,\n\t\t\t\tversion,\n\t\t\t\tcapabilities: tools.map((tool) => ({ id: `mcp:${serverId}:${tool.name}`, version: 1 })),\n\t\t\t\tenabled,\n\t\t\t};\n\t\t},\n\t\twireDiscoveredDependencies({ availableCapabilities, disabledItemIds }) {\n\t\t\tconst disabled = new Set(disabledItemIds ?? []);\n\t\t\tconst enabledItems = [...items.values()].filter((item) => item.enabled && !disabled.has(keyOf(item)));\n\n\t\t\t// Version conflicts: same capability id, different declared versions,\n\t\t\t// across different enabled items.\n\t\t\tconst byCapability = new Map<\n\t\t\t\tstring,\n\t\t\t\tArray<{ sourceKind: DiscoverySourceKindV1; itemId: string; version: number }>\n\t\t\t>();\n\t\t\tfor (const item of enabledItems) {\n\t\t\t\tfor (const capability of item.capabilities) {\n\t\t\t\t\tconst list = byCapability.get(capability.id) ?? [];\n\t\t\t\t\tif (!list.some((entry) => entry.itemId === item.itemId)) {\n\t\t\t\t\t\tlist.push({ sourceKind: item.sourceKind, itemId: item.itemId, version: capability.version });\n\t\t\t\t\t}\n\t\t\t\t\tbyCapability.set(capability.id, list);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst conflicts: DiscoveryVersionConflictV1[] = [];\n\t\t\tfor (const [capabilityId, declarations] of byCapability) {\n\t\t\t\tconst versions = new Set(declarations.map((entry) => entry.version));\n\t\t\t\tif (versions.size > 1) conflicts.push({ capabilityId, declarations });\n\t\t\t}\n\n\t\t\t// Disabled items stay in the manifests so the wiring result shows an\n\t\t\t// explicit skipped_disabled entry (visible audit, not silent removal).\n\t\t\tconst manifests: ResolvedPluginManifestV1[] = [...items.values()].map((item) => ({\n\t\t\t\tpluginId: keyOf(item),\n\t\t\t\tpluginVersion: item.version,\n\t\t\t\tcapabilityRefs: [...item.capabilities],\n\t\t\t}));\n\t\t\tconst wiring = wireProfileDependencies({\n\t\t\t\tresolvedPlugins: manifests,\n\t\t\t\tavailableCapabilities,\n\t\t\t\tdisabledPluginIds: disabledItemIds,\n\t\t\t});\n\t\t\treturn { conflicts: Object.freeze(conflicts), wiring };\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"skill-discovery-wiring.d.ts","sourceRoot":"","sources":["../../src/profile/skill-discovery-wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAIxE,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,KAAK,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,SAAS;QAC/B,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;QAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KACzB,EAAE,CAAC;CACJ;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACvC,aAAa,CAAC,KAAK,EAAE;QACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,KAAK,EAAE,SAAS;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACpF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;KAC3B,GAAG,gBAAgB,CAAC;IACrB,0BAA0B,CAAC,KAAK,EAAE;QACjC,QAAQ,CAAC,qBAAqB,EAAE,SAAS;YAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC7F,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;KAC7C,GAAG;QAAE,QAAQ,CAAC,SAAS,EAAE,SAAS,0BAA0B,EAAE,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAA;KAAE,CAAC;CAC9G;AAED,wBAAgB,0BAA0B,IAAI,iBAAiB,CAoE9D","sourcesContent":["/**\n * Skill/MCP discovery wiring (4.4) — turns discovered Skill and MCP tool\n * capabilities into profile-assembly inputs, with all four failure modes\n * explicit BEFORE a session exists: missing dependencies, version conflicts\n * between sources, disabled items, and replacements.\n *\n * Each registered item (a Skill or an MCP server) contributes capability\n * declarations; MCP tools derive capability ids `mcp:<serverId>:<toolName>`.\n * Two enabled items declaring the SAME capability id with DIFFERENT\n * versions is a structured version conflict; identical versions dedupe.\n * Disabled items contribute nothing (replacement = disable + register).\n * Resolution reuses the 2.5a exact-version wiring — no kernel special\n * cases. Implementation lives entirely in profile/assembly land.\n */\n\nimport { t } from \"../core/i18n/index.ts\";\nimport type { ProfileDependencyWiringV1 } from \"./dependency-wiring.ts\";\nimport { wireProfileDependencies } from \"./dependency-wiring.ts\";\nimport type { ResolvedPluginManifestV1 } from \"./identity.ts\";\n\nexport type DiscoverySourceKindV1 = \"skill\" | \"mcp\";\n\nexport interface DiscoveredItemV1 {\n\treadonly sourceKind: DiscoverySourceKindV1;\n\treadonly itemId: string;\n\treadonly version: string;\n\treadonly capabilities: readonly { readonly id: string; readonly version: number }[];\n\treadonly enabled: boolean;\n}\n\nexport interface DiscoveryVersionConflictV1 {\n\treadonly capabilityId: string;\n\treadonly declarations: readonly {\n\t\treadonly sourceKind: DiscoverySourceKindV1;\n\t\treadonly itemId: string;\n\t\treadonly version: number;\n\t}[];\n}\n\nexport interface DiscoveryWiringV1 {\n\tregister(item: DiscoveredItemV1): void;\n\tderiveMcpItem(input: {\n\t\treadonly serverId: string;\n\t\treadonly version: string;\n\t\treadonly tools: readonly { readonly name: string; readonly description?: string }[];\n\t\treadonly enabled?: boolean;\n\t}): DiscoveredItemV1;\n\twireDiscoveredDependencies(input: {\n\t\treadonly availableCapabilities: readonly { readonly id: string; readonly version: number }[];\n\t\treadonly disabledItemIds?: readonly string[];\n\t}): { readonly conflicts: readonly DiscoveryVersionConflictV1[]; readonly wiring: ProfileDependencyWiringV1 };\n}\n\nexport function createSkillDiscoveryWiring(): DiscoveryWiringV1 {\n\tconst items = new Map<string, DiscoveredItemV1>();\n\tconst keyOf = (item: DiscoveredItemV1): string => `${item.sourceKind}:${item.itemId}`;\n\n\treturn {\n\t\tregister(item) {\n\t\t\tif (item.itemId.trim().length === 0) throw new Error(t(\"Discovered item id must be a non-empty string\"));\n\t\t\tconst existing = items.get(keyOf(item));\n\t\t\tif (existing && existing.version !== item.version) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Item {key} re-registered with a different version ({from} -> {to})\", {\n\t\t\t\t\t\tkey: keyOf(item),\n\t\t\t\t\t\tfrom: existing.version,\n\t\t\t\t\t\tto: item.version,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\titems.set(keyOf(item), { ...item, capabilities: [...item.capabilities] });\n\t\t},\n\t\tderiveMcpItem({ serverId, version, tools, enabled = true }) {\n\t\t\treturn {\n\t\t\t\tsourceKind: \"mcp\",\n\t\t\t\titemId: serverId,\n\t\t\t\tversion,\n\t\t\t\tcapabilities: tools.map((tool) => ({ id: `mcp:${serverId}:${tool.name}`, version: 1 })),\n\t\t\t\tenabled,\n\t\t\t};\n\t\t},\n\t\twireDiscoveredDependencies({ availableCapabilities, disabledItemIds }) {\n\t\t\tconst disabled = new Set(disabledItemIds ?? []);\n\t\t\tconst enabledItems = [...items.values()].filter((item) => item.enabled && !disabled.has(keyOf(item)));\n\n\t\t\t// Version conflicts: same capability id, different declared versions,\n\t\t\t// across different enabled items.\n\t\t\tconst byCapability = new Map<\n\t\t\t\tstring,\n\t\t\t\tArray<{ sourceKind: DiscoverySourceKindV1; itemId: string; version: number }>\n\t\t\t>();\n\t\t\tfor (const item of enabledItems) {\n\t\t\t\tfor (const capability of item.capabilities) {\n\t\t\t\t\tconst list = byCapability.get(capability.id) ?? [];\n\t\t\t\t\tif (!list.some((entry) => entry.itemId === item.itemId)) {\n\t\t\t\t\t\tlist.push({ sourceKind: item.sourceKind, itemId: item.itemId, version: capability.version });\n\t\t\t\t\t}\n\t\t\t\t\tbyCapability.set(capability.id, list);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst conflicts: DiscoveryVersionConflictV1[] = [];\n\t\t\tfor (const [capabilityId, declarations] of byCapability) {\n\t\t\t\tconst versions = new Set(declarations.map((entry) => entry.version));\n\t\t\t\tif (versions.size > 1) conflicts.push({ capabilityId, declarations });\n\t\t\t}\n\n\t\t\t// Disabled items stay in the manifests so the wiring result shows an\n\t\t\t// explicit skipped_disabled entry (visible audit, not silent removal).\n\t\t\tconst manifests: ResolvedPluginManifestV1[] = [...items.values()].map((item) => ({\n\t\t\t\tpluginId: keyOf(item),\n\t\t\t\tpluginVersion: item.version,\n\t\t\t\tcapabilityRefs: [...item.capabilities],\n\t\t\t}));\n\t\t\tconst wiring = wireProfileDependencies({\n\t\t\t\tresolvedPlugins: manifests,\n\t\t\t\tavailableCapabilities,\n\t\t\t\tdisabledPluginIds: disabledItemIds,\n\t\t\t});\n\t\t\treturn { conflicts: Object.freeze(conflicts), wiring };\n\t\t},\n\t};\n}\n"]}
@@ -12,6 +12,7 @@
12
12
  * Resolution reuses the 2.5a exact-version wiring — no kernel special
13
13
  * cases. Implementation lives entirely in profile/assembly land.
14
14
  */
15
+ import { t } from "../core/i18n/index.js";
15
16
  import { wireProfileDependencies } from "./dependency-wiring.js";
16
17
  export function createSkillDiscoveryWiring() {
17
18
  const items = new Map();
@@ -19,10 +20,14 @@ export function createSkillDiscoveryWiring() {
19
20
  return {
20
21
  register(item) {
21
22
  if (item.itemId.trim().length === 0)
22
- throw new Error("Discovered item id must be a non-empty string");
23
+ throw new Error(t("Discovered item id must be a non-empty string"));
23
24
  const existing = items.get(keyOf(item));
24
25
  if (existing && existing.version !== item.version) {
25
- throw new Error(`Item ${keyOf(item)} re-registered with a different version (${existing.version} -> ${item.version})`);
26
+ throw new Error(t("Item {key} re-registered with a different version ({from} -> {to})", {
27
+ key: keyOf(item),
28
+ from: existing.version,
29
+ to: item.version,
30
+ }));
26
31
  }
27
32
  items.set(keyOf(item), { ...item, capabilities: [...item.capabilities] });
28
33
  },
@@ -1 +1 @@
1
- {"version":3,"file":"skill-discovery-wiring.js","sourceRoot":"","sources":["../../src/profile/skill-discovery-wiring.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Skill/MCP discovery wiring (4.4) — turns discovered Skill and MCP tool\n * capabilities into profile-assembly inputs, with all four failure modes\n * explicit BEFORE a session exists: missing dependencies, version conflicts\n * between sources, disabled items, and replacements.\n *\n * Each registered item (a Skill or an MCP server) contributes capability\n * declarations; MCP tools derive capability ids `mcp:<serverId>:<toolName>`.\n * Two enabled items declaring the SAME capability id with DIFFERENT\n * versions is a structured version conflict; identical versions dedupe.\n * Disabled items contribute nothing (replacement = disable + register).\n * Resolution reuses the 2.5a exact-version wiring — no kernel special\n * cases. Implementation lives entirely in profile/assembly land.\n */\n\nimport type { ProfileDependencyWiringV1 } from \"./dependency-wiring.ts\";\nimport { wireProfileDependencies } from \"./dependency-wiring.ts\";\nimport type { ResolvedPluginManifestV1 } from \"./identity.ts\";\n\nexport type DiscoverySourceKindV1 = \"skill\" | \"mcp\";\n\nexport interface DiscoveredItemV1 {\n\treadonly sourceKind: DiscoverySourceKindV1;\n\treadonly itemId: string;\n\treadonly version: string;\n\treadonly capabilities: readonly { readonly id: string; readonly version: number }[];\n\treadonly enabled: boolean;\n}\n\nexport interface DiscoveryVersionConflictV1 {\n\treadonly capabilityId: string;\n\treadonly declarations: readonly {\n\t\treadonly sourceKind: DiscoverySourceKindV1;\n\t\treadonly itemId: string;\n\t\treadonly version: number;\n\t}[];\n}\n\nexport interface DiscoveryWiringV1 {\n\tregister(item: DiscoveredItemV1): void;\n\tderiveMcpItem(input: {\n\t\treadonly serverId: string;\n\t\treadonly version: string;\n\t\treadonly tools: readonly { readonly name: string; readonly description?: string }[];\n\t\treadonly enabled?: boolean;\n\t}): DiscoveredItemV1;\n\twireDiscoveredDependencies(input: {\n\t\treadonly availableCapabilities: readonly { readonly id: string; readonly version: number }[];\n\t\treadonly disabledItemIds?: readonly string[];\n\t}): { readonly conflicts: readonly DiscoveryVersionConflictV1[]; readonly wiring: ProfileDependencyWiringV1 };\n}\n\nexport function createSkillDiscoveryWiring(): DiscoveryWiringV1 {\n\tconst items = new Map<string, DiscoveredItemV1>();\n\tconst keyOf = (item: DiscoveredItemV1): string => `${item.sourceKind}:${item.itemId}`;\n\n\treturn {\n\t\tregister(item) {\n\t\t\tif (item.itemId.trim().length === 0) throw new Error(\"Discovered item id must be a non-empty string\");\n\t\t\tconst existing = items.get(keyOf(item));\n\t\t\tif (existing && existing.version !== item.version) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Item ${keyOf(item)} re-registered with a different version (${existing.version} -> ${item.version})`,\n\t\t\t\t);\n\t\t\t}\n\t\t\titems.set(keyOf(item), { ...item, capabilities: [...item.capabilities] });\n\t\t},\n\t\tderiveMcpItem({ serverId, version, tools, enabled = true }) {\n\t\t\treturn {\n\t\t\t\tsourceKind: \"mcp\",\n\t\t\t\titemId: serverId,\n\t\t\t\tversion,\n\t\t\t\tcapabilities: tools.map((tool) => ({ id: `mcp:${serverId}:${tool.name}`, version: 1 })),\n\t\t\t\tenabled,\n\t\t\t};\n\t\t},\n\t\twireDiscoveredDependencies({ availableCapabilities, disabledItemIds }) {\n\t\t\tconst disabled = new Set(disabledItemIds ?? []);\n\t\t\tconst enabledItems = [...items.values()].filter((item) => item.enabled && !disabled.has(keyOf(item)));\n\n\t\t\t// Version conflicts: same capability id, different declared versions,\n\t\t\t// across different enabled items.\n\t\t\tconst byCapability = new Map<\n\t\t\t\tstring,\n\t\t\t\tArray<{ sourceKind: DiscoverySourceKindV1; itemId: string; version: number }>\n\t\t\t>();\n\t\t\tfor (const item of enabledItems) {\n\t\t\t\tfor (const capability of item.capabilities) {\n\t\t\t\t\tconst list = byCapability.get(capability.id) ?? [];\n\t\t\t\t\tif (!list.some((entry) => entry.itemId === item.itemId)) {\n\t\t\t\t\t\tlist.push({ sourceKind: item.sourceKind, itemId: item.itemId, version: capability.version });\n\t\t\t\t\t}\n\t\t\t\t\tbyCapability.set(capability.id, list);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst conflicts: DiscoveryVersionConflictV1[] = [];\n\t\t\tfor (const [capabilityId, declarations] of byCapability) {\n\t\t\t\tconst versions = new Set(declarations.map((entry) => entry.version));\n\t\t\t\tif (versions.size > 1) conflicts.push({ capabilityId, declarations });\n\t\t\t}\n\n\t\t\t// Disabled items stay in the manifests so the wiring result shows an\n\t\t\t// explicit skipped_disabled entry (visible audit, not silent removal).\n\t\t\tconst manifests: ResolvedPluginManifestV1[] = [...items.values()].map((item) => ({\n\t\t\t\tpluginId: keyOf(item),\n\t\t\t\tpluginVersion: item.version,\n\t\t\t\tcapabilityRefs: [...item.capabilities],\n\t\t\t}));\n\t\t\tconst wiring = wireProfileDependencies({\n\t\t\t\tresolvedPlugins: manifests,\n\t\t\t\tavailableCapabilities,\n\t\t\t\tdisabledPluginIds: disabledItemIds,\n\t\t\t});\n\t\t\treturn { conflicts: Object.freeze(conflicts), wiring };\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"skill-discovery-wiring.js","sourceRoot":"","sources":["../../src/profile/skill-discovery-wiring.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Skill/MCP discovery wiring (4.4) — turns discovered Skill and MCP tool\n * capabilities into profile-assembly inputs, with all four failure modes\n * explicit BEFORE a session exists: missing dependencies, version conflicts\n * between sources, disabled items, and replacements.\n *\n * Each registered item (a Skill or an MCP server) contributes capability\n * declarations; MCP tools derive capability ids `mcp:<serverId>:<toolName>`.\n * Two enabled items declaring the SAME capability id with DIFFERENT\n * versions is a structured version conflict; identical versions dedupe.\n * Disabled items contribute nothing (replacement = disable + register).\n * Resolution reuses the 2.5a exact-version wiring — no kernel special\n * cases. Implementation lives entirely in profile/assembly land.\n */\n\nimport { t } from \"../core/i18n/index.ts\";\nimport type { ProfileDependencyWiringV1 } from \"./dependency-wiring.ts\";\nimport { wireProfileDependencies } from \"./dependency-wiring.ts\";\nimport type { ResolvedPluginManifestV1 } from \"./identity.ts\";\n\nexport type DiscoverySourceKindV1 = \"skill\" | \"mcp\";\n\nexport interface DiscoveredItemV1 {\n\treadonly sourceKind: DiscoverySourceKindV1;\n\treadonly itemId: string;\n\treadonly version: string;\n\treadonly capabilities: readonly { readonly id: string; readonly version: number }[];\n\treadonly enabled: boolean;\n}\n\nexport interface DiscoveryVersionConflictV1 {\n\treadonly capabilityId: string;\n\treadonly declarations: readonly {\n\t\treadonly sourceKind: DiscoverySourceKindV1;\n\t\treadonly itemId: string;\n\t\treadonly version: number;\n\t}[];\n}\n\nexport interface DiscoveryWiringV1 {\n\tregister(item: DiscoveredItemV1): void;\n\tderiveMcpItem(input: {\n\t\treadonly serverId: string;\n\t\treadonly version: string;\n\t\treadonly tools: readonly { readonly name: string; readonly description?: string }[];\n\t\treadonly enabled?: boolean;\n\t}): DiscoveredItemV1;\n\twireDiscoveredDependencies(input: {\n\t\treadonly availableCapabilities: readonly { readonly id: string; readonly version: number }[];\n\t\treadonly disabledItemIds?: readonly string[];\n\t}): { readonly conflicts: readonly DiscoveryVersionConflictV1[]; readonly wiring: ProfileDependencyWiringV1 };\n}\n\nexport function createSkillDiscoveryWiring(): DiscoveryWiringV1 {\n\tconst items = new Map<string, DiscoveredItemV1>();\n\tconst keyOf = (item: DiscoveredItemV1): string => `${item.sourceKind}:${item.itemId}`;\n\n\treturn {\n\t\tregister(item) {\n\t\t\tif (item.itemId.trim().length === 0) throw new Error(t(\"Discovered item id must be a non-empty string\"));\n\t\t\tconst existing = items.get(keyOf(item));\n\t\t\tif (existing && existing.version !== item.version) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Item {key} re-registered with a different version ({from} -> {to})\", {\n\t\t\t\t\t\tkey: keyOf(item),\n\t\t\t\t\t\tfrom: existing.version,\n\t\t\t\t\t\tto: item.version,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\titems.set(keyOf(item), { ...item, capabilities: [...item.capabilities] });\n\t\t},\n\t\tderiveMcpItem({ serverId, version, tools, enabled = true }) {\n\t\t\treturn {\n\t\t\t\tsourceKind: \"mcp\",\n\t\t\t\titemId: serverId,\n\t\t\t\tversion,\n\t\t\t\tcapabilities: tools.map((tool) => ({ id: `mcp:${serverId}:${tool.name}`, version: 1 })),\n\t\t\t\tenabled,\n\t\t\t};\n\t\t},\n\t\twireDiscoveredDependencies({ availableCapabilities, disabledItemIds }) {\n\t\t\tconst disabled = new Set(disabledItemIds ?? []);\n\t\t\tconst enabledItems = [...items.values()].filter((item) => item.enabled && !disabled.has(keyOf(item)));\n\n\t\t\t// Version conflicts: same capability id, different declared versions,\n\t\t\t// across different enabled items.\n\t\t\tconst byCapability = new Map<\n\t\t\t\tstring,\n\t\t\t\tArray<{ sourceKind: DiscoverySourceKindV1; itemId: string; version: number }>\n\t\t\t>();\n\t\t\tfor (const item of enabledItems) {\n\t\t\t\tfor (const capability of item.capabilities) {\n\t\t\t\t\tconst list = byCapability.get(capability.id) ?? [];\n\t\t\t\t\tif (!list.some((entry) => entry.itemId === item.itemId)) {\n\t\t\t\t\t\tlist.push({ sourceKind: item.sourceKind, itemId: item.itemId, version: capability.version });\n\t\t\t\t\t}\n\t\t\t\t\tbyCapability.set(capability.id, list);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst conflicts: DiscoveryVersionConflictV1[] = [];\n\t\t\tfor (const [capabilityId, declarations] of byCapability) {\n\t\t\t\tconst versions = new Set(declarations.map((entry) => entry.version));\n\t\t\t\tif (versions.size > 1) conflicts.push({ capabilityId, declarations });\n\t\t\t}\n\n\t\t\t// Disabled items stay in the manifests so the wiring result shows an\n\t\t\t// explicit skipped_disabled entry (visible audit, not silent removal).\n\t\t\tconst manifests: ResolvedPluginManifestV1[] = [...items.values()].map((item) => ({\n\t\t\t\tpluginId: keyOf(item),\n\t\t\t\tpluginVersion: item.version,\n\t\t\t\tcapabilityRefs: [...item.capabilities],\n\t\t\t}));\n\t\t\tconst wiring = wireProfileDependencies({\n\t\t\t\tresolvedPlugins: manifests,\n\t\t\t\tavailableCapabilities,\n\t\t\t\tdisabledPluginIds: disabledItemIds,\n\t\t\t});\n\t\t\treturn { conflicts: Object.freeze(conflicts), wiring };\n\t\t},\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"state-store.d.ts","sourceRoot":"","sources":["../../src/profile/state-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B;AAyDD,MAAM,WAAW,iBAAiB;IACjC,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,kBAAkB,CAAC;IACzD,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACpH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,kBAAkB,EAAE,CAAC;IACzD,iFAAiF;IACjF,MAAM,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACrD,QAAQ,IAAI,SAAS,MAAM,EAAE,CAAC;CAC9B;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE;IAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAAO,GAAG,iBAAiB,CAiFtG","sourcesContent":["/**\n * Generic transition/evidence/revision store (2.3a) — the domain-agnostic\n * contract base for Goal/Plan/Todo plugins.\n *\n * The store knows NOTHING about goal/plan/todo semantics. It only enforces:\n * - causality: a transition's `fromStatus` must equal the entity's current\n * status (null = initial transition), otherwise an explicit conflict;\n * - idempotency: replaying the same (domain, entityId, operationId, toStatus)\n * returns the existing record and never advances the revision;\n * - evidence: every transition carries structured evidence references;\n * - payload: transitions may carry an optional domain payload (e.g. a goal\n * title) that is validated JSON and part of the replayable record;\n * - replay: the full history rebuilds the identical current state.\n */\nimport type { JsonValue } from \"@agent-forge/ai\";\n\nexport interface TransitionEvidenceRefV1 {\n\treadonly kind: string;\n\treadonly ref: string;\n\treadonly digest?: string;\n}\n\nexport interface TransitionRecordV1 {\n\treadonly domain: string;\n\treadonly entityId: string;\n\treadonly owner: string;\n\treadonly fromStatus: string | null;\n\treadonly toStatus: string;\n\treadonly operationId: string;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly payload?: JsonValue;\n\treadonly revision: number;\n\treadonly at: number;\n}\n\nexport interface TransitionInputV1 {\n\treadonly domain: string;\n\treadonly entityId: string;\n\treadonly owner: string;\n\treadonly fromStatus: string | null;\n\treadonly toStatus: string;\n\treadonly operationId: string;\n\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\treadonly payload?: JsonValue;\n\treadonly at?: number;\n}\n\nexport interface TransitionResultV1 {\n\treadonly record: TransitionRecordV1;\n\treadonly deduped: boolean;\n}\n\nfunction assertNonEmptyString(value: unknown, label: string): asserts value is string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) throw new Error(`${label} must be a non-empty string`);\n}\n\nfunction validateEvidence(value: unknown, label: string): TransitionEvidenceRefV1[] {\n\tif (value === undefined) return [];\n\tif (!Array.isArray(value)) throw new Error(`${label} must be an array`);\n\treturn value.map((item, index) => {\n\t\tconst depLabel = `${label}[${index}]`;\n\t\tif (item === null || typeof item !== \"object\" || Array.isArray(item)) {\n\t\t\tthrow new Error(`${depLabel} must be a plain object`);\n\t\t}\n\t\tconst record = item as Record<string, unknown>;\n\t\tassertNonEmptyString(record.kind, `${depLabel}.kind`);\n\t\tassertNonEmptyString(record.ref, `${depLabel}.ref`);\n\t\tif (record.digest !== undefined) assertNonEmptyString(record.digest, `${depLabel}.digest`);\n\t\treturn Object.freeze({\n\t\t\tkind: record.kind,\n\t\t\tref: record.ref,\n\t\t\t...(record.digest === undefined ? {} : { digest: record.digest }),\n\t\t});\n\t});\n}\n\nfunction validatePayload(value: unknown, label: string): JsonValue | undefined {\n\tif (value === undefined) return undefined;\n\tconst seen = new Set<object>();\n\tconst check = (node: unknown): void => {\n\t\tif (node === null || typeof node === \"string\" || typeof node === \"boolean\") return;\n\t\tif (typeof node === \"number\") {\n\t\t\tif (!Number.isFinite(node)) throw new Error(`${label} must be JSON-safe: ${node} is not a finite number`);\n\t\t\treturn;\n\t\t}\n\t\tif (typeof node === \"object\") {\n\t\t\tif (seen.has(node)) throw new Error(`${label} must be JSON-safe: circular reference`);\n\t\t\tseen.add(node);\n\t\t\tif (Array.isArray(node)) {\n\t\t\t\tfor (const item of node) check(item);\n\t\t\t} else {\n\t\t\t\tconst proto = Object.getPrototypeOf(node) as unknown;\n\t\t\t\tif (proto !== Object.prototype && proto !== null) throw new Error(`${label} must be a plain object`);\n\t\t\t\tfor (const entry of Object.entries(node)) {\n\t\t\t\t\tif (entry[1] === undefined) throw new Error(`${label} must be JSON-safe: ${entry[0]} is undefined`);\n\t\t\t\t\tcheck(entry[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tseen.delete(node);\n\t\t\treturn;\n\t\t}\n\t\tthrow new Error(`${label} must be JSON-safe: unsupported value of type ${typeof node}`);\n\t};\n\tcheck(value);\n\treturn JSON.parse(JSON.stringify(value)) as JsonValue;\n}\n\nexport interface TransitionStoreV1 {\n\ttransition(input: TransitionInputV1): TransitionResultV1;\n\tcurrentStatus(domain: string, entityId: string): { readonly status: string; readonly revision: number } | undefined;\n\thistory(entityId: string): readonly TransitionRecordV1[];\n\t/** Replays a history into a fresh store; the rebuilt state must be identical. */\n\treplay(history: readonly TransitionRecordV1[]): void;\n\tentities(): readonly string[];\n}\n\nexport function createTransitionStore(options: { readonly now?: () => number } = {}): TransitionStoreV1 {\n\tconst now = options.now ?? (() => Date.now());\n\tconst recordsByEntity = new Map<string, TransitionRecordV1[]>();\n\tconst idempotency = new Map<string, TransitionRecordV1>();\n\tconst currentStatus = new Map<string, { status: string; revision: number }>();\n\tconst revisions = new Map<string, number>();\n\n\tconst entityKey = (domain: string, entityId: string): string => `${domain}\\u0000${entityId}`;\n\n\treturn {\n\t\ttransition(input) {\n\t\t\tassertNonEmptyString(input.domain, \"Transition domain\");\n\t\t\tassertNonEmptyString(input.entityId, \"Transition entityId\");\n\t\t\tassertNonEmptyString(input.owner, \"Transition owner\");\n\t\t\tassertNonEmptyString(input.operationId, \"Transition operationId\");\n\t\t\tassertNonEmptyString(input.toStatus, \"Transition toStatus\");\n\t\t\tconst evidence = validateEvidence(input.evidence, \"Transition evidence\");\n\t\t\tconst payload = validatePayload(input.payload, \"Transition payload\");\n\t\t\tconst key = `${entityKey(input.domain, input.entityId)}\\u0000${input.operationId}\\u0000${input.toStatus}`;\n\n\t\t\tconst existing = idempotency.get(key);\n\t\t\tif (existing) return { record: existing, deduped: true };\n\n\t\t\tconst entityKeyId = entityKey(input.domain, input.entityId);\n\t\t\tconst current = currentStatus.get(entityKeyId);\n\t\t\tconst fromStatus = input.fromStatus;\n\t\t\tif ((current?.status ?? null) !== fromStatus) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Transition conflict: expected fromStatus ${JSON.stringify(current?.status ?? null)}, got ${JSON.stringify(fromStatus)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst revision = (revisions.get(entityKeyId) ?? 0) + 1;\n\t\t\trevisions.set(entityKeyId, revision);\n\t\t\tconst record: TransitionRecordV1 = Object.freeze({\n\t\t\t\tdomain: input.domain,\n\t\t\t\tentityId: input.entityId,\n\t\t\t\towner: input.owner,\n\t\t\t\tfromStatus,\n\t\t\t\ttoStatus: input.toStatus,\n\t\t\t\toperationId: input.operationId,\n\t\t\t\tevidence: Object.freeze(evidence),\n\t\t\t\t...(payload === undefined ? {} : { payload }),\n\t\t\t\trevision,\n\t\t\t\tat: input.at ?? now(),\n\t\t\t});\n\t\t\tconst log = recordsByEntity.get(entityKeyId) ?? [];\n\t\t\tlog.push(record);\n\t\t\trecordsByEntity.set(entityKeyId, log);\n\t\t\tcurrentStatus.set(entityKeyId, { status: input.toStatus, revision });\n\t\t\tidempotency.set(key, record);\n\t\t\treturn { record, deduped: false };\n\t\t},\n\t\tcurrentStatus(domain: string, entityId: string) {\n\t\t\treturn currentStatus.get(entityKey(domain, entityId));\n\t\t},\n\t\thistory(entityId: string) {\n\t\t\treturn Object.freeze(\n\t\t\t\t[...recordsByEntity.entries()]\n\t\t\t\t\t.filter(([entityKeyId]) => entityKeyId.endsWith(`\\u0000${entityId}`))\n\t\t\t\t\t.flatMap(([, log]) => log),\n\t\t\t);\n\t\t},\n\t\treplay(history) {\n\t\t\tfor (const record of history) {\n\t\t\t\tthis.transition({\n\t\t\t\t\tdomain: record.domain,\n\t\t\t\t\tentityId: record.entityId,\n\t\t\t\t\towner: record.owner,\n\t\t\t\t\tfromStatus: record.fromStatus,\n\t\t\t\t\ttoStatus: record.toStatus,\n\t\t\t\t\toperationId: record.operationId,\n\t\t\t\t\tevidence: record.evidence,\n\t\t\t\t\tpayload: record.payload,\n\t\t\t\t\tat: record.at,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tentities() {\n\t\t\treturn Object.freeze([...new Set([...currentStatus.keys()].map((key) => key.split(\"\\u0000\")[1]!))]);\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"state-store.d.ts","sourceRoot":"","sources":["../../src/profile/state-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B;AA+DD,MAAM,WAAW,iBAAiB;IACjC,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,kBAAkB,CAAC;IACzD,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACpH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,kBAAkB,EAAE,CAAC;IACzD,iFAAiF;IACjF,MAAM,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACrD,QAAQ,IAAI,SAAS,MAAM,EAAE,CAAC;CAC9B;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE;IAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAAO,GAAG,iBAAiB,CAoFtG","sourcesContent":["/**\n * Generic transition/evidence/revision store (2.3a) — the domain-agnostic\n * contract base for Goal/Plan/Todo plugins.\n *\n * The store knows NOTHING about goal/plan/todo semantics. It only enforces:\n * - causality: a transition's `fromStatus` must equal the entity's current\n * status (null = initial transition), otherwise an explicit conflict;\n * - idempotency: replaying the same (domain, entityId, operationId, toStatus)\n * returns the existing record and never advances the revision;\n * - evidence: every transition carries structured evidence references;\n * - payload: transitions may carry an optional domain payload (e.g. a goal\n * title) that is validated JSON and part of the replayable record;\n * - replay: the full history rebuilds the identical current state.\n */\nimport type { JsonValue } from \"@agent-forge/ai\";\nimport { t } from \"../core/i18n/index.ts\";\n\nexport interface TransitionEvidenceRefV1 {\n\treadonly kind: string;\n\treadonly ref: string;\n\treadonly digest?: string;\n}\n\nexport interface TransitionRecordV1 {\n\treadonly domain: string;\n\treadonly entityId: string;\n\treadonly owner: string;\n\treadonly fromStatus: string | null;\n\treadonly toStatus: string;\n\treadonly operationId: string;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly payload?: JsonValue;\n\treadonly revision: number;\n\treadonly at: number;\n}\n\nexport interface TransitionInputV1 {\n\treadonly domain: string;\n\treadonly entityId: string;\n\treadonly owner: string;\n\treadonly fromStatus: string | null;\n\treadonly toStatus: string;\n\treadonly operationId: string;\n\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\treadonly payload?: JsonValue;\n\treadonly at?: number;\n}\n\nexport interface TransitionResultV1 {\n\treadonly record: TransitionRecordV1;\n\treadonly deduped: boolean;\n}\n\nfunction assertNonEmptyString(value: unknown, label: string): asserts value is string {\n\tif (typeof value !== \"string\" || value.trim().length === 0)\n\t\tthrow new Error(t(\"{label} must be a non-empty string\", { label }));\n}\n\nfunction validateEvidence(value: unknown, label: string): TransitionEvidenceRefV1[] {\n\tif (value === undefined) return [];\n\tif (!Array.isArray(value)) throw new Error(t(\"{label} must be an array\", { label }));\n\treturn value.map((item, index) => {\n\t\tconst depLabel = `${label}[${index}]`;\n\t\tif (item === null || typeof item !== \"object\" || Array.isArray(item)) {\n\t\t\tthrow new Error(t(\"{label} must be a plain object\", { label: depLabel }));\n\t\t}\n\t\tconst record = item as Record<string, unknown>;\n\t\tassertNonEmptyString(record.kind, `${depLabel}.kind`);\n\t\tassertNonEmptyString(record.ref, `${depLabel}.ref`);\n\t\tif (record.digest !== undefined) assertNonEmptyString(record.digest, `${depLabel}.digest`);\n\t\treturn Object.freeze({\n\t\t\tkind: record.kind,\n\t\t\tref: record.ref,\n\t\t\t...(record.digest === undefined ? {} : { digest: record.digest }),\n\t\t});\n\t});\n}\n\nfunction validatePayload(value: unknown, label: string): JsonValue | undefined {\n\tif (value === undefined) return undefined;\n\tconst seen = new Set<object>();\n\tconst check = (node: unknown): void => {\n\t\tif (node === null || typeof node === \"string\" || typeof node === \"boolean\") return;\n\t\tif (typeof node === \"number\") {\n\t\t\tif (!Number.isFinite(node))\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"{label} must be JSON-safe: {node} is not a finite number\", { label, node: String(node) }),\n\t\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (typeof node === \"object\") {\n\t\t\tif (seen.has(node)) throw new Error(t(\"{label} must be JSON-safe: circular reference\", { label }));\n\t\t\tseen.add(node);\n\t\t\tif (Array.isArray(node)) {\n\t\t\t\tfor (const item of node) check(item);\n\t\t\t} else {\n\t\t\t\tconst proto = Object.getPrototypeOf(node) as unknown;\n\t\t\t\tif (proto !== Object.prototype && proto !== null)\n\t\t\t\t\tthrow new Error(t(\"{label} must be a plain object\", { label }));\n\t\t\t\tfor (const entry of Object.entries(node)) {\n\t\t\t\t\tif (entry[1] === undefined)\n\t\t\t\t\t\tthrow new Error(t(\"{label} must be JSON-safe: {key} is undefined\", { label, key: entry[0] }));\n\t\t\t\t\tcheck(entry[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tseen.delete(node);\n\t\t\treturn;\n\t\t}\n\t\tthrow new Error(t(\"{label} must be JSON-safe: unsupported value of type {type}\", { label, type: typeof node }));\n\t};\n\tcheck(value);\n\treturn JSON.parse(JSON.stringify(value)) as JsonValue;\n}\n\nexport interface TransitionStoreV1 {\n\ttransition(input: TransitionInputV1): TransitionResultV1;\n\tcurrentStatus(domain: string, entityId: string): { readonly status: string; readonly revision: number } | undefined;\n\thistory(entityId: string): readonly TransitionRecordV1[];\n\t/** Replays a history into a fresh store; the rebuilt state must be identical. */\n\treplay(history: readonly TransitionRecordV1[]): void;\n\tentities(): readonly string[];\n}\n\nexport function createTransitionStore(options: { readonly now?: () => number } = {}): TransitionStoreV1 {\n\tconst now = options.now ?? (() => Date.now());\n\tconst recordsByEntity = new Map<string, TransitionRecordV1[]>();\n\tconst idempotency = new Map<string, TransitionRecordV1>();\n\tconst currentStatus = new Map<string, { status: string; revision: number }>();\n\tconst revisions = new Map<string, number>();\n\n\tconst entityKey = (domain: string, entityId: string): string => `${domain}\\u0000${entityId}`;\n\n\treturn {\n\t\ttransition(input) {\n\t\t\tassertNonEmptyString(input.domain, \"Transition domain\");\n\t\t\tassertNonEmptyString(input.entityId, \"Transition entityId\");\n\t\t\tassertNonEmptyString(input.owner, \"Transition owner\");\n\t\t\tassertNonEmptyString(input.operationId, \"Transition operationId\");\n\t\t\tassertNonEmptyString(input.toStatus, \"Transition toStatus\");\n\t\t\tconst evidence = validateEvidence(input.evidence, \"Transition evidence\");\n\t\t\tconst payload = validatePayload(input.payload, \"Transition payload\");\n\t\t\tconst key = `${entityKey(input.domain, input.entityId)}\\u0000${input.operationId}\\u0000${input.toStatus}`;\n\n\t\t\tconst existing = idempotency.get(key);\n\t\t\tif (existing) return { record: existing, deduped: true };\n\n\t\t\tconst entityKeyId = entityKey(input.domain, input.entityId);\n\t\t\tconst current = currentStatus.get(entityKeyId);\n\t\t\tconst fromStatus = input.fromStatus;\n\t\t\tif ((current?.status ?? null) !== fromStatus) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Transition conflict: expected fromStatus {from}, got {to}\", {\n\t\t\t\t\t\tfrom: JSON.stringify(current?.status ?? null),\n\t\t\t\t\t\tto: JSON.stringify(fromStatus),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst revision = (revisions.get(entityKeyId) ?? 0) + 1;\n\t\t\trevisions.set(entityKeyId, revision);\n\t\t\tconst record: TransitionRecordV1 = Object.freeze({\n\t\t\t\tdomain: input.domain,\n\t\t\t\tentityId: input.entityId,\n\t\t\t\towner: input.owner,\n\t\t\t\tfromStatus,\n\t\t\t\ttoStatus: input.toStatus,\n\t\t\t\toperationId: input.operationId,\n\t\t\t\tevidence: Object.freeze(evidence),\n\t\t\t\t...(payload === undefined ? {} : { payload }),\n\t\t\t\trevision,\n\t\t\t\tat: input.at ?? now(),\n\t\t\t});\n\t\t\tconst log = recordsByEntity.get(entityKeyId) ?? [];\n\t\t\tlog.push(record);\n\t\t\trecordsByEntity.set(entityKeyId, log);\n\t\t\tcurrentStatus.set(entityKeyId, { status: input.toStatus, revision });\n\t\t\tidempotency.set(key, record);\n\t\t\treturn { record, deduped: false };\n\t\t},\n\t\tcurrentStatus(domain: string, entityId: string) {\n\t\t\treturn currentStatus.get(entityKey(domain, entityId));\n\t\t},\n\t\thistory(entityId: string) {\n\t\t\treturn Object.freeze(\n\t\t\t\t[...recordsByEntity.entries()]\n\t\t\t\t\t.filter(([entityKeyId]) => entityKeyId.endsWith(`\\u0000${entityId}`))\n\t\t\t\t\t.flatMap(([, log]) => log),\n\t\t\t);\n\t\t},\n\t\treplay(history) {\n\t\t\tfor (const record of history) {\n\t\t\t\tthis.transition({\n\t\t\t\t\tdomain: record.domain,\n\t\t\t\t\tentityId: record.entityId,\n\t\t\t\t\towner: record.owner,\n\t\t\t\t\tfromStatus: record.fromStatus,\n\t\t\t\t\ttoStatus: record.toStatus,\n\t\t\t\t\toperationId: record.operationId,\n\t\t\t\t\tevidence: record.evidence,\n\t\t\t\t\tpayload: record.payload,\n\t\t\t\t\tat: record.at,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tentities() {\n\t\t\treturn Object.freeze([...new Set([...currentStatus.keys()].map((key) => key.split(\"\\u0000\")[1]!))]);\n\t\t},\n\t};\n}\n"]}
@@ -1,16 +1,17 @@
1
+ import { t } from "../core/i18n/index.js";
1
2
  function assertNonEmptyString(value, label) {
2
3
  if (typeof value !== "string" || value.trim().length === 0)
3
- throw new Error(`${label} must be a non-empty string`);
4
+ throw new Error(t("{label} must be a non-empty string", { label }));
4
5
  }
5
6
  function validateEvidence(value, label) {
6
7
  if (value === undefined)
7
8
  return [];
8
9
  if (!Array.isArray(value))
9
- throw new Error(`${label} must be an array`);
10
+ throw new Error(t("{label} must be an array", { label }));
10
11
  return value.map((item, index) => {
11
12
  const depLabel = `${label}[${index}]`;
12
13
  if (item === null || typeof item !== "object" || Array.isArray(item)) {
13
- throw new Error(`${depLabel} must be a plain object`);
14
+ throw new Error(t("{label} must be a plain object", { label: depLabel }));
14
15
  }
15
16
  const record = item;
16
17
  assertNonEmptyString(record.kind, `${depLabel}.kind`);
@@ -33,12 +34,12 @@ function validatePayload(value, label) {
33
34
  return;
34
35
  if (typeof node === "number") {
35
36
  if (!Number.isFinite(node))
36
- throw new Error(`${label} must be JSON-safe: ${node} is not a finite number`);
37
+ throw new Error(t("{label} must be JSON-safe: {node} is not a finite number", { label, node: String(node) }));
37
38
  return;
38
39
  }
39
40
  if (typeof node === "object") {
40
41
  if (seen.has(node))
41
- throw new Error(`${label} must be JSON-safe: circular reference`);
42
+ throw new Error(t("{label} must be JSON-safe: circular reference", { label }));
42
43
  seen.add(node);
43
44
  if (Array.isArray(node)) {
44
45
  for (const item of node)
@@ -47,17 +48,17 @@ function validatePayload(value, label) {
47
48
  else {
48
49
  const proto = Object.getPrototypeOf(node);
49
50
  if (proto !== Object.prototype && proto !== null)
50
- throw new Error(`${label} must be a plain object`);
51
+ throw new Error(t("{label} must be a plain object", { label }));
51
52
  for (const entry of Object.entries(node)) {
52
53
  if (entry[1] === undefined)
53
- throw new Error(`${label} must be JSON-safe: ${entry[0]} is undefined`);
54
+ throw new Error(t("{label} must be JSON-safe: {key} is undefined", { label, key: entry[0] }));
54
55
  check(entry[1]);
55
56
  }
56
57
  }
57
58
  seen.delete(node);
58
59
  return;
59
60
  }
60
- throw new Error(`${label} must be JSON-safe: unsupported value of type ${typeof node}`);
61
+ throw new Error(t("{label} must be JSON-safe: unsupported value of type {type}", { label, type: typeof node }));
61
62
  };
62
63
  check(value);
63
64
  return JSON.parse(JSON.stringify(value));
@@ -86,7 +87,10 @@ export function createTransitionStore(options = {}) {
86
87
  const current = currentStatus.get(entityKeyId);
87
88
  const fromStatus = input.fromStatus;
88
89
  if ((current?.status ?? null) !== fromStatus) {
89
- throw new Error(`Transition conflict: expected fromStatus ${JSON.stringify(current?.status ?? null)}, got ${JSON.stringify(fromStatus)}`);
90
+ throw new Error(t("Transition conflict: expected fromStatus {from}, got {to}", {
91
+ from: JSON.stringify(current?.status ?? null),
92
+ to: JSON.stringify(fromStatus),
93
+ }));
90
94
  }
91
95
  const revision = (revisions.get(entityKeyId) ?? 0) + 1;
92
96
  revisions.set(entityKeyId, revision);
@@ -1 +1 @@
1
- {"version":3,"file":"state-store.js","sourceRoot":"","sources":["../../src/profile/state-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Generic transition/evidence/revision store (2.3a) — the domain-agnostic\n * contract base for Goal/Plan/Todo plugins.\n *\n * The store knows NOTHING about goal/plan/todo semantics. It only enforces:\n * - causality: a transition's `fromStatus` must equal the entity's current\n * status (null = initial transition), otherwise an explicit conflict;\n * - idempotency: replaying the same (domain, entityId, operationId, toStatus)\n * returns the existing record and never advances the revision;\n * - evidence: every transition carries structured evidence references;\n * - payload: transitions may carry an optional domain payload (e.g. a goal\n * title) that is validated JSON and part of the replayable record;\n * - replay: the full history rebuilds the identical current state.\n */\nimport type { JsonValue } from \"@agent-forge/ai\";\n\nexport interface TransitionEvidenceRefV1 {\n\treadonly kind: string;\n\treadonly ref: string;\n\treadonly digest?: string;\n}\n\nexport interface TransitionRecordV1 {\n\treadonly domain: string;\n\treadonly entityId: string;\n\treadonly owner: string;\n\treadonly fromStatus: string | null;\n\treadonly toStatus: string;\n\treadonly operationId: string;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly payload?: JsonValue;\n\treadonly revision: number;\n\treadonly at: number;\n}\n\nexport interface TransitionInputV1 {\n\treadonly domain: string;\n\treadonly entityId: string;\n\treadonly owner: string;\n\treadonly fromStatus: string | null;\n\treadonly toStatus: string;\n\treadonly operationId: string;\n\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\treadonly payload?: JsonValue;\n\treadonly at?: number;\n}\n\nexport interface TransitionResultV1 {\n\treadonly record: TransitionRecordV1;\n\treadonly deduped: boolean;\n}\n\nfunction assertNonEmptyString(value: unknown, label: string): asserts value is string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) throw new Error(`${label} must be a non-empty string`);\n}\n\nfunction validateEvidence(value: unknown, label: string): TransitionEvidenceRefV1[] {\n\tif (value === undefined) return [];\n\tif (!Array.isArray(value)) throw new Error(`${label} must be an array`);\n\treturn value.map((item, index) => {\n\t\tconst depLabel = `${label}[${index}]`;\n\t\tif (item === null || typeof item !== \"object\" || Array.isArray(item)) {\n\t\t\tthrow new Error(`${depLabel} must be a plain object`);\n\t\t}\n\t\tconst record = item as Record<string, unknown>;\n\t\tassertNonEmptyString(record.kind, `${depLabel}.kind`);\n\t\tassertNonEmptyString(record.ref, `${depLabel}.ref`);\n\t\tif (record.digest !== undefined) assertNonEmptyString(record.digest, `${depLabel}.digest`);\n\t\treturn Object.freeze({\n\t\t\tkind: record.kind,\n\t\t\tref: record.ref,\n\t\t\t...(record.digest === undefined ? {} : { digest: record.digest }),\n\t\t});\n\t});\n}\n\nfunction validatePayload(value: unknown, label: string): JsonValue | undefined {\n\tif (value === undefined) return undefined;\n\tconst seen = new Set<object>();\n\tconst check = (node: unknown): void => {\n\t\tif (node === null || typeof node === \"string\" || typeof node === \"boolean\") return;\n\t\tif (typeof node === \"number\") {\n\t\t\tif (!Number.isFinite(node)) throw new Error(`${label} must be JSON-safe: ${node} is not a finite number`);\n\t\t\treturn;\n\t\t}\n\t\tif (typeof node === \"object\") {\n\t\t\tif (seen.has(node)) throw new Error(`${label} must be JSON-safe: circular reference`);\n\t\t\tseen.add(node);\n\t\t\tif (Array.isArray(node)) {\n\t\t\t\tfor (const item of node) check(item);\n\t\t\t} else {\n\t\t\t\tconst proto = Object.getPrototypeOf(node) as unknown;\n\t\t\t\tif (proto !== Object.prototype && proto !== null) throw new Error(`${label} must be a plain object`);\n\t\t\t\tfor (const entry of Object.entries(node)) {\n\t\t\t\t\tif (entry[1] === undefined) throw new Error(`${label} must be JSON-safe: ${entry[0]} is undefined`);\n\t\t\t\t\tcheck(entry[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tseen.delete(node);\n\t\t\treturn;\n\t\t}\n\t\tthrow new Error(`${label} must be JSON-safe: unsupported value of type ${typeof node}`);\n\t};\n\tcheck(value);\n\treturn JSON.parse(JSON.stringify(value)) as JsonValue;\n}\n\nexport interface TransitionStoreV1 {\n\ttransition(input: TransitionInputV1): TransitionResultV1;\n\tcurrentStatus(domain: string, entityId: string): { readonly status: string; readonly revision: number } | undefined;\n\thistory(entityId: string): readonly TransitionRecordV1[];\n\t/** Replays a history into a fresh store; the rebuilt state must be identical. */\n\treplay(history: readonly TransitionRecordV1[]): void;\n\tentities(): readonly string[];\n}\n\nexport function createTransitionStore(options: { readonly now?: () => number } = {}): TransitionStoreV1 {\n\tconst now = options.now ?? (() => Date.now());\n\tconst recordsByEntity = new Map<string, TransitionRecordV1[]>();\n\tconst idempotency = new Map<string, TransitionRecordV1>();\n\tconst currentStatus = new Map<string, { status: string; revision: number }>();\n\tconst revisions = new Map<string, number>();\n\n\tconst entityKey = (domain: string, entityId: string): string => `${domain}\\u0000${entityId}`;\n\n\treturn {\n\t\ttransition(input) {\n\t\t\tassertNonEmptyString(input.domain, \"Transition domain\");\n\t\t\tassertNonEmptyString(input.entityId, \"Transition entityId\");\n\t\t\tassertNonEmptyString(input.owner, \"Transition owner\");\n\t\t\tassertNonEmptyString(input.operationId, \"Transition operationId\");\n\t\t\tassertNonEmptyString(input.toStatus, \"Transition toStatus\");\n\t\t\tconst evidence = validateEvidence(input.evidence, \"Transition evidence\");\n\t\t\tconst payload = validatePayload(input.payload, \"Transition payload\");\n\t\t\tconst key = `${entityKey(input.domain, input.entityId)}\\u0000${input.operationId}\\u0000${input.toStatus}`;\n\n\t\t\tconst existing = idempotency.get(key);\n\t\t\tif (existing) return { record: existing, deduped: true };\n\n\t\t\tconst entityKeyId = entityKey(input.domain, input.entityId);\n\t\t\tconst current = currentStatus.get(entityKeyId);\n\t\t\tconst fromStatus = input.fromStatus;\n\t\t\tif ((current?.status ?? null) !== fromStatus) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Transition conflict: expected fromStatus ${JSON.stringify(current?.status ?? null)}, got ${JSON.stringify(fromStatus)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst revision = (revisions.get(entityKeyId) ?? 0) + 1;\n\t\t\trevisions.set(entityKeyId, revision);\n\t\t\tconst record: TransitionRecordV1 = Object.freeze({\n\t\t\t\tdomain: input.domain,\n\t\t\t\tentityId: input.entityId,\n\t\t\t\towner: input.owner,\n\t\t\t\tfromStatus,\n\t\t\t\ttoStatus: input.toStatus,\n\t\t\t\toperationId: input.operationId,\n\t\t\t\tevidence: Object.freeze(evidence),\n\t\t\t\t...(payload === undefined ? {} : { payload }),\n\t\t\t\trevision,\n\t\t\t\tat: input.at ?? now(),\n\t\t\t});\n\t\t\tconst log = recordsByEntity.get(entityKeyId) ?? [];\n\t\t\tlog.push(record);\n\t\t\trecordsByEntity.set(entityKeyId, log);\n\t\t\tcurrentStatus.set(entityKeyId, { status: input.toStatus, revision });\n\t\t\tidempotency.set(key, record);\n\t\t\treturn { record, deduped: false };\n\t\t},\n\t\tcurrentStatus(domain: string, entityId: string) {\n\t\t\treturn currentStatus.get(entityKey(domain, entityId));\n\t\t},\n\t\thistory(entityId: string) {\n\t\t\treturn Object.freeze(\n\t\t\t\t[...recordsByEntity.entries()]\n\t\t\t\t\t.filter(([entityKeyId]) => entityKeyId.endsWith(`\\u0000${entityId}`))\n\t\t\t\t\t.flatMap(([, log]) => log),\n\t\t\t);\n\t\t},\n\t\treplay(history) {\n\t\t\tfor (const record of history) {\n\t\t\t\tthis.transition({\n\t\t\t\t\tdomain: record.domain,\n\t\t\t\t\tentityId: record.entityId,\n\t\t\t\t\towner: record.owner,\n\t\t\t\t\tfromStatus: record.fromStatus,\n\t\t\t\t\ttoStatus: record.toStatus,\n\t\t\t\t\toperationId: record.operationId,\n\t\t\t\t\tevidence: record.evidence,\n\t\t\t\t\tpayload: record.payload,\n\t\t\t\t\tat: record.at,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tentities() {\n\t\t\treturn Object.freeze([...new Set([...currentStatus.keys()].map((key) => key.split(\"\\u0000\")[1]!))]);\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"state-store.js","sourceRoot":"","sources":["../../src/profile/state-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Generic transition/evidence/revision store (2.3a) — the domain-agnostic\n * contract base for Goal/Plan/Todo plugins.\n *\n * The store knows NOTHING about goal/plan/todo semantics. It only enforces:\n * - causality: a transition's `fromStatus` must equal the entity's current\n * status (null = initial transition), otherwise an explicit conflict;\n * - idempotency: replaying the same (domain, entityId, operationId, toStatus)\n * returns the existing record and never advances the revision;\n * - evidence: every transition carries structured evidence references;\n * - payload: transitions may carry an optional domain payload (e.g. a goal\n * title) that is validated JSON and part of the replayable record;\n * - replay: the full history rebuilds the identical current state.\n */\nimport type { JsonValue } from \"@agent-forge/ai\";\nimport { t } from \"../core/i18n/index.ts\";\n\nexport interface TransitionEvidenceRefV1 {\n\treadonly kind: string;\n\treadonly ref: string;\n\treadonly digest?: string;\n}\n\nexport interface TransitionRecordV1 {\n\treadonly domain: string;\n\treadonly entityId: string;\n\treadonly owner: string;\n\treadonly fromStatus: string | null;\n\treadonly toStatus: string;\n\treadonly operationId: string;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly payload?: JsonValue;\n\treadonly revision: number;\n\treadonly at: number;\n}\n\nexport interface TransitionInputV1 {\n\treadonly domain: string;\n\treadonly entityId: string;\n\treadonly owner: string;\n\treadonly fromStatus: string | null;\n\treadonly toStatus: string;\n\treadonly operationId: string;\n\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\treadonly payload?: JsonValue;\n\treadonly at?: number;\n}\n\nexport interface TransitionResultV1 {\n\treadonly record: TransitionRecordV1;\n\treadonly deduped: boolean;\n}\n\nfunction assertNonEmptyString(value: unknown, label: string): asserts value is string {\n\tif (typeof value !== \"string\" || value.trim().length === 0)\n\t\tthrow new Error(t(\"{label} must be a non-empty string\", { label }));\n}\n\nfunction validateEvidence(value: unknown, label: string): TransitionEvidenceRefV1[] {\n\tif (value === undefined) return [];\n\tif (!Array.isArray(value)) throw new Error(t(\"{label} must be an array\", { label }));\n\treturn value.map((item, index) => {\n\t\tconst depLabel = `${label}[${index}]`;\n\t\tif (item === null || typeof item !== \"object\" || Array.isArray(item)) {\n\t\t\tthrow new Error(t(\"{label} must be a plain object\", { label: depLabel }));\n\t\t}\n\t\tconst record = item as Record<string, unknown>;\n\t\tassertNonEmptyString(record.kind, `${depLabel}.kind`);\n\t\tassertNonEmptyString(record.ref, `${depLabel}.ref`);\n\t\tif (record.digest !== undefined) assertNonEmptyString(record.digest, `${depLabel}.digest`);\n\t\treturn Object.freeze({\n\t\t\tkind: record.kind,\n\t\t\tref: record.ref,\n\t\t\t...(record.digest === undefined ? {} : { digest: record.digest }),\n\t\t});\n\t});\n}\n\nfunction validatePayload(value: unknown, label: string): JsonValue | undefined {\n\tif (value === undefined) return undefined;\n\tconst seen = new Set<object>();\n\tconst check = (node: unknown): void => {\n\t\tif (node === null || typeof node === \"string\" || typeof node === \"boolean\") return;\n\t\tif (typeof node === \"number\") {\n\t\t\tif (!Number.isFinite(node))\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"{label} must be JSON-safe: {node} is not a finite number\", { label, node: String(node) }),\n\t\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (typeof node === \"object\") {\n\t\t\tif (seen.has(node)) throw new Error(t(\"{label} must be JSON-safe: circular reference\", { label }));\n\t\t\tseen.add(node);\n\t\t\tif (Array.isArray(node)) {\n\t\t\t\tfor (const item of node) check(item);\n\t\t\t} else {\n\t\t\t\tconst proto = Object.getPrototypeOf(node) as unknown;\n\t\t\t\tif (proto !== Object.prototype && proto !== null)\n\t\t\t\t\tthrow new Error(t(\"{label} must be a plain object\", { label }));\n\t\t\t\tfor (const entry of Object.entries(node)) {\n\t\t\t\t\tif (entry[1] === undefined)\n\t\t\t\t\t\tthrow new Error(t(\"{label} must be JSON-safe: {key} is undefined\", { label, key: entry[0] }));\n\t\t\t\t\tcheck(entry[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tseen.delete(node);\n\t\t\treturn;\n\t\t}\n\t\tthrow new Error(t(\"{label} must be JSON-safe: unsupported value of type {type}\", { label, type: typeof node }));\n\t};\n\tcheck(value);\n\treturn JSON.parse(JSON.stringify(value)) as JsonValue;\n}\n\nexport interface TransitionStoreV1 {\n\ttransition(input: TransitionInputV1): TransitionResultV1;\n\tcurrentStatus(domain: string, entityId: string): { readonly status: string; readonly revision: number } | undefined;\n\thistory(entityId: string): readonly TransitionRecordV1[];\n\t/** Replays a history into a fresh store; the rebuilt state must be identical. */\n\treplay(history: readonly TransitionRecordV1[]): void;\n\tentities(): readonly string[];\n}\n\nexport function createTransitionStore(options: { readonly now?: () => number } = {}): TransitionStoreV1 {\n\tconst now = options.now ?? (() => Date.now());\n\tconst recordsByEntity = new Map<string, TransitionRecordV1[]>();\n\tconst idempotency = new Map<string, TransitionRecordV1>();\n\tconst currentStatus = new Map<string, { status: string; revision: number }>();\n\tconst revisions = new Map<string, number>();\n\n\tconst entityKey = (domain: string, entityId: string): string => `${domain}\\u0000${entityId}`;\n\n\treturn {\n\t\ttransition(input) {\n\t\t\tassertNonEmptyString(input.domain, \"Transition domain\");\n\t\t\tassertNonEmptyString(input.entityId, \"Transition entityId\");\n\t\t\tassertNonEmptyString(input.owner, \"Transition owner\");\n\t\t\tassertNonEmptyString(input.operationId, \"Transition operationId\");\n\t\t\tassertNonEmptyString(input.toStatus, \"Transition toStatus\");\n\t\t\tconst evidence = validateEvidence(input.evidence, \"Transition evidence\");\n\t\t\tconst payload = validatePayload(input.payload, \"Transition payload\");\n\t\t\tconst key = `${entityKey(input.domain, input.entityId)}\\u0000${input.operationId}\\u0000${input.toStatus}`;\n\n\t\t\tconst existing = idempotency.get(key);\n\t\t\tif (existing) return { record: existing, deduped: true };\n\n\t\t\tconst entityKeyId = entityKey(input.domain, input.entityId);\n\t\t\tconst current = currentStatus.get(entityKeyId);\n\t\t\tconst fromStatus = input.fromStatus;\n\t\t\tif ((current?.status ?? null) !== fromStatus) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Transition conflict: expected fromStatus {from}, got {to}\", {\n\t\t\t\t\t\tfrom: JSON.stringify(current?.status ?? null),\n\t\t\t\t\t\tto: JSON.stringify(fromStatus),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst revision = (revisions.get(entityKeyId) ?? 0) + 1;\n\t\t\trevisions.set(entityKeyId, revision);\n\t\t\tconst record: TransitionRecordV1 = Object.freeze({\n\t\t\t\tdomain: input.domain,\n\t\t\t\tentityId: input.entityId,\n\t\t\t\towner: input.owner,\n\t\t\t\tfromStatus,\n\t\t\t\ttoStatus: input.toStatus,\n\t\t\t\toperationId: input.operationId,\n\t\t\t\tevidence: Object.freeze(evidence),\n\t\t\t\t...(payload === undefined ? {} : { payload }),\n\t\t\t\trevision,\n\t\t\t\tat: input.at ?? now(),\n\t\t\t});\n\t\t\tconst log = recordsByEntity.get(entityKeyId) ?? [];\n\t\t\tlog.push(record);\n\t\t\trecordsByEntity.set(entityKeyId, log);\n\t\t\tcurrentStatus.set(entityKeyId, { status: input.toStatus, revision });\n\t\t\tidempotency.set(key, record);\n\t\t\treturn { record, deduped: false };\n\t\t},\n\t\tcurrentStatus(domain: string, entityId: string) {\n\t\t\treturn currentStatus.get(entityKey(domain, entityId));\n\t\t},\n\t\thistory(entityId: string) {\n\t\t\treturn Object.freeze(\n\t\t\t\t[...recordsByEntity.entries()]\n\t\t\t\t\t.filter(([entityKeyId]) => entityKeyId.endsWith(`\\u0000${entityId}`))\n\t\t\t\t\t.flatMap(([, log]) => log),\n\t\t\t);\n\t\t},\n\t\treplay(history) {\n\t\t\tfor (const record of history) {\n\t\t\t\tthis.transition({\n\t\t\t\t\tdomain: record.domain,\n\t\t\t\t\tentityId: record.entityId,\n\t\t\t\t\towner: record.owner,\n\t\t\t\t\tfromStatus: record.fromStatus,\n\t\t\t\t\ttoStatus: record.toStatus,\n\t\t\t\t\toperationId: record.operationId,\n\t\t\t\t\tevidence: record.evidence,\n\t\t\t\t\tpayload: record.payload,\n\t\t\t\t\tat: record.at,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tentities() {\n\t\t\treturn Object.freeze([...new Set([...currentStatus.keys()].map((key) => key.split(\"\\u0000\")[1]!))]);\n\t\t},\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"todo-plugin.d.ts","sourceRoot":"","sources":["../../src/profile/todo-plugin.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEnF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,aAAa,GAAG,WAAW,GAAG,WAAW,CAAC;AAE9E,MAAM,WAAW,MAAM;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC5B,UAAU,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IACzG,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC1F,8FAA8F;IAC9F,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC5G,QAAQ,CACP,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,SAAS,uBAAuB,EAAE,EAC7C,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GACzC,MAAM,CAAC;IACV,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/D,gDAAgD;IAChD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC3F,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACvD;AAyBD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAA;CAAE,GAAG,YAAY,CAuInG","sourcesContent":["/**\n * Todo plugin (2.3d) — Todo content lifecycle with cancellation and restart\n * over the 2.3a transition store.\n *\n * Status graph: null → open → in_progress → completed; open/in_progress →\n * cancelled; cancelled → open (restart). Content updates rewrite the payload\n * in place while the todo is open/in_progress, and every terminal transition\n * stays replayable from the ledger. The plugin holds NO shadow state —\n * content and status are always derived from the transition history.\n */\nimport type { JsonValue } from \"@agent-forge/ai\";\nimport type { TransitionEvidenceRefV1, TransitionStoreV1 } from \"./state-store.ts\";\n\nexport type TodoStatusV1 = \"open\" | \"in_progress\" | \"completed\" | \"cancelled\";\n\nexport interface TodoV1 {\n\treadonly todoId: string;\n\treadonly owner: string;\n\treadonly content: string;\n\treadonly status: TodoStatusV1;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly revision: number;\n}\n\nexport interface TodoPluginV1 {\n\tcreateTodo(input: { readonly todoId: string; readonly owner: string; readonly content: string }): TodoV1;\n\tstart(todoId: string, owner: string, options?: { readonly operationId?: string }): TodoV1;\n\t/** Rewrites the content while open/in_progress; the ledger keeps every version replayable. */\n\tupdate(todoId: string, owner: string, content: string, options?: { readonly operationId?: string }): TodoV1;\n\tcomplete(\n\t\ttodoId: string,\n\t\towner: string,\n\t\tevidence?: readonly TransitionEvidenceRefV1[],\n\t\toptions?: { readonly operationId?: string },\n\t): TodoV1;\n\tcancel(todoId: string, owner: string, reason?: string): TodoV1;\n\t/** Restarts a cancelled todo back into open. */\n\treopen(todoId: string, owner: string, options?: { readonly operationId?: string }): TodoV1;\n\tget(todoId: string, owner: string): TodoV1 | undefined;\n}\n\ninterface TodoPayloadV1 {\n\treadonly content: string;\n\treadonly cancelReason?: string;\n}\n\n/** FNV-1a 32-bit — a short deterministic operationId suffix for content updates. */\nfunction contentHash(content: string): string {\n\tlet hash = 0x811c9dc5;\n\tfor (let index = 0; index < content.length; index += 1) {\n\t\thash ^= content.charCodeAt(index);\n\t\thash = Math.imul(hash, 0x01000193);\n\t}\n\treturn (hash >>> 0).toString(36);\n}\n\nfunction todoPayloadOf(record: { readonly payload?: unknown }): Partial<TodoPayloadV1> | undefined {\n\tconst payload = record.payload;\n\tif (payload !== null && typeof payload === \"object\" && !Array.isArray(payload)) {\n\t\treturn payload as Partial<TodoPayloadV1>;\n\t}\n\treturn undefined;\n}\n\nexport function createTodoPlugin(options: { readonly transitions: TransitionStoreV1 }): TodoPluginV1 {\n\tconst transitions = options.transitions;\n\n\tconst todoHistory = (todoId: string, owner: string) =>\n\t\ttransitions.history(todoId).filter((record) => record.domain === \"todo\" && record.owner === owner);\n\n\tconst current = (todoId: string, owner: string): { status: TodoStatusV1; revision: number } | undefined => {\n\t\tconst state = transitions.currentStatus(\"todo\", todoId);\n\t\tif (state === undefined || todoHistory(todoId, owner).length === 0) return undefined;\n\t\treturn { status: state.status as TodoStatusV1, revision: state.revision };\n\t};\n\n\tconst todoGet = (todoId: string, owner: string): TodoV1 | undefined => {\n\t\tconst state = current(todoId, owner);\n\t\tif (!state) return undefined;\n\t\tconst history = todoHistory(todoId, owner);\n\t\tconst content = [...history]\n\t\t\t.reverse()\n\t\t\t.map((record) => todoPayloadOf(record)?.content)\n\t\t\t.find((value): value is string => typeof value === \"string\");\n\t\tconst lastEvidence = [...history].reverse().find((record) => record.evidence.length > 0)?.evidence ?? [];\n\t\treturn {\n\t\t\ttodoId,\n\t\t\towner,\n\t\t\t// v8 ignore next -- createTodo 恒写入 content payload,标题扫描必命中\n\t\t\tcontent: content ?? \"\",\n\t\t\tstatus: state.status,\n\t\t\tevidence: lastEvidence,\n\t\t\trevision: state.revision,\n\t\t};\n\t};\n\n\t/** A retried transition with an already-applied operationId returns the existing state instead of conflicting. */\n\tconst replayedTodo = (\n\t\ttodoId: string,\n\t\towner: string,\n\t\ttoStatus: TodoStatusV1,\n\t\toperationId?: string,\n\t): TodoV1 | undefined => {\n\t\tif (!operationId) return undefined;\n\t\tconst applied = todoHistory(todoId, owner).some(\n\t\t\t(record) => record.toStatus === toStatus && record.operationId === operationId,\n\t\t);\n\t\treturn applied ? todoGet(todoId, owner) : undefined;\n\t};\n\n\tconst transitionTodo = (\n\t\ttodoId: string,\n\t\towner: string,\n\t\tfromStatus: TodoStatusV1 | null,\n\t\ttoStatus: TodoStatusV1,\n\t\ttodoOptions: {\n\t\t\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\t\t\treadonly payload?: TodoPayloadV1;\n\t\t\treadonly operationId?: string;\n\t\t},\n\t): TodoV1 => {\n\t\ttransitions.transition({\n\t\t\tdomain: \"todo\",\n\t\t\tentityId: todoId,\n\t\t\towner,\n\t\t\tfromStatus,\n\t\t\ttoStatus,\n\t\t\toperationId: todoOptions.operationId ?? `${toStatus}:${todoId}`,\n\t\t\tevidence: todoOptions.evidence,\n\t\t\tpayload: todoOptions.payload as JsonValue | undefined,\n\t\t});\n\t\treturn todoGet(todoId, owner)!;\n\t};\n\n\tconst requireStatus = (todoId: string, owner: string, allowed: readonly TodoStatusV1[]): TodoV1 => {\n\t\tconst todo = todoGet(todoId, owner);\n\t\tif (!todo || !allowed.includes(todo.status)) {\n\t\t\tthrow new Error(`Todo ${todoId} must be ${allowed.join(\"/\")} (current: ${todo?.status ?? \"missing\"})`);\n\t\t}\n\t\treturn todo;\n\t};\n\n\treturn {\n\t\tcreateTodo({ todoId, owner, content }) {\n\t\t\tif (content.trim().length === 0) throw new Error(\"Todo content must be a non-empty string\");\n\t\t\treturn transitionTodo(todoId, owner, null, \"open\", {\n\t\t\t\tpayload: { content },\n\t\t\t\toperationId: `create:${todoId}`,\n\t\t\t});\n\t\t},\n\t\tstart(todoId, owner, startOptions) {\n\t\t\tconst replayed = replayedTodo(todoId, owner, \"in_progress\", startOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\trequireStatus(todoId, owner, [\"open\"]);\n\t\t\treturn transitionTodo(todoId, owner, \"open\", \"in_progress\", { operationId: startOptions?.operationId });\n\t\t},\n\t\tupdate(todoId, owner, content, updateOptions) {\n\t\t\tif (content.trim().length === 0) throw new Error(\"Todo content must be a non-empty string\");\n\t\t\tconst replayed = replayedTodo(\n\t\t\t\ttodoId,\n\t\t\t\towner,\n\t\t\t\ttodoGet(todoId, owner)?.status ?? \"open\",\n\t\t\t\tupdateOptions?.operationId,\n\t\t\t);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst todo = requireStatus(todoId, owner, [\"open\", \"in_progress\"]);\n\t\t\treturn transitionTodo(todoId, owner, todo.status, todo.status, {\n\t\t\t\tpayload: { content },\n\t\t\t\toperationId: updateOptions?.operationId ?? `update:${todoId}:${contentHash(content)}`,\n\t\t\t});\n\t\t},\n\t\tcomplete(todoId, owner, evidence, completeOptions) {\n\t\t\tconst replayed = replayedTodo(todoId, owner, \"completed\", completeOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\trequireStatus(todoId, owner, [\"in_progress\"]);\n\t\t\treturn transitionTodo(todoId, owner, \"in_progress\", \"completed\", {\n\t\t\t\tevidence: evidence ?? [],\n\t\t\t\toperationId: completeOptions?.operationId,\n\t\t\t});\n\t\t},\n\t\tcancel(todoId, owner, reason) {\n\t\t\tconst todo = requireStatus(todoId, owner, [\"open\", \"in_progress\"]);\n\t\t\tif (reason !== undefined && reason.trim().length === 0) {\n\t\t\t\tthrow new Error(\"Todo cancel reason must be a non-empty string when provided\");\n\t\t\t}\n\t\t\treturn transitionTodo(todoId, owner, todo.status, \"cancelled\", {\n\t\t\t\t...(reason === undefined ? {} : { payload: { content: todo.content, cancelReason: reason } }),\n\t\t\t});\n\t\t},\n\t\treopen(todoId, owner, reopenOptions) {\n\t\t\tconst replayed = replayedTodo(todoId, owner, \"open\", reopenOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\trequireStatus(todoId, owner, [\"cancelled\"]);\n\t\t\treturn transitionTodo(todoId, owner, \"cancelled\", \"open\", { operationId: reopenOptions?.operationId });\n\t\t},\n\t\tget(todoId, owner) {\n\t\t\treturn todoGet(todoId, owner);\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"todo-plugin.d.ts","sourceRoot":"","sources":["../../src/profile/todo-plugin.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEnF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,aAAa,GAAG,WAAW,GAAG,WAAW,CAAC;AAE9E,MAAM,WAAW,MAAM;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC5B,UAAU,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IACzG,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC1F,8FAA8F;IAC9F,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC5G,QAAQ,CACP,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,SAAS,uBAAuB,EAAE,EAC7C,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GACzC,MAAM,CAAC;IACV,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/D,gDAAgD;IAChD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC3F,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACvD;AAyBD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAA;CAAE,GAAG,YAAY,CA6InG","sourcesContent":["/**\n * Todo plugin (2.3d) — Todo content lifecycle with cancellation and restart\n * over the 2.3a transition store.\n *\n * Status graph: null → open → in_progress → completed; open/in_progress →\n * cancelled; cancelled → open (restart). Content updates rewrite the payload\n * in place while the todo is open/in_progress, and every terminal transition\n * stays replayable from the ledger. The plugin holds NO shadow state —\n * content and status are always derived from the transition history.\n */\nimport type { JsonValue } from \"@agent-forge/ai\";\nimport { t } from \"../core/i18n/index.ts\";\nimport type { TransitionEvidenceRefV1, TransitionStoreV1 } from \"./state-store.ts\";\n\nexport type TodoStatusV1 = \"open\" | \"in_progress\" | \"completed\" | \"cancelled\";\n\nexport interface TodoV1 {\n\treadonly todoId: string;\n\treadonly owner: string;\n\treadonly content: string;\n\treadonly status: TodoStatusV1;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly revision: number;\n}\n\nexport interface TodoPluginV1 {\n\tcreateTodo(input: { readonly todoId: string; readonly owner: string; readonly content: string }): TodoV1;\n\tstart(todoId: string, owner: string, options?: { readonly operationId?: string }): TodoV1;\n\t/** Rewrites the content while open/in_progress; the ledger keeps every version replayable. */\n\tupdate(todoId: string, owner: string, content: string, options?: { readonly operationId?: string }): TodoV1;\n\tcomplete(\n\t\ttodoId: string,\n\t\towner: string,\n\t\tevidence?: readonly TransitionEvidenceRefV1[],\n\t\toptions?: { readonly operationId?: string },\n\t): TodoV1;\n\tcancel(todoId: string, owner: string, reason?: string): TodoV1;\n\t/** Restarts a cancelled todo back into open. */\n\treopen(todoId: string, owner: string, options?: { readonly operationId?: string }): TodoV1;\n\tget(todoId: string, owner: string): TodoV1 | undefined;\n}\n\ninterface TodoPayloadV1 {\n\treadonly content: string;\n\treadonly cancelReason?: string;\n}\n\n/** FNV-1a 32-bit — a short deterministic operationId suffix for content updates. */\nfunction contentHash(content: string): string {\n\tlet hash = 0x811c9dc5;\n\tfor (let index = 0; index < content.length; index += 1) {\n\t\thash ^= content.charCodeAt(index);\n\t\thash = Math.imul(hash, 0x01000193);\n\t}\n\treturn (hash >>> 0).toString(36);\n}\n\nfunction todoPayloadOf(record: { readonly payload?: unknown }): Partial<TodoPayloadV1> | undefined {\n\tconst payload = record.payload;\n\tif (payload !== null && typeof payload === \"object\" && !Array.isArray(payload)) {\n\t\treturn payload as Partial<TodoPayloadV1>;\n\t}\n\treturn undefined;\n}\n\nexport function createTodoPlugin(options: { readonly transitions: TransitionStoreV1 }): TodoPluginV1 {\n\tconst transitions = options.transitions;\n\n\tconst todoHistory = (todoId: string, owner: string) =>\n\t\ttransitions.history(todoId).filter((record) => record.domain === \"todo\" && record.owner === owner);\n\n\tconst current = (todoId: string, owner: string): { status: TodoStatusV1; revision: number } | undefined => {\n\t\tconst state = transitions.currentStatus(\"todo\", todoId);\n\t\tif (state === undefined || todoHistory(todoId, owner).length === 0) return undefined;\n\t\treturn { status: state.status as TodoStatusV1, revision: state.revision };\n\t};\n\n\tconst todoGet = (todoId: string, owner: string): TodoV1 | undefined => {\n\t\tconst state = current(todoId, owner);\n\t\tif (!state) return undefined;\n\t\tconst history = todoHistory(todoId, owner);\n\t\tconst content = [...history]\n\t\t\t.reverse()\n\t\t\t.map((record) => todoPayloadOf(record)?.content)\n\t\t\t.find((value): value is string => typeof value === \"string\");\n\t\tconst lastEvidence = [...history].reverse().find((record) => record.evidence.length > 0)?.evidence ?? [];\n\t\treturn {\n\t\t\ttodoId,\n\t\t\towner,\n\t\t\t// v8 ignore next -- createTodo 恒写入 content payload,标题扫描必命中\n\t\t\tcontent: content ?? \"\",\n\t\t\tstatus: state.status,\n\t\t\tevidence: lastEvidence,\n\t\t\trevision: state.revision,\n\t\t};\n\t};\n\n\t/** A retried transition with an already-applied operationId returns the existing state instead of conflicting. */\n\tconst replayedTodo = (\n\t\ttodoId: string,\n\t\towner: string,\n\t\ttoStatus: TodoStatusV1,\n\t\toperationId?: string,\n\t): TodoV1 | undefined => {\n\t\tif (!operationId) return undefined;\n\t\tconst applied = todoHistory(todoId, owner).some(\n\t\t\t(record) => record.toStatus === toStatus && record.operationId === operationId,\n\t\t);\n\t\treturn applied ? todoGet(todoId, owner) : undefined;\n\t};\n\n\tconst transitionTodo = (\n\t\ttodoId: string,\n\t\towner: string,\n\t\tfromStatus: TodoStatusV1 | null,\n\t\ttoStatus: TodoStatusV1,\n\t\ttodoOptions: {\n\t\t\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\t\t\treadonly payload?: TodoPayloadV1;\n\t\t\treadonly operationId?: string;\n\t\t},\n\t): TodoV1 => {\n\t\ttransitions.transition({\n\t\t\tdomain: \"todo\",\n\t\t\tentityId: todoId,\n\t\t\towner,\n\t\t\tfromStatus,\n\t\t\ttoStatus,\n\t\t\toperationId: todoOptions.operationId ?? `${toStatus}:${todoId}`,\n\t\t\tevidence: todoOptions.evidence,\n\t\t\tpayload: todoOptions.payload as JsonValue | undefined,\n\t\t});\n\t\treturn todoGet(todoId, owner)!;\n\t};\n\n\tconst requireStatus = (todoId: string, owner: string, allowed: readonly TodoStatusV1[]): TodoV1 => {\n\t\tconst todo = todoGet(todoId, owner);\n\t\tif (!todo || !allowed.includes(todo.status)) {\n\t\t\tthrow new Error(\n\t\t\t\tt(\"Todo {todoId} must be {allowed} (current: {status})\", {\n\t\t\t\t\ttodoId,\n\t\t\t\t\tallowed: allowed.join(\"/\"),\n\t\t\t\t\tstatus: todo?.status ?? \"missing\",\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn todo;\n\t};\n\n\treturn {\n\t\tcreateTodo({ todoId, owner, content }) {\n\t\t\tif (content.trim().length === 0) throw new Error(t(\"Todo content must be a non-empty string\"));\n\t\t\treturn transitionTodo(todoId, owner, null, \"open\", {\n\t\t\t\tpayload: { content },\n\t\t\t\toperationId: `create:${todoId}`,\n\t\t\t});\n\t\t},\n\t\tstart(todoId, owner, startOptions) {\n\t\t\tconst replayed = replayedTodo(todoId, owner, \"in_progress\", startOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\trequireStatus(todoId, owner, [\"open\"]);\n\t\t\treturn transitionTodo(todoId, owner, \"open\", \"in_progress\", { operationId: startOptions?.operationId });\n\t\t},\n\t\tupdate(todoId, owner, content, updateOptions) {\n\t\t\tif (content.trim().length === 0) throw new Error(t(\"Todo content must be a non-empty string\"));\n\t\t\tconst replayed = replayedTodo(\n\t\t\t\ttodoId,\n\t\t\t\towner,\n\t\t\t\ttodoGet(todoId, owner)?.status ?? \"open\",\n\t\t\t\tupdateOptions?.operationId,\n\t\t\t);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst todo = requireStatus(todoId, owner, [\"open\", \"in_progress\"]);\n\t\t\treturn transitionTodo(todoId, owner, todo.status, todo.status, {\n\t\t\t\tpayload: { content },\n\t\t\t\toperationId: updateOptions?.operationId ?? `update:${todoId}:${contentHash(content)}`,\n\t\t\t});\n\t\t},\n\t\tcomplete(todoId, owner, evidence, completeOptions) {\n\t\t\tconst replayed = replayedTodo(todoId, owner, \"completed\", completeOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\trequireStatus(todoId, owner, [\"in_progress\"]);\n\t\t\treturn transitionTodo(todoId, owner, \"in_progress\", \"completed\", {\n\t\t\t\tevidence: evidence ?? [],\n\t\t\t\toperationId: completeOptions?.operationId,\n\t\t\t});\n\t\t},\n\t\tcancel(todoId, owner, reason) {\n\t\t\tconst todo = requireStatus(todoId, owner, [\"open\", \"in_progress\"]);\n\t\t\tif (reason !== undefined && reason.trim().length === 0) {\n\t\t\t\tthrow new Error(t(\"Todo cancel reason must be a non-empty string when provided\"));\n\t\t\t}\n\t\t\treturn transitionTodo(todoId, owner, todo.status, \"cancelled\", {\n\t\t\t\t...(reason === undefined ? {} : { payload: { content: todo.content, cancelReason: reason } }),\n\t\t\t});\n\t\t},\n\t\treopen(todoId, owner, reopenOptions) {\n\t\t\tconst replayed = replayedTodo(todoId, owner, \"open\", reopenOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\trequireStatus(todoId, owner, [\"cancelled\"]);\n\t\t\treturn transitionTodo(todoId, owner, \"cancelled\", \"open\", { operationId: reopenOptions?.operationId });\n\t\t},\n\t\tget(todoId, owner) {\n\t\t\treturn todoGet(todoId, owner);\n\t\t},\n\t};\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { t } from "../core/i18n/index.js";
1
2
  /** FNV-1a 32-bit — a short deterministic operationId suffix for content updates. */
2
3
  function contentHash(content) {
3
4
  let hash = 0x811c9dc5;
@@ -66,14 +67,18 @@ export function createTodoPlugin(options) {
66
67
  const requireStatus = (todoId, owner, allowed) => {
67
68
  const todo = todoGet(todoId, owner);
68
69
  if (!todo || !allowed.includes(todo.status)) {
69
- throw new Error(`Todo ${todoId} must be ${allowed.join("/")} (current: ${todo?.status ?? "missing"})`);
70
+ throw new Error(t("Todo {todoId} must be {allowed} (current: {status})", {
71
+ todoId,
72
+ allowed: allowed.join("/"),
73
+ status: todo?.status ?? "missing",
74
+ }));
70
75
  }
71
76
  return todo;
72
77
  };
73
78
  return {
74
79
  createTodo({ todoId, owner, content }) {
75
80
  if (content.trim().length === 0)
76
- throw new Error("Todo content must be a non-empty string");
81
+ throw new Error(t("Todo content must be a non-empty string"));
77
82
  return transitionTodo(todoId, owner, null, "open", {
78
83
  payload: { content },
79
84
  operationId: `create:${todoId}`,
@@ -88,7 +93,7 @@ export function createTodoPlugin(options) {
88
93
  },
89
94
  update(todoId, owner, content, updateOptions) {
90
95
  if (content.trim().length === 0)
91
- throw new Error("Todo content must be a non-empty string");
96
+ throw new Error(t("Todo content must be a non-empty string"));
92
97
  const replayed = replayedTodo(todoId, owner, todoGet(todoId, owner)?.status ?? "open", updateOptions?.operationId);
93
98
  if (replayed)
94
99
  return replayed;
@@ -111,7 +116,7 @@ export function createTodoPlugin(options) {
111
116
  cancel(todoId, owner, reason) {
112
117
  const todo = requireStatus(todoId, owner, ["open", "in_progress"]);
113
118
  if (reason !== undefined && reason.trim().length === 0) {
114
- throw new Error("Todo cancel reason must be a non-empty string when provided");
119
+ throw new Error(t("Todo cancel reason must be a non-empty string when provided"));
115
120
  }
116
121
  return transitionTodo(todoId, owner, todo.status, "cancelled", {
117
122
  ...(reason === undefined ? {} : { payload: { content: todo.content, cancelReason: reason } }),
@@ -1 +1 @@
1
- {"version":3,"file":"todo-plugin.js","sourceRoot":"","sources":["../../src/profile/todo-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Todo plugin (2.3d) — Todo content lifecycle with cancellation and restart\n * over the 2.3a transition store.\n *\n * Status graph: null → open → in_progress → completed; open/in_progress →\n * cancelled; cancelled → open (restart). Content updates rewrite the payload\n * in place while the todo is open/in_progress, and every terminal transition\n * stays replayable from the ledger. The plugin holds NO shadow state —\n * content and status are always derived from the transition history.\n */\nimport type { JsonValue } from \"@agent-forge/ai\";\nimport type { TransitionEvidenceRefV1, TransitionStoreV1 } from \"./state-store.ts\";\n\nexport type TodoStatusV1 = \"open\" | \"in_progress\" | \"completed\" | \"cancelled\";\n\nexport interface TodoV1 {\n\treadonly todoId: string;\n\treadonly owner: string;\n\treadonly content: string;\n\treadonly status: TodoStatusV1;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly revision: number;\n}\n\nexport interface TodoPluginV1 {\n\tcreateTodo(input: { readonly todoId: string; readonly owner: string; readonly content: string }): TodoV1;\n\tstart(todoId: string, owner: string, options?: { readonly operationId?: string }): TodoV1;\n\t/** Rewrites the content while open/in_progress; the ledger keeps every version replayable. */\n\tupdate(todoId: string, owner: string, content: string, options?: { readonly operationId?: string }): TodoV1;\n\tcomplete(\n\t\ttodoId: string,\n\t\towner: string,\n\t\tevidence?: readonly TransitionEvidenceRefV1[],\n\t\toptions?: { readonly operationId?: string },\n\t): TodoV1;\n\tcancel(todoId: string, owner: string, reason?: string): TodoV1;\n\t/** Restarts a cancelled todo back into open. */\n\treopen(todoId: string, owner: string, options?: { readonly operationId?: string }): TodoV1;\n\tget(todoId: string, owner: string): TodoV1 | undefined;\n}\n\ninterface TodoPayloadV1 {\n\treadonly content: string;\n\treadonly cancelReason?: string;\n}\n\n/** FNV-1a 32-bit — a short deterministic operationId suffix for content updates. */\nfunction contentHash(content: string): string {\n\tlet hash = 0x811c9dc5;\n\tfor (let index = 0; index < content.length; index += 1) {\n\t\thash ^= content.charCodeAt(index);\n\t\thash = Math.imul(hash, 0x01000193);\n\t}\n\treturn (hash >>> 0).toString(36);\n}\n\nfunction todoPayloadOf(record: { readonly payload?: unknown }): Partial<TodoPayloadV1> | undefined {\n\tconst payload = record.payload;\n\tif (payload !== null && typeof payload === \"object\" && !Array.isArray(payload)) {\n\t\treturn payload as Partial<TodoPayloadV1>;\n\t}\n\treturn undefined;\n}\n\nexport function createTodoPlugin(options: { readonly transitions: TransitionStoreV1 }): TodoPluginV1 {\n\tconst transitions = options.transitions;\n\n\tconst todoHistory = (todoId: string, owner: string) =>\n\t\ttransitions.history(todoId).filter((record) => record.domain === \"todo\" && record.owner === owner);\n\n\tconst current = (todoId: string, owner: string): { status: TodoStatusV1; revision: number } | undefined => {\n\t\tconst state = transitions.currentStatus(\"todo\", todoId);\n\t\tif (state === undefined || todoHistory(todoId, owner).length === 0) return undefined;\n\t\treturn { status: state.status as TodoStatusV1, revision: state.revision };\n\t};\n\n\tconst todoGet = (todoId: string, owner: string): TodoV1 | undefined => {\n\t\tconst state = current(todoId, owner);\n\t\tif (!state) return undefined;\n\t\tconst history = todoHistory(todoId, owner);\n\t\tconst content = [...history]\n\t\t\t.reverse()\n\t\t\t.map((record) => todoPayloadOf(record)?.content)\n\t\t\t.find((value): value is string => typeof value === \"string\");\n\t\tconst lastEvidence = [...history].reverse().find((record) => record.evidence.length > 0)?.evidence ?? [];\n\t\treturn {\n\t\t\ttodoId,\n\t\t\towner,\n\t\t\t// v8 ignore next -- createTodo 恒写入 content payload,标题扫描必命中\n\t\t\tcontent: content ?? \"\",\n\t\t\tstatus: state.status,\n\t\t\tevidence: lastEvidence,\n\t\t\trevision: state.revision,\n\t\t};\n\t};\n\n\t/** A retried transition with an already-applied operationId returns the existing state instead of conflicting. */\n\tconst replayedTodo = (\n\t\ttodoId: string,\n\t\towner: string,\n\t\ttoStatus: TodoStatusV1,\n\t\toperationId?: string,\n\t): TodoV1 | undefined => {\n\t\tif (!operationId) return undefined;\n\t\tconst applied = todoHistory(todoId, owner).some(\n\t\t\t(record) => record.toStatus === toStatus && record.operationId === operationId,\n\t\t);\n\t\treturn applied ? todoGet(todoId, owner) : undefined;\n\t};\n\n\tconst transitionTodo = (\n\t\ttodoId: string,\n\t\towner: string,\n\t\tfromStatus: TodoStatusV1 | null,\n\t\ttoStatus: TodoStatusV1,\n\t\ttodoOptions: {\n\t\t\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\t\t\treadonly payload?: TodoPayloadV1;\n\t\t\treadonly operationId?: string;\n\t\t},\n\t): TodoV1 => {\n\t\ttransitions.transition({\n\t\t\tdomain: \"todo\",\n\t\t\tentityId: todoId,\n\t\t\towner,\n\t\t\tfromStatus,\n\t\t\ttoStatus,\n\t\t\toperationId: todoOptions.operationId ?? `${toStatus}:${todoId}`,\n\t\t\tevidence: todoOptions.evidence,\n\t\t\tpayload: todoOptions.payload as JsonValue | undefined,\n\t\t});\n\t\treturn todoGet(todoId, owner)!;\n\t};\n\n\tconst requireStatus = (todoId: string, owner: string, allowed: readonly TodoStatusV1[]): TodoV1 => {\n\t\tconst todo = todoGet(todoId, owner);\n\t\tif (!todo || !allowed.includes(todo.status)) {\n\t\t\tthrow new Error(`Todo ${todoId} must be ${allowed.join(\"/\")} (current: ${todo?.status ?? \"missing\"})`);\n\t\t}\n\t\treturn todo;\n\t};\n\n\treturn {\n\t\tcreateTodo({ todoId, owner, content }) {\n\t\t\tif (content.trim().length === 0) throw new Error(\"Todo content must be a non-empty string\");\n\t\t\treturn transitionTodo(todoId, owner, null, \"open\", {\n\t\t\t\tpayload: { content },\n\t\t\t\toperationId: `create:${todoId}`,\n\t\t\t});\n\t\t},\n\t\tstart(todoId, owner, startOptions) {\n\t\t\tconst replayed = replayedTodo(todoId, owner, \"in_progress\", startOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\trequireStatus(todoId, owner, [\"open\"]);\n\t\t\treturn transitionTodo(todoId, owner, \"open\", \"in_progress\", { operationId: startOptions?.operationId });\n\t\t},\n\t\tupdate(todoId, owner, content, updateOptions) {\n\t\t\tif (content.trim().length === 0) throw new Error(\"Todo content must be a non-empty string\");\n\t\t\tconst replayed = replayedTodo(\n\t\t\t\ttodoId,\n\t\t\t\towner,\n\t\t\t\ttodoGet(todoId, owner)?.status ?? \"open\",\n\t\t\t\tupdateOptions?.operationId,\n\t\t\t);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst todo = requireStatus(todoId, owner, [\"open\", \"in_progress\"]);\n\t\t\treturn transitionTodo(todoId, owner, todo.status, todo.status, {\n\t\t\t\tpayload: { content },\n\t\t\t\toperationId: updateOptions?.operationId ?? `update:${todoId}:${contentHash(content)}`,\n\t\t\t});\n\t\t},\n\t\tcomplete(todoId, owner, evidence, completeOptions) {\n\t\t\tconst replayed = replayedTodo(todoId, owner, \"completed\", completeOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\trequireStatus(todoId, owner, [\"in_progress\"]);\n\t\t\treturn transitionTodo(todoId, owner, \"in_progress\", \"completed\", {\n\t\t\t\tevidence: evidence ?? [],\n\t\t\t\toperationId: completeOptions?.operationId,\n\t\t\t});\n\t\t},\n\t\tcancel(todoId, owner, reason) {\n\t\t\tconst todo = requireStatus(todoId, owner, [\"open\", \"in_progress\"]);\n\t\t\tif (reason !== undefined && reason.trim().length === 0) {\n\t\t\t\tthrow new Error(\"Todo cancel reason must be a non-empty string when provided\");\n\t\t\t}\n\t\t\treturn transitionTodo(todoId, owner, todo.status, \"cancelled\", {\n\t\t\t\t...(reason === undefined ? {} : { payload: { content: todo.content, cancelReason: reason } }),\n\t\t\t});\n\t\t},\n\t\treopen(todoId, owner, reopenOptions) {\n\t\t\tconst replayed = replayedTodo(todoId, owner, \"open\", reopenOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\trequireStatus(todoId, owner, [\"cancelled\"]);\n\t\t\treturn transitionTodo(todoId, owner, \"cancelled\", \"open\", { operationId: reopenOptions?.operationId });\n\t\t},\n\t\tget(todoId, owner) {\n\t\t\treturn todoGet(todoId, owner);\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"todo-plugin.js","sourceRoot":"","sources":["../../src/profile/todo-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Todo plugin (2.3d) — Todo content lifecycle with cancellation and restart\n * over the 2.3a transition store.\n *\n * Status graph: null → open → in_progress → completed; open/in_progress →\n * cancelled; cancelled → open (restart). Content updates rewrite the payload\n * in place while the todo is open/in_progress, and every terminal transition\n * stays replayable from the ledger. The plugin holds NO shadow state —\n * content and status are always derived from the transition history.\n */\nimport type { JsonValue } from \"@agent-forge/ai\";\nimport { t } from \"../core/i18n/index.ts\";\nimport type { TransitionEvidenceRefV1, TransitionStoreV1 } from \"./state-store.ts\";\n\nexport type TodoStatusV1 = \"open\" | \"in_progress\" | \"completed\" | \"cancelled\";\n\nexport interface TodoV1 {\n\treadonly todoId: string;\n\treadonly owner: string;\n\treadonly content: string;\n\treadonly status: TodoStatusV1;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly revision: number;\n}\n\nexport interface TodoPluginV1 {\n\tcreateTodo(input: { readonly todoId: string; readonly owner: string; readonly content: string }): TodoV1;\n\tstart(todoId: string, owner: string, options?: { readonly operationId?: string }): TodoV1;\n\t/** Rewrites the content while open/in_progress; the ledger keeps every version replayable. */\n\tupdate(todoId: string, owner: string, content: string, options?: { readonly operationId?: string }): TodoV1;\n\tcomplete(\n\t\ttodoId: string,\n\t\towner: string,\n\t\tevidence?: readonly TransitionEvidenceRefV1[],\n\t\toptions?: { readonly operationId?: string },\n\t): TodoV1;\n\tcancel(todoId: string, owner: string, reason?: string): TodoV1;\n\t/** Restarts a cancelled todo back into open. */\n\treopen(todoId: string, owner: string, options?: { readonly operationId?: string }): TodoV1;\n\tget(todoId: string, owner: string): TodoV1 | undefined;\n}\n\ninterface TodoPayloadV1 {\n\treadonly content: string;\n\treadonly cancelReason?: string;\n}\n\n/** FNV-1a 32-bit — a short deterministic operationId suffix for content updates. */\nfunction contentHash(content: string): string {\n\tlet hash = 0x811c9dc5;\n\tfor (let index = 0; index < content.length; index += 1) {\n\t\thash ^= content.charCodeAt(index);\n\t\thash = Math.imul(hash, 0x01000193);\n\t}\n\treturn (hash >>> 0).toString(36);\n}\n\nfunction todoPayloadOf(record: { readonly payload?: unknown }): Partial<TodoPayloadV1> | undefined {\n\tconst payload = record.payload;\n\tif (payload !== null && typeof payload === \"object\" && !Array.isArray(payload)) {\n\t\treturn payload as Partial<TodoPayloadV1>;\n\t}\n\treturn undefined;\n}\n\nexport function createTodoPlugin(options: { readonly transitions: TransitionStoreV1 }): TodoPluginV1 {\n\tconst transitions = options.transitions;\n\n\tconst todoHistory = (todoId: string, owner: string) =>\n\t\ttransitions.history(todoId).filter((record) => record.domain === \"todo\" && record.owner === owner);\n\n\tconst current = (todoId: string, owner: string): { status: TodoStatusV1; revision: number } | undefined => {\n\t\tconst state = transitions.currentStatus(\"todo\", todoId);\n\t\tif (state === undefined || todoHistory(todoId, owner).length === 0) return undefined;\n\t\treturn { status: state.status as TodoStatusV1, revision: state.revision };\n\t};\n\n\tconst todoGet = (todoId: string, owner: string): TodoV1 | undefined => {\n\t\tconst state = current(todoId, owner);\n\t\tif (!state) return undefined;\n\t\tconst history = todoHistory(todoId, owner);\n\t\tconst content = [...history]\n\t\t\t.reverse()\n\t\t\t.map((record) => todoPayloadOf(record)?.content)\n\t\t\t.find((value): value is string => typeof value === \"string\");\n\t\tconst lastEvidence = [...history].reverse().find((record) => record.evidence.length > 0)?.evidence ?? [];\n\t\treturn {\n\t\t\ttodoId,\n\t\t\towner,\n\t\t\t// v8 ignore next -- createTodo 恒写入 content payload,标题扫描必命中\n\t\t\tcontent: content ?? \"\",\n\t\t\tstatus: state.status,\n\t\t\tevidence: lastEvidence,\n\t\t\trevision: state.revision,\n\t\t};\n\t};\n\n\t/** A retried transition with an already-applied operationId returns the existing state instead of conflicting. */\n\tconst replayedTodo = (\n\t\ttodoId: string,\n\t\towner: string,\n\t\ttoStatus: TodoStatusV1,\n\t\toperationId?: string,\n\t): TodoV1 | undefined => {\n\t\tif (!operationId) return undefined;\n\t\tconst applied = todoHistory(todoId, owner).some(\n\t\t\t(record) => record.toStatus === toStatus && record.operationId === operationId,\n\t\t);\n\t\treturn applied ? todoGet(todoId, owner) : undefined;\n\t};\n\n\tconst transitionTodo = (\n\t\ttodoId: string,\n\t\towner: string,\n\t\tfromStatus: TodoStatusV1 | null,\n\t\ttoStatus: TodoStatusV1,\n\t\ttodoOptions: {\n\t\t\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\t\t\treadonly payload?: TodoPayloadV1;\n\t\t\treadonly operationId?: string;\n\t\t},\n\t): TodoV1 => {\n\t\ttransitions.transition({\n\t\t\tdomain: \"todo\",\n\t\t\tentityId: todoId,\n\t\t\towner,\n\t\t\tfromStatus,\n\t\t\ttoStatus,\n\t\t\toperationId: todoOptions.operationId ?? `${toStatus}:${todoId}`,\n\t\t\tevidence: todoOptions.evidence,\n\t\t\tpayload: todoOptions.payload as JsonValue | undefined,\n\t\t});\n\t\treturn todoGet(todoId, owner)!;\n\t};\n\n\tconst requireStatus = (todoId: string, owner: string, allowed: readonly TodoStatusV1[]): TodoV1 => {\n\t\tconst todo = todoGet(todoId, owner);\n\t\tif (!todo || !allowed.includes(todo.status)) {\n\t\t\tthrow new Error(\n\t\t\t\tt(\"Todo {todoId} must be {allowed} (current: {status})\", {\n\t\t\t\t\ttodoId,\n\t\t\t\t\tallowed: allowed.join(\"/\"),\n\t\t\t\t\tstatus: todo?.status ?? \"missing\",\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn todo;\n\t};\n\n\treturn {\n\t\tcreateTodo({ todoId, owner, content }) {\n\t\t\tif (content.trim().length === 0) throw new Error(t(\"Todo content must be a non-empty string\"));\n\t\t\treturn transitionTodo(todoId, owner, null, \"open\", {\n\t\t\t\tpayload: { content },\n\t\t\t\toperationId: `create:${todoId}`,\n\t\t\t});\n\t\t},\n\t\tstart(todoId, owner, startOptions) {\n\t\t\tconst replayed = replayedTodo(todoId, owner, \"in_progress\", startOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\trequireStatus(todoId, owner, [\"open\"]);\n\t\t\treturn transitionTodo(todoId, owner, \"open\", \"in_progress\", { operationId: startOptions?.operationId });\n\t\t},\n\t\tupdate(todoId, owner, content, updateOptions) {\n\t\t\tif (content.trim().length === 0) throw new Error(t(\"Todo content must be a non-empty string\"));\n\t\t\tconst replayed = replayedTodo(\n\t\t\t\ttodoId,\n\t\t\t\towner,\n\t\t\t\ttodoGet(todoId, owner)?.status ?? \"open\",\n\t\t\t\tupdateOptions?.operationId,\n\t\t\t);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst todo = requireStatus(todoId, owner, [\"open\", \"in_progress\"]);\n\t\t\treturn transitionTodo(todoId, owner, todo.status, todo.status, {\n\t\t\t\tpayload: { content },\n\t\t\t\toperationId: updateOptions?.operationId ?? `update:${todoId}:${contentHash(content)}`,\n\t\t\t});\n\t\t},\n\t\tcomplete(todoId, owner, evidence, completeOptions) {\n\t\t\tconst replayed = replayedTodo(todoId, owner, \"completed\", completeOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\trequireStatus(todoId, owner, [\"in_progress\"]);\n\t\t\treturn transitionTodo(todoId, owner, \"in_progress\", \"completed\", {\n\t\t\t\tevidence: evidence ?? [],\n\t\t\t\toperationId: completeOptions?.operationId,\n\t\t\t});\n\t\t},\n\t\tcancel(todoId, owner, reason) {\n\t\t\tconst todo = requireStatus(todoId, owner, [\"open\", \"in_progress\"]);\n\t\t\tif (reason !== undefined && reason.trim().length === 0) {\n\t\t\t\tthrow new Error(t(\"Todo cancel reason must be a non-empty string when provided\"));\n\t\t\t}\n\t\t\treturn transitionTodo(todoId, owner, todo.status, \"cancelled\", {\n\t\t\t\t...(reason === undefined ? {} : { payload: { content: todo.content, cancelReason: reason } }),\n\t\t\t});\n\t\t},\n\t\treopen(todoId, owner, reopenOptions) {\n\t\t\tconst replayed = replayedTodo(todoId, owner, \"open\", reopenOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\trequireStatus(todoId, owner, [\"cancelled\"]);\n\t\t\treturn transitionTodo(todoId, owner, \"cancelled\", \"open\", { operationId: reopenOptions?.operationId });\n\t\t},\n\t\tget(todoId, owner) {\n\t\t\treturn todoGet(todoId, owner);\n\t\t},\n\t};\n}\n"]}
@@ -54,8 +54,13 @@ export declare const SUITE_SCHEMA_VERSION = 1;
54
54
  * 5 receive the upgrade-proposal diagnostic and adopt via `--suite-reset`.
55
55
  */
56
56
  export declare const FACTORY_CONTENTS_VERSION = 6;
57
- /** Factory default suite used when no suite is configured anywhere (设计 §9). */
58
- export declare const DEFAULT_SUITE_ID = "assistant";
57
+ /**
58
+ * Factory default suite used when no suite is configured anywhere (设计 §9).
59
+ * 2026-10-02 user ruling: the product is a coding agent, so the factory
60
+ * default flipped from "assistant" to "coding"; assistant stays as the
61
+ * explicit-switch fallback suite.
62
+ */
63
+ export declare const DEFAULT_SUITE_ID = "coding";
59
64
  /** Suite ids become directory names: lowercase letters, digits, hyphens (设计 §9). */
60
65
  export declare const SUITE_ID_MAX_LENGTH = 64;
61
66
  /** The single unrestricted tool surface shared by both builtin suites (设计 §5/§6). */
@@ -76,15 +81,17 @@ export declare const BUILTIN_SUITE_TOOLS: readonly string[];
76
81
  */
77
82
  export declare const BUILTIN_SUITE_CAPABILITIES: readonly string[];
78
83
  export type SuiteMemoryStrategy = "assistant" | "code";
79
- export type SuiteOrientation = "assistant" | "coding";
84
+ export type SuiteOrientation = "assistant" | "coding" | "custom";
80
85
  /**
81
86
  * Orientation persona texts injected into the system prompt (设计 §6.2, M2).
82
87
  * The strings are verbatim from the design spec: the assistant persona is the
83
88
  * companion style, the coding persona is the rigor-first style. Both are
84
89
  * session-nature declarations, so they ride every system prompt branch
85
- * (default and customPrompt).
90
+ * (default and customPrompt). The custom orientation is not in this table: its
91
+ * persona text comes from the suite workspace persona.md (设计 §6.3, resolved
92
+ * by suite-loader).
86
93
  */
87
- export declare const ORIENTATION_PROMPTS: Record<SuiteOrientation, string>;
94
+ export declare const ORIENTATION_PROMPTS: Record<"assistant" | "coding", string>;
88
95
  export interface SuiteAssociations {
89
96
  readonly skills: readonly string[];
90
97
  readonly mcp: readonly string[];
@@ -130,7 +137,7 @@ export interface SuiteDefinition {
130
137
  * 编译内的角色定义;删掉文件只会让该关联成为 dangling 诊断。
131
138
  */
132
139
  export declare const DEFAULT_ROLE_ASSOCIATIONS: readonly string[];
133
- /** The factory builtin pair: assistant (fallback default) and coding (尖刀). */
140
+ /** The factory builtin pair: coding (factory default 尖刀) and assistant (fallback). */
134
141
  export declare const BUILTIN_SUITES: readonly SuiteDefinition[];
135
142
  export declare function getBuiltinSuite(id: string): SuiteDefinition | undefined;
136
143
  export declare function isBuiltinSuiteId(id: string): boolean;