agentworkshop 0.7.39 → 0.7.41

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 (405) hide show
  1. package/.AgentWorkShop/prompts/host-tools.json +55 -0
  2. package/.output/.AgentWorkShop/prompts/host-tools.json +55 -0
  3. package/.output/nitro.json +1 -1
  4. package/.output/public/_nuxt/88GOowgO2.js +1 -0
  5. package/.output/public/_nuxt/{BNT8gYU92.js → BC9wjTJK2.js} +2 -2
  6. package/.output/public/_nuxt/{CY9LbPCI.js → BN16aRdQ.js} +1 -1
  7. package/.output/public/_nuxt/BWVhZntO.js +1 -0
  8. package/.output/public/_nuxt/{HBLJ-wei.js → BXxH0UQE.js} +1 -1
  9. package/.output/public/_nuxt/{zIGh7R49.js → BneN7fbu.js} +1 -1
  10. package/.output/public/_nuxt/BsROmY89.js +1 -0
  11. package/.output/public/_nuxt/{DUrecWPx.js → C0ZrS1KL.js} +2 -2
  12. package/.output/public/_nuxt/{C_OLzD09.js → C4oW1HsE.js} +1 -1
  13. package/.output/public/_nuxt/{CUDwzgLV.js → C4s_niy-.js} +9 -9
  14. package/.output/public/_nuxt/CFxtLwjp.js +1 -0
  15. package/.output/public/_nuxt/{Cec0Ua3F.js → CS50LB_l.js} +1 -1
  16. package/.output/public/_nuxt/CssgYAAL2.js +1 -0
  17. package/.output/public/_nuxt/D6mbFA-a.js +1 -0
  18. package/.output/public/_nuxt/D98NH8kG.js +1 -0
  19. package/.output/public/_nuxt/DGIuvyRN2.js +1 -0
  20. package/.output/public/_nuxt/DGbd-UiG.js +1 -0
  21. package/.output/public/_nuxt/{CojCTLKD.js → DGj-WEBg.js} +1 -1
  22. package/.output/public/_nuxt/{DDShH71m.js → DS8qj8EL.js} +1 -1
  23. package/.output/public/_nuxt/DTFCy6h-.js +1 -0
  24. package/.output/public/_nuxt/{DrYV5i68.js → DUjW5Yq5.js} +1 -1
  25. package/.output/public/_nuxt/{45zuyAso.js → D_OTvQza.js} +1 -1
  26. package/.output/public/_nuxt/Dap5PmTL.js +2 -0
  27. package/.output/public/_nuxt/Dqw1lpr-.js +1 -0
  28. package/.output/public/_nuxt/DvLxILQP.js +1 -0
  29. package/.output/public/_nuxt/IREZ1eC2.js +1 -0
  30. package/.output/public/_nuxt/TownView.f-YOdXRs.css +1 -0
  31. package/.output/public/_nuxt/_id_.D9ymtHB5.css +1 -0
  32. package/.output/public/_nuxt/_id_.jf-_8E_c.css +1 -0
  33. package/.output/public/_nuxt/_wsId_.B4WiqkIS.css +1 -0
  34. package/.output/public/_nuxt/agents.ZD0rVdHE.css +1 -0
  35. package/.output/public/_nuxt/aml.BN8ZEW4h.css +1 -0
  36. package/.output/public/_nuxt/builds/latest.json +1 -1
  37. package/.output/public/_nuxt/builds/meta/78a295bb-2072-48a4-8b46-6d545fdae743.json +1 -0
  38. package/.output/public/_nuxt/ca4TJ3Op.js +1 -0
  39. package/.output/public/_nuxt/channel-templates.BOtahzPi.css +1 -0
  40. package/.output/public/_nuxt/daq.DjSgY94l.css +1 -0
  41. package/.output/public/_nuxt/dcw.8Y7FqCVN.css +1 -0
  42. package/.output/public/_nuxt/default.J32SgqFY.css +1 -0
  43. package/.output/public/_nuxt/entry.bdm0tv6M.css +1 -0
  44. package/.output/public/_nuxt/eqq3wWQF.js +18 -0
  45. package/.output/public/_nuxt/logs.BpKzmKsh.css +1 -0
  46. package/.output/public/_nuxt/monitor.D9pe7qN6.css +1 -0
  47. package/.output/public/_nuxt/pages.D7aSDlUI.css +1 -0
  48. package/.output/public/_nuxt/permissions.DwTVlFe6.css +1 -0
  49. package/.output/public/_nuxt/plugins.sb4nDGqr.css +1 -0
  50. package/.output/public/_nuxt/{Cbq-mryP.js → qr6R6Ha1.js} +1 -1
  51. package/.output/public/_nuxt/settings.BTgR-NiE.css +1 -0
  52. package/.output/public/_nuxt/teams.CxnxKVVs.css +1 -0
  53. package/.output/public/_nuxt/tokens.BFY7qv4f.css +1 -0
  54. package/.output/public/_nuxt/{town.DKIAhKnx.css → town.BBXZmeoP.css} +1 -1
  55. package/.output/public/_nuxt/users.DLgZ1D0h.css +1 -0
  56. package/.output/public/_nuxt/workshop.CR_QzeAN.css +1 -0
  57. package/.output/public/_nuxt/{BzHEilTt.js → xh3_vYcu.js} +1 -1
  58. package/.output/public/_nuxt/yF0aYMF1.js +4 -0
  59. package/.output/server/chunks/_/entity.mjs.map +1 -1
  60. package/.output/server/chunks/_/nitro.mjs +2355 -1362
  61. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  62. package/.output/server/chunks/build/{TownView-jVazYOjN.mjs → TownView--otsnr_7.mjs} +290 -208
  63. package/.output/server/chunks/build/TownView--otsnr_7.mjs.map +1 -0
  64. package/.output/server/chunks/build/{_id_-CfVosNg3.mjs → _id_-Brv-JSvr.mjs} +142 -141
  65. package/.output/server/chunks/build/_id_-Brv-JSvr.mjs.map +1 -0
  66. package/.output/server/chunks/build/{_id_-Hwr4rZpr.mjs → _id_-D9pl1OZy.mjs} +38 -36
  67. package/.output/server/chunks/build/_id_-D9pl1OZy.mjs.map +1 -0
  68. package/.output/server/chunks/build/{_wsId_-BVg3bB77.mjs → _wsId_-BASfDf0s.mjs} +295 -261
  69. package/.output/server/chunks/build/{_wsId_-BVg3bB77.mjs.map → _wsId_-BASfDf0s.mjs.map} +1 -1
  70. package/.output/server/chunks/build/{agents-Bvin73QY.mjs → agents-CLQqJF2y.mjs} +21 -27
  71. package/.output/server/chunks/build/agents-CLQqJF2y.mjs.map +1 -0
  72. package/.output/server/chunks/build/{aml-BCSJCdX7.mjs → aml-_7FdFL2p.mjs} +109 -109
  73. package/.output/server/chunks/build/{aml-BCSJCdX7.mjs.map → aml-_7FdFL2p.mjs.map} +1 -1
  74. package/.output/server/chunks/build/api-error-dul30BYQ.mjs.map +1 -1
  75. package/.output/server/chunks/build/{channel-templates-BTq8570n.mjs → channel-templates-p6SZNjlM.mjs} +19 -19
  76. package/.output/server/chunks/build/{channel-templates-BTq8570n.mjs.map → channel-templates-p6SZNjlM.mjs.map} +1 -1
  77. package/.output/server/chunks/build/{daq-C03Uu5UE.mjs → daq-DkMvD8sg.mjs} +193 -126
  78. package/.output/server/chunks/build/daq-DkMvD8sg.mjs.map +1 -0
  79. package/.output/server/chunks/build/{dcw-6vEYVeje.mjs → dcw-C1jgVJkO.mjs} +46 -46
  80. package/.output/server/chunks/build/{dcw-6vEYVeje.mjs.map → dcw-C1jgVJkO.mjs.map} +1 -1
  81. package/.output/server/chunks/build/{default-CZmZFpqH.mjs → default-BE4r0FZN.mjs} +152 -58
  82. package/.output/server/chunks/build/{default-CZmZFpqH.mjs.map → default-BE4r0FZN.mjs.map} +1 -1
  83. package/.output/server/chunks/build/{logs-B-xhuqln.mjs → logs--dByNyhw.mjs} +35 -35
  84. package/.output/server/chunks/build/{logs-B-xhuqln.mjs.map → logs--dByNyhw.mjs.map} +1 -1
  85. package/.output/server/chunks/build/{monitor-CyfDt4nR.mjs → monitor-C0okQaXz.mjs} +33 -33
  86. package/.output/server/chunks/build/{monitor-CyfDt4nR.mjs.map → monitor-C0okQaXz.mjs.map} +1 -1
  87. package/.output/server/chunks/build/{pages-BO7yZsXA.mjs → pages-B0bUWnC6.mjs} +35 -19
  88. package/.output/server/chunks/build/pages-B0bUWnC6.mjs.map +1 -0
  89. package/.output/server/chunks/build/{permissions-B52oOmaO.mjs → permissions-68SsNjex.mjs} +12 -12
  90. package/.output/server/chunks/build/{permissions-B52oOmaO.mjs.map → permissions-68SsNjex.mjs.map} +1 -1
  91. package/.output/server/chunks/build/{plugins-CUWmMdyt.mjs → plugins-lGlUr1lj.mjs} +17 -17
  92. package/.output/server/chunks/build/{plugins-CUWmMdyt.mjs.map → plugins-lGlUr1lj.mjs.map} +1 -1
  93. package/.output/server/chunks/build/{settings-DoQ2Oq3P.mjs → settings-Ddd1qx2Z.mjs} +50 -47
  94. package/.output/server/chunks/build/settings-Ddd1qx2Z.mjs.map +1 -0
  95. package/.output/server/chunks/build/{teams-2kz3CusY.mjs → teams-MEDLZdMn.mjs} +38 -34
  96. package/.output/server/chunks/build/teams-MEDLZdMn.mjs.map +1 -0
  97. package/.output/server/chunks/build/{tokens-BbWLqtVz.mjs → tokens-C7fTM5C2.mjs} +14 -14
  98. package/.output/server/chunks/build/{tokens-BbWLqtVz.mjs.map → tokens-C7fTM5C2.mjs.map} +1 -1
  99. package/.output/server/chunks/build/{town-BOl6hs9B.mjs → town-CoQdblbZ.mjs} +38 -12
  100. package/.output/server/chunks/build/town-CoQdblbZ.mjs.map +1 -0
  101. package/.output/server/chunks/build/{useDaqStream-CIBaiGAl.mjs → useDaqStream-DfCFpb3p.mjs} +9 -3
  102. package/.output/server/chunks/build/useDaqStream-DfCFpb3p.mjs.map +1 -0
  103. package/.output/server/chunks/build/{useDcwStream-CBbiYnWe.mjs → useDcwStream-UPiX-3iO.mjs} +11 -2
  104. package/.output/server/chunks/build/useDcwStream-UPiX-3iO.mjs.map +1 -0
  105. package/.output/server/chunks/build/useResponsive-BKDMGTHs.mjs +49 -0
  106. package/.output/server/chunks/build/useResponsive-BKDMGTHs.mjs.map +1 -0
  107. package/.output/server/chunks/build/{users-fohSmF-J.mjs → users-Cfd5-l2-.mjs} +6 -6
  108. package/.output/server/chunks/build/{users-fohSmF-J.mjs.map → users-Cfd5-l2-.mjs.map} +1 -1
  109. package/.output/server/chunks/build/{workshop-DX5-ldc4.mjs → workshop-BL5bhfs0.mjs} +15 -15
  110. package/.output/server/chunks/build/{workshop-DX5-ldc4.mjs.map → workshop-BL5bhfs0.mjs.map} +1 -1
  111. package/.output/server/chunks/build/{workspaces-BuydxM-3.mjs → workspaces-Bgz5Ekwp.mjs} +18 -3
  112. package/.output/server/chunks/build/workspaces-Bgz5Ekwp.mjs.map +1 -0
  113. package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs.map +1 -1
  114. package/.output/server/chunks/routes/api/system/index.patch.mjs.map +1 -1
  115. package/.output/server/chunks/routes/api/system/index.post.mjs.map +1 -1
  116. package/.output/server/chunks/routes/api/system/settings/events.get.mjs.map +1 -1
  117. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +6 -2
  118. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
  119. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +2 -1
  120. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs.map +1 -1
  121. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  122. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +3 -3
  123. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs.map +1 -1
  124. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs.map +1 -1
  125. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs.map +1 -1
  126. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +3 -2
  127. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs.map +1 -1
  128. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +2 -1
  129. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs.map +1 -1
  130. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +8 -6
  131. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs.map +1 -1
  132. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +5 -5
  133. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs.map +1 -1
  134. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +14 -4
  135. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs.map +1 -1
  136. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +4 -4
  137. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs.map +1 -1
  138. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +4 -3
  139. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs.map +1 -1
  140. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +31 -0
  141. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs.map +1 -0
  142. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +28 -0
  143. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs.map +1 -0
  144. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  145. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  146. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs.map +1 -1
  147. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +32 -0
  148. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs.map +1 -0
  149. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +34 -0
  150. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs.map +1 -0
  151. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +33 -0
  152. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs.map +1 -0
  153. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +34 -0
  154. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs.map +1 -0
  155. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  156. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  157. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  158. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  159. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  160. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  161. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  162. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +3 -1
  163. package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
  164. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +5 -1
  165. package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
  166. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +3 -1
  167. package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
  168. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  169. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  170. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  171. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  172. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  173. package/.output/server/chunks/routes/renderer.mjs +3 -3
  174. package/.output/server/chunks/virtual/entry.mjs +51 -25
  175. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  176. package/.output/server/package.json +1 -1
  177. package/README-zh.md +203 -39
  178. package/README.md +739 -591
  179. package/app/app.vue +9 -3
  180. package/app/assets/css/main.css +517 -7
  181. package/app/components/AppHeader.vue +98 -7
  182. package/app/components/AppSidebar.vue +117 -11
  183. package/app/components/AwChart.vue +2 -1
  184. package/app/components/workshop/AgentInspectorDrawer.vue +6 -6
  185. package/app/components/workshop/AgentLanesView.vue +52 -1
  186. package/app/components/workshop/AssetLibrary.vue +4 -2
  187. package/app/components/workshop/ChannelSessionList.vue +4 -2
  188. package/app/components/workshop/Composer.vue +96 -0
  189. package/app/components/workshop/DaqNodeRow.vue +19 -0
  190. package/app/components/workshop/DaqTemplateIcon.vue +33 -0
  191. package/app/components/workshop/DeviceTwinPanel.vue +37 -35
  192. package/app/components/workshop/EventBlock.vue +3 -3
  193. package/app/components/workshop/InspectorPanel.vue +47 -11
  194. package/app/components/workshop/LiveAgentBar.vue +34 -0
  195. package/app/components/workshop/TaskBoardView.vue +83 -33
  196. package/app/components/workshop/TranscriptTimeline.vue +56 -0
  197. package/app/components/workshop/blocks/ClusterError.vue +1 -1
  198. package/app/components/workshop/blocks/ClusterRoute.vue +3 -1
  199. package/app/components/workshop/blocks/ClusterStatus.vue +2 -2
  200. package/app/components/workshop/blocks/ClusterStream.vue +8 -2
  201. package/app/components/workshop/town/ModelPreview3D.vue +1 -1
  202. package/app/components/workshop/town/TownView.vue +507 -82
  203. package/app/composables/useResponsive.ts +88 -0
  204. package/app/composables/useRouteMeta.ts +3 -0
  205. package/app/composables/workshop/useDaqStream.ts +7 -4
  206. package/app/composables/workshop/useDcwStream.ts +8 -2
  207. package/app/composables/workshop/useVisibleInterval.ts +2 -2
  208. package/app/composables/workshop/useWorkshopApi.ts +1 -1
  209. package/app/layouts/default.vue +46 -2
  210. package/app/pages/aml/index.vue +712 -616
  211. package/app/pages/daq/[id].vue +12 -7
  212. package/app/pages/daq/index.vue +216 -13
  213. package/app/pages/dcw/[id].vue +117 -32
  214. package/app/pages/dcw/index.vue +83 -23
  215. package/app/pages/index.vue +35 -1
  216. package/app/pages/logs/index.vue +147 -13
  217. package/app/pages/monitor.vue +56 -12
  218. package/app/pages/permissions/index.vue +34 -0
  219. package/app/pages/plugins/index.vue +35 -4
  220. package/app/pages/settings.vue +90 -21
  221. package/app/pages/tokens.vue +23 -0
  222. package/app/pages/town.vue +50 -5
  223. package/app/pages/users.vue +23 -0
  224. package/app/pages/workshop/agents.vue +92 -2
  225. package/app/pages/workshop/channel-templates.vue +53 -0
  226. package/app/pages/workshop/index.vue +14 -0
  227. package/app/pages/workshop/teams.vue +66 -6
  228. package/app/pages/workshop/w/[wsId].vue +202 -14
  229. package/app/plugins/aw-plugins.client.ts +13 -8
  230. package/app/stores/app.ts +33 -1
  231. package/app/stores/workshop/user.ts +1 -1
  232. package/app/stores/workshop/workspaces.ts +18 -2
  233. package/app/utils/api-error.ts +1 -1
  234. package/cli/commands/build.mjs +8 -1
  235. package/docker-compose.yml +6 -0
  236. package/docs/cli.en.md +2 -2
  237. package/docs/cli.md +2 -2
  238. package/docs/plugins.en.md +33 -1
  239. package/docs/plugins.md +29 -1
  240. package/docs/sdk.en.md +1 -1
  241. package/docs/sdk.md +1 -1
  242. package/i18n/locales/en.ts +2 -0
  243. package/i18n/locales/zh-CN.ts +2 -0
  244. package/nuxt.config.ts +31 -0
  245. package/package.json +11 -2
  246. package/scripts/_dbg-param-map-e2e.ts +242 -0
  247. package/scripts/_dbg-param-map-rest-smoke.mjs +73 -0
  248. package/scripts/_dbg-param-real-scenario.mjs +153 -0
  249. package/scripts/_loop-biax-campaign.mjs +124 -0
  250. package/scripts/api-live-e2e.mjs +40 -8
  251. package/scripts/capture-walkthrough.mjs +232 -0
  252. package/scripts/render-walkthrough-figure.mjs +46 -0
  253. package/scripts/seed-walkthrough-fixture.mjs +143 -0
  254. package/scripts/test-plugin-hardening.mjs +8 -0
  255. package/scripts/test-serial-bridge.mjs +418 -0
  256. package/scripts/ui/admin-shots.mjs +46 -0
  257. package/scripts/ui/audit-layout.mjs +301 -0
  258. package/scripts/ui/bump-microfont.mjs +39 -0
  259. package/scripts/ui/e2e-interactive.mjs +328 -0
  260. package/scripts/ui/lib.mjs +198 -0
  261. package/scripts/ui/linkcheck2.mjs +37 -0
  262. package/scripts/ui/live-render-check.mjs +72 -0
  263. package/scripts/ui/md-lint.mjs +80 -0
  264. package/scripts/ui/perf-audit.mjs +132 -0
  265. package/scripts/ui/readme-assets.mjs +30 -0
  266. package/scripts/ui/readme-shots.mjs +42 -0
  267. package/scripts/ui/record.mjs +225 -0
  268. package/scripts/ui/seed-admin.mjs +68 -0
  269. package/scripts/ui/seed-demo.mjs +83 -0
  270. package/scripts/ui/seed-industrial-demo.mjs +171 -0
  271. package/scripts/ui/shot-hero.mjs +25 -0
  272. package/scripts/ui/shots.mjs +75 -0
  273. package/scripts/ui/sim-ui-shot.mjs +16 -0
  274. package/scripts/ui/verify-nav.mjs +51 -0
  275. package/scripts/ui/verify-responsive.mjs +285 -0
  276. package/server/api/system/config-groups/[id].patch.ts +1 -1
  277. package/server/api/system/config-groups/index.post.ts +1 -1
  278. package/server/api/system/settings/events.get.ts +1 -1
  279. package/server/api/system/settings/index.patch.ts +1 -1
  280. package/server/api/workshop/agent-tools/invoke.post.ts +16 -2
  281. package/server/api/workshop/aml/datasets/[id].get.ts +8 -1
  282. package/server/api/workshop/daq/index.get.ts +3 -1
  283. package/server/api/workshop/daq/infra/reconnect.post.ts +1 -1
  284. package/server/api/workshop/daq/templates/[key].delete.ts +1 -0
  285. package/server/api/workshop/daq/templates/[key].patch.ts +1 -0
  286. package/server/api/workshop/daq/templates/index.post.ts +1 -0
  287. package/server/api/workshop/dcw/[id]/write.post.ts +10 -2
  288. package/server/api/workshop/dcw/[id].delete.ts +5 -2
  289. package/server/api/workshop/dcw/index.get.ts +5 -0
  290. package/server/api/workshop/dcw/lines/[id].patch.ts +1 -1
  291. package/server/api/workshop/dcw/params/[id]/read.post.ts +17 -0
  292. package/server/api/workshop/dcw/params/[id]/write.post.ts +21 -0
  293. package/server/api/workshop/dcw/params/[id].delete.ts +19 -0
  294. package/server/api/workshop/dcw/params/[id].patch.ts +23 -0
  295. package/server/api/workshop/dcw/params/index.get.ts +27 -0
  296. package/server/api/workshop/dcw/params/index.post.ts +25 -0
  297. package/server/api/workshop/permissions/index.get.ts +3 -1
  298. package/server/plugins/aw-plugins.ts +23 -10
  299. package/server/plugins/dev-stability-guard.ts +3 -1
  300. package/server/plugins/system-config.ts +6 -1
  301. package/server/plugins-builtin/serial-bridge/client.mjs +210 -0
  302. package/server/plugins-builtin/serial-bridge/drivers.mjs +409 -0
  303. package/server/plugins-builtin/serial-bridge/i18n.json +62 -0
  304. package/server/plugins-builtin/serial-bridge/index.mjs +247 -0
  305. package/server/plugins-builtin/serial-bridge/lib.mjs +208 -0
  306. package/server/plugins-builtin/serial-bridge/rtu.mjs +168 -0
  307. package/server/services/system-config.ts +28 -9
  308. package/server/services/workshop/agents/adapters/one-shot-cli-agent.ts +2 -1
  309. package/server/services/workshop/agents/agent-interface.ts +8 -6
  310. package/server/services/workshop/agents/base-agent.ts +18 -4
  311. package/server/services/workshop/agents/claude-agent.ts +7 -3
  312. package/server/services/workshop/agents/codex-agent.ts +3 -3
  313. package/server/services/workshop/agents/dsh-agent.ts +3 -3
  314. package/server/services/workshop/agents/goose-agent.ts +0 -1
  315. package/server/services/workshop/agents/harness-terminal.ts +14 -1
  316. package/server/services/workshop/agents/hermes-agent.ts +4 -2
  317. package/server/services/workshop/agents/host-tool-bridge.ts +5 -1
  318. package/server/services/workshop/agents/industrial-context.ts +4 -1
  319. package/server/services/workshop/agents/industrial-tools.ts +164 -6
  320. package/server/services/workshop/agents/omp-agent.ts +15 -9
  321. package/server/services/workshop/agents/opencode-agent.ts +47 -21
  322. package/server/services/workshop/agents/qwen-agent.ts +10 -5
  323. package/server/services/workshop/aml/entity.ts +3 -1
  324. package/server/services/workshop/aml/python-runtime.ts +3 -2
  325. package/server/services/workshop/daq/bus/mqtt.adapter.ts +8 -4
  326. package/server/services/workshop/daq/daq-controller.ts +25 -5
  327. package/server/services/workshop/daq/daq-runtime.ts +5 -3
  328. package/server/services/workshop/daq/drivers.ts +141 -11
  329. package/server/services/workshop/daq/host-ports.ts +3 -2
  330. package/server/services/workshop/daq/storage/timescale.adapter.ts +3 -1
  331. package/server/services/workshop/db/channel.repo.ts +4 -0
  332. package/server/services/workshop/db/ops.repo.ts +5 -2
  333. package/server/services/workshop/db/retention.ts +8 -3
  334. package/server/services/workshop/dcw/dcw-controller.ts +147 -16
  335. package/server/services/workshop/dcw/dcw-product.repo.ts +38 -1
  336. package/server/services/workshop/dcw/dcw-runtime.ts +3 -2
  337. package/server/services/workshop/dcw/drivers.ts +90 -4
  338. package/server/services/workshop/dcw/param-conversion.ts +78 -0
  339. package/server/services/workshop/dcw/param-limits.ts +142 -0
  340. package/server/services/workshop/dcw/param-map.repo.ts +305 -0
  341. package/server/services/workshop/dcw/plugin-bridge.ts +45 -0
  342. package/server/services/workshop/dcw/recipe-rollback-manager.ts +13 -7
  343. package/server/services/workshop/plugins/host.mjs +30 -0
  344. package/server/services/workshop/runtime/agent-runtime.ts +4 -0
  345. package/server/services/workshop/runtime/manager.ts +9 -2
  346. package/server/services/workshop/settings.ts +4 -2
  347. package/server/types/pg.d.ts +49 -0
  348. package/server/utils/stability-severity.ts +13 -2
  349. package/shared/config/groups.mjs +22 -1
  350. package/shared/config/home.d.mts +28 -0
  351. package/shared/daq-protocol.ts +15 -0
  352. package/shared/dcw-protocol.ts +136 -0
  353. package/uno.config.ts +12 -1
  354. package/.output/public/_nuxt/8NMOXZOV.js +0 -1
  355. package/.output/public/_nuxt/BFkgkW8u.js +0 -4
  356. package/.output/public/_nuxt/C5gUkRwn.js +0 -1
  357. package/.output/public/_nuxt/CM12FuB42.js +0 -1
  358. package/.output/public/_nuxt/CZiw7sEV.js +0 -1
  359. package/.output/public/_nuxt/Cc_9VzD42.js +0 -1
  360. package/.output/public/_nuxt/CdPzkOMV.js +0 -1
  361. package/.output/public/_nuxt/CmsOtOAA2.js +0 -1
  362. package/.output/public/_nuxt/D1YDxZpZ.js +0 -1
  363. package/.output/public/_nuxt/D20Yamr4.js +0 -1
  364. package/.output/public/_nuxt/DAe0h2MB.js +0 -1
  365. package/.output/public/_nuxt/DmqknNvV.js +0 -18
  366. package/.output/public/_nuxt/DnUuIR83.js +0 -1
  367. package/.output/public/_nuxt/S_fVQwJK.js +0 -1
  368. package/.output/public/_nuxt/TownView.0oLiQgTC.css +0 -1
  369. package/.output/public/_nuxt/_id_.D-SYuyZb.css +0 -1
  370. package/.output/public/_nuxt/_id_.hma_BU6T.css +0 -1
  371. package/.output/public/_nuxt/_wsId_.B12v3PhY.css +0 -1
  372. package/.output/public/_nuxt/agents.BV70ioCv.css +0 -1
  373. package/.output/public/_nuxt/ahgEJu2R.js +0 -1
  374. package/.output/public/_nuxt/aml.COEKNNqK.css +0 -1
  375. package/.output/public/_nuxt/builds/meta/4457d63f-0866-4cea-b320-04a321f24795.json +0 -1
  376. package/.output/public/_nuxt/channel-templates.C-M5nKcC.css +0 -1
  377. package/.output/public/_nuxt/daq.B3265ZDn.css +0 -1
  378. package/.output/public/_nuxt/dcw.DLYZqEhT.css +0 -1
  379. package/.output/public/_nuxt/default.BXI_fZUi.css +0 -1
  380. package/.output/public/_nuxt/entry.BB-Eeh-J.css +0 -1
  381. package/.output/public/_nuxt/logs.CqFyMrJw.css +0 -1
  382. package/.output/public/_nuxt/monitor.B--1dPzs.css +0 -1
  383. package/.output/public/_nuxt/pages.ooEzrMm9.css +0 -1
  384. package/.output/public/_nuxt/permissions.B1pjGChZ.css +0 -1
  385. package/.output/public/_nuxt/plugins.5e5chZ67.css +0 -1
  386. package/.output/public/_nuxt/pz2JDAM7.js +0 -2
  387. package/.output/public/_nuxt/settings.Dm3M0RLy.css +0 -1
  388. package/.output/public/_nuxt/teams.BC75EGnR.css +0 -1
  389. package/.output/public/_nuxt/tokens.xRb1fSPU.css +0 -1
  390. package/.output/public/_nuxt/users.CXnP2E08.css +0 -1
  391. package/.output/public/_nuxt/workshop.Jk5HxWPE.css +0 -1
  392. package/.output/server/chunks/build/TownView-jVazYOjN.mjs.map +0 -1
  393. package/.output/server/chunks/build/_id_-CfVosNg3.mjs.map +0 -1
  394. package/.output/server/chunks/build/_id_-Hwr4rZpr.mjs.map +0 -1
  395. package/.output/server/chunks/build/agents-Bvin73QY.mjs.map +0 -1
  396. package/.output/server/chunks/build/daq-C03Uu5UE.mjs.map +0 -1
  397. package/.output/server/chunks/build/pages-BO7yZsXA.mjs.map +0 -1
  398. package/.output/server/chunks/build/settings-DoQ2Oq3P.mjs.map +0 -1
  399. package/.output/server/chunks/build/teams-2kz3CusY.mjs.map +0 -1
  400. package/.output/server/chunks/build/town-BOl6hs9B.mjs.map +0 -1
  401. package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs.map +0 -1
  402. package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs.map +0 -1
  403. package/.output/server/chunks/build/workspaces-BuydxM-3.mjs.map +0 -1
  404. /package/.output/public/_nuxt/{36oeS8_R2.js → 36oeS8_R.js} +0 -0
  405. /package/.output/public/_nuxt/{CYWVXZTS.js → CYWVXZTS2.js} +0 -0
package/README.md CHANGED
@@ -1,591 +1,739 @@
1
- <div align="center">
2
-
3
- <img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/hero.png" alt="AgentWorkShop — Agents that run the production line" width="100%" />
4
-
5
- # AgentWorkShop
6
-
7
- **Where AI agent teams meet the production line.**
8
-
9
- [![Nuxt 4](https://img.shields.io/badge/Nuxt-4-00DC82?logo=nuxt&logoColor=white)](https://nuxt.com)
10
- [![Vue 3.5](https://img.shields.io/badge/Vue-3.5-42B883?logo=vuedotjs&logoColor=white)](https://vuejs.org)
11
- [![TypeScript 5.7](https://img.shields.io/badge/TypeScript-5.7-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org)
12
- [![Node ≥ 23.4](https://img.shields.io/badge/Node.js-%E2%89%A5%2023.4-3C873A?logo=nodedotjs&logoColor=white)](https://nodejs.org)
13
- [![SQLite node:sqlite](https://img.shields.io/badge/SQLite-node:sqlite-003B57?logo=sqlite&logoColor=white)](https://nodejs.org/api/sqlite.html)
14
- [![License: PolyForm Noncommercial](https://img.shields.io/badge/License-PolyForm_NC_1.0-8A2BE2?logo=openaccess&logoColor=white)](./LICENSE)
15
-
16
- **[中文文档 →](./README-zh.md)** · **[Online Docs →](https://kingdol666.github.io/AgentWorkShop/)** · **[Releases →](https://github.com/kingdol666/AgentWorkShop/releases)** · **[Changelog →](./changelog.md)**
17
-
18
- *Current version: **v0.7.39** · 14 agent engines · 5 field protocols · 99 runtime settings · bilingual docs (简体中文 / English)*
19
-
20
- *A configuration-driven platform where **AI agent teams** and an **industrial digital twin** share one runtime — agents query real telemetry, issue supervisory setpoints through human-approved write control, and every event streams live to a 3D twin.*
21
-
22
- </div>
23
-
24
- > **Positioning: supervisory layer.** AgentWorkShop is a *supervisory* (SCADA-adjacent) layer for production-line management, digital twins, DAQ and agent orchestration, operating at **second-level soft real-time**. It is **not** a hard real-time controller: any time-critical loop (**< 10 ms**, interlocks, safety, servo) **must live inside the PLC**. Setpoints written here are advisory — plant-side logic may veto.
25
-
26
- ---
27
-
28
- ## Contents
29
-
30
- | | | |
31
- |---|---|---|
32
- | [What is this?](#what-is-this) | [Highlights](#highlights) | [Interface](#interface) |
33
- | [Architecture](#architecture) | [Quick start](#quick-start) | [Configuration & CLI](#configuration--cli--config-driven-by-design) |
34
- | [Industrial stack](#the-industrial-stack-in-detail) | [Usage](#usage) | [Verification](#verified-end-to-end) |
35
- | [Project layout](#project-layout) | [Tech stack](#tech-stack) | [Development](#development) |
36
- | [Roadmap](#roadmap) | [License](#license) | |
37
-
38
- ## Documentation
39
-
40
- Docs are bilingual — the [VitePress site](https://kingdol666.github.io/AgentWorkShop/) ships a language switcher (简体中文 / English) across every section. Deep-dive pages ship in this repo too, and the CLI copies them into the published tarball:
41
-
42
- | Topic | Online | In-repo | What it covers |
43
- |---|---|---|---|
44
- | **Getting started** | [Guide](https://kingdol666.github.io/AgentWorkShop/guide/getting-started) | `docs/site/guide/` | install → first run → first agent × line session, configuration, DAQ protocols, DCW read/write, HITL, recipe versioning, multi-harness teams, line permissions, AML |
45
- | **Plugin development** | [Plugin guide](https://kingdol666.github.io/AgentWorkShop/plugins/) | [`docs/plugins.md`](./docs/plugins.md) | the full extension contract: three scopes, `index.mjs` manifest, `ctx` server/browser surface, `settings`/`groups` declarations, lifecycle events, i18n, panels, team-scoped switches, a real example |
46
- | **SDK** | [SDK guide](https://kingdol666.github.io/AgentWorkShop/sdk/) | [`docs/sdk.md`](./docs/sdk.md) | `agentworkshop/sdk` as a programming client (platform REST client with envelope handling) and as the plugin extension base; TypeScript types; browser-side SDK |
47
- | **CLI** | [CLI manual](https://kingdol666.github.io/AgentWorkShop/cli/) | [`docs/cli.md`](./docs/cli.md) | all 14 `aw` commands, global options, exit codes, dual-mode path model, the command-registration system, maintainer publish guide |
48
- | **AML** | [AML guide](https://kingdol666.github.io/AgentWorkShop/guide/aml) | [`docs/aml.md`](./docs/aml.md) | auto-modeling lab: dataset build, job orchestration, model registry, promotion gates, agent tools |
49
- | **TUI** | — | [`docs/tui.md`](./docs/tui.md) · [`tui/README.md`](./tui/README.md) | terminal workbench: channels, agents, tasks, live monitor, HITL answering |
50
- | **Multi-harness architecture** | — | [`docs/multi-harness-architecture.md`](./docs/multi-harness-architecture.md) | engine taxonomy, normalized session contract, provider/model catalog, failure modes |
51
-
52
- ---
53
-
54
- ## What is this?
55
-
56
- AgentWorkShop started as a **multi-agent software workshop** — channels of coding agents with a lead-agent scheduler, a 7-state task machine, persistent memory, and four interoperable entry points (WebSocket / MCP / A2A / REST).
57
-
58
- It grew an **industrial half**: a full data-acquisition and write-control stack (Modbus TCP / OPC UA), production lines with recipes and batch runs, a 3D digital-twin town, an **auto-modeling lab** (dataset → training job → leaderboard → gated promotion) — and the bridge that makes it unique: **agents can be granted bound, permission-scoped access to real industrial nodes**, query their live telemetry with physical semantics attached, and drive write operations through an interlock → human-in-the-loop → readback pipeline.
59
-
60
- It is also **extensible by design**: a self-contained plugin can enhance the server (hooks, routes, agent tools, DAQ drivers, config groups) and the browser (panels, i18n) at the same time, and the same surfaces are available to ordinary programs through the SDK — see [`docs/plugins.md`](./docs/plugins.md) and [`docs/sdk.md`](./docs/sdk.md).
61
-
62
- The result: submit a goal like *"analyze the melt temperature trend and optimize the setpoint"* — and an agent team reads real sensor history, computes statistics, proposes a new setpoint, waits for your approval in the HITL panel, writes it to the PLC, verifies the readback, and reports the numbers back. **End to end, verified by automated E2E.**
63
-
64
- <div align="center">
65
- <img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/town-demo.gif" alt="3D digital twin — live production line" width="86%" />
66
- <br><sub><b>Live 3D twin.</b> Line equipment, device health, DAQ channels and trend analysis — all driven by real-time telemetry.</sub>
67
- </div>
68
-
69
- ---
70
-
71
- ## Highlights
72
-
73
- #### Agent team runtime
74
-
75
- | Capability | Why it matters |
76
- |---|---|
77
- | **Lead-agent orchestration** | Each channel has one lead: decomposes goals, dispatches to idle workers, reassigns failures, judges goal satisfaction. LLM decisions with a deterministic rule-engine fallback — the system never stalls. |
78
- | **Three execution modes** | `goal` (satisfaction judging) · `loop` (fixed-interval replay) · `pipeline` (ordered stages). 7-state task machine with progress, artifacts and full history. |
79
- | **Harness-agnostic** | One `AgentInterface`, **14 engines** in three transport classes: **in-process** — `mock` (no LLM), `claude` (Claude Agent SDK, resident session, same-turn steer); **persistent session over a protocol** — `omp` (RPC subprocess), `codex` (app-server JSON-RPC), `dsh` / `qwen` / `hermes` (ACP), `opencode` (serve + HTTP/SSE); **headless CLI with a structured event stream** — `gemini` (stream-json), `copilot` (JSONL), `cursor` (stream-json), `crush` (non-interactive run), `goose` (stream-json), `pi` (`-p --mode json`). The platform never knows which one runs. |
80
- | **Per-channel LLM selection** | Each channel picks a **harness → provider → model (+effort)** triple from the harness's live catalog (e.g. `zhipu-coding-plan/glm-5.3-flash` on omp). Members inherit it unless they override — mixing harnesses in one team is a first-class setup, not a workaround. |
81
- | **Harness availability check** | `GET /api/workshop/harnesses` probes each engine's CLI on PATH. The UI disables not-installed engines, and dispatch is hard-checked at every entry point. |
82
- | **Stall-safe supervision** | Task reclaim distinguishes *stuck* from *slow*: the watchdog treats agent tool invocations as a liveness signal, so healthy long-running industrial work survives while genuinely stalled tasks surface to the lead. |
83
- | **Persistent memory** | Private + channel-shared domains; FTS5 with CJK segmentation, optional vector hybrid recall, token-budgeted injection; team chronicle and idle reflections keep accumulating. |
84
- | **Four entry points** | One manager behind every door: **WS** (AEP v1 event stream with seq-resume), **MCP** (~25 in-process tools), **A2A** (JSON-RPC 2.0 + AgentCard), **REST**. |
85
-
86
- #### Industrial stack
87
-
88
- | Capability | Why it matters |
89
- |---|---|
90
- | **Five field protocols** | Modbus TCP, Modbus RTU-over-TCP (serial gateway), OPC UA, MQTT and HTTP/REST — acquisition **and** write-control drivers with connection pools, classified error messages and per-driver connection tests. `mock` covers demos/CI; plugins can register new protocols. |
91
- | **Agent teams, industrial scope** | Agents bind to DAQ/DCW nodes and see semantic cards — physical meaning, units, safe range, recipe window — never raw registers. |
92
- | **Human-approved write control** | DCW writes flow through **safe-range ∩ recipe-window** interlock → optional **HITL approval** → PLC write → **readback verification** → signed write history. |
93
- | **Read-write DCW channels** | Every control node also **reads its PLC value back** through the same calibration path it writes with: periodic + on-demand + agent reads surface **SET vs ACT** side by side — passive observation, never blocked by write interlocks. |
94
- | **Recipe versioning & governance** | Parameter changes are versioned with attribution (user/agent/system + operator + reason). Roll back to any revision or the last-good batch — non-destructively. Stale-node params are skipped and clearly marked. |
95
- | **Line operations** | Lines → products → recipes → batch runs. Recipe windows gate acquisition and interlock writes; every sample is tagged `product/recipe/run` for per-batch isolation. |
96
- | **Multi-modal DAQ frame pipeline** | Multi-point profiles (thickness/scanner) and CCD image frames flow through template sink pipelines: vectors & metadata into Timescale (`daq_frames`), pixels into object storage (MinIO, auto disk fallback); derived-metric thresholds ride the existing alarm chain. |
97
- | **Agent self-audit tools** | `line_context`, `ops_log`, `recipe_log`, `recipe_versions`, `dcw_journal` — agents see exactly which line/product/recipe they control, who did what, and how every value changed. |
98
-
99
- #### Governance, configuration & extension
100
-
101
- | Capability | Why it matters |
102
- |---|---|
103
- | **Line-level permissions** | Industrial data is gated **per production line** with three states (none / read-only / operate), enforced in the data plane — regular users see no line data until granted. |
104
- | **Full-operation audit log** | Every user / agent / system action lands in one queryable log; operators are attributed to "Channel/Member", distinct from users and the system. Streamed live over WS. |
105
- | **Team-scoped plugin switches** | Each team (channel) keeps an **independent plugin switch set** (`channel_plugins`): a disabled plugin's tools are not injected into that team's agents. Plugins themselves are hot-managed via `aw plugin` and the `/plugins` page. |
106
- | **Plugin extension API** | A self-contained directory under `plugins/<name>/` enhances **both halves at once**: `index.mjs` (server: hooks, routes, agent tools, DAQ drivers/processors/templates, config groups, KV, timers) and `client.mjs` (browser: panels injected into named slots, i18n, settings UI). Three scopes — `builtin` (shipped) > `project` (checkout) > `user` (`~/.AgentWorkShop`) — with ~1 s hot reload on enable/disable **and on code edits**. Full contract in [`docs/plugins.md`](./docs/plugins.md). |
107
- | **AML — auto-modeling lab** | Dataset build → training job → leaderboard → promotion gates → model reference, all driven from `/aml` or by agents through 10 `aml_*` tools. Python runtime bootstrapped with `uv` into an `./aml` asset root; artifacts and metadata stay under the config root. |
108
- | **Fully config-driven runtime** | Every runtime knob (memory budgets, compaction, rollback guardrails, retention, backups, log level…) is declared once in the settings descriptor registry with precedence **config.yml < runtime-settings < env** — **99 settings across 16 groups**, no hardcoded defaults in code. |
109
- | **Configurable cadences** | Sampling and query defaults/floors are **live settings** (`daq.sampling.*`, `daq.query.*`): hot-reloaded, clamped on node create/patch, and agent tool descriptions always carry the current values. |
110
-
111
- #### Digital twin
112
-
113
- | Capability | Why it matters |
114
- |---|---|
115
- | **3D digital twin** | Three.js town: place line equipment and channel territories, watch device health, alarms and live values — driven by the same event bus. An adaptive quality ladder (DPR / shadow / bloom tiers, wall-clock FPS budget) matches the machine, and `window.__townStats` exposes real render metrics for perf probes. |
116
-
117
- ---
118
-
119
- ## Interface
120
-
121
- <div align="center">
122
-
123
- | Agent Workbench | Line Operations |
124
- |:---:|:---:|
125
- | ![Agent workbench](https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/workshop.png) | ![Line operations](https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/dcw.png) |
126
-
127
- | DAQ Center | Digital Twin Town |
128
- |:---:|:---:|
129
- | ![DAQ center](https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/daq.png) | ![Digital twin town](https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/town.png) |
130
-
131
- | Dashboard | Monitor & HITL |
132
- |:---:|:---:|
133
- | ![Dashboard](https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/dashboard.png) | ![Monitor and HITL](https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/monitor.png) |
134
-
135
- </div>
136
-
137
- ---
138
-
139
- ## Architecture
140
-
141
- ```mermaid
142
- flowchart TB
143
- subgraph FE["Frontend — Nuxt 4 / Vue 3"]
144
- UI["Workshop UI · 3D Twin · Dashboards"]
145
- WS["AEP client — seq resume"]
146
- end
147
- subgraph SRV["Server — Nitro / h3"]
148
- REST["REST /api/workshop/**"]
149
- HUB["WS Hub — AEP v1"]
150
- A2A["A2A JSON-RPC"]
151
- MCP["MCP Server"]
152
- subgraph RT["Runtime"]
153
- MGR["AgentChannelManager"]
154
- SCH["SchedulerLoop — lead supervision"]
155
- TE["TaskEngine — 7-state machine"]
156
- AR["AgentRuntime × N"]
157
- MEM["AgentMemory — FTS5 + vector"]
158
- BUS["ChannelBus — per-channel seq + ring"]
159
- end
160
- subgraph IND["Industrial"]
161
- DAQ["DAQ gateway — per-node edge runtimes"]
162
- DCW["DCW gateway — write control"]
163
- BR["Bus — inproc / MQTT"]
164
- TSDB["TSDB — SQLite / Timescale"]
165
- end
166
- subgraph HB["Harness adapters — 14 engines"]
167
- MOCK["mock · claude — in-process"]
168
- OMP["omp — RPC subprocess"]
169
- CDX["codex — app-server"]
170
- DSH["dsh · qwen · hermes — ACP"]
171
- OC["opencode — serve"]
172
- FAM["gemini · copilot · cursor · crush · goose · pi — headless CLI"]
173
- end
174
- DB[("SQLite — channels · agents · tasks
175
- messages · memories (FTS5) · events")]
176
- end
177
- UI <--> WS
178
- WS --> BUS
179
- REST & A2A & MCP --> MGR
180
- MGR --> SCH & TE & AR
181
- AR --> MEM
182
- AR --> MOCK & OMP & CDX & DSH & OC & FAM
183
- MGR & TE & MEM & BUS --> DB
184
- DAQ <--> BR --> TSDB
185
- DCW --> BR
186
- DAQ & DCW --> BUS
187
- ```
188
-
189
- **The agent × machine bridge** (the part worth reading the source for):
190
-
191
- ```
192
- agent ──binds to──▶ node (daq: auto / dcw: manual)
193
- │ │
194
- │ my_industrial_nodes ◀── semantic card: meaning · unit · safe range · recipe window
195
- │ daq_query ◀── TSDB history, stats + physical semantics
196
- │ dcw_control ──▶ interlock (safe range ∩ recipe window)
197
- │ ──▶ HITL approval (manual mode, 180 s timeout)
198
- │ ──▶ PLC write → readback check → ACK + write history
199
- ◀── result text with numbers the agent can cite
200
- ```
201
-
202
- ---
203
-
204
- ## Quick start
205
-
206
- ### Prerequisites
207
-
208
- ```bash
209
- node -v # ≥ 23.4.0 (needs built-in node:sqlite)
210
- ```
211
-
212
- > Real-agent harnesses require their CLI on PATH — `omp`, `codex`, `dsh`, `opencode`, `gemini`, `qwen`, `copilot`, `cursor`, `crush`, `goose`, `pi` or `hermes` (any subset; each channel can mix harnesses). `mock` and `claude` (SDK) run in-process and need no PATH CLI. The dashboard "execution engines" panel shows per-engine readiness with a green/grey dot; uninstalled engines link to their official install page. Optional DAQ infrastructure (MQTT broker + TimescaleDB) auto-starts via Docker when reachable (`docker compose up -d`).
213
-
214
- ### Option A — install from npm (recommended)
215
-
216
- ```bash
217
- npm install -g agentworkshop # → `aw` / `agentworkshop` on PATH
218
- aw start # → http://localhost:3001
219
- ```
220
-
221
- The published tarball ships a **prebuilt production bundle** (`.output/`), so an npm install boots straight away — no build step, no build tools. On first launch everything initializes into the config root **`~/.AgentWorkShop`**: the default `config.yml`, a generated `.env` holding a random session secret, `runtime-settings.json`, a docker-compose seed, `prompts/`, `commands/`, `plugins/` (seeded from the SDK examples, **disabled** by default) and an empty `data/` directory. All runtime data (SQLite, JSON repos, backups, logs) lives there too — config and data stay with the install, not the working directory.
222
-
223
- Prefer a one-off run without installing globally?
224
-
225
- ```bash
226
- npx agentworkshop start # no global npm install required
227
- ```
228
-
229
- > `npx` still creates `~/.AgentWorkShop` — running without a global install is not the same as leaving no trace on disk.
230
-
231
- ### Option B — from source
232
-
233
- ```bash
234
- git clone https://github.com/kingdol666/AgentWorkShop.git && cd AgentWorkShop
235
- pnpm install
236
- pnpm dev # → http://localhost:3000 (port from config.yml)
237
- ```
238
-
239
- Production from source:
240
-
241
- ```bash
242
- pnpm build # nuxt build → .output/
243
- pnpm start # port from config.yml → server.prod.port
244
- ```
245
-
246
- > In a source checkout the config root is the project's **`.AgentWorkShop/`** folder (runtime overrides, data, project-level commands), while `config.yml` / `.env` stay at the checkout root, version-controlled as the factory defaults.
247
-
248
- ### Updating
249
-
250
- ```bash
251
- aw update # check + self-update the global install
252
- aw update --check # only report; nothing is installed
253
- npm install -g agentworkshop@latest # manual equivalent
254
- ```
255
-
256
- Releases follow semver. `aw start` verifies the config root on every launch and migrates the legacy pre-`home` `data/` layout into it (newest file wins), so data survives upgrades. SQLite schema migrations run server-side at boot. Current version: **v0.7.39** — see [Releases](https://github.com/kingdol666/AgentWorkShop/releases).
257
-
258
- ### Your first agent × line session (~2 minutes)
259
-
260
- 1. **Sign in** — register in the sidebar (or `POST /api/users/register`).
261
- 2. **Build a line** — `Line Operations` → create a line, add DAQ nodes (e.g. `daq-temp-tc`) and control nodes (e.g. `dcw-temp-sp`), create a product + recipe, hit **Start**. Live values start flowing.
262
- 3. **Create a team** — `Agent Workshop` → pick a lead + workers, **deploy** into a channel.
263
- 4. **Bind nodes** — open the agent's detail panel → bind the DAQ node (*auto*) and the control node (*manual* = needs your approval).
264
- 5. **Submit the goal** — *"Analyze the last 5 minutes of melt temperature; if deviation from 182 °C exceeds 1 °C, correct the setpoint (wait for my approval)."*
265
- 6. **Approve** — the agent reads real history, computes the mean, requests the write → approve in the HITL panel → watch the setpoint change and the goal close with a numeric report.
266
-
267
- ---
268
-
269
- ## Configuration & CLI — config-driven by design
270
-
271
- One runtime, one source of truth. **`config.yml`** declares defaults; **`runtime-settings.json`** inside the config root carries runtime overrides; environment variables and CLI flags sit on top. Every editable key is described once in `shared/config/schema.json` (type, range, enum, live-vs-restart) and surfaced through the same descriptors in **both the UI and the CLI**.
272
-
273
- ```
274
- config.yml (defaults) < .AgentWorkShop/runtime-settings.json (runtime) < env vars / CLI flags
275
- ```
276
-
277
- The config root is **`~/.AgentWorkShop`** for a global install (`npm i -g`) — wherever you run `aw` from — and **`<repo>/.AgentWorkShop`** in a source checkout (with `config.yml` / `.env` staying at the checkout root as version-controlled factory defaults). `AW_HOME` redirects it; `AW_MODE=home` forces the global shape.
278
-
279
- ### Live settings, persisted, hot-reloaded
280
-
281
- - The **Settings → Runtime config** tab renders every editable key from the descriptors — change server ports, theme, API timeouts, locale or the approval gate, hit save.
282
- - `live` keys apply instantly (theme, title, timeouts, approval gate, DAQ sampling cadences, TSDB query buckets…) over a server-sent event stream — no reload, no restart.
283
- - `restart` keys (ports, hosts) persist to disk and take effect on the next launch of the matching mode (`aw dev` / `aw start`).
284
- - One channel for every writer: the UI, the CLI and the server's file watcher all converge on the same settings file, so a change made anywhere shows up everywhere.
285
-
286
- Example — retune the acquisition and query cadences live:
287
-
288
- ```bash
289
- aw config set daq.sampling.defaultIntervalMs 2000 # new nodes sample every 2 s
290
- aw config set daq.sampling.minIntervalMs 500 # per-node floor (create/patch clamp)
291
- aw config set daq.query.defaultBucketMs 3000 # TSDB reads default to a 3 s bucket
292
- aw config set daq.query.minBucketMs 500 # query floor (samples/line query/agent tool)
293
- ```
294
-
295
- Agent tool descriptions are re-rendered with the current values on every injection, so an LLM always sees the floor and default that will actually apply to its `daq_query` calls.
296
-
297
- ### The `aw` CLI
298
-
299
- | Command | What it does |
300
- |---|---|
301
- | `aw start · aw dev · aw build` | Production server / dev server / build — ports from the effective config; first `start` builds once |
302
- | `aw stop` | Stop a running `aw` service instance via the single-instance lock |
303
- | `aw config list · get · set · unset · reset` | Read & write runtime settings (validated against the schema, atomic writes) |
304
- | `aw plugin list · create · enable · disable` | Manage plugins across all three scopes: inspect, scaffold (project scope; `--global` for user scope), enable/disable (state file, ~1 s hot reload on the running server) |
305
- | `aw home` | Inspect / initialize the config root `.AgentWorkShop` |
306
- | `aw init <dir>` | Scaffold a runnable project (full config system + CLI included) |
307
- | `aw register <path\|url\|npm:pkg>` | Register a new command — project-local or `--global` |
308
- | `aw update` | Check npm for the latest release and self-update the global install |
309
- | `aw doctor` | Environment + project health check (node, config, ports, keys) |
310
- | `aw status` | Live overview: mode, config sources, running server, command table |
311
- | `aw tui` | Terminal workbench: channel/agent management, task submission, live monitor pane, HITL answering (see [`docs/tui.md`](./docs/tui.md) · [`tui/README.md`](./tui/README.md)) |
312
- | `aw version` | Print the CLI/package version (alias `v`) |
313
-
314
- Global flags: `--help/-h` · `--version/-v` · `--json` (machine-readable) · `--root <dir>` · `--debug`.
315
-
316
- Exit codes: **0** success · **1** runtime error · **2** usage error. With `--json`, failures come back as an envelope carrying `{ ok: false, error: 'unknown-command' \| 'no-project' \| 'usage' \| 'internal' \| <code> }`, so automation can branch without parsing stderr.
317
-
318
- ### Command registration
319
-
320
- Commands are plain modules exporting `{ meta, run }`. Drop one into a scanned directory and it's live on the next invocation — no registry bookkeeping, convention over configuration:
321
-
322
- | Scope (highest wins) | Directory |
323
- |---|---|
324
- | project | `<root>/.AgentWorkShop/commands/` |
325
- | user | `~/.AgentWorkShop/commands/` |
326
- | built-in | packaged with the CLI (`cli/commands/`) |
327
-
328
- `aw register <file|url|npm:pkg>` copies a command into the right scope (`--global` for user scope); `aw help` lists everything that's registered.
329
-
330
- ```js
331
- // ~/.AgentWorkShop/commands/hello.mjs
332
- export const meta = { name: 'hello', group: 'Custom', summary: 'Say hi', usage: 'aw hello [--name <n>]' }
333
- export async function run(argv, ctx) {
334
- console.log(`Hi ${argv.flags.name ?? 'AW'} — mode: ${ctx.mode}`)
335
- }
336
- ```
337
-
338
- ---
339
-
340
- ## The industrial stack in detail
341
-
342
- ### Data acquisition (DAQ)
343
-
344
- - **Five protocol drivers**: Modbus TCP, Modbus RTU-over-TCP (serial gateway), OPC UA, MQTT, HTTP/REST — connection pools, classified error messages, per-driver connection tests; the driver registry accepts plugin-registered protocols.
345
- - **Per-node edge runtimes**: independent sampling cadence, publish cadence, in-flight mutex per node — one slow driver never blocks its neighbors. Sampling and query defaults/floors are driven by the live `daq.sampling.*` / `daq.query.*` settings.
346
- - **Pipeline**: driver → queue (in-process or MQTT, offline buffer on disconnect) → consumer with out-of-order defense → three-way fan-out: WS live push (gated), TSDB batch write, device-twin writeback.
347
- - **Robustness**: TSDB single-in-flight writes with bounded retries, buffer backpressure with drop counters, real loss metrics exposed on `daq.controller` frames.
348
- - **Alarms**: recipe-scoped monitoring windows with **2 % hysteresis + 3-tick debounce**; alarm/offline transitions are instant (safety first).
349
-
350
- ### Write control (DCW)
351
-
352
- - Engineering-unit writes: `linear` calibration (scale/offset) PLC↔physical, **readback verification** with deadband tolerance, ACK states and write history.
353
- - **Interlock**: with a line running, the active recipe's parameter window *replaces* the node's global safe range for that node.
354
- - **HITL**: `manual`-mode bindings suspend the write for user approval (deduped per agent+node; re-validation at approval time — permission is re-checked when you click approve).
355
-
356
- ### Recipe & batch
357
-
358
- `Line → Product → Recipe → Run`. Starting a run applies recipe params node-by-node (each write verified), gates acquisition per line, and tags every sample with `line/product/recipe/run` — per-product data isolation with five-dimension queries (line × product × recipe × time × node).
359
-
360
- ### AML — auto-modeling lab
361
-
362
- The modeling half of the loop: `/aml` builds **datasets** out of tagged telemetry, submits **training jobs** to a `uv`-managed Python runtime, ranks runs on a **leaderboard**, and promotes a model only when it clears the configured **gates** (NRMSE, rollout NRMSE, validation/test gap, minimum rows and runs). Promoted models are referenced by id, so an MPC or shadow-twin controller can consume a versioned artifact instead of a vague "latest".
363
-
364
- - Agents do the same work through 10 tools (`aml_dataset_build`, `aml_job_submit`, `aml_job_status`, `aml_leaderboard`, `aml_model_promote`, …) — submit a goal and let the team train and report.
365
- - The Python runtime bootstraps itself with `uv` into an `./aml` asset root inside the config root; dataset/artifact/metadata paths, disk quota, job timeout, concurrency and retention are all **settings** (16 in the `aml` group), not constants.
366
- - Governance defaults are conservative: cross-recipe datasets are refused unless explicitly allowed, and every job is attributed.
367
-
368
- ---
369
-
370
- ## Usage
371
-
372
- ### Authentication
373
-
374
- Email + password login issues a **bearer token** (multiple tokens per user, individually revocable).
375
-
376
- ```bash
377
- # register
378
- curl -X POST http://localhost:3000/api/users/register \
379
- -H 'content-type: application/json' \
380
- -d '{"email":"you@example.com","password":"secret","name":"you"}'
381
-
382
- # every workshop call
383
- curl http://localhost:3000/api/workshop/channels \
384
- -H 'authorization: Bearer <token>'
385
- ```
386
-
387
- ### Line-level permissions
388
-
389
- Industrial data is gated **per production line** with three states, managed by an admin
390
- in the built-in **Permissions** page (`/permissions`, admin-only in the sidebar):
391
-
392
- | State | DAQ nodes | DCW (write) nodes | Visibility |
393
- | --- | --- | --- | --- |
394
- | **none** (default for regular users) | hidden | hidden | line data withheld server-side — invisible in Line Ops, DAQ center and the digital twin |
395
- | **read-only** | read | ✕ | line visible, values stream, no writes / dispatch / device binding |
396
- | **operate** | read | read + write | full access incl. setpoint writes, dispatch, binding |
397
-
398
- - `admin` / `editor` roles are unrestricted (operations roles).
399
- - Regular users **default to none** — they see no line data until granted.
400
- - Enforcement lives in the data plane: list endpoints filter by grant, write/dispatch
401
- endpoints return a human-readable 403, and Agent↔node bindings validate the line grant
402
- (DAQ needs read-only+, DCW needs operate).
403
- - Plugins get the same surface via `ctx.permissions` (`lineMode` / `visibleLineIds` /
404
- `listGrants` / `setGrants`) plus a `permissions:changed` lifecycle hook; the SDK REST
405
- client exposes `client.permissions.overview()` / `client.permissions.set(...)`.
406
-
407
- ### Execution modes
408
-
409
- Prefix the task description (or pick in the composer UI):
410
-
411
- | Mode | Semantics | Config |
412
- |---|---|---|
413
- | `goal` | lead decomposes → workers deliver → **lead judges satisfaction**; unmet → more subtasks; met → parent completes. | `goalCriteria` |
414
- | `loop` | replay the same task on a fixed interval. | `intervalMs` (default 60 000), `maxIterations` (default ∞) |
415
- | `pipeline` | ordered stages; stage N+1 consumes stage N's output. | `stages: [{name, description, assigneeId?}]` |
416
-
417
- ### The four entry points
418
-
419
- | Entry | Endpoint | Audience |
420
- |---|---|---|
421
- | **WS** | `/api/workshop/ws?channelId=…` | Dashboards / UI — AEP v1 envelopes, per-channel monotonic `seq`, 5 000-event ring, `lastSeq` resume, snapshot fallback. |
422
- | **MCP** | in-process server, ~25 tools | Agents (omp host tools) — management + job-face tools, channel-scoped. |
423
- | **A2A** | `POST /api/workshop/a2a/:agentId/rpc` | External agents — JSON-RPC 2.0, `AgentCard` at `/card`, `tasks/sendSubscribe` SSE. |
424
- | **REST** | `/api/workshop/**` | Humans / scripts — full management face. |
425
-
426
- ### Task state machine
427
-
428
- ```
429
- SUBMITTED ─▶ ASSIGNED ─▶ WORKING ─▶ WAITING ─▶ COMPLETED
430
- │ │ │ │
431
- └────────────┴───────────┴──▶ CANCELED / FAILED ─▶ (retry ≤ 3 or cancel)
432
- ```
433
-
434
- ---
435
-
436
- ## Verified end-to-end
437
-
438
- Every claim above is backed by a suite you can re-run. The closed-loop suite drives a
439
- **production instance over real simulated plant protocols** (Modbus TCP/RTU, OPC UA, MQTT,
440
- HTTP + an MQTT/Timescale pipeline) with a real LLM agent, and asserts on the database,
441
- the event stream and the HTTP API — not on mocks.
442
-
443
- | Suite | Latest result | What it covers | Reproduce |
444
- |---|---|---|---|
445
- | `e2e-full-closedloop.mjs` | **124 PASS / 0 FAIL** (2026-09-12, v0.7.36) | registration → login → line/product/recipe → DAQ sampling → agent bound to nodes → `daq_query` → `dcw_control` → HITL approval → PLC write → readback → recipe rollback → cascade delete → data-root isolation | `node scripts/e2e-full-closedloop.mjs http://127.0.0.1:3111` |
446
- | `e2e-aml.ts --real` | 0 failures (2026-09-11) | AML datasets → job submit → status/logs → leaderboard → promotion gates, against the real Python runtime | `node node_modules/tsx/dist/cli.mjs --tsconfig .nuxt/tsconfig.server.json scripts/e2e-aml.ts --real` |
447
- | Five-protocol live line | 37/37 (re-verified 2026-09-12 on a clean instance) | driver connectivity, sampling into Timescale, DCW dispatch + readback per protocol, agent closed loop, HITL over a real OPC UA write, recipe + param-ledger rollback | `node scripts/_dbg-live-line-e2e.mjs` |
448
- | Production API live | 64/64 (re-verified 2026-09-12 on a clean instance) | persistence across restart, template CRUD, task assign/complete/cancel/loop/pipeline, A2A + mailbox, WS broadcast, MCP endpoint, cascade delete | `AW_E2E_TOKEN=<token> node scripts/api-live-e2e.mjs` |
449
- | Line permissions / audit-negative | 21/21 + 9/9 | three-state line grants with human-readable 403s, binding-subject validation, revocation convergence, unauthenticated WS receives zero telemetry | `node scripts/_dbg-perms-e2e.mjs <base> <adminPass>` · `node scripts/_dbg-audit-neg-e2e.mjs <base> <adminPass>` |
450
- | Render regression | 30/30 | DAQ table integrity (row count aligned with the API), WS-driven row updates, filters, detail page, 3D town + model library, 7-page smoke, zero page errors | `node scripts/_dbg-render-regression.mjs <base> <email> <pass>` |
451
- | Multi-harness parallel | 21 | omp closed loop · codex real register write · dsh real acquisition · opencode recipe write+rollback — four engines on one running line | `node scripts/e2e-multiharness-team.mjs` |
452
- | Offline unit/property suites | all green | AEP event index (`test-events-index`), LRU, data-root split (`test-data-root`), log flooding, rollback index, plugin hardening, memory month query, CLI exit codes (`test-cli-exit`), SDK surface (`test-sdk-surface`) | `node scripts/test-<name>.mjs` |
453
-
454
- The five-protocol and API-live rows are the historical **v0.7.20** acceptance baseline —
455
- *156 assertions, 0 failures*, full report in [`docs/audit/e2e-2026-09-07.md`](./docs/audit/e2e-2026-09-07.md).
456
- The closed-loop and AML rows are the current-head runs. Perf probing:
457
- `scripts/_dbg-render-perf.mjs`.
458
-
459
- ---
460
-
461
- ## Project layout
462
-
463
- ```
464
- AgentWorkShop/
465
- ├── bin/ · cli/ # aw CLI — command registry · built-in commands · config engine
466
- ├── app/ # Nuxt 4 frontend (srcDir)
467
- │ ├── pages/ # / · /workshop · /workshop/agents · /workshop/teams
468
- │ │ # /workshop/channel-templates · /workshop/w/:id
469
- │ │ # /town · /daq · /daq/:id · /dcw · /dcw/:id
470
- │ │ # /aml · /monitor · /logs · /permissions
471
- │ │ # /plugins · /users · /tokens · /settings
472
- │ ├── components/workshop/ # timeline · lanes · task board · memory panel · 3D town
473
- │ └── stores/composables/ # Pinia + AEP client
474
- ├── server/
475
- │ ├── api/ # REST + WS + A2A + MCP routes
476
- │ ├── services/workshop/
477
- │ │ ├── runtime/ # manager · scheduler-loop · task-engine · memory · mailbox
478
- │ │ ├── agents/ # AgentInterface: 14 engines (+ industrial tools)
479
- │ │ ├── daq/ dcw/ aml/ # edge runtimes · drivers · bus · storage · modeling lab
480
- │ │ └── db/ # repos over node:sqlite
481
- │ ├── mcp/ # MCP server (25 tools)
482
- │ ├── plugins-builtin/ # plugins shipped with the package (diag-bridge · rag-bridge)
483
- │ └── plugins/ # runtime assembly (singletons)
484
- ├── sdk/ # agentworkshop/sdk — plugin context, hook bus, REST client, browser SDK
485
- ├── tui/ # terminal workbench (aw tui)
486
- ├── shared/
487
- │ └── config/ # schema.json (99 setting descriptors) + engine (merge/validate/persist) + path resolver
488
- ├── config.yml # factory defaults (read at build/start; version comes from package.json)
489
- ├── .AgentWorkShop/ # config root in a checkout — prompts (versioned) + runtime overrides · data · logs · commands (git-ignored)
490
- ├── data/ # legacy pre-migration location (auto-migrated into the config root)
491
- └── scripts/ # launchers · home bootstrap · E2E · verification suites
492
- ```
493
-
494
- ## Tech stack
495
-
496
- | Layer | Tech |
497
- |---|---|
498
- | Framework | [Nuxt 4](https://nuxt.com) + Nitro (WebSocket) |
499
- | UI | Vue 3.5 · Pinia · Ant Design Vue · UnoCSS · Three.js · ECharts |
500
- | Language | TypeScript 5.7 across the stack; `shared/` used by both sides |
501
- | CLI | Node ESM CLI with a pluggable command registry (`bin/aw.mjs`) |
502
- | Persistence | `node:sqlite` (zero native deps) + FTS5 + optional `sqlite-vec`; TimescaleDB for time-series |
503
- | Validation | `zod` at every message boundary |
504
- | Interop | `@modelcontextprotocol/sdk` · A2A (JSON-RPC 2.0) · AEP v1 (in-house WS protocol) |
505
- | Field bus | `modbus-serial` · `node-opcua` · `mqtt` |
506
-
507
- ## Development
508
-
509
- ```bash
510
- pnpm dev # dev server (port from effective config)
511
- pnpm cli … # the CLI in-repo: pnpm cli config list
512
- pnpm tui # terminal workbench against a running instance
513
- pnpm build && pnpm start
514
- pnpm typecheck
515
- pnpm lint
516
- pnpm test:api-live # API suite against a running server
517
- node scripts/e2e-full-closedloop.mjs # full closed loop (server must be running)
518
- node scripts/test-sdk-surface.mjs # SDK export-surface guard
519
- ```
520
-
521
- The docs site lives in `docs/site/` (VitePress) and is deployed to GitHub Pages by
522
- [`.github/workflows/deploy-docs.yml`](./.github/workflows/deploy-docs.yml):
523
-
524
- ```bash
525
- cd docs/site && npx vitepress dev # preview locally
526
- cd docs/site && npx vitepress build # production build → .vitepress/dist
527
- ```
528
-
529
- The workflow syncs `docs/{cli,plugins,sdk}.md` (and their `.en.md` twins) into the site before
530
- building, so those files are the single source of truth for the single-page guides.
531
-
532
- ## Roadmap
533
-
534
- | Capability | Status |
535
- |---|---|
536
- | Channel runtime, lead orchestration, 7-state task engine | Shipped |
537
- | Four entry points: WS (AEP v1) · MCP · A2A · REST | Shipped |
538
- | Persistent memory (FTS5 + optional vector hybrid) | Shipped |
539
- | Industrial stack: DAQ · DCW write control · lines/recipes/runs | Shipped |
540
- | Agent ↔ node binding + HITL approval + interlock | Shipped |
541
- | 3D digital-twin town · line operations UI · dashboards | Shipped |
542
- | Full-feature live E2E (agent reads/writes a real line, 23 checks) | Shipped |
543
- | Runtime configuration system: settings persistence · hot reload · settings UI | Shipped |
544
- | `aw` CLI: config · run · init · register · doctor | Shipped |
545
- | Multi-harness registry: omp · codex · dsh · opencode subprocess engines | Shipped |
546
- | Five field protocols: Modbus RTU-over-TCP · MQTT · HTTP (acquisition + write control) | Shipped |
547
- | Harness availability probing + dispatch-time engine checks (UI disable + 409) | Shipped |
548
- | Recipe versioning with attribution + non-destructive rollback (UI + agent tools) | Shipped |
549
- | Agent self-audit: line_context / ops_log / recipe_log / recipe_versions / dcw_journal | Shipped |
550
- | Multi-harness parallel live E2E on a real protocol line (four engines, one line) | Shipped |
551
- | HITL approval flow verified over real OPC UA writes | Shipped |
552
- | Bilingual docs (简体中文 / English) with VitePress language switcher | Shipped |
553
- | Per-channel LLM provider/model selection from live harness catalogs | Shipped |
554
- | Configurable DAQ/TSDB cadences (sampling & query defaults + floors, live) | Shipped |
555
- | Team-scoped plugin switches (create-time pick + team dialog, per-channel tool injection) | Shipped |
556
- | Plugin hot management: `/plugins` page + `aw plugin list/enable/disable` | Shipped |
557
- | Rendering perf pass (v0.7.27): DAQ main-thread blocking −90%, twin −69%, adaptive quality restored to top tier; `window.__townStats` instrumentation | Shipped |
558
- | Plugin system v2: browser panel injection, plugin-scoped settings/groups, plugin i18n, host runtime services (`ctx.services`/`ctx.daq`/`ctx.omp`) | Shipped |
559
- | Instrument Glass material layer (v0.7.36): three-tier translucent materials, vibrancy, specular edges, spring motion, per-page route transitions | Shipped |
560
- | Realtime pipeline optimizations: DAQ frame indexing O(n²)→O(n), incremental per-agent event index, chart in-place updates, size-aware JSON persistence | Shipped |
561
- | AML auto-modeling lab: dataset build · job orchestration (uv-managed Python) · leaderboard · promotion gates · 10 agent tools | Shipped |
562
- | Claude Agent SDK adapter — resident sessions with same-turn steer and `canUseTool` HITL | Shipped |
563
- | Production hardening: TLS, MQTT auth, OPC UA sign+encrypt defaults, structured audit log | Planned |
564
- | Edge deployment shape: standalone edge-agent + central broker | Planned |
565
- | Alarm outbound delivery (email/webhook) + ack workflow | Planned |
566
- | CI pipeline (typecheck + lint + e2e) — docs deployment already runs on GitHub Actions | Planned |
567
- | License: PolyForm Noncommercial 1.0.0 (source-available, non-commercial) | Shipped |
568
-
569
- ## License
570
-
571
- AgentWorkShop is an independent project and is **not an official product of Anthropic** or any LLM vendor. It integrates with agent harnesses (e.g. `omp`) through their public interfaces.
572
-
573
- **AgentWorkShop is source-available software, licensed under the [PolyForm Noncommercial 1.0.0](./LICENSE).**
574
-
575
- - **Permitted** — personal study, research, hobby projects, teaching, and use by noncommercial organizations (charities, education, public research, government).
576
- - **Not permitted without prior written permission** — any **commercial use**: selling, paid services, integrating into commercial products, or production use serving a business. Commercial licenses are available from the copyright holder.
577
- - **When you redistribute** the software, you must pass through the `Required Notice` line and these terms.
578
-
579
- For commercial licensing, contact: [GitHub @kingdol666](https://github.com/kingdol666) · kingdol6080@gmail.com
580
-
581
- <div align="center">
582
-
583
- <a href="https://star-history.com/#kingdol666/AgentWorkShop&Date">
584
- <picture>
585
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=kingdol666/AgentWorkShop&type=Date&theme=dark" />
586
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=kingdol666/AgentWorkShop&type=Date" />
587
- <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=kingdol666/AgentWorkShop&type=Date" width="80%" />
588
- </picture>
589
- </a>
590
-
591
- </div>
1
+ <div align="center">
2
+
3
+ <img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/hero.png" alt="AgentWorkShop — agent teams driving a real production line" width="100%" />
4
+
5
+ <br />
6
+
7
+ # AgentWorkShop
8
+
9
+ **Where AI agent teams meet the production line.**
10
+
11
+ [![npm version](https://img.shields.io/npm/v/agentworkshop?logo=npm&logoColor=white&label=npm&color=CB3837)](https://github.com/kingdol666/AgentWorkShop)
12
+ [![npm downloads](https://img.shields.io/npm/dm/agentworkshop?logo=npm&logoColor=white&label=downloads&color=CB3837)](https://github.com/kingdol666/AgentWorkShop)
13
+ [![GitHub release](https://img.shields.io/github/v/release/kingdol666/AgentWorkShop?logo=github&label=release&color=35e0a0)](https://github.com/kingdol666/AgentWorkShop/releases)
14
+ [![Stars](https://img.shields.io/github/stars/kingdol666/AgentWorkShop?logo=github&label=stars&color=35e0a0)](https://github.com/kingdol666/AgentWorkShop/stargazers)
15
+ [![Last commit](https://img.shields.io/github/last-commit/kingdol666/AgentWorkShop?logo=git&logoColor=white&label=last%20commit)](https://github.com/kingdol666/AgentWorkShop/commits)
16
+ [![Issues](https://img.shields.io/github/issues/kingdol666/AgentWorkShop?logo=github&label=issues)](https://github.com/kingdol666/AgentWorkShop/issues)
17
+ [![License](https://img.shields.io/badge/license-PolyForm%20Noncommercial%201.0.0-8A2BE2?logo=openaccess&logoColor=white)](./LICENSE)
18
+
19
+ [![Nuxt 4](https://img.shields.io/badge/Nuxt-4-00DC82?logo=nuxt&logoColor=white)](https://nuxt.com)
20
+ [![Vue 3.5](https://img.shields.io/badge/Vue-3.5-42B883?logo=vuedotjs&logoColor=white)](https://vuejs.org)
21
+ [![TypeScript 5.7](https://img.shields.io/badge/TypeScript-5.7-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org)
22
+ [![Node ≥ 23.4](https://img.shields.io/badge/Node.js-%E2%89%A5%2023.4-3C873A?logo=nodedotjs&logoColor=white)](https://nodejs.org)
23
+ [![SQLite node:sqlite](https://img.shields.io/badge/SQLite-node%3Asqlite-003B57?logo=sqlite&logoColor=white)](https://nodejs.org/api/sqlite.html)
24
+ [![Modbus · OPC UA · MQTT · HTTP](https://img.shields.io/badge/field%20bus-Modbus%20%C2%B7%20OPC%20UA%20%C2%B7%20MQTT%20%C2%B7%20HTTP-41c8f4?logo=siemens&logoColor=white)](./docs/site/guide/daq-protocols.md)
25
+ [![Plugins](https://img.shields.io/badge/plugins-hot%20reload-8b5cf6?logo=puzzle&logoColor=white)](./docs/plugins.md)
26
+ [![Docs](https://img.shields.io/badge/docs-VitePress%20%C2%B7%20%E4%B8%AD%2FEN-ffd75e?logo=vitepress&logoColor=black)](https://kingdol666.github.io/AgentWorkShop)
27
+ [![PRs welcome](https://img.shields.io/badge/PRs-welcome-ff69b4?logo=git&logoColor=white)](https://github.com/kingdol666/AgentWorkShop/pulls)
28
+
29
+ **[简体中文](./README-zh.md)** · **[Documentation](https://kingdol666.github.io/AgentWorkShop)** · **[Releases](https://github.com/kingdol666/AgentWorkShop/releases)** · **[Changelog](./changelog.md)** · **[Plugin API](./docs/plugins.md)** · **[SDK](./docs/sdk.md)**
30
+
31
+ <sub><b>v0.7.41</b> · 14 agent engines · 6 field protocols · 99 runtime settings · bilingual docs (简体中文 / English)</sub>
32
+
33
+ <br />
34
+
35
+ *A configuration-driven platform where **AI agent teams** and an **industrial digital twin** share one runtime — agents query real telemetry, issue supervisory setpoints through human-approved write control, and every event streams live to a 3D twin.*
36
+
37
+ </div>
38
+
39
+ > [!IMPORTANT]
40
+ > **Positioning: supervisory layer.** AgentWorkShop is a *supervisory* (SCADA-adjacent) layer for production-line management, digital twins, DAQ and agent orchestration, operating at **second-level soft real-time**.
41
+ > It is **not** a hard real-time controller: any time-critical loop (**< 10 ms**, interlocks, safety, servo) **must live inside the PLC**. Setpoints written here are advisory — plant-side logic may veto.
42
+
43
+ ---
44
+
45
+ <table>
46
+ <tr>
47
+ <td width="33%" valign="top">
48
+
49
+ **FIGURE INDEX**
50
+
51
+ `FIG.01` closed loop ·<br/>
52
+ `FIG.02` DAQ console ·<br/>
53
+ `FIG.03` line operations ·<br/>
54
+ `FIG.04` digital twin ·<br/>
55
+ `FIG.05` dashboard ·<br/>
56
+ `FIG.06` responsive
57
+
58
+ </td>
59
+ <td width="33%" valign="top">
60
+
61
+ **JUMP TO**
62
+
63
+ [What is this?](#what-is-this) · [Highlights](#highlights)<br/>
64
+ [Interface](#the-interface) · [Architecture](#architecture)<br/>
65
+ [Quick start](#quick-start) · [Configuration & CLI](#configuration--cli--config-driven-by-design)<br/>
66
+ [Industrial stack](#the-industrial-stack-in-detail) · [Usage](#usage)<br/>
67
+ [Verification](#verified-end-to-end) · [Project layout](#project-layout)<br/>
68
+ [Tech stack](#tech-stack) · [Development](#development)<br/>
69
+ [Roadmap](#roadmap) · [License](#license)
70
+
71
+ </td>
72
+ <td width="33%" valign="top">
73
+
74
+ **AT A GLANCE**
75
+
76
+ Supervisory layer, second-level soft real-time<br/>
77
+ 14 harness engines · 4 entry points<br/>
78
+ 6 field protocols (5 built-in + serial plugin, read + write)<br/>
79
+ 7-state task machine · FTS5 + vector memory<br/>
80
+ Hot-reloadable plugins · SDK · CLI · TUI
81
+
82
+ </td>
83
+ </tr>
84
+ </table>
85
+
86
+ ---
87
+
88
+ ## Documentation
89
+
90
+ Docs are bilingual — the [VitePress site](https://kingdol666.github.io/AgentWorkShop) ships a language switcher (简体中文 / English) across every section. Deep-dive pages ship in this repo too, and the CLI copies them into the published tarball:
91
+
92
+ | Topic | Online | In-repo | What it covers |
93
+ |---|---|---|---|
94
+ | **Getting started** | [Guide](https://kingdol666.github.io/AgentWorkShop/guide/getting-started) | `docs/site/guide/` | install → first run → first agent × line session, configuration, DAQ protocols, DCW read/write, HITL, recipe versioning, multi-harness teams, line permissions, AML |
95
+ | **Plugin development** | [Plugin guide](https://kingdol666.github.io/AgentWorkShop/plugins/) | [`docs/plugins.md`](./docs/plugins.md) | the full extension contract: three scopes, `index.mjs` manifest, `ctx` server/browser surface, `settings`/`groups` declarations, lifecycle events, i18n, panels, team-scoped switches, a real example |
96
+ | **SDK** | [SDK guide](https://kingdol666.github.io/AgentWorkShop/sdk/) | [`docs/sdk.md`](./docs/sdk.md) | `agentworkshop/sdk` as a programming client (platform REST client with envelope handling) and as the plugin extension base; TypeScript types; browser-side SDK |
97
+ | **CLI** | [CLI manual](https://kingdol666.github.io/AgentWorkShop/cli/) | [`docs/cli.md`](./docs/cli.md) | all 14 `aw` commands, global options, exit codes, dual-mode path model, the command-registration system, maintainer publish guide |
98
+ | **AML** | [AML guide](https://kingdol666.github.io/AgentWorkShop/guide/aml) | [`docs/aml.md`](./docs/aml.md) | auto-modeling lab: dataset build, job orchestration, model registry, promotion gates, agent tools |
99
+ | **TUI** | — | [`docs/tui.md`](./docs/tui.md) · [`tui/README.md`](./tui/README.md) | terminal workbench: channels, agents, tasks, live monitor, HITL answering |
100
+ | **Multi-harness architecture** | — | [`docs/multi-harness-architecture.md`](./docs/multi-harness-architecture.md) | engine taxonomy, normalized session contract, provider/model catalog, failure modes |
101
+
102
+ ---
103
+
104
+ ## What is this?
105
+
106
+ AgentWorkShop started as a **multi-agent software workshop** — channels of coding agents with a lead-agent scheduler, a 7-state task machine, persistent memory, and four interoperable entry points (WebSocket / MCP / A2A / REST).
107
+
108
+ It grew an **industrial half**: a full data-acquisition and write-control stack (Modbus TCP / OPC UA), production lines with recipes and batch runs, a 3D digital-twin town, an **auto-modeling lab** (dataset → training job → leaderboard → gated promotion) — and the bridge that makes it unique: **agents can be granted bound, permission-scoped access to real industrial nodes**, query their live telemetry with physical semantics attached, and drive write operations through an interlock → human-in-the-loop → readback pipeline.
109
+
110
+ It is also **extensible by design**: a self-contained plugin can enhance the server (hooks, routes, agent tools, DAQ drivers, config groups) and the browser (panels, i18n) at the same time, and the same surfaces are available to ordinary programs through the SDK — see [`docs/plugins.md`](./docs/plugins.md) and [`docs/sdk.md`](./docs/sdk.md).
111
+
112
+ The result: submit a goal like *"analyze the melt temperature trend and optimize the setpoint"* — and an agent team reads real sensor history, computes statistics, proposes a new setpoint, waits for your approval in the HITL panel, writes it to the PLC, verifies the readback, and reports the numbers back. **End to end, verified by automated E2E.**
113
+
114
+ <div align="center">
115
+
116
+ ### FIG.01 — The closed loop
117
+
118
+ <img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/fig-01-closedloop.gif" alt="An agent team reads live telemetry, proposes a setpoint, waits for approval, writes to the PLC and verifies the readback" width="88%" />
119
+
120
+ <sub><b>Goal → read → compute → approve → write → readback → report.</b><br/>
121
+ Recorded against a running instance: real DAQ history, real write control, real HITL approval.</sub>
122
+
123
+ </div>
124
+
125
+ > [!NOTE]
126
+ > Every figure in this README is a recording or screenshot of a **running** instance — not a mockup. The numbers on screen come from seeded industrial data flowing through the same code paths the product ships.
127
+
128
+ ---
129
+
130
+ ## Highlights
131
+
132
+ #### Agent team runtime
133
+
134
+ | Capability | Why it matters |
135
+ |---|---|
136
+ | **Lead-agent orchestration** | Each channel has one lead: decomposes goals, dispatches to idle workers, reassigns failures, judges goal satisfaction. LLM decisions with a deterministic rule-engine fallback — the system never stalls. |
137
+ | **Three execution modes** | `goal` (satisfaction judging) · `loop` (fixed-interval replay) · `pipeline` (ordered stages). 7-state task machine with progress, artifacts and full history. |
138
+ | **Harness-agnostic** | One `AgentInterface`, **14 engines** in three transport classes: **in-process** — `mock` (no LLM), `claude` (Claude Agent SDK, resident session, same-turn steer); **persistent session over a protocol** — `omp` (RPC subprocess), `codex` (app-server JSON-RPC), `dsh` / `qwen` / `hermes` (ACP), `opencode` (serve + HTTP/SSE); **headless CLI with a structured event stream** — `gemini` (stream-json), `copilot` (JSONL), `cursor` (stream-json), `crush` (non-interactive run), `goose` (stream-json), `pi` (`-p --mode json`). The platform never knows which one runs. |
139
+ | **Per-channel LLM selection** | Each channel picks a **harness → provider → model (+effort)** triple from the harness's live catalog (e.g. `zhipu-coding-plan/glm-5.3-flash` on omp). Members inherit it unless they override — mixing harnesses in one team is a first-class setup, not a workaround. |
140
+ | **Harness availability check** | `GET /api/workshop/harnesses` probes each engine's CLI on PATH. The UI disables not-installed engines, and dispatch is hard-checked at every entry point. |
141
+ | **Stall-safe supervision** | Task reclaim distinguishes *stuck* from *slow*: the watchdog treats agent tool invocations as a liveness signal, so healthy long-running industrial work survives while genuinely stalled tasks surface to the lead. |
142
+ | **Persistent memory** | Private + channel-shared domains; FTS5 with CJK segmentation, optional vector hybrid recall, token-budgeted injection; team chronicle and idle reflections keep accumulating. |
143
+ | **Four entry points** | One manager behind every door: **WS** (AEP v1 event stream with seq-resume), **MCP** (~25 in-process tools), **A2A** (JSON-RPC 2.0 + AgentCard), **REST**. |
144
+
145
+ #### Industrial stack
146
+
147
+ | Capability | Why it matters |
148
+ |---|---|
149
+ | **Six field protocols** | Modbus TCP, Modbus RTU-over-TCP (serial gateway), OPC UA, MQTT and HTTP/REST, plus a **built-in serial plugin** (direct RS-232/485: Modbus RTU + ASCII line) — acquisition **and** write-control drivers with connection pools, classified error messages and per-driver connection tests. `mock` covers demos/CI. Protocols are plugins: `ctx.daq.registerDriver` / `ctx.dcw.registerWriteDriver` inject straight into the frontend protocol dropdown and dynamic forms (⌁ badge), zero frontend changes. |
150
+ | **Agent teams, industrial scope** | Agents bind to DAQ/DCW nodes and see semantic cards — physical meaning, units, safe range, recipe window — never raw registers. |
151
+ | **Human-approved write control** | DCW writes flow through **safe-range ∩ recipe-window** interlock → optional **HITL approval** → PLC write → **readback verification** → signed write history. |
152
+ | **Read-write DCW channels** | Every control node also **reads its PLC value back** through the same calibration path it writes with: periodic + on-demand + agent reads surface **SET vs ACT** side by side — passive observation, never blocked by write interlocks. |
153
+ | **Recipe versioning & governance** | Parameter changes are versioned with attribution (user/agent/system + operator + reason). Roll back to any revision or the last-good batch — non-destructively. Stale-node params are skipped and clearly marked. |
154
+ | **Line operations** | Lines → products → recipes → batch runs. Recipe windows gate acquisition and interlock writes; every sample is tagged `product/recipe/run` for per-batch isolation. |
155
+ | **Multi-modal DAQ frame pipeline** | Multi-point profiles (thickness/scanner) and CCD image frames flow through template sink pipelines: vectors & metadata into Timescale (`daq_frames`), pixels into object storage (MinIO, auto disk fallback); derived-metric thresholds ride the existing alarm chain. |
156
+ | **Agent self-audit tools** | `line_context`, `ops_log`, `recipe_log`, `recipe_versions`, `dcw_journal` — agents see exactly which line/product/recipe they control, who did what, and how every value changed. |
157
+
158
+ #### Governance, configuration & extension
159
+
160
+ | Capability | Why it matters |
161
+ |---|---|
162
+ | **Line-level permissions** | Industrial data is gated **per production line** with three states (none / read-only / operate), enforced in the data plane — regular users see no line data until granted. |
163
+ | **Full-operation audit log** | Every user / agent / system action lands in one queryable log; operators are attributed to "Channel/Member", distinct from users and the system. Streamed live over WS. |
164
+ | **Team-scoped plugin switches** | Each team (channel) keeps an **independent plugin switch set** (`channel_plugins`): a disabled plugin's tools are not injected into that team's agents. Plugins themselves are hot-managed via `aw plugin` and the `/plugins` page. |
165
+ | **Plugin extension API** | A self-contained directory under `plugins/<name>/` enhances **both halves at once**: `index.mjs` (server: hooks, routes, agent tools, **DAQ read drivers / DCW write drivers**, frame processors, node templates, config groups, KV, timers) and `client.mjs` (browser: panels injected into named slots, i18n, settings UI). Three scopes — `builtin` (shipped) > `project` (checkout) > `user` (`~/.AgentWorkShop`) — with ~1 s hot reload on enable/disable **and on code edits**; a disabled plugin's drivers are removed on hot reload immediately. Built-in example: **serial-bridge** (serial communication: read/write drivers, serial probe API, frontend panel). Full contract in [`docs/plugins.md`](./docs/plugins.md). |
166
+ | **AML — auto-modeling lab** | Dataset build → training job → leaderboard → promotion gates → model reference, all driven from `/aml` or by agents through 10 `aml_*` tools. Python runtime bootstrapped with `uv` into an `./aml` asset root; artifacts and metadata stay under the config root. |
167
+ | **Fully config-driven runtime** | Every runtime knob (memory budgets, compaction, rollback guardrails, retention, backups, log level…) is declared once in the settings descriptor registry with precedence **config.yml < runtime-settings < env** — **99 settings across 16 groups**, no hardcoded defaults in code. |
168
+ | **Configurable cadences** | Sampling and query defaults/floors are **live settings** (`daq.sampling.*`, `daq.query.*`): hot-reloaded, clamped on node create/patch, and agent tool descriptions always carry the current values. |
169
+
170
+ #### Digital twin
171
+
172
+ | Capability | Why it matters |
173
+ |---|---|
174
+ | **3D digital twin** | Three.js town: place line equipment and channel territories, watch device health, alarms and live values — driven by the same event bus. An adaptive quality ladder (DPR / shadow / bloom tiers, wall-clock FPS budget) matches the machine, and `window.__townStats` exposes real render metrics for perf probes. |
175
+
176
+ ---
177
+
178
+ ## The interface
179
+
180
+ Every panel below is the real UI, at 1440×900, recorded from a running instance.
181
+
182
+ <div align="center">
183
+
184
+ ### FIG.02 — DAQ console
185
+
186
+ <img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/fig-02-daq.gif" alt="DAQ console: node inventory, live trends, alarm strip and event stream" width="92%" />
187
+
188
+ <sub><b>Acquisition, end to end.</b> Node inventory and health under a live gauge band, trends that fill as samples land,
189
+ an alarm strip that only holds what is actually unacknowledged, and a tailing event stream.</sub>
190
+
191
+ <br />
192
+
193
+ ### FIG.03 — Line operations
194
+
195
+ <img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/fig-03-dcw.gif" alt="Line operations: production lines, products, recipes and write control" width="92%" />
196
+
197
+ <sub><b>Lines, products, recipes, batches.</b> Starting a line gates acquisition through its recipe window and tags every
198
+ sample with <code>product/recipe/run</code>; control nodes expose <b>SET vs ACT</b> through the same calibration path they write with.</sub>
199
+
200
+ <br />
201
+
202
+ ### FIG.04 — Digital twin
203
+
204
+ <img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/fig-04-town.gif" alt="3D digital twin town driven by live telemetry" width="92%" />
205
+
206
+ <sub><b>The twin is the same event bus, rendered.</b> Equipment, channel territories, alarms and live values — an adaptive
207
+ quality ladder (DPR / shadow / bloom, wall-clock FPS budget) keeps it honest on modest hardware.</sub>
208
+
209
+ <br />
210
+
211
+ ### FIG.05 — Dashboard
212
+
213
+ <img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/fig-05-dashboard.gif" alt="Runtime dashboard with KPI gauges and trends" width="92%" />
214
+
215
+ <sub><b>One screen for the whole workshop.</b> Channels, agents, tasks, DAQ throughput and alarms — read from the same
216
+ state the API serves, not a separate metrics store.</sub>
217
+
218
+ <br />
219
+
220
+ ### FIG.06 — Responsive
221
+
222
+ <img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/fig-06-responsive.gif" alt="The same interface adapting from desktop to tablet to phone" width="92%" />
223
+
224
+ <sub><b>Desktop → tablet → phone.</b> The instrument rail collapses to an icon rail, then to an off-canvas drawer;
225
+ page headers stack, dense tables become scrollable ledgers with a pinned identity column.</sub>
226
+
227
+ </div>
228
+
229
+ <table>
230
+ <tr>
231
+ <td width="50%"><img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/shot-workshop.png" alt="Agent workshop" width="100%" /><br/><sub><b>Agent workshop.</b> Channel timeline, lanes, tasks, memory and HITL in one workbench.</sub></td>
232
+ <td width="50%"><img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/shot-monitor.png" alt="Runtime monitor" width="100%" /><br/><sub><b>Runtime monitor.</b> Every wired channel, member count, dependency cycle and owner.</sub></td>
233
+ </tr>
234
+ <tr>
235
+ <td><img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/shot-settings.png" alt="Settings" width="100%" /><br/><sub><b>Settings.</b> 99 keys across 16 groups, descriptor-driven — the same registry the CLI reads.</sub></td>
236
+ <td><img src="https://raw.githubusercontent.com/kingdol666/AgentWorkShop/main/docs/readme-assets/shot-plugins.png" alt="Plugins" width="100%" /><br/><sub><b>Plugins.</b> Three scopes, hot reload on edit, per-team switches.</sub></td>
237
+ </tr>
238
+ </table>
239
+
240
+ ---
241
+ ## Architecture
242
+
243
+ ```mermaid
244
+ flowchart TB
245
+ subgraph FE["Frontend — Nuxt 4 / Vue 3"]
246
+ UI["Workshop UI · 3D Twin · Dashboards"]
247
+ WS["AEP client — seq resume"]
248
+ end
249
+ subgraph SRV["Server — Nitro / h3"]
250
+ REST["REST /api/workshop/**"]
251
+ HUB["WS Hub — AEP v1"]
252
+ A2A["A2A JSON-RPC"]
253
+ MCP["MCP Server"]
254
+ subgraph RT["Runtime"]
255
+ MGR["AgentChannelManager"]
256
+ SCH["SchedulerLoop — lead supervision"]
257
+ TE["TaskEngine — 7-state machine"]
258
+ AR["AgentRuntime × N"]
259
+ MEM["AgentMemory — FTS5 + vector"]
260
+ BUS["ChannelBus — per-channel seq + ring"]
261
+ end
262
+ subgraph IND["Industrial"]
263
+ DAQ["DAQ gateway — per-node edge runtimes"]
264
+ DCW["DCW gateway — write control"]
265
+ BR["Bus — inproc / MQTT"]
266
+ TSDB["TSDB — SQLite / Timescale"]
267
+ end
268
+ subgraph HB["Harness adapters — 14 engines"]
269
+ MOCK["mock · claude — in-process"]
270
+ OMP["omp — RPC subprocess"]
271
+ CDX["codex — app-server"]
272
+ DSH["dsh · qwen · hermes — ACP"]
273
+ OC["opencode — serve"]
274
+ FAM["gemini · copilot · cursor · crush · goose · pi — headless CLI"]
275
+ end
276
+ DB[("SQLite — channels · agents · tasks
277
+ messages · memories (FTS5) · events")]
278
+ end
279
+ UI <--> WS
280
+ WS --> BUS
281
+ REST & A2A & MCP --> MGR
282
+ MGR --> SCH & TE & AR
283
+ AR --> MEM
284
+ AR --> MOCK & OMP & CDX & DSH & OC & FAM
285
+ MGR & TE & MEM & BUS --> DB
286
+ DAQ <--> BR --> TSDB
287
+ DCW --> BR
288
+ DAQ & DCW --> BUS
289
+ ```
290
+
291
+ **The agent × machine bridge** (the part worth reading the source for):
292
+
293
+ ```
294
+ agent ──binds to──▶ node (daq: auto / dcw: manual)
295
+ │ │
296
+ │ my_industrial_nodes ◀── semantic card: meaning · unit · safe range · recipe window
297
+ │ daq_query ◀── TSDB history, stats + physical semantics
298
+ │ dcw_control ──▶ interlock (safe range ∩ recipe window)
299
+ │ ──▶ HITL approval (manual mode, 180 s timeout)
300
+ │ ──▶ PLC write → readback check → ACK + write history
301
+ ◀── result text with numbers the agent can cite
302
+ ```
303
+
304
+ ---
305
+
306
+ ## Quick start
307
+
308
+ ### Prerequisites
309
+
310
+ ```bash
311
+ node -v # ≥ 23.4.0 (needs built-in node:sqlite)
312
+ ```
313
+
314
+ > Real-agent harnesses require their CLI on PATH — `omp`, `codex`, `dsh`, `opencode`, `gemini`, `qwen`, `copilot`, `cursor`, `crush`, `goose`, `pi` or `hermes` (any subset; each channel can mix harnesses). `mock` and `claude` (SDK) run in-process and need no PATH CLI. The dashboard "execution engines" panel shows per-engine readiness with a green/grey dot; uninstalled engines link to their official install page. Optional DAQ infrastructure (MQTT broker + TimescaleDB) auto-starts via Docker when reachable (`docker compose up -d`).
315
+
316
+ ### Option A — install from npm (recommended)
317
+
318
+ ```bash
319
+ npm install -g agentworkshop # → `aw` / `agentworkshop` on PATH
320
+ aw start # → http://localhost:3001
321
+ ```
322
+
323
+ The published tarball ships a **prebuilt production bundle** (`.output/`), so an npm install boots straight away — no build step, no build tools. On first launch everything initializes into the config root **`~/.AgentWorkShop`**: the default `config.yml`, a generated `.env` holding a random session secret, `runtime-settings.json`, a docker-compose seed, `prompts/`, `commands/`, `plugins/` (seeded from the SDK examples, **disabled** by default) and an empty `data/` directory. All runtime data (SQLite, JSON repos, backups, logs) lives there too — config and data stay with the install, not the working directory.
324
+
325
+ Prefer a one-off run without installing globally?
326
+
327
+ ```bash
328
+ npx agentworkshop start # no global npm install required
329
+ ```
330
+
331
+ > `npx` still creates `~/.AgentWorkShop` — running without a global install is not the same as leaving no trace on disk.
332
+
333
+ ### Option B — from source
334
+
335
+ ```bash
336
+ git clone https://github.com/kingdol666/AgentWorkShop.git && cd AgentWorkShop
337
+ pnpm install
338
+ pnpm dev # → http://localhost:3000 (port from config.yml)
339
+ ```
340
+
341
+ Production from source:
342
+
343
+ ```bash
344
+ pnpm build # nuxt build → .output/
345
+ pnpm start # port from config.yml → server.prod.port
346
+ ```
347
+
348
+ > In a source checkout the config root is the project's **`.AgentWorkShop/`** folder (runtime overrides, data, project-level commands), while `config.yml` / `.env` stay at the checkout root, version-controlled as the factory defaults.
349
+
350
+ ### Updating
351
+
352
+ ```bash
353
+ aw update # check + self-update the global install
354
+ aw update --check # only report; nothing is installed
355
+ npm install -g agentworkshop@latest # manual equivalent
356
+ ```
357
+
358
+ Releases follow semver. `aw start` verifies the config root on every launch and migrates the legacy pre-`home` `data/` layout into it (newest file wins), so data survives upgrades. SQLite schema migrations run server-side at boot. Current version: **v0.7.41** — see [Releases](https://github.com/kingdol666/AgentWorkShop/releases).
359
+
360
+ ### Your first agent × line session (~2 minutes)
361
+
362
+ 1. **Sign in** — register in the sidebar (or `POST /api/users/register`).
363
+ 2. **Build a line** — `Line Operations` → create a line, add DAQ nodes (e.g. `daq-temp-tc`) and control nodes (e.g. `dcw-temp-sp`), create a product + recipe, hit **Start**. Live values start flowing.
364
+ 3. **Create a team** — `Agent Workshop` → pick a lead + workers, **deploy** into a channel.
365
+ 4. **Bind nodes** — open the agent's detail panel → bind the DAQ node (*auto*) and the control node (*manual* = needs your approval).
366
+ 5. **Submit the goal** — *"Analyze the last 5 minutes of melt temperature; if deviation from 182 °C exceeds 1 °C, correct the setpoint (wait for my approval)."*
367
+ 6. **Approve** — the agent reads real history, computes the mean, requests the write → approve in the HITL panel → watch the setpoint change and the goal close with a numeric report.
368
+
369
+ ---
370
+
371
+ ## Configuration & CLI — config-driven by design
372
+
373
+ One runtime, one source of truth. **`config.yml`** declares defaults; **`runtime-settings.json`** inside the config root carries runtime overrides; environment variables and CLI flags sit on top. Every editable key is described once in `shared/config/schema.json` (type, range, enum, live-vs-restart) and surfaced through the same descriptors in **both the UI and the CLI**.
374
+
375
+ ```
376
+ config.yml (defaults) < .AgentWorkShop/runtime-settings.json (runtime) < env vars / CLI flags
377
+ ```
378
+
379
+ The config root is **`~/.AgentWorkShop`** for a global install (`npm i -g`) — wherever you run `aw` from — and **`<repo>/.AgentWorkShop`** in a source checkout (with `config.yml` / `.env` staying at the checkout root as version-controlled factory defaults). `AW_HOME` redirects it; `AW_MODE=home` forces the global shape.
380
+
381
+ ### Live settings, persisted, hot-reloaded
382
+
383
+ - The **Settings → Runtime config** tab renders every editable key from the descriptors — change server ports, theme, API timeouts, locale or the approval gate, hit save.
384
+ - `live` keys apply instantly (theme, title, timeouts, approval gate, DAQ sampling cadences, TSDB query buckets…) over a server-sent event stream — no reload, no restart.
385
+ - `restart` keys (ports, hosts) persist to disk and take effect on the next launch of the matching mode (`aw dev` / `aw start`).
386
+ - One channel for every writer: the UI, the CLI and the server's file watcher all converge on the same settings file, so a change made anywhere shows up everywhere.
387
+
388
+ Example — retune the acquisition and query cadences live:
389
+
390
+ ```bash
391
+ aw config set daq.sampling.defaultIntervalMs 2000 # new nodes sample every 2 s
392
+ aw config set daq.sampling.minIntervalMs 500 # per-node floor (create/patch clamp)
393
+ aw config set daq.query.defaultBucketMs 3000 # TSDB reads default to a 3 s bucket
394
+ aw config set daq.query.minBucketMs 500 # query floor (samples/line query/agent tool)
395
+ ```
396
+
397
+ Agent tool descriptions are re-rendered with the current values on every injection, so an LLM always sees the floor and default that will actually apply to its `daq_query` calls.
398
+
399
+ ### The `aw` CLI
400
+
401
+ | Command | What it does |
402
+ |---|---|
403
+ | `aw start · aw dev · aw build` | Production server / dev server / build — ports from the effective config; first `start` builds once |
404
+ | `aw stop` | Stop a running `aw` service instance via the single-instance lock |
405
+ | `aw config list · get · set · unset · reset` | Read & write runtime settings (validated against the schema, atomic writes) |
406
+ | `aw plugin list · create · enable · disable` | Manage plugins across all three scopes: inspect, scaffold (project scope; `--global` for user scope), enable/disable (state file, ~1 s hot reload on the running server) |
407
+ | `aw home` | Inspect / initialize the config root `.AgentWorkShop` |
408
+ | `aw init <dir>` | Scaffold a runnable project (full config system + CLI included) |
409
+ | `aw register <path\|url\|npm:pkg>` | Register a new command — project-local or `--global` |
410
+ | `aw update` | Check npm for the latest release and self-update the global install |
411
+ | `aw doctor` | Environment + project health check (node, config, ports, keys) |
412
+ | `aw status` | Live overview: mode, config sources, running server, command table |
413
+ | `aw tui` | Terminal workbench: channel/agent management, task submission, live monitor pane, HITL answering (see [`docs/tui.md`](./docs/tui.md) · [`tui/README.md`](./tui/README.md)) |
414
+ | `aw version` | Print the CLI/package version (alias `v`) |
415
+
416
+ Global flags: `--help/-h` · `--version/-v` · `--json` (machine-readable) · `--root <dir>` · `--debug`.
417
+
418
+ Exit codes: **0** success · **1** runtime error · **2** usage error. With `--json`, failures come back as an envelope carrying `{ ok: false, error: 'unknown-command' \| 'no-project' \| 'usage' \| 'internal' \| … }`, so automation can branch without parsing stderr.
419
+
420
+ ### Command registration
421
+
422
+ Commands are plain modules exporting `{ meta, run }`. Drop one into a scanned directory and it's live on the next invocation — no registry bookkeeping, convention over configuration:
423
+
424
+ | Scope (highest wins) | Directory |
425
+ |---|---|
426
+ | project | `<root>/.AgentWorkShop/commands/` |
427
+ | user | `~/.AgentWorkShop/commands/` |
428
+ | built-in | packaged with the CLI (`cli/commands/`) |
429
+
430
+ `aw register <file|url|npm:pkg>` copies a command into the right scope (`--global` for user scope); `aw help` lists everything that's registered.
431
+
432
+ ```js
433
+ // ~/.AgentWorkShop/commands/hello.mjs
434
+ export const meta = { name: 'hello', group: 'Custom', summary: 'Say hi', usage: 'aw hello [--name <n>]' }
435
+ export async function run(argv, ctx) {
436
+ console.log(`Hi ${argv.flags.name ?? 'AW'} — mode: ${ctx.mode}`)
437
+ }
438
+ ```
439
+
440
+ ---
441
+
442
+ ## The industrial stack in detail
443
+
444
+ ### Data acquisition (DAQ)
445
+
446
+ - **Six protocol drivers**: Modbus TCP, Modbus RTU-over-TCP (serial gateway), OPC UA, MQTT, HTTP/REST, plus the **serial-bridge built-in plugin** (direct RS-232/485: Modbus RTU framing + ASCII line protocol, write side with same-address readback verification, serial enumeration/probe API and a frontend panel) — connection pools, classified error messages, per-driver connection tests; the driver registry accepts plugin-registered protocols of any kind (with self-describing metadata, the frontend forms render with zero changes).
447
+ - **Per-node edge runtimes**: independent sampling cadence, publish cadence, in-flight mutex per node — one slow driver never blocks its neighbors. Sampling and query defaults/floors are driven by the live `daq.sampling.*` / `daq.query.*` settings.
448
+ - **Pipeline**: driver → queue (in-process or MQTT, offline buffer on disconnect) → consumer with out-of-order defense → three-way fan-out: WS live push (gated), TSDB batch write, device-twin writeback.
449
+ - **Robustness**: TSDB single-in-flight writes with bounded retries, buffer backpressure with drop counters, real loss metrics exposed on `daq.controller` frames.
450
+ - **Alarms**: recipe-scoped monitoring windows with **2 % hysteresis + 3-tick debounce**; alarm/offline transitions are instant (safety first).
451
+
452
+ ### Write control (DCW)
453
+
454
+ - Engineering-unit writes: `linear` calibration (scale/offset) PLC↔physical, **readback verification** with deadband tolerance, ACK states and write history.
455
+ - **Interlock**: with a line running, the active recipe's parameter window *replaces* the node's global safe range for that node.
456
+ - **HITL**: `manual`-mode bindings suspend the write for user approval (deduped per agent+node; re-validation at approval time — permission is re-checked when you click approve).
457
+
458
+ ### Recipe & batch
459
+
460
+ `Line → Product → Recipe → Run`. Starting a run applies recipe params node-by-node (each write verified), gates acquisition per line, and tags every sample with `line/product/recipe/run` — per-product data isolation with five-dimension queries (line × product × recipe × time × node).
461
+
462
+ ### AML — auto-modeling lab
463
+
464
+ The modeling half of the loop: `/aml` builds **datasets** out of tagged telemetry, submits **training jobs** to a `uv`-managed Python runtime, ranks runs on a **leaderboard**, and promotes a model only when it clears the configured **gates** (NRMSE, rollout NRMSE, validation/test gap, minimum rows and runs). Promoted models are referenced by id, so an MPC or shadow-twin controller can consume a versioned artifact instead of a vague "latest".
465
+
466
+ - Agents do the same work through 10 tools (`aml_dataset_build`, `aml_job_submit`, `aml_job_status`, `aml_leaderboard`, `aml_model_promote`, …) — submit a goal and let the team train and report.
467
+ - The Python runtime bootstraps itself with `uv` into an `./aml` asset root inside the config root; dataset/artifact/metadata paths, disk quota, job timeout, concurrency and retention are all **settings** (16 in the `aml` group), not constants.
468
+ - Governance defaults are conservative: cross-recipe datasets are refused unless explicitly allowed, and every job is attributed.
469
+
470
+ ---
471
+
472
+ ## Usage
473
+
474
+ ### Authentication
475
+
476
+ Email + password login issues a **bearer token** (multiple tokens per user, individually revocable).
477
+
478
+ ```bash
479
+ # register
480
+ curl -X POST http://localhost:3000/api/users/register \
481
+ -H 'content-type: application/json' \
482
+ -d '{"email":"you@example.com","password":"secret","name":"you"}'
483
+
484
+ # every workshop call
485
+ curl http://localhost:3000/api/workshop/channels \
486
+ -H 'authorization: Bearer <token>'
487
+ ```
488
+
489
+ ### Line-level permissions
490
+
491
+ Industrial data is gated **per production line** with three states, managed by an admin
492
+ in the built-in **Permissions** page (`/permissions`, admin-only in the sidebar):
493
+
494
+ | State | DAQ nodes | DCW (write) nodes | Visibility |
495
+ | --- | --- | --- | --- |
496
+ | **none** (default for regular users) | hidden | hidden | line data withheld server-side — invisible in Line Ops, DAQ center and the digital twin |
497
+ | **read-only** | read | ✕ | line visible, values stream, no writes / dispatch / device binding |
498
+ | **operate** | read | read + write | full access incl. setpoint writes, dispatch, binding |
499
+
500
+ - `admin` / `editor` roles are unrestricted (operations roles).
501
+ - Regular users **default to none** — they see no line data until granted.
502
+ - Enforcement lives in the data plane: list endpoints filter by grant, write/dispatch
503
+ endpoints return a human-readable 403, and Agent↔node bindings validate the line grant
504
+ (DAQ needs read-only+, DCW needs operate).
505
+ - Plugins get the same surface via `ctx.permissions` (`lineMode` / `visibleLineIds` /
506
+ `listGrants` / `setGrants`) plus a `permissions:changed` lifecycle hook; the SDK REST
507
+ client exposes `client.permissions.overview()` / `client.permissions.set(...)`.
508
+
509
+ ### Execution modes
510
+
511
+ Prefix the task description (or pick in the composer UI):
512
+
513
+ | Mode | Semantics | Config |
514
+ |---|---|---|
515
+ | `goal` | lead decomposes → workers deliver → **lead judges satisfaction**; unmet → more subtasks; met → parent completes. | `goalCriteria` |
516
+ | `loop` | replay the same task on a fixed interval. | `intervalMs` (default 60 000), `maxIterations` (default ∞) |
517
+ | `pipeline` | ordered stages; stage N+1 consumes stage N's output. | `stages: [{name, description, assigneeId?}]` |
518
+
519
+ ### The four entry points
520
+
521
+ | Entry | Endpoint | Audience |
522
+ |---|---|---|
523
+ | **WS** | `/api/workshop/ws?channelId=…` | Dashboards / UI — AEP v1 envelopes, per-channel monotonic `seq`, 5 000-event ring, `lastSeq` resume, snapshot fallback. |
524
+ | **MCP** | in-process server, ~25 tools | Agents (omp host tools) — management + job-face tools, channel-scoped. |
525
+ | **A2A** | `POST /api/workshop/a2a/:agentId/rpc` | External agents — JSON-RPC 2.0, `AgentCard` at `/card`, `tasks/sendSubscribe` SSE. |
526
+ | **REST** | `/api/workshop/**` | Humans / scripts — full management face. |
527
+
528
+ ### Task state machine
529
+
530
+ ```
531
+ SUBMITTED ─▶ ASSIGNED ─▶ WORKING ─▶ WAITING ─▶ COMPLETED
532
+ │ │ │ │
533
+ └────────────┴───────────┴──▶ CANCELED / FAILED ─▶ (retry ≤ 3 or cancel)
534
+ ```
535
+
536
+ ---
537
+
538
+ ## Verified end-to-end
539
+
540
+ Every claim above is backed by a suite you can re-run. The closed-loop suite drives a
541
+ **production instance over real simulated plant protocols** (Modbus TCP/RTU, OPC UA, MQTT,
542
+ HTTP + an MQTT/Timescale pipeline) with a real LLM agent, and asserts on the database,
543
+ the event stream and the HTTP API — not on mocks.
544
+
545
+ | Suite | Latest result | What it covers | Reproduce |
546
+ |---|---|---|---|
547
+ | `e2e-full-closedloop.mjs` | **124 PASS / 0 FAIL** (2026-09-12, v0.7.36) | registration → login → line/product/recipe → DAQ sampling → agent bound to nodes → `daq_query` → `dcw_control` → HITL approval → PLC write → readback → recipe rollback → cascade delete → data-root isolation | `node scripts/e2e-full-closedloop.mjs http://127.0.0.1:3111` |
548
+ | `e2e-aml.ts --real` | 0 failures (2026-09-11) | AML datasets → job submit → status/logs → leaderboard → promotion gates, against the real Python runtime | `node node_modules/tsx/dist/cli.mjs --tsconfig .nuxt/tsconfig.server.json scripts/e2e-aml.ts --real` |
549
+ | Five-protocol live line | 37/37 (re-verified 2026-09-12 on a clean instance) | driver connectivity, sampling into Timescale, DCW dispatch + readback per protocol, agent closed loop, HITL over a real OPC UA write, recipe + param-ledger rollback | `node scripts/_dbg-live-line-e2e.mjs` |
550
+ | Production API live | 64/64 (re-verified 2026-09-12 on a clean instance) | persistence across restart, template CRUD, task assign/complete/cancel/loop/pipeline, A2A + mailbox, WS broadcast, MCP endpoint, cascade delete | `AW_E2E_TOKEN=<token> node scripts/api-live-e2e.mjs` |
551
+ | Line permissions / audit-negative | 21/21 + 9/9 | three-state line grants with human-readable 403s, binding-subject validation, revocation convergence, unauthenticated WS receives zero telemetry | `node scripts/_dbg-perms-e2e.mjs <base> <adminPass>` · `node scripts/_dbg-audit-neg-e2e.mjs <base> <adminPass>` |
552
+ | Render regression | 30/30 | DAQ table integrity (row count aligned with the API), WS-driven row updates, filters, detail page, 3D town + model library, 7-page smoke, zero page errors | `node scripts/_dbg-render-regression.mjs <base> <email> <pass>` |
553
+ | Multi-harness parallel | 21 | omp closed loop · codex real register write · dsh real acquisition · opencode recipe write+rollback — four engines on one running line | `node scripts/e2e-multiharness-team.mjs` |
554
+ | Offline unit/property suites | all green | AEP event index (`test-events-index`), LRU, data-root split (`test-data-root`), log flooding, rollback index, plugin hardening, memory month query, CLI exit codes (`test-cli-exit`), SDK surface (`test-sdk-surface`) | `node scripts/test-<name>.mjs` |
555
+
556
+ The five-protocol and API-live rows are the historical **v0.7.20** acceptance baseline —
557
+ *156 assertions, 0 failures*, full report in [`docs/audit/e2e-2026-09-07.md`](./docs/audit/e2e-2026-09-07.md).
558
+ The closed-loop and AML rows are the current-head runs. Perf probing:
559
+ `scripts/_dbg-render-perf.mjs`.
560
+
561
+ ---
562
+
563
+ ## Project layout
564
+
565
+ ```
566
+ AgentWorkShop/
567
+ ├── bin/ · cli/ # aw CLI — command registry · built-in commands · config engine
568
+ ├── app/ # Nuxt 4 frontend (srcDir)
569
+ │ ├── pages/ # / · /workshop · /workshop/agents · /workshop/teams
570
+ │ │ # /workshop/channel-templates · /workshop/w/:id
571
+ │ │ # /town · /daq · /daq/:id · /dcw · /dcw/:id
572
+ │ │ # /aml · /monitor · /logs · /permissions
573
+ │ │ # /plugins · /users · /tokens · /settings
574
+ │ ├── components/workshop/ # timeline · lanes · task board · memory panel · 3D town
575
+ │ └── stores/composables/ # Pinia + AEP client
576
+ ├── server/
577
+ │ ├── api/ # REST + WS + A2A + MCP routes
578
+ │ ├── services/workshop/
579
+ │ │ ├── runtime/ # manager · scheduler-loop · task-engine · memory · mailbox
580
+ │ │ ├── agents/ # AgentInterface: 14 engines (+ industrial tools)
581
+ │ │ ├── daq/ dcw/ aml/ # edge runtimes · drivers · bus · storage · modeling lab
582
+ │ │ └── db/ # repos over node:sqlite
583
+ │ ├── mcp/ # MCP server (25 tools)
584
+ │ ├── plugins-builtin/ # plugins shipped with the package (diag-bridge · rag-bridge)
585
+ │ └── plugins/ # runtime assembly (singletons)
586
+ ├── sdk/ # agentworkshop/sdk — plugin context, hook bus, REST client, browser SDK
587
+ ├── tui/ # terminal workbench (aw tui)
588
+ ├── shared/
589
+ │ └── config/ # schema.json (99 setting descriptors) + engine (merge/validate/persist) + path resolver
590
+ ├── config.yml # factory defaults (read at build/start; version comes from package.json)
591
+ ├── .AgentWorkShop/ # config root in a checkout — prompts (versioned) + runtime overrides · data · logs · commands (git-ignored)
592
+ ├── data/ # legacy pre-migration location (auto-migrated into the config root)
593
+ └── scripts/ # launchers · home bootstrap · E2E · verification suites
594
+ ```
595
+
596
+ ## Tech stack
597
+
598
+ | Layer | Tech |
599
+ |---|---|
600
+ | Framework | [Nuxt 4](https://nuxt.com) + Nitro (WebSocket) |
601
+ | UI | Vue 3.5 · Pinia · Ant Design Vue · UnoCSS · Three.js · ECharts |
602
+ | Language | TypeScript 5.7 across the stack; `shared/` used by both sides |
603
+ | CLI | Node ESM CLI with a pluggable command registry (`bin/aw.mjs`) |
604
+ | Persistence | `node:sqlite` (zero native deps) + FTS5 + optional `sqlite-vec`; TimescaleDB for time-series |
605
+ | Validation | `zod` at every message boundary |
606
+ | Interop | `@modelcontextprotocol/sdk` · A2A (JSON-RPC 2.0) · AEP v1 (in-house WS protocol) |
607
+ | Field bus | `modbus-serial` · `node-opcua` · `mqtt` |
608
+
609
+ ## Development
610
+
611
+ ```bash
612
+ pnpm dev # dev server (port from effective config)
613
+ pnpm cli … # the CLI in-repo: pnpm cli config list
614
+ pnpm tui # terminal workbench against a running instance
615
+ pnpm build && pnpm start
616
+ pnpm typecheck
617
+ pnpm lint
618
+ pnpm test:api-live # API suite against a running server
619
+ node scripts/e2e-full-closedloop.mjs # full closed loop (server must be running)
620
+ node scripts/test-sdk-surface.mjs # SDK export-surface guard
621
+ ```
622
+
623
+ The docs site lives in `docs/site/` (VitePress) and is deployed to GitHub Pages by
624
+ [`.github/workflows/deploy-docs.yml`](./.github/workflows/deploy-docs.yml):
625
+
626
+ ```bash
627
+ cd docs/site && npx vitepress dev # preview locally
628
+ cd docs/site && npx vitepress build # production build → .vitepress/dist
629
+ ```
630
+
631
+ The workflow syncs `docs/{cli,plugins,sdk}.md` (and their `.en.md` twins) into the site before
632
+ building, so those files are the single source of truth for the single-page guides.
633
+
634
+ ## Roadmap
635
+
636
+ | Capability | Status |
637
+ |---|---|
638
+ | Channel runtime, lead orchestration, 7-state task engine | Shipped |
639
+ | Four entry points: WS (AEP v1) · MCP · A2A · REST | Shipped |
640
+ | Persistent memory (FTS5 + optional vector hybrid) | Shipped |
641
+ | Industrial stack: DAQ · DCW write control · lines/recipes/runs | Shipped |
642
+ | Agent ↔ node binding + HITL approval + interlock | Shipped |
643
+ | 3D digital-twin town · line operations UI · dashboards | Shipped |
644
+ | Full-feature live E2E (agent reads/writes a real line, 23 checks) | Shipped |
645
+ | Runtime configuration system: settings persistence · hot reload · settings UI | Shipped |
646
+ | `aw` CLI: config · run · init · register · doctor | Shipped |
647
+ | Multi-harness registry: omp · codex · dsh · opencode subprocess engines | Shipped |
648
+ | Five field protocols: Modbus RTU-over-TCP · MQTT · HTTP (acquisition + write control) | Shipped |
649
+ | Harness availability probing + dispatch-time engine checks (UI disable + 409) | Shipped |
650
+ | Recipe versioning with attribution + non-destructive rollback (UI + agent tools) | Shipped |
651
+ | Agent self-audit: line_context / ops_log / recipe_log / recipe_versions / dcw_journal | Shipped |
652
+ | Multi-harness parallel live E2E on a real protocol line (four engines, one line) | Shipped |
653
+ | HITL approval flow verified over real OPC UA writes | Shipped |
654
+ | Bilingual docs (简体中文 / English) with VitePress language switcher | Shipped |
655
+ | Per-channel LLM provider/model selection from live harness catalogs | Shipped |
656
+ | Configurable DAQ/TSDB cadences (sampling & query defaults + floors, live) | Shipped |
657
+ | Team-scoped plugin switches (create-time pick + team dialog, per-channel tool injection) | Shipped |
658
+ | Plugin hot management: `/plugins` page + `aw plugin list/enable/disable` | Shipped |
659
+ | Rendering perf pass (v0.7.27): DAQ main-thread blocking −90%, twin −69%, adaptive quality restored to top tier; `window.__townStats` instrumentation | Shipped |
660
+ | Plugin system v2: browser panel injection, plugin-scoped settings/groups, plugin i18n, host runtime services (`ctx.services`/`ctx.daq`/`ctx.omp`) | Shipped |
661
+ | Instrument Glass material layer (v0.7.36): three-tier translucent materials, vibrancy, specular edges, spring motion, per-page route transitions | Shipped |
662
+ | Realtime pipeline optimizations: DAQ frame indexing O(n²)→O(n), incremental per-agent event index, chart in-place updates, size-aware JSON persistence | Shipped |
663
+ | AML auto-modeling lab: dataset build · job orchestration (uv-managed Python) · leaderboard · promotion gates · 10 agent tools | Shipped |
664
+ | Claude Agent SDK adapter — resident sessions with same-turn steer and `canUseTool` HITL | Shipped |
665
+ | Production hardening: TLS, MQTT auth, OPC UA sign+encrypt defaults, structured audit log | Planned |
666
+ | Edge deployment shape: standalone edge-agent + central broker | Planned |
667
+ | Alarm outbound delivery (email/webhook) + ack workflow | Planned |
668
+ | CI pipeline (typecheck + lint + e2e) — docs deployment already runs on GitHub Actions | Planned |
669
+ | License: PolyForm Noncommercial 1.0.0 (source-available, non-commercial) | Shipped |
670
+
671
+ ## License
672
+
673
+ AgentWorkShop is an independent project and is **not an official product of Anthropic** or any LLM vendor. It integrates with agent harnesses (e.g. `omp`) through their public interfaces.
674
+
675
+ **AgentWorkShop is source-available software, licensed under the [PolyForm Noncommercial 1.0.0](./LICENSE).**
676
+
677
+ - **Permitted** — personal study, research, hobby projects, teaching, and use by noncommercial organizations (charities, education, public research, government).
678
+ - **Not permitted without prior written permission** — any **commercial use**: selling, paid services, integrating into commercial products, or production use serving a business. Commercial licenses are available from the copyright holder.
679
+ - **When you redistribute** the software, you must pass through the `Required Notice` line and these terms.
680
+
681
+ For commercial licensing, contact: [GitHub @kingdol666](https://github.com/kingdol666) · kingdol6080@gmail.com
682
+
683
+ <div align="center">
684
+
685
+ <a href="https://star-history.com/#kingdol666/AgentWorkShop&Date">
686
+ <picture>
687
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=kingdol666/AgentWorkShop&type=Date&theme=dark" />
688
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=kingdol666/AgentWorkShop&type=Date" />
689
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=kingdol666/AgentWorkShop&type=Date" width="80%" />
690
+ </picture>
691
+ </a>
692
+
693
+ </div>
694
+
695
+ ---
696
+
697
+ ## Contributing
698
+
699
+ Issues and pull requests are welcome. Before opening a PR:
700
+
701
+ 1. **Read the contract you are touching** — [`docs/plugins.md`](./docs/plugins.md) for the extension surface, [`docs/sdk.md`](./docs/sdk.md) for the programming client, [`docs/cli.md`](./docs/cli.md) for the command registry.
702
+ 2. **Run the guards locally**:
703
+
704
+ ```bash
705
+ pnpm typecheck # vue-tsc across app + server + shared
706
+ pnpm lint # eslint 9, zero warnings expected
707
+ node scripts/e2e-full-closedloop.mjs # full closed loop, server must be running
708
+ node scripts/test-sdk-surface.mjs # SDK export surface must not drift
709
+ node scripts/check-docs-sync.mjs # docs/site pages stay in sync with docs/*.md
710
+ ```
711
+
712
+ 3. **Keep commits conventional** — `commitlint` runs on `commit-msg` (`feat:`, `fix:`, `docs:`, `refactor:`, `perf:`, `test:`, `chore:`), and `lint-staged` fixes staged JS/TS/Vue on commit.
713
+ 4. **Add a test for behaviour you change.** The repo leans on live E2E scripts under `scripts/` rather than mocks — a new industrial path should be provable against a running instance.
714
+
715
+ > [!TIP]
716
+ > `aw doctor` checks your environment end to end (Node version, config root, port availability, SQLite, optional Docker services) before you file a bug — it answers most "it does not start" reports immediately.
717
+
718
+ ## Security
719
+
720
+ Please **do not** open a public issue for a vulnerability. Report it privately through [GitHub Security Advisories](https://github.com/kingdol666/AgentWorkShop/security/advisories/new) with a reproduction and the affected version.
721
+
722
+ AgentWorkShop drives real equipment when you point it at real equipment: review `config.yml` interlocks, safe ranges and HITL settings before connecting a live PLC. The default posture is advisory — writes are interlocked, approved and read back — but the plant-side logic is always the final veto.
723
+
724
+ ---
725
+
726
+ <div align="center">
727
+
728
+ **If this project is useful to you, a ⭐ helps other people find it.**
729
+
730
+ [![Star History Chart](https://api.star-history.com/svg?repos=kingdol666/AgentWorkShop&type=Date)](https://star-history.com/#kingdol666/AgentWorkShop&Date)
731
+
732
+ <br />
733
+
734
+ **[Documentation](https://kingdol666.github.io/AgentWorkShop)** · **[Guide](https://kingdol666.github.io/AgentWorkShop/guide/getting-started)** · **[Plugin API](./docs/plugins.md)** · **[SDK](./docs/sdk.md)** · **[CLI](./docs/cli.md)** · **[中文](./README-zh.md)**
735
+
736
+ <sub>Built with Nuxt 4 · Vue 3 · TypeScript · <code>node:sqlite</code> — supervisory layer, second-level soft real-time.<br />
737
+ Time-critical loops stay in the PLC.</sub>
738
+
739
+ </div>