@ai-agent-forge/agent-forge 0.87.0 → 0.88.1

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 (451) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +2 -2
  3. package/bundled-plugins/agent-loop-policy/agent-forge.json +19 -0
  4. package/bundled-plugins/agent-loop-policy/dist/entry.d.ts +28 -0
  5. package/bundled-plugins/agent-loop-policy/dist/entry.d.ts.map +1 -0
  6. package/bundled-plugins/agent-loop-policy/dist/entry.js +69 -0
  7. package/bundled-plugins/agent-loop-policy/dist/entry.js.map +1 -0
  8. package/bundled-plugins/agent-loop-policy/dist/loop-guard.d.ts +199 -0
  9. package/bundled-plugins/agent-loop-policy/dist/loop-guard.d.ts.map +1 -0
  10. package/bundled-plugins/agent-loop-policy/dist/loop-guard.js +208 -0
  11. package/bundled-plugins/agent-loop-policy/dist/loop-guard.js.map +1 -0
  12. package/bundled-plugins/agent-loop-policy/dist/run-loop-strategy.d.ts +17 -0
  13. package/bundled-plugins/agent-loop-policy/dist/run-loop-strategy.d.ts.map +1 -0
  14. package/bundled-plugins/agent-loop-policy/dist/run-loop-strategy.js +18 -0
  15. package/bundled-plugins/agent-loop-policy/dist/run-loop-strategy.js.map +1 -0
  16. package/bundled-plugins/agent-loop-policy/plugin.json +7 -0
  17. package/bundled-plugins/coding-tools/agent-forge.json +19 -0
  18. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/bash.d.ts +5 -44
  19. package/bundled-plugins/coding-tools/dist/bash.d.ts.map +1 -0
  20. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/bash.js +15 -119
  21. package/bundled-plugins/coding-tools/dist/bash.js.map +1 -0
  22. package/bundled-plugins/coding-tools/dist/capability.d.ts +25 -0
  23. package/bundled-plugins/coding-tools/dist/capability.d.ts.map +1 -0
  24. package/bundled-plugins/coding-tools/dist/capability.js +98 -0
  25. package/bundled-plugins/coding-tools/dist/capability.js.map +1 -0
  26. package/bundled-plugins/coding-tools/dist/config.d.ts +8 -0
  27. package/bundled-plugins/coding-tools/dist/config.d.ts.map +1 -0
  28. package/bundled-plugins/coding-tools/dist/config.js +8 -0
  29. package/bundled-plugins/coding-tools/dist/config.js.map +1 -0
  30. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/edit.d.ts +3 -3
  31. package/bundled-plugins/coding-tools/dist/edit.d.ts.map +1 -0
  32. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/edit.js +12 -10
  33. package/bundled-plugins/coding-tools/dist/edit.js.map +1 -0
  34. package/bundled-plugins/coding-tools/dist/entry.d.ts +14 -0
  35. package/bundled-plugins/coding-tools/dist/entry.d.ts.map +1 -0
  36. package/bundled-plugins/coding-tools/dist/entry.js +23 -0
  37. package/bundled-plugins/coding-tools/dist/entry.js.map +1 -0
  38. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/find.d.ts +4 -4
  39. package/bundled-plugins/coding-tools/dist/find.d.ts.map +1 -0
  40. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/find.js +10 -8
  41. package/bundled-plugins/coding-tools/dist/find.js.map +1 -0
  42. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/grep.d.ts +3 -3
  43. package/bundled-plugins/coding-tools/dist/grep.d.ts.map +1 -0
  44. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/grep.js +10 -8
  45. package/bundled-plugins/coding-tools/dist/grep.js.map +1 -0
  46. package/bundled-plugins/coding-tools/dist/index.d.ts +17 -0
  47. package/bundled-plugins/coding-tools/dist/index.d.ts.map +1 -0
  48. package/bundled-plugins/coding-tools/dist/index.js +17 -0
  49. package/bundled-plugins/coding-tools/dist/index.js.map +1 -0
  50. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/ls.d.ts +3 -3
  51. package/bundled-plugins/coding-tools/dist/ls.d.ts.map +1 -0
  52. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/ls.js +8 -6
  53. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/ls.js.map +1 -1
  54. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/powershell.d.ts +2 -1
  55. package/bundled-plugins/coding-tools/dist/powershell.d.ts.map +1 -0
  56. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/powershell.js +6 -3
  57. package/bundled-plugins/coding-tools/dist/powershell.js.map +1 -0
  58. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/read.d.ts +3 -3
  59. package/bundled-plugins/coding-tools/dist/read.d.ts.map +1 -0
  60. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/read.js +15 -13
  61. package/bundled-plugins/coding-tools/dist/read.js.map +1 -0
  62. package/bundled-plugins/coding-tools/dist/types.d.ts +74 -0
  63. package/bundled-plugins/coding-tools/dist/types.d.ts.map +1 -0
  64. package/bundled-plugins/coding-tools/dist/types.js +28 -0
  65. package/bundled-plugins/coding-tools/dist/types.js.map +1 -0
  66. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/write.d.ts +2 -2
  67. package/bundled-plugins/coding-tools/dist/write.d.ts.map +1 -0
  68. package/{dist/core/tools → bundled-plugins/coding-tools/dist}/write.js +11 -9
  69. package/bundled-plugins/coding-tools/dist/write.js.map +1 -0
  70. package/bundled-plugins/coding-tools/plugin.json +10 -0
  71. package/bundled-plugins/compaction-policy/agent-forge.json +19 -0
  72. package/bundled-plugins/compaction-policy/dist/branch-summary-policy.d.ts +6 -0
  73. package/bundled-plugins/compaction-policy/dist/branch-summary-policy.d.ts.map +1 -0
  74. package/bundled-plugins/compaction-policy/dist/branch-summary-policy.js +19 -0
  75. package/bundled-plugins/compaction-policy/dist/branch-summary-policy.js.map +1 -0
  76. package/bundled-plugins/compaction-policy/dist/compaction-policy.d.ts +6 -0
  77. package/bundled-plugins/compaction-policy/dist/compaction-policy.d.ts.map +1 -0
  78. package/bundled-plugins/compaction-policy/dist/compaction-policy.js +38 -0
  79. package/bundled-plugins/compaction-policy/dist/compaction-policy.js.map +1 -0
  80. package/bundled-plugins/compaction-policy/dist/entry.d.ts +13 -0
  81. package/bundled-plugins/compaction-policy/dist/entry.d.ts.map +1 -0
  82. package/bundled-plugins/compaction-policy/dist/entry.js +23 -0
  83. package/bundled-plugins/compaction-policy/dist/entry.js.map +1 -0
  84. package/bundled-plugins/compaction-policy/plugin.json +10 -0
  85. package/bundled-plugins/mcp-http/dist/index.d.ts +8 -0
  86. package/bundled-plugins/mcp-http/dist/index.d.ts.map +1 -0
  87. package/bundled-plugins/mcp-http/dist/index.js +8 -0
  88. package/bundled-plugins/mcp-http/dist/index.js.map +1 -0
  89. package/bundled-plugins/mcp-http/dist/mcp-http.d.ts.map +1 -0
  90. package/{dist/plugins → bundled-plugins/mcp-http/dist}/mcp-http.js +1 -1
  91. package/bundled-plugins/mcp-http/dist/mcp-http.js.map +1 -0
  92. package/bundled-plugins/overflow-policy/agent-forge.json +19 -0
  93. package/bundled-plugins/overflow-policy/dist/entry.d.ts +16 -0
  94. package/bundled-plugins/overflow-policy/dist/entry.d.ts.map +1 -0
  95. package/bundled-plugins/overflow-policy/dist/entry.js +35 -0
  96. package/bundled-plugins/overflow-policy/dist/entry.js.map +1 -0
  97. package/bundled-plugins/overflow-policy/plugin.json +10 -0
  98. package/bundled-plugins/provider-failover/agent-forge.json +19 -0
  99. package/bundled-plugins/provider-failover/dist/entry.d.ts +8 -0
  100. package/bundled-plugins/provider-failover/dist/entry.d.ts.map +1 -0
  101. package/bundled-plugins/provider-failover/dist/entry.js +8 -0
  102. package/bundled-plugins/provider-failover/dist/entry.js.map +1 -0
  103. package/bundled-plugins/provider-failover/dist/provider-failover.d.ts +122 -0
  104. package/bundled-plugins/provider-failover/dist/provider-failover.d.ts.map +1 -0
  105. package/{dist/core/extensions → bundled-plugins/provider-failover/dist}/provider-failover.js +149 -61
  106. package/bundled-plugins/provider-failover/dist/provider-failover.js.map +1 -0
  107. package/bundled-plugins/provider-failover/plugin.json +7 -0
  108. package/bundled-plugins/retry-policy/agent-forge.json +19 -0
  109. package/bundled-plugins/retry-policy/dist/entry.d.ts +16 -0
  110. package/bundled-plugins/retry-policy/dist/entry.d.ts.map +1 -0
  111. package/bundled-plugins/retry-policy/dist/entry.js +34 -0
  112. package/bundled-plugins/retry-policy/dist/entry.js.map +1 -0
  113. package/bundled-plugins/retry-policy/plugin.json +10 -0
  114. package/dist/bundle/.build-manifest.json +105 -183
  115. package/dist/bundle/chunks/{anthropic-messages-ALDZBUKI.js → anthropic-messages-PLAKXR73.js} +1 -1
  116. package/dist/bundle/chunks/{azure-openai-responses-A2WJWZFB.js → azure-openai-responses-OUWQ2AZD.js} +1 -1
  117. package/dist/bundle/chunks/{chunk-CIX3FSBK.js → chunk-A3JYRWB6.js} +1 -1
  118. package/dist/bundle/chunks/{chunk-SQFG22WN.js → chunk-AC2FIS4G.js} +1 -1
  119. package/dist/bundle/chunks/chunk-AQLNTW2B.js +664 -0
  120. package/dist/bundle/chunks/chunk-D3ARGZFR.js +13 -0
  121. package/dist/bundle/chunks/{chunk-YJCQVXW5.js → chunk-HTEVUY7F.js} +1 -1
  122. package/dist/bundle/chunks/{chunk-Y7HXTASS.js → chunk-HV64ASMT.js} +1 -1
  123. package/dist/bundle/chunks/chunk-LZOEQITZ.js +855 -0
  124. package/dist/bundle/chunks/{chunk-7ZY7IXZD.js → chunk-TRDNDS6A.js} +1 -1
  125. package/dist/bundle/chunks/chunk-Z72JWUZ4.js +4 -0
  126. package/dist/bundle/chunks/{google-generative-ai-NIB4WONV.js → google-generative-ai-DLII6DAT.js} +1 -1
  127. package/dist/bundle/chunks/{google-vertex-DCPYUEUO.js → google-vertex-G7BZL7GM.js} +1 -1
  128. package/dist/bundle/chunks/image-resize-worker.js +3 -3
  129. package/dist/bundle/chunks/{mistral-conversations-OC6LA5XL.js → mistral-conversations-JXUK24ID.js} +1 -1
  130. package/dist/bundle/chunks/{openai-codex-responses-IO2X4Y7L.js → openai-codex-responses-5GSGFIPG.js} +1 -1
  131. package/dist/bundle/chunks/{openai-completions-XYQQHETU.js → openai-completions-EI2I6DTG.js} +1 -1
  132. package/dist/bundle/chunks/{openai-responses-DLIRN3CI.js → openai-responses-AUJQ3NWT.js} +1 -1
  133. package/dist/bundle/chunks/{pi-messages-E6RRYBO7.js → pi-messages-PWU2VJMR.js} +1 -1
  134. package/dist/bundle/chunks/virtual-modules-WF6WRHP7.js +5 -0
  135. package/dist/bundle/cli.js +1 -1
  136. package/dist/bundle/client.js +1 -1
  137. package/dist/bundle/index.js +3 -3
  138. package/dist/bundle/rpc-entry.js +1 -1
  139. package/dist/capabilities/builtin.d.ts +1 -1
  140. package/dist/capabilities/builtin.d.ts.map +1 -1
  141. package/dist/capabilities/builtin.js +5 -0
  142. package/dist/capabilities/builtin.js.map +1 -1
  143. package/dist/cli/auth-check.d.ts.map +1 -1
  144. package/dist/cli/auth-check.js +14 -2
  145. package/dist/cli/auth-check.js.map +1 -1
  146. package/dist/cli/auth-command.d.ts.map +1 -1
  147. package/dist/cli/auth-command.js +1 -1
  148. package/dist/cli/auth-command.js.map +1 -1
  149. package/dist/cli/plugin-command.d.ts.map +1 -1
  150. package/dist/cli/plugin-command.js +17 -1
  151. package/dist/cli/plugin-command.js.map +1 -1
  152. package/dist/config.d.ts +2 -3
  153. package/dist/config.d.ts.map +1 -1
  154. package/dist/config.js +5 -6
  155. package/dist/config.js.map +1 -1
  156. package/dist/core/agent-session-bash.d.ts +1 -1
  157. package/dist/core/agent-session-bash.d.ts.map +1 -1
  158. package/dist/core/agent-session-bash.js +1 -1
  159. package/dist/core/agent-session-bash.js.map +1 -1
  160. package/dist/core/agent-session-compaction.d.ts +6 -10
  161. package/dist/core/agent-session-compaction.d.ts.map +1 -1
  162. package/dist/core/agent-session-compaction.js +21 -112
  163. package/dist/core/agent-session-compaction.js.map +1 -1
  164. package/dist/core/agent-session-internal.d.ts +1 -7
  165. package/dist/core/agent-session-internal.d.ts.map +1 -1
  166. package/dist/core/agent-session-internal.js.map +1 -1
  167. package/dist/core/agent-session-loop.d.ts +4 -3
  168. package/dist/core/agent-session-loop.d.ts.map +1 -1
  169. package/dist/core/agent-session-loop.js +9 -6
  170. package/dist/core/agent-session-loop.js.map +1 -1
  171. package/dist/core/agent-session-retry.d.ts +1 -1
  172. package/dist/core/agent-session-retry.d.ts.map +1 -1
  173. package/dist/core/agent-session-retry.js +32 -4
  174. package/dist/core/agent-session-retry.js.map +1 -1
  175. package/dist/core/agent-session-services.d.ts.map +1 -1
  176. package/dist/core/agent-session-services.js +30 -9
  177. package/dist/core/agent-session-services.js.map +1 -1
  178. package/dist/core/agent-session-tools.d.ts.map +1 -1
  179. package/dist/core/agent-session-tools.js +5 -1
  180. package/dist/core/agent-session-tools.js.map +1 -1
  181. package/dist/core/agent-session.d.ts +12 -33
  182. package/dist/core/agent-session.d.ts.map +1 -1
  183. package/dist/core/agent-session.js +61 -67
  184. package/dist/core/agent-session.js.map +1 -1
  185. package/dist/core/bash-executor.d.ts +1 -1
  186. package/dist/core/bash-executor.d.ts.map +1 -1
  187. package/dist/core/bash-executor.js.map +1 -1
  188. package/dist/core/extensions/bootstrap-agent-loop.d.ts +23 -151
  189. package/dist/core/extensions/bootstrap-agent-loop.d.ts.map +1 -1
  190. package/dist/core/extensions/bootstrap-agent-loop.js +28 -290
  191. package/dist/core/extensions/bootstrap-agent-loop.js.map +1 -1
  192. package/dist/core/extensions/capability-runtime-types.d.ts +5 -3
  193. package/dist/core/extensions/capability-runtime-types.d.ts.map +1 -1
  194. package/dist/core/extensions/capability-runtime-types.js.map +1 -1
  195. package/dist/core/extensions/capability-runtime.d.ts.map +1 -1
  196. package/dist/core/extensions/capability-runtime.js +42 -6
  197. package/dist/core/extensions/capability-runtime.js.map +1 -1
  198. package/dist/core/extensions/index.d.ts +12 -5
  199. package/dist/core/extensions/index.d.ts.map +1 -1
  200. package/dist/core/extensions/index.js +12 -5
  201. package/dist/core/extensions/index.js.map +1 -1
  202. package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
  203. package/dist/core/extensions/virtual-modules.js +65 -0
  204. package/dist/core/extensions/virtual-modules.js.map +1 -1
  205. package/dist/core/facade/coding-agent-facade.d.ts +1 -7
  206. package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
  207. package/dist/core/facade/coding-agent-facade.js +0 -3
  208. package/dist/core/facade/coding-agent-facade.js.map +1 -1
  209. package/dist/core/i18n/locales/zh-cn/cli.d.ts.map +1 -1
  210. package/dist/core/i18n/locales/zh-cn/cli.js +3 -1
  211. package/dist/core/i18n/locales/zh-cn/cli.js.map +1 -1
  212. package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts +1 -1
  213. package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts.map +1 -1
  214. package/dist/core/i18n/locales/zh-cn/core-contract-core.js +1 -1
  215. package/dist/core/i18n/locales/zh-cn/core-contract-core.js.map +1 -1
  216. package/dist/core/i18n/locales/zh-cn/core-contract-extensions.d.ts.map +1 -1
  217. package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js +2 -4
  218. package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js.map +1 -1
  219. package/dist/core/i18n/locales/zh-cn/core-errors.d.ts.map +1 -1
  220. package/dist/core/i18n/locales/zh-cn/core-errors.js +3 -1
  221. package/dist/core/i18n/locales/zh-cn/core-errors.js.map +1 -1
  222. package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts.map +1 -1
  223. package/dist/core/i18n/locales/zh-cn/interactive-mode.js +2 -0
  224. package/dist/core/i18n/locales/zh-cn/interactive-mode.js.map +1 -1
  225. package/dist/core/i18n/locales/zh-cn/tui-components-selectors.d.ts.map +1 -1
  226. package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js +0 -2
  227. package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js.map +1 -1
  228. package/dist/core/model-config.d.ts +0 -1
  229. package/dist/core/model-config.d.ts.map +1 -1
  230. package/dist/core/model-config.js +9 -1
  231. package/dist/core/model-config.js.map +1 -1
  232. package/dist/core/model-runtime.d.ts.map +1 -1
  233. package/dist/core/model-runtime.js +3 -3
  234. package/dist/core/model-runtime.js.map +1 -1
  235. package/dist/core/provider-composer.d.ts +2 -2
  236. package/dist/core/provider-composer.d.ts.map +1 -1
  237. package/dist/core/provider-composer.js +7 -8
  238. package/dist/core/provider-composer.js.map +1 -1
  239. package/dist/core/sdk.d.ts +18 -3
  240. package/dist/core/sdk.d.ts.map +1 -1
  241. package/dist/core/sdk.js +267 -76
  242. package/dist/core/sdk.js.map +1 -1
  243. package/dist/core/settings-manager.d.ts +9 -20
  244. package/dist/core/settings-manager.d.ts.map +1 -1
  245. package/dist/core/settings-manager.js +20 -54
  246. package/dist/core/settings-manager.js.map +1 -1
  247. package/dist/core/tools/bash-operations.d.ts +41 -0
  248. package/dist/core/tools/bash-operations.d.ts.map +1 -0
  249. package/dist/core/tools/bash-operations.js +113 -0
  250. package/dist/core/tools/bash-operations.js.map +1 -0
  251. package/dist/core/tools/index.d.ts +12 -36
  252. package/dist/core/tools/index.d.ts.map +1 -1
  253. package/dist/core/tools/index.js +1 -117
  254. package/dist/core/tools/index.js.map +1 -1
  255. package/dist/core/tools/readme-path.d.ts +3 -0
  256. package/dist/core/tools/readme-path.d.ts.map +1 -0
  257. package/dist/core/tools/readme-path.js +15 -0
  258. package/dist/core/tools/readme-path.js.map +1 -0
  259. package/dist/index.d.ts +3 -19
  260. package/dist/index.d.ts.map +1 -1
  261. package/dist/index.js +6 -39
  262. package/dist/index.js.map +1 -1
  263. package/dist/main.d.ts.map +1 -1
  264. package/dist/main.js +3 -2
  265. package/dist/main.js.map +1 -1
  266. package/dist/modes/interactive/components/footer.d.ts +0 -2
  267. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  268. package/dist/modes/interactive/components/footer.js +2 -7
  269. package/dist/modes/interactive/components/footer.js.map +1 -1
  270. package/dist/modes/interactive/components/settings-selector.d.ts +2 -6
  271. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  272. package/dist/modes/interactive/components/settings-selector.js +6 -28
  273. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  274. package/dist/modes/interactive/components/tool-execution.d.ts +0 -1
  275. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  276. package/dist/modes/interactive/components/tool-execution.js +9 -25
  277. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  278. package/dist/modes/interactive/interactive-mode.d.ts +0 -1
  279. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  280. package/dist/modes/interactive/interactive-mode.js +23 -36
  281. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  282. package/dist/modes/rpc/rpc-client.d.ts +0 -8
  283. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  284. package/dist/modes/rpc/rpc-client.js +0 -12
  285. package/dist/modes/rpc/rpc-client.js.map +1 -1
  286. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  287. package/dist/modes/rpc/rpc-mode.js +0 -9
  288. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  289. package/dist/modes/rpc/rpc-types.d.ts +0 -19
  290. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  291. package/dist/modes/rpc/rpc-types.js.map +1 -1
  292. package/dist/plugins/ecosystem/cli.d.ts.map +1 -1
  293. package/dist/plugins/ecosystem/cli.js +14 -2
  294. package/dist/plugins/ecosystem/cli.js.map +1 -1
  295. package/dist/plugins/ecosystem/node-npm-registry-source.d.ts +7 -2
  296. package/dist/plugins/ecosystem/node-npm-registry-source.d.ts.map +1 -1
  297. package/dist/plugins/ecosystem/node-npm-registry-source.js +64 -9
  298. package/dist/plugins/ecosystem/node-npm-registry-source.js.map +1 -1
  299. package/dist/plugins/ecosystem/node-plugin-acquisition-host.d.ts.map +1 -1
  300. package/dist/plugins/ecosystem/node-plugin-acquisition-host.js +6 -0
  301. package/dist/plugins/ecosystem/node-plugin-acquisition-host.js.map +1 -1
  302. package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts +9 -2
  303. package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts.map +1 -1
  304. package/dist/plugins/ecosystem/node-plugin-bootstrap.js +23 -0
  305. package/dist/plugins/ecosystem/node-plugin-bootstrap.js.map +1 -1
  306. package/dist/plugins/ecosystem/plugin-bootstrap.d.ts +9 -1
  307. package/dist/plugins/ecosystem/plugin-bootstrap.d.ts.map +1 -1
  308. package/dist/plugins/ecosystem/plugin-bootstrap.js +5 -0
  309. package/dist/plugins/ecosystem/plugin-bootstrap.js.map +1 -1
  310. package/dist/profiles/builtin-suites.d.ts +5 -1
  311. package/dist/profiles/builtin-suites.d.ts.map +1 -1
  312. package/dist/profiles/builtin-suites.js +6 -1
  313. package/dist/profiles/builtin-suites.js.map +1 -1
  314. package/dist/utils/photon.d.ts +2 -2
  315. package/dist/utils/photon.d.ts.map +1 -1
  316. package/dist/utils/photon.js +2 -2
  317. package/dist/utils/photon.js.map +1 -1
  318. package/docs/compaction.md +1 -3
  319. package/docs/docs.json +4 -0
  320. package/docs/index.md +1 -0
  321. package/docs/mcp.md +103 -0
  322. package/docs/models.md +14 -22
  323. package/docs/providers.md +0 -1
  324. package/docs/rpc.md +1 -26
  325. package/docs/sdk.md +4 -6
  326. package/docs/settings.md +9 -12
  327. package/docs/skills.md +1 -9
  328. package/docs/usage.md +1 -1
  329. package/examples/extensions/bash-spawn-hook/index.ts +7 -2
  330. package/examples/extensions/built-in-tool-renderer/index.ts +4 -2
  331. package/examples/extensions/minimal-mode/index.ts +2 -2
  332. package/examples/extensions/truncated-tool/index.ts +1 -1
  333. package/examples/extensions/with-deps/package-lock.json +2 -2
  334. package/examples/extensions/with-deps/package.json +1 -1
  335. package/examples/extensions/with-deps/plugin.json +1 -1
  336. package/examples/sdk/10-settings.ts +2 -4
  337. package/examples/sdk/12-full-control.ts +1 -2
  338. package/package.json +3 -4
  339. package/dist/bundle/chunks/chunk-6ZKDNZHA.js +0 -145
  340. package/dist/bundle/chunks/chunk-BFC2BDVJ.js +0 -13
  341. package/dist/bundle/chunks/chunk-MOHOLL3F.js +0 -1456
  342. package/dist/bundle/chunks/virtual-modules-KZ5DRH7Q.js +0 -2
  343. package/dist/core/extensions/bootstrap-branch-summary-policy.d.ts +0 -7
  344. package/dist/core/extensions/bootstrap-branch-summary-policy.d.ts.map +0 -1
  345. package/dist/core/extensions/bootstrap-branch-summary-policy.js +0 -28
  346. package/dist/core/extensions/bootstrap-branch-summary-policy.js.map +0 -1
  347. package/dist/core/extensions/bootstrap-compaction-policy.d.ts +0 -7
  348. package/dist/core/extensions/bootstrap-compaction-policy.d.ts.map +0 -1
  349. package/dist/core/extensions/bootstrap-compaction-policy.js +0 -82
  350. package/dist/core/extensions/bootstrap-compaction-policy.js.map +0 -1
  351. package/dist/core/extensions/bootstrap-overflow-policy.d.ts +0 -7
  352. package/dist/core/extensions/bootstrap-overflow-policy.d.ts.map +0 -1
  353. package/dist/core/extensions/bootstrap-overflow-policy.js +0 -30
  354. package/dist/core/extensions/bootstrap-overflow-policy.js.map +0 -1
  355. package/dist/core/extensions/bootstrap-retry-policy.d.ts +0 -7
  356. package/dist/core/extensions/bootstrap-retry-policy.d.ts.map +0 -1
  357. package/dist/core/extensions/bootstrap-retry-policy.js +0 -29
  358. package/dist/core/extensions/bootstrap-retry-policy.js.map +0 -1
  359. package/dist/core/extensions/bootstrap-tools.d.ts +0 -20
  360. package/dist/core/extensions/bootstrap-tools.d.ts.map +0 -1
  361. package/dist/core/extensions/bootstrap-tools.js +0 -36
  362. package/dist/core/extensions/bootstrap-tools.js.map +0 -1
  363. package/dist/core/extensions/microcompact.d.ts +0 -80
  364. package/dist/core/extensions/microcompact.d.ts.map +0 -1
  365. package/dist/core/extensions/microcompact.js +0 -134
  366. package/dist/core/extensions/microcompact.js.map +0 -1
  367. package/dist/core/extensions/provider-failover.d.ts +0 -106
  368. package/dist/core/extensions/provider-failover.d.ts.map +0 -1
  369. package/dist/core/extensions/provider-failover.js.map +0 -1
  370. package/dist/core/tools/bash.d.ts.map +0 -1
  371. package/dist/core/tools/bash.js.map +0 -1
  372. package/dist/core/tools/edit.d.ts.map +0 -1
  373. package/dist/core/tools/edit.js.map +0 -1
  374. package/dist/core/tools/find.d.ts.map +0 -1
  375. package/dist/core/tools/find.js.map +0 -1
  376. package/dist/core/tools/grep.d.ts.map +0 -1
  377. package/dist/core/tools/grep.js.map +0 -1
  378. package/dist/core/tools/ls.d.ts.map +0 -1
  379. package/dist/core/tools/powershell.d.ts.map +0 -1
  380. package/dist/core/tools/powershell.js.map +0 -1
  381. package/dist/core/tools/read.d.ts.map +0 -1
  382. package/dist/core/tools/read.js.map +0 -1
  383. package/dist/core/tools/write.d.ts.map +0 -1
  384. package/dist/core/tools/write.js.map +0 -1
  385. package/dist/plugins/mcp-http.d.ts.map +0 -1
  386. package/dist/plugins/mcp-http.js.map +0 -1
  387. package/dist/profile/child-facade.d.ts +0 -44
  388. package/dist/profile/child-facade.d.ts.map +0 -1
  389. package/dist/profile/child-facade.js +0 -56
  390. package/dist/profile/child-facade.js.map +0 -1
  391. package/dist/profile/dependency-wiring.d.ts +0 -48
  392. package/dist/profile/dependency-wiring.d.ts.map +0 -1
  393. package/dist/profile/dependency-wiring.js +0 -56
  394. package/dist/profile/dependency-wiring.js.map +0 -1
  395. package/dist/profile/domain-recovery.d.ts +0 -60
  396. package/dist/profile/domain-recovery.d.ts.map +0 -1
  397. package/dist/profile/domain-recovery.js +0 -94
  398. package/dist/profile/domain-recovery.js.map +0 -1
  399. package/dist/profile/first-roles.d.ts +0 -30
  400. package/dist/profile/first-roles.d.ts.map +0 -1
  401. package/dist/profile/first-roles.js +0 -83
  402. package/dist/profile/first-roles.js.map +0 -1
  403. package/dist/profile/goal-plugin.d.ts +0 -38
  404. package/dist/profile/goal-plugin.d.ts.map +0 -1
  405. package/dist/profile/goal-plugin.js +0 -132
  406. package/dist/profile/goal-plugin.js.map +0 -1
  407. package/dist/profile/plan-plugin.d.ts +0 -44
  408. package/dist/profile/plan-plugin.d.ts.map +0 -1
  409. package/dist/profile/plan-plugin.js +0 -157
  410. package/dist/profile/plan-plugin.js.map +0 -1
  411. package/dist/profile/policy-manifest.d.ts +0 -53
  412. package/dist/profile/policy-manifest.d.ts.map +0 -1
  413. package/dist/profile/policy-manifest.js +0 -53
  414. package/dist/profile/policy-manifest.js.map +0 -1
  415. package/dist/profile/role-assembly.d.ts +0 -47
  416. package/dist/profile/role-assembly.d.ts.map +0 -1
  417. package/dist/profile/role-assembly.js +0 -31
  418. package/dist/profile/role-assembly.js.map +0 -1
  419. package/dist/profile/role-catalog.d.ts +0 -43
  420. package/dist/profile/role-catalog.d.ts.map +0 -1
  421. package/dist/profile/role-catalog.js +0 -132
  422. package/dist/profile/role-catalog.js.map +0 -1
  423. package/dist/profile/role-orchestrator.d.ts +0 -123
  424. package/dist/profile/role-orchestrator.d.ts.map +0 -1
  425. package/dist/profile/role-orchestrator.js +0 -195
  426. package/dist/profile/role-orchestrator.js.map +0 -1
  427. package/dist/profile/role-runner.d.ts +0 -99
  428. package/dist/profile/role-runner.d.ts.map +0 -1
  429. package/dist/profile/role-runner.js +0 -79
  430. package/dist/profile/role-runner.js.map +0 -1
  431. package/dist/profile/root-facade.d.ts +0 -36
  432. package/dist/profile/root-facade.d.ts.map +0 -1
  433. package/dist/profile/root-facade.js +0 -49
  434. package/dist/profile/root-facade.js.map +0 -1
  435. package/dist/profile/skill-discovery-wiring.d.ts +0 -58
  436. package/dist/profile/skill-discovery-wiring.d.ts.map +0 -1
  437. package/dist/profile/skill-discovery-wiring.js +0 -80
  438. package/dist/profile/skill-discovery-wiring.js.map +0 -1
  439. package/dist/profile/state-store.d.ts +0 -62
  440. package/dist/profile/state-store.d.ts.map +0 -1
  441. package/dist/profile/state-store.js +0 -144
  442. package/dist/profile/state-store.js.map +0 -1
  443. package/dist/profile/todo-plugin.d.ts +0 -37
  444. package/dist/profile/todo-plugin.d.ts.map +0 -1
  445. package/dist/profile/todo-plugin.js +0 -137
  446. package/dist/profile/todo-plugin.js.map +0 -1
  447. package/dist/server/create-harness.d.ts +0 -26
  448. package/dist/server/create-harness.d.ts.map +0 -1
  449. package/dist/server/create-harness.js +0 -106
  450. package/dist/server/create-harness.js.map +0 -1
  451. /package/{dist/plugins → bundled-plugins/mcp-http/dist}/mcp-http.d.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-bootstrap.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/plugin-bootstrap.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Startup plugin bootstrap orchestrator (design\n * `插件独立分发与启动装配设计.md` §4.4, §0.7). Pure injectable decision loop\n * over the frozen factory manifest: every entry is compared against the\n * locally resolved active installations and only missing plugins are handed\n * to the npm install dependency — bootstrap never acquires through any other\n * source.\n *\n * Coverage rules (G5): an existing active installation is never replaced. A\n * satisfied range is skipped silently (zero acquisition calls, G3); an\n * unsatisfied one produces a diagnostic with a manual install command and no\n * automatic replacement. Failure semantics (G4): one plugin's install\n * failure is recorded and the loop continues; the run itself never throws.\n * All effects live behind the injected dependencies, so the loop is fully\n * deterministic under mocks.\n */\n\nimport type { PluginBootstrapFactoryEntryV1 } from \"./bootstrap-factory-manifest.ts\";\nimport { selectNpmPackageVersionV1 } from \"./node-npm-registry-source.ts\";\nimport { PluginAcquisitionErrorV1 } from \"./plugin-acquisition.ts\";\n\nexport const PLUGIN_BOOTSTRAP_VERSION_V1 = 1 as const;\n\n/** Read-only local lookup of active installation versions (never networked). */\nexport type PluginBootstrapListActiveV1 = (input: {\n\treadonly signal?: AbortSignal;\n}) => Promise<ReadonlyMap<string, string>>;\n\n/** npm-only install action; resolves with the installed version and source label. */\nexport type PluginBootstrapInstallFromNpmV1 = (input: {\n\treadonly npmName: string;\n\treadonly range?: string;\n\treadonly signal?: AbortSignal;\n}) => Promise<{ readonly pluginVersion: string; readonly source: string }>;\n\nexport interface PluginBootstrapDepsV1 {\n\treadonly listActive: PluginBootstrapListActiveV1;\n\treadonly installFromNpm: PluginBootstrapInstallFromNpmV1;\n\t/** Deterministic clock for the observed duration; defaults to Date.now. */\n\treadonly now?: () => number;\n\t/** Cooperative cancellation; checked before each manifest entry. */\n\treadonly signal?: AbortSignal;\n}\n\nexport type PluginBootstrapActionStatusV1 = \"skipped\" | \"diagnosed\" | \"installed\" | \"failed\";\n\nexport type PluginBootstrapActionReasonV1 = \"satisfies_range\" | \"range_not_satisfied\" | \"installed\" | \"install_failed\";\n\n/** One per-entry outcome; the version fields carry what each status observed. */\nexport interface PluginBootstrapActionV1 {\n\treadonly pluginId: string;\n\treadonly status: PluginBootstrapActionStatusV1;\n\treadonly reason: PluginBootstrapActionReasonV1;\n\treadonly npmName: string;\n\treadonly range?: string;\n\t/** Active version that decided a skipped/diagnosed outcome. */\n\treadonly activeVersion?: string;\n\t/** Version reported by the install action. */\n\treadonly installedVersion?: string;\n\t/** npm source label reported by the install action. */\n\treadonly source?: string;\n\t/** Acquisition or install failure code for failed actions. */\n\treadonly errorCode?: string;\n}\n\nexport type PluginBootstrapDiagnosticCodeV1 =\n\t| \"range_not_satisfied\"\n\t| \"install_failed\"\n\t| \"list_active_failed\"\n\t| \"cancelled\"\n\t| \"bootstrap_failed\";\n\nexport interface PluginBootstrapDiagnosticV1 {\n\treadonly code: PluginBootstrapDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly pluginId?: string;\n}\n\nexport type PluginBootstrapStatusV1 = \"succeeded\" | \"degraded\" | \"failed\";\n\nexport interface PluginBootstrapResultV1 {\n\treadonly version: typeof PLUGIN_BOOTSTRAP_VERSION_V1;\n\t/** Aggregated outcome: failed > degraded (diagnosed entries) > succeeded. */\n\treadonly status: PluginBootstrapStatusV1;\n\treadonly actions: readonly PluginBootstrapActionV1[];\n\treadonly diagnostics: readonly PluginBootstrapDiagnosticV1[];\n\treadonly durationMs: number;\n}\n\n/**\n * A version satisfies a factory range under the same selection semantics npm\n * resolution uses: it is the version that would be picked if it were the only\n * candidate. Keeps local comparison and registry resolution consistent.\n */\nfunction satisfiesRangeV1(version: string, range: string | undefined): boolean {\n\treturn selectNpmPackageVersionV1([version], range) === version;\n}\n\n/** Executable repair command for diagnostics (G4/G5 remediation hint). */\nexport function pluginBootstrapInstallCommandV1(entry: { readonly npmName: string; readonly range?: string }): string {\n\treturn `agent-forge plugin install ${entry.npmName}@${entry.range ?? \"latest\"}`;\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction acquireErrorCode(error: unknown): string {\n\treturn error instanceof PluginAcquisitionErrorV1 ? error.code : \"install_failed\";\n}\n\nfunction actionOf(\n\tentry: PluginBootstrapFactoryEntryV1,\n\tstatus: PluginBootstrapActionStatusV1,\n\treason: PluginBootstrapActionReasonV1,\n): PluginBootstrapActionV1 {\n\treturn Object.freeze({\n\t\tpluginId: entry.pluginId,\n\t\tstatus,\n\t\treason,\n\t\tnpmName: entry.npmName,\n\t\t...(entry.range === undefined ? {} : { range: entry.range }),\n\t});\n}\n\n/**\n * Run the bootstrap decision loop. An empty manifest short-circuits before\n * any dependency is touched, so the factory-empty S1-c2 state performs zero\n * reads on real startups.\n */\nexport async function runPluginBootstrapV1(input: {\n\treadonly manifest: readonly PluginBootstrapFactoryEntryV1[];\n\treadonly deps: PluginBootstrapDepsV1;\n}): Promise<PluginBootstrapResultV1> {\n\tconst now = input.deps.now ?? Date.now;\n\tconst startedAt = now();\n\tconst finish = (\n\t\tstatus: PluginBootstrapStatusV1,\n\t\tactions: readonly PluginBootstrapActionV1[],\n\t\tdiagnostics: readonly PluginBootstrapDiagnosticV1[],\n\t): PluginBootstrapResultV1 =>\n\t\tObject.freeze({\n\t\t\tversion: PLUGIN_BOOTSTRAP_VERSION_V1,\n\t\t\tstatus,\n\t\t\tactions: Object.freeze([...actions]),\n\t\t\tdiagnostics: Object.freeze([...diagnostics]),\n\t\t\tdurationMs: Math.max(0, now() - startedAt),\n\t\t});\n\tif (input.manifest.length === 0) return finish(\"succeeded\", [], []);\n\tconst signal = input.deps.signal;\n\tlet active: ReadonlyMap<string, string>;\n\ttry {\n\t\tactive = await input.deps.listActive({ ...(signal === undefined ? {} : { signal }) });\n\t} catch (error) {\n\t\treturn finish(\n\t\t\t\"failed\",\n\t\t\t[],\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tcode: \"list_active_failed\",\n\t\t\t\t\tmessage: `Active plugin state could not be read; bootstrap installed nothing: ${errorMessage(error)}`,\n\t\t\t\t},\n\t\t\t],\n\t\t);\n\t}\n\tconst actions: PluginBootstrapActionV1[] = [];\n\tconst diagnostics: PluginBootstrapDiagnosticV1[] = [];\n\tfor (const entry of input.manifest) {\n\t\tif (signal?.aborted === true) {\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"cancelled\",\n\t\t\t\tmessage: \"Plugin bootstrap was cancelled before all factory entries were processed\",\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\t\tconst activeVersion = active.get(entry.pluginId);\n\t\tif (activeVersion !== undefined) {\n\t\t\tif (satisfiesRangeV1(activeVersion, entry.range)) {\n\t\t\t\tactions.push(Object.freeze({ ...actionOf(entry, \"skipped\", \"satisfies_range\"), activeVersion }));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tactions.push(Object.freeze({ ...actionOf(entry, \"diagnosed\", \"range_not_satisfied\"), activeVersion }));\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"range_not_satisfied\",\n\t\t\t\tpluginId: entry.pluginId,\n\t\t\t\tmessage:\n\t\t\t\t\t`Active version ${activeVersion} of ${entry.pluginId} does not satisfy the factory range ` +\n\t\t\t\t\t`${entry.range ?? \"latest\"}; bootstrap never replaces active installations. ` +\n\t\t\t\t\t`Run \\`${pluginBootstrapInstallCommandV1(entry)}\\` to install a matching version, ` +\n\t\t\t\t\t`or \\`agent-forge plugin update --all\\` to upgrade every outdated plugin at once.`,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst installed = await input.deps.installFromNpm({\n\t\t\t\tnpmName: entry.npmName,\n\t\t\t\t...(entry.range === undefined ? {} : { range: entry.range }),\n\t\t\t\t...(signal === undefined ? {} : { signal }),\n\t\t\t});\n\t\t\tactions.push(\n\t\t\t\tObject.freeze({\n\t\t\t\t\t...actionOf(entry, \"installed\", \"installed\"),\n\t\t\t\t\tinstalledVersion: installed.pluginVersion,\n\t\t\t\t\tsource: installed.source,\n\t\t\t\t}),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst errorCode = acquireErrorCode(error);\n\t\t\tactions.push(Object.freeze({ ...actionOf(entry, \"failed\", \"install_failed\"), errorCode }));\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"install_failed\",\n\t\t\t\tpluginId: entry.pluginId,\n\t\t\t\tmessage:\n\t\t\t\t\t`Bootstrap could not install ${entry.pluginId} from npm (${errorCode}: ${errorMessage(error)}). ` +\n\t\t\t\t\t`Startup continues without it; its capabilities stay unavailable until installed. ` +\n\t\t\t\t\t`Run \\`${pluginBootstrapInstallCommandV1(entry)}\\` to install it manually.`,\n\t\t\t});\n\t\t}\n\t}\n\tconst status: PluginBootstrapStatusV1 = actions.some((action) => action.status === \"failed\")\n\t\t? \"failed\"\n\t\t: actions.some((action) => action.status === \"diagnosed\")\n\t\t\t? \"degraded\"\n\t\t\t: \"succeeded\";\n\treturn finish(status, actions, diagnostics);\n}\n"]}
1
+ {"version":3,"file":"plugin-bootstrap.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/plugin-bootstrap.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Startup plugin bootstrap orchestrator (design\n * `插件独立分发与启动装配设计.md` §4.4, §0.7). Pure injectable decision loop\n * over the frozen factory manifest: every entry is compared against the\n * locally resolved active installations and only missing plugins are handed\n * to the npm install dependency — bootstrap never acquires through any other\n * source.\n *\n * Coverage rules (G5): an existing active installation is never replaced. A\n * satisfied range is skipped silently (zero acquisition calls, G3); an\n * unsatisfied one produces a diagnostic with a manual install command and no\n * automatic replacement. Failure semantics (G4): one plugin's install\n * failure is recorded and the loop continues; the run itself never throws.\n * All effects live behind the injected dependencies, so the loop is fully\n * deterministic under mocks.\n */\n\nimport type { PluginBootstrapFactoryEntryV1 } from \"./bootstrap-factory-manifest.ts\";\nimport { selectNpmPackageVersionV1 } from \"./node-npm-registry-source.ts\";\nimport { PluginAcquisitionErrorV1 } from \"./plugin-acquisition.ts\";\n\nexport const PLUGIN_BOOTSTRAP_VERSION_V1 = 1 as const;\n\n/** Read-only local lookup of active installation versions (never networked). */\nexport type PluginBootstrapListActiveV1 = (input: {\n\treadonly signal?: AbortSignal;\n}) => Promise<ReadonlyMap<string, string>>;\n\n/** npm-only install action; resolves with the installed version and source label. */\nexport type PluginBootstrapInstallFromNpmV1 = (input: {\n\treadonly npmName: string;\n\treadonly range?: string;\n\treadonly signal?: AbortSignal;\n}) => Promise<{ readonly pluginVersion: string; readonly source: string }>;\n\nexport interface PluginBootstrapDepsV1 {\n\treadonly listActive: PluginBootstrapListActiveV1;\n\treadonly installFromNpm: PluginBootstrapInstallFromNpmV1;\n\t/** Deterministic clock for the observed duration; defaults to Date.now. */\n\treadonly now?: () => number;\n\t/** Cooperative cancellation; checked before each manifest entry. */\n\treadonly signal?: AbortSignal;\n}\n\nexport type PluginBootstrapActionStatusV1 = \"skipped\" | \"diagnosed\" | \"installed\" | \"failed\";\n\nexport type PluginBootstrapActionReasonV1 = \"satisfies_range\" | \"range_not_satisfied\" | \"installed\" | \"install_failed\";\n\n/** One per-entry outcome; the version fields carry what each status observed. */\nexport interface PluginBootstrapActionV1 {\n\treadonly pluginId: string;\n\treadonly status: PluginBootstrapActionStatusV1;\n\treadonly reason: PluginBootstrapActionReasonV1;\n\treadonly npmName: string;\n\treadonly range?: string;\n\t/** Active version that decided a skipped/diagnosed outcome. */\n\treadonly activeVersion?: string;\n\t/** Version reported by the install action. */\n\treadonly installedVersion?: string;\n\t/** npm source label reported by the install action. */\n\treadonly source?: string;\n\t/** Acquisition or install failure code for failed actions. */\n\treadonly errorCode?: string;\n}\n\nexport type PluginBootstrapDiagnosticCodeV1 =\n\t| \"range_not_satisfied\"\n\t| \"install_failed\"\n\t| \"list_active_failed\"\n\t| \"cancelled\"\n\t| \"bootstrap_failed\"\n\t| \"bootstrap_skipped_offline\";\n\nexport interface PluginBootstrapDiagnosticV1 {\n\treadonly code: PluginBootstrapDiagnosticCodeV1;\n\treadonly message: string;\n\treadonly pluginId?: string;\n}\n\nexport type PluginBootstrapStatusV1 = \"succeeded\" | \"degraded\" | \"failed\";\n\nexport interface PluginBootstrapResultV1 {\n\treadonly version: typeof PLUGIN_BOOTSTRAP_VERSION_V1;\n\t/** Aggregated outcome: failed > degraded (diagnosed entries) > succeeded. */\n\treadonly status: PluginBootstrapStatusV1;\n\treadonly actions: readonly PluginBootstrapActionV1[];\n\treadonly diagnostics: readonly PluginBootstrapDiagnosticV1[];\n\treadonly durationMs: number;\n}\n\n/**\n * A version satisfies a factory range under the same selection semantics npm\n * resolution uses: it is the version that would be picked if it were the only\n * candidate. Keeps local comparison and registry resolution consistent.\n */\nfunction satisfiesRangeV1(version: string, range: string | undefined): boolean {\n\treturn selectNpmPackageVersionV1([version], range) === version;\n}\n\n/** Executable repair command for diagnostics (G4/G5 remediation hint). */\nexport function pluginBootstrapInstallCommandV1(entry: { readonly npmName: string; readonly range?: string }): string {\n\treturn `agent-forge plugin install ${entry.npmName}@${entry.range ?? \"latest\"}`;\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction acquireErrorCode(error: unknown): string {\n\treturn error instanceof PluginAcquisitionErrorV1 ? error.code : \"install_failed\";\n}\n\nfunction actionOf(\n\tentry: PluginBootstrapFactoryEntryV1,\n\tstatus: PluginBootstrapActionStatusV1,\n\treason: PluginBootstrapActionReasonV1,\n): PluginBootstrapActionV1 {\n\treturn Object.freeze({\n\t\tpluginId: entry.pluginId,\n\t\tstatus,\n\t\treason,\n\t\tnpmName: entry.npmName,\n\t\t...(entry.range === undefined ? {} : { range: entry.range }),\n\t});\n}\n\n/**\n * Run the bootstrap decision loop. An empty manifest short-circuits before\n * any dependency is touched, so the factory-empty S1-c2 state performs zero\n * reads on real startups.\n */\nexport async function runPluginBootstrapV1(input: {\n\treadonly manifest: readonly PluginBootstrapFactoryEntryV1[];\n\treadonly deps: PluginBootstrapDepsV1;\n\t/**\n\t * Fired once after the local active-state read when at least one factory\n\t * entry has no active installation — the host's first-run progress line\n\t * hook (设计 §4.4 首装进度行, 2026-10-03): a fresh install is otherwise\n\t * silent for the whole network install window. Injected effect, the loop\n\t * itself stays free of console I/O.\n\t */\n\treadonly onPendingInstalls?: (count: number) => void;\n}): Promise<PluginBootstrapResultV1> {\n\tconst now = input.deps.now ?? Date.now;\n\tconst startedAt = now();\n\tconst finish = (\n\t\tstatus: PluginBootstrapStatusV1,\n\t\tactions: readonly PluginBootstrapActionV1[],\n\t\tdiagnostics: readonly PluginBootstrapDiagnosticV1[],\n\t): PluginBootstrapResultV1 =>\n\t\tObject.freeze({\n\t\t\tversion: PLUGIN_BOOTSTRAP_VERSION_V1,\n\t\t\tstatus,\n\t\t\tactions: Object.freeze([...actions]),\n\t\t\tdiagnostics: Object.freeze([...diagnostics]),\n\t\t\tdurationMs: Math.max(0, now() - startedAt),\n\t\t});\n\tif (input.manifest.length === 0) return finish(\"succeeded\", [], []);\n\tconst signal = input.deps.signal;\n\tlet active: ReadonlyMap<string, string>;\n\ttry {\n\t\tactive = await input.deps.listActive({ ...(signal === undefined ? {} : { signal }) });\n\t} catch (error) {\n\t\treturn finish(\n\t\t\t\"failed\",\n\t\t\t[],\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tcode: \"list_active_failed\",\n\t\t\t\t\tmessage: `Active plugin state could not be read; bootstrap installed nothing: ${errorMessage(error)}`,\n\t\t\t\t},\n\t\t\t],\n\t\t);\n\t}\n\tconst actions: PluginBootstrapActionV1[] = [];\n\tconst diagnostics: PluginBootstrapDiagnosticV1[] = [];\n\tif (input.onPendingInstalls !== undefined) {\n\t\tconst pending = input.manifest.filter((entry) => !active.has(entry.pluginId)).length;\n\t\tif (pending > 0) input.onPendingInstalls(pending);\n\t}\n\tfor (const entry of input.manifest) {\n\t\tif (signal?.aborted === true) {\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"cancelled\",\n\t\t\t\tmessage: \"Plugin bootstrap was cancelled before all factory entries were processed\",\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\t\tconst activeVersion = active.get(entry.pluginId);\n\t\tif (activeVersion !== undefined) {\n\t\t\tif (satisfiesRangeV1(activeVersion, entry.range)) {\n\t\t\t\tactions.push(Object.freeze({ ...actionOf(entry, \"skipped\", \"satisfies_range\"), activeVersion }));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tactions.push(Object.freeze({ ...actionOf(entry, \"diagnosed\", \"range_not_satisfied\"), activeVersion }));\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"range_not_satisfied\",\n\t\t\t\tpluginId: entry.pluginId,\n\t\t\t\tmessage:\n\t\t\t\t\t`Active version ${activeVersion} of ${entry.pluginId} does not satisfy the factory range ` +\n\t\t\t\t\t`${entry.range ?? \"latest\"}; bootstrap never replaces active installations. ` +\n\t\t\t\t\t`Run \\`${pluginBootstrapInstallCommandV1(entry)}\\` to install a matching version, ` +\n\t\t\t\t\t`or \\`agent-forge plugin update --all\\` to upgrade every outdated plugin at once.`,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst installed = await input.deps.installFromNpm({\n\t\t\t\tnpmName: entry.npmName,\n\t\t\t\t...(entry.range === undefined ? {} : { range: entry.range }),\n\t\t\t\t...(signal === undefined ? {} : { signal }),\n\t\t\t});\n\t\t\tactions.push(\n\t\t\t\tObject.freeze({\n\t\t\t\t\t...actionOf(entry, \"installed\", \"installed\"),\n\t\t\t\t\tinstalledVersion: installed.pluginVersion,\n\t\t\t\t\tsource: installed.source,\n\t\t\t\t}),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst errorCode = acquireErrorCode(error);\n\t\t\tactions.push(Object.freeze({ ...actionOf(entry, \"failed\", \"install_failed\"), errorCode }));\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"install_failed\",\n\t\t\t\tpluginId: entry.pluginId,\n\t\t\t\tmessage:\n\t\t\t\t\t`Bootstrap could not install ${entry.pluginId} from npm (${errorCode}: ${errorMessage(error)}). ` +\n\t\t\t\t\t`Startup continues without it; its capabilities stay unavailable until installed. ` +\n\t\t\t\t\t`Run \\`${pluginBootstrapInstallCommandV1(entry)}\\` to install it manually.`,\n\t\t\t});\n\t\t}\n\t}\n\tconst status: PluginBootstrapStatusV1 = actions.some((action) => action.status === \"failed\")\n\t\t? \"failed\"\n\t\t: actions.some((action) => action.status === \"diagnosed\")\n\t\t\t? \"degraded\"\n\t\t\t: \"succeeded\";\n\treturn finish(status, actions, diagnostics);\n}\n"]}
@@ -77,7 +77,11 @@ export declare const BUILTIN_SUITE_TOOLS: readonly string[];
77
77
  * unconfigured default answers `/share` with the explicit configuration
78
78
  * prompt — never an implicit Radius/Gist fallback. `builtin.workflow` joins
79
79
  * at goal/plan/todo-set parity (D-077, 2026-10-02: factory default install
80
- * plus this suite declaration, plugin form unchanged).
80
+ * plus this suite declaration, plugin form unchanged). `builtin.coding-tools`
81
+ * joins with the D-082 batch-1 tool split (2026-10-03): the default coding
82
+ * tools assemble from the `plugins/coding-tools` package through the bundled
83
+ * distribution channel (插件独立分发与启动装配设计 §4.9), not the install
84
+ * store.
81
85
  */
82
86
  export declare const BUILTIN_SUITE_CAPABILITIES: readonly string[];
83
87
  export type SuiteMemoryStrategy = "assistant" | "code";
@@ -1 +1 @@
1
- {"version":3,"file":"builtin-suites.d.ts","sourceRoot":"","sources":["../../src/profiles/builtin-suites.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAEzC,yFAAoF;AACpF,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,2FAAqF;AACrF,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAShD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAQvD,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,MAAM,CAAC;AACvD,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEjE;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,WAAW,GAAG,QAAQ,EAAE,MAAM,CAiBtE,CAAC;AAEF,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACpB;AAED,8EAAyE;AACzE,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC;IACzC,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI,CAAC;IAC5C;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CAClC;AAID;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAA4B,CAAC;AAoCpF,0FAAsF;AACtF,eAAO,MAAM,cAAc,EAAE,SAAS,eAAe,EAAkC,CAAC;AAExF,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAEvE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEpD;AA6BD,oGAA+F;AAC/F,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAMlD;AAED,kGAAkG;AAClG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAyBjE;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACzD,oBAAoB,CAWtB;AAED,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,OAAO,EACd,OAAO,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9D,oBAAoB,CA0FtB","sourcesContent":["/**\n * Builtin suite (方案) declarations and suite.json (schemaVersion 1)\n * serialization, parsing, and validation — 方案系统设计.md v2 §5/§6/§9, M1a.\n *\n * Suites are pure data plus default policy: both builtin suites share the same\n * unrestricted tool surface and differ only in orientation and memory strategy\n * (the orientation persona text is injected into the system prompt, M2).\n * Nothing here touches the packages/agent kernel; association resolution is\n * declaration-only until M1b.\n */\n\nexport const SUITE_SCHEMA_VERSION = 1;\n\n/**\n * Factory contents revision (M4): the revision of the factory builtin\n * declarations, independent of SUITE_SCHEMA_VERSION. Bump it (and update both\n * builtin declarations' `factoryRevision`) whenever the factory contents\n * change; the registry upgrade proposal then offers `--suite-reset` for\n * workspaces still on an older revision. Suite schema evolution keeps using\n * SUITE_SCHEMA_VERSION.\n *\n * Revision 2 (统一修复轮集成收口, 2026-09-08): assistant and coding now share\n * the same active 8-tool surface in full-control — the sdk `suiteToolOverride`\n * DEFAULT_SUITE_ID exemption was removed (方案设计 §5 + user decision). Existing\n * workspaces provisioned at revision 1 receive the upgrade-proposal diagnostic\n * and adopt via `--suite-reset`.\n *\n * Revision 3 (2026-09-18): `builtin.session-share` joins both builtin suites\n * (开发计划 §216: session-share productized from the example plugin into a\n * first-party default-distributed capability) once the agent-dir config\n * channel for embedded capabilities landed\n * (`<agentDir>/capabilities/<short-id>.json`, see capabilities/builtin.ts).\n * Existing workspaces provisioned at revision 2 receive the upgrade-proposal\n * diagnostic and adopt via `--suite-reset`.\n *\n * Revision 4 (2026-09-18): `builtin.subagent-delegate` joins both builtin\n * suites — the first-party subagent delegation tool (`subagent_run`) now ships\n * by default in shared mode (zero extra processes; pooled runner processes stay\n * opt-in through the capability config channel). Existing workspaces\n * provisioned at revision 3 receive the upgrade-proposal diagnostic and adopt\n * via `--suite-reset`.\n *\n * Revision 5 (2026-09-20): subagent role profiles land on disk only\n * (`<agentDir>/roles/<id>.json` — the factory seeds explore/reviewer and never\n * overwrites user edits) and both builtin suites associate them by default via\n * the new `suite.associations.roles` field, with skill/MCP-isomorphic\n * visibility: unassociated roles stay invisible, associated-but-missing files\n * surface as dangling diagnostics. Existing workspaces provisioned at\n * revision 4 receive the upgrade-proposal diagnostic and adopt via\n * `--suite-reset`.\n *\n * Revision 6 (D-077, 2026-10-02): `builtin.workflow` joins both builtin suites\n * — the workflow orchestration plugin enters the factory bootstrap manifest\n * (ninth package) and the suite capability declaration at goal/plan/todo-set\n * parity, keeping its plugin form. Existing workspaces provisioned at revision\n * 5 receive the upgrade-proposal diagnostic and adopt via `--suite-reset`.\n */\nexport const FACTORY_CONTENTS_VERSION = 6;\n\n/**\n * Factory default suite used when no suite is configured anywhere (设计 §9).\n * 2026-10-02 user ruling: the product is a coding agent, so the factory\n * default flipped from \"assistant\" to \"coding\"; assistant stays as the\n * explicit-switch fallback suite.\n */\nexport const DEFAULT_SUITE_ID = \"coding\";\n\n/** Suite ids become directory names: lowercase letters, digits, hyphens (设计 §9). */\nexport const SUITE_ID_MAX_LENGTH = 64;\n\n/** The single unrestricted tool surface shared by both builtin suites (设计 §5/§6). */\nexport const BUILTIN_SUITE_TOOLS: readonly string[] = [\n\t\"read\",\n\t\"write\",\n\t\"edit\",\n\t\"bash\",\n\t\"ls\",\n\t\"find\",\n\t\"grep\",\n\t\"powershell\",\n];\n\n/**\n * Builtin capability plugins associated with both suites. Declaration-only\n * data in M1a; the actual plugin wiring is delivered in M3. `builtin.memory`\n * joins in the 统一修复轮 A 路 (方案系统设计 §6.1: both suites share the same\n * memory tool surface; the strategy difference lives in the suiteId domain\n * isolation and the assistant preference card). `builtin.session-share` joins\n * in the session-share productization slice (开发计划 §216); its\n * target/gateway/viewerUrl are configured through the agent-dir config\n * channel (`<agentDir>/capabilities/builtin.session-share.json`), and the\n * unconfigured default answers `/share` with the explicit configuration\n * prompt — never an implicit Radius/Gist fallback. `builtin.workflow` joins\n * at goal/plan/todo-set parity (D-077, 2026-10-02: factory default install\n * plus this suite declaration, plugin form unchanged).\n */\nexport const BUILTIN_SUITE_CAPABILITIES: readonly string[] = [\n\t\"builtin.goal\",\n\t\"builtin.plan\",\n\t\"builtin.todo-set\",\n\t\"builtin.workflow\",\n\t\"builtin.memory\",\n\t\"builtin.session-share\",\n\t\"builtin.subagent-delegate\",\n];\n\nexport type SuiteMemoryStrategy = \"assistant\" | \"code\";\nexport type SuiteOrientation = \"assistant\" | \"coding\" | \"custom\";\n\n/**\n * Orientation persona texts injected into the system prompt (设计 §6.2, M2).\n * The strings are verbatim from the design spec: the assistant persona is the\n * companion style, the coding persona is the rigor-first style. Both are\n * session-nature declarations, so they ride every system prompt branch\n * (default and customPrompt). The custom orientation is not in this table: its\n * persona text comes from the suite workspace persona.md (设计 §6.3, resolved\n * by suite-loader).\n */\nexport const ORIENTATION_PROMPTS: Record<\"assistant\" | \"coding\", string> = {\n\tassistant: `You are the user's thoughtful companion — warm, patient, and helpful.\n- Understand the intent behind the question, including the unspoken parts; when something that matters is ambiguous, ask one short clarifying question instead of assuming.\n- Pay attention to detail: notice what the user might have missed and gently point it out.\n- Be proactive and divergent: after answering, offer next steps, related ideas, or creative alternatives — without being pushy.\n- Adapt tone to the user; stay natural and flexible, never robotic or formulaic.\n- When you can help by doing, act through tools autonomously (minimal interruption).\n- Structure longer answers clearly: short paragraphs, lists where they help, and a concrete \"what you can do next\" at the end.`,\n\tcoding: `You are an autonomous software engineering agent with a rigor-first mindset.\n- Never guess. Ground every claim in code you have read, commands you have run, or documented evidence; cite file paths and line numbers. If the evidence is insufficient, investigate, and report what is unverified — or \"unknown\" — instead of a plausible invention.\n- First principles: trace problems to the earliest reasonable root cause and fix that; do not patch symptoms.\n- No over-engineering: add no abstraction, options, or defensive handling for imagined future needs; generalise only when a second concrete case demands it.\n- Tests first: pin expected behavior with a failing or updated test before or alongside the fix, then run the smallest sufficient relevant checks; the work is not done until they pass.\n- Reproducible: prefer deterministic tests and mocks over ad-hoc verification, and report the exact commands and results so others can re-run them.\n- Docs as code: repository documentation is part of the change — keep design docs, READMEs, and changelogs consistent with the behavior they describe.\n- Self-review before finishing: re-check your changes for correctness, edge cases, regressions, and missing tests; prefer a second review pass over shipping the first draft.\n- Cautious: weigh side effects, compatibility, and failure modes; when in doubt, take the safer path.`,\n};\n\nexport interface SuiteAssociations {\n\treadonly skills: readonly string[];\n\treadonly mcp: readonly string[];\n\treadonly plugins: readonly string[];\n\t/**\n\t * 子代理角色关联(D-044 角色机制):关联的是 `<agentDir>/roles/<id>.json` 里的角色 id。\n\t * 角色定义只在磁盘上(工厂仅做种子落盘),方案只决定哪些角色对主代理可见——与\n\t * skill/MCP/插件同构,第一方与第三方角色没有区别。\n\t */\n\treadonly roles: readonly string[];\n}\n\nexport interface SuiteClonedFrom {\n\treadonly id: string;\n\treadonly digest: string;\n\treadonly at: number;\n}\n\n/** The serializable suite definition persisted as suite.json (设计 §5). */\nexport interface SuiteDefinition {\n\treadonly schemaVersion: number;\n\treadonly id: string;\n\treadonly name: string;\n\treadonly builtin: boolean;\n\treadonly tools: readonly string[];\n\treadonly capabilities: readonly string[];\n\treadonly associations: SuiteAssociations;\n\treadonly inheritSystemAgentsMd: boolean;\n\treadonly memory: SuiteMemoryStrategy;\n\treadonly orientation: SuiteOrientation;\n\treadonly model: string | null;\n\treadonly thinking: string | null;\n\treadonly clonedFrom: SuiteClonedFrom | null;\n\t/**\n\t * Factory contents revision this declaration was written at (M4). Builtin\n\t * declarations carry it; on-disk builtin suite.json may omit it (pre-M4\n\t * files parse as FACTORY_CONTENTS_VERSION). User suites are outside factory\n\t * upgrade governance: the key stays optional and may be absent.\n\t */\n\treadonly factoryRevision?: number;\n}\n\nconst EMPTY_ASSOCIATIONS: SuiteAssociations = { skills: [], mcp: [], plugins: [], roles: [] };\n\n/**\n * 默认方案关联的子代理角色(开箱即用):这两个 id 对应工厂种子落盘的两个普通角色文件\n * (`<agentDir>/roles/{explore,reviewer}.json`,用户可改可删)。工厂不在运行期回退到任何\n * 编译内的角色定义;删掉文件只会让该关联成为 dangling 诊断。\n */\nexport const DEFAULT_ROLE_ASSOCIATIONS: readonly string[] = [\"explore\", \"reviewer\"];\n\nconst assistantSuite: SuiteDefinition = {\n\tschemaVersion: SUITE_SCHEMA_VERSION,\n\tid: \"assistant\",\n\tname: \"Assistant\",\n\tbuiltin: true,\n\ttools: BUILTIN_SUITE_TOOLS,\n\tcapabilities: BUILTIN_SUITE_CAPABILITIES,\n\tassociations: { ...EMPTY_ASSOCIATIONS, roles: DEFAULT_ROLE_ASSOCIATIONS },\n\tinheritSystemAgentsMd: false,\n\tmemory: \"assistant\",\n\torientation: \"assistant\",\n\tmodel: null,\n\tthinking: null,\n\tclonedFrom: null,\n\tfactoryRevision: FACTORY_CONTENTS_VERSION,\n};\n\nconst codingSuite: SuiteDefinition = {\n\tschemaVersion: SUITE_SCHEMA_VERSION,\n\tid: \"coding\",\n\tname: \"Coding\",\n\tbuiltin: true,\n\ttools: BUILTIN_SUITE_TOOLS,\n\tcapabilities: BUILTIN_SUITE_CAPABILITIES,\n\tassociations: { ...EMPTY_ASSOCIATIONS, roles: DEFAULT_ROLE_ASSOCIATIONS },\n\tinheritSystemAgentsMd: false,\n\tmemory: \"code\",\n\torientation: \"coding\",\n\tmodel: null,\n\tthinking: null,\n\tclonedFrom: null,\n\tfactoryRevision: FACTORY_CONTENTS_VERSION,\n};\n\n/** The factory builtin pair: coding (factory default 尖刀) and assistant (fallback). */\nexport const BUILTIN_SUITES: readonly SuiteDefinition[] = [assistantSuite, codingSuite];\n\nexport function getBuiltinSuite(id: string): SuiteDefinition | undefined {\n\treturn BUILTIN_SUITES.find((suite) => suite.id === id);\n}\n\nexport function isBuiltinSuiteId(id: string): boolean {\n\treturn BUILTIN_SUITES.some((suite) => suite.id === id);\n}\n\nconst WINDOWS_RESERVED_IDS = new Set([\n\t\"con\",\n\t\"prn\",\n\t\"aux\",\n\t\"nul\",\n\t\"com1\",\n\t\"com2\",\n\t\"com3\",\n\t\"com4\",\n\t\"com5\",\n\t\"com6\",\n\t\"com7\",\n\t\"com8\",\n\t\"com9\",\n\t\"lpt1\",\n\t\"lpt2\",\n\t\"lpt3\",\n\t\"lpt4\",\n\t\"lpt5\",\n\t\"lpt6\",\n\t\"lpt7\",\n\t\"lpt8\",\n\t\"lpt9\",\n\t\"conin$\",\n\t\"conout$\",\n]);\n\n/** Suite id rule (设计 §9): `a-z0-9-`, no leading/trailing hyphen, no Windows reserved names. */\nexport function isValidSuiteId(id: string): boolean {\n\tif (id.length === 0 || id.length > SUITE_ID_MAX_LENGTH) return false;\n\tif (!/^[a-z0-9-]+$/.test(id)) return false;\n\tif (id.startsWith(\"-\") || id.endsWith(\"-\")) return false;\n\tif (WINDOWS_RESERVED_IDS.has(id)) return false;\n\treturn true;\n}\n\n/** Serializes a suite to the canonical suite.json text (stable field order, trailing newline). */\nexport function serializeSuiteJson(suite: SuiteDefinition): string {\n\tconst ordered = {\n\t\tschemaVersion: suite.schemaVersion,\n\t\tid: suite.id,\n\t\tname: suite.name,\n\t\tbuiltin: suite.builtin,\n\t\ttools: [...suite.tools],\n\t\tcapabilities: [...suite.capabilities],\n\t\tassociations: {\n\t\t\tskills: [...suite.associations.skills],\n\t\t\tmcp: [...suite.associations.mcp],\n\t\t\tplugins: [...suite.associations.plugins],\n\t\t\troles: [...suite.associations.roles],\n\t\t},\n\t\tinheritSystemAgentsMd: suite.inheritSystemAgentsMd,\n\t\tmemory: suite.memory,\n\t\torientation: suite.orientation,\n\t\tmodel: suite.model,\n\t\tthinking: suite.thinking,\n\t\tclonedFrom: suite.clonedFrom\n\t\t\t? { id: suite.clonedFrom.id, digest: suite.clonedFrom.digest, at: suite.clonedFrom.at }\n\t\t\t: null,\n\t\tfactoryRevision: suite.factoryRevision,\n\t};\n\treturn `${JSON.stringify(ordered, null, 2)}\\n`;\n}\n\nexport interface SuiteJsonParseResult {\n\treadonly valid: boolean;\n\treadonly suite?: SuiteDefinition;\n\treadonly errors: readonly string[];\n}\n\n/**\n * Parses suite.json text. Never throws: an invalid result carries every\n * validation error so callers can apply the corruption policy (设计 §9) —\n * builtin suites fall back to factory content, user suites fail fast.\n */\nexport function parseSuiteJson(\n\traw: string,\n\toptions: { expectedBuiltin?: boolean; expectedId?: string },\n): SuiteJsonParseResult {\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(raw);\n\t} catch (error) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terrors: [`invalid JSON: ${error instanceof Error ? error.message : String(error)}`],\n\t\t};\n\t}\n\treturn validateSuiteJson(value, options);\n}\n\nexport function validateSuiteJson(\n\tvalue: unknown,\n\toptions: { expectedBuiltin?: boolean; expectedId?: string } = {},\n): SuiteJsonParseResult {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\treturn { valid: false, errors: [\"suite.json must be a JSON object\"] };\n\t}\n\tconst record = value as Record<string, unknown>;\n\tconst errors: string[] = [];\n\n\tif (record.schemaVersion !== SUITE_SCHEMA_VERSION) {\n\t\terrors.push(`schemaVersion must be ${SUITE_SCHEMA_VERSION}, found ${JSON.stringify(record.schemaVersion)}`);\n\t}\n\n\t// Each field keeps a typed local: valid values land here, invalid ones only\n\t// contribute errors. The suite below is constructed exclusively when\n\t// `errors` is empty, so the fallbacks/coercions at that point are dead.\n\tconst idValue = record.id;\n\tconst id = typeof idValue === \"string\" && isValidSuiteId(idValue) ? idValue : undefined;\n\tif (id === undefined) {\n\t\terrors.push(\n\t\t\t`id must be a suite id (^[a-z0-9-]+$, no leading/trailing hyphen, Windows reserved names rejected), found ${JSON.stringify(idValue)}`,\n\t\t);\n\t} else if (options.expectedId !== undefined && id !== options.expectedId) {\n\t\terrors.push(`id \"${id}\" does not match the suite workspace directory id \"${options.expectedId}\"`);\n\t}\n\n\tconst nameValue = record.name;\n\tconst name = typeof nameValue === \"string\" && nameValue.trim().length > 0 ? nameValue : undefined;\n\tif (name === undefined) {\n\t\terrors.push(`name must be a non-empty string, found ${JSON.stringify(nameValue)}`);\n\t}\n\n\tconst builtinValue = record.builtin;\n\tconst builtin = typeof builtinValue === \"boolean\" ? builtinValue : undefined;\n\tif (builtin === undefined) {\n\t\terrors.push(`builtin must be a boolean, found ${JSON.stringify(builtinValue)}`);\n\t} else if (options.expectedBuiltin === true && builtin !== true) {\n\t\terrors.push(`builtin must be true for a builtin suite workspace, found ${builtin}`);\n\t}\n\n\tconst tools = readStringArray(record, \"tools\", errors);\n\tconst capabilities = readStringArray(record, \"capabilities\", errors);\n\tconst associations = readAssociations(record.associations, errors);\n\n\tconst inheritValue = record.inheritSystemAgentsMd;\n\tconst inheritSystemAgentsMd = typeof inheritValue === \"boolean\" ? inheritValue : undefined;\n\tif (inheritSystemAgentsMd === undefined) {\n\t\terrors.push(`inheritSystemAgentsMd must be a boolean, found ${JSON.stringify(inheritValue)}`);\n\t}\n\n\tconst memoryValue = record.memory;\n\tconst memory = memoryValue === \"assistant\" || memoryValue === \"code\" ? memoryValue : undefined;\n\tif (memory === undefined) {\n\t\terrors.push(`memory must be \"assistant\" or \"code\", found ${JSON.stringify(memoryValue)}`);\n\t}\n\n\tconst orientationValue = record.orientation;\n\tconst orientation =\n\t\torientationValue === \"assistant\" || orientationValue === \"coding\" || orientationValue === \"custom\"\n\t\t\t? orientationValue\n\t\t\t: undefined;\n\tif (orientationValue !== undefined && orientation === undefined) {\n\t\terrors.push(`orientation must be \"assistant\", \"coding\", or \"custom\", found ${JSON.stringify(orientationValue)}`);\n\t}\n\n\tconst model = readOptionalString(record, \"model\", errors);\n\tconst thinking = readOptionalString(record, \"thinking\", errors);\n\tconst clonedFrom = readClonedFrom(record.clonedFrom, errors);\n\tconst factoryRevision = readFactoryRevision(record.factoryRevision, options.expectedBuiltin === true, errors);\n\n\tif (errors.length > 0) return { valid: false, errors };\n\n\treturn {\n\t\tvalid: true,\n\t\terrors: [],\n\t\tsuite: {\n\t\t\tschemaVersion: SUITE_SCHEMA_VERSION,\n\t\t\tid: id!,\n\t\t\tname: name!,\n\t\t\tbuiltin: builtin!,\n\t\t\ttools,\n\t\t\tcapabilities,\n\t\t\tassociations,\n\t\t\tinheritSystemAgentsMd: inheritSystemAgentsMd!,\n\t\t\tmemory: memory!,\n\t\t\torientation: orientation ?? \"assistant\",\n\t\t\tmodel,\n\t\t\tthinking,\n\t\t\tclonedFrom,\n\t\t\t...(factoryRevision === undefined ? {} : { factoryRevision }),\n\t\t},\n\t};\n}\n\nfunction readStringArray(record: Record<string, unknown>, key: string, errors: string[]): readonly string[] {\n\tconst value = record[key];\n\tif (!Array.isArray(value)) {\n\t\terrors.push(`${key} must be an array of strings, found ${JSON.stringify(value)}`);\n\t\treturn [];\n\t}\n\tconst entries: string[] = [];\n\tconst seen = new Set<string>();\n\tfor (const item of value) {\n\t\tif (typeof item !== \"string\" || item.trim().length === 0) {\n\t\t\terrors.push(`${key} entries must be non-empty strings, found ${JSON.stringify(item)}`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (seen.has(item)) {\n\t\t\terrors.push(`${key} contains duplicate entry \"${item}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tseen.add(item);\n\t\tentries.push(item);\n\t}\n\treturn entries;\n}\n\nfunction readAssociations(value: unknown, errors: string[]): SuiteAssociations {\n\tif (value === undefined) return { skills: [], mcp: [], plugins: [], roles: [] };\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\terrors.push(\n\t\t\t`associations must be an object with skills/mcp/plugins/roles arrays, found ${JSON.stringify(value)}`,\n\t\t);\n\t\treturn { skills: [], mcp: [], plugins: [], roles: [] };\n\t}\n\tconst record = value as Record<string, unknown>;\n\t// A key left out entirely means an empty list, consistent with a fully\n\t// absent `associations` object; a key that is present but malformed still\n\t// reports its errors. The removed legacy `extensions` kind is ignored on\n\t// read (it lost its loader with the old ExtensionAPI surface).\n\treturn {\n\t\tskills: record.skills === undefined ? [] : readStringArray(record, \"skills\", errors),\n\t\tmcp: record.mcp === undefined ? [] : readStringArray(record, \"mcp\", errors),\n\t\tplugins: record.plugins === undefined ? [] : readStringArray(record, \"plugins\", errors),\n\t\troles: record.roles === undefined ? [] : readStringArray(record, \"roles\", errors),\n\t};\n}\n\nfunction readOptionalString(record: Record<string, unknown>, key: string, errors: string[]): string | null {\n\tconst value = record[key];\n\tif (value === undefined || value === null) return null;\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\terrors.push(`${key} must be a non-empty string or null, found ${JSON.stringify(value)}`);\n\t\treturn null;\n\t}\n\treturn value;\n}\n\n/**\n * Reads the optional `factoryRevision` key (M4). A missing key means\n * FACTORY_CONTENTS_VERSION for builtin workspaces (pre-M4 on-disk files stay\n * compatible) and stays absent for user suites (outside factory upgrade\n * governance). A present key must be a positive integer.\n */\nfunction readFactoryRevision(value: unknown, expectedBuiltin: boolean, errors: string[]): number | undefined {\n\tif (value === undefined) return expectedBuiltin ? FACTORY_CONTENTS_VERSION : undefined;\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0) {\n\t\terrors.push(`factoryRevision must be a positive integer, found ${JSON.stringify(value)}`);\n\t\treturn undefined;\n\t}\n\treturn value;\n}\n\nfunction readClonedFrom(value: unknown, errors: string[]): SuiteClonedFrom | null {\n\tif (value === undefined || value === null) return null;\n\tif (typeof value !== \"object\" || Array.isArray(value)) {\n\t\terrors.push(`clonedFrom must be an object with id/digest/at, found ${JSON.stringify(value)}`);\n\t\treturn null;\n\t}\n\tconst record = value as Record<string, unknown>;\n\tif (\n\t\ttypeof record.id !== \"string\" ||\n\t\trecord.id.trim().length === 0 ||\n\t\ttypeof record.digest !== \"string\" ||\n\t\trecord.digest.trim().length === 0 ||\n\t\ttypeof record.at !== \"number\" ||\n\t\t!Number.isSafeInteger(record.at)\n\t) {\n\t\terrors.push(\n\t\t\t`clonedFrom must be an object with non-empty id/digest strings and an integer at, found ${JSON.stringify(value)}`,\n\t\t);\n\t\treturn null;\n\t}\n\treturn { id: record.id, digest: record.digest, at: record.at };\n}\n"]}
1
+ {"version":3,"file":"builtin-suites.d.ts","sourceRoot":"","sources":["../../src/profiles/builtin-suites.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Builtin suite (方案) declarations and suite.json (schemaVersion 1)\n * serialization, parsing, and validation — 方案系统设计.md v2 §5/§6/§9, M1a.\n *\n * Suites are pure data plus default policy: both builtin suites share the same\n * unrestricted tool surface and differ only in orientation and memory strategy\n * (the orientation persona text is injected into the system prompt, M2).\n * Nothing here touches the packages/agent kernel; association resolution is\n * declaration-only until M1b.\n */\n\nexport const SUITE_SCHEMA_VERSION = 1;\n\n/**\n * Factory contents revision (M4): the revision of the factory builtin\n * declarations, independent of SUITE_SCHEMA_VERSION. Bump it (and update both\n * builtin declarations' `factoryRevision`) whenever the factory contents\n * change; the registry upgrade proposal then offers `--suite-reset` for\n * workspaces still on an older revision. Suite schema evolution keeps using\n * SUITE_SCHEMA_VERSION.\n *\n * Revision 2 (统一修复轮集成收口, 2026-09-08): assistant and coding now share\n * the same active 8-tool surface in full-control — the sdk `suiteToolOverride`\n * DEFAULT_SUITE_ID exemption was removed (方案设计 §5 + user decision). Existing\n * workspaces provisioned at revision 1 receive the upgrade-proposal diagnostic\n * and adopt via `--suite-reset`.\n *\n * Revision 3 (2026-09-18): `builtin.session-share` joins both builtin suites\n * (开发计划 §216: session-share productized from the example plugin into a\n * first-party default-distributed capability) once the agent-dir config\n * channel for embedded capabilities landed\n * (`<agentDir>/capabilities/<short-id>.json`, see capabilities/builtin.ts).\n * Existing workspaces provisioned at revision 2 receive the upgrade-proposal\n * diagnostic and adopt via `--suite-reset`.\n *\n * Revision 4 (2026-09-18): `builtin.subagent-delegate` joins both builtin\n * suites — the first-party subagent delegation tool (`subagent_run`) now ships\n * by default in shared mode (zero extra processes; pooled runner processes stay\n * opt-in through the capability config channel). Existing workspaces\n * provisioned at revision 3 receive the upgrade-proposal diagnostic and adopt\n * via `--suite-reset`.\n *\n * Revision 5 (2026-09-20): subagent role profiles land on disk only\n * (`<agentDir>/roles/<id>.json` — the factory seeds explore/reviewer and never\n * overwrites user edits) and both builtin suites associate them by default via\n * the new `suite.associations.roles` field, with skill/MCP-isomorphic\n * visibility: unassociated roles stay invisible, associated-but-missing files\n * surface as dangling diagnostics. Existing workspaces provisioned at\n * revision 4 receive the upgrade-proposal diagnostic and adopt via\n * `--suite-reset`.\n *\n * Revision 6 (D-077, 2026-10-02): `builtin.workflow` joins both builtin suites\n * — the workflow orchestration plugin enters the factory bootstrap manifest\n * (ninth package) and the suite capability declaration at goal/plan/todo-set\n * parity, keeping its plugin form. Existing workspaces provisioned at revision\n * 5 receive the upgrade-proposal diagnostic and adopt via `--suite-reset`.\n */\nexport const FACTORY_CONTENTS_VERSION = 6;\n\n/**\n * Factory default suite used when no suite is configured anywhere (设计 §9).\n * 2026-10-02 user ruling: the product is a coding agent, so the factory\n * default flipped from \"assistant\" to \"coding\"; assistant stays as the\n * explicit-switch fallback suite.\n */\nexport const DEFAULT_SUITE_ID = \"coding\";\n\n/** Suite ids become directory names: lowercase letters, digits, hyphens (设计 §9). */\nexport const SUITE_ID_MAX_LENGTH = 64;\n\n/** The single unrestricted tool surface shared by both builtin suites (设计 §5/§6). */\nexport const BUILTIN_SUITE_TOOLS: readonly string[] = [\n\t\"read\",\n\t\"write\",\n\t\"edit\",\n\t\"bash\",\n\t\"ls\",\n\t\"find\",\n\t\"grep\",\n\t\"powershell\",\n];\n\n/**\n * Builtin capability plugins associated with both suites. Declaration-only\n * data in M1a; the actual plugin wiring is delivered in M3. `builtin.memory`\n * joins in the 统一修复轮 A 路 (方案系统设计 §6.1: both suites share the same\n * memory tool surface; the strategy difference lives in the suiteId domain\n * isolation and the assistant preference card). `builtin.session-share` joins\n * in the session-share productization slice (开发计划 §216); its\n * target/gateway/viewerUrl are configured through the agent-dir config\n * channel (`<agentDir>/capabilities/builtin.session-share.json`), and the\n * unconfigured default answers `/share` with the explicit configuration\n * prompt — never an implicit Radius/Gist fallback. `builtin.workflow` joins\n * at goal/plan/todo-set parity (D-077, 2026-10-02: factory default install\n * plus this suite declaration, plugin form unchanged). `builtin.coding-tools`\n * joins with the D-082 batch-1 tool split (2026-10-03): the default coding\n * tools assemble from the `plugins/coding-tools` package through the bundled\n * distribution channel (插件独立分发与启动装配设计 §4.9), not the install\n * store.\n */\nexport const BUILTIN_SUITE_CAPABILITIES: readonly string[] = [\n\t\"builtin.goal\",\n\t\"builtin.plan\",\n\t\"builtin.todo-set\",\n\t\"builtin.workflow\",\n\t\"builtin.memory\",\n\t\"builtin.session-share\",\n\t\"builtin.subagent-delegate\",\n\t\"builtin.coding-tools\",\n];\n\nexport type SuiteMemoryStrategy = \"assistant\" | \"code\";\nexport type SuiteOrientation = \"assistant\" | \"coding\" | \"custom\";\n\n/**\n * Orientation persona texts injected into the system prompt (设计 §6.2, M2).\n * The strings are verbatim from the design spec: the assistant persona is the\n * companion style, the coding persona is the rigor-first style. Both are\n * session-nature declarations, so they ride every system prompt branch\n * (default and customPrompt). The custom orientation is not in this table: its\n * persona text comes from the suite workspace persona.md (设计 §6.3, resolved\n * by suite-loader).\n */\nexport const ORIENTATION_PROMPTS: Record<\"assistant\" | \"coding\", string> = {\n\tassistant: `You are the user's thoughtful companion — warm, patient, and helpful.\n- Understand the intent behind the question, including the unspoken parts; when something that matters is ambiguous, ask one short clarifying question instead of assuming.\n- Pay attention to detail: notice what the user might have missed and gently point it out.\n- Be proactive and divergent: after answering, offer next steps, related ideas, or creative alternatives — without being pushy.\n- Adapt tone to the user; stay natural and flexible, never robotic or formulaic.\n- When you can help by doing, act through tools autonomously (minimal interruption).\n- Structure longer answers clearly: short paragraphs, lists where they help, and a concrete \"what you can do next\" at the end.`,\n\tcoding: `You are an autonomous software engineering agent with a rigor-first mindset.\n- Never guess. Ground every claim in code you have read, commands you have run, or documented evidence; cite file paths and line numbers. If the evidence is insufficient, investigate, and report what is unverified — or \"unknown\" — instead of a plausible invention.\n- First principles: trace problems to the earliest reasonable root cause and fix that; do not patch symptoms.\n- No over-engineering: add no abstraction, options, or defensive handling for imagined future needs; generalise only when a second concrete case demands it.\n- Tests first: pin expected behavior with a failing or updated test before or alongside the fix, then run the smallest sufficient relevant checks; the work is not done until they pass.\n- Reproducible: prefer deterministic tests and mocks over ad-hoc verification, and report the exact commands and results so others can re-run them.\n- Docs as code: repository documentation is part of the change — keep design docs, READMEs, and changelogs consistent with the behavior they describe.\n- Self-review before finishing: re-check your changes for correctness, edge cases, regressions, and missing tests; prefer a second review pass over shipping the first draft.\n- Cautious: weigh side effects, compatibility, and failure modes; when in doubt, take the safer path.`,\n};\n\nexport interface SuiteAssociations {\n\treadonly skills: readonly string[];\n\treadonly mcp: readonly string[];\n\treadonly plugins: readonly string[];\n\t/**\n\t * 子代理角色关联(D-044 角色机制):关联的是 `<agentDir>/roles/<id>.json` 里的角色 id。\n\t * 角色定义只在磁盘上(工厂仅做种子落盘),方案只决定哪些角色对主代理可见——与\n\t * skill/MCP/插件同构,第一方与第三方角色没有区别。\n\t */\n\treadonly roles: readonly string[];\n}\n\nexport interface SuiteClonedFrom {\n\treadonly id: string;\n\treadonly digest: string;\n\treadonly at: number;\n}\n\n/** The serializable suite definition persisted as suite.json (设计 §5). */\nexport interface SuiteDefinition {\n\treadonly schemaVersion: number;\n\treadonly id: string;\n\treadonly name: string;\n\treadonly builtin: boolean;\n\treadonly tools: readonly string[];\n\treadonly capabilities: readonly string[];\n\treadonly associations: SuiteAssociations;\n\treadonly inheritSystemAgentsMd: boolean;\n\treadonly memory: SuiteMemoryStrategy;\n\treadonly orientation: SuiteOrientation;\n\treadonly model: string | null;\n\treadonly thinking: string | null;\n\treadonly clonedFrom: SuiteClonedFrom | null;\n\t/**\n\t * Factory contents revision this declaration was written at (M4). Builtin\n\t * declarations carry it; on-disk builtin suite.json may omit it (pre-M4\n\t * files parse as FACTORY_CONTENTS_VERSION). User suites are outside factory\n\t * upgrade governance: the key stays optional and may be absent.\n\t */\n\treadonly factoryRevision?: number;\n}\n\nconst EMPTY_ASSOCIATIONS: SuiteAssociations = { skills: [], mcp: [], plugins: [], roles: [] };\n\n/**\n * 默认方案关联的子代理角色(开箱即用):这两个 id 对应工厂种子落盘的两个普通角色文件\n * (`<agentDir>/roles/{explore,reviewer}.json`,用户可改可删)。工厂不在运行期回退到任何\n * 编译内的角色定义;删掉文件只会让该关联成为 dangling 诊断。\n */\nexport const DEFAULT_ROLE_ASSOCIATIONS: readonly string[] = [\"explore\", \"reviewer\"];\n\nconst assistantSuite: SuiteDefinition = {\n\tschemaVersion: SUITE_SCHEMA_VERSION,\n\tid: \"assistant\",\n\tname: \"Assistant\",\n\tbuiltin: true,\n\ttools: BUILTIN_SUITE_TOOLS,\n\tcapabilities: BUILTIN_SUITE_CAPABILITIES,\n\tassociations: { ...EMPTY_ASSOCIATIONS, roles: DEFAULT_ROLE_ASSOCIATIONS },\n\tinheritSystemAgentsMd: false,\n\tmemory: \"assistant\",\n\torientation: \"assistant\",\n\tmodel: null,\n\tthinking: null,\n\tclonedFrom: null,\n\tfactoryRevision: FACTORY_CONTENTS_VERSION,\n};\n\nconst codingSuite: SuiteDefinition = {\n\tschemaVersion: SUITE_SCHEMA_VERSION,\n\tid: \"coding\",\n\tname: \"Coding\",\n\tbuiltin: true,\n\ttools: BUILTIN_SUITE_TOOLS,\n\tcapabilities: BUILTIN_SUITE_CAPABILITIES,\n\tassociations: { ...EMPTY_ASSOCIATIONS, roles: DEFAULT_ROLE_ASSOCIATIONS },\n\tinheritSystemAgentsMd: false,\n\tmemory: \"code\",\n\torientation: \"coding\",\n\tmodel: null,\n\tthinking: null,\n\tclonedFrom: null,\n\tfactoryRevision: FACTORY_CONTENTS_VERSION,\n};\n\n/** The factory builtin pair: coding (factory default 尖刀) and assistant (fallback). */\nexport const BUILTIN_SUITES: readonly SuiteDefinition[] = [assistantSuite, codingSuite];\n\nexport function getBuiltinSuite(id: string): SuiteDefinition | undefined {\n\treturn BUILTIN_SUITES.find((suite) => suite.id === id);\n}\n\nexport function isBuiltinSuiteId(id: string): boolean {\n\treturn BUILTIN_SUITES.some((suite) => suite.id === id);\n}\n\nconst WINDOWS_RESERVED_IDS = new Set([\n\t\"con\",\n\t\"prn\",\n\t\"aux\",\n\t\"nul\",\n\t\"com1\",\n\t\"com2\",\n\t\"com3\",\n\t\"com4\",\n\t\"com5\",\n\t\"com6\",\n\t\"com7\",\n\t\"com8\",\n\t\"com9\",\n\t\"lpt1\",\n\t\"lpt2\",\n\t\"lpt3\",\n\t\"lpt4\",\n\t\"lpt5\",\n\t\"lpt6\",\n\t\"lpt7\",\n\t\"lpt8\",\n\t\"lpt9\",\n\t\"conin$\",\n\t\"conout$\",\n]);\n\n/** Suite id rule (设计 §9): `a-z0-9-`, no leading/trailing hyphen, no Windows reserved names. */\nexport function isValidSuiteId(id: string): boolean {\n\tif (id.length === 0 || id.length > SUITE_ID_MAX_LENGTH) return false;\n\tif (!/^[a-z0-9-]+$/.test(id)) return false;\n\tif (id.startsWith(\"-\") || id.endsWith(\"-\")) return false;\n\tif (WINDOWS_RESERVED_IDS.has(id)) return false;\n\treturn true;\n}\n\n/** Serializes a suite to the canonical suite.json text (stable field order, trailing newline). */\nexport function serializeSuiteJson(suite: SuiteDefinition): string {\n\tconst ordered = {\n\t\tschemaVersion: suite.schemaVersion,\n\t\tid: suite.id,\n\t\tname: suite.name,\n\t\tbuiltin: suite.builtin,\n\t\ttools: [...suite.tools],\n\t\tcapabilities: [...suite.capabilities],\n\t\tassociations: {\n\t\t\tskills: [...suite.associations.skills],\n\t\t\tmcp: [...suite.associations.mcp],\n\t\t\tplugins: [...suite.associations.plugins],\n\t\t\troles: [...suite.associations.roles],\n\t\t},\n\t\tinheritSystemAgentsMd: suite.inheritSystemAgentsMd,\n\t\tmemory: suite.memory,\n\t\torientation: suite.orientation,\n\t\tmodel: suite.model,\n\t\tthinking: suite.thinking,\n\t\tclonedFrom: suite.clonedFrom\n\t\t\t? { id: suite.clonedFrom.id, digest: suite.clonedFrom.digest, at: suite.clonedFrom.at }\n\t\t\t: null,\n\t\tfactoryRevision: suite.factoryRevision,\n\t};\n\treturn `${JSON.stringify(ordered, null, 2)}\\n`;\n}\n\nexport interface SuiteJsonParseResult {\n\treadonly valid: boolean;\n\treadonly suite?: SuiteDefinition;\n\treadonly errors: readonly string[];\n}\n\n/**\n * Parses suite.json text. Never throws: an invalid result carries every\n * validation error so callers can apply the corruption policy (设计 §9) —\n * builtin suites fall back to factory content, user suites fail fast.\n */\nexport function parseSuiteJson(\n\traw: string,\n\toptions: { expectedBuiltin?: boolean; expectedId?: string },\n): SuiteJsonParseResult {\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(raw);\n\t} catch (error) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terrors: [`invalid JSON: ${error instanceof Error ? error.message : String(error)}`],\n\t\t};\n\t}\n\treturn validateSuiteJson(value, options);\n}\n\nexport function validateSuiteJson(\n\tvalue: unknown,\n\toptions: { expectedBuiltin?: boolean; expectedId?: string } = {},\n): SuiteJsonParseResult {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\treturn { valid: false, errors: [\"suite.json must be a JSON object\"] };\n\t}\n\tconst record = value as Record<string, unknown>;\n\tconst errors: string[] = [];\n\n\tif (record.schemaVersion !== SUITE_SCHEMA_VERSION) {\n\t\terrors.push(`schemaVersion must be ${SUITE_SCHEMA_VERSION}, found ${JSON.stringify(record.schemaVersion)}`);\n\t}\n\n\t// Each field keeps a typed local: valid values land here, invalid ones only\n\t// contribute errors. The suite below is constructed exclusively when\n\t// `errors` is empty, so the fallbacks/coercions at that point are dead.\n\tconst idValue = record.id;\n\tconst id = typeof idValue === \"string\" && isValidSuiteId(idValue) ? idValue : undefined;\n\tif (id === undefined) {\n\t\terrors.push(\n\t\t\t`id must be a suite id (^[a-z0-9-]+$, no leading/trailing hyphen, Windows reserved names rejected), found ${JSON.stringify(idValue)}`,\n\t\t);\n\t} else if (options.expectedId !== undefined && id !== options.expectedId) {\n\t\terrors.push(`id \"${id}\" does not match the suite workspace directory id \"${options.expectedId}\"`);\n\t}\n\n\tconst nameValue = record.name;\n\tconst name = typeof nameValue === \"string\" && nameValue.trim().length > 0 ? nameValue : undefined;\n\tif (name === undefined) {\n\t\terrors.push(`name must be a non-empty string, found ${JSON.stringify(nameValue)}`);\n\t}\n\n\tconst builtinValue = record.builtin;\n\tconst builtin = typeof builtinValue === \"boolean\" ? builtinValue : undefined;\n\tif (builtin === undefined) {\n\t\terrors.push(`builtin must be a boolean, found ${JSON.stringify(builtinValue)}`);\n\t} else if (options.expectedBuiltin === true && builtin !== true) {\n\t\terrors.push(`builtin must be true for a builtin suite workspace, found ${builtin}`);\n\t}\n\n\tconst tools = readStringArray(record, \"tools\", errors);\n\tconst capabilities = readStringArray(record, \"capabilities\", errors);\n\tconst associations = readAssociations(record.associations, errors);\n\n\tconst inheritValue = record.inheritSystemAgentsMd;\n\tconst inheritSystemAgentsMd = typeof inheritValue === \"boolean\" ? inheritValue : undefined;\n\tif (inheritSystemAgentsMd === undefined) {\n\t\terrors.push(`inheritSystemAgentsMd must be a boolean, found ${JSON.stringify(inheritValue)}`);\n\t}\n\n\tconst memoryValue = record.memory;\n\tconst memory = memoryValue === \"assistant\" || memoryValue === \"code\" ? memoryValue : undefined;\n\tif (memory === undefined) {\n\t\terrors.push(`memory must be \"assistant\" or \"code\", found ${JSON.stringify(memoryValue)}`);\n\t}\n\n\tconst orientationValue = record.orientation;\n\tconst orientation =\n\t\torientationValue === \"assistant\" || orientationValue === \"coding\" || orientationValue === \"custom\"\n\t\t\t? orientationValue\n\t\t\t: undefined;\n\tif (orientationValue !== undefined && orientation === undefined) {\n\t\terrors.push(`orientation must be \"assistant\", \"coding\", or \"custom\", found ${JSON.stringify(orientationValue)}`);\n\t}\n\n\tconst model = readOptionalString(record, \"model\", errors);\n\tconst thinking = readOptionalString(record, \"thinking\", errors);\n\tconst clonedFrom = readClonedFrom(record.clonedFrom, errors);\n\tconst factoryRevision = readFactoryRevision(record.factoryRevision, options.expectedBuiltin === true, errors);\n\n\tif (errors.length > 0) return { valid: false, errors };\n\n\treturn {\n\t\tvalid: true,\n\t\terrors: [],\n\t\tsuite: {\n\t\t\tschemaVersion: SUITE_SCHEMA_VERSION,\n\t\t\tid: id!,\n\t\t\tname: name!,\n\t\t\tbuiltin: builtin!,\n\t\t\ttools,\n\t\t\tcapabilities,\n\t\t\tassociations,\n\t\t\tinheritSystemAgentsMd: inheritSystemAgentsMd!,\n\t\t\tmemory: memory!,\n\t\t\torientation: orientation ?? \"assistant\",\n\t\t\tmodel,\n\t\t\tthinking,\n\t\t\tclonedFrom,\n\t\t\t...(factoryRevision === undefined ? {} : { factoryRevision }),\n\t\t},\n\t};\n}\n\nfunction readStringArray(record: Record<string, unknown>, key: string, errors: string[]): readonly string[] {\n\tconst value = record[key];\n\tif (!Array.isArray(value)) {\n\t\terrors.push(`${key} must be an array of strings, found ${JSON.stringify(value)}`);\n\t\treturn [];\n\t}\n\tconst entries: string[] = [];\n\tconst seen = new Set<string>();\n\tfor (const item of value) {\n\t\tif (typeof item !== \"string\" || item.trim().length === 0) {\n\t\t\terrors.push(`${key} entries must be non-empty strings, found ${JSON.stringify(item)}`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (seen.has(item)) {\n\t\t\terrors.push(`${key} contains duplicate entry \"${item}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tseen.add(item);\n\t\tentries.push(item);\n\t}\n\treturn entries;\n}\n\nfunction readAssociations(value: unknown, errors: string[]): SuiteAssociations {\n\tif (value === undefined) return { skills: [], mcp: [], plugins: [], roles: [] };\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\terrors.push(\n\t\t\t`associations must be an object with skills/mcp/plugins/roles arrays, found ${JSON.stringify(value)}`,\n\t\t);\n\t\treturn { skills: [], mcp: [], plugins: [], roles: [] };\n\t}\n\tconst record = value as Record<string, unknown>;\n\t// A key left out entirely means an empty list, consistent with a fully\n\t// absent `associations` object; a key that is present but malformed still\n\t// reports its errors. The removed legacy `extensions` kind is ignored on\n\t// read (it lost its loader with the old ExtensionAPI surface).\n\treturn {\n\t\tskills: record.skills === undefined ? [] : readStringArray(record, \"skills\", errors),\n\t\tmcp: record.mcp === undefined ? [] : readStringArray(record, \"mcp\", errors),\n\t\tplugins: record.plugins === undefined ? [] : readStringArray(record, \"plugins\", errors),\n\t\troles: record.roles === undefined ? [] : readStringArray(record, \"roles\", errors),\n\t};\n}\n\nfunction readOptionalString(record: Record<string, unknown>, key: string, errors: string[]): string | null {\n\tconst value = record[key];\n\tif (value === undefined || value === null) return null;\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\terrors.push(`${key} must be a non-empty string or null, found ${JSON.stringify(value)}`);\n\t\treturn null;\n\t}\n\treturn value;\n}\n\n/**\n * Reads the optional `factoryRevision` key (M4). A missing key means\n * FACTORY_CONTENTS_VERSION for builtin workspaces (pre-M4 on-disk files stay\n * compatible) and stays absent for user suites (outside factory upgrade\n * governance). A present key must be a positive integer.\n */\nfunction readFactoryRevision(value: unknown, expectedBuiltin: boolean, errors: string[]): number | undefined {\n\tif (value === undefined) return expectedBuiltin ? FACTORY_CONTENTS_VERSION : undefined;\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0) {\n\t\terrors.push(`factoryRevision must be a positive integer, found ${JSON.stringify(value)}`);\n\t\treturn undefined;\n\t}\n\treturn value;\n}\n\nfunction readClonedFrom(value: unknown, errors: string[]): SuiteClonedFrom | null {\n\tif (value === undefined || value === null) return null;\n\tif (typeof value !== \"object\" || Array.isArray(value)) {\n\t\terrors.push(`clonedFrom must be an object with id/digest/at, found ${JSON.stringify(value)}`);\n\t\treturn null;\n\t}\n\tconst record = value as Record<string, unknown>;\n\tif (\n\t\ttypeof record.id !== \"string\" ||\n\t\trecord.id.trim().length === 0 ||\n\t\ttypeof record.digest !== \"string\" ||\n\t\trecord.digest.trim().length === 0 ||\n\t\ttypeof record.at !== \"number\" ||\n\t\t!Number.isSafeInteger(record.at)\n\t) {\n\t\terrors.push(\n\t\t\t`clonedFrom must be an object with non-empty id/digest strings and an integer at, found ${JSON.stringify(value)}`,\n\t\t);\n\t\treturn null;\n\t}\n\treturn { id: record.id, digest: record.digest, at: record.at };\n}\n"]}
@@ -86,7 +86,11 @@ export const BUILTIN_SUITE_TOOLS = [
86
86
  * unconfigured default answers `/share` with the explicit configuration
87
87
  * prompt — never an implicit Radius/Gist fallback. `builtin.workflow` joins
88
88
  * at goal/plan/todo-set parity (D-077, 2026-10-02: factory default install
89
- * plus this suite declaration, plugin form unchanged).
89
+ * plus this suite declaration, plugin form unchanged). `builtin.coding-tools`
90
+ * joins with the D-082 batch-1 tool split (2026-10-03): the default coding
91
+ * tools assemble from the `plugins/coding-tools` package through the bundled
92
+ * distribution channel (插件独立分发与启动装配设计 §4.9), not the install
93
+ * store.
90
94
  */
91
95
  export const BUILTIN_SUITE_CAPABILITIES = [
92
96
  "builtin.goal",
@@ -96,6 +100,7 @@ export const BUILTIN_SUITE_CAPABILITIES = [
96
100
  "builtin.memory",
97
101
  "builtin.session-share",
98
102
  "builtin.subagent-delegate",
103
+ "builtin.coding-tools",
99
104
  ];
100
105
  /**
101
106
  * Orientation persona texts injected into the system prompt (设计 §6.2, M2).
@@ -1 +1 @@
1
- {"version":3,"file":"builtin-suites.js","sourceRoot":"","sources":["../../src/profiles/builtin-suites.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Builtin suite (方案) declarations and suite.json (schemaVersion 1)\n * serialization, parsing, and validation — 方案系统设计.md v2 §5/§6/§9, M1a.\n *\n * Suites are pure data plus default policy: both builtin suites share the same\n * unrestricted tool surface and differ only in orientation and memory strategy\n * (the orientation persona text is injected into the system prompt, M2).\n * Nothing here touches the packages/agent kernel; association resolution is\n * declaration-only until M1b.\n */\n\nexport const SUITE_SCHEMA_VERSION = 1;\n\n/**\n * Factory contents revision (M4): the revision of the factory builtin\n * declarations, independent of SUITE_SCHEMA_VERSION. Bump it (and update both\n * builtin declarations' `factoryRevision`) whenever the factory contents\n * change; the registry upgrade proposal then offers `--suite-reset` for\n * workspaces still on an older revision. Suite schema evolution keeps using\n * SUITE_SCHEMA_VERSION.\n *\n * Revision 2 (统一修复轮集成收口, 2026-09-08): assistant and coding now share\n * the same active 8-tool surface in full-control — the sdk `suiteToolOverride`\n * DEFAULT_SUITE_ID exemption was removed (方案设计 §5 + user decision). Existing\n * workspaces provisioned at revision 1 receive the upgrade-proposal diagnostic\n * and adopt via `--suite-reset`.\n *\n * Revision 3 (2026-09-18): `builtin.session-share` joins both builtin suites\n * (开发计划 §216: session-share productized from the example plugin into a\n * first-party default-distributed capability) once the agent-dir config\n * channel for embedded capabilities landed\n * (`<agentDir>/capabilities/<short-id>.json`, see capabilities/builtin.ts).\n * Existing workspaces provisioned at revision 2 receive the upgrade-proposal\n * diagnostic and adopt via `--suite-reset`.\n *\n * Revision 4 (2026-09-18): `builtin.subagent-delegate` joins both builtin\n * suites — the first-party subagent delegation tool (`subagent_run`) now ships\n * by default in shared mode (zero extra processes; pooled runner processes stay\n * opt-in through the capability config channel). Existing workspaces\n * provisioned at revision 3 receive the upgrade-proposal diagnostic and adopt\n * via `--suite-reset`.\n *\n * Revision 5 (2026-09-20): subagent role profiles land on disk only\n * (`<agentDir>/roles/<id>.json` — the factory seeds explore/reviewer and never\n * overwrites user edits) and both builtin suites associate them by default via\n * the new `suite.associations.roles` field, with skill/MCP-isomorphic\n * visibility: unassociated roles stay invisible, associated-but-missing files\n * surface as dangling diagnostics. Existing workspaces provisioned at\n * revision 4 receive the upgrade-proposal diagnostic and adopt via\n * `--suite-reset`.\n *\n * Revision 6 (D-077, 2026-10-02): `builtin.workflow` joins both builtin suites\n * — the workflow orchestration plugin enters the factory bootstrap manifest\n * (ninth package) and the suite capability declaration at goal/plan/todo-set\n * parity, keeping its plugin form. Existing workspaces provisioned at revision\n * 5 receive the upgrade-proposal diagnostic and adopt via `--suite-reset`.\n */\nexport const FACTORY_CONTENTS_VERSION = 6;\n\n/**\n * Factory default suite used when no suite is configured anywhere (设计 §9).\n * 2026-10-02 user ruling: the product is a coding agent, so the factory\n * default flipped from \"assistant\" to \"coding\"; assistant stays as the\n * explicit-switch fallback suite.\n */\nexport const DEFAULT_SUITE_ID = \"coding\";\n\n/** Suite ids become directory names: lowercase letters, digits, hyphens (设计 §9). */\nexport const SUITE_ID_MAX_LENGTH = 64;\n\n/** The single unrestricted tool surface shared by both builtin suites (设计 §5/§6). */\nexport const BUILTIN_SUITE_TOOLS: readonly string[] = [\n\t\"read\",\n\t\"write\",\n\t\"edit\",\n\t\"bash\",\n\t\"ls\",\n\t\"find\",\n\t\"grep\",\n\t\"powershell\",\n];\n\n/**\n * Builtin capability plugins associated with both suites. Declaration-only\n * data in M1a; the actual plugin wiring is delivered in M3. `builtin.memory`\n * joins in the 统一修复轮 A 路 (方案系统设计 §6.1: both suites share the same\n * memory tool surface; the strategy difference lives in the suiteId domain\n * isolation and the assistant preference card). `builtin.session-share` joins\n * in the session-share productization slice (开发计划 §216); its\n * target/gateway/viewerUrl are configured through the agent-dir config\n * channel (`<agentDir>/capabilities/builtin.session-share.json`), and the\n * unconfigured default answers `/share` with the explicit configuration\n * prompt — never an implicit Radius/Gist fallback. `builtin.workflow` joins\n * at goal/plan/todo-set parity (D-077, 2026-10-02: factory default install\n * plus this suite declaration, plugin form unchanged).\n */\nexport const BUILTIN_SUITE_CAPABILITIES: readonly string[] = [\n\t\"builtin.goal\",\n\t\"builtin.plan\",\n\t\"builtin.todo-set\",\n\t\"builtin.workflow\",\n\t\"builtin.memory\",\n\t\"builtin.session-share\",\n\t\"builtin.subagent-delegate\",\n];\n\nexport type SuiteMemoryStrategy = \"assistant\" | \"code\";\nexport type SuiteOrientation = \"assistant\" | \"coding\" | \"custom\";\n\n/**\n * Orientation persona texts injected into the system prompt (设计 §6.2, M2).\n * The strings are verbatim from the design spec: the assistant persona is the\n * companion style, the coding persona is the rigor-first style. Both are\n * session-nature declarations, so they ride every system prompt branch\n * (default and customPrompt). The custom orientation is not in this table: its\n * persona text comes from the suite workspace persona.md (设计 §6.3, resolved\n * by suite-loader).\n */\nexport const ORIENTATION_PROMPTS: Record<\"assistant\" | \"coding\", string> = {\n\tassistant: `You are the user's thoughtful companion — warm, patient, and helpful.\n- Understand the intent behind the question, including the unspoken parts; when something that matters is ambiguous, ask one short clarifying question instead of assuming.\n- Pay attention to detail: notice what the user might have missed and gently point it out.\n- Be proactive and divergent: after answering, offer next steps, related ideas, or creative alternatives — without being pushy.\n- Adapt tone to the user; stay natural and flexible, never robotic or formulaic.\n- When you can help by doing, act through tools autonomously (minimal interruption).\n- Structure longer answers clearly: short paragraphs, lists where they help, and a concrete \"what you can do next\" at the end.`,\n\tcoding: `You are an autonomous software engineering agent with a rigor-first mindset.\n- Never guess. Ground every claim in code you have read, commands you have run, or documented evidence; cite file paths and line numbers. If the evidence is insufficient, investigate, and report what is unverified — or \"unknown\" — instead of a plausible invention.\n- First principles: trace problems to the earliest reasonable root cause and fix that; do not patch symptoms.\n- No over-engineering: add no abstraction, options, or defensive handling for imagined future needs; generalise only when a second concrete case demands it.\n- Tests first: pin expected behavior with a failing or updated test before or alongside the fix, then run the smallest sufficient relevant checks; the work is not done until they pass.\n- Reproducible: prefer deterministic tests and mocks over ad-hoc verification, and report the exact commands and results so others can re-run them.\n- Docs as code: repository documentation is part of the change — keep design docs, READMEs, and changelogs consistent with the behavior they describe.\n- Self-review before finishing: re-check your changes for correctness, edge cases, regressions, and missing tests; prefer a second review pass over shipping the first draft.\n- Cautious: weigh side effects, compatibility, and failure modes; when in doubt, take the safer path.`,\n};\n\nexport interface SuiteAssociations {\n\treadonly skills: readonly string[];\n\treadonly mcp: readonly string[];\n\treadonly plugins: readonly string[];\n\t/**\n\t * 子代理角色关联(D-044 角色机制):关联的是 `<agentDir>/roles/<id>.json` 里的角色 id。\n\t * 角色定义只在磁盘上(工厂仅做种子落盘),方案只决定哪些角色对主代理可见——与\n\t * skill/MCP/插件同构,第一方与第三方角色没有区别。\n\t */\n\treadonly roles: readonly string[];\n}\n\nexport interface SuiteClonedFrom {\n\treadonly id: string;\n\treadonly digest: string;\n\treadonly at: number;\n}\n\n/** The serializable suite definition persisted as suite.json (设计 §5). */\nexport interface SuiteDefinition {\n\treadonly schemaVersion: number;\n\treadonly id: string;\n\treadonly name: string;\n\treadonly builtin: boolean;\n\treadonly tools: readonly string[];\n\treadonly capabilities: readonly string[];\n\treadonly associations: SuiteAssociations;\n\treadonly inheritSystemAgentsMd: boolean;\n\treadonly memory: SuiteMemoryStrategy;\n\treadonly orientation: SuiteOrientation;\n\treadonly model: string | null;\n\treadonly thinking: string | null;\n\treadonly clonedFrom: SuiteClonedFrom | null;\n\t/**\n\t * Factory contents revision this declaration was written at (M4). Builtin\n\t * declarations carry it; on-disk builtin suite.json may omit it (pre-M4\n\t * files parse as FACTORY_CONTENTS_VERSION). User suites are outside factory\n\t * upgrade governance: the key stays optional and may be absent.\n\t */\n\treadonly factoryRevision?: number;\n}\n\nconst EMPTY_ASSOCIATIONS: SuiteAssociations = { skills: [], mcp: [], plugins: [], roles: [] };\n\n/**\n * 默认方案关联的子代理角色(开箱即用):这两个 id 对应工厂种子落盘的两个普通角色文件\n * (`<agentDir>/roles/{explore,reviewer}.json`,用户可改可删)。工厂不在运行期回退到任何\n * 编译内的角色定义;删掉文件只会让该关联成为 dangling 诊断。\n */\nexport const DEFAULT_ROLE_ASSOCIATIONS: readonly string[] = [\"explore\", \"reviewer\"];\n\nconst assistantSuite: SuiteDefinition = {\n\tschemaVersion: SUITE_SCHEMA_VERSION,\n\tid: \"assistant\",\n\tname: \"Assistant\",\n\tbuiltin: true,\n\ttools: BUILTIN_SUITE_TOOLS,\n\tcapabilities: BUILTIN_SUITE_CAPABILITIES,\n\tassociations: { ...EMPTY_ASSOCIATIONS, roles: DEFAULT_ROLE_ASSOCIATIONS },\n\tinheritSystemAgentsMd: false,\n\tmemory: \"assistant\",\n\torientation: \"assistant\",\n\tmodel: null,\n\tthinking: null,\n\tclonedFrom: null,\n\tfactoryRevision: FACTORY_CONTENTS_VERSION,\n};\n\nconst codingSuite: SuiteDefinition = {\n\tschemaVersion: SUITE_SCHEMA_VERSION,\n\tid: \"coding\",\n\tname: \"Coding\",\n\tbuiltin: true,\n\ttools: BUILTIN_SUITE_TOOLS,\n\tcapabilities: BUILTIN_SUITE_CAPABILITIES,\n\tassociations: { ...EMPTY_ASSOCIATIONS, roles: DEFAULT_ROLE_ASSOCIATIONS },\n\tinheritSystemAgentsMd: false,\n\tmemory: \"code\",\n\torientation: \"coding\",\n\tmodel: null,\n\tthinking: null,\n\tclonedFrom: null,\n\tfactoryRevision: FACTORY_CONTENTS_VERSION,\n};\n\n/** The factory builtin pair: coding (factory default 尖刀) and assistant (fallback). */\nexport const BUILTIN_SUITES: readonly SuiteDefinition[] = [assistantSuite, codingSuite];\n\nexport function getBuiltinSuite(id: string): SuiteDefinition | undefined {\n\treturn BUILTIN_SUITES.find((suite) => suite.id === id);\n}\n\nexport function isBuiltinSuiteId(id: string): boolean {\n\treturn BUILTIN_SUITES.some((suite) => suite.id === id);\n}\n\nconst WINDOWS_RESERVED_IDS = new Set([\n\t\"con\",\n\t\"prn\",\n\t\"aux\",\n\t\"nul\",\n\t\"com1\",\n\t\"com2\",\n\t\"com3\",\n\t\"com4\",\n\t\"com5\",\n\t\"com6\",\n\t\"com7\",\n\t\"com8\",\n\t\"com9\",\n\t\"lpt1\",\n\t\"lpt2\",\n\t\"lpt3\",\n\t\"lpt4\",\n\t\"lpt5\",\n\t\"lpt6\",\n\t\"lpt7\",\n\t\"lpt8\",\n\t\"lpt9\",\n\t\"conin$\",\n\t\"conout$\",\n]);\n\n/** Suite id rule (设计 §9): `a-z0-9-`, no leading/trailing hyphen, no Windows reserved names. */\nexport function isValidSuiteId(id: string): boolean {\n\tif (id.length === 0 || id.length > SUITE_ID_MAX_LENGTH) return false;\n\tif (!/^[a-z0-9-]+$/.test(id)) return false;\n\tif (id.startsWith(\"-\") || id.endsWith(\"-\")) return false;\n\tif (WINDOWS_RESERVED_IDS.has(id)) return false;\n\treturn true;\n}\n\n/** Serializes a suite to the canonical suite.json text (stable field order, trailing newline). */\nexport function serializeSuiteJson(suite: SuiteDefinition): string {\n\tconst ordered = {\n\t\tschemaVersion: suite.schemaVersion,\n\t\tid: suite.id,\n\t\tname: suite.name,\n\t\tbuiltin: suite.builtin,\n\t\ttools: [...suite.tools],\n\t\tcapabilities: [...suite.capabilities],\n\t\tassociations: {\n\t\t\tskills: [...suite.associations.skills],\n\t\t\tmcp: [...suite.associations.mcp],\n\t\t\tplugins: [...suite.associations.plugins],\n\t\t\troles: [...suite.associations.roles],\n\t\t},\n\t\tinheritSystemAgentsMd: suite.inheritSystemAgentsMd,\n\t\tmemory: suite.memory,\n\t\torientation: suite.orientation,\n\t\tmodel: suite.model,\n\t\tthinking: suite.thinking,\n\t\tclonedFrom: suite.clonedFrom\n\t\t\t? { id: suite.clonedFrom.id, digest: suite.clonedFrom.digest, at: suite.clonedFrom.at }\n\t\t\t: null,\n\t\tfactoryRevision: suite.factoryRevision,\n\t};\n\treturn `${JSON.stringify(ordered, null, 2)}\\n`;\n}\n\nexport interface SuiteJsonParseResult {\n\treadonly valid: boolean;\n\treadonly suite?: SuiteDefinition;\n\treadonly errors: readonly string[];\n}\n\n/**\n * Parses suite.json text. Never throws: an invalid result carries every\n * validation error so callers can apply the corruption policy (设计 §9) —\n * builtin suites fall back to factory content, user suites fail fast.\n */\nexport function parseSuiteJson(\n\traw: string,\n\toptions: { expectedBuiltin?: boolean; expectedId?: string },\n): SuiteJsonParseResult {\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(raw);\n\t} catch (error) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terrors: [`invalid JSON: ${error instanceof Error ? error.message : String(error)}`],\n\t\t};\n\t}\n\treturn validateSuiteJson(value, options);\n}\n\nexport function validateSuiteJson(\n\tvalue: unknown,\n\toptions: { expectedBuiltin?: boolean; expectedId?: string } = {},\n): SuiteJsonParseResult {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\treturn { valid: false, errors: [\"suite.json must be a JSON object\"] };\n\t}\n\tconst record = value as Record<string, unknown>;\n\tconst errors: string[] = [];\n\n\tif (record.schemaVersion !== SUITE_SCHEMA_VERSION) {\n\t\terrors.push(`schemaVersion must be ${SUITE_SCHEMA_VERSION}, found ${JSON.stringify(record.schemaVersion)}`);\n\t}\n\n\t// Each field keeps a typed local: valid values land here, invalid ones only\n\t// contribute errors. The suite below is constructed exclusively when\n\t// `errors` is empty, so the fallbacks/coercions at that point are dead.\n\tconst idValue = record.id;\n\tconst id = typeof idValue === \"string\" && isValidSuiteId(idValue) ? idValue : undefined;\n\tif (id === undefined) {\n\t\terrors.push(\n\t\t\t`id must be a suite id (^[a-z0-9-]+$, no leading/trailing hyphen, Windows reserved names rejected), found ${JSON.stringify(idValue)}`,\n\t\t);\n\t} else if (options.expectedId !== undefined && id !== options.expectedId) {\n\t\terrors.push(`id \"${id}\" does not match the suite workspace directory id \"${options.expectedId}\"`);\n\t}\n\n\tconst nameValue = record.name;\n\tconst name = typeof nameValue === \"string\" && nameValue.trim().length > 0 ? nameValue : undefined;\n\tif (name === undefined) {\n\t\terrors.push(`name must be a non-empty string, found ${JSON.stringify(nameValue)}`);\n\t}\n\n\tconst builtinValue = record.builtin;\n\tconst builtin = typeof builtinValue === \"boolean\" ? builtinValue : undefined;\n\tif (builtin === undefined) {\n\t\terrors.push(`builtin must be a boolean, found ${JSON.stringify(builtinValue)}`);\n\t} else if (options.expectedBuiltin === true && builtin !== true) {\n\t\terrors.push(`builtin must be true for a builtin suite workspace, found ${builtin}`);\n\t}\n\n\tconst tools = readStringArray(record, \"tools\", errors);\n\tconst capabilities = readStringArray(record, \"capabilities\", errors);\n\tconst associations = readAssociations(record.associations, errors);\n\n\tconst inheritValue = record.inheritSystemAgentsMd;\n\tconst inheritSystemAgentsMd = typeof inheritValue === \"boolean\" ? inheritValue : undefined;\n\tif (inheritSystemAgentsMd === undefined) {\n\t\terrors.push(`inheritSystemAgentsMd must be a boolean, found ${JSON.stringify(inheritValue)}`);\n\t}\n\n\tconst memoryValue = record.memory;\n\tconst memory = memoryValue === \"assistant\" || memoryValue === \"code\" ? memoryValue : undefined;\n\tif (memory === undefined) {\n\t\terrors.push(`memory must be \"assistant\" or \"code\", found ${JSON.stringify(memoryValue)}`);\n\t}\n\n\tconst orientationValue = record.orientation;\n\tconst orientation =\n\t\torientationValue === \"assistant\" || orientationValue === \"coding\" || orientationValue === \"custom\"\n\t\t\t? orientationValue\n\t\t\t: undefined;\n\tif (orientationValue !== undefined && orientation === undefined) {\n\t\terrors.push(`orientation must be \"assistant\", \"coding\", or \"custom\", found ${JSON.stringify(orientationValue)}`);\n\t}\n\n\tconst model = readOptionalString(record, \"model\", errors);\n\tconst thinking = readOptionalString(record, \"thinking\", errors);\n\tconst clonedFrom = readClonedFrom(record.clonedFrom, errors);\n\tconst factoryRevision = readFactoryRevision(record.factoryRevision, options.expectedBuiltin === true, errors);\n\n\tif (errors.length > 0) return { valid: false, errors };\n\n\treturn {\n\t\tvalid: true,\n\t\terrors: [],\n\t\tsuite: {\n\t\t\tschemaVersion: SUITE_SCHEMA_VERSION,\n\t\t\tid: id!,\n\t\t\tname: name!,\n\t\t\tbuiltin: builtin!,\n\t\t\ttools,\n\t\t\tcapabilities,\n\t\t\tassociations,\n\t\t\tinheritSystemAgentsMd: inheritSystemAgentsMd!,\n\t\t\tmemory: memory!,\n\t\t\torientation: orientation ?? \"assistant\",\n\t\t\tmodel,\n\t\t\tthinking,\n\t\t\tclonedFrom,\n\t\t\t...(factoryRevision === undefined ? {} : { factoryRevision }),\n\t\t},\n\t};\n}\n\nfunction readStringArray(record: Record<string, unknown>, key: string, errors: string[]): readonly string[] {\n\tconst value = record[key];\n\tif (!Array.isArray(value)) {\n\t\terrors.push(`${key} must be an array of strings, found ${JSON.stringify(value)}`);\n\t\treturn [];\n\t}\n\tconst entries: string[] = [];\n\tconst seen = new Set<string>();\n\tfor (const item of value) {\n\t\tif (typeof item !== \"string\" || item.trim().length === 0) {\n\t\t\terrors.push(`${key} entries must be non-empty strings, found ${JSON.stringify(item)}`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (seen.has(item)) {\n\t\t\terrors.push(`${key} contains duplicate entry \"${item}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tseen.add(item);\n\t\tentries.push(item);\n\t}\n\treturn entries;\n}\n\nfunction readAssociations(value: unknown, errors: string[]): SuiteAssociations {\n\tif (value === undefined) return { skills: [], mcp: [], plugins: [], roles: [] };\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\terrors.push(\n\t\t\t`associations must be an object with skills/mcp/plugins/roles arrays, found ${JSON.stringify(value)}`,\n\t\t);\n\t\treturn { skills: [], mcp: [], plugins: [], roles: [] };\n\t}\n\tconst record = value as Record<string, unknown>;\n\t// A key left out entirely means an empty list, consistent with a fully\n\t// absent `associations` object; a key that is present but malformed still\n\t// reports its errors. The removed legacy `extensions` kind is ignored on\n\t// read (it lost its loader with the old ExtensionAPI surface).\n\treturn {\n\t\tskills: record.skills === undefined ? [] : readStringArray(record, \"skills\", errors),\n\t\tmcp: record.mcp === undefined ? [] : readStringArray(record, \"mcp\", errors),\n\t\tplugins: record.plugins === undefined ? [] : readStringArray(record, \"plugins\", errors),\n\t\troles: record.roles === undefined ? [] : readStringArray(record, \"roles\", errors),\n\t};\n}\n\nfunction readOptionalString(record: Record<string, unknown>, key: string, errors: string[]): string | null {\n\tconst value = record[key];\n\tif (value === undefined || value === null) return null;\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\terrors.push(`${key} must be a non-empty string or null, found ${JSON.stringify(value)}`);\n\t\treturn null;\n\t}\n\treturn value;\n}\n\n/**\n * Reads the optional `factoryRevision` key (M4). A missing key means\n * FACTORY_CONTENTS_VERSION for builtin workspaces (pre-M4 on-disk files stay\n * compatible) and stays absent for user suites (outside factory upgrade\n * governance). A present key must be a positive integer.\n */\nfunction readFactoryRevision(value: unknown, expectedBuiltin: boolean, errors: string[]): number | undefined {\n\tif (value === undefined) return expectedBuiltin ? FACTORY_CONTENTS_VERSION : undefined;\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0) {\n\t\terrors.push(`factoryRevision must be a positive integer, found ${JSON.stringify(value)}`);\n\t\treturn undefined;\n\t}\n\treturn value;\n}\n\nfunction readClonedFrom(value: unknown, errors: string[]): SuiteClonedFrom | null {\n\tif (value === undefined || value === null) return null;\n\tif (typeof value !== \"object\" || Array.isArray(value)) {\n\t\terrors.push(`clonedFrom must be an object with id/digest/at, found ${JSON.stringify(value)}`);\n\t\treturn null;\n\t}\n\tconst record = value as Record<string, unknown>;\n\tif (\n\t\ttypeof record.id !== \"string\" ||\n\t\trecord.id.trim().length === 0 ||\n\t\ttypeof record.digest !== \"string\" ||\n\t\trecord.digest.trim().length === 0 ||\n\t\ttypeof record.at !== \"number\" ||\n\t\t!Number.isSafeInteger(record.at)\n\t) {\n\t\terrors.push(\n\t\t\t`clonedFrom must be an object with non-empty id/digest strings and an integer at, found ${JSON.stringify(value)}`,\n\t\t);\n\t\treturn null;\n\t}\n\treturn { id: record.id, digest: record.digest, at: record.at };\n}\n"]}
1
+ {"version":3,"file":"builtin-suites.js","sourceRoot":"","sources":["../../src/profiles/builtin-suites.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Builtin suite (方案) declarations and suite.json (schemaVersion 1)\n * serialization, parsing, and validation — 方案系统设计.md v2 §5/§6/§9, M1a.\n *\n * Suites are pure data plus default policy: both builtin suites share the same\n * unrestricted tool surface and differ only in orientation and memory strategy\n * (the orientation persona text is injected into the system prompt, M2).\n * Nothing here touches the packages/agent kernel; association resolution is\n * declaration-only until M1b.\n */\n\nexport const SUITE_SCHEMA_VERSION = 1;\n\n/**\n * Factory contents revision (M4): the revision of the factory builtin\n * declarations, independent of SUITE_SCHEMA_VERSION. Bump it (and update both\n * builtin declarations' `factoryRevision`) whenever the factory contents\n * change; the registry upgrade proposal then offers `--suite-reset` for\n * workspaces still on an older revision. Suite schema evolution keeps using\n * SUITE_SCHEMA_VERSION.\n *\n * Revision 2 (统一修复轮集成收口, 2026-09-08): assistant and coding now share\n * the same active 8-tool surface in full-control — the sdk `suiteToolOverride`\n * DEFAULT_SUITE_ID exemption was removed (方案设计 §5 + user decision). Existing\n * workspaces provisioned at revision 1 receive the upgrade-proposal diagnostic\n * and adopt via `--suite-reset`.\n *\n * Revision 3 (2026-09-18): `builtin.session-share` joins both builtin suites\n * (开发计划 §216: session-share productized from the example plugin into a\n * first-party default-distributed capability) once the agent-dir config\n * channel for embedded capabilities landed\n * (`<agentDir>/capabilities/<short-id>.json`, see capabilities/builtin.ts).\n * Existing workspaces provisioned at revision 2 receive the upgrade-proposal\n * diagnostic and adopt via `--suite-reset`.\n *\n * Revision 4 (2026-09-18): `builtin.subagent-delegate` joins both builtin\n * suites — the first-party subagent delegation tool (`subagent_run`) now ships\n * by default in shared mode (zero extra processes; pooled runner processes stay\n * opt-in through the capability config channel). Existing workspaces\n * provisioned at revision 3 receive the upgrade-proposal diagnostic and adopt\n * via `--suite-reset`.\n *\n * Revision 5 (2026-09-20): subagent role profiles land on disk only\n * (`<agentDir>/roles/<id>.json` — the factory seeds explore/reviewer and never\n * overwrites user edits) and both builtin suites associate them by default via\n * the new `suite.associations.roles` field, with skill/MCP-isomorphic\n * visibility: unassociated roles stay invisible, associated-but-missing files\n * surface as dangling diagnostics. Existing workspaces provisioned at\n * revision 4 receive the upgrade-proposal diagnostic and adopt via\n * `--suite-reset`.\n *\n * Revision 6 (D-077, 2026-10-02): `builtin.workflow` joins both builtin suites\n * — the workflow orchestration plugin enters the factory bootstrap manifest\n * (ninth package) and the suite capability declaration at goal/plan/todo-set\n * parity, keeping its plugin form. Existing workspaces provisioned at revision\n * 5 receive the upgrade-proposal diagnostic and adopt via `--suite-reset`.\n */\nexport const FACTORY_CONTENTS_VERSION = 6;\n\n/**\n * Factory default suite used when no suite is configured anywhere (设计 §9).\n * 2026-10-02 user ruling: the product is a coding agent, so the factory\n * default flipped from \"assistant\" to \"coding\"; assistant stays as the\n * explicit-switch fallback suite.\n */\nexport const DEFAULT_SUITE_ID = \"coding\";\n\n/** Suite ids become directory names: lowercase letters, digits, hyphens (设计 §9). */\nexport const SUITE_ID_MAX_LENGTH = 64;\n\n/** The single unrestricted tool surface shared by both builtin suites (设计 §5/§6). */\nexport const BUILTIN_SUITE_TOOLS: readonly string[] = [\n\t\"read\",\n\t\"write\",\n\t\"edit\",\n\t\"bash\",\n\t\"ls\",\n\t\"find\",\n\t\"grep\",\n\t\"powershell\",\n];\n\n/**\n * Builtin capability plugins associated with both suites. Declaration-only\n * data in M1a; the actual plugin wiring is delivered in M3. `builtin.memory`\n * joins in the 统一修复轮 A 路 (方案系统设计 §6.1: both suites share the same\n * memory tool surface; the strategy difference lives in the suiteId domain\n * isolation and the assistant preference card). `builtin.session-share` joins\n * in the session-share productization slice (开发计划 §216); its\n * target/gateway/viewerUrl are configured through the agent-dir config\n * channel (`<agentDir>/capabilities/builtin.session-share.json`), and the\n * unconfigured default answers `/share` with the explicit configuration\n * prompt — never an implicit Radius/Gist fallback. `builtin.workflow` joins\n * at goal/plan/todo-set parity (D-077, 2026-10-02: factory default install\n * plus this suite declaration, plugin form unchanged). `builtin.coding-tools`\n * joins with the D-082 batch-1 tool split (2026-10-03): the default coding\n * tools assemble from the `plugins/coding-tools` package through the bundled\n * distribution channel (插件独立分发与启动装配设计 §4.9), not the install\n * store.\n */\nexport const BUILTIN_SUITE_CAPABILITIES: readonly string[] = [\n\t\"builtin.goal\",\n\t\"builtin.plan\",\n\t\"builtin.todo-set\",\n\t\"builtin.workflow\",\n\t\"builtin.memory\",\n\t\"builtin.session-share\",\n\t\"builtin.subagent-delegate\",\n\t\"builtin.coding-tools\",\n];\n\nexport type SuiteMemoryStrategy = \"assistant\" | \"code\";\nexport type SuiteOrientation = \"assistant\" | \"coding\" | \"custom\";\n\n/**\n * Orientation persona texts injected into the system prompt (设计 §6.2, M2).\n * The strings are verbatim from the design spec: the assistant persona is the\n * companion style, the coding persona is the rigor-first style. Both are\n * session-nature declarations, so they ride every system prompt branch\n * (default and customPrompt). The custom orientation is not in this table: its\n * persona text comes from the suite workspace persona.md (设计 §6.3, resolved\n * by suite-loader).\n */\nexport const ORIENTATION_PROMPTS: Record<\"assistant\" | \"coding\", string> = {\n\tassistant: `You are the user's thoughtful companion — warm, patient, and helpful.\n- Understand the intent behind the question, including the unspoken parts; when something that matters is ambiguous, ask one short clarifying question instead of assuming.\n- Pay attention to detail: notice what the user might have missed and gently point it out.\n- Be proactive and divergent: after answering, offer next steps, related ideas, or creative alternatives — without being pushy.\n- Adapt tone to the user; stay natural and flexible, never robotic or formulaic.\n- When you can help by doing, act through tools autonomously (minimal interruption).\n- Structure longer answers clearly: short paragraphs, lists where they help, and a concrete \"what you can do next\" at the end.`,\n\tcoding: `You are an autonomous software engineering agent with a rigor-first mindset.\n- Never guess. Ground every claim in code you have read, commands you have run, or documented evidence; cite file paths and line numbers. If the evidence is insufficient, investigate, and report what is unverified — or \"unknown\" — instead of a plausible invention.\n- First principles: trace problems to the earliest reasonable root cause and fix that; do not patch symptoms.\n- No over-engineering: add no abstraction, options, or defensive handling for imagined future needs; generalise only when a second concrete case demands it.\n- Tests first: pin expected behavior with a failing or updated test before or alongside the fix, then run the smallest sufficient relevant checks; the work is not done until they pass.\n- Reproducible: prefer deterministic tests and mocks over ad-hoc verification, and report the exact commands and results so others can re-run them.\n- Docs as code: repository documentation is part of the change — keep design docs, READMEs, and changelogs consistent with the behavior they describe.\n- Self-review before finishing: re-check your changes for correctness, edge cases, regressions, and missing tests; prefer a second review pass over shipping the first draft.\n- Cautious: weigh side effects, compatibility, and failure modes; when in doubt, take the safer path.`,\n};\n\nexport interface SuiteAssociations {\n\treadonly skills: readonly string[];\n\treadonly mcp: readonly string[];\n\treadonly plugins: readonly string[];\n\t/**\n\t * 子代理角色关联(D-044 角色机制):关联的是 `<agentDir>/roles/<id>.json` 里的角色 id。\n\t * 角色定义只在磁盘上(工厂仅做种子落盘),方案只决定哪些角色对主代理可见——与\n\t * skill/MCP/插件同构,第一方与第三方角色没有区别。\n\t */\n\treadonly roles: readonly string[];\n}\n\nexport interface SuiteClonedFrom {\n\treadonly id: string;\n\treadonly digest: string;\n\treadonly at: number;\n}\n\n/** The serializable suite definition persisted as suite.json (设计 §5). */\nexport interface SuiteDefinition {\n\treadonly schemaVersion: number;\n\treadonly id: string;\n\treadonly name: string;\n\treadonly builtin: boolean;\n\treadonly tools: readonly string[];\n\treadonly capabilities: readonly string[];\n\treadonly associations: SuiteAssociations;\n\treadonly inheritSystemAgentsMd: boolean;\n\treadonly memory: SuiteMemoryStrategy;\n\treadonly orientation: SuiteOrientation;\n\treadonly model: string | null;\n\treadonly thinking: string | null;\n\treadonly clonedFrom: SuiteClonedFrom | null;\n\t/**\n\t * Factory contents revision this declaration was written at (M4). Builtin\n\t * declarations carry it; on-disk builtin suite.json may omit it (pre-M4\n\t * files parse as FACTORY_CONTENTS_VERSION). User suites are outside factory\n\t * upgrade governance: the key stays optional and may be absent.\n\t */\n\treadonly factoryRevision?: number;\n}\n\nconst EMPTY_ASSOCIATIONS: SuiteAssociations = { skills: [], mcp: [], plugins: [], roles: [] };\n\n/**\n * 默认方案关联的子代理角色(开箱即用):这两个 id 对应工厂种子落盘的两个普通角色文件\n * (`<agentDir>/roles/{explore,reviewer}.json`,用户可改可删)。工厂不在运行期回退到任何\n * 编译内的角色定义;删掉文件只会让该关联成为 dangling 诊断。\n */\nexport const DEFAULT_ROLE_ASSOCIATIONS: readonly string[] = [\"explore\", \"reviewer\"];\n\nconst assistantSuite: SuiteDefinition = {\n\tschemaVersion: SUITE_SCHEMA_VERSION,\n\tid: \"assistant\",\n\tname: \"Assistant\",\n\tbuiltin: true,\n\ttools: BUILTIN_SUITE_TOOLS,\n\tcapabilities: BUILTIN_SUITE_CAPABILITIES,\n\tassociations: { ...EMPTY_ASSOCIATIONS, roles: DEFAULT_ROLE_ASSOCIATIONS },\n\tinheritSystemAgentsMd: false,\n\tmemory: \"assistant\",\n\torientation: \"assistant\",\n\tmodel: null,\n\tthinking: null,\n\tclonedFrom: null,\n\tfactoryRevision: FACTORY_CONTENTS_VERSION,\n};\n\nconst codingSuite: SuiteDefinition = {\n\tschemaVersion: SUITE_SCHEMA_VERSION,\n\tid: \"coding\",\n\tname: \"Coding\",\n\tbuiltin: true,\n\ttools: BUILTIN_SUITE_TOOLS,\n\tcapabilities: BUILTIN_SUITE_CAPABILITIES,\n\tassociations: { ...EMPTY_ASSOCIATIONS, roles: DEFAULT_ROLE_ASSOCIATIONS },\n\tinheritSystemAgentsMd: false,\n\tmemory: \"code\",\n\torientation: \"coding\",\n\tmodel: null,\n\tthinking: null,\n\tclonedFrom: null,\n\tfactoryRevision: FACTORY_CONTENTS_VERSION,\n};\n\n/** The factory builtin pair: coding (factory default 尖刀) and assistant (fallback). */\nexport const BUILTIN_SUITES: readonly SuiteDefinition[] = [assistantSuite, codingSuite];\n\nexport function getBuiltinSuite(id: string): SuiteDefinition | undefined {\n\treturn BUILTIN_SUITES.find((suite) => suite.id === id);\n}\n\nexport function isBuiltinSuiteId(id: string): boolean {\n\treturn BUILTIN_SUITES.some((suite) => suite.id === id);\n}\n\nconst WINDOWS_RESERVED_IDS = new Set([\n\t\"con\",\n\t\"prn\",\n\t\"aux\",\n\t\"nul\",\n\t\"com1\",\n\t\"com2\",\n\t\"com3\",\n\t\"com4\",\n\t\"com5\",\n\t\"com6\",\n\t\"com7\",\n\t\"com8\",\n\t\"com9\",\n\t\"lpt1\",\n\t\"lpt2\",\n\t\"lpt3\",\n\t\"lpt4\",\n\t\"lpt5\",\n\t\"lpt6\",\n\t\"lpt7\",\n\t\"lpt8\",\n\t\"lpt9\",\n\t\"conin$\",\n\t\"conout$\",\n]);\n\n/** Suite id rule (设计 §9): `a-z0-9-`, no leading/trailing hyphen, no Windows reserved names. */\nexport function isValidSuiteId(id: string): boolean {\n\tif (id.length === 0 || id.length > SUITE_ID_MAX_LENGTH) return false;\n\tif (!/^[a-z0-9-]+$/.test(id)) return false;\n\tif (id.startsWith(\"-\") || id.endsWith(\"-\")) return false;\n\tif (WINDOWS_RESERVED_IDS.has(id)) return false;\n\treturn true;\n}\n\n/** Serializes a suite to the canonical suite.json text (stable field order, trailing newline). */\nexport function serializeSuiteJson(suite: SuiteDefinition): string {\n\tconst ordered = {\n\t\tschemaVersion: suite.schemaVersion,\n\t\tid: suite.id,\n\t\tname: suite.name,\n\t\tbuiltin: suite.builtin,\n\t\ttools: [...suite.tools],\n\t\tcapabilities: [...suite.capabilities],\n\t\tassociations: {\n\t\t\tskills: [...suite.associations.skills],\n\t\t\tmcp: [...suite.associations.mcp],\n\t\t\tplugins: [...suite.associations.plugins],\n\t\t\troles: [...suite.associations.roles],\n\t\t},\n\t\tinheritSystemAgentsMd: suite.inheritSystemAgentsMd,\n\t\tmemory: suite.memory,\n\t\torientation: suite.orientation,\n\t\tmodel: suite.model,\n\t\tthinking: suite.thinking,\n\t\tclonedFrom: suite.clonedFrom\n\t\t\t? { id: suite.clonedFrom.id, digest: suite.clonedFrom.digest, at: suite.clonedFrom.at }\n\t\t\t: null,\n\t\tfactoryRevision: suite.factoryRevision,\n\t};\n\treturn `${JSON.stringify(ordered, null, 2)}\\n`;\n}\n\nexport interface SuiteJsonParseResult {\n\treadonly valid: boolean;\n\treadonly suite?: SuiteDefinition;\n\treadonly errors: readonly string[];\n}\n\n/**\n * Parses suite.json text. Never throws: an invalid result carries every\n * validation error so callers can apply the corruption policy (设计 §9) —\n * builtin suites fall back to factory content, user suites fail fast.\n */\nexport function parseSuiteJson(\n\traw: string,\n\toptions: { expectedBuiltin?: boolean; expectedId?: string },\n): SuiteJsonParseResult {\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(raw);\n\t} catch (error) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terrors: [`invalid JSON: ${error instanceof Error ? error.message : String(error)}`],\n\t\t};\n\t}\n\treturn validateSuiteJson(value, options);\n}\n\nexport function validateSuiteJson(\n\tvalue: unknown,\n\toptions: { expectedBuiltin?: boolean; expectedId?: string } = {},\n): SuiteJsonParseResult {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\treturn { valid: false, errors: [\"suite.json must be a JSON object\"] };\n\t}\n\tconst record = value as Record<string, unknown>;\n\tconst errors: string[] = [];\n\n\tif (record.schemaVersion !== SUITE_SCHEMA_VERSION) {\n\t\terrors.push(`schemaVersion must be ${SUITE_SCHEMA_VERSION}, found ${JSON.stringify(record.schemaVersion)}`);\n\t}\n\n\t// Each field keeps a typed local: valid values land here, invalid ones only\n\t// contribute errors. The suite below is constructed exclusively when\n\t// `errors` is empty, so the fallbacks/coercions at that point are dead.\n\tconst idValue = record.id;\n\tconst id = typeof idValue === \"string\" && isValidSuiteId(idValue) ? idValue : undefined;\n\tif (id === undefined) {\n\t\terrors.push(\n\t\t\t`id must be a suite id (^[a-z0-9-]+$, no leading/trailing hyphen, Windows reserved names rejected), found ${JSON.stringify(idValue)}`,\n\t\t);\n\t} else if (options.expectedId !== undefined && id !== options.expectedId) {\n\t\terrors.push(`id \"${id}\" does not match the suite workspace directory id \"${options.expectedId}\"`);\n\t}\n\n\tconst nameValue = record.name;\n\tconst name = typeof nameValue === \"string\" && nameValue.trim().length > 0 ? nameValue : undefined;\n\tif (name === undefined) {\n\t\terrors.push(`name must be a non-empty string, found ${JSON.stringify(nameValue)}`);\n\t}\n\n\tconst builtinValue = record.builtin;\n\tconst builtin = typeof builtinValue === \"boolean\" ? builtinValue : undefined;\n\tif (builtin === undefined) {\n\t\terrors.push(`builtin must be a boolean, found ${JSON.stringify(builtinValue)}`);\n\t} else if (options.expectedBuiltin === true && builtin !== true) {\n\t\terrors.push(`builtin must be true for a builtin suite workspace, found ${builtin}`);\n\t}\n\n\tconst tools = readStringArray(record, \"tools\", errors);\n\tconst capabilities = readStringArray(record, \"capabilities\", errors);\n\tconst associations = readAssociations(record.associations, errors);\n\n\tconst inheritValue = record.inheritSystemAgentsMd;\n\tconst inheritSystemAgentsMd = typeof inheritValue === \"boolean\" ? inheritValue : undefined;\n\tif (inheritSystemAgentsMd === undefined) {\n\t\terrors.push(`inheritSystemAgentsMd must be a boolean, found ${JSON.stringify(inheritValue)}`);\n\t}\n\n\tconst memoryValue = record.memory;\n\tconst memory = memoryValue === \"assistant\" || memoryValue === \"code\" ? memoryValue : undefined;\n\tif (memory === undefined) {\n\t\terrors.push(`memory must be \"assistant\" or \"code\", found ${JSON.stringify(memoryValue)}`);\n\t}\n\n\tconst orientationValue = record.orientation;\n\tconst orientation =\n\t\torientationValue === \"assistant\" || orientationValue === \"coding\" || orientationValue === \"custom\"\n\t\t\t? orientationValue\n\t\t\t: undefined;\n\tif (orientationValue !== undefined && orientation === undefined) {\n\t\terrors.push(`orientation must be \"assistant\", \"coding\", or \"custom\", found ${JSON.stringify(orientationValue)}`);\n\t}\n\n\tconst model = readOptionalString(record, \"model\", errors);\n\tconst thinking = readOptionalString(record, \"thinking\", errors);\n\tconst clonedFrom = readClonedFrom(record.clonedFrom, errors);\n\tconst factoryRevision = readFactoryRevision(record.factoryRevision, options.expectedBuiltin === true, errors);\n\n\tif (errors.length > 0) return { valid: false, errors };\n\n\treturn {\n\t\tvalid: true,\n\t\terrors: [],\n\t\tsuite: {\n\t\t\tschemaVersion: SUITE_SCHEMA_VERSION,\n\t\t\tid: id!,\n\t\t\tname: name!,\n\t\t\tbuiltin: builtin!,\n\t\t\ttools,\n\t\t\tcapabilities,\n\t\t\tassociations,\n\t\t\tinheritSystemAgentsMd: inheritSystemAgentsMd!,\n\t\t\tmemory: memory!,\n\t\t\torientation: orientation ?? \"assistant\",\n\t\t\tmodel,\n\t\t\tthinking,\n\t\t\tclonedFrom,\n\t\t\t...(factoryRevision === undefined ? {} : { factoryRevision }),\n\t\t},\n\t};\n}\n\nfunction readStringArray(record: Record<string, unknown>, key: string, errors: string[]): readonly string[] {\n\tconst value = record[key];\n\tif (!Array.isArray(value)) {\n\t\terrors.push(`${key} must be an array of strings, found ${JSON.stringify(value)}`);\n\t\treturn [];\n\t}\n\tconst entries: string[] = [];\n\tconst seen = new Set<string>();\n\tfor (const item of value) {\n\t\tif (typeof item !== \"string\" || item.trim().length === 0) {\n\t\t\terrors.push(`${key} entries must be non-empty strings, found ${JSON.stringify(item)}`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (seen.has(item)) {\n\t\t\terrors.push(`${key} contains duplicate entry \"${item}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tseen.add(item);\n\t\tentries.push(item);\n\t}\n\treturn entries;\n}\n\nfunction readAssociations(value: unknown, errors: string[]): SuiteAssociations {\n\tif (value === undefined) return { skills: [], mcp: [], plugins: [], roles: [] };\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\terrors.push(\n\t\t\t`associations must be an object with skills/mcp/plugins/roles arrays, found ${JSON.stringify(value)}`,\n\t\t);\n\t\treturn { skills: [], mcp: [], plugins: [], roles: [] };\n\t}\n\tconst record = value as Record<string, unknown>;\n\t// A key left out entirely means an empty list, consistent with a fully\n\t// absent `associations` object; a key that is present but malformed still\n\t// reports its errors. The removed legacy `extensions` kind is ignored on\n\t// read (it lost its loader with the old ExtensionAPI surface).\n\treturn {\n\t\tskills: record.skills === undefined ? [] : readStringArray(record, \"skills\", errors),\n\t\tmcp: record.mcp === undefined ? [] : readStringArray(record, \"mcp\", errors),\n\t\tplugins: record.plugins === undefined ? [] : readStringArray(record, \"plugins\", errors),\n\t\troles: record.roles === undefined ? [] : readStringArray(record, \"roles\", errors),\n\t};\n}\n\nfunction readOptionalString(record: Record<string, unknown>, key: string, errors: string[]): string | null {\n\tconst value = record[key];\n\tif (value === undefined || value === null) return null;\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\terrors.push(`${key} must be a non-empty string or null, found ${JSON.stringify(value)}`);\n\t\treturn null;\n\t}\n\treturn value;\n}\n\n/**\n * Reads the optional `factoryRevision` key (M4). A missing key means\n * FACTORY_CONTENTS_VERSION for builtin workspaces (pre-M4 on-disk files stay\n * compatible) and stays absent for user suites (outside factory upgrade\n * governance). A present key must be a positive integer.\n */\nfunction readFactoryRevision(value: unknown, expectedBuiltin: boolean, errors: string[]): number | undefined {\n\tif (value === undefined) return expectedBuiltin ? FACTORY_CONTENTS_VERSION : undefined;\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0) {\n\t\terrors.push(`factoryRevision must be a positive integer, found ${JSON.stringify(value)}`);\n\t\treturn undefined;\n\t}\n\treturn value;\n}\n\nfunction readClonedFrom(value: unknown, errors: string[]): SuiteClonedFrom | null {\n\tif (value === undefined || value === null) return null;\n\tif (typeof value !== \"object\" || Array.isArray(value)) {\n\t\terrors.push(`clonedFrom must be an object with id/digest/at, found ${JSON.stringify(value)}`);\n\t\treturn null;\n\t}\n\tconst record = value as Record<string, unknown>;\n\tif (\n\t\ttypeof record.id !== \"string\" ||\n\t\trecord.id.trim().length === 0 ||\n\t\ttypeof record.digest !== \"string\" ||\n\t\trecord.digest.trim().length === 0 ||\n\t\ttypeof record.at !== \"number\" ||\n\t\t!Number.isSafeInteger(record.at)\n\t) {\n\t\terrors.push(\n\t\t\t`clonedFrom must be an object with non-empty id/digest strings and an integer at, found ${JSON.stringify(value)}`,\n\t\t);\n\t\treturn null;\n\t}\n\treturn { id: record.id, digest: record.digest, at: record.at };\n}\n"]}
@@ -3,14 +3,14 @@
3
3
  *
4
4
  * This module provides a unified interface to @silvia-odwyer/photon-node that works in:
5
5
  * 1. Node.js (development, npm run build)
6
- * 2. Bun compiled binaries (standalone distribution)
6
+ * 2. Bun as a runtime host (the standalone-binary distribution line was retired 2026-10-03)
7
7
  *
8
8
  * The challenge: photon-node's CJS entry uses fs.readFileSync(__dirname + '/photon_rs_bg.wasm')
9
9
  * which bakes the build machine's absolute path into Bun compiled binaries.
10
10
  *
11
11
  * Solution:
12
12
  * 1. Patch fs.readFileSync to redirect missing photon_rs_bg.wasm reads
13
- * 2. Copy photon_rs_bg.wasm next to the executable in build:binary
13
+ * 2. Copy photon_rs_bg.wasm next to the executable when packaging a Bun binary
14
14
  */
15
15
  export type { PhotonImage as PhotonImageType } from "@silvia-odwyer/photon-node";
16
16
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"photon.d.ts","sourceRoot":"","sources":["../../src/utils/photon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAWH,YAAY,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AA0FjF;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,cAAc,4BAA4B,CAAC,GAAG,IAAI,CAAC,CAuB9F","sourcesContent":["/**\n * Photon image processing wrapper.\n *\n * This module provides a unified interface to @silvia-odwyer/photon-node that works in:\n * 1. Node.js (development, npm run build)\n * 2. Bun compiled binaries (standalone distribution)\n *\n * The challenge: photon-node's CJS entry uses fs.readFileSync(__dirname + '/photon_rs_bg.wasm')\n * which bakes the build machine's absolute path into Bun compiled binaries.\n *\n * Solution:\n * 1. Patch fs.readFileSync to redirect missing photon_rs_bg.wasm reads\n * 2. Copy photon_rs_bg.wasm next to the executable in build:binary\n */\n\nimport type { PathOrFileDescriptor } from \"fs\";\nimport { createRequire } from \"module\";\nimport * as path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nconst require = createRequire(import.meta.url);\nconst fs = require(\"fs\") as typeof import(\"fs\");\n\n// Re-export types from the main package\nexport type { PhotonImage as PhotonImageType } from \"@silvia-odwyer/photon-node\";\n\ntype ReadFileSync = typeof fs.readFileSync;\n\nconst WASM_FILENAME = \"photon_rs_bg.wasm\";\n\n// Lazy-loaded photon module\nlet photonModule: typeof import(\"@silvia-odwyer/photon-node\") | null = null;\nlet loadPromise: Promise<typeof import(\"@silvia-odwyer/photon-node\") | null> | null = null;\n\nfunction pathOrNull(file: PathOrFileDescriptor): string | null {\n\tif (typeof file === \"string\") {\n\t\treturn file;\n\t}\n\t// v8 ignore next -- wasm 仅在加载期以字符串路径读取,非字符串非 URL 入参不可达\n\tif (file instanceof URL) {\n\t\treturn fileURLToPath(file);\n\t}\n\treturn null;\n}\n\nfunction getFallbackWasmPaths(): string[] {\n\tconst execDir = path.dirname(process.execPath);\n\treturn [\n\t\tpath.join(execDir, WASM_FILENAME),\n\t\tpath.join(execDir, \"photon\", WASM_FILENAME),\n\t\tpath.join(process.cwd(), WASM_FILENAME),\n\t];\n}\n\nfunction patchPhotonWasmRead(): () => void {\n\tconst originalReadFileSync: ReadFileSync = fs.readFileSync.bind(fs);\n\tconst fallbackPaths = getFallbackWasmPaths();\n\tconst mutableFs = fs as { readFileSync: ReadFileSync };\n\n\tconst patchedReadFileSync: ReadFileSync = ((...args: Parameters<ReadFileSync>) => {\n\t\tconst [file, options] = args;\n\t\tconst resolvedPath = pathOrNull(file);\n\n\t\tif (resolvedPath?.endsWith(WASM_FILENAME)) {\n\t\t\ttry {\n\t\t\t\treturn originalReadFileSync(...args);\n\t\t\t} catch (error) {\n\t\t\t\tconst err = error as NodeJS.ErrnoException;\n\t\t\t\tif (err?.code && err.code !== \"ENOENT\") {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\tfor (const fallbackPath of fallbackPaths) {\n\t\t\t\t\tif (!fs.existsSync(fallbackPath)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (options === undefined) {\n\t\t\t\t\t\treturn originalReadFileSync(fallbackPath);\n\t\t\t\t\t}\n\t\t\t\t\treturn originalReadFileSync(fallbackPath, options);\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn originalReadFileSync(...args);\n\t}) as ReadFileSync;\n\n\ttry {\n\t\tmutableFs.readFileSync = patchedReadFileSync;\n\t} catch {\n\t\tObject.defineProperty(fs, \"readFileSync\", {\n\t\t\tvalue: patchedReadFileSync,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\n\treturn () => {\n\t\ttry {\n\t\t\tmutableFs.readFileSync = originalReadFileSync;\n\t\t} catch {\n\t\t\t// v8 ignore start -- 同上,恢复赋值的回退不可达\n\t\t\tObject.defineProperty(fs, \"readFileSync\", {\n\t\t\t\tvalue: originalReadFileSync,\n\t\t\t\twritable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t\t// v8 ignore stop\n\t\t}\n\t};\n}\n\n/**\n * Load the photon module asynchronously.\n * Returns cached module on subsequent calls.\n */\nexport async function loadPhoton(): Promise<typeof import(\"@silvia-odwyer/photon-node\") | null> {\n\tif (photonModule) {\n\t\treturn photonModule;\n\t}\n\n\tif (loadPromise) {\n\t\treturn loadPromise;\n\t}\n\n\tloadPromise = (async () => {\n\t\tconst restoreReadFileSync = patchPhotonWasmRead();\n\t\ttry {\n\t\t\tphotonModule = await import(\"@silvia-odwyer/photon-node\");\n\t\t\treturn photonModule;\n\t\t} catch {\n\t\t\tphotonModule = null;\n\t\t\treturn photonModule;\n\t\t} finally {\n\t\t\trestoreReadFileSync();\n\t\t}\n\t})();\n\n\treturn loadPromise;\n}\n"]}
1
+ {"version":3,"file":"photon.d.ts","sourceRoot":"","sources":["../../src/utils/photon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAWH,YAAY,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AA0FjF;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,cAAc,4BAA4B,CAAC,GAAG,IAAI,CAAC,CAuB9F","sourcesContent":["/**\n * Photon image processing wrapper.\n *\n * This module provides a unified interface to @silvia-odwyer/photon-node that works in:\n * 1. Node.js (development, npm run build)\n * 2. Bun as a runtime host (the standalone-binary distribution line was retired 2026-10-03)\n *\n * The challenge: photon-node's CJS entry uses fs.readFileSync(__dirname + '/photon_rs_bg.wasm')\n * which bakes the build machine's absolute path into Bun compiled binaries.\n *\n * Solution:\n * 1. Patch fs.readFileSync to redirect missing photon_rs_bg.wasm reads\n * 2. Copy photon_rs_bg.wasm next to the executable when packaging a Bun binary\n */\n\nimport type { PathOrFileDescriptor } from \"fs\";\nimport { createRequire } from \"module\";\nimport * as path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nconst require = createRequire(import.meta.url);\nconst fs = require(\"fs\") as typeof import(\"fs\");\n\n// Re-export types from the main package\nexport type { PhotonImage as PhotonImageType } from \"@silvia-odwyer/photon-node\";\n\ntype ReadFileSync = typeof fs.readFileSync;\n\nconst WASM_FILENAME = \"photon_rs_bg.wasm\";\n\n// Lazy-loaded photon module\nlet photonModule: typeof import(\"@silvia-odwyer/photon-node\") | null = null;\nlet loadPromise: Promise<typeof import(\"@silvia-odwyer/photon-node\") | null> | null = null;\n\nfunction pathOrNull(file: PathOrFileDescriptor): string | null {\n\tif (typeof file === \"string\") {\n\t\treturn file;\n\t}\n\t// v8 ignore next -- wasm 仅在加载期以字符串路径读取,非字符串非 URL 入参不可达\n\tif (file instanceof URL) {\n\t\treturn fileURLToPath(file);\n\t}\n\treturn null;\n}\n\nfunction getFallbackWasmPaths(): string[] {\n\tconst execDir = path.dirname(process.execPath);\n\treturn [\n\t\tpath.join(execDir, WASM_FILENAME),\n\t\tpath.join(execDir, \"photon\", WASM_FILENAME),\n\t\tpath.join(process.cwd(), WASM_FILENAME),\n\t];\n}\n\nfunction patchPhotonWasmRead(): () => void {\n\tconst originalReadFileSync: ReadFileSync = fs.readFileSync.bind(fs);\n\tconst fallbackPaths = getFallbackWasmPaths();\n\tconst mutableFs = fs as { readFileSync: ReadFileSync };\n\n\tconst patchedReadFileSync: ReadFileSync = ((...args: Parameters<ReadFileSync>) => {\n\t\tconst [file, options] = args;\n\t\tconst resolvedPath = pathOrNull(file);\n\n\t\tif (resolvedPath?.endsWith(WASM_FILENAME)) {\n\t\t\ttry {\n\t\t\t\treturn originalReadFileSync(...args);\n\t\t\t} catch (error) {\n\t\t\t\tconst err = error as NodeJS.ErrnoException;\n\t\t\t\tif (err?.code && err.code !== \"ENOENT\") {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\tfor (const fallbackPath of fallbackPaths) {\n\t\t\t\t\tif (!fs.existsSync(fallbackPath)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (options === undefined) {\n\t\t\t\t\t\treturn originalReadFileSync(fallbackPath);\n\t\t\t\t\t}\n\t\t\t\t\treturn originalReadFileSync(fallbackPath, options);\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn originalReadFileSync(...args);\n\t}) as ReadFileSync;\n\n\ttry {\n\t\tmutableFs.readFileSync = patchedReadFileSync;\n\t} catch {\n\t\tObject.defineProperty(fs, \"readFileSync\", {\n\t\t\tvalue: patchedReadFileSync,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\n\treturn () => {\n\t\ttry {\n\t\t\tmutableFs.readFileSync = originalReadFileSync;\n\t\t} catch {\n\t\t\t// v8 ignore start -- 同上,恢复赋值的回退不可达\n\t\t\tObject.defineProperty(fs, \"readFileSync\", {\n\t\t\t\tvalue: originalReadFileSync,\n\t\t\t\twritable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t\t// v8 ignore stop\n\t\t}\n\t};\n}\n\n/**\n * Load the photon module asynchronously.\n * Returns cached module on subsequent calls.\n */\nexport async function loadPhoton(): Promise<typeof import(\"@silvia-odwyer/photon-node\") | null> {\n\tif (photonModule) {\n\t\treturn photonModule;\n\t}\n\n\tif (loadPromise) {\n\t\treturn loadPromise;\n\t}\n\n\tloadPromise = (async () => {\n\t\tconst restoreReadFileSync = patchPhotonWasmRead();\n\t\ttry {\n\t\t\tphotonModule = await import(\"@silvia-odwyer/photon-node\");\n\t\t\treturn photonModule;\n\t\t} catch {\n\t\t\tphotonModule = null;\n\t\t\treturn photonModule;\n\t\t} finally {\n\t\t\trestoreReadFileSync();\n\t\t}\n\t})();\n\n\treturn loadPromise;\n}\n"]}
@@ -3,14 +3,14 @@
3
3
  *
4
4
  * This module provides a unified interface to @silvia-odwyer/photon-node that works in:
5
5
  * 1. Node.js (development, npm run build)
6
- * 2. Bun compiled binaries (standalone distribution)
6
+ * 2. Bun as a runtime host (the standalone-binary distribution line was retired 2026-10-03)
7
7
  *
8
8
  * The challenge: photon-node's CJS entry uses fs.readFileSync(__dirname + '/photon_rs_bg.wasm')
9
9
  * which bakes the build machine's absolute path into Bun compiled binaries.
10
10
  *
11
11
  * Solution:
12
12
  * 1. Patch fs.readFileSync to redirect missing photon_rs_bg.wasm reads
13
- * 2. Copy photon_rs_bg.wasm next to the executable in build:binary
13
+ * 2. Copy photon_rs_bg.wasm next to the executable when packaging a Bun binary
14
14
  */
15
15
  import { createRequire } from "module";
16
16
  import * as path from "path";
@@ -1 +1 @@
1
- {"version":3,"file":"photon.js","sourceRoot":"","sources":["../../src/utils/photon.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Photon image processing wrapper.\n *\n * This module provides a unified interface to @silvia-odwyer/photon-node that works in:\n * 1. Node.js (development, npm run build)\n * 2. Bun compiled binaries (standalone distribution)\n *\n * The challenge: photon-node's CJS entry uses fs.readFileSync(__dirname + '/photon_rs_bg.wasm')\n * which bakes the build machine's absolute path into Bun compiled binaries.\n *\n * Solution:\n * 1. Patch fs.readFileSync to redirect missing photon_rs_bg.wasm reads\n * 2. Copy photon_rs_bg.wasm next to the executable in build:binary\n */\n\nimport type { PathOrFileDescriptor } from \"fs\";\nimport { createRequire } from \"module\";\nimport * as path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nconst require = createRequire(import.meta.url);\nconst fs = require(\"fs\") as typeof import(\"fs\");\n\n// Re-export types from the main package\nexport type { PhotonImage as PhotonImageType } from \"@silvia-odwyer/photon-node\";\n\ntype ReadFileSync = typeof fs.readFileSync;\n\nconst WASM_FILENAME = \"photon_rs_bg.wasm\";\n\n// Lazy-loaded photon module\nlet photonModule: typeof import(\"@silvia-odwyer/photon-node\") | null = null;\nlet loadPromise: Promise<typeof import(\"@silvia-odwyer/photon-node\") | null> | null = null;\n\nfunction pathOrNull(file: PathOrFileDescriptor): string | null {\n\tif (typeof file === \"string\") {\n\t\treturn file;\n\t}\n\t// v8 ignore next -- wasm 仅在加载期以字符串路径读取,非字符串非 URL 入参不可达\n\tif (file instanceof URL) {\n\t\treturn fileURLToPath(file);\n\t}\n\treturn null;\n}\n\nfunction getFallbackWasmPaths(): string[] {\n\tconst execDir = path.dirname(process.execPath);\n\treturn [\n\t\tpath.join(execDir, WASM_FILENAME),\n\t\tpath.join(execDir, \"photon\", WASM_FILENAME),\n\t\tpath.join(process.cwd(), WASM_FILENAME),\n\t];\n}\n\nfunction patchPhotonWasmRead(): () => void {\n\tconst originalReadFileSync: ReadFileSync = fs.readFileSync.bind(fs);\n\tconst fallbackPaths = getFallbackWasmPaths();\n\tconst mutableFs = fs as { readFileSync: ReadFileSync };\n\n\tconst patchedReadFileSync: ReadFileSync = ((...args: Parameters<ReadFileSync>) => {\n\t\tconst [file, options] = args;\n\t\tconst resolvedPath = pathOrNull(file);\n\n\t\tif (resolvedPath?.endsWith(WASM_FILENAME)) {\n\t\t\ttry {\n\t\t\t\treturn originalReadFileSync(...args);\n\t\t\t} catch (error) {\n\t\t\t\tconst err = error as NodeJS.ErrnoException;\n\t\t\t\tif (err?.code && err.code !== \"ENOENT\") {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\tfor (const fallbackPath of fallbackPaths) {\n\t\t\t\t\tif (!fs.existsSync(fallbackPath)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (options === undefined) {\n\t\t\t\t\t\treturn originalReadFileSync(fallbackPath);\n\t\t\t\t\t}\n\t\t\t\t\treturn originalReadFileSync(fallbackPath, options);\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn originalReadFileSync(...args);\n\t}) as ReadFileSync;\n\n\ttry {\n\t\tmutableFs.readFileSync = patchedReadFileSync;\n\t} catch {\n\t\tObject.defineProperty(fs, \"readFileSync\", {\n\t\t\tvalue: patchedReadFileSync,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\n\treturn () => {\n\t\ttry {\n\t\t\tmutableFs.readFileSync = originalReadFileSync;\n\t\t} catch {\n\t\t\t// v8 ignore start -- 同上,恢复赋值的回退不可达\n\t\t\tObject.defineProperty(fs, \"readFileSync\", {\n\t\t\t\tvalue: originalReadFileSync,\n\t\t\t\twritable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t\t// v8 ignore stop\n\t\t}\n\t};\n}\n\n/**\n * Load the photon module asynchronously.\n * Returns cached module on subsequent calls.\n */\nexport async function loadPhoton(): Promise<typeof import(\"@silvia-odwyer/photon-node\") | null> {\n\tif (photonModule) {\n\t\treturn photonModule;\n\t}\n\n\tif (loadPromise) {\n\t\treturn loadPromise;\n\t}\n\n\tloadPromise = (async () => {\n\t\tconst restoreReadFileSync = patchPhotonWasmRead();\n\t\ttry {\n\t\t\tphotonModule = await import(\"@silvia-odwyer/photon-node\");\n\t\t\treturn photonModule;\n\t\t} catch {\n\t\t\tphotonModule = null;\n\t\t\treturn photonModule;\n\t\t} finally {\n\t\t\trestoreReadFileSync();\n\t\t}\n\t})();\n\n\treturn loadPromise;\n}\n"]}
1
+ {"version":3,"file":"photon.js","sourceRoot":"","sources":["../../src/utils/photon.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Photon image processing wrapper.\n *\n * This module provides a unified interface to @silvia-odwyer/photon-node that works in:\n * 1. Node.js (development, npm run build)\n * 2. Bun as a runtime host (the standalone-binary distribution line was retired 2026-10-03)\n *\n * The challenge: photon-node's CJS entry uses fs.readFileSync(__dirname + '/photon_rs_bg.wasm')\n * which bakes the build machine's absolute path into Bun compiled binaries.\n *\n * Solution:\n * 1. Patch fs.readFileSync to redirect missing photon_rs_bg.wasm reads\n * 2. Copy photon_rs_bg.wasm next to the executable when packaging a Bun binary\n */\n\nimport type { PathOrFileDescriptor } from \"fs\";\nimport { createRequire } from \"module\";\nimport * as path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nconst require = createRequire(import.meta.url);\nconst fs = require(\"fs\") as typeof import(\"fs\");\n\n// Re-export types from the main package\nexport type { PhotonImage as PhotonImageType } from \"@silvia-odwyer/photon-node\";\n\ntype ReadFileSync = typeof fs.readFileSync;\n\nconst WASM_FILENAME = \"photon_rs_bg.wasm\";\n\n// Lazy-loaded photon module\nlet photonModule: typeof import(\"@silvia-odwyer/photon-node\") | null = null;\nlet loadPromise: Promise<typeof import(\"@silvia-odwyer/photon-node\") | null> | null = null;\n\nfunction pathOrNull(file: PathOrFileDescriptor): string | null {\n\tif (typeof file === \"string\") {\n\t\treturn file;\n\t}\n\t// v8 ignore next -- wasm 仅在加载期以字符串路径读取,非字符串非 URL 入参不可达\n\tif (file instanceof URL) {\n\t\treturn fileURLToPath(file);\n\t}\n\treturn null;\n}\n\nfunction getFallbackWasmPaths(): string[] {\n\tconst execDir = path.dirname(process.execPath);\n\treturn [\n\t\tpath.join(execDir, WASM_FILENAME),\n\t\tpath.join(execDir, \"photon\", WASM_FILENAME),\n\t\tpath.join(process.cwd(), WASM_FILENAME),\n\t];\n}\n\nfunction patchPhotonWasmRead(): () => void {\n\tconst originalReadFileSync: ReadFileSync = fs.readFileSync.bind(fs);\n\tconst fallbackPaths = getFallbackWasmPaths();\n\tconst mutableFs = fs as { readFileSync: ReadFileSync };\n\n\tconst patchedReadFileSync: ReadFileSync = ((...args: Parameters<ReadFileSync>) => {\n\t\tconst [file, options] = args;\n\t\tconst resolvedPath = pathOrNull(file);\n\n\t\tif (resolvedPath?.endsWith(WASM_FILENAME)) {\n\t\t\ttry {\n\t\t\t\treturn originalReadFileSync(...args);\n\t\t\t} catch (error) {\n\t\t\t\tconst err = error as NodeJS.ErrnoException;\n\t\t\t\tif (err?.code && err.code !== \"ENOENT\") {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\tfor (const fallbackPath of fallbackPaths) {\n\t\t\t\t\tif (!fs.existsSync(fallbackPath)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (options === undefined) {\n\t\t\t\t\t\treturn originalReadFileSync(fallbackPath);\n\t\t\t\t\t}\n\t\t\t\t\treturn originalReadFileSync(fallbackPath, options);\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn originalReadFileSync(...args);\n\t}) as ReadFileSync;\n\n\ttry {\n\t\tmutableFs.readFileSync = patchedReadFileSync;\n\t} catch {\n\t\tObject.defineProperty(fs, \"readFileSync\", {\n\t\t\tvalue: patchedReadFileSync,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\n\treturn () => {\n\t\ttry {\n\t\t\tmutableFs.readFileSync = originalReadFileSync;\n\t\t} catch {\n\t\t\t// v8 ignore start -- 同上,恢复赋值的回退不可达\n\t\t\tObject.defineProperty(fs, \"readFileSync\", {\n\t\t\t\tvalue: originalReadFileSync,\n\t\t\t\twritable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t\t// v8 ignore stop\n\t\t}\n\t};\n}\n\n/**\n * Load the photon module asynchronously.\n * Returns cached module on subsequent calls.\n */\nexport async function loadPhoton(): Promise<typeof import(\"@silvia-odwyer/photon-node\") | null> {\n\tif (photonModule) {\n\t\treturn photonModule;\n\t}\n\n\tif (loadPromise) {\n\t\treturn loadPromise;\n\t}\n\n\tloadPromise = (async () => {\n\t\tconst restoreReadFileSync = patchPhotonWasmRead();\n\t\ttry {\n\t\t\tphotonModule = await import(\"@silvia-odwyer/photon-node\");\n\t\t\treturn photonModule;\n\t\t} catch {\n\t\t\tphotonModule = null;\n\t\t\treturn photonModule;\n\t\t} finally {\n\t\t\trestoreReadFileSync();\n\t\t}\n\t})();\n\n\treturn loadPromise;\n}\n"]}
@@ -334,7 +334,6 @@ Configure compaction in `~/.agent-forge/agent/settings.json` or `<project-dir>/.
334
334
  ```json
335
335
  {
336
336
  "compaction": {
337
- "enabled": true,
338
337
  "reserveTokens": 16384,
339
338
  "keepRecentTokens": 20000
340
339
  }
@@ -343,8 +342,7 @@ Configure compaction in `~/.agent-forge/agent/settings.json` or `<project-dir>/.
343
342
 
344
343
  | Setting | Default | Description |
345
344
  |---------|---------|-------------|
346
- | `enabled` | `true` | Enable auto-compaction |
347
345
  | `reserveTokens` | `16384` | Tokens to reserve for LLM response |
348
346
  | `keepRecentTokens` | `20000` | Recent tokens to keep (not summarized) |
349
347
 
350
- Disable auto-compaction with `"enabled": false`. You can still compact manually with `/compact`.
348
+ Auto-compaction is always on; the `enabled` key (and the legacy `microcompactEnabled` / `summarySelfCritique` keys) were removed and are silently ignored if present in settings files. Manual compaction via `/compact` is unchanged.
package/docs/docs.json CHANGED
@@ -52,6 +52,10 @@
52
52
  "title": "Skills",
53
53
  "path": "skills.md"
54
54
  },
55
+ {
56
+ "title": "MCP",
57
+ "path": "mcp.md"
58
+ },
55
59
  {
56
60
  "title": "Prompt Templates",
57
61
  "path": "prompt-templates.md"
package/docs/index.md CHANGED
@@ -46,6 +46,7 @@ For the full first-run flow, see [Quickstart](quickstart.md).
46
46
  ## Customization
47
47
 
48
48
  - [Skills](skills.md) - Agent Skills for reusable on-demand capabilities.
49
+ - [MCP](mcp.md) - connect to MCP servers through `mcp.json` (stdio and remote HTTP).
49
50
  - [Prompt templates](prompt-templates.md) - reusable prompts that expand from slash commands.
50
51
  - [Themes](themes.md) - built-in and custom terminal themes.
51
52
  - [Plugins](packages.md) - bundle and share optional capabilities.