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