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
@@ -0,0 +1,88 @@
1
+ /**
2
+ * 视口断点(browser-only,SSR 安全) —— 全站响应式布局的唯一判据。
3
+ *
4
+ * 为什么需要它:CSS 媒体查询能改样式,但改不了**行为**——
5
+ * 窄屏的侧栏不是"收窄的侧栏",而是一个抽屉(开合状态、焦点陷阱、滚动锁定
6
+ * 都是行为)。行为必须由 JS 知道当前处于哪一档。
7
+ *
8
+ * 断点值与 main.css v5 响应式层注释一一对应(那里是数值的唯一出处):
9
+ * ≥1024 桌面 / 900–1023 图标轨 / 640–899 抽屉 / <640 单列
10
+ *
11
+ * SSR 期间一律返回桌面档:服务端没有视口,猜一个"手机"会让桌面首帧闪一下抽屉。
12
+ * 首帧由 CSS 媒体查询兜住布局,客户端挂载后再由本 composable 接管行为。
13
+ */
14
+ import { onBeforeUnmount, onMounted, ref } from 'vue'
15
+
16
+ export type ViewportTier = 'desktop' | 'compact' | 'tablet' | 'mobile'
17
+
18
+ /** 断点常量(唯一出处见 main.css v5 注释) */
19
+ export const BREAKPOINTS = {
20
+ /** 三栏仪表台下限 */
21
+ desktop: 1024,
22
+ /** 抽屉导航阈值 */
23
+ drawer: 900,
24
+ /** 单列阈值 */
25
+ single: 640,
26
+ } as const
27
+
28
+ const width = ref(0)
29
+ let listeners = 0
30
+ let onResize: (() => void) | null = null
31
+
32
+ function ensureListener() {
33
+ if (typeof window === 'undefined' || onResize) return
34
+ onResize = () => {
35
+ width.value = window.innerWidth
36
+ }
37
+ window.addEventListener('resize', onResize, { passive: true })
38
+ window.addEventListener('orientationchange', onResize, { passive: true })
39
+ width.value = window.innerWidth
40
+ }
41
+
42
+ function releaseListener() {
43
+ if (typeof window === 'undefined' || !onResize) return
44
+ window.removeEventListener('resize', onResize)
45
+ window.removeEventListener('orientationchange', onResize)
46
+ onResize = null
47
+ }
48
+
49
+ export function useResponsive() {
50
+ // 客户端 setup 期就取一次真实视口:不能只等 onMounted ——
51
+ // 依赖方(侧栏/顶栏)的判断会在首帧就求值,晚一拍就会渲染出桌面结构再翻转。
52
+ if (typeof window !== 'undefined' && !width.value) {
53
+ width.value = window.innerWidth
54
+ }
55
+
56
+ onMounted(() => {
57
+ listeners += 1
58
+ ensureListener()
59
+ })
60
+ onBeforeUnmount(() => {
61
+ listeners = Math.max(0, listeners - 1)
62
+ if (listeners === 0) releaseListener()
63
+ })
64
+
65
+ /** 未挂载(=SSR/首帧)时按桌面档渲染,避免首屏结构抖动 */
66
+ const w = computed(() => (width.value || 1440))
67
+
68
+ const isMobile = computed(() => w.value < BREAKPOINTS.single)
69
+ const isDrawer = computed(() => w.value < BREAKPOINTS.drawer)
70
+ const isTablet = computed(() => w.value >= BREAKPOINTS.drawer && w.value < BREAKPOINTS.desktop)
71
+ const isDesktop = computed(() => w.value >= BREAKPOINTS.desktop)
72
+
73
+ const tier = computed<ViewportTier>(() => {
74
+ if (isDrawer.value) return isMobile.value ? 'mobile' : 'compact'
75
+ if (isTablet.value) return 'tablet'
76
+ return 'desktop'
77
+ })
78
+
79
+ // 把当前档位镜像到 <html data-vp-tier>:E2E 与视觉走查脚本据此断言,
80
+ // 不必反推"这一屏到底该不该有抽屉"。
81
+ if (import.meta.client) {
82
+ watchEffect(() => {
83
+ document.documentElement.dataset.vpTier = tier.value
84
+ })
85
+ }
86
+
87
+ return { width: w, tier, isMobile, isTablet, isDesktop, isDrawer }
88
+ }
@@ -28,6 +28,9 @@ export function useRouteMeta() {
28
28
  '/tokens': { key: 'menu.tokens', icon: 'i-tabler-key' },
29
29
  '/daq': { key: 'menu.daq', icon: 'i-tabler-activity' },
30
30
  '/dcw': { key: 'menu.dcw', icon: 'i-tabler-settings-automation' },
31
+ // ⚠️ 漏了这条时 /aml 会落到 slug 兜底,顶栏标题显示成「Aml」—— 实测破相。
32
+ // 新增路由必须同时登记进这张表,否则标题就是"路径首字母大写"。
33
+ '/aml': { key: 'menu.aml', icon: 'i-tabler-flask' },
31
34
  '/logs': { key: 'menu.logs', icon: 'i-tabler-list-details' },
32
35
  '/permissions': { key: 'menu.permissions', icon: 'i-tabler-shield-lock' },
33
36
  '/plugins': { key: 'menu.plugins', icon: 'i-tabler-puzzle' },
@@ -10,7 +10,7 @@ import { reactive } from 'vue'
10
10
  import { useTownBus } from './useTownBus'
11
11
  import { apiFetch } from './apiClient'
12
12
  import type { AepEnvelope } from '#shared/workshop-protocol'
13
- import { DAQ_TEMPLATES, type AepDaqControllerState, type AepDaqFrame, type AepDaqReading, type AepDaqNodeChange, type AepDaqTemplateChange, type DaqNodeView, type DaqTemplateDef, type DaqTemplateInput } from '#shared/daq-protocol'
13
+ import { DAQ_TEMPLATES, DAQ_DRIVERS, type AepDaqControllerState, type AepDaqFrame, type AepDaqReading, type AepDaqNodeChange, type AepDaqTemplateChange, type DaqDriverCatalogEntry, type DaqNodeView, type DaqTemplateDef, type DaqTemplateInput } from '#shared/daq-protocol'
14
14
 
15
15
  /** 历史缓冲长度(1s 默认周期 ≈ 最近 5 分钟趋势) */
16
16
  const HIST_CAP = 60
@@ -57,7 +57,8 @@ interface DaqControllerState {
57
57
  interface DaqBackendMeta {
58
58
  tsdb: string
59
59
  queue: string
60
- drivers: Array<{ kind: string, label: string, status: 'builtin' | 'planned' | 'real' }>
60
+ /** 驱动目录(REST `drivers` 权威收敛:内置 + 协议插件自描述;首帧先用内置目录) */
61
+ drivers: DaqDriverCatalogEntry[]
61
62
  produced: number
62
63
  consumed: number
63
64
  dropped: number
@@ -110,7 +111,7 @@ const createStore = () => {
110
111
  const alarms = reactive<DaqAlarmRow[]>([]) // S5:未确认报警(轮询 + ack 后刷新)
111
112
  const controller = reactive<DaqControllerState>({ running: true, defaultIntervalMs: 1000, defaultPublishIntervalMs: 0, queryDisplayIntervalMs: 5000, nodesTotal: 0, nodesOnline: 0 })
112
113
  const meta = reactive<DaqBackendMeta>({
113
- tsdb: '…', queue: '…', drivers: [], driverAvailable: {},
114
+ tsdb: '…', queue: '…', drivers: DAQ_DRIVERS.map(d => ({ kind: d.kind, label: d.label, status: d.status, configFields: d.configFields })), driverAvailable: {},
114
115
  infra: undefined,
115
116
  produced: 0, consumed: 0, dropped: 0, samplesStored: 0,
116
117
  })
@@ -266,7 +267,7 @@ const createStore = () => {
266
267
 
267
268
  async function load(): Promise<void> {
268
269
  try {
269
- const data = await api<{ controller: DaqControllerState, nodes: DaqNodeView[], meta: DaqBackendMeta, driverAvailable?: Record<string, boolean>, infra?: DaqInfraState, templates?: DaqTemplateDef[] }>('')
270
+ const data = await api<{ controller: DaqControllerState, nodes: DaqNodeView[], meta: DaqBackendMeta, driverAvailable?: Record<string, boolean>, drivers?: DaqDriverCatalogEntry[], infra?: DaqInfraState, templates?: DaqTemplateDef[] }>('')
270
271
  // 快照合并:hist 是客户端读数流资产,轮询重载不得清零;
271
272
  // 已有节点就地 assign(保留对象身份 → Vue 只补丁变化字段,不触发整表数组级失效),hist 自然保留
272
273
  const prev = new Map(nodes.map(n => [n.id, n]))
@@ -291,6 +292,8 @@ const createStore = () => {
291
292
  Object.assign(controller, data.controller)
292
293
  Object.assign(meta, data.meta ?? {})
293
294
  meta.driverAvailable = data.driverAvailable ?? {}
295
+ // 驱动目录 server 权威(含协议插件);server 未下发(旧版)时保留内置目录
296
+ if (data.drivers?.length) meta.drivers = data.drivers
294
297
  meta.infra = data.infra
295
298
  if (data.templates?.length) applyTemplates(data.templates)
296
299
  store.loaded = true
@@ -8,7 +8,8 @@ import { reactive } from 'vue'
8
8
  import { useTownBus } from './useTownBus'
9
9
  import { apiFetch } from './apiClient'
10
10
  import type { AepEnvelope } from '#shared/workshop-protocol'
11
- import { DCW_TEMPLATES, type AepDcwControllerState, type AepDcwNodeChange, type AepDcwRead, type AepDcwWritten, type DcwNodeView, type DcwParamLedger, type DcwTemplateDef, type DcwTemplateInput, type LineInput, type LineQueryOpts, type LineQueryResult, type LineRunState, type LineView, type OptimizationRecord, type OptimizationVerdict, type ProductInput, type ProductView, type RecipeInput, type RecipeRunView, type RecipeView, type RecipeRunData } from '#shared/dcw-protocol'
11
+ import { DCW_TEMPLATES, DCW_DRIVERS, type AepDcwControllerState, type AepDcwNodeChange, type AepDcwRead, type AepDcwWritten, type DcwNodeView, type DcwParamLedger, type DcwTemplateDef, type DcwTemplateInput, type LineInput, type LineQueryOpts, type LineQueryResult, type LineRunState, type LineView, type OptimizationRecord, type OptimizationVerdict, type ProductInput, type ProductView, type RecipeInput, type RecipeParam, type RecipeRunView, type RecipeView, type RecipeRunData } from '#shared/dcw-protocol'
12
+ import type { DaqDriverCatalogEntry } from '#shared/daq-protocol'
12
13
 
13
14
  export type { DcwNodeView }
14
15
 
@@ -35,6 +36,8 @@ function createStore() {
35
36
  const lineStates = reactive<Record<string, LineRunState>>({})
36
37
  /** Agent 优化记录(调控闭环;dcw.optimization.changed 实时收敛) */
37
38
  const optimizations = reactive<OptimizationRecord[]>([])
39
+ /** 写驱动目录(REST `drivers` 权威:内置 + 协议插件自描述;首帧先用内置目录) */
40
+ const driverCatalog = reactive<DaqDriverCatalogEntry[]>(DCW_DRIVERS.map(d => ({ kind: d.kind, label: d.label, status: d.status, configFields: d.configFields })))
38
41
 
39
42
  function upsert(node: DcwNodeView): void {
40
43
  const i = nodes.findIndex(x => x.id === node.id)
@@ -112,12 +115,14 @@ function createStore() {
112
115
 
113
116
  async function load(): Promise<void> {
114
117
  try {
115
- const data = await api<{ controller: AepDcwControllerState, nodes: DcwNodeView[], templates?: DcwTemplateDef[], recipes?: RecipeView[], runs?: RecipeRunView[], history?: DcwWriteHistoryEntry[], products?: ProductView[], lines?: LineView[], lineStates?: LineRunState[] }>('')
118
+ const data = await api<{ controller: AepDcwControllerState, nodes: DcwNodeView[], templates?: DcwTemplateDef[], drivers?: DaqDriverCatalogEntry[], recipes?: RecipeView[], runs?: RecipeRunView[], history?: DcwWriteHistoryEntry[], products?: ProductView[], lines?: LineView[], lineStates?: LineRunState[] }>('')
116
119
  nodes.splice(0, nodes.length, ...data.nodes)
117
120
  nodeIndex.clear()
118
121
  for (const n of nodes) nodeIndex.set(n.id, n)
119
122
  Object.assign(controller, data.controller)
120
123
  if (data.templates?.length) templates.splice(0, templates.length, ...data.templates.map(t => ({ ...t })))
124
+ // 写驱动目录 server 权威(含协议插件);server 未下发(旧版)时保留内置目录
125
+ if (data.drivers?.length) driverCatalog.splice(0, driverCatalog.length, ...data.drivers)
121
126
  recipes.splice(0, recipes.length, ...(data.recipes ?? []))
122
127
  runs.splice(0, runs.length, ...(data.runs ?? []))
123
128
  history.splice(0, history.length, ...(data.history ?? []))
@@ -144,6 +149,7 @@ function createStore() {
144
149
  lines,
145
150
  lineStates,
146
151
  optimizations,
152
+ driverCatalog,
147
153
  loaded: false,
148
154
  error: '',
149
155
  ensureWsFeed,
@@ -13,9 +13,9 @@ export function useVisibleInterval(
13
13
  const bgMs = opts.bgMs === undefined ? ms * 3 : opts.bgMs
14
14
  let timer: ReturnType<typeof setInterval> | null = null
15
15
 
16
- function start(interval: number): void {
16
+ function start(interval: number | null): void {
17
17
  stop()
18
- if (interval > 0) timer = setInterval(fn, interval)
18
+ if (interval !== null && interval > 0) timer = setInterval(fn, interval)
19
19
  }
20
20
  function stop(): void {
21
21
  if (timer) {
@@ -109,7 +109,7 @@ export function useWorkshopApi() {
109
109
  http.post<{ data: { channelId: string, leadAgentId?: string, workspace: string } }>('/workshop/channels', body),
110
110
  deleteChannel: (id: string) => http.delete<{ data: unknown }>(`/workshop/channels/${id}`),
111
111
  /** 修改 Channel 实例设置(场景 prompt / 工作目录热更新;成员运行时自动回收重装配) */
112
- patchChannel: (id: string, body: { name?: string, description?: string, scenarioPrompt?: string, workspace?: string, enabled?: number }) =>
112
+ patchChannel: (id: string, body: { name?: string, description?: string, scenarioPrompt?: string, workspace?: string, enabled?: number, llm?: { provider?: string, model?: string, effort?: string } | null }) =>
113
113
  http.request<{ data: ChannelDto }>({ method: 'PATCH', url: `/workshop/channels/${id}`, data: body }),
114
114
  // channel agents
115
115
  listChannelAgents: (id: string) => http.get<{ data: AgentInfoDto[] }>(`/workshop/channels/${id}/agents`),
@@ -44,9 +44,25 @@ const site = useSiteConfig()
44
44
  >
45
45
  <span class="footer-title aw-serif-accent">{{ site.title }}</span>
46
46
  <span class="sep">/</span>
47
- <span>v{{ site.version }}</span>
48
- <span class="sep">/</span>
49
47
  <span>mode={{ site.mode }}</span>
48
+ <!-- 右下角:版本 + 开源地址 + 文档(弱化铭牌,hover 才现交互态) -->
49
+ <span class="footer-corner">
50
+ <span>v{{ site.version }}</span>
51
+ <span class="sep">·</span>
52
+ <a
53
+ class="footer-link"
54
+ href="https://github.com/kingdol666/AgentWorkShop"
55
+ target="_blank"
56
+ rel="noopener"
57
+ >GitHub</a>
58
+ <span class="sep">·</span>
59
+ <a
60
+ class="footer-link"
61
+ href="https://kingdol666.github.io/AgentWorkShop/"
62
+ target="_blank"
63
+ rel="noopener"
64
+ >Docs</a>
65
+ </span>
50
66
  </a-layout-footer>
51
67
  </a-layout>
52
68
 
@@ -91,6 +107,7 @@ const site = useSiteConfig()
91
107
 
92
108
  /* 页脚:mono 铭牌行(固定高度,供 harness 页计算视口高度);壳层玻璃收边 */
93
109
  .app-footer {
110
+ position: relative;
94
111
  background: var(--mat-chrome-bg);
95
112
  backdrop-filter: var(--vibrancy-chrome);
96
113
  border-top: 1px solid var(--glass-line);
@@ -114,4 +131,31 @@ const site = useSiteConfig()
114
131
  .footer-title {
115
132
  font-size: 13px;
116
133
  }
134
+
135
+ /* 右下角铭牌:版本/开源地址/文档 —— 与中央铭牌同色系弱化,hover 才亮起,不抢视觉 */
136
+ .footer-corner {
137
+ position: absolute;
138
+ right: 24px;
139
+ bottom: 0;
140
+ display: inline-flex;
141
+ gap: 8px;
142
+ align-items: center;
143
+ height: 100%;
144
+ color: var(--ink-faint);
145
+ font-size: 10px;
146
+ letter-spacing: 0.06em;
147
+ }
148
+
149
+ .footer-corner .footer-link {
150
+ color: inherit;
151
+ text-decoration: none;
152
+ border-bottom: 1px solid transparent;
153
+ transition: color 0.15s ease, border-color 0.15s ease;
154
+ }
155
+
156
+ .footer-corner .footer-link:hover {
157
+ color: inherit;
158
+ opacity: 0.85;
159
+ border-bottom-color: currentColor;
160
+ }
117
161
  </style>