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.
- package/.AgentWorkShop/prompts/host-tools.json +55 -0
- package/.output/.AgentWorkShop/prompts/host-tools.json +55 -0
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/88GOowgO2.js +1 -0
- package/.output/public/_nuxt/{BNT8gYU92.js → BC9wjTJK2.js} +2 -2
- package/.output/public/_nuxt/BOt2SP4z.js +1 -0
- package/.output/public/_nuxt/BP-NyKVG.js +18 -0
- package/.output/public/_nuxt/{HBLJ-wei.js → BXxH0UQE.js} +1 -1
- package/.output/public/_nuxt/{zIGh7R49.js → BneN7fbu.js} +1 -1
- package/.output/public/_nuxt/BsROmY89.js +1 -0
- package/.output/public/_nuxt/{C_OLzD09.js → C4oW1HsE.js} +1 -1
- package/.output/public/_nuxt/CFxtLwjp.js +1 -0
- package/.output/public/_nuxt/{Cec0Ua3F.js → CS50LB_l.js} +1 -1
- package/.output/public/_nuxt/C_iYD-EB.js +1 -0
- package/.output/public/_nuxt/{DAe0h2MB.js → ClILjvWH.js} +1 -1
- package/.output/public/_nuxt/CssgYAAL2.js +1 -0
- package/.output/public/_nuxt/{CY9LbPCI.js → CzOCSGLe.js} +1 -1
- package/.output/public/_nuxt/D8qvkfyY.js +1 -0
- package/.output/public/_nuxt/DCn7QZ5N.js +2 -0
- package/.output/public/_nuxt/DGIuvyRN2.js +1 -0
- package/.output/public/_nuxt/{CojCTLKD.js → DGj-WEBg.js} +1 -1
- package/.output/public/_nuxt/{DDShH71m.js → DS8qj8EL.js} +1 -1
- package/.output/public/_nuxt/DTFCy6h-.js +1 -0
- package/.output/public/_nuxt/{DrYV5i68.js → DUjW5Yq5.js} +1 -1
- package/.output/public/_nuxt/DZshyNLa.js +1 -0
- package/.output/public/_nuxt/{45zuyAso.js → D_OTvQza.js} +1 -1
- package/.output/public/_nuxt/DcsCcxp4.js +1 -0
- package/.output/public/_nuxt/{DUrecWPx.js → Dihnimlk.js} +2 -2
- package/.output/public/_nuxt/Dqw1lpr-.js +1 -0
- package/.output/public/_nuxt/{CUDwzgLV.js → Dr9v6C0f.js} +9 -9
- package/.output/public/_nuxt/{8NMOXZOV.js → Du9ZJtnj.js} +1 -1
- package/.output/public/_nuxt/TownView.f-YOdXRs.css +1 -0
- package/.output/public/_nuxt/_id_.CM4bIgKY.css +1 -0
- package/.output/public/_nuxt/_id_.bNV69Dtf.css +1 -0
- package/.output/public/_nuxt/_wsId_.B4WiqkIS.css +1 -0
- package/.output/public/_nuxt/agents.ZD0rVdHE.css +1 -0
- package/.output/public/_nuxt/aml.BN8ZEW4h.css +1 -0
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/f4707884-7cf4-4a31-80d2-e3d72b73745f.json +1 -0
- package/.output/public/_nuxt/channel-templates.BOtahzPi.css +1 -0
- package/.output/public/_nuxt/daq.B0D3dPAc.css +1 -0
- package/.output/public/_nuxt/dcw.8Y7FqCVN.css +1 -0
- package/.output/public/_nuxt/default.J32SgqFY.css +1 -0
- package/.output/public/_nuxt/entry.bdm0tv6M.css +1 -0
- package/.output/public/_nuxt/logs.BpKzmKsh.css +1 -0
- package/.output/public/_nuxt/monitor.D9pe7qN6.css +1 -0
- package/.output/public/_nuxt/pages.D7aSDlUI.css +1 -0
- package/.output/public/_nuxt/permissions.DwTVlFe6.css +1 -0
- package/.output/public/_nuxt/plugins.sb4nDGqr.css +1 -0
- package/.output/public/_nuxt/{Cbq-mryP.js → qr6R6Ha1.js} +1 -1
- package/.output/public/_nuxt/settings.BTgR-NiE.css +1 -0
- package/.output/public/_nuxt/teams.CxnxKVVs.css +1 -0
- package/.output/public/_nuxt/tokens.BFY7qv4f.css +1 -0
- package/.output/public/_nuxt/{town.DKIAhKnx.css → town.BBXZmeoP.css} +1 -1
- package/.output/public/_nuxt/users.DLgZ1D0h.css +1 -0
- package/.output/public/_nuxt/workshop.CR_QzeAN.css +1 -0
- package/.output/public/_nuxt/{BzHEilTt.js → xh3_vYcu.js} +1 -1
- package/.output/public/_nuxt/yF0aYMF1.js +4 -0
- package/.output/server/chunks/_/entity.mjs.map +1 -1
- package/.output/server/chunks/_/nitro.mjs +2225 -1445
- package/.output/server/chunks/_/nitro.mjs.map +1 -1
- package/.output/server/chunks/build/{TownView-jVazYOjN.mjs → TownView-BuLAsmpR.mjs} +288 -206
- package/.output/server/chunks/build/TownView-BuLAsmpR.mjs.map +1 -0
- package/.output/server/chunks/build/{_id_-CfVosNg3.mjs → _id_-BU1wfOID.mjs} +138 -138
- package/.output/server/chunks/build/{_id_-CfVosNg3.mjs.map → _id_-BU1wfOID.mjs.map} +1 -1
- package/.output/server/chunks/build/{_id_-Hwr4rZpr.mjs → _id_-BYsEua57.mjs} +33 -32
- package/.output/server/chunks/build/_id_-BYsEua57.mjs.map +1 -0
- package/.output/server/chunks/build/{_wsId_-BVg3bB77.mjs → _wsId_-BxlDcJHg.mjs} +293 -259
- package/.output/server/chunks/build/{_wsId_-BVg3bB77.mjs.map → _wsId_-BxlDcJHg.mjs.map} +1 -1
- package/.output/server/chunks/build/{agents-Bvin73QY.mjs → agents-CLQqJF2y.mjs} +21 -27
- package/.output/server/chunks/build/agents-CLQqJF2y.mjs.map +1 -0
- package/.output/server/chunks/build/{aml-BCSJCdX7.mjs → aml-_7FdFL2p.mjs} +109 -109
- package/.output/server/chunks/build/{aml-BCSJCdX7.mjs.map → aml-_7FdFL2p.mjs.map} +1 -1
- package/.output/server/chunks/build/api-error-dul30BYQ.mjs.map +1 -1
- package/.output/server/chunks/build/{channel-templates-BTq8570n.mjs → channel-templates-p6SZNjlM.mjs} +19 -19
- package/.output/server/chunks/build/{channel-templates-BTq8570n.mjs.map → channel-templates-p6SZNjlM.mjs.map} +1 -1
- package/.output/server/chunks/build/{daq-C03Uu5UE.mjs → daq-cgyjKmJu.mjs} +188 -122
- package/.output/server/chunks/build/daq-cgyjKmJu.mjs.map +1 -0
- package/.output/server/chunks/build/{dcw-6vEYVeje.mjs → dcw-CoTxBlAZ.mjs} +45 -45
- package/.output/server/chunks/build/{dcw-6vEYVeje.mjs.map → dcw-CoTxBlAZ.mjs.map} +1 -1
- package/.output/server/chunks/build/{default-CZmZFpqH.mjs → default-BE4r0FZN.mjs} +152 -58
- package/.output/server/chunks/build/{default-CZmZFpqH.mjs.map → default-BE4r0FZN.mjs.map} +1 -1
- package/.output/server/chunks/build/{logs-B-xhuqln.mjs → logs-BSOeZwwI.mjs} +34 -34
- package/.output/server/chunks/build/{logs-B-xhuqln.mjs.map → logs-BSOeZwwI.mjs.map} +1 -1
- package/.output/server/chunks/build/{monitor-CyfDt4nR.mjs → monitor-C0okQaXz.mjs} +33 -33
- package/.output/server/chunks/build/{monitor-CyfDt4nR.mjs.map → monitor-C0okQaXz.mjs.map} +1 -1
- package/.output/server/chunks/build/{pages-BO7yZsXA.mjs → pages-DFxjn9Xa.mjs} +33 -17
- package/.output/server/chunks/build/pages-DFxjn9Xa.mjs.map +1 -0
- package/.output/server/chunks/build/{permissions-B52oOmaO.mjs → permissions-68SsNjex.mjs} +12 -12
- package/.output/server/chunks/build/{permissions-B52oOmaO.mjs.map → permissions-68SsNjex.mjs.map} +1 -1
- package/.output/server/chunks/build/{plugins-CUWmMdyt.mjs → plugins-lGlUr1lj.mjs} +17 -17
- package/.output/server/chunks/build/{plugins-CUWmMdyt.mjs.map → plugins-lGlUr1lj.mjs.map} +1 -1
- package/.output/server/chunks/build/{settings-DoQ2Oq3P.mjs → settings-Ddd1qx2Z.mjs} +50 -47
- package/.output/server/chunks/build/settings-Ddd1qx2Z.mjs.map +1 -0
- package/.output/server/chunks/build/{teams-2kz3CusY.mjs → teams-MEDLZdMn.mjs} +38 -34
- package/.output/server/chunks/build/teams-MEDLZdMn.mjs.map +1 -0
- package/.output/server/chunks/build/{tokens-BbWLqtVz.mjs → tokens-C7fTM5C2.mjs} +14 -14
- package/.output/server/chunks/build/{tokens-BbWLqtVz.mjs.map → tokens-C7fTM5C2.mjs.map} +1 -1
- package/.output/server/chunks/build/{town-BOl6hs9B.mjs → town-qMPql9Se.mjs} +36 -10
- package/.output/server/chunks/build/town-qMPql9Se.mjs.map +1 -0
- package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs +1 -1
- package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs +1 -1
- package/.output/server/chunks/build/useResponsive-BKDMGTHs.mjs +49 -0
- package/.output/server/chunks/build/useResponsive-BKDMGTHs.mjs.map +1 -0
- package/.output/server/chunks/build/{users-fohSmF-J.mjs → users-Cfd5-l2-.mjs} +6 -6
- package/.output/server/chunks/build/{users-fohSmF-J.mjs.map → users-Cfd5-l2-.mjs.map} +1 -1
- package/.output/server/chunks/build/{workshop-DX5-ldc4.mjs → workshop-BL5bhfs0.mjs} +15 -15
- package/.output/server/chunks/build/{workshop-DX5-ldc4.mjs.map → workshop-BL5bhfs0.mjs.map} +1 -1
- package/.output/server/chunks/build/{workspaces-BuydxM-3.mjs → workspaces-Bgz5Ekwp.mjs} +18 -3
- package/.output/server/chunks/build/workspaces-Bgz5Ekwp.mjs.map +1 -0
- package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/index.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/settings/events.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +6 -2
- package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels.post.mjs +3 -3
- package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +3 -2
- package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +8 -6
- package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +5 -5
- package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +14 -4
- package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +4 -4
- package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +4 -3
- package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +31 -0
- package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +28 -0
- package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +32 -0
- package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +34 -0
- package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +33 -0
- package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +34 -0
- package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index6.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index9.get.mjs +3 -1
- package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
- package/.output/server/chunks/routes/renderer.mjs +3 -3
- package/.output/server/chunks/virtual/entry.mjs +51 -25
- package/.output/server/chunks/virtual/precomputed.mjs +1 -1
- package/.output/server/package.json +1 -1
- package/README-zh.md +199 -35
- package/README.md +739 -591
- package/app/app.vue +9 -3
- package/app/assets/css/main.css +517 -7
- package/app/components/AppHeader.vue +98 -7
- package/app/components/AppSidebar.vue +117 -11
- package/app/components/AwChart.vue +2 -1
- package/app/components/workshop/AgentInspectorDrawer.vue +6 -6
- package/app/components/workshop/AgentLanesView.vue +52 -1
- package/app/components/workshop/AssetLibrary.vue +4 -2
- package/app/components/workshop/ChannelSessionList.vue +4 -2
- package/app/components/workshop/Composer.vue +96 -0
- package/app/components/workshop/DaqNodeRow.vue +19 -0
- package/app/components/workshop/DaqTemplateIcon.vue +33 -0
- package/app/components/workshop/DeviceTwinPanel.vue +37 -35
- package/app/components/workshop/EventBlock.vue +3 -3
- package/app/components/workshop/InspectorPanel.vue +47 -11
- package/app/components/workshop/LiveAgentBar.vue +34 -0
- package/app/components/workshop/TaskBoardView.vue +83 -33
- package/app/components/workshop/TranscriptTimeline.vue +56 -0
- package/app/components/workshop/blocks/ClusterError.vue +1 -1
- package/app/components/workshop/blocks/ClusterRoute.vue +3 -1
- package/app/components/workshop/blocks/ClusterStatus.vue +2 -2
- package/app/components/workshop/blocks/ClusterStream.vue +8 -2
- package/app/components/workshop/town/ModelPreview3D.vue +1 -1
- package/app/components/workshop/town/TownView.vue +507 -82
- package/app/composables/useResponsive.ts +88 -0
- package/app/composables/useRouteMeta.ts +3 -0
- package/app/composables/workshop/useDcwStream.ts +1 -1
- package/app/composables/workshop/useVisibleInterval.ts +2 -2
- package/app/composables/workshop/useWorkshopApi.ts +1 -1
- package/app/layouts/default.vue +46 -2
- package/app/pages/aml/index.vue +712 -616
- package/app/pages/daq/[id].vue +3 -2
- package/app/pages/daq/index.vue +209 -9
- package/app/pages/dcw/[id].vue +109 -28
- package/app/pages/dcw/index.vue +83 -23
- package/app/pages/index.vue +35 -1
- package/app/pages/logs/index.vue +147 -13
- package/app/pages/monitor.vue +56 -12
- package/app/pages/permissions/index.vue +34 -0
- package/app/pages/plugins/index.vue +35 -4
- package/app/pages/settings.vue +90 -21
- package/app/pages/tokens.vue +23 -0
- package/app/pages/town.vue +50 -5
- package/app/pages/users.vue +23 -0
- package/app/pages/workshop/agents.vue +92 -2
- package/app/pages/workshop/channel-templates.vue +53 -0
- package/app/pages/workshop/index.vue +14 -0
- package/app/pages/workshop/teams.vue +66 -6
- package/app/pages/workshop/w/[wsId].vue +202 -14
- package/app/plugins/aw-plugins.client.ts +13 -8
- package/app/stores/app.ts +33 -1
- package/app/stores/workshop/user.ts +1 -1
- package/app/stores/workshop/workspaces.ts +18 -2
- package/app/utils/api-error.ts +1 -1
- package/cli/commands/build.mjs +8 -1
- package/docker-compose.yml +6 -0
- package/i18n/locales/en.ts +2 -0
- package/i18n/locales/zh-CN.ts +2 -0
- package/nuxt.config.ts +31 -0
- package/package.json +9 -1
- package/scripts/_dbg-param-map-e2e.ts +242 -0
- package/scripts/_dbg-param-map-rest-smoke.mjs +73 -0
- package/scripts/_dbg-param-real-scenario.mjs +153 -0
- package/scripts/api-live-e2e.mjs +40 -8
- package/scripts/capture-walkthrough.mjs +232 -0
- package/scripts/render-walkthrough-figure.mjs +46 -0
- package/scripts/seed-walkthrough-fixture.mjs +143 -0
- package/scripts/test-plugin-hardening.mjs +8 -0
- package/scripts/ui/admin-shots.mjs +46 -0
- package/scripts/ui/audit-layout.mjs +301 -0
- package/scripts/ui/bump-microfont.mjs +39 -0
- package/scripts/ui/lib.mjs +198 -0
- package/scripts/ui/linkcheck2.mjs +37 -0
- package/scripts/ui/live-render-check.mjs +72 -0
- package/scripts/ui/md-lint.mjs +80 -0
- package/scripts/ui/perf-audit.mjs +132 -0
- package/scripts/ui/readme-assets.mjs +30 -0
- package/scripts/ui/readme-shots.mjs +42 -0
- package/scripts/ui/record.mjs +225 -0
- package/scripts/ui/seed-admin.mjs +68 -0
- package/scripts/ui/seed-demo.mjs +83 -0
- package/scripts/ui/shot-hero.mjs +25 -0
- package/scripts/ui/shots.mjs +75 -0
- package/scripts/ui/sim-ui-shot.mjs +16 -0
- package/scripts/ui/verify-nav.mjs +51 -0
- package/scripts/ui/verify-responsive.mjs +285 -0
- package/server/api/system/config-groups/[id].patch.ts +1 -1
- package/server/api/system/config-groups/index.post.ts +1 -1
- package/server/api/system/settings/events.get.ts +1 -1
- package/server/api/system/settings/index.patch.ts +1 -1
- package/server/api/workshop/agent-tools/invoke.post.ts +16 -2
- package/server/api/workshop/aml/datasets/[id].get.ts +8 -1
- package/server/api/workshop/daq/infra/reconnect.post.ts +1 -1
- package/server/api/workshop/daq/templates/[key].delete.ts +1 -0
- package/server/api/workshop/daq/templates/[key].patch.ts +1 -0
- package/server/api/workshop/daq/templates/index.post.ts +1 -0
- package/server/api/workshop/dcw/[id]/write.post.ts +10 -2
- package/server/api/workshop/dcw/[id].delete.ts +5 -2
- package/server/api/workshop/dcw/index.get.ts +2 -0
- package/server/api/workshop/dcw/lines/[id].patch.ts +1 -1
- package/server/api/workshop/dcw/params/[id]/read.post.ts +17 -0
- package/server/api/workshop/dcw/params/[id]/write.post.ts +21 -0
- package/server/api/workshop/dcw/params/[id].delete.ts +19 -0
- package/server/api/workshop/dcw/params/[id].patch.ts +23 -0
- package/server/api/workshop/dcw/params/index.get.ts +27 -0
- package/server/api/workshop/dcw/params/index.post.ts +25 -0
- package/server/api/workshop/permissions/index.get.ts +3 -1
- package/server/plugins/aw-plugins.ts +14 -3
- package/server/plugins/dev-stability-guard.ts +3 -1
- package/server/plugins/system-config.ts +6 -1
- package/server/services/system-config.ts +28 -9
- package/server/services/workshop/agents/adapters/one-shot-cli-agent.ts +2 -1
- package/server/services/workshop/agents/agent-interface.ts +8 -6
- package/server/services/workshop/agents/base-agent.ts +18 -4
- package/server/services/workshop/agents/claude-agent.ts +7 -3
- package/server/services/workshop/agents/codex-agent.ts +3 -3
- package/server/services/workshop/agents/dsh-agent.ts +3 -3
- package/server/services/workshop/agents/goose-agent.ts +0 -1
- package/server/services/workshop/agents/harness-terminal.ts +14 -1
- package/server/services/workshop/agents/hermes-agent.ts +4 -2
- package/server/services/workshop/agents/host-tool-bridge.ts +5 -1
- package/server/services/workshop/agents/industrial-context.ts +4 -1
- package/server/services/workshop/agents/industrial-tools.ts +164 -6
- package/server/services/workshop/agents/omp-agent.ts +15 -9
- package/server/services/workshop/agents/opencode-agent.ts +47 -21
- package/server/services/workshop/agents/qwen-agent.ts +10 -5
- package/server/services/workshop/aml/entity.ts +3 -1
- package/server/services/workshop/aml/python-runtime.ts +3 -2
- package/server/services/workshop/daq/bus/mqtt.adapter.ts +8 -4
- package/server/services/workshop/daq/daq-controller.ts +18 -3
- package/server/services/workshop/daq/daq-runtime.ts +5 -3
- package/server/services/workshop/daq/drivers.ts +63 -8
- package/server/services/workshop/daq/host-ports.ts +3 -2
- package/server/services/workshop/daq/storage/timescale.adapter.ts +3 -1
- package/server/services/workshop/db/channel.repo.ts +4 -0
- package/server/services/workshop/db/ops.repo.ts +5 -2
- package/server/services/workshop/db/retention.ts +8 -3
- package/server/services/workshop/dcw/dcw-controller.ts +143 -16
- package/server/services/workshop/dcw/dcw-product.repo.ts +38 -1
- package/server/services/workshop/dcw/dcw-runtime.ts +3 -2
- package/server/services/workshop/dcw/drivers.ts +5 -2
- package/server/services/workshop/dcw/param-conversion.ts +78 -0
- package/server/services/workshop/dcw/param-limits.ts +142 -0
- package/server/services/workshop/dcw/param-map.repo.ts +305 -0
- package/server/services/workshop/dcw/recipe-rollback-manager.ts +13 -7
- package/server/services/workshop/runtime/agent-runtime.ts +4 -0
- package/server/services/workshop/runtime/manager.ts +9 -2
- package/server/services/workshop/settings.ts +4 -2
- package/server/types/pg.d.ts +49 -0
- package/server/utils/stability-severity.ts +13 -2
- package/shared/config/groups.mjs +22 -1
- package/shared/config/home.d.mts +28 -0
- package/shared/dcw-protocol.ts +136 -0
- package/uno.config.ts +12 -1
- package/.output/public/_nuxt/BFkgkW8u.js +0 -4
- package/.output/public/_nuxt/C5gUkRwn.js +0 -1
- package/.output/public/_nuxt/CM12FuB42.js +0 -1
- package/.output/public/_nuxt/CZiw7sEV.js +0 -1
- package/.output/public/_nuxt/Cc_9VzD42.js +0 -1
- package/.output/public/_nuxt/CdPzkOMV.js +0 -1
- package/.output/public/_nuxt/CmsOtOAA2.js +0 -1
- package/.output/public/_nuxt/D1YDxZpZ.js +0 -1
- package/.output/public/_nuxt/D20Yamr4.js +0 -1
- package/.output/public/_nuxt/DmqknNvV.js +0 -18
- package/.output/public/_nuxt/DnUuIR83.js +0 -1
- package/.output/public/_nuxt/S_fVQwJK.js +0 -1
- package/.output/public/_nuxt/TownView.0oLiQgTC.css +0 -1
- package/.output/public/_nuxt/_id_.D-SYuyZb.css +0 -1
- package/.output/public/_nuxt/_id_.hma_BU6T.css +0 -1
- package/.output/public/_nuxt/_wsId_.B12v3PhY.css +0 -1
- package/.output/public/_nuxt/agents.BV70ioCv.css +0 -1
- package/.output/public/_nuxt/ahgEJu2R.js +0 -1
- package/.output/public/_nuxt/aml.COEKNNqK.css +0 -1
- package/.output/public/_nuxt/builds/meta/4457d63f-0866-4cea-b320-04a321f24795.json +0 -1
- package/.output/public/_nuxt/channel-templates.C-M5nKcC.css +0 -1
- package/.output/public/_nuxt/daq.B3265ZDn.css +0 -1
- package/.output/public/_nuxt/dcw.DLYZqEhT.css +0 -1
- package/.output/public/_nuxt/default.BXI_fZUi.css +0 -1
- package/.output/public/_nuxt/entry.BB-Eeh-J.css +0 -1
- package/.output/public/_nuxt/logs.CqFyMrJw.css +0 -1
- package/.output/public/_nuxt/monitor.B--1dPzs.css +0 -1
- package/.output/public/_nuxt/pages.ooEzrMm9.css +0 -1
- package/.output/public/_nuxt/permissions.B1pjGChZ.css +0 -1
- package/.output/public/_nuxt/plugins.5e5chZ67.css +0 -1
- package/.output/public/_nuxt/pz2JDAM7.js +0 -2
- package/.output/public/_nuxt/settings.Dm3M0RLy.css +0 -1
- package/.output/public/_nuxt/teams.BC75EGnR.css +0 -1
- package/.output/public/_nuxt/tokens.xRb1fSPU.css +0 -1
- package/.output/public/_nuxt/users.CXnP2E08.css +0 -1
- package/.output/public/_nuxt/workshop.Jk5HxWPE.css +0 -1
- package/.output/server/chunks/build/TownView-jVazYOjN.mjs.map +0 -1
- package/.output/server/chunks/build/_id_-Hwr4rZpr.mjs.map +0 -1
- package/.output/server/chunks/build/agents-Bvin73QY.mjs.map +0 -1
- package/.output/server/chunks/build/daq-C03Uu5UE.mjs.map +0 -1
- package/.output/server/chunks/build/pages-BO7yZsXA.mjs.map +0 -1
- package/.output/server/chunks/build/settings-DoQ2Oq3P.mjs.map +0 -1
- package/.output/server/chunks/build/teams-2kz3CusY.mjs.map +0 -1
- package/.output/server/chunks/build/town-BOl6hs9B.mjs.map +0 -1
- package/.output/server/chunks/build/workspaces-BuydxM-3.mjs.map +0 -1
- /package/.output/public/_nuxt/{36oeS8_R2.js → 36oeS8_R.js} +0 -0
- /package/.output/public/_nuxt/{CYWVXZTS.js → CYWVXZTS2.js} +0 -0
|
@@ -50,9 +50,9 @@ const loadHarnessAvail = async (): Promise<void> => {
|
|
|
50
50
|
}
|
|
51
51
|
if (import.meta.client) void loadHarnessAvail()
|
|
52
52
|
const tplUnavailable = (tpl: AgentTemplateDto): boolean => harnessAvail.value[tpl.harness] === false
|
|
53
|
-
const memberOptions = computed(() => templates.value.map((
|
|
54
|
-
const un = tplUnavailable(
|
|
55
|
-
return { value:
|
|
53
|
+
const memberOptions = computed(() => templates.value.map((tpl) => {
|
|
54
|
+
const un = tplUnavailable(tpl)
|
|
55
|
+
return { value: tpl.id, label: un ? `${tpl.name}(${tpl.harness} · ${t('agents.notInstalled')})` : `${tpl.name}(${tpl.harness})`, disabled: un }
|
|
56
56
|
}))
|
|
57
57
|
|
|
58
58
|
// ===== 过滤 =====
|
|
@@ -312,12 +312,12 @@ useHead({ title: () => t('titles.teams') })
|
|
|
312
312
|
:class="visTag(team).icon"
|
|
313
313
|
/>{{ visTag(team).text }}
|
|
314
314
|
</a-tag>
|
|
315
|
+
<!-- 开关不带文字:左边那枚 tag 已经在说"公开/私有"了(与模板库同一条规则) -->
|
|
315
316
|
<a-switch
|
|
316
317
|
v-if="!team.isBuiltin && canWrite(team)"
|
|
317
318
|
:checked="team.visibility === 'public'"
|
|
318
319
|
size="small"
|
|
319
|
-
|
|
320
|
-
un-checked-children="私有"
|
|
320
|
+
:title="team.visibility === 'public' ? '点击转为私有' : '点击公开(全员可部署)'"
|
|
321
321
|
@change="(v: unknown) => toggleVisibility(team, v === true)"
|
|
322
322
|
/>
|
|
323
323
|
<span class="owner">{{ team.ownerName ?? '-' }}</span>
|
|
@@ -340,10 +340,13 @@ useHead({ title: () => t('titles.teams') })
|
|
|
340
340
|
</a-menu>
|
|
341
341
|
</template>
|
|
342
342
|
</a-dropdown>
|
|
343
|
+
<!-- 用 outlined 而不是 text:text 按钮在卡片头上与旁边的 owner 文本
|
|
344
|
+
长得一模一样,用户看不出这里是**唯一的主操作**(实测三张卡片都如此)。 -->
|
|
343
345
|
<a-button
|
|
344
346
|
v-else
|
|
347
|
+
class="deploy-btn"
|
|
345
348
|
size="small"
|
|
346
|
-
type="
|
|
349
|
+
type="default"
|
|
347
350
|
:title="$t('teams.kxheuf1001')"
|
|
348
351
|
@click="openDeploy(team)"
|
|
349
352
|
>
|
|
@@ -591,6 +594,12 @@ h2 { margin: 0 0 4px; }
|
|
|
591
594
|
font-size: 11px;
|
|
592
595
|
color: var(--ink-faint);
|
|
593
596
|
}
|
|
597
|
+
.deploy-btn {
|
|
598
|
+
flex: none;
|
|
599
|
+
font-size: 11.5px;
|
|
600
|
+
border-color: var(--line-strong);
|
|
601
|
+
}
|
|
602
|
+
|
|
594
603
|
.op { cursor: pointer; opacity: 0.4; }
|
|
595
604
|
.op:hover { opacity: 1; }
|
|
596
605
|
.members {
|
|
@@ -677,4 +686,55 @@ h2 { margin: 0 0 4px; }
|
|
|
677
686
|
line-height: 1.5;
|
|
678
687
|
color: var(--ink-faint);
|
|
679
688
|
}
|
|
689
|
+
|
|
690
|
+
/* ══ 窄屏(v9):页头纵向堆叠 / 筛选条换行 / 卡片单列 ══════════════════════ */
|
|
691
|
+
@media (max-width: 900px) {
|
|
692
|
+
.head {
|
|
693
|
+
flex-direction: column;
|
|
694
|
+
align-items: stretch;
|
|
695
|
+
gap: 12px;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.head > div { min-width: 0; }
|
|
699
|
+
.head h2 { font-size: 21px; line-height: 1.25; }
|
|
700
|
+
|
|
701
|
+
.head :deep(.ant-space) {
|
|
702
|
+
display: flex;
|
|
703
|
+
flex-direction: column;
|
|
704
|
+
gap: 8px;
|
|
705
|
+
align-items: stretch;
|
|
706
|
+
width: 100%;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
.head :deep(.ant-space-item) { width: 100%; }
|
|
710
|
+
.head :deep(.ant-btn) { width: 100%; min-height: 40px; }
|
|
711
|
+
|
|
712
|
+
.toolbar {
|
|
713
|
+
flex-wrap: wrap;
|
|
714
|
+
gap: 8px;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
.toolbar :deep(.ant-segmented) {
|
|
718
|
+
flex: 1 1 100%;
|
|
719
|
+
min-width: 0;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
.admin-note {
|
|
723
|
+
flex: 1 1 100%;
|
|
724
|
+
min-width: 0;
|
|
725
|
+
font-size: 11.5px;
|
|
726
|
+
line-height: 1.5;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
.grid { grid-template-columns: 1fr; }
|
|
730
|
+
.card-head { flex-wrap: wrap; }
|
|
731
|
+
.member { flex-wrap: wrap; }
|
|
732
|
+
.member-harness { font-size: 11.5px; }
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
@media (max-width: 640px) {
|
|
736
|
+
.page { padding: 0; }
|
|
737
|
+
.head h2 { font-size: 19px; }
|
|
738
|
+
.sub { font-size: 11.5px; line-height: 1.5; }
|
|
739
|
+
}
|
|
680
740
|
</style>
|
|
@@ -11,6 +11,7 @@ import { useEntitiesStore } from '../../../stores/workshop/entities'
|
|
|
11
11
|
import { useWorkshopWs } from '../../../composables/workshop/useWorkshopWs'
|
|
12
12
|
import { useUserStore } from '../../../stores/workshop/user'
|
|
13
13
|
import { useStorage } from '@vueuse/core'
|
|
14
|
+
import { useResponsive } from '../../../composables/useResponsive'
|
|
14
15
|
|
|
15
16
|
const { t } = useI18n()
|
|
16
17
|
|
|
@@ -36,6 +37,10 @@ onMounted(() => {
|
|
|
36
37
|
const entities = useEntitiesStore()
|
|
37
38
|
const { subscribe, unsubscribe, conn } = useWorkshopWs()
|
|
38
39
|
|
|
40
|
+
// 视口档位(唯一判据;SSR 期返回桌面档)——
|
|
41
|
+
// 窄屏(≤1023)三栏仪表台只剩 ~460px 画布,必须换成「单通道示波器」形态
|
|
42
|
+
const { isDesktop } = useResponsive()
|
|
43
|
+
|
|
39
44
|
const workspace = computed(() => wsStore.workspaces.find(w => w.id === wsId.value))
|
|
40
45
|
// 聚焦 channel:activeChannelId 须在挂载清单内(陈旧持久化/竞态下回退首频道),
|
|
41
46
|
// 避免订阅死频道 → 快照永不到达 → 右栏/时间线长时间"空数据"假象
|
|
@@ -77,7 +82,8 @@ const lastSeq = computed(() => (channelId.value ? conn.cursors[channelId.value]
|
|
|
77
82
|
|
|
78
83
|
// 视图切换(P1 三视图 + P2 多通道同屏 + P5 RPG 小镇)
|
|
79
84
|
// 深链:?view=lanes/board/split/town 直达指定视图(可分享/收藏)
|
|
80
|
-
|
|
85
|
+
// inspector 只在窄屏出现(桌面它是右侧常驻栏),故不进深链白名单
|
|
86
|
+
type CenterView = 'timeline' | 'lanes' | 'board' | 'split' | 'town' | 'inspector'
|
|
81
87
|
const VIEW_KEYS: Record<string, CenterView> = {
|
|
82
88
|
1: 'timeline',
|
|
83
89
|
2: 'lanes',
|
|
@@ -90,15 +96,24 @@ const initView = route.query.view
|
|
|
90
96
|
const view = ref<CenterView>(
|
|
91
97
|
typeof initView === 'string' && VIEW_VALUES.has(initView) ? initView as CenterView : 'timeline',
|
|
92
98
|
)
|
|
93
|
-
const viewOptions =
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
const viewOptions = computed(() => {
|
|
100
|
+
const base = [
|
|
101
|
+
{ value: 'timeline', label: t('wsView.k3otu32010') },
|
|
102
|
+
{ value: 'lanes', label: 'Agent lanes' },
|
|
103
|
+
{ value: 'board', label: t('wsView.k3ko7a8011') },
|
|
104
|
+
{ value: 'split', label: t('wsView.k3xbmo012') },
|
|
105
|
+
{ value: 'town', label: t('wsView.k1cz0pbw013') },
|
|
106
|
+
]
|
|
107
|
+
// 窄屏「一次一区」:检查器不占侧栏,并入切换条(四区都由同一条承载)
|
|
108
|
+
return narrowUI.value ? [...base, { value: 'inspector', label: '检查器' }] : base
|
|
109
|
+
})
|
|
100
110
|
// 数字快捷键 1-5 直切视图(非输入焦点时;控制台型键盘操作与 ⌘K 面板同一取向)
|
|
101
111
|
const onViewKey = (ev: KeyboardEvent): void => {
|
|
112
|
+
// 窄屏抽屉:Esc 收起(与全站侧栏抽屉一致)
|
|
113
|
+
if (ev.key === 'Escape' && narrowUI.value && leftOpen.value) {
|
|
114
|
+
leftOpen.value = false
|
|
115
|
+
return
|
|
116
|
+
}
|
|
102
117
|
if (ev.metaKey || ev.ctrlKey || ev.altKey) return
|
|
103
118
|
const t = ev.target as HTMLElement | null
|
|
104
119
|
if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.isContentEditable)) return
|
|
@@ -111,8 +126,31 @@ onMounted(() => window.addEventListener('keydown', onViewKey))
|
|
|
111
126
|
onBeforeUnmount(() => window.removeEventListener('keydown', onViewKey))
|
|
112
127
|
|
|
113
128
|
// 侧栏折叠(现代 harness 布局:左会话栏 / 右检查器可按需收起)
|
|
129
|
+
// 形态差异只在挂载后生效:SSR/首帧一律按桌面结构渲染,客户端接管后才翻档,
|
|
130
|
+
// 否则服务端 5 项切换条 vs 客户端 6 项会触发水合告警
|
|
131
|
+
const mounted = ref(false)
|
|
132
|
+
onMounted(() => {
|
|
133
|
+
mounted.value = true
|
|
134
|
+
})
|
|
135
|
+
const narrowUI = computed(() => mounted.value && !isDesktop.value)
|
|
136
|
+
|
|
114
137
|
const leftOpen = ref(true)
|
|
115
138
|
const rightOpen = ref(true)
|
|
139
|
+
/** 窄屏:左右侧栏都不再占位(收成覆盖式抽屉 / 并入切换条) */
|
|
140
|
+
const applyTier = (desktop: boolean): void => {
|
|
141
|
+
leftOpen.value = desktop
|
|
142
|
+
rightOpen.value = desktop
|
|
143
|
+
// 检查器只是窄屏的第 4 区:回桌面后它回到右栏,中部得有自己的区(否则中部空白)
|
|
144
|
+
if (desktop && view.value === 'inspector') view.value = 'timeline'
|
|
145
|
+
}
|
|
146
|
+
onMounted(() => {
|
|
147
|
+
if (!isDesktop.value) applyTier(false)
|
|
148
|
+
})
|
|
149
|
+
watch(isDesktop, d => applyTier(d))
|
|
150
|
+
// 抽屉里选中频道后自动收起(窄屏少一次手动关闭)
|
|
151
|
+
watch(channelId, (next, prev) => {
|
|
152
|
+
if (prev !== undefined && next !== prev && narrowUI.value) leftOpen.value = false
|
|
153
|
+
})
|
|
116
154
|
|
|
117
155
|
// 侧栏宽度拖拽调节(PaneSplitter;localStorage 持久化,双击复位到默认值)
|
|
118
156
|
const LEFT_W_DEFAULT = 248
|
|
@@ -192,8 +230,18 @@ useHead({ title: () => `${workspace.value?.name ?? 'Workspace'} · AgentWorkShop
|
|
|
192
230
|
/>
|
|
193
231
|
</div>
|
|
194
232
|
<div class="right">
|
|
233
|
+
<!-- 窄屏:频道会话列表入口(覆盖式抽屉;该页一次只看一区) -->
|
|
195
234
|
<button
|
|
196
|
-
|
|
235
|
+
v-if="narrowUI"
|
|
236
|
+
class="pane-toggle im toggle-left-narrow"
|
|
237
|
+
:class="{ off: !leftOpen }"
|
|
238
|
+
title="频道会话列表"
|
|
239
|
+
@click="leftOpen = !leftOpen"
|
|
240
|
+
>
|
|
241
|
+
<span class="i-tabler-list-details im-pop" />
|
|
242
|
+
</button>
|
|
243
|
+
<button
|
|
244
|
+
class="pane-toggle im toggle-left-desk"
|
|
197
245
|
:class="{ off: !leftOpen }"
|
|
198
246
|
:title="$t('wsView.k1tsy2e4002')"
|
|
199
247
|
@click="leftOpen = !leftOpen"
|
|
@@ -201,7 +249,7 @@ useHead({ title: () => `${workspace.value?.name ?? 'Workspace'} · AgentWorkShop
|
|
|
201
249
|
<span class="i-tabler-layout-sidebar-left-collapse im-pop" />
|
|
202
250
|
</button>
|
|
203
251
|
<button
|
|
204
|
-
class="pane-toggle im"
|
|
252
|
+
class="pane-toggle im toggle-right-desk"
|
|
205
253
|
:class="{ off: !rightOpen }"
|
|
206
254
|
:title="$t('wsView.k1tx0ppf003')"
|
|
207
255
|
@click="rightOpen = !rightOpen"
|
|
@@ -236,10 +284,16 @@ useHead({ title: () => `${workspace.value?.name ?? 'Workspace'} · AgentWorkShop
|
|
|
236
284
|
|
|
237
285
|
<!-- 主体三栏(左/右侧栏可折叠 + 拖拽调宽;分隔条 hairline 即面板边界) -->
|
|
238
286
|
<div class="main">
|
|
287
|
+
<!-- 窄屏抽屉遮罩:点空白收起(不盖住底部 Composer,输入不被"锁在"抽屉后) -->
|
|
288
|
+
<div
|
|
289
|
+
v-if="narrowUI && leftOpen"
|
|
290
|
+
class="drawer-scrim"
|
|
291
|
+
@click="leftOpen = false"
|
|
292
|
+
/>
|
|
239
293
|
<div
|
|
240
294
|
v-if="leftOpen"
|
|
241
295
|
class="left-pane"
|
|
242
|
-
:style="{ flexBasis: `${leftWidth}px` }"
|
|
296
|
+
:style="{ flexBasis: narrowUI ? 'auto' : `${leftWidth}px` }"
|
|
243
297
|
>
|
|
244
298
|
<div class="left-scroll">
|
|
245
299
|
<workshop-channel-session-list :ws-id="wsId" />
|
|
@@ -250,7 +304,7 @@ useHead({ title: () => `${workspace.value?.name ?? 'Workspace'} · AgentWorkShop
|
|
|
250
304
|
/>
|
|
251
305
|
</div>
|
|
252
306
|
<workshop-pane-splitter
|
|
253
|
-
v-if="leftOpen"
|
|
307
|
+
v-if="leftOpen && !narrowUI"
|
|
254
308
|
:label="$t('wsView.k1fkfvra005')"
|
|
255
309
|
@resize="resizeLeft"
|
|
256
310
|
@reset="leftWidth = LEFT_W_DEFAULT"
|
|
@@ -279,6 +333,13 @@ useHead({ title: () => `${workspace.value?.name ?? 'Workspace'} · AgentWorkShop
|
|
|
279
333
|
v-else-if="view === 'town'"
|
|
280
334
|
:channel-id="channelId"
|
|
281
335
|
/>
|
|
336
|
+
<!-- 窄屏第 4 区:检查器并入切换条(桌面仍是右侧常驻栏) -->
|
|
337
|
+
<workshop-inspector-panel
|
|
338
|
+
v-else-if="view === 'inspector' && narrowUI"
|
|
339
|
+
:channel-id="channelId"
|
|
340
|
+
@open-agent="openAgent"
|
|
341
|
+
@open-task="openTask"
|
|
342
|
+
/>
|
|
282
343
|
</template>
|
|
283
344
|
<div
|
|
284
345
|
v-else
|
|
@@ -294,13 +355,13 @@ useHead({ title: () => `${workspace.value?.name ?? 'Workspace'} · AgentWorkShop
|
|
|
294
355
|
</div>
|
|
295
356
|
</div>
|
|
296
357
|
<workshop-pane-splitter
|
|
297
|
-
v-if="rightOpen"
|
|
358
|
+
v-if="rightOpen && !narrowUI"
|
|
298
359
|
:label="$t('wsView.kwqb0st006')"
|
|
299
360
|
@resize="resizeRight"
|
|
300
361
|
@reset="rightWidth = RIGHT_W_DEFAULT"
|
|
301
362
|
/>
|
|
302
363
|
<div
|
|
303
|
-
v-if="rightOpen"
|
|
364
|
+
v-if="rightOpen && !narrowUI"
|
|
304
365
|
class="right-pane"
|
|
305
366
|
:class="{ empty: wsStore.loaded && !channelId }"
|
|
306
367
|
:style="{ flexBasis: `${rightWidth}px` }"
|
|
@@ -513,4 +574,131 @@ useHead({ title: () => `${workspace.value?.name ?? 'Workspace'} · AgentWorkShop
|
|
|
513
574
|
color: var(--ink-faint);
|
|
514
575
|
}
|
|
515
576
|
.composer-pane { flex: 0 0 auto; }
|
|
577
|
+
|
|
578
|
+
/* ══════════════════════════════════════════════════════════════════════════
|
|
579
|
+
窄屏形态 · 单通道示波器(≤1023px) —— 一次只看一路信号
|
|
580
|
+
──────────────────────────────────────────────────────────────────────────
|
|
581
|
+
桌面是「三栏仪表台」:会话栏 248 + 画布 + 检查器 300 + 两条分隔条。
|
|
582
|
+
到了 ≤1023,画布只剩 ~460px(900–1023 还要再让 64px 图标轨),
|
|
583
|
+
硬塞的结果是三栏互相压扁。所以窄屏换一台仪器,而不是把仪表台缩小:
|
|
584
|
+
|
|
585
|
+
· 中部视图(时间线 / lanes / 任务板 / 检查器)→ 由顶栏切换条承载,
|
|
586
|
+
一次只挂载一区,顶部切换条独占一行、可横扫;
|
|
587
|
+
· 频道会话列表 → 覆盖式抽屉(点遮罩/Esc/选中频道收起),不再占位;
|
|
588
|
+
· 拖拽分隔条在窄屏没有意义(没有第二栏可分配宽度)→ 隐藏;
|
|
589
|
+
· 触摸目标 ≥40px、标签 ≥11.5px(手持 30cm 距离下 10px 只剩 6px 有效字号)。
|
|
590
|
+
|
|
591
|
+
⚠️ 断点数值与 main.css v5 / useResponsive.ts 一致(1024 = 三栏仪表台下限),
|
|
592
|
+
此处不再引入新魔数。桌面(≥1024)样式完全不受影响。
|
|
593
|
+
══════════════════════════════════════════════════════════════════════════ */
|
|
594
|
+
@media (max-width: 1023.98px) {
|
|
595
|
+
.harness {
|
|
596
|
+
/* 窄屏收掉壳体外留白,把纵向像素让给内容与底部 Composer */
|
|
597
|
+
height: calc(100dvh - var(--app-header-h, 56px) - var(--app-footer-h, 46px) - 8px);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
.topbar {
|
|
601
|
+
flex-wrap: wrap;
|
|
602
|
+
gap: 6px 8px;
|
|
603
|
+
padding: 8px 10px;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.topbar .left {
|
|
607
|
+
row-gap: 8px;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
.ws-name {
|
|
611
|
+
max-width: 40vw;
|
|
612
|
+
font-size: 15px;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
.chan-chip {
|
|
616
|
+
max-width: 34vw;
|
|
617
|
+
font-size: 12px;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/* 切换条独占一行:五个视图名不再挤掉工作区名(channel 名仍可见) */
|
|
621
|
+
.view-switch {
|
|
622
|
+
flex: 1 1 100%;
|
|
623
|
+
margin-left: 0;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
.ws-state,
|
|
627
|
+
.seq {
|
|
628
|
+
font-size: 11.5px;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/* 触摸目标:26px 的幽灵图标钮在手持设备上点不中 */
|
|
632
|
+
.pane-toggle {
|
|
633
|
+
width: 40px;
|
|
634
|
+
height: 40px;
|
|
635
|
+
font-size: 18px;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
.toggle-left-desk,
|
|
639
|
+
.toggle-right-desk {
|
|
640
|
+
display: none;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
.main {
|
|
644
|
+
position: relative;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
.left-pane {
|
|
648
|
+
position: absolute;
|
|
649
|
+
top: 0;
|
|
650
|
+
bottom: 0;
|
|
651
|
+
left: 0;
|
|
652
|
+
z-index: 30;
|
|
653
|
+
width: min(86vw, 320px);
|
|
654
|
+
border-right: 1px solid var(--line);
|
|
655
|
+
box-shadow: var(--shadow-float);
|
|
656
|
+
animation: pane-in 0.18s cubic-bezier(0.22, 1, 0.36, 1);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
.drawer-scrim {
|
|
660
|
+
position: absolute;
|
|
661
|
+
inset: 0;
|
|
662
|
+
z-index: 25;
|
|
663
|
+
background: color-mix(in srgb, var(--ink) 34%, transparent);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/* 窄屏没有第二栏可分宽度,拖拽条只会白占 9px */
|
|
667
|
+
.pane-splitter {
|
|
668
|
+
display: none;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
.pane-loading {
|
|
672
|
+
font-size: 13px;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/* 窄屏专属入口在桌面不出现(响应式形态差异不用 JS 表达,避免水合抖动) */
|
|
677
|
+
.toggle-left-narrow {
|
|
678
|
+
display: none;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
@media (max-width: 1023.98px) {
|
|
682
|
+
.toggle-left-narrow {
|
|
683
|
+
display: inline-flex;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
@media (prefers-reduced-motion: reduce) {
|
|
688
|
+
.left-pane {
|
|
689
|
+
animation: none;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
@keyframes pane-in {
|
|
694
|
+
from {
|
|
695
|
+
opacity: 0.5;
|
|
696
|
+
transform: translateX(-16px);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
to {
|
|
700
|
+
opacity: 1;
|
|
701
|
+
transform: none;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
516
704
|
</style>
|
|
@@ -13,10 +13,12 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { watch } from 'vue'
|
|
15
15
|
import { createClientContext, type ClientContext } from '@/sdk/client.mjs'
|
|
16
|
-
import { usePluginPanels } from '@/app/composables/workshop/usePluginPanels'
|
|
17
|
-
import type
|
|
16
|
+
import { usePluginPanels, type PluginPanelEntry } from '@/app/composables/workshop/usePluginPanels'
|
|
17
|
+
import { useTownBus, type TownBus } from '~/composables/workshop/useTownBus'
|
|
18
18
|
|
|
19
19
|
interface ManifestEntry { name: string, enabled?: boolean, hasClient?: boolean }
|
|
20
|
+
/** vue-i18n 实例在 NuxtApp 上的最小面(只用到 mergeLocaleMessage + locale,故按鸭子类型声明确切形状) */
|
|
21
|
+
interface I18nLike { mergeLocaleMessage?: (locale: string, messages: Record<string, unknown>) => void, locale?: unknown }
|
|
20
22
|
interface I18nBundle { i18n?: Record<string, Record<string, Record<string, string>>> }
|
|
21
23
|
|
|
22
24
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
@@ -26,8 +28,8 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
26
28
|
const loaded = new Map<string, ClientContext>()
|
|
27
29
|
const { unregisterPlugin } = usePluginPanels()
|
|
28
30
|
const panels = usePluginPanels()
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
// NuxtApp.$i18n 的库类型与本文件用到的两个成员结构不同(mergeLocaleMessage 的参数更宽),故在边界处收敛成 I18nLike
|
|
32
|
+
const i18n = ((nuxtApp.$i18n ?? null) as unknown) as I18nLike | null
|
|
31
33
|
let bus: TownBus | null = null
|
|
32
34
|
try {
|
|
33
35
|
bus = useTownBus()
|
|
@@ -102,10 +104,13 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
102
104
|
}
|
|
103
105
|
const ctx = createClientContext({
|
|
104
106
|
name,
|
|
105
|
-
eventBridge: bridgeFactory
|
|
107
|
+
eventBridge: bridgeFactory,
|
|
106
108
|
ui: {
|
|
107
109
|
slots: ['plugins.page', 'settings.plugins', 'dashboard.widgets'],
|
|
108
|
-
|
|
110
|
+
// SDK 的 ClientPanelEntry.mount 声明为 void,宿主 PluginPanelEntry 则允许返回清理函数
|
|
111
|
+
// (宿主编排器按返回值回收面板)。这里只在边界处断言 mount 形状,entry 原样透传、不包一层:
|
|
112
|
+
// 插件真返回清理函数时仍会被回收,返回 void 时同样合法。
|
|
113
|
+
registerPanel: entry => panels.registerPanel({ ...entry, plugin: name, mount: entry.mount as PluginPanelEntry['mount'] }),
|
|
109
114
|
},
|
|
110
115
|
t: translatorFor(name),
|
|
111
116
|
getLocale: () => {
|
|
@@ -168,7 +173,7 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
168
173
|
const localeRef = i18n?.locale as { value?: string } | undefined
|
|
169
174
|
if (localeRef && typeof localeRef === 'object') {
|
|
170
175
|
watch(localeRef, (loc) => {
|
|
171
|
-
for (const
|
|
176
|
+
for (const ctx of loaded.values()) {
|
|
172
177
|
try {
|
|
173
178
|
ctx?.hooks?.emit('i18n:changed', { locale: loc })
|
|
174
179
|
}
|
|
@@ -185,7 +190,7 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
185
190
|
path = useRoute().path ?? ''
|
|
186
191
|
}
|
|
187
192
|
catch { /* 路由上下文不可用时静默 */ }
|
|
188
|
-
for (const
|
|
193
|
+
for (const ctx of loaded.values()) {
|
|
189
194
|
try {
|
|
190
195
|
ctx?.hooks?.emit('page:change', { path })
|
|
191
196
|
}
|
package/app/stores/app.ts
CHANGED
|
@@ -5,6 +5,8 @@ export const useAppStore = defineStore('app', () => {
|
|
|
5
5
|
// 默认暗色 = Digital Twin 控制室是产品首态(可切换亮色,选择被持久化)
|
|
6
6
|
const isDark = ref(true)
|
|
7
7
|
const sidebarCollapsed = ref(false)
|
|
8
|
+
/** 窄屏抽屉导航是否展开(不持久化:每次进入页面都应关闭) */
|
|
9
|
+
const mobileNavOpen = ref(false)
|
|
8
10
|
/**
|
|
9
11
|
* 用户是否在设置页/页头显式切换过明暗。
|
|
10
12
|
* 只有"显式选择"才锁死主题,阻止服务端 theme.mode 的运行时跟随——
|
|
@@ -26,11 +28,41 @@ export const useAppStore = defineStore('app', () => {
|
|
|
26
28
|
sidebarCollapsed.value = !sidebarCollapsed.value
|
|
27
29
|
}
|
|
28
30
|
|
|
31
|
+
/**
|
|
32
|
+
* 抽屉式导航(窄屏,<900px)。与 sidebarCollapsed 分开的原因:
|
|
33
|
+
* 折叠是**桌面用户的持久偏好**(图标轨),抽屉是**窄屏的临时浮层**——
|
|
34
|
+
* 两者语义不同,共用一个状态会让"手机上开过一次抽屉"变成
|
|
35
|
+
* "桌面侧栏永久收起"(实测:antd Sider 的 breakpoint 就会这么干)。
|
|
36
|
+
*/
|
|
37
|
+
function openMobileNav() {
|
|
38
|
+
mobileNavOpen.value = true
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function closeMobileNav() {
|
|
42
|
+
mobileNavOpen.value = false
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function toggleMobileNav() {
|
|
46
|
+
mobileNavOpen.value = !mobileNavOpen.value
|
|
47
|
+
}
|
|
48
|
+
|
|
29
49
|
function setAccent(color: string | null) {
|
|
30
50
|
accent.value = color
|
|
31
51
|
}
|
|
32
52
|
|
|
33
|
-
return {
|
|
53
|
+
return {
|
|
54
|
+
isDark,
|
|
55
|
+
sidebarCollapsed,
|
|
56
|
+
mobileNavOpen,
|
|
57
|
+
accent,
|
|
58
|
+
themeTouched,
|
|
59
|
+
toggleDark,
|
|
60
|
+
toggleSidebar,
|
|
61
|
+
openMobileNav,
|
|
62
|
+
closeMobileNav,
|
|
63
|
+
toggleMobileNav,
|
|
64
|
+
setAccent,
|
|
65
|
+
}
|
|
34
66
|
}, {
|
|
35
67
|
persist: {
|
|
36
68
|
pick: ['isDark', 'sidebarCollapsed', 'accent', 'themeTouched'],
|
|
@@ -176,7 +176,7 @@ export const useUserStore = defineStore('workshop.user', {
|
|
|
176
176
|
// token 真源是 30 天 cookie;hydration 后从 cookie 回填,无 cookie 即回登出态
|
|
177
177
|
pick: ['user'],
|
|
178
178
|
afterHydrate: (ctx) => {
|
|
179
|
-
const store = ctx.store as { user?:
|
|
179
|
+
const store = ctx.store as { user?: CurrentUser | null, applyCookie?: () => void }
|
|
180
180
|
if (!store.user) return
|
|
181
181
|
try {
|
|
182
182
|
const cookie = useCookie<string | null>('token')
|
|
@@ -30,8 +30,21 @@ interface ServerWorkspace {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
const ACTIVE_KEY = 'workshop.activeChannel'
|
|
33
|
+
const ACTIVE_WS_KEY = 'workshop.activeWorkspace'
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* localStorage 只在浏览器存在。这几个读写点都在 **store 的初始化路径**上
|
|
37
|
+
* (load() → saveActiveMap()),而 load() 完全可能被服务端调用 ——
|
|
38
|
+
* 少了守卫,一次 SSR 调用就会抛 "localStorage is not defined",
|
|
39
|
+
* 被 stability-guard 当成 fatal unhandledRejection **直接结束进程**
|
|
40
|
+
* (实测:生产实例在 /town 刷新后静默退出,日志只有一行 ReferenceError)。
|
|
41
|
+
*
|
|
42
|
+
* 约定与 app/stores/app.ts 一致:持久化层自己保证 SSR 安全,调用方不必先判断环境。
|
|
43
|
+
*/
|
|
44
|
+
const hasLocalStorage = (): boolean => typeof localStorage !== 'undefined'
|
|
33
45
|
|
|
34
46
|
function loadActiveMap(): Record<string, string> {
|
|
47
|
+
if (!hasLocalStorage()) return {}
|
|
35
48
|
try {
|
|
36
49
|
return JSON.parse(localStorage.getItem(ACTIVE_KEY) ?? '{}') as Record<string, string>
|
|
37
50
|
}
|
|
@@ -41,6 +54,7 @@ function loadActiveMap(): Record<string, string> {
|
|
|
41
54
|
}
|
|
42
55
|
|
|
43
56
|
function saveActiveMap(map: Record<string, string>): void {
|
|
57
|
+
if (!hasLocalStorage()) return
|
|
44
58
|
localStorage.setItem(ACTIVE_KEY, JSON.stringify(map))
|
|
45
59
|
}
|
|
46
60
|
|
|
@@ -51,12 +65,14 @@ export const useWorkspacesStore = defineStore('workshop.workspaces', {
|
|
|
51
65
|
}),
|
|
52
66
|
getters: {
|
|
53
67
|
activeWorkspaceId(state): string | null {
|
|
54
|
-
|
|
68
|
+
if (!hasLocalStorage()) return state.workspaces[0]?.id ?? null
|
|
69
|
+
return localStorage.getItem(ACTIVE_WS_KEY) ?? state.workspaces[0]?.id ?? null
|
|
55
70
|
},
|
|
56
71
|
},
|
|
57
72
|
actions: {
|
|
58
73
|
setActiveWorkspaceId(id: string | null): void {
|
|
59
|
-
|
|
74
|
+
if (!hasLocalStorage()) return
|
|
75
|
+
localStorage.setItem(ACTIVE_WS_KEY, id ?? '')
|
|
60
76
|
},
|
|
61
77
|
/** 拉取服务端 workspace 列表(合并本地 activeChannelId) */
|
|
62
78
|
async load(): Promise<void> {
|
package/app/utils/api-error.ts
CHANGED
package/cli/commands/build.mjs
CHANGED
|
@@ -25,10 +25,17 @@ export async function run(argv, ctx) {
|
|
|
25
25
|
console.log(`${color.cyan('›')} 构建生产产物 .output/ ...`)
|
|
26
26
|
// 统一生命周期:转发 SIGINT/SIGTERM(子进程不再变孤儿) + 等待退出 + 超时强杀
|
|
27
27
|
// + 退出码传播(被信号杀死 → 128+N,不再 code ?? 0 误报成功)
|
|
28
|
+
const env = localBypassEnv()
|
|
29
|
+
// Node ≥21 对 exports 里的"尾部斜杠映射"(\"./\": \"./x/\")发 DEP0155 弃用警告。
|
|
30
|
+
// 本项目依赖树里有两个这样的包(@babel/runtime → ./regenerator/、diff → ./lib/),
|
|
31
|
+
// 它们**不是我们的代码**,也改不动(除非 patch 上游);这条提示不影响产物正确性。
|
|
32
|
+
// 只关这一个 code,其它弃用/实验性警告照常显示 —— 不是把日志静音,是把
|
|
33
|
+
// "上游已弃用、我们无权修改"的确定噪音摘掉。
|
|
34
|
+
env.NODE_OPTIONS = [env.NODE_OPTIONS, '--disable-warning=DEP0155'].filter(Boolean).join(' ')
|
|
28
35
|
const code = await runChild(process.execPath, [nuxtBin, 'build'], {
|
|
29
36
|
cwd: root,
|
|
30
37
|
stdio: 'inherit',
|
|
31
|
-
env
|
|
38
|
+
env,
|
|
32
39
|
onSpawnError: err => console.log(`${color.red('✖')} 构建失败: ${err.message}`),
|
|
33
40
|
})
|
|
34
41
|
if (code !== 0) return code
|
package/docker-compose.yml
CHANGED
|
@@ -21,6 +21,12 @@ services:
|
|
|
21
21
|
daq-timescale:
|
|
22
22
|
image: timescale/timescaledb:latest-pg16
|
|
23
23
|
container_name: awshop-daq-timescale
|
|
24
|
+
# ⚠️ 必须显式放大 /dev/shm:Docker 默认只给 64MB,而 PostgreSQL 的并行查询
|
|
25
|
+
# 会按需扩容共享内存段 —— 不够时报的错是
|
|
26
|
+
# could not resize shared memory segment "...": No space left on device
|
|
27
|
+
# 这句话看起来像"磁盘满了",实际是 shm 满了,极难排查(实测在回退账本的
|
|
28
|
+
# 兜底评估查询上稳定复现,而宿主机还剩 230GB)。512MB 是 Postgres 官方镜像文档的建议值。
|
|
29
|
+
shm_size: 512mb
|
|
24
30
|
environment:
|
|
25
31
|
POSTGRES_USER: postgres # config.yml daq.timescale.user
|
|
26
32
|
POSTGRES_PASSWORD: awshop # config.yml daq.timescale.password
|
package/i18n/locales/en.ts
CHANGED