agentworkshop 0.7.58 → 0.7.60
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 +108 -0
- package/.output/.AgentWorkShop/prompts/host-tools.json +108 -0
- package/.output/.AgentWorkShop/schema.json +1 -0
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/{CZwDnomB.js → 59a6cSgj.js} +1 -1
- package/.output/public/_nuxt/5juo_WO2.js +13 -0
- package/.output/public/_nuxt/9j2J4k4w.js +1 -0
- package/.output/public/_nuxt/B-WTxXEK2.js +1 -0
- package/.output/public/_nuxt/{DTx_DtUo.js → B0w8DZ4C.js} +1 -1
- package/.output/public/_nuxt/B1BCga5h2.js +13 -0
- package/.output/public/_nuxt/B5lMtA7I2.js +1 -0
- package/.output/public/_nuxt/B6_fJd2X.js +1 -0
- package/.output/public/_nuxt/B7K5B04W2.js +1 -0
- package/.output/public/_nuxt/B7KyS_q2.js +1 -0
- package/.output/public/_nuxt/B8q3BGY5.js +37 -0
- package/.output/public/_nuxt/B9IK8kDl2.js +1 -0
- package/.output/public/_nuxt/BFBysc2M2.js +1 -0
- package/.output/public/_nuxt/{BMUEVeOK.js → BGFhOMVM.js} +2 -2
- package/.output/public/_nuxt/{cBI0JqsV.js → BMlesJth.js} +1 -1
- package/.output/public/_nuxt/BNd2NDxg2.js +1 -0
- package/.output/public/_nuxt/BP629NAi.js +1 -0
- package/.output/public/_nuxt/BVinTfuN.js +1 -0
- package/.output/public/_nuxt/{DJZzthKt2.js → B_BYwIf22.js} +1 -1
- package/.output/public/_nuxt/{CW1HGp5X.js → B_JLVF30.js} +1 -1
- package/.output/public/_nuxt/BdE41Y_c.js +28 -0
- package/.output/public/_nuxt/Bdq2LNSO.js +1 -0
- package/.output/public/_nuxt/{BMZ1d25O.js → BeNdseTX.js} +1 -1
- package/.output/public/_nuxt/Be_StT8b2.js +1 -0
- package/.output/public/_nuxt/BhllzW3K2.js +1 -0
- package/.output/public/_nuxt/BjUpWKS6.js +1 -0
- package/.output/public/_nuxt/{CCCq9H7D2.js → BlEJRYAn2.js} +1 -1
- package/.output/public/_nuxt/{Du0zf-d3.js → BplhglEM.js} +1 -1
- package/.output/public/_nuxt/BsYEYxWv.js +24 -0
- package/.output/public/_nuxt/BtXwFpv42.js +1 -0
- package/.output/public/_nuxt/{BrFF_9742.js → BuNXYpib2.js} +1 -1
- package/.output/public/_nuxt/{BzKT-ne_2.js → C0sNwDTK2.js} +1 -1
- package/.output/public/_nuxt/{h46i74oE.js → C4AICl3l.js} +4 -4
- package/.output/public/_nuxt/{BuVH9MB-.js → C5OSTzBh.js} +1 -1
- package/.output/public/_nuxt/{DKhRushG.js → C8XVZGSZ.js} +1 -1
- package/.output/public/_nuxt/{zGDAozGA.js → C93LpBMF.js} +4 -4
- package/.output/public/_nuxt/CDaZC0_6.js +3 -0
- package/.output/public/_nuxt/CE43-V_L.js +2 -0
- package/.output/public/_nuxt/{B4R5CHkk.js → CEHT9inW.js} +1 -1
- package/.output/public/_nuxt/CGChCy-w2.js +1 -0
- package/.output/public/_nuxt/{DvUt9uMt2.js → CMDAjShv2.js} +1 -1
- package/.output/public/_nuxt/CUjdqsjC2.js +1 -0
- package/.output/public/_nuxt/CWfBtswB.js +70 -0
- package/.output/public/_nuxt/CYtH1bv2.js +1 -0
- package/.output/public/_nuxt/CZmMgjIK.js +1 -0
- package/.output/public/_nuxt/{iZa330UY.js → Cdw4juXw.js} +1 -1
- package/.output/public/_nuxt/{DMPpE41S2.js → Ce5SiMQR2.js} +1 -1
- package/.output/public/_nuxt/{B03LfmKR.js → Cfp00Rdo.js} +1 -1
- package/.output/public/_nuxt/{Dy-V8OEW2.js → CgbP5yJk2.js} +7 -7
- package/.output/public/_nuxt/ChPNKPw_.js +1 -0
- package/.output/public/_nuxt/{C5wBzGO7.js → CjeMxUv8.js} +1 -1
- package/.output/public/_nuxt/CktUrk8z.js +1 -0
- package/.output/public/_nuxt/Cst8yEet.js +1 -0
- package/.output/public/_nuxt/Cuw2--X2.js +2 -0
- package/.output/public/_nuxt/Cyd68Xbv2.js +1 -0
- package/.output/public/_nuxt/{pNy4V4kd.js → Cyuxcv5s2.js} +1 -1
- package/.output/public/_nuxt/{CIz7SM4H.js → D0vmf1z9.js} +1 -1
- package/.output/public/_nuxt/D5-QB_-l.js +1 -0
- package/.output/public/_nuxt/D9sgxxsM2.js +1 -0
- package/.output/public/_nuxt/DBdwjOGB2.js +1 -0
- package/.output/public/_nuxt/DBzdrPzw2.js +1 -0
- package/.output/public/_nuxt/DD4J2Otc.js +1 -0
- package/.output/public/_nuxt/DMCoWgSb2.js +1 -0
- package/.output/public/_nuxt/{CmTqFlYZ.js → DTcsb0fG.js} +1 -1
- package/.output/public/_nuxt/Ddc_Pn7D.js +19 -0
- package/.output/public/_nuxt/Dg1iMuZ-.js +1 -0
- package/.output/public/_nuxt/DhSlJyZD2.js +1 -0
- package/.output/public/_nuxt/DmwMkvoQ2.js +1 -0
- package/.output/public/_nuxt/EQijmkCh2.js +1 -0
- package/.output/public/_nuxt/KXQppTXc.js +1 -0
- package/.output/public/_nuxt/{CZ0Gt81h.js → KXvRkBgg.js} +2 -2
- package/.output/public/_nuxt/LwITbamf2.js +47 -0
- package/.output/public/_nuxt/N9TYd_Mk2.js +1 -0
- package/.output/public/_nuxt/VeOVO2sE2.js +1 -0
- package/.output/public/_nuxt/_jfzcYrl.js +1 -0
- package/.output/public/_nuxt/analysis.D2Pao1rm.css +1 -0
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/f78a1992-e424-494d-ac4b-aa18971ffc10.json +1 -0
- package/.output/public/_nuxt/{default.8ac6QU28.css → default.Bx6RJSbr.css} +1 -1
- package/.output/public/_nuxt/{entry.BHNNQA9H.css → entry.BlbU43qz.css} +1 -1
- package/.output/public/_nuxt/{MEwEMEMl2.js → iCvdSYYN2.js} +6 -6
- package/.output/public/_nuxt/{CYGkUj5M2.js → p2sDc0tO2.js} +1 -1
- package/.output/public/_nuxt/{Drhta6gr.js → zVupTo2z2.js} +2 -2
- package/.output/server/chunks/_/LeftOutlined.mjs +1 -1
- package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
- package/.output/server/chunks/_/host-bindings.mjs +1 -1
- package/.output/server/chunks/_/nitro.mjs +1629 -1246
- package/.output/server/chunks/_/nitro.mjs.map +1 -1
- package/.output/server/chunks/_/scene-layout.repo.mjs +1 -1
- package/.output/server/chunks/build/{AuthGate-DDPYswkA.mjs → AuthGate-CZYkvPrg.mjs} +5 -5
- package/.output/server/chunks/build/{AuthGate-DDPYswkA.mjs.map → AuthGate-CZYkvPrg.mjs.map} +1 -1
- package/.output/server/chunks/build/Checkbox-4EdGAAl_.mjs +1 -1
- package/.output/server/chunks/build/{FormItemContext-4ORSzhWv.mjs → FormItemContext-DcWIIAaK.mjs} +2 -2
- package/.output/server/chunks/build/{FormItemContext-4ORSzhWv.mjs.map → FormItemContext-DcWIIAaK.mjs.map} +1 -1
- package/.output/server/chunks/build/{OmpTerminalPanel-DZ2wHMS1.mjs → OmpTerminalPanel-CtFJ6Kc8.mjs} +4 -4
- package/.output/server/chunks/build/{OmpTerminalPanel-DZ2wHMS1.mjs.map → OmpTerminalPanel-CtFJ6Kc8.mjs.map} +1 -1
- package/.output/server/chunks/build/{PluginSlot-CT4YaNrB.mjs → PluginSlot-BT7kYQgK.mjs} +2 -2
- package/.output/server/chunks/build/{PluginSlot-CT4YaNrB.mjs.map → PluginSlot-BT7kYQgK.mjs.map} +1 -1
- package/.output/server/chunks/build/{TownView-CZbFn6mO.mjs → TownView-kQZFf4zj.mjs} +3 -3
- package/.output/server/chunks/build/{TownView-CZbFn6mO.mjs.map → TownView-kQZFf4zj.mjs.map} +1 -1
- package/.output/server/chunks/build/{_id_-Df2pgsAq.mjs → _id_-Bbx1b74O.mjs} +3 -3
- package/.output/server/chunks/build/{_id_-Df2pgsAq.mjs.map → _id_-Bbx1b74O.mjs.map} +1 -1
- package/.output/server/chunks/build/{_id_-CCVhpJtj.mjs → _id_-IijrRw3f.mjs} +3 -3
- package/.output/server/chunks/build/{_id_-CCVhpJtj.mjs.map → _id_-IijrRw3f.mjs.map} +1 -1
- package/.output/server/chunks/build/{_wsId_-CJqF-hmP.mjs → _wsId_-DOEw9jgZ.mjs} +22 -21
- package/.output/server/chunks/build/{_wsId_-CJqF-hmP.mjs.map → _wsId_-DOEw9jgZ.mjs.map} +1 -1
- package/.output/server/chunks/build/{agents-BTsbna5H.mjs → agents-C36wR56A.mjs} +18 -17
- package/.output/server/chunks/build/agents-C36wR56A.mjs.map +1 -0
- package/.output/server/chunks/build/{aml-BBKfWto1.mjs → aml-CBGndvHT.mjs} +7 -7
- package/.output/server/chunks/build/{aml-BBKfWto1.mjs.map → aml-CBGndvHT.mjs.map} +1 -1
- package/.output/server/chunks/build/analysis-tgzvOWmD.mjs +332 -0
- package/.output/server/chunks/build/analysis-tgzvOWmD.mjs.map +1 -0
- package/.output/server/chunks/build/{card-DJOYGuVH.mjs → card-Db7OB49d.mjs} +4 -4
- package/.output/server/chunks/build/{card-DJOYGuVH.mjs.map → card-Db7OB49d.mjs.map} +1 -1
- package/.output/server/chunks/build/{channel-templates-BPKJ8e4l.mjs → channel-templates-BixUrDmU.mjs} +11 -10
- package/.output/server/chunks/build/channel-templates-BixUrDmU.mjs.map +1 -0
- package/.output/server/chunks/build/{checkbox-C4AKj81e.mjs → checkbox-CyF96D30.mjs} +3 -3
- package/.output/server/chunks/build/{checkbox-C4AKj81e.mjs.map → checkbox-CyF96D30.mjs.map} +1 -1
- package/.output/server/chunks/build/{daq-Cz7TaUAM.mjs → daq-DLMLufDq.mjs} +5 -5
- package/.output/server/chunks/build/{daq-Cz7TaUAM.mjs.map → daq-DLMLufDq.mjs.map} +1 -1
- package/.output/server/chunks/build/dcw-EhjJpVQM.mjs +2 -2
- package/.output/server/chunks/build/{default-DweMY872.mjs → default-C7Qmdyz_.mjs} +30 -19
- package/.output/server/chunks/build/{default-DweMY872.mjs.map → default-C7Qmdyz_.mjs.map} +1 -1
- package/.output/server/chunks/build/{descriptions-CFaUq4y4.mjs → descriptions-1bH81YsZ.mjs} +2 -2
- package/.output/server/chunks/build/{descriptions-CFaUq4y4.mjs.map → descriptions-1bH81YsZ.mjs.map} +1 -1
- package/.output/server/chunks/build/{drawer-Cfh9_zft.mjs → drawer-C7shdEHy.mjs} +2 -2
- package/.output/server/chunks/build/{drawer-Cfh9_zft.mjs.map → drawer-C7shdEHy.mjs.map} +1 -1
- package/.output/server/chunks/build/{dropdown-CIsqbX4P.mjs → dropdown-BhLSIp5A.mjs} +2 -2
- package/.output/server/chunks/build/{dropdown-CIsqbX4P.mjs.map → dropdown-BhLSIp5A.mjs.map} +1 -1
- package/.output/server/chunks/build/{dropdown-CV9GW3z9.mjs → dropdown-BiwcuXDi.mjs} +6 -5
- package/.output/server/chunks/build/{dropdown-CV9GW3z9.mjs.map → dropdown-BiwcuXDi.mjs.map} +1 -1
- package/.output/server/chunks/build/{form-cs_RcfGx.mjs → form-nE8C0G8B.mjs} +7 -6
- package/.output/server/chunks/build/{form-cs_RcfGx.mjs.map → form-nE8C0G8B.mjs.map} +1 -1
- package/.output/server/chunks/build/{input-CobQ5LJ5.mjs → input-DwF72eVI.mjs} +93 -3449
- package/.output/server/chunks/build/input-DwF72eVI.mjs.map +1 -0
- package/.output/server/chunks/build/{input-number-BpPYAWMk.mjs → input-number-TSq6ltkz.mjs} +6 -5
- package/.output/server/chunks/build/{input-number-BpPYAWMk.mjs.map → input-number-TSq6ltkz.mjs.map} +1 -1
- package/.output/server/chunks/build/{logs-As9fZqU-.mjs → logs-hOEVuxqm.mjs} +3 -3
- package/.output/server/chunks/build/{logs-As9fZqU-.mjs.map → logs-hOEVuxqm.mjs.map} +1 -1
- package/.output/server/chunks/build/{menu-CVmvHyFT.mjs → menu-Cy5Nrecn.mjs} +4 -3
- package/.output/server/chunks/build/{menu-CVmvHyFT.mjs.map → menu-Cy5Nrecn.mjs.map} +1 -1
- package/.output/server/chunks/build/{monitor-CdFQ2z4g.mjs → monitor-CfVoiavp.mjs} +20 -19
- package/.output/server/chunks/build/{monitor-CdFQ2z4g.mjs.map → monitor-CfVoiavp.mjs.map} +1 -1
- package/.output/server/chunks/build/{operations-B2gHCWgZ.mjs → operations-fxI8lEBJ.mjs} +3 -3
- package/.output/server/chunks/build/{operations-B2gHCWgZ.mjs.map → operations-fxI8lEBJ.mjs.map} +1 -1
- package/.output/server/chunks/build/{pages-BItCt1ar.mjs → pages-6JD9VSbx.mjs} +5 -5
- package/.output/server/chunks/build/{pages-BItCt1ar.mjs.map → pages-6JD9VSbx.mjs.map} +1 -1
- package/.output/server/chunks/build/{permissions-D6mQw_9j.mjs → permissions-XPtQJSaO.mjs} +14 -13
- package/.output/server/chunks/build/permissions-XPtQJSaO.mjs.map +1 -0
- package/.output/server/chunks/build/{plugins-NAS9MQ5r.mjs → plugins-DjBSG9pV.mjs} +5 -5
- package/.output/server/chunks/build/{plugins-NAS9MQ5r.mjs.map → plugins-DjBSG9pV.mjs.map} +1 -1
- package/.output/server/chunks/build/{popconfirm-DFfoFhmt.mjs → popconfirm-DKeEbaGd.mjs} +3 -3
- package/.output/server/chunks/build/{popconfirm-DFfoFhmt.mjs.map → popconfirm-DKeEbaGd.mjs.map} +1 -1
- package/.output/server/chunks/build/{schedules-BjWNDWL5.mjs → schedules-PcDLCUWN.mjs} +20 -19
- package/.output/server/chunks/build/{schedules-BjWNDWL5.mjs.map → schedules-PcDLCUWN.mjs.map} +1 -1
- package/.output/server/chunks/build/{segmented-D7FkCgg7.mjs → segmented-BdWCdZUM.mjs} +3 -3
- package/.output/server/chunks/build/{segmented-D7FkCgg7.mjs.map → segmented-BdWCdZUM.mjs.map} +1 -1
- package/.output/server/chunks/build/{select-FqBNxgxT.mjs → select-C5yighj8.mjs} +5 -4
- package/.output/server/chunks/build/{select-FqBNxgxT.mjs.map → select-C5yighj8.mjs.map} +1 -1
- package/.output/server/chunks/build/{settings-Cl_KRyEn.mjs → settings-90zT_h9w.mjs} +14 -13
- package/.output/server/chunks/build/settings-90zT_h9w.mjs.map +1 -0
- package/.output/server/chunks/build/{space-B2uhHJG8.mjs → space-BCffbXIG.mjs} +3 -3
- package/.output/server/chunks/build/{space-B2uhHJG8.mjs.map → space-BCffbXIG.mjs.map} +1 -1
- package/.output/server/chunks/build/{switch-DZAUIbIN.mjs → switch-OG0SM_Px.mjs} +3 -3
- package/.output/server/chunks/build/{switch-DZAUIbIN.mjs.map → switch-OG0SM_Px.mjs.map} +1 -1
- package/.output/server/chunks/build/{table-CeOYERqr.mjs → table-UpVzu50c.mjs} +11 -10
- package/.output/server/chunks/build/{table-CeOYERqr.mjs.map → table-UpVzu50c.mjs.map} +1 -1
- package/.output/server/chunks/build/{tabs-LLNSdLl2.mjs → tabs-CWwoL33v.mjs} +6 -5
- package/.output/server/chunks/build/{tabs-LLNSdLl2.mjs.map → tabs-CWwoL33v.mjs.map} +1 -1
- package/.output/server/chunks/build/{tag-Dwvkh0Dj.mjs → tag-CS7mwrfG.mjs} +5 -4
- package/.output/server/chunks/build/{tag-Dwvkh0Dj.mjs.map → tag-CS7mwrfG.mjs.map} +1 -1
- package/.output/server/chunks/build/{teams-CGDZHaQl.mjs → teams-BIAFvRw1.mjs} +19 -18
- package/.output/server/chunks/build/teams-BIAFvRw1.mjs.map +1 -0
- package/.output/server/chunks/build/{tokens-BOYkZuoB.mjs → tokens-CLpdrzQ7.mjs} +19 -18
- package/.output/server/chunks/build/tokens-CLpdrzQ7.mjs.map +1 -0
- package/.output/server/chunks/build/tooltip-CJlH_8ZK.mjs +3362 -0
- package/.output/server/chunks/build/tooltip-CJlH_8ZK.mjs.map +1 -0
- package/.output/server/chunks/build/town-BV-hbwb5.mjs +1 -1
- package/.output/server/chunks/build/{town-P1rYoi0v.mjs → town-Bfme7P2I.mjs} +5 -5
- package/.output/server/chunks/build/{town-P1rYoi0v.mjs.map → town-Bfme7P2I.mjs.map} +1 -1
- package/.output/server/chunks/build/types-D6J7slEa.mjs +1 -1
- package/.output/server/chunks/build/types-DWqIeMRP.mjs +75 -0
- package/.output/server/chunks/build/types-DWqIeMRP.mjs.map +1 -0
- package/.output/server/chunks/build/{useAgentTemplateActions-DsBRUQni.mjs → useAgentTemplateActions-6VyAHgu5.mjs} +1 -1
- package/.output/server/chunks/build/{useAgentTemplateActions-DsBRUQni.mjs.map → useAgentTemplateActions-6VyAHgu5.mjs.map} +1 -1
- package/.output/server/chunks/build/{useAgentTemplateForm-DzQ_t2Ue.mjs → useAgentTemplateForm-DWa-ezNq.mjs} +1 -1
- package/.output/server/chunks/build/{useAgentTemplateForm-DzQ_t2Ue.mjs.map → useAgentTemplateForm-DWa-ezNq.mjs.map} +1 -1
- package/.output/server/chunks/build/{useAmlEntities-BMLHU_39.mjs → useAmlEntities-Co2fgjzh.mjs} +1 -1
- package/.output/server/chunks/build/{useAmlEntities-BMLHU_39.mjs.map → useAmlEntities-Co2fgjzh.mjs.map} +1 -1
- package/.output/server/chunks/build/{useAmlEnv-DdlyVzPu.mjs → useAmlEnv-JTiWPrzH.mjs} +1 -1
- package/.output/server/chunks/build/{useAmlEnv-DdlyVzPu.mjs.map → useAmlEnv-JTiWPrzH.mjs.map} +1 -1
- package/.output/server/chunks/build/{useAmlJobs-BG_v21hJ.mjs → useAmlJobs-By4pjOzc.mjs} +1 -1
- package/.output/server/chunks/build/{useAmlJobs-BG_v21hJ.mjs.map → useAmlJobs-By4pjOzc.mjs.map} +1 -1
- package/.output/server/chunks/build/{useAmlModels-D7MuOWOy.mjs → useAmlModels-B1_5vjMA.mjs} +1 -1
- package/.output/server/chunks/build/{useAmlModels-D7MuOWOy.mjs.map → useAmlModels-B1_5vjMA.mjs.map} +1 -1
- package/.output/server/chunks/build/{useAmlNotes-CTZe-GI0.mjs → useAmlNotes-5uwvCb3h.mjs} +1 -1
- package/.output/server/chunks/build/{useAmlNotes-CTZe-GI0.mjs.map → useAmlNotes-5uwvCb3h.mjs.map} +1 -1
- package/.output/server/chunks/build/{useAmlPredict-BToRrVRV.mjs → useAmlPredict-lxUv7lAO.mjs} +1 -1
- package/.output/server/chunks/build/{useAmlPredict-BToRrVRV.mjs.map → useAmlPredict-lxUv7lAO.mjs.map} +1 -1
- package/.output/server/chunks/build/useAnalysisFeed-B4OwUd7p.mjs +128 -0
- package/.output/server/chunks/build/useAnalysisFeed-B4OwUd7p.mjs.map +1 -0
- package/.output/server/chunks/build/useDaqAddNode-CaOCbe4-.mjs +1 -1
- package/.output/server/chunks/build/{useDaqDetailNode-DXgwAu5u.mjs → useDaqDetailNode-DtZ0oDAn.mjs} +3 -3
- package/.output/server/chunks/build/{useDaqDetailNode-DXgwAu5u.mjs.map → useDaqDetailNode-DtZ0oDAn.mjs.map} +1 -1
- package/.output/server/chunks/build/useDaqDetailParams-CrTMDs-2.mjs +1 -1
- package/.output/server/chunks/build/{useDaqFilters-Jx6EERfr.mjs → useDaqFilters-DYHGhECw.mjs} +3 -3
- package/.output/server/chunks/build/{useDaqFilters-Jx6EERfr.mjs.map → useDaqFilters-DYHGhECw.mjs.map} +1 -1
- package/.output/server/chunks/build/useDaqStream-DhzdoyIR.mjs +1 -1
- package/.output/server/chunks/build/useDaqTemplates-C7GzQmdJ.mjs +1 -1
- package/.output/server/chunks/build/{useDashboardData-Ce-EU5DJ.mjs → useDashboardData-B3lZjE7x.mjs} +3 -3
- package/.output/server/chunks/build/{useDashboardData-Ce-EU5DJ.mjs.map → useDashboardData-B3lZjE7x.mjs.map} +1 -1
- package/.output/server/chunks/build/useDcwAddNode-4mTPQ6T8.mjs +1 -1
- package/.output/server/chunks/build/{useDcwDetailScope-4j3B03Pi.mjs → useDcwDetailScope-BWH7jnVh.mjs} +2 -2
- package/.output/server/chunks/build/{useDcwDetailScope-4j3B03Pi.mjs.map → useDcwDetailScope-BWH7jnVh.mjs.map} +1 -1
- package/.output/server/chunks/build/useDcwStream-BXJ2V8HM.mjs +1 -1
- package/.output/server/chunks/build/{useLogsManual-CMjD62nt.mjs → useLogsManual-BLfiSU3u.mjs} +1 -1
- package/.output/server/chunks/build/{useLogsManual-CMjD62nt.mjs.map → useLogsManual-BLfiSU3u.mjs.map} +1 -1
- package/.output/server/chunks/build/{useMonitorData-D2gFSonG.mjs → useMonitorData-BZ6Z-Sy8.mjs} +1 -1
- package/.output/server/chunks/build/{useMonitorData-D2gFSonG.mjs.map → useMonitorData-BZ6Z-Sy8.mjs.map} +1 -1
- package/.output/server/chunks/build/{useTeamActions-BOLQkYxg.mjs → useTeamActions-ahht5J8Y.mjs} +1 -1
- package/.output/server/chunks/build/{useTeamActions-BOLQkYxg.mjs.map → useTeamActions-ahht5J8Y.mjs.map} +1 -1
- package/.output/server/chunks/build/{useTeamAddMemberDialog-BCgrLPxI.mjs → useTeamAddMemberDialog-DvXxsVy0.mjs} +1 -1
- package/.output/server/chunks/build/{useTeamAddMemberDialog-BCgrLPxI.mjs.map → useTeamAddMemberDialog-DvXxsVy0.mjs.map} +1 -1
- package/.output/server/chunks/build/{useTeamCreateDialog-CJk40LqS.mjs → useTeamCreateDialog-A_k-XX5B.mjs} +1 -1
- package/.output/server/chunks/build/{useTeamCreateDialog-CJk40LqS.mjs.map → useTeamCreateDialog-A_k-XX5B.mjs.map} +1 -1
- package/.output/server/chunks/build/{useTeamDeployDialog-49hdUXQP.mjs → useTeamDeployDialog-CfAFjIr_.mjs} +1 -1
- package/.output/server/chunks/build/{useTeamDeployDialog-49hdUXQP.mjs.map → useTeamDeployDialog-CfAFjIr_.mjs.map} +1 -1
- package/.output/server/chunks/build/{useTeamPluginDialog-Dh-QOoiU.mjs → useTeamPluginDialog-Djmkk1Nl.mjs} +1 -1
- package/.output/server/chunks/build/{useTeamPluginDialog-Dh-QOoiU.mjs.map → useTeamPluginDialog-Djmkk1Nl.mjs.map} +1 -1
- package/.output/server/chunks/build/{useTokenCreate-DkYvEQUD.mjs → useTokenCreate-CkWoxSI-.mjs} +1 -1
- package/.output/server/chunks/build/{useTokenCreate-DkYvEQUD.mjs.map → useTokenCreate-CkWoxSI-.mjs.map} +1 -1
- package/.output/server/chunks/build/{useTokenRename-DOCP4aeI.mjs → useTokenRename-BohjnGT0.mjs} +1 -1
- package/.output/server/chunks/build/{useTokenRename-DOCP4aeI.mjs.map → useTokenRename-BohjnGT0.mjs.map} +1 -1
- package/.output/server/chunks/build/{useTokenReveal-CybwwflV.mjs → useTokenReveal-BBN5iGz7.mjs} +1 -1
- package/.output/server/chunks/build/{useTokenReveal-CybwwflV.mjs.map → useTokenReveal-BBN5iGz7.mjs.map} +1 -1
- package/.output/server/chunks/build/{useTokensList-BLiMvrc4.mjs → useTokensList-BQX9WqfT.mjs} +1 -1
- package/.output/server/chunks/build/{useTokensList-BLiMvrc4.mjs.map → useTokensList-BQX9WqfT.mjs.map} +1 -1
- package/.output/server/chunks/build/{useWorkbenchAuth-DAabQl7X.mjs → useWorkbenchAuth-BTRlS2wZ.mjs} +1 -1
- package/.output/server/chunks/build/{useWorkbenchAuth-DAabQl7X.mjs.map → useWorkbenchAuth-BTRlS2wZ.mjs.map} +1 -1
- package/.output/server/chunks/build/{useWorkbenchWorkspaces-6-mpCGCR.mjs → useWorkbenchWorkspaces-C6ky7OJH.mjs} +1 -1
- package/.output/server/chunks/build/{useWorkbenchWorkspaces-6-mpCGCR.mjs.map → useWorkbenchWorkspaces-C6ky7OJH.mjs.map} +1 -1
- package/.output/server/chunks/build/{users-B_pHStEa.mjs → users-BHOEW3Az.mjs} +15 -14
- package/.output/server/chunks/build/users-BHOEW3Az.mjs.map +1 -0
- package/.output/server/chunks/build/{workshop-C0DefygA.mjs → workshop-DyJ1LXwu.mjs} +11 -10
- package/.output/server/chunks/build/workshop-DyJ1LXwu.mjs.map +1 -0
- package/.output/server/chunks/routes/api/mcp/workshop.mjs +1 -1
- package/.output/server/chunks/routes/api/system/backup/run.post.mjs +2 -2
- package/.output/server/chunks/routes/api/workshop/analysis/_id_.delete.mjs +46 -0
- package/.output/server/chunks/routes/api/workshop/analysis/_id_.delete.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs +39 -0
- package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +2 -2
- package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/line.put.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels.post.mjs +7 -7
- package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index7.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/mes-artifacts/file.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/mes-hook-test.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/mes-test-read.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +1 -1
- 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/dcw/test-driver.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/exp/confirmations/_id/decide.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/exp/index.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/fs/dirs.get.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/index10.get.mjs +20 -23
- package/.output/server/chunks/routes/api/workshop/index10.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index11.get.mjs +25 -11
- package/.output/server/chunks/routes/api/workshop/index11.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index12.get.mjs +10 -4
- package/.output/server/chunks/routes/api/workshop/index12.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index13.get.mjs +2 -3
- package/.output/server/chunks/routes/api/workshop/index13.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index14.get.mjs +3 -2
- package/.output/server/chunks/routes/api/workshop/index14.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index15.get.mjs +30 -0
- package/.output/server/chunks/routes/api/workshop/index15.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/index3.get.mjs +20 -9
- package/.output/server/chunks/routes/api/workshop/index3.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index3.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index4.get.mjs +10 -4
- package/.output/server/chunks/routes/api/workshop/index4.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index4.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index5.get.mjs +4 -29
- package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index5.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index6.get.mjs +25 -22
- package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index7.get.mjs +26 -5
- package/.output/server/chunks/routes/api/workshop/index7.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index8.get.mjs +4 -39
- package/.output/server/chunks/routes/api/workshop/index8.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index9.get.mjs +40 -20
- 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/teams/_id/deploy.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -2
- package/.output/server/chunks/routes/renderer.mjs +2 -2
- package/.output/server/chunks/virtual/entry.mjs +551 -824
- package/.output/server/chunks/virtual/entry.mjs.map +1 -1
- package/.output/server/chunks/virtual/precomputed.mjs +1 -1
- package/.output/server/package.json +1 -1
- package/README-zh.md +17 -0
- package/README.md +20 -0
- package/app/components/AppSidebar.vue +1 -0
- package/app/components/analysis/AnalysisFilterCard.vue +160 -0
- package/app/components/analysis/AnalysisPageHead.vue +47 -0
- package/app/components/analysis/AnalysisTable.vue +306 -0
- package/app/composables/useRouteMeta.ts +1 -0
- package/app/config/schema.ts +1 -0
- package/app/pages/analysis/composables/useAnalysisFeed.ts +85 -0
- package/app/pages/analysis/index.vue +92 -0
- package/app/pages/analysis/types.ts +44 -0
- package/cli/commands/mcp.mjs +160 -154
- package/config.yml +1 -1
- package/i18n/locales/en.ts +55 -0
- package/i18n/locales/zh-CN.ts +55 -0
- package/mcp/aw-mcp-server.mjs +799 -796
- package/package.json +2 -2
- package/scripts/onboarding/onboard.mjs +5 -2
- package/scripts/onboarding/sim-twin.mjs +312 -0
- package/server/api/workshop/analysis/[id].delete.ts +30 -0
- package/server/api/workshop/analysis/[id].get.ts +23 -0
- package/server/api/workshop/analysis/index.get.ts +33 -0
- package/server/plugins/workshop.ts +4 -0
- package/server/repositories/user.repository.ts +2 -2
- package/server/services/workshop/agents/host-tool-bridge/catalog.ts +4 -1
- package/server/services/workshop/agents/host-tool-bridge/tools/industrial.ts +5 -2
- package/server/services/workshop/agents/industrial/analysis-tools.ts +242 -0
- package/server/services/workshop/agents/industrial/index.ts +1 -0
- package/server/services/workshop/agents/industrial/ops-tools.ts +3 -2
- package/server/services/workshop/analysis/analysis.repo.ts +189 -0
- package/server/services/workshop/db/database/schema.ts +28 -1
- package/server/services/workshop/db/ops.repo.ts +1 -1
- package/server/services/workshop/db/retention.ts +2 -0
- package/server/services/workshop/db/schema.sql +27 -0
- package/server/services/workshop/settings.ts +1 -0
- package/shared/config/schema.json +1 -0
- package/.output/public/_nuxt/B-Y_rsfn.js +0 -106
- package/.output/public/_nuxt/B02cxZz72.js +0 -1
- package/.output/public/_nuxt/BAqtRt0q.js +0 -1
- package/.output/public/_nuxt/BKHd_sKD2.js +0 -47
- package/.output/public/_nuxt/BXKCB3rS.js +0 -1
- package/.output/public/_nuxt/BhrnGVGz.js +0 -1
- package/.output/public/_nuxt/BikIgp9R.js +0 -1
- package/.output/public/_nuxt/BkGqyjWm.js +0 -3
- package/.output/public/_nuxt/Bn1N3mJv.js +0 -1
- package/.output/public/_nuxt/Br2LgfbH2.js +0 -13
- package/.output/public/_nuxt/BtNT93vm2.js +0 -1
- package/.output/public/_nuxt/BtYg4aGR2.js +0 -1
- package/.output/public/_nuxt/C4X_Z1lA.js +0 -1
- package/.output/public/_nuxt/CBATzTUf.js +0 -13
- package/.output/public/_nuxt/CEP4UrDv.js +0 -1
- package/.output/public/_nuxt/CIPKYgrH2.js +0 -1
- package/.output/public/_nuxt/CPSHP_EI.js +0 -1
- package/.output/public/_nuxt/CSyIwYcJ2.js +0 -1
- package/.output/public/_nuxt/CZkTlW93.js +0 -2
- package/.output/public/_nuxt/CZyYdpqZ2.js +0 -1
- package/.output/public/_nuxt/CeDkXWCz.js +0 -1
- package/.output/public/_nuxt/Cl19UD7U.js +0 -1
- package/.output/public/_nuxt/ClrkV0C4.js +0 -1
- package/.output/public/_nuxt/CoGETbe-2.js +0 -1
- package/.output/public/_nuxt/CuRtzvsa2.js +0 -1
- package/.output/public/_nuxt/Cv_H1gOM2.js +0 -1
- package/.output/public/_nuxt/D5i2ofVw2.js +0 -1
- package/.output/public/_nuxt/D6XGn5vM.js +0 -2
- package/.output/public/_nuxt/D6c5ppqB.js +0 -1
- package/.output/public/_nuxt/D8VQGThE.js +0 -28
- package/.output/public/_nuxt/DBwuADr82.js +0 -1
- package/.output/public/_nuxt/DTZO6WMs2.js +0 -1
- package/.output/public/_nuxt/DfqRQSFn.js +0 -19
- package/.output/public/_nuxt/DraEWn4N2.js +0 -1
- package/.output/public/_nuxt/DyMgrV29.js +0 -1
- package/.output/public/_nuxt/H7Rbu32y2.js +0 -1
- package/.output/public/_nuxt/TjGWqrHo.js +0 -1
- package/.output/public/_nuxt/VVomhVqu2.js +0 -1
- package/.output/public/_nuxt/YDs3mbQu2.js +0 -1
- package/.output/public/_nuxt/Z3MSTcdu2.js +0 -1
- package/.output/public/_nuxt/_vR_sc7t.js +0 -24
- package/.output/public/_nuxt/builds/meta/082ac92a-d8d0-4e78-8d5a-b4a610080231.json +0 -1
- package/.output/public/_nuxt/gbaq2UOO.js +0 -1
- package/.output/public/_nuxt/o-G6YtmK2.js +0 -1
- package/.output/public/_nuxt/ylowSquM2.js +0 -1
- package/.output/server/chunks/build/agents-BTsbna5H.mjs.map +0 -1
- package/.output/server/chunks/build/channel-templates-BPKJ8e4l.mjs.map +0 -1
- package/.output/server/chunks/build/input-CobQ5LJ5.mjs.map +0 -1
- package/.output/server/chunks/build/permissions-D6mQw_9j.mjs.map +0 -1
- package/.output/server/chunks/build/settings-Cl_KRyEn.mjs.map +0 -1
- package/.output/server/chunks/build/teams-CGDZHaQl.mjs.map +0 -1
- package/.output/server/chunks/build/tokens-BOYkZuoB.mjs.map +0 -1
- package/.output/server/chunks/build/users-B_pHStEa.mjs.map +0 -1
- package/.output/server/chunks/build/workshop-C0DefygA.mjs.map +0 -1
- package/scripts/_audit/.tmp/audit-data/dcw-params.json +0 -15
- package/scripts/_audit/.tmp/audit-data/dcws.json +0 -30
- package/scripts/_audit/aml-layout-diag.mjs +0 -83
- package/scripts/_audit/channel-inspect.mjs +0 -49
- package/scripts/_audit/cleanup-apply.mjs +0 -89
- package/scripts/_audit/cleanup-plan.mjs +0 -82
- package/scripts/_audit/contrast-check.mjs +0 -43
- package/scripts/_audit/dcw-controller-e2e.ts +0 -106
- package/scripts/_audit/dcw-flush-cost.ts +0 -43
- package/scripts/_audit/dcw-rollback-ledger.ts +0 -156
- package/scripts/_audit/dcw-unrecorded-write.ts +0 -171
- package/scripts/_audit/dcw-write-mutex.ts +0 -157
- package/scripts/_audit/design-shots.mjs +0 -145
- package/scripts/_audit/docs-font-probe.mjs +0 -68
- package/scripts/_audit/docs-probe.mjs +0 -107
- package/scripts/_audit/docs-shots.mjs +0 -171
- package/scripts/_audit/docs-v3-verify.mjs +0 -255
- package/scripts/_audit/docs-vue-lint.mjs +0 -81
- package/scripts/_audit/docs-vue-lint2.mjs +0 -91
- package/scripts/_audit/exp-cost-scaling.mjs +0 -57
- package/scripts/_audit/exp-envelope-and-png.mjs +0 -78
- package/scripts/_audit/exp-png-decode.mjs +0 -67
- package/scripts/_audit/exp-retention-plan.mjs +0 -61
- package/scripts/_audit/exp-retention-rescan.mjs +0 -42
- package/scripts/_audit/exp-sweep-fairness.mjs +0 -50
- package/scripts/_audit/feature-audit-e2e.mjs +0 -342
- package/scripts/_audit/fix-settings-count.mjs +0 -57
- package/scripts/_audit/full-e2e-adopt.mjs +0 -238
- package/scripts/_audit/full-e2e-close-loop.mjs +0 -134
- package/scripts/_audit/full-e2e-retrain.mjs +0 -320
- package/scripts/_audit/full-e2e-supplement.mjs +0 -192
- package/scripts/_audit/full-e2e-ui-final.mjs +0 -111
- package/scripts/_audit/full-e2e-ui-mount.mjs +0 -111
- package/scripts/_audit/full-feature-e2e-20260927.mjs +0 -627
- package/scripts/_audit/glass-verify.mjs +0 -155
- package/scripts/_audit/hydration-diff.mjs +0 -104
- package/scripts/_audit/hydration-head.mjs +0 -36
- package/scripts/_audit/hydration-probe.mjs +0 -59
- package/scripts/_audit/idd-scenarios-e2e.mjs +0 -239
- package/scripts/_audit/kb-diag-complete.mjs +0 -261
- package/scripts/_audit/kb-diag-complete2.mjs +0 -271
- package/scripts/_audit/kb-diag-loop-e2e.mjs +0 -357
- package/scripts/_audit/kb-diag-loop-mock.mjs +0 -416
- package/scripts/_audit/kb-diag-loop-v2.mjs +0 -314
- package/scripts/_audit/lead-matrix-test.mjs +0 -172
- package/scripts/_audit/plc-agent-task.mjs +0 -74
- package/scripts/_audit/plc-clean-scenario.mjs +0 -434
- package/scripts/_audit/plc-clean-shots.mjs +0 -161
- package/scripts/_audit/plc-fc10-probe.mjs +0 -30
- package/scripts/_audit/probe-binding.mjs +0 -114
- package/scripts/_audit/recipe-save-e2e.mjs +0 -365
- package/scripts/_audit/review-fix-verify.mjs +0 -158
- package/scripts/_audit/runtime-dir-e2e.mjs +0 -393
- package/scripts/_audit/town-focus-shot.mjs +0 -129
- package/scripts/_audit/town-reposition.mjs +0 -85
- package/scripts/_audit/verify-cleanup.mjs +0 -67
- package/scripts/_audit/verify-data-integrity.mjs +0 -112
- package/scripts/_audit/watchdog-recovery-test.mjs +0 -149
- package/scripts/_dbg-optloop-ui-shots.mjs +0 -52
- /package/.output/public/_nuxt/{4RTUlYvj2.js → 4RTUlYvj.js} +0 -0
- /package/.output/public/_nuxt/{BBhLVYdM.js → BBhLVYdM2.js} +0 -0
- /package/.output/public/_nuxt/{BG7XSX-S2.js → BG7XSX-S.js} +0 -0
- /package/.output/public/_nuxt/{BU7WuuKh.js → BU7WuuKh2.js} +0 -0
- /package/.output/public/_nuxt/{BrRX-l9B2.js → BrRX-l9B.js} +0 -0
- /package/.output/public/_nuxt/{CHyzK5m52.js → CHyzK5m5.js} +0 -0
- /package/.output/public/_nuxt/{Ckafrjnw2.js → Ckafrjnw.js} +0 -0
- /package/.output/public/_nuxt/{D1Xw30Dj2.js → D1Xw30Dj.js} +0 -0
- /package/.output/public/_nuxt/{DEhjFhZ2.js → DEhjFhZ22.js} +0 -0
- /package/.output/public/_nuxt/{DdNujZN5.js → DdNujZN52.js} +0 -0
- /package/.output/public/_nuxt/{DzwIZ81f.js → DzwIZ81f2.js} +0 -0
- /package/.output/public/_nuxt/{M6NcguDO.js → M6NcguDO2.js} +0 -0
- /package/.output/public/_nuxt/{MW-V7IIP2.js → MW-V7IIP.js} +0 -0
- /package/.output/public/_nuxt/{WmMwIS4y.js → WmMwIS4y2.js} +0 -0
- /package/.output/public/_nuxt/{qIQFsHtF.js → qIQFsHtF2.js} +0 -0
|
@@ -1,393 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* scripts/_audit/runtime-dir-e2e.mjs —— 运行时目录规约验收(A1-A6)。
|
|
4
|
-
*
|
|
5
|
-
* 验收规范:
|
|
6
|
-
* A1 目录优先级:cwd ./.AgentWorkShop(最高)> ~/.AgentWorkShop 兜底;AW_HOME/AW_AML_DIR 可显式覆盖
|
|
7
|
-
* A2 全产物落位配置根:data/、aml/{datasets,jobs,models,.venv,tools,runtime} 全在 <配置根>;检出根零新增
|
|
8
|
-
* A3 AML 训练产物入运行时目录:datasets/<id>/jobs/<id>/models/<id> 全在 <配置根>/aml,模型可读
|
|
9
|
-
* A4 uv 优先+启动预热:有 uv → 启动后自动后台创建 <配置根>/aml/.venv 并 ready(无 uv 回退 python -m venv)
|
|
10
|
-
* A5 清数据冷启动:删 data/aml 后重启全部自动重建;家目录兜底模式成立
|
|
11
|
-
* A6 更新链路:aw update --check 可用;配置根在包外 → 更新不触碰数据/模型/venv
|
|
12
|
-
*
|
|
13
|
-
* 流程:捕获真实 physics_spec → 预清(改名保留 *.pre-clean-20260927)→ repo 模式冷启 3467 →
|
|
14
|
-
* A2/A4 断言 → 注册 admin → 等 venv ready → 建线跑 4 批(4017 模拟器)→ A3 数据集+训练 →
|
|
15
|
-
* 家目录兜底实例 3468(临时 cwd)→ aw update --check → 清场。
|
|
16
|
-
*/
|
|
17
|
-
import { spawn, spawnSync } from 'node:child_process'
|
|
18
|
-
import { closeSync, existsSync, mkdtempSync, openSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs'
|
|
19
|
-
import { tmpdir, homedir } from 'node:os'
|
|
20
|
-
import { dirname, join, resolve } from 'node:path'
|
|
21
|
-
import { fileURLToPath } from 'node:url'
|
|
22
|
-
|
|
23
|
-
const REPO = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..')
|
|
24
|
-
const AW_PORT = 3467
|
|
25
|
-
const HOME_PORT = 3468
|
|
26
|
-
const SIM_PORT = 4017
|
|
27
|
-
const SIM_DIR = resolve(REPO, '..', 'plc-node-simulator-bench-4017')
|
|
28
|
-
const CONFIG_ROOT = join(REPO, '.AgentWorkShop')
|
|
29
|
-
const TODAY = '20260927'
|
|
30
|
-
let BASE = `http://127.0.0.1:${AW_PORT}`
|
|
31
|
-
const SIM = `http://127.0.0.1:${SIM_PORT}`
|
|
32
|
-
|
|
33
|
-
let pass = 0
|
|
34
|
-
const fails = []
|
|
35
|
-
const ok = (name, cond, detail = '') => {
|
|
36
|
-
if (cond) { pass++; console.log(` ✔ ${name}`) }
|
|
37
|
-
else { fails.push(name); console.log(` ✖ ${name}${detail ? ` — ${String(detail).slice(0, 240)}` : ''}`) }
|
|
38
|
-
}
|
|
39
|
-
const sleep = ms => new Promise(r => setTimeout(r, ms))
|
|
40
|
-
const getJson = async (url, token) => {
|
|
41
|
-
try {
|
|
42
|
-
const r = await fetch(url, { signal: AbortSignal.timeout(15000), headers: token ? { authorization: `Bearer ${token}` } : {} })
|
|
43
|
-
return await r.json()
|
|
44
|
-
}
|
|
45
|
-
catch { return null }
|
|
46
|
-
}
|
|
47
|
-
const killPort = (port) => {
|
|
48
|
-
try {
|
|
49
|
-
const psi = spawnSync('powershell', ['-NoProfile', '-Command',
|
|
50
|
-
`Get-NetTCPConnection -LocalPort ${port} -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty OwningProcess`], { encoding: 'utf8' })
|
|
51
|
-
const pid = Number(psi.stdout.trim())
|
|
52
|
-
if (Number.isInteger(pid) && pid > 0) spawnSync('taskkill', ['/PID', String(pid), '/T', '/F'], { stdio: 'ignore' })
|
|
53
|
-
}
|
|
54
|
-
catch { /* 尽力而为 */ }
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** 捕获既有真实 physics_spec(训练器 fail-closed 要求真实骨架;S0 重命名前取样,训练时空 nodeIds 重映射)。
|
|
58
|
-
* 候选:aml/jobs 与各 aml.pre-clean-NNN/jobs;优先含 artifacts 目录(已完成)的最新作业。 */
|
|
59
|
-
function captureRealSpec() {
|
|
60
|
-
const candidates = [join(REPO, 'aml', 'jobs'), ...readdirSync(REPO).filter(d => d.startsWith('aml.pre-clean-')).map(d => join(REPO, d, 'jobs'))]
|
|
61
|
-
for (const jobsDir of candidates) {
|
|
62
|
-
try {
|
|
63
|
-
if (!existsSync(jobsDir)) continue
|
|
64
|
-
const done = readdirSync(jobsDir, { withFileTypes: true })
|
|
65
|
-
.filter(d => d.isDirectory() && existsSync(join(jobsDir, d.name, 'artifacts')) && existsSync(join(jobsDir, d.name, 'physics_spec.json')))
|
|
66
|
-
.map(d => ({ name: d.name, m: statSync(join(jobsDir, d.name)).mtimeMs }))
|
|
67
|
-
.sort((a, b) => b.m - a.m)
|
|
68
|
-
if (done.length) return JSON.parse(readFileSync(join(jobsDir, done[0].name, 'physics_spec.json'), 'utf8'))
|
|
69
|
-
}
|
|
70
|
-
catch { /* 试下一个候选 */ }
|
|
71
|
-
}
|
|
72
|
-
return null
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/* ── S0 · 捕获 spec + 预清数据(改名保留,遵循 *.pre-clean-* 惯例)── */
|
|
76
|
-
console.log('[S0] 捕获真实 physics_spec + 预清运行时数据(改名保留)')
|
|
77
|
-
const realSpec = captureRealSpec()
|
|
78
|
-
ok('捕获真实 physics_spec(训练骨架样本)', Boolean(realSpec), realSpec ? `variables=${realSpec.variables?.length}` : 'aml/jobs 无历史作业')
|
|
79
|
-
for (const port of [AW_PORT, HOME_PORT, SIM_PORT]) killPort(port)
|
|
80
|
-
if (existsSync(join(REPO, 'aml'))) {
|
|
81
|
-
renameSync(join(REPO, 'aml'), join(REPO, `aml.pre-clean-${TODAY}`))
|
|
82
|
-
console.log(` · repo/aml → aml.pre-clean-${TODAY}`)
|
|
83
|
-
}
|
|
84
|
-
// 备份已存在 → 当前目录必是上一轮验收后的全新重建,直接清(真实数据早在首个备份里)
|
|
85
|
-
const moveAside = (src, label) => {
|
|
86
|
-
if (!existsSync(src)) return
|
|
87
|
-
const dst = join(dirname(src), `${label}.pre-clean-${TODAY}`)
|
|
88
|
-
if (existsSync(dst)) {
|
|
89
|
-
rmSync(src, { recursive: true, force: true })
|
|
90
|
-
console.log(` · ${label} → 已有备份 ${label}.pre-clean-${TODAY},当前(上次重建)直接清除`)
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
renameSync(src, dst)
|
|
94
|
-
console.log(` · ${label} → ${label}.pre-clean-${TODAY}`)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
moveAside(join(REPO, 'aml'), 'aml')
|
|
98
|
-
moveAside(join(CONFIG_ROOT, 'data'), 'data')
|
|
99
|
-
moveAside(join(CONFIG_ROOT, 'aml'), 'aml')
|
|
100
|
-
// 预置运行时设置:MCP 开关 + 门禁校准(placement 验收用松门禁;数据/模型落位与门禁强弱无关)
|
|
101
|
-
writeFileSync(join(CONFIG_ROOT, 'runtime-settings.json'), JSON.stringify({ version: 1, overrides: { 'mcp.enabled': true, 'aml.gates.nrmse': 0.9, 'aml.gates.rolloutNrmse': Number(process.env.RTD_GATE_ROLLOUT ?? 0.99), 'aml.gates.valTestGap': 2, 'aml.gates.minRows': 100 } }))
|
|
102
|
-
ok('A0 预清完成(检出根/aml 与配置根/data·aml 均已移除)', !existsSync(join(REPO, 'aml')) && !existsSync(join(CONFIG_ROOT, 'data')) && !existsSync(join(CONFIG_ROOT, 'aml')))
|
|
103
|
-
|
|
104
|
-
/* ── S1 · repo 模式冷启动(无 AW_HOME/AW_MODE,配置根=.AgentWorkShop)── */
|
|
105
|
-
console.log('[S1] repo 模式冷启动(配置根 = <repo>/.AgentWorkShop)')
|
|
106
|
-
{
|
|
107
|
-
const out = openSync(join(CONFIG_ROOT, 'boot-audit.log'), 'a')
|
|
108
|
-
const p = spawn(process.execPath, [join(REPO, 'bin', 'aw.mjs'), 'start', '--port', String(AW_PORT)], {
|
|
109
|
-
cwd: REPO,
|
|
110
|
-
env: { ...process.env, NO_PROXY: '127.0.0.1,localhost', HTTP_PROXY: '', HTTPS_PROXY: '', NUXT_SESSION_PASSWORD: 'runtime-dir-e2e-session-password-0123456' },
|
|
111
|
-
detached: true, windowsHide: true, stdio: ['ignore', out, out],
|
|
112
|
-
})
|
|
113
|
-
closeSync(out); p.unref()
|
|
114
|
-
}
|
|
115
|
-
let actualPort = AW_PORT
|
|
116
|
-
for (let i = 0; i < 20; i++) {
|
|
117
|
-
await sleep(1500)
|
|
118
|
-
try {
|
|
119
|
-
const lock = JSON.parse(readFileSync(join(CONFIG_ROOT, '.runtime', 'aw.lock'), 'utf8'))
|
|
120
|
-
if (Number.isInteger(lock?.port)) { actualPort = lock.port; break }
|
|
121
|
-
}
|
|
122
|
-
catch { /* 等锁 */ }
|
|
123
|
-
}
|
|
124
|
-
BASE = `http://127.0.0.1:${actualPort}`
|
|
125
|
-
let up = false
|
|
126
|
-
for (let i = 0; i < 40; i++) {
|
|
127
|
-
await sleep(2000)
|
|
128
|
-
if ((await getJson(`${BASE}/api/health`))?.data?.status === 'ok') { up = true; break }
|
|
129
|
-
}
|
|
130
|
-
ok('平台健康门', up, `BASE=${BASE} 日志 ${join(CONFIG_ROOT, 'boot-audit.log')}`)
|
|
131
|
-
if (!up) { console.log(`═══ ${pass} PASS / ${fails.length + 1} FAIL ═══`); process.exit(1) }
|
|
132
|
-
|
|
133
|
-
/* ── S2 · A2 全产物落位 + A4 预热已触发 ── */
|
|
134
|
-
console.log('[S2] A2 全产物落位配置根 + A4 启动预热触发')
|
|
135
|
-
let TOKEN = ''
|
|
136
|
-
{
|
|
137
|
-
ok('A2a data/ 重建于配置根', existsSync(join(CONFIG_ROOT, 'data')))
|
|
138
|
-
ok('A2b aml 骨架重建于配置根', ['datasets', 'jobs', 'models', 'tools', 'runtime'].every(s => existsSync(join(CONFIG_ROOT, 'aml', s))))
|
|
139
|
-
ok('A2c 检出根无 aml/ 运行时目录(零新增)', !existsSync(join(REPO, 'aml')))
|
|
140
|
-
|
|
141
|
-
for (let i = 0; i < 15; i++) {
|
|
142
|
-
try {
|
|
143
|
-
const r = await fetch(`${BASE}/api/users/register`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ name: 'runtime-audit', email: `runtime-${Date.now()}@awshop.local`, password: 'runtime-e2e-passw0rd' }) })
|
|
144
|
-
const j = await r.json()
|
|
145
|
-
if (j?.data?.token) { TOKEN = j.data.token; break }
|
|
146
|
-
}
|
|
147
|
-
catch { /* 服务未就绪,重试 */ }
|
|
148
|
-
await sleep(2000)
|
|
149
|
-
}
|
|
150
|
-
ok('admin 注册(全新库首注册即 admin)', Boolean(TOKEN))
|
|
151
|
-
const envInfo = await getJson(`${BASE}/api/workshop/aml/env`, TOKEN)
|
|
152
|
-
ok('A2d aml/env 报告运行时根', envInfo?.data?.amlRoot === join(CONFIG_ROOT, 'aml'), JSON.stringify({ root: envInfo?.data?.amlRoot, src: envInfo?.data?.amlRootSource }))
|
|
153
|
-
ok('A2e 来源标签=项目运行时根', /项目运行时根/.test(envInfo?.data?.amlRootSource ?? ''), envInfo?.data?.amlRootSource)
|
|
154
|
-
const bootLog = existsSync(join(CONFIG_ROOT, 'boot-audit.log')) ? readFileSync(join(CONFIG_ROOT, 'boot-audit.log'), 'utf8') : ''
|
|
155
|
-
ok('A4a 启动预热已触发(uv 探测+后台建环境)', bootLog.includes('[aml] 启动预热'), bootLog.split('\n').filter(l => l.includes('[aml]')).slice(-2).join(' | ') || '(无 [aml] 行)')
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/* ── S3 · A4 等 venv ready(uv 供给)── */
|
|
159
|
-
console.log('[S3] A4 等待训练环境就绪(uv 后台供给,最长 10 分钟)')
|
|
160
|
-
{
|
|
161
|
-
let ready = false
|
|
162
|
-
let last = ''
|
|
163
|
-
for (let i = 0; i < 60; i++) {
|
|
164
|
-
await sleep(10_000)
|
|
165
|
-
const st = await getJson(`${BASE}/api/workshop/aml/env`, TOKEN)
|
|
166
|
-
last = JSON.stringify({ ready: st?.data?.venv?.ready, task: st?.data?.task?.status, tail: st?.data?.task?.log?.slice(-1) })
|
|
167
|
-
if (st?.data?.venv?.ready) { ready = true; break }
|
|
168
|
-
}
|
|
169
|
-
ok('A4b .venv 在配置根就绪(uv 供给)', ready, last)
|
|
170
|
-
ok('A4c venv 落点在配置根内', existsSync(join(CONFIG_ROOT, 'aml', '.venv')), join(CONFIG_ROOT, 'aml', '.venv'))
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/* ── S4 · A3 训练产物入配置根(权威建线 → 4 批 → 数据集 → hybrid 训练 → 模型)── */
|
|
174
|
-
console.log('[S4] A3 训练产物入运行时目录(建线→4 批次→数据集→训练→模型)')
|
|
175
|
-
{
|
|
176
|
-
process.env.SIM_BASE = SIM
|
|
177
|
-
process.env.SIM_SHADOW_DIR = SIM_DIR
|
|
178
|
-
const { ensureSimulator, applyPreset } = await import('../../bench/lib/sim.mjs')
|
|
179
|
-
await ensureSimulator({ log: () => {} })
|
|
180
|
-
await applyPreset('cast-film-physics')
|
|
181
|
-
const simDevices = (await getJson(`${SIM}/api/nodes`))?.data ?? []
|
|
182
|
-
|
|
183
|
-
const { provisionTwinLine, startTwinBatch } = await import('../../bench/lib/closedloop.mjs')
|
|
184
|
-
const callA = async (method, path, body) => {
|
|
185
|
-
const r = await fetch(`${BASE}${path}`, { method, headers: { 'content-type': 'application/json', 'authorization': `Bearer ${TOKEN}` }, body: body === undefined ? undefined : JSON.stringify(body), signal: AbortSignal.timeout(60000) })
|
|
186
|
-
const json = await r.json().catch(() => null)
|
|
187
|
-
return { status: r.status, json, message: json?.message, data: json?.data }
|
|
188
|
-
}
|
|
189
|
-
const twin = await provisionTwinLine({ call: async (m, p, b) => { const r = await callA(m, p, b); return { status: r.status, data: r.data, message: r.message } } }, { simDevices, sfx: 'rtdir' })
|
|
190
|
-
ok('S4a 权威建线(6 DCW + 5 DAQ)', twin.ok, (twin.ev ?? []).join(' | ').slice(0, 200))
|
|
191
|
-
globalThis.__lineId = twin.lineId
|
|
192
|
-
|
|
193
|
-
const spReadback = {}
|
|
194
|
-
{
|
|
195
|
-
// SP 回读 DAQ 节点(two-modes 同款:export 取配置,http/mqtt 的 jsonKey 修成 jsonPath)
|
|
196
|
-
for (const dev of simDevices) {
|
|
197
|
-
const exp = (await getJson(`${SIM}/api/nodes/${dev.id}/export`))?.data?.items ?? []
|
|
198
|
-
for (const id of Object.keys(twin.dcw)) {
|
|
199
|
-
if (spReadback[id]) continue
|
|
200
|
-
const sig = (dev.signals ?? []).find(s => s.id === id)
|
|
201
|
-
if (!sig) continue
|
|
202
|
-
const item = exp.find(i => i.signal === sig.name)
|
|
203
|
-
if (!item?.driverConfig) continue
|
|
204
|
-
const cfg = { ...item.driverConfig }
|
|
205
|
-
if (cfg.jsonKey !== undefined && cfg.jsonPath === undefined) { cfg.jsonPath = cfg.jsonKey; delete cfg.jsonKey }
|
|
206
|
-
const r = await callA('POST', '/api/workshop/daq', {
|
|
207
|
-
name: `${sig.name} 回读 rtdir`, templateRef: 'daq-temp-tc', driver: dev.protocol, driverConfig: cfg,
|
|
208
|
-
unit: sig.unit, min: sig.min, max: sig.max, lineId: twin.lineId, intervalMs: 1000, publishIntervalMs: 0,
|
|
209
|
-
semantics: `执行器设定点回读(AML control 输入) ${item.signal}`,
|
|
210
|
-
})
|
|
211
|
-
spReadback[id] = r.json?.data?.node?.id ?? r.json?.data?.id
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
ok('S4a-2 SP 回读 DAQ ×6', Object.keys(spReadback).length === 6, JSON.stringify(spReadback))
|
|
216
|
-
// 膜厚语义补「目标 goal + 厚度」词表(scene 编译 target 识别依据;two-modes 同款 PATCH)
|
|
217
|
-
await callA('PATCH', `/api/workshop/daq/${twin.daq['film-thickness']}`, { semantics: '流延膜厚度测量(优化目标 goal,单位 μm;厚度质量输出)' })
|
|
218
|
-
await callA('POST', '/api/workshop/daq/controller', { action: 'start' })
|
|
219
|
-
const batch = await startTwinBatch({ call: async (m, p, b) => { const r = await callA(m, p, b); return { status: r.status, data: r.data, message: r.message } } }, { lineId: twin.lineId, productId: twin.productId, dcw: twin.dcw, sfx: 'rtdir' })
|
|
220
|
-
globalThis.__lineId = twin.lineId
|
|
221
|
-
ok('S4b 配方开跑(批次1)', batch.ok && Boolean(batch.recipeId), JSON.stringify(batch).slice(0, 140))
|
|
222
|
-
const recipeId = batch.recipeId
|
|
223
|
-
|
|
224
|
-
/* ── S4c 训练通道(hybrid_twin)+ 场景发现/编译/冻结 + 骨架 PhysicsSpec ── */
|
|
225
|
-
const scene = { sceneId: `runtime-dir-accept`, sceneVersion: '1.0.0', lineId: twin.lineId, productId: twin.productId, recipeId }
|
|
226
|
-
const inst = await callA('POST', '/api/workshop/channel-templates/chtpl-hybrid-twin-mpc-default/instantiate', {
|
|
227
|
-
name: `运行时目录训练通道 rtdir`, toolProfile: 'hybrid_twin', scene,
|
|
228
|
-
objective: { objectiveId: 'thickness-50um', targets: { film_thickness: 50 } },
|
|
229
|
-
controlPolicy: 'recommendation_only',
|
|
230
|
-
})
|
|
231
|
-
const instData = inst.json?.data ?? {}
|
|
232
|
-
const channelA = instData.channelId
|
|
233
|
-
const workerA = (instData.agents ?? []).find(a => a.role === 'worker')?.id
|
|
234
|
-
ok('S4c-1 训练通道实例化(hybrid_twin)+ worker', Boolean(channelA && workerA), JSON.stringify({ channelA, workerA }).slice(0, 120))
|
|
235
|
-
for (const nodeId of Object.values(twin.dcw)) await callA('POST', '/api/workshop/agent-tools/bindings', { agentId: workerA, nodeId, kind: 'dcw', mode: 'auto' })
|
|
236
|
-
for (const nodeId of Object.values(twin.daq)) await callA('POST', '/api/workshop/agent-tools/bindings', { agentId: workerA, nodeId, kind: 'daq', mode: 'auto' })
|
|
237
|
-
const invoke = async (tool, args, agentId) => {
|
|
238
|
-
const r = await callA('POST', '/api/workshop/agent-tools/invoke', { agentId, tool, args })
|
|
239
|
-
const result = r.json?.data?.result
|
|
240
|
-
return { isError: Boolean(result?.isError), text: String(result?.text ?? ''), data: result?.data ?? null }
|
|
241
|
-
}
|
|
242
|
-
const disco = await invoke('twin_scene_discover', {}, workerA)
|
|
243
|
-
ok('S4c-2 场景发现(target=1 语义命中)', !disco.isError && /"target"\s*:\s*1/.test(disco.text), disco.text.slice(0, 140))
|
|
244
|
-
const compiled = await invoke('twin_scene_compile', {
|
|
245
|
-
scene_id: scene.sceneId, scene_version: '1.0.0', line_id: twin.lineId, product_id: twin.productId, recipe_id: recipeId,
|
|
246
|
-
prompt: '流延膜厚度闭环优化:目标膜厚 50μm。控制=6 个执行器设定点,观测=膜厚(目标)/熔温/熔压。约束:熔温 195~225℃,熔压 ≤22MPa。膜厚为目标输出。',
|
|
247
|
-
}, workerA)
|
|
248
|
-
ok('S4c-3 场景编译', !compiled.isError, compiled.text.slice(0, 140))
|
|
249
|
-
const frozen = await invoke('twin_scene_freeze', {
|
|
250
|
-
scene_id: scene.sceneId, scene_version: '1.0.0', confirmation: 'USER_CONFIRMED_SCENE_CONTRACT', approved_by: 'runtime-dir-e2e',
|
|
251
|
-
}, workerA)
|
|
252
|
-
ok('S4c-4 场景冻结(用户确认令牌)', !frozen.isError, frozen.text.slice(0, 140))
|
|
253
|
-
const draft = await invoke('twin_physics_spec_draft', { dt_sec: 1 }, workerA)
|
|
254
|
-
const draftArtifactPath = (draft.text.match(/artifact:\s*([^\n]+)/) || [])[1]?.trim()
|
|
255
|
-
ok('S4c-5 骨架 PhysicsSpec 生成', !draft.isError && Boolean(draftArtifactPath) && existsSync(draftArtifactPath), draft.text.slice(0, 140))
|
|
256
|
-
const physicsSpec = JSON.parse(readFileSync(draftArtifactPath, 'utf8'))
|
|
257
|
-
const dwToDn = {}
|
|
258
|
-
for (const [sig, dn] of Object.entries(spReadback)) dwToDn[twin.dcw[sig]] = dn
|
|
259
|
-
console.log(' ↳ 批次1 采样积累 300s(物理滞后:阶跃全响应需要长批)')
|
|
260
|
-
await sleep(300_000)
|
|
261
|
-
|
|
262
|
-
/* ── S4d 4 个已闭合批次(每批 ~75s;首批已跑)── */
|
|
263
|
-
const closeAndRestart = async (i) => {
|
|
264
|
-
await callA('POST', `/api/workshop/dcw/lines/${twin.lineId}/stop`, {})
|
|
265
|
-
await sleep(3000)
|
|
266
|
-
const st = await callA('POST', `/api/workshop/dcw/lines/${twin.lineId}/start`, { recipeId })
|
|
267
|
-
if (st.status !== 200) { await sleep(8000); await callA('POST', `/api/workshop/dcw/lines/${twin.lineId}/start`, { recipeId }) }
|
|
268
|
-
console.log(` ↳ 批次 ${i} 闭合/重启`)
|
|
269
|
-
}
|
|
270
|
-
// 批次 2-4:每批 300s + 两次工况阶跃(+65s/+200s)。物理滞后(熔体延迟/热惯性)需要长批
|
|
271
|
-
// 才能看到阶跃的全响应;短批数据"输入已变输出未动"会毁掉一致性(实测 NRMSE>1 的根因)。
|
|
272
|
-
const BATCHES = [
|
|
273
|
-
{ n: 2, steps: [{ at: 65_000, node: 'linespeed-sp', v: 97 }, { at: 200_000, node: 'diegap-sp', v: 1.03 }] },
|
|
274
|
-
{ n: 3, steps: [{ at: 65_000, node: 'linespeed-sp', v: 93 }, { at: 200_000, node: 'diegap-sp', v: 0.97 }] },
|
|
275
|
-
{ n: 4, steps: [{ at: 65_000, node: 'linespeed-sp', v: 97 }, { at: 200_000, node: 'diegap-sp', v: 1.0 }] },
|
|
276
|
-
]
|
|
277
|
-
for (const b of BATCHES) {
|
|
278
|
-
await closeAndRestart(b.n) // 闭合上一批 → 新批配方下发(锚定 60s 冷却)
|
|
279
|
-
let prev = 0
|
|
280
|
-
for (const st of b.steps) {
|
|
281
|
-
await sleep(st.at - prev)
|
|
282
|
-
prev = st.at
|
|
283
|
-
const w = await callA('POST', `/api/workshop/dcw/${twin.dcw[st.node]}/write`, { value: st.v })
|
|
284
|
-
console.log(` ↳ 批次 ${b.n} 阶跃 ${st.node} ← ${st.v} ${w.status === 200 ? '√' : '✘ ' + String(w.json?.message ?? '').slice(0, 70)}`)
|
|
285
|
-
}
|
|
286
|
-
await sleep(300_000 - prev)
|
|
287
|
-
}
|
|
288
|
-
await callA('POST', `/api/workshop/dcw/lines/${twin.lineId}/stop`, {})
|
|
289
|
-
await sleep(3000)
|
|
290
|
-
|
|
291
|
-
const runs = (await callA('GET', '/api/workshop/dcw/recipes')).json?.data?.runs ?? []
|
|
292
|
-
const closed = runs.filter(x => x.endedAt && x.recipeId === recipeId)
|
|
293
|
-
ok('S4d 4 个已闭合批次', closed.length >= 4, `closed=${closed.length}`)
|
|
294
|
-
|
|
295
|
-
/* ── S4e 数据集(9 节点)+ spec 变量改绑回读 + 训练 + 模型 ── */
|
|
296
|
-
const ds = (await callA('POST', '/api/workshop/aml/datasets', {
|
|
297
|
-
lineId: twin.lineId, productId: twin.productId, recipeId,
|
|
298
|
-
nodes: [
|
|
299
|
-
...Object.values(spReadback).map(nid => ({ nodeId: nid, role: 'control' })),
|
|
300
|
-
{ nodeId: twin.daq['film-thickness'], role: 'target' },
|
|
301
|
-
{ nodeId: twin.daq['melt-pressure'], role: 'feature' },
|
|
302
|
-
{ nodeId: twin.daq['melt-temp'], role: 'feature' },
|
|
303
|
-
],
|
|
304
|
-
beatMs: 1000, window: { historySteps: 8, horizonSteps: 4 },
|
|
305
|
-
split: { valRatio: 0.34, testRatio: 0.33, seed: Number(process.env.RTD_SPLIT_SEED ?? 42) },
|
|
306
|
-
purpose: 'mpc_surrogate', note: '运行时目录规约验收数据集',
|
|
307
|
-
})).json?.data?.dataset
|
|
308
|
-
ok('S4e-1 数据集构建(9 变量对齐 spec)', Boolean(ds?.id) && ds.runIds?.length >= 4, JSON.stringify({ id: ds?.id, rows: ds?.rowCount, runs: ds?.runIds?.length }).slice(0, 140))
|
|
309
|
-
ok('A3a 数据集实体在配置根', existsSync(join(CONFIG_ROOT, 'aml', 'datasets', ds.id, 'manifest.json')), join(CONFIG_ROOT, 'aml', 'datasets', ds.id))
|
|
310
|
-
|
|
311
|
-
// 训练前对齐(two-modes 同款):spec 变量改绑回读节点 + 剔除数据集外变量
|
|
312
|
-
const man = JSON.parse(readFileSync(join(CONFIG_ROOT, 'aml', 'datasets', ds.id, 'manifest.json'), 'utf8'))
|
|
313
|
-
const datasetNodes = new Set(man.allNodes)
|
|
314
|
-
for (const v of physicsSpec.variables) {
|
|
315
|
-
if (v.nodeId && !datasetNodes.has(v.nodeId) && dwToDn[v.nodeId]) v.nodeId = dwToDn[v.nodeId]
|
|
316
|
-
}
|
|
317
|
-
const keptVars = physicsSpec.variables.filter(v => !v.nodeId || datasetNodes.has(v.nodeId))
|
|
318
|
-
const keptIds = new Set(keptVars.map(v => v.id))
|
|
319
|
-
physicsSpec.variables = keptVars
|
|
320
|
-
physicsSpec.states = physicsSpec.states.filter((e) => { const base = e.lhs.endsWith('_next') ? e.lhs.slice(0, -5) : e.lhs; return keptIds.has(base) })
|
|
321
|
-
physicsSpec.observations = physicsSpec.observations.filter(e => keptIds.has(e.lhs))
|
|
322
|
-
physicsSpec.guards = (physicsSpec.guards ?? []).filter(e => keptIds.has(e.lhs))
|
|
323
|
-
physicsSpec.constraints = physicsSpec.constraints.filter(c => keptIds.has(c.id))
|
|
324
|
-
|
|
325
|
-
const job = (await callA('POST', '/api/workshop/aml/jobs', {
|
|
326
|
-
datasetId: ds.id, purpose: 'mpc_surrogate', changeNote: '运行时目录规约验收训练',
|
|
327
|
-
params: { epochs: 600, hidden: 128, lr: 0.0015, residual_scale: 2, ensemble: 3 },
|
|
328
|
-
seed: 11, jobKind: 'hybrid_residual', sceneId: scene.sceneId, sceneVersion: '1.0.0', objectiveId: 'thickness-50um',
|
|
329
|
-
physicsSpec, providerId: physicsSpec.modelId, providerVersion: '1.0.0', providerHash: `sha256:${JSON.stringify(physicsSpec).length}`,
|
|
330
|
-
modelName: `运行时目录验收模型 rtdir`, modelDescription: 'A3 验收:模型工件应落在运行时目录',
|
|
331
|
-
})).json?.data?.job
|
|
332
|
-
ok('S4e-2 训练作业提交', Boolean(job?.id), JSON.stringify(job ?? {}).slice(0, 160))
|
|
333
|
-
|
|
334
|
-
let jobDone = null
|
|
335
|
-
for (let i = 0; i < 60; i++) {
|
|
336
|
-
await sleep(5000)
|
|
337
|
-
const r = await callA('GET', `/api/workshop/aml/jobs/${job.id}`)
|
|
338
|
-
jobDone = r.json?.data?.job
|
|
339
|
-
if (jobDone?.status === 'done' || jobDone?.status === 'failed') break
|
|
340
|
-
}
|
|
341
|
-
ok('S4f 训练完成(平台门禁全过)', jobDone?.status === 'done', `status=${jobDone?.status} err=${(jobDone?.error ?? '').slice(0, 160)}`)
|
|
342
|
-
const models = (await callA('GET', '/api/workshop/aml/models')).json?.data?.models ?? []
|
|
343
|
-
const model = models.find(m => m.datasetId === ds.id)
|
|
344
|
-
ok('A3b 模型注册且工件在配置根', Boolean(model?.id) && existsSync(join(CONFIG_ROOT, 'aml', 'models', model.id, 'model.onnx')), join(CONFIG_ROOT, 'aml', 'models', model?.id ?? '?'))
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/* ── S5 · A5 家目录兜底(临时 cwd 启动,真 ~/.AgentWorkShop)── */
|
|
348
|
-
console.log('[S5] A5 家目录兜底:临时 cwd 启动(无 AW_HOME/AW_MODE)')
|
|
349
|
-
{
|
|
350
|
-
const tempCwd = mkdtempSync(join(tmpdir(), 'aw-fallback-cwd-'))
|
|
351
|
-
const homeRoot = join(homedir(), '.AgentWorkShop')
|
|
352
|
-
const out = openSync(join(tempCwd, 'home-instance.log'), 'a')
|
|
353
|
-
const p = spawn(process.execPath, [join(REPO, 'bin', 'aw.mjs'), 'start', '--port', String(HOME_PORT)], {
|
|
354
|
-
cwd: tempCwd,
|
|
355
|
-
env: { ...process.env, NO_PROXY: '127.0.0.1,localhost', HTTP_PROXY: '', HTTPS_PROXY: '', NUXT_SESSION_PASSWORD: 'runtime-dir-e2e-session-password-0123456' },
|
|
356
|
-
detached: true, windowsHide: true, stdio: ['ignore', out, out],
|
|
357
|
-
})
|
|
358
|
-
closeSync(out); p.unref()
|
|
359
|
-
let hb = false
|
|
360
|
-
for (let i = 0; i < 40; i++) {
|
|
361
|
-
await sleep(2000)
|
|
362
|
-
if ((await getJson(`http://127.0.0.1:${HOME_PORT}/api/health`))?.data?.status === 'ok') { hb = true; break }
|
|
363
|
-
}
|
|
364
|
-
ok('A5a 家目录兜底实例健康(检出外 cwd)', hb, `日志 ${join(tempCwd, 'home-instance.log')}`)
|
|
365
|
-
await sleep(4000)
|
|
366
|
-
const bootLog = existsSync(join(tempCwd, 'home-instance.log')) ? readFileSync(join(tempCwd, 'home-instance.log'), 'utf8') : ''
|
|
367
|
-
ok('A5b 兜底实例同样触发 AML 环境预热', bootLog.includes('[aml] 启动预热'), bootLog.split('\n').filter(l => l.includes('[aml]')).slice(-1).join('') || '(无)')
|
|
368
|
-
ok('A5c 数据/AML 落 ~/.AgentWorkShop', existsSync(join(homeRoot, 'data')) && existsSync(join(homeRoot, 'aml', 'datasets')))
|
|
369
|
-
killPort(HOME_PORT)
|
|
370
|
-
try { rmSync(tempCwd, { recursive: true, force: true, maxRetries: 3, retryDelay: 1500 }) } catch { /* 实例句柄延迟释放,允许残留 */ }
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/* ── S6 · A6 更新链路 ── */
|
|
374
|
-
console.log('[S6] A6 更新链路:aw update --check(npm registry 对比)')
|
|
375
|
-
{
|
|
376
|
-
const r = spawnSync(process.execPath, [join(REPO, 'bin', 'aw.mjs'), 'update', '--check'], { cwd: REPO, encoding: 'utf8', timeout: 120_000, shell: true })
|
|
377
|
-
const out = `${r.stdout ?? ''}${r.stderr ?? ''}`
|
|
378
|
-
ok('A6 aw update --check 正常执行(版本对比/网络说明)', r.status === 0 || /latest|version|registry|npm|网络|超时/i.test(out), out.slice(0, 200))
|
|
379
|
-
ok('A6b 配置根在包外(更新不触碰数据/模型/venv——设计断言)', !resolve(REPO, '.output').startsWith(join(homedir(), '.AgentWorkShop')) && existsSync(join(CONFIG_ROOT, 'aml', '.venv')))
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
/* ── 清场 ── */
|
|
383
|
-
console.log('[清场]')
|
|
384
|
-
killPort(actualPort)
|
|
385
|
-
killPort(SIM_PORT)
|
|
386
|
-
await sleep(1500)
|
|
387
|
-
console.log(` · 保留新初始化的运行时目录(${CONFIG_ROOT})与 aml.pre-clean-${TODAY}/data.pre-clean-${TODAY} 备份`)
|
|
388
|
-
|
|
389
|
-
console.log('')
|
|
390
|
-
console.log(`═══ 运行时目录规约验收:${pass} PASS / ${fails.length} FAIL ═══`)
|
|
391
|
-
for (const f of fails) console.log(` ✖ ${f}`)
|
|
392
|
-
console.log('')
|
|
393
|
-
process.exit(fails.length ? 1 : 0)
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* town-focus-shot.mjs —— 只拍数字孪生,并尝试把 3D 视角调到能看清设备
|
|
3
|
-
* 用 window.__townStats 读真实渲染指标(设备数/实例数/FPS)作为"模型真的在场"的判据,
|
|
4
|
-
* 而不是靠肉眼看截图。
|
|
5
|
-
*/
|
|
6
|
-
import { existsSync, mkdirSync } from 'node:fs'
|
|
7
|
-
import { dirname, join, resolve } from 'node:path'
|
|
8
|
-
import { fileURLToPath } from 'node:url'
|
|
9
|
-
import puppeteer from 'puppeteer-core'
|
|
10
|
-
|
|
11
|
-
const HERE = dirname(fileURLToPath(import.meta.url))
|
|
12
|
-
const REPO = resolve(HERE, '..', '..')
|
|
13
|
-
const arg = (k, d) => {
|
|
14
|
-
const i = process.argv.indexOf(`--${k}`)
|
|
15
|
-
return i > 0 && process.argv[i + 1] ? process.argv[i + 1] : d
|
|
16
|
-
}
|
|
17
|
-
const BASE = arg('base', 'http://127.0.0.1:3112').replace(/\/$/, '')
|
|
18
|
-
const OUT = arg('out', join(REPO, '.e2e-shots', 'plc-clean'))
|
|
19
|
-
const EDGE = 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe'
|
|
20
|
-
const CHROME = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
|
|
21
|
-
const EXEC = existsSync(EDGE) ? EDGE : CHROME
|
|
22
|
-
const sleep = ms => new Promise(r => setTimeout(r, ms))
|
|
23
|
-
|
|
24
|
-
mkdirSync(OUT, { recursive: true })
|
|
25
|
-
const login = await fetch(`${BASE}/api/users/login`, {
|
|
26
|
-
method: 'POST',
|
|
27
|
-
headers: { 'content-type': 'application/json' },
|
|
28
|
-
body: JSON.stringify({ email: 'plant@awshop.local', password: 'Plant!2026' }),
|
|
29
|
-
}).then(r => r.json()).catch(() => null)
|
|
30
|
-
const token = login?.data?.token ?? ''
|
|
31
|
-
if (!token) { console.error('✖ 登录失败'); process.exit(2) }
|
|
32
|
-
|
|
33
|
-
const browser = await puppeteer.launch({
|
|
34
|
-
executablePath: EXEC,
|
|
35
|
-
headless: 'new',
|
|
36
|
-
args: ['--no-sandbox', '--disable-dev-shm-usage', '--force-device-scale-factor=1', '--hide-scrollbars', '--use-gl=angle', '--enable-unsafe-swiftshader'],
|
|
37
|
-
defaultViewport: { width: 1920, height: 1200 },
|
|
38
|
-
})
|
|
39
|
-
try {
|
|
40
|
-
const page = await browser.newPage()
|
|
41
|
-
await page.goto(`${BASE}/town`, { waitUntil: 'domcontentloaded', timeout: 60_000 })
|
|
42
|
-
await page.evaluate((tok) => {
|
|
43
|
-
document.cookie = `token=${encodeURIComponent(tok)}; path=/`
|
|
44
|
-
document.cookie = 'aw-theme=light; path=/'
|
|
45
|
-
localStorage.setItem('app', JSON.stringify({ isDark: false, sidebarCollapsed: true, accent: '', themeTouched: true }))
|
|
46
|
-
}, token)
|
|
47
|
-
await page.reload({ waitUntil: 'networkidle2', timeout: 60_000 })
|
|
48
|
-
// 3D 首帧 + 模型 GLB 异步加载,给足时间
|
|
49
|
-
await sleep(12000)
|
|
50
|
-
|
|
51
|
-
const stats = await page.evaluate(() => {
|
|
52
|
-
const s = globalThis.__townStats
|
|
53
|
-
return s ? JSON.parse(JSON.stringify(s)) : null
|
|
54
|
-
})
|
|
55
|
-
console.log('window.__townStats =', JSON.stringify(stats))
|
|
56
|
-
|
|
57
|
-
// 尝试点「复位视角」把相机拉到能看全设备的位置(按钮存在才点)
|
|
58
|
-
const resetBtn = await page.evaluateHandle(() => {
|
|
59
|
-
const els = [...document.querySelectorAll('button, .ant-btn, [role="button"]')]
|
|
60
|
-
return els.find(e => /复位视角|重置视角|复位/.test(e.textContent ?? '')) ?? null
|
|
61
|
-
})
|
|
62
|
-
const el = resetBtn.asElement()
|
|
63
|
-
if (el) {
|
|
64
|
-
await el.click().catch(() => {})
|
|
65
|
-
console.log('已点击「复位视角」')
|
|
66
|
-
await sleep(3500)
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
console.log('未找到「复位视角」按钮,跳过')
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// 相机默认拉得很远,设备只有几十像素;点几次放大让设备读得清
|
|
73
|
-
const zoomIn = await page.evaluateHandle(() => {
|
|
74
|
-
const els = [...document.querySelectorAll('button, .ant-btn, [role="button"], [class*="zoom"]')]
|
|
75
|
-
return els.find((e) => {
|
|
76
|
-
const txt = (e.textContent ?? '').trim()
|
|
77
|
-
const title = `${e.getAttribute('title') ?? ''} ${e.getAttribute('aria-label') ?? ''}`
|
|
78
|
-
return txt === '+' || txt === '+' || /放大|zoom in/i.test(title)
|
|
79
|
-
}) ?? null
|
|
80
|
-
})
|
|
81
|
-
const z = zoomIn.asElement()
|
|
82
|
-
const ZOOM_CLICKS = Number(arg('zoom', '2'))
|
|
83
|
-
if (z) {
|
|
84
|
-
for (let i = 0; i < ZOOM_CLICKS; i++) {
|
|
85
|
-
await z.click().catch(() => {})
|
|
86
|
-
await sleep(700)
|
|
87
|
-
}
|
|
88
|
-
console.log(`已放大 ${ZOOM_CLICKS} 档`)
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
console.log('未找到放大按钮,保持默认视角')
|
|
92
|
-
}
|
|
93
|
-
await sleep(1500)
|
|
94
|
-
|
|
95
|
-
const file = join(OUT, '数字孪生小镇-1920.png')
|
|
96
|
-
await page.screenshot({ path: file, fullPage: false })
|
|
97
|
-
console.log(`截图 → ${file}`)
|
|
98
|
-
|
|
99
|
-
// 再出一张只含 3D 视口的图:全页截图里场景只占一小块,细节看不出来
|
|
100
|
-
const viewport = await page.evaluate(() => {
|
|
101
|
-
const canvases = [...document.querySelectorAll('canvas')].map((c) => {
|
|
102
|
-
const r = c.getBoundingClientRect()
|
|
103
|
-
return { w: r.width, h: r.height, x: r.x, y: r.y }
|
|
104
|
-
}).filter(c => c.w > 200 && c.h > 200)
|
|
105
|
-
canvases.sort((a, b) => b.w * b.h - a.w * a.h)
|
|
106
|
-
const c = canvases[0]
|
|
107
|
-
if (!c) return null
|
|
108
|
-
// 把 HUD(统计条/趋势/控制面板)也算进去,给出完整场景区
|
|
109
|
-
return { x: Math.max(0, c.x - 10), y: Math.max(0, c.y - 60), width: c.w + 20, height: c.h + 80 }
|
|
110
|
-
})
|
|
111
|
-
if (viewport) {
|
|
112
|
-
const sceneFile = join(OUT, '数字孪生小镇-3D视口.png')
|
|
113
|
-
await page.screenshot({ path: sceneFile, clip: viewport })
|
|
114
|
-
console.log(`3D 视口截图 → ${sceneFile} ${JSON.stringify(viewport)}`)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const canvasInfo = await page.evaluate(() => {
|
|
118
|
-
const cs = [...document.querySelectorAll('canvas')].map((c) => {
|
|
119
|
-
const r = c.getBoundingClientRect()
|
|
120
|
-
return `${c.width}x${c.height} css ${Math.round(r.width)}x${Math.round(r.height)}`
|
|
121
|
-
})
|
|
122
|
-
return cs
|
|
123
|
-
})
|
|
124
|
-
console.log('canvases:', JSON.stringify(canvasInfo))
|
|
125
|
-
console.log(stats && (stats.devices ?? stats.deviceCount) ? '✅ 场景内确有设备实例' : '⚠ __townStats 未暴露设备计数,以截图为准')
|
|
126
|
-
}
|
|
127
|
-
finally {
|
|
128
|
-
await browser.close()
|
|
129
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* town-reposition.mjs —— 把设备孪生收拢到默认相机取景范围内
|
|
3
|
-
* 起因:posX/posZ 用的是场景世界坐标,初版按"米"给了 ±14,实际远在默认视锥之外 ——
|
|
4
|
-
* __townStats 显示 devices=12(实例确实存在),但画面里几乎看不到。
|
|
5
|
-
* 这里按小坐标重新落位,并顺带把频道领地收紧。
|
|
6
|
-
*/
|
|
7
|
-
const BASE = (() => {
|
|
8
|
-
const i = process.argv.indexOf('--base')
|
|
9
|
-
return (i > 0 ? process.argv[i + 1] : 'http://127.0.0.1:3112').replace(/\/$/, '')
|
|
10
|
-
})()
|
|
11
|
-
|
|
12
|
-
let TOKEN = null
|
|
13
|
-
const api = async (method, path, { body } = {}) => {
|
|
14
|
-
const headers = { 'content-type': 'application/json' }
|
|
15
|
-
if (TOKEN) headers.authorization = `Bearer ${TOKEN}`
|
|
16
|
-
const res = await fetch(`${BASE}${path}`, { method, headers, body: body !== undefined ? JSON.stringify(body) : undefined })
|
|
17
|
-
return { status: res.status, ...(await res.json().catch(() => ({}))) }
|
|
18
|
-
}
|
|
19
|
-
const data = r => r?.data ?? {}
|
|
20
|
-
|
|
21
|
-
TOKEN = data(await api('POST', '/api/users/login', { body: { email: 'plant@awshop.local', password: 'Plant!2026' } })).token
|
|
22
|
-
if (!TOKEN) { console.error('✖ 登录失败'); process.exit(2) }
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* 三组工艺设备:围绕**世界中心**一字排开。
|
|
26
|
-
* ⚠️ 这里是世界坐标,不是"米":shared/town-scene-math.ts 里
|
|
27
|
-
* WORLD_W=3200 / WORLD_H=2400,相机看向 (WORLD_CX, WORLD_CZ) = (1600, 1200)。
|
|
28
|
-
* 初版按 ±14 给坐标 → 设备落在世界原点那一角,相机根本看不到
|
|
29
|
-
* (__townStats 仍报 devices=12,但画面里只有一个位于世界中心的物体)。
|
|
30
|
-
*/
|
|
31
|
-
const CX = 1600
|
|
32
|
-
const CZ = 1200
|
|
33
|
-
const PLAN = [
|
|
34
|
-
{ match: /挤出主机/, posX: CX - 120, posZ: CZ - 70 },
|
|
35
|
-
{ match: /收卷机组/, posX: CX, posZ: CZ - 70 },
|
|
36
|
-
{ match: /MDO/, posX: CX + 120, posZ: CZ - 70 },
|
|
37
|
-
{ match: /配电柜/, posX: CX - 120, posZ: CZ + 80 },
|
|
38
|
-
{ match: /机械臂/, posX: CX, posZ: CZ + 80 },
|
|
39
|
-
{ match: /测厚仪/, posX: CX + 120, posZ: CZ + 80 },
|
|
40
|
-
]
|
|
41
|
-
/** 数采/数控节点也参与场景渲染(伪孪生),它们的 posX/posZ 同样要对齐世界中心 */
|
|
42
|
-
const NODE_PLAN = [
|
|
43
|
-
{ match: /温度采集/, posX: CX - 120, posZ: CZ - 70 },
|
|
44
|
-
{ match: /速度采集/, posX: CX, posZ: CZ - 70 },
|
|
45
|
-
{ match: /张力采集/, posX: CX + 120, posZ: CZ - 70 },
|
|
46
|
-
{ match: /温度设定/, posX: CX - 120, posZ: CZ + 80 },
|
|
47
|
-
{ match: /速度设定/, posX: CX, posZ: CZ + 80 },
|
|
48
|
-
{ match: /张力设定/, posX: CX + 120, posZ: CZ + 80 },
|
|
49
|
-
]
|
|
50
|
-
|
|
51
|
-
const twins = data(await api('GET', '/api/workshop/device-twins')).twins ?? []
|
|
52
|
-
console.log(`孪生实体 ${twins.length} 个`)
|
|
53
|
-
let moved = 0
|
|
54
|
-
for (const tw of twins) {
|
|
55
|
-
const plan = PLAN.find(p => p.match.test(tw.name))
|
|
56
|
-
if (!plan) continue
|
|
57
|
-
const r = await api('PATCH', `/api/workshop/device-twins/${tw.id}`, { body: { posX: plan.posX, posZ: plan.posZ, rotationY: 0 } })
|
|
58
|
-
const okr = r.code === 0 || (r.status >= 200 && r.status < 300)
|
|
59
|
-
console.log(` ${okr ? '✔' : '✖'} ${tw.name} → (${plan.posX}, ${plan.posZ})`)
|
|
60
|
-
if (okr) moved++
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// 数采/数控节点:它们的 posX/posZ 决定场景里的伪孪生落点
|
|
64
|
-
let movedNodes = 0
|
|
65
|
-
for (const [ep, plan] of [['daq', NODE_PLAN], ['dcw', NODE_PLAN]]) {
|
|
66
|
-
const nodes = data(await api('GET', `/api/workshop/${ep}`)).nodes ?? []
|
|
67
|
-
for (const n of nodes) {
|
|
68
|
-
const p = plan.find(x => x.match.test(n.name))
|
|
69
|
-
if (!p) continue
|
|
70
|
-
const r = await api('PATCH', `/api/workshop/${ep}/${n.id}`, { body: { posX: p.posX, posZ: p.posZ } })
|
|
71
|
-
const okr = r.code === 0 || (r.status >= 200 && r.status < 300)
|
|
72
|
-
if (okr) movedNodes++
|
|
73
|
-
console.log(` ${okr ? '✔' : '✖'} [${ep}] ${n.name} → (${p.posX}, ${p.posZ})`)
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// 频道领地铺在世界中心,让地面环与设备尺度匹配
|
|
78
|
-
const chans = data(await api('GET', '/api/workshop/channels'))
|
|
79
|
-
const ch = (Array.isArray(chans) ? chans : (chans.channels ?? []))[0]
|
|
80
|
-
if (ch) {
|
|
81
|
-
const r = await api('PUT', `/api/workshop/scene/layouts/${ch.id}`, { body: { x: CX, z: CZ, radiusX: 260, radiusZ: 180, shape: 'ellipse' } })
|
|
82
|
-
console.log(` 领地铺在世界中心 (${CX}, ${CZ}) radius 260×180 (code=${r.code})`)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
console.log(`\n${moved === PLAN.length && movedNodes === 6 ? '✅' : '⚠'} 孪生 ${moved}/${PLAN.length} · 节点 ${movedNodes}/6 已重排`)
|