agentworkshop 0.7.6 → 0.7.7

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 (517) hide show
  1. package/.AgentWorkShop/prompts/host-tools.json +1 -1
  2. package/.output/.AgentWorkShop/prompts/host-tools.json +1 -1
  3. package/.output/nitro.json +1 -1
  4. package/.output/public/_nuxt/{rzGB_ojX.js → 3612gD2V.js} +2 -2
  5. package/.output/public/_nuxt/8eIQAVlb.js +1 -0
  6. package/.output/public/_nuxt/Ah9qOv1m.js +1 -0
  7. package/.output/public/_nuxt/{DdPeifHR.js → B4Fia4FB.js} +1 -1
  8. package/.output/public/_nuxt/B7aqqzkY.js +1 -0
  9. package/.output/public/_nuxt/BJ-fxrSw.js +1 -0
  10. package/.output/public/_nuxt/{DPDqAD1e.js → BSXx2vqR.js} +1 -1
  11. package/.output/public/_nuxt/{CdSgfcYR.js → BVZjSVs2.js} +1 -1
  12. package/.output/public/_nuxt/{DP6bdyIp.js → BVzDoF8t.js} +1 -1
  13. package/.output/public/_nuxt/BYL0Rjqj.js +7 -0
  14. package/.output/public/_nuxt/{CXmkVXS5.js → BjVLsC3M.js} +1 -1
  15. package/.output/public/_nuxt/{7ZABjMRh2.js → BkfchkK62.js} +1 -1
  16. package/.output/public/_nuxt/BnVoQ74r.js +1 -0
  17. package/.output/public/_nuxt/Bnp4vIAf.js +1 -0
  18. package/.output/public/_nuxt/BsMpJf7S.js +70 -0
  19. package/.output/public/_nuxt/{Z8k0uMSI.js → Bt_HDizI.js} +1 -1
  20. package/.output/public/_nuxt/Bu-P92Pe.js +18 -0
  21. package/.output/public/_nuxt/ButLXkjo.js +2 -0
  22. package/.output/public/_nuxt/C-GarxYC.js +1 -0
  23. package/.output/public/_nuxt/{D8DDDzV62.js → C2iWjzEC2.js} +1 -1
  24. package/.output/public/_nuxt/{HWXLx5Hz.js → C8dxXc6K.js} +5 -5
  25. package/.output/public/_nuxt/CGdPdJPP.js +1 -0
  26. package/.output/public/_nuxt/{CyygA0q4.js → CQiKcuoG.js} +4 -4
  27. package/.output/public/_nuxt/{CN7Zh8GQ.js → CRGlf1Gb.js} +1 -1
  28. package/.output/public/_nuxt/{DSBfvCi5.js → CblLEiCZ.js} +7 -7
  29. package/.output/public/_nuxt/Cd15nPnG2.js +1 -0
  30. package/.output/public/_nuxt/{OwJ1LJkF.js → CsCpu2Zh.js} +1 -1
  31. package/.output/public/_nuxt/CvbHIGQY2.js +1 -0
  32. package/.output/public/_nuxt/Cyk3du4K2.js +1 -0
  33. package/.output/public/_nuxt/{DVQAz9WI.js → D4qXvjuV.js} +2 -2
  34. package/.output/public/_nuxt/{CfIXY-ET.js → DCEyMaN-.js} +1 -1
  35. package/.output/public/_nuxt/{BFYNhG9S.js → DCXIGxzT.js} +1 -1
  36. package/.output/public/_nuxt/{B9aPoQvt.js → DM8DS9MA.js} +1 -1
  37. package/.output/public/_nuxt/{ChnfyQHz.js → DNzaswei.js} +1 -1
  38. package/.output/public/_nuxt/{CrFGZYVB2.js → DYZBdSSg2.js} +1 -1
  39. package/.output/public/_nuxt/{dObsRdSQ.js → DZk24ego.js} +1 -1
  40. package/.output/public/_nuxt/DeYsUzhr.js +1 -0
  41. package/.output/public/_nuxt/Dk6pq9JB2.js +1 -0
  42. package/.output/public/_nuxt/{ByGNWgAr.js → Do88WZG2.js} +3 -3
  43. package/.output/public/_nuxt/{R_WxTozV2.js → Du-eSpo2.js} +1 -1
  44. package/.output/public/_nuxt/OmpTerminalPanel.B_Pl5Ynm.css +1 -0
  45. package/.output/public/_nuxt/{Bsc69G4x.js → VnIWJ0ts.js} +3 -3
  46. package/.output/public/_nuxt/_id_.BzKMZnLe.css +1 -0
  47. package/.output/public/_nuxt/_id_.CbpDAWRh.css +1 -0
  48. package/.output/public/_nuxt/{_wsId_.DET_GinP.css → _wsId_.COUzMXpP.css} +1 -1
  49. package/.output/public/_nuxt/agents.BlejnOOC.css +1 -0
  50. package/.output/public/_nuxt/builds/latest.json +1 -1
  51. package/.output/public/_nuxt/builds/meta/14df171d-89cb-43ec-ad6f-9df72d6da7f5.json +1 -0
  52. package/.output/public/_nuxt/daq.zZ8GR433.css +1 -0
  53. package/.output/public/_nuxt/{default.D17kXlD6.css → default.V3_hUJq1.css} +1 -1
  54. package/.output/public/_nuxt/{B4GHHF6d2.js → fQUs58kX2.js} +1 -1
  55. package/.output/public/_nuxt/p7wSGMtc.js +1 -0
  56. package/.output/public/_nuxt/tRBT-plo.js +1 -0
  57. package/.output/server/chunks/_/SearchOutlined.mjs +4 -4
  58. package/.output/server/chunks/_/SearchOutlined.mjs.map +1 -1
  59. package/.output/server/chunks/_/character-asset.repo.mjs +3 -6
  60. package/.output/server/chunks/_/character-asset.repo.mjs.map +1 -1
  61. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  62. package/.output/server/chunks/_/nitro.mjs +4967 -2035
  63. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  64. package/.output/server/chunks/_/scene-layout.repo.mjs +4 -10
  65. package/.output/server/chunks/_/scene-layout.repo.mjs.map +1 -1
  66. package/.output/server/chunks/build/{Col-D7fjGDF6.mjs → Col-biaNnEPf.mjs} +2 -2
  67. package/.output/server/chunks/build/{Col-D7fjGDF6.mjs.map → Col-biaNnEPf.mjs.map} +1 -1
  68. package/.output/server/chunks/build/{OmpTerminalPanel-B_SYhmgb.mjs → OmpTerminalPanel-COphA1br.mjs} +20 -19
  69. package/.output/server/chunks/build/OmpTerminalPanel-COphA1br.mjs.map +1 -0
  70. package/.output/server/chunks/build/{TownView-Bl8Gkcxi.mjs → TownView-B5KifIaT.mjs} +4 -4
  71. package/.output/server/chunks/build/{TownView-Bl8Gkcxi.mjs.map → TownView-B5KifIaT.mjs.map} +1 -1
  72. package/.output/server/chunks/build/{_id_-GnRJPykX.mjs → _id_-C-ewLgfl.mjs} +119 -119
  73. package/.output/server/chunks/build/{_id_-GnRJPykX.mjs.map → _id_-C-ewLgfl.mjs.map} +1 -1
  74. package/.output/server/chunks/build/{_id_-CWLFGZjV.mjs → _id_-Ct4Jhvl1.mjs} +42 -38
  75. package/.output/server/chunks/build/_id_-Ct4Jhvl1.mjs.map +1 -0
  76. package/.output/server/chunks/build/{_wsId_-BhQMjyHG.mjs → _wsId_-CanI_6Su.mjs} +591 -53
  77. package/.output/server/chunks/build/{_wsId_-BhQMjyHG.mjs.map → _wsId_-CanI_6Su.mjs.map} +1 -1
  78. package/.output/server/chunks/build/{agents-D4l1icvn.mjs → agents-DSOptxXA.mjs} +146 -91
  79. package/.output/server/chunks/build/agents-DSOptxXA.mjs.map +1 -0
  80. package/.output/server/chunks/build/{alert-gH-s7yIh.mjs → alert-qJnjyRcP.mjs} +3 -3
  81. package/.output/server/chunks/build/{alert-gH-s7yIh.mjs.map → alert-qJnjyRcP.mjs.map} +1 -1
  82. package/.output/server/chunks/build/{button-BhbX5ACI.mjs → button-DEcZFcqN.mjs} +3 -3
  83. package/.output/server/chunks/build/{button-BhbX5ACI.mjs.map → button-DEcZFcqN.mjs.map} +1 -1
  84. package/.output/server/chunks/build/{card-l4BbX67w.mjs → card-Dipvaykh.mjs} +5 -5
  85. package/.output/server/chunks/build/{card-l4BbX67w.mjs.map → card-Dipvaykh.mjs.map} +1 -1
  86. package/.output/server/chunks/build/{channel-templates-DqjtC-R0.mjs → channel-templates-BK0KuPOd.mjs} +13 -12
  87. package/.output/server/chunks/build/channel-templates-BK0KuPOd.mjs.map +1 -0
  88. package/.output/server/chunks/build/{checkbox-BF11p3dH.mjs → checkbox-dzcpU_Cd.mjs} +4 -4
  89. package/.output/server/chunks/build/{checkbox-BF11p3dH.mjs.map → checkbox-dzcpU_Cd.mjs.map} +1 -1
  90. package/.output/server/chunks/build/{daq-BOgpn9sl.mjs → daq-D9RA_uze.mjs} +102 -102
  91. package/.output/server/chunks/build/{daq-BOgpn9sl.mjs.map → daq-D9RA_uze.mjs.map} +1 -1
  92. package/.output/server/chunks/build/dcw-BTM5YU-B.mjs +1 -1
  93. package/.output/server/chunks/build/{default-CKJWhkot.mjs → default-BfWGTlbj.mjs} +81 -23
  94. package/.output/server/chunks/build/{default-CKJWhkot.mjs.map → default-BfWGTlbj.mjs.map} +1 -1
  95. package/.output/server/chunks/build/{drawer-CVValqoh.mjs → drawer-Cmh90erI.mjs} +3 -3
  96. package/.output/server/chunks/build/{drawer-CVValqoh.mjs.map → drawer-Cmh90erI.mjs.map} +1 -1
  97. package/.output/server/chunks/build/{dropdown-ByCsEWlQ.mjs → dropdown-CGQ0KAzA.mjs} +2 -2
  98. package/.output/server/chunks/build/{dropdown-ByCsEWlQ.mjs.map → dropdown-CGQ0KAzA.mjs.map} +1 -1
  99. package/.output/server/chunks/build/{dropdown-Dex8PXu6.mjs → dropdown-vhn1NPFs.mjs} +4 -4
  100. package/.output/server/chunks/build/{dropdown-Dex8PXu6.mjs.map → dropdown-vhn1NPFs.mjs.map} +1 -1
  101. package/.output/server/chunks/build/{input-number-BBlRoAJ7.mjs → input-number-Bd55elNN.mjs} +5 -5
  102. package/.output/server/chunks/build/{input-number-BBlRoAJ7.mjs.map → input-number-Bd55elNN.mjs.map} +1 -1
  103. package/.output/server/chunks/build/{input--KMeLYqZ.mjs → input-sf_BT6o6.mjs} +3 -3
  104. package/.output/server/chunks/build/{input--KMeLYqZ.mjs.map → input-sf_BT6o6.mjs.map} +1 -1
  105. package/.output/server/chunks/build/logs-Dyk0I2I9.mjs +1 -1
  106. package/.output/server/chunks/build/{menu-xN-SXb9Q.mjs → menu-WCrlpYVh.mjs} +3 -3
  107. package/.output/server/chunks/build/{menu-xN-SXb9Q.mjs.map → menu-WCrlpYVh.mjs.map} +1 -1
  108. package/.output/server/chunks/build/{modal-DrCOcjrl.mjs → modal-yvUquPj5.mjs} +4 -4
  109. package/.output/server/chunks/build/{modal-DrCOcjrl.mjs.map → modal-yvUquPj5.mjs.map} +1 -1
  110. package/.output/server/chunks/build/{monitor-KW8WLOJd.mjs → monitor-MIOvsyLa.mjs} +21 -21
  111. package/.output/server/chunks/build/{monitor-KW8WLOJd.mjs.map → monitor-MIOvsyLa.mjs.map} +1 -1
  112. package/.output/server/chunks/build/pages-DR2bzczM.mjs +1 -1
  113. package/.output/server/chunks/build/{plugins-B-ZNey0Z.mjs → plugins-DnOBIWGg.mjs} +7 -7
  114. package/.output/server/chunks/build/{plugins-B-ZNey0Z.mjs.map → plugins-DnOBIWGg.mjs.map} +1 -1
  115. package/.output/server/chunks/build/{popconfirm-C5H1Qoh3.mjs → popconfirm-CRaHcz5O.mjs} +4 -4
  116. package/.output/server/chunks/build/{popconfirm-C5H1Qoh3.mjs.map → popconfirm-CRaHcz5O.mjs.map} +1 -1
  117. package/.output/server/chunks/build/{useWorkshopApi-Bh5VUHWu.mjs → segmented-DPe9ZzLO.mjs} +7 -78
  118. package/.output/server/chunks/build/segmented-DPe9ZzLO.mjs.map +1 -0
  119. package/.output/server/chunks/build/{select-D7H2ysgT.mjs → select-D-CeE5vY.mjs} +3 -3
  120. package/.output/server/chunks/build/{select-D7H2ysgT.mjs.map → select-D-CeE5vY.mjs.map} +1 -1
  121. package/.output/server/chunks/build/{settings-Cr06lbRy.mjs → settings-DA8IkGLo.mjs} +11 -11
  122. package/.output/server/chunks/build/{settings-Cr06lbRy.mjs.map → settings-DA8IkGLo.mjs.map} +1 -1
  123. package/.output/server/chunks/build/{space-DCwIlnkI.mjs → space-CCBYAkXt.mjs} +2 -2
  124. package/.output/server/chunks/build/{space-DCwIlnkI.mjs.map → space-CCBYAkXt.mjs.map} +1 -1
  125. package/.output/server/chunks/build/{switch-VC0m9ede.mjs → switch-CelRXpcy.mjs} +3 -3
  126. package/.output/server/chunks/build/{switch-VC0m9ede.mjs.map → switch-CelRXpcy.mjs.map} +1 -1
  127. package/.output/server/chunks/build/{table-BksLg3Q_.mjs → table-Cswq-l2r.mjs} +10 -10
  128. package/.output/server/chunks/build/{table-BksLg3Q_.mjs.map → table-Cswq-l2r.mjs.map} +1 -1
  129. package/.output/server/chunks/build/{tabs-CzUfD3iX.mjs → tabs-BM3tAh_J.mjs} +5 -5
  130. package/.output/server/chunks/build/{tabs-CzUfD3iX.mjs.map → tabs-BM3tAh_J.mjs.map} +1 -1
  131. package/.output/server/chunks/build/{tag-oQI3VtqM.mjs → tag-NO9jEqKy.mjs} +4 -4
  132. package/.output/server/chunks/build/{tag-oQI3VtqM.mjs.map → tag-NO9jEqKy.mjs.map} +1 -1
  133. package/.output/server/chunks/build/{teams-QR3BBF7A.mjs → teams-BhSKBBBM.mjs} +15 -14
  134. package/.output/server/chunks/build/teams-BhSKBBBM.mjs.map +1 -0
  135. package/.output/server/chunks/build/{tokens-DFvr_TLj.mjs → tokens-D_eyxmcv.mjs} +16 -16
  136. package/.output/server/chunks/build/{tokens-DFvr_TLj.mjs.map → tokens-D_eyxmcv.mjs.map} +1 -1
  137. package/.output/server/chunks/build/town-BUqRobze.mjs +1 -1
  138. package/.output/server/chunks/build/{town-_4tEEEVW.mjs → town-DPtOPRRO.mjs} +4 -4
  139. package/.output/server/chunks/build/{town-_4tEEEVW.mjs.map → town-DPtOPRRO.mjs.map} +1 -1
  140. package/.output/server/chunks/build/useLocalTime-9a4B-aHv.mjs +42 -0
  141. package/.output/server/chunks/build/useLocalTime-9a4B-aHv.mjs.map +1 -0
  142. package/.output/server/chunks/build/useWorkshopApi-D2gq06N2.mjs +81 -0
  143. package/.output/server/chunks/build/useWorkshopApi-D2gq06N2.mjs.map +1 -0
  144. package/.output/server/chunks/build/useWorkshopWs-B3j5wIAK.mjs +1 -1
  145. package/.output/server/chunks/build/user-Dk-ytEUV.mjs +1 -1
  146. package/.output/server/chunks/build/{users-4FZ0yFUO.mjs → users-CmVvb1oq.mjs} +16 -16
  147. package/.output/server/chunks/build/{users-4FZ0yFUO.mjs.map → users-CmVvb1oq.mjs.map} +1 -1
  148. package/.output/server/chunks/build/{workshop-k0XZTFKg.mjs → workshop-iCzNRifn.mjs} +9 -9
  149. package/.output/server/chunks/build/{workshop-k0XZTFKg.mjs.map → workshop-iCzNRifn.mjs.map} +1 -1
  150. package/.output/server/chunks/build/workspaces-IfORCDJE.mjs +1 -1
  151. package/.output/server/chunks/routes/api/health.get.mjs +1 -1
  152. package/.output/server/chunks/routes/api/index.get.mjs +1 -1
  153. package/.output/server/chunks/routes/api/index.post.mjs +1 -1
  154. package/.output/server/chunks/routes/api/mcp/workshop.mjs +1 -1
  155. package/.output/server/chunks/routes/api/metrics.mjs +1 -1
  156. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +1 -1
  157. package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs +1 -1
  158. package/.output/server/chunks/routes/api/plugins/manifest.get.mjs +1 -1
  159. package/.output/server/chunks/routes/api/system/config.get.mjs +1 -1
  160. package/.output/server/chunks/routes/api/system/index.get.mjs +3 -3
  161. package/.output/server/chunks/routes/api/system/index.get.mjs.map +1 -1
  162. package/.output/server/chunks/routes/api/system/index.patch.mjs +1 -1
  163. package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs +1 -1
  164. package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs +1 -1
  165. package/.output/server/chunks/routes/api/system/monitor.get.mjs +1 -1
  166. package/.output/server/chunks/routes/api/system/settings/events.get.mjs +1 -1
  167. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs +1 -1
  168. package/.output/server/chunks/routes/api/users/_id_.delete.mjs +1 -1
  169. package/.output/server/chunks/routes/api/users/_id_.get.mjs +1 -1
  170. package/.output/server/chunks/routes/api/users/_id_.put.mjs +1 -1
  171. package/.output/server/chunks/routes/api/users/index.get.mjs +1 -1
  172. package/.output/server/chunks/routes/api/users/index.post.mjs +1 -1
  173. package/.output/server/chunks/routes/api/users/login.post.mjs +1 -1
  174. package/.output/server/chunks/routes/api/users/logout.post.mjs +1 -1
  175. package/.output/server/chunks/routes/api/users/me.get.mjs +1 -1
  176. package/.output/server/chunks/routes/api/users/register.post.mjs +1 -1
  177. package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs +1 -1
  178. package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs +1 -1
  179. package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs +1 -1
  180. package/.output/server/chunks/routes/api/workshop/_...path_.mjs +1 -1
  181. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs +1 -1
  182. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs +1 -1
  183. package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs +1 -1
  184. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +1 -1
  185. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs +1 -1
  186. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +1 -1
  187. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +1 -1
  188. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +1 -1
  189. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +1 -1
  190. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +6 -14
  191. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
  192. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs +39 -0
  193. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs.map +1 -0
  194. package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs +1 -1
  195. package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs +1 -1
  196. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +1 -1
  197. package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs +1 -1
  198. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +1 -1
  199. package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs +1 -1
  200. package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs +1 -1
  201. package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs +1 -1
  202. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +2 -2
  203. package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs +1 -1
  204. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +2 -2
  205. package/.output/server/chunks/routes/api/workshop/audit.get.mjs +1 -1
  206. package/.output/server/chunks/routes/api/workshop/caller.mjs +1 -1
  207. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +2 -2
  208. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs +1 -1
  209. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs +1 -1
  210. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +1 -1
  211. package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs +1 -1
  212. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +2 -2
  213. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs +1 -1
  214. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs +1 -1
  215. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs +1 -1
  216. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs +1 -1
  217. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs +1 -1
  218. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs +1 -1
  219. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs +1 -1
  220. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs +1 -1
  221. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs +1 -1
  222. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +1 -1
  223. package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs +1 -1
  224. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +1 -1
  225. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +2 -2
  226. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs +1 -1
  227. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs +1 -1
  228. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.mjs +1 -1
  229. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
  230. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +1 -1
  231. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
  232. package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs +1 -1
  233. package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs +1 -1
  234. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +2 -2
  235. package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs +1 -1
  236. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +2 -2
  237. package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs +9 -2
  238. package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs.map +1 -1
  239. package/.output/server/chunks/routes/api/workshop/channels.get.mjs +1 -1
  240. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +2 -2
  241. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +2 -2
  242. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +2 -2
  243. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +2 -2
  244. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +6 -4
  245. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs.map +1 -1
  246. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +2 -2
  247. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +2 -2
  248. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +2 -2
  249. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +2 -2
  250. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +2 -2
  251. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +2 -2
  252. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +2 -2
  253. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +2 -2
  254. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +2 -2
  255. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +2 -2
  256. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +2 -2
  257. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +2 -2
  258. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +2 -2
  259. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +2 -2
  260. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +2 -2
  261. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +2 -2
  262. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +2 -2
  263. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +2 -2
  264. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +2 -2
  265. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +2 -2
  266. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +2 -2
  267. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +2 -2
  268. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +2 -2
  269. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +2 -2
  270. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +2 -2
  271. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +2 -2
  272. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +2 -2
  273. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +2 -2
  274. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +2 -2
  275. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +2 -2
  276. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +2 -2
  277. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +2 -2
  278. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +2 -2
  279. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +2 -2
  280. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs +2 -2
  281. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +2 -2
  282. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +2 -2
  283. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +2 -2
  284. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +2 -2
  285. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +2 -2
  286. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +2 -2
  287. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +2 -2
  288. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +2 -2
  289. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +2 -2
  290. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +2 -2
  291. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.patch.mjs +2 -2
  292. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +2 -2
  293. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +2 -2
  294. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +2 -2
  295. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +2 -2
  296. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +2 -2
  297. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +2 -2
  298. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +1 -1
  299. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +1 -1
  300. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +2 -2
  301. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +2 -2
  302. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +1 -1
  303. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +247 -0
  304. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs.map +1 -0
  305. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +27 -0
  306. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs.map +1 -0
  307. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  308. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +19 -7
  309. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs.map +1 -1
  310. package/.output/server/chunks/routes/api/workshop/index.get.mjs +1 -1
  311. package/.output/server/chunks/routes/api/workshop/index.post.mjs +1 -1
  312. package/.output/server/chunks/routes/api/workshop/index10.get.mjs +1 -1
  313. package/.output/server/chunks/routes/api/workshop/index2.get.mjs +1 -1
  314. package/.output/server/chunks/routes/api/workshop/index2.post.mjs +1 -1
  315. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +1 -1
  316. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +2 -2
  317. package/.output/server/chunks/routes/api/workshop/index4.get.mjs +2 -2
  318. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +2 -2
  319. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +2 -2
  320. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +2 -2
  321. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +1 -1
  322. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +2 -2
  323. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +1 -1
  324. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +1 -1
  325. package/.output/server/chunks/routes/api/workshop/index8.get.mjs +1 -1
  326. package/.output/server/chunks/routes/api/workshop/index8.post.mjs +1 -1
  327. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +1 -1
  328. package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs +1 -1
  329. package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs +1 -1
  330. package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs +1 -1
  331. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  332. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  333. package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs +1 -1
  334. package/.output/server/chunks/routes/api/workshop/runtime.get.mjs +1 -1
  335. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  336. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  337. package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs +1 -1
  338. package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs +1 -1
  339. package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs +1 -1
  340. package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs +1 -1
  341. package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs +1 -1
  342. package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs +1 -1
  343. package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs +1 -1
  344. package/.output/server/chunks/routes/api/workshop/tasks.get.mjs +1 -1
  345. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +2 -2
  346. package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs +1 -1
  347. package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs +1 -1
  348. package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs +1 -1
  349. package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs +1 -1
  350. package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs +1 -1
  351. package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs +1 -1
  352. package/.output/server/chunks/routes/api/workshop/users/me.get.mjs +1 -1
  353. package/.output/server/chunks/routes/api/workshop/users/register.post.mjs +1 -1
  354. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -2
  355. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs +1 -1
  356. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs +1 -1
  357. package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs +1 -1
  358. package/.output/server/chunks/routes/renderer.mjs +1 -1
  359. package/.output/server/chunks/virtual/entry.mjs +123 -113
  360. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  361. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  362. package/.output/server/index.mjs +1 -1
  363. package/.output/server/package.json +1 -1
  364. package/app/components/AppHeader.vue +56 -2
  365. package/app/components/workshop/ChannelSessionList.vue +703 -593
  366. package/app/components/workshop/terminal/OmpTerminalPanel.vue +2 -1
  367. package/app/composables/workshop/useLocalTime.ts +16 -0
  368. package/app/composables/workshop/useSceneLayouts.ts +2 -1
  369. package/app/composables/workshop/useWorkshopApi.ts +249 -224
  370. package/app/pages/daq/[id].vue +7 -6
  371. package/app/pages/daq/index.vue +2 -2
  372. package/app/pages/dcw/[id].vue +3 -3
  373. package/app/pages/workshop/agents.vue +432 -382
  374. package/bin/aw.mjs +0 -0
  375. package/cli/aw.mjs +8 -1
  376. package/cli/commands/stop.mjs +7 -4
  377. package/cli/commands/tui.mjs +10 -1
  378. package/cli/core/registry.mjs +5 -3
  379. package/config.yml +134 -134
  380. package/docs/tui.md +1 -1
  381. package/i18n/locales/en.ts +5 -0
  382. package/i18n/locales/zh-CN.ts +5 -0
  383. package/package.json +148 -140
  384. package/scripts/_dbg-catalog-smoke.ts +20 -0
  385. package/scripts/_dbg-codex-probe.mjs +58 -0
  386. package/scripts/_dbg-dsh-probe.mjs +31 -0
  387. package/scripts/_dbg-interval-scenario.mjs +126 -0
  388. package/scripts/_dbg-line-spawn.ts +31 -0
  389. package/scripts/_dbg-live-engine-probe.mjs +80 -0
  390. package/scripts/_dbg-mcp-bridge-probe.mjs +147 -0
  391. package/scripts/_dbg-opencode-sse.mjs +101 -0
  392. package/scripts/_dbg-opencode-start.ts +57 -0
  393. package/scripts/_dbg-plugin-matrix.mjs +212 -0
  394. package/scripts/_dbg-protocol-matrix.mjs +425 -0
  395. package/scripts/_dbg-real-scenario-timeline.log +123 -0
  396. package/scripts/_dbg-registry-smoke.ts +14 -0
  397. package/scripts/_dbg-sim-keeper.mjs +100 -0
  398. package/scripts/_dbg-team-drill.mjs +173 -0
  399. package/scripts/dev-guard.mjs +11 -3
  400. package/scripts/dev-protocol-simulators.mjs +28 -1
  401. package/scripts/e2e-multi-harness.ts +374 -0
  402. package/scripts/e2e-multiharness-team.mjs +319 -0
  403. package/scripts/e2e-plc-scenario.mjs +292 -0
  404. package/scripts/e2e-real-scenario.mjs +452 -0
  405. package/scripts/migrate-local-time.mjs +123 -0
  406. package/scripts/start.mjs +30 -2
  407. package/server/api/system/settings/index.get.ts +3 -3
  408. package/server/api/workshop/agent-tools/invoke.post.ts +27 -41
  409. package/server/api/workshop/agent-tools/list.get.ts +25 -0
  410. package/server/api/workshop/channels/[id]/index.patch.ts +38 -30
  411. package/server/api/workshop/daq/[id]/samples.get.ts +6 -3
  412. package/server/api/workshop/harnesses/[id]/providers.get.ts +16 -0
  413. package/server/api/workshop/harnesses.get.ts +12 -0
  414. package/server/api/workshop/hitl/respond.post.ts +87 -67
  415. package/server/api/workshop/ws.ts +13 -0
  416. package/server/data/daqs.json +1366 -16
  417. package/server/data/dcw-lines.json +266 -0
  418. package/server/data/dcw-products.json +203 -0
  419. package/server/data/dcw-recipes.json +784 -0
  420. package/server/data/dcw-rollback.json +1144 -1
  421. package/server/data/dcw-runs.json +983 -791
  422. package/server/data/dcw-writes.json +1080 -0
  423. package/server/data/dcws.json +3278 -203
  424. package/server/data/line-runs.json +52 -2
  425. package/server/harness/aw-mcp-bridge.mjs +153 -0
  426. package/server/plugins/00-local-time.ts +10 -0
  427. package/server/plugins/aw-plugins.ts +3 -0
  428. package/server/plugins/backup.ts +116 -97
  429. package/server/plugins/dev-stability-guard.ts +24 -15
  430. package/server/plugins/retention.ts +1 -0
  431. package/server/plugins/security.ts +24 -3
  432. package/server/plugins/workshop.ts +156 -153
  433. package/server/repositories/user.repository.ts +414 -391
  434. package/server/services/system-config.ts +30 -6
  435. package/server/services/workshop/.mimosa/hook-state/sess_fed429fb-c8b7-4a50-bbd6-45afc580893f.json +1 -0
  436. package/server/services/workshop/.mimosa/hook-status/sess_fed429fb-c8b7-4a50-bbd6-45afc580893f-e6b75bbfe6.json +14 -0
  437. package/server/services/workshop/agents/adapters/line-spawn.ts +108 -0
  438. package/server/services/workshop/agents/adapters/stdio-jsonrpc.ts +316 -0
  439. package/server/services/workshop/agents/agent-interface.ts +17 -0
  440. package/server/services/workshop/agents/codex-agent.ts +822 -0
  441. package/server/services/workshop/agents/dsh-agent.ts +670 -0
  442. package/server/services/workshop/agents/factory.ts +4 -16
  443. package/server/services/workshop/agents/harness-env.ts +54 -0
  444. package/server/services/workshop/agents/harness-models.ts +270 -0
  445. package/server/services/workshop/agents/host-tool-bridge.ts +592 -0
  446. package/server/services/workshop/agents/industrial-tools.ts +5 -1
  447. package/server/services/workshop/agents/node-bindings.repo.ts +4 -5
  448. package/server/services/workshop/agents/omp-agent.ts +1178 -1957
  449. package/server/services/workshop/agents/opencode-agent.ts +987 -0
  450. package/server/services/workshop/agents/prompt-builder.ts +393 -0
  451. package/server/services/workshop/agents/registry.ts +125 -0
  452. package/server/services/workshop/assets/character-asset.repo.ts +3 -5
  453. package/server/services/workshop/assets/device-twin.repo.ts +3 -5
  454. package/server/services/workshop/daq/daq-controller.ts +8 -4
  455. package/server/services/workshop/daq/daq-node.repo.ts +3 -5
  456. package/server/services/workshop/daq/daq-node.ts +2 -2
  457. package/server/services/workshop/daq/daq-templates.ts +3 -5
  458. package/server/services/workshop/daq/drivers.ts +41 -12
  459. package/server/services/workshop/daq/storage/sqlite.adapter.ts +313 -309
  460. package/server/services/workshop/db/backup-registry.ts +33 -0
  461. package/server/services/workshop/db/channel.repo.ts +104 -101
  462. package/server/services/workshop/db/database.ts +956 -949
  463. package/server/services/workshop/dcw/dcw-controller.ts +3 -1
  464. package/server/services/workshop/dcw/dcw-line.repo.ts +4 -11
  465. package/server/services/workshop/dcw/dcw-node.repo.ts +3 -5
  466. package/server/services/workshop/dcw/dcw-node.ts +13 -1
  467. package/server/services/workshop/dcw/dcw-product.repo.ts +3 -4
  468. package/server/services/workshop/dcw/dcw-recipe.repo.ts +3 -19
  469. package/server/services/workshop/dcw/dcw-templates.ts +3 -5
  470. package/server/services/workshop/dcw/drivers.ts +37 -13
  471. package/server/services/workshop/dcw/line-run.ts +3 -5
  472. package/server/services/workshop/dcw/recipe-rollback.repo.ts +4 -10
  473. package/server/services/workshop/json-store.mjs +72 -0
  474. package/server/services/workshop/plugins/host.mjs +2 -1
  475. package/server/services/workshop/runtime/agent-runtime.ts +44 -0
  476. package/server/services/workshop/runtime/manager.ts +2953 -2868
  477. package/server/services/workshop/scene/scene-layout.repo.ts +4 -11
  478. package/server/services/workshop/settings.ts +7 -0
  479. package/shared/config/schema.json +5 -0
  480. package/shared/config/single-instance.mjs +5 -1
  481. package/shared/local-time.mjs +36 -0
  482. package/shared/workshop-protocol.ts +11 -5
  483. package/tui/aw-tui.mjs +28 -10
  484. package/tui/components/hitl-card.mjs +47 -36
  485. package/tui/lib/ws.mjs +2 -1
  486. package/.output/public/_nuxt/9X0fVBD7.js +0 -57
  487. package/.output/public/_nuxt/B6M2WJWm2.js +0 -1
  488. package/.output/public/_nuxt/B9Yie5HN.js +0 -2
  489. package/.output/public/_nuxt/BF9XPEuw.js +0 -1
  490. package/.output/public/_nuxt/BbQornXa.js +0 -1
  491. package/.output/public/_nuxt/Bxgaym6j.js +0 -1
  492. package/.output/public/_nuxt/Bxh5nf8j.js +0 -1
  493. package/.output/public/_nuxt/CXLI50Sq.js +0 -1
  494. package/.output/public/_nuxt/CdfAP_IH2.js +0 -1
  495. package/.output/public/_nuxt/Ce1zyNYu.js +0 -1
  496. package/.output/public/_nuxt/D-Ne4C9a.js +0 -1
  497. package/.output/public/_nuxt/DEHNjlTq2.js +0 -1
  498. package/.output/public/_nuxt/DFnGFEav.js +0 -18
  499. package/.output/public/_nuxt/DYWgGHNo.js +0 -7
  500. package/.output/public/_nuxt/OmpTerminalPanel.Bc9GjNU5.css +0 -1
  501. package/.output/public/_nuxt/W1E3-5ML.js +0 -14
  502. package/.output/public/_nuxt/XVB9_zwP.js +0 -1
  503. package/.output/public/_nuxt/Xaf_HIR3.js +0 -1
  504. package/.output/public/_nuxt/_id_.BeqSLvl_.css +0 -1
  505. package/.output/public/_nuxt/_id_.DN3U6EF9.css +0 -1
  506. package/.output/public/_nuxt/agents.BJwgTLFZ.css +0 -1
  507. package/.output/public/_nuxt/builds/meta/55c10854-ee0e-4be4-924b-a1b0e100fe11.json +0 -1
  508. package/.output/public/_nuxt/daq.BXsnevQv.css +0 -1
  509. package/.output/public/_nuxt/yIKY_V1P.js +0 -1
  510. package/.output/server/chunks/build/OmpTerminalPanel-B_SYhmgb.mjs.map +0 -1
  511. package/.output/server/chunks/build/_id_-CWLFGZjV.mjs.map +0 -1
  512. package/.output/server/chunks/build/agents-D4l1icvn.mjs.map +0 -1
  513. package/.output/server/chunks/build/channel-templates-DqjtC-R0.mjs.map +0 -1
  514. package/.output/server/chunks/build/interval-WlxgjTzO.mjs +0 -9
  515. package/.output/server/chunks/build/interval-WlxgjTzO.mjs.map +0 -1
  516. package/.output/server/chunks/build/teams-QR3BBF7A.mjs.map +0 -1
  517. package/.output/server/chunks/build/useWorkshopApi-Bh5VUHWu.mjs.map +0 -1
@@ -0,0 +1,452 @@
1
+ /**
2
+ * 多 Harness 真实场景端到端(针对真实运行中的 AgentWorkShop 服务)。
3
+ *
4
+ * 前置:服务已启动(pnpm dev / npm start),且服务进程 PATH 上有 omp/codex/dsh。
5
+ * 运行:node scripts/e2e-real-scenario.mjs [--base http://127.0.0.1:3000]
6
+ *
7
+ * 场景:
8
+ * 0. 注册测试用户 + WS 事件监控(全程录制 AEP 帧)+ REST 事件历史轮询(权威记录)
9
+ * 1. 产线:新建产线 + DCW 温控节点(mock)+ DAQ 温度采集节点(mock)
10
+ * 2. 班组:AgentChannel(lead=omp)+ worker-codex + worker-dsh,绑定工业节点
11
+ * (dsh↔DCW manual / dsh↔DAQ auto / codex↔DCW manual)
12
+ * 3. 兼容性对话:人类→codex、人类→dsh(要求回执);codex 经工具跨引擎发信 dsh
13
+ * 4. 团队作业:goal 任务 → lead 派发 → dsh 数采(daq_query)→ 数控写入(dcw_control
14
+ * 触发 dcw-approval HITL)→ 测试员批准 → 写入生效 → 复读确认 → 任务闭环
15
+ * 5. HITL 超时:再次写入,故意不批准 → 等满 security.hitl_timeout_ms →
16
+ * 自动按拒绝收敛(expired)→ worker 收到拒绝结果并汇报
17
+ */
18
+ const BASE = process.env.AW_BASE ?? 'http://127.0.0.1:3000'
19
+ const WS_BASE = BASE.replace(/^http/, 'ws')
20
+
21
+ let failures = 0
22
+ let passed = 0
23
+ const timeline = []
24
+
25
+ const ts = () => new Date().toISOString().slice(11, 23)
26
+ const log = (line) => {
27
+ console.log(`[${ts()}] ${line}`)
28
+ timeline.push(`[${ts()}] ${line}`)
29
+ }
30
+ const check = (name, ok, detail = '') => {
31
+ const tag = ok ? 'PASS' : 'FAIL'
32
+ log(` ${tag} ${name}${detail ? ` — ${detail}` : ''}`)
33
+ if (ok) {
34
+ passed += 1
35
+ }
36
+ else {
37
+ failures += 1
38
+ }
39
+ return ok
40
+ }
41
+ const sleep = ms => new Promise(r => setTimeout(r, ms))
42
+
43
+ // ---------- 用户与 API ----------
44
+ const reg = await fetch(`${BASE}/api/workshop/users/register`, {
45
+ method: 'POST', headers: { 'content-type': 'application/json' },
46
+ body: JSON.stringify({ name: 'live-scen-' + Math.random().toString(36).slice(2, 8) }),
47
+ }).then(r => r.json()).catch(() => null)
48
+ const TOKEN = reg?.data?.token
49
+ if (!TOKEN) {
50
+ console.error('用户注册失败 — 服务未启动或接口不可用:', JSON.stringify(reg))
51
+ process.exit(1)
52
+ }
53
+ log(`测试用户已注册(token=${TOKEN.slice(0, 8)}…)BASE=${BASE}`)
54
+
55
+ async function api(method, path, body) {
56
+ const res = await fetch(`${BASE}${path}`, {
57
+ method,
58
+ headers: { 'content-type': 'application/json', 'authorization': `Bearer ${TOKEN}` },
59
+ body: body !== undefined ? JSON.stringify(body) : undefined,
60
+ })
61
+ const json = await res.json().catch(() => ({}))
62
+ return { status: res.status, ...json }
63
+ }
64
+
65
+ /** 回执判定:平台代投/模型回执(in_reply_to 帧)或时间线产物含预期文本(兜底) */
66
+ function matchReply(frames, from, mid, textPattern) {
67
+ return frames.find(f => f.type === 'a2a.message' && f.payload?.metadata?.['x-aw-in-reply-to'] === mid)
68
+ ?? frames.find(f => (f.type === 'a2a.artifact' || f.type === 'agent.status.message')
69
+ && textPattern.test(JSON.stringify(f.payload ?? ''))) ?? null
70
+ }
71
+
72
+ async function waitUntil(name, cond, timeoutMs, intervalMs = 1000) {
73
+ const deadline = Date.now() + timeoutMs
74
+ let last = null
75
+ while (Date.now() < deadline) {
76
+ try {
77
+ last = await cond()
78
+ }
79
+ catch (e) {
80
+ last = e
81
+ }
82
+ if (last) return last
83
+ await sleep(intervalMs)
84
+ }
85
+ return last ?? null
86
+ }
87
+
88
+ // ---------- 事件监控:REST 历史轮询(权威)+ WS 实时 ----------
89
+ const eventFrames = []
90
+ let lastSeq = 0
91
+ let wsSeen = 0
92
+
93
+ async function pollEvents(channelId) {
94
+ const res = await api('GET', `/api/workshop/channels/${channelId}/events?limit=500`)
95
+ const list = res?.data?.items ?? []
96
+ for (const f of list) {
97
+ const seq = Number(f.seq ?? 0)
98
+ if (seq > lastSeq) {
99
+ lastSeq = seq
100
+ eventFrames.push(f)
101
+ const t = f.type
102
+ if (['hitl.request', 'hitl.resolved', 'task.status', 'a2a.message', 'a2a.artifact', 'error'].includes(t)) {
103
+ const p = f.payload ?? {}
104
+ const brief = t === 'a2a.message'
105
+ ? `${p.fromAgentId ?? p.from ?? '?'}→${p.toAgentId ?? p.to ?? '?'}: ${(p.parts ?? []).map(x => x.text ?? '').join(' ').slice(0, 110)}`
106
+ : t === 'hitl.request'
107
+ ? `${p.kind}:${p.title ?? ''}`
108
+ : t === 'hitl.resolved'
109
+ ? `${p.kind} outcome=${p.outcome}`
110
+ : t === 'task.status'
111
+ ? `${(p.title ?? '').slice(0, 40)} → ${p.state}`
112
+ : t === 'a2a.artifact'
113
+ ? `artifact(${p.artifact?.name ?? '?'})`
114
+ : JSON.stringify(p).slice(0, 120)
115
+ log(` [事件] #${seq} ${t} ${brief}`)
116
+ }
117
+ }
118
+ }
119
+ }
120
+
121
+ function startPolling(channelId) {
122
+ const timer = setInterval(() => {
123
+ void pollEvents(channelId).catch(() => {})
124
+ }, 2000)
125
+ return () => clearInterval(timer)
126
+ }
127
+
128
+ async function startWs(channelId) {
129
+ try {
130
+ const { createRequire } = await import('node:module')
131
+ const req = createRequire(import.meta.url)
132
+ let WebSocket = null
133
+ try {
134
+ WebSocket = req('D:/codes/ABO/AgentWorkShop/node_modules/.pnpm/ws@8.21.3/node_modules/ws')
135
+ }
136
+ catch (e) {
137
+ log(`ws 模块加载失败: ${e.message}`)
138
+ }
139
+ if (!WebSocket) {
140
+ log('WS 客户端不可用,仅用 REST 轮询监控')
141
+ return () => {}
142
+ }
143
+ const ws = new WebSocket(`${WS_BASE}/api/workshop/ws`)
144
+ ws.on('open', () => {
145
+ ws.send(JSON.stringify({ type: 'sub', channelId, token: TOKEN }))
146
+ log('WS 监控已接入(AEP 实时帧)')
147
+ })
148
+ ws.on('message', (raw) => {
149
+ wsSeen++
150
+ try {
151
+ const f = JSON.parse(String(raw))
152
+ if (f.type === 'hitl.request') log(` [WS/hitl.request] ${f.payload?.kind}: ${f.payload?.title ?? ''}`)
153
+ if (f.type === 'hitl.resolved') log(` [WS/hitl.resolved] ${f.payload?.kind} outcome=${f.payload?.outcome}`)
154
+ }
155
+ catch { /* 忽略 */ }
156
+ })
157
+ ws.on('error', e => log(`WS 错误(不影响 REST 权威记录): ${e.message}`))
158
+ return () => {
159
+ try {
160
+ ws.close()
161
+ }
162
+ catch { /* ignore */ }
163
+ }
164
+ }
165
+ catch (e) {
166
+ log(`WS 初始化失败(仅 REST 轮询): ${e.message}`)
167
+ return () => {}
168
+ }
169
+ }
170
+
171
+ // ---------- 工具调用(REST 直调,用于验证/准备;worker 侧走 MCP 桥) ----------
172
+ async function invokeTool(agentId, tool, args) {
173
+ return await api('POST', '/api/workshop/agent-tools/invoke', { agentId, tool, args })
174
+ }
175
+
176
+ /**
177
+ * 确保 worker-dsh 在组(lead 可能自主移除成员——实测发生过):不在则重建并重绑工业节点。
178
+ * 返回当前可用的 dsh 实例 id。
179
+ */
180
+ async function ensureDshWorker() {
181
+ const members = await api('GET', `/api/workshop/channels/${channelId}/agents`)
182
+ const live = (members?.data ?? []).find(m => m.name === 'worker-dsh' && m.enabled !== 0)
183
+ if (live) return live.id
184
+ log(' [自愈] worker-dsh 已不在组(被 lead 移除?)→ 重建并重绑工业节点')
185
+ const w = await createWorker('worker-dsh', 'dsh', { promptTimeoutMs: 600_000 })
186
+ if (!w.agentId) throw new Error(`重建 worker-dsh 失败: ${w.err}`)
187
+ await api('POST', '/api/workshop/agent-tools/bindings', { agentId: w.agentId, nodeId: dcwNodeId, kind: 'dcw', mode: 'manual' })
188
+ await api('POST', '/api/workshop/agent-tools/bindings', { agentId: w.agentId, nodeId: daqNodeId, kind: 'daq', mode: 'auto' })
189
+ await sleep(1500)
190
+ return w.agentId
191
+ }
192
+
193
+ // ============================================================
194
+ console.log('\n━━━ 0. 服务连通性 ━━━')
195
+ const harnesses = await api('GET', '/api/workshop/harnesses')
196
+ const hIds = (harnesses?.data?.harnesses ?? []).map(h => h.id)
197
+ check('服务可达且为多引擎版本(注册表含 codex/dsh/opencode)', hIds.includes('codex') && hIds.includes('dsh') && hIds.includes('opencode'), `harnesses=${hIds.join(',')}`)
198
+
199
+ // ============================================================
200
+ console.log('\n━━━ 1. 产线与工业节点 ━━━')
201
+ const line = await api('POST', '/api/workshop/dcw/lines', { name: '多引擎联调线' })
202
+ const lineId = line?.data?.line?.id
203
+ check('新建产线', !!lineId, `line=${line?.data?.line?.name ?? JSON.stringify(line).slice(0, 80)}`)
204
+
205
+ const dcwNode = await api('POST', '/api/workshop/dcw', {
206
+ templateRef: 'dcw-temp-sp', name: '联调温度设定器', driver: 'mock', lineId,
207
+ readIntervalMs: 2000, unit: '℃', min: 150, max: 200,
208
+ })
209
+ const dcwNodeId = dcwNode?.data?.node?.id
210
+ check('新建 DCW 数控节点(mock 温控)', !!dcwNodeId, `id=${dcwNodeId}`)
211
+
212
+ const daqNode = await api('POST', '/api/workshop/daq', {
213
+ templateRef: 'daq-temp-tc', name: '联调温度采集', driver: 'mock', lineId,
214
+ intervalMs: 1000,
215
+ })
216
+ const daqNodeId = daqNode?.data?.node?.id
217
+ check('新建 DAQ 数采节点(mock 温度)', !!daqNodeId, `id=${daqNodeId} driver=${daqNode?.data?.node?.driver}`)
218
+
219
+ // ============================================================
220
+ console.log('\n━━━ 2. 班组(多引擎 AgentChannel)━━━')
221
+ const ch = await api('POST', '/api/workshop/channels', {
222
+ name: '多引擎联调-产线班组',
223
+ scenarioPrompt: '多引擎兼容性联调班组:成员来自不同 Agent Harness(omp/codex/dsh),协作完成产线数采与数控写入。所有写入必须走审批流程,如实汇报执行结果。',
224
+ leadAgent: { name: 'lead-omp', harness: 'omp', config: { provider: 'zhipu-coding-plan', model: 'glm-5.2' } },
225
+ })
226
+ const channelId = ch?.data?.channelId
227
+ check('创建 AgentChannel(lead=omp)', !!channelId, `channelId=${channelId}`)
228
+
229
+ async function createWorker(name, harness, config) {
230
+ // 一步创建(新建模板并克隆):响应即 channel 内实例(独立 id,后续绑定/调用一律用实例 id)
231
+ const add = await api('POST', `/api/workshop/channels/${channelId}/agents`, { name, harness, role: 'worker', config })
232
+ const agentId = add?.data?.id
233
+ if (!agentId) return { agentId: null, err: JSON.stringify(add).slice(0, 200) }
234
+ return { agentId, err: null }
235
+ }
236
+
237
+ const codex = await createWorker('worker-codex', 'codex', {
238
+ approvalPolicy: 'on-request', sandbox: 'workspace-write', promptTimeoutMs: 600_000,
239
+ systemPromptPrefix: '执行要直接:按任务指令调用平台工具并汇报,不探索文件系统。',
240
+ })
241
+ check('创建 worker-codex 并入组(harness=codex)', !!codex.agentId, codex.err ?? codex.agentId)
242
+ const dsh = await createWorker('worker-dsh', 'dsh', { promptTimeoutMs: 600_000 })
243
+ check('创建 worker-dsh 并入组(harness=dsh)', !!dsh.agentId, dsh.err ?? dsh.agentId)
244
+
245
+ if (!channelId || !codex.agentId || !dsh.agentId || !dcwNodeId || !daqNodeId) {
246
+ log('前置实体创建失败,中止场景')
247
+ console.log(`FAILURES=${failures} PASSED=${passed}`)
248
+ process.exit(1)
249
+ }
250
+
251
+ const stopPoll = startPolling(channelId)
252
+ const stopWs = await startWs(channelId)
253
+ await sleep(2500)
254
+ await pollEvents(channelId)
255
+
256
+ // ---------- 绑定工业节点 ----------
257
+ const b1 = await api('POST', '/api/workshop/agent-tools/bindings', { agentId: dsh.agentId, nodeId: dcwNodeId, kind: 'dcw', mode: 'manual' })
258
+ check('绑定 dsh↔DCW(manual,HITL 模式)', !!b1?.data?.binding?.id, `mode=${b1?.data?.binding?.mode}`)
259
+ const b2 = await api('POST', '/api/workshop/agent-tools/bindings', { agentId: dsh.agentId, nodeId: daqNodeId, kind: 'daq', mode: 'auto' })
260
+ check('绑定 dsh↔DAQ(auto,数采)', !!b2?.data?.binding?.id)
261
+ const b3 = await api('POST', '/api/workshop/agent-tools/bindings', { agentId: codex.agentId, nodeId: dcwNodeId, kind: 'dcw', mode: 'manual' })
262
+ check('绑定 codex↔DCW(manual)', !!b3?.data?.binding?.id)
263
+
264
+ // dsh 引擎侧工具可见性验证(my_industrial_nodes 直调;worker 实际经 MCP 桥)
265
+ const mine = await invokeTool(dsh.agentId, 'my_industrial_nodes', {})
266
+ check('dsh 工具面可见绑定节点(my_industrial_nodes)', /温度设定器|联调温度/.test(String(mine?.data?.result?.text ?? '')), String(mine?.data?.result?.text ?? '').replace(/\n/g, ' ').slice(0, 120))
267
+
268
+ // ============================================================
269
+ console.log('\n━━━ 3. 兼容性对话(三通道)━━━')
270
+ const seq0 = lastSeq
271
+
272
+ // 3a. 人类 → codex(要求回执)
273
+ const m1 = await api('POST', `/api/workshop/channels/${channelId}/messages`, {
274
+ toAgentId: codex.agentId, fromLabel: '测试员', requireReply: true, priority: 'task',
275
+ text: '兼容性检查:请用一句话汇报你正在运行的引擎类型(如 codex),然后调用 report_progress 工具上报 10% 进度(无任务上下文则忽略报错),最后原样回复"codex 在线"。',
276
+ })
277
+ check('人类→codex 消息已投递', m1.status === 200 || !!m1?.data?.messageId, `status=${m1.status}`)
278
+
279
+ const codexReply = await waitUntil('codex 回执', async () => {
280
+ await pollEvents(channelId)
281
+ return matchReply(eventFrames.slice(seq0), codex.agentId, m1?.data?.messageId ?? m1?.messageId, /codex 在线/)
282
+ }, 240_000)
283
+ check('codex 回执到达(真实引擎回合)', !!codexReply,
284
+ codexReply ? `内容=${(codexReply.payload?.parts ?? []).map(x => x.text ?? '').join('').slice(0, 80)}` : '240s 未回')
285
+
286
+ // 3b. 人类 → dsh(要求回执)
287
+ const seqA = lastSeq
288
+ const m2 = await api('POST', `/api/workshop/channels/${channelId}/messages`, {
289
+ toAgentId: dsh.agentId, fromLabel: '测试员', requireReply: true, priority: 'task',
290
+ text: '兼容性检查:请用一句话汇报你正在运行的引擎类型(如 dsh/ACP),然后原样回复"dsh 在线"。',
291
+ })
292
+ check('人类→dsh 消息已投递', m2.status === 200 || !!m2?.data?.messageId, `status=${m2.status}`)
293
+ const dshReply = await waitUntil('dsh 回执', async () => {
294
+ await pollEvents(channelId)
295
+ return matchReply(eventFrames.slice(seqA), dsh.agentId, m2?.data?.messageId ?? m2?.messageId, /dsh 在线/)
296
+ }, 240_000)
297
+ check('dsh 回执到达(真实引擎回合)', !!dshReply,
298
+ dshReply ? `内容=${(dshReply.payload?.parts ?? []).map(x => x.text ?? '').join('').slice(0, 80)}` : '240s 未回')
299
+
300
+ // 3c. codex →(工具)→ dsh 跨引擎发信
301
+ const seqB = lastSeq
302
+ const m3 = await api('POST', `/api/workshop/channels/${channelId}/messages`, {
303
+ toAgentId: codex.agentId, fromLabel: '测试员', requireReply: true, priority: 'task',
304
+ text: '请使用 send_message_to_agent 工具向同事 worker-dsh 发送一句话:"跨引擎测试:请回复你的引擎类型",并设置 require_reply=true;发送完成后回复我"已发送"。',
305
+ })
306
+ check('人类→codex(要求跨引擎发信)已投递', m3.status === 200 || !!m3?.data?.messageId, `status=${m3.status}`)
307
+ const crossReply = await waitUntil('跨引擎回执', async () => {
308
+ await pollEvents(channelId)
309
+ return matchReply(eventFrames.slice(seqB), codex.agentId, m3?.data?.messageId ?? m3?.messageId, /已发送|发送完/)
310
+ }, 240_000)
311
+ check('codex 经工具跨引擎发信完成', !!crossReply,
312
+ crossReply ? `内容=${(crossReply.payload?.parts ?? []).map(x => x.text ?? '').join('').slice(0, 80)}` : '240s 未回')
313
+ const dshGotCross = await waitUntil('dsh 收到跨引擎消息', async () => {
314
+ await pollEvents(channelId)
315
+ return eventFrames.slice(seqB).find(f => f.type === 'a2a.message'
316
+ && String(f.payload?.metadata?.['x-aw-from-agent'] ?? '') === codex.agentId
317
+ && f.payload?.toAgentId === dsh.agentId)
318
+ }, 120_000)
319
+ check('dsh 侧收到 codex 来信', !!dshGotCross)
320
+
321
+ // ============================================================
322
+ console.log('\n━━━ 4. 团队作业:数采 → 数控写入(HITL 确认)→ 复读 ━━━')
323
+ dsh.agentId = await ensureDshWorker()
324
+ const task = await api('POST', `/api/workshop/channels/${channelId}/tasks`, {
325
+ title: '温度工艺整定(数采+数控)',
326
+ mode: 'goal',
327
+ description: [
328
+ '班组作业目标:完成一次温度设定整定并留痕。',
329
+ '1. 让 worker-dsh 用 daq_query 工具查询其绑定的温度采集节点最近 5 分钟数据,并向你汇报均值;',
330
+ '2. 让 worker-dsh 用 dcw_control 工具将其绑定的「联调温度设定器」写入 175.0(该写入走人工审批:若平台弹出审批请求,等待测试员批准后再继续;不要绕过审批);',
331
+ '3. 写入成功后让 worker-dsh 用 dcw_read 复读设定值并向你确认;',
332
+ '4. 全部完成后调用 complete_task 汇总结果。',
333
+ '注意:写入节点 id 以 worker 的 my_industrial_nodes 工具输出为准。',
334
+ ].join('\n'),
335
+ })
336
+ const taskId = task?.data?.id
337
+ check('团队作业(goal)已提交至 lead', !!taskId, `taskId=${taskId} state=${task?.data?.state}`)
338
+
339
+ // 等待 HITL 审批出现
340
+ const hitlAt = Date.now()
341
+ const approval = await waitUntil('dcw-approval 出现', async () => {
342
+ await pollEvents(channelId)
343
+ const pending = await api('GET', '/api/workshop/hitl/pending')
344
+ const items = pending?.data?.items ?? []
345
+ return items.find(i => i.kind === 'dcw-approval') ?? null
346
+ }, 600_000)
347
+ check('数控写入触发 dcw-approval HITL(worker-dsh)', !!approval,
348
+ approval ? `id=${approval.id} detail=${String(approval.detail ?? '').slice(0, 90)}` : '600s 内未触发(检查 worker 是否调用了 dcw_control)')
349
+ log(`审批从提交到出现耗时 ${(Date.now() - hitlAt) / 1000}s`)
350
+
351
+ if (approval) {
352
+ log('测试员批准审批(模拟用户确认)…')
353
+ const resp = await api('POST', '/api/workshop/hitl/respond', { kind: 'dcw-approval', id: approval.id, confirmed: true, comment: '场景测试批准' })
354
+ check('HITL 批准应答成功(respond 200)', resp.status === 200 || resp?.data?.ok === true, `status=${resp.status} ${JSON.stringify(resp).slice(0, 100)}`)
355
+ }
356
+
357
+ // 等待任务闭环 + 读回验证
358
+ const taskDone = await waitUntil('团队任务闭环', async () => {
359
+ await pollEvents(channelId)
360
+ const t = await api('GET', `/api/workshop/tasks/${taskId}`)
361
+ const state = t?.data?.state
362
+ if (state === 'COMPLETED' || state === 'FAILED' || state === 'CANCELED') return state
363
+ return null
364
+ }, 900_000)
365
+ check('团队任务闭环 COMPLETED', taskDone === 'COMPLETED', `state=${taskDone}`)
366
+
367
+ // 数控写入是否真实生效(平台侧直读节点)
368
+ let readBack = await invokeTool(dsh.agentId, 'dcw_read', { node_id: dcwNodeId })
369
+ let rbText = String(readBack?.data?.result?.text ?? '')
370
+ if (!rbText) {
371
+ dsh.agentId = await ensureDshWorker()
372
+ readBack = await invokeTool(dsh.agentId, 'dcw_read', { node_id: dcwNodeId })
373
+ rbText = String(readBack?.data?.result?.text ?? '')
374
+ }
375
+ check('写入生效:dcw_read 读回 175 附近', /17[4-6]/.test(rbText), rbText.replace(/\n/g, ' ').slice(0, 120))
376
+
377
+ // ============================================================
378
+ console.log('\n━━━ 5. HITL 超时路径(不批准 → 等满上限 → 自动拒绝)━━━')
379
+ dsh.agentId = await ensureDshWorker()
380
+ const seqD = lastSeq
381
+ const m4Text = '请用 dcw_control 工具将「联调温度设定器」下调至 160.0(hypothesis=超时路径验证)。该写入需要人工审批:请发起审批后耐心等待;若审批被拒绝或超时未批,请如实汇报等待与结果,不要重复发起。'
382
+ let m4 = await api('POST', `/api/workshop/channels/${channelId}/messages`, {
383
+ toAgentId: dsh.agentId, fromLabel: '测试员', requireReply: true, priority: 'task', text: m4Text,
384
+ })
385
+ if (m4.status !== 200) {
386
+ // 成员可能在上一阶段被 lead 自主移除:自愈后重发
387
+ await sleep(3000)
388
+ dsh.agentId = await ensureDshWorker()
389
+ m4 = await api('POST', `/api/workshop/channels/${channelId}/messages`, {
390
+ toAgentId: dsh.agentId, fromLabel: '测试员', requireReply: true, priority: 'task', text: m4Text,
391
+ })
392
+ }
393
+ check('超时场景消息已投递(下调 160)', m4.status === 200 || !!m4?.data?.messageId, `status=${m4.status}`)
394
+
395
+ const approval2 = await waitUntil('第二次审批出现', async () => {
396
+ await pollEvents(channelId)
397
+ const pending = await api('GET', '/api/workshop/hitl/pending')
398
+ const items = pending?.data?.items ?? []
399
+ return items.find(i => i.kind === 'dcw-approval') ?? null
400
+ }, 300_000)
401
+ check('第二次写入触发审批', !!approval2, approval2 ? `id=${approval2.id} expiresAt=${approval2.expiresAt}` : '300s 未触发')
402
+
403
+ if (approval2) {
404
+ log('测试员故意不批准 — 等待审批超时上限(security.hitl_timeout_ms,默认 180s)…')
405
+ const expiryMs = Math.max(0, Date.parse(approval2.expiresAt) - Date.now()) + 15_000
406
+ const expired = await waitUntil('审批超时自动拒绝', async () => {
407
+ await pollEvents(channelId)
408
+ return eventFrames.slice(seqD).find(f => f.type === 'hitl.resolved'
409
+ && f.payload?.id === approval2.id
410
+ && (f.payload?.outcome === 'expired' || f.payload?.outcome === 'cancelled')) ?? null
411
+ }, expiryMs + 60_000)
412
+ check('审批到上限自动收敛(expired)', !!expired,
413
+ expired ? `outcome=${expired.payload?.outcome}` : '超时窗内未观察到 resolved 帧')
414
+ const stillPending = await api('GET', '/api/workshop/hitl/pending')
415
+ const remains = (stillPending?.data?.items ?? []).filter(i => i.id === approval2.id)
416
+ check('审批从待办清单移除', remains.length === 0)
417
+
418
+ // 值未被写入(160 ≠ 当前 175)
419
+ const readBack2 = await invokeTool(dsh.agentId, 'dcw_read', { node_id: dcwNodeId })
420
+ const rb2 = String(readBack2?.data?.result?.text ?? '')
421
+ check('拒绝后值未变(仍 ~175,非 160)', /17[4-6]/.test(rb2) && !/160/.test(rb2.split('\n').find(l => /当前|设定|值/i.test(l)) ?? rb2), rb2.replace(/\n/g, ' ').slice(0, 120))
422
+
423
+ // worker 汇报(回执应说明等待/拒绝)
424
+ const workerReport = await waitUntil('worker 汇报超时结果', async () => {
425
+ await pollEvents(channelId)
426
+ return eventFrames.slice(seqD).find(f => f.type === 'a2a.message'
427
+ && f.payload?.metadata?.['x-aw-in-reply-to'] === (m4?.data?.messageId ?? m4?.messageId)) ?? null
428
+ }, 300_000)
429
+ check('worker 回执汇报超时/拒绝结果', !!workerReport,
430
+ workerReport ? `内容=${(workerReport.payload?.parts ?? []).map(x => x.text ?? '').join('').slice(0, 120)}` : '300s 未回')
431
+ }
432
+
433
+ // ============================================================
434
+ console.log('\n━━━ 6. 事件监控汇总 ━━━')
435
+ const byType = {}
436
+ for (const f of eventFrames) byType[f.type] = (byType[f.type] ?? 0) + 1
437
+ log(`REST 事件历史共 ${eventFrames.length} 帧;WS 实时收到 ${wsSeen} 帧`)
438
+ log('帧分布: ' + JSON.stringify(byType))
439
+ check('事件流覆盖关键类型(task/status/message/hitl)',
440
+ (byType['task.status'] ?? 0) > 0 && (byType['hitl.request'] ?? 0) > 0,
441
+ JSON.stringify(byType).slice(0, 160))
442
+
443
+ stopPoll()
444
+ stopWs()
445
+ try {
446
+ const { writeFileSync } = await import('node:fs')
447
+ writeFileSync('scripts/_dbg-real-scenario-timeline.log', timeline.join('\n'), 'utf-8')
448
+ }
449
+ catch { /* ignore */ }
450
+
451
+ console.log(`\n━━━ 场景结论:PASS=${passed} FAIL=${failures} ━━━`)
452
+ process.exit(failures === 0 ? 0 : 1)
@@ -0,0 +1,123 @@
1
+ /**
2
+ * 存量时间迁移:把数据库/JSON 仓库中的 UTC ISO 字符串(`Z` 后缀)改写为本地偏移形式
3
+ * (`+08:00` 等,值=同一绝对时刻)。目的:与 00-local-time 补丁后的新数据排序一致。
4
+ *
5
+ * NO_PROXY='*' node scripts/migrate-local-time.mjs [--home <dir>] [--dry]
6
+ *
7
+ * 范围:
8
+ * - workshop.sqlite / users.sqlite:全表全 TEXT 列中形如 `...Z` 的 ISO 时间戳
9
+ * - <configRoot>/data/*.json:递归遍历对象树中的 `...Z` 字符串字段
10
+ * 不动:Timescale(timestamptz 绝对时刻)、daq-timeseries.sqlite(ts_ms 整数)、历史日志文件。
11
+ */
12
+ import { DatabaseSync } from 'node:sqlite'
13
+ import { readdirSync, readFileSync, writeFileSync, renameSync, statSync } from 'node:fs'
14
+ import { join, resolve } from 'node:path'
15
+ import { installLocalIso } from '../shared/local-time.mjs'
16
+
17
+ installLocalIso() // 迁移脚本自身用补丁后的 toISOString 产出本地偏移串
18
+
19
+ const DRY = process.argv.includes('--dry')
20
+ const homeIdx = process.argv.indexOf('--home')
21
+ const configRoot = homeIdx > 0 ? resolve(process.argv[homeIdx + 1] ?? '') : resolve(process.cwd(), '.AgentWorkShop')
22
+ const ISO_UTC = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/
23
+
24
+ let converted = 0
25
+ const toLocal = (s) => {
26
+ const ms = Date.parse(s)
27
+ if (Number.isNaN(ms)) return s
28
+ return new Date(ms).toISOString() // 补丁后 = 本地偏移
29
+ }
30
+
31
+ // ---- sqlite ----
32
+ function migrateSqlite(path) {
33
+ let db
34
+ try {
35
+ db = new DatabaseSync(path)
36
+ }
37
+ catch (err) {
38
+ console.log(`[skip] ${path}: ${err.message}`)
39
+ return
40
+ }
41
+ const tables = db.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'`).all()
42
+ for (const { name: table } of tables) {
43
+ const cols = db.prepare(`PRAGMA table_info(${JSON.stringify(table).slice(1, -1)})`).all()
44
+ for (const col of cols) {
45
+ if ((col.type ?? '').toUpperCase() !== 'TEXT') continue
46
+ let rows
47
+ try {
48
+ rows = db.prepare(`SELECT rowid AS rid, ${JSON.stringify(col.name).slice(1, -1)} AS v FROM ${JSON.stringify(table).slice(1, -1)}`).all()
49
+ }
50
+ catch { continue }
51
+ const hits = rows.filter(r => typeof r.v === 'string' && ISO_UTC.test(r.v))
52
+ if (hits.length === 0) continue
53
+ console.log(`[sqlite] ${table}.${col.name}: ${hits.length} rows`)
54
+ if (DRY) {
55
+ converted += hits.length
56
+ continue
57
+ }
58
+ const upd = db.prepare(`UPDATE ${JSON.stringify(table).slice(1, -1)} SET ${JSON.stringify(col.name).slice(1, -1)} = ? WHERE rowid = ?`)
59
+ for (const r of hits) {
60
+ upd.run(toLocal(r.v), r.rid)
61
+ converted++
62
+ }
63
+ }
64
+ }
65
+ db.close()
66
+ }
67
+
68
+ // ---- json 仓库 ----
69
+ function walkJson(node) {
70
+ if (typeof node === 'string') return ISO_UTC.test(node) ? toLocal(node) : node
71
+ if (Array.isArray(node)) return node.map(walkJson)
72
+ if (node && typeof node === 'object') {
73
+ for (const k of Object.keys(node)) node[k] = walkJson(node[k])
74
+ return node
75
+ }
76
+ return node
77
+ }
78
+
79
+ function migrateJsonDir(dir) {
80
+ let entries
81
+ try {
82
+ entries = readdirSync(dir)
83
+ }
84
+ catch { return }
85
+ for (const name of entries) {
86
+ const p = join(dir, name)
87
+ let st
88
+ try {
89
+ st = statSync(p)
90
+ }
91
+ catch { continue }
92
+ if (st.isDirectory()) {
93
+ if (name === 'plugins' || name === 'daq-objects' || name.startsWith('backup')) continue
94
+ migrateJsonDir(p)
95
+ continue
96
+ }
97
+ if (!name.endsWith('.json') || name === 'runtime-settings.json') continue
98
+ try {
99
+ const raw = readFileSync(p, 'utf-8')
100
+ const parsed = JSON.parse(raw)
101
+ const before = (raw.match(/Z"/g) ?? []).length
102
+ const next = walkJson(parsed)
103
+ const out = JSON.stringify(next, null, 2)
104
+ const after = (out.match(/Z"/g) ?? []).length
105
+ if (before === after) continue
106
+ console.log(`[json] ${p}: ${before - after} timestamps`)
107
+ if (DRY) {
108
+ converted += before - after
109
+ continue
110
+ }
111
+ writeFileSync(p + '.tmp', out)
112
+ renameSync(p + '.tmp', p)
113
+ converted += before - after
114
+ }
115
+ catch { /* 非 JSON 内容/读失败跳过 */ }
116
+ }
117
+ }
118
+
119
+ console.log(`[migrate] configRoot=${configRoot} dry=${DRY}`)
120
+ migrateSqlite(join(configRoot, 'data', 'workshop.sqlite'))
121
+ migrateSqlite(join(configRoot, 'data', 'users.sqlite'))
122
+ migrateJsonDir(join(configRoot, 'data'))
123
+ console.log(`[migrate] done: ${converted} timestamps converted${DRY ? ' (dry-run,未写盘)' : ''}`)
package/scripts/start.mjs CHANGED
@@ -7,10 +7,14 @@
7
7
  // 另在启动前预载 .env(cwd 的 .env;NUXT_SESSION_PASSWORD 等密钥只经环境
8
8
  // 注入,绝不写入 config.yml/仓库;已导出的真实环境变量优先)。
9
9
  // ============================================================
10
- import { existsSync, readFileSync } from 'node:fs'
10
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs'
11
11
  import { dirname, join, resolve } from 'node:path'
12
12
  import { fileURLToPath } from 'node:url'
13
13
  import { resolveRunMode } from '../shared/config/home.mjs'
14
+ import { installLocalIso } from '../shared/local-time.mjs'
15
+
16
+ // 生产进程时间输出统一本地时区(先于 .env 预载与 worker 启动)
17
+ installLocalIso()
14
18
 
15
19
  const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..')
16
20
 
@@ -22,6 +26,8 @@ for (const envPath of [resolve(process.cwd(), '.env'), join(packageRoot, '.env')
22
26
  if (!m || line.trim().startsWith('#')) continue
23
27
  const key = m[1]
24
28
  let val = m[2] ?? ''
29
+ // 行内注释剥离(未加引号时):`KEY=value # 说明` 不应把 " # 说明" 烧进密钥
30
+ if (hashIdx(val) >= 0) val = val.slice(0, hashIdx(val)).trim()
25
31
  if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith('\'') && val.endsWith('\''))) val = val.slice(1, -1)
26
32
  if (process.env[key] === undefined) process.env[key] = val
27
33
  }
@@ -30,6 +36,12 @@ for (const envPath of [resolve(process.cwd(), '.env'), join(packageRoot, '.env')
30
36
  // 共享配置引擎:config.yml + runtime-settings + env(模式感知路径)
31
37
  const { loadEffective } = await import('../shared/config/engine.mjs')
32
38
 
39
+ /** 未加引号值中行内注释的起始下标(` #` 起算,避开 URL hash 等无空格场景) */
40
+ function hashIdx(val) {
41
+ const i = val.indexOf(' #')
42
+ return i
43
+ }
44
+
33
45
  // CLI 传参优先(node scripts/start.mjs --port 8080)
34
46
  let argPort
35
47
  {
@@ -56,6 +68,11 @@ const portSource = eff.sources['server.prod.port']
56
68
  // ---- 单实例互斥 + 自动顶替:同配置根已有实例 → 自动停止后重启新实例(防 SQLite 锁崩溃) ----
57
69
  const { acquireLock, checkPort, terminatePid } = await import('../shared/config/single-instance.mjs')
58
70
  let requestedPort = argPort ? Number(argPort) : prodPort
71
+ // CLI 传参校验:--port -1 之类会被 parseArgs 弄成怪值,这里显式拒绝而非绑定到端口 1
72
+ if (!Number.isInteger(requestedPort) || requestedPort < 1 || requestedPort > 65535) {
73
+ console.error(`✖ 无效端口:${argPort ?? requestedPort}(须为 1-65535 的整数)`)
74
+ process.exit(1)
75
+ }
59
76
  let lock = acquireLock(rm.configRoot, { mode: `prod:${rm.mode}`, port: requestedPort })
60
77
  if (!lock.ok) {
61
78
  const h = lock.holder
@@ -84,7 +101,18 @@ if (bumped >= 10) {
84
101
  console.error(`✖ ${host} 上 ${requestedPort}-${port} 全部被占用,无法启动`)
85
102
  process.exit(1)
86
103
  }
87
- if (bumped > 0) console.log(`✔ 使用顺延端口 ${port}(配置端口 ${requestedPort} 被占用)`)
104
+ if (bumped > 0) {
105
+ console.log(`✔ 使用顺延端口 ${port}(配置端口 ${requestedPort} 被占用)`)
106
+ // 顺延结果回写锁文件:aw stop 的展示、aw status/TUI 的端口发现都读锁
107
+ try {
108
+ const cur = JSON.parse(readFileSync(lock.lockPath, 'utf8'))
109
+ if (cur?.pid === process.pid) {
110
+ cur.port = port
111
+ writeFileSync(lock.lockPath, JSON.stringify(cur, null, 2), 'utf-8')
112
+ }
113
+ }
114
+ catch { /* 锁自清/被接管等场景:展示值回退为配置端口,可接受 */ }
115
+ }
88
116
 
89
117
  process.env.HOST = process.env.HOST || process.env.NITRO_HOST || String(host)
90
118
  process.env.PORT = process.env.PORT || process.env.NITRO_PORT || String(port)
@@ -2,13 +2,13 @@
2
2
  * GET /api/system/settings —— 运行时设置全量快照。
3
3
  * 返回描述符 + 有效值 + 各键来源(config.yml/runtime/env) + 覆盖文件路径。
4
4
  * 前端「系统设置 → 运行配置」表单据此渲染;CLI `aw status` 也走同源概念。
5
- * 鉴权:任何已登录用户可读(config.get 同语义)。
5
+ * 鉴权:admin/editor(effective 含 MQTT 密钥/objectstore secretKey 等敏感字段)。
6
6
  */
7
7
  import { defineApiHandler } from '../../../utils/response'
8
- import { resolveUser } from '../../workshop/caller'
8
+ import { requireRole } from '../../workshop/caller'
9
9
  import { getSystemConfigService } from '../../../services/system-config'
10
10
 
11
11
  export default defineApiHandler((event) => {
12
- resolveUser(event)
12
+ requireRole(event, ['admin', 'editor'])
13
13
  return getSystemConfigService().snapshot()
14
14
  })