agentworkshop 0.7.38 → 0.7.40

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 (392) hide show
  1. package/.AgentWorkShop/prompts/aml-mission-default.md +20 -20
  2. package/.AgentWorkShop/prompts/aml-playbook.md +49 -49
  3. package/.AgentWorkShop/prompts/host-tools.json +1293 -1238
  4. package/.AgentWorkShop/prompts/peer-reply-cross-channel.md +10 -10
  5. package/.output/.AgentWorkShop/prompts/aml-mission-default.md +20 -20
  6. package/.output/.AgentWorkShop/prompts/aml-playbook.md +49 -49
  7. package/.output/.AgentWorkShop/prompts/host-tools.json +1293 -1238
  8. package/.output/.AgentWorkShop/prompts/peer-reply-cross-channel.md +10 -10
  9. package/.output/nitro.json +1 -1
  10. package/.output/public/_nuxt/88GOowgO2.js +1 -0
  11. package/.output/public/_nuxt/{BNT8gYU92.js → BC9wjTJK2.js} +2 -2
  12. package/.output/public/_nuxt/BOt2SP4z.js +1 -0
  13. package/.output/public/_nuxt/BP-NyKVG.js +18 -0
  14. package/.output/public/_nuxt/{HBLJ-wei.js → BXxH0UQE.js} +1 -1
  15. package/.output/public/_nuxt/{zIGh7R49.js → BneN7fbu.js} +1 -1
  16. package/.output/public/_nuxt/BsROmY89.js +1 -0
  17. package/.output/public/_nuxt/{C_OLzD09.js → C4oW1HsE.js} +1 -1
  18. package/.output/public/_nuxt/CFxtLwjp.js +1 -0
  19. package/.output/public/_nuxt/{Cec0Ua3F.js → CS50LB_l.js} +1 -1
  20. package/.output/public/_nuxt/C_iYD-EB.js +1 -0
  21. package/.output/public/_nuxt/{DAe0h2MB.js → ClILjvWH.js} +1 -1
  22. package/.output/public/_nuxt/CssgYAAL2.js +1 -0
  23. package/.output/public/_nuxt/{CY9LbPCI.js → CzOCSGLe.js} +1 -1
  24. package/.output/public/_nuxt/D8qvkfyY.js +1 -0
  25. package/.output/public/_nuxt/DCn7QZ5N.js +2 -0
  26. package/.output/public/_nuxt/DGIuvyRN2.js +1 -0
  27. package/.output/public/_nuxt/{CojCTLKD.js → DGj-WEBg.js} +1 -1
  28. package/.output/public/_nuxt/{DDShH71m.js → DS8qj8EL.js} +1 -1
  29. package/.output/public/_nuxt/DTFCy6h-.js +1 -0
  30. package/.output/public/_nuxt/{DrYV5i68.js → DUjW5Yq5.js} +1 -1
  31. package/.output/public/_nuxt/DZshyNLa.js +1 -0
  32. package/.output/public/_nuxt/{45zuyAso.js → D_OTvQza.js} +1 -1
  33. package/.output/public/_nuxt/DcsCcxp4.js +1 -0
  34. package/.output/public/_nuxt/{DUrecWPx.js → Dihnimlk.js} +2 -2
  35. package/.output/public/_nuxt/Dqw1lpr-.js +1 -0
  36. package/.output/public/_nuxt/{BG8sCcwx.js → Dr9v6C0f.js} +9 -9
  37. package/.output/public/_nuxt/{8NMOXZOV.js → Du9ZJtnj.js} +1 -1
  38. package/.output/public/_nuxt/TownView.f-YOdXRs.css +1 -0
  39. package/.output/public/_nuxt/_id_.CM4bIgKY.css +1 -0
  40. package/.output/public/_nuxt/_id_.bNV69Dtf.css +1 -0
  41. package/.output/public/_nuxt/_wsId_.B4WiqkIS.css +1 -0
  42. package/.output/public/_nuxt/agents.ZD0rVdHE.css +1 -0
  43. package/.output/public/_nuxt/aml.BN8ZEW4h.css +1 -0
  44. package/.output/public/_nuxt/builds/latest.json +1 -1
  45. package/.output/public/_nuxt/builds/meta/f4707884-7cf4-4a31-80d2-e3d72b73745f.json +1 -0
  46. package/.output/public/_nuxt/channel-templates.BOtahzPi.css +1 -0
  47. package/.output/public/_nuxt/daq.B0D3dPAc.css +1 -0
  48. package/.output/public/_nuxt/dcw.8Y7FqCVN.css +1 -0
  49. package/.output/public/_nuxt/default.J32SgqFY.css +1 -0
  50. package/.output/public/_nuxt/entry.bdm0tv6M.css +1 -0
  51. package/.output/public/_nuxt/logs.BpKzmKsh.css +1 -0
  52. package/.output/public/_nuxt/monitor.D9pe7qN6.css +1 -0
  53. package/.output/public/_nuxt/pages.D7aSDlUI.css +1 -0
  54. package/.output/public/_nuxt/permissions.DwTVlFe6.css +1 -0
  55. package/.output/public/_nuxt/plugins.sb4nDGqr.css +1 -0
  56. package/.output/public/_nuxt/{Cbq-mryP.js → qr6R6Ha1.js} +1 -1
  57. package/.output/public/_nuxt/settings.BTgR-NiE.css +1 -0
  58. package/.output/public/_nuxt/teams.CxnxKVVs.css +1 -0
  59. package/.output/public/_nuxt/tokens.BFY7qv4f.css +1 -0
  60. package/.output/public/_nuxt/{town.DKIAhKnx.css → town.BBXZmeoP.css} +1 -1
  61. package/.output/public/_nuxt/users.DLgZ1D0h.css +1 -0
  62. package/.output/public/_nuxt/workshop.CR_QzeAN.css +1 -0
  63. package/.output/public/_nuxt/{BzHEilTt.js → xh3_vYcu.js} +1 -1
  64. package/.output/public/_nuxt/yF0aYMF1.js +4 -0
  65. package/.output/server/chunks/_/entity.mjs.map +1 -1
  66. package/.output/server/chunks/_/nitro.mjs +2244 -1464
  67. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  68. package/.output/server/chunks/build/{TownView-jVazYOjN.mjs → TownView-BuLAsmpR.mjs} +288 -206
  69. package/.output/server/chunks/build/TownView-BuLAsmpR.mjs.map +1 -0
  70. package/.output/server/chunks/build/{_id_-CfVosNg3.mjs → _id_-BU1wfOID.mjs} +138 -138
  71. package/.output/server/chunks/build/{_id_-CfVosNg3.mjs.map → _id_-BU1wfOID.mjs.map} +1 -1
  72. package/.output/server/chunks/build/{_id_-Hwr4rZpr.mjs → _id_-BYsEua57.mjs} +33 -32
  73. package/.output/server/chunks/build/_id_-BYsEua57.mjs.map +1 -0
  74. package/.output/server/chunks/build/{_wsId_-BVg3bB77.mjs → _wsId_-BxlDcJHg.mjs} +293 -259
  75. package/.output/server/chunks/build/{_wsId_-BVg3bB77.mjs.map → _wsId_-BxlDcJHg.mjs.map} +1 -1
  76. package/.output/server/chunks/build/{agents-Bvin73QY.mjs → agents-CLQqJF2y.mjs} +21 -27
  77. package/.output/server/chunks/build/agents-CLQqJF2y.mjs.map +1 -0
  78. package/.output/server/chunks/build/{aml-BCSJCdX7.mjs → aml-_7FdFL2p.mjs} +109 -109
  79. package/.output/server/chunks/build/{aml-BCSJCdX7.mjs.map → aml-_7FdFL2p.mjs.map} +1 -1
  80. package/.output/server/chunks/build/api-error-dul30BYQ.mjs.map +1 -1
  81. package/.output/server/chunks/build/{channel-templates-BTq8570n.mjs → channel-templates-p6SZNjlM.mjs} +19 -19
  82. package/.output/server/chunks/build/{channel-templates-BTq8570n.mjs.map → channel-templates-p6SZNjlM.mjs.map} +1 -1
  83. package/.output/server/chunks/build/{daq-C03Uu5UE.mjs → daq-cgyjKmJu.mjs} +188 -122
  84. package/.output/server/chunks/build/daq-cgyjKmJu.mjs.map +1 -0
  85. package/.output/server/chunks/build/{dcw-6vEYVeje.mjs → dcw-CoTxBlAZ.mjs} +45 -45
  86. package/.output/server/chunks/build/{dcw-6vEYVeje.mjs.map → dcw-CoTxBlAZ.mjs.map} +1 -1
  87. package/.output/server/chunks/build/{default-hseyOqBT.mjs → default-BE4r0FZN.mjs} +158 -79
  88. package/.output/server/chunks/build/{default-hseyOqBT.mjs.map → default-BE4r0FZN.mjs.map} +1 -1
  89. package/.output/server/chunks/build/{logs-B-xhuqln.mjs → logs-BSOeZwwI.mjs} +34 -34
  90. package/.output/server/chunks/build/{logs-B-xhuqln.mjs.map → logs-BSOeZwwI.mjs.map} +1 -1
  91. package/.output/server/chunks/build/{monitor-CyfDt4nR.mjs → monitor-C0okQaXz.mjs} +33 -33
  92. package/.output/server/chunks/build/{monitor-CyfDt4nR.mjs.map → monitor-C0okQaXz.mjs.map} +1 -1
  93. package/.output/server/chunks/build/{pages-BO7yZsXA.mjs → pages-DFxjn9Xa.mjs} +33 -17
  94. package/.output/server/chunks/build/pages-DFxjn9Xa.mjs.map +1 -0
  95. package/.output/server/chunks/build/{permissions-B52oOmaO.mjs → permissions-68SsNjex.mjs} +12 -12
  96. package/.output/server/chunks/build/{permissions-B52oOmaO.mjs.map → permissions-68SsNjex.mjs.map} +1 -1
  97. package/.output/server/chunks/build/{plugins-CUWmMdyt.mjs → plugins-lGlUr1lj.mjs} +17 -17
  98. package/.output/server/chunks/build/{plugins-CUWmMdyt.mjs.map → plugins-lGlUr1lj.mjs.map} +1 -1
  99. package/.output/server/chunks/build/{settings-DoQ2Oq3P.mjs → settings-Ddd1qx2Z.mjs} +50 -47
  100. package/.output/server/chunks/build/settings-Ddd1qx2Z.mjs.map +1 -0
  101. package/.output/server/chunks/build/{teams-2kz3CusY.mjs → teams-MEDLZdMn.mjs} +38 -34
  102. package/.output/server/chunks/build/teams-MEDLZdMn.mjs.map +1 -0
  103. package/.output/server/chunks/build/{tokens-BbWLqtVz.mjs → tokens-C7fTM5C2.mjs} +14 -14
  104. package/.output/server/chunks/build/{tokens-BbWLqtVz.mjs.map → tokens-C7fTM5C2.mjs.map} +1 -1
  105. package/.output/server/chunks/build/{town-BOl6hs9B.mjs → town-qMPql9Se.mjs} +36 -10
  106. package/.output/server/chunks/build/town-qMPql9Se.mjs.map +1 -0
  107. package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs +1 -1
  108. package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs +1 -1
  109. package/.output/server/chunks/build/useResponsive-BKDMGTHs.mjs +49 -0
  110. package/.output/server/chunks/build/useResponsive-BKDMGTHs.mjs.map +1 -0
  111. package/.output/server/chunks/build/{users-fohSmF-J.mjs → users-Cfd5-l2-.mjs} +6 -6
  112. package/.output/server/chunks/build/{users-fohSmF-J.mjs.map → users-Cfd5-l2-.mjs.map} +1 -1
  113. package/.output/server/chunks/build/{workshop-DX5-ldc4.mjs → workshop-BL5bhfs0.mjs} +15 -15
  114. package/.output/server/chunks/build/{workshop-DX5-ldc4.mjs.map → workshop-BL5bhfs0.mjs.map} +1 -1
  115. package/.output/server/chunks/build/{workspaces-BuydxM-3.mjs → workspaces-Bgz5Ekwp.mjs} +18 -3
  116. package/.output/server/chunks/build/workspaces-Bgz5Ekwp.mjs.map +1 -0
  117. package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs.map +1 -1
  118. package/.output/server/chunks/routes/api/system/index.patch.mjs.map +1 -1
  119. package/.output/server/chunks/routes/api/system/index.post.mjs.map +1 -1
  120. package/.output/server/chunks/routes/api/system/settings/events.get.mjs.map +1 -1
  121. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +6 -2
  122. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
  123. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +2 -1
  124. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs.map +1 -1
  125. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  126. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +3 -3
  127. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs.map +1 -1
  128. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs.map +1 -1
  129. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs.map +1 -1
  130. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +3 -2
  131. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs.map +1 -1
  132. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +2 -1
  133. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs.map +1 -1
  134. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +8 -6
  135. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs.map +1 -1
  136. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +5 -5
  137. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs.map +1 -1
  138. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +14 -4
  139. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs.map +1 -1
  140. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +4 -4
  141. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs.map +1 -1
  142. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +4 -3
  143. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs.map +1 -1
  144. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +31 -0
  145. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs.map +1 -0
  146. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +28 -0
  147. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs.map +1 -0
  148. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs.map +1 -1
  149. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +32 -0
  150. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs.map +1 -0
  151. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +34 -0
  152. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs.map +1 -0
  153. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +33 -0
  154. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs.map +1 -0
  155. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +34 -0
  156. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs.map +1 -0
  157. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  158. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  159. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  160. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  161. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  162. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  163. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  164. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +2 -0
  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 +53 -25
  175. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  176. package/.output/server/package.json +1 -1
  177. package/README-zh.md +204 -40
  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 -24
  182. package/app/components/AppSidebar.vue +118 -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/useDcwStream.ts +1 -1
  206. package/app/composables/workshop/useVisibleInterval.ts +2 -2
  207. package/app/composables/workshop/useWorkshopApi.ts +1 -1
  208. package/app/layouts/default.vue +46 -2
  209. package/app/pages/aml/index.vue +712 -616
  210. package/app/pages/daq/[id].vue +3 -2
  211. package/app/pages/daq/index.vue +209 -9
  212. package/app/pages/dcw/[id].vue +109 -28
  213. package/app/pages/dcw/index.vue +83 -23
  214. package/app/pages/index.vue +35 -1
  215. package/app/pages/logs/index.vue +147 -13
  216. package/app/pages/monitor.vue +56 -12
  217. package/app/pages/permissions/index.vue +34 -0
  218. package/app/pages/plugins/index.vue +35 -4
  219. package/app/pages/settings.vue +90 -21
  220. package/app/pages/tokens.vue +23 -0
  221. package/app/pages/town.vue +50 -5
  222. package/app/pages/users.vue +23 -0
  223. package/app/pages/workshop/agents.vue +92 -2
  224. package/app/pages/workshop/channel-templates.vue +53 -0
  225. package/app/pages/workshop/index.vue +14 -0
  226. package/app/pages/workshop/teams.vue +66 -6
  227. package/app/pages/workshop/w/[wsId].vue +202 -14
  228. package/app/plugins/aw-plugins.client.ts +13 -8
  229. package/app/stores/app.ts +33 -1
  230. package/app/stores/workshop/user.ts +1 -1
  231. package/app/stores/workshop/workspaces.ts +18 -2
  232. package/app/utils/api-error.ts +1 -1
  233. package/cli/commands/build.mjs +8 -1
  234. package/docker-compose.yml +6 -0
  235. package/docs/full-test-plan.md +4 -0
  236. package/docs/plugins.en.md +1 -0
  237. package/docs/plugins.md +1 -0
  238. package/i18n/locales/en.ts +3 -0
  239. package/i18n/locales/zh-CN.ts +3 -0
  240. package/nuxt.config.ts +31 -0
  241. package/package.json +9 -1
  242. package/scripts/_audit/detached-start.mjs +103 -0
  243. package/scripts/_audit/guard-upstream-liveness.mjs +104 -0
  244. package/scripts/_dbg-param-map-e2e.ts +242 -0
  245. package/scripts/_dbg-param-map-rest-smoke.mjs +73 -0
  246. package/scripts/_dbg-param-real-scenario.mjs +153 -0
  247. package/scripts/_dbg-perms-e2e.mjs +10 -3
  248. package/scripts/_dbg-protocol-matrix.mjs +453 -441
  249. package/scripts/_dbg-render-regression.mjs +151 -130
  250. package/scripts/_dbg-town-agents-probe.mjs +60 -0
  251. package/scripts/_dbg-visual-acceptance.mjs +63 -0
  252. package/scripts/api-live-e2e.mjs +40 -8
  253. package/scripts/capture-walkthrough.mjs +232 -0
  254. package/scripts/e2e-agent-team.mjs +5 -3
  255. package/scripts/render-walkthrough-figure.mjs +46 -0
  256. package/scripts/seed-walkthrough-fixture.mjs +143 -0
  257. package/scripts/test-plugin-hardening.mjs +8 -0
  258. package/scripts/three-system-e2e.mjs +6 -6
  259. package/scripts/ui/admin-shots.mjs +46 -0
  260. package/scripts/ui/audit-layout.mjs +301 -0
  261. package/scripts/ui/bump-microfont.mjs +39 -0
  262. package/scripts/ui/lib.mjs +198 -0
  263. package/scripts/ui/linkcheck2.mjs +37 -0
  264. package/scripts/ui/live-render-check.mjs +72 -0
  265. package/scripts/ui/md-lint.mjs +80 -0
  266. package/scripts/ui/perf-audit.mjs +132 -0
  267. package/scripts/ui/readme-assets.mjs +30 -0
  268. package/scripts/ui/readme-shots.mjs +42 -0
  269. package/scripts/ui/record.mjs +225 -0
  270. package/scripts/ui/seed-admin.mjs +68 -0
  271. package/scripts/ui/seed-demo.mjs +83 -0
  272. package/scripts/ui/shot-hero.mjs +25 -0
  273. package/scripts/ui/shots.mjs +75 -0
  274. package/scripts/ui/sim-ui-shot.mjs +16 -0
  275. package/scripts/ui/verify-nav.mjs +51 -0
  276. package/scripts/ui/verify-responsive.mjs +285 -0
  277. package/server/api/system/config-groups/[id].patch.ts +1 -1
  278. package/server/api/system/config-groups/index.post.ts +1 -1
  279. package/server/api/system/settings/events.get.ts +1 -1
  280. package/server/api/system/settings/index.patch.ts +1 -1
  281. package/server/api/workshop/agent-tools/invoke.post.ts +16 -2
  282. package/server/api/workshop/aml/datasets/[id].get.ts +8 -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 +2 -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 +14 -3
  299. package/server/plugins/dev-stability-guard.ts +3 -1
  300. package/server/plugins/system-config.ts +6 -1
  301. package/server/plugins-builtin/rag-bridge/index.mjs +9 -2
  302. package/server/services/system-config.ts +28 -9
  303. package/server/services/workshop/agents/adapters/one-shot-cli-agent.ts +2 -1
  304. package/server/services/workshop/agents/agent-interface.ts +8 -6
  305. package/server/services/workshop/agents/base-agent.ts +18 -4
  306. package/server/services/workshop/agents/claude-agent.ts +7 -3
  307. package/server/services/workshop/agents/codex-agent.ts +3 -3
  308. package/server/services/workshop/agents/dsh-agent.ts +3 -3
  309. package/server/services/workshop/agents/goose-agent.ts +0 -1
  310. package/server/services/workshop/agents/harness-terminal.ts +14 -1
  311. package/server/services/workshop/agents/hermes-agent.ts +4 -2
  312. package/server/services/workshop/agents/host-tool-bridge.ts +5 -1
  313. package/server/services/workshop/agents/industrial-context.ts +4 -1
  314. package/server/services/workshop/agents/industrial-tools.ts +164 -6
  315. package/server/services/workshop/agents/omp-agent.ts +15 -9
  316. package/server/services/workshop/agents/opencode-agent.ts +47 -21
  317. package/server/services/workshop/agents/qwen-agent.ts +10 -5
  318. package/server/services/workshop/aml/entity.ts +3 -1
  319. package/server/services/workshop/aml/python-runtime.ts +3 -2
  320. package/server/services/workshop/daq/bus/mqtt.adapter.ts +8 -4
  321. package/server/services/workshop/daq/daq-controller.ts +18 -3
  322. package/server/services/workshop/daq/daq-runtime.ts +5 -3
  323. package/server/services/workshop/daq/drivers.ts +63 -8
  324. package/server/services/workshop/daq/host-ports.ts +3 -2
  325. package/server/services/workshop/daq/storage/timescale.adapter.ts +3 -1
  326. package/server/services/workshop/db/channel.repo.ts +4 -0
  327. package/server/services/workshop/db/ops.repo.ts +5 -2
  328. package/server/services/workshop/db/retention.ts +8 -3
  329. package/server/services/workshop/dcw/dcw-controller.ts +143 -16
  330. package/server/services/workshop/dcw/dcw-product.repo.ts +38 -1
  331. package/server/services/workshop/dcw/dcw-runtime.ts +3 -2
  332. package/server/services/workshop/dcw/drivers.ts +5 -2
  333. package/server/services/workshop/dcw/param-conversion.ts +78 -0
  334. package/server/services/workshop/dcw/param-limits.ts +142 -0
  335. package/server/services/workshop/dcw/param-map.repo.ts +305 -0
  336. package/server/services/workshop/dcw/recipe-rollback-manager.ts +13 -7
  337. package/server/services/workshop/runtime/agent-runtime.ts +4 -0
  338. package/server/services/workshop/runtime/manager.ts +9 -2
  339. package/server/services/workshop/settings.ts +4 -2
  340. package/server/types/pg.d.ts +49 -0
  341. package/server/utils/stability-severity.ts +13 -2
  342. package/shared/config/groups.mjs +22 -1
  343. package/shared/config/home.d.mts +28 -0
  344. package/shared/dcw-protocol.ts +136 -0
  345. package/uno.config.ts +12 -1
  346. package/.output/public/_nuxt/BFkgkW8u.js +0 -4
  347. package/.output/public/_nuxt/C5gUkRwn.js +0 -1
  348. package/.output/public/_nuxt/CM12FuB42.js +0 -1
  349. package/.output/public/_nuxt/CZiw7sEV.js +0 -1
  350. package/.output/public/_nuxt/Cc_9VzD42.js +0 -1
  351. package/.output/public/_nuxt/CdPzkOMV.js +0 -1
  352. package/.output/public/_nuxt/D1YDxZpZ.js +0 -1
  353. package/.output/public/_nuxt/D20Yamr4.js +0 -1
  354. package/.output/public/_nuxt/DVsjtsvZ2.js +0 -1
  355. package/.output/public/_nuxt/DmqknNvV.js +0 -18
  356. package/.output/public/_nuxt/DnUuIR83.js +0 -1
  357. package/.output/public/_nuxt/S_fVQwJK.js +0 -1
  358. package/.output/public/_nuxt/TownView.0oLiQgTC.css +0 -1
  359. package/.output/public/_nuxt/_id_.D-SYuyZb.css +0 -1
  360. package/.output/public/_nuxt/_id_.hma_BU6T.css +0 -1
  361. package/.output/public/_nuxt/_wsId_.B12v3PhY.css +0 -1
  362. package/.output/public/_nuxt/agents.BV70ioCv.css +0 -1
  363. package/.output/public/_nuxt/ahgEJu2R.js +0 -1
  364. package/.output/public/_nuxt/aml.COEKNNqK.css +0 -1
  365. package/.output/public/_nuxt/builds/meta/44b66249-54d0-4c8a-9057-9755a32329e2.json +0 -1
  366. package/.output/public/_nuxt/channel-templates.C-M5nKcC.css +0 -1
  367. package/.output/public/_nuxt/daq.B3265ZDn.css +0 -1
  368. package/.output/public/_nuxt/dcw.DLYZqEhT.css +0 -1
  369. package/.output/public/_nuxt/default.DE_vT238.css +0 -1
  370. package/.output/public/_nuxt/entry.BB-Eeh-J.css +0 -1
  371. package/.output/public/_nuxt/logs.CqFyMrJw.css +0 -1
  372. package/.output/public/_nuxt/monitor.B--1dPzs.css +0 -1
  373. package/.output/public/_nuxt/pages.ooEzrMm9.css +0 -1
  374. package/.output/public/_nuxt/permissions.B1pjGChZ.css +0 -1
  375. package/.output/public/_nuxt/plugins.5e5chZ67.css +0 -1
  376. package/.output/public/_nuxt/pz2JDAM7.js +0 -2
  377. package/.output/public/_nuxt/settings.Dm3M0RLy.css +0 -1
  378. package/.output/public/_nuxt/teams.BC75EGnR.css +0 -1
  379. package/.output/public/_nuxt/tokens.xRb1fSPU.css +0 -1
  380. package/.output/public/_nuxt/users.CXnP2E08.css +0 -1
  381. package/.output/public/_nuxt/workshop.Jk5HxWPE.css +0 -1
  382. package/.output/server/chunks/build/TownView-jVazYOjN.mjs.map +0 -1
  383. package/.output/server/chunks/build/_id_-Hwr4rZpr.mjs.map +0 -1
  384. package/.output/server/chunks/build/agents-Bvin73QY.mjs.map +0 -1
  385. package/.output/server/chunks/build/daq-C03Uu5UE.mjs.map +0 -1
  386. package/.output/server/chunks/build/pages-BO7yZsXA.mjs.map +0 -1
  387. package/.output/server/chunks/build/settings-DoQ2Oq3P.mjs.map +0 -1
  388. package/.output/server/chunks/build/teams-2kz3CusY.mjs.map +0 -1
  389. package/.output/server/chunks/build/town-BOl6hs9B.mjs.map +0 -1
  390. package/.output/server/chunks/build/workspaces-BuydxM-3.mjs.map +0 -1
  391. /package/.output/public/_nuxt/{36oeS8_R2.js → 36oeS8_R.js} +0 -0
  392. /package/.output/public/_nuxt/{CYWVXZTS.js → CYWVXZTS2.js} +0 -0
@@ -60,9 +60,13 @@ const hitlAnswer = async (item: AepHitlItem, confirmed: boolean): Promise<void>
60
60
  }
61
61
  }
62
62
 
63
+ /* 语言选择器在窄屏显示"短名":完整语言名(简体中文=56px @14px)配上
64
+ * antd 给箭头预留的 24px 内距,92px 的选择器只剩 46px 文本位 ——
65
+ * 实测被截成「简 体…」,这是每页都出现的破相。
66
+ * 窄屏用 2 字标签,桌面保留完整语言名。 */
63
67
  const localeOptions = computed(() =>
64
68
  (locales.value as Array<{ code: string, name: string }>).map(l => ({
65
- label: l.name,
69
+ label: isMobile.value ? l.code.split('-')[0]!.toUpperCase() : l.name,
66
70
  value: l.code,
67
71
  })),
68
72
  )
@@ -76,6 +80,26 @@ const switchLocale: SelectProps['onChange'] = (value) => {
76
80
  }
77
81
  }
78
82
 
83
+ /* ── 响应式:窄屏顶栏不是"缩小版顶栏",而是换一套信息优先级 ─────────────
84
+ * 桌面:航迹页签是主角(多页并行来回切)。
85
+ * 窄屏:页签轨与右侧功能簇争抢横向空间 —— 实测 390px 下页签被右侧图标
86
+ * 逐个压过去,最后连用户铭牌都被推出视口(顶栏 overflow:hidden 直接裁掉)。
87
+ * 所以窄屏撤掉页签轨,用**当前页标题**替代:窄屏用户要的是"我在哪",
88
+ * 不是"我刚才还开过哪 5 个页面"。 */
89
+ const { isDrawer, isMobile } = useResponsive()
90
+
91
+ const navToggleLabel = computed(() =>
92
+ isDrawer.value
93
+ ? (store.mobileNavOpen ? t('header.closeNav') : t('header.openNav'))
94
+ : (store.sidebarCollapsed ? t('header.expand') : t('header.collapse')))
95
+
96
+ const toggleNav = () => {
97
+ if (isDrawer.value) store.toggleMobileNav()
98
+ else store.toggleSidebar()
99
+ }
100
+
101
+ const currentTitle = computed(() => metaFor(route.path).title)
102
+
79
103
  // ── 航迹导航:路由变化 → 记录航点;切换时进度线扫过 ──
80
104
  const hydrated = ref(false)
81
105
  const plotting = ref(false)
@@ -196,24 +220,17 @@ const onAvatarMenu: MenuProps['onClick'] = async ({ key }) => {
196
220
  <div class="header-left">
197
221
  <button
198
222
  class="collapse-btn"
199
- :aria-label="store.sidebarCollapsed ? t('header.expand') : t('header.collapse')"
200
- @click="store.toggleSidebar()"
223
+ :aria-label="navToggleLabel"
224
+ :aria-expanded="isDrawer ? store.mobileNavOpen : !store.sidebarCollapsed"
225
+ @click="toggleNav()"
201
226
  >
202
227
  <span class="i-tabler-menu-2" />
203
228
  </button>
204
229
 
205
- <span class="rail-mark i-tabler-route" />
230
+ <!-- 窄屏:当前页标题(替代被撤掉的页签轨) -->
231
+ <span class="mobile-title">{{ currentTitle }}</span>
206
232
 
207
- <!-- AML 建模入口:固定导航点(航迹由访问历史生成,/aml 需常驻入口) -->
208
- <NuxtLink
209
- class="trail-node aml-entry"
210
- :class="{ active: route.path.startsWith('/aml') }"
211
- to="/aml"
212
- :title="t('aml.k1amlx159')"
213
- >
214
- <span class="node-icon i-tabler-flask" />
215
- <span class="node-title">{{ t('aml.k1amlx158') }}</span>
216
- </NuxtLink>
233
+ <span class="rail-mark i-tabler-route" />
217
234
 
218
235
  <nav
219
236
  class="trail"
@@ -324,14 +341,14 @@ const onAvatarMenu: MenuProps['onClick'] = async ({ key }) => {
324
341
  </ClientOnly>
325
342
  <!-- 实时连接状态点(WS 会话全局单例;未用过 WS 的会话不显示) -->
326
343
  <span
327
- v-if="wsVisible"
344
+ v-if="hydrated && wsVisible"
328
345
  class="ws-dot"
329
346
  :class="wsClass"
330
347
  :title="wsLabel"
331
348
  />
332
349
  <a-tooltip :title="t('header.fullscreen')">
333
350
  <button
334
- class="icon-btn"
351
+ class="icon-btn hdr-fullscreen"
335
352
  @click="toggleFullscreen"
336
353
  >
337
354
  <span
@@ -462,12 +479,6 @@ const onAvatarMenu: MenuProps['onClick'] = async ({ key }) => {
462
479
  color: var(--ink-faint);
463
480
  }
464
481
 
465
- /* AML 固定入口:复用航点 chip 语言,紧贴 rail-mark 常驻 */
466
- .aml-entry {
467
- flex: 0 0 auto;
468
- margin-right: 2px;
469
- }
470
-
471
482
  .trail {
472
483
  flex: 0 1 auto;
473
484
  min-width: 0;
@@ -751,12 +762,75 @@ const onAvatarMenu: MenuProps['onClick'] = async ({ key }) => {
751
762
 
752
763
  .user-role {
753
764
  font-family: var(--font-mono);
754
- font-size: 8.5px;
755
- letter-spacing: 0.18em;
765
+ /* 8.5px 是"看得见读不了"的下限之外(实测常驻被审计标红);
766
+ 角色是身份信息,不是装饰刻度,抬到 9.5px 仍保持铭牌声部 */
767
+ font-size: 9.5px;
768
+ letter-spacing: 0.14em;
756
769
  text-transform: uppercase;
757
770
  color: var(--app-text-secondary, var(--ink-faint));
758
771
  }
759
772
 
773
+ /* 移动端当前页标题:桌面不存在(那里有页签轨) */
774
+ .mobile-title {
775
+ display: none;
776
+ min-width: 0;
777
+ overflow: hidden;
778
+ font-size: 14px;
779
+ font-weight: 600;
780
+ color: var(--app-text, var(--ink));
781
+ text-overflow: ellipsis;
782
+ white-space: nowrap;
783
+ }
784
+
785
+ /* ══ 顶栏响应式:按信息优先级逐级卸载,而不是让它们互相挤压 ═══════════════
786
+ * 卸载顺序(从最可省到最不可省):页签轨 → 全屏钮 → 用户双行铭牌 → 语言文字。
787
+ * 留下的核心是:HITL 铃标(有待办必须看得见)、连接状态点、主题、语言、身份。 */
788
+ @media (max-width: 899px) {
789
+ .rail-mark,
790
+ .trail {
791
+ display: none;
792
+ }
793
+
794
+ .mobile-title {
795
+ display: block;
796
+ margin-left: 2px;
797
+ }
798
+
799
+ .app-header {
800
+ padding: 0 12px 0 8px;
801
+ }
802
+ }
803
+
804
+ @media (max-width: 639px) {
805
+ .hdr-fullscreen {
806
+ display: none;
807
+ }
808
+
809
+ .user-chip {
810
+ height: 38px;
811
+ padding: 0 6px;
812
+ }
813
+
814
+ .user-meta {
815
+ display: none;
816
+ }
817
+
818
+ /* 窄屏标签已换成 2 字符(ZH / EN),选择器只需容纳标签 + 箭头 + 内距 */
819
+ .lang-select {
820
+ width: 76px;
821
+ }
822
+
823
+ .lang-select :deep(.ant-select-selection-item) {
824
+ padding-inline-end: 16px;
825
+ font-size: 12.5px;
826
+ }
827
+
828
+ .header-left,
829
+ .header-right {
830
+ gap: 4px;
831
+ }
832
+ }
833
+
760
834
  .hidden {
761
835
  display: none;
762
836
  }
@@ -23,6 +23,13 @@ interface MenuGroup {
23
23
  items: MenuItem[]
24
24
  }
25
25
 
26
+ /**
27
+ * 是否已完成客户端水合。
28
+ * 服务端拿不到会话(cookie 里的 workshop.user 只在浏览器可读),
29
+ * 任何"按身份增删 DOM"的渲染都必须由它门控,否则 SSR 与客户端首帧结构不一致。
30
+ */
31
+ const navHydrated = ref(false)
32
+
26
33
  /**
27
34
  * 导航信息架构:12 个平铺条目 → 三组语义分区(控制台 / 运维 / 系统)。
28
35
  * 分组的价值不在多一层容器,而在"扫视成本":同组内的入口是同一件事的不同面,
@@ -38,6 +45,7 @@ const menuGroups = computed<MenuGroup[]>(() => [
38
45
  { key: '/town', icon: 'i-tabler-map-2', label: t('menu.town'), motion: 'im-pop' },
39
46
  { key: '/daq', icon: 'i-tabler-activity', label: t('menu.daq'), motion: 'im-pop' },
40
47
  { key: '/dcw', icon: 'i-tabler-settings-automation', label: t('menu.dcw'), motion: 'im-pop' },
48
+ { key: '/aml', icon: 'i-tabler-flask', label: t('menu.aml'), motion: 'im-pop' },
41
49
  ],
42
50
  },
43
51
  {
@@ -60,26 +68,96 @@ const menuGroups = computed<MenuGroup[]>(() => [
60
68
  ],
61
69
  },
62
70
  ]
63
- .map(g => ({ ...g, items: g.items.filter(m => !m.adminOnly || userStore.isAdmin) }))
71
+ /* ⚠️ admin-only 条目必须等挂载后再放行:服务端没有会话(读不到 cookie 里的
72
+ * workshop.user),SSR 会少渲染「权限管理」这一条 → 客户端多一条 →
73
+ * 实测触发 Hydration 链式 mismatch(插件管理/系统设置的图标与文案整体错位一格)。
74
+ * 用 navHydrated 门控后,服务端与客户端首帧的 v-for 长度一致,水合干净。 */
75
+ .map(g => ({ ...g, items: g.items.filter(m => !m.adminOnly || (navHydrated.value && userStore.isAdmin)) }))
64
76
  .filter(g => g.items.length > 0))
65
77
 
66
78
  const isActive = (key: string): boolean =>
67
79
  key === '/' ? route.path === '/' : route.path.startsWith(key)
68
80
 
69
81
  const go = (key: string) => {
82
+ // 抽屉是浮层:点完必须收起来,否则用户看到的是"导航没反应"(内容被浮层盖着)
83
+ if (isDrawer.value) store.closeMobileNav()
70
84
  if (!isActive(key)) navigateTo(key)
71
85
  }
86
+
87
+ /* ── 响应式形态 ──────────────────────────────────────────────────────────
88
+ * 同一份导航有三种形态,由视口决定,不新增组件(避免三份 IA 各自漂移):
89
+ * ≥1024 三栏仪表台:跟随用户的折叠偏好
90
+ * 900–1023 双栏:强制图标轨 —— 228px 文字轨会把画布压到不可用
91
+ * <900 抽屉:强制展开(抽屉关着时展开与否无意义),汉堡开合 */
92
+ const { isDrawer, isTablet } = useResponsive()
93
+
94
+ /* 形态属性只在挂载后渲染:SSR 没有视口、一律按桌面档出 HTML,
95
+ * 若首帧就把 data-nav-mode="drawer" 打上去,水合时属性对不上会报 mismatch。
96
+ * 布局本身由 body 类 + CSS 媒体查询兜住,不依赖这个属性。 */
97
+ onMounted(() => {
98
+ navHydrated.value = true
99
+ })
100
+ const navMode = computed(() =>
101
+ navHydrated.value ? (isDrawer.value ? 'drawer' : (isTablet.value ? 'rail' : 'full')) : undefined)
102
+
103
+ const effectiveCollapsed = computed(() =>
104
+ isDrawer.value ? false : isTablet.value ? true : store.sidebarCollapsed)
105
+
106
+ const showLabels = computed(() => !effectiveCollapsed.value)
107
+
108
+ const drawerOpen = computed(() => isDrawer.value && store.mobileNavOpen)
109
+
110
+ /** 路由变化即收抽屉:抽屉是"去别处"的中转,不是常驻面板 */
111
+ watch(() => route.path, () => {
112
+ if (store.mobileNavOpen) store.closeMobileNav()
113
+ })
114
+
115
+ /**
116
+ * 形态镜像到 <body>(nav-drawer / nav-drawer-open)。
117
+ *
118
+ * 为什么不用 :class 直接打在 a-layout-sider 上:实测 antd 的 Sider 不会把
119
+ * 动态 class 落到它渲染的 <aside> 上(静态 class 可以,DOM 里查不到 is-drawer)。
120
+ * 依赖第三方组件的 attr 透传行为来做**结构性**布局是脆的 ——
121
+ * 改为把形态写在 body 上,CSS 由 main.css 的响应式层接管,只依赖自己的状态。
122
+ */
123
+ watchEffect(() => {
124
+ if (typeof document === 'undefined') return
125
+ document.body.classList.toggle('nav-drawer', isDrawer.value)
126
+ document.body.classList.toggle('nav-drawer-open', drawerOpen.value)
127
+ })
128
+
129
+ onBeforeUnmount(() => {
130
+ if (typeof document === 'undefined') return
131
+ document.body.classList.remove('nav-drawer', 'nav-drawer-open')
132
+ })
133
+
134
+ /** 抽屉展开时锁画布滚动(否则背景跟着手指跑,浮层失去"压在台面上"的物理感) */
135
+ watch(drawerOpen, (open) => {
136
+ if (typeof document === 'undefined') return
137
+ document.body.style.overflow = open ? 'hidden' : ''
138
+ })
139
+
140
+ /** Esc 关闭:仅抽屉形态接管,桌面侧栏不受影响 */
141
+ const onKeydown = (e: KeyboardEvent) => {
142
+ if (e.key === 'Escape' && drawerOpen.value) store.closeMobileNav()
143
+ }
144
+ onMounted(() => window.addEventListener('keydown', onKeydown))
145
+ onBeforeUnmount(() => {
146
+ window.removeEventListener('keydown', onKeydown)
147
+ if (typeof document !== 'undefined') document.body.style.overflow = ''
148
+ })
72
149
  </script>
73
150
 
74
151
  <template>
75
152
  <a-layout-sider
76
- v-model:collapsed="store.sidebarCollapsed"
153
+ :collapsed="effectiveCollapsed"
77
154
  :trigger="null"
78
155
  collapsible
79
- breakpoint="lg"
80
156
  :width="228"
81
157
  :collapsed-width="64"
82
158
  class="app-sider"
159
+ :data-nav-mode="navMode"
160
+ :aria-hidden="isDrawer && !drawerOpen ? 'true' : undefined"
83
161
  >
84
162
  <!-- 品牌区:AwLogo 六边形标志(绿→青渐变 + 孪生虚影 + 三节点互连,与 favicon 同源) -->
85
163
  <div class="logo">
@@ -91,7 +169,7 @@ const go = (key: string) => {
91
169
  </div>
92
170
  <transition name="slide-fade">
93
171
  <div
94
- v-show="!store.sidebarCollapsed"
172
+ v-show="showLabels"
95
173
  class="logo-text"
96
174
  >
97
175
  <span class="logo-title">{{ site.name }}</span>
@@ -108,7 +186,7 @@ const go = (key: string) => {
108
186
  >
109
187
  <!-- 分组标:mono 微字 + 收尾 hairline(仪器命名牌 + 刻度线的同一语言) -->
110
188
  <div
111
- v-show="!store.sidebarCollapsed"
189
+ v-show="showLabels"
112
190
  class="menu-group-label"
113
191
  >
114
192
  <span class="menu-group-text">{{ group.label }}</span>
@@ -118,7 +196,7 @@ const go = (key: string) => {
118
196
  />
119
197
  </div>
120
198
  <div
121
- v-show="store.sidebarCollapsed"
199
+ v-show="!showLabels"
122
200
  class="menu-group-sep"
123
201
  aria-hidden="true"
124
202
  />
@@ -128,7 +206,7 @@ const go = (key: string) => {
128
206
  type="button"
129
207
  class="menu-item im"
130
208
  :class="{ active: isActive(item.key) }"
131
- :title="store.sidebarCollapsed ? item.label : undefined"
209
+ :title="!showLabels ? item.label : undefined"
132
210
  @click="go(item.key)"
133
211
  >
134
212
  <span
@@ -136,7 +214,7 @@ const go = (key: string) => {
136
214
  :class="[item.icon, item.motion]"
137
215
  />
138
216
  <span
139
- v-show="!store.sidebarCollapsed"
217
+ v-show="showLabels"
140
218
  class="menu-label"
141
219
  >{{ item.label }}</span>
142
220
  </button>
@@ -145,7 +223,7 @@ const go = (key: string) => {
145
223
 
146
224
  <!-- 底部铭牌:版本与运行模式(上缘刻度收边,与画布分节同语言) -->
147
225
  <div
148
- v-show="!store.sidebarCollapsed"
226
+ v-show="showLabels"
149
227
  class="sider-footer"
150
228
  >
151
229
  <div class="footer-rule" />
@@ -156,6 +234,14 @@ const go = (key: string) => {
156
234
  </div>
157
235
  </div>
158
236
  </a-layout-sider>
237
+
238
+ <!-- 抽屉遮罩:点空白处关闭(与 esc-close 的 @click.self 契约一致) -->
239
+ <div
240
+ v-if="drawerOpen"
241
+ class="nav-scrim"
242
+ aria-hidden="true"
243
+ @click="store.closeMobileNav()"
244
+ />
159
245
  </template>
160
246
 
161
247
  <style scoped>
@@ -215,8 +301,10 @@ const go = (key: string) => {
215
301
 
216
302
  .logo-sub {
217
303
  font-family: var(--font-mono);
218
- font-size: 8.5px;
219
- letter-spacing: 0.2em;
304
+ /* 8.5px 在这块铭牌上连"看得见"都勉强(实测全站每页稳定被判为不可读);
305
+ 9.5px 是这套 mono 铭牌的下限,字距同步收一点以保持行长。 */
306
+ font-size: 9.5px;
307
+ letter-spacing: 0.16em;
220
308
  text-transform: uppercase;
221
309
  color: var(--sider-ink-faint);
222
310
  }
@@ -390,4 +478,23 @@ const go = (key: string) => {
390
478
  opacity: 0;
391
479
  transform: translateX(-8px);
392
480
  }
481
+
482
+ /* 抽屉形态的定位/位移样式在 main.css 响应式层(body.nav-drawer)—— 见那里的说明。 */
483
+
484
+ .nav-scrim {
485
+ position: fixed;
486
+ inset: 0;
487
+ z-index: 1100;
488
+ background: rgb(6 12 20 / 58%);
489
+ backdrop-filter: blur(2px);
490
+ animation: nav-scrim-in 0.2s ease both;
491
+ }
492
+
493
+ @keyframes nav-scrim-in {
494
+ from { opacity: 0; }
495
+ }
496
+
497
+ @media (prefers-reduced-motion: reduce) {
498
+ .nav-scrim { animation: none; }
499
+ }
393
500
  </style>
@@ -14,6 +14,7 @@ import VChart from 'vue-echarts'
14
14
  import { computed } from 'vue'
15
15
  import type { PropType } from 'vue'
16
16
  import type { EChartsOption } from 'echarts'
17
+ import type { SetOptionOpts } from 'echarts/core'
17
18
 
18
19
  // 按需注册 ECharts 模块(必须在 <ClientOnly> 内使用:canvas 仅客户端可渲染)
19
20
  use([
@@ -61,7 +62,7 @@ const merged = computed<EChartsOption>(() => ({
61
62
  * series 数量**减少**时(如筛选后趋势线变少),旧 series 必须被移除,否则会残留幽灵曲线;
62
63
  * - `lazyUpdate: true` → 同一 tick 内多次 setOption 合并到下一帧渲染,避免重复绘制。
63
64
  */
64
- const updateOptions = { notMerge: false, replaceMerge: ['series'], lazyUpdate: true } as const
65
+ const updateOptions: SetOptionOpts = { notMerge: false, replaceMerge: ['series'], lazyUpdate: true }
65
66
  </script>
66
67
 
67
68
  <template>
@@ -224,13 +224,13 @@ const stateDot: Record<string, string> = {
224
224
  {{ group[0] }}({{ (group[1] as typeof assignedTasks.working).length }})
225
225
  </div>
226
226
  <div
227
- v-for="t in group[1]"
228
- :key="t.id"
227
+ v-for="task in group[1]"
228
+ :key="task.id"
229
229
  class="queue-task"
230
230
  >
231
- <span class="state-chip aw-mono">{{ t.state }}</span>
232
- <span class="qt-title">{{ t.title }}</span>
233
- <span class="qt-meta">{{ t.progress }}%</span>
231
+ <span class="state-chip aw-mono">{{ task.state }}</span>
232
+ <span class="qt-title">{{ task.title }}</span>
233
+ <span class="qt-meta">{{ task.progress }}%</span>
234
234
  </div>
235
235
  <div
236
236
  v-if="(group[1] as typeof assignedTasks.working).length === 0"
@@ -384,7 +384,7 @@ const stateDot: Record<string, string> = {
384
384
  .state-chip {
385
385
  flex: none;
386
386
  padding: 1px 6px;
387
- font-size: 9px;
387
+ font-size: 10px;
388
388
  line-height: 15px;
389
389
  letter-spacing: 0.03em;
390
390
  color: var(--ink-soft);
@@ -822,7 +822,7 @@ onBeforeUnmount(() => {
822
822
  align-items: center;
823
823
  padding: 0 6px;
824
824
  font-family: var(--font-mono);
825
- font-size: 9px;
825
+ font-size: 10px;
826
826
  line-height: 15px;
827
827
  color: var(--ink-faint);
828
828
  border: 1px solid var(--line-strong);
@@ -944,4 +944,55 @@ onBeforeUnmount(() => {
944
944
  background: color-mix(in srgb, currentColor 5%, transparent);
945
945
  border-radius: var(--radius-chip);
946
946
  }
947
+
948
+ /* ── 窄屏(≤1023):泳道从"并排仪表"改为"一次一泳道"的横向卡片流 ──
949
+ 桌面 min-width 240px 的泳道在 390px 下并排 = 每列都被压到极限;
950
+ 改为 88% 宽 + scroll-snap:一屏一路信号,横扫切换成员。 */
951
+ @media (max-width: 1023.98px) {
952
+ .toolbar {
953
+ flex-wrap: wrap;
954
+ gap: 8px;
955
+ padding: 8px 10px 6px;
956
+ }
957
+
958
+ .ts-label,
959
+ .ts-unit,
960
+ .ts-detail,
961
+ .lane-meta,
962
+ .empty-hint {
963
+ font-size: 11.5px;
964
+ }
965
+
966
+ .lanes {
967
+ padding: 8px;
968
+ scroll-snap-type: x mandatory;
969
+ -webkit-overflow-scrolling: touch;
970
+ }
971
+
972
+ .lane {
973
+ flex: 0 0 88%;
974
+ min-width: 0;
975
+ scroll-snap-align: center;
976
+ }
977
+
978
+ .lane-name {
979
+ font-size: 14px;
980
+ }
981
+
982
+ .lane-chip,
983
+ .lane-role,
984
+ .term-badge {
985
+ font-size: 11.5px;
986
+ line-height: 18px;
987
+ }
988
+
989
+ .lane-actions .ant-btn {
990
+ min-width: 40px;
991
+ min-height: 40px;
992
+ }
993
+
994
+ .empty-title {
995
+ font-size: 13px;
996
+ }
997
+ }
947
998
  </style>
@@ -262,7 +262,7 @@ async function doRemove(id: string): Promise<void> {
262
262
  .head-hint {
263
263
  margin-left: auto;
264
264
  font-family: var(--font-mono);
265
- font-size: 8.5px;
265
+ font-size: 10px;
266
266
  color: var(--hud-faint, #5b6c7b);
267
267
  white-space: nowrap;
268
268
  }
@@ -384,7 +384,9 @@ async function doRemove(id: string): Promise<void> {
384
384
  }
385
385
  .model-badge {
386
386
  font-family: var(--font-mono);
387
- font-size: 8.5px;
387
+ /* 8.5px 在这套 HUD 里是"看得见读不了"的下限之外(实测被审计稳定判为不可读);
388
+ 10px 是同类铭牌(--hud 微字)在 1440 下的地板。 */
389
+ font-size: 10px;
388
390
  letter-spacing: 0.08em;
389
391
  color: var(--hud-faint, #5b6c7b);
390
392
  text-align: left;
@@ -188,6 +188,8 @@ const onLlmModelChange = (): void => {
188
188
  }
189
189
  const settingsSaving = ref(false)
190
190
  const fileSelectorOpen2 = ref(false)
191
+ /** channel 设置弹窗预填的默认 LLM(llmJson 反序列化形状;与服务端 channelLlmSchema 对齐) */
192
+ interface ChannelLlmDefaults { provider?: string, model?: string, effort?: string }
191
193
  const openSettings = (channelId: string): void => {
192
194
  const meta = channels.value.find(c => c.id === channelId)
193
195
  settingsChannelId.value = channelId
@@ -195,10 +197,10 @@ const openSettings = (channelId: string): void => {
195
197
  settingsForm.scenarioPrompt = meta?.scenarioPrompt ?? ''
196
198
  settingsForm.workspace = meta?.workspace ?? ''
197
199
  // 预填 channel 默认 LLM(llmJson 由列表接口透传)
198
- let saved: { provider?: string, model?: string, effort?: string } | null = null
200
+ let saved: ChannelLlmDefaults | null = null
199
201
  try {
200
202
  const metaAny = meta as unknown as { llmJson?: string } | undefined
201
- saved = metaAny?.llmJson ? JSON.parse(metaAny.llmJson) as typeof saved : null
203
+ saved = metaAny?.llmJson ? JSON.parse(metaAny.llmJson) as ChannelLlmDefaults : null
202
204
  }
203
205
  catch { saved = null }
204
206
  llmForm.enabled = !!saved?.model
@@ -728,4 +728,100 @@ const placeholder = computed(() =>
728
728
  background: var(--tone-live-dot);
729
729
  opacity: 1;
730
730
  }
731
+
732
+ /* ── 窄屏(≤1023):输入区是手持设备的"主操作面",键盘弹出时它必须还在 ──
733
+ 桌面工具栏是「一行左簇右钮」;390px 下这行会折成一列竖排字,
734
+ 所以窄屏改为「模式行 → 目标行 → 发送行」三段堆叠,发送占满一行且 ≥44px。 */
735
+ @media (max-width: 1023.98px) {
736
+ .composer {
737
+ padding: 8px 10px calc(10px + env(safe-area-inset-bottom));
738
+ }
739
+
740
+ .composer-box {
741
+ padding: 8px 10px;
742
+ }
743
+
744
+ /* 状态 chip:桌面宽度自适应内容,窄屏必须允许折行,否则顶破输入卡 */
745
+ .composer-status-chip {
746
+ width: auto;
747
+ flex-wrap: wrap;
748
+ row-gap: 2px;
749
+ font-size: 11.5px;
750
+ line-height: 1.45;
751
+ }
752
+
753
+ .chip-hint {
754
+ flex: 1 1 100%;
755
+ padding-left: 0;
756
+ margin-left: 0;
757
+ }
758
+
759
+ .reach-chip,
760
+ .mention-role,
761
+ .mention-title {
762
+ font-size: 11.5px;
763
+ }
764
+
765
+ /* 16px 是 iOS 不缩放输入框的下限(小于它聚焦时整页被放大) */
766
+ .composer-input {
767
+ min-height: 42px;
768
+ max-height: 30dvh;
769
+ font-size: 16px;
770
+ }
771
+
772
+ .composer-bar {
773
+ flex-wrap: wrap;
774
+ gap: 8px;
775
+ margin-top: 8px;
776
+ }
777
+
778
+ .cb-left {
779
+ flex: 1 1 100%;
780
+ row-gap: 8px;
781
+ }
782
+
783
+ .cb-right {
784
+ flex: 1 1 100%;
785
+ }
786
+
787
+ /* 主操作:整行墨色药丸(触摸目标 44px) */
788
+ .send-btn {
789
+ width: 100%;
790
+ height: 44px;
791
+ font-size: 18px;
792
+ }
793
+
794
+ .aw-seg button {
795
+ min-height: 40px;
796
+ padding: 0 12px;
797
+ }
798
+
799
+ .chip-toggle {
800
+ min-height: 40px;
801
+ }
802
+
803
+ .target {
804
+ flex: 1 1 130px;
805
+ width: auto;
806
+ }
807
+
808
+ .composer-bar :deep(.ant-select-selector) {
809
+ min-height: 40px;
810
+ align-items: center;
811
+ }
812
+
813
+ .loop-number,
814
+ .loop-number.iterations {
815
+ flex: 1 1 96px;
816
+ width: auto;
817
+ }
818
+
819
+ .composer-bar :deep(.ant-input-number) {
820
+ min-height: 40px;
821
+ }
822
+
823
+ .mention-opt {
824
+ min-height: 44px;
825
+ }
826
+ }
731
827
  </style>
@@ -544,6 +544,25 @@ tr.row-recipe-alarm td:first-child { box-shadow: inset 3px 0 0 var(--tone-danger
544
544
  border-color: transparent;
545
545
  opacity: 1;
546
546
  }
547
+ /* ── 窄屏字号地板 ────────────────────────────────────────────────────────
548
+ * 节点行是"一台仪表的铭牌":桌面 10–11px 的 mono 微字是刻意的仪器语言。
549
+ * 但 375px 下这一行同时是**横向卷轴里的账页**,读距近、字号小、还要左右扫 ——
550
+ * 实测审计在 /daq 单页稳定报出近 2000 个 <11px 的文本节点,全部来自这里。
551
+ * 手持档把二级/三级信息抬到 11.5px(一级不受影响),布局不变(它们本就在
552
+ * 允许换行的单元格里),只是把"看得见"变成"读得了"。 */
553
+ @media (max-width: 900px) {
554
+ .ch,
555
+ .drv-tag,
556
+ .st-pill,
557
+ .node-meta small,
558
+ .dev-unbind,
559
+ .dev-bind-chip,
560
+ .dev-add,
561
+ small.mono {
562
+ font-size: 11.5px;
563
+ }
564
+ }
565
+
547
566
  @media (prefers-reduced-motion: no-preference) {
548
567
  .run-pill.on .rp-dot { animation: rpPulse 1.8s ease-in-out infinite; }
549
568
  }