axon-code 2.4.0 → 2.5.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 (569) hide show
  1. package/dist/auth/snapshot.d.ts +24 -0
  2. package/dist/auth/snapshot.d.ts.map +1 -0
  3. package/dist/auth/snapshot.js +144 -0
  4. package/dist/auth/snapshot.js.map +1 -0
  5. package/dist/cli.js +3 -1
  6. package/dist/cli.js.map +1 -1
  7. package/dist/config/index.d.ts +30 -15
  8. package/dist/config/index.d.ts.map +1 -1
  9. package/dist/config/index.js +13 -2
  10. package/dist/config/index.js.map +1 -1
  11. package/dist/core/client.d.ts +7 -2
  12. package/dist/core/client.d.ts.map +1 -1
  13. package/dist/core/client.js +50 -18
  14. package/dist/core/client.js.map +1 -1
  15. package/dist/core/loop.d.ts +2 -7
  16. package/dist/core/loop.d.ts.map +1 -1
  17. package/dist/core/loop.js +16 -38
  18. package/dist/core/loop.js.map +1 -1
  19. package/dist/core/max-tokens.d.ts +24 -0
  20. package/dist/core/max-tokens.d.ts.map +1 -0
  21. package/dist/core/max-tokens.js +64 -0
  22. package/dist/core/max-tokens.js.map +1 -0
  23. package/dist/goals/goal-store.d.ts +1 -1
  24. package/dist/goals/goal-store.d.ts.map +1 -1
  25. package/dist/goals/goal-store.js.map +1 -1
  26. package/dist/hooks/auto-verify.d.ts +86 -0
  27. package/dist/hooks/auto-verify.d.ts.map +1 -0
  28. package/dist/hooks/auto-verify.js +297 -0
  29. package/dist/hooks/auto-verify.js.map +1 -0
  30. package/dist/mcp/config.d.ts +8 -8
  31. package/dist/media/index.d.ts +1 -0
  32. package/dist/media/index.d.ts.map +1 -1
  33. package/dist/media/index.js +2 -0
  34. package/dist/media/index.js.map +1 -1
  35. package/dist/media/office-visual.d.ts +66 -0
  36. package/dist/media/office-visual.d.ts.map +1 -0
  37. package/dist/media/office-visual.js +409 -0
  38. package/dist/media/office-visual.js.map +1 -0
  39. package/dist/memory/long-term-store.d.ts +6 -0
  40. package/dist/memory/long-term-store.d.ts.map +1 -1
  41. package/dist/memory/long-term-store.js +66 -48
  42. package/dist/memory/long-term-store.js.map +1 -1
  43. package/dist/memory/memory-search.d.ts +5 -2
  44. package/dist/memory/memory-search.d.ts.map +1 -1
  45. package/dist/memory/memory-search.js +27 -10
  46. package/dist/memory/memory-search.js.map +1 -1
  47. package/dist/memory/memory-sync.d.ts.map +1 -1
  48. package/dist/memory/memory-sync.js +4 -0
  49. package/dist/memory/memory-sync.js.map +1 -1
  50. package/dist/memory/notebook.d.ts +7 -0
  51. package/dist/memory/notebook.d.ts.map +1 -1
  52. package/dist/memory/notebook.js +62 -9
  53. package/dist/memory/notebook.js.map +1 -1
  54. package/dist/network/discovery.d.ts +2 -0
  55. package/dist/network/discovery.d.ts.map +1 -1
  56. package/dist/network/discovery.js +10 -5
  57. package/dist/network/discovery.js.map +1 -1
  58. package/dist/network/global-proxy.d.ts +7 -0
  59. package/dist/network/global-proxy.d.ts.map +1 -1
  60. package/dist/network/global-proxy.js +67 -0
  61. package/dist/network/global-proxy.js.map +1 -1
  62. package/dist/network/index.d.ts +6 -1
  63. package/dist/network/index.d.ts.map +1 -1
  64. package/dist/network/index.js +16 -11
  65. package/dist/network/index.js.map +1 -1
  66. package/dist/network/transport.d.ts +41 -4
  67. package/dist/network/transport.d.ts.map +1 -1
  68. package/dist/network/transport.js +234 -61
  69. package/dist/network/transport.js.map +1 -1
  70. package/dist/network/types.d.ts +19 -1
  71. package/dist/network/types.d.ts.map +1 -1
  72. package/dist/network/types.js.map +1 -1
  73. package/dist/notifications/cmux.d.ts +115 -0
  74. package/dist/notifications/cmux.d.ts.map +1 -0
  75. package/dist/notifications/cmux.js +436 -0
  76. package/dist/notifications/cmux.js.map +1 -0
  77. package/dist/prompt/attachments.d.ts +7 -0
  78. package/dist/prompt/attachments.d.ts.map +1 -1
  79. package/dist/prompt/attachments.js +57 -0
  80. package/dist/prompt/attachments.js.map +1 -1
  81. package/dist/prompt/builder.js +1 -1
  82. package/dist/prompt/builder.js.map +1 -1
  83. package/dist/prompt/cache.d.ts +2 -0
  84. package/dist/prompt/cache.d.ts.map +1 -1
  85. package/dist/prompt/cache.js +2 -0
  86. package/dist/prompt/cache.js.map +1 -1
  87. package/dist/prompt/templates.d.ts +1 -1
  88. package/dist/prompt/templates.d.ts.map +1 -1
  89. package/dist/prompt/templates.js +4 -3
  90. package/dist/prompt/templates.js.map +1 -1
  91. package/dist/prompt/types.d.ts +3 -1
  92. package/dist/prompt/types.d.ts.map +1 -1
  93. package/dist/prompt/types.js.map +1 -1
  94. package/dist/proxy/server.d.ts.map +1 -1
  95. package/dist/proxy/server.js +32 -11
  96. package/dist/proxy/server.js.map +1 -1
  97. package/dist/search/ripgrep.d.ts.map +1 -1
  98. package/dist/search/ripgrep.js +11 -0
  99. package/dist/search/ripgrep.js.map +1 -1
  100. package/dist/session/index.d.ts +2 -0
  101. package/dist/session/index.d.ts.map +1 -1
  102. package/dist/session/index.js +1 -0
  103. package/dist/session/index.js.map +1 -1
  104. package/dist/skills/builtin/algorithmic-art/LICENSE.txt +202 -0
  105. package/dist/skills/builtin/algorithmic-art/SKILL.md +405 -0
  106. package/dist/skills/builtin/algorithmic-art/templates/generator_template.js +223 -0
  107. package/dist/skills/builtin/algorithmic-art/templates/viewer.html +599 -0
  108. package/dist/skills/builtin/analyze-logs/SKILL.md +75 -0
  109. package/dist/skills/builtin/audit-official/SKILL.md +81 -0
  110. package/dist/skills/builtin/brand-guidelines/LICENSE.txt +202 -0
  111. package/dist/skills/builtin/brand-guidelines/SKILL.md +73 -0
  112. package/dist/skills/builtin/build-portable/SKILL.md +53 -0
  113. package/dist/skills/builtin/canvas-design/SKILL.md +130 -0
  114. package/dist/skills/builtin/changelog/SKILL.md +65 -0
  115. package/dist/skills/builtin/code-review/SKILL.md +75 -0
  116. package/dist/skills/builtin/doc-coauthoring/SKILL.md +375 -0
  117. package/dist/skills/builtin/doctor/SKILL.md +166 -0
  118. package/dist/skills/builtin/docx/LICENSE.txt +30 -0
  119. package/dist/skills/builtin/docx/SKILL.md +590 -0
  120. package/dist/skills/builtin/docx/scripts/__init__.py +1 -0
  121. package/dist/skills/builtin/docx/scripts/accept_changes.py +135 -0
  122. package/dist/skills/builtin/docx/scripts/comment.py +318 -0
  123. package/dist/skills/builtin/docx/scripts/office/helpers/__init__.py +0 -0
  124. package/dist/skills/builtin/docx/scripts/office/helpers/merge_runs.py +199 -0
  125. package/dist/skills/builtin/docx/scripts/office/helpers/simplify_redlines.py +197 -0
  126. package/dist/skills/builtin/docx/scripts/office/pack.py +159 -0
  127. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  128. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  129. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  130. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  131. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  132. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  133. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  134. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  135. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  136. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  137. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  138. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  139. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  140. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  141. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  142. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  143. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  144. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  145. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  146. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  147. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  148. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  149. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  150. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  151. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  152. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  153. package/dist/skills/builtin/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  154. package/dist/skills/builtin/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  155. package/dist/skills/builtin/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  156. package/dist/skills/builtin/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  157. package/dist/skills/builtin/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  158. package/dist/skills/builtin/docx/scripts/office/schemas/mce/mc.xsd +75 -0
  159. package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  160. package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  161. package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  162. package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  163. package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  164. package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  165. package/dist/skills/builtin/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  166. package/dist/skills/builtin/docx/scripts/office/soffice.py +183 -0
  167. package/dist/skills/builtin/docx/scripts/office/unpack.py +132 -0
  168. package/dist/skills/builtin/docx/scripts/office/validate.py +111 -0
  169. package/dist/skills/builtin/docx/scripts/office/validators/__init__.py +15 -0
  170. package/dist/skills/builtin/docx/scripts/office/validators/base.py +847 -0
  171. package/dist/skills/builtin/docx/scripts/office/validators/docx.py +446 -0
  172. package/dist/skills/builtin/docx/scripts/office/validators/pptx.py +275 -0
  173. package/dist/skills/builtin/docx/scripts/office/validators/redlining.py +247 -0
  174. package/dist/skills/builtin/docx/scripts/templates/comments.xml +3 -0
  175. package/dist/skills/builtin/docx/scripts/templates/commentsExtended.xml +3 -0
  176. package/dist/skills/builtin/docx/scripts/templates/commentsExtensible.xml +3 -0
  177. package/dist/skills/builtin/docx/scripts/templates/commentsIds.xml +3 -0
  178. package/dist/skills/builtin/docx/scripts/templates/people.xml +3 -0
  179. package/dist/skills/builtin/frontend-design/LICENSE.txt +177 -0
  180. package/dist/skills/builtin/frontend-design/SKILL.md +42 -0
  181. package/dist/skills/builtin/i18n-check/SKILL.md +56 -0
  182. package/dist/skills/builtin/internal-comms/LICENSE.txt +202 -0
  183. package/dist/skills/builtin/internal-comms/SKILL.md +32 -0
  184. package/dist/skills/builtin/internal-comms/examples/3p-updates.md +47 -0
  185. package/dist/skills/builtin/internal-comms/examples/company-newsletter.md +65 -0
  186. package/dist/skills/builtin/internal-comms/examples/faq-answers.md +30 -0
  187. package/dist/skills/builtin/internal-comms/examples/general-comms.md +16 -0
  188. package/dist/skills/builtin/mcp-builder/LICENSE.txt +202 -0
  189. package/dist/skills/builtin/mcp-builder/SKILL.md +236 -0
  190. package/dist/skills/builtin/mcp-builder/reference/evaluation.md +602 -0
  191. package/dist/skills/builtin/mcp-builder/reference/mcp_best_practices.md +249 -0
  192. package/dist/skills/builtin/mcp-builder/reference/node_mcp_server.md +970 -0
  193. package/dist/skills/builtin/mcp-builder/reference/python_mcp_server.md +719 -0
  194. package/dist/skills/builtin/mcp-builder/scripts/connections.py +151 -0
  195. package/dist/skills/builtin/mcp-builder/scripts/evaluation.py +373 -0
  196. package/dist/skills/builtin/mcp-builder/scripts/example_evaluation.xml +22 -0
  197. package/dist/skills/builtin/mcp-builder/scripts/requirements.txt +2 -0
  198. package/dist/skills/builtin/pdf/LICENSE.txt +30 -0
  199. package/dist/skills/builtin/pdf/SKILL.md +314 -0
  200. package/dist/skills/builtin/pdf/forms.md +294 -0
  201. package/dist/skills/builtin/pdf/reference.md +612 -0
  202. package/dist/skills/builtin/pdf/scripts/check_bounding_boxes.py +65 -0
  203. package/dist/skills/builtin/pdf/scripts/check_fillable_fields.py +11 -0
  204. package/dist/skills/builtin/pdf/scripts/convert_pdf_to_images.py +33 -0
  205. package/dist/skills/builtin/pdf/scripts/create_validation_image.py +37 -0
  206. package/dist/skills/builtin/pdf/scripts/extract_form_field_info.py +122 -0
  207. package/dist/skills/builtin/pdf/scripts/extract_form_structure.py +115 -0
  208. package/dist/skills/builtin/pdf/scripts/fill_fillable_fields.py +98 -0
  209. package/dist/skills/builtin/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
  210. package/dist/skills/builtin/pptx/LICENSE.txt +30 -0
  211. package/dist/skills/builtin/pptx/SKILL.md +232 -0
  212. package/dist/skills/builtin/pptx/editing.md +205 -0
  213. package/dist/skills/builtin/pptx/pptxgenjs.md +420 -0
  214. package/dist/skills/builtin/pptx/scripts/__init__.py +0 -0
  215. package/dist/skills/builtin/pptx/scripts/add_slide.py +195 -0
  216. package/dist/skills/builtin/pptx/scripts/clean.py +286 -0
  217. package/dist/skills/builtin/pptx/scripts/office/helpers/__init__.py +0 -0
  218. package/dist/skills/builtin/pptx/scripts/office/helpers/merge_runs.py +199 -0
  219. package/dist/skills/builtin/pptx/scripts/office/helpers/simplify_redlines.py +197 -0
  220. package/dist/skills/builtin/pptx/scripts/office/pack.py +159 -0
  221. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  222. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  223. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  224. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  225. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  226. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  227. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  228. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  229. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  230. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  231. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  232. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  233. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  234. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  235. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  236. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  237. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  238. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  239. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  240. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  241. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  242. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  243. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  244. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  245. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  246. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  247. package/dist/skills/builtin/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  248. package/dist/skills/builtin/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  249. package/dist/skills/builtin/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  250. package/dist/skills/builtin/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  251. package/dist/skills/builtin/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  252. package/dist/skills/builtin/pptx/scripts/office/schemas/mce/mc.xsd +75 -0
  253. package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  254. package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  255. package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  256. package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  257. package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  258. package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  259. package/dist/skills/builtin/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  260. package/dist/skills/builtin/pptx/scripts/office/soffice.py +183 -0
  261. package/dist/skills/builtin/pptx/scripts/office/unpack.py +132 -0
  262. package/dist/skills/builtin/pptx/scripts/office/validate.py +111 -0
  263. package/dist/skills/builtin/pptx/scripts/office/validators/__init__.py +15 -0
  264. package/dist/skills/builtin/pptx/scripts/office/validators/base.py +847 -0
  265. package/dist/skills/builtin/pptx/scripts/office/validators/docx.py +446 -0
  266. package/dist/skills/builtin/pptx/scripts/office/validators/pptx.py +275 -0
  267. package/dist/skills/builtin/pptx/scripts/office/validators/redlining.py +247 -0
  268. package/dist/skills/builtin/pptx/scripts/thumbnail.py +289 -0
  269. package/dist/skills/builtin/promo-video/SKILL.md +124 -0
  270. package/dist/skills/builtin/promote/SKILL.md +77 -0
  271. package/dist/skills/builtin/skill-creator/LICENSE.txt +202 -0
  272. package/dist/skills/builtin/skill-creator/SKILL.md +598 -0
  273. package/dist/skills/builtin/skill-creator/agents/analyzer.md +274 -0
  274. package/dist/skills/builtin/skill-creator/agents/comparator.md +202 -0
  275. package/dist/skills/builtin/skill-creator/agents/grader.md +223 -0
  276. package/dist/skills/builtin/skill-creator/assets/eval_review.html +146 -0
  277. package/dist/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -0
  278. package/dist/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -0
  279. package/dist/skills/builtin/skill-creator/references/schemas.md +430 -0
  280. package/dist/skills/builtin/skill-creator/scripts/__init__.py +0 -0
  281. package/dist/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -0
  282. package/dist/skills/builtin/skill-creator/scripts/generate_report.py +326 -0
  283. package/dist/skills/builtin/skill-creator/scripts/improve_description.py +248 -0
  284. package/dist/skills/builtin/skill-creator/scripts/package_skill.py +136 -0
  285. package/dist/skills/builtin/skill-creator/scripts/quick_validate.py +103 -0
  286. package/dist/skills/builtin/skill-creator/scripts/run_eval.py +310 -0
  287. package/dist/skills/builtin/skill-creator/scripts/run_loop.py +332 -0
  288. package/dist/skills/builtin/skill-creator/scripts/utils.py +47 -0
  289. package/dist/skills/builtin/slack-gif-creator/LICENSE.txt +202 -0
  290. package/dist/skills/builtin/slack-gif-creator/SKILL.md +254 -0
  291. package/dist/skills/builtin/slack-gif-creator/core/easing.py +234 -0
  292. package/dist/skills/builtin/slack-gif-creator/core/frame_composer.py +176 -0
  293. package/dist/skills/builtin/slack-gif-creator/core/gif_builder.py +269 -0
  294. package/dist/skills/builtin/slack-gif-creator/core/validators.py +136 -0
  295. package/dist/skills/builtin/slack-gif-creator/requirements.txt +4 -0
  296. package/dist/skills/builtin/sync-version/SKILL.md +39 -0
  297. package/dist/skills/builtin/theme-factory/LICENSE.txt +202 -0
  298. package/dist/skills/builtin/theme-factory/SKILL.md +59 -0
  299. package/dist/skills/builtin/theme-factory/theme-showcase.pdf +0 -0
  300. package/dist/skills/builtin/theme-factory/themes/arctic-frost.md +19 -0
  301. package/dist/skills/builtin/theme-factory/themes/botanical-garden.md +19 -0
  302. package/dist/skills/builtin/theme-factory/themes/desert-rose.md +19 -0
  303. package/dist/skills/builtin/theme-factory/themes/forest-canopy.md +19 -0
  304. package/dist/skills/builtin/theme-factory/themes/golden-hour.md +19 -0
  305. package/dist/skills/builtin/theme-factory/themes/midnight-galaxy.md +19 -0
  306. package/dist/skills/builtin/theme-factory/themes/modern-minimalist.md +19 -0
  307. package/dist/skills/builtin/theme-factory/themes/ocean-depths.md +19 -0
  308. package/dist/skills/builtin/theme-factory/themes/sunset-boulevard.md +19 -0
  309. package/dist/skills/builtin/theme-factory/themes/tech-innovation.md +19 -0
  310. package/dist/skills/builtin/web-artifacts-builder/LICENSE.txt +202 -0
  311. package/dist/skills/builtin/web-artifacts-builder/SKILL.md +74 -0
  312. package/dist/skills/builtin/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
  313. package/dist/skills/builtin/web-artifacts-builder/scripts/init-artifact.sh +322 -0
  314. package/dist/skills/builtin/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  315. package/dist/skills/builtin/webapp-testing/LICENSE.txt +202 -0
  316. package/dist/skills/builtin/webapp-testing/SKILL.md +96 -0
  317. package/dist/skills/builtin/webapp-testing/examples/console_logging.py +35 -0
  318. package/dist/skills/builtin/webapp-testing/examples/element_discovery.py +40 -0
  319. package/dist/skills/builtin/webapp-testing/examples/static_html_automation.py +33 -0
  320. package/dist/skills/builtin/webapp-testing/scripts/with_server.py +106 -0
  321. package/dist/skills/builtin/xlsx/LICENSE.txt +30 -0
  322. package/dist/skills/builtin/xlsx/SKILL.md +292 -0
  323. package/dist/skills/builtin/xlsx/scripts/office/helpers/__init__.py +0 -0
  324. package/dist/skills/builtin/xlsx/scripts/office/helpers/merge_runs.py +199 -0
  325. package/dist/skills/builtin/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
  326. package/dist/skills/builtin/xlsx/scripts/office/pack.py +159 -0
  327. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  328. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  329. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  330. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  331. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  332. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  333. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  334. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  335. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  336. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  337. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  338. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  339. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  340. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  341. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  342. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  343. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  344. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  345. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  346. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  347. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  348. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  349. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  350. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  351. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  352. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  353. package/dist/skills/builtin/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  354. package/dist/skills/builtin/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  355. package/dist/skills/builtin/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  356. package/dist/skills/builtin/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  357. package/dist/skills/builtin/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  358. package/dist/skills/builtin/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
  359. package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  360. package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  361. package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  362. package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  363. package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  364. package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  365. package/dist/skills/builtin/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  366. package/dist/skills/builtin/xlsx/scripts/office/soffice.py +183 -0
  367. package/dist/skills/builtin/xlsx/scripts/office/unpack.py +132 -0
  368. package/dist/skills/builtin/xlsx/scripts/office/validate.py +111 -0
  369. package/dist/skills/builtin/xlsx/scripts/office/validators/__init__.py +15 -0
  370. package/dist/skills/builtin/xlsx/scripts/office/validators/base.py +847 -0
  371. package/dist/skills/builtin/xlsx/scripts/office/validators/docx.py +446 -0
  372. package/dist/skills/builtin/xlsx/scripts/office/validators/pptx.py +275 -0
  373. package/dist/skills/builtin/xlsx/scripts/office/validators/redlining.py +247 -0
  374. package/dist/skills/builtin/xlsx/scripts/recalc.py +184 -0
  375. package/dist/tools/base.d.ts +16 -0
  376. package/dist/tools/base.d.ts.map +1 -1
  377. package/dist/tools/base.js +32 -0
  378. package/dist/tools/base.js.map +1 -1
  379. package/dist/tools/bash.d.ts.map +1 -1
  380. package/dist/tools/bash.js +8 -0
  381. package/dist/tools/bash.js.map +1 -1
  382. package/dist/tools/file.d.ts +3 -1
  383. package/dist/tools/file.d.ts.map +1 -1
  384. package/dist/tools/file.js +116 -126
  385. package/dist/tools/file.js.map +1 -1
  386. package/dist/tools/generate-design.d.ts +5 -1
  387. package/dist/tools/generate-design.d.ts.map +1 -1
  388. package/dist/tools/generate-design.js +25 -3
  389. package/dist/tools/generate-design.js.map +1 -1
  390. package/dist/tools/goal.d.ts +1 -1
  391. package/dist/tools/goal.d.ts.map +1 -1
  392. package/dist/tools/goal.js +18 -9
  393. package/dist/tools/goal.js.map +1 -1
  394. package/dist/tools/index.d.ts +7 -0
  395. package/dist/tools/index.d.ts.map +1 -1
  396. package/dist/tools/index.js +67 -1
  397. package/dist/tools/index.js.map +1 -1
  398. package/dist/tools/network-agent.js +2 -1
  399. package/dist/tools/network-agent.js.map +1 -1
  400. package/dist/tools/schedule.d.ts.map +1 -1
  401. package/dist/tools/schedule.js +2 -26
  402. package/dist/tools/schedule.js.map +1 -1
  403. package/dist/tools/skill.d.ts +1 -1
  404. package/dist/tools/skill.d.ts.map +1 -1
  405. package/dist/tools/skill.js +18 -31
  406. package/dist/tools/skill.js.map +1 -1
  407. package/dist/web/server/api-manager.d.ts +3 -0
  408. package/dist/web/server/api-manager.d.ts.map +1 -1
  409. package/dist/web/server/api-manager.js +128 -12
  410. package/dist/web/server/api-manager.js.map +1 -1
  411. package/dist/web/server/app-manager.d.ts +71 -0
  412. package/dist/web/server/app-manager.d.ts.map +1 -0
  413. package/dist/web/server/app-manager.js +364 -0
  414. package/dist/web/server/app-manager.js.map +1 -0
  415. package/dist/web/server/channels/bridge.d.ts.map +1 -1
  416. package/dist/web/server/channels/bridge.js +2 -1
  417. package/dist/web/server/channels/bridge.js.map +1 -1
  418. package/dist/web/server/codex-auth-manager.d.ts +43 -0
  419. package/dist/web/server/codex-auth-manager.d.ts.map +1 -0
  420. package/dist/web/server/codex-auth-manager.js +429 -0
  421. package/dist/web/server/codex-auth-manager.js.map +1 -0
  422. package/dist/web/server/conversation.d.ts +34 -5
  423. package/dist/web/server/conversation.d.ts.map +1 -1
  424. package/dist/web/server/conversation.js +408 -132
  425. package/dist/web/server/conversation.js.map +1 -1
  426. package/dist/web/server/image-attachments.d.ts +23 -0
  427. package/dist/web/server/image-attachments.d.ts.map +1 -0
  428. package/dist/web/server/image-attachments.js +93 -0
  429. package/dist/web/server/image-attachments.js.map +1 -0
  430. package/dist/web/server/index.d.ts.map +1 -1
  431. package/dist/web/server/index.js +28 -0
  432. package/dist/web/server/index.js.map +1 -1
  433. package/dist/web/server/routes/__tests__/app-api.test.d.ts +5 -0
  434. package/dist/web/server/routes/__tests__/app-api.test.d.ts.map +1 -0
  435. package/dist/web/server/routes/__tests__/app-api.test.js +48 -0
  436. package/dist/web/server/routes/__tests__/app-api.test.js.map +1 -0
  437. package/dist/web/server/routes/__tests__/tunnel-api.test.d.ts +2 -0
  438. package/dist/web/server/routes/__tests__/tunnel-api.test.d.ts.map +1 -0
  439. package/dist/web/server/routes/__tests__/tunnel-api.test.js +96 -0
  440. package/dist/web/server/routes/__tests__/tunnel-api.test.js.map +1 -0
  441. package/dist/web/server/routes/ai-editor.d.ts.map +1 -1
  442. package/dist/web/server/routes/ai-editor.js +9 -45
  443. package/dist/web/server/routes/ai-editor.js.map +1 -1
  444. package/dist/web/server/routes/ai-hover.d.ts.map +1 -1
  445. package/dist/web/server/routes/ai-hover.js +6 -23
  446. package/dist/web/server/routes/ai-hover.js.map +1 -1
  447. package/dist/web/server/routes/api.d.ts.map +1 -1
  448. package/dist/web/server/routes/api.js +27 -20
  449. package/dist/web/server/routes/api.js.map +1 -1
  450. package/dist/web/server/routes/app-api.d.ts +8 -0
  451. package/dist/web/server/routes/app-api.d.ts.map +1 -0
  452. package/dist/web/server/routes/app-api.js +191 -0
  453. package/dist/web/server/routes/app-api.js.map +1 -0
  454. package/dist/web/server/routes/auth.d.ts.map +1 -1
  455. package/dist/web/server/routes/auth.js +306 -5
  456. package/dist/web/server/routes/auth.js.map +1 -1
  457. package/dist/web/server/routes/autocomplete-api.d.ts.map +1 -1
  458. package/dist/web/server/routes/autocomplete-api.js +5 -43
  459. package/dist/web/server/routes/autocomplete-api.js.map +1 -1
  460. package/dist/web/server/routes/axon-cloud.d.ts.map +1 -1
  461. package/dist/web/server/routes/axon-cloud.js +2 -0
  462. package/dist/web/server/routes/axon-cloud.js.map +1 -1
  463. package/dist/web/server/routes/network-api.d.ts +1 -0
  464. package/dist/web/server/routes/network-api.d.ts.map +1 -1
  465. package/dist/web/server/routes/network-api.js +36 -11
  466. package/dist/web/server/routes/network-api.js.map +1 -1
  467. package/dist/web/server/routes/port-forward.d.ts.map +1 -1
  468. package/dist/web/server/routes/port-forward.js +3 -2
  469. package/dist/web/server/routes/port-forward.js.map +1 -1
  470. package/dist/web/server/routes/schedule-api.d.ts.map +1 -1
  471. package/dist/web/server/routes/schedule-api.js +5 -1
  472. package/dist/web/server/routes/schedule-api.js.map +1 -1
  473. package/dist/web/server/routes/tunnel-api.d.ts +14 -0
  474. package/dist/web/server/routes/tunnel-api.d.ts.map +1 -0
  475. package/dist/web/server/routes/tunnel-api.js +52 -0
  476. package/dist/web/server/routes/tunnel-api.js.map +1 -0
  477. package/dist/web/server/runtime/codex-client.d.ts +30 -0
  478. package/dist/web/server/runtime/codex-client.d.ts.map +1 -0
  479. package/dist/web/server/runtime/codex-client.js +1002 -0
  480. package/dist/web/server/runtime/codex-client.js.map +1 -0
  481. package/dist/web/server/runtime/factory.d.ts +3 -0
  482. package/dist/web/server/runtime/factory.d.ts.map +1 -0
  483. package/dist/web/server/runtime/factory.js +16 -0
  484. package/dist/web/server/runtime/factory.js.map +1 -0
  485. package/dist/web/server/runtime/runtime-selection.d.ts +16 -0
  486. package/dist/web/server/runtime/runtime-selection.d.ts.map +1 -0
  487. package/dist/web/server/runtime/runtime-selection.js +33 -0
  488. package/dist/web/server/runtime/runtime-selection.js.map +1 -0
  489. package/dist/web/server/runtime/tool-input-normalizer.d.ts +3 -0
  490. package/dist/web/server/runtime/tool-input-normalizer.d.ts.map +1 -0
  491. package/dist/web/server/runtime/tool-input-normalizer.js +52 -0
  492. package/dist/web/server/runtime/tool-input-normalizer.js.map +1 -0
  493. package/dist/web/server/runtime/types.d.ts +97 -0
  494. package/dist/web/server/runtime/types.d.ts.map +1 -0
  495. package/dist/web/server/runtime/types.js +2 -0
  496. package/dist/web/server/runtime/types.js.map +1 -0
  497. package/dist/web/server/runtime/utility-client.d.ts +5 -0
  498. package/dist/web/server/runtime/utility-client.d.ts.map +1 -0
  499. package/dist/web/server/runtime/utility-client.js +65 -0
  500. package/dist/web/server/runtime/utility-client.js.map +1 -0
  501. package/dist/web/server/services/config-service.d.ts +7 -2
  502. package/dist/web/server/services/config-service.d.ts.map +1 -1
  503. package/dist/web/server/services/config-service.js +41 -0
  504. package/dist/web/server/services/config-service.js.map +1 -1
  505. package/dist/web/server/services/gemini-image-service.d.ts +20 -1
  506. package/dist/web/server/services/gemini-image-service.d.ts.map +1 -1
  507. package/dist/web/server/services/gemini-image-service.js +121 -13
  508. package/dist/web/server/services/gemini-image-service.js.map +1 -1
  509. package/dist/web/server/session-manager.d.ts +1 -0
  510. package/dist/web/server/session-manager.d.ts.map +1 -1
  511. package/dist/web/server/session-manager.js +1 -0
  512. package/dist/web/server/session-manager.js.map +1 -1
  513. package/dist/web/server/slash-commands.d.ts.map +1 -1
  514. package/dist/web/server/slash-commands.js +59 -17
  515. package/dist/web/server/slash-commands.js.map +1 -1
  516. package/dist/web/server/tunnel.d.ts +47 -0
  517. package/dist/web/server/tunnel.d.ts.map +1 -0
  518. package/dist/web/server/tunnel.js +165 -0
  519. package/dist/web/server/tunnel.js.map +1 -0
  520. package/dist/web/server/user-interaction.d.ts +10 -0
  521. package/dist/web/server/user-interaction.d.ts.map +1 -1
  522. package/dist/web/server/user-interaction.js +28 -0
  523. package/dist/web/server/user-interaction.js.map +1 -1
  524. package/dist/web/server/web-auth.d.ts +35 -3
  525. package/dist/web/server/web-auth.d.ts.map +1 -1
  526. package/dist/web/server/web-auth.js +298 -29
  527. package/dist/web/server/web-auth.js.map +1 -1
  528. package/dist/web/server/web-scheduler.d.ts.map +1 -1
  529. package/dist/web/server/web-scheduler.js +9 -0
  530. package/dist/web/server/web-scheduler.js.map +1 -1
  531. package/dist/web/server/websocket-git-handlers.d.ts.map +1 -1
  532. package/dist/web/server/websocket-git-handlers.js +5 -29
  533. package/dist/web/server/websocket-git-handlers.js.map +1 -1
  534. package/dist/web/server/websocket.d.ts.map +1 -1
  535. package/dist/web/server/websocket.js +193 -44
  536. package/dist/web/server/websocket.js.map +1 -1
  537. package/dist/web/shared/auth-summary.d.ts +28 -0
  538. package/dist/web/shared/auth-summary.d.ts.map +1 -0
  539. package/dist/web/shared/auth-summary.js +53 -0
  540. package/dist/web/shared/auth-summary.js.map +1 -0
  541. package/dist/web/shared/model-catalog.d.ts +30 -0
  542. package/dist/web/shared/model-catalog.d.ts.map +1 -0
  543. package/dist/web/shared/model-catalog.js +373 -0
  544. package/dist/web/shared/model-catalog.js.map +1 -0
  545. package/dist/web/shared/model-preferences.d.ts +5 -0
  546. package/dist/web/shared/model-preferences.d.ts.map +1 -0
  547. package/dist/web/shared/model-preferences.js +13 -0
  548. package/dist/web/shared/model-preferences.js.map +1 -0
  549. package/dist/web/shared/setup-runtime.d.ts +27 -0
  550. package/dist/web/shared/setup-runtime.d.ts.map +1 -0
  551. package/dist/web/shared/setup-runtime.js +114 -0
  552. package/dist/web/shared/setup-runtime.js.map +1 -0
  553. package/dist/web/shared/thinking-config.d.ts +20 -0
  554. package/dist/web/shared/thinking-config.d.ts.map +1 -0
  555. package/dist/web/shared/thinking-config.js +99 -0
  556. package/dist/web/shared/thinking-config.js.map +1 -0
  557. package/dist/web/shared/types.d.ts +22 -2
  558. package/dist/web/shared/types.d.ts.map +1 -1
  559. package/dist/web/shared/types.js.map +1 -1
  560. package/electron/main.cjs +7 -2
  561. package/package.json +4 -2
  562. package/src/web/client/dist/assets/index-B0gwq5PJ.js +727 -0
  563. package/src/web/client/dist/assets/index-CwhuMLtk.css +32 -0
  564. package/src/web/client/dist/icons/icon-192.png +0 -0
  565. package/src/web/client/dist/icons/icon-512.png +0 -0
  566. package/src/web/client/dist/index.html +31 -0
  567. package/src/web/client/dist/logo.png +0 -0
  568. package/src/web/client/dist/manifest.webmanifest +25 -0
  569. package/src/web/client/dist/sw.js +78 -0
@@ -2,7 +2,6 @@
2
2
  * 对话管理器
3
3
  * 封装核心对话逻辑,提供 WebUI 专用接口
4
4
  */
5
- import { ClaudeClient } from '../../core/client.js';
6
5
  import { Session } from '../../core/session.js';
7
6
  import { runWithCwd } from '../../core/cwd-context.js';
8
7
  import { runWithSessionId } from '../../core/session-context.js';
@@ -15,6 +14,7 @@ import { createOAuthApiKey } from '../../auth/index.js';
15
14
  import { UserInteractionHandler } from './user-interaction.js';
16
15
  import { PermissionHandler } from './permission-handler.js';
17
16
  import { runPreToolUseHooks, runPostToolUseHooks, runPostToolUseFailureHooks } from '../../hooks/index.js';
17
+ import { getChangeTracker } from '../../hooks/auto-verify.js';
18
18
  import { WebSessionManager } from './session-manager.js';
19
19
  import { walAppend, walCheckpoint } from '../../session/index.js';
20
20
  import { TaskManager } from './task-manager.js';
@@ -45,6 +45,13 @@ import { appendRunLog } from '../../daemon/run-log.js';
45
45
  import { promptSnippetsManager } from './prompt-snippets.js';
46
46
  import { isEvolveRestartRequested, triggerGracefulShutdown } from './evolve-state.js';
47
47
  import { loadActiveGoals } from '../../goals/index.js';
48
+ import { getAppManager } from './app-manager.js';
49
+ import { createConversationClient } from './runtime/factory.js';
50
+ import { resolveRuntimeSelection } from './runtime/runtime-selection.js';
51
+ import { normalizeToolInputForWebRuntime } from './runtime/tool-input-normalizer.js';
52
+ import { resolveImageGenSource, } from './image-attachments.js';
53
+ import { getProviderForRuntimeBackend, } from '../shared/model-catalog.js';
54
+ import { mapThinkingConfigToRuntimeOptions, } from '../shared/thinking-config.js';
48
55
  import * as fs from 'fs';
49
56
  import * as path from 'path';
50
57
  import * as os from 'os';
@@ -360,7 +367,7 @@ export class ConversationManager {
360
367
  temporarilyEnabledMcpServers = new Set();
361
368
  constructor(cwd, defaultModel = 'opus', options) {
362
369
  this.cwd = cwd;
363
- this.defaultModel = defaultModel;
370
+ this.defaultModel = this.normalizeRuntimeModel(defaultModel);
364
371
  this.options = options;
365
372
  this.sessionManager = new WebSessionManager(cwd);
366
373
  this.mcpConfigManager = new McpConfigManager({
@@ -384,6 +391,13 @@ export class ConversationManager {
384
391
  });
385
392
  // 注册蓝图工具(仅 Web 模式需要,CLI 模式不加载)
386
393
  registerBlueprintTools();
394
+ // 初始化插件工具同步 — 将插件注册的工具桥接到 toolRegistry
395
+ // 这样 ConversationLoop 通过 toolRegistry.getDefinitions() 能拿到插件工具,模型 API 可以调用
396
+ const { initPluginToolSync } = await import('../../tools/index.js');
397
+ initPluginToolSync();
398
+ // 发现并加载已安装的插件,触发工具注册事件
399
+ await pluginManager.discover();
400
+ console.log(`[ConversationManager] Plugin discover completed, ${pluginManager.getTools().length} plugin tools synced`);
387
401
  // v12.0: 注入 StartLeadAgent 自包含执行上下文(支持 TaskPlan + 结构化错误)
388
402
  StartLeadAgentTool.setContext({
389
403
  getBlueprint: (id) => blueprintStore.get(id),
@@ -734,36 +748,78 @@ export class ConversationManager {
734
748
  /**
735
749
  * 计算凭据指纹,用于检测认证变更
736
750
  */
737
- getCredentialsFingerprint() {
738
- const creds = webAuth.getCredentials();
751
+ getCredentialsFingerprint(runtimeBackend = this.getRuntimeBackend()) {
752
+ const creds = webAuth.getCredentials(runtimeBackend);
739
753
  // 用凭据的关键字段拼接成指纹,任何变更都会导致指纹不同
740
- return `${creds.apiKey || ''}\0${creds.authToken || ''}\0${creds.baseUrl || ''}`;
754
+ return `${this.getRuntimeProvider(runtimeBackend)}\0${creds.apiKey || ''}\0${creds.authToken || ''}\0${creds.baseUrl || ''}\0${creds.accountId || ''}`;
741
755
  }
742
756
  /**
743
757
  * 检查凭据是否变更,如果变更则重建客户端
744
758
  * 处理场景:用户在 WebUI 重新登录/切换 API Key 后,已有会话自动使用新凭据
745
759
  */
746
760
  ensureClientCredentialsFresh(state) {
747
- const currentFingerprint = this.getCredentialsFingerprint();
761
+ const currentFingerprint = this.getCredentialsFingerprint(state.runtimeBackend);
748
762
  if (state.credentialsFingerprint && state.credentialsFingerprint !== currentFingerprint) {
749
763
  console.log('[ConversationManager] Detected auth credentials change, rebuilding client');
750
- const newConfig = this.buildClientConfig(state.model);
751
- state.client = new ClaudeClient({ ...newConfig });
764
+ const newConfig = this.buildClientConfig(state.model, state.runtimeBackend);
765
+ state.client = createConversationClient(newConfig);
752
766
  state.credentialsFingerprint = currentFingerprint;
753
767
  }
754
768
  }
769
+ getRuntimeBackend() {
770
+ return webAuth.getRuntimeBackend();
771
+ }
772
+ getRuntimeSelection(model, runtimeBackend = this.getRuntimeBackend()) {
773
+ return resolveRuntimeSelection({
774
+ runtimeBackend,
775
+ model,
776
+ defaultModelByBackend: webAuth.getDefaultModelByBackend(),
777
+ codexModelName: webAuth.getCodexModelName(),
778
+ customModelName: webAuth.getCustomModelName(),
779
+ });
780
+ }
781
+ getRuntimeProvider(runtimeBackend = this.getRuntimeBackend()) {
782
+ return this.getRuntimeSelection(undefined, runtimeBackend).provider;
783
+ }
784
+ getRuntimeCustomModelName(runtimeBackend = this.getRuntimeBackend()) {
785
+ return this.getRuntimeSelection(undefined, runtimeBackend).customModelName;
786
+ }
787
+ normalizeRuntimeModel(model, runtimeBackend = this.getRuntimeBackend()) {
788
+ return this.getRuntimeSelection(model, runtimeBackend).normalizedModel;
789
+ }
790
+ ensureStateModelMatchesRuntime(state) {
791
+ const normalizedModel = this.normalizeRuntimeModel(state.model, state.runtimeBackend);
792
+ if (normalizedModel === state.model) {
793
+ return;
794
+ }
795
+ state.model = normalizedModel;
796
+ state.client = createConversationClient(this.buildClientConfig(normalizedModel, state.runtimeBackend));
797
+ }
755
798
  /**
756
799
  * 构建 ClaudeClient 配置
757
800
  * 认证全部委托给 webAuth(唯一认证入口)
758
801
  */
759
- buildClientConfig(model) {
760
- const creds = webAuth.getCredentials();
761
- const customModel = webAuth.getCustomModelName();
802
+ buildClientConfig(model, runtimeBackend = this.getRuntimeBackend()) {
803
+ const creds = webAuth.getCredentials(runtimeBackend);
804
+ const selection = this.getRuntimeSelection(model, runtimeBackend);
805
+ const normalizedModel = selection.normalizedModel;
806
+ const provider = selection.provider;
807
+ const customModel = selection.customModelName;
808
+ const authStatus = webAuth.getStatus();
809
+ const identityVariant = provider === 'anthropic'
810
+ && runtimeBackend === 'claude-compatible-api'
811
+ && authStatus.type === 'oauth'
812
+ ? 'agent'
813
+ : undefined;
762
814
  return {
763
- model: customModel || this.getModelId(model),
815
+ provider,
816
+ model: provider === 'codex' ? normalizedModel : this.getModelId(normalizedModel),
764
817
  apiKey: creds.apiKey,
765
818
  authToken: creds.authToken,
766
819
  baseUrl: creds.baseUrl,
820
+ accountId: creds.accountId,
821
+ customModelName: customModel,
822
+ identityVariant,
767
823
  timeout: 300000,
768
824
  };
769
825
  }
@@ -777,6 +833,7 @@ export class ConversationManager {
777
833
  apiKey: config.apiKey,
778
834
  authToken: config.authToken,
779
835
  baseUrl: config.baseUrl,
836
+ accountId: config.accountId,
780
837
  };
781
838
  }
782
839
  /**
@@ -784,6 +841,26 @@ export class ConversationManager {
784
841
  * 这个方法在每次调用 API 之前被调用,检查 token 是否过期,如果过期则自动刷新
785
842
  */
786
843
  async ensureValidOAuthToken(state) {
844
+ const runtimeProvider = getProviderForRuntimeBackend(state.runtimeBackend, state.model);
845
+ const authStatus = webAuth.getStatus();
846
+ if (runtimeProvider !== 'anthropic') {
847
+ const tokenBefore = webAuth.getCredentials(state.runtimeBackend).authToken;
848
+ const refreshOk = await webAuth.ensureValidToken(state.runtimeBackend);
849
+ if (!refreshOk) {
850
+ throw new Error('OAuth token expired, refresh failed. Please log in again.');
851
+ }
852
+ const tokenAfter = webAuth.getCredentials(state.runtimeBackend).authToken;
853
+ if (tokenBefore !== tokenAfter) {
854
+ const newConfig = this.buildClientConfig(state.model, state.runtimeBackend);
855
+ state.client = createConversationClient(newConfig);
856
+ state.credentialsFingerprint = this.getCredentialsFingerprint(state.runtimeBackend);
857
+ console.log('[ConversationManager] Client now using refreshed OAuth credentials');
858
+ }
859
+ return;
860
+ }
861
+ if (authStatus.type !== 'oauth') {
862
+ return;
863
+ }
787
864
  // 只在使用 OAuth 时处理
788
865
  const oauthConfig = oauthManager.getOAuthConfig();
789
866
  if (!oauthConfig) {
@@ -799,9 +876,9 @@ export class ConversationManager {
799
876
  if (apiKey) {
800
877
  await oauthManager.saveOAuthConfig({ oauthApiKey: apiKey });
801
878
  console.log('[ConversationManager] OAuth API Key auto-created, rebuilding client');
802
- const newConfig = this.buildClientConfig(state.model);
803
- state.client = new ClaudeClient({ ...newConfig });
804
- state.credentialsFingerprint = this.getCredentialsFingerprint();
879
+ const newConfig = this.buildClientConfig(state.model, state.runtimeBackend);
880
+ state.client = createConversationClient(newConfig);
881
+ state.credentialsFingerprint = this.getCredentialsFingerprint(state.runtimeBackend);
805
882
  }
806
883
  else {
807
884
  console.warn('[ConversationManager] createOAuthApiKey returned null, inference may fail');
@@ -814,16 +891,16 @@ export class ConversationManager {
814
891
  // 记住刷新前的 token,用于判断是否需要重建客户端
815
892
  const tokenBefore = oauthManager.getOAuthConfig()?.accessToken;
816
893
  // 统一的 token 有效性检查(对齐官方 NM() 语义)
817
- const refreshOk = await webAuth.ensureValidToken();
894
+ const refreshOk = await webAuth.ensureValidToken(state.runtimeBackend);
818
895
  if (!refreshOk) {
819
896
  throw new Error('OAuth token expired, refresh failed. Please log in again.');
820
897
  }
821
898
  // 只有 token 真正变更了才重建客户端
822
899
  const tokenAfter = oauthManager.getOAuthConfig()?.accessToken;
823
900
  if (tokenBefore !== tokenAfter) {
824
- const newConfig = this.buildClientConfig(state.model);
825
- state.client = new ClaudeClient({ ...newConfig });
826
- state.credentialsFingerprint = this.getCredentialsFingerprint();
901
+ const newConfig = this.buildClientConfig(state.model, state.runtimeBackend);
902
+ state.client = createConversationClient(newConfig);
903
+ state.credentialsFingerprint = this.getCredentialsFingerprint(state.runtimeBackend);
827
904
  console.log('[ConversationManager] Client now using refreshed OAuth credentials');
828
905
  }
829
906
  }
@@ -834,6 +911,8 @@ export class ConversationManager {
834
911
  async getOrCreateSession(sessionId, model, projectPath, permissionMode) {
835
912
  let state = this.sessions.get(sessionId);
836
913
  if (state) {
914
+ state.runtimeBackend = state.runtimeBackend || this.getRuntimeBackend();
915
+ this.ensureStateModelMatchesRuntime(state);
837
916
  // 会话已存在,检查是否需要更新工作目录
838
917
  if (projectPath && state.session.cwd !== projectPath) {
839
918
  console.log(`[ConversationManager] Updated session ${sessionId} working directory: ${state.session.cwd} -> ${projectPath}`);
@@ -848,15 +927,14 @@ export class ConversationManager {
848
927
  }
849
928
  // 创建新会话
850
929
  const workingDir = projectPath || this.cwd;
930
+ const runtimeBackend = this.getRuntimeBackend();
931
+ const resolvedModel = this.normalizeRuntimeModel(model || this.defaultModel, runtimeBackend);
851
932
  console.log(`[ConversationManager] Creating new session ${sessionId}, workingDir: ${workingDir}, permissionMode: ${permissionMode || 'default'}`);
852
933
  const session = new Session(workingDir, sessionId);
853
934
  await session.initializeGitInfo();
854
935
  // 使用与核心 loop.ts 一致的认证逻辑
855
- const clientConfig = this.buildClientConfig(model || this.defaultModel);
856
- const client = new ClaudeClient({
857
- ...clientConfig,
858
- timeout: clientConfig.timeout,
859
- });
936
+ const clientConfig = this.buildClientConfig(resolvedModel, runtimeBackend);
937
+ const client = createConversationClient(clientConfig);
860
938
  // 创建用户交互处理器
861
939
  const userInteractionHandler = new UserInteractionHandler();
862
940
  userInteractionHandler.setSessionId(sessionId);
@@ -870,7 +948,8 @@ export class ConversationManager {
870
948
  session,
871
949
  client,
872
950
  messages: [],
873
- model: model || this.defaultModel,
951
+ model: resolvedModel,
952
+ runtimeBackend,
874
953
  cancelled: false,
875
954
  chatHistory: [],
876
955
  userInteractionHandler,
@@ -887,8 +966,9 @@ export class ConversationManager {
887
966
  processingGeneration: 0,
888
967
  lastActualInputTokens: 0,
889
968
  messagesLenAtLastApiCall: 0,
969
+ latestImageAttachments: [],
890
970
  lastPersistedMessageCount: 0,
891
- credentialsFingerprint: this.getCredentialsFingerprint(),
971
+ credentialsFingerprint: this.getCredentialsFingerprint(runtimeBackend),
892
972
  };
893
973
  this.sessions.set(sessionId, state);
894
974
  // 初始化 session memory(官方 session-memory 功能)
@@ -925,14 +1005,27 @@ export class ConversationManager {
925
1005
  setModel(sessionId, model) {
926
1006
  const state = this.sessions.get(sessionId);
927
1007
  if (state) {
928
- state.model = model;
1008
+ const normalizedModel = this.normalizeRuntimeModel(model, state.runtimeBackend);
1009
+ state.model = normalizedModel;
929
1010
  // 使用与核心 loop.ts 一致的认证逻辑
930
- const clientConfig = this.buildClientConfig(model);
931
- state.client = new ClaudeClient({
932
- ...clientConfig,
933
- timeout: clientConfig.timeout,
934
- });
1011
+ const clientConfig = this.buildClientConfig(normalizedModel, state.runtimeBackend);
1012
+ state.client = createConversationClient(clientConfig);
1013
+ }
1014
+ }
1015
+ getSessionModel(sessionId) {
1016
+ const state = this.sessions.get(sessionId);
1017
+ if (!state) {
1018
+ return null;
935
1019
  }
1020
+ this.ensureStateModelMatchesRuntime(state);
1021
+ return state.model;
1022
+ }
1023
+ getSessionRuntimeBackend(sessionId) {
1024
+ const state = this.sessions.get(sessionId);
1025
+ if (!state) {
1026
+ return null;
1027
+ }
1028
+ return state.runtimeBackend;
936
1029
  }
937
1030
  /**
938
1031
  * 获取历史记录
@@ -961,7 +1054,7 @@ export class ConversationManager {
961
1054
  const hasCompactBoundary = state.chatHistory.some(m => m.isCompactBoundary);
962
1055
  if (!hasCompactBoundary) {
963
1056
  // 未压缩:messages 是完整的,可以安全重建
964
- return this.convertMessagesToChatHistory(state.messages);
1057
+ return this.convertMessagesToChatHistory(state.messages, state.runtimeBackend);
965
1058
  }
966
1059
  // 已压缩:以 chatHistory 为基础,找出 messages 中还没同步的增量部分
967
1060
  // chatHistory 中最后一条记录的 _messagesLen 表示已经同步到 messages 的哪个位置
@@ -975,7 +1068,7 @@ export class ConversationManager {
975
1068
  if (incrementalMessages.length === 0) {
976
1069
  return state.chatHistory;
977
1070
  }
978
- const incrementalHistory = this.convertMessagesToChatHistory(incrementalMessages);
1071
+ const incrementalHistory = this.convertMessagesToChatHistory(incrementalMessages, state.runtimeBackend);
979
1072
  return [...state.chatHistory, ...incrementalHistory];
980
1073
  }
981
1074
  /**
@@ -1134,13 +1227,28 @@ export class ConversationManager {
1134
1227
  const state = this.sessions.get(sessionId);
1135
1228
  return state?.userInteractionHandler.getPendingPayloads() ?? [];
1136
1229
  }
1230
+ /**
1231
+ * 获取当前 ws 还未收到的待处理用户问题。
1232
+ * 用于恢复会话时补发,避免重复弹窗。
1233
+ */
1234
+ getUndeliveredPendingUserQuestions(sessionId) {
1235
+ const state = this.sessions.get(sessionId);
1236
+ return state?.userInteractionHandler.getUndeliveredPayloadsForCurrentWebSocket() ?? [];
1237
+ }
1238
+ /**
1239
+ * 标记问题已经送达当前 ws,防止同一连接被重复补发。
1240
+ */
1241
+ markPendingUserQuestionDelivered(sessionId, requestId) {
1242
+ const state = this.sessions.get(sessionId);
1243
+ state?.userInteractionHandler.markDeliveredToCurrentWebSocket(requestId);
1244
+ }
1137
1245
  /**
1138
1246
  * 媒体附件信息(图片或 PDF)
1139
1247
  */
1140
1248
  /**
1141
1249
  * 发送聊天消息
1142
1250
  */
1143
- async chat(sessionId, content, mediaAttachments, model, callbacks, projectPath, ws, permissionMode, messageId) {
1251
+ async chat(sessionId, content, mediaAttachments, model, callbacks, projectPath, ws, permissionMode, messageId, thinkingConfig) {
1144
1252
  const state = await this.getOrCreateSession(sessionId, model, projectPath, permissionMode);
1145
1253
  // 插话模式:如果会话正在处理中,取消当前操作并等待其完成
1146
1254
  if (state.isProcessing) {
@@ -1184,6 +1292,9 @@ export class ConversationManager {
1184
1292
  catch {
1185
1293
  // 增强失败不影响主流程
1186
1294
  }
1295
+ if (mediaAttachments && mediaAttachments.length > 0) {
1296
+ state.latestImageAttachments = mediaAttachments.map(attachment => ({ ...attachment }));
1297
+ }
1187
1298
  // 构建用户消息
1188
1299
  const userMessage = {
1189
1300
  role: 'user',
@@ -1217,6 +1328,7 @@ export class ConversationManager {
1217
1328
  media_type: attachment.mimeType,
1218
1329
  data: attachment.data,
1219
1330
  },
1331
+ fileName: attachment.name,
1220
1332
  });
1221
1333
  }
1222
1334
  }
@@ -1226,6 +1338,7 @@ export class ConversationManager {
1226
1338
  role: 'user',
1227
1339
  timestamp: Date.now(),
1228
1340
  content: chatContentItems,
1341
+ runtimeBackend: state.runtimeBackend,
1229
1342
  _messagesLen: state.messages.length,
1230
1343
  };
1231
1344
  state.chatHistory.push(chatEntry);
@@ -1237,7 +1350,7 @@ export class ConversationManager {
1237
1350
  // 使用工作目录上下文包裹对话循环(与 CLI loop.ts 保持一致)
1238
1351
  // 确保所有工具执行都在正确的工作目录上下文中
1239
1352
  await runWithCwd(state.session.cwd, async () => {
1240
- await this.conversationLoop(state, callbacks, sessionId);
1353
+ await this.conversationLoop(state, callbacks, sessionId, thinkingConfig);
1241
1354
  });
1242
1355
  }
1243
1356
  catch (error) {
@@ -1272,7 +1385,7 @@ export class ConversationManager {
1272
1385
  /**
1273
1386
  * 对话循环
1274
1387
  */
1275
- async conversationLoop(state, callbacks, sessionId) {
1388
+ async conversationLoop(state, callbacks, sessionId, thinkingConfig) {
1276
1389
  let continueLoop = true;
1277
1390
  let totalInputTokens = 0;
1278
1391
  let totalOutputTokens = 0;
@@ -1289,12 +1402,23 @@ export class ConversationManager {
1289
1402
  let messageConsistencyHealed = false;
1290
1403
  // 创建 AbortController,用于在取消时中断正在执行的工具
1291
1404
  state.currentAbortController = new AbortController();
1405
+ // Auto-verify: 设置全局 sessionId 供工具层追踪文件变更
1406
+ if (sessionId) {
1407
+ globalThis.__currentSessionId = sessionId;
1408
+ }
1292
1409
  while (continueLoop && !state.cancelled) {
1293
1410
  // 标记本次迭代是否已有内容流式输出到前端
1294
1411
  // 如果有内容已输出,则不进行自动重试(避免前端内容重复)
1295
1412
  let hasStreamedContent = false;
1296
1413
  // 初始化流式中间内容追踪(用于浏览器刷新后恢复)
1297
1414
  state.streamingContent = { thinkingText: '', textContent: '' };
1415
+ // Auto-verify: 每轮迭代重置注入标记
1416
+ if (sessionId) {
1417
+ try {
1418
+ getChangeTracker(sessionId).resetTurnFlag();
1419
+ }
1420
+ catch { /* ignore */ }
1421
+ }
1298
1422
  // 凭据变更检测(处理用户在 WebUI 重新登录后已有会话自动使用新凭据)
1299
1423
  this.ensureClientCredentialsFresh(state);
1300
1424
  // OAuth Token 自动刷新检查(在调用 API 之前)
@@ -1542,11 +1666,13 @@ export class ConversationManager {
1542
1666
  }
1543
1667
  }
1544
1668
  try {
1545
- // 调用 Claude API(使用 createMessageStream,默认开启 Extended Thinking)
1669
+ const thinkingOptions = mapThinkingConfigToRuntimeOptions(state.runtimeBackend, state.model, thinkingConfig);
1670
+ // 调用运行时 API(思考能力由前端 per-message 配置映射到真实 runtime 选项)
1546
1671
  // 传递 abort signal,取消时可直接中止 HTTP 流(对齐官方 CLI)
1547
1672
  const stream = state.client.createMessageStream(cleanedMessages, tools, systemPrompt.content, {
1548
- enableThinking: true,
1549
- thinkingBudget: 10000,
1673
+ enableThinking: thinkingOptions.enableThinking,
1674
+ thinkingBudget: thinkingOptions.thinkingBudget,
1675
+ reasoningEffort: thinkingOptions.reasoningEffort,
1550
1676
  signal: state.currentAbortController?.signal,
1551
1677
  promptBlocks: systemPrompt.blocks,
1552
1678
  toolSearchEnabled: hasToolSearch,
@@ -1592,25 +1718,38 @@ export class ConversationManager {
1592
1718
  }
1593
1719
  // 如果有未完成的工具调用(多工具响应时 content_block_stop 不产生事件),先完成它
1594
1720
  if (currentToolUse) {
1721
+ // 优先使用 SDK 注入的 parsedInput
1722
+ const sdkPrev = currentToolUse.parsedInput;
1595
1723
  let prevInput = {};
1596
- try {
1597
- prevInput = JSON.parse(currentToolUse.inputJson || '{}');
1724
+ if (sdkPrev && typeof sdkPrev === 'object' && Object.keys(sdkPrev).length > 0) {
1725
+ prevInput = sdkPrev;
1598
1726
  }
1599
- catch { /* 解析失败用空对象 */ }
1727
+ else {
1728
+ try {
1729
+ prevInput = JSON.parse(currentToolUse.inputJson || '{}');
1730
+ }
1731
+ catch {
1732
+ console.warn(`[StreamDebug] Failed to parse tool input JSON for ${currentToolUse.name} (length=${currentToolUse.inputJson.length}), raw start: ${currentToolUse.inputJson.slice(0, 100)}`);
1733
+ }
1734
+ }
1735
+ console.log(`[StreamDebug] tool_use_start: completing previous tool ${currentToolUse.name}(${currentToolUse.id}), keys=[${Object.keys(prevInput)}]`);
1600
1736
  assistantContent.push({
1601
1737
  type: 'tool_use',
1602
1738
  id: currentToolUse.id,
1603
1739
  name: currentToolUse.name,
1604
1740
  input: prevInput,
1605
1741
  });
1606
- callbacks.onToolUseStart?.(currentToolUse.id, currentToolUse.name, prevInput);
1742
+ // 通知前端完整 input(参数流完毕)
1743
+ callbacks.onToolUseInputReady?.(currentToolUse.id, prevInput);
1607
1744
  }
1608
- // 开始新的工具调用(先不发送 onToolUseStart,等参数解析完成后再发送)
1745
+ // 开始新的工具调用 — 立即通知前端(参数尚在流式传输)
1609
1746
  currentToolUse = {
1610
1747
  id: event.id || '',
1611
1748
  name: event.name || '',
1612
1749
  inputJson: '',
1613
1750
  };
1751
+ console.log(`[StreamDebug] tool_use_start: new tool ${currentToolUse.name}(${currentToolUse.id}), sending _streaming=true to frontend`);
1752
+ callbacks.onToolUseStart?.(currentToolUse.id, currentToolUse.name, { _streaming: true });
1614
1753
  break;
1615
1754
  case 'tool_use_delta':
1616
1755
  if (currentToolUse && event.input) {
@@ -1618,6 +1757,31 @@ export class ConversationManager {
1618
1757
  callbacks.onToolUseDelta?.(currentToolUse.id, event.input);
1619
1758
  }
1620
1759
  break;
1760
+ case 'tool_use_complete': {
1761
+ // 来自 SDK finalMessage 的完整 tool_use(input 已由 SDK parse 好)
1762
+ // 覆盖手动拼接的 inputJson,确保 input 的正确性
1763
+ const completeId = event.id;
1764
+ const completeInput = event.input;
1765
+ console.log(`[StreamDebug] tool_use_complete: id=${completeId}, inputKeys=${completeInput ? Object.keys(completeInput) : 'null'}`);
1766
+ // 如果当前有正在流式接收的工具且 id 匹配,直接注入解析好的 input
1767
+ if (currentToolUse && currentToolUse.id === completeId) {
1768
+ // 把 SDK 解析好的 input 保存到 currentToolUse(stop 事件会用)
1769
+ currentToolUse.parsedInput = completeInput;
1770
+ }
1771
+ else {
1772
+ // 可能是之前已经 push 到 assistantContent 的工具(多工具场景)
1773
+ // 用 SDK 的 input 覆盖手动 parse 的结果
1774
+ for (const block of assistantContent) {
1775
+ if (block.type === 'tool_use' && block.id === completeId) {
1776
+ block.input = completeInput || {};
1777
+ // 同时通知前端更新
1778
+ callbacks.onToolUseInputReady?.(completeId, completeInput || {});
1779
+ break;
1780
+ }
1781
+ }
1782
+ }
1783
+ break;
1784
+ }
1621
1785
  case 'stop':
1622
1786
  // 完成当前文本块
1623
1787
  if (currentTextContent) {
@@ -1626,12 +1790,22 @@ export class ConversationManager {
1626
1790
  }
1627
1791
  // 完成当前工具调用
1628
1792
  if (currentToolUse) {
1793
+ // 优先使用 SDK finalMessage 中的 input(由 tool_use_complete 事件注入)
1794
+ // 回退到手动拼接 inputJson + JSON.parse(兼容非标准 API)
1629
1795
  let parsedInput = {};
1630
- try {
1631
- parsedInput = JSON.parse(currentToolUse.inputJson || '{}');
1796
+ const sdkInput = currentToolUse.parsedInput;
1797
+ if (sdkInput && typeof sdkInput === 'object' && Object.keys(sdkInput).length > 0) {
1798
+ parsedInput = sdkInput;
1799
+ console.log(`[StreamDebug] stop: using SDK input for ${currentToolUse.name}(${currentToolUse.id}), keys=[${Object.keys(parsedInput)}]`);
1632
1800
  }
1633
- catch (e) {
1634
- // 解析失败使用空对象
1801
+ else {
1802
+ try {
1803
+ parsedInput = JSON.parse(currentToolUse.inputJson || '{}');
1804
+ console.log(`[StreamDebug] stop: using manual JSON.parse for ${currentToolUse.name}(${currentToolUse.id}), inputJson.length=${currentToolUse.inputJson.length}, keys=[${Object.keys(parsedInput)}]`);
1805
+ }
1806
+ catch (e) {
1807
+ console.warn(`[StreamDebug] stop: JSON.parse FAILED for ${currentToolUse.name} (length=${currentToolUse.inputJson.length}, stopReason=${event.stopReason}), raw start: ${currentToolUse.inputJson.slice(0, 200)}`);
1808
+ }
1635
1809
  }
1636
1810
  assistantContent.push({
1637
1811
  type: 'tool_use',
@@ -1639,8 +1813,8 @@ export class ConversationManager {
1639
1813
  name: currentToolUse.name,
1640
1814
  input: parsedInput,
1641
1815
  });
1642
- // 现在发送 onToolUseStart(参数已完整解析,只发送一次)
1643
- callbacks.onToolUseStart?.(currentToolUse.id, currentToolUse.name, parsedInput);
1816
+ // 通知前端完整 input(onToolUseStart 已在 tool_use_start 事件时发送)
1817
+ callbacks.onToolUseInputReady?.(currentToolUse.id, parsedInput);
1644
1818
  currentToolUse = null;
1645
1819
  }
1646
1820
  stopReason = event.stopReason || null;
@@ -1794,6 +1968,28 @@ export class ConversationManager {
1794
1968
  allNewMessages.push(...result.newMessages);
1795
1969
  }
1796
1970
  }
1971
+ // Auto-verify: 注入验证提示到最后一个工具结果
1972
+ if (sessionId && toolResults.length > 0) {
1973
+ try {
1974
+ const tracker = getChangeTracker(sessionId);
1975
+ const cwd = state.session.cwd || process.cwd();
1976
+ const hint = tracker.generateHint(cwd);
1977
+ if (hint) {
1978
+ // 找到最后一个 text 类型的工具结果并追加提示
1979
+ const lastResult = toolResults[toolResults.length - 1];
1980
+ if (typeof lastResult.content === 'string') {
1981
+ lastResult.content += `\n\n<auto-verify>${hint}</auto-verify>`;
1982
+ }
1983
+ else if (Array.isArray(lastResult.content)) {
1984
+ const textBlocks = lastResult.content.filter((b) => b.type === 'text');
1985
+ if (textBlocks.length > 0) {
1986
+ textBlocks[textBlocks.length - 1].text += `\n\n<auto-verify>${hint}</auto-verify>`;
1987
+ }
1988
+ }
1989
+ }
1990
+ }
1991
+ catch { /* auto-verify 失败不影响主流程 */ }
1992
+ }
1797
1993
  // 添加工具结果到消息
1798
1994
  if (toolResults.length > 0) {
1799
1995
  const toolResultMsg = {
@@ -1834,6 +2030,13 @@ export class ConversationManager {
1834
2030
  else {
1835
2031
  // 对话结束
1836
2032
  continueLoop = false;
2033
+ // 对齐官方:max_tokens 截断时,流式输出错误消息告知用户
2034
+ if (stopReason === 'max_tokens') {
2035
+ const currentMax = getMaxOutputTokens(resolvedModel);
2036
+ const errorMsg = `\n\nClaude's response exceeded the ${currentMax} output token maximum. ` +
2037
+ `Set CLAUDE_CODE_MAX_OUTPUT_TOKENS environment variable to a higher value to configure.`;
2038
+ callbacks.onTextDelta?.(errorMsg);
2039
+ }
1837
2040
  // 添加到聊天历史
1838
2041
  const chatContent = assistantContent.map(block => {
1839
2042
  if (block.type === 'text') {
@@ -1857,6 +2060,7 @@ export class ConversationManager {
1857
2060
  timestamp: Date.now(),
1858
2061
  content: chatContent,
1859
2062
  model: state.model,
2063
+ runtimeBackend: state.runtimeBackend,
1860
2064
  usage: {
1861
2065
  inputTokens: totalInputTokens,
1862
2066
  outputTokens: totalOutputTokens,
@@ -2083,6 +2287,7 @@ export class ConversationManager {
2083
2287
  sessionData.messages = state.messages;
2084
2288
  sessionData.chatHistory = state.chatHistory;
2085
2289
  sessionData.currentModel = state.model;
2290
+ sessionData.metadata.runtimeBackend = state.runtimeBackend;
2086
2291
  sessionData.toolFilterConfig = state.toolFilterConfig;
2087
2292
  sessionData.systemPromptConfig = state.systemPromptConfig;
2088
2293
  sessionData.metadata.messageCount = state.messages.length;
@@ -2124,7 +2329,7 @@ export class ConversationManager {
2124
2329
  // 如果 messages 中的 assistant 消息比 chatHistory 多,说明有消息没有同步
2125
2330
  if (assistantMsgCount > assistantChatCount) {
2126
2331
  // 从 messages 重建 chatHistory
2127
- state.chatHistory = this.convertMessagesToChatHistory(state.messages);
2332
+ state.chatHistory = this.convertMessagesToChatHistory(state.messages, state.runtimeBackend);
2128
2333
  console.log(`[ConversationManager] Syncing chatHistory: messages=${assistantMsgCount}, chatHistory=${state.chatHistory.filter(m => m.role === 'assistant').length}`);
2129
2334
  }
2130
2335
  }
@@ -2246,7 +2451,7 @@ export class ConversationManager {
2246
2451
  // --- 阶段 2: 执行子 agent ---
2247
2452
  sendCountdown('executing', 0);
2248
2453
  console.log(`[ScheduleTask] Countdown finished, starting execution: ${taskName}`);
2249
- const mainClientConfig = this.buildClientConfig(input.model || state.model);
2454
+ const mainClientConfig = this.buildClientConfig(input.model || state.model, state.runtimeBackend);
2250
2455
  const startedAt = Date.now();
2251
2456
  try {
2252
2457
  const result = await state.taskManager.executeScheduleTaskInline(taskName, task.prompt, {
@@ -2370,20 +2575,24 @@ export class ConversationManager {
2370
2575
  callbacks.onToolResult?.(toolUse.id, false, undefined, error);
2371
2576
  return { success: false, error };
2372
2577
  }
2578
+ const normalizedToolInput = normalizeToolInputForWebRuntime(toolUse.input, tool?.getInputSchema());
2579
+ const normalizedToolUse = normalizedToolInput === toolUse.input
2580
+ ? toolUse
2581
+ : { ...toolUse, input: normalizedToolInput };
2373
2582
  // 检查工具是否被过滤
2374
- if (!this.isToolEnabled(toolUse.name, state.toolFilterConfig)) {
2375
- const error = `Tool ${toolUse.name} is disabled`;
2376
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
2583
+ if (!this.isToolEnabled(normalizedToolUse.name, state.toolFilterConfig)) {
2584
+ const error = `Tool ${normalizedToolUse.name} is disabled`;
2585
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2377
2586
  return { success: false, error };
2378
2587
  }
2379
2588
  // ========================================================================
2380
2589
  // 权限检查(对齐 CLI loop.ts 的 handlePermissionRequest 逻辑)
2381
2590
  // ========================================================================
2382
2591
  try {
2383
- const permissionResult = await this.checkToolPermission(toolUse, state, callbacks);
2592
+ const permissionResult = await this.checkToolPermission(normalizedToolUse, state, callbacks);
2384
2593
  if (permissionResult === 'denied') {
2385
- const error = `User denied execution permission for ${toolUse.name}`;
2386
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
2594
+ const error = `User denied execution permission for ${normalizedToolUse.name}`;
2595
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2387
2596
  return { success: false, error };
2388
2597
  }
2389
2598
  // permissionResult === 'allowed' 或 'skipped'(无需权限),继续执行
@@ -2391,7 +2600,7 @@ export class ConversationManager {
2391
2600
  catch (permError) {
2392
2601
  // 权限请求超时或被取消
2393
2602
  const error = permError instanceof Error ? permError.message : 'Permission request failed';
2394
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
2603
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2395
2604
  return { success: false, error };
2396
2605
  }
2397
2606
  // ========================================================================
@@ -2399,10 +2608,10 @@ export class ConversationManager {
2399
2608
  // ========================================================================
2400
2609
  const hookSessionId = state.session.sessionId || '';
2401
2610
  try {
2402
- const hookResult = await runPreToolUseHooks(toolUse.name, toolUse.input, hookSessionId);
2611
+ const hookResult = await runPreToolUseHooks(normalizedToolUse.name, normalizedToolUse.input, hookSessionId);
2403
2612
  if (!hookResult.allowed) {
2404
- const error = hookResult.message || `PreToolUse hook blocked execution of ${toolUse.name}`;
2405
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
2613
+ const error = hookResult.message || `PreToolUse hook blocked execution of ${normalizedToolUse.name}`;
2614
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2406
2615
  return { success: false, error };
2407
2616
  }
2408
2617
  }
@@ -2411,23 +2620,23 @@ export class ConversationManager {
2411
2620
  console.warn(`[Hook] PreToolUse hook execution failed:`, hookError);
2412
2621
  }
2413
2622
  try {
2414
- console.log(`[Tool] Executing ${toolUse.name}:`, JSON.stringify(toolUse.input).slice(0, 200));
2623
+ console.log(`[Tool] Executing ${normalizedToolUse.name}:`, JSON.stringify(normalizedToolUse.input).slice(0, 200));
2415
2624
  // 拦截 Task 工具 - WebUI 模式下使用同步执行 + WebSocket 实时推送
2416
2625
  // 不再默认后台执行,避免 TaskOutput 多次轮询的性能浪费
2417
- if (toolUse.name === 'Task') {
2418
- const input = toolUse.input;
2626
+ if (normalizedToolUse.name === 'Task') {
2627
+ const input = normalizedToolUse.input;
2419
2628
  const description = input.description || 'Background task';
2420
2629
  const prompt = input.prompt || '';
2421
2630
  const agentType = input.subagent_type || 'general-purpose';
2422
2631
  // 验证必需参数
2423
2632
  if (!prompt) {
2424
2633
  const error = 'Task prompt is required';
2425
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
2634
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2426
2635
  return { success: false, error };
2427
2636
  }
2428
2637
  try {
2429
2638
  // 获取主 agent 的认证信息,传递给子 agent 复用(避免子 agent initAuth 拿到不同凭证导致 403)
2430
- const mainClientConfig = this.buildClientConfig(input.model || state.model);
2639
+ const mainClientConfig = this.buildClientConfig(input.model || state.model, state.runtimeBackend);
2431
2640
  // WebUI 始终使用同步执行:await 拿结果,中间过程由 TaskManager 通过 WebSocket 实时推送
2432
2641
  const result = await state.taskManager.executeTaskSync(description, prompt, agentType, {
2433
2642
  model: input.model || state.model,
@@ -2438,7 +2647,7 @@ export class ConversationManager {
2438
2647
  authToken: mainClientConfig.authToken,
2439
2648
  baseUrl: mainClientConfig.baseUrl,
2440
2649
  },
2441
- toolUseId: toolUse.id,
2650
+ toolUseId: normalizedToolUse.id,
2442
2651
  maxTurns: input.max_turns,
2443
2652
  });
2444
2653
  let output;
@@ -2460,7 +2669,7 @@ export class ConversationManager {
2460
2669
  }
2461
2670
  output = parts.join('');
2462
2671
  }
2463
- callbacks.onToolResult?.(toolUse.id, result.success, output, result.success ? undefined : result.error, {
2672
+ callbacks.onToolResult?.(normalizedToolUse.id, result.success, output, result.success ? undefined : result.error, {
2464
2673
  tool: 'Task',
2465
2674
  agentType,
2466
2675
  description,
@@ -2472,13 +2681,13 @@ export class ConversationManager {
2472
2681
  catch (error) {
2473
2682
  const errorMessage = error instanceof Error ? error.message : String(error);
2474
2683
  console.error(`[Tool] Task execution failed:`, errorMessage);
2475
- callbacks.onToolResult?.(toolUse.id, false, undefined, errorMessage);
2684
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
2476
2685
  return { success: false, error: errorMessage };
2477
2686
  }
2478
2687
  }
2479
2688
  // 拦截 ScheduleTask 工具 - inline 执行时提供倒计时 + 子 agent 渲染
2480
- if (toolUse.name === 'ScheduleTask') {
2481
- const input = toolUse.input;
2689
+ if (normalizedToolUse.name === 'ScheduleTask') {
2690
+ const input = normalizedToolUse.input;
2482
2691
  // 只拦截 create + once + 10分钟内的情况(即 inline 执行路径)
2483
2692
  if (input.action === 'create' && input.type === 'once' && input.triggerAt) {
2484
2693
  try {
@@ -2506,15 +2715,15 @@ export class ConversationManager {
2506
2715
  const scheduleTool = toolRegistry.get('ScheduleTask');
2507
2716
  if (!scheduleTool) {
2508
2717
  const error = 'ScheduleTask tool not found in registry';
2509
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
2718
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2510
2719
  return { success: false, error };
2511
2720
  }
2512
- const rawResult = await scheduleTool.execute(toolUse.input);
2721
+ const rawResult = await scheduleTool.execute(normalizedToolUse.input);
2513
2722
  const result = typeof rawResult === 'object' && rawResult !== null
2514
2723
  ? rawResult
2515
2724
  : { success: true, output: String(rawResult) };
2516
2725
  // 通知前端工具结果
2517
- callbacks.onToolResult?.(toolUse.id, result.success, result.output, result.error);
2726
+ callbacks.onToolResult?.(normalizedToolUse.id, result.success, result.output, result.error);
2518
2727
  // 用差集精确找到新创建的任务
2519
2728
  if (result.success && existingIds) {
2520
2729
  try {
@@ -2533,15 +2742,15 @@ export class ConversationManager {
2533
2742
  // list/cancel/watch 走正常工具执行路径
2534
2743
  }
2535
2744
  // 拦截 TaskOutput 工具 - 从 TaskManager 获取任务输出
2536
- if (toolUse.name === 'TaskOutput') {
2537
- const input = toolUse.input;
2745
+ if (normalizedToolUse.name === 'TaskOutput') {
2746
+ const input = normalizedToolUse.input;
2538
2747
  const taskId = input.task_id;
2539
2748
  const block = input.block !== false;
2540
2749
  const timeout = input.timeout || 300000; // 默认5分钟超时
2541
2750
  const showHistory = input.show_history || false;
2542
2751
  if (!taskId) {
2543
2752
  const error = 'task_id is required';
2544
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
2753
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2545
2754
  return { success: false, error };
2546
2755
  }
2547
2756
  try {
@@ -2560,11 +2769,11 @@ export class ConversationManager {
2560
2769
  const fallbackSuccess = typeof fallbackResult === 'string'
2561
2770
  ? true
2562
2771
  : fallbackResult?.success ?? false;
2563
- callbacks.onToolResult?.(toolUse.id, fallbackSuccess, fallbackOutput, fallbackSuccess ? undefined : fallbackOutput);
2772
+ callbacks.onToolResult?.(normalizedToolUse.id, fallbackSuccess, fallbackOutput, fallbackSuccess ? undefined : fallbackOutput);
2564
2773
  return { success: fallbackSuccess, output: fallbackOutput, error: fallbackSuccess ? undefined : fallbackOutput };
2565
2774
  }
2566
2775
  const error = `Task ${taskId} not found`;
2567
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
2776
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2568
2777
  return { success: false, error };
2569
2778
  }
2570
2779
  // 如果需要阻塞等待完成
@@ -2575,7 +2784,7 @@ export class ConversationManager {
2575
2784
  }
2576
2785
  if (task.status === 'running') {
2577
2786
  const output = `Task ${taskId} is still running (timeout reached).\n\nStatus: ${task.status}\nDescription: ${task.description}`;
2578
- callbacks.onToolResult?.(toolUse.id, true, output);
2787
+ callbacks.onToolResult?.(normalizedToolUse.id, true, output);
2579
2788
  return { success: true, output };
2580
2789
  }
2581
2790
  }
@@ -2608,23 +2817,23 @@ export class ConversationManager {
2608
2817
  else if (task.error) {
2609
2818
  output += `\nError: ${task.error}`;
2610
2819
  }
2611
- callbacks.onToolResult?.(toolUse.id, true, output);
2820
+ callbacks.onToolResult?.(normalizedToolUse.id, true, output);
2612
2821
  return { success: true, output };
2613
2822
  }
2614
2823
  catch (error) {
2615
2824
  const errorMessage = error instanceof Error ? error.message : String(error);
2616
2825
  console.error(`[Tool] TaskOutput execution failed:`, errorMessage);
2617
- callbacks.onToolResult?.(toolUse.id, false, undefined, errorMessage);
2826
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
2618
2827
  return { success: false, error: errorMessage };
2619
2828
  }
2620
2829
  }
2621
2830
  // 拦截 AskUserQuestion 工具 - 通过 WebSocket 向前端发送问题
2622
- if (toolUse.name === 'AskUserQuestion') {
2623
- const input = toolUse.input;
2831
+ if (normalizedToolUse.name === 'AskUserQuestion') {
2832
+ const input = normalizedToolUse.input;
2624
2833
  const questions = input.questions || [];
2625
2834
  if (questions.length === 0) {
2626
2835
  const error = 'No questions provided';
2627
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
2836
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2628
2837
  return { success: false, error };
2629
2838
  }
2630
2839
  const answers = {};
@@ -2645,19 +2854,19 @@ export class ConversationManager {
2645
2854
  .map(([header, answer]) => `"${header}"="${answer}"`)
2646
2855
  .join(', ');
2647
2856
  const output = `User has answered your questions: ${formattedAnswers}. You can now continue with the user's answers in mind.`;
2648
- callbacks.onToolResult?.(toolUse.id, true, output);
2857
+ callbacks.onToolResult?.(normalizedToolUse.id, true, output);
2649
2858
  return { success: true, output };
2650
2859
  }
2651
2860
  catch (error) {
2652
2861
  const errorMessage = error instanceof Error ? error.message : String(error);
2653
2862
  console.error(`[Tool] AskUserQuestion failed:`, errorMessage);
2654
- callbacks.onToolResult?.(toolUse.id, false, undefined, errorMessage);
2863
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
2655
2864
  return { success: false, error: errorMessage };
2656
2865
  }
2657
2866
  }
2658
2867
  // 拦截 GenerateBlueprint 工具 - 将对话需求结构化为蓝图
2659
- if (toolUse.name === 'GenerateBlueprint') {
2660
- const input = toolUse.input;
2868
+ if (normalizedToolUse.name === 'GenerateBlueprint') {
2869
+ const input = normalizedToolUse.input;
2661
2870
  try {
2662
2871
  const blueprintId = `bp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
2663
2872
  const hasModules = Array.isArray(input.modules) && input.modules.length > 0;
@@ -2735,19 +2944,19 @@ export class ConversationManager {
2735
2944
  ? `Modules: ${moduleCount}, Processes: ${processCount}, NFR: ${nfrCount}`
2736
2945
  : `Requirements: ${reqCount}`;
2737
2946
  const output = `Blueprint generated and saved.\nBlueprint ID: ${blueprint.id}\nProject: ${blueprint.name}\nType: ${isCodebase ? 'Panoramic Blueprint' : 'Requirements Blueprint'}\n${stats}\n\nYou can now call StartLeadAgent to start execution.`;
2738
- callbacks.onToolResult?.(toolUse.id, true, output);
2947
+ callbacks.onToolResult?.(normalizedToolUse.id, true, output);
2739
2948
  return { success: true, output };
2740
2949
  }
2741
2950
  catch (error) {
2742
2951
  const errorMessage = error instanceof Error ? error.message : String(error);
2743
2952
  console.error(`[Tool] GenerateBlueprint execution failed:`, errorMessage);
2744
- callbacks.onToolResult?.(toolUse.id, false, undefined, errorMessage);
2953
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
2745
2954
  return { success: false, error: errorMessage };
2746
2955
  }
2747
2956
  }
2748
2957
  // v11.0: StartLeadAgent 不再拦截,走正常 tool.execute() 路径
2749
2958
  // 执行前动态绑定当前会话的 WebSocket 和工作目录,确保蜂群在正确的项目路径下执行
2750
- if (toolUse.name === 'StartLeadAgent') {
2959
+ if (normalizedToolUse.name === 'StartLeadAgent') {
2751
2960
  const currentCtx = StartLeadAgentTool.getContext();
2752
2961
  if (currentCtx) {
2753
2962
  StartLeadAgentTool.setContext({
@@ -2766,15 +2975,30 @@ export class ConversationManager {
2766
2975
  }
2767
2976
  }
2768
2977
  // 拦截 ImageGen 工具 - 文生图 / 图生图
2769
- if (toolUse.name === 'ImageGen') {
2770
- const input = toolUse.input;
2978
+ if (normalizedToolUse.name === 'ImageGen') {
2979
+ const input = normalizedToolUse.input;
2771
2980
  try {
2772
- const { prompt, style, image_path } = input;
2773
- console.log(`[Tool] ImageGen: ${image_path ? 'image-to-image' : 'text-to-image'} - ${prompt.substring(0, 50)}...`);
2774
- const result = await geminiImageService.generateImage(prompt, style, image_path);
2981
+ const { prompt, style, size, edit_strength, image_path, image_base64, image_mime_type, output_path } = input;
2982
+ console.log(`[Tool] ImageGen: ${image_path || image_base64 ? 'image-to-image' : 'text-to-image'} - ${prompt.substring(0, 50)}...`);
2983
+ const resolvedImageSource = resolveImageGenSource({
2984
+ image_path,
2985
+ image_base64,
2986
+ image_mime_type,
2987
+ }, state.latestImageAttachments);
2988
+ if (image_path && resolvedImageSource.imagePath && resolvedImageSource.imagePath !== image_path) {
2989
+ console.log(`[Tool] ImageGen: remapped uploaded image_path "${image_path}" -> "${resolvedImageSource.imagePath}"`);
2990
+ }
2991
+ else if (image_path && resolvedImageSource.imageBase64) {
2992
+ console.log(`[Tool] ImageGen: fell back to uploaded image base64 for "${image_path}"`);
2993
+ }
2994
+ const result = await geminiImageService.generateImage(prompt, style, {
2995
+ imagePath: resolvedImageSource.imagePath,
2996
+ imageBase64: resolvedImageSource.imageBase64,
2997
+ imageMimeType: resolvedImageSource.imageMimeType,
2998
+ }, output_path, size, edit_strength);
2775
2999
  if (!result.success) {
2776
3000
  const error = result.error || 'Image generation failed';
2777
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
3001
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2778
3002
  return { success: false, error };
2779
3003
  }
2780
3004
  // 通过 WebSocket 发送图片给前端显示
@@ -2789,21 +3013,28 @@ export class ConversationManager {
2789
3013
  },
2790
3014
  }));
2791
3015
  }
2792
- const output = `Image generated and sent to user for preview.${result.generatedText ? `\n\nDescription: ${result.generatedText}` : ''}\n\nUser can view the generated image in the chat interface.`;
2793
- callbacks.onToolResult?.(toolUse.id, true, output);
3016
+ const parts = ['Image generated and sent to user for preview.'];
3017
+ if (result.savedPath) {
3018
+ parts.push(`\nSaved to: ${result.savedPath}`);
3019
+ }
3020
+ if (result.generatedText) {
3021
+ parts.push(`\nDescription: ${result.generatedText}`);
3022
+ }
3023
+ const output = parts.join('');
3024
+ callbacks.onToolResult?.(normalizedToolUse.id, true, output);
2794
3025
  return { success: true, output };
2795
3026
  }
2796
3027
  catch (error) {
2797
3028
  const errorMessage = error instanceof Error ? error.message : String(error);
2798
3029
  console.error(`[Tool] ImageGen execution failed:`, errorMessage);
2799
- callbacks.onToolResult?.(toolUse.id, false, undefined, errorMessage);
3030
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
2800
3031
  return { success: false, error: errorMessage };
2801
3032
  }
2802
3033
  }
2803
3034
  // 拦截 Mcp 工具的 server management actions (action=list/enable/disable)
2804
3035
  // 这些 action 需要访问 ConversationManager 的 toggleMcpServer/listMcpServers
2805
- if (toolUse.name === 'Mcp') {
2806
- const input = toolUse.input;
3036
+ if (normalizedToolUse.name === 'Mcp') {
3037
+ const input = normalizedToolUse.input;
2807
3038
  if (input.action) {
2808
3039
  try {
2809
3040
  if (input.action === 'list') {
@@ -2812,13 +3043,13 @@ export class ConversationManager {
2812
3043
  const output = servers.length > 0
2813
3044
  ? `MCP Servers (${servers.length}):\n${lines.join('\n')}`
2814
3045
  : 'No MCP servers configured.';
2815
- callbacks.onToolResult?.(toolUse.id, true, output);
3046
+ callbacks.onToolResult?.(normalizedToolUse.id, true, output);
2816
3047
  return { success: true, output };
2817
3048
  }
2818
3049
  if (input.action === 'enable' || input.action === 'disable') {
2819
3050
  if (!input.name) {
2820
3051
  const error = `"name" parameter is required for ${input.action} action.`;
2821
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
3052
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2822
3053
  return { success: false, error };
2823
3054
  }
2824
3055
  const enabled = input.action === 'enable';
@@ -2832,23 +3063,23 @@ export class ConversationManager {
2832
3063
  this.temporarilyEnabledMcpServers.delete(input.name);
2833
3064
  }
2834
3065
  const output = `MCP server "${input.name}" has been ${result.enabled ? 'enabled' : 'disabled'}.`;
2835
- callbacks.onToolResult?.(toolUse.id, true, output);
3066
+ callbacks.onToolResult?.(normalizedToolUse.id, true, output);
2836
3067
  return { success: true, output };
2837
3068
  }
2838
3069
  else {
2839
3070
  const error = `Failed to ${input.action} MCP server "${input.name}". The server may not exist in the configuration. Use action="list" to see available servers.`;
2840
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
3071
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2841
3072
  return { success: false, error };
2842
3073
  }
2843
3074
  }
2844
3075
  const error = `Unknown Mcp action: ${input.action}. Use "list", "enable", or "disable".`;
2845
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
3076
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2846
3077
  return { success: false, error };
2847
3078
  }
2848
3079
  catch (error) {
2849
3080
  const errorMessage = error instanceof Error ? error.message : String(error);
2850
3081
  console.error(`[Tool] Mcp server management failed:`, errorMessage);
2851
- callbacks.onToolResult?.(toolUse.id, false, undefined, errorMessage);
3082
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, errorMessage);
2852
3083
  return { success: false, error: errorMessage };
2853
3084
  }
2854
3085
  }
@@ -2856,34 +3087,34 @@ export class ConversationManager {
2856
3087
  }
2857
3088
  // MCP 工具执行:解析 mcp__{serverName}__{toolName} 格式,调用 callMcpTool()
2858
3089
  if (isMcpTool) {
2859
- const parts = toolUse.name.split('__');
3090
+ const parts = normalizedToolUse.name.split('__');
2860
3091
  // 格式: mcp__{serverName}__{toolName}
2861
3092
  const mcpServerName = parts[1];
2862
3093
  const mcpToolName = parts.slice(2).join('__');
2863
3094
  if (!mcpServerName || !mcpToolName) {
2864
- const error = `Invalid MCP tool name format: ${toolUse.name}`;
2865
- callbacks.onToolResult?.(toolUse.id, false, undefined, error);
3095
+ const error = `Invalid MCP tool name format: ${normalizedToolUse.name}`;
3096
+ callbacks.onToolResult?.(normalizedToolUse.id, false, undefined, error);
2866
3097
  return { success: false, error };
2867
3098
  }
2868
- const mcpResult = await callMcpTool(mcpServerName, mcpToolName, toolUse.input);
3099
+ const mcpResult = await callMcpTool(mcpServerName, mcpToolName, normalizedToolUse.input);
2869
3100
  const mcpOutput = mcpResult.output || mcpResult.error || JSON.stringify(mcpResult);
2870
3101
  const truncatedMcpOutput = mcpOutput.length > 50000
2871
3102
  ? mcpOutput.slice(0, 50000) + '\n... (output truncated)'
2872
3103
  : mcpOutput;
2873
3104
  // PostToolUse Hook
2874
3105
  try {
2875
- await runPostToolUseHooks(toolUse.name, toolUse.input, truncatedMcpOutput, hookSessionId);
3106
+ await runPostToolUseHooks(normalizedToolUse.name, normalizedToolUse.input, truncatedMcpOutput, hookSessionId);
2876
3107
  }
2877
3108
  catch (hookError) {
2878
3109
  console.warn(`[Hook] PostToolUse hook execution failed:`, hookError);
2879
3110
  }
2880
- callbacks.onToolResult?.(toolUse.id, mcpResult.success, truncatedMcpOutput, mcpResult.error ? mcpResult.error : undefined);
3111
+ callbacks.onToolResult?.(normalizedToolUse.id, mcpResult.success, truncatedMcpOutput, mcpResult.error ? mcpResult.error : undefined);
2881
3112
  return { success: mcpResult.success, output: truncatedMcpOutput, error: mcpResult.error };
2882
3113
  }
2883
3114
  // 执行其他工具(内置 registry 工具)
2884
- const result = await tool.execute(toolUse.input);
3115
+ const result = await tool.execute(normalizedToolUse.input);
2885
3116
  // 构建结构化数据
2886
- const data = this.buildToolResultData(toolUse.name, toolUse.input, result);
3117
+ const data = this.buildToolResultData(normalizedToolUse.name, normalizedToolUse.input, result);
2887
3118
  // 格式化输出
2888
3119
  let output;
2889
3120
  if (typeof result === 'string') {
@@ -2918,7 +3149,7 @@ export class ConversationManager {
2918
3149
  : undefined;
2919
3150
  // PostToolUse Hook
2920
3151
  try {
2921
- await runPostToolUseHooks(toolUse.name, toolUse.input, output, hookSessionId);
3152
+ await runPostToolUseHooks(normalizedToolUse.name, normalizedToolUse.input, output, hookSessionId);
2922
3153
  }
2923
3154
  catch (hookError) {
2924
3155
  console.warn(`[Hook] PostToolUse hook execution failed:`, hookError);
@@ -3467,6 +3698,10 @@ Respond ONLY with valid JSON, no other text.`;
3467
3698
  }
3468
3699
  // 构建提示上下文(与 CLI loop.ts 保持一致)
3469
3700
  // 注意:不注入 contextUsage,保持 system prompt 稳定可缓存
3701
+ const runtimeBackend = state.runtimeBackend || this.getRuntimeBackend();
3702
+ const authStatus = webAuth.getStatus();
3703
+ const isAnthropicOauth = authStatus.type === 'oauth'
3704
+ && getProviderForRuntimeBackend(runtimeBackend, state.model) === 'anthropic';
3470
3705
  const promptContext = {
3471
3706
  workingDir: state.session.cwd,
3472
3707
  model: this.getModelId(state.model),
@@ -3480,8 +3715,12 @@ Respond ONLY with valid JSON, no other text.`;
3480
3715
  debug: false,
3481
3716
  // v2.1.0+: 语言配置 - 与 CLI 保持一致
3482
3717
  language: configManager.get('language'),
3483
- // 是否使用官方订阅认证(有 oauthToken oauthAccount 说明通过 Claude.ai 登录)
3484
- isOfficialAuth: webAuth.getStatus().type === 'oauth',
3718
+ // 只有 Claude 官方订阅 OAuth 才使用官方 CLI 身份前缀
3719
+ isOfficialAuth: isAnthropicOauth && runtimeBackend === 'claude-subscription',
3720
+ // Console OAuth + oauthApiKey 必须使用 Agent SDK 身份前缀
3721
+ coreIdentityVariant: isAnthropicOauth && runtimeBackend === 'claude-compatible-api'
3722
+ ? 'agent'
3723
+ : undefined,
3485
3724
  // Agent 笔记本内容
3486
3725
  notebookSummary,
3487
3726
  // MCP 服务器信息(用于系统提示中的 MCP 指令)
@@ -3638,6 +3877,29 @@ You are running in web server mode accessible by multiple users. HIGHEST PRIORIT
3638
3877
  // 端口转发功能提示 — 精简版
3639
3878
  sections.push(`# Port Forwarding
3640
3879
  When starting a web server for the user, they access it via \`/proxy/:port/\` (e.g. \`/proxy/9090/\`). After starting a server, tell the user: "Preview it here: [Open Preview](/proxy/9090/)". Supports HTTP and WebSocket, ports 1024-65535, localhost only.`);
3880
+ // 已注册应用感知
3881
+ try {
3882
+ const apps = getAppManager().list();
3883
+ if (apps.length > 0) {
3884
+ const appLines = apps.map(a => {
3885
+ const status = a.status === 'running' ? `running (pid ${a.pid}, port ${a.port || '?'})` : a.status;
3886
+ return `- **${a.name}** [${status}]: ${a.description || 'no description'} (dir: \`${a.directory}\`, cmd: \`${a.startCommand}\`)`;
3887
+ }).join('\n');
3888
+ sections.push(`# Managed Apps
3889
+ You have ${apps.length} registered app(s) in the Apps page. You can start/stop/manage them via \`GET/POST /api/apps\`.
3890
+ ${appLines}`);
3891
+ }
3892
+ }
3893
+ catch {
3894
+ // AppManager 未初始化时忽略
3895
+ }
3896
+ // ImageGen 使用约束
3897
+ sections.push(`## ImageGen tool usage
3898
+ - When the user provides an image attachment and asks to edit or transform that image, prefer calling ImageGen instead of only describing edits in text.
3899
+ - If the conversation context includes image attachment edit preferences, copy that preference into the ImageGen tool call as \`edit_strength\` ('low' | 'medium' | 'high').
3900
+ - For conservative/local edits, prefer \`edit_strength: 'low'\`.
3901
+ - For broader but still recognizable edits, prefer \`edit_strength: 'medium'\` or \`edit_strength: 'high'\` as appropriate.
3902
+ - When editing an uploaded image, pass the image through \`image_base64\` (or \`image_path\` if you truly have a file path) and keep the tool prompt focused on the requested change.`);
3641
3903
  if (sections.length === 0) {
3642
3904
  return null;
3643
3905
  }
@@ -3894,6 +4156,9 @@ Guidelines:
3894
4156
  broadcast({ type: 'tool_use_start', payload: { messageId, toolUseId, toolName, input, sessionId: targetSessionId } });
3895
4157
  broadcast({ type: 'status', payload: { status: 'tool_executing', message: `Executing ${toolName}...`, sessionId: targetSessionId } });
3896
4158
  },
4159
+ onToolUseInputReady: (toolUseId, input) => {
4160
+ broadcast({ type: 'tool_use_input_ready', payload: { toolUseId, input, sessionId: targetSessionId } });
4161
+ },
3897
4162
  onToolUseDelta: (toolUseId, partialJson) => broadcast({ type: 'tool_use_delta', payload: { toolUseId, partialJson, sessionId: targetSessionId } }),
3898
4163
  onToolResult: (toolUseId, success, output, error, data) => {
3899
4164
  broadcast({ type: 'tool_result', payload: { toolUseId, success, output, error, data: data, defaultCollapsed: true, sessionId: targetSessionId } });
@@ -3934,6 +4199,13 @@ Guidelines:
3934
4199
  }
3935
4200
  return state.session.cwd;
3936
4201
  }
4202
+ /**
4203
+ * 获取会话名称(从 sessionManager 的持久化数据中读取)
4204
+ */
4205
+ getSessionName(sessionId) {
4206
+ const sessionData = this.sessionManager.loadSessionById(sessionId);
4207
+ return sessionData?.metadata?.name;
4208
+ }
3937
4209
  /**
3938
4210
  * 持久化会话
3939
4211
  */
@@ -3963,6 +4235,7 @@ Guidelines:
3963
4235
  sessionData.messages = state.messages;
3964
4236
  sessionData.chatHistory = state.chatHistory;
3965
4237
  sessionData.currentModel = state.model;
4238
+ sessionData.metadata.runtimeBackend = state.runtimeBackend;
3966
4239
  sessionData.toolFilterConfig = state.toolFilterConfig;
3967
4240
  sessionData.systemPromptConfig = state.systemPromptConfig;
3968
4241
  // 关键:更新 messageCount(官方规范:统计消息数)
@@ -4019,9 +4292,10 @@ Guidelines:
4019
4292
  try {
4020
4293
  // 如果会话已经在内存中,直接返回成功(避免重复创建)
4021
4294
  if (this.sessions.has(sessionId)) {
4295
+ const state = this.sessions.get(sessionId);
4296
+ this.ensureStateModelMatchesRuntime(state);
4022
4297
  // 同步权限模式(修复切换会话后 YOLO 模式丢失的问题)
4023
4298
  if (permissionMode) {
4024
- const state = this.sessions.get(sessionId);
4025
4299
  state.permissionHandler.updateConfig({ mode: permissionMode });
4026
4300
  }
4027
4301
  return true;
@@ -4035,15 +4309,14 @@ Guidelines:
4035
4309
  const session = new Session(sessionData.metadata.workingDirectory || this.cwd);
4036
4310
  // 在后台异步获取 Git 信息,不阻塞会话切换(Git 信息主要用于 system prompt,在用户发送消息时才需要)
4037
4311
  session.initializeGitInfo().catch(() => { });
4038
- const clientConfig = this.buildClientConfig(sessionData.currentModel || this.defaultModel);
4039
- const client = new ClaudeClient({
4040
- ...clientConfig,
4041
- timeout: clientConfig.timeout,
4042
- });
4312
+ const runtimeBackend = sessionData.metadata.runtimeBackend || this.getRuntimeBackend();
4313
+ const resolvedModel = this.normalizeRuntimeModel(sessionData.currentModel || sessionData.metadata.model || this.defaultModel, runtimeBackend);
4314
+ const clientConfig = this.buildClientConfig(resolvedModel, runtimeBackend);
4315
+ const client = createConversationClient(clientConfig);
4043
4316
  // 如果 chatHistory 为空但 messages 不为空,从 messages 构建 chatHistory
4044
4317
  let chatHistory = sessionData.chatHistory || [];
4045
4318
  if (chatHistory.length === 0 && sessionData.messages && sessionData.messages.length > 0) {
4046
- chatHistory = this.convertMessagesToChatHistory(sessionData.messages);
4319
+ chatHistory = this.convertMessagesToChatHistory(sessionData.messages, runtimeBackend);
4047
4320
  }
4048
4321
  const resumeUserInteractionHandler = new UserInteractionHandler();
4049
4322
  resumeUserInteractionHandler.setSessionId(sessionId);
@@ -4051,7 +4324,8 @@ Guidelines:
4051
4324
  session,
4052
4325
  client,
4053
4326
  messages: sessionData.messages,
4054
- model: sessionData.currentModel || sessionData.metadata.model,
4327
+ model: resolvedModel,
4328
+ runtimeBackend,
4055
4329
  cancelled: false,
4056
4330
  chatHistory,
4057
4331
  userInteractionHandler: resumeUserInteractionHandler,
@@ -4068,8 +4342,9 @@ Guidelines:
4068
4342
  processingGeneration: 0,
4069
4343
  lastActualInputTokens: 0,
4070
4344
  messagesLenAtLastApiCall: 0,
4345
+ latestImageAttachments: [],
4071
4346
  lastPersistedMessageCount: sessionData.messages.length, // 从磁盘加载时,初始化为当前消息数
4072
- credentialsFingerprint: this.getCredentialsFingerprint(),
4347
+ credentialsFingerprint: this.getCredentialsFingerprint(runtimeBackend),
4073
4348
  };
4074
4349
  this.sessions.set(sessionId, state);
4075
4350
  // 初始化 NotebookManager(SelfEvolve 重启后 resumeSession 不经过 getOrCreateSession,需要在这里初始化)
@@ -4141,7 +4416,7 @@ Guidelines:
4141
4416
  /**
4142
4417
  * 将 API 消息格式转换为 ChatHistory 格式
4143
4418
  */
4144
- convertMessagesToChatHistory(messages) {
4419
+ convertMessagesToChatHistory(messages, runtimeBackend = this.getRuntimeBackend()) {
4145
4420
  const chatHistory = [];
4146
4421
  // 预构建 tool_use_id → tool_result 映射,用于将工具结果关联回工具调用
4147
4422
  const toolResultMap = new Map();
@@ -4192,6 +4467,7 @@ Guidelines:
4192
4467
  role: msg.role,
4193
4468
  timestamp: Date.now(),
4194
4469
  content: [],
4470
+ runtimeBackend,
4195
4471
  // 记录此 chatEntry 对应的 messages 位置(i+1 表示包含当前消息)
4196
4472
  _messagesLen: i + 1,
4197
4473
  };