agentworkshop 0.7.39 → 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 (373) 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/BOt2SP4z.js +1 -0
  7. package/.output/public/_nuxt/BP-NyKVG.js +18 -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/{C_OLzD09.js → C4oW1HsE.js} +1 -1
  12. package/.output/public/_nuxt/CFxtLwjp.js +1 -0
  13. package/.output/public/_nuxt/{Cec0Ua3F.js → CS50LB_l.js} +1 -1
  14. package/.output/public/_nuxt/C_iYD-EB.js +1 -0
  15. package/.output/public/_nuxt/{DAe0h2MB.js → ClILjvWH.js} +1 -1
  16. package/.output/public/_nuxt/CssgYAAL2.js +1 -0
  17. package/.output/public/_nuxt/{CY9LbPCI.js → CzOCSGLe.js} +1 -1
  18. package/.output/public/_nuxt/D8qvkfyY.js +1 -0
  19. package/.output/public/_nuxt/DCn7QZ5N.js +2 -0
  20. package/.output/public/_nuxt/DGIuvyRN2.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/DZshyNLa.js +1 -0
  26. package/.output/public/_nuxt/{45zuyAso.js → D_OTvQza.js} +1 -1
  27. package/.output/public/_nuxt/DcsCcxp4.js +1 -0
  28. package/.output/public/_nuxt/{DUrecWPx.js → Dihnimlk.js} +2 -2
  29. package/.output/public/_nuxt/Dqw1lpr-.js +1 -0
  30. package/.output/public/_nuxt/{CUDwzgLV.js → Dr9v6C0f.js} +9 -9
  31. package/.output/public/_nuxt/{8NMOXZOV.js → Du9ZJtnj.js} +1 -1
  32. package/.output/public/_nuxt/TownView.f-YOdXRs.css +1 -0
  33. package/.output/public/_nuxt/_id_.CM4bIgKY.css +1 -0
  34. package/.output/public/_nuxt/_id_.bNV69Dtf.css +1 -0
  35. package/.output/public/_nuxt/_wsId_.B4WiqkIS.css +1 -0
  36. package/.output/public/_nuxt/agents.ZD0rVdHE.css +1 -0
  37. package/.output/public/_nuxt/aml.BN8ZEW4h.css +1 -0
  38. package/.output/public/_nuxt/builds/latest.json +1 -1
  39. package/.output/public/_nuxt/builds/meta/f4707884-7cf4-4a31-80d2-e3d72b73745f.json +1 -0
  40. package/.output/public/_nuxt/channel-templates.BOtahzPi.css +1 -0
  41. package/.output/public/_nuxt/daq.B0D3dPAc.css +1 -0
  42. package/.output/public/_nuxt/dcw.8Y7FqCVN.css +1 -0
  43. package/.output/public/_nuxt/default.J32SgqFY.css +1 -0
  44. package/.output/public/_nuxt/entry.bdm0tv6M.css +1 -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 +2225 -1445
  61. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  62. package/.output/server/chunks/build/{TownView-jVazYOjN.mjs → TownView-BuLAsmpR.mjs} +288 -206
  63. package/.output/server/chunks/build/TownView-BuLAsmpR.mjs.map +1 -0
  64. package/.output/server/chunks/build/{_id_-CfVosNg3.mjs → _id_-BU1wfOID.mjs} +138 -138
  65. package/.output/server/chunks/build/{_id_-CfVosNg3.mjs.map → _id_-BU1wfOID.mjs.map} +1 -1
  66. package/.output/server/chunks/build/{_id_-Hwr4rZpr.mjs → _id_-BYsEua57.mjs} +33 -32
  67. package/.output/server/chunks/build/_id_-BYsEua57.mjs.map +1 -0
  68. package/.output/server/chunks/build/{_wsId_-BVg3bB77.mjs → _wsId_-BxlDcJHg.mjs} +293 -259
  69. package/.output/server/chunks/build/{_wsId_-BVg3bB77.mjs.map → _wsId_-BxlDcJHg.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-cgyjKmJu.mjs} +188 -122
  78. package/.output/server/chunks/build/daq-cgyjKmJu.mjs.map +1 -0
  79. package/.output/server/chunks/build/{dcw-6vEYVeje.mjs → dcw-CoTxBlAZ.mjs} +45 -45
  80. package/.output/server/chunks/build/{dcw-6vEYVeje.mjs.map → dcw-CoTxBlAZ.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-BSOeZwwI.mjs} +34 -34
  84. package/.output/server/chunks/build/{logs-B-xhuqln.mjs.map → logs-BSOeZwwI.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-DFxjn9Xa.mjs} +33 -17
  88. package/.output/server/chunks/build/pages-DFxjn9Xa.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-qMPql9Se.mjs} +36 -10
  100. package/.output/server/chunks/build/town-qMPql9Se.mjs.map +1 -0
  101. package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs +1 -1
  102. package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs +1 -1
  103. package/.output/server/chunks/build/useResponsive-BKDMGTHs.mjs +49 -0
  104. package/.output/server/chunks/build/useResponsive-BKDMGTHs.mjs.map +1 -0
  105. package/.output/server/chunks/build/{users-fohSmF-J.mjs → users-Cfd5-l2-.mjs} +6 -6
  106. package/.output/server/chunks/build/{users-fohSmF-J.mjs.map → users-Cfd5-l2-.mjs.map} +1 -1
  107. package/.output/server/chunks/build/{workshop-DX5-ldc4.mjs → workshop-BL5bhfs0.mjs} +15 -15
  108. package/.output/server/chunks/build/{workshop-DX5-ldc4.mjs.map → workshop-BL5bhfs0.mjs.map} +1 -1
  109. package/.output/server/chunks/build/{workspaces-BuydxM-3.mjs → workspaces-Bgz5Ekwp.mjs} +18 -3
  110. package/.output/server/chunks/build/workspaces-Bgz5Ekwp.mjs.map +1 -0
  111. package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs.map +1 -1
  112. package/.output/server/chunks/routes/api/system/index.patch.mjs.map +1 -1
  113. package/.output/server/chunks/routes/api/system/index.post.mjs.map +1 -1
  114. package/.output/server/chunks/routes/api/system/settings/events.get.mjs.map +1 -1
  115. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +6 -2
  116. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
  117. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +2 -1
  118. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs.map +1 -1
  119. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  120. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +3 -3
  121. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs.map +1 -1
  122. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs.map +1 -1
  123. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs.map +1 -1
  124. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +3 -2
  125. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs.map +1 -1
  126. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +2 -1
  127. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs.map +1 -1
  128. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +8 -6
  129. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs.map +1 -1
  130. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +5 -5
  131. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs.map +1 -1
  132. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +14 -4
  133. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs.map +1 -1
  134. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +4 -4
  135. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs.map +1 -1
  136. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +4 -3
  137. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs.map +1 -1
  138. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +31 -0
  139. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs.map +1 -0
  140. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +28 -0
  141. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs.map +1 -0
  142. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs.map +1 -1
  143. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +32 -0
  144. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs.map +1 -0
  145. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +34 -0
  146. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs.map +1 -0
  147. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +33 -0
  148. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs.map +1 -0
  149. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +34 -0
  150. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs.map +1 -0
  151. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  152. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  153. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  154. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  155. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  156. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  157. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  158. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +2 -0
  159. package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
  160. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +3 -1
  161. package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
  162. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  163. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  164. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  165. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  166. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  167. package/.output/server/chunks/routes/renderer.mjs +3 -3
  168. package/.output/server/chunks/virtual/entry.mjs +51 -25
  169. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  170. package/.output/server/package.json +1 -1
  171. package/README-zh.md +199 -35
  172. package/README.md +739 -591
  173. package/app/app.vue +9 -3
  174. package/app/assets/css/main.css +517 -7
  175. package/app/components/AppHeader.vue +98 -7
  176. package/app/components/AppSidebar.vue +117 -11
  177. package/app/components/AwChart.vue +2 -1
  178. package/app/components/workshop/AgentInspectorDrawer.vue +6 -6
  179. package/app/components/workshop/AgentLanesView.vue +52 -1
  180. package/app/components/workshop/AssetLibrary.vue +4 -2
  181. package/app/components/workshop/ChannelSessionList.vue +4 -2
  182. package/app/components/workshop/Composer.vue +96 -0
  183. package/app/components/workshop/DaqNodeRow.vue +19 -0
  184. package/app/components/workshop/DaqTemplateIcon.vue +33 -0
  185. package/app/components/workshop/DeviceTwinPanel.vue +37 -35
  186. package/app/components/workshop/EventBlock.vue +3 -3
  187. package/app/components/workshop/InspectorPanel.vue +47 -11
  188. package/app/components/workshop/LiveAgentBar.vue +34 -0
  189. package/app/components/workshop/TaskBoardView.vue +83 -33
  190. package/app/components/workshop/TranscriptTimeline.vue +56 -0
  191. package/app/components/workshop/blocks/ClusterError.vue +1 -1
  192. package/app/components/workshop/blocks/ClusterRoute.vue +3 -1
  193. package/app/components/workshop/blocks/ClusterStatus.vue +2 -2
  194. package/app/components/workshop/blocks/ClusterStream.vue +8 -2
  195. package/app/components/workshop/town/ModelPreview3D.vue +1 -1
  196. package/app/components/workshop/town/TownView.vue +507 -82
  197. package/app/composables/useResponsive.ts +88 -0
  198. package/app/composables/useRouteMeta.ts +3 -0
  199. package/app/composables/workshop/useDcwStream.ts +1 -1
  200. package/app/composables/workshop/useVisibleInterval.ts +2 -2
  201. package/app/composables/workshop/useWorkshopApi.ts +1 -1
  202. package/app/layouts/default.vue +46 -2
  203. package/app/pages/aml/index.vue +712 -616
  204. package/app/pages/daq/[id].vue +3 -2
  205. package/app/pages/daq/index.vue +209 -9
  206. package/app/pages/dcw/[id].vue +109 -28
  207. package/app/pages/dcw/index.vue +83 -23
  208. package/app/pages/index.vue +35 -1
  209. package/app/pages/logs/index.vue +147 -13
  210. package/app/pages/monitor.vue +56 -12
  211. package/app/pages/permissions/index.vue +34 -0
  212. package/app/pages/plugins/index.vue +35 -4
  213. package/app/pages/settings.vue +90 -21
  214. package/app/pages/tokens.vue +23 -0
  215. package/app/pages/town.vue +50 -5
  216. package/app/pages/users.vue +23 -0
  217. package/app/pages/workshop/agents.vue +92 -2
  218. package/app/pages/workshop/channel-templates.vue +53 -0
  219. package/app/pages/workshop/index.vue +14 -0
  220. package/app/pages/workshop/teams.vue +66 -6
  221. package/app/pages/workshop/w/[wsId].vue +202 -14
  222. package/app/plugins/aw-plugins.client.ts +13 -8
  223. package/app/stores/app.ts +33 -1
  224. package/app/stores/workshop/user.ts +1 -1
  225. package/app/stores/workshop/workspaces.ts +18 -2
  226. package/app/utils/api-error.ts +1 -1
  227. package/cli/commands/build.mjs +8 -1
  228. package/docker-compose.yml +6 -0
  229. package/i18n/locales/en.ts +2 -0
  230. package/i18n/locales/zh-CN.ts +2 -0
  231. package/nuxt.config.ts +31 -0
  232. package/package.json +9 -1
  233. package/scripts/_dbg-param-map-e2e.ts +242 -0
  234. package/scripts/_dbg-param-map-rest-smoke.mjs +73 -0
  235. package/scripts/_dbg-param-real-scenario.mjs +153 -0
  236. package/scripts/api-live-e2e.mjs +40 -8
  237. package/scripts/capture-walkthrough.mjs +232 -0
  238. package/scripts/render-walkthrough-figure.mjs +46 -0
  239. package/scripts/seed-walkthrough-fixture.mjs +143 -0
  240. package/scripts/test-plugin-hardening.mjs +8 -0
  241. package/scripts/ui/admin-shots.mjs +46 -0
  242. package/scripts/ui/audit-layout.mjs +301 -0
  243. package/scripts/ui/bump-microfont.mjs +39 -0
  244. package/scripts/ui/lib.mjs +198 -0
  245. package/scripts/ui/linkcheck2.mjs +37 -0
  246. package/scripts/ui/live-render-check.mjs +72 -0
  247. package/scripts/ui/md-lint.mjs +80 -0
  248. package/scripts/ui/perf-audit.mjs +132 -0
  249. package/scripts/ui/readme-assets.mjs +30 -0
  250. package/scripts/ui/readme-shots.mjs +42 -0
  251. package/scripts/ui/record.mjs +225 -0
  252. package/scripts/ui/seed-admin.mjs +68 -0
  253. package/scripts/ui/seed-demo.mjs +83 -0
  254. package/scripts/ui/shot-hero.mjs +25 -0
  255. package/scripts/ui/shots.mjs +75 -0
  256. package/scripts/ui/sim-ui-shot.mjs +16 -0
  257. package/scripts/ui/verify-nav.mjs +51 -0
  258. package/scripts/ui/verify-responsive.mjs +285 -0
  259. package/server/api/system/config-groups/[id].patch.ts +1 -1
  260. package/server/api/system/config-groups/index.post.ts +1 -1
  261. package/server/api/system/settings/events.get.ts +1 -1
  262. package/server/api/system/settings/index.patch.ts +1 -1
  263. package/server/api/workshop/agent-tools/invoke.post.ts +16 -2
  264. package/server/api/workshop/aml/datasets/[id].get.ts +8 -1
  265. package/server/api/workshop/daq/infra/reconnect.post.ts +1 -1
  266. package/server/api/workshop/daq/templates/[key].delete.ts +1 -0
  267. package/server/api/workshop/daq/templates/[key].patch.ts +1 -0
  268. package/server/api/workshop/daq/templates/index.post.ts +1 -0
  269. package/server/api/workshop/dcw/[id]/write.post.ts +10 -2
  270. package/server/api/workshop/dcw/[id].delete.ts +5 -2
  271. package/server/api/workshop/dcw/index.get.ts +2 -0
  272. package/server/api/workshop/dcw/lines/[id].patch.ts +1 -1
  273. package/server/api/workshop/dcw/params/[id]/read.post.ts +17 -0
  274. package/server/api/workshop/dcw/params/[id]/write.post.ts +21 -0
  275. package/server/api/workshop/dcw/params/[id].delete.ts +19 -0
  276. package/server/api/workshop/dcw/params/[id].patch.ts +23 -0
  277. package/server/api/workshop/dcw/params/index.get.ts +27 -0
  278. package/server/api/workshop/dcw/params/index.post.ts +25 -0
  279. package/server/api/workshop/permissions/index.get.ts +3 -1
  280. package/server/plugins/aw-plugins.ts +14 -3
  281. package/server/plugins/dev-stability-guard.ts +3 -1
  282. package/server/plugins/system-config.ts +6 -1
  283. package/server/services/system-config.ts +28 -9
  284. package/server/services/workshop/agents/adapters/one-shot-cli-agent.ts +2 -1
  285. package/server/services/workshop/agents/agent-interface.ts +8 -6
  286. package/server/services/workshop/agents/base-agent.ts +18 -4
  287. package/server/services/workshop/agents/claude-agent.ts +7 -3
  288. package/server/services/workshop/agents/codex-agent.ts +3 -3
  289. package/server/services/workshop/agents/dsh-agent.ts +3 -3
  290. package/server/services/workshop/agents/goose-agent.ts +0 -1
  291. package/server/services/workshop/agents/harness-terminal.ts +14 -1
  292. package/server/services/workshop/agents/hermes-agent.ts +4 -2
  293. package/server/services/workshop/agents/host-tool-bridge.ts +5 -1
  294. package/server/services/workshop/agents/industrial-context.ts +4 -1
  295. package/server/services/workshop/agents/industrial-tools.ts +164 -6
  296. package/server/services/workshop/agents/omp-agent.ts +15 -9
  297. package/server/services/workshop/agents/opencode-agent.ts +47 -21
  298. package/server/services/workshop/agents/qwen-agent.ts +10 -5
  299. package/server/services/workshop/aml/entity.ts +3 -1
  300. package/server/services/workshop/aml/python-runtime.ts +3 -2
  301. package/server/services/workshop/daq/bus/mqtt.adapter.ts +8 -4
  302. package/server/services/workshop/daq/daq-controller.ts +18 -3
  303. package/server/services/workshop/daq/daq-runtime.ts +5 -3
  304. package/server/services/workshop/daq/drivers.ts +63 -8
  305. package/server/services/workshop/daq/host-ports.ts +3 -2
  306. package/server/services/workshop/daq/storage/timescale.adapter.ts +3 -1
  307. package/server/services/workshop/db/channel.repo.ts +4 -0
  308. package/server/services/workshop/db/ops.repo.ts +5 -2
  309. package/server/services/workshop/db/retention.ts +8 -3
  310. package/server/services/workshop/dcw/dcw-controller.ts +143 -16
  311. package/server/services/workshop/dcw/dcw-product.repo.ts +38 -1
  312. package/server/services/workshop/dcw/dcw-runtime.ts +3 -2
  313. package/server/services/workshop/dcw/drivers.ts +5 -2
  314. package/server/services/workshop/dcw/param-conversion.ts +78 -0
  315. package/server/services/workshop/dcw/param-limits.ts +142 -0
  316. package/server/services/workshop/dcw/param-map.repo.ts +305 -0
  317. package/server/services/workshop/dcw/recipe-rollback-manager.ts +13 -7
  318. package/server/services/workshop/runtime/agent-runtime.ts +4 -0
  319. package/server/services/workshop/runtime/manager.ts +9 -2
  320. package/server/services/workshop/settings.ts +4 -2
  321. package/server/types/pg.d.ts +49 -0
  322. package/server/utils/stability-severity.ts +13 -2
  323. package/shared/config/groups.mjs +22 -1
  324. package/shared/config/home.d.mts +28 -0
  325. package/shared/dcw-protocol.ts +136 -0
  326. package/uno.config.ts +12 -1
  327. package/.output/public/_nuxt/BFkgkW8u.js +0 -4
  328. package/.output/public/_nuxt/C5gUkRwn.js +0 -1
  329. package/.output/public/_nuxt/CM12FuB42.js +0 -1
  330. package/.output/public/_nuxt/CZiw7sEV.js +0 -1
  331. package/.output/public/_nuxt/Cc_9VzD42.js +0 -1
  332. package/.output/public/_nuxt/CdPzkOMV.js +0 -1
  333. package/.output/public/_nuxt/CmsOtOAA2.js +0 -1
  334. package/.output/public/_nuxt/D1YDxZpZ.js +0 -1
  335. package/.output/public/_nuxt/D20Yamr4.js +0 -1
  336. package/.output/public/_nuxt/DmqknNvV.js +0 -18
  337. package/.output/public/_nuxt/DnUuIR83.js +0 -1
  338. package/.output/public/_nuxt/S_fVQwJK.js +0 -1
  339. package/.output/public/_nuxt/TownView.0oLiQgTC.css +0 -1
  340. package/.output/public/_nuxt/_id_.D-SYuyZb.css +0 -1
  341. package/.output/public/_nuxt/_id_.hma_BU6T.css +0 -1
  342. package/.output/public/_nuxt/_wsId_.B12v3PhY.css +0 -1
  343. package/.output/public/_nuxt/agents.BV70ioCv.css +0 -1
  344. package/.output/public/_nuxt/ahgEJu2R.js +0 -1
  345. package/.output/public/_nuxt/aml.COEKNNqK.css +0 -1
  346. package/.output/public/_nuxt/builds/meta/4457d63f-0866-4cea-b320-04a321f24795.json +0 -1
  347. package/.output/public/_nuxt/channel-templates.C-M5nKcC.css +0 -1
  348. package/.output/public/_nuxt/daq.B3265ZDn.css +0 -1
  349. package/.output/public/_nuxt/dcw.DLYZqEhT.css +0 -1
  350. package/.output/public/_nuxt/default.BXI_fZUi.css +0 -1
  351. package/.output/public/_nuxt/entry.BB-Eeh-J.css +0 -1
  352. package/.output/public/_nuxt/logs.CqFyMrJw.css +0 -1
  353. package/.output/public/_nuxt/monitor.B--1dPzs.css +0 -1
  354. package/.output/public/_nuxt/pages.ooEzrMm9.css +0 -1
  355. package/.output/public/_nuxt/permissions.B1pjGChZ.css +0 -1
  356. package/.output/public/_nuxt/plugins.5e5chZ67.css +0 -1
  357. package/.output/public/_nuxt/pz2JDAM7.js +0 -2
  358. package/.output/public/_nuxt/settings.Dm3M0RLy.css +0 -1
  359. package/.output/public/_nuxt/teams.BC75EGnR.css +0 -1
  360. package/.output/public/_nuxt/tokens.xRb1fSPU.css +0 -1
  361. package/.output/public/_nuxt/users.CXnP2E08.css +0 -1
  362. package/.output/public/_nuxt/workshop.Jk5HxWPE.css +0 -1
  363. package/.output/server/chunks/build/TownView-jVazYOjN.mjs.map +0 -1
  364. package/.output/server/chunks/build/_id_-Hwr4rZpr.mjs.map +0 -1
  365. package/.output/server/chunks/build/agents-Bvin73QY.mjs.map +0 -1
  366. package/.output/server/chunks/build/daq-C03Uu5UE.mjs.map +0 -1
  367. package/.output/server/chunks/build/pages-BO7yZsXA.mjs.map +0 -1
  368. package/.output/server/chunks/build/settings-DoQ2Oq3P.mjs.map +0 -1
  369. package/.output/server/chunks/build/teams-2kz3CusY.mjs.map +0 -1
  370. package/.output/server/chunks/build/town-BOl6hs9B.mjs.map +0 -1
  371. package/.output/server/chunks/build/workspaces-BuydxM-3.mjs.map +0 -1
  372. /package/.output/public/_nuxt/{36oeS8_R2.js → 36oeS8_R.js} +0 -0
  373. /package/.output/public/_nuxt/{CYWVXZTS.js → CYWVXZTS2.js} +0 -0
@@ -619,25 +619,25 @@ const builtinCount = computed(() => dcw.templates.filter(t => t.builtin).length)
619
619
  </p>
620
620
  <div class="tpl-list">
621
621
  <div
622
- v-for="t in dcw.templates"
623
- :key="t.key"
622
+ v-for="tpl in dcw.templates"
623
+ :key="tpl.key"
624
624
  class="tpl-row"
625
- :title="t.semantics ?? ''"
625
+ :title="tpl.semantics ?? ''"
626
626
  >
627
- <b>{{ t.name }}</b>
628
- <small class="mono dim">{{ t.code }} · {{ t.min }}~{{ t.max }} {{ t.unit }}</small>
627
+ <b>{{ tpl.name }}</b>
628
+ <small class="mono dim">{{ tpl.code }} · {{ tpl.min }}~{{ tpl.max }} {{ tpl.unit }}</small>
629
629
  <small
630
- v-if="t.semantics"
630
+ v-if="tpl.semantics"
631
631
  class="tpl-sem"
632
- >{{ t.semantics.slice(0, 40) }}{{ t.semantics.length > 40 ? '…' : '' }}</small>
632
+ >{{ tpl.semantics.slice(0, 40) }}{{ tpl.semantics.length > 40 ? '…' : '' }}</small>
633
633
  <span
634
634
  class="tpl-tag"
635
- :class="{ builtin: t.builtin }"
636
- >{{ t.builtin ? $t('dcw.k3x23c054') : $t('dcw.k3t616a058') }}</span>
635
+ :class="{ builtin: tpl.builtin }"
636
+ >{{ tpl.builtin ? $t('dcw.k3x23c054') : $t('dcw.k3t616a058') }}</span>
637
637
  <button
638
- v-if="!t.builtin"
638
+ v-if="!tpl.builtin"
639
639
  class="mini-btn danger"
640
- @click="doRemoveTemplate(t.key)"
640
+ @click="doRemoveTemplate(tpl.key)"
641
641
  >
642
642
  {{ $t('dcw.k3xakp026') }}
643
643
  </button>
@@ -768,7 +768,7 @@ const builtinCount = computed(() => dcw.templates.filter(t => t.builtin).length)
768
768
  /* 状态徽章 = 玻璃芯片:双主题令牌化,浅色不再发白发黄 */
769
769
  .badge {
770
770
  padding: 3px 10px;
771
- font-size: 11px;
771
+ font-size: 11.5px;
772
772
  color: var(--ink-faint);
773
773
  background: var(--glass-bg);
774
774
  border: 1px solid var(--glass-line);
@@ -848,7 +848,7 @@ const builtinCount = computed(() => dcw.templates.filter(t => t.builtin).length)
848
848
  .line-card.idle .lc-name {
849
849
  color: var(--ink-faint);
850
850
  }
851
- .lc-head { display: flex; gap: 8px; align-items: center; }
851
+ .lc-head { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
852
852
  .lc-dot {
853
853
  width: 10px;
854
854
  height: 10px;
@@ -857,18 +857,19 @@ const builtinCount = computed(() => dcw.templates.filter(t => t.builtin).length)
857
857
  border-radius: 4px;
858
858
  box-shadow: 0 0 10px color-mix(in srgb, var(--lc) 70%, transparent);
859
859
  }
860
+ /* 名称不再用 ellipsis 硬裁:窄屏改用换行,长名不消失(审计的 text-clipped 根因) */
860
861
  .lc-name {
861
- overflow: hidden;
862
+ flex: 1 1 auto;
863
+ min-width: 0;
862
864
  font-size: 14.5px;
863
865
  color: var(--ink);
864
- text-overflow: ellipsis;
865
- white-space: nowrap;
866
+ overflow-wrap: anywhere;
866
867
  }
867
868
  .lc-state {
868
869
  margin-left: auto;
869
870
  flex: none;
870
871
  font-family: var(--font-mono);
871
- font-size: 10px;
872
+ font-size: 11.5px;
872
873
  color: var(--ink-faint);
873
874
  }
874
875
  .lc-state.on { color: var(--tone-success-dot); }
@@ -899,14 +900,15 @@ const builtinCount = computed(() => dcw.templates.filter(t => t.builtin).length)
899
900
  .lc-act:hover { color: var(--tone-info-dot); background: var(--tone-info-bg); }
900
901
  .lc-act.danger:hover { color: var(--tone-danger-dot); background: var(--tone-danger-bg); }
901
902
  .lc-act:active { transform: scale(0.9); }
902
- .lc-run { font-size: 10.5px; color: var(--tone-info-dot); }
903
+ .lc-run { font-size: 11.5px; color: var(--tone-info-dot); }
903
904
  .lc-run.dim { color: var(--ink-faint); }
904
905
  /* 无描述时的兜底提示进一步退后(77 张卡同文反复出现即是噪音;不压到 0.55 以下,保浅色可读) */
905
906
  .lc-run.dim.ph { opacity: 0.75; }
906
907
  .lc-stats {
907
908
  display: flex;
908
- gap: 14px;
909
- font-size: 10.5px;
909
+ flex-wrap: wrap;
910
+ gap: 6px 14px;
911
+ font-size: 11.5px;
910
912
  color: var(--ink-faint);
911
913
  }
912
914
  .lc-stats b { color: var(--ink); font-weight: 600; }
@@ -945,7 +947,7 @@ const builtinCount = computed(() => dcw.templates.filter(t => t.builtin).length)
945
947
  cursor: pointer;
946
948
  }
947
949
  .new-card:hover { color: var(--tone-success-dot); border-color: var(--tone-success-dot); transform: none; }
948
- .new-card small { font-weight: 400; font-size: 10px; color: var(--ink-faint); }
950
+ .new-card small { font-weight: 400; font-size: 11.5px; color: var(--ink-faint); }
949
951
 
950
952
  .banner { padding: 8px 12px; font-size: 12px; border-radius: 10px; }
951
953
  .banner.bad { color: var(--tone-danger-dot); background: var(--tone-danger-bg); border: 1px solid color-mix(in srgb, var(--tone-danger-dot) 30%, transparent); }
@@ -1008,7 +1010,7 @@ const builtinCount = computed(() => dcw.templates.filter(t => t.builtin).length)
1008
1010
  .m-actions { display: flex; gap: 8px; justify-content: flex-end; }
1009
1011
  .m-err { font-size: 11px; color: var(--tone-danger-dot); }
1010
1012
  .dim { color: var(--ink-faint); }
1011
- .sec-label { font-size: 10px; font-weight: 700; color: var(--ink-faint); letter-spacing: 0.16em; }
1013
+ .sec-label { font-size: 11.5px; font-weight: 700; color: var(--ink-faint); letter-spacing: 0.14em; }
1012
1014
  /* 删除确认:摘要行 + 级联勾选 */
1013
1015
  .del-summary { font-size: 12px; line-height: 1.6; color: var(--ink-soft); }
1014
1016
  .del-purge { display: flex; gap: 8px; align-items: center; font-size: 12px; color: var(--ink); cursor: pointer; }
@@ -1034,7 +1036,7 @@ const builtinCount = computed(() => dcw.templates.filter(t => t.builtin).length)
1034
1036
  .tpl-tag {
1035
1037
  padding: 1px 8px;
1036
1038
  font-family: var(--font-mono);
1037
- font-size: 9px;
1039
+ font-size: 11.5px;
1038
1040
  color: var(--tone-info-dot);
1039
1041
  border: 1px solid color-mix(in srgb, var(--tone-info-dot) 40%, transparent);
1040
1042
  border-radius: 5px;
@@ -1043,4 +1045,62 @@ const builtinCount = computed(() => dcw.templates.filter(t => t.builtin).length)
1043
1045
  .tpl-form { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
1044
1046
  .tpl-sem { flex: 1; color: var(--ink-faint); }
1045
1047
  textarea.inp { height: auto; padding: 6px 9px; font-size: 11.5px; resize: vertical; }
1048
+
1049
+ /* ══ 窄屏自适应层(≤900 手持/平板竖,≤640 单列)════════════════════════════
1050
+ 本页 375px 下的三类实测缺陷:可点元素 <40px(每张卡一个主操作)、
1051
+ 卡片微标签 10~10.5px、卡片头把长产线名硬裁成省略号。 */
1052
+ @media (max-width: 900px) {
1053
+ /* 1. 触摸目标:手持命中区 ≥40px(与 main.css 的 coarse-pointer 地板同值,
1054
+ 但那层只认 pointer:coarse,窄视口下也必须成立) */
1055
+ .line-card .pill-btn,
1056
+ .fleet-filter .aw-seg button,
1057
+ .badge.tpl-btn,
1058
+ .m-actions .pill-btn,
1059
+ .m-actions .mini-btn,
1060
+ .tpl-row .mini-btn,
1061
+ .lc-ctl .inp,
1062
+ .fleet-search {
1063
+ min-height: 40px;
1064
+ }
1065
+
1066
+ /* 卡片头的编辑/删除原本只在 hover 才显形 —— 触屏没有 hover,等于功能消失 */
1067
+ .lc-act {
1068
+ width: 40px;
1069
+ height: 40px;
1070
+ font-size: 16px;
1071
+ opacity: 1;
1072
+ }
1073
+
1074
+ .lc-ctl { flex-wrap: wrap; }
1075
+ .lc-ctl .inp { flex: 1 1 150px; }
1076
+ .lc-ctl .pill-btn { flex: 1 1 auto; }
1077
+
1078
+ /* 「产线管理 →」是 <a>:17px 行高在触屏上点不中,给它一条 40px 的整行命中区 */
1079
+ .lc-manage {
1080
+ display: inline-flex;
1081
+ align-items: center;
1082
+ min-height: 40px;
1083
+ }
1084
+
1085
+ /* 弹窗内的可点色块/勾选同样抬到 40 命中 */
1086
+ .color-row { flex-wrap: wrap; }
1087
+ .color-dot { width: 40px; height: 40px; }
1088
+ .del-purge input { width: 20px; height: 20px; }
1089
+ .modal { width: min(440px, calc(100vw - 20px)); padding: 14px; }
1090
+ .modal.wide { width: min(640px, calc(100vw - 20px)); }
1091
+ .tpl-form { grid-template-columns: 1fr; }
1092
+ .tpl-row { flex-wrap: wrap; }
1093
+ .m-actions { flex-wrap: wrap; }
1094
+ .m-actions > * { flex: 1 1 auto; }
1095
+
1096
+ /* 筛选条:分段可横扫,搜索占满整行 */
1097
+ .fleet-filter { gap: 10px; }
1098
+ .fleet-search { flex: 1 1 100%; width: 100%; margin-left: 0; }
1099
+ }
1100
+
1101
+ /* 2. 窄屏产线网格:显式单列(不再依赖 auto-fill 的隐式收敛) */
1102
+ @media (max-width: 640px) {
1103
+ .line-grid { grid-template-columns: 1fr; }
1104
+ .line-card { padding: 12px; }
1105
+ }
1046
1106
  </style>
@@ -47,6 +47,21 @@ onMounted(() => {
47
47
  // ---------- Harness 可用性(引擎 CLI 环境探测;服务端 30s 探测缓存,随兜底节拍刷新) ----------
48
48
  const api = useWorkshopApi()
49
49
  const harnesses = ref<HarnessMetaDto[]>([])
50
+
51
+ /**
52
+ * 引擎卡片第二行的命令名。
53
+ * 返回空串表示"这一行没有新信息":标签已经以命令名开头时
54
+ * (omp(真实 LLM) / omp、opencode / opencode、codex / codex…),
55
+ * 再写一遍只是把同一件事讲两遍 —— 实测 14 张卡里有 9 张是重复的。
56
+ * 真正有信息量的只有:不可用状态、in-process、以及与标签不同的真实二进制名。
57
+ */
58
+ const harnessCmd = (h: HarnessMetaDto): string => {
59
+ if (h.available === false) return t('home.harness.missing')
60
+ if (h.inprocess) return 'in-process'
61
+ const cmd = String(h.command ?? '')
62
+ if (!cmd) return ''
63
+ return h.label.startsWith(cmd) ? '' : cmd
64
+ }
50
65
  const loadHarnesses = async (): Promise<void> => {
51
66
  try {
52
67
  const res = await api.listHarnesses()
@@ -427,7 +442,10 @@ const fleetOverflow = computed(() => Math.max(lineCards.value.length - FLEET_CAP
427
442
  >
428
443
  <span class="h-dot" />
429
444
  <span class="h-name">{{ h.label }}</span>
430
- <span class="h-cmd mono">{{ h.available === false ? t('home.harness.missing') : (h.inprocess ? 'in-process' : h.command) }}</span>
445
+ <span
446
+ v-if="harnessCmd(h)"
447
+ class="h-cmd mono"
448
+ >{{ harnessCmd(h) }}</span>
431
449
  <span
432
450
  v-if="h.available === false && h.homepage"
433
451
  class="h-go"
@@ -901,7 +919,23 @@ const fleetOverflow = computed(() => Math.max(lineCards.value.length - FLEET_CAP
901
919
  .h-item.off .h-dot { background: var(--tone-danger-dot, #c25a4e); }
902
920
  .h-name { font-weight: 600; color: var(--ink); }
903
921
  .h-item.off .h-name { color: var(--ink-soft); }
922
+ /* 引擎命令名是"铭牌"级信息:桌面 10px 尚可,手持档必须让位给可读性
923
+ * (实测 / 在 390 下稳定报出 54 条 <11px,全部来自这里与 .aw-gauge-label) */
904
924
  .h-cmd { font-size: 10px; color: var(--ink-faint); }
925
+
926
+ /* 手持档字号地板:本页所有"铭牌级"微字(引擎命令名、产线状态、产线指标行、
927
+ 跳转箭头)统一抬到 11.5px。它们在桌面是仪器铭牌语言,在手机上就是读不了的小字。 */
928
+ @media (max-width: 900px) {
929
+ .h-cmd,
930
+ .h-go,
931
+ .lc-state,
932
+ .lc-run small,
933
+ .lc-meta,
934
+ .lc-meta span,
935
+ .fleet-all small {
936
+ font-size: 11.5px;
937
+ }
938
+ }
905
939
  /* 全部产线入口:虚线幽灵卡,聚合清单外的余量 */
906
940
  .fleet-all {
907
941
  display: flex;
@@ -243,7 +243,10 @@
243
243
  </td>
244
244
  </tr>
245
245
  <!-- 详情行内展开:紧贴事件行,点击即见(不再沉到表尾) -->
246
- <tr v-if="expandedId === row.id">
246
+ <tr
247
+ v-if="expandedId === row.id"
248
+ class="log-detail-row"
249
+ >
247
250
  <td
248
251
  colspan="7"
249
252
  class="detail-td"
@@ -252,7 +255,7 @@
252
255
  </td>
253
256
  </tr>
254
257
  </template>
255
- <tr>
258
+ <tr class="log-empty-row">
256
259
  <td
257
260
  v-if="opsLog.results.length === 0"
258
261
  colspan="7"
@@ -519,7 +522,7 @@ export default { name: 'OpsLogsPage' }
519
522
  <style scoped>
520
523
  .page { display: flex; flex-direction: column; gap: 12px; }
521
524
  .head-actions { display: flex; gap: 10px; align-items: center; padding-bottom: 4px; }
522
- .sub { margin: 8px 0 0; font-size: 12.5px; color: var(--ink-faint); }
525
+ .sub { margin: 8px 0 0; font-size: 13px; color: var(--ink-faint); }
523
526
  .live-dot {
524
527
  width: 8px; height: 8px; border-radius: 50%;
525
528
  background: var(--tone-success-dot);
@@ -531,7 +534,7 @@ export default { name: 'OpsLogsPage' }
531
534
  70% { box-shadow: 0 0 0 8px transparent; }
532
535
  100% { box-shadow: 0 0 0 0 transparent; }
533
536
  }
534
- .live-txt { font-size: 11px; color: var(--ink-faint); }
537
+ .live-txt { font-size: 11.5px; color: var(--ink-faint); }
535
538
 
536
539
  .filter-card {
537
540
  display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end;
@@ -541,10 +544,27 @@ export default { name: 'OpsLogsPage' }
541
544
  border-radius: 10px;
542
545
  backdrop-filter: var(--aurora-blur) saturate(1.15);
543
546
  }
547
+ /* 窄屏:6 个筛选维度从"一行一个"改成两列网格。
548
+ * 单列时筛选区独占整整一屏,用户要滚过 6 个下拉才看到第一条日志(实测 390)。 */
549
+ @media (max-width: 640px) {
550
+ .filter-card {
551
+ display: grid;
552
+ grid-template-columns: 1fr 1fr;
553
+ gap: 8px;
554
+ align-items: end;
555
+ }
556
+
557
+ /* 关键词是"宽输入",跨两列;两个动作按钮也跨两列,各自成行 */
558
+ .filter-card .flt-grow,
559
+ .filter-card > button {
560
+ grid-column: 1 / -1;
561
+ }
562
+ }
563
+
544
564
  .flt { display: flex; flex-direction: column; gap: 4px; font-size: 11.5px; color: var(--ink-faint); }
545
565
  .flt-grow { flex: 1 1 180px; }
546
566
  .inp-sel {
547
- min-width: 0; padding: 6px 9px; font-size: 12.5px; color: var(--ink);
567
+ min-width: 0; padding: 6px 9px; font-size: 13px; color: var(--ink);
548
568
  background: var(--frost-bg);
549
569
  border: 1px solid var(--glass-line); border-radius: 7px; outline: none;
550
570
  }
@@ -557,8 +577,8 @@ export default { name: 'OpsLogsPage' }
557
577
  overflow: hidden;
558
578
  backdrop-filter: var(--aurora-blur) saturate(1.15);
559
579
  }
560
- .err { margin: 0; padding: 8px 14px; font-size: 12px; color: var(--tone-danger-dot); }
561
- .log-table { width: 100%; font-size: 12.5px; border-collapse: collapse; }
580
+ .err { margin: 0; padding: 8px 14px; font-size: 13px; color: var(--tone-danger-dot); }
581
+ .log-table { width: 100%; font-size: 13px; border-collapse: collapse; }
562
582
  .log-table th {
563
583
  position: sticky; top: 0; z-index: 1;
564
584
  padding: 8px 10px; text-align: left; font-weight: 600; color: var(--ink-soft);
@@ -573,10 +593,10 @@ export default { name: 'OpsLogsPage' }
573
593
  .th-time, .th-src, .th-kind { white-space: nowrap; }
574
594
  .th-detail { width: 72px; }
575
595
  .actor { white-space: nowrap; }
576
- .summary .action { display: block; font-size: 10px; color: var(--ink-faint); }
596
+ .summary .action { display: block; font-size: 11.5px; color: var(--ink-faint); }
577
597
  .scope { display: flex; flex-wrap: wrap; gap: 4px; max-width: 220px; }
578
598
  .scope-chip {
579
- padding: 1px 7px; font-size: 10.5px; color: var(--ink-soft);
599
+ padding: 1px 7px; font-size: 11.5px; color: var(--ink-soft);
580
600
  background: var(--frost-bg); border-radius: 99px; white-space: nowrap;
581
601
  }
582
602
  .detail-cell { white-space: nowrap; }
@@ -585,17 +605,17 @@ export default { name: 'OpsLogsPage' }
585
605
  .detail-td { padding: 0 !important; }
586
606
  .detail-box {
587
607
  max-height: 260px; margin: 0; padding: 10px 14px; overflow: auto;
588
- font-size: 11.5px; color: var(--ink-soft); white-space: pre-wrap; word-break: break-word;
608
+ font-size: 12.5px; color: var(--ink-soft); white-space: pre-wrap; word-break: break-word;
589
609
  background: var(--paper-deep); border-top: 1px solid var(--glass-line);
590
610
  }
591
611
  .src-badge {
592
- display: inline-block; padding: 1px 8px; font-size: 10.5px;
612
+ display: inline-block; padding: 1px 8px; font-size: 11.5px;
593
613
  border: 1px solid var(--glass-line); border-radius: 99px; color: var(--ink-faint);
594
614
  }
595
615
  .src-badge.agent { color: var(--tone-info-dot); border-color: color-mix(in srgb, var(--tone-info-dot) 40%, transparent); }
596
616
  .src-badge.user { color: var(--tone-success-dot); border-color: color-mix(in srgb, var(--tone-success-dot) 40%, transparent); }
597
617
  .kind-chip {
598
- display: inline-block; padding: 1px 7px; font-size: 10.5px;
618
+ display: inline-block; padding: 1px 7px; font-size: 11.5px;
599
619
  color: var(--ink-soft); background: var(--frost-bg); border-radius: 5px; white-space: nowrap;
600
620
  }
601
621
  .kind-chip.alarm { color: var(--tone-danger-dot); background: var(--tone-danger-bg); }
@@ -621,11 +641,125 @@ export default { name: 'OpsLogsPage' }
621
641
  }
622
642
  .m-f { display: flex; flex-direction: column; gap: 4px; font-size: 11.5px; color: var(--ink-faint); }
623
643
  .m-f textarea, .m-f .inp-sel {
624
- padding: 7px 9px; font-size: 12.5px; color: var(--ink);
644
+ padding: 7px 9px; font-size: 13px; color: var(--ink);
625
645
  background: var(--frost-bg); border: 1px solid var(--glass-line); border-radius: 7px; outline: none;
626
646
  font-family: inherit; resize: vertical;
627
647
  }
628
648
  .m-f textarea:focus, .m-f .inp-sel:focus { border-color: color-mix(in srgb, var(--tone-info-dot) 55%, transparent); }
629
649
  .m-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 8px; }
630
650
  .m-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 12px; }
651
+
652
+ /* ══ 窄屏(≤899px):7 列表格在 375px 上被卡片裁掉四列(实测只剩"时间/来源/操作者"),
653
+ 每行高达 154px,字号被压到 10px。窄屏不再横向拖动"账页",
654
+ 而是把每行折成一张事件卡 —— 三段堆叠,一条日志一眼读完:
655
+ ① 时间戳 · 来源徽标 · 分类 chip · [展开]
656
+ ② 消息摘要(整行,可换行,13px)
657
+ ③ 操作者 + 归属维度(产线/产品/Recipe)
658
+ 表格语义(thead)在窄屏隐藏,列身份由"位置 + chip 颜色"承担。 */
659
+ @media (max-width: 899px) {
660
+ .log-table {
661
+ display: block;
662
+ font-size: 13px;
663
+ }
664
+
665
+ .log-table thead {
666
+ display: none;
667
+ }
668
+
669
+ .log-table tbody {
670
+ display: block;
671
+ }
672
+
673
+ .log-table tr {
674
+ display: flex;
675
+ flex-wrap: wrap;
676
+ gap: 6px 8px;
677
+ align-items: center;
678
+ padding: 10px 12px;
679
+ border-bottom: 1px solid color-mix(in srgb, var(--glass-line) 55%, transparent);
680
+ }
681
+
682
+ .log-table td {
683
+ display: block;
684
+ max-width: 100%;
685
+ padding: 0;
686
+ border-bottom: 0;
687
+ }
688
+
689
+ .log-table td.mono.dim {
690
+ order: 1;
691
+ font-size: 11.5px;
692
+ }
693
+
694
+ .log-table td:nth-child(2) { order: 2; }
695
+
696
+ .log-table td:nth-child(4) { order: 3; }
697
+
698
+ .log-table td.actor {
699
+ order: 4;
700
+ font-size: 11.5px;
701
+ color: var(--ink-faint);
702
+ }
703
+
704
+ .log-table td.detail-cell {
705
+ order: 5;
706
+ margin-left: auto;
707
+ white-space: normal;
708
+ }
709
+
710
+ .log-table td.summary {
711
+ order: 6;
712
+ flex: 1 1 100%;
713
+ font-size: 13px;
714
+ line-height: 1.5;
715
+ }
716
+
717
+ .log-table td.scope {
718
+ order: 7;
719
+ flex: 1 1 100%;
720
+ max-width: 100%;
721
+ }
722
+
723
+ /* 详情行 / 空态行不参与"事件卡"排布 */
724
+ .log-table tr.log-detail-row {
725
+ display: block;
726
+ padding: 0;
727
+ }
728
+
729
+ .log-table tr.log-detail-row td {
730
+ display: block;
731
+ }
732
+
733
+ .log-table tr.log-empty-row td,
734
+ .log-table td.empty {
735
+ flex: 1 1 100%;
736
+ width: 100%;
737
+ text-align: center;
738
+ }
739
+
740
+ /* 手指命中区:表格内的 mini-btn 原始高度只有 ~24px */
741
+ .log-table .mini-btn,
742
+ .filter-card .mini-btn,
743
+ .filter-card .pill-btn,
744
+ .head-actions .pill-btn,
745
+ .m-actions .pill-btn,
746
+ .m-actions .ghost-btn {
747
+ min-height: 40px;
748
+ padding: 8px 14px;
749
+ }
750
+
751
+ /* 筛选条:窄屏一项一行,不再两列互挤 */
752
+ .filter-card {
753
+ padding: 10px;
754
+ gap: 8px;
755
+ }
756
+
757
+ .flt,
758
+ .flt-grow,
759
+ .flt .inp-sel {
760
+ flex: 1 1 100%;
761
+ width: 100%;
762
+ min-width: 0;
763
+ }
764
+ }
631
765
  </style>
@@ -580,19 +580,34 @@ const processColumns = computed(() => [
580
580
  align-items: center;
581
581
  }
582
582
 
583
+ /* 前三张是"一个数"的量规;第四张「服务进程」内容是 PID + 时长 + ISO 快照时间,
584
+ * 等宽 4 列时它只有 ~200px,文案折成三行(实测 1440)。给它两列 ——
585
+ * 列宽按**内容长度**分,不是按卡片数量平均分。 */
583
586
  .stat-grid {
584
587
  display: grid;
585
- grid-template-columns: repeat(4, minmax(0, 1fr));
588
+ grid-template-columns: repeat(5, minmax(0, 1fr));
586
589
  gap: 14px;
587
590
  margin-bottom: 16px;
588
591
  }
589
592
 
593
+ .stat-grid > :last-child {
594
+ grid-column: span 2;
595
+ }
596
+
590
597
  @media (max-width: 1100px) {
591
598
  .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
592
599
  }
593
600
 
601
+ /* 窄屏两列:前三张是"一个数"的量规(标签 + 大字),单列会让每张卡
602
+ * 占掉 ~150px 高、四张卡吃掉整整一屏(实测)。第四张「服务进程」内容是长字符串,
603
+ * 让它独自跨两列 —— 这是按**内容**分的列,不是按数量硬凑。 */
594
604
  @media (max-width: 640px) {
595
- .stat-grid { grid-template-columns: 1fr; }
605
+ .stat-grid {
606
+ grid-template-columns: repeat(2, minmax(0, 1fr));
607
+ gap: 10px;
608
+ }
609
+
610
+ .stat-grid > :last-child { grid-column: 1 / -1; }
596
611
  }
597
612
 
598
613
  .stat {
@@ -602,10 +617,10 @@ const processColumns = computed(() => [
602
617
  .stat-label {
603
618
  margin: 0 0 6px;
604
619
  font-family: var(--font-mono);
605
- font-size: 10px;
620
+ font-size: 11.5px;
606
621
  letter-spacing: 0.14em;
607
622
  text-transform: uppercase;
608
- color: var(--ink-soft, rgba(120, 112, 96, 0.8));
623
+ color: var(--ink-soft);
609
624
  }
610
625
 
611
626
  .stat-value {
@@ -619,17 +634,20 @@ const processColumns = computed(() => [
619
634
  font-size: 17px;
620
635
  }
621
636
 
637
+ /* 实测:opacity 0.6 会把 11px 的说明文字压到 4.5:1 之下,
638
+ 改为直接使用 ink-faint(两套主题实测均 ≥5.4:1),不再靠透明度降级。 */
622
639
  .stat-updated {
623
640
  margin: 6px 0 0;
624
- font-size: 11px;
625
- opacity: 0.6;
641
+ font-size: 11.5px;
642
+ color: var(--ink-faint);
643
+ overflow-wrap: anywhere;
626
644
  }
627
645
 
628
646
  .orphan-badge {
629
647
  margin-left: 6px;
630
648
  padding: 1px 6px;
631
649
  font-family: var(--font-mono);
632
- font-size: 11px;
650
+ font-size: 11.5px;
633
651
  color: var(--tone-warning-dot);
634
652
  background: rgb(250 140 22 / 12%);
635
653
  border-radius: var(--radius-chip);
@@ -638,32 +656,58 @@ const processColumns = computed(() => [
638
656
  .agent-sub {
639
657
  display: block;
640
658
  margin-top: 2px;
641
- font-size: 10px;
659
+ font-size: 11.5px;
642
660
  color: var(--ink-faint);
643
661
  }
644
662
 
645
663
  .scope-tag {
646
664
  margin-left: 10px;
647
- font-size: 11px;
665
+ font-size: 11.5px;
648
666
  vertical-align: 3px;
649
667
  }
650
668
 
651
669
  /* 卡片右上角计数:tabular mono 数据(非眉题) */
652
670
  .count-extra {
653
- font-size: 11px;
671
+ font-size: 11.5px;
654
672
  color: var(--ink-faint);
655
673
  }
656
674
 
657
675
  .toggle-label {
658
- font-size: 12px;
676
+ font-size: 12.5px;
659
677
  color: var(--ink-soft);
660
678
  }
661
679
 
662
680
  .small {
663
- font-size: 12px;
681
+ font-size: 12.5px;
664
682
  }
665
683
 
666
684
  .aw-panel + .aw-panel {
667
685
  margin-top: 16px;
668
686
  }
687
+
688
+ /* ══ 窄屏(≤899px)═══════════════════════════════════════════════════════
689
+ 概要卡在 ≤640 已是单列(见上方 .stat-grid);这里只处理行内文字的收边:
690
+ 说明句长(时间 + 版本)在 375px 会顶到卡片右缘,允许它断行。 */
691
+ /* 空表占位行:antd 会给固定列单元格加 position: sticky,而 scroll.x=980
692
+ 让整行宽 980px —— 在 375px 视口里它就成了"视口外的固定元素"(实测
693
+ td.ant-table-cell 暂无数据 left=47 right=1027)。占位单元格没有固定列语义,
694
+ 取消 sticky 即可(有数据时固定列行为不变)。 */
695
+ .monitor :deep(.ant-table-placeholder > td) {
696
+ position: static !important;
697
+ }
698
+
699
+ @media (max-width: 899px) {
700
+ .stat-updated {
701
+ line-height: 1.5;
702
+ }
703
+
704
+ .head-right {
705
+ flex-wrap: wrap;
706
+ gap: 8px;
707
+ }
708
+
709
+ .toggle-label {
710
+ font-size: 13px;
711
+ }
712
+ }
669
713
  </style>
@@ -331,4 +331,38 @@ onMounted(load)
331
331
  .matrix .row { display: flex; align-items: center; justify-content: space-between; gap: 12px;
332
332
  padding: 8px 12px; border: 1px solid var(--aw-border, rgba(128, 152, 199, .25)); border-radius: 10px; }
333
333
  .line-name { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
334
+
335
+ /* ══ 窄屏(v9):页面收边 / 搜索框占满行 / 矩阵表横向卷轴 + 首列可读 ═══════ */
336
+ @media (max-width: 900px) {
337
+ .perm-page {
338
+ max-width: 100%;
339
+ padding: 16px 12px 40px;
340
+ }
341
+
342
+ .aw-page-head :deep(.ant-input-search) {
343
+ width: 100% !important;
344
+ max-width: 100% !important;
345
+ }
346
+
347
+ .perm-page :deep(.ant-table-content) table { min-width: 820px; }
348
+
349
+ .perm-page :deep(.ant-table-thead > tr > th:first-child),
350
+ .perm-page :deep(.ant-table-tbody > tr > td:first-child) { min-width: 120px; }
351
+
352
+ /* 抽屉里的授权矩阵:窄屏"线名 — 三态"必须上下堆叠,否则线名被压成竖排 */
353
+ .matrix .row {
354
+ flex-direction: column;
355
+ align-items: stretch;
356
+ gap: 6px;
357
+ }
358
+
359
+ .line-name { white-space: normal; }
360
+ .detail dd { overflow-wrap: anywhere; }
361
+ }
362
+
363
+ @media (max-width: 640px) {
364
+ .perm-page { padding: 12px 8px 40px; }
365
+ .pg-sub { font-size: 11.5px; line-height: 1.5; }
366
+ .hint { font-size: 11.5px; }
367
+ }
334
368
  </style>