agentworkshop 0.7.24 → 0.7.33
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/aml-mission-default.md +20 -0
- package/.AgentWorkShop/prompts/aml-playbook.md +49 -0
- package/.AgentWorkShop/prompts/host-tools.json +314 -0
- package/.output/.AgentWorkShop/prompts/aml-mission-default.md +20 -0
- package/.output/.AgentWorkShop/prompts/aml-playbook.md +49 -0
- package/.output/.AgentWorkShop/prompts/host-tools.json +314 -0
- package/.output/.AgentWorkShop/schema.json +120 -0
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/{Djir5rSD.js → 4bHdIqEg.js} +8 -8
- package/.output/public/_nuxt/B7gZokg82.js +209 -0
- package/.output/public/_nuxt/B9nXmjSB.js +19 -0
- package/.output/public/_nuxt/BASN8nZ0.js +1 -0
- package/.output/public/_nuxt/{DNQF_TXX.js → BBBtwOpo.js} +1 -1
- package/.output/public/_nuxt/{DoAlYsiF.js → BBwMH_hG.js} +1 -1
- package/.output/public/_nuxt/BWSE6hR6.js +1 -0
- package/.output/public/_nuxt/BZv4RFYN.js +1 -0
- package/.output/public/_nuxt/Bc0AmjfT.js +1 -0
- package/.output/public/_nuxt/BcmbLh2z2.js +1 -0
- package/.output/public/_nuxt/BgTB6h_q.js +2 -0
- package/.output/public/_nuxt/BkLJA9J5.js +1 -0
- package/.output/public/_nuxt/{CuVGPuP1.js → BuCHayqN.js} +1 -1
- package/.output/public/_nuxt/{0jKrzLuM.js → BuvcLKh1.js} +1 -1
- package/.output/public/_nuxt/C-mDhyEd.js +1 -0
- package/.output/public/_nuxt/{Ct68Z0232.js → C77oC8yC2.js} +2 -2
- package/.output/public/_nuxt/CQvmN-Mi.js +1 -0
- package/.output/public/_nuxt/CUDrOuW7.js +1 -0
- package/.output/public/_nuxt/{Coik560n.js → CZcC-gpk.js} +1 -1
- package/.output/public/_nuxt/{Cz9gD2Yo.js → CbzsPO5H.js} +1 -1
- package/.output/public/_nuxt/CdSOrh2c.js +1 -0
- package/.output/public/_nuxt/Cgx818r-.js +1 -0
- package/.output/public/_nuxt/Cjm7VogC.js +1 -0
- package/.output/public/_nuxt/Cm5mDxzH.js +1 -0
- package/.output/public/_nuxt/Cp6z0RN7.js +1 -0
- package/.output/public/_nuxt/Ct-WOVr4.js +1 -0
- package/.output/public/_nuxt/CwqIxJGj.js +2 -0
- package/.output/public/_nuxt/{BMb80_tm.js → D0fhp-Ga.js} +2 -2
- package/.output/public/_nuxt/DIaTPH1M.js +1 -0
- package/.output/public/_nuxt/DLljr7g0.js +1 -0
- package/.output/public/_nuxt/DTYBfjRY.js +1 -0
- package/.output/public/_nuxt/DYKVPzN-.js +1 -0
- package/.output/public/_nuxt/DZzGarBE2.js +13 -0
- package/.output/public/_nuxt/DaMCzQhv.js +1 -0
- package/.output/public/_nuxt/DoMxCWN52.js +4 -0
- package/.output/public/_nuxt/{kZV5TQvh2.js → DoTdlVVe2.js} +1 -1
- package/.output/public/_nuxt/DsVcWfyR.js +1 -0
- package/.output/public/_nuxt/{BCJFMBQ6.js → DzuC31-i.js} +2 -2
- package/.output/public/_nuxt/FQri3dV3.js +1 -0
- package/.output/public/_nuxt/Lp7Ll94I.js +1 -0
- package/.output/public/_nuxt/PluginSlot.DmjNbrcX.css +1 -0
- package/.output/public/_nuxt/{TownView.zu2rU5nS.css → TownView.CtskuMXS.css} +1 -1
- package/.output/public/_nuxt/_id_.hRYo-EAB.css +1 -0
- package/.output/public/_nuxt/_wsId_.gXMEOYgX.css +1 -0
- package/.output/public/_nuxt/agents.BV70ioCv.css +1 -0
- package/.output/public/_nuxt/aml.WU_bh87J.css +1 -0
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/291ef3e6-fa6a-4dee-8f46-05da1aeab815.json +1 -0
- package/.output/public/_nuxt/daq.Bb6l44-O.css +1 -0
- package/.output/public/_nuxt/default.jNT73_hq.css +1 -0
- package/.output/public/_nuxt/ekuGmQ7R.js +1 -0
- package/.output/public/_nuxt/entry.jFrFAWuA.css +1 -0
- package/.output/public/_nuxt/pMoIO6rr.js +14 -0
- package/.output/public/_nuxt/pages.Cc8GX9T1.css +1 -0
- package/.output/public/_nuxt/plugins.wIPyfPn-.css +1 -0
- package/.output/public/_nuxt/settings.BCm4NZIc.css +1 -0
- package/.output/public/_nuxt/teams.BC75EGnR.css +1 -0
- package/.output/public/assets/game/character/yangyang-walk.glb +0 -0
- package/.output/server/chunks/_/binding-authz.mjs +23 -0
- package/.output/server/chunks/_/binding-authz.mjs.map +1 -0
- 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 +14422 -7551
- package/.output/server/chunks/_/nitro.mjs.map +1 -1
- package/.output/server/chunks/_/scene-layout.repo.mjs +3 -3
- package/.output/server/chunks/_/scene-layout.repo.mjs.map +1 -1
- package/.output/server/chunks/build/Checkbox-eax2M3o-.mjs +207 -0
- package/.output/server/chunks/build/Checkbox-eax2M3o-.mjs.map +1 -0
- package/.output/server/chunks/build/{OmpTerminalPanel-Cw_Vw9oO.mjs → OmpTerminalPanel-Cu_s4i0A.mjs} +2 -2
- package/.output/server/chunks/build/{OmpTerminalPanel-Cw_Vw9oO.mjs.map → OmpTerminalPanel-Cu_s4i0A.mjs.map} +1 -1
- package/.output/server/chunks/build/{alert-qJnjyRcP.mjs → PluginSlot-CcR4Ys3T.mjs} +140 -4
- package/.output/server/chunks/build/PluginSlot-CcR4Ys3T.mjs.map +1 -0
- package/.output/server/chunks/build/{TownView-DxeQe1Bl.mjs → TownView-BdHnAilw.mjs} +178 -151
- package/.output/server/chunks/build/{TownView-DxeQe1Bl.mjs.map → TownView-BdHnAilw.mjs.map} +1 -1
- package/.output/server/chunks/build/{_id_-DY6v6sqB.mjs → _id_-Cb845FHR.mjs} +7 -5
- package/.output/server/chunks/build/_id_-Cb845FHR.mjs.map +1 -0
- package/.output/server/chunks/build/{_id_-DQDqj-cZ.mjs → _id_-fadFPl2i.mjs} +50 -35
- package/.output/server/chunks/build/_id_-fadFPl2i.mjs.map +1 -0
- package/.output/server/chunks/build/{_wsId_-D38Vx6Ky.mjs → _wsId_-CTZswnm5.mjs} +181 -22
- package/.output/server/chunks/build/{_wsId_-D38Vx6Ky.mjs.map → _wsId_-CTZswnm5.mjs.map} +1 -1
- package/.output/server/chunks/build/{agents-GnmUGZir.mjs → agents-Bvin73QY.mjs} +82 -32
- package/.output/server/chunks/build/agents-Bvin73QY.mjs.map +1 -0
- package/.output/server/chunks/build/aml-uBNIppIf.mjs +508 -0
- package/.output/server/chunks/build/aml-uBNIppIf.mjs.map +1 -0
- package/.output/server/chunks/build/apiClient-BwnfOQU8.mjs +81 -0
- package/.output/server/chunks/build/apiClient-BwnfOQU8.mjs.map +1 -0
- package/.output/server/chunks/build/{channel-templates-B4z6v8Z5.mjs → channel-templates-BTq8570n.mjs} +6 -5
- package/.output/server/chunks/build/channel-templates-BTq8570n.mjs.map +1 -0
- package/.output/server/chunks/build/{checkbox-dzcpU_Cd.mjs → checkbox-8fB-wI-T.mjs} +5 -5
- package/.output/server/chunks/build/{checkbox-dzcpU_Cd.mjs.map → checkbox-8fB-wI-T.mjs.map} +1 -1
- package/.output/server/chunks/build/{daq-B-3xCp_2.mjs → daq-BvihjQyW.mjs} +314 -426
- package/.output/server/chunks/build/daq-BvihjQyW.mjs.map +1 -0
- package/.output/server/chunks/build/{dcw-BL2dhuz7.mjs → dcw-Ks2vJ4PF.mjs} +5 -3
- package/.output/server/chunks/build/dcw-Ks2vJ4PF.mjs.map +1 -0
- package/.output/server/chunks/build/{default-CLf5m0NE.mjs → default-GgHt4O2R.mjs} +164 -101
- package/.output/server/chunks/build/{default-CLf5m0NE.mjs.map → default-GgHt4O2R.mjs.map} +1 -1
- package/.output/server/chunks/build/{input-number-Bd55elNN.mjs → input-number-DzpyYB99.mjs} +2 -2
- package/.output/server/chunks/build/{input-number-Bd55elNN.mjs.map → input-number-DzpyYB99.mjs.map} +1 -1
- package/.output/server/chunks/build/{logs-Dto_umFY.mjs → logs-CYBhkQwh.mjs} +5 -3
- package/.output/server/chunks/build/logs-CYBhkQwh.mjs.map +1 -0
- package/.output/server/chunks/build/{monitor-Cp4V-H2n.mjs → monitor-CyfDt4nR.mjs} +7 -6
- package/.output/server/chunks/build/{monitor-Cp4V-H2n.mjs.map → monitor-CyfDt4nR.mjs.map} +1 -1
- package/.output/server/chunks/build/{pages-Dc2H1QFu.mjs → pages-C-6BRtv8.mjs} +57 -47
- package/.output/server/chunks/build/pages-C-6BRtv8.mjs.map +1 -0
- package/.output/server/chunks/build/{permissions-BTRW2CVd.mjs → permissions-B52oOmaO.mjs} +6 -5
- package/.output/server/chunks/build/permissions-B52oOmaO.mjs.map +1 -0
- package/.output/server/chunks/build/{plugins-DZR0T4Mh.mjs → plugins-dZRegC7m.mjs} +22 -18
- package/.output/server/chunks/build/plugins-dZRegC7m.mjs.map +1 -0
- package/.output/server/chunks/build/{segmented-LPPREMtZ.mjs → segmented-3TrWo0lS.mjs} +3 -3
- package/.output/server/chunks/build/{segmented-LPPREMtZ.mjs.map → segmented-3TrWo0lS.mjs.map} +1 -1
- package/.output/server/chunks/build/settings-CgDLkP3s.mjs +1171 -0
- package/.output/server/chunks/build/settings-CgDLkP3s.mjs.map +1 -0
- package/.output/server/chunks/build/{table-Cswq-l2r.mjs → table-BjSWwmic.mjs} +4 -4
- package/.output/server/chunks/build/{table-Cswq-l2r.mjs.map → table-BjSWwmic.mjs.map} +1 -1
- package/.output/server/chunks/build/{tag-NO9jEqKy.mjs → tag-DNE9vXc0.mjs} +3 -131
- package/.output/server/chunks/build/tag-DNE9vXc0.mjs.map +1 -0
- package/.output/server/chunks/build/{teams-Cbg27MWW.mjs → teams-2kz3CusY.mjs} +350 -49
- package/.output/server/chunks/build/teams-2kz3CusY.mjs.map +1 -0
- package/.output/server/chunks/build/{tokens-Bmm6rDfj.mjs → tokens-BbWLqtVz.mjs} +6 -5
- package/.output/server/chunks/build/tokens-BbWLqtVz.mjs.map +1 -0
- package/.output/server/chunks/build/town-BUqRobze.mjs +1 -0
- package/.output/server/chunks/build/town-BUqRobze.mjs.map +1 -1
- package/.output/server/chunks/build/{town-Dsh0jlwZ.mjs → town-DJ-V5G9U.mjs} +7 -5
- package/.output/server/chunks/build/town-DJ-V5G9U.mjs.map +1 -0
- package/.output/server/chunks/build/{useDaqStream-DkRL3tEW.mjs → useDaqStream-CIBaiGAl.mjs} +27 -11
- package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs.map +1 -0
- package/.output/server/chunks/build/{useDcwStream-DyB2ufQI.mjs → useDcwStream-CBbiYnWe.mjs} +16 -84
- package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs.map +1 -0
- package/.output/server/chunks/build/{useDeviceTwins-ZbT86L9O.mjs → useDeviceTwins-Yko6nNPF.mjs} +2 -2
- package/.output/server/chunks/build/{useDeviceTwins-ZbT86L9O.mjs.map → useDeviceTwins-Yko6nNPF.mjs.map} +1 -1
- package/.output/server/chunks/build/{useOpsLog-8HCYFb6n.mjs → useOpsLog-CO_VWh7t.mjs} +2 -2
- package/.output/server/chunks/build/{useOpsLog-8HCYFb6n.mjs.map → useOpsLog-CO_VWh7t.mjs.map} +1 -1
- package/.output/server/chunks/build/{useWorkshopApi-D2gq06N2.mjs → useWorkshopApi-NyjL0L3j.mjs} +11 -2
- package/.output/server/chunks/build/{useWorkshopApi-D2gq06N2.mjs.map → useWorkshopApi-NyjL0L3j.mjs.map} +1 -1
- package/.output/server/chunks/build/{users-B50HHrfi.mjs → users-4nzxTjFT.mjs} +6 -5
- package/.output/server/chunks/build/users-4nzxTjFT.mjs.map +1 -0
- package/.output/server/chunks/build/workshop-81xhz368.mjs +1 -0
- package/.output/server/chunks/build/workshop-81xhz368.mjs.map +1 -1
- package/.output/server/chunks/routes/api/health.get.mjs +1 -0
- package/.output/server/chunks/routes/api/health.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get.mjs +1 -1
- package/.output/server/chunks/routes/api/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/metrics.mjs +1 -0
- package/.output/server/chunks/routes/api/metrics.mjs.map +1 -1
- package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +15 -2
- package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs.map +1 -1
- package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs +1 -0
- package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/plugins/i18n.get.mjs +26 -0
- package/.output/server/chunks/routes/api/plugins/i18n.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/plugins/manifest.get.mjs +2 -1
- package/.output/server/chunks/routes/api/plugins/manifest.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/config-groups/_id_.delete.mjs +32 -0
- package/.output/server/chunks/routes/api/system/config-groups/_id_.delete.mjs.map +1 -0
- package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs +36 -0
- package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs.map +1 -0
- package/.output/server/chunks/routes/api/system/config.get.mjs +1 -0
- package/.output/server/chunks/routes/api/system/config.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/index.get.mjs +7 -2
- package/.output/server/chunks/routes/api/system/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/index.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/system/index.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/index.post.mjs +36 -0
- package/.output/server/chunks/routes/api/system/index.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/system/index2.get.mjs +28 -0
- package/.output/server/chunks/routes/api/system/index2.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs +2 -1
- package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs +2 -1
- package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/monitor.get.mjs +1 -0
- package/.output/server/chunks/routes/api/system/monitor.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/settings/events.get.mjs +8 -5
- package/.output/server/chunks/routes/api/system/settings/events.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/settings/reset.post.mjs +2 -1
- package/.output/server/chunks/routes/api/system/settings/reset.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/users/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/users/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/_id_.put.mjs +1 -1
- package/.output/server/chunks/routes/api/users/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/users/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/users/login.post.mjs +1 -1
- package/.output/server/chunks/routes/api/users/logout.post.mjs +2 -1
- package/.output/server/chunks/routes/api/users/logout.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/me.get.mjs +2 -1
- package/.output/server/chunks/routes/api/users/me.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/register.post.mjs +1 -1
- package/.output/server/chunks/routes/api/users/setup-status.get.mjs +2 -1
- package/.output/server/chunks/routes/api/users/setup-status.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs +2 -1
- package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/_...path_.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/_...path_.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs +5 -2
- package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +9 -3
- package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +23 -3
- package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +21 -3
- package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs +75 -0
- package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +35 -0
- package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs +35 -0
- package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs +46 -0
- package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs +47 -0
- package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs +48 -0
- package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs +41 -0
- package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs +62 -0
- package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs +35 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs +36 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs +34 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs +38 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs +37 -0
- package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs +42 -0
- package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/audit.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/audit.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/caller.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/caller.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +2 -2
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs.map +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 +41 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.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.get.mjs +22 -9
- package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs.map +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 +34 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/channels.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels.post.mjs +16 -2
- package/.output/server/chunks/routes/api/workshop/channels.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +3 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +2 -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 +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +2 -1
- 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/_id_.patch.mjs +7 -2
- package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +32 -1
- package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +3 -2
- package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index.put.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/index.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index10.get.mjs +12 -6
- package/.output/server/chunks/routes/api/workshop/index10.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index11.get.mjs +4 -2
- package/.output/server/chunks/routes/api/workshop/index11.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index12.get.mjs +28 -0
- package/.output/server/chunks/routes/api/workshop/index12.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/index2.get.mjs +17 -11
- package/.output/server/chunks/routes/api/workshop/index2.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index2.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index3.get.mjs +11 -4
- package/.output/server/chunks/routes/api/workshop/index3.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index3.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/index3.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index4.get.mjs +5 -27
- package/.output/server/chunks/routes/api/workshop/index4.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index4.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/index4.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index5.get.mjs +24 -18
- package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index5.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/index5.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index6.get.mjs +23 -5
- package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index6.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/index6.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index7.get.mjs +4 -17
- package/.output/server/chunks/routes/api/workshop/index7.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index7.post.mjs +8 -3
- package/.output/server/chunks/routes/api/workshop/index7.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index8.get.mjs +20 -21
- package/.output/server/chunks/routes/api/workshop/index8.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index8.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index9.get.mjs +24 -11
- package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/runtime.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/runtime.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/tasks.get.mjs.map +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.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +44 -0
- package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +47 -0
- package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/users/me.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/users/me.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/users/register.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -2
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/renderer.mjs +2 -2
- package/.output/server/chunks/virtual/entry.mjs +933 -449
- package/.output/server/chunks/virtual/entry.mjs.map +1 -1
- package/.output/server/chunks/virtual/precomputed.mjs +1 -1
- package/.output/server/index.mjs +1 -0
- package/.output/server/node_modules/@anthropic-ai/claude-agent-sdk/package.json +84 -0
- package/.output/server/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs +225 -0
- package/.output/server/package.json +2 -1
- package/README-zh.md +507 -478
- package/README.md +517 -486
- package/app/app.vue +17 -2
- package/app/assets/css/main.css +421 -30
- package/app/components/AppHeader.vue +17 -0
- package/app/components/AppSidebar.vue +162 -63
- package/app/components/AwChart.vue +57 -54
- package/app/components/workshop/ChannelSessionList.vue +802 -703
- package/app/components/workshop/DaqNodeRow.vue +554 -0
- package/app/components/workshop/PluginSlot.vue +120 -0
- package/app/components/workshop/town/ModelPreview3D.vue +26 -4
- package/app/components/workshop/town/TownScene3D.ts +60 -12
- package/app/components/workshop/town/TownView.vue +4 -3
- package/app/composables/workshop/useAmlStream.ts +136 -0
- package/app/composables/workshop/useCharacterAssets.ts +1 -0
- package/app/composables/workshop/useDaqStream.ts +32 -6
- package/app/composables/workshop/useDcwStream.ts +13 -4
- package/app/composables/workshop/usePluginPanels.ts +72 -0
- package/app/composables/workshop/useWorkshopApi.ts +301 -259
- package/app/pages/aml/index.vue +1949 -0
- package/app/pages/daq/[id].vue +86 -4
- package/app/pages/daq/index.vue +15 -503
- package/app/pages/index.vue +235 -213
- package/app/pages/plugins/index.vue +280 -274
- package/app/pages/settings.vue +807 -79
- package/app/pages/workshop/agents.vue +23 -1
- package/app/pages/workshop/teams.vue +212 -2
- package/app/plugins/aw-plugins.client.ts +95 -6
- package/app/plugins/runtime-config.client.ts +4 -14
- package/app/plugins/theme.client.ts +13 -3
- package/app/stores/app.ts +9 -2
- package/app/stores/runtime-config.ts +113 -7
- package/cli/aw.mjs +16 -3
- package/cli/commands/build.mjs +8 -8
- package/cli/commands/dev.mjs +5 -13
- package/cli/commands/init.mjs +1 -1
- package/cli/commands/start.mjs +10 -17
- package/cli/core/args.mjs +85 -4
- package/cli/core/child-lifecycle.mjs +136 -0
- package/config.yml +24 -0
- package/docs/plugins.md +128 -220
- package/docs/sdk.md +1 -1
- package/i18n/dicts/_en.json +403 -2
- package/i18n/dicts/aml.json +163 -0
- package/i18n/dicts/channelSessionList.json +4 -1
- package/i18n/dicts/daqDetail.json +1 -0
- package/i18n/dicts/plugins.json +10 -0
- package/i18n/dicts/settings.json +34 -1
- package/i18n/dicts/teamPlugins.json +10 -0
- package/i18n/dicts/teams.json +9 -1
- package/i18n/locales/en.ts +2059 -1867
- package/i18n/locales/zh-CN.ts +2059 -1868
- package/nuxt.config.ts +18 -3
- package/package.json +7 -2
- package/public/assets/game/character/yangyang-walk.glb +0 -0
- package/scripts/_audit/.tmp/audit-data/dcws.json +28 -0
- package/scripts/_audit/.tmp/dcw-writes.json +15650 -0
- package/scripts/_audit/.tmp/dcws.json +9033 -0
- package/scripts/_audit/.tmp/pollution-backup/dcw-rollback.polluted.json +470006 -0
- package/scripts/_audit/.tmp/pollution-backup/dcws.polluted.json +9085 -0
- package/scripts/_audit/.tmp/probe-cwd.txt +1 -0
- package/scripts/_audit/audit-harness-adapters.md +664 -0
- package/scripts/_audit/awhome/commands/README.md +3 -0
- package/scripts/_audit/awhome/commands/hello.mjs +12 -0
- package/scripts/_audit/dcw-controller-e2e.ts +99 -0
- package/scripts/_audit/dcw-flush-cost.ts +43 -0
- package/scripts/_audit/dcw-rollback-ledger.ts +153 -0
- package/scripts/_audit/dcw-unrecorded-write.ts +171 -0
- package/scripts/_audit/dcw-write-mutex.ts +157 -0
- package/scripts/_audit/diag-cwd.ts +20 -0
- package/scripts/_audit/diag-cwd2.ts +19 -0
- package/scripts/_audit/exp-cost-scaling.mjs +54 -0
- package/scripts/_audit/exp-envelope-and-png.mjs +77 -0
- package/scripts/_audit/exp-png-decode.mjs +67 -0
- package/scripts/_audit/exp-retention-plan.mjs +61 -0
- package/scripts/_audit/exp-retention-rescan.mjs +42 -0
- package/scripts/_audit/exp-sweep-fairness.mjs +48 -0
- package/scripts/_audit/hello.mjs +12 -0
- package/scripts/_audit/http-api-authz-audit.md +657 -0
- package/scripts/_audit/ndjson-partial-line-repro.mjs +77 -0
- package/scripts/_audit/opencode-await-ternary-repro.mjs +20 -0
- package/scripts/_audit/part-frag.txt +84 -0
- package/scripts/_audit/part-head.txt +45 -0
- package/scripts/_audit/probe-binding.mjs +103 -0
- package/scripts/_audit/probe-child.mjs +17 -0
- package/scripts/_audit/probe-envelope.mjs +49 -0
- package/scripts/_audit/probe-packlist.mjs +67 -0
- package/scripts/_audit/probe-routes.mjs +47 -0
- package/scripts/_audit/probe-routes2.mjs +38 -0
- package/scripts/_audit/probe.ts +9 -0
- package/scripts/_audit/probe2.ts +6 -0
- package/scripts/_audit/probe3.ts +3 -0
- package/scripts/_audit/probe4.ts +3 -0
- package/scripts/_audit/proj/.AgentWorkShop/commands/echoargs.mjs +13 -0
- package/scripts/_audit/proj/config.yml +1 -0
- package/scripts/_audit/run.mjs +30 -0
- package/scripts/_audit/runtime-audit.md +716 -0
- package/scripts/_audit/ts-resolve-hook.mjs +41 -0
- package/scripts/_audit/tsconfig.probe.json +24 -0
- package/scripts/_audit/typecheck-out.txt +466 -0
- package/scripts/_audit/verify-data-integrity.mjs +112 -0
- package/scripts/_dbg-agents-dropdown-shot.py +33 -0
- package/scripts/_dbg-anim-verify.mjs +1 -1
- package/scripts/_dbg-audit-all-pages.mjs +1 -1
- package/scripts/_dbg-availability-probe.ts +11 -0
- package/scripts/_dbg-bind-bidi-e2e.mjs +1 -1
- package/scripts/_dbg-cf-line-shot.mjs +18 -0
- package/scripts/_dbg-channel-plugin-ui.mjs +94 -0
- package/scripts/_dbg-configroot-audit.mjs +84 -0
- package/scripts/_dbg-cpu-profile.mjs +53 -0
- package/scripts/_dbg-crash-recovery.mjs +1 -1
- package/scripts/_dbg-crush-probe.sh +21 -0
- package/scripts/_dbg-crush-spawn-probe.ts +22 -0
- package/scripts/_dbg-daq-acc-probe.mjs +1 -1
- package/scripts/_dbg-daq-attrib.mjs +1 -1
- package/scripts/_dbg-daq-debug.mjs +1 -1
- package/scripts/_dbg-daq-diag.mjs +1 -1
- package/scripts/_dbg-daq-e2e.mjs +1 -1
- package/scripts/_dbg-daq-filter-e2e.mjs +1 -1
- package/scripts/_dbg-daq-filter-e2e2.mjs +1 -1
- package/scripts/_dbg-daq-final-regression.mjs +1 -1
- package/scripts/_dbg-daq-frame-alarm.mjs +1 -1
- package/scripts/_dbg-daq-frame-ui.mjs +1 -1
- package/scripts/_dbg-daq-frame-ws.mjs +1 -1
- package/scripts/_dbg-daq-frames-e2e.mjs +1 -1
- package/scripts/_dbg-daq-full-check.mjs +1 -1
- package/scripts/_dbg-daq-intervals-func.mjs +94 -0
- package/scripts/_dbg-daq-pages-shot.mjs +1 -1
- package/scripts/_dbg-daq-perf.mjs +1 -1
- package/scripts/_dbg-daq-probe.mjs +1 -1
- package/scripts/_dbg-daq-recipe-e2e.mjs +1 -1
- package/scripts/_dbg-daq-rows-probe.mjs +1 -1
- package/scripts/_dbg-daq-rowstate-e2e.mjs +1 -1
- package/scripts/_dbg-daq-rowstate-shot.mjs +1 -1
- package/scripts/_dbg-daq-rowstate-shot2.mjs +1 -1
- package/scripts/_dbg-daq-rowstyle-verify.mjs +112 -0
- package/scripts/_dbg-dash-console-check.mjs +1 -1
- package/scripts/_dbg-dash-deep-probe.mjs +1 -1
- package/scripts/_dbg-dash-hitpoint.mjs +1 -1
- package/scripts/_dbg-dcw-read-rest.mjs +1 -1
- package/scripts/_dbg-dcw-read-ui.mjs +1 -1
- package/scripts/_dbg-dcw-shot2.mjs +1 -1
- package/scripts/_dbg-diag-mock-loop.mjs +89 -0
- package/scripts/_dbg-diag-watch.mjs +95 -0
- package/scripts/_dbg-error-probe.mjs +2 -2
- package/scripts/_dbg-filter-light-verify.mjs +1 -1
- package/scripts/_dbg-final-acceptance-2.mjs +1 -1
- package/scripts/_dbg-final-acceptance.mjs +1 -1
- package/scripts/_dbg-final-full-e2e.mjs +1 -1
- package/scripts/_dbg-final-shots.mjs +32 -0
- package/scripts/_dbg-final-t6-hitl.mjs +1 -1
- package/scripts/_dbg-fix-unused-imports.py +41 -0
- package/scripts/_dbg-fresh-scene-e2e.mjs +1 -1
- package/scripts/_dbg-goose-probe.mjs +33 -0
- package/scripts/_dbg-goose-probe.sh +10 -0
- package/scripts/_dbg-groups-ui-verify.mjs +122 -0
- package/scripts/_dbg-harness-ui-shot.py +109 -0
- package/scripts/_dbg-hidden-check.mjs +1 -1
- package/scripts/_dbg-home-repro.mjs +1 -1
- package/scripts/_dbg-home-stack.mjs +1 -1
- package/scripts/_dbg-hydration-detail.mjs +1 -1
- package/scripts/_dbg-infra-lifecycle.mjs +1 -1
- package/scripts/_dbg-line-live-e2e.mjs +1 -1
- package/scripts/_dbg-line-repo-test.ts +10 -0
- package/scripts/_dbg-login-debug.py +23 -0
- package/scripts/_dbg-modbus-latency.mjs +22 -0
- package/scripts/_dbg-mqtt-chain-e2e.mjs +1 -1
- package/scripts/_dbg-oneshot-impl-probe.ts +67 -0
- package/scripts/_dbg-opt-team-e2e.mjs +1 -1
- package/scripts/_dbg-panesplitter-fix-check.mjs +1 -1
- package/scripts/_dbg-phase-e3-monitor.mjs +1 -1
- package/scripts/_dbg-pi-spawn-probe.ts +33 -0
- package/scripts/_dbg-plc-e2e.mjs +1 -1
- package/scripts/_dbg-plugin-config-ui.mjs +111 -0
- package/scripts/_dbg-plugin-panels-ui.mjs +54 -0
- package/scripts/_dbg-plugin-sink-rest.mjs +1 -1
- package/scripts/_dbg-plugin-sink-ui.mjs +1 -1
- package/scripts/_dbg-plugin-ui-wizard.mjs +1 -1
- package/scripts/_dbg-plugin-verify-e2e.mjs +1 -1
- package/scripts/_dbg-pop-clamp-verify.mjs +1 -1
- package/scripts/_dbg-preview-console.mjs +1 -1
- package/scripts/_dbg-preview-minrepro.mjs +1 -1
- package/scripts/_dbg-preview-pixels.mjs +1 -1
- package/scripts/_dbg-quality-pages-e2e.mjs +1 -1
- package/scripts/_dbg-qwen-acp-probe.mjs +30 -0
- package/scripts/_dbg-qwen-capture.mjs +21 -0
- package/scripts/_dbg-rail-tree-e2e.mjs +1 -1
- package/scripts/_dbg-real-driver-e2e.mjs +1 -1
- package/scripts/_dbg-real-scenario-timeline.log +55 -123
- package/scripts/_dbg-redesign-shots.mjs +1 -1
- package/scripts/_dbg-release-smoke.mjs +1 -1
- package/scripts/_dbg-render-perf.mjs +142 -0
- package/scripts/_dbg-render-regression.mjs +130 -0
- package/scripts/_dbg-resolve-probe.ts +6 -0
- package/scripts/_dbg-restart-persist.mjs +1 -1
- package/scripts/_dbg-sc001-dispatch.mjs +1 -1
- package/scripts/_dbg-scenario-final-shot.mjs +1 -1
- package/scripts/_dbg-scenario-phase-e2.mjs +1 -1
- package/scripts/_dbg-scenario-phase-e3.mjs +1 -1
- package/scripts/_dbg-scenario-phase1.mjs +1 -1
- package/scripts/_dbg-scenario-phase2.mjs +1 -1
- package/scripts/_dbg-scenario-phase3-monitor.mjs +1 -1
- package/scripts/_dbg-scenario-phase3.mjs +1 -1
- package/scripts/_dbg-settings-draft-probe.mjs +39 -0
- package/scripts/_dbg-settings-probe.mjs +33 -0
- package/scripts/_dbg-task-cancel-probe.mjs +66 -0
- package/scripts/_dbg-town-alarm-e2e.mjs +1 -1
- package/scripts/_dbg-town-daq-shot.mjs +1 -1
- package/scripts/_dbg-town-full-e2e.mjs +1 -1
- package/scripts/_dbg-town-gate.mjs +1 -1
- package/scripts/_dbg-town-ins-probe.mjs +1 -1
- package/scripts/_dbg-town-perf.mjs +1 -1
- package/scripts/_dbg-town-realtime.mjs +1 -1
- package/scripts/_dbg-town-shot.py +25 -0
- package/scripts/_dbg-town-shot3.mjs +1 -1
- package/scripts/_dbg-town-smoke.mjs +54 -0
- package/scripts/_dbg-town-truth.mjs +1 -1
- package/scripts/_dbg-town-truth2.mjs +1 -1
- package/scripts/_dbg-trend-expand-test.mjs +1 -1
- package/scripts/_dbg-twindaq-focus.mjs +1 -1
- package/scripts/_dbg-ui-polish-shot.mjs +1 -1
- package/scripts/_dbg-ui-polish-verify1.mjs +1 -1
- package/scripts/_dbg-ui-polish-verify2.mjs +1 -1
- package/scripts/_dbg-ui-polish-verify3.mjs +1 -1
- package/scripts/_dbg-ui-polish-verify4.mjs +1 -1
- package/scripts/_dbg-unify-shot.mjs +1 -1
- package/scripts/_dbg-uplink-probe.mjs +1 -1
- package/scripts/_dbg-wizard-preview-shot.mjs +1 -1
- package/scripts/_dbg-wizard-ui-e2e.mjs +1 -1
- package/scripts/_dbg-ws-probe.mjs +1 -1
- package/scripts/_dbg-wsdot-sanity.mjs +1 -1
- package/scripts/_node-state-probe.mjs +1 -1
- package/scripts/_tmp-args-probe.mjs +20 -0
- package/scripts/_tmp-cyc-entry.mjs +8 -0
- package/scripts/_tmp-cyc-main.mjs +5 -0
- package/scripts/_tmp-cyc-mod.mjs +2 -0
- package/scripts/_tmp-cycle-a.mjs +6 -0
- package/scripts/_tmp-cycle-b.mjs +2 -0
- package/scripts/_tmp-cycle-probe.mjs +4 -0
- package/scripts/_tmp-entry-variant.mjs +2 -0
- package/scripts/_tmp-help-probe.mjs +19 -0
- package/scripts/_tmp-help-probe2.mjs +2 -0
- package/scripts/_tmp-trace-preload.mjs +1 -0
- package/scripts/aml-agent-bridge.ts +230 -0
- package/scripts/aml-industrial-loop.ts +232 -0
- package/scripts/aml-ui-smoke.mjs +67 -0
- package/scripts/aw-start-smoke.mjs +194 -0
- package/scripts/design-verify-templates.mjs +1 -1
- package/scripts/device-line-restore.mjs +1 -1
- package/scripts/e2e-aml.ts +259 -0
- package/scripts/e2e-config-groups.mjs +238 -0
- package/scripts/e2e-full-closedloop.mjs +911 -0
- package/scripts/e2e-full-scenario.ts +321 -0
- package/scripts/e2e-harness-consistency.ts +204 -0
- package/scripts/e2e-multi-harness.ts +233 -76
- package/scripts/e2e-plc-plugin-closedloop.mjs +518 -0
- package/scripts/e2e-real-scenario.mjs +466 -452
- package/scripts/e2e-template-isolation.mjs +2 -2
- package/scripts/experiment-castfilm-closedloop.mjs +423 -0
- package/scripts/experiment-castfilm-finish.mjs +194 -0
- package/scripts/experiment-castfilm-ui-shot.mjs +52 -0
- package/scripts/experiment-castfilm-viz.mjs +172 -0
- package/scripts/i18n-merge.mjs +152 -30
- package/scripts/production-closed-loop-e2e.mjs +300 -0
- package/scripts/team-plugins-api-smoke.mjs +149 -0
- package/scripts/test-aml-integration.ts +159 -0
- package/scripts/test-aml-job.ts +174 -0
- package/scripts/test-aml-unit.ts +184 -0
- package/scripts/test-cli-exit.mjs +235 -0
- package/scripts/test-daq-frame-race.mjs +310 -0
- package/scripts/test-data-root.mjs +208 -0
- package/scripts/test-log-flooding.mjs +160 -0
- package/scripts/test-lru.mjs +78 -0
- package/scripts/test-memory-month-query.mjs +62 -0
- package/scripts/test-plugin-hardening.mjs +45 -0
- package/scripts/test-rollback-index.mjs +79 -0
- package/scripts/test-sdk-surface.mjs +155 -0
- package/scripts/three-system-e2e.mjs +662 -0
- package/scripts/town-scene-clear.mjs +1 -1
- package/sdk/client.d.mts +110 -0
- package/sdk/client.mjs +144 -124
- package/sdk/context.mjs +161 -1
- package/sdk/index.d.mts +37 -5
- package/sdk/index.mjs +44 -41
- package/sdk/lifecycle.mjs +4 -1
- package/server/api/plugins/[name]/[...path].ts +46 -31
- package/server/api/plugins/i18n.get.ts +12 -0
- package/server/api/system/config-groups/[id].delete.ts +21 -0
- package/server/api/system/config-groups/[id].patch.ts +26 -0
- package/server/api/system/config-groups/index.get.ts +21 -0
- package/server/api/system/config-groups/index.post.ts +33 -0
- package/server/api/system/settings/events.get.ts +8 -4
- package/server/api/workshop/agent-tools/bindings/[id].delete.ts +6 -1
- package/server/api/workshop/agent-tools/bindings/[id].patch.ts +12 -3
- package/server/api/workshop/agent-tools/bindings/index.get.ts +29 -2
- package/server/api/workshop/agent-tools/invoke.post.ts +30 -5
- package/server/api/workshop/aml/datasets/[id]/preview.get.ts +68 -0
- package/server/api/workshop/aml/datasets/[id].get.ts +24 -0
- package/server/api/workshop/aml/datasets/index.get.ts +20 -0
- package/server/api/workshop/aml/datasets/index.post.ts +27 -0
- package/server/api/workshop/aml/experiments/index.get.ts +35 -0
- package/server/api/workshop/aml/index.get.ts +24 -0
- package/server/api/workshop/aml/jobs/[id]/cancel.post.ts +21 -0
- package/server/api/workshop/aml/jobs/[id]/logs.get.ts +23 -0
- package/server/api/workshop/aml/jobs/[id]/retry.post.ts +20 -0
- package/server/api/workshop/aml/jobs/[id].get.ts +23 -0
- package/server/api/workshop/aml/jobs/index.get.ts +26 -0
- package/server/api/workshop/aml/jobs/index.post.ts +44 -0
- package/server/api/workshop/aml/models/[id]/predict.post.ts +24 -0
- package/server/api/workshop/aml/models/[id]/promote.post.ts +30 -0
- package/server/api/workshop/aml/models/index.get.ts +48 -0
- package/server/api/workshop/channels/[id]/plugins/index.get.ts +35 -0
- package/server/api/workshop/channels/[id]/plugins/index.put.ts +39 -0
- package/server/api/workshop/channels.post.ts +17 -0
- package/server/api/workshop/daq/[id].delete.ts +6 -0
- package/server/api/workshop/dcw/[id].patch.ts +14 -2
- package/server/api/workshop/hitl/respond.post.ts +3 -1
- package/server/api/workshop/teams/[id]/plugins/index.get.ts +36 -0
- package/server/api/workshop/teams/[id]/plugins/index.put.ts +42 -0
- package/server/api/workshop/teams/index.post.ts +13 -0
- package/server/api/workshop/users/me.get.ts +5 -0
- package/server/api/workshop/ws.ts +14 -2
- package/server/data/daqs.json +1648 -123
- package/server/data/dcw-lines.json +308 -0
- package/server/data/dcw-products.json +147 -0
- package/server/data/dcw-recipes.json +891 -1
- package/server/data/dcw-rollback.json +11903 -5540
- package/server/data/dcw-runs.json +3745 -3559
- package/server/data/dcw-templates.json +120 -0
- package/server/data/dcw-writes.json +1872 -0
- package/server/data/dcws.json +1723 -434
- package/server/data/line-runs.json +137 -27
- package/server/data/scene-layouts.json +66 -0
- package/server/harness/pi-aw-tools.mjs +51 -0
- package/server/plugins/aw-plugins.ts +35 -27
- package/server/plugins/dev-stability-guard.ts +63 -63
- package/server/plugins/system-config.ts +10 -11
- package/server/plugins/workshop.ts +10 -0
- package/server/plugins-builtin/diag-bridge/client.mjs +84 -0
- package/server/plugins-builtin/diag-bridge/i18n.json +72 -0
- package/server/plugins-builtin/diag-bridge/index.mjs +661 -0
- package/server/plugins-builtin/rag-bridge/client.mjs +108 -0
- package/server/plugins-builtin/rag-bridge/i18n.json +60 -0
- package/server/plugins-builtin/rag-bridge/index.mjs +411 -0
- package/server/services/system-config.ts +610 -396
- package/server/services/workshop/agents/adapters/line-spawn.ts +15 -6
- package/server/services/workshop/agents/adapters/one-shot-cli-agent.ts +530 -0
- package/server/services/workshop/agents/base-agent.ts +210 -0
- package/server/services/workshop/agents/binding-authz.ts +57 -0
- package/server/services/workshop/agents/claude-agent.ts +546 -30
- package/server/services/workshop/agents/codex-agent.ts +729 -822
- package/server/services/workshop/agents/copilot-agent.ts +136 -0
- package/server/services/workshop/agents/crush-agent.ts +107 -0
- package/server/services/workshop/agents/cursor-agent.ts +102 -0
- package/server/services/workshop/agents/dsh-agent.ts +578 -670
- package/server/services/workshop/agents/gemini-agent.ts +121 -0
- package/server/services/workshop/agents/goose-agent.ts +98 -0
- package/server/services/workshop/agents/harness-models.ts +305 -270
- package/server/services/workshop/agents/hermes-agent.ts +528 -0
- package/server/services/workshop/agents/host-tool-bridge.ts +710 -642
- package/server/services/workshop/agents/industrial-tools.ts +659 -7
- package/server/services/workshop/agents/omp-agent.ts +1193 -1178
- package/server/services/workshop/agents/opencode-agent.ts +936 -987
- package/server/services/workshop/agents/pi-agent.ts +108 -0
- package/server/services/workshop/agents/plugin-tools.ts +10 -1
- package/server/services/workshop/agents/qwen-agent.ts +540 -0
- package/server/services/workshop/agents/registry.ts +117 -5
- package/server/services/workshop/agents/tool-approvals.ts +3 -3
- package/server/services/workshop/aml/aml.repo.ts +368 -0
- package/server/services/workshop/aml/clean.ts +120 -0
- package/server/services/workshop/aml/dataset-builder.ts +491 -0
- package/server/services/workshop/aml/gates.ts +121 -0
- package/server/services/workshop/aml/job-orchestrator.ts +650 -0
- package/server/services/workshop/aml/model-registry.ts +169 -0
- package/server/services/workshop/aml/predictor.ts +262 -0
- package/server/services/workshop/aml/python/aml_eval.py +171 -0
- package/server/services/workshop/aml/python/amlkit.py +120 -0
- package/server/services/workshop/aml/python/requirements.txt +7 -0
- package/server/services/workshop/aml/python/train-example.py +92 -0
- package/server/services/workshop/aml/python-runtime.ts +217 -0
- package/server/services/workshop/aml/retention.ts +98 -0
- package/server/services/workshop/aml/runtime.ts +45 -0
- package/server/services/workshop/aml/spec.ts +63 -0
- package/server/services/workshop/aml/stats.ts +140 -0
- package/server/services/workshop/daq/bus/mqtt.adapter.ts +8 -1
- package/server/services/workshop/daq/daq-controller.ts +147 -19
- package/server/services/workshop/daq/daq-node.repo.ts +13 -11
- package/server/services/workshop/daq/daq-runtime.ts +11 -0
- package/server/services/workshop/daq/drivers.ts +89 -8
- package/server/services/workshop/db/aml-team-seeds.ts +118 -0
- package/server/services/workshop/db/channel-plugins.repo.ts +91 -0
- package/server/services/workshop/db/database.ts +89 -1
- package/server/services/workshop/db/memory.repo.ts +31 -0
- package/server/services/workshop/db/user.repo.ts +9 -0
- package/server/services/workshop/dcw/dcw-controller.ts +33 -7
- package/server/services/workshop/dcw/dcw-line.repo.ts +5 -3
- package/server/services/workshop/dcw/dcw-node.repo.ts +4 -4
- package/server/services/workshop/dcw/dcw-product.repo.ts +8 -8
- package/server/services/workshop/dcw/dcw-recipe.repo.ts +6 -7
- package/server/services/workshop/dcw/dcw-runtime.ts +16 -2
- package/server/services/workshop/dcw/dcw-templates.ts +4 -4
- package/server/services/workshop/dcw/line-run.ts +5 -5
- package/server/services/workshop/dcw/recipe-rollback-manager.ts +3 -1
- package/server/services/workshop/dcw/recipe-rollback.repo.ts +155 -52
- package/server/services/workshop/logger.ts +145 -3
- package/server/services/workshop/plugins/host.mjs +857 -518
- package/server/services/workshop/prompts/loader.ts +32 -6
- package/server/services/workshop/runtime/manager.ts +3016 -2968
- package/server/services/workshop/runtime/scheduler-loop.ts +18 -1
- package/server/services/workshop/scene/scene-layout.repo.ts +5 -5
- package/server/services/workshop/settings.ts +64 -0
- package/shared/config/engine.mjs +5 -0
- package/shared/config/groups.mjs +220 -0
- package/shared/config/home.mjs +11 -2
- package/shared/config/schema.json +31 -2
- package/shared/daq-protocol.ts +6 -0
- package/shared/lru.mjs +94 -0
- package/shared/workshop-protocol.ts +2 -2
- package/.output/public/_nuxt/BAfp6tmu.js +0 -14
- package/.output/public/_nuxt/BUcmySDa2.js +0 -209
- package/.output/public/_nuxt/Bc-_IsBP.js +0 -19
- package/.output/public/_nuxt/BvNJUu3s.js +0 -1
- package/.output/public/_nuxt/BytVi9VX2.js +0 -4
- package/.output/public/_nuxt/C1CSiSBN.js +0 -1
- package/.output/public/_nuxt/CAGL7TNK.js +0 -1
- package/.output/public/_nuxt/CDLv-n51.js +0 -1
- package/.output/public/_nuxt/CJviSvm-.js +0 -1
- package/.output/public/_nuxt/CLZWFhZC.js +0 -1
- package/.output/public/_nuxt/CYzpZzB_.js +0 -1
- package/.output/public/_nuxt/Cb3SnTM8.js +0 -1
- package/.output/public/_nuxt/CjXIpPMR.js +0 -1
- package/.output/public/_nuxt/CxY6LfeN.js +0 -1
- package/.output/public/_nuxt/D6HDb-vN2.js +0 -1
- package/.output/public/_nuxt/D95h62Jn.js +0 -1
- package/.output/public/_nuxt/DAR70Lf52.js +0 -1
- package/.output/public/_nuxt/DGAOugLt.js +0 -1
- package/.output/public/_nuxt/DKHcFE1i.js +0 -1
- package/.output/public/_nuxt/DSa2O56y.js +0 -1
- package/.output/public/_nuxt/DUToq-k_.js +0 -1
- package/.output/public/_nuxt/Dfe8vXdG.js +0 -1
- package/.output/public/_nuxt/DjtE7AYt.js +0 -1
- package/.output/public/_nuxt/DvgKXPgu2.js +0 -13
- package/.output/public/_nuxt/JOwsShod.js +0 -2
- package/.output/public/_nuxt/X6IraCTB.js +0 -1
- package/.output/public/_nuxt/_id_.C-YXjn8Q.css +0 -1
- package/.output/public/_nuxt/_wsId_.BqWBlY7X.css +0 -1
- package/.output/public/_nuxt/agents.CB9Ck7VQ.css +0 -1
- package/.output/public/_nuxt/b50gYVZl.js +0 -1
- package/.output/public/_nuxt/builds/meta/024de5f7-6a10-4f53-82ab-bc65f3ec9e35.json +0 -1
- package/.output/public/_nuxt/daq.3OKj58HH.css +0 -1
- package/.output/public/_nuxt/default.BbgdTDCk.css +0 -1
- package/.output/public/_nuxt/entry.AZM1Culo.css +0 -1
- package/.output/public/_nuxt/pages.CG8UJ2TK.css +0 -1
- package/.output/public/_nuxt/plugins.DpCuwaJt.css +0 -1
- package/.output/public/_nuxt/settings.BqMF2nfj.css +0 -1
- package/.output/public/_nuxt/teams.DN0pAGGu.css +0 -1
- package/.output/server/chunks/build/_id_-DQDqj-cZ.mjs.map +0 -1
- package/.output/server/chunks/build/_id_-DY6v6sqB.mjs.map +0 -1
- package/.output/server/chunks/build/agents-GnmUGZir.mjs.map +0 -1
- package/.output/server/chunks/build/alert-qJnjyRcP.mjs.map +0 -1
- package/.output/server/chunks/build/channel-templates-B4z6v8Z5.mjs.map +0 -1
- package/.output/server/chunks/build/daq-B-3xCp_2.mjs.map +0 -1
- package/.output/server/chunks/build/dcw-BL2dhuz7.mjs.map +0 -1
- package/.output/server/chunks/build/logs-Dto_umFY.mjs.map +0 -1
- package/.output/server/chunks/build/pages-Dc2H1QFu.mjs.map +0 -1
- package/.output/server/chunks/build/permissions-BTRW2CVd.mjs.map +0 -1
- package/.output/server/chunks/build/plugins-DZR0T4Mh.mjs.map +0 -1
- package/.output/server/chunks/build/responsiveObserve-CS0UB6wQ.mjs +0 -78
- package/.output/server/chunks/build/responsiveObserve-CS0UB6wQ.mjs.map +0 -1
- package/.output/server/chunks/build/settings-UfGyDgM7.mjs +0 -567
- package/.output/server/chunks/build/settings-UfGyDgM7.mjs.map +0 -1
- package/.output/server/chunks/build/tag-NO9jEqKy.mjs.map +0 -1
- package/.output/server/chunks/build/teams-Cbg27MWW.mjs.map +0 -1
- package/.output/server/chunks/build/tokens-Bmm6rDfj.mjs.map +0 -1
- package/.output/server/chunks/build/town-Dsh0jlwZ.mjs.map +0 -1
- package/.output/server/chunks/build/useDaqStream-DkRL3tEW.mjs.map +0 -1
- package/.output/server/chunks/build/useDcwStream-DyB2ufQI.mjs.map +0 -1
- package/.output/server/chunks/build/users-B50HHrfi.mjs.map +0 -1
- /package/.output/public/_nuxt/{ORt9oDIy.js → ORt9oDIy2.js} +0 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// scratch audit command (registration target experiment)
|
|
2
|
+
export const meta = {
|
|
3
|
+
name: 'hello-audit',
|
|
4
|
+
group: 'audit',
|
|
5
|
+
summary: 'hello from audit scratch',
|
|
6
|
+
needsProject: false,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export async function run() {
|
|
10
|
+
console.log('hello-audit ok')
|
|
11
|
+
return 0
|
|
12
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 审计实验 5 —— 端到端:真实 DcwController + mock 驱动,验证
|
|
3
|
+
* ① 正常写:硬件写入 + 账本锚 + 写历史(正对照)
|
|
4
|
+
* ② PATCH decimals=101(无校验)→ 后续写「已落硬件但记账抛错」→ 无账本锚/无写历史/500
|
|
5
|
+
* ③ 不存在节点 id 的语义(服务层 404)
|
|
6
|
+
*
|
|
7
|
+
* cwd 已切到 scripts/_audit/.tmp:所有仓库文件写到临时目录,绝不碰 server/data/*。
|
|
8
|
+
* 运行:node --experimental-transform-types scripts/_audit/run.mjs scripts/_audit/dcw-controller-e2e.ts
|
|
9
|
+
*/
|
|
10
|
+
import { mkdirSync, rmSync } from 'node:fs'
|
|
11
|
+
|
|
12
|
+
// 清空本次实验的隔离数据目录(run.mjs 已把 AW_DATA_DIR 指向 scripts/_audit/.tmp/audit-data;
|
|
13
|
+
// 同目录其它实验残留的 20000 锚账本会污染断言,故先清空)
|
|
14
|
+
const ISOLATED = new URL('./.tmp/audit-data/', import.meta.url)
|
|
15
|
+
rmSync(ISOLATED, { recursive: true, force: true })
|
|
16
|
+
mkdirSync(ISOLATED, { recursive: true })
|
|
17
|
+
// 清空上次实验留下的临时库(benchmark 会写出 10MB+ 的 dcw-rollback.json)
|
|
18
|
+
rmSync(new URL('./.tmp/server/', import.meta.url), { recursive: true, force: true })
|
|
19
|
+
mkdirSync(new URL('./.tmp/server/data/', import.meta.url), { recursive: true })
|
|
20
|
+
process.chdir(new URL('./.tmp/', import.meta.url).pathname.replace(/^\//, ''))
|
|
21
|
+
|
|
22
|
+
const { getDcwController } = await import('../../server/services/workshop/dcw/dcw-controller')
|
|
23
|
+
const { getRecipeRollBackRepo } = await import('../../server/services/workshop/dcw/recipe-rollback.repo')
|
|
24
|
+
const { getDcwRecipeRepo } = await import('../../server/services/workshop/dcw/dcw-recipe.repo')
|
|
25
|
+
|
|
26
|
+
let failures = 0
|
|
27
|
+
function check(name: string, cond: boolean, extra = ''): void {
|
|
28
|
+
if (cond) {
|
|
29
|
+
console.log(` PASS ${name}${extra ? ` (${extra})` : ''}`)
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
failures++
|
|
33
|
+
console.log(` FAIL ${name}${extra ? ` (${extra})` : ''}`)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const mockPlc = (globalThis as { __dcwMockPlc?: Map<string, number> }).__dcwMockPlc!
|
|
38
|
+
const plcValue = (): number | undefined => mockPlc.get('default')
|
|
39
|
+
|
|
40
|
+
const ctrl = getDcwController()
|
|
41
|
+
const ledger = getRecipeRollBackRepo()
|
|
42
|
+
const writes = getDcwRecipeRepo()
|
|
43
|
+
|
|
44
|
+
const node = ctrl.create({ templateRef: 'temp-sp', driver: 'mock', min: 150, max: 200, decimals: 1, enabled: true })
|
|
45
|
+
console.log(` 节点 ${node.id} 创建(mock 驱动,min150 max200 decimals1)`)
|
|
46
|
+
|
|
47
|
+
console.log('\n=== ① 正对照:正常写 ===')
|
|
48
|
+
{
|
|
49
|
+
const anchorsBefore = ledger.stats().anchors
|
|
50
|
+
const out = await ctrl.write(node.id, 160, null, { source: 'manual', actor: 'audit' })
|
|
51
|
+
check('写入返回 ok', out.ok === true, out.message)
|
|
52
|
+
check('mock PLC 记录写入值 160(硬件已写)', plcValue() === 160, `plc=${plcValue()}`)
|
|
53
|
+
check('账本新增 1 条锚', ledger.stats().anchors === anchorsBefore + 1, `anchors=${ledger.stats().anchors}`)
|
|
54
|
+
check('写历史新增 1 条', writes.historyList(5).length === 1, `n=${writes.historyList(5).length}`)
|
|
55
|
+
check('节点 value=160', node.value === 160, `value=${node.value}`)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log('\n=== ② PATCH decimals=101(接口无任何范围校验)→ 再写 ===')
|
|
59
|
+
{
|
|
60
|
+
const patched = ctrl.patch(node.id, { decimals: 101 })
|
|
61
|
+
check('PATCH decimals=101 被接受(无校验)', patched.decimals === 101, `decimals=${patched.decimals}`)
|
|
62
|
+
|
|
63
|
+
const anchorsBefore = ledger.stats().anchors
|
|
64
|
+
const historyBefore = writes.historyList(50).length
|
|
65
|
+
let err: unknown
|
|
66
|
+
try {
|
|
67
|
+
await ctrl.write(node.id, 170, null, { source: 'manual', actor: 'audit' })
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
err = e
|
|
71
|
+
}
|
|
72
|
+
console.log(` 写 170 抛错: ${(err as Error)?.name}: ${(err as Error)?.message}`)
|
|
73
|
+
check('写入抛出异常(调用方得到 500 而非 ACK)', err != null, String((err as Error)?.name))
|
|
74
|
+
check('异常来自 toFixed 的 RangeError 语义', /toFixed|digits|RangeError/i.test(`${(err as Error)?.name} ${(err as Error)?.message}`), `${(err as Error)?.name}`)
|
|
75
|
+
check('mock PLC 已记录 170(硬件写入已发生)', plcValue() === 170, `plc=${plcValue()}`)
|
|
76
|
+
check('账本未新增锚(这次硬件变更无法回退)', ledger.stats().anchors === anchorsBefore, `anchors=${ledger.stats().anchors}`)
|
|
77
|
+
check('写历史未新增条目(审计缺失)', writes.historyList(50).length === historyBefore, `n=${writes.historyList(50).length}`)
|
|
78
|
+
check('节点 state=error 且 value 仍是旧值 160', node.state === 'error' && node.value === 160, `state=${node.state} value=${node.value}`)
|
|
79
|
+
|
|
80
|
+
const stable = ledger.lastStableAnchor(node.id)
|
|
81
|
+
console.log(` 账本最新稳定锚={prev:${stable?.prevValue}, new:${stable?.newValue}};硬件实际=${plcValue()};节点显示=${node.value}`)
|
|
82
|
+
check('硬件(170)≠ 账本(160):账本与硬件已漂移', plcValue() !== stable?.newValue)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log('\n=== ③ 不存在节点 id 的服务层语义 ===')
|
|
86
|
+
{
|
|
87
|
+
let e404: unknown
|
|
88
|
+
try {
|
|
89
|
+
await ctrl.write('dw-nonexistent', 160, null, { source: 'manual', actor: 'audit' })
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
e404 = e
|
|
93
|
+
}
|
|
94
|
+
const status = (e404 as { status?: number })?.status
|
|
95
|
+
check('不存在节点 → AppError 404(控制器层)', status === 404, `status=${status}`)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
console.log(`\nresult: ${failures === 0 ? 'ALL PASS' : `${failures} FAILED`}`)
|
|
99
|
+
process.exit(failures === 0 ? 0 : 1)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 审计实验 4 —— DCW 落盘放大成本(只读:仅读真实 data/*.json,写入 scripts/_audit/.tmp)。
|
|
3
|
+
*
|
|
4
|
+
* 运行:node --experimental-transform-types scripts/_audit/run.mjs scripts/_audit/dcw-flush-cost.ts
|
|
5
|
+
*/
|
|
6
|
+
import { mkdirSync, readFileSync, statSync } from 'node:fs'
|
|
7
|
+
import { saveJsonFileAtomic } from '../../server/services/workshop/json-store.mjs'
|
|
8
|
+
|
|
9
|
+
const TMP = new URL('./.tmp/', import.meta.url).pathname.replace(/^\//, '')
|
|
10
|
+
mkdirSync(TMP, { recursive: true })
|
|
11
|
+
|
|
12
|
+
const rows = (f: string): unknown => JSON.parse(readFileSync(`server/data/${f}`, 'utf-8'))
|
|
13
|
+
|
|
14
|
+
const nodes = rows('dcws.json') as Array<Record<string, unknown>>
|
|
15
|
+
const writes = rows('dcw-writes.json') as Array<Record<string, unknown>>
|
|
16
|
+
|
|
17
|
+
function bench(label: string, data: unknown, target: string, iters: number): void {
|
|
18
|
+
const t0 = performance.now()
|
|
19
|
+
for (let i = 0; i < iters; i++) saveJsonFileAtomic(target, data)
|
|
20
|
+
const dt = performance.now() - t0
|
|
21
|
+
const size = statSync(target).size
|
|
22
|
+
// JSON.stringify 单独计量(纯 CPU,事件循环阻塞部分)
|
|
23
|
+
const t1 = performance.now()
|
|
24
|
+
for (let i = 0; i < iters; i++) JSON.stringify(data, null, 2)
|
|
25
|
+
const ds = performance.now() - t1
|
|
26
|
+
console.log(
|
|
27
|
+
` ${label}: flushNow 全量落盘 per-op=${(dt / iters).toFixed(1)}ms`
|
|
28
|
+
+ ` (其中 JSON.stringify(pretty) ${(ds / iters).toFixed(1)}ms), 文件=${(size / 1024).toFixed(1)}KB,`
|
|
29
|
+
+ ` iters=${iters}`,
|
|
30
|
+
)
|
|
31
|
+
console.log(` 记录数=${Array.isArray(data) ? data.length : Object.keys(data as object).length}`)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log('=== 真实数据规模下的落盘成本(与生产 server/data/*.json 同形) ===')
|
|
35
|
+
bench('dcws.json(节点快照;每次写值/读值后防抖落盘 dcw-controller.ts:179,235)', nodes, `${TMP}/dcws.json`, 20)
|
|
36
|
+
bench('dcw-writes.json(写历史;每次下发后防抖落盘 dcw-controller.ts:193)', writes, `${TMP}/dcw-writes.json`, 20)
|
|
37
|
+
|
|
38
|
+
const readInt = nodes.map(n => Number(n.readIntervalMs)).filter(v => Number.isFinite(v) && v > 0)
|
|
39
|
+
const perSec = readInt.reduce((a, v) => a + (1000 / v), 0)
|
|
40
|
+
console.log('\n=== 生产规模推算 ===')
|
|
41
|
+
console.log(` 配置了周期读的节点=${readInt.length},合计周期读频率=${perSec.toFixed(1)} 次/秒`)
|
|
42
|
+
console.log(` 每次周期读 executeRead 尾部调用 repo.flushDebounced()(dcw-controller.ts:235)`)
|
|
43
|
+
console.log(` 防抖窗 1.5s(dcw-node.repo.ts:60-66)→ 稳态下 dcws.json 全量重写≈每 1.5s 一次`)
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 审计实验 2 —— RecipeRollBackRepo 账本算法/落盘成本(只读审计)。
|
|
3
|
+
*
|
|
4
|
+
* 关键:cwd 切到 scripts/_audit/.tmp,使 repo 的 DATA_DIR 指向临时目录,
|
|
5
|
+
* **绝不触碰 server/data/dcw-rollback.json**(真实数据文件)。
|
|
6
|
+
*
|
|
7
|
+
* 运行:node --experimental-transform-types scripts/_audit/run.mjs scripts/_audit/dcw-rollback-ledger.ts
|
|
8
|
+
*/
|
|
9
|
+
import { mkdirSync } from 'node:fs'
|
|
10
|
+
|
|
11
|
+
const TMP = new URL('./.tmp/', import.meta.url)
|
|
12
|
+
mkdirSync(new URL('server/data/', TMP), { recursive: true })
|
|
13
|
+
process.chdir(new URL('.tmp/', new URL('.', import.meta.url)).pathname.replace(/^\//, ''))
|
|
14
|
+
|
|
15
|
+
const { RecipeRollBackRepo } = await import('../../server/services/workshop/dcw/recipe-rollback.repo')
|
|
16
|
+
|
|
17
|
+
const CAP_ANCHORS = 20000
|
|
18
|
+
const CAP_RECORDS = 2000
|
|
19
|
+
|
|
20
|
+
function anchorOf(i: number, nodeId = `n-${i % 50}`) {
|
|
21
|
+
return {
|
|
22
|
+
lineId: 'ln-audit',
|
|
23
|
+
nodeId,
|
|
24
|
+
prevValue: i,
|
|
25
|
+
newValue: i + 1,
|
|
26
|
+
source: 'manual' as const,
|
|
27
|
+
actor: 'user',
|
|
28
|
+
recipeRunId: null,
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** 贴近真实形状的 windowAgg(实测 server/data/dcw-rollback.json:平均记录 1267 B) */
|
|
33
|
+
function aggOf(nodeId: string) {
|
|
34
|
+
return {
|
|
35
|
+
at: new Date().toISOString(),
|
|
36
|
+
fromMs: Date.now() - 600_000,
|
|
37
|
+
toMs: Date.now(),
|
|
38
|
+
channels: Array.from({ length: 8 }, (_, k) => ({
|
|
39
|
+
daqNodeId: `dq-${k}`,
|
|
40
|
+
ch: `CH${k}`,
|
|
41
|
+
unit: 'C',
|
|
42
|
+
latest: 123.45,
|
|
43
|
+
avg: 121.11,
|
|
44
|
+
min: 100.5,
|
|
45
|
+
max: 140.25,
|
|
46
|
+
cnt: 120,
|
|
47
|
+
breaches: 0,
|
|
48
|
+
nodeIdFallback: nodeId,
|
|
49
|
+
})),
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function ms(fn: () => void): number {
|
|
54
|
+
const t0 = performance.now()
|
|
55
|
+
fn()
|
|
56
|
+
return performance.now() - t0
|
|
57
|
+
}
|
|
58
|
+
function report(label: string, totalMs: number, iters: number): void {
|
|
59
|
+
console.log(` ${label}: total=${totalMs.toFixed(1)}ms per-op=${(totalMs / iters).toFixed(3)}ms (iters=${iters})`)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log('=== A. anchors 到达上限后的每次 appendAnchor 成本 ===')
|
|
63
|
+
{
|
|
64
|
+
const repo = new RecipeRollBackRepo()
|
|
65
|
+
for (let i = 0; i < CAP_ANCHORS; i++) repo.appendAnchor(anchorOf(i))
|
|
66
|
+
console.log(` 填充后 anchors=${repo.stats().anchors}(cap=${CAP_ANCHORS})`)
|
|
67
|
+
const iters = 200
|
|
68
|
+
const t = ms(() => {
|
|
69
|
+
for (let i = 0; i < iters; i++) repo.appendAnchor(anchorOf(CAP_ANCHORS + i))
|
|
70
|
+
}, iters)
|
|
71
|
+
report('appendAnchor(在上限稳态,每次触发 splice+new Set)', t, iters)
|
|
72
|
+
console.log(` 追加后 anchors=${repo.stats().anchors}(仍为 cap,说明每写都触发淘汰路径)`)
|
|
73
|
+
|
|
74
|
+
console.log('\n=== B. 查询方法成本(20000 锚 / 50 节点) ===')
|
|
75
|
+
const nodeId = 'n-0'
|
|
76
|
+
let t1 = ms(() => { for (let i = 0; i < 1000; i++) repo.lastStableAnchor(nodeId) }, 1000)
|
|
77
|
+
report('lastStableAnchor (O(1) 索引)', t1, 1000)
|
|
78
|
+
t1 = ms(() => { for (let i = 0; i < 1000; i++) repo.lastRollbackAnchor(nodeId) }, 1000)
|
|
79
|
+
report('lastRollbackAnchor (节点子序列倒扫)', t1, 1000)
|
|
80
|
+
t1 = ms(() => { for (let i = 0; i < 200; i++) repo.anchorById('anc-nonexistent') }, 200)
|
|
81
|
+
report('anchorById (全量 find,未命中=最坏)', t1, 200)
|
|
82
|
+
t1 = ms(() => { for (let i = 0; i < 200; i++) repo.listAnchors({ lineId: 'ln-nope', limit: 100 }) }, 200)
|
|
83
|
+
report('listAnchors({lineId}) 无命中 → 全量 20000 倒扫', t1, 200)
|
|
84
|
+
t1 = ms(() => { for (let i = 0; i < 200; i++) repo.listAnchors({ nodeId, limit: 30 }) }, 200)
|
|
85
|
+
report('listAnchors({nodeId, limit:30}) 走索引', t1, 200)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
console.log('\n=== C. records(2000 上限)+ open 索引 ===')
|
|
89
|
+
{
|
|
90
|
+
const repo = new RecipeRollBackRepo()
|
|
91
|
+
for (let i = 0; i < CAP_RECORDS; i++) {
|
|
92
|
+
repo.insertRecord({
|
|
93
|
+
lineId: 'ln-audit',
|
|
94
|
+
nodeId: `n-${i % 50}`,
|
|
95
|
+
nodeName: `node-${i % 50}`,
|
|
96
|
+
recipeId: null,
|
|
97
|
+
hypothesis: 'h',
|
|
98
|
+
params: [{ nodeId: `n-${i % 50}`, templateRef: 'cw-temp', from: i, to: i + 1 }],
|
|
99
|
+
setAt: new Date().toISOString(),
|
|
100
|
+
status: 'open',
|
|
101
|
+
judge: null,
|
|
102
|
+
anchorId: `anc-${i}`,
|
|
103
|
+
policy: 'auto_rollback',
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
console.log(` records=${repo.stats().records} open=${repo.stats().open}(每节点仅索引最后一条)`)
|
|
107
|
+
const t = ms(() => { for (let i = 0; i < 200; i++) repo.listOpenRecords() }, 200)
|
|
108
|
+
report('listOpenRecords (O(open))', t, 200)
|
|
109
|
+
const t2 = ms(() => { for (let i = 0; i < 200; i++) repo.chainRollbackCount('n-0') }, 200)
|
|
110
|
+
report('chainRollbackCount (全量 2000 filter)', t2, 200)
|
|
111
|
+
const t3 = ms(() => { for (let i = 0; i < 2000; i++) repo.byId('opt-nonexistent') }, 2000)
|
|
112
|
+
report('byId (全量 find,未命中=最坏)', t3, 2000)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
console.log('\n=== D. 同节点第二条 open 记录 → 索引可见性 ===')
|
|
116
|
+
{
|
|
117
|
+
const repo = new RecipeRollBackRepo()
|
|
118
|
+
const r1 = repo.insertRecord({ nodeId: 'n-x', status: 'open', policy: 'auto_rollback', setAt: new Date().toISOString(), params: [], lineId: 'l' } as never)
|
|
119
|
+
const r2 = repo.insertRecord({ nodeId: 'n-x', status: 'open', policy: 'auto_rollback', setAt: new Date().toISOString(), params: [], lineId: 'l' } as never)
|
|
120
|
+
const open = repo.listOpenRecords()
|
|
121
|
+
const listed = repo.listRecords({ nodeId: 'n-x', status: 'open', limit: 50 })
|
|
122
|
+
console.log(` insertRecord #1=${r1.id} #2=${r2.id}`)
|
|
123
|
+
console.log(` listOpenRecords() 返回 ${open.length} 条;listRecords(status=open) 返回 ${listed.length} 条`)
|
|
124
|
+
console.log(` → 未被索引的 open 记录是否可达:${open.some(r => r.id === r1.id) ? '可达' : '不可达(永不被 sweep 评估)'}`)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
console.log('\n=== E. flushNow(全量序列化)成本 ===')
|
|
128
|
+
{
|
|
129
|
+
const repo = new RecipeRollBackRepo()
|
|
130
|
+
for (let i = 0; i < CAP_ANCHORS; i++) repo.appendAnchor(anchorOf(i))
|
|
131
|
+
for (let i = 0; i < CAP_RECORDS; i++) {
|
|
132
|
+
repo.insertRecord({
|
|
133
|
+
lineId: 'ln-audit',
|
|
134
|
+
nodeId: `n-${i % 50}`,
|
|
135
|
+
nodeName: `node-${i % 50}`,
|
|
136
|
+
recipeId: null,
|
|
137
|
+
hypothesis: 'h',
|
|
138
|
+
params: [{ nodeId: `n-${i % 50}`, templateRef: 'cw-temp', from: i, to: i + 1 }],
|
|
139
|
+
setAt: new Date().toISOString(),
|
|
140
|
+
status: 'closed-line-stop',
|
|
141
|
+
judge: null,
|
|
142
|
+
anchorId: `anc-${i}`,
|
|
143
|
+
policy: 'auto_rollback',
|
|
144
|
+
windowAgg: aggOf(`n-${i % 50}`),
|
|
145
|
+
} as never)
|
|
146
|
+
}
|
|
147
|
+
const iters = 20
|
|
148
|
+
const t = ms(() => { for (let i = 0; i < iters; i++) repo.flushNow() }, iters)
|
|
149
|
+
report(`flushNow(anchors=${CAP_ANCHORS} + records=${CAP_RECORDS} 含聚合)`, t, iters)
|
|
150
|
+
const { statSync } = await import('node:fs')
|
|
151
|
+
const size = statSync(process.cwd() + '/server/data/dcw-rollback.json').size
|
|
152
|
+
console.log(` 落盘文件大小=${(size / 1024 / 1024).toFixed(2)} MB(每次 agent/rollback 写后同步全量重写)`)
|
|
153
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 审计实验 3 —— 「写入落到硬件但未入账」链路(只读审计;全部走本地假 PLC,不触真实数据)。
|
|
3
|
+
*
|
|
4
|
+
* 组成:
|
|
5
|
+
* A) 假 Modbus TCP PLC(FC16 写 / FC03 读;可切换「回读返回陈旧值」和「永不响应」)
|
|
6
|
+
* B) 真实 modbus-tcp 写驱动(server/services/workshop/dcw/drivers.ts)
|
|
7
|
+
* C) 真实 RecipeRollBackRepo(账本;cwd 已切到 scripts/_audit/.tmp,绝不碰 server/data/*)
|
|
8
|
+
* D) 忠实复刻 dcw-controller.ts:536 的入册闸门 `if (outcome.ok !== false)`
|
|
9
|
+
*
|
|
10
|
+
* 运行:node --experimental-transform-types scripts/_audit/run.mjs scripts/_audit/dcw-unrecorded-write.ts
|
|
11
|
+
*/
|
|
12
|
+
import { mkdirSync } from 'node:fs'
|
|
13
|
+
import net from 'node:net'
|
|
14
|
+
|
|
15
|
+
const TMP_DIR = new URL('./.tmp/server/data/', import.meta.url)
|
|
16
|
+
mkdirSync(TMP_DIR, { recursive: true })
|
|
17
|
+
process.chdir(new URL('./.tmp/', import.meta.url).pathname.replace(/^\//, ''))
|
|
18
|
+
|
|
19
|
+
const { modbusTcpDcwDriver } = await import('../../server/services/workshop/dcw/drivers')
|
|
20
|
+
const { RecipeRollBackRepo } = await import('../../server/services/workshop/dcw/recipe-rollback.repo')
|
|
21
|
+
const { writeTolerance } = await import('../../server/services/workshop/dcw/dcw-runtime')
|
|
22
|
+
|
|
23
|
+
let failures = 0
|
|
24
|
+
function check(name: string, cond: boolean, extra = ''): void {
|
|
25
|
+
if (cond) {
|
|
26
|
+
console.log(` PASS ${name}${extra ? ` (${extra})` : ''}`)
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
failures++
|
|
30
|
+
console.log(` FAIL ${name}${extra ? ` (${extra})` : ''}`)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface FakePlc {
|
|
35
|
+
port: number
|
|
36
|
+
registers: Map<number, number>
|
|
37
|
+
writeCount: number
|
|
38
|
+
mode: 'stale-readback' | 'hang'
|
|
39
|
+
close: () => void
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function startFakePlc(opts: { staleReadback?: number, mode?: 'stale-readback' | 'hang' }): Promise<FakePlc> {
|
|
43
|
+
const registers = new Map<number, number>()
|
|
44
|
+
const state = { writeCount: 0, mode: opts.mode ?? 'stale-readback' as 'stale-readback' | 'hang' }
|
|
45
|
+
const server = net.createServer((sock) => {
|
|
46
|
+
let buf = Buffer.alloc(0)
|
|
47
|
+
sock.on('data', (chunk) => {
|
|
48
|
+
buf = Buffer.concat([buf, chunk])
|
|
49
|
+
while (buf.length >= 6) {
|
|
50
|
+
const len = buf.readUInt16BE(4)
|
|
51
|
+
const total = 6 + len
|
|
52
|
+
if (buf.length < total) break
|
|
53
|
+
const unitId = buf.readUInt8(6)
|
|
54
|
+
const pdu = buf.subarray(7, total)
|
|
55
|
+
const fc = pdu.readUInt8(0)
|
|
56
|
+
const tid = buf.readUInt16BE(0)
|
|
57
|
+
if (state.mode === 'hang') {
|
|
58
|
+
buf = buf.subarray(total)
|
|
59
|
+
continue // 收到即吞:模拟半开链路(不响应)
|
|
60
|
+
}
|
|
61
|
+
let resp: Buffer
|
|
62
|
+
if (fc === 0x10) { // write multiple registers
|
|
63
|
+
const addr = pdu.readUInt16BE(1)
|
|
64
|
+
const qty = pdu.readUInt16BE(3)
|
|
65
|
+
for (let i = 0; i < qty; i++) registers.set(addr + i, pdu.readUInt16BE(6 + i * 2))
|
|
66
|
+
state.writeCount++
|
|
67
|
+
resp = Buffer.from([0x10, pdu[1]!, pdu[2]!, pdu[3]!, pdu[4]!])
|
|
68
|
+
}
|
|
69
|
+
else if (fc === 0x03) { // read holding registers
|
|
70
|
+
const addr = pdu.readUInt16BE(1)
|
|
71
|
+
const qty = pdu.readUInt16BE(3)
|
|
72
|
+
const data: number[] = []
|
|
73
|
+
for (let i = 0; i < qty; i++) {
|
|
74
|
+
// 关键:回读一律返回「陈旧值」——模拟 PLC 尚未生效/慢一拍
|
|
75
|
+
data.push(opts.staleReadback != null ? opts.staleReadback : (registers.get(addr + i) ?? 0))
|
|
76
|
+
}
|
|
77
|
+
resp = Buffer.from([0x03, data.length * 2, ...data.flatMap(v => [v >> 8 & 0xFF, v & 0xFF])])
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
resp = Buffer.from([fc | 0x80, 0x01])
|
|
81
|
+
}
|
|
82
|
+
const head = Buffer.alloc(6)
|
|
83
|
+
head.writeUInt16BE(tid, 0)
|
|
84
|
+
head.writeUInt16BE(0, 2)
|
|
85
|
+
head.writeUInt16BE(resp.length + 1, 4)
|
|
86
|
+
sock.write(Buffer.concat([head, Buffer.from([unitId]), resp]))
|
|
87
|
+
buf = buf.subarray(total)
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
sock.on('error', () => {})
|
|
91
|
+
})
|
|
92
|
+
return new Promise((resolve) => {
|
|
93
|
+
server.listen(0, '127.0.0.1', () => {
|
|
94
|
+
resolve({
|
|
95
|
+
port: (server.address() as net.AddressInfo).port,
|
|
96
|
+
registers,
|
|
97
|
+
get writeCount() { return state.writeCount },
|
|
98
|
+
mode: state.mode,
|
|
99
|
+
close: () => server.close(),
|
|
100
|
+
} as FakePlc)
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const nodeLike = { decimals: 2, min: 0, max: 100 } as never
|
|
106
|
+
|
|
107
|
+
console.log('\n=== A. 回读陈旧值:写已落到寄存器,但 ACK 判定失败(ok=false) ===')
|
|
108
|
+
{
|
|
109
|
+
const plc = await startFakePlc({ staleReadback: 5 })
|
|
110
|
+
const cfg = { host: '127.0.0.1', port: plc.port, unitId: 1, register: 0, dataType: 'int16', byteOrder: 'big' }
|
|
111
|
+
const res = await modbusTcpDcwDriver.write({
|
|
112
|
+
eng: 20,
|
|
113
|
+
tolerance: writeTolerance(nodeLike),
|
|
114
|
+
domain: { min: 0, max: 100 },
|
|
115
|
+
driverConfig: cfg,
|
|
116
|
+
})
|
|
117
|
+
console.log(` 驱动返回: ok=${res.ok} raw=${res.raw} readback=${res.readback} message=${res.message}`)
|
|
118
|
+
check('硬件寄存器已收到写入值 20', plc.registers.get(0) === 20, `reg0=${plc.registers.get(0)}`)
|
|
119
|
+
check('驱动判定为 ACK 失败(ok=false)', res.ok === false)
|
|
120
|
+
check('失败原因 = 回读偏差超容差', /回读偏差超容差/.test(res.message), res.message)
|
|
121
|
+
check('readback 为陈旧值 5', res.readback === 5)
|
|
122
|
+
|
|
123
|
+
// 账本语义复刻:dcw-controller.ts:536「仅成功写记锚」→ ok=false 时 afterWrite 不被调用
|
|
124
|
+
const repo = new RecipeRollBackRepo()
|
|
125
|
+
const seeded = repo.appendAnchor({ lineId: 'ln', nodeId: 'dw-1', prevValue: 5, newValue: 10, source: 'manual', actor: 'user', recipeRunId: null })
|
|
126
|
+
const outcome = res
|
|
127
|
+
let ledgerAppends = 0
|
|
128
|
+
if (outcome.ok !== false) { // ← 与 dcw-controller.ts:532-536 同构
|
|
129
|
+
repo.appendAnchor({ lineId: 'ln', nodeId: 'dw-1', prevValue: 10, newValue: 20, source: 'manual', actor: 'user', recipeRunId: null })
|
|
130
|
+
ledgerAppends++
|
|
131
|
+
}
|
|
132
|
+
check('ok=false 时账本未入册(闸门同构复刻)', ledgerAppends === 0)
|
|
133
|
+
const stable = repo.lastStableAnchor('dw-1')
|
|
134
|
+
console.log(` 账本最新稳定锚 = {prev:${stable?.prevValue}, new:${stable?.newValue}};硬件寄存器 = ${plc.registers.get(0)}`)
|
|
135
|
+
check('入册锚不是本次写入(20 不在册)', stable?.newValue === 10, `new=${stable?.newValue}`)
|
|
136
|
+
check('硬件实际值(20)≠ 入册锚 newValue(10):账本与硬件漂移', plc.registers.get(0) !== stable?.newValue)
|
|
137
|
+
check('seeded 锚的 prevValue=5 仍是回退目标:回退将跳过真实的上一设定值 10', stable?.prevValue === 5)
|
|
138
|
+
plc.close()
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
console.log('\n=== B. 同理:另一个方向的漂移(node.value = 陈旧回读值 → 保写心跳将重下发陈旧值) ===')
|
|
142
|
+
{
|
|
143
|
+
const plc = await startFakePlc({ staleReadback: 5 })
|
|
144
|
+
const cfg = { host: '127.0.0.1', port: plc.port, unitId: 1, register: 0, dataType: 'int16', byteOrder: 'big' }
|
|
145
|
+
const res = await modbusTcpDcwDriver.write({ eng: 20, tolerance: writeTolerance(nodeLike), domain: { min: 0, max: 100 }, driverConfig: cfg })
|
|
146
|
+
// dcw-controller.ts:176 等价:node.applyWriteResult(outcome.readback ?? eng, ok, ...)
|
|
147
|
+
const DcwNodeMod = await import('../../server/services/workshop/dcw/dcw-node')
|
|
148
|
+
const node = DcwNodeMod.DcwNode.fromRow({ id: 'dw-1', templateRef: 'cw-temp', min: 0, max: 100, decimals: 2, holdIntervalMs: 1000, driver: 'modbus-tcp', driverConfig: cfg })
|
|
149
|
+
node.value = 10
|
|
150
|
+
node.applyWriteResult(res.readback ?? 20, res.ok, res.message, new Date().toISOString())
|
|
151
|
+
console.log(` 写入 20 / 回读 ${res.readback} → node.value=${node.value}(state=${node.state})`)
|
|
152
|
+
check('node.value 被写成陈旧回读值 5(既非设定值 20 也非真实上一设定 10)', node.value === 5, `value=${node.value}`)
|
|
153
|
+
plc.close()
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
console.log('\n=== C. 写超时(假 PLC 收到即吞):是否 bounded、是否误判 ===')
|
|
157
|
+
{
|
|
158
|
+
const plc = await startFakePlc({ mode: 'hang' })
|
|
159
|
+
const cfg = { host: '127.0.0.1', port: plc.port, unitId: 1, register: 0, dataType: 'int16', byteOrder: 'big' }
|
|
160
|
+
const t0 = Date.now()
|
|
161
|
+
const res = await modbusTcpDcwDriver.write({ eng: 30, tolerance: writeTolerance(nodeLike), domain: { min: 0, max: 100 }, driverConfig: cfg })
|
|
162
|
+
const dt = Date.now() - t0
|
|
163
|
+
console.log(` 返回: ok=${res.ok} message=${res.message} elapsed=${dt}ms`)
|
|
164
|
+
check('写有硬超时(<=4s 返回,实测 withModbusConn 3s)', dt < 4000, `${dt}ms`)
|
|
165
|
+
check('超时映射为 ACK 失败(ok=false)', res.ok === false)
|
|
166
|
+
check('超时时 readback=null(账本/节点值无法判定硬件真实状态)', res.readback === null, `readback=${res.readback}`)
|
|
167
|
+
plc.close()
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
console.log(`\nresult: ${failures === 0 ? 'ALL PASS' : `${failures} FAILED`}`)
|
|
171
|
+
process.exit(failures === 0 ? 0 : 1)
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 审计实验 1 —— DCW 单节点写在飞互斥 + 周期读互斥(只读:不碰任何源码/数据文件)。
|
|
3
|
+
*
|
|
4
|
+
* 驱动真实 DcwNodeRuntime(dcw-runtime.ts),host 全部打桩,统计同一节点的
|
|
5
|
+
* 并发在飞写/读数;断言心跳重下发(tick)与手动 write() 共享同一 writing 闸门。
|
|
6
|
+
*
|
|
7
|
+
* 运行:node --experimental-transform-types scripts/_audit/run.mjs scripts/_audit/dcw-write-mutex.ts
|
|
8
|
+
*/
|
|
9
|
+
import { DcwNode } from '../../server/services/workshop/dcw/dcw-node'
|
|
10
|
+
import { DcwNodeRuntime } from '../../server/services/workshop/dcw/dcw-runtime'
|
|
11
|
+
|
|
12
|
+
let failures = 0
|
|
13
|
+
function check(name: string, cond: boolean, extra = ''): void {
|
|
14
|
+
if (cond) {
|
|
15
|
+
console.log(` PASS ${name}${extra ? ` (${extra})` : ''}`)
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
failures++
|
|
19
|
+
console.log(` FAIL ${name}${extra ? ` (${extra})` : ''}`)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const statusOf = (e: unknown): string => {
|
|
24
|
+
const s = (e as { status?: number }).status
|
|
25
|
+
return s ? String(s) : `no-status:${(e as Error)?.message ?? String(e)}`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface Stats {
|
|
29
|
+
writeCalls: number
|
|
30
|
+
readCalls: number
|
|
31
|
+
inFlightWrites: number
|
|
32
|
+
maxInFlightWrites: number
|
|
33
|
+
inFlightReads: number
|
|
34
|
+
maxInFlightReads: number
|
|
35
|
+
writeEng: number[]
|
|
36
|
+
concurrentReadPairs: number
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function makeNode(): DcwNode {
|
|
40
|
+
return DcwNode.fromRow({
|
|
41
|
+
id: 'n-audit-1',
|
|
42
|
+
templateRef: 'cw-temp',
|
|
43
|
+
name: 'audit-node',
|
|
44
|
+
driver: 'mock',
|
|
45
|
+
min: 0,
|
|
46
|
+
max: 200,
|
|
47
|
+
decimals: 2,
|
|
48
|
+
holdIntervalMs: 10,
|
|
49
|
+
readIntervalMs: 1000,
|
|
50
|
+
enabled: true,
|
|
51
|
+
lineId: 'ln-audit',
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function makeHarness(opts: { writeDelayMs: number, readDelayMs: number }) {
|
|
56
|
+
const stats: Stats = {
|
|
57
|
+
writeCalls: 0,
|
|
58
|
+
readCalls: 0,
|
|
59
|
+
inFlightWrites: 0,
|
|
60
|
+
maxInFlightWrites: 0,
|
|
61
|
+
inFlightReads: 0,
|
|
62
|
+
maxInFlightReads: 0,
|
|
63
|
+
writeEng: [],
|
|
64
|
+
concurrentReadPairs: 0,
|
|
65
|
+
}
|
|
66
|
+
const sleep = (ms: number): Promise<void> => new Promise(r => setTimeout(r, ms))
|
|
67
|
+
const host = {
|
|
68
|
+
running: () => true,
|
|
69
|
+
defaults: () => ({ holdIntervalMs: 10, readIntervalMs: 1000 }),
|
|
70
|
+
async executeWrite(node: DcwNode, eng: number) {
|
|
71
|
+
stats.writeCalls++
|
|
72
|
+
stats.writeEng.push(eng)
|
|
73
|
+
stats.inFlightWrites++
|
|
74
|
+
stats.maxInFlightWrites = Math.max(stats.maxInFlightWrites, stats.inFlightWrites)
|
|
75
|
+
await sleep(opts.writeDelayMs)
|
|
76
|
+
stats.inFlightWrites--
|
|
77
|
+
node.applyWriteResult(eng, true, 'stub ok', new Date().toISOString())
|
|
78
|
+
return { ok: true, message: 'stub ok', raw: eng, readback: eng }
|
|
79
|
+
},
|
|
80
|
+
async executeRead() {
|
|
81
|
+
stats.readCalls++
|
|
82
|
+
stats.inFlightReads++
|
|
83
|
+
stats.maxInFlightReads = Math.max(stats.maxInFlightReads, stats.inFlightReads)
|
|
84
|
+
if (stats.inFlightReads > 1)
|
|
85
|
+
stats.concurrentReadPairs++
|
|
86
|
+
await sleep(opts.readDelayMs)
|
|
87
|
+
stats.inFlightReads--
|
|
88
|
+
return { ok: true, value: 1, raw: 1, message: 'stub read', at: new Date().toISOString() }
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
return { host, stats }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function main(): Promise<void> {
|
|
95
|
+
// ---------- 场景 A:手动写在飞时,保写心跳必须跳过本拍(不得并发) ----------
|
|
96
|
+
console.log('\n[A] manual write in flight -> tick keep-alive must skip')
|
|
97
|
+
{
|
|
98
|
+
const node = makeNode()
|
|
99
|
+
const { host, stats } = makeHarness({ writeDelayMs: 120, readDelayMs: 0 })
|
|
100
|
+
const rt = new DcwNodeRuntime(node, host as never)
|
|
101
|
+
const p = rt.write(50)
|
|
102
|
+
let tickAt = 1_000_000
|
|
103
|
+
for (let i = 0; i < 20; i++) {
|
|
104
|
+
tickAt += 50 // 远超 holdIntervalMs=10,心跳到点
|
|
105
|
+
rt.tick(tickAt)
|
|
106
|
+
}
|
|
107
|
+
const concurrentSecondWrite = await rt.write(60).then(() => 'resolved', e => `rejected:${statusOf(e)}`)
|
|
108
|
+
const outcome = await p
|
|
109
|
+
check('manual write ok', outcome.ok === true)
|
|
110
|
+
check('heartbeat skipped while manual write in flight (executeWrite called once)', stats.writeCalls === 1, `calls=${stats.writeCalls}`)
|
|
111
|
+
check('max concurrent in-flight writes == 1', stats.maxInFlightWrites === 1, `max=${stats.maxInFlightWrites}`)
|
|
112
|
+
check('second concurrent manual write rejected with 409', concurrentSecondWrite === 'rejected:409', concurrentSecondWrite)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ---------- 场景 B:手动写结束后,心跳按节奏重下发且仍与手动写互斥 ----------
|
|
116
|
+
console.log('\n[B] heartbeat re-write shares the same gate')
|
|
117
|
+
{
|
|
118
|
+
const node = makeNode()
|
|
119
|
+
const { host, stats } = makeHarness({ writeDelayMs: 60, readDelayMs: 0 })
|
|
120
|
+
const rt = new DcwNodeRuntime(node, host as never)
|
|
121
|
+
await rt.write(80)
|
|
122
|
+
const callsAfterManual = stats.writeCalls
|
|
123
|
+
const t = 2_000_100
|
|
124
|
+
rt.tick(t) // 到点 -> 心跳下发 node.value
|
|
125
|
+
rt.tick(t) // 同一拍再次 tick:心跳在飞,必须跳过
|
|
126
|
+
await new Promise(r => setTimeout(r, 5))
|
|
127
|
+
const second = await rt.write(90).then(() => 'resolved', e => `rejected:${statusOf(e)}`)
|
|
128
|
+
await new Promise(r => setTimeout(r, 150))
|
|
129
|
+
check('heartbeat issued at least one write', stats.writeCalls > callsAfterManual, `calls=${stats.writeCalls}`)
|
|
130
|
+
check('heartbeat wrote current setpoint 80', stats.writeEng.includes(80), JSON.stringify(stats.writeEng))
|
|
131
|
+
check('manual write during heartbeat in flight rejected with 409', second === 'rejected:409', second)
|
|
132
|
+
check('max concurrent in-flight writes == 1 (whole scenario)', stats.maxInFlightWrites === 1, `max=${stats.maxInFlightWrites}`)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// ---------- 场景 C:周期读的在飞互斥(readNow 与 tick 读) ----------
|
|
136
|
+
console.log('\n[C] readNow() while periodic read in flight')
|
|
137
|
+
{
|
|
138
|
+
const node = makeNode()
|
|
139
|
+
const { host, stats } = makeHarness({ writeDelayMs: 0, readDelayMs: 120 })
|
|
140
|
+
const rt = new DcwNodeRuntime(node, host as never)
|
|
141
|
+
rt.tick(3_000_000) // 触发周期读(不 await)
|
|
142
|
+
await new Promise(r => setTimeout(r, 10)) // 让周期读进入在飞
|
|
143
|
+
const res = await rt.readNow().then(() => 'resolved', e => `rejected:${statusOf(e)}`)
|
|
144
|
+
await new Promise(r => setTimeout(r, 250))
|
|
145
|
+
check('periodic read started', stats.readCalls >= 1, `readCalls=${stats.readCalls}`)
|
|
146
|
+
check(
|
|
147
|
+
'readNow() rejected (expect rejected:409) while periodic read in flight',
|
|
148
|
+
res === 'rejected:409',
|
|
149
|
+
`actual=${res}; concurrent read pairs=${stats.concurrentReadPairs}, maxInFlightReads=${stats.maxInFlightReads}`,
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
console.log(`\nresult: ${failures === 0 ? 'ALL PASS' : `${failures} FAILED`}`)
|
|
154
|
+
process.exit(failures === 0 ? 0 : 1)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
void main()
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, rmSync } from 'node:fs'
|
|
2
|
+
|
|
3
|
+
const target = new URL('./.tmp/server/', import.meta.url)
|
|
4
|
+
console.log('[diag] entry file url =', import.meta.url)
|
|
5
|
+
console.log('[diag] rm target =', target.href)
|
|
6
|
+
console.log('[diag] before rm exists =', existsSync(target))
|
|
7
|
+
rmSync(target, { recursive: true, force: true })
|
|
8
|
+
console.log('[diag] after rm exists =', existsSync(target))
|
|
9
|
+
mkdirSync(new URL('./.tmp/server/data/', import.meta.url), { recursive: true })
|
|
10
|
+
|
|
11
|
+
const chdirTo = new URL('./.tmp/', import.meta.url).pathname.replace(/^\//, '')
|
|
12
|
+
console.log('[diag] chdir target =', chdirTo)
|
|
13
|
+
process.chdir(chdirTo)
|
|
14
|
+
console.log('[diag] cwd =', process.cwd())
|
|
15
|
+
console.log('[diag] cwd contents =', readdirSync(process.cwd()))
|
|
16
|
+
|
|
17
|
+
const mod = await import('../../server/services/workshop/dcw/recipe-rollback.repo')
|
|
18
|
+
const repo = new mod.RecipeRollBackRepo()
|
|
19
|
+
console.log('[diag] ledger stats =', JSON.stringify(repo.stats()))
|
|
20
|
+
console.log('[diag] data dir contents =', readdirSync(new URL('./.tmp/server/data/', import.meta.url)))
|