agentworkshop 0.7.27 → 0.7.33

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 (1030) hide show
  1. package/.AgentWorkShop/prompts/aml-mission-default.md +20 -0
  2. package/.AgentWorkShop/prompts/aml-playbook.md +49 -0
  3. package/.AgentWorkShop/prompts/host-tools.json +314 -0
  4. package/.output/.AgentWorkShop/prompts/aml-mission-default.md +20 -0
  5. package/.output/.AgentWorkShop/prompts/aml-playbook.md +49 -0
  6. package/.output/.AgentWorkShop/prompts/host-tools.json +314 -0
  7. package/.output/.AgentWorkShop/schema.json +120 -0
  8. package/.output/nitro.json +1 -1
  9. package/.output/public/_nuxt/{BTLEvDxM.js → 4bHdIqEg.js} +8 -8
  10. package/.output/public/_nuxt/B9nXmjSB.js +19 -0
  11. package/.output/public/_nuxt/BASN8nZ0.js +1 -0
  12. package/.output/public/_nuxt/{DNQF_TXX.js → BBBtwOpo.js} +1 -1
  13. package/.output/public/_nuxt/{DoAlYsiF.js → BBwMH_hG.js} +1 -1
  14. package/.output/public/_nuxt/BWSE6hR6.js +1 -0
  15. package/.output/public/_nuxt/BZv4RFYN.js +1 -0
  16. package/.output/public/_nuxt/{BgCrZKv_2.js → Bc0AmjfT.js} +1 -1
  17. package/.output/public/_nuxt/BcmbLh2z2.js +1 -0
  18. package/.output/public/_nuxt/BgTB6h_q.js +2 -0
  19. package/.output/public/_nuxt/BkLJA9J5.js +1 -0
  20. package/.output/public/_nuxt/{XY2z78rj.js → BuCHayqN.js} +1 -1
  21. package/.output/public/_nuxt/{0jKrzLuM.js → BuvcLKh1.js} +1 -1
  22. package/.output/public/_nuxt/C-mDhyEd.js +1 -0
  23. package/.output/public/_nuxt/{DosOJEmZ2.js → C77oC8yC2.js} +1 -1
  24. package/.output/public/_nuxt/CQvmN-Mi.js +1 -0
  25. package/.output/public/_nuxt/CUDrOuW7.js +1 -0
  26. package/.output/public/_nuxt/{DjU9Dx5Y.js → CZcC-gpk.js} +1 -1
  27. package/.output/public/_nuxt/{Cz9gD2Yo.js → CbzsPO5H.js} +1 -1
  28. package/.output/public/_nuxt/CdSOrh2c.js +1 -0
  29. package/.output/public/_nuxt/Cgx818r-.js +1 -0
  30. package/.output/public/_nuxt/Cjm7VogC.js +1 -0
  31. package/.output/public/_nuxt/Cm5mDxzH.js +1 -0
  32. package/.output/public/_nuxt/Cp6z0RN7.js +1 -0
  33. package/.output/public/_nuxt/Ct-WOVr4.js +1 -0
  34. package/.output/public/_nuxt/CwqIxJGj.js +2 -0
  35. package/.output/public/_nuxt/{BGhOrgle.js → D0fhp-Ga.js} +2 -2
  36. package/.output/public/_nuxt/DIaTPH1M.js +1 -0
  37. package/.output/public/_nuxt/DLljr7g0.js +1 -0
  38. package/.output/public/_nuxt/DTYBfjRY.js +1 -0
  39. package/.output/public/_nuxt/DYKVPzN-.js +1 -0
  40. package/.output/public/_nuxt/DZzGarBE2.js +13 -0
  41. package/.output/public/_nuxt/DaMCzQhv.js +1 -0
  42. package/.output/public/_nuxt/DoMxCWN52.js +4 -0
  43. package/.output/public/_nuxt/{CucID8qg2.js → DoTdlVVe2.js} +1 -1
  44. package/.output/public/_nuxt/DsVcWfyR.js +1 -0
  45. package/.output/public/_nuxt/{BCJFMBQ6.js → DzuC31-i.js} +2 -2
  46. package/.output/public/_nuxt/FQri3dV3.js +1 -0
  47. package/.output/public/_nuxt/Lp7Ll94I.js +1 -0
  48. package/.output/public/_nuxt/PluginSlot.DmjNbrcX.css +1 -0
  49. package/.output/public/_nuxt/_id_.hRYo-EAB.css +1 -0
  50. package/.output/public/_nuxt/_wsId_.gXMEOYgX.css +1 -0
  51. package/.output/public/_nuxt/agents.BV70ioCv.css +1 -0
  52. package/.output/public/_nuxt/aml.WU_bh87J.css +1 -0
  53. package/.output/public/_nuxt/builds/latest.json +1 -1
  54. package/.output/public/_nuxt/builds/meta/291ef3e6-fa6a-4dee-8f46-05da1aeab815.json +1 -0
  55. package/.output/public/_nuxt/daq.Bb6l44-O.css +1 -0
  56. package/.output/public/_nuxt/default.jNT73_hq.css +1 -0
  57. package/.output/public/_nuxt/ekuGmQ7R.js +1 -0
  58. package/.output/public/_nuxt/entry.jFrFAWuA.css +1 -0
  59. package/.output/public/_nuxt/pMoIO6rr.js +14 -0
  60. package/.output/public/_nuxt/pages.Cc8GX9T1.css +1 -0
  61. package/.output/public/_nuxt/plugins.wIPyfPn-.css +1 -0
  62. package/.output/public/_nuxt/settings.BCm4NZIc.css +1 -0
  63. package/.output/public/_nuxt/teams.BC75EGnR.css +1 -0
  64. package/.output/server/chunks/_/binding-authz.mjs +23 -0
  65. package/.output/server/chunks/_/binding-authz.mjs.map +1 -0
  66. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  67. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  68. package/.output/server/chunks/_/nitro.mjs +13557 -6855
  69. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  70. package/.output/server/chunks/_/scene-layout.repo.mjs +3 -3
  71. package/.output/server/chunks/_/scene-layout.repo.mjs.map +1 -1
  72. package/.output/server/chunks/build/Checkbox-eax2M3o-.mjs +207 -0
  73. package/.output/server/chunks/build/Checkbox-eax2M3o-.mjs.map +1 -0
  74. package/.output/server/chunks/build/{OmpTerminalPanel-Cw_Vw9oO.mjs → OmpTerminalPanel-Cu_s4i0A.mjs} +2 -2
  75. package/.output/server/chunks/build/{OmpTerminalPanel-Cw_Vw9oO.mjs.map → OmpTerminalPanel-Cu_s4i0A.mjs.map} +1 -1
  76. package/.output/server/chunks/build/{alert-qJnjyRcP.mjs → PluginSlot-CcR4Ys3T.mjs} +140 -4
  77. package/.output/server/chunks/build/PluginSlot-CcR4Ys3T.mjs.map +1 -0
  78. package/.output/server/chunks/build/{TownView-ftIylqiD.mjs → TownView-BdHnAilw.mjs} +5 -5
  79. package/.output/server/chunks/build/{TownView-ftIylqiD.mjs.map → TownView-BdHnAilw.mjs.map} +1 -1
  80. package/.output/server/chunks/build/{_id_-CahfkmEt.mjs → _id_-Cb845FHR.mjs} +7 -5
  81. package/.output/server/chunks/build/_id_-Cb845FHR.mjs.map +1 -0
  82. package/.output/server/chunks/build/{_id_-3Axz2-gV.mjs → _id_-fadFPl2i.mjs} +50 -35
  83. package/.output/server/chunks/build/_id_-fadFPl2i.mjs.map +1 -0
  84. package/.output/server/chunks/build/{_wsId_-BymlQhzS.mjs → _wsId_-CTZswnm5.mjs} +181 -22
  85. package/.output/server/chunks/build/{_wsId_-BymlQhzS.mjs.map → _wsId_-CTZswnm5.mjs.map} +1 -1
  86. package/.output/server/chunks/build/{agents-DuMiSWKp.mjs → agents-Bvin73QY.mjs} +82 -32
  87. package/.output/server/chunks/build/agents-Bvin73QY.mjs.map +1 -0
  88. package/.output/server/chunks/build/aml-uBNIppIf.mjs +508 -0
  89. package/.output/server/chunks/build/aml-uBNIppIf.mjs.map +1 -0
  90. package/.output/server/chunks/build/apiClient-BwnfOQU8.mjs +81 -0
  91. package/.output/server/chunks/build/apiClient-BwnfOQU8.mjs.map +1 -0
  92. package/.output/server/chunks/build/{channel-templates-BStqJ-of.mjs → channel-templates-BTq8570n.mjs} +6 -5
  93. package/.output/server/chunks/build/channel-templates-BTq8570n.mjs.map +1 -0
  94. package/.output/server/chunks/build/{checkbox-C1gABOca.mjs → checkbox-8fB-wI-T.mjs} +2 -2
  95. package/.output/server/chunks/build/{checkbox-C1gABOca.mjs.map → checkbox-8fB-wI-T.mjs.map} +1 -1
  96. package/.output/server/chunks/build/{daq-ChYCABz1.mjs → daq-BvihjQyW.mjs} +111 -109
  97. package/.output/server/chunks/build/daq-BvihjQyW.mjs.map +1 -0
  98. package/.output/server/chunks/build/{dcw-CcQNGggh.mjs → dcw-Ks2vJ4PF.mjs} +5 -3
  99. package/.output/server/chunks/build/dcw-Ks2vJ4PF.mjs.map +1 -0
  100. package/.output/server/chunks/build/{default-95-zOTPt.mjs → default-GgHt4O2R.mjs} +164 -101
  101. package/.output/server/chunks/build/{default-95-zOTPt.mjs.map → default-GgHt4O2R.mjs.map} +1 -1
  102. package/.output/server/chunks/build/{input-number-Bd55elNN.mjs → input-number-DzpyYB99.mjs} +2 -2
  103. package/.output/server/chunks/build/{input-number-Bd55elNN.mjs.map → input-number-DzpyYB99.mjs.map} +1 -1
  104. package/.output/server/chunks/build/{logs-D-2UyGtE.mjs → logs-CYBhkQwh.mjs} +5 -3
  105. package/.output/server/chunks/build/logs-CYBhkQwh.mjs.map +1 -0
  106. package/.output/server/chunks/build/{monitor-mfG5jBtz.mjs → monitor-CyfDt4nR.mjs} +7 -6
  107. package/.output/server/chunks/build/{monitor-mfG5jBtz.mjs.map → monitor-CyfDt4nR.mjs.map} +1 -1
  108. package/.output/server/chunks/build/{pages-Dfosfchr.mjs → pages-C-6BRtv8.mjs} +57 -47
  109. package/.output/server/chunks/build/pages-C-6BRtv8.mjs.map +1 -0
  110. package/.output/server/chunks/build/{permissions-B-hhZuzm.mjs → permissions-B52oOmaO.mjs} +6 -5
  111. package/.output/server/chunks/build/permissions-B52oOmaO.mjs.map +1 -0
  112. package/.output/server/chunks/build/{plugins-DZR0T4Mh.mjs → plugins-dZRegC7m.mjs} +22 -18
  113. package/.output/server/chunks/build/plugins-dZRegC7m.mjs.map +1 -0
  114. package/.output/server/chunks/build/{segmented-LPPREMtZ.mjs → segmented-3TrWo0lS.mjs} +3 -3
  115. package/.output/server/chunks/build/{segmented-LPPREMtZ.mjs.map → segmented-3TrWo0lS.mjs.map} +1 -1
  116. package/.output/server/chunks/build/{settings-BajN9TQW.mjs → settings-CgDLkP3s.mjs} +437 -62
  117. package/.output/server/chunks/build/settings-CgDLkP3s.mjs.map +1 -0
  118. package/.output/server/chunks/build/{table-Bf1r2JjE.mjs → table-BjSWwmic.mjs} +4 -4
  119. package/.output/server/chunks/build/{table-Bf1r2JjE.mjs.map → table-BjSWwmic.mjs.map} +1 -1
  120. package/.output/server/chunks/build/{tag-NO9jEqKy.mjs → tag-DNE9vXc0.mjs} +3 -131
  121. package/.output/server/chunks/build/tag-DNE9vXc0.mjs.map +1 -0
  122. package/.output/server/chunks/build/{teams-t2SkRlJP.mjs → teams-2kz3CusY.mjs} +31 -30
  123. package/.output/server/chunks/build/teams-2kz3CusY.mjs.map +1 -0
  124. package/.output/server/chunks/build/{tokens-DiCojbN8.mjs → tokens-BbWLqtVz.mjs} +6 -5
  125. package/.output/server/chunks/build/tokens-BbWLqtVz.mjs.map +1 -0
  126. package/.output/server/chunks/build/town-BUqRobze.mjs +1 -0
  127. package/.output/server/chunks/build/town-BUqRobze.mjs.map +1 -1
  128. package/.output/server/chunks/build/{town-C7QM8DYK.mjs → town-DJ-V5G9U.mjs} +7 -5
  129. package/.output/server/chunks/build/town-DJ-V5G9U.mjs.map +1 -0
  130. package/.output/server/chunks/build/{useDaqStream-BeA2X8KR.mjs → useDaqStream-CIBaiGAl.mjs} +4 -3
  131. package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs.map +1 -0
  132. package/.output/server/chunks/build/{useDcwStream-BJW_MitY.mjs → useDcwStream-CBbiYnWe.mjs} +4 -80
  133. package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs.map +1 -0
  134. package/.output/server/chunks/build/{useDeviceTwins-Dwz_EY_i.mjs → useDeviceTwins-Yko6nNPF.mjs} +2 -2
  135. package/.output/server/chunks/build/{useDeviceTwins-Dwz_EY_i.mjs.map → useDeviceTwins-Yko6nNPF.mjs.map} +1 -1
  136. package/.output/server/chunks/build/{useOpsLog-Dm8QEb1I.mjs → useOpsLog-CO_VWh7t.mjs} +2 -2
  137. package/.output/server/chunks/build/{useOpsLog-Dm8QEb1I.mjs.map → useOpsLog-CO_VWh7t.mjs.map} +1 -1
  138. package/.output/server/chunks/build/{useWorkshopApi-B-L3MmIX.mjs → useWorkshopApi-NyjL0L3j.mjs} +4 -2
  139. package/.output/server/chunks/build/{useWorkshopApi-B-L3MmIX.mjs.map → useWorkshopApi-NyjL0L3j.mjs.map} +1 -1
  140. package/.output/server/chunks/build/{users-B9SAdEtH.mjs → users-4nzxTjFT.mjs} +6 -5
  141. package/.output/server/chunks/build/users-4nzxTjFT.mjs.map +1 -0
  142. package/.output/server/chunks/build/workshop-81xhz368.mjs +1 -0
  143. package/.output/server/chunks/build/workshop-81xhz368.mjs.map +1 -1
  144. package/.output/server/chunks/routes/api/health.get.mjs +1 -0
  145. package/.output/server/chunks/routes/api/health.get.mjs.map +1 -1
  146. package/.output/server/chunks/routes/api/index.get.mjs +1 -1
  147. package/.output/server/chunks/routes/api/index.post.mjs +1 -1
  148. package/.output/server/chunks/routes/api/metrics.mjs +1 -0
  149. package/.output/server/chunks/routes/api/metrics.mjs.map +1 -1
  150. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +1 -0
  151. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs.map +1 -1
  152. package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs +1 -0
  153. package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs.map +1 -1
  154. package/.output/server/chunks/routes/api/plugins/i18n.get.mjs +26 -0
  155. package/.output/server/chunks/routes/api/plugins/i18n.get.mjs.map +1 -0
  156. package/.output/server/chunks/routes/api/plugins/manifest.get.mjs +2 -1
  157. package/.output/server/chunks/routes/api/plugins/manifest.get.mjs.map +1 -1
  158. package/.output/server/chunks/routes/api/system/config-groups/_id_.delete.mjs +32 -0
  159. package/.output/server/chunks/routes/api/system/config-groups/_id_.delete.mjs.map +1 -0
  160. package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs +36 -0
  161. package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs.map +1 -0
  162. package/.output/server/chunks/routes/api/system/config.get.mjs +1 -0
  163. package/.output/server/chunks/routes/api/system/config.get.mjs.map +1 -1
  164. package/.output/server/chunks/routes/api/system/index.get.mjs +7 -2
  165. package/.output/server/chunks/routes/api/system/index.get.mjs.map +1 -1
  166. package/.output/server/chunks/routes/api/system/index.patch.mjs +2 -1
  167. package/.output/server/chunks/routes/api/system/index.patch.mjs.map +1 -1
  168. package/.output/server/chunks/routes/api/system/index.post.mjs +36 -0
  169. package/.output/server/chunks/routes/api/system/index.post.mjs.map +1 -0
  170. package/.output/server/chunks/routes/api/system/index2.get.mjs +28 -0
  171. package/.output/server/chunks/routes/api/system/index2.get.mjs.map +1 -0
  172. package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs +2 -1
  173. package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs.map +1 -1
  174. package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs +2 -1
  175. package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs.map +1 -1
  176. package/.output/server/chunks/routes/api/system/monitor.get.mjs +1 -0
  177. package/.output/server/chunks/routes/api/system/monitor.get.mjs.map +1 -1
  178. package/.output/server/chunks/routes/api/system/settings/events.get.mjs +8 -5
  179. package/.output/server/chunks/routes/api/system/settings/events.get.mjs.map +1 -1
  180. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs +2 -1
  181. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs.map +1 -1
  182. package/.output/server/chunks/routes/api/users/_id_.delete.mjs +2 -1
  183. package/.output/server/chunks/routes/api/users/_id_.delete.mjs.map +1 -1
  184. package/.output/server/chunks/routes/api/users/_id_.get.mjs +2 -1
  185. package/.output/server/chunks/routes/api/users/_id_.get.mjs.map +1 -1
  186. package/.output/server/chunks/routes/api/users/_id_.put.mjs +1 -1
  187. package/.output/server/chunks/routes/api/users/index.get.mjs +2 -1
  188. package/.output/server/chunks/routes/api/users/index.get.mjs.map +1 -1
  189. package/.output/server/chunks/routes/api/users/index.post.mjs +1 -1
  190. package/.output/server/chunks/routes/api/users/login.post.mjs +1 -1
  191. package/.output/server/chunks/routes/api/users/logout.post.mjs +2 -1
  192. package/.output/server/chunks/routes/api/users/logout.post.mjs.map +1 -1
  193. package/.output/server/chunks/routes/api/users/me.get.mjs +2 -1
  194. package/.output/server/chunks/routes/api/users/me.get.mjs.map +1 -1
  195. package/.output/server/chunks/routes/api/users/register.post.mjs +1 -1
  196. package/.output/server/chunks/routes/api/users/setup-status.get.mjs +2 -1
  197. package/.output/server/chunks/routes/api/users/setup-status.get.mjs.map +1 -1
  198. package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs +2 -1
  199. package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs.map +1 -1
  200. package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs +2 -1
  201. package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs.map +1 -1
  202. package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs +1 -1
  203. package/.output/server/chunks/routes/api/workshop/_...path_.mjs +2 -1
  204. package/.output/server/chunks/routes/api/workshop/_...path_.mjs.map +1 -1
  205. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs +2 -1
  206. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs.map +1 -1
  207. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs +1 -1
  208. package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs +1 -1
  209. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +2 -1
  210. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs.map +1 -1
  211. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs +5 -2
  212. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs.map +1 -1
  213. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +9 -3
  214. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs.map +1 -1
  215. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +2 -1
  216. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs.map +1 -1
  217. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +2 -1
  218. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs.map +1 -1
  219. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +23 -3
  220. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs.map +1 -1
  221. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +21 -3
  222. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
  223. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs +2 -1
  224. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs.map +1 -1
  225. package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs +2 -1
  226. package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs.map +1 -1
  227. package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs +2 -1
  228. package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs.map +1 -1
  229. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +1 -1
  230. package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs +1 -1
  231. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs +75 -0
  232. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs.map +1 -0
  233. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +35 -0
  234. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs.map +1 -0
  235. package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs +35 -0
  236. package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs.map +1 -0
  237. package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs +46 -0
  238. package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs.map +1 -0
  239. package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs +47 -0
  240. package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs.map +1 -0
  241. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs +48 -0
  242. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs.map +1 -0
  243. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs +41 -0
  244. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs.map +1 -0
  245. package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs +62 -0
  246. package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs.map +1 -0
  247. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs +35 -0
  248. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs.map +1 -0
  249. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs +36 -0
  250. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs.map +1 -0
  251. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs +34 -0
  252. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs.map +1 -0
  253. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs +38 -0
  254. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs.map +1 -0
  255. package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs +37 -0
  256. package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs.map +1 -0
  257. package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs +42 -0
  258. package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs.map +1 -0
  259. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +2 -1
  260. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs.map +1 -1
  261. package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs +2 -1
  262. package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs.map +1 -1
  263. package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs +2 -1
  264. package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs.map +1 -1
  265. package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs +2 -1
  266. package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs.map +1 -1
  267. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +2 -1
  268. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs.map +1 -1
  269. package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs +1 -0
  270. package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs.map +1 -1
  271. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +2 -1
  272. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs.map +1 -1
  273. package/.output/server/chunks/routes/api/workshop/audit.get.mjs +2 -1
  274. package/.output/server/chunks/routes/api/workshop/audit.get.mjs.map +1 -1
  275. package/.output/server/chunks/routes/api/workshop/caller.mjs +2 -1
  276. package/.output/server/chunks/routes/api/workshop/caller.mjs.map +1 -1
  277. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +2 -2
  278. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs +2 -1
  279. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs.map +1 -1
  280. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs +2 -1
  281. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs.map +1 -1
  282. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +1 -1
  283. package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs +1 -1
  284. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +2 -1
  285. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs.map +1 -1
  286. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs +2 -1
  287. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs.map +1 -1
  288. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs +1 -1
  289. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs +2 -1
  290. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs.map +1 -1
  291. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs +1 -1
  292. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs +2 -1
  293. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs.map +1 -1
  294. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs +2 -1
  295. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs.map +1 -1
  296. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs +2 -1
  297. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs.map +1 -1
  298. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs +2 -1
  299. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs.map +1 -1
  300. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs +2 -1
  301. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs.map +1 -1
  302. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +2 -1
  303. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs.map +1 -1
  304. package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs +1 -1
  305. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +2 -1
  306. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs.map +1 -1
  307. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
  308. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +2 -1
  309. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs.map +1 -1
  310. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs +2 -1
  311. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs.map +1 -1
  312. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs +1 -1
  313. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.mjs +1 -1
  314. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
  315. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +2 -1
  316. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs.map +1 -1
  317. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
  318. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +1 -0
  319. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs.map +1 -1
  320. package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs +2 -1
  321. package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs.map +1 -1
  322. package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs +2 -1
  323. package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs.map +1 -1
  324. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +2 -1
  325. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs.map +1 -1
  326. package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs +1 -0
  327. package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs.map +1 -1
  328. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +2 -1
  329. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs.map +1 -1
  330. package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs +1 -1
  331. package/.output/server/chunks/routes/api/workshop/channels.get.mjs +1 -0
  332. package/.output/server/chunks/routes/api/workshop/channels.get.mjs.map +1 -1
  333. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +4 -4
  334. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +2 -1
  335. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs.map +1 -1
  336. package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs +2 -1
  337. package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs.map +1 -1
  338. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +2 -1
  339. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs.map +1 -1
  340. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +2 -1
  341. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs.map +1 -1
  342. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +2 -1
  343. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs.map +1 -1
  344. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +2 -1
  345. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs.map +1 -1
  346. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +3 -1
  347. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs.map +1 -1
  348. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +2 -1
  349. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs.map +1 -1
  350. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +2 -1
  351. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs.map +1 -1
  352. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +2 -1
  353. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs.map +1 -1
  354. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +2 -1
  355. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs.map +1 -1
  356. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +2 -1
  357. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs.map +1 -1
  358. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +2 -1
  359. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs.map +1 -1
  360. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +2 -1
  361. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs.map +1 -1
  362. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +2 -1
  363. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs.map +1 -1
  364. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +2 -1
  365. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs.map +1 -1
  366. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +2 -1
  367. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs.map +1 -1
  368. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +2 -1
  369. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs.map +1 -1
  370. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +2 -1
  371. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs.map +1 -1
  372. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +2 -1
  373. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs.map +1 -1
  374. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +2 -1
  375. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs.map +1 -1
  376. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +2 -1
  377. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs.map +1 -1
  378. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +2 -1
  379. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs.map +1 -1
  380. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +2 -1
  381. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs.map +1 -1
  382. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +7 -2
  383. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs.map +1 -1
  384. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +2 -1
  385. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs.map +1 -1
  386. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +2 -1
  387. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs.map +1 -1
  388. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +2 -1
  389. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs.map +1 -1
  390. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +2 -1
  391. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs.map +1 -1
  392. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +2 -1
  393. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs.map +1 -1
  394. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +2 -1
  395. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs.map +1 -1
  396. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +2 -1
  397. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs.map +1 -1
  398. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +2 -1
  399. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs.map +1 -1
  400. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +2 -1
  401. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs.map +1 -1
  402. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +2 -1
  403. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs.map +1 -1
  404. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +2 -1
  405. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs.map +1 -1
  406. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +2 -1
  407. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs.map +1 -1
  408. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +2 -1
  409. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs.map +1 -1
  410. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +2 -1
  411. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs.map +1 -1
  412. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +2 -1
  413. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs.map +1 -1
  414. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs +2 -1
  415. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs.map +1 -1
  416. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +2 -1
  417. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs.map +1 -1
  418. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +2 -1
  419. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs.map +1 -1
  420. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +2 -1
  421. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs.map +1 -1
  422. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +2 -1
  423. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs.map +1 -1
  424. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +2 -1
  425. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs.map +1 -1
  426. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +2 -1
  427. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs.map +1 -1
  428. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +2 -1
  429. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs.map +1 -1
  430. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +2 -1
  431. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs.map +1 -1
  432. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs +2 -1
  433. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs.map +1 -1
  434. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +2 -1
  435. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs.map +1 -1
  436. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs +2 -1
  437. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs.map +1 -1
  438. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +2 -1
  439. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs.map +1 -1
  440. package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs +2 -1
  441. package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs.map +1 -1
  442. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +2 -1
  443. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs.map +1 -1
  444. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +2 -1
  445. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs.map +1 -1
  446. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +2 -1
  447. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs.map +1 -1
  448. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +2 -1
  449. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs.map +1 -1
  450. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +2 -1
  451. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs.map +1 -1
  452. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +2 -1
  453. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs.map +1 -1
  454. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +2 -1
  455. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs.map +1 -1
  456. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +2 -1
  457. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs.map +1 -1
  458. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +2 -1
  459. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs.map +1 -1
  460. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +2 -1
  461. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs.map +1 -1
  462. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +2 -1
  463. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs.map +1 -1
  464. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +32 -1
  465. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs.map +1 -1
  466. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +2 -1
  467. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs.map +1 -1
  468. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +2 -1
  469. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs.map +1 -1
  470. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +3 -2
  471. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs.map +1 -1
  472. package/.output/server/chunks/routes/api/workshop/index.get.mjs +1 -0
  473. package/.output/server/chunks/routes/api/workshop/index.get.mjs.map +1 -1
  474. package/.output/server/chunks/routes/api/workshop/index.post.mjs +1 -1
  475. package/.output/server/chunks/routes/api/workshop/index.put.mjs +2 -1
  476. package/.output/server/chunks/routes/api/workshop/index.put.mjs.map +1 -1
  477. package/.output/server/chunks/routes/api/workshop/index10.get.mjs +12 -6
  478. package/.output/server/chunks/routes/api/workshop/index10.get.mjs.map +1 -1
  479. package/.output/server/chunks/routes/api/workshop/index11.get.mjs +4 -2
  480. package/.output/server/chunks/routes/api/workshop/index11.get.mjs.map +1 -1
  481. package/.output/server/chunks/routes/api/workshop/index12.get.mjs +28 -0
  482. package/.output/server/chunks/routes/api/workshop/index12.get.mjs.map +1 -0
  483. package/.output/server/chunks/routes/api/workshop/index2.get.mjs +17 -11
  484. package/.output/server/chunks/routes/api/workshop/index2.get.mjs.map +1 -1
  485. package/.output/server/chunks/routes/api/workshop/index2.post.mjs +1 -1
  486. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +11 -4
  487. package/.output/server/chunks/routes/api/workshop/index3.get.mjs.map +1 -1
  488. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +2 -1
  489. package/.output/server/chunks/routes/api/workshop/index3.post.mjs.map +1 -1
  490. package/.output/server/chunks/routes/api/workshop/index4.get.mjs +5 -27
  491. package/.output/server/chunks/routes/api/workshop/index4.get.mjs.map +1 -1
  492. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +2 -1
  493. package/.output/server/chunks/routes/api/workshop/index4.post.mjs.map +1 -1
  494. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +24 -18
  495. package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
  496. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +2 -1
  497. package/.output/server/chunks/routes/api/workshop/index5.post.mjs.map +1 -1
  498. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +23 -5
  499. package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
  500. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +2 -1
  501. package/.output/server/chunks/routes/api/workshop/index6.post.mjs.map +1 -1
  502. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +4 -17
  503. package/.output/server/chunks/routes/api/workshop/index7.get.mjs.map +1 -1
  504. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +8 -3
  505. package/.output/server/chunks/routes/api/workshop/index7.post.mjs.map +1 -1
  506. package/.output/server/chunks/routes/api/workshop/index8.get.mjs +20 -21
  507. package/.output/server/chunks/routes/api/workshop/index8.get.mjs.map +1 -1
  508. package/.output/server/chunks/routes/api/workshop/index8.post.mjs +1 -1
  509. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +24 -11
  510. package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
  511. package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs +1 -0
  512. package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs.map +1 -1
  513. package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs +1 -0
  514. package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs.map +1 -1
  515. package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs +2 -1
  516. package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs.map +1 -1
  517. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +2 -1
  518. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs.map +1 -1
  519. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +2 -1
  520. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs.map +1 -1
  521. package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs +2 -1
  522. package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs.map +1 -1
  523. package/.output/server/chunks/routes/api/workshop/runtime.get.mjs +1 -0
  524. package/.output/server/chunks/routes/api/workshop/runtime.get.mjs.map +1 -1
  525. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +2 -1
  526. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs.map +1 -1
  527. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +2 -1
  528. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs.map +1 -1
  529. package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs +1 -0
  530. package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs.map +1 -1
  531. package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs +1 -1
  532. package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs +1 -1
  533. package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs +2 -1
  534. package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs.map +1 -1
  535. package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs +1 -1
  536. package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs +2 -1
  537. package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs.map +1 -1
  538. package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs +2 -1
  539. package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs.map +1 -1
  540. package/.output/server/chunks/routes/api/workshop/tasks.get.mjs +1 -0
  541. package/.output/server/chunks/routes/api/workshop/tasks.get.mjs.map +1 -1
  542. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -1
  543. package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs +2 -1
  544. package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs.map +1 -1
  545. package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs +1 -1
  546. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +44 -0
  547. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs.map +1 -0
  548. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +47 -0
  549. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs.map +1 -0
  550. package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs +2 -1
  551. package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs.map +1 -1
  552. package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs +2 -1
  553. package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs.map +1 -1
  554. package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs +2 -1
  555. package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs.map +1 -1
  556. package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs +1 -1
  557. package/.output/server/chunks/routes/api/workshop/users/me.get.mjs +2 -0
  558. package/.output/server/chunks/routes/api/workshop/users/me.get.mjs.map +1 -1
  559. package/.output/server/chunks/routes/api/workshop/users/register.post.mjs +1 -1
  560. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -2
  561. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs +1 -0
  562. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs.map +1 -1
  563. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs +1 -0
  564. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs.map +1 -1
  565. package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs +1 -0
  566. package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs.map +1 -1
  567. package/.output/server/chunks/routes/renderer.mjs +2 -2
  568. package/.output/server/chunks/virtual/entry.mjs +601 -36
  569. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  570. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  571. package/.output/server/index.mjs +1 -0
  572. package/.output/server/node_modules/@anthropic-ai/claude-agent-sdk/package.json +84 -0
  573. package/.output/server/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs +225 -0
  574. package/.output/server/package.json +2 -1
  575. package/README-zh.md +507 -478
  576. package/README.md +517 -486
  577. package/app/app.vue +17 -2
  578. package/app/assets/css/main.css +421 -30
  579. package/app/components/AppHeader.vue +17 -0
  580. package/app/components/AppSidebar.vue +162 -63
  581. package/app/components/AwChart.vue +57 -54
  582. package/app/components/workshop/ChannelSessionList.vue +802 -703
  583. package/app/components/workshop/DaqNodeRow.vue +156 -0
  584. package/app/components/workshop/PluginSlot.vue +120 -0
  585. package/app/composables/workshop/useAmlStream.ts +136 -0
  586. package/app/composables/workshop/useDaqStream.ts +8 -1
  587. package/app/composables/workshop/usePluginPanels.ts +72 -0
  588. package/app/composables/workshop/useWorkshopApi.ts +7 -0
  589. package/app/pages/aml/index.vue +1949 -0
  590. package/app/pages/daq/[id].vue +60 -2
  591. package/app/pages/daq/index.vue +7 -148
  592. package/app/pages/index.vue +235 -213
  593. package/app/pages/plugins/index.vue +280 -274
  594. package/app/pages/settings.vue +555 -78
  595. package/app/pages/workshop/agents.vue +23 -1
  596. package/app/pages/workshop/teams.vue +2 -2
  597. package/app/plugins/aw-plugins.client.ts +95 -6
  598. package/app/plugins/runtime-config.client.ts +4 -14
  599. package/app/plugins/theme.client.ts +13 -3
  600. package/app/stores/app.ts +9 -2
  601. package/app/stores/runtime-config.ts +113 -7
  602. package/cli/aw.mjs +16 -3
  603. package/cli/commands/build.mjs +8 -8
  604. package/cli/commands/dev.mjs +5 -13
  605. package/cli/commands/init.mjs +1 -1
  606. package/cli/commands/start.mjs +10 -17
  607. package/cli/core/args.mjs +85 -4
  608. package/cli/core/child-lifecycle.mjs +136 -0
  609. package/config.yml +24 -0
  610. package/docs/plugins.md +128 -220
  611. package/docs/sdk.md +1 -1
  612. package/i18n/dicts/_en.json +43 -2
  613. package/i18n/dicts/aml.json +163 -0
  614. package/i18n/dicts/channelSessionList.json +4 -1
  615. package/i18n/dicts/daqDetail.json +1 -0
  616. package/i18n/dicts/settings.json +33 -1
  617. package/i18n/dicts/teams.json +9 -1
  618. package/i18n/locales/en.ts +364 -132
  619. package/i18n/locales/zh-CN.ts +433 -201
  620. package/nuxt.config.ts +18 -3
  621. package/package.json +153 -149
  622. package/scripts/_audit/.tmp/audit-data/dcws.json +28 -0
  623. package/scripts/_audit/.tmp/dcw-writes.json +15650 -0
  624. package/scripts/_audit/.tmp/dcws.json +9033 -0
  625. package/scripts/_audit/.tmp/pollution-backup/dcw-rollback.polluted.json +470006 -0
  626. package/scripts/_audit/.tmp/pollution-backup/dcws.polluted.json +9085 -0
  627. package/scripts/_audit/.tmp/probe-cwd.txt +1 -0
  628. package/scripts/_audit/audit-harness-adapters.md +664 -0
  629. package/scripts/_audit/awhome/commands/README.md +3 -0
  630. package/scripts/_audit/awhome/commands/hello.mjs +12 -0
  631. package/scripts/_audit/dcw-controller-e2e.ts +99 -0
  632. package/scripts/_audit/dcw-flush-cost.ts +43 -0
  633. package/scripts/_audit/dcw-rollback-ledger.ts +153 -0
  634. package/scripts/_audit/dcw-unrecorded-write.ts +171 -0
  635. package/scripts/_audit/dcw-write-mutex.ts +157 -0
  636. package/scripts/_audit/diag-cwd.ts +20 -0
  637. package/scripts/_audit/diag-cwd2.ts +19 -0
  638. package/scripts/_audit/exp-cost-scaling.mjs +54 -0
  639. package/scripts/_audit/exp-envelope-and-png.mjs +77 -0
  640. package/scripts/_audit/exp-png-decode.mjs +67 -0
  641. package/scripts/_audit/exp-retention-plan.mjs +61 -0
  642. package/scripts/_audit/exp-retention-rescan.mjs +42 -0
  643. package/scripts/_audit/exp-sweep-fairness.mjs +48 -0
  644. package/scripts/_audit/hello.mjs +12 -0
  645. package/scripts/_audit/http-api-authz-audit.md +657 -0
  646. package/scripts/_audit/ndjson-partial-line-repro.mjs +77 -0
  647. package/scripts/_audit/opencode-await-ternary-repro.mjs +20 -0
  648. package/scripts/_audit/part-frag.txt +84 -0
  649. package/scripts/_audit/part-head.txt +45 -0
  650. package/scripts/_audit/probe-binding.mjs +103 -0
  651. package/scripts/_audit/probe-child.mjs +17 -0
  652. package/scripts/_audit/probe-envelope.mjs +49 -0
  653. package/scripts/_audit/probe-packlist.mjs +67 -0
  654. package/scripts/_audit/probe-routes.mjs +47 -0
  655. package/scripts/_audit/probe-routes2.mjs +38 -0
  656. package/scripts/_audit/probe.ts +9 -0
  657. package/scripts/_audit/probe2.ts +6 -0
  658. package/scripts/_audit/probe3.ts +3 -0
  659. package/scripts/_audit/probe4.ts +3 -0
  660. package/scripts/_audit/proj/.AgentWorkShop/commands/echoargs.mjs +13 -0
  661. package/scripts/_audit/proj/config.yml +1 -0
  662. package/scripts/_audit/run.mjs +30 -0
  663. package/scripts/_audit/runtime-audit.md +716 -0
  664. package/scripts/_audit/ts-resolve-hook.mjs +41 -0
  665. package/scripts/_audit/tsconfig.probe.json +24 -0
  666. package/scripts/_audit/typecheck-out.txt +466 -0
  667. package/scripts/_audit/verify-data-integrity.mjs +112 -0
  668. package/scripts/_dbg-agents-dropdown-shot.py +33 -0
  669. package/scripts/_dbg-anim-verify.mjs +1 -1
  670. package/scripts/_dbg-audit-all-pages.mjs +1 -1
  671. package/scripts/_dbg-availability-probe.ts +11 -0
  672. package/scripts/_dbg-bind-bidi-e2e.mjs +1 -1
  673. package/scripts/_dbg-cf-line-shot.mjs +18 -0
  674. package/scripts/_dbg-channel-plugin-ui.mjs +94 -0
  675. package/scripts/_dbg-configroot-audit.mjs +84 -0
  676. package/scripts/_dbg-crash-recovery.mjs +1 -1
  677. package/scripts/_dbg-crush-probe.sh +21 -0
  678. package/scripts/_dbg-crush-spawn-probe.ts +22 -0
  679. package/scripts/_dbg-daq-acc-probe.mjs +1 -1
  680. package/scripts/_dbg-daq-attrib.mjs +1 -1
  681. package/scripts/_dbg-daq-debug.mjs +1 -1
  682. package/scripts/_dbg-daq-diag.mjs +1 -1
  683. package/scripts/_dbg-daq-e2e.mjs +1 -1
  684. package/scripts/_dbg-daq-filter-e2e.mjs +1 -1
  685. package/scripts/_dbg-daq-filter-e2e2.mjs +1 -1
  686. package/scripts/_dbg-daq-final-regression.mjs +1 -1
  687. package/scripts/_dbg-daq-frame-alarm.mjs +1 -1
  688. package/scripts/_dbg-daq-frame-ui.mjs +1 -1
  689. package/scripts/_dbg-daq-frame-ws.mjs +1 -1
  690. package/scripts/_dbg-daq-frames-e2e.mjs +1 -1
  691. package/scripts/_dbg-daq-full-check.mjs +1 -1
  692. package/scripts/_dbg-daq-intervals-func.mjs +94 -0
  693. package/scripts/_dbg-daq-pages-shot.mjs +1 -1
  694. package/scripts/_dbg-daq-perf.mjs +1 -1
  695. package/scripts/_dbg-daq-probe.mjs +1 -1
  696. package/scripts/_dbg-daq-recipe-e2e.mjs +1 -1
  697. package/scripts/_dbg-daq-rows-probe.mjs +1 -1
  698. package/scripts/_dbg-daq-rowstate-e2e.mjs +1 -1
  699. package/scripts/_dbg-daq-rowstate-shot.mjs +1 -1
  700. package/scripts/_dbg-daq-rowstate-shot2.mjs +1 -1
  701. package/scripts/_dbg-daq-rowstyle-verify.mjs +112 -0
  702. package/scripts/_dbg-dash-console-check.mjs +1 -1
  703. package/scripts/_dbg-dash-deep-probe.mjs +1 -1
  704. package/scripts/_dbg-dash-hitpoint.mjs +1 -1
  705. package/scripts/_dbg-dcw-read-rest.mjs +1 -1
  706. package/scripts/_dbg-dcw-read-ui.mjs +1 -1
  707. package/scripts/_dbg-dcw-shot2.mjs +1 -1
  708. package/scripts/_dbg-diag-mock-loop.mjs +89 -0
  709. package/scripts/_dbg-diag-watch.mjs +95 -0
  710. package/scripts/_dbg-error-probe.mjs +2 -2
  711. package/scripts/_dbg-filter-light-verify.mjs +1 -1
  712. package/scripts/_dbg-final-acceptance-2.mjs +1 -1
  713. package/scripts/_dbg-final-acceptance.mjs +1 -1
  714. package/scripts/_dbg-final-full-e2e.mjs +1 -1
  715. package/scripts/_dbg-final-shots.mjs +32 -0
  716. package/scripts/_dbg-final-t6-hitl.mjs +1 -1
  717. package/scripts/_dbg-fix-unused-imports.py +41 -0
  718. package/scripts/_dbg-fresh-scene-e2e.mjs +1 -1
  719. package/scripts/_dbg-goose-probe.mjs +33 -0
  720. package/scripts/_dbg-goose-probe.sh +10 -0
  721. package/scripts/_dbg-groups-ui-verify.mjs +122 -0
  722. package/scripts/_dbg-harness-ui-shot.py +109 -0
  723. package/scripts/_dbg-hidden-check.mjs +1 -1
  724. package/scripts/_dbg-home-repro.mjs +1 -1
  725. package/scripts/_dbg-home-stack.mjs +1 -1
  726. package/scripts/_dbg-hydration-detail.mjs +1 -1
  727. package/scripts/_dbg-infra-lifecycle.mjs +1 -1
  728. package/scripts/_dbg-line-live-e2e.mjs +1 -1
  729. package/scripts/_dbg-line-repo-test.ts +10 -0
  730. package/scripts/_dbg-login-debug.py +23 -0
  731. package/scripts/_dbg-modbus-latency.mjs +22 -0
  732. package/scripts/_dbg-mqtt-chain-e2e.mjs +1 -1
  733. package/scripts/_dbg-oneshot-impl-probe.ts +67 -0
  734. package/scripts/_dbg-opt-team-e2e.mjs +1 -1
  735. package/scripts/_dbg-panesplitter-fix-check.mjs +1 -1
  736. package/scripts/_dbg-phase-e3-monitor.mjs +1 -1
  737. package/scripts/_dbg-pi-spawn-probe.ts +33 -0
  738. package/scripts/_dbg-plc-e2e.mjs +1 -1
  739. package/scripts/_dbg-plugin-config-ui.mjs +111 -0
  740. package/scripts/_dbg-plugin-panels-ui.mjs +54 -0
  741. package/scripts/_dbg-plugin-sink-rest.mjs +1 -1
  742. package/scripts/_dbg-plugin-sink-ui.mjs +1 -1
  743. package/scripts/_dbg-plugin-ui-wizard.mjs +1 -1
  744. package/scripts/_dbg-plugin-verify-e2e.mjs +1 -1
  745. package/scripts/_dbg-pop-clamp-verify.mjs +1 -1
  746. package/scripts/_dbg-preview-console.mjs +1 -1
  747. package/scripts/_dbg-preview-minrepro.mjs +1 -1
  748. package/scripts/_dbg-preview-pixels.mjs +1 -1
  749. package/scripts/_dbg-quality-pages-e2e.mjs +1 -1
  750. package/scripts/_dbg-qwen-acp-probe.mjs +30 -0
  751. package/scripts/_dbg-qwen-capture.mjs +21 -0
  752. package/scripts/_dbg-rail-tree-e2e.mjs +1 -1
  753. package/scripts/_dbg-real-driver-e2e.mjs +1 -1
  754. package/scripts/_dbg-real-scenario-timeline.log +55 -123
  755. package/scripts/_dbg-redesign-shots.mjs +1 -1
  756. package/scripts/_dbg-release-smoke.mjs +1 -1
  757. package/scripts/_dbg-resolve-probe.ts +6 -0
  758. package/scripts/_dbg-restart-persist.mjs +1 -1
  759. package/scripts/_dbg-sc001-dispatch.mjs +1 -1
  760. package/scripts/_dbg-scenario-final-shot.mjs +1 -1
  761. package/scripts/_dbg-scenario-phase-e2.mjs +1 -1
  762. package/scripts/_dbg-scenario-phase-e3.mjs +1 -1
  763. package/scripts/_dbg-scenario-phase1.mjs +1 -1
  764. package/scripts/_dbg-scenario-phase2.mjs +1 -1
  765. package/scripts/_dbg-scenario-phase3-monitor.mjs +1 -1
  766. package/scripts/_dbg-scenario-phase3.mjs +1 -1
  767. package/scripts/_dbg-settings-draft-probe.mjs +39 -0
  768. package/scripts/_dbg-settings-probe.mjs +33 -0
  769. package/scripts/_dbg-task-cancel-probe.mjs +66 -0
  770. package/scripts/_dbg-town-alarm-e2e.mjs +1 -1
  771. package/scripts/_dbg-town-daq-shot.mjs +1 -1
  772. package/scripts/_dbg-town-full-e2e.mjs +1 -1
  773. package/scripts/_dbg-town-gate.mjs +1 -1
  774. package/scripts/_dbg-town-ins-probe.mjs +1 -1
  775. package/scripts/_dbg-town-perf.mjs +1 -1
  776. package/scripts/_dbg-town-realtime.mjs +1 -1
  777. package/scripts/_dbg-town-shot.py +25 -0
  778. package/scripts/_dbg-town-shot3.mjs +1 -1
  779. package/scripts/_dbg-town-smoke.mjs +54 -0
  780. package/scripts/_dbg-town-truth.mjs +1 -1
  781. package/scripts/_dbg-town-truth2.mjs +1 -1
  782. package/scripts/_dbg-trend-expand-test.mjs +1 -1
  783. package/scripts/_dbg-twindaq-focus.mjs +1 -1
  784. package/scripts/_dbg-ui-polish-shot.mjs +1 -1
  785. package/scripts/_dbg-ui-polish-verify1.mjs +1 -1
  786. package/scripts/_dbg-ui-polish-verify2.mjs +1 -1
  787. package/scripts/_dbg-ui-polish-verify3.mjs +1 -1
  788. package/scripts/_dbg-ui-polish-verify4.mjs +1 -1
  789. package/scripts/_dbg-unify-shot.mjs +1 -1
  790. package/scripts/_dbg-uplink-probe.mjs +1 -1
  791. package/scripts/_dbg-wizard-preview-shot.mjs +1 -1
  792. package/scripts/_dbg-wizard-ui-e2e.mjs +1 -1
  793. package/scripts/_dbg-ws-probe.mjs +1 -1
  794. package/scripts/_dbg-wsdot-sanity.mjs +1 -1
  795. package/scripts/_node-state-probe.mjs +1 -1
  796. package/scripts/_tmp-args-probe.mjs +20 -0
  797. package/scripts/_tmp-cyc-entry.mjs +8 -0
  798. package/scripts/_tmp-cyc-main.mjs +5 -0
  799. package/scripts/_tmp-cyc-mod.mjs +2 -0
  800. package/scripts/_tmp-cycle-a.mjs +6 -0
  801. package/scripts/_tmp-cycle-b.mjs +2 -0
  802. package/scripts/_tmp-cycle-probe.mjs +4 -0
  803. package/scripts/_tmp-entry-variant.mjs +2 -0
  804. package/scripts/_tmp-help-probe.mjs +19 -0
  805. package/scripts/_tmp-help-probe2.mjs +2 -0
  806. package/scripts/_tmp-trace-preload.mjs +1 -0
  807. package/scripts/aml-agent-bridge.ts +230 -0
  808. package/scripts/aml-industrial-loop.ts +232 -0
  809. package/scripts/aml-ui-smoke.mjs +67 -0
  810. package/scripts/aw-start-smoke.mjs +194 -0
  811. package/scripts/design-verify-templates.mjs +1 -1
  812. package/scripts/device-line-restore.mjs +1 -1
  813. package/scripts/e2e-aml.ts +259 -0
  814. package/scripts/e2e-config-groups.mjs +238 -0
  815. package/scripts/e2e-full-closedloop.mjs +911 -0
  816. package/scripts/e2e-full-scenario.ts +321 -0
  817. package/scripts/e2e-harness-consistency.ts +204 -0
  818. package/scripts/e2e-multi-harness.ts +233 -76
  819. package/scripts/e2e-plc-plugin-closedloop.mjs +518 -0
  820. package/scripts/e2e-real-scenario.mjs +466 -452
  821. package/scripts/e2e-template-isolation.mjs +2 -2
  822. package/scripts/experiment-castfilm-closedloop.mjs +423 -0
  823. package/scripts/experiment-castfilm-finish.mjs +194 -0
  824. package/scripts/experiment-castfilm-ui-shot.mjs +52 -0
  825. package/scripts/experiment-castfilm-viz.mjs +172 -0
  826. package/scripts/production-closed-loop-e2e.mjs +74 -28
  827. package/scripts/test-aml-integration.ts +159 -0
  828. package/scripts/test-aml-job.ts +174 -0
  829. package/scripts/test-aml-unit.ts +184 -0
  830. package/scripts/test-cli-exit.mjs +235 -0
  831. package/scripts/test-daq-frame-race.mjs +310 -0
  832. package/scripts/test-data-root.mjs +208 -0
  833. package/scripts/test-log-flooding.mjs +160 -0
  834. package/scripts/test-lru.mjs +78 -0
  835. package/scripts/test-memory-month-query.mjs +62 -0
  836. package/scripts/test-plugin-hardening.mjs +45 -0
  837. package/scripts/test-rollback-index.mjs +79 -0
  838. package/scripts/test-sdk-surface.mjs +155 -0
  839. package/scripts/three-system-e2e.mjs +662 -448
  840. package/scripts/town-scene-clear.mjs +1 -1
  841. package/sdk/client.d.mts +110 -0
  842. package/sdk/client.mjs +144 -124
  843. package/sdk/context.mjs +161 -1
  844. package/sdk/index.d.mts +37 -5
  845. package/sdk/index.mjs +44 -41
  846. package/sdk/lifecycle.mjs +4 -1
  847. package/server/api/plugins/i18n.get.ts +12 -0
  848. package/server/api/system/config-groups/[id].delete.ts +21 -0
  849. package/server/api/system/config-groups/[id].patch.ts +26 -0
  850. package/server/api/system/config-groups/index.get.ts +21 -0
  851. package/server/api/system/config-groups/index.post.ts +33 -0
  852. package/server/api/system/settings/events.get.ts +8 -4
  853. package/server/api/workshop/agent-tools/bindings/[id].delete.ts +6 -1
  854. package/server/api/workshop/agent-tools/bindings/[id].patch.ts +12 -3
  855. package/server/api/workshop/agent-tools/bindings/index.get.ts +29 -2
  856. package/server/api/workshop/agent-tools/invoke.post.ts +30 -5
  857. package/server/api/workshop/aml/datasets/[id]/preview.get.ts +68 -0
  858. package/server/api/workshop/aml/datasets/[id].get.ts +24 -0
  859. package/server/api/workshop/aml/datasets/index.get.ts +20 -0
  860. package/server/api/workshop/aml/datasets/index.post.ts +27 -0
  861. package/server/api/workshop/aml/experiments/index.get.ts +35 -0
  862. package/server/api/workshop/aml/index.get.ts +24 -0
  863. package/server/api/workshop/aml/jobs/[id]/cancel.post.ts +21 -0
  864. package/server/api/workshop/aml/jobs/[id]/logs.get.ts +23 -0
  865. package/server/api/workshop/aml/jobs/[id]/retry.post.ts +20 -0
  866. package/server/api/workshop/aml/jobs/[id].get.ts +23 -0
  867. package/server/api/workshop/aml/jobs/index.get.ts +26 -0
  868. package/server/api/workshop/aml/jobs/index.post.ts +44 -0
  869. package/server/api/workshop/aml/models/[id]/predict.post.ts +24 -0
  870. package/server/api/workshop/aml/models/[id]/promote.post.ts +30 -0
  871. package/server/api/workshop/aml/models/index.get.ts +48 -0
  872. package/server/api/workshop/daq/[id].delete.ts +6 -0
  873. package/server/api/workshop/dcw/[id].patch.ts +14 -2
  874. package/server/api/workshop/hitl/respond.post.ts +3 -1
  875. package/server/api/workshop/teams/[id]/plugins/index.get.ts +36 -0
  876. package/server/api/workshop/teams/[id]/plugins/index.put.ts +42 -0
  877. package/server/api/workshop/teams/index.post.ts +13 -0
  878. package/server/api/workshop/users/me.get.ts +5 -0
  879. package/server/api/workshop/ws.ts +14 -2
  880. package/server/data/daqs.json +1648 -123
  881. package/server/data/dcw-lines.json +301 -0
  882. package/server/data/dcw-products.json +140 -0
  883. package/server/data/dcw-recipes.json +890 -0
  884. package/server/data/dcw-rollback.json +11591 -5740
  885. package/server/data/dcw-runs.json +3745 -3559
  886. package/server/data/dcw-templates.json +120 -0
  887. package/server/data/dcw-writes.json +1800 -0
  888. package/server/data/dcws.json +1576 -287
  889. package/server/data/line-runs.json +137 -27
  890. package/server/harness/pi-aw-tools.mjs +51 -0
  891. package/server/plugins/dev-stability-guard.ts +63 -63
  892. package/server/plugins/system-config.ts +10 -11
  893. package/server/plugins/workshop.ts +10 -0
  894. package/server/plugins-builtin/diag-bridge/client.mjs +84 -0
  895. package/server/plugins-builtin/diag-bridge/i18n.json +72 -0
  896. package/server/plugins-builtin/diag-bridge/index.mjs +127 -22
  897. package/server/plugins-builtin/rag-bridge/client.mjs +108 -0
  898. package/server/plugins-builtin/rag-bridge/i18n.json +60 -0
  899. package/server/plugins-builtin/rag-bridge/index.mjs +67 -20
  900. package/server/services/system-config.ts +610 -396
  901. package/server/services/workshop/agents/adapters/line-spawn.ts +15 -6
  902. package/server/services/workshop/agents/adapters/one-shot-cli-agent.ts +530 -0
  903. package/server/services/workshop/agents/base-agent.ts +210 -0
  904. package/server/services/workshop/agents/binding-authz.ts +57 -0
  905. package/server/services/workshop/agents/claude-agent.ts +546 -30
  906. package/server/services/workshop/agents/codex-agent.ts +729 -822
  907. package/server/services/workshop/agents/copilot-agent.ts +136 -0
  908. package/server/services/workshop/agents/crush-agent.ts +107 -0
  909. package/server/services/workshop/agents/cursor-agent.ts +102 -0
  910. package/server/services/workshop/agents/dsh-agent.ts +578 -670
  911. package/server/services/workshop/agents/gemini-agent.ts +121 -0
  912. package/server/services/workshop/agents/goose-agent.ts +98 -0
  913. package/server/services/workshop/agents/harness-models.ts +305 -270
  914. package/server/services/workshop/agents/hermes-agent.ts +528 -0
  915. package/server/services/workshop/agents/host-tool-bridge.ts +53 -2
  916. package/server/services/workshop/agents/industrial-tools.ts +659 -7
  917. package/server/services/workshop/agents/omp-agent.ts +74 -59
  918. package/server/services/workshop/agents/opencode-agent.ts +936 -987
  919. package/server/services/workshop/agents/pi-agent.ts +108 -0
  920. package/server/services/workshop/agents/qwen-agent.ts +540 -0
  921. package/server/services/workshop/agents/registry.ts +117 -5
  922. package/server/services/workshop/agents/tool-approvals.ts +3 -3
  923. package/server/services/workshop/aml/aml.repo.ts +368 -0
  924. package/server/services/workshop/aml/clean.ts +120 -0
  925. package/server/services/workshop/aml/dataset-builder.ts +491 -0
  926. package/server/services/workshop/aml/gates.ts +121 -0
  927. package/server/services/workshop/aml/job-orchestrator.ts +650 -0
  928. package/server/services/workshop/aml/model-registry.ts +169 -0
  929. package/server/services/workshop/aml/predictor.ts +262 -0
  930. package/server/services/workshop/aml/python/aml_eval.py +171 -0
  931. package/server/services/workshop/aml/python/amlkit.py +120 -0
  932. package/server/services/workshop/aml/python/requirements.txt +7 -0
  933. package/server/services/workshop/aml/python/train-example.py +92 -0
  934. package/server/services/workshop/aml/python-runtime.ts +217 -0
  935. package/server/services/workshop/aml/retention.ts +98 -0
  936. package/server/services/workshop/aml/runtime.ts +45 -0
  937. package/server/services/workshop/aml/spec.ts +63 -0
  938. package/server/services/workshop/aml/stats.ts +140 -0
  939. package/server/services/workshop/daq/bus/mqtt.adapter.ts +8 -1
  940. package/server/services/workshop/daq/daq-controller.ts +147 -19
  941. package/server/services/workshop/daq/daq-node.repo.ts +13 -11
  942. package/server/services/workshop/daq/daq-runtime.ts +11 -0
  943. package/server/services/workshop/daq/drivers.ts +89 -8
  944. package/server/services/workshop/db/aml-team-seeds.ts +118 -0
  945. package/server/services/workshop/db/channel-plugins.repo.ts +27 -1
  946. package/server/services/workshop/db/database.ts +89 -1
  947. package/server/services/workshop/db/memory.repo.ts +31 -0
  948. package/server/services/workshop/db/user.repo.ts +9 -0
  949. package/server/services/workshop/dcw/dcw-controller.ts +33 -7
  950. package/server/services/workshop/dcw/dcw-line.repo.ts +5 -3
  951. package/server/services/workshop/dcw/dcw-node.repo.ts +4 -4
  952. package/server/services/workshop/dcw/dcw-product.repo.ts +8 -8
  953. package/server/services/workshop/dcw/dcw-recipe.repo.ts +6 -7
  954. package/server/services/workshop/dcw/dcw-runtime.ts +16 -2
  955. package/server/services/workshop/dcw/dcw-templates.ts +4 -4
  956. package/server/services/workshop/dcw/line-run.ts +5 -5
  957. package/server/services/workshop/dcw/recipe-rollback-manager.ts +3 -1
  958. package/server/services/workshop/dcw/recipe-rollback.repo.ts +155 -52
  959. package/server/services/workshop/logger.ts +145 -3
  960. package/server/services/workshop/plugins/host.mjs +857 -566
  961. package/server/services/workshop/prompts/loader.ts +32 -6
  962. package/server/services/workshop/runtime/manager.ts +53 -13
  963. package/server/services/workshop/runtime/scheduler-loop.ts +18 -1
  964. package/server/services/workshop/scene/scene-layout.repo.ts +5 -5
  965. package/server/services/workshop/settings.ts +64 -0
  966. package/shared/config/engine.mjs +5 -0
  967. package/shared/config/groups.mjs +220 -0
  968. package/shared/config/home.mjs +11 -2
  969. package/shared/config/schema.json +31 -6
  970. package/shared/daq-protocol.ts +6 -0
  971. package/shared/lru.mjs +94 -0
  972. package/shared/workshop-protocol.ts +2 -2
  973. package/.output/public/_nuxt/2jaJHWIJ.js +0 -1
  974. package/.output/public/_nuxt/B8kt898d.js +0 -1
  975. package/.output/public/_nuxt/BFGpEo8S.js +0 -1
  976. package/.output/public/_nuxt/BG4zduPf.js +0 -14
  977. package/.output/public/_nuxt/BHcpzI2n.js +0 -19
  978. package/.output/public/_nuxt/BWyR3awA.js +0 -1
  979. package/.output/public/_nuxt/Bc89zKq2.js +0 -1
  980. package/.output/public/_nuxt/BetmGSO4.js +0 -1
  981. package/.output/public/_nuxt/BowTbasd.js +0 -1
  982. package/.output/public/_nuxt/BvtknqSC2.js +0 -1
  983. package/.output/public/_nuxt/BytVi9VX2.js +0 -4
  984. package/.output/public/_nuxt/CJviSvm-.js +0 -1
  985. package/.output/public/_nuxt/CTfqWGdy.js +0 -1
  986. package/.output/public/_nuxt/Cb3SnTM8.js +0 -1
  987. package/.output/public/_nuxt/Chc5pfAA.js +0 -1
  988. package/.output/public/_nuxt/CobSUzQv.js +0 -2
  989. package/.output/public/_nuxt/D95h62Jn.js +0 -1
  990. package/.output/public/_nuxt/DGAOugLt.js +0 -1
  991. package/.output/public/_nuxt/DHbTyoAV.js +0 -1
  992. package/.output/public/_nuxt/DfLUN8kY.js +0 -1
  993. package/.output/public/_nuxt/DnziMlcX.js +0 -1
  994. package/.output/public/_nuxt/DvgKXPgu2.js +0 -13
  995. package/.output/public/_nuxt/Q_SJDSgx.js +0 -1
  996. package/.output/public/_nuxt/_id_.DdbYeLqn.css +0 -1
  997. package/.output/public/_nuxt/_wsId_.BqWBlY7X.css +0 -1
  998. package/.output/public/_nuxt/agents.CB9Ck7VQ.css +0 -1
  999. package/.output/public/_nuxt/bFnZa2yd.js +0 -1
  1000. package/.output/public/_nuxt/builds/meta/f7a8e33d-5422-45ac-895d-27168f97e3ad.json +0 -1
  1001. package/.output/public/_nuxt/daq.DGV9QS8d.css +0 -1
  1002. package/.output/public/_nuxt/default.BbgdTDCk.css +0 -1
  1003. package/.output/public/_nuxt/entry.BN02X8iR.css +0 -1
  1004. package/.output/public/_nuxt/pages.CG8UJ2TK.css +0 -1
  1005. package/.output/public/_nuxt/plugins.DpCuwaJt.css +0 -1
  1006. package/.output/public/_nuxt/rkVgzg62.js +0 -1
  1007. package/.output/public/_nuxt/settings.W6qrYAui.css +0 -1
  1008. package/.output/public/_nuxt/teams.BBXVkyKq.css +0 -1
  1009. package/.output/server/chunks/build/_id_-3Axz2-gV.mjs.map +0 -1
  1010. package/.output/server/chunks/build/_id_-CahfkmEt.mjs.map +0 -1
  1011. package/.output/server/chunks/build/agents-DuMiSWKp.mjs.map +0 -1
  1012. package/.output/server/chunks/build/alert-qJnjyRcP.mjs.map +0 -1
  1013. package/.output/server/chunks/build/channel-templates-BStqJ-of.mjs.map +0 -1
  1014. package/.output/server/chunks/build/daq-ChYCABz1.mjs.map +0 -1
  1015. package/.output/server/chunks/build/dcw-CcQNGggh.mjs.map +0 -1
  1016. package/.output/server/chunks/build/logs-D-2UyGtE.mjs.map +0 -1
  1017. package/.output/server/chunks/build/pages-Dfosfchr.mjs.map +0 -1
  1018. package/.output/server/chunks/build/permissions-B-hhZuzm.mjs.map +0 -1
  1019. package/.output/server/chunks/build/plugins-DZR0T4Mh.mjs.map +0 -1
  1020. package/.output/server/chunks/build/responsiveObserve-CS0UB6wQ.mjs +0 -78
  1021. package/.output/server/chunks/build/responsiveObserve-CS0UB6wQ.mjs.map +0 -1
  1022. package/.output/server/chunks/build/settings-BajN9TQW.mjs.map +0 -1
  1023. package/.output/server/chunks/build/tag-NO9jEqKy.mjs.map +0 -1
  1024. package/.output/server/chunks/build/teams-t2SkRlJP.mjs.map +0 -1
  1025. package/.output/server/chunks/build/tokens-DiCojbN8.mjs.map +0 -1
  1026. package/.output/server/chunks/build/town-C7QM8DYK.mjs.map +0 -1
  1027. package/.output/server/chunks/build/useDaqStream-BeA2X8KR.mjs.map +0 -1
  1028. package/.output/server/chunks/build/useDcwStream-BJW_MitY.mjs.map +0 -1
  1029. package/.output/server/chunks/build/users-B9SAdEtH.mjs.map +0 -1
  1030. /package/.output/public/_nuxt/{ORt9oDIy.js → ORt9oDIy2.js} +0 -0
@@ -1,566 +1,857 @@
1
- // ============================================================
2
- // AgentWorkShop 插件宿主 —— 发现 / 装载 / 启停状态 / 热重载 / 路由表
3
- // ------------------------------------------------------------
4
- // 目录(与 aw commands 同哲学):
5
- // project: <repo>/.AgentWorkShop/plugins/<name>/index.mjs
6
- // user: ~/.AgentWorkShop/plugins/<name>/index.mjs(同名 project 优先)
7
- // 契约:入口导出普通对象 { name, version?, description?, setup(ctx)?,
8
- // client?: './client.mjs', routes?: [{method,path,handler}] }
9
- // —— ctx 由宿主注入,插件运行时零导入依赖(sdk/ 供类型与显式糖)。
10
- //
11
- // 启停状态机:配置根 plugins-state.json { version, updatedAt, disabled: string[] }
12
- // · 装载时跳过 disabled 插件(manifest 仍可见,enabled:false)
13
- // · 状态文件变化(fs.watch)→ 热重载:全部 dispose/解绑 → 重新装载
14
- // · CLI(aw plugin enable/disable) 与 Web 设置页均只写状态文件,服务自感知
15
- // 错误隔离:单插件装载/执行失败记入 failures,绝不拖垮主服务。
16
- // ============================================================
17
- import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, watch, writeFileSync } from 'node:fs'
18
- import { dirname, join, resolve } from 'node:path'
19
- import { pathToFileURL } from 'node:url'
20
- import { HookBus, createPluginContext, createRouteTable, validatePluginModule } from '@/sdk/index.mjs'
21
-
22
- // 延迟解析的产线权限服务(esbuild/别名下避免 nitro 打包循环导入;失败降级为拒绝一切)
23
- let permissions = null
24
- let userRepository = null
25
- async function loadPermissions() {
26
- if (permissions) return
27
- try {
28
- permissions = await import('@/server/services/workshop/permissions')
29
- userRepository = await import('@/server/repositories/user.repository').then(m => m.userRepository)
30
- }
31
- catch (err) {
32
- hostLoggerFallback()?.warn('权限服务加载失败(插件 ctx.permissions 降级):', err?.message)
33
- }
34
- }
35
- function hostLoggerFallback() {
36
- return globalThis.__awPluginHost?.logger ?? console
37
- }
38
-
39
- const g = globalThis
40
-
41
- function log() {
42
- return {
43
- debug: (...a) => console.log('[aw-plugins][debug]', ...a),
44
- info: (...a) => console.log('[aw-plugins]', ...a),
45
- warn: (...a) => console.warn('[aw-plugins]', ...a),
46
- error: (...a) => console.error('[aw-plugins]', ...a),
47
- }
48
- }
49
-
50
- function defaultHome() {
51
- const home = process.env.HOME ?? process.env.USERPROFILE ?? ''
52
- return join(home, '.AgentWorkShop')
53
- }
54
-
55
- /** 运行模式路径(cwd 为检出根时启用 project 作用域) */
56
- function modePaths(cwd) {
57
- const isRepo = existsSync(join(cwd, 'config.yml')) && existsSync(join(cwd, 'nuxt.config.ts'))
58
- // packageRoot:宿主运行时取 initPluginHost 注入值;冒烟/单测(cwd 在包根)回退 cwd
59
- const packageRoot = g.__awPluginHost?.packageRoot ?? (isRepo ? cwd : null)
60
- const builtinDir = packageRoot ? join(packageRoot, 'server', 'plugins-builtin') : null
61
- return {
62
- builtinDir: builtinDir && existsSync(builtinDir) ? builtinDir : null,
63
- projectDir: isRepo ? join(cwd, '.AgentWorkShop', 'plugins') : null,
64
- userDir: join(process.env.AW_HOME && String(process.env.AW_HOME).trim() ? String(process.env.AW_HOME).trim() : defaultHome(), 'plugins'),
65
- homeDir: process.env.AW_HOME && String(process.env.AW_HOME).trim() ? String(process.env.AW_HOME).trim() : defaultHome(),
66
- }
67
- }
68
-
69
- function pathToUrl(p) {
70
- return pathToFileURL(resolve(p)).href
71
- }
72
-
73
- // ---- 启停状态(单一事实源:<配置根>/plugins-state.json;CLI/Web/宿主三方读写) ----
74
- export function statePathFor(homeDir) {
75
- return join(homeDir, 'plugins-state.json')
76
- }
77
-
78
- export function readDisabledSet(homeDir) {
79
- try {
80
- const j = JSON.parse(readFileSync(statePathFor(homeDir), 'utf8'))
81
- return new Set(Array.isArray(j.disabled) ? j.disabled : [])
82
- }
83
- catch {
84
- return new Set()
85
- }
86
- }
87
-
88
- export function writeDisabledSet(homeDir, disabled) {
89
- const p = statePathFor(homeDir)
90
- mkdirSync(dirname(p), { recursive: true })
91
- const tmp = `${p}.${process.pid}.tmp`
92
- writeFileSync(tmp, `${JSON.stringify({ version: 1, updatedAt: new Date().toISOString(), disabled: [...disabled] }, null, 2)}\n`, 'utf8')
93
- renameSync(tmp, p)
94
- }
95
-
96
- /** 发现插件入口,三作用域(builtin 同名被 project 覆盖,project 同名被 user 覆盖) */
97
- export function discoverPluginDirs(cwd = process.cwd()) {
98
- const { builtinDir, projectDir, userDir } = modePaths(cwd)
99
- const out = []
100
- const seen = new Set()
101
- for (const [dir, scope] of [[builtinDir, 'builtin'], [projectDir, 'project'], [userDir, 'user']]) {
102
- if (!dir || !existsSync(dir)) continue
103
- for (const name of readdirSync(dir)) {
104
- const sub = join(dir, name)
105
- if (!existsSync(join(sub, 'index.mjs'))) continue
106
- if (seen.has(name)) continue
107
- seen.add(name)
108
- out.push({ dir: sub, scope })
109
- }
110
- }
111
- return out.sort((a, b) => a.dir.localeCompare(b.dir))
112
- }
113
-
114
- /**
115
- * 装载插件宿主(idempotent;nitro 启动期调用一次)。
116
- */
117
- export async function initPluginHost({ cwd = process.cwd(), packageRoot } = {}) {
118
- if (g.__awPluginHost) return g.__awPluginHost
119
- const logger = log()
120
- const homeDir = modePaths(cwd).homeDir
121
- const host = {
122
- bus: new HookBus({
123
- name: 'aw-plugins',
124
- onError: (err, meta) => logger.warn(`钩子错误(${meta?.type}):`, err?.message ?? err),
125
- }),
126
- routes: createRouteTable(),
127
- plugins: new Map(),
128
- disposables: new Map(), // name → fn[](ctx.onDispose 登记)
129
- hookOffs: new Map(), // name → off[](ctx.hooks.on 登记;热重载时解绑)
130
- failures: [],
131
- initedAt: null,
132
- cwd,
133
- packageRoot,
134
- logger,
135
- }
136
- g.__awPluginHost = host
137
-
138
- // 有效配置(只读面;引擎/模式解析从运行根动态加载)
139
- let config = null
140
- let settingsPath = null
141
- let paths = { home: homeDir, configRoot: join(cwd, '.AgentWorkShop'), dataDir: join(cwd, '.AgentWorkShop', 'data') }
142
- try {
143
- const homeMod = await import(pathToUrl(join(cwd, 'shared', 'config', 'home.mjs')))
144
- const rm = homeMod.resolveRunMode({ cwd, packageRoot, env: process.env })
145
- const engineRoot = rm.mode === 'repo' ? rm.root : (packageRoot ?? rm.root)
146
- if (engineRoot && existsSync(join(engineRoot, 'shared', 'config', 'engine.mjs'))) {
147
- const engine = await import(pathToUrl(join(engineRoot, 'shared', 'config', 'engine.mjs')))
148
- config = engine.loadEffective({ configPath: rm.configPath, settingsPath: rm.settingsPath, env: process.env })
149
- settingsPath = rm.settingsPath
150
- }
151
- paths = { home: rm.home, configRoot: rm.configRoot, dataDir: rm.dataDir }
152
- host.logger.info(`配置根: ${rm.configRoot} (${rm.mode} 模式)`)
153
- }
154
- catch (err) {
155
- host.logger.warn('配置引擎加载降级(插件 ctx.config 将为空):', err?.message)
156
- }
157
- // 配置热更新:system-config 变化(设置页 PATCH / runtime-settings 文件监听)即刷新
158
- // effective —— 插件 ctx.config.get 每次调用实时读到新值(插件 API 地址等改配置即生效,无需重启)
159
- try {
160
- const { getSystemConfigService } = await import('@/server/services/system-config')
161
- getSystemConfigService().subscribe((tail) => {
162
- try {
163
- if (config?.effective && tail?.effective) Object.assign(config.effective, tail.effective)
164
- }
165
- catch { /* 刷新失败保留旧值 */ }
166
- })
167
- }
168
- catch (err) {
169
- host.logger.warn('配置热更新订阅失败(插件 ctx.config 为装载时快照):', err?.message)
170
- }
171
- host.config = config
172
-
173
- // 自环 origin:PORT env(prod:start.mjs 注入 / dev:dev-guard 注入 CLI 显式值)权威;
174
- // nitro listen 钩子兜底回填
175
- const argPort = (() => {
176
- const argv = process.argv
177
- const i = argv.indexOf('--port')
178
- if (i >= 0 && argv[i + 1]) return argv[i + 1]
179
- const eq = argv.find(a => a.startsWith('--port='))
180
- return eq ? eq.slice(7) : null
181
- })()
182
- let selfOrigin = `http://127.0.0.1:${process.env.PORT ?? process.env.NITRO_PORT ?? argPort ?? config?.effective?.['server.dev.port'] ?? 3000}`
183
- host.setSelfOrigin = (port) => {
184
- selfOrigin = `http://127.0.0.1:${port}`
185
- host.logger.info(`自环 origin 就绪: ${selfOrigin}`)
186
- }
187
- host.selfOrigin = () => selfOrigin
188
- host.logger.info(`自环 origin: ${selfOrigin}`)
189
-
190
- await loadAllPlugins(host, { config, settingsPath, paths })
191
- ensureStateWatcher(host)
192
- return host
193
- }
194
-
195
- /** 装载/重载全部插件(跳过 disabled;manifest 仍可见) */
196
- async function loadAllPlugins(host, { config, paths }) {
197
- const homeDir = modePaths(host.cwd).homeDir
198
- const disabled = readDisabledSet(homeDir)
199
- host.disabledSet = disabled
200
-
201
- // 产线权限服务(ctx.permissions 注入用;失败降级)
202
- await loadPermissions()
203
-
204
- const entries = discoverPluginDirs(host.cwd)
205
- if (entries.length) host.logger.info(`发现 ${entries.length} 个插件(停用 ${disabled.size}),开始装载 ...`)
206
-
207
- for (const { dir, scope } of entries) {
208
- const entry = join(dir, 'index.mjs')
209
- try {
210
- // cache-busting:热重载时 ESM 按 URL 缓存,不带 query 永远拿到旧模块(插件改代码不生效)
211
- const mod = await import(`${pathToUrl(entry)}?t=${Date.now()}`)
212
- const check = validatePluginModule(mod, entry)
213
- if (!check.ok) throw new Error(check.error)
214
- const def = check.def
215
-
216
- if (host.plugins.has(def.name)) throw new Error(`插件重名(后装载者跳过): ${def.name}`)
217
- if (disabled.has(def.name)) {
218
- host.plugins.set(def.name, {
219
- name: def.name,
220
- version: String(def.version ?? '0.0.0'),
221
- description: String(def.description ?? ''),
222
- auth: String(def.auth ?? 'none'),
223
- scope,
224
- dir,
225
- entry,
226
- clientPath: def.client ? resolve(dir, def.client) : null,
227
- routes: [],
228
- enabled: false,
229
- error: null,
230
- })
231
- host.logger.info(`⊘ 跳过(已停用) [${scope}] ${def.name}`)
232
- continue
233
- }
234
-
235
- const rec = {
236
- name: def.name,
237
- version: String(def.version ?? '0.0.0'),
238
- description: String(def.description ?? ''),
239
- auth: String(def.auth ?? 'none'),
240
- scope,
241
- dir,
242
- entry,
243
- clientPath: def.client ? resolve(dir, def.client) : null,
244
- routes: [],
245
- enabled: true,
246
- error: null,
247
- }
248
-
249
- const emitter = {
250
- registerRoute: (n, m, p, h) => {
251
- host.routes.register(n, m, p, h)
252
- rec.routes.push({ method: String(m).toUpperCase(), path: p })
253
- },
254
- }
255
- const perPluginDisposables = []
256
- const hookOffs = []
257
- host.disposables.set(def.name, perPluginDisposables)
258
- host.hookOffs.set(def.name, hookOffs)
259
- const scopedHooks = {
260
- on: (t, fn) => {
261
- const off = host.bus.on(t, fn)
262
- hookOffs.push(off)
263
- return off
264
- },
265
- once: (t, fn) => {
266
- const off = host.bus.once(t, fn)
267
- hookOffs.push(off)
268
- return off
269
- },
270
- off: (t, fn) => host.bus.off(t, fn),
271
- emit: (t, p) => host.bus.emit(t, p),
272
- }
273
- const ctx = createPluginContext({
274
- name: def.name,
275
- scope,
276
- dir,
277
- hooks: scopedHooks,
278
- logger: {
279
- debug: (...a) => host.logger.info(`[${def.name}][debug]`, ...a),
280
- info: (...a) => host.logger.info(`[${def.name}]`, ...a),
281
- warn: (...a) => host.logger.warn(`[${def.name}]`, ...a),
282
- error: (...a) => host.logger.error(`[${def.name}]`, ...a),
283
- },
284
- config,
285
- paths,
286
- emitter,
287
- onDispose: (fn) => {
288
- perPluginDisposables.push(fn)
289
- return fn
290
- },
291
- selfOrigin: () => selfOriginRef(host),
292
- // 产线权限拓展面(SDK ctx.permissions):插件可查询/管理用户×产线授权
293
- permissions: {
294
- lineMode: (user, lineId) => permissions.lineMode(user, lineId),
295
- visibleLineIds: user => permissions.visibleLineIds(user),
296
- listGrants: userId => userRepository.listGrants(userId),
297
- setGrants: (userId, entries, grantedBy = 'plugin') => {
298
- for (const g of (entries ?? [])) {
299
- if (!g?.lineId) continue
300
- userRepository.setGrant(userId, String(g.lineId), (g.mode ?? null), grantedBy)
301
- }
302
- permissions.notifyGrantsChanged(userId)
303
- return userRepository.listGrants(userId)
304
- },
305
- },
306
- })
307
- // DAQ 扩展面(v2 帧管线):插件注册自定义驱动与下沉处理器。
308
- // 桥经 globalThis 排队 —— daq 模块晚于插件宿主装载时,注册项先排队、
309
- // daq 侧 plugin-bridge 接管后回放;重复装载由同名覆盖语义兜底。
310
- const daqExt = (globalThis.__daqPluginExt ??= {
311
- pendingDrivers: [],
312
- pendingProcessors: [],
313
- pendingTemplates: [],
314
- registerDriver(d) {
315
- this.pendingDrivers.push(d)
316
- this._drain?.()
317
- },
318
- registerProcessor(kind, name, fn) {
319
- this.pendingProcessors.push({ kind, name, fn })
320
- this._drain?.()
321
- },
322
- registerTemplate(def) {
323
- this.pendingTemplates.push(def)
324
- this._drain?.()
325
- },
326
- drain(onDriver, onProcessor, onTemplate) {
327
- this._drain = () => {
328
- for (const d of this.pendingDrivers.splice(0)) onDriver(d)
329
- for (const p of this.pendingProcessors.splice(0)) onProcessor(p.kind, p.name, p.fn)
330
- for (const t of this.pendingTemplates.splice(0)) onTemplate(t)
331
- }
332
- this._drain()
333
- },
334
- })
335
- ctx.daq = {
336
- registerDriver: d => daqExt.registerDriver(d),
337
- registerProcessor: (kind, name, fn) => daqExt.registerProcessor(kind, name, fn),
338
- /** 注册数采节点模板(signalKind/sink.processors/metrics 全量可用;同名覆盖) */
339
- registerTemplate: def => daqExt.registerTemplate(def),
340
- /** 帧消费便捷别名(= hooks.on('daq:frame') / hooks.on('daq:sample')) */
341
- onFrame: fn => scopedHooks.on('daq:frame', fn),
342
- onSample: fn => scopedHooks.on('daq:sample', fn),
343
- /** 时序查询直通(queryTagged):插件免鉴权拉取产线/节点窗口样本(bucket/raw),诊断取数用 */
344
- query: async (q) => {
345
- const m = await import('@/server/services/workshop/daq/storage/index')
346
- return m.getTsdb().queryTagged(q)
347
- },
348
- /** 数采节点元数据快照(含产线归属,插件定位某产线的全部节点) */
349
- nodes: async () => {
350
- const m = await import('@/server/services/workshop/daq/daq-node.repo')
351
- return m.getDaqNodeRepo().snapshot()
352
- },
353
- }
354
- // OMP 工具扩展面:插件注册自定义 host 工具 → omp 会话运行时热注入
355
- const ompExt = (globalThis.__ompPluginToolsBridge ??= {
356
- pending: [],
357
- register(plugin, tool) {
358
- this.pending.push({ plugin, tool })
359
- this._drain?.()
360
- },
361
- drain(onTool) {
362
- this._drain = () => {
363
- for (const def of this.pending.splice(0)) onTool(def)
364
- }
365
- this._drain()
366
- },
367
- })
368
- ctx.omp = {
369
- registerTool: (tool) => {
370
- ompExt.register(def.name, tool)
371
- ctx.logger.info(`已注册 omp 工具:「${tool?.name}」`)
372
- },
373
- }
374
-
375
- for (const r of (Array.isArray(def.routes) ? def.routes : [])) {
376
- emitter.registerRoute(def.name, r.method ?? 'GET', r.path, r.handler)
377
- }
378
- await def.setup?.(ctx)
379
-
380
- host.plugins.set(def.name, rec)
381
- host.logger.info(`✔ 已装载 [${scope}] ${def.name}@${rec.version}${rec.clientPath ? ' (+client)' : ''}`)
382
- }
383
- catch (err) {
384
- host.failures.push({ source: entry, error: err?.message ?? String(err) })
385
- host.logger.error(`装载失败 ${entry}:`, err?.message ?? err)
386
- }
387
- }
388
-
389
- host.initedAt = new Date().toISOString()
390
- await host.bus.emit('plugin:host:init', { plugins: [...host.plugins.keys()], failures: host.failures.length })
391
- host.logger.info(`装载完成: ${host.plugins.size} 个(含停用)/ ${host.failures.length} 失败 / 活跃路由 ${host.routes.size} 条`)
392
- }
393
-
394
- function selfOriginRef(host) {
395
- return host.selfOrigin()
396
- }
397
-
398
- /** 热重载:全部 dispose/解绑 → 重新装载(跳过停用)→ 广播 plugins.reloaded(并发合并) */
399
- export async function reloadPluginHost() {
400
- const host = getPluginHost()
401
- if (!host) return null
402
- if (host.reloadInFlight) return host.reloadInFlight
403
- host.reloadInFlight = doReload(host).finally(() => {
404
- host.reloadInFlight = null
405
- })
406
- return host.reloadInFlight
407
- }
408
-
409
- async function doReload(host) {
410
- host.logger.info('热重载插件宿主 ...')
411
- for (const [name, list] of host.disposables ?? []) {
412
- for (const fn of list.splice(0)) {
413
- try {
414
- await fn()
415
- }
416
- catch (err) {
417
- host.logger.warn(`[${name}] onDispose 失败:`, err?.message)
418
- }
419
- }
420
- }
421
- for (const offs of (host.hookOffs ?? new Map()).values()) {
422
- for (const off of offs.splice(0)) {
423
- try {
424
- off()
425
- }
426
- catch { /* 解绑失败忽略 */ }
427
- }
428
- }
429
- const prevNames = [...host.plugins.keys()]
430
- // 卸载即注销其注册的全部 agent 工具(否则停用插件后工具仍残留在注册表、可被继续调用)
431
- const ompTools = await import('@/server/services/workshop/agents/plugin-tools').catch(() => null)
432
- for (const prev of prevNames) {
433
- try {
434
- ompTools?.unregisterPluginTools(prev)
435
- }
436
- catch { /* 注销失败不阻断重载 */ }
437
- }
438
- host.plugins.clear()
439
- host.routes = createRouteTable()
440
- host.failures = []
441
- await loadAllPlugins(host, { config: host.config, settingsPath: null, paths: { home: modePaths(host.cwd).homeDir, configRoot: join(host.cwd, '.AgentWorkShop'), dataDir: join(host.cwd, '.AgentWorkShop', 'data') } })
442
- // 装载中途失败(setup 抛错)的插件可能留下半注册工具,兜底再清一次
443
- for (const prev of prevNames) {
444
- if (!host.plugins.has(prev)) {
445
- try {
446
- ompTools?.unregisterPluginTools(prev)
447
- }
448
- catch { /* 忽略 */ }
449
- }
450
- }
451
- await host.bus.emit('plugins:reloaded', { plugins: pluginManifest() })
452
- try {
453
- const m = await import('@/server/services/workshop/scene-events')
454
- m.broadcastSceneEvent('plugins.reloaded', { plugins: pluginManifest() })
455
- }
456
- catch { /* 广播失败不影响重载 */ }
457
- return host
458
- }
459
-
460
- /** 启停单插件(写状态文件;调用方随后 reloadPluginHost 或由 state watcher 触发) */
461
- export function setPluginEnabled(name, enabled) {
462
- const host = getPluginHost()
463
- const homeDir = modePaths(host?.cwd ?? process.cwd()).homeDir
464
- const set = readDisabledSet(homeDir)
465
- if (enabled) set.delete(name)
466
- else set.add(name)
467
- writeDisabledSet(homeDir, set)
468
- return [...set]
469
- }
470
-
471
- /** 状态文件监视 → 热重载(CLI/Web 只写文件,服务自感知) */
472
- function ensureStateWatcher(host) {
473
- const statePath = statePathFor(modePaths(host.cwd).homeDir)
474
- try {
475
- mkdirSync(dirname(statePath), { recursive: true })
476
- if (!existsSync(statePath)) writeDisabledSet(modePaths(host.cwd).homeDir, new Set())
477
- let debounce = null
478
- // watch 目录而非文件:writeDisabledSet 用 rename 原子替换,POSIX 的文件级
479
- // watch 挂在旧 inode 上,首次启停后静默失效;目录监听对 rename 稳定
480
- watch(dirname(statePath), (_event, filename) => {
481
- if (filename && filename !== 'plugins-state.json') return
482
- clearTimeout(debounce)
483
- debounce = setTimeout(() => {
484
- void reloadPluginHost()
485
- }, 400)
486
- })
487
- }
488
- catch (err) {
489
- host.logger.warn('状态文件监视不可用(启停需手动重启):', err?.message)
490
- }
491
- }
492
-
493
- /** 单例访问(未初始化返回 null —— 桥接点据此快速 no-op) */
494
- export function getPluginHost() {
495
- return g.__awPluginHost ?? null
496
- }
497
-
498
- /** scene-events 桥:全部无频道实时事件 → 插件 event:<type> */
499
- export function emitPluginEvent(type, payload) {
500
- void g.__awPluginHost?.bus.emit(`event:${type}`, payload)
501
- }
502
-
503
- /** DAQ 下发级采样钩子(与 WS daq.reading 同点、同节拍语义) */
504
- export function emitDaqSample(payload) {
505
- void g.__awPluginHost?.bus.emit('daq:sample', payload)
506
- }
507
-
508
- /** 帧观察钩子(v2 多形态信号;载荷只含元数据/指标/预览,不含 blob) */
509
- export function emitDaqFrame(payload) {
510
- void g.__awPluginHost?.bus.emit('daq:frame', payload)
511
- }
512
-
513
- /** 写控 ACK 后观察钩子 */
514
- export function emitDcwWrite(payload) {
515
- void g.__awPluginHost?.bus.emit('dcw:write', payload)
516
- }
517
-
518
- /** 产线启停钩子 */
519
- export function emitLineLifecycle(kind, payload) {
520
- void g.__awPluginHost?.bus.emit(kind, payload)
521
- }
522
-
523
- /** 客户端脚本读取(免鉴权只读端点用;越界路径拒绝) */
524
- export function readClientScript(name) {
525
- const host = getPluginHost()
526
- const rec = host?.plugins.get(name)
527
- if (!host || !rec) return { status: 404 }
528
- if (!rec.clientPath || !existsSync(rec.clientPath)) return { status: 404 }
529
- if (!resolve(rec.clientPath).startsWith(resolve(rec.dir))) return { status: 400 }
530
- return { status: 200, code: readFileSync(rec.clientPath, 'utf8'), contentType: 'text/javascript; charset=utf-8' }
531
- }
532
-
533
- /** 清单(非敏感只读;含启停状态与路由)。builtin = 随项目检出提供的内置示例插件 */
534
- export function pluginManifest() {
535
- const host = getPluginHost()
536
- if (!host) return []
537
- return [...host.plugins.values()].map(r => ({
538
- name: r.name,
539
- version: r.version,
540
- description: r.description,
541
- scope: r.scope,
542
- builtin: r.scope === 'project' || r.scope === 'builtin',
543
- enabled: r.enabled !== false,
544
- hasClient: Boolean(r.clientPath),
545
- routes: host.routes.byPlugin(r.name),
546
- error: r.error,
547
- }))
548
- }
549
-
550
- /** 关机钩子(nitro close 时调用):先逐插件回收订阅/定时器,再广播 server:close */
551
- export async function shutdownPluginHost() {
552
- const host = getPluginHost()
553
- if (!host) return
554
- for (const [name, list] of host.disposables ?? []) {
555
- for (const fn of list.splice(0)) {
556
- try {
557
- await fn()
558
- }
559
- catch (err) {
560
- host.logger.warn(`[${name}] onDispose 失败:`, err?.message)
561
- }
562
- }
563
- }
564
- await host.bus.emit('server:close', { at: new Date().toISOString() })
565
- host.logger.info('插件清理完成,已发出 server:close')
566
- }
1
+ // ============================================================
2
+ // AgentWorkShop 插件宿主 —— 发现 / 装载 / 启停状态 / 热重载 / 路由表
3
+ // ------------------------------------------------------------
4
+ // 目录(与 aw commands 同哲学):
5
+ // project: <repo>/.AgentWorkShop/plugins/<name>/index.mjs
6
+ // user: ~/.AgentWorkShop/plugins/<name>/index.mjs(同名 project 优先)
7
+ // 契约:入口导出普通对象 { name, version?, description?, setup(ctx)?,
8
+ // client?: './client.mjs', routes?: [{method,path,handler}] }
9
+ // —— ctx 由宿主注入,插件运行时零导入依赖(sdk/ 供类型与显式糖)。
10
+ //
11
+ // 启停状态机:配置根 plugins-state.json { version, updatedAt, disabled: string[] }
12
+ // · 装载时跳过 disabled 插件(manifest 仍可见,enabled:false)
13
+ // · 状态文件变化(fs.watch)→ 热重载:全部 dispose/解绑 → 重新装载
14
+ // · CLI(aw plugin enable/disable) 与 Web 设置页均只写状态文件,服务自感知
15
+ // 错误隔离:单插件装载/执行失败记入 failures,绝不拖垮主服务。
16
+ // ============================================================
17
+ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, watch, writeFileSync } from 'node:fs'
18
+ import { dirname, join, resolve } from 'node:path'
19
+ import { pathToFileURL } from 'node:url'
20
+ import { HookBus, createPluginContext, createRouteTable, isPathInside, validatePluginModule, validatePluginGroups, validatePluginSettings } from '@/sdk/index.mjs'
21
+
22
+ // 延迟解析的产线权限服务(esbuild/别名下避免 nitro 打包循环导入;失败降级为拒绝一切)
23
+ let permissions = null
24
+ let userRepository = null
25
+ async function loadPermissions() {
26
+ if (permissions) return
27
+ try {
28
+ permissions = await import('@/server/services/workshop/permissions')
29
+ userRepository = await import('@/server/repositories/user.repository').then(m => m.userRepository)
30
+ }
31
+ catch (err) {
32
+ hostLoggerFallback()?.warn('权限服务加载失败(插件 ctx.permissions 降级):', err?.message)
33
+ }
34
+ }
35
+ function hostLoggerFallback() {
36
+ return globalThis.__awPluginHost?.logger ?? console
37
+ }
38
+
39
+ const g = globalThis
40
+
41
+ function log() {
42
+ return {
43
+ debug: (...a) => console.log('[aw-plugins][debug]', ...a),
44
+ info: (...a) => console.log('[aw-plugins]', ...a),
45
+ warn: (...a) => console.warn('[aw-plugins]', ...a),
46
+ error: (...a) => console.error('[aw-plugins]', ...a),
47
+ }
48
+ }
49
+
50
+ function defaultHome() {
51
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? ''
52
+ return join(home, '.AgentWorkShop')
53
+ }
54
+
55
+ /** 运行模式路径(cwd 为检出根时启用 project 作用域) */
56
+ function modePaths(cwd) {
57
+ const isRepo = existsSync(join(cwd, 'config.yml')) && existsSync(join(cwd, 'nuxt.config.ts'))
58
+ // packageRoot:宿主运行时取 initPluginHost 注入值;冒烟/单测(cwd 在包根)回退 cwd
59
+ const packageRoot = g.__awPluginHost?.packageRoot ?? (isRepo ? cwd : null)
60
+ const builtinDir = packageRoot ? join(packageRoot, 'server', 'plugins-builtin') : null
61
+ return {
62
+ builtinDir: builtinDir && existsSync(builtinDir) ? builtinDir : null,
63
+ projectDir: isRepo ? join(cwd, '.AgentWorkShop', 'plugins') : null,
64
+ userDir: join(process.env.AW_HOME && String(process.env.AW_HOME).trim() ? String(process.env.AW_HOME).trim() : defaultHome(), 'plugins'),
65
+ homeDir: process.env.AW_HOME && String(process.env.AW_HOME).trim() ? String(process.env.AW_HOME).trim() : defaultHome(),
66
+ }
67
+ }
68
+
69
+ function pathToUrl(p) {
70
+ return pathToFileURL(resolve(p)).href
71
+ }
72
+
73
+ /** 插件根目录 i18n.json 路径(存在才返回;多语言消息包,按 plugin.<name> 命名空间注入前端) */
74
+ function pluginI18nPath(dir) {
75
+ const p = join(dir, 'i18n.json')
76
+ return existsSync(p) ? p : null
77
+ }
78
+
79
+ /** 读取并解析插件 i18n.json(形态 { "<locale>": { key: value } };坏文件返回 null 不阻断) */
80
+ export function readPluginI18n(rec) {
81
+ if (!rec?.i18nPath || !existsSync(rec.i18nPath)) return null
82
+ try {
83
+ const obj = JSON.parse(readFileSync(rec.i18nPath, 'utf8'))
84
+ if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return null
85
+ const out = {}
86
+ for (const [locale, messages] of Object.entries(obj)) {
87
+ if (messages && typeof messages === 'object' && !Array.isArray(messages)) out[locale] = messages
88
+ }
89
+ return Object.keys(out).length ? out : null
90
+ }
91
+ catch {
92
+ return null
93
+ }
94
+ }
95
+
96
+ /**
97
+ * 全部插件的 i18n 消息包(免鉴权只读端点用;仅 UI 文案,插件作者不得放置敏感信息):
98
+ * { "<plugin>": { "<locale>": { key: value } } }
99
+ */
100
+ export function pluginI18nBundle() {
101
+ const host = getPluginHost()
102
+ if (!host) return {}
103
+ const out = {}
104
+ for (const rec of host.plugins.values()) {
105
+ if (rec.enabled === false) continue
106
+ const bundle = readPluginI18n(rec)
107
+ if (bundle) out[rec.name] = bundle
108
+ }
109
+ return out
110
+ }
111
+
112
+ // ---- 后端运行时服务面(ctx.services;只读取数优先,跨插件服务带 <plugin>. 前缀) ----
113
+ const servicesExt = (g.__awPluginServices ??= {
114
+ registry: new Map(),
115
+ /** 核心服务注册(name → 惰性 getter);宿主启动期 seed */
116
+ register(name, get) {
117
+ this.registry.set(String(name), get)
118
+ },
119
+ /** 插件供服务(自动加 `<plugin>.` 前缀;同前缀同名覆盖) */
120
+ provide(plugin, name, get) {
121
+ this.registry.set(`${plugin}.${String(name)}`, get)
122
+ },
123
+ names() {
124
+ return [...this.registry.keys()]
125
+ },
126
+ /** 取运行时服务对象(惰性求值并缓存;失败抛错由调用方兜底) */
127
+ async get(name) {
128
+ const get = this.registry.get(String(name))
129
+ if (!get) throw new Error(`未知运行时服务: ${name}(可用: ${this.names().join(', ')})`)
130
+ get._cache ??= get()
131
+ return await get._cache
132
+ },
133
+ })
134
+
135
+ /** 插件可获取的后端运行时对象(只读取数面;懒加载避免循环导入,失败即抛由插件兜底) */
136
+ async function seedRuntimeServices() {
137
+ if (servicesExt.registry.has('daq')) return
138
+ servicesExt.register('daq', async () => {
139
+ const storage = await import('@/server/services/workshop/daq/storage/index')
140
+ const nodes = await import('@/server/services/workshop/daq/daq-node.repo')
141
+ return {
142
+ query: q => storage.getTsdb().queryTagged(q),
143
+ nodes: () => nodes.getDaqNodeRepo().snapshot(),
144
+ }
145
+ })
146
+ servicesExt.register('lines', async () => {
147
+ const m = await import('@/server/services/workshop/dcw/dcw-line.repo')
148
+ const repo = m.getDcwLineRepo()
149
+ return { list: () => repo.all(), byId: id => repo.byId(id) }
150
+ })
151
+ servicesExt.register('channels', async () => {
152
+ const m = await import('@/server/plugins/workshop')
153
+ const mgr = m.getWorkshopManager()
154
+ return {
155
+ list: () => mgr.deps.repos.channels.list(),
156
+ agents: channelId => mgr.deps.repos.channelAgents.listByChannel(channelId),
157
+ }
158
+ })
159
+ servicesExt.register('plugins', async () => pluginManifest())
160
+ }
161
+
162
+ // ---- 启停状态(单一事实源:<配置根>/plugins-state.json;CLI/Web/宿主三方读写) ----
163
+ export function statePathFor(homeDir) {
164
+ return join(homeDir, 'plugins-state.json')
165
+ }
166
+
167
+ export function readDisabledSet(homeDir) {
168
+ try {
169
+ const j = JSON.parse(readFileSync(statePathFor(homeDir), 'utf8'))
170
+ return new Set(Array.isArray(j.disabled) ? j.disabled : [])
171
+ }
172
+ catch {
173
+ return new Set()
174
+ }
175
+ }
176
+
177
+ export function writeDisabledSet(homeDir, disabled) {
178
+ const p = statePathFor(homeDir)
179
+ mkdirSync(dirname(p), { recursive: true })
180
+ const tmp = `${p}.${process.pid}.tmp`
181
+ writeFileSync(tmp, `${JSON.stringify({ version: 1, updatedAt: new Date().toISOString(), disabled: [...disabled] }, null, 2)}\n`, 'utf8')
182
+ renameSync(tmp, p)
183
+ }
184
+
185
+ /** 发现插件入口,三作用域(builtin 同名被 project 覆盖,project 同名被 user 覆盖) */
186
+ export function discoverPluginDirs(cwd = process.cwd()) {
187
+ const { builtinDir, projectDir, userDir } = modePaths(cwd)
188
+ const out = []
189
+ const seen = new Set()
190
+ for (const [dir, scope] of [[builtinDir, 'builtin'], [projectDir, 'project'], [userDir, 'user']]) {
191
+ if (!dir || !existsSync(dir)) continue
192
+ for (const name of readdirSync(dir)) {
193
+ const sub = join(dir, name)
194
+ if (!existsSync(join(sub, 'index.mjs'))) continue
195
+ if (seen.has(name)) continue
196
+ seen.add(name)
197
+ out.push({ dir: sub, scope })
198
+ }
199
+ }
200
+ return out.sort((a, b) => a.dir.localeCompare(b.dir))
201
+ }
202
+
203
+ /**
204
+ * 装载插件宿主(idempotent;nitro 启动期调用一次)。
205
+ */
206
+ export async function initPluginHost({ cwd = process.cwd(), packageRoot } = {}) {
207
+ if (g.__awPluginHost) return g.__awPluginHost
208
+ const logger = log()
209
+ const homeDir = modePaths(cwd).homeDir
210
+ const host = {
211
+ bus: new HookBus({
212
+ name: 'aw-plugins',
213
+ onError: (err, meta) => logger.warn(`钩子错误(${meta?.type}):`, err?.message ?? err),
214
+ }),
215
+ routes: createRouteTable(),
216
+ plugins: new Map(),
217
+ disposables: new Map(), // name → fn[](ctx.onDispose 登记)
218
+ hookOffs: new Map(), // name → off[](ctx.hooks.on 登记;热重载时解绑)
219
+ failures: [],
220
+ initedAt: null,
221
+ cwd,
222
+ packageRoot,
223
+ logger,
224
+ configRelayOff: null,
225
+ }
226
+ g.__awPluginHost = host
227
+
228
+ // 有效配置(只读面;引擎/模式解析从运行根动态加载)
229
+ let config = null
230
+ let settingsPath = null
231
+ let paths = { home: homeDir, configRoot: join(cwd, '.AgentWorkShop'), dataDir: join(cwd, '.AgentWorkShop', 'data') }
232
+ try {
233
+ const homeMod = await import(pathToUrl(join(cwd, 'shared', 'config', 'home.mjs')))
234
+ const rm = homeMod.resolveRunMode({ cwd, packageRoot, env: process.env })
235
+ const engineRoot = rm.mode === 'repo' ? rm.root : (packageRoot ?? rm.root)
236
+ if (engineRoot && existsSync(join(engineRoot, 'shared', 'config', 'engine.mjs'))) {
237
+ const engine = await import(pathToUrl(join(engineRoot, 'shared', 'config', 'engine.mjs')))
238
+ config = engine.loadEffective({ configPath: rm.configPath, settingsPath: rm.settingsPath, env: process.env })
239
+ settingsPath = rm.settingsPath
240
+ }
241
+ paths = { home: rm.home, configRoot: rm.configRoot, dataDir: rm.dataDir }
242
+ host.logger.info(`配置根: ${rm.configRoot} (${rm.mode} 模式)`)
243
+ }
244
+ catch (err) {
245
+ host.logger.warn('配置引擎加载降级(插件 ctx.config 将为空):', err?.message)
246
+ }
247
+ // 配置热更新:system-config 变化(设置页 PATCH / runtime-settings 文件监听)即刷新
248
+ // effective —— 插件 ctx.config.get 每次调用实时读到新值(插件 API 地址等改配置即生效,无需重启)
249
+ try {
250
+ const { getSystemConfigService } = await import('@/server/services/system-config')
251
+ getSystemConfigService().subscribe((tail) => {
252
+ try {
253
+ if (config?.effective && tail?.effective) Object.assign(config.effective, tail.effective)
254
+ }
255
+ catch { /* 刷新失败保留旧值 */ }
256
+ })
257
+ }
258
+ catch (err) {
259
+ host.logger.warn('配置热更新订阅失败(插件 ctx.config 为装载时快照):', err?.message)
260
+ }
261
+ host.config = config
262
+
263
+ // 自环 origin:PORT env(prod:start.mjs 注入 / dev:dev-guard 注入 CLI 显式值)权威;
264
+ // nitro listen 钩子兜底回填
265
+ const argPort = (() => {
266
+ const argv = process.argv
267
+ const i = argv.indexOf('--port')
268
+ if (i >= 0 && argv[i + 1]) return argv[i + 1]
269
+ const eq = argv.find(a => a.startsWith('--port='))
270
+ return eq ? eq.slice(7) : null
271
+ })()
272
+ let selfOrigin = `http://127.0.0.1:${process.env.PORT ?? process.env.NITRO_PORT ?? argPort ?? config?.effective?.['server.dev.port'] ?? 3000}`
273
+ host.setSelfOrigin = (port) => {
274
+ selfOrigin = `http://127.0.0.1:${port}`
275
+ host.logger.info(`自环 origin 就绪: ${selfOrigin}`)
276
+ }
277
+ host.selfOrigin = () => selfOrigin
278
+ host.logger.info(`自环 origin: ${selfOrigin}`)
279
+
280
+ await loadAllPlugins(host, { config, settingsPath, paths })
281
+ await syncPluginSettings()
282
+ relayConfigEvents(host)
283
+ ensureStateWatcher(host)
284
+ return host
285
+ }
286
+
287
+ /**
288
+ * 平台设置变更 → 转发到插件总线。
289
+ *
290
+ * SDK 的 `ctx.config.onChange(fn)` 订阅的是 `config:changed`,而该事件此前只广播给
291
+ * SystemConfigService 自己的 listeners —— 插件永远收不到,「配置变更即时生效」对插件
292
+ * 是空承诺(实测:改 base_url 后插件的出站守卫仍沿用装载期判定)。这里做一次桥接。
293
+ * 只在宿主初始化时挂一次(热重载不会重复订阅)。
294
+ */
295
+ function relayConfigEvents(host) {
296
+ if (host.configRelayOff) return
297
+ void import('@/server/services/system-config')
298
+ .then(({ getSystemConfigService }) => {
299
+ host.configRelayOff = getSystemConfigService().subscribe((payload) => {
300
+ host.bus.emit('config:changed', {
301
+ type: payload.type,
302
+ changed: payload.changed ?? [],
303
+ effective: payload.effective,
304
+ sources: payload.sources,
305
+ })
306
+ })
307
+ })
308
+ .catch(err => host.logger.warn('设置变更转发到插件总线失败(插件收不到 config:changed):', err?.message ?? err))
309
+ }
310
+
311
+ /** 装载/重载全部插件(跳过 disabled;manifest 仍可见) */
312
+ async function loadAllPlugins(host, { config, paths }) {
313
+ const homeDir = modePaths(host.cwd).homeDir
314
+ const disabled = readDisabledSet(homeDir)
315
+ host.disabledSet = disabled
316
+ host.lastDisabledSnapshot = new Set(disabled) // 重装载竞态检测基线(见 reloadPluginHost)
317
+
318
+ // 产线权限服务(ctx.permissions 注入用;失败降级)
319
+ await loadPermissions()
320
+ await seedRuntimeServices()
321
+
322
+ const entries = discoverPluginDirs(host.cwd)
323
+ if (entries.length) host.logger.info(`发现 ${entries.length} 个插件(停用 ${disabled.size}),开始装载 ...`)
324
+
325
+ for (const { dir, scope } of entries) {
326
+ const entry = join(dir, 'index.mjs')
327
+ // 提到 try 外:catch 回滚需要知道插件名(def 在 try 内声明时 catch 不可见)
328
+ let def = null
329
+ try {
330
+ // cache-busting:热重载时 ESM 按 URL 缓存,不带 query 永远拿到旧模块(插件改代码不生效)
331
+ const mod = await import(`${pathToUrl(entry)}?t=${Date.now()}`)
332
+ const check = validatePluginModule(mod, entry)
333
+ if (!check.ok) throw new Error(check.error)
334
+ def = check.def
335
+
336
+ if (host.plugins.has(def.name)) throw new Error(`插件重名(后装载者跳过): ${def.name}`)
337
+ if (disabled.has(def.name)) {
338
+ host.plugins.set(def.name, {
339
+ name: def.name,
340
+ version: String(def.version ?? '0.0.0'),
341
+ description: String(def.description ?? ''),
342
+ auth: String(def.auth ?? 'none'),
343
+ scope,
344
+ dir,
345
+ entry,
346
+ clientPath: def.client ? resolve(dir, def.client) : null,
347
+ i18nPath: pluginI18nPath(dir),
348
+ settings: [],
349
+ groups: [],
350
+ routes: [],
351
+ enabled: false,
352
+ error: null,
353
+ })
354
+ host.logger.info(`⊘ 跳过(已停用) [${scope}] ${def.name}`)
355
+ continue
356
+ }
357
+
358
+ // 插件设置声明 → 平台设置描述符(key 编址 plugins.<name>.<key>;校验失败仅告警跳过条目)
359
+ const settingsCheck = validatePluginSettings(def.name, def.settings)
360
+ for (const e of settingsCheck.errors) host.logger.warn(`[${def.name}] 设置声明已跳过: ${e}`)
361
+ // 插件配置分组声明(manifest.configGroups;setup 里还可经 ctx.config.defineGroup 动态增加)
362
+ const groupsCheck = validatePluginGroups(def.name, def.configGroups ?? [])
363
+
364
+ const rec = {
365
+ name: def.name,
366
+ version: String(def.version ?? '0.0.0'),
367
+ description: String(def.description ?? ''),
368
+ auth: String(def.auth ?? 'none'),
369
+ scope,
370
+ dir,
371
+ entry,
372
+ clientPath: def.client ? resolve(dir, def.client) : null,
373
+ i18nPath: pluginI18nPath(dir),
374
+ settings: settingsCheck.descriptors,
375
+ /** 本插件声明的配置分组(独占命名空间;卸载时随插件一起摘除) */
376
+ groups: groupsCheck.groups,
377
+ routes: [],
378
+ enabled: true,
379
+ error: null,
380
+ }
381
+ for (const e of groupsCheck.errors) host.logger.warn(`[${def.name}] 分组声明已跳过: ${e}`)
382
+
383
+ const emitter = {
384
+ registerRoute: (n, m, p, h) => {
385
+ host.routes.register(n, m, p, h)
386
+ rec.routes.push({ method: String(m).toUpperCase(), path: p })
387
+ },
388
+ }
389
+ const perPluginDisposables = []
390
+ const hookOffs = []
391
+ host.disposables.set(def.name, perPluginDisposables)
392
+ host.hookOffs.set(def.name, hookOffs)
393
+ const scopedHooks = {
394
+ on: (t, fn) => {
395
+ const off = host.bus.on(t, fn)
396
+ hookOffs.push(off)
397
+ return off
398
+ },
399
+ once: (t, fn) => {
400
+ const off = host.bus.once(t, fn)
401
+ hookOffs.push(off)
402
+ return off
403
+ },
404
+ off: (t, fn) => host.bus.off(t, fn),
405
+ emit: (t, p) => host.bus.emit(t, p),
406
+ }
407
+ const ctx = createPluginContext({
408
+ name: def.name,
409
+ scope,
410
+ dir,
411
+ hooks: scopedHooks,
412
+ logger: {
413
+ debug: (...a) => host.logger.info(`[${def.name}][debug]`, ...a),
414
+ info: (...a) => host.logger.info(`[${def.name}]`, ...a),
415
+ warn: (...a) => host.logger.warn(`[${def.name}]`, ...a),
416
+ error: (...a) => host.logger.error(`[${def.name}]`, ...a),
417
+ },
418
+ config,
419
+ paths,
420
+ emitter,
421
+ onDispose: (fn) => {
422
+ perPluginDisposables.push(fn)
423
+ return fn
424
+ },
425
+ selfOrigin: () => selfOriginRef(host),
426
+ // 插件配置分组/字段注册面(SDK ctx.config.defineGroup / defineField):
427
+ // 插件可在 setup 里按条件增加自己的配置分区与字段,登记后立即回流设置页。
428
+ registerGroup: (g) => {
429
+ const chk = validatePluginGroups(def.name, [g])
430
+ // validatePluginGroups 返回 { groups, errors }(无 ok 字段)——只认 groups 长度
431
+ if (!chk.groups.length) {
432
+ for (const e of chk.errors) host.logger.warn(`[${def.name}] ctx.config.defineGroup 失败: ${e}`)
433
+ return null
434
+ }
435
+ const group = chk.groups[0]
436
+ rec.groups = [...rec.groups.filter(x => x.id !== group.id), group]
437
+ void syncPluginSettings()
438
+ return group
439
+ },
440
+ registerField: (decl) => {
441
+ const chk = validatePluginSettings(def.name, [decl])
442
+ if (!chk.descriptors.length) {
443
+ for (const e of chk.errors) host.logger.warn(`[${def.name}] ctx.config.defineField 失败: ${e}`)
444
+ return null
445
+ }
446
+ const d = chk.descriptors[0]
447
+ rec.settings = [...rec.settings.filter(x => x.key !== d.key), d]
448
+ void syncPluginSettings()
449
+ return d
450
+ },
451
+ removeGroup: (id) => {
452
+ const before = rec.groups.length
453
+ rec.groups = rec.groups.filter(x => x.id !== String(id))
454
+ if (rec.groups.length !== before) void syncPluginSettings()
455
+ return rec.groups.length !== before
456
+ },
457
+ removeField: (key) => {
458
+ const full = `plugins.${def.name}.${String(key)}`
459
+ const before = rec.settings.length
460
+ rec.settings = rec.settings.filter(x => x.key !== full)
461
+ if (rec.settings.length !== before) void syncPluginSettings()
462
+ return rec.settings.length !== before
463
+ },
464
+ groups: () => rec.groups,
465
+ fields: () => rec.settings,
466
+ // 产线权限拓展面(SDK ctx.permissions):插件可查询/管理用户×产线授权
467
+ permissions: {
468
+ lineMode: (user, lineId) => permissions.lineMode(user, lineId),
469
+ visibleLineIds: user => permissions.visibleLineIds(user),
470
+ listGrants: userId => userRepository.listGrants(userId),
471
+ setGrants: (userId, entries, grantedBy = 'plugin') => {
472
+ for (const g of (entries ?? [])) {
473
+ if (!g?.lineId) continue
474
+ userRepository.setGrant(userId, String(g.lineId), (g.mode ?? null), grantedBy)
475
+ }
476
+ permissions.notifyGrantsChanged(userId)
477
+ return userRepository.listGrants(userId)
478
+ },
479
+ },
480
+ })
481
+ // DAQ 扩展面(v2 帧管线):插件注册自定义驱动与下沉处理器。
482
+ // 桥经 globalThis 排队 —— daq 模块晚于插件宿主装载时,注册项先排队、
483
+ // daq 侧 plugin-bridge 接管后回放;重复装载由同名覆盖语义兜底。
484
+ const daqExt = (globalThis.__daqPluginExt ??= {
485
+ pendingDrivers: [],
486
+ pendingProcessors: [],
487
+ pendingTemplates: [],
488
+ registerDriver(d) {
489
+ this.pendingDrivers.push(d)
490
+ this._drain?.()
491
+ },
492
+ registerProcessor(kind, name, fn) {
493
+ this.pendingProcessors.push({ kind, name, fn })
494
+ this._drain?.()
495
+ },
496
+ registerTemplate(def) {
497
+ this.pendingTemplates.push(def)
498
+ this._drain?.()
499
+ },
500
+ drain(onDriver, onProcessor, onTemplate) {
501
+ this._drain = () => {
502
+ for (const d of this.pendingDrivers.splice(0)) onDriver(d)
503
+ for (const p of this.pendingProcessors.splice(0)) onProcessor(p.kind, p.name, p.fn)
504
+ for (const t of this.pendingTemplates.splice(0)) onTemplate(t)
505
+ }
506
+ this._drain()
507
+ },
508
+ })
509
+ ctx.daq = {
510
+ registerDriver: d => daqExt.registerDriver(d),
511
+ registerProcessor: (kind, name, fn) => daqExt.registerProcessor(kind, name, fn),
512
+ /** 注册数采节点模板(signalKind/sink.processors/metrics 全量可用;同名覆盖) */
513
+ registerTemplate: def => daqExt.registerTemplate(def),
514
+ /** 帧消费便捷别名(= hooks.on('daq:frame') / hooks.on('daq:sample')) */
515
+ onFrame: fn => scopedHooks.on('daq:frame', fn),
516
+ onSample: fn => scopedHooks.on('daq:sample', fn),
517
+ /** 时序查询直通(queryTagged):插件免鉴权拉取产线/节点窗口样本(bucket/raw),诊断取数用 */
518
+ query: async (q) => {
519
+ const m = await import('@/server/services/workshop/daq/storage/index')
520
+ return m.getTsdb().queryTagged(q)
521
+ },
522
+ /** 数采节点元数据快照(含产线归属,插件定位某产线的全部节点) */
523
+ nodes: async () => {
524
+ const m = await import('@/server/services/workshop/daq/daq-node.repo')
525
+ return m.getDaqNodeRepo().snapshot()
526
+ },
527
+ }
528
+ // OMP 工具扩展面:插件注册自定义 host 工具 → omp 会话运行时热注入
529
+ const ompExt = (globalThis.__ompPluginToolsBridge ??= {
530
+ pending: [],
531
+ register(plugin, tool) {
532
+ this.pending.push({ plugin, tool })
533
+ this._drain?.()
534
+ },
535
+ drain(onTool) {
536
+ this._drain = () => {
537
+ for (const def of this.pending.splice(0)) onTool(def)
538
+ }
539
+ this._drain()
540
+ },
541
+ })
542
+ ctx.omp = {
543
+ registerTool: (tool) => {
544
+ ompExt.register(def.name, tool)
545
+ ctx.logger.info(`已注册 omp 工具:「${tool?.name}」`)
546
+ },
547
+ }
548
+ // 后端运行时对象面:ctx.services.get('daq'|'lines'|'channels'|'plugins') /
549
+ // ctx.services.provide(name, getter) 跨插件供服务(自动 <plugin>. 前缀)
550
+ ctx.services = {
551
+ names: () => servicesExt.names(),
552
+ get: name => servicesExt.get(name),
553
+ provide: (name, get) => servicesExt.provide(def.name, name, get),
554
+ }
555
+
556
+ // 先 setup 再注册路由:反过来会在 setup 抛错时留下"路由活着、host.plugins 无记录"的幽灵路由,
557
+ // 而 doReload 的清退以 host.plugins.keys() 为准 → 该插件的 omp 工具与路由永久泄漏(不可回收)。
558
+ await def.setup?.(ctx)
559
+ for (const r of (Array.isArray(def.routes) ? def.routes : [])) {
560
+ emitter.registerRoute(def.name, r.method ?? 'GET', r.path, r.handler)
561
+ }
562
+
563
+ host.plugins.set(def.name, rec)
564
+ host.logger.info(`✔ 已装载 [${scope}] ${def.name}@${rec.version}${rec.clientPath ? ' (+client)' : ''}`)
565
+ }
566
+ catch (err) {
567
+ // setup/注册失败:逐项回滚已产生的半注册状态,保证"要么完整装载,要么完全无痕"
568
+ rollbackPartialLoad(host, def?.name)
569
+ host.failures.push({ source: entry, error: err?.message ?? String(err) })
570
+ host.logger.error(`装载失败 ${entry}:`, err?.message ?? err)
571
+ }
572
+ }
573
+
574
+ host.initedAt = new Date().toISOString()
575
+ await host.bus.emit('plugin:host:init', { plugins: [...host.plugins.keys()], failures: host.failures.length })
576
+ host.logger.info(`装载完成: ${host.plugins.size} 个(含停用)/ ${host.failures.length} 失败 / 活跃路由 ${host.routes.size} 条`)
577
+ }
578
+
579
+ /**
580
+ * 回滚一次失败的插件装载 —— 保证「要么完整装载,要么完全无痕」。
581
+ * 覆盖 setup 抛错 / 路由注册抛错两条路径:路由、disposables、hookOffs、omp 待注入工具、服务注册
582
+ * 全部按插件名回收,避免出现「路由活着但 host.plugins 无记录」的幽灵态
583
+ * (doReload 以 host.plugins.keys() 为清退依据,漏掉即永久泄漏)。
584
+ */
585
+ function rollbackPartialLoad(host, name) {
586
+ if (!name) return
587
+ try {
588
+ const removed = host.routes.unregisterPlugin?.(name) ?? 0
589
+ const disposables = host.disposables.get(name) ?? []
590
+ for (const d of disposables.splice(0)) {
591
+ try {
592
+ d?.()
593
+ }
594
+ catch (e) {
595
+ host.logger.warn(`[插件回滚] dispose 失败 ${name}:`, e?.message ?? e)
596
+ }
597
+ }
598
+ host.disposables.delete(name)
599
+ for (const off of (host.hookOffs.get(name) ?? []).splice(0)) {
600
+ try {
601
+ off?.()
602
+ }
603
+ catch { /* 解绑失败不影响回滚 */ }
604
+ }
605
+ host.hookOffs.delete(name)
606
+ // omp 桥:把已入 pending 未注入的工具摘掉(bridge 未挂载时为空操作)
607
+ const bridge = globalThis.__ompPluginToolsBridge
608
+ if (bridge?.pending) {
609
+ bridge.pending = bridge.pending.filter(p => p.plugin !== name)
610
+ }
611
+ host.plugins.delete(name)
612
+ // 设置的描述符与配置分组都挂在 rec 上 → 随 rec 一并消失;重算一次让设置页立即收敛
613
+ void syncPluginSettings()
614
+ if (removed > 0) host.logger.warn(`[插件回滚] ${name}:已卸下 ${removed} 条半注册路由`)
615
+ }
616
+ catch (e) {
617
+ host.logger.error(`[插件回滚] ${name} 回滚自身异常:`, e?.message ?? e)
618
+ }
619
+ }
620
+
621
+ function selfOriginRef(host) {
622
+ return host.selfOrigin()
623
+ }
624
+
625
+ /** 插件设置声明 + 配置分组声明 → SystemConfigService
626
+ * (合并进平台描述符:前端设置页渲染 + PATCH 校验 + 热生效;分组供设置页分区渲染) */
627
+ async function syncPluginSettings() {
628
+ try {
629
+ const { getSystemConfigService } = await import('@/server/services/system-config')
630
+ const host = getPluginHost()
631
+ const descs = []
632
+ const groups = []
633
+ const labels = new Map()
634
+ for (const rec of host?.plugins.values() ?? []) {
635
+ if (rec.enabled === false) continue
636
+ labels.set(rec.name, rec.label ?? rec.name)
637
+ descs.push(...(rec.settings ?? []))
638
+ groups.push(...(rec.groups ?? []))
639
+ }
640
+ getSystemConfigService().setPluginDescriptors(descs, groups, labels)
641
+ }
642
+ catch (err) {
643
+ hostLoggerFallback()?.warn('插件设置同步失败(设置页将不渲染插件配置):', err?.message)
644
+ }
645
+ }
646
+
647
+ /** 热重载:全部 dispose/解绑 → 重新装载(跳过停用)→ 广播 plugins.reloaded(并发合并)。
648
+ * 竞态防护:重装载期间状态文件再变化(如 disable→enable 连击)时,去抖回调会撞上
649
+ * in-flight 守卫被吞 —— 装载结束后比对禁用集快照,有差异自动补跑一次,事件绝不丢失。 */
650
+ export async function reloadPluginHost() {
651
+ const host = getPluginHost()
652
+ if (!host) return null
653
+ if (host.reloadInFlight) return host.reloadInFlight
654
+ host.reloadInFlight = doReload(host).finally(() => {
655
+ host.reloadInFlight = null
656
+ try {
657
+ const current = readDisabledSet(modePaths(host.cwd).homeDir)
658
+ const prev = host.lastDisabledSnapshot
659
+ const drifted = prev
660
+ ? (current.size !== prev.size || [...current].some(x => !prev.has(x)))
661
+ : false
662
+ host.lastDisabledSnapshot = current
663
+ if (drifted) void reloadPluginHost()
664
+ }
665
+ catch { /* 快照比对失败忽略(下个事件兜底) */ }
666
+ })
667
+ return host.reloadInFlight
668
+ }
669
+
670
+ async function doReload(host) {
671
+ host.logger.info('热重载插件宿主 ...')
672
+ for (const [name, list] of host.disposables ?? []) {
673
+ for (const fn of list.splice(0)) {
674
+ try {
675
+ await fn()
676
+ }
677
+ catch (err) {
678
+ host.logger.warn(`[${name}] onDispose 失败:`, err?.message)
679
+ }
680
+ }
681
+ }
682
+ for (const offs of (host.hookOffs ?? new Map()).values()) {
683
+ for (const off of offs.splice(0)) {
684
+ try {
685
+ off()
686
+ }
687
+ catch { /* 解绑失败忽略 */ }
688
+ }
689
+ }
690
+ const prevNames = [...host.plugins.keys()]
691
+ // 卸载即注销其注册的全部 agent 工具(否则停用插件后工具仍残留在注册表、可被继续调用)
692
+ const ompTools = await import('@/server/services/workshop/agents/plugin-tools').catch(() => null)
693
+ for (const prev of prevNames) {
694
+ try {
695
+ ompTools?.unregisterPluginTools(prev)
696
+ }
697
+ catch { /* 注销失败不阻断重载 */ }
698
+ }
699
+ host.plugins.clear()
700
+ host.routes = createRouteTable()
701
+ host.failures = []
702
+ await loadAllPlugins(host, { config: host.config, settingsPath: null, paths: { home: modePaths(host.cwd).homeDir, configRoot: join(host.cwd, '.AgentWorkShop'), dataDir: join(host.cwd, '.AgentWorkShop', 'data') } })
703
+ // 装载中途失败(setup 抛错)的插件可能留下半注册工具,兜底再清一次
704
+ for (const prev of prevNames) {
705
+ if (!host.plugins.has(prev)) {
706
+ try {
707
+ ompTools?.unregisterPluginTools(prev)
708
+ }
709
+ catch { /* 忽略 */ }
710
+ }
711
+ }
712
+ await host.bus.emit('plugins:reloaded', { plugins: pluginManifest() })
713
+ await syncPluginSettings()
714
+ try {
715
+ const m = await import('@/server/services/workshop/scene-events')
716
+ m.broadcastSceneEvent('plugins.reloaded', { plugins: pluginManifest() })
717
+ }
718
+ catch { /* 广播失败不影响重载 */ }
719
+ return host
720
+ }
721
+
722
+ /** 启停单插件(写状态文件;调用方随后 reloadPluginHost 或由 state watcher 触发) */
723
+ export function setPluginEnabled(name, enabled) {
724
+ const host = getPluginHost()
725
+ const homeDir = modePaths(host?.cwd ?? process.cwd()).homeDir
726
+ const set = readDisabledSet(homeDir)
727
+ if (enabled) set.delete(name)
728
+ else set.add(name)
729
+ writeDisabledSet(homeDir, set)
730
+ return [...set]
731
+ }
732
+
733
+ /** 状态文件监视 → 热重载(CLI/Web 只写文件,服务自感知)。
734
+ * 双保险:fs.watch 的 rename 事件在 Windows 上可能丢名字/丢事件(tmp+rename 原子写
735
+ * 尤其如此)→ 另设 10s 轮询比对 mtime,确保启停/热重载事件绝不丢失。 */
736
+ function ensureStateWatcher(host) {
737
+ const statePath = statePathFor(modePaths(host.cwd).homeDir)
738
+ let lastMtime = 0
739
+ let debounce = null
740
+ const onChange = () => {
741
+ clearTimeout(debounce)
742
+ debounce = setTimeout(() => {
743
+ void reloadPluginHost()
744
+ }, 400)
745
+ }
746
+ try {
747
+ mkdirSync(dirname(statePath), { recursive: true })
748
+ if (!existsSync(statePath)) writeDisabledSet(modePaths(host.cwd).homeDir, new Set())
749
+ lastMtime = existsSync(statePath) ? statSync(statePath).mtimeMs : 0
750
+ // watch 目录而非文件:writeDisabledSet 用 rename 原子替换,POSIX 的文件级
751
+ // watch 挂在旧 inode 上,首次启停后静默失效;目录监听对 rename 稳定
752
+ watch(dirname(statePath), (_event, filename) => {
753
+ if (filename && filename !== 'plugins-state.json') return
754
+ onChange()
755
+ })
756
+ }
757
+ catch (err) {
758
+ host.logger.warn('状态文件监视不可用(启停需手动重启):', err?.message)
759
+ }
760
+ // 轮询兜底(与 watch 互冗余;reloadPluginHost 幂等且并发合并)
761
+ const poll = setInterval(() => {
762
+ try {
763
+ if (!existsSync(statePath)) return
764
+ const m = statSync(statePath).mtimeMs
765
+ if (m !== lastMtime) {
766
+ lastMtime = m
767
+ onChange()
768
+ }
769
+ }
770
+ catch { /* 文件正被替换:下一轮再看 */ }
771
+ }, 10_000)
772
+ poll.unref?.()
773
+ }
774
+
775
+ /** 单例访问(未初始化返回 null —— 桥接点据此快速 no-op) */
776
+ export function getPluginHost() {
777
+ return g.__awPluginHost ?? null
778
+ }
779
+
780
+ /** scene-events 桥:全部无频道实时事件 → 插件 event:<type> */
781
+ export function emitPluginEvent(type, payload) {
782
+ void g.__awPluginHost?.bus.emit(`event:${type}`, payload)
783
+ }
784
+
785
+ /** DAQ 下发级采样钩子(与 WS daq.reading 同点、同节拍语义) */
786
+ export function emitDaqSample(payload) {
787
+ void g.__awPluginHost?.bus.emit('daq:sample', payload)
788
+ }
789
+
790
+ /** 帧观察钩子(v2 多形态信号;载荷只含元数据/指标/预览,不含 blob) */
791
+ export function emitDaqFrame(payload) {
792
+ void g.__awPluginHost?.bus.emit('daq:frame', payload)
793
+ }
794
+
795
+ /** 写控 ACK 后观察钩子 */
796
+ export function emitDcwWrite(payload) {
797
+ void g.__awPluginHost?.bus.emit('dcw:write', payload)
798
+ }
799
+
800
+ /** 产线启停钩子 */
801
+ export function emitLineLifecycle(kind, payload) {
802
+ void g.__awPluginHost?.bus.emit(kind, payload)
803
+ }
804
+
805
+ /** 客户端脚本读取(免鉴权只读端点用;越界路径拒绝) */
806
+ export function readClientScript(name) {
807
+ const host = getPluginHost()
808
+ const rec = host?.plugins.get(name)
809
+ if (!host || !rec) return { status: 404 }
810
+ if (!rec.clientPath || !existsSync(rec.clientPath)) return { status: 404 }
811
+ // 必须用 isPathInside:startsWith 会把兄弟同前缀目录(…/foo-evil)判为在内,可被 ../ 逃逸
812
+ if (!isPathInside(rec.dir, rec.clientPath)) return { status: 400 }
813
+ return { status: 200, code: readFileSync(rec.clientPath, 'utf8'), contentType: 'text/javascript; charset=utf-8' }
814
+ }
815
+
816
+ /** 清单(非敏感只读;含启停状态与路由)。builtin = 随项目检出提供的内置示例插件 */
817
+ export function pluginManifest() {
818
+ const host = getPluginHost()
819
+ if (!host) return []
820
+ return [...host.plugins.values()].map(r => ({
821
+ name: r.name,
822
+ version: r.version,
823
+ description: r.description,
824
+ scope: r.scope,
825
+ builtin: r.scope === 'project' || r.scope === 'builtin',
826
+ enabled: r.enabled !== false,
827
+ hasClient: Boolean(r.clientPath),
828
+ hasI18n: Boolean(r.i18nPath),
829
+ settingsCount: Array.isArray(r.settings) ? r.settings.length : 0,
830
+ /** 本插件声明的配置分组(设置页独立分区;id 已收敛进 plugin-<name> 命名空间) */
831
+ configGroups: (Array.isArray(r.groups) ? r.groups : []).map(g => ({
832
+ id: g.id,
833
+ label: g.label,
834
+ fieldCount: (r.settings ?? []).filter(d => d.group === g.id).length,
835
+ })),
836
+ routes: host.routes.byPlugin(r.name),
837
+ error: r.error,
838
+ }))
839
+ }
840
+
841
+ /** 关机钩子(nitro close 时调用):先逐插件回收订阅/定时器,再广播 server:close */
842
+ export async function shutdownPluginHost() {
843
+ const host = getPluginHost()
844
+ if (!host) return
845
+ for (const [name, list] of host.disposables ?? []) {
846
+ for (const fn of list.splice(0)) {
847
+ try {
848
+ await fn()
849
+ }
850
+ catch (err) {
851
+ host.logger.warn(`[${name}] onDispose 失败:`, err?.message)
852
+ }
853
+ }
854
+ }
855
+ await host.bus.emit('server:close', { at: new Date().toISOString() })
856
+ host.logger.info('插件清理完成,已发出 server:close')
857
+ }