agentworkshop 0.7.40 → 0.7.44

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 (327) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/B8uy9iRW.js +1 -0
  3. package/.output/public/_nuxt/BGTYYQH-.js +1 -0
  4. package/.output/public/_nuxt/BUmHEJ77.js +2 -0
  5. package/.output/public/_nuxt/BY7YrV_D.js +1 -0
  6. package/.output/public/_nuxt/Bqcgz95s.js +18 -0
  7. package/.output/public/_nuxt/C7UlqPeD.js +1 -0
  8. package/.output/public/_nuxt/CTmDn-YP.js +1 -0
  9. package/.output/public/_nuxt/Cs8pVeVG.js +1 -0
  10. package/.output/public/_nuxt/{DcsCcxp4.js → D98NH8kG.js} +1 -1
  11. package/.output/public/_nuxt/DKySmNPI.js +14 -0
  12. package/.output/public/_nuxt/Di0NY_ht.js +1 -0
  13. package/.output/public/_nuxt/Du9v6qGB.js +1 -0
  14. package/.output/public/_nuxt/{C_iYD-EB.js → EHlEMRii.js} +1 -1
  15. package/.output/public/_nuxt/Eke1fs-U.js +1 -0
  16. package/.output/public/_nuxt/{DeJykBFf.js → H0BcqZtT.js} +1 -1
  17. package/.output/public/_nuxt/{C4oW1HsE.js → HSYEkkce.js} +1 -1
  18. package/.output/public/_nuxt/{DZshyNLa.js → IREZ1eC2.js} +1 -1
  19. package/.output/public/_nuxt/{D_OTvQza.js → J9oU00D1.js} +1 -1
  20. package/.output/public/_nuxt/OmpTerminalPanel.BxR5-lvi.css +1 -0
  21. package/.output/public/_nuxt/SSyAPaHc.js +1 -0
  22. package/.output/public/_nuxt/TownView.li4EMQxK.css +1 -0
  23. package/.output/public/_nuxt/VdLk4jLE2.js +1 -0
  24. package/.output/public/_nuxt/_id_.BhsXoEuk.css +1 -0
  25. package/.output/public/_nuxt/_id_.DQyj-WKN.css +1 -0
  26. package/.output/public/_nuxt/{_wsId_.B4WiqkIS.css → _wsId_.CTx-BlfF.css} +1 -1
  27. package/.output/public/_nuxt/aShsv_rG.js +19 -0
  28. package/.output/public/_nuxt/{yF0aYMF1.js → aesgXKSr.js} +3 -3
  29. package/.output/public/_nuxt/agents.B21nUEUX.css +1 -0
  30. package/.output/public/_nuxt/aml.ekTjxFkf.css +1 -0
  31. package/.output/public/_nuxt/builds/latest.json +1 -1
  32. package/.output/public/_nuxt/builds/meta/b5506ef0-f48e-4f14-a6c0-d65e505d0b09.json +1 -0
  33. package/.output/public/_nuxt/ca4TJ3Op.js +1 -0
  34. package/.output/public/_nuxt/channel-templates.DplM1pJ3.css +1 -0
  35. package/.output/public/_nuxt/daq.BdVmoIfe.css +1 -0
  36. package/.output/public/_nuxt/dcw.DCgyzpWV.css +1 -0
  37. package/.output/public/_nuxt/{default.J32SgqFY.css → default.Bh3L2HU8.css} +1 -1
  38. package/.output/public/_nuxt/lHAxdSsj.js +1 -0
  39. package/.output/public/_nuxt/pages.j9rzRocr.css +1 -0
  40. package/.output/public/_nuxt/plugins.DhiZbHU8.css +1 -0
  41. package/.output/public/_nuxt/settings.BRx9rIDg.css +1 -0
  42. package/.output/public/_nuxt/teams.BLlOPB_Z.css +1 -0
  43. package/.output/public/_nuxt/tokens.De8xzszn.css +1 -0
  44. package/.output/public/_nuxt/workshop.D1jFNkrn.css +1 -0
  45. package/.output/server/chunks/_/nitro.mjs +1058 -830
  46. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  47. package/.output/server/chunks/build/{OmpTerminalPanel-Cu_s4i0A.mjs → OmpTerminalPanel-CVvxpsF7.mjs} +15 -15
  48. package/.output/server/chunks/build/{OmpTerminalPanel-Cu_s4i0A.mjs.map → OmpTerminalPanel-CVvxpsF7.mjs.map} +1 -1
  49. package/.output/server/chunks/build/{TownView-BuLAsmpR.mjs → TownView-CJ6IsDCc.mjs} +229 -228
  50. package/.output/server/chunks/build/{TownView-BuLAsmpR.mjs.map → TownView-CJ6IsDCc.mjs.map} +1 -1
  51. package/.output/server/chunks/build/{_id_-BU1wfOID.mjs → _id_-CVD_H0ir.mjs} +149 -147
  52. package/.output/server/chunks/build/_id_-CVD_H0ir.mjs.map +1 -0
  53. package/.output/server/chunks/build/{_id_-BYsEua57.mjs → _id_-CtxMb3qp.mjs} +47 -46
  54. package/.output/server/chunks/build/_id_-CtxMb3qp.mjs.map +1 -0
  55. package/.output/server/chunks/build/{_wsId_-BxlDcJHg.mjs → _wsId_-DpY3T-md.mjs} +516 -446
  56. package/.output/server/chunks/build/{_wsId_-BxlDcJHg.mjs.map → _wsId_-DpY3T-md.mjs.map} +1 -1
  57. package/.output/server/chunks/build/{agents-CLQqJF2y.mjs → agents-DsCkuXDV.mjs} +49 -46
  58. package/.output/server/chunks/build/agents-DsCkuXDV.mjs.map +1 -0
  59. package/.output/server/chunks/build/{aml-_7FdFL2p.mjs → aml-CT0xKGKI.mjs} +122 -105
  60. package/.output/server/chunks/build/aml-CT0xKGKI.mjs.map +1 -0
  61. package/.output/server/chunks/build/builtin-catalog-edpDcgfL.mjs +117 -0
  62. package/.output/server/chunks/build/builtin-catalog-edpDcgfL.mjs.map +1 -0
  63. package/.output/server/chunks/build/{channel-templates-p6SZNjlM.mjs → channel-templates-Dla9FbYa.mjs} +49 -37
  64. package/.output/server/chunks/build/channel-templates-Dla9FbYa.mjs.map +1 -0
  65. package/.output/server/chunks/build/{daq-cgyjKmJu.mjs → daq-DWWSKGAV.mjs} +95 -93
  66. package/.output/server/chunks/build/daq-DWWSKGAV.mjs.map +1 -0
  67. package/.output/server/chunks/build/{dcw-CoTxBlAZ.mjs → dcw-CT8k17_E.mjs} +46 -45
  68. package/.output/server/chunks/build/dcw-CT8k17_E.mjs.map +1 -0
  69. package/.output/server/chunks/build/{default-BE4r0FZN.mjs → default-D3525UFX.mjs} +16 -15
  70. package/.output/server/chunks/build/{default-BE4r0FZN.mjs.map → default-D3525UFX.mjs.map} +1 -1
  71. package/.output/server/chunks/build/{logs-BSOeZwwI.mjs → logs--dByNyhw.mjs} +2 -2
  72. package/.output/server/chunks/build/{logs-BSOeZwwI.mjs.map → logs--dByNyhw.mjs.map} +1 -1
  73. package/.output/server/chunks/build/{monitor-C0okQaXz.mjs → monitor-Dh2Kvaq5.mjs} +2 -2
  74. package/.output/server/chunks/build/{monitor-C0okQaXz.mjs.map → monitor-Dh2Kvaq5.mjs.map} +1 -1
  75. package/.output/server/chunks/build/{pages-DFxjn9Xa.mjs → pages-BHcSBM2D.mjs} +26 -20
  76. package/.output/server/chunks/build/pages-BHcSBM2D.mjs.map +1 -0
  77. package/.output/server/chunks/build/{plugins-lGlUr1lj.mjs → plugins-BNgIi61W.mjs} +23 -17
  78. package/.output/server/chunks/build/plugins-BNgIi61W.mjs.map +1 -0
  79. package/.output/server/chunks/build/{settings-Ddd1qx2Z.mjs → settings-ipYBDWdn.mjs} +45 -44
  80. package/.output/server/chunks/build/settings-ipYBDWdn.mjs.map +1 -0
  81. package/.output/server/chunks/build/{teams-MEDLZdMn.mjs → teams-5lx-CwFa.mjs} +47 -44
  82. package/.output/server/chunks/build/teams-5lx-CwFa.mjs.map +1 -0
  83. package/.output/server/chunks/build/{tokens-C7fTM5C2.mjs → tokens-q-IDT8Io.mjs} +73 -53
  84. package/.output/server/chunks/build/tokens-q-IDT8Io.mjs.map +1 -0
  85. package/.output/server/chunks/build/{town-qMPql9Se.mjs → town-QJWB5wng.mjs} +5 -4
  86. package/.output/server/chunks/build/town-QJWB5wng.mjs.map +1 -0
  87. package/.output/server/chunks/build/{useDaqStream-CIBaiGAl.mjs → useDaqStream-DfCFpb3p.mjs} +9 -3
  88. package/.output/server/chunks/build/useDaqStream-DfCFpb3p.mjs.map +1 -0
  89. package/.output/server/chunks/build/{useDcwStream-CBbiYnWe.mjs → useDcwStream-UPiX-3iO.mjs} +11 -2
  90. package/.output/server/chunks/build/useDcwStream-UPiX-3iO.mjs.map +1 -0
  91. package/.output/server/chunks/build/{workshop-BL5bhfs0.mjs → workshop-BIlCj_ZP.mjs} +45 -45
  92. package/.output/server/chunks/build/workshop-BIlCj_ZP.mjs.map +1 -0
  93. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  94. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +3 -3
  95. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +1 -1
  96. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  97. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  98. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +1 -1
  99. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +1 -1
  100. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  101. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  102. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  103. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  104. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  105. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  106. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  107. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +3 -1
  108. package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
  109. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +3 -1
  110. package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
  111. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  112. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  113. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  114. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  115. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  116. package/.output/server/chunks/routes/renderer.mjs +2 -2
  117. package/.output/server/chunks/virtual/entry.mjs +639 -88
  118. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  119. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  120. package/.output/server/package.json +1 -1
  121. package/README-zh.md +16 -6
  122. package/README.md +17 -7
  123. package/app/components/AppHeader.vue +961 -959
  124. package/app/components/workshop/A2aRpcDebugger.vue +237 -237
  125. package/app/components/workshop/AgentInspectorDrawer.vue +424 -424
  126. package/app/components/workshop/AgentLanesView.vue +998 -998
  127. package/app/components/workshop/ArtifactCard.vue +120 -120
  128. package/app/components/workshop/AssetLibrary.vue +452 -452
  129. package/app/components/workshop/ChannelSessionList.vue +812 -804
  130. package/app/components/workshop/CommandPalette.vue +269 -269
  131. package/app/components/workshop/Composer.vue +827 -827
  132. package/app/components/workshop/DeviceTwinPanel.vue +643 -643
  133. package/app/components/workshop/EventBlock.vue +602 -602
  134. package/app/components/workshop/FileSelectorModal.vue +188 -188
  135. package/app/components/workshop/InspectorPanel.vue +301 -301
  136. package/app/components/workshop/MemoryPanel.vue +364 -364
  137. package/app/components/workshop/MultiChannelView.vue +189 -189
  138. package/app/components/workshop/TaskBoardView.vue +686 -686
  139. package/app/components/workshop/TaskInspectorDrawer.vue +390 -390
  140. package/app/components/workshop/TranscriptTimeline.vue +601 -601
  141. package/app/components/workshop/blocks/ClusterArtifact.vue +61 -61
  142. package/app/components/workshop/blocks/ClusterError.vue +85 -85
  143. package/app/components/workshop/blocks/ClusterLife.vue +87 -87
  144. package/app/components/workshop/blocks/ClusterMember.vue +95 -93
  145. package/app/components/workshop/blocks/ClusterMemory.vue +84 -84
  146. package/app/components/workshop/blocks/ClusterOther.vue +67 -67
  147. package/app/components/workshop/blocks/ClusterStatus.vue +149 -147
  148. package/app/components/workshop/blocks/ClusterTool.vue +158 -158
  149. package/app/components/workshop/terminal/OmpTerminalPanel.vue +1011 -1011
  150. package/app/components/workshop/town/TownView.vue +56 -56
  151. package/app/composables/workshop/useDaqStream.ts +7 -4
  152. package/app/composables/workshop/useDcwStream.ts +8 -2
  153. package/app/middleware/locale-cookie.global.ts +22 -0
  154. package/app/pages/aml/index.vue +24 -2
  155. package/app/pages/daq/[id].vue +20 -16
  156. package/app/pages/daq/index.vue +2310 -2307
  157. package/app/pages/dcw/[id].vue +26 -23
  158. package/app/pages/dcw/index.vue +3 -3
  159. package/app/pages/index.vue +987 -981
  160. package/app/pages/plugins/index.vue +317 -311
  161. package/app/pages/settings.vue +1564 -1562
  162. package/app/pages/tokens.vue +15 -15
  163. package/app/pages/workshop/agents.vue +612 -609
  164. package/app/pages/workshop/channel-templates.vue +18 -11
  165. package/app/pages/workshop/index.vue +668 -668
  166. package/app/pages/workshop/teams.vue +743 -740
  167. package/app/pages/workshop/w/[wsId].vue +704 -704
  168. package/app/plugins/locale-restore.client.ts +16 -1
  169. package/app/utils/builtin-catalog.ts +104 -0
  170. package/config.yml +170 -170
  171. package/docs/cli.en.md +2 -2
  172. package/docs/cli.md +2 -2
  173. package/docs/full-test-plan.md +2 -3
  174. package/docs/plugins.en.md +33 -1
  175. package/docs/plugins.md +29 -1
  176. package/docs/sdk.en.md +1 -1
  177. package/docs/sdk.md +1 -1
  178. package/i18n/locales/en.ts +293 -35
  179. package/i18n/locales/zh-CN.ts +265 -7
  180. package/package.json +4 -3
  181. package/scripts/_dbg-perms-e2e.mjs +132 -109
  182. package/scripts/_demo-agentteam-capture.mjs +278 -0
  183. package/scripts/_e2e-ui-functional.mjs +371 -0
  184. package/scripts/_i18n-en-cjk-scan.mjs +28 -0
  185. package/scripts/_i18n-en-verify.mjs +107 -0
  186. package/scripts/_i18n-extra-checks.mjs +53 -0
  187. package/scripts/_i18n-scan-hardcoded.mjs +180 -0
  188. package/scripts/_i18n-verify-keys.mjs +50 -0
  189. package/scripts/_loop-biax-campaign.mjs +130 -0
  190. package/scripts/_sweep-button-contrast.mjs +87 -0
  191. package/scripts/test-serial-bridge.mjs +418 -0
  192. package/scripts/ui/e2e-interactive.mjs +328 -0
  193. package/scripts/ui/record-demo.mjs +557 -0
  194. package/scripts/ui/seed-industrial-demo.mjs +171 -0
  195. package/server/api/workshop/daq/index.get.ts +3 -1
  196. package/server/api/workshop/dcw/index.get.ts +3 -0
  197. package/server/plugins/aw-plugins.ts +9 -7
  198. package/server/plugins-builtin/diag-bridge/index.mjs +608 -661
  199. package/server/plugins-builtin/rag-bridge/index.mjs +57 -133
  200. package/server/plugins-builtin/serial-bridge/client.mjs +210 -0
  201. package/server/plugins-builtin/serial-bridge/drivers.mjs +409 -0
  202. package/server/plugins-builtin/serial-bridge/i18n.json +62 -0
  203. package/server/plugins-builtin/serial-bridge/index.mjs +247 -0
  204. package/server/plugins-builtin/serial-bridge/lib.mjs +208 -0
  205. package/server/plugins-builtin/serial-bridge/rtu.mjs +168 -0
  206. package/server/services/workshop/daq/daq-controller.ts +7 -2
  207. package/server/services/workshop/daq/drivers.ts +89 -3
  208. package/server/services/workshop/dcw/dcw-controller.ts +5 -1
  209. package/server/services/workshop/dcw/drivers.ts +85 -2
  210. package/server/services/workshop/dcw/plugin-bridge.ts +45 -0
  211. package/server/services/workshop/plugins/host.mjs +30 -0
  212. package/shared/daq-protocol.ts +15 -0
  213. package/.output/public/_nuxt/88GOowgO2.js +0 -1
  214. package/.output/public/_nuxt/BOt2SP4z.js +0 -1
  215. package/.output/public/_nuxt/BP-NyKVG.js +0 -18
  216. package/.output/public/_nuxt/BXxH0UQE.js +0 -1
  217. package/.output/public/_nuxt/BsROmY89.js +0 -1
  218. package/.output/public/_nuxt/ClILjvWH.js +0 -1
  219. package/.output/public/_nuxt/CzOCSGLe.js +0 -1
  220. package/.output/public/_nuxt/D8qvkfyY.js +0 -1
  221. package/.output/public/_nuxt/DCn7QZ5N.js +0 -2
  222. package/.output/public/_nuxt/DS8qj8EL.js +0 -1
  223. package/.output/public/_nuxt/DUjW5Yq5.js +0 -1
  224. package/.output/public/_nuxt/Dihnimlk.js +0 -19
  225. package/.output/public/_nuxt/Dqw1lpr-.js +0 -1
  226. package/.output/public/_nuxt/Dr9v6C0f.js +0 -14
  227. package/.output/public/_nuxt/Du9ZJtnj.js +0 -1
  228. package/.output/public/_nuxt/OmpTerminalPanel.B_Pl5Ynm.css +0 -1
  229. package/.output/public/_nuxt/TownView.f-YOdXRs.css +0 -1
  230. package/.output/public/_nuxt/_id_.CM4bIgKY.css +0 -1
  231. package/.output/public/_nuxt/_id_.bNV69Dtf.css +0 -1
  232. package/.output/public/_nuxt/agents.ZD0rVdHE.css +0 -1
  233. package/.output/public/_nuxt/aml.BN8ZEW4h.css +0 -1
  234. package/.output/public/_nuxt/builds/meta/f4707884-7cf4-4a31-80d2-e3d72b73745f.json +0 -1
  235. package/.output/public/_nuxt/channel-templates.BOtahzPi.css +0 -1
  236. package/.output/public/_nuxt/daq.B0D3dPAc.css +0 -1
  237. package/.output/public/_nuxt/dcw.8Y7FqCVN.css +0 -1
  238. package/.output/public/_nuxt/pages.D7aSDlUI.css +0 -1
  239. package/.output/public/_nuxt/plugins.sb4nDGqr.css +0 -1
  240. package/.output/public/_nuxt/qr6R6Ha1.js +0 -1
  241. package/.output/public/_nuxt/settings.BTgR-NiE.css +0 -1
  242. package/.output/public/_nuxt/teams.CxnxKVVs.css +0 -1
  243. package/.output/public/_nuxt/tokens.BFY7qv4f.css +0 -1
  244. package/.output/public/_nuxt/workshop.CR_QzeAN.css +0 -1
  245. package/.output/server/chunks/build/_id_-BU1wfOID.mjs.map +0 -1
  246. package/.output/server/chunks/build/_id_-BYsEua57.mjs.map +0 -1
  247. package/.output/server/chunks/build/agents-CLQqJF2y.mjs.map +0 -1
  248. package/.output/server/chunks/build/aml-_7FdFL2p.mjs.map +0 -1
  249. package/.output/server/chunks/build/channel-templates-p6SZNjlM.mjs.map +0 -1
  250. package/.output/server/chunks/build/daq-cgyjKmJu.mjs.map +0 -1
  251. package/.output/server/chunks/build/dcw-CoTxBlAZ.mjs.map +0 -1
  252. package/.output/server/chunks/build/pages-DFxjn9Xa.mjs.map +0 -1
  253. package/.output/server/chunks/build/plugins-lGlUr1lj.mjs.map +0 -1
  254. package/.output/server/chunks/build/settings-Ddd1qx2Z.mjs.map +0 -1
  255. package/.output/server/chunks/build/teams-MEDLZdMn.mjs.map +0 -1
  256. package/.output/server/chunks/build/tokens-C7fTM5C2.mjs.map +0 -1
  257. package/.output/server/chunks/build/town-qMPql9Se.mjs.map +0 -1
  258. package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs.map +0 -1
  259. package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs.map +0 -1
  260. package/.output/server/chunks/build/workshop-BL5bhfs0.mjs.map +0 -1
  261. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.continue.json +0 -1
  262. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.json +0 -1
  263. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/054bb4bc4e4217a2ab0b0c6b663747214a9af464f5568ea60e784704e340bb0f.source +0 -153
  264. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/0554197c3d2bac203a1f5c48a5d52495d1336db1bd7aa4f4c19875810363e684.source +0 -153
  265. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/05c203d12a954fffba942e1d626e3f5fec05b18a5aef2bac003b7884a4b77406.source +0 -431
  266. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/145a6e6ba811af35aed31e0cc3211f53706a14980fa069ee9e3c1591139f96f0.source +0 -180
  267. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/1ae0fb281f97899c025e368ca73f41349b01fb5f85b19e08d7ebccff49095ed5.source +0 -112
  268. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/20ee9967aa0541c516db7575bdd4a1a745939bc7016bd10d7635903113edb8ec.source +0 -227
  269. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/233751843aeba9d4c5263f275b8102de00443c06f286918cbd23e0b6729e01aa.source +0 -131
  270. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/263c2e05b425e5c322e60c6475279f963bab3a873eb521b21df7fec935a46597.source +0 -160
  271. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/2ac5eaac28eaaee2178c4b32014df8e732f9dd432a285a872f5b7f31c1395fa4.source +0 -157
  272. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/33a0db0d2d95d2c11d0720090458e5fba1425376f5ceb5b422d1d3471be3226b.source +0 -348
  273. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/359e474ae83db35e4615d3728de6bf694b64d4dce9b536730a3b6518f9c0494a.source +0 -296
  274. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/37a4c3c31c4b70f6b719c53d1e9c4fcba603f31adfdd11bb6ef9f0d094923c56.source +0 -285
  275. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/461feca1c14a695eb8b0f17a6f95fe97eeceabc0510faaea4ba6d25bde147d8d.source +0 -217
  276. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/4cfadbda8591f29d5e1e230dc000e701b756e850441b3900fb596a4d2f6e98c2.source +0 -301
  277. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/50ca2810cf0b248c96948994c0c404531bbad6e553166b6816b3b03bfa0f75d2.source +0 -151
  278. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/52d9e8cb591a9ae86e238c3620a610cd386717bee222c0f37b25b2ac7e523dc4.source +0 -135
  279. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/6c87daafa4c006560a954636a97333f6123153c9d34d96203f7ee3a14e556357.source +0 -156
  280. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/77bc47854b577900621cacf1697f81fa2bc005af129d37614a97a3441c08f99f.source +0 -72
  281. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/7bbb789d3a527817118cf8399ed1861d6a962ade10878fd07223435d333a7089.source +0 -469
  282. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/86b7c1daafc8b60ba9982dde5bf1bcc74265709483c176e71f23ec6fc267451f.source +0 -259
  283. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/8df66d62bd41984d0970e8236882080c5085ac937d07a29779463d6a03b37c76.source +0 -97
  284. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/9962f2d1b3a85137bd40cc835725600b39f89ee02a27c06b2e0402e1eafde115.source +0 -277
  285. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/a1090ea066b792cb201739f4994e37bf7c12f52e805239a1eab87f18a537f266.source +0 -171
  286. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/a5241091650134d0919897e086a606a3846c8b2b54f8b4c84a8696c145ac3e9e.source +0 -425
  287. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/af19fa4c6e34d5540028be4b17600161283af3a2a2dfc61a3fdc0834436a0c14.source +0 -99
  288. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/b3713d78e2b2f93905ff6be8d58a8d0a2f42dea322eb67c987fda22ff6a084d5.source +0 -325
  289. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/b3849943c3aff102d1af815631fc843a2a52c17646a4b04696ece323e483bbec.source +0 -332
  290. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/bac735a3803a6650b7f1eb8f587e6dc5c68ea055000c3c99a11789438b78e837.source +0 -43
  291. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/d32c24d61eb8b33c73e5a8fc7e4dc7ef437aed238ee4371c2b00617e6104090a.source +0 -154
  292. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/d5170dc9a9879fda04fdf91d8a110d4efb6787ee38dda596d4da899883d36a72.source +0 -531
  293. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/dc59bcd7bb397be63ba2f2c3fec23f3782dcb17d2d75a9981eeced761f33eb32.source +0 -439
  294. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/eb5ff8cf66b92aec7bf6726781d8df74faa2b030c3aaac17d6b00c1fc04c9b32.source +0 -323
  295. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/f10615a6fae18436e70d1201b2d44fdae3174a3aa7bb4db97dea1b3ed291d721.source +0 -433
  296. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/f36d3e271668bc1260c2823542d22dbf1d0f7041ff16b1ac175bce2256e582ca.source +0 -280
  297. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/f94449380af09f31ac352152007146a75cc80bae8d6411ffe57b2c56f933b0ff.source +0 -117
  298. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/fe4dfd81178fd6b648335f6405d9ede71319aebde796008e50db21f8adf44c99.source +0 -160
  299. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/ffb4e3aa548cfdadabaa44ab599f9b6a3ca6288176a2cc7a4b2fc2a12b5fb848.source +0 -101
  300. package/scripts/.mimosa/hook-status/sess_aeaecb58-8833-4b83-b93c-050467d21e03-d944d71bb3.json +0 -14
  301. package/scripts/_dbg-audit-all-pages.mjs +0 -43
  302. package/scripts/_dbg-daq-frames-e2e.mjs +0 -118
  303. package/scripts/_dbg-daq-rowstyle-verify.mjs +0 -112
  304. package/scripts/_dbg-hitl-timeout-e2e.mjs +0 -93
  305. package/scripts/_dbg-live-line-e2e.mjs +0 -279
  306. package/scripts/_dbg-minimal-omp.mjs +0 -77
  307. package/scripts/_dbg-mode-nav.mjs +0 -173
  308. package/scripts/_dbg-real-scenario-timeline.log +0 -55
  309. package/scripts/_dbg-team-repro.mjs +0 -76
  310. package/scripts/_dbg-town-agents-probe.mjs +0 -60
  311. package/scripts/_dbg-visual-acceptance.mjs +0 -63
  312. package/scripts/_townview_style.css +0 -1185
  313. package/scripts/_townview_template.html +0 -1215
  314. package/server/data/agent-node-bindings.json +0 -554
  315. package/server/data/daq-templates.json +0 -16
  316. package/server/data/daqs.json +0 -7464
  317. package/server/data/dcw-lines.json +0 -1787
  318. package/server/data/dcw-products.json +0 -1626
  319. package/server/data/dcw-recipes.json +0 -4672
  320. package/server/data/dcw-rollback.json +0 -20754
  321. package/server/data/dcw-runs.json +0 -6354
  322. package/server/data/dcw-templates.json +0 -146
  323. package/server/data/dcw-writes.json +0 -15650
  324. package/server/data/dcws.json +0 -9033
  325. package/server/data/device-twins.json +0 -133
  326. package/server/data/line-runs.json +0 -322
  327. package/server/data/scene-layouts.json +0 -277
@@ -1,11 +1,26 @@
1
1
  /**
2
2
  * 语言恢复(detectBrowserLanguage 关闭):客户端启动时读取持久化选择。
3
- * AppHeader/settings 切换时写入 localStorage 并强刷(保证 setup 期词条整体切换)。
3
+ * AppHeader/settings 切换时写入 localStorage + cookie 并强刷(保证 setup 期词条整体切换)。
4
4
  * 注意:插件上下文不能调 useI18n()(要求 setup),必须走 nuxtApp.$i18n。
5
+ *
6
+ * cookie 镜像(locale-cookie.global.ts 消费):老用户偏好只存在于 localStorage,
7
+ * 首次加载时镜像进 cookie 并强刷一次,让 SSR 首帧即以偏好语言渲染
8
+ * (否则 SSR 恒 zh,客户端异步切换在水合竞态下会留下中文 attr 残留)。
9
+ * sessionStorage 守卫防 cookie 写入被挡时的刷新循环。
5
10
  */
6
11
  export default defineNuxtPlugin((nuxtApp) => {
7
12
  const saved = localStorage.getItem('aw.locale')
13
+ const cookie = useCookie<string | undefined>('aw.locale', { maxAge: 60 * 60 * 24 * 365 })
8
14
  if (!saved) return
15
+ if (cookie.value !== saved) {
16
+ const mirrored = sessionStorage.getItem('aw.locale.mirrored')
17
+ if (mirrored !== saved) {
18
+ sessionStorage.setItem('aw.locale.mirrored', saved)
19
+ cookie.value = saved
20
+ window.location.reload()
21
+ return
22
+ }
23
+ }
9
24
  const $i18n = (nuxtApp as unknown as { $i18n?: { locale: { value?: string } | string, setLocale: (l: string) => Promise<unknown> } }).$i18n
10
25
  if (!$i18n) return
11
26
  const current = typeof $i18n.locale === 'string' ? $i18n.locale : $i18n.locale?.value
@@ -0,0 +1,104 @@
1
+ /**
2
+ * 内置目录/种子的展示层翻译映射。
3
+ *
4
+ * 背景:模板目录(shared/daq-protocol、dcw-protocol)与内置种子(模板/编组/Channel 模板/
5
+ * 插件 manifest)的 name/description 是服务端写入的中文数据,DB 记录不做翻译;
6
+ * 但展示层可以按**稳定 key/id** 命中 i18n 词条 —— 未命中(用户自建/改名)回退原始名。
7
+ * 词条在 locale 的 `tplCatalog` / `builtinSeeds` / `plugins` 命名空间。
8
+ */
9
+
10
+ /** 数采/智控模板目录的稳定 key(shared 协议目录) */
11
+ export const TPL_CATALOG_IDS = new Set([
12
+ 'temp-tc',
13
+ 'pressure-tx',
14
+ 'tension-cell',
15
+ 'line-encoder',
16
+ 'vision-cam',
17
+ 'power-meter',
18
+ 'thickness-scan',
19
+ 'ccd-image',
20
+ 'temp-sp',
21
+ 'speed-sp',
22
+ 'tension-sp',
23
+ 'pressure-sp',
24
+ ])
25
+
26
+ /** 内置 Agent 模板 id → 名称词条(server/db DEFAULT_AGENT_TEMPLATES + aml-team-seeds) */
27
+ export const SEED_NAME_KEYS: Record<string, string> = {
28
+ 'tpl-default-lead': 'builtinSeeds.tplDefaultLead',
29
+ 'tpl-default-backend': 'builtinSeeds.tplDefaultBackend',
30
+ 'tpl-default-frontend': 'builtinSeeds.tplDefaultFrontend',
31
+ 'tpl-default-qa': 'builtinSeeds.tplDefaultQa',
32
+ 'tpl-default-docs': 'builtinSeeds.tplDefaultDocs',
33
+ 'tpl-scenario-payment-lead': 'builtinSeeds.tplScenarioPaymentLead',
34
+ 'tpl-aml-lead': 'builtinSeeds.tplAmlLead',
35
+ 'tpl-aml-data': 'builtinSeeds.tplAmlData',
36
+ 'tpl-aml-trainer': 'builtinSeeds.tplAmlTrainer',
37
+ 'tpl-aml-eval': 'builtinSeeds.tplAmlEval',
38
+ 'team-default-fullstack': 'builtinSeeds.teamDefaultFullstack',
39
+ 'team-default-docs': 'builtinSeeds.teamDefaultDocs',
40
+ 'team-aml-shadow': 'builtinSeeds.teamAmlShadow',
41
+ 'chtpl-default-fullstack': 'builtinSeeds.chtplDefaultFullstack',
42
+ 'chtpl-default-review': 'builtinSeeds.chtplDefaultReview',
43
+ 'chtpl-preset-optical-film': 'builtinSeeds.chtplPresetOpticalFilm',
44
+ 'chtpl-preset-extrusion': 'builtinSeeds.chtplPresetExtrusion',
45
+ }
46
+
47
+ /** 内置 Channel 模板 id → 描述/场景预览词条 */
48
+ export const SEED_EXTRA_KEYS: Record<string, { desc?: string, scenario?: string }> = {
49
+ 'chtpl-default-fullstack': { desc: 'builtinSeeds.chtplDefaultFullstackDesc', scenario: 'builtinSeeds.chtplDefaultFullstackScenario' },
50
+ 'chtpl-default-review': { desc: 'builtinSeeds.chtplDefaultReviewDesc', scenario: 'builtinSeeds.chtplDefaultReviewScenario' },
51
+ 'chtpl-preset-optical-film': { desc: 'builtinSeeds.chtplPresetOpticalFilmDesc', scenario: 'builtinSeeds.chtplPresetOpticalFilmScenario' },
52
+ 'chtpl-preset-extrusion': { desc: 'builtinSeeds.chtplPresetExtrusionDesc', scenario: 'builtinSeeds.chtplPresetExtrusionScenario' },
53
+ }
54
+
55
+ /** 插件名 → 描述词条(manifest description 是服务端文件数据) */
56
+ export const PLUGIN_DESC_KEYS: Record<string, string> = {
57
+ 'line-sentinel': 'plugins.descLineSentinel',
58
+ 'ops-notifier': 'plugins.descOpsNotifier',
59
+ 'sample-insight': 'plugins.descSampleInsight',
60
+ 'diag-bridge': 'plugins.descDiagBridge',
61
+ 'rag-bridge': 'plugins.descRagBridge',
62
+ 'serial-bridge': 'plugins.descSerialBridge',
63
+ }
64
+
65
+ type NameLike = { key?: string, id?: string, name: string }
66
+
67
+ /** 内置角色/设备模型 id → 名称/提示词条(useCharacterAssets 内置目录;扫描项回退文件名) */
68
+ export const TOWN_MODEL_KEYS: Record<string, { name: string, hint?: string }> = {
69
+ 'knight': { name: 'builtinSeeds.mKnight' },
70
+ 'mage': { name: 'builtinSeeds.mMage' },
71
+ 'bot': { name: 'builtinSeeds.mBot' },
72
+ 'hero-3d': { name: 'builtinSeeds.mHero3d', hint: 'builtinSeeds.mHero3dHint' },
73
+ 'yangyang-walk': { name: 'builtinSeeds.mYangyang', hint: 'builtinSeeds.mYangyangHint' },
74
+ 'device-3d': { name: 'builtinSeeds.mDevice3d', hint: 'builtinSeeds.mDevice3dHint' },
75
+ }
76
+
77
+ /** 模型 hint 的兜底字面量(composable 里的固定中文提示)→ 词条 */
78
+ export const MODEL_HINT_FALLBACKS: Record<string, string> = {
79
+ '设备实体(拖入场景生成数字孪生)': 'builtinSeeds.mDeviceFallbackHint',
80
+ '角色 3D 模型(在频道成员管理中设置)': 'builtinSeeds.mScannedCharacterHint',
81
+ }
82
+
83
+ export function townModelName(tr: (k: string) => string, m: { id: string, name: string }): string {
84
+ return TOWN_MODEL_KEYS[m.id]?.name ? tr(TOWN_MODEL_KEYS[m.id]!.name) : m.name
85
+ }
86
+
87
+ export function townModelHint(tr: (k: string) => string, m: { id: string, hint?: string }): string | undefined {
88
+ const mapped = TOWN_MODEL_KEYS[m.id]?.hint
89
+ if (mapped) return tr(mapped)
90
+ const fallback = m.hint ? MODEL_HINT_FALLBACKS[m.hint] : undefined
91
+ return fallback ? tr(fallback) : m.hint
92
+ }
93
+
94
+ /** 模板目录显示名:命中稳定 key 走 i18n,否则回退服务端名 */
95
+ export function catalogTplName(tr: (k: string) => string, t: NameLike): string {
96
+ const k = t.key ?? t.id
97
+ return (k && TPL_CATALOG_IDS.has(k)) ? tr(`tplCatalog.${k}`) : t.name
98
+ }
99
+
100
+ /** 内置种子记录显示名:命中稳定 id 走 i18n,否则回退原始名(用户自建/改名不翻译) */
101
+ export function seedName(tr: (k: string) => string, t: { id?: string, templateId?: string, name: string }): string {
102
+ const k = SEED_NAME_KEYS[t.id ?? t.templateId ?? '']
103
+ return k ? tr(k) : t.name
104
+ }
package/config.yml CHANGED
@@ -1,170 +1,170 @@
1
- # ============================================================
2
- # AgentWorkShop 运行配置 —— 运行时默认值的单一事实来源
3
- # ------------------------------------------------------------
4
- # 本文件由 nuxt.config.ts(构建/开发期)与 scripts/start.mjs(生产启动期)
5
- # 读取并解析,驱动整个运行时。修改后重启对应模式即可生效:
6
- # 开发:pnpm dev -> 读取 server.dev
7
- # 生产:pnpm start -> 读取 server.prod
8
- # 例外:app.version 的权威值在 package.json(nuxt.config.ts 以包版本优先,
9
- # 本字段仅作回退)—— 长期不同步过(曾停在 0.7.9 而包已 0.7.35),勿再依赖它。
10
- # ============================================================
11
-
12
- app:
13
- name: AgentWorkShop
14
- title: AgentWorkShop
15
- version: 0.7.36
16
- description: 基于 Nuxt 4 的配置驱动运行范式
17
-
18
- # 运行模式(dev/prod 实际由启动命令决定,此处仅作运行时展示)
19
- mode: dev
20
-
21
- # ------------------------------------------------------------
22
- # 服务端口:dev 与 prod 可分别自定义
23
- # ------------------------------------------------------------
24
- server:
25
- host: 0.0.0.0
26
- dev:
27
- port: 3000
28
- prod:
29
- port: 3001
30
-
31
- # 后端 API(前端 axios 基址 + 服务端行为均由本段驱动)
32
- api:
33
- baseURL: /api
34
- timeout: 15000
35
- pageSize: 20 # 服务端默认分页大小
36
- maxPageSize: 100 # 服务端分页大小上限
37
-
38
- # 国际化
39
- i18n:
40
- defaultLocale: zh-CN
41
- locales:
42
- - code: zh-CN
43
- name: 简体中文
44
- - code: en
45
- name: English
46
-
47
- # 主题
48
- theme:
49
- # Agent Harness · Digital Twin 控制室色板:品牌绿(交互/确认/DAQ)+ 数据青,见 TownView.vue --hud-*
50
- primaryColor: "#35e0a0"
51
- mode: light # light | dark
52
-
53
- # 安全配置
54
- # 数据采集基础设施(数采 DAQ;地址与 docker-compose.yml 默认一致)
55
- # startInfrastructure: never=启动探测,不通且有 Docker 则自动 docker compose 拉起;
56
- # always=仅 Docker 拉起;never=只直连。连接失败降级并警告,可前端一键重连。
57
- daq:
58
- startInfrastructure: auto
59
- mqtt:
60
- host: 127.0.0.1
61
- port: 1883
62
- timescale:
63
- host: 127.0.0.1
64
- port: 5432
65
- user: postgres
66
- password: awshop
67
- database: awshop
68
- # 对象存储(图像帧;MinIO,S3 兼容)。不可达时自动降级本地磁盘 data/daq-objects/,采集不中断。
69
- objectstore:
70
- host: 127.0.0.1
71
- port: 9000
72
- accessKey: awshop
73
- secretKey: awshop-secret
74
- bucket: daq
75
- # 采样节拍(live 可调,热重载):节点未显式指定 intervalMs 时的采集周期与可配置下限。
76
- # 下限同时钳制 create/patch/存量节点;设置页/`aw config set daq.sampling.*` 均可改。
77
- sampling:
78
- defaultIntervalMs: 5000 # 默认 5s
79
- minIntervalMs: 1000 # 下限 1s(绝对硬底 200ms)
80
- # 时序查询节拍(live 可调,热重载):查询未指定 bucketMs 时的降采样桶宽与下限。
81
- # samples / 产线数据查询 / Agent daq_query 三处共用;Agent 工具描述实时携带当前值。
82
- query:
83
- defaultBucketMs: 15000 # 缺省 15s
84
- minBucketMs: 1000 # 下限 1s(绝对硬底 100ms)
85
-
86
- security:
87
- # Session cookie 加密密钥(nuxt-auth-utils 使用)
88
- # 生产环境必须修改为强随机值;可用环境变量 NUXT_SESSION_PASSWORD 覆盖
89
- sessionPassword: awshop-dev-secret-change-me-0123456789
90
- # HITL 审批超时窗 ms(超时默认拒绝;env HITL_TIMEOUT_MS 兼容)
91
- # hitl_timeout_ms: 180000
92
-
93
- # ------------------------------------------------------------
94
- # 以下运行语义组:全部键均可被 env AW_<键>(点转下划线)或历史别名覆盖,
95
- # 优先级 config.yml < data/runtime-settings.json < 环境变量。缺省即用默认。
96
- # ------------------------------------------------------------
97
-
98
- # Agent 记忆系统(env AW_MEMORY_*)
99
- memory:
100
- primer_tokens: 300 # 记忆引子 token 预算(AW_MEMORY_PRIMER_TOKENS)
101
- inject_total: 500 # 单次注入总硬顶(AW_MEMORY_INJECT_TOTAL)
102
- maintenance_ms: 21600000 # 维护调度周期(AW_MEMORY_MAINTENANCE_MS)
103
- expire_days: 180 # 情景记忆保留天数(AW_MEMORY_EXPIRE_DAYS)
104
- expire_session_days: 14 # 会话记忆保留天数(AW_MEMORY_EXPIRE_SESSION_DAYS)
105
- cap: 500 # 条目驱逐上限(AW_MEMORY_CAP)
106
- reflect_trigger: 8 # 空闲反思触发阈值(AW_MEMORY_REFLECT_TRIGGER)
107
- embed_base_url: '' # OpenAI 兼容 /embeddings 基址(AW_MEMORY_EMBED_BASE_URL;空=纯 FTS)
108
- embed_model: '' # 向量模型名(AW_MEMORY_EMBED_MODEL)
109
- embed_api_key: '' # Bearer 密钥(AW_MEMORY_EMBED_API_KEY)
110
-
111
- # omp Agent Harness(env AW_OMP_COMPACT_*)
112
- omp:
113
- compact_enabled: true # 上下文自动压缩总开关(AW_OMP_COMPACT_ENABLED=0 可关)
114
- compact_threshold: 0.7 # 触发压缩的上下文占用比例(AW_OMP_COMPACT_THRESHOLD)
115
- compact_min_interval_ms: 300000 # 两次压缩最小间隔(AW_OMP_COMPACT_MIN_INTERVAL_MS)
116
- compact_wait_ms: 120000 # 等待压缩完成超时(AW_OMP_COMPACT_WAIT_MS)
117
-
118
- # 数控写控制(env DCW_ROLLBACK_*)
119
- dcw:
120
- rollback_cooldown_ms: 300000 # 回退后同向重写冷却(DCW_ROLLBACK_COOLDOWN_MS)
121
- rollback_min_window_ms: 120000 # 判定最小观察窗(DCW_ROLLBACK_MIN_WINDOW_MS)
122
- rollback_baseline_ms: 600000 # 基线回看窗(DCW_ROLLBACK_BASELINE_MS)
123
- rollback_stale_ms: 1800000 # open 记录接管阈值(DCW_ROLLBACK_STALE_MS)
124
-
125
- # 车间运行(env WORKSHOP_IDLE_*)
126
- workshop:
127
- idle_sweep_ms: 30000 # 空闲 agent 扫描周期(WORKSHOP_IDLE_SWEEP_MS)
128
- idle_grace_ms: 120000 # 空闲卸载宽限(WORKSHOP_IDLE_GRACE_MS)
129
-
130
- # 数据备份(env BACKUP_*)
131
- backup:
132
- disabled: false # BACKUP_DISABLED=1 关闭
133
- interval_hours: 24 # 备份间隔(BACKUP_INTERVAL_HOURS)
134
- keep: 7 # 保留份数(BACKUP_KEEP)
135
-
136
- # 数据保留清理(env RETENTION_DISABLED / AW_EVENTS_RETENTION_D 等)
137
- retention:
138
- disabled: false # RETENTION_DISABLED=1 / AW_RETENTION_DISABLED=1 关闭
139
- events_days: 7 # WS 事件流保留天数(AW_EVENTS_RETENTION_D)
140
- messages_days: 30 # Channel 消息(AW_MESSAGES_RETENTION_D)
141
- audit_days: 90 # 审计日志(AW_AUDIT_RETENTION_D)
142
- approval_days: 180 # 审批历史(AW_APPROVAL_RETENTION_D)
143
-
144
- # 服务端日志(env AWSHOP_LOG_LEVEL)
145
- log:
146
- level: info # debug | info | warn | error
147
-
148
- # AML 自动建模平台(Python 训练运行时/作业限额/GC 保留/评测门禁;全部键见 shared/config/schema.json)
149
- aml:
150
- python:
151
- pythonBin: '' # 空=自动探测 python / py -3
152
- uvBin: '' # 空=自动探测 uv(存在则优先)
153
- indexUrl: '' # PyPI 兼容镜像,空=默认源;仅 venv 供给阶段联网,训练进程不联网
154
- job:
155
- timeoutMs: 1800000
156
- maxConcurrent: 2
157
- diskQuotaMb: 2048
158
- stallMs: 600000
159
- dataset:
160
- maxRows: 200000
161
- retentionDays: 30
162
- allowCrossRecipe: false
163
- model:
164
- retiredKeepDays: 90
165
- gates:
166
- nrmse: 0.10
167
- rolloutNrmse: 0.25
168
- valTestGap: 0.20
169
- minRows: 500
170
- minRuns: 3
1
+ # ============================================================
2
+ # AgentWorkShop 运行配置 —— 运行时默认值的单一事实来源
3
+ # ------------------------------------------------------------
4
+ # 本文件由 nuxt.config.ts(构建/开发期)与 scripts/start.mjs(生产启动期)
5
+ # 读取并解析,驱动整个运行时。修改后重启对应模式即可生效:
6
+ # 开发:pnpm dev -> 读取 server.dev
7
+ # 生产:pnpm start -> 读取 server.prod
8
+ # 例外:app.version 的权威值在 package.json(nuxt.config.ts 以包版本优先,
9
+ # 本字段仅作回退)—— 长期不同步过(曾停在 0.7.9 而包已 0.7.35),勿再依赖它。
10
+ # ============================================================
11
+
12
+ app:
13
+ name: AgentWorkShop
14
+ title: AgentWorkShop
15
+ version: 0.7.43
16
+ description: 基于 Nuxt 4 的配置驱动运行范式
17
+
18
+ # 运行模式(dev/prod 实际由启动命令决定,此处仅作运行时展示)
19
+ mode: dev
20
+
21
+ # ------------------------------------------------------------
22
+ # 服务端口:dev 与 prod 可分别自定义
23
+ # ------------------------------------------------------------
24
+ server:
25
+ host: 0.0.0.0
26
+ dev:
27
+ port: 3000
28
+ prod:
29
+ port: 3001
30
+
31
+ # 后端 API(前端 axios 基址 + 服务端行为均由本段驱动)
32
+ api:
33
+ baseURL: /api
34
+ timeout: 15000
35
+ pageSize: 20 # 服务端默认分页大小
36
+ maxPageSize: 100 # 服务端分页大小上限
37
+
38
+ # 国际化
39
+ i18n:
40
+ defaultLocale: zh-CN
41
+ locales:
42
+ - code: zh-CN
43
+ name: 简体中文
44
+ - code: en
45
+ name: English
46
+
47
+ # 主题
48
+ theme:
49
+ # Agent Harness · Digital Twin 控制室色板:品牌绿(交互/确认/DAQ)+ 数据青,见 TownView.vue --hud-*
50
+ primaryColor: "#35e0a0"
51
+ mode: light # light | dark
52
+
53
+ # 安全配置
54
+ # 数据采集基础设施(数采 DAQ;地址与 docker-compose.yml 默认一致)
55
+ # startInfrastructure: never=启动探测,不通且有 Docker 则自动 docker compose 拉起;
56
+ # always=仅 Docker 拉起;never=只直连。连接失败降级并警告,可前端一键重连。
57
+ daq:
58
+ startInfrastructure: auto
59
+ mqtt:
60
+ host: 127.0.0.1
61
+ port: 1883
62
+ timescale:
63
+ host: 127.0.0.1
64
+ port: 5432
65
+ user: postgres
66
+ password: awshop
67
+ database: awshop
68
+ # 对象存储(图像帧;MinIO,S3 兼容)。不可达时自动降级本地磁盘 data/daq-objects/,采集不中断。
69
+ objectstore:
70
+ host: 127.0.0.1
71
+ port: 9000
72
+ accessKey: awshop
73
+ secretKey: awshop-secret
74
+ bucket: daq
75
+ # 采样节拍(live 可调,热重载):节点未显式指定 intervalMs 时的采集周期与可配置下限。
76
+ # 下限同时钳制 create/patch/存量节点;设置页/`aw config set daq.sampling.*` 均可改。
77
+ sampling:
78
+ defaultIntervalMs: 5000 # 默认 5s
79
+ minIntervalMs: 1000 # 下限 1s(绝对硬底 200ms)
80
+ # 时序查询节拍(live 可调,热重载):查询未指定 bucketMs 时的降采样桶宽与下限。
81
+ # samples / 产线数据查询 / Agent daq_query 三处共用;Agent 工具描述实时携带当前值。
82
+ query:
83
+ defaultBucketMs: 15000 # 缺省 15s
84
+ minBucketMs: 1000 # 下限 1s(绝对硬底 100ms)
85
+
86
+ security:
87
+ # Session cookie 加密密钥(nuxt-auth-utils 使用)
88
+ # 生产环境必须修改为强随机值;可用环境变量 NUXT_SESSION_PASSWORD 覆盖
89
+ sessionPassword: awshop-dev-secret-change-me-0123456789
90
+ # HITL 审批超时窗 ms(超时默认拒绝;env HITL_TIMEOUT_MS 兼容)
91
+ # hitl_timeout_ms: 180000
92
+
93
+ # ------------------------------------------------------------
94
+ # 以下运行语义组:全部键均可被 env AW_<键>(点转下划线)或历史别名覆盖,
95
+ # 优先级 config.yml < data/runtime-settings.json < 环境变量。缺省即用默认。
96
+ # ------------------------------------------------------------
97
+
98
+ # Agent 记忆系统(env AW_MEMORY_*)
99
+ memory:
100
+ primer_tokens: 300 # 记忆引子 token 预算(AW_MEMORY_PRIMER_TOKENS)
101
+ inject_total: 500 # 单次注入总硬顶(AW_MEMORY_INJECT_TOTAL)
102
+ maintenance_ms: 21600000 # 维护调度周期(AW_MEMORY_MAINTENANCE_MS)
103
+ expire_days: 180 # 情景记忆保留天数(AW_MEMORY_EXPIRE_DAYS)
104
+ expire_session_days: 14 # 会话记忆保留天数(AW_MEMORY_EXPIRE_SESSION_DAYS)
105
+ cap: 500 # 条目驱逐上限(AW_MEMORY_CAP)
106
+ reflect_trigger: 8 # 空闲反思触发阈值(AW_MEMORY_REFLECT_TRIGGER)
107
+ embed_base_url: '' # OpenAI 兼容 /embeddings 基址(AW_MEMORY_EMBED_BASE_URL;空=纯 FTS)
108
+ embed_model: '' # 向量模型名(AW_MEMORY_EMBED_MODEL)
109
+ embed_api_key: '' # Bearer 密钥(AW_MEMORY_EMBED_API_KEY)
110
+
111
+ # omp Agent Harness(env AW_OMP_COMPACT_*)
112
+ omp:
113
+ compact_enabled: true # 上下文自动压缩总开关(AW_OMP_COMPACT_ENABLED=0 可关)
114
+ compact_threshold: 0.7 # 触发压缩的上下文占用比例(AW_OMP_COMPACT_THRESHOLD)
115
+ compact_min_interval_ms: 300000 # 两次压缩最小间隔(AW_OMP_COMPACT_MIN_INTERVAL_MS)
116
+ compact_wait_ms: 120000 # 等待压缩完成超时(AW_OMP_COMPACT_WAIT_MS)
117
+
118
+ # 数控写控制(env DCW_ROLLBACK_*)
119
+ dcw:
120
+ rollback_cooldown_ms: 300000 # 回退后同向重写冷却(DCW_ROLLBACK_COOLDOWN_MS)
121
+ rollback_min_window_ms: 120000 # 判定最小观察窗(DCW_ROLLBACK_MIN_WINDOW_MS)
122
+ rollback_baseline_ms: 600000 # 基线回看窗(DCW_ROLLBACK_BASELINE_MS)
123
+ rollback_stale_ms: 1800000 # open 记录接管阈值(DCW_ROLLBACK_STALE_MS)
124
+
125
+ # 车间运行(env WORKSHOP_IDLE_*)
126
+ workshop:
127
+ idle_sweep_ms: 30000 # 空闲 agent 扫描周期(WORKSHOP_IDLE_SWEEP_MS)
128
+ idle_grace_ms: 120000 # 空闲卸载宽限(WORKSHOP_IDLE_GRACE_MS)
129
+
130
+ # 数据备份(env BACKUP_*)
131
+ backup:
132
+ disabled: false # BACKUP_DISABLED=1 关闭
133
+ interval_hours: 24 # 备份间隔(BACKUP_INTERVAL_HOURS)
134
+ keep: 7 # 保留份数(BACKUP_KEEP)
135
+
136
+ # 数据保留清理(env RETENTION_DISABLED / AW_EVENTS_RETENTION_D 等)
137
+ retention:
138
+ disabled: false # RETENTION_DISABLED=1 / AW_RETENTION_DISABLED=1 关闭
139
+ events_days: 7 # WS 事件流保留天数(AW_EVENTS_RETENTION_D)
140
+ messages_days: 30 # Channel 消息(AW_MESSAGES_RETENTION_D)
141
+ audit_days: 90 # 审计日志(AW_AUDIT_RETENTION_D)
142
+ approval_days: 180 # 审批历史(AW_APPROVAL_RETENTION_D)
143
+
144
+ # 服务端日志(env AWSHOP_LOG_LEVEL)
145
+ log:
146
+ level: info # debug | info | warn | error
147
+
148
+ # AML 自动建模平台(Python 训练运行时/作业限额/GC 保留/评测门禁;全部键见 shared/config/schema.json)
149
+ aml:
150
+ python:
151
+ pythonBin: '' # 空=自动探测 python / py -3
152
+ uvBin: '' # 空=自动探测 uv(存在则优先)
153
+ indexUrl: '' # PyPI 兼容镜像,空=默认源;仅 venv 供给阶段联网,训练进程不联网
154
+ job:
155
+ timeoutMs: 1800000
156
+ maxConcurrent: 2
157
+ diskQuotaMb: 2048
158
+ stallMs: 600000
159
+ dataset:
160
+ maxRows: 200000
161
+ retentionDays: 30
162
+ allowCrossRecipe: false
163
+ model:
164
+ retiredKeepDays: 90
165
+ gates:
166
+ nrmse: 0.10
167
+ rolloutNrmse: 0.25
168
+ valTestGap: 0.20
169
+ minRows: 500
170
+ minRuns: 3
package/docs/cli.en.md CHANGED
@@ -62,7 +62,7 @@ pnpm tui # the terminal workbench
62
62
  ### 3. Quick use via npx (no global install)
63
63
 
64
64
  ```bash
65
- npx agentworkshop start # fetch and start (pin a version with: npx agentworkshop@0.7.38 start)
65
+ npx agentworkshop start # fetch and start (pin a version with: npx agentworkshop@0.7.41 start)
66
66
  npx agentworkshop doctor # subcommands work as usual
67
67
  npx -p agentworkshop aw doctor # use -p when you want the name aw
68
68
  ```
@@ -79,7 +79,7 @@ npx -p agentworkshop aw doctor # use -p when you want the name aw
79
79
  | Package manager | `pnpm@11.9.0` (`packageManager`, needed only for source development) |
80
80
  | Module format | ESM (`type: module`) |
81
81
  | License | `PolyForm-Noncommercial-1.0.0` |
82
- | Current version | `0.7.38` (`package.json`) |
82
+ | Current version | `0.7.41` (`package.json`) |
83
83
 
84
84
  ## 2. First start (the Claude Code experience)
85
85
 
package/docs/cli.md CHANGED
@@ -60,7 +60,7 @@ pnpm tui # 终端工作台
60
60
  ### 3. npx 快速使用(免全局安装)
61
61
 
62
62
  ```bash
63
- npx agentworkshop start # 拉取并启动(可锁定版本: npx agentworkshop@0.7.38 start)
63
+ npx agentworkshop start # 拉取并启动(可锁定版本: npx agentworkshop@0.7.41 start)
64
64
  npx agentworkshop doctor # 子命令照常可用
65
65
  npx -p agentworkshop aw doctor # 需要 aw 这个名字时用 -p 指定包
66
66
  ```
@@ -76,7 +76,7 @@ npx -p agentworkshop aw doctor # 需要 aw 这个名字时用 -p 指定包
76
76
  | 包管理器 | `pnpm@11.9.0`(`packageManager`,仅源码开发需要) |
77
77
  | 模块形态 | ESM(`type: module`) |
78
78
  | 许可证 | `PolyForm-Noncommercial-1.0.0` |
79
- | 当前版本 | `0.7.38`(`package.json`) |
79
+ | 当前版本 | `0.7.41`(`package.json`) |
80
80
 
81
81
  ## 二、首次启动(Claude Code 式)
82
82
 
@@ -74,7 +74,6 @@
74
74
  | `NO_PROXY='127.0.0.1,localhost' node scripts/_dbg-render-regression.mjs http://127.0.0.1:3001 admin@awshop.local admin123` | 关键页渲染回归 | 29 |
75
75
  | `AW_E2E_TOKEN=… NO_PROXY='127.0.0.1,localhost' node scripts/e2e-config-groups.mjs` | 配置分组系统 + 两桥接插件正确/错误 token·URL 实测 | 58 |
76
76
  | `E2E_USER=admin@awshop.local E2E_PASS=admin123 NO_PROXY='127.0.0.1,localhost' node scripts/_dbg-groups-ui-verify.mjs` | 设置页分组 UI(浏览器实测) | 16 |
77
- | `node scripts/_dbg-daq-rowstyle-verify.mjs` | 数采行样式 + 设置页三节拍 | 10+6 |
78
77
  | `node scripts/_dbg-daq-intervals-func.mjs` | 三节拍(采集/WS下发/趋势刷新)独立热生效 + 下限钳制 + 详情页按节拍实测重拉 | 13 |
79
78
  | `node scripts/_dbg-town-smoke.mjs` | 数字孪生画布/场景钩子/帧推进 | 5 |
80
79
 
@@ -87,7 +86,7 @@
87
86
  | 脚本 | 覆盖 | 基线 |
88
87
  |---|---|---|
89
88
  | `NO_PROXY='*' node scripts/_dbg-protocol-matrix.mjs` | 5 协议 DAQ 读取 + 4 路 DCW 读/写闭环(modbus-tcp SP→PV 真收敛) | 全绿 |
90
- | `NO_PROXY='127.0.0.1,localhost' node scripts/_dbg-live-line-e2e.mjs http://127.0.0.1:3001` | S1 夹具→S2 协议连通→S3 数采落库→S4 五路数控→S5 Agent 闭环(CLOSEDLOOP-OK)→S6 HITL 真实写入 | 37 |
89
+ | `node bench/pipeline.mjs --profile integrated` | 五协议工业闭环现行门禁(原 37 项 live-line 脚本因模拟器端口演进退役,覆盖并入 bench P 阶段):连通→数采落库→五路数控→Agent 闭环→HITL→配方/参数回退 | 75 |
91
90
  | `AW_E2E_TOKEN=… NO_PROXY='127.0.0.1,localhost' node scripts/e2e-plc-plugin-closedloop.mjs` | A 插件健康 / B 产线供给 / C 数采交叉核对 / D 真实诊断 / E 知识闭环 / F 参数逐键热生效 / G Channel 级开关 | 71 |
92
91
  | `AW_E2E_TOKEN=… NO_PROXY='127.0.0.1,localhost' node scripts/production-closed-loop-e2e.mjs` | 生产闭环增强:事件自动诊断(source=auto)→kb_search→dcw_control(HITL)→回写 | 23 |
93
92
  | `AW_E2E_TOKEN=… NO_PROXY='127.0.0.1,localhost' node scripts/three-system-e2e.mjs`(可选 `--full` 走 omp 真实诊断) | AW × 深度诊断 × rag-knowledge 三系统;插件启停热重载 | 52 |
@@ -135,7 +134,7 @@
135
134
  ## Phase 7 浏览器目视验收(Puppeteer 截图逐页过目)
136
135
 
137
136
  覆盖页:登录/仪表盘/产线管理/数采列表+详情(趋势图在动)/数控/数字孪生(帧推进+无黑屏)/设置(分组渲染+折叠+来源徽标)/插件/运维日志 /logs/AML/AgentTeam。
138
- 工具:`scripts/ui-screenshot.mjs`、`scripts/_dbg-audit-all-pages.mjs`(全页 console error 扫描=0)。截图存 `.e2e-shots/` 逐张目视;破版/白屏/控制台报错即红项。
137
+ 工具:`scripts/ui-screenshot.mjs`、`scripts/ui/audit-layout.mjs`、`scripts/_sweep-button-contrast.mjs`(双主题全路由按钮对比度+空按钮扫描)。截图存 `.e2e-shots/` 逐张目视;破版/白屏/控制台报错即红项。
139
138
 
140
139
  ---
141
140
 
@@ -9,7 +9,7 @@
9
9
  >
10
10
  > Applies to: plugin system v2 has been available since **v0.7.29** (frontend component
11
11
  > injection / plugin settings / plugin i18n / runtime services surface); this document
12
- > describes **v0.7.38**. `ctx.sdkVersion` is currently `0.3.0`.
12
+ > describes **v0.7.41**. `ctx.sdkVersion` is currently `0.3.0`.
13
13
 
14
14
  ## 1. Folder layout & quick start
15
15
 
@@ -210,10 +210,41 @@ async setup(ctx) {
210
210
  | Events | `ctx.events.on(type, fn)` / `ctx.events.off(type, fn)` | scene-event sugar: subscribes to `event:<type>` internally (see §7) |
211
211
  | Paths | `ctx.paths.home / configRoot / dataDir`; `ctx.dataDir` | `ctx.dataDir` is this plugin's KV folder, `<configRoot>/data/plugins/<plugin>` |
212
212
  | DAQ | `ctx.daq.registerDriver / registerProcessor / registerTemplate / onFrame / onSample / query / nodes` | driver, sink-processor and node-template registration + time-series queries + node metadata snapshot |
213
+ | Write control | `ctx.dcw.registerWriteDriver(driver)` | write-driver injection (symmetric to DAQ read drivers): contract `{ kind, available(), write(input), test(cfg), read?(input), meta? }`; disabled plugins lose their drivers on hot reload |
213
214
  | Tools | `ctx.omp.registerTool({ name, label?, description, parameters, roles?, handler })` | agent tool injection; `roles` accepts `'lead'` and `'worker'` only (see §10) |
214
215
  | Services | `ctx.services.names()` / `.get(name)` / `.provide(name, getter)` | runtime object surface: `get('daq' \| 'lines' \| 'channels' \| 'plugins')`; `provide` auto-prefixes `<plugin>.` |
215
216
  | Permissions | `ctx.permissions.lineMode / visibleLineIds / listGrants / setGrants` | line-grant queries and management |
216
217
 
218
+ ### Communication-protocol plugins (custom interface connections)
219
+
220
+ `ctx.daq.registerDriver` / `ctx.dcw.registerWriteDriver` are the **protocol plug-in points**: serial
221
+ links, other PLC protocols and private buses all inject here — the main pipelines (sampling loop /
222
+ write gateway / frontend forms) need zero changes.
223
+
224
+ ```js
225
+ ctx.daq.registerDriver({
226
+ kind: 'serial', // custom protocol kind (overriding a builtin logs a warning)
227
+ async available() { return true }, // protocol-stack probe (missing package → UI shows "not installed")
228
+ async sample({ driverConfig }) { return 25.3 }, // reading (scalar or v2 frame envelope)
229
+ async test(driverConfig) { return { ok: true, message: 'connected', sampleValue: 25.3 } },
230
+ meta: { // self-description (frontend "add node" dropdown + dynamic form)
231
+ label: 'Serial (RS-232/485)',
232
+ status: 'real',
233
+ configFields: [{ key: 'path', label: 'Port path', type: 'string', required: true, placeholder: 'COM3' }],
234
+ },
235
+ })
236
+ ```
237
+
238
+ Key points:
239
+ - The driver catalog is served via the `drivers` field of `GET /api/workshop/daq` (read) and
240
+ `GET /api/workshop/dcw` (write); the DAQ/DCW pages render plugin protocols and their forms from it
241
+ (with a ⌁ badge). Drivers registered without `meta` only appear in availability;
242
+ - Hot reload clears all plugin drivers first, then re-loads: **disabled/unloaded protocol drivers
243
+ take effect immediately upon removal** and never linger until restart;
244
+ - Builtin example: `server/plugins-builtin/serial-bridge` (serial Modbus RTU + ASCII line protocol,
245
+ with read/write drivers, `health`/`ports`/`probe` APIs, a frontend panel and the `serial_ports`
246
+ agent tool) — use it as the template for new protocol plugins.
247
+
217
248
  ### Where KV lives
218
249
 
219
250
  `<configRoot>/data/plugins/<plugin>/kv.json` — **not** inside the plugin folder. Writes are authoritative in memory and flushed atomically (`tmp` + `rename`) after a 200 ms debounce; on shutdown and hot reload the pending debounce is cancelled and the state is flushed synchronously. `ctx.kv` has exactly four methods: `get / set / all / bump`.
@@ -524,6 +555,7 @@ export default {
524
555
  - **A newly enabled browser plugin injects within 15 s** (instantly when the WS channel is up).
525
556
  - **`server:close` / `onDispose` depend on graceful shutdown signals**; a forced kill on Windows does not trigger them.
526
557
  - **`aw plugin list` only scans directories** — it reflects neither load failures nor runtime health.
558
+ - **Protocol plugins share the host process with their native stacks**: serial-bridge's RTU framing is a self-contained implementation (single serialport native stack; modbus-serial is deliberately NOT used — its wrapper reproducibly crashed under dev mode). Known boundary: **inside the `aw dev` process, a serial transaction that ends in write → timeout → close can trigger a native V8 crash in `bindings-cpp`** (HandleScope fatal — not catchable in JS, regardless of which port is used); **production mode (`aw start`) is unaffected — the exact same sequence was verified live to return an honest timeout with the server healthy**, and open-only probes are also fine under dev. Connect real hardware during development with this in mind; for hardened deployments, run the serial gateway in its own process (see the plc-node-simulator child-process pattern).
527
559
 
528
560
  ## 13. Pre-release checklist
529
561