agentworkshop 0.7.59 → 0.7.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. package/.AgentWorkShop/prompts/host-tools.json +108 -0
  2. package/.output/.AgentWorkShop/prompts/host-tools.json +108 -0
  3. package/.output/.AgentWorkShop/schema.json +1 -0
  4. package/.output/nitro.json +1 -1
  5. package/.output/public/_nuxt/9j2J4k4w.js +1 -0
  6. package/.output/public/_nuxt/{DTx_DtUo.js → B0w8DZ4C.js} +1 -1
  7. package/.output/public/_nuxt/{cBI0JqsV.js → BMlesJth.js} +1 -1
  8. package/.output/public/_nuxt/BTXdYngG.js +1 -0
  9. package/.output/public/_nuxt/{DMPpE41S2.js → BXbKTAwC2.js} +1 -1
  10. package/.output/public/_nuxt/{Bn1N3mJv.js → B_6yBa_Z.js} +1 -1
  11. package/.output/public/_nuxt/{D6c5ppqB.js → B_ic601Y.js} +1 -1
  12. package/.output/public/_nuxt/BegV7-FE2.js +1 -0
  13. package/.output/public/_nuxt/BhllzW3K2.js +1 -0
  14. package/.output/public/_nuxt/BrRXGr472.js +1 -0
  15. package/.output/public/_nuxt/{BMZ1d25O.js → BtBgrPNT.js} +1 -1
  16. package/.output/public/_nuxt/C5MPzgon2.js +1 -0
  17. package/.output/public/_nuxt/CGChCy-w2.js +1 -0
  18. package/.output/public/_nuxt/CI5sliIF2.js +1 -0
  19. package/.output/public/_nuxt/{DTZO6WMs2.js → CI8awYVQ2.js} +1 -1
  20. package/.output/public/_nuxt/{B03LfmKR.js → CK2ts9sD.js} +1 -1
  21. package/.output/public/_nuxt/CPZKwmLQ.js +1 -0
  22. package/.output/public/_nuxt/CUjdqsjC2.js +1 -0
  23. package/.output/public/_nuxt/{C5wBzGO7.js → CVUMEGa1.js} +1 -1
  24. package/.output/public/_nuxt/{CYGkUj5M2.js → CcLFZjCI2.js} +1 -1
  25. package/.output/public/_nuxt/{iZa330UY.js → Cdw4juXw.js} +1 -1
  26. package/.output/public/_nuxt/{h46i74oE.js → CeEzUIvN.js} +4 -4
  27. package/.output/public/_nuxt/{zGDAozGA.js → CfIGBe_4.js} +4 -4
  28. package/.output/public/_nuxt/{CmTqFlYZ.js → Ci5kuU1q.js} +1 -1
  29. package/.output/public/_nuxt/CiyTTgqr.js +106 -0
  30. package/.output/public/_nuxt/{Dy-V8OEW2.js → CkYk8bj02.js} +6 -6
  31. package/.output/public/_nuxt/Cmiz_VOb2.js +47 -0
  32. package/.output/public/_nuxt/{VVomhVqu2.js → Cnf1PFhB2.js} +1 -1
  33. package/.output/public/_nuxt/CoTm7jd3.js +28 -0
  34. package/.output/public/_nuxt/{BzKT-ne_2.js → CsN8RHJ02.js} +1 -1
  35. package/.output/public/_nuxt/Cst8yEet.js +1 -0
  36. package/.output/public/_nuxt/Cuw2--X2.js +2 -0
  37. package/.output/public/_nuxt/D-jg-SoR.js +1 -0
  38. package/.output/public/_nuxt/{B4R5CHkk.js → D-z6N1Cz.js} +1 -1
  39. package/.output/public/_nuxt/D3gfSKKi2.js +1 -0
  40. package/.output/public/_nuxt/{BtNT93vm2.js → D4elH6Bo2.js} +1 -1
  41. package/.output/public/_nuxt/{BuVH9MB-.js → D4tAdwYm.js} +1 -1
  42. package/.output/public/_nuxt/D5-QB_-l.js +1 -0
  43. package/.output/public/_nuxt/DBzdrPzw2.js +1 -0
  44. package/.output/public/_nuxt/{CCCq9H7D2.js → DC7WzYCf2.js} +1 -1
  45. package/.output/public/_nuxt/DD4J2Otc.js +1 -0
  46. package/.output/public/_nuxt/DE-qkHRd2.js +1 -0
  47. package/.output/public/_nuxt/{BXKCB3rS.js → DE2kUGPK.js} +1 -1
  48. package/.output/public/_nuxt/{CoGETbe-2.js → DI4sdLmu2.js} +1 -1
  49. package/.output/public/_nuxt/DKHA3XxF.js +2 -0
  50. package/.output/public/_nuxt/{Drhta6gr.js → DL6fliAT.js} +2 -2
  51. package/.output/public/_nuxt/{DvUt9uMt2.js → DP6tsk912.js} +1 -1
  52. package/.output/public/_nuxt/DP_e7Vwv.js +24 -0
  53. package/.output/public/_nuxt/{DKhRushG.js → DR83EvmX.js} +1 -1
  54. package/.output/public/_nuxt/DSWuWYx_2.js +1 -0
  55. package/.output/public/_nuxt/{BhrnGVGz.js → DSdxfFX_.js} +1 -1
  56. package/.output/public/_nuxt/DVS06wUy2.js +13 -0
  57. package/.output/public/_nuxt/DXlAfhEi.js +3 -0
  58. package/.output/public/_nuxt/Dc5NeCDq.js +1 -0
  59. package/.output/public/_nuxt/{CW1HGp5X.js → DiHL9ehB.js} +1 -1
  60. package/.output/public/_nuxt/DjtDexGg.js +1 -0
  61. package/.output/public/_nuxt/{CuRtzvsa2.js → DnunMTRD2.js} +1 -1
  62. package/.output/public/_nuxt/{CZ0Gt81h.js → Dok0B4Ol.js} +2 -2
  63. package/.output/public/_nuxt/DqT2_Jtw2.js +1 -0
  64. package/.output/public/_nuxt/{DJZzthKt2.js → DtMlAxCm2.js} +1 -1
  65. package/.output/public/_nuxt/{Du0zf-d3.js → DwzJpr7P.js} +1 -1
  66. package/.output/public/_nuxt/J94L7hHq2.js +1 -0
  67. package/.output/public/_nuxt/LQBLwrYS2.js +1 -0
  68. package/.output/public/_nuxt/N9TYd_Mk2.js +1 -0
  69. package/.output/public/_nuxt/QSY9fE482.js +1 -0
  70. package/.output/public/_nuxt/{MEwEMEMl2.js → Qa9rS9oK2.js} +6 -6
  71. package/.output/public/_nuxt/{pNy4V4kd.js → R3gBFghJ2.js} +1 -1
  72. package/.output/public/_nuxt/{BAqtRt0q.js → ZxBwmbs9.js} +1 -1
  73. package/.output/public/_nuxt/{BMUEVeOK.js → _mD4IkJj.js} +1 -1
  74. package/.output/public/_nuxt/analysis.DfMg76el.css +1 -0
  75. package/.output/public/_nuxt/builds/latest.json +1 -1
  76. package/.output/public/_nuxt/builds/meta/eba8574d-1991-47df-944c-18608bb58181.json +1 -0
  77. package/.output/public/_nuxt/c_nqArmG.js +1 -0
  78. package/.output/public/_nuxt/{default.8ac6QU28.css → default.Bx6RJSbr.css} +1 -1
  79. package/.output/public/_nuxt/{entry.BHNNQA9H.css → entry.BlbU43qz.css} +1 -1
  80. package/.output/public/_nuxt/h8ddxY892.js +1 -0
  81. package/.output/public/_nuxt/{TjGWqrHo.js → i3KBHle7.js} +1 -1
  82. package/.output/public/_nuxt/jmKfTQMN.js +13 -0
  83. package/.output/public/_nuxt/{CZwDnomB.js → taHLOXkS.js} +1 -1
  84. package/.output/public/_nuxt/uYP6z4G72.js +1 -0
  85. package/.output/public/_nuxt/{CIz7SM4H.js → yuIP6K9s.js} +1 -1
  86. package/.output/public/_nuxt/zWg-9WN6.js +19 -0
  87. package/.output/public/_nuxt/zrgcKVTq.js +2 -0
  88. package/.output/server/chunks/_/LeftOutlined.mjs +1 -1
  89. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  90. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  91. package/.output/server/chunks/_/nitro.mjs +1662 -1232
  92. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  93. package/.output/server/chunks/_/scene-layout.repo.mjs +1 -1
  94. package/.output/server/chunks/build/{AuthGate-DDPYswkA.mjs → AuthGate-BK2RqkbD.mjs} +5 -5
  95. package/.output/server/chunks/build/{AuthGate-DDPYswkA.mjs.map → AuthGate-BK2RqkbD.mjs.map} +1 -1
  96. package/.output/server/chunks/build/Checkbox-4EdGAAl_.mjs +1 -1
  97. package/.output/server/chunks/build/{FormItemContext-4ORSzhWv.mjs → FormItemContext-BqtgOBDe.mjs} +2 -2
  98. package/.output/server/chunks/build/{FormItemContext-4ORSzhWv.mjs.map → FormItemContext-BqtgOBDe.mjs.map} +1 -1
  99. package/.output/server/chunks/build/{OmpTerminalPanel-DZ2wHMS1.mjs → OmpTerminalPanel-Bun6rpAk.mjs} +4 -4
  100. package/.output/server/chunks/build/{OmpTerminalPanel-DZ2wHMS1.mjs.map → OmpTerminalPanel-Bun6rpAk.mjs.map} +1 -1
  101. package/.output/server/chunks/build/{PluginSlot-CT4YaNrB.mjs → PluginSlot-Do6dX0RE.mjs} +2 -2
  102. package/.output/server/chunks/build/{PluginSlot-CT4YaNrB.mjs.map → PluginSlot-Do6dX0RE.mjs.map} +1 -1
  103. package/.output/server/chunks/build/{TownView-CZbFn6mO.mjs → TownView-kQZFf4zj.mjs} +3 -3
  104. package/.output/server/chunks/build/{TownView-CZbFn6mO.mjs.map → TownView-kQZFf4zj.mjs.map} +1 -1
  105. package/.output/server/chunks/build/{_id_-Df2pgsAq.mjs → _id_-Bbx1b74O.mjs} +3 -3
  106. package/.output/server/chunks/build/{_id_-Df2pgsAq.mjs.map → _id_-Bbx1b74O.mjs.map} +1 -1
  107. package/.output/server/chunks/build/{_id_-CCVhpJtj.mjs → _id_-IijrRw3f.mjs} +3 -3
  108. package/.output/server/chunks/build/{_id_-CCVhpJtj.mjs.map → _id_-IijrRw3f.mjs.map} +1 -1
  109. package/.output/server/chunks/build/{_wsId_-CJqF-hmP.mjs → _wsId_-Dp3ACbQ5.mjs} +22 -21
  110. package/.output/server/chunks/build/{_wsId_-CJqF-hmP.mjs.map → _wsId_-Dp3ACbQ5.mjs.map} +1 -1
  111. package/.output/server/chunks/build/{agents-BTsbna5H.mjs → agents-BfIoGr_p.mjs} +18 -17
  112. package/.output/server/chunks/build/agents-BfIoGr_p.mjs.map +1 -0
  113. package/.output/server/chunks/build/{aml-BBKfWto1.mjs → aml-B5zKrvB3.mjs} +7 -7
  114. package/.output/server/chunks/build/{aml-BBKfWto1.mjs.map → aml-B5zKrvB3.mjs.map} +1 -1
  115. package/.output/server/chunks/build/analysis-MVEnlO7A.mjs +531 -0
  116. package/.output/server/chunks/build/analysis-MVEnlO7A.mjs.map +1 -0
  117. package/.output/server/chunks/build/{card-DJOYGuVH.mjs → card-IyQjdGXA.mjs} +4 -4
  118. package/.output/server/chunks/build/{card-DJOYGuVH.mjs.map → card-IyQjdGXA.mjs.map} +1 -1
  119. package/.output/server/chunks/build/{channel-templates-BPKJ8e4l.mjs → channel-templates-Bd8bgBCh.mjs} +11 -10
  120. package/.output/server/chunks/build/channel-templates-Bd8bgBCh.mjs.map +1 -0
  121. package/.output/server/chunks/build/{checkbox-C4AKj81e.mjs → checkbox-NnjtOam0.mjs} +3 -3
  122. package/.output/server/chunks/build/{checkbox-C4AKj81e.mjs.map → checkbox-NnjtOam0.mjs.map} +1 -1
  123. package/.output/server/chunks/build/{daq-Cz7TaUAM.mjs → daq-mC3-5A0L.mjs} +5 -5
  124. package/.output/server/chunks/build/{daq-Cz7TaUAM.mjs.map → daq-mC3-5A0L.mjs.map} +1 -1
  125. package/.output/server/chunks/build/dcw-EhjJpVQM.mjs +2 -2
  126. package/.output/server/chunks/build/{default-DweMY872.mjs → default-flcNWlNg.mjs} +30 -19
  127. package/.output/server/chunks/build/{default-DweMY872.mjs.map → default-flcNWlNg.mjs.map} +1 -1
  128. package/.output/server/chunks/build/{descriptions-CFaUq4y4.mjs → descriptions-DuAefuzp.mjs} +2 -2
  129. package/.output/server/chunks/build/{descriptions-CFaUq4y4.mjs.map → descriptions-DuAefuzp.mjs.map} +1 -1
  130. package/.output/server/chunks/build/{drawer-Cfh9_zft.mjs → drawer-DEIB1_X6.mjs} +2 -2
  131. package/.output/server/chunks/build/{drawer-Cfh9_zft.mjs.map → drawer-DEIB1_X6.mjs.map} +1 -1
  132. package/.output/server/chunks/build/{dropdown-CV9GW3z9.mjs → dropdown-BuD1pxH2.mjs} +6 -5
  133. package/.output/server/chunks/build/{dropdown-CV9GW3z9.mjs.map → dropdown-BuD1pxH2.mjs.map} +1 -1
  134. package/.output/server/chunks/build/{dropdown-CIsqbX4P.mjs → dropdown-w7qhyN2D.mjs} +2 -2
  135. package/.output/server/chunks/build/{dropdown-CIsqbX4P.mjs.map → dropdown-w7qhyN2D.mjs.map} +1 -1
  136. package/.output/server/chunks/build/es-DfgEl5n-.mjs +42 -0
  137. package/.output/server/chunks/build/es-DfgEl5n-.mjs.map +1 -0
  138. package/.output/server/chunks/build/{form-cs_RcfGx.mjs → form-CMLL_-Xx.mjs} +7 -6
  139. package/.output/server/chunks/build/{form-cs_RcfGx.mjs.map → form-CMLL_-Xx.mjs.map} +1 -1
  140. package/.output/server/chunks/build/{input-CobQ5LJ5.mjs → input-DZcioTwL.mjs} +93 -3449
  141. package/.output/server/chunks/build/input-DZcioTwL.mjs.map +1 -0
  142. package/.output/server/chunks/build/{input-number-BpPYAWMk.mjs → input-number-BRnbiKLd.mjs} +6 -5
  143. package/.output/server/chunks/build/{input-number-BpPYAWMk.mjs.map → input-number-BRnbiKLd.mjs.map} +1 -1
  144. package/.output/server/chunks/build/{logs-As9fZqU-.mjs → logs-BYop3JfX.mjs} +3 -3
  145. package/.output/server/chunks/build/{logs-As9fZqU-.mjs.map → logs-BYop3JfX.mjs.map} +1 -1
  146. package/.output/server/chunks/build/{menu-CVmvHyFT.mjs → menu-DXfhc0qN.mjs} +4 -3
  147. package/.output/server/chunks/build/{menu-CVmvHyFT.mjs.map → menu-DXfhc0qN.mjs.map} +1 -1
  148. package/.output/server/chunks/build/{monitor-CdFQ2z4g.mjs → monitor-BjBGkUm2.mjs} +20 -19
  149. package/.output/server/chunks/build/{monitor-CdFQ2z4g.mjs.map → monitor-BjBGkUm2.mjs.map} +1 -1
  150. package/.output/server/chunks/build/{operations-B2gHCWgZ.mjs → operations-fxI8lEBJ.mjs} +3 -3
  151. package/.output/server/chunks/build/{operations-B2gHCWgZ.mjs.map → operations-fxI8lEBJ.mjs.map} +1 -1
  152. package/.output/server/chunks/build/{pages-BItCt1ar.mjs → pages-6JD9VSbx.mjs} +5 -5
  153. package/.output/server/chunks/build/{pages-BItCt1ar.mjs.map → pages-6JD9VSbx.mjs.map} +1 -1
  154. package/.output/server/chunks/build/{permissions-D6mQw_9j.mjs → permissions-u5SZL8Fe.mjs} +14 -13
  155. package/.output/server/chunks/build/permissions-u5SZL8Fe.mjs.map +1 -0
  156. package/.output/server/chunks/build/{plugins-NAS9MQ5r.mjs → plugins-Cas6KOF-.mjs} +5 -5
  157. package/.output/server/chunks/build/{plugins-NAS9MQ5r.mjs.map → plugins-Cas6KOF-.mjs.map} +1 -1
  158. package/.output/server/chunks/build/{popconfirm-DFfoFhmt.mjs → popconfirm-BWxt-53K.mjs} +3 -3
  159. package/.output/server/chunks/build/{popconfirm-DFfoFhmt.mjs.map → popconfirm-BWxt-53K.mjs.map} +1 -1
  160. package/.output/server/chunks/build/{schedules-BjWNDWL5.mjs → schedules-Ct68Jrvw.mjs} +20 -19
  161. package/.output/server/chunks/build/{schedules-BjWNDWL5.mjs.map → schedules-Ct68Jrvw.mjs.map} +1 -1
  162. package/.output/server/chunks/build/{segmented-D7FkCgg7.mjs → segmented-DN62bOFu.mjs} +3 -3
  163. package/.output/server/chunks/build/{segmented-D7FkCgg7.mjs.map → segmented-DN62bOFu.mjs.map} +1 -1
  164. package/.output/server/chunks/build/{select-FqBNxgxT.mjs → select-DQv1DXcW.mjs} +5 -4
  165. package/.output/server/chunks/build/{select-FqBNxgxT.mjs.map → select-DQv1DXcW.mjs.map} +1 -1
  166. package/.output/server/chunks/build/{settings-Cl_KRyEn.mjs → settings-CQzR1YXR.mjs} +14 -13
  167. package/.output/server/chunks/build/settings-CQzR1YXR.mjs.map +1 -0
  168. package/.output/server/chunks/build/{space-B2uhHJG8.mjs → space-6FfG3llN.mjs} +2 -2
  169. package/.output/server/chunks/build/{space-B2uhHJG8.mjs.map → space-6FfG3llN.mjs.map} +1 -1
  170. package/.output/server/chunks/build/{switch-DZAUIbIN.mjs → switch-CfsCVFQP.mjs} +3 -3
  171. package/.output/server/chunks/build/{switch-DZAUIbIN.mjs.map → switch-CfsCVFQP.mjs.map} +1 -1
  172. package/.output/server/chunks/build/{table-CeOYERqr.mjs → table-HOjbB5YY.mjs} +11 -10
  173. package/.output/server/chunks/build/{table-CeOYERqr.mjs.map → table-HOjbB5YY.mjs.map} +1 -1
  174. package/.output/server/chunks/build/{tabs-LLNSdLl2.mjs → tabs-CC26Rbcw.mjs} +6 -5
  175. package/.output/server/chunks/build/{tabs-LLNSdLl2.mjs.map → tabs-CC26Rbcw.mjs.map} +1 -1
  176. package/.output/server/chunks/build/{tag-Dwvkh0Dj.mjs → tag-BtOMjpDx.mjs} +5 -4
  177. package/.output/server/chunks/build/{tag-Dwvkh0Dj.mjs.map → tag-BtOMjpDx.mjs.map} +1 -1
  178. package/.output/server/chunks/build/{teams-CGDZHaQl.mjs → teams-Re0wY2SQ.mjs} +19 -18
  179. package/.output/server/chunks/build/teams-Re0wY2SQ.mjs.map +1 -0
  180. package/.output/server/chunks/build/{tokens-BOYkZuoB.mjs → tokens-DLFIUvXE.mjs} +19 -18
  181. package/.output/server/chunks/build/tokens-DLFIUvXE.mjs.map +1 -0
  182. package/.output/server/chunks/build/tooltip-BSDwL_LM.mjs +3362 -0
  183. package/.output/server/chunks/build/tooltip-BSDwL_LM.mjs.map +1 -0
  184. package/.output/server/chunks/build/town-BV-hbwb5.mjs +1 -1
  185. package/.output/server/chunks/build/{town-P1rYoi0v.mjs → town-Bfme7P2I.mjs} +5 -5
  186. package/.output/server/chunks/build/{town-P1rYoi0v.mjs.map → town-Bfme7P2I.mjs.map} +1 -1
  187. package/.output/server/chunks/build/types-D6J7slEa.mjs +1 -1
  188. package/.output/server/chunks/build/types-DWqIeMRP.mjs +75 -0
  189. package/.output/server/chunks/build/types-DWqIeMRP.mjs.map +1 -0
  190. package/.output/server/chunks/build/{useAgentTemplateActions-DsBRUQni.mjs → useAgentTemplateActions-CjBwCb3u.mjs} +1 -1
  191. package/.output/server/chunks/build/{useAgentTemplateActions-DsBRUQni.mjs.map → useAgentTemplateActions-CjBwCb3u.mjs.map} +1 -1
  192. package/.output/server/chunks/build/{useAgentTemplateForm-DzQ_t2Ue.mjs → useAgentTemplateForm-BX9_xqj8.mjs} +1 -1
  193. package/.output/server/chunks/build/{useAgentTemplateForm-DzQ_t2Ue.mjs.map → useAgentTemplateForm-BX9_xqj8.mjs.map} +1 -1
  194. package/.output/server/chunks/build/{useAmlEntities-BMLHU_39.mjs → useAmlEntities-BrcTqHwa.mjs} +2 -2
  195. package/.output/server/chunks/build/{useAmlEntities-BMLHU_39.mjs.map → useAmlEntities-BrcTqHwa.mjs.map} +1 -1
  196. package/.output/server/chunks/build/{useAmlEnv-DdlyVzPu.mjs → useAmlEnv-jiGYK790.mjs} +1 -1
  197. package/.output/server/chunks/build/{useAmlEnv-DdlyVzPu.mjs.map → useAmlEnv-jiGYK790.mjs.map} +1 -1
  198. package/.output/server/chunks/build/{useAmlJobs-BG_v21hJ.mjs → useAmlJobs-CVZ1btzg.mjs} +1 -1
  199. package/.output/server/chunks/build/{useAmlJobs-BG_v21hJ.mjs.map → useAmlJobs-CVZ1btzg.mjs.map} +1 -1
  200. package/.output/server/chunks/build/{useAmlModels-D7MuOWOy.mjs → useAmlModels-DJkQzcCU.mjs} +1 -1
  201. package/.output/server/chunks/build/{useAmlModels-D7MuOWOy.mjs.map → useAmlModels-DJkQzcCU.mjs.map} +1 -1
  202. package/.output/server/chunks/build/{useAmlNotes-CTZe-GI0.mjs → useAmlNotes-DKnx9a8x.mjs} +1 -1
  203. package/.output/server/chunks/build/{useAmlNotes-CTZe-GI0.mjs.map → useAmlNotes-DKnx9a8x.mjs.map} +1 -1
  204. package/.output/server/chunks/build/{useAmlPredict-BToRrVRV.mjs → useAmlPredict-Bp4ehwKw.mjs} +1 -1
  205. package/.output/server/chunks/build/{useAmlPredict-BToRrVRV.mjs.map → useAmlPredict-Bp4ehwKw.mjs.map} +1 -1
  206. package/.output/server/chunks/build/useAnalysisFeed-B4OwUd7p.mjs +128 -0
  207. package/.output/server/chunks/build/useAnalysisFeed-B4OwUd7p.mjs.map +1 -0
  208. package/.output/server/chunks/build/useDaqAddNode-CaOCbe4-.mjs +1 -1
  209. package/.output/server/chunks/build/{useDaqDetailNode-DXgwAu5u.mjs → useDaqDetailNode-DtZ0oDAn.mjs} +3 -3
  210. package/.output/server/chunks/build/{useDaqDetailNode-DXgwAu5u.mjs.map → useDaqDetailNode-DtZ0oDAn.mjs.map} +1 -1
  211. package/.output/server/chunks/build/useDaqDetailParams-CrTMDs-2.mjs +1 -1
  212. package/.output/server/chunks/build/{useDaqFilters-Jx6EERfr.mjs → useDaqFilters-DYHGhECw.mjs} +3 -3
  213. package/.output/server/chunks/build/{useDaqFilters-Jx6EERfr.mjs.map → useDaqFilters-DYHGhECw.mjs.map} +1 -1
  214. package/.output/server/chunks/build/useDaqStream-DhzdoyIR.mjs +1 -1
  215. package/.output/server/chunks/build/useDaqTemplates-C7GzQmdJ.mjs +1 -1
  216. package/.output/server/chunks/build/{useDashboardData-Ce-EU5DJ.mjs → useDashboardData-B3lZjE7x.mjs} +3 -3
  217. package/.output/server/chunks/build/{useDashboardData-Ce-EU5DJ.mjs.map → useDashboardData-B3lZjE7x.mjs.map} +1 -1
  218. package/.output/server/chunks/build/useDcwAddNode-4mTPQ6T8.mjs +1 -1
  219. package/.output/server/chunks/build/{useDcwDetailScope-4j3B03Pi.mjs → useDcwDetailScope-BWH7jnVh.mjs} +2 -2
  220. package/.output/server/chunks/build/{useDcwDetailScope-4j3B03Pi.mjs.map → useDcwDetailScope-BWH7jnVh.mjs.map} +1 -1
  221. package/.output/server/chunks/build/useDcwStream-BXJ2V8HM.mjs +1 -1
  222. package/.output/server/chunks/build/{useLogsManual-CMjD62nt.mjs → useLogsManual-CElmZuJh.mjs} +1 -1
  223. package/.output/server/chunks/build/{useLogsManual-CMjD62nt.mjs.map → useLogsManual-CElmZuJh.mjs.map} +1 -1
  224. package/.output/server/chunks/build/{useMonitorData-D2gFSonG.mjs → useMonitorData-DcIfMEiz.mjs} +1 -1
  225. package/.output/server/chunks/build/{useMonitorData-D2gFSonG.mjs.map → useMonitorData-DcIfMEiz.mjs.map} +1 -1
  226. package/.output/server/chunks/build/{useTeamActions-BOLQkYxg.mjs → useTeamActions-C3_O_AIU.mjs} +1 -1
  227. package/.output/server/chunks/build/{useTeamActions-BOLQkYxg.mjs.map → useTeamActions-C3_O_AIU.mjs.map} +1 -1
  228. package/.output/server/chunks/build/{useTeamAddMemberDialog-BCgrLPxI.mjs → useTeamAddMemberDialog-DWAoZCKd.mjs} +1 -1
  229. package/.output/server/chunks/build/{useTeamAddMemberDialog-BCgrLPxI.mjs.map → useTeamAddMemberDialog-DWAoZCKd.mjs.map} +1 -1
  230. package/.output/server/chunks/build/{useTeamCreateDialog-CJk40LqS.mjs → useTeamCreateDialog-911mIPWd.mjs} +1 -1
  231. package/.output/server/chunks/build/{useTeamCreateDialog-CJk40LqS.mjs.map → useTeamCreateDialog-911mIPWd.mjs.map} +1 -1
  232. package/.output/server/chunks/build/{useTeamDeployDialog-49hdUXQP.mjs → useTeamDeployDialog-D0STROoQ.mjs} +1 -1
  233. package/.output/server/chunks/build/{useTeamDeployDialog-49hdUXQP.mjs.map → useTeamDeployDialog-D0STROoQ.mjs.map} +1 -1
  234. package/.output/server/chunks/build/{useTeamPluginDialog-Dh-QOoiU.mjs → useTeamPluginDialog-Df6-e2OW.mjs} +1 -1
  235. package/.output/server/chunks/build/{useTeamPluginDialog-Dh-QOoiU.mjs.map → useTeamPluginDialog-Df6-e2OW.mjs.map} +1 -1
  236. package/.output/server/chunks/build/{useTokenCreate-DkYvEQUD.mjs → useTokenCreate-DOojAhM5.mjs} +1 -1
  237. package/.output/server/chunks/build/{useTokenCreate-DkYvEQUD.mjs.map → useTokenCreate-DOojAhM5.mjs.map} +1 -1
  238. package/.output/server/chunks/build/{useTokenRename-DOCP4aeI.mjs → useTokenRename-CMA5dLHx.mjs} +1 -1
  239. package/.output/server/chunks/build/{useTokenRename-DOCP4aeI.mjs.map → useTokenRename-CMA5dLHx.mjs.map} +1 -1
  240. package/.output/server/chunks/build/{useTokenReveal-CybwwflV.mjs → useTokenReveal-C19aCKzt.mjs} +1 -1
  241. package/.output/server/chunks/build/{useTokenReveal-CybwwflV.mjs.map → useTokenReveal-C19aCKzt.mjs.map} +1 -1
  242. package/.output/server/chunks/build/{useTokensList-BLiMvrc4.mjs → useTokensList-D0ZpLOhR.mjs} +1 -1
  243. package/.output/server/chunks/build/{useTokensList-BLiMvrc4.mjs.map → useTokensList-D0ZpLOhR.mjs.map} +1 -1
  244. package/.output/server/chunks/build/{useWorkbenchAuth-DAabQl7X.mjs → useWorkbenchAuth-CN5E3J5L.mjs} +1 -1
  245. package/.output/server/chunks/build/{useWorkbenchAuth-DAabQl7X.mjs.map → useWorkbenchAuth-CN5E3J5L.mjs.map} +1 -1
  246. package/.output/server/chunks/build/{useWorkbenchWorkspaces-6-mpCGCR.mjs → useWorkbenchWorkspaces-ChKByQSD.mjs} +1 -1
  247. package/.output/server/chunks/build/{useWorkbenchWorkspaces-6-mpCGCR.mjs.map → useWorkbenchWorkspaces-ChKByQSD.mjs.map} +1 -1
  248. package/.output/server/chunks/build/{users-B_pHStEa.mjs → users-BW4jowK4.mjs} +15 -14
  249. package/.output/server/chunks/build/users-BW4jowK4.mjs.map +1 -0
  250. package/.output/server/chunks/build/{workshop-C0DefygA.mjs → workshop-Bx55czXL.mjs} +11 -10
  251. package/.output/server/chunks/build/workshop-Bx55czXL.mjs.map +1 -0
  252. package/.output/server/chunks/routes/api/mcp/workshop.mjs +1 -1
  253. package/.output/server/chunks/routes/api/system/backup/run.post.mjs +2 -2
  254. package/.output/server/chunks/routes/api/workshop/analysis/_id_.delete.mjs +46 -0
  255. package/.output/server/chunks/routes/api/workshop/analysis/_id_.delete.mjs.map +1 -0
  256. package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs +40 -0
  257. package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs.map +1 -0
  258. package/.output/server/chunks/routes/api/workshop/analysis/_id_.patch.mjs +103 -0
  259. package/.output/server/chunks/routes/api/workshop/analysis/_id_.patch.mjs.map +1 -0
  260. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +1 -1
  261. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +1 -1
  262. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +2 -2
  263. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +1 -1
  264. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.post.mjs +1 -1
  265. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
  266. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +1 -1
  267. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
  268. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
  269. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +1 -1
  270. package/.output/server/chunks/routes/api/workshop/channels/_id/line.put.mjs +1 -1
  271. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +1 -1
  272. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs +1 -1
  273. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.patch.mjs +1 -1
  274. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +1 -1
  275. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +7 -7
  276. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +1 -1
  277. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +1 -1
  278. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +1 -1
  279. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +1 -1
  280. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +1 -1
  281. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +1 -1
  282. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +1 -1
  283. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +1 -1
  284. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +1 -1
  285. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +1 -1
  286. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +1 -1
  287. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +1 -1
  288. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +1 -1
  289. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +1 -1
  290. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +1 -1
  291. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +1 -1
  292. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +1 -1
  293. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -1
  294. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +1 -1
  295. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +1 -1
  296. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +1 -1
  297. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +1 -1
  298. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +1 -1
  299. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
  300. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +1 -1
  301. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +1 -1
  302. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +1 -1
  303. package/.output/server/chunks/routes/api/workshop/dcw/index7.get.mjs +1 -1
  304. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +1 -1
  305. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +1 -1
  306. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  307. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  308. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
  309. package/.output/server/chunks/routes/api/workshop/dcw/mes-artifacts/file.get.mjs +1 -1
  310. package/.output/server/chunks/routes/api/workshop/dcw/mes-hook-test.post.mjs +1 -1
  311. package/.output/server/chunks/routes/api/workshop/dcw/mes-test-read.post.mjs +1 -1
  312. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +1 -1
  313. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +1 -1
  314. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +1 -1
  315. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +1 -1
  316. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +1 -1
  317. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +1 -1
  318. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +1 -1
  319. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +1 -1
  320. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +1 -1
  321. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +1 -1
  322. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +1 -1
  323. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +1 -1
  324. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +1 -1
  325. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +1 -1
  326. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +1 -1
  327. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
  328. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +1 -1
  329. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  330. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  331. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +1 -1
  332. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +1 -1
  333. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +1 -1
  334. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +1 -1
  335. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +1 -1
  336. package/.output/server/chunks/routes/api/workshop/exp/confirmations/_id/decide.post.mjs +1 -1
  337. package/.output/server/chunks/routes/api/workshop/exp/index.get.mjs +1 -1
  338. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +1 -1
  339. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  340. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  341. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  342. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  343. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  344. package/.output/server/chunks/routes/api/workshop/index10.get.mjs +20 -23
  345. package/.output/server/chunks/routes/api/workshop/index10.get.mjs.map +1 -1
  346. package/.output/server/chunks/routes/api/workshop/index11.get.mjs +25 -11
  347. package/.output/server/chunks/routes/api/workshop/index11.get.mjs.map +1 -1
  348. package/.output/server/chunks/routes/api/workshop/index12.get.mjs +10 -4
  349. package/.output/server/chunks/routes/api/workshop/index12.get.mjs.map +1 -1
  350. package/.output/server/chunks/routes/api/workshop/index13.get.mjs +2 -3
  351. package/.output/server/chunks/routes/api/workshop/index13.get.mjs.map +1 -1
  352. package/.output/server/chunks/routes/api/workshop/index14.get.mjs +3 -2
  353. package/.output/server/chunks/routes/api/workshop/index14.get.mjs.map +1 -1
  354. package/.output/server/chunks/routes/api/workshop/index15.get.mjs +30 -0
  355. package/.output/server/chunks/routes/api/workshop/index15.get.mjs.map +1 -0
  356. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +24 -9
  357. package/.output/server/chunks/routes/api/workshop/index3.get.mjs.map +1 -1
  358. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +1 -1
  359. package/.output/server/chunks/routes/api/workshop/index4.get.mjs +10 -4
  360. package/.output/server/chunks/routes/api/workshop/index4.get.mjs.map +1 -1
  361. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +1 -1
  362. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +4 -29
  363. package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
  364. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +1 -1
  365. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +25 -22
  366. package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
  367. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +26 -5
  368. package/.output/server/chunks/routes/api/workshop/index7.get.mjs.map +1 -1
  369. package/.output/server/chunks/routes/api/workshop/index8.get.mjs +4 -39
  370. package/.output/server/chunks/routes/api/workshop/index8.get.mjs.map +1 -1
  371. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +40 -20
  372. package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
  373. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  374. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  375. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  376. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  377. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -1
  378. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +1 -1
  379. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +1 -1
  380. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -2
  381. package/.output/server/chunks/routes/renderer.mjs +3 -3
  382. package/.output/server/chunks/virtual/entry.mjs +199 -468
  383. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  384. package/.output/server/package.json +1 -1
  385. package/README-zh.md +17 -0
  386. package/README.md +20 -0
  387. package/app/components/AppSidebar.vue +1 -0
  388. package/app/components/analysis/AnalysisEditModal.vue +192 -0
  389. package/app/components/analysis/AnalysisFilterCard.vue +159 -0
  390. package/app/components/analysis/AnalysisPageHead.vue +47 -0
  391. package/app/components/analysis/AnalysisTable.vue +322 -0
  392. package/app/composables/useRouteMeta.ts +1 -0
  393. package/app/config/schema.ts +1 -0
  394. package/app/pages/analysis/composables/useAnalysisFeed.ts +85 -0
  395. package/app/pages/analysis/index.vue +128 -0
  396. package/app/pages/analysis/types.ts +50 -0
  397. package/cli/commands/mcp.mjs +160 -160
  398. package/i18n/locales/en.ts +63 -0
  399. package/i18n/locales/zh-CN.ts +63 -0
  400. package/mcp/aw-mcp-server.mjs +799 -799
  401. package/package.json +2 -2
  402. package/scripts/onboarding/onboard.mjs +5 -2
  403. package/scripts/onboarding/sim-twin.mjs +312 -0
  404. package/server/api/workshop/analysis/[id].delete.ts +30 -0
  405. package/server/api/workshop/analysis/[id].get.ts +25 -0
  406. package/server/api/workshop/analysis/[id].patch.ts +100 -0
  407. package/server/api/workshop/analysis/index.get.ts +39 -0
  408. package/server/plugins/workshop.ts +4 -0
  409. package/server/repositories/user.repository.ts +2 -2
  410. package/server/services/workshop/agents/host-tool-bridge/catalog.ts +4 -1
  411. package/server/services/workshop/agents/host-tool-bridge/tools/industrial.ts +5 -2
  412. package/server/services/workshop/agents/industrial/analysis-tools.ts +242 -0
  413. package/server/services/workshop/agents/industrial/index.ts +1 -0
  414. package/server/services/workshop/agents/industrial/ops-tools.ts +3 -2
  415. package/server/services/workshop/analysis/analysis.repo.ts +241 -0
  416. package/server/services/workshop/db/database/migrations.ts +10 -0
  417. package/server/services/workshop/db/database/open.ts +3 -1
  418. package/server/services/workshop/db/database/schema.ts +32 -1
  419. package/server/services/workshop/db/ops.repo.ts +1 -1
  420. package/server/services/workshop/db/retention.ts +2 -0
  421. package/server/services/workshop/db/schema.sql +31 -0
  422. package/server/services/workshop/settings.ts +1 -0
  423. package/shared/config/schema.json +1 -0
  424. package/.output/public/_nuxt/B-Y_rsfn.js +0 -106
  425. package/.output/public/_nuxt/B02cxZz72.js +0 -1
  426. package/.output/public/_nuxt/BKHd_sKD2.js +0 -47
  427. package/.output/public/_nuxt/BikIgp9R.js +0 -1
  428. package/.output/public/_nuxt/BkGqyjWm.js +0 -3
  429. package/.output/public/_nuxt/Br2LgfbH2.js +0 -13
  430. package/.output/public/_nuxt/BrFF_9742.js +0 -1
  431. package/.output/public/_nuxt/BtYg4aGR2.js +0 -1
  432. package/.output/public/_nuxt/C4X_Z1lA.js +0 -1
  433. package/.output/public/_nuxt/CBATzTUf.js +0 -13
  434. package/.output/public/_nuxt/CEP4UrDv.js +0 -1
  435. package/.output/public/_nuxt/CIPKYgrH2.js +0 -1
  436. package/.output/public/_nuxt/CPSHP_EI.js +0 -1
  437. package/.output/public/_nuxt/CSyIwYcJ2.js +0 -1
  438. package/.output/public/_nuxt/CZkTlW93.js +0 -2
  439. package/.output/public/_nuxt/CZyYdpqZ2.js +0 -1
  440. package/.output/public/_nuxt/CeDkXWCz.js +0 -1
  441. package/.output/public/_nuxt/Cl19UD7U.js +0 -1
  442. package/.output/public/_nuxt/ClrkV0C4.js +0 -1
  443. package/.output/public/_nuxt/Cv_H1gOM2.js +0 -1
  444. package/.output/public/_nuxt/D5i2ofVw2.js +0 -1
  445. package/.output/public/_nuxt/D6XGn5vM.js +0 -2
  446. package/.output/public/_nuxt/D8VQGThE.js +0 -28
  447. package/.output/public/_nuxt/DBwuADr82.js +0 -1
  448. package/.output/public/_nuxt/DfqRQSFn.js +0 -19
  449. package/.output/public/_nuxt/DraEWn4N2.js +0 -1
  450. package/.output/public/_nuxt/DyMgrV29.js +0 -1
  451. package/.output/public/_nuxt/H7Rbu32y2.js +0 -1
  452. package/.output/public/_nuxt/YDs3mbQu2.js +0 -1
  453. package/.output/public/_nuxt/Z3MSTcdu2.js +0 -1
  454. package/.output/public/_nuxt/_vR_sc7t.js +0 -24
  455. package/.output/public/_nuxt/builds/meta/92fd7e2e-18f2-45c3-8588-d93004dda6e3.json +0 -1
  456. package/.output/public/_nuxt/gbaq2UOO.js +0 -1
  457. package/.output/public/_nuxt/o-G6YtmK2.js +0 -1
  458. package/.output/public/_nuxt/ylowSquM2.js +0 -1
  459. package/.output/server/chunks/build/agents-BTsbna5H.mjs.map +0 -1
  460. package/.output/server/chunks/build/channel-templates-BPKJ8e4l.mjs.map +0 -1
  461. package/.output/server/chunks/build/input-CobQ5LJ5.mjs.map +0 -1
  462. package/.output/server/chunks/build/permissions-D6mQw_9j.mjs.map +0 -1
  463. package/.output/server/chunks/build/settings-Cl_KRyEn.mjs.map +0 -1
  464. package/.output/server/chunks/build/teams-CGDZHaQl.mjs.map +0 -1
  465. package/.output/server/chunks/build/tokens-BOYkZuoB.mjs.map +0 -1
  466. package/.output/server/chunks/build/users-B_pHStEa.mjs.map +0 -1
  467. package/.output/server/chunks/build/workshop-C0DefygA.mjs.map +0 -1
  468. package/scripts/_audit/.tmp/audit-data/dcw-params.json +0 -15
  469. package/scripts/_audit/.tmp/audit-data/dcws.json +0 -30
  470. package/scripts/_audit/aml-layout-diag.mjs +0 -83
  471. package/scripts/_audit/channel-inspect.mjs +0 -49
  472. package/scripts/_audit/cleanup-apply.mjs +0 -89
  473. package/scripts/_audit/cleanup-plan.mjs +0 -82
  474. package/scripts/_audit/contrast-check.mjs +0 -43
  475. package/scripts/_audit/dcw-controller-e2e.ts +0 -106
  476. package/scripts/_audit/dcw-flush-cost.ts +0 -43
  477. package/scripts/_audit/dcw-rollback-ledger.ts +0 -156
  478. package/scripts/_audit/dcw-unrecorded-write.ts +0 -171
  479. package/scripts/_audit/dcw-write-mutex.ts +0 -157
  480. package/scripts/_audit/design-shots.mjs +0 -145
  481. package/scripts/_audit/docs-font-probe.mjs +0 -68
  482. package/scripts/_audit/docs-probe.mjs +0 -107
  483. package/scripts/_audit/docs-shots.mjs +0 -171
  484. package/scripts/_audit/docs-v3-verify.mjs +0 -255
  485. package/scripts/_audit/docs-vue-lint.mjs +0 -81
  486. package/scripts/_audit/docs-vue-lint2.mjs +0 -91
  487. package/scripts/_audit/exp-cost-scaling.mjs +0 -57
  488. package/scripts/_audit/exp-envelope-and-png.mjs +0 -78
  489. package/scripts/_audit/exp-png-decode.mjs +0 -67
  490. package/scripts/_audit/exp-retention-plan.mjs +0 -61
  491. package/scripts/_audit/exp-retention-rescan.mjs +0 -42
  492. package/scripts/_audit/exp-sweep-fairness.mjs +0 -50
  493. package/scripts/_audit/feature-audit-e2e.mjs +0 -342
  494. package/scripts/_audit/fix-settings-count.mjs +0 -57
  495. package/scripts/_audit/full-e2e-adopt.mjs +0 -238
  496. package/scripts/_audit/full-e2e-close-loop.mjs +0 -134
  497. package/scripts/_audit/full-e2e-retrain.mjs +0 -320
  498. package/scripts/_audit/full-e2e-supplement.mjs +0 -192
  499. package/scripts/_audit/full-e2e-ui-final.mjs +0 -111
  500. package/scripts/_audit/full-e2e-ui-mount.mjs +0 -111
  501. package/scripts/_audit/full-feature-e2e-20260927.mjs +0 -627
  502. package/scripts/_audit/glass-verify.mjs +0 -155
  503. package/scripts/_audit/hydration-diff.mjs +0 -104
  504. package/scripts/_audit/hydration-head.mjs +0 -36
  505. package/scripts/_audit/hydration-probe.mjs +0 -59
  506. package/scripts/_audit/idd-scenarios-e2e.mjs +0 -239
  507. package/scripts/_audit/kb-diag-complete.mjs +0 -261
  508. package/scripts/_audit/kb-diag-complete2.mjs +0 -271
  509. package/scripts/_audit/kb-diag-loop-e2e.mjs +0 -357
  510. package/scripts/_audit/kb-diag-loop-mock.mjs +0 -416
  511. package/scripts/_audit/kb-diag-loop-v2.mjs +0 -314
  512. package/scripts/_audit/lead-matrix-test.mjs +0 -172
  513. package/scripts/_audit/plc-agent-task.mjs +0 -74
  514. package/scripts/_audit/plc-clean-scenario.mjs +0 -434
  515. package/scripts/_audit/plc-clean-shots.mjs +0 -161
  516. package/scripts/_audit/plc-fc10-probe.mjs +0 -30
  517. package/scripts/_audit/probe-binding.mjs +0 -114
  518. package/scripts/_audit/recipe-save-e2e.mjs +0 -365
  519. package/scripts/_audit/review-fix-verify.mjs +0 -158
  520. package/scripts/_audit/runtime-dir-e2e.mjs +0 -393
  521. package/scripts/_audit/town-focus-shot.mjs +0 -129
  522. package/scripts/_audit/town-reposition.mjs +0 -85
  523. package/scripts/_audit/verify-cleanup.mjs +0 -67
  524. package/scripts/_audit/verify-data-integrity.mjs +0 -112
  525. package/scripts/_audit/watchdog-recovery-test.mjs +0 -149
  526. package/scripts/_dbg-optloop-ui-shots.mjs +0 -52
  527. /package/.output/public/_nuxt/{4RTUlYvj2.js → 4RTUlYvj.js} +0 -0
  528. /package/.output/public/_nuxt/{BBhLVYdM.js → BBhLVYdM2.js} +0 -0
  529. /package/.output/public/_nuxt/{BG7XSX-S2.js → BG7XSX-S.js} +0 -0
  530. /package/.output/public/_nuxt/{BU7WuuKh.js → BU7WuuKh2.js} +0 -0
  531. /package/.output/public/_nuxt/{BrRX-l9B2.js → BrRX-l9B.js} +0 -0
  532. /package/.output/public/_nuxt/{CHyzK5m52.js → CHyzK5m5.js} +0 -0
  533. /package/.output/public/_nuxt/{Ckafrjnw2.js → Ckafrjnw.js} +0 -0
  534. /package/.output/public/_nuxt/{D1Xw30Dj2.js → D1Xw30Dj.js} +0 -0
  535. /package/.output/public/_nuxt/{DEhjFhZ2.js → DEhjFhZ22.js} +0 -0
  536. /package/.output/public/_nuxt/{DdNujZN5.js → DdNujZN52.js} +0 -0
  537. /package/.output/public/_nuxt/{DzwIZ81f.js → DzwIZ81f2.js} +0 -0
  538. /package/.output/public/_nuxt/{M6NcguDO.js → M6NcguDO2.js} +0 -0
  539. /package/.output/public/_nuxt/{MW-V7IIP2.js → MW-V7IIP.js} +0 -0
  540. /package/.output/public/_nuxt/{WmMwIS4y.js → WmMwIS4y2.js} +0 -0
  541. /package/.output/public/_nuxt/{qIQFsHtF.js → qIQFsHtF2.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentworkshop",
3
- "version": "0.7.59",
3
+ "version": "0.7.61",
4
4
  "type": "module",
5
5
  "description": "AgentWorkShop 软件开发系统 - 基于 Nuxt 4 的配置驱动运行范式",
6
6
  "license": "Apache-2.0",
@@ -136,7 +136,7 @@
136
136
  "minio": "^8.0.7",
137
137
  "modbus-serial": "^8.0.25",
138
138
  "mqtt": "^5.15.2",
139
- "node-opcua": "^2.178.0",
139
+ "node-opcua": "2.178.0",
140
140
  "nuxt": "^4.0.0",
141
141
  "nuxt-auth-utils": "^0.5.0",
142
142
  "pg": "^8.23.0",
@@ -35,6 +35,7 @@ if (!configPath) {
35
35
  const cfg = JSON.parse(readFileSync(configPath, 'utf8'))
36
36
 
37
37
  let pass = 0, fail = 0
38
+ let smokeRunId = null
38
39
  const ok = (name, cond, detail = '') => {
39
40
  console.log(`${cond ? '✅' : '❌'} ${name}${detail ? ` — ${String(detail).slice(0, 150)}` : ''}`)
40
41
  cond ? pass++ : fail++
@@ -178,8 +179,8 @@ if (smoke) {
178
179
  }
179
180
  }
180
181
  }
181
- const runId = /runId[::]\s*(rr-[\w-]+)/.exec(propTxt)?.[1] ?? ''
182
- ok('冒烟闭环步(自动 HITL):批准→下发→设备证实', okDispatch, `${propTxt.split('\n')[0]?.slice(0, 90)} runId=${runId}`)
182
+ smokeRunId = /runId[::]\s*(rr-[\w-]+)/.exec(propTxt)?.[1] ?? null
183
+ ok('冒烟闭环步(自动 HITL):批准→下发→设备证实', okDispatch, `${propTxt.split('\n')[0]?.slice(0, 90)} runId=${smokeRunId}`)
183
184
  }
184
185
 
185
186
  // ---------- 交接声明 ----------
@@ -192,5 +193,7 @@ console.log(`
192
193
  ③ 由人裁决首批真实提案后,方可视为正式投用。
193
194
  (对产线负责:任何不确定 —— 量程/步限/SP-PV 判定/认证方式/场景目标 —— skill 必须先询问用户,禁止猜测。)
194
195
  =====================================================`)
196
+ // 机器可读摘要(末行 JSON;与 provision-line/forge-channel 摘要惯例对齐,供管道解析)
197
+ console.log(JSON.stringify({ summary: true, lineId: prov.lineId, recipeId: prov.recipeId, channelId: chSummary.channelId, smokeRunId, pass, fail }))
195
198
  console.log(`\n======== 一键接入: ${pass} 通过 / ${fail} 失败 ========`)
196
199
  process.exit(fail === 0 ? 0 : 1)
@@ -0,0 +1,312 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * scripts/onboarding/sim-twin.mjs —— PLC 模拟器孪生生成器(aw-plc-sim-twin skill 的执行体)。
4
+ *
5
+ * 两种模式:
6
+ * A. 从平台既有节点反向构造孪生(最常用:虚拟预演/割接前演练):
7
+ * node scripts/onboarding/sim-twin.mjs --from-platform --line <lineId> [--sim-port 4034] \
8
+ * [--dynamics <dynamics.json>] [--shadow <dir>] [--keep-if-up]
9
+ * 拉取该线全部 DCW(SV)+ DAQ(PV),按协议族归并成孪生设备写入模拟器:
10
+ * SV→manual(可写),PV→hook 一阶滞后跟随同名 SP(无 SP 则有界随机游走);
11
+ * --dynamics 可对指定 PV 覆盖因果(base/follows[{sp,gain}]/tau/noise)。
12
+ * B. 从文档蓝图直接构造(文档协议/API 输入输出已提炼成蓝图 JSON):
13
+ * node scripts/onboarding/sim-twin.mjs --blueprint <blueprint.json> [--sim-port 4034]
14
+ *
15
+ * 蓝图 JSON 形状(模式 B;devices[] 同模式 A 的内部设备模型):
16
+ * { "simPort": 4034, "shadowDir": "..", "mqttPort": 41830?,
17
+ * "devices": [ { "id":"wb-machine", "name":"键合主机", "protocol":"modbus-tcp"|"modbus-rtu"|"mqtt",
18
+ * "port": 37532?, "unitId": 1?,
19
+ * "signals": [ { "id":"usPower-sp","name":"超声功率SP","unit":"%","min":20,"max":100,
20
+ * "decimals":0,"kind":"sp","initial":60 },
21
+ * { "id":"pullForce-pv","name":"拉力强度","unit":"gf","min":0,"max":120,
22
+ * "decimals":2,"kind":"pv",
23
+ * "dynamics":{ "base":18,"tau":8,"noise":1.1,
24
+ * "follows":[{"sp":"超声功率SP","gain":0.55}] } } ] } ] }
25
+ *
26
+ * 输出(末行 JSON):{simBase, shadowDir, devices:[{id,protocol,port,signals}],
27
+ * driverSource:"sim-export", next:"对每设备 GET /api/nodes/:id/export 取 driverConfig 喂给 provision-line/onboard"}
28
+ *
29
+ * 纪律:本脚本只写模拟器(影子树),绝不写平台;平台侧接入走 onboard.mjs/provision-line.mjs。
30
+ * 孪生协议归一:mes-rest/http/opcua 族节点映射到 modbus-tcp 孪生设备(语义/量程保留;
31
+ * 协议真实性由 onboard 期的 export driverConfig 保证——模拟器 export 什么,平台就接什么)。
32
+ */
33
+ import { spawnSync } from 'node:child_process'
34
+ import { existsSync, readFileSync } from 'node:fs'
35
+ import { dirname, join, resolve } from 'node:path'
36
+ import { fileURLToPath } from 'node:url'
37
+
38
+ const REPO = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..')
39
+ const args = process.argv.slice(2)
40
+ const argOf = (k, d = '') => {
41
+ const i = args.indexOf(k)
42
+ return i >= 0 && args[i + 1] && !args[i + 1].startsWith('--') ? args[i + 1] : d
43
+ }
44
+ const SIM_PORT = Number(argOf('--sim-port', '4034'))
45
+ const SIM = `http://127.0.0.1:${SIM_PORT}`
46
+ const SIM_DIR = resolve(argOf('--shadow', join(REPO, '..', `plc-node-simulator-twin-${SIM_PORT}`)))
47
+ const AW_BASE = process.env.AW_BASE ?? 'http://127.0.0.1:3001'
48
+ process.env.NO_PROXY = '127.0.0.1,localhost'
49
+ process.env.HTTP_PROXY = ''
50
+ process.env.HTTPS_PROXY = ''
51
+
52
+ let pass = 0
53
+ const fails = []
54
+ const ok = (name, cond, detail = '') => {
55
+ if (cond) {
56
+ pass++
57
+ console.log(` ✔ ${name}`)
58
+ }
59
+ else {
60
+ fails.push(name)
61
+ console.log(` ✖ ${name}${detail ? ` — ${String(detail).slice(0, 200)}` : ''}`)
62
+ }
63
+ }
64
+ const sleep = ms => new Promise(r => setTimeout(r, ms))
65
+
66
+ /* ── 平台 REST ── */
67
+ let TOKEN = process.env.AW_TOKEN ?? ''
68
+ async function platformLogin() {
69
+ if (TOKEN) return
70
+ const email = process.env.AW_EMAIL
71
+ const passW = process.env.AW_PASS
72
+ if (!email || !passW) throw new Error('未鉴权:设 AW_TOKEN 或 AW_EMAIL/AW_PASS')
73
+ const r = await fetch(`${AW_BASE}/api/users/login`, {
74
+ method: 'POST', headers: { 'content-type': 'application/json' },
75
+ body: JSON.stringify({ email, password: passW }), signal: AbortSignal.timeout(20000),
76
+ })
77
+ const j = await r.json()
78
+ TOKEN = j?.data?.token ?? ''
79
+ if (!TOKEN) throw new Error(`登录失败:${j?.message ?? r.status}`)
80
+ }
81
+ const platform = async (method, path) => {
82
+ await platformLogin()
83
+ const r = await fetch(AW_BASE + path, {
84
+ method, headers: { 'content-type': 'application/json', 'authorization': `Bearer ${TOKEN}` }, signal: AbortSignal.timeout(60000),
85
+ })
86
+ return { status: r.status, ...(await r.json().catch(() => ({}))) }
87
+ }
88
+
89
+ /* ── 模拟器 REST(带就绪/HTML 容错) ── */
90
+ const simApi = async (method, path, body, tries = 5) => {
91
+ for (let i = 0; i < tries; i++) {
92
+ try {
93
+ const r = await fetch(SIM + path, {
94
+ method, headers: { 'content-type': 'application/json' },
95
+ body: body === undefined ? undefined : JSON.stringify(body), signal: AbortSignal.timeout(30000),
96
+ })
97
+ if (!String(r.headers.get('content-type') ?? '').includes('json')) {
98
+ await sleep(3000)
99
+ continue
100
+ }
101
+ return await r.json()
102
+ }
103
+ catch (e) {
104
+ if (i === tries - 1) return { code: -1, message: e.message }
105
+ await sleep(3000)
106
+ }
107
+ }
108
+ return { code: -1, message: 'sim 未就绪' }
109
+ }
110
+
111
+ /* ── 模拟器保活(影子树复用 bench/lib/sim.mjs 的 spawn 纪律) ── */
112
+ async function ensureSim() {
113
+ const psi = spawnSync('powershell', ['-NoProfile', '-Command',
114
+ `Get-NetTCPConnection -LocalPort ${SIM_PORT} -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty OwningProcess`], { encoding: 'utf8' })
115
+ const pid = Number(psi.stdout.trim())
116
+ if (Number.isInteger(pid) && pid > 0 && !args.includes('--restart')) return
117
+ if (Number.isInteger(pid) && pid > 0) spawnSync('taskkill', ['/PID', String(pid), '/T', '/F'], { stdio: 'ignore' })
118
+ await sleep(1500)
119
+ process.env.SIM_BASE = SIM
120
+ process.env.SIM_SHADOW_DIR = SIM_DIR
121
+ const { ensureSimulator } = await import('../../bench/lib/sim.mjs')
122
+ await ensureSimulator({ log: () => {} })
123
+ let ready = false
124
+ for (let i = 0; i < 30 && !ready; i++) {
125
+ const probe = await simApi('GET', '/api/nodes', undefined, 2)
126
+ if (probe?.code === 0) ready = true
127
+ else await sleep(2000)
128
+ }
129
+ if (!ready) throw new Error('模拟器路由未就绪(端口已开但 API 非 JSON)')
130
+ }
131
+
132
+ /* ── 信号动力学(hook 代码生成;首拍 state.v=undefined → 两项都必须取 fallback,否则 NaN 永久毒化) ── */
133
+ const lagHook = (spName, tau, noise, fallback) =>
134
+ `const cur = Number.isFinite(state.v)?state.v:${fallback};`
135
+ + `const tgt = Number.isFinite(vars['${spName}']) ? vars['${spName}'] : ${fallback};`
136
+ + `const k = Math.min(1, dt/1000/${tau}); state.v = cur + (tgt-cur)*k + (rand()-0.5)*${noise}; return state.v`
137
+ const causalHook = (d, fallback, nominals = {}) => {
138
+ // 偏差语义:base=标称点输出,每项增益作用于 (SP 当前值 − SP 标称值) —— 与文档「工艺耦合」公式同构
139
+ const terms = (d.follows ?? []).map((f) => {
140
+ const nom = Number.isFinite(f.at) ? f.at : (nominals[f.sp] ?? 0)
141
+ return `${f.gain}*((Number.isFinite(vars['${f.sp}'])?vars['${f.sp}']:0) - ${nom})`
142
+ })
143
+ const base = d.base ?? fallback
144
+ return `const tgt = ${base}${terms.length ? ' + ' + terms.join(' + ') : ''};`
145
+ + `const cur = Number.isFinite(state.v)?state.v:${fallback};`
146
+ + `const k = Math.min(1, dt/1000/${d.tau ?? 8}); state.v = cur + (tgt-cur)*k + (rand()-0.5)*${d.noise ?? 1}; return state.v`
147
+ }
148
+ const wanderHook = (mid, span) =>
149
+ `state.v = (Number.isFinite(state.v)?state.v:${mid}) + (rand()-0.5)*${span}; `
150
+ + `if (state.v > ${mid + span * 4}) state.v = ${mid + span * 4}; if (state.v < ${mid - span * 4}) state.v = ${mid - span * 4}; return state.v`
151
+
152
+ const norm = n => String(n).replace(/(PV|实测|实际|回读|-回读|值)$/g, '').trim()
153
+
154
+ /* ── 模式 A:平台节点 → 孪生设备 ── */
155
+ async function fromPlatform(lineId, dynamicsFile) {
156
+ const dyn = dynamicsFile && existsSync(dynamicsFile) ? JSON.parse(readFileSync(dynamicsFile, 'utf8')) : {}
157
+ const dcw = (await platform('GET', '/api/workshop/dcw?limit=200'))?.data?.nodes?.filter(n => n.lineId === lineId) ?? []
158
+ const daq = (await platform('GET', '/api/workshop/daq?limit=300'))?.data?.nodes?.filter(n => n.lineId === lineId) ?? []
159
+ if (!dcw.length && !daq.length) throw new Error(`线 ${lineId} 无节点(dcw=${dcw.length} daq=${daq.length})`)
160
+ // 协议族归并(mes-rest/http/opcua → modbus-tcp 孪生;语义/量程保留)
161
+ const fam = n => (['modbus-tcp', 'modbus-rtu', 'mqtt'].includes(n.driver) ? n.driver : 'modbus-tcp')
162
+ const families = {}
163
+ for (const n of [...dcw, ...daq]) (families[fam(n)] ??= []).push(n)
164
+ const devices = []
165
+ for (const [family, nodes] of Object.entries(families)) {
166
+ const spNodes = nodes.filter(n => n.templateRef?.startsWith('dcw') || dcw.some(d => d.id === n.id))
167
+ const spNames = spNodes.map(n => norm(n.name))
168
+ const nominals = Object.fromEntries(spNodes.map(n => [norm(n.name), Number(n.value ?? ((Number(n.min ?? 0) + Number(n.max ?? 100)) / 2).toFixed(3))]))
169
+ const signals = []
170
+ for (const n of nodes) {
171
+ const isSp = dcw.some(d => d.id === n.id)
172
+ const min = Number(n.min ?? 0), max = Number(n.max ?? 100)
173
+ const mid = Number(((min + max) / 2).toFixed(3))
174
+ if (isSp) {
175
+ signals.push({ id: n.id, name: n.name, unit: n.unit ?? '', min, max, decimals: n.decimals ?? 2, kind: 'sp', initial: Number(n.value ?? mid) })
176
+ }
177
+ else {
178
+ const d = dyn[n.name] ?? {}
179
+ // 同设备同名 SP 归属:strip 后缀匹配
180
+ const spHit = spNames.find(sp => sp === norm(n.name))
181
+ let code
182
+ if (d.follows?.length || d.base != null) code = causalHook(d, mid, nominals)
183
+ else if (spHit) code = lagHook(spHit, d.tau ?? 10, d.noise ?? 0.8, mid)
184
+ else code = wanderHook(mid, Math.max((max - min) / 200, 0.2))
185
+ signals.push({ id: n.id, name: n.name, unit: n.unit ?? '', min, max, decimals: n.decimals ?? 3, kind: 'pv', code, dynamics: { tau: d.tau ?? 10, noise: d.noise ?? 0.8, sp: spHit ?? null } })
186
+ }
187
+ }
188
+ devices.push({ family, nodes, signals })
189
+ }
190
+ return { devices }
191
+ }
192
+
193
+ /* ── 蓝图 → 设备(模式 B 归一到同一内部模型) ── */
194
+ function fromBlueprint(file) {
195
+ const bp = JSON.parse(readFileSync(file, 'utf8'))
196
+ const devices = (bp.devices ?? []).map(d => ({
197
+ id: d.id,
198
+ family: d.protocol ?? 'modbus-tcp',
199
+ port: d.port,
200
+ unitId: d.unitId ?? 1,
201
+ mqtt: d.mqtt,
202
+ signals: (d.signals ?? []).map(s => ({
203
+ id: s.id, name: s.name, unit: s.unit ?? '', min: Number(s.min ?? 0), max: Number(s.max ?? 100),
204
+ decimals: s.decimals ?? 2, kind: s.kind ?? (String(s.id).endsWith('-sp') ? 'sp' : 'pv'),
205
+ initial: s.initial, code: s.code, dynamics: s.dynamics ?? {},
206
+ })),
207
+ }))
208
+ return { devices, mqttPort: bp.mqttPort }
209
+ }
210
+
211
+ /* ── 设备写入模拟器 ── */
212
+ let port = 37540
213
+ async function materialize(devices, mqttPort) {
214
+ const created = []
215
+ for (const dev of devices) {
216
+ const id = dev.id ?? `twin-${dev.family}-${created.length + 1}`
217
+ const protocol = dev.family
218
+ const config = {}
219
+ if (protocol === 'modbus-tcp' || protocol === 'modbus-rtu') {
220
+ config.host = '0.0.0.0'
221
+ config.port = dev.port ?? (port += 2)
222
+ config.unitId = dev.unitId ?? 1
223
+ config.registerMaps = dev.signals.map((s, i) => ({ address: 40001 + i * 2, area: 'holding', signalId: s.id, dataType: 'float32', byteOrder: 'big' }))
224
+ }
225
+ else if (protocol === 'mqtt') {
226
+ config.brokerUrl = `mqtt://127.0.0.1:${mqttPort}`
227
+ config.topics = dev.signals.filter(s => s.kind === 'pv').map(s => ({ topic: `aw/twin/${id}/${s.id}`, signalId: s.id, payloadTemplate: `{"data":{"${s.id}":\${value}}}`, qos: 0 }))
228
+ const sp = dev.signals.find(s => s.kind === 'sp')
229
+ if (sp) {
230
+ config.commandTopic = `aw/twin/${id}/set`
231
+ config.commandSignalId = sp.id
232
+ }
233
+ }
234
+ const nominals = Object.fromEntries(dev.signals.filter(s => s.kind === 'sp').map(s => [s.name, Number(s.initial ?? (s.min + s.max) / 2)]))
235
+ const signals = dev.signals.map(s => ({
236
+ id: s.id, name: s.name, description: `孪生:${s.name}`, unit: s.unit, min: s.min, max: s.max, decimals: s.decimals,
237
+ strategy: s.kind === 'sp'
238
+ ? { kind: 'manual', value: s.initial ?? (s.min + s.max) / 2 }
239
+ : { kind: 'hook', code: s.code
240
+ ?? (s.dynamics && (s.dynamics.follows?.length || s.dynamics.base != null)
241
+ ? causalHook(s.dynamics, (s.min + s.max) / 2, nominals)
242
+ : wanderHook((s.min + s.max) / 2, Math.max((s.max - s.min) / 200, 0.2))) },
243
+ }))
244
+ const r = await simApi('POST', '/api/nodes', { id, name: `${id}(孪生)`, description: `aw-plc-sim-twin 生成:${dev.signals.length} 信号`, protocol, enabled: true, tickMs: 1000, signals, config })
245
+ ok(`设备 ${id}(${protocol},${signals.length} 信号)`, r?.code === 0, r?.message ?? '')
246
+ created.push({ id, protocol, port: config.port ?? null, signals: signals.length, sourceNodes: dev.nodes?.map(n => n.id) ?? null })
247
+ }
248
+ return created
249
+ }
250
+
251
+ /* ── 孪生活性自检(PV 应随时间波动;只查本轮创建的设备) ── */
252
+ async function livenessCheck(createdIds) {
253
+ await sleep(8000)
254
+ const a = await simApi('GET', '/api/nodes')
255
+ const devs = (a?.data ?? []).filter(n => createdIds.includes(n.id))
256
+ const snap = devs.map(n => ({ id: n.id, v: (n.signals ?? []).map(s => s.value) }))
257
+ await sleep(6000)
258
+ const b = await simApi('GET', '/api/nodes')
259
+ const devs2 = (b?.data ?? []).filter(n => createdIds.includes(n.id))
260
+ let moved = 0
261
+ const dead = []
262
+ for (const d2 of devs2) {
263
+ const before = snap.find(x => x.id === d2.id)
264
+ const pv = (d2.signals ?? []).filter(s => s.strategy?.kind === 'hook' || s.strategy?.kind === 'expression')
265
+ const changed = pv.some((s, i) => Number(s.value) !== Number(before?.v?.[before.v.length - pv.length + i]))
266
+ if (changed) moved++
267
+ else dead.push(d2.id)
268
+ }
269
+ ok(`孪生 tick 活性(${moved}/${devs2.length} 设备 PV 在动)`, moved === devs2.length && devs2.length > 0, dead.length ? `冻结:${dead.join(',')} — 处方:整树重启模拟器(POST 不可修)` : '')
270
+ return { devices: devs2.length, signals: devs2.reduce((a, n) => a + (n.signals ?? []).length, 0) }
271
+ }
272
+
273
+ /* ── 主流程 ── */
274
+ console.log(`[sim-twin] 模拟器 :${SIM_PORT} 影子树 ${SIM_DIR}`)
275
+ await ensureSim()
276
+ let created, liveness
277
+ if (args.includes('--from-platform')) {
278
+ const lineId = argOf('--line')
279
+ if (!lineId) {
280
+ console.error('用法:--from-platform 需要 --line <lineId>')
281
+ process.exit(1)
282
+ }
283
+ console.log(`[sim-twin] 从平台线 ${lineId} 反向构造孪生…`)
284
+ const { devices } = await fromPlatform(lineId, argOf('--dynamics'))
285
+ console.log(` 协议族归并:${devices.map(d => `${d.family}×${d.signals.length}`).join(' + ')}`)
286
+ created = await materialize(devices, Number(argOf('--mqtt-port', String(18830 + (SIM_PORT - 4010) * 1000))))
287
+ }
288
+ else if (args.includes('--blueprint')) {
289
+ const bpFile = argOf('--blueprint')
290
+ if (!bpFile || !existsSync(bpFile)) {
291
+ console.error('用法:--blueprint <file.json>')
292
+ process.exit(1)
293
+ }
294
+ const { devices, mqttPort } = fromBlueprint(bpFile)
295
+ created = await materialize(devices, Number(argOf('--mqtt-port', mqttPort ?? String(18830 + (SIM_PORT - 4010) * 1000))))
296
+ }
297
+ else {
298
+ console.error('用法:sim-twin.mjs --from-platform --line <id> | --blueprint <file> [--sim-port 4034] [--dynamics file]')
299
+ process.exit(1)
300
+ }
301
+ liveness = await livenessCheck(created.map(c => c.id))
302
+ console.log('')
303
+ console.log('════════════════════════════════════════')
304
+ console.log(` sim-twin:${pass} PASS / ${fails.length} FAIL`)
305
+ for (const f of fails) console.log(` ✖ ${f}`)
306
+ const summary = {
307
+ simBase: SIM, shadowDir: SIM_DIR, devices: created, totalSignals: liveness.signals,
308
+ driverSource: 'sim-export',
309
+ next: `对每设备 GET ${SIM}/api/nodes/<id>/export 取 items[].driverConfig,喂给 provision-line/onboard(driverConfig 替换为模拟器 export,量程/stepLimit 保留)`,
310
+ }
311
+ console.log(JSON.stringify(summary))
312
+ if (fails.length) process.exit(1)
@@ -0,0 +1,30 @@
1
+ /**
2
+ * DELETE /api/workshop/analysis/:id —— 删除分析报告(仅 admin;台账 Agent 面无删,清污数据走此口)。
3
+ */
4
+ import { getRouterParam } from 'h3'
5
+ import { requireRole } from '@/server/api/workshop/caller'
6
+ import { defineApiHandler } from '@/server/utils/response'
7
+ import { AppError } from '@/server/utils/errors'
8
+ import { getAnalysisRepo } from '@/server/services/workshop/analysis/analysis.repo'
9
+ import { recordOps } from '@/server/services/workshop/ops/ops'
10
+
11
+ export default defineApiHandler(async (event) => {
12
+ const user = requireRole(event)
13
+ const id = getRouterParam(event, 'id')!
14
+ const report = getAnalysisRepo().get(id)
15
+ if (!report) throw new AppError(404, 'NOT_FOUND', `分析报告不存在: ${id}`)
16
+ getAnalysisRepo().remove(id)
17
+ recordOps({
18
+ actor: user.id,
19
+ actorName: user.name,
20
+ actorKind: 'user',
21
+ action: 'analysis.delete',
22
+ kind: 'analysis',
23
+ targetKind: 'analysis',
24
+ targetId: id,
25
+ lineId: report.lineId,
26
+ recipeId: report.recipeId,
27
+ summary: `删除分析报告「${report.title}」(产线「${report.lineName || report.lineId || '-'}」)`,
28
+ })
29
+ return { ok: true }
30
+ })
@@ -0,0 +1,25 @@
1
+ /**
2
+ * GET /api/workshop/analysis/:id —— 分析报告详情(含完整正文;产线可见性校验)。
3
+ */
4
+ import { getRouterParam } from 'h3'
5
+ import { defineApiHandler } from '@/server/utils/response'
6
+ import { AppError } from '@/server/utils/errors'
7
+ import { resolveUser } from '@/server/api/workshop/caller'
8
+ import { visibleLineIds, lineMode } from '@/server/services/workshop/permissions'
9
+ import { getAnalysisRepo } from '@/server/services/workshop/analysis/analysis.repo'
10
+
11
+ export default defineApiHandler(async (event) => {
12
+ const user = resolveUser(event)
13
+ const id = getRouterParam(event, 'id')!
14
+ const report = getAnalysisRepo().get(id)
15
+ if (!report) throw new AppError(404, 'NOT_FOUND', `分析报告不存在: ${id}`)
16
+ if (report.lineId) {
17
+ const visible = visibleLineIds(user)
18
+ if (visible && !visible.has(report.lineId)) {
19
+ throw new AppError(403, 'LINE_FORBIDDEN', `无权查看产线「${report.lineName || report.lineId}」的分析报告`)
20
+ }
21
+ }
22
+ // v27 编辑能力位(与列表端点同口径:admin 或产线 operate)
23
+ const canEdit = user.role === 'admin' || (Boolean(report.lineId) && lineMode(user, report.lineId) === 'operate')
24
+ return { report: { ...report, canEdit } }
25
+ })
@@ -0,0 +1,100 @@
1
+ /**
2
+ * PATCH /api/workshop/analysis/:id —— 人工修订分析报告(v27 编辑面)。
3
+ * 权限:admin,或对该报告产线有「可操控」(operate)的用户;readonly/无授权 403。
4
+ * 可编辑字段:title/category/summary/conclusions/report/metrics/recipe_id/recipe_version/
5
+ * window_from/window_to/data_sources(缺省 = 保留原值);修订归因固化进 updated_*。
6
+ * Agent 面仍无改删 —— 编辑是带审计的人类管理操作(recordOps analysis.update)。
7
+ */
8
+ import { getQuery, getRouterParam, readBody } from 'h3'
9
+ import { resolveUser } from '@/server/api/workshop/caller'
10
+ import { defineApiHandler } from '@/server/utils/response'
11
+ import { AppError } from '@/server/utils/errors'
12
+ import { lineMode } from '@/server/services/workshop/permissions'
13
+ import { getAnalysisRepo } from '@/server/services/workshop/analysis/analysis.repo'
14
+ import { getDcwRecipeRepo } from '@/server/services/workshop/dcw/dcw-recipe.repo'
15
+ import { recordOps } from '@/server/services/workshop/ops/ops'
16
+
17
+ export default defineApiHandler(async (event) => {
18
+ const user = resolveUser(event)
19
+ const id = getRouterParam(event, 'id')!
20
+ const repo = getAnalysisRepo()
21
+ const report = repo.get(id)
22
+ if (!report) throw new AppError(404, 'NOT_FOUND', `分析报告不存在: ${id}`)
23
+
24
+ // 编辑权限:admin 或产线 operate(readonly/无授权不可改)
25
+ const isAdmin = user.role === 'admin'
26
+ if (!isAdmin && (!report.lineId || lineMode(user, report.lineId) !== 'operate')) {
27
+ throw new AppError(403, 'ANALYSIS_FORBIDDEN', `无权修订该分析报告:需要产线「可操控」权限或 admin(报告产线 ${report.lineName || report.lineId || '-'})`)
28
+ }
29
+
30
+ const body = (await readBody<Record<string, unknown>>(event)) ?? {}
31
+ const str = (k: string): string | undefined => (body[k] === undefined ? undefined : String(body[k] ?? '').trim())
32
+ const title = str('title')
33
+ const summary = str('summary')
34
+ if (title !== undefined && !title) throw new AppError(400, 'VALIDATION_ERROR', 'title 不能为空')
35
+ if (summary !== undefined && !summary) throw new AppError(400, 'VALIDATION_ERROR', 'summary 不能为空')
36
+
37
+ // 配方校验(与保存面同口径:存在且归属该产线)
38
+ const recipeId = str('recipe_id')
39
+ if (recipeId) {
40
+ const recipe = getDcwRecipeRepo().list().find(r => r.id === recipeId)
41
+ if (!recipe) throw new AppError(404, 'NOT_FOUND', `配方不存在: ${recipeId}`)
42
+ if (recipe.lineId && report.lineId && recipe.lineId !== report.lineId) {
43
+ throw new AppError(400, 'VALIDATION_ERROR', `配方「${recipe.name}」不属于该报告的产线`)
44
+ }
45
+ }
46
+
47
+ // 时间窗归一:列内为本地 ISO(平台 toISOString 补丁),外部 Z 格式/epoch ms 归一后入库
48
+ const timeArg = (k: string): string | null | undefined => {
49
+ if (body[k] === undefined) return undefined
50
+ const raw = String(body[k] ?? '').trim()
51
+ if (!raw) return null
52
+ const ms = /^\d{10,}$/.test(raw) ? Number(raw) : Date.parse(raw)
53
+ if (!Number.isFinite(ms)) throw new AppError(400, 'VALIDATION_ERROR', `${k} 时间格式无效(ISO 8601 或 epoch ms)`)
54
+ return new Date(ms).toISOString()
55
+ }
56
+
57
+ const conclusions = body.conclusions === undefined
58
+ ? undefined
59
+ : (Array.isArray(body.conclusions) ? body.conclusions : String(body.conclusions ?? '').split('\n'))
60
+ .map((x: unknown) => String(x).replace(/^[-*\d.\s]+/, '').trim())
61
+ .filter(Boolean)
62
+ let metrics: Record<string, unknown> | undefined
63
+ if (body.metrics !== undefined && body.metrics !== null && String(body.metrics).trim() !== '') {
64
+ try {
65
+ metrics = typeof body.metrics === 'object' && !Array.isArray(body.metrics)
66
+ ? (body.metrics as Record<string, unknown>)
67
+ : JSON.parse(String(body.metrics))
68
+ }
69
+ catch {
70
+ throw new AppError(400, 'VALIDATION_ERROR', 'metrics 需为 JSON 对象(或留空保留原值)')
71
+ }
72
+ }
73
+
74
+ const updated = repo.update(id, {
75
+ title: title ?? undefined,
76
+ category: str('category') ?? undefined,
77
+ summary: summary ?? undefined,
78
+ conclusions,
79
+ report: body.report === undefined ? undefined : String(body.report ?? ''),
80
+ metrics,
81
+ recipeId,
82
+ recipeVersion: str('recipe_version'),
83
+ windowFrom: timeArg('window_from'),
84
+ windowTo: timeArg('window_to'),
85
+ dataSources: str('data_sources'),
86
+ }, { id: user.id, name: user.name })
87
+ if (!updated) throw new AppError(404, 'NOT_FOUND', `分析报告不存在: ${id}`)
88
+
89
+ try {
90
+ recordOps({
91
+ actor: user.id, actorName: user.name, actorKind: 'user',
92
+ action: 'analysis.update', kind: 'analysis', targetKind: 'analysis', targetId: id,
93
+ lineId: updated.lineId, recipeId: updated.recipeId,
94
+ summary: `人工修订分析报告「${updated.title}」(产线「${updated.lineName || updated.lineId || '-'}」)`,
95
+ })
96
+ }
97
+ catch { /* 审计失败不阻断 */ }
98
+
99
+ return { report: updated }
100
+ })
@@ -0,0 +1,39 @@
1
+ /**
2
+ * GET /api/workshop/analysis —— 分析报告台账列表(线/配方/分类/关键词/时间窗过滤;产线可见性过滤)。
3
+ */
4
+ import { getQuery } from 'h3'
5
+ import { defineApiHandler } from '@/server/utils/response'
6
+ import { resolveUser } from '@/server/api/workshop/caller'
7
+ import { filterByLine, lineMode } from '@/server/services/workshop/permissions'
8
+ import { getAnalysisRepo } from '@/server/services/workshop/analysis/analysis.repo'
9
+
10
+ export default defineApiHandler(async (event) => {
11
+ const user = resolveUser(event)
12
+ const q = getQuery(event)
13
+ const s = (k: string): string | undefined => (typeof q[k] === 'string' && q[k] ? (q[k] as string) : undefined)
14
+ // 时间窗归一:列内 created_at 是本地时区 ISO(平台 toISOString 补丁),外部传入的
15
+ // Z 格式/epoch ms 必须归一到同一文本形态,否则 SQL 文本比较错位
16
+ const timeArg = (k: string): string | undefined => {
17
+ const raw = s(k)
18
+ if (!raw) return undefined
19
+ const ms = /^\d{10,}$/.test(raw) ? Number(raw) : Date.parse(raw)
20
+ return Number.isFinite(ms) ? new Date(ms).toISOString() : undefined
21
+ }
22
+ const rows = getAnalysisRepo().list({
23
+ lineId: s('lineId'),
24
+ recipeId: s('recipeId'),
25
+ category: s('category'),
26
+ q: s('q'),
27
+ from: timeArg('from'),
28
+ to: timeArg('to'),
29
+ limit: Math.min(500, Math.max(1, Number(q.limit) || 100)),
30
+ })
31
+ const visible = filterByLine(user, rows, r => r.lineId || null)
32
+ // v27 编辑能力位:admin 或产线 operate(与 PATCH 端点同口径,前端据此显隐编辑入口)
33
+ const canEdit = (lineId: string): boolean =>
34
+ user.role === 'admin' || (Boolean(lineId) && lineMode(user, lineId) === 'operate')
35
+ return {
36
+ reports: visible.map(r => ({ ...r, canEdit: canEdit(r.lineId) })),
37
+ count: visible.length,
38
+ }
39
+ })
@@ -56,6 +56,7 @@ import { envStatus, startCreateVenv } from '../services/workshop/aml/env-manager
56
56
  import { attachOmpPluginBridge } from '../services/workshop/agents/plugin-tools'
57
57
  import { startAmlRetentionTimer, stopAmlRetentionTimer } from '../services/workshop/aml/retention'
58
58
  import { configureMesDatasets, defaultDatasetsDir } from '../services/workshop/mes/mes-datasets'
59
+ import { configureAnalysisRepo } from '../services/workshop/analysis/analysis.repo'
59
60
  import { configureMesHooks } from '../services/workshop/mes/mes-hook'
60
61
 
61
62
  declare global {
@@ -156,6 +157,9 @@ export default function workshopPlugin(nitroApp: {
156
157
  // MES 数据下沉 hook 运行时(产物落 <configRoot>/data/mes-artifacts/<nodeId>/)
157
158
  configureMesHooks(dataDir)
158
159
 
160
+ // 数据分析系统:分析报告台账(v26 新表由 SCHEMA_SQL 启动建出)
161
+ configureAnalysisRepo(db)
162
+
159
163
  // 插件 omp 工具注册桥:启动即接管 pending 队列(此前首次 spawn omp agent 才挂桥,
160
164
  // 全新实例未 spawn 前 kb_agent/diag_run 等插件工具会一直"未知工具")
161
165
  attachOmpPluginBridge()
@@ -398,7 +398,7 @@ export const userRepository = {
398
398
  const current = this.findById(id)
399
399
  if (!current) return undefined
400
400
  const fields: string[] = []
401
- const params: string[] = []
401
+ const params: Array<string | number> = []
402
402
  if (input.name !== undefined) {
403
403
  fields.push('name = ?')
404
404
  params.push(input.name)
@@ -496,7 +496,7 @@ export const userRepository = {
496
496
  /** 吊销某用户全部会话 token(管理面重置密码后强制重新登录,旧会话即死) */
497
497
  revokeAllTokens(userId: string): number {
498
498
  const d = getDb()
499
- return d.prepare('DELETE FROM user_tokens WHERE user_id = ?').run(userId).changes
499
+ return Number(d.prepare('DELETE FROM user_tokens WHERE user_id = ?').run(userId).changes)
500
500
  },
501
501
 
502
502
  /** 测试钩子:替换内部 DB(重开内存库等) */
@@ -48,7 +48,8 @@ export const AML_MODEL_BACKED_TOOL_NAMES = new Set([
48
48
  * 直接写族(agents/tool-classes 清单)在尾部 writesBlocked 再兜底过滤一道。
49
49
  * kb_agent/diag_run/diag_status 等 KB/诊断工具走 rag-bridge/diag-bridge 插件面,照常按频道插件开关注入,不进本白名单。
50
50
  */
51
- /** 只读观察读面(两档共用,全部只读;exp_collect 由经验采集底座注册,此处按名引用) */
51
+ /** 只读观察读面(两档共用,全部只读;exp_collect 由经验采集底座注册,此处按名引用;
52
+ * analysis_save/query 为数据分析留痕台账面 —— 台账写入非产线写,观察档位同样要留痕诊断结论) */
52
53
  export const OBSERVER_READ_TOOL_NAMES = new Set([
53
54
  'ops_log',
54
55
  'recipe_log',
@@ -57,6 +58,8 @@ export const OBSERVER_READ_TOOL_NAMES = new Set([
57
58
  'dcw_journal',
58
59
  'daq_query',
59
60
  'exp_collect',
61
+ 'analysis_save',
62
+ 'analysis_query',
60
63
  ])
61
64
 
62
65
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * 工业工具族(my_industrial_nodes / aml_* / dcw_* / param_* / daq_* / ops_log / recipe_* / line_context)。
2
+ * 工业工具族(my_industrial_nodes / aml_* / dcw_* / param_* / daq_* / ops_log / recipe_* / line_context / analysis_*)。
3
3
  *
4
4
  * 原 dispatchHostTool 首个 switch 的 26 个转发分支按行搬运到本模块:每个分支都只是
5
5
  * 「按 agentId 查绑定与节点后转交 industrial 模块的同名函数」,因此把闭包捕获的
@@ -9,7 +9,7 @@
9
9
  * 该族**不依赖 workspace**,由 dispatch 在 workspace 门控之前分流(保持原分发顺序)。
10
10
  */
11
11
  import type { HostToolResult } from '../types'
12
- import { toolLineStart, toolLineStop, toolLineStatus, toolAmlDatasetBuild, toolAmlDatasetStats, toolAmlJobCancel, toolAmlJobLogs, toolAmlJobStatus, toolAmlJobSubmit, toolAmlLeaderboard, toolAmlModelFind, toolAmlModelPromote, toolAmlModelReference, toolAmlNodeCatalog, toolAmlTrainingPlanCreate, toolAmlTrainingPlanList, toolAmlTrainingPlanTrain, toolDaqExport, toolDaqFrames, toolDaqQuery, toolDcwControl, toolDcwJudge, toolDcwJournal, toolDcwRead, toolDcwRollback, toolLineContext, toolMesCatalog, toolMesDatasetRead, toolMesDatasets, toolMesFetch, toolMyIndustrialNodes, toolOpsLog, toolParamControl, toolParamRead, toolRecipeApply, toolRecipeLog, toolRecipeRollback, toolRecipeTrial, toolRecipeUpdate, toolRecipeVersions, toolOptimizationExplore, toolTwinProviderCatalog, toolTwinSceneDiscover, toolTwinSceneCompile, toolTwinSceneFreeze, toolTwinSceneRead, toolTwinPhysicsSpecDraft, toolTwinPhysicsSpecValidate, toolTwinPhysicsSpecCompile, toolTwinSnapshotCreate, toolTwinTrialRun, toolMpcOptimize, toolTwinGateEvaluate, toolTwinBayesOptimize, toolTwinCalibrationRequest } from '../../industrial'
12
+ import { toolLineStart, toolLineStop, toolLineStatus, toolAmlDatasetBuild, toolAmlDatasetStats, toolAmlJobCancel, toolAmlJobLogs, toolAmlJobStatus, toolAmlJobSubmit, toolAmlLeaderboard, toolAmlModelFind, toolAmlModelPromote, toolAmlModelReference, toolAmlNodeCatalog, toolAmlTrainingPlanCreate, toolAmlTrainingPlanList, toolAmlTrainingPlanTrain, toolDaqExport, toolDaqFrames, toolDaqQuery, toolDcwControl, toolDcwJudge, toolDcwJournal, toolDcwRead, toolDcwRollback, toolLineContext, toolMesCatalog, toolMesDatasetRead, toolMesDatasets, toolMesFetch, toolMyIndustrialNodes, toolOpsLog, toolParamControl, toolParamRead, toolRecipeApply, toolRecipeLog, toolRecipeRollback, toolRecipeTrial, toolRecipeUpdate, toolRecipeVersions, toolOptimizationExplore, toolTwinProviderCatalog, toolTwinSceneDiscover, toolTwinSceneCompile, toolTwinSceneFreeze, toolTwinSceneRead, toolTwinPhysicsSpecDraft, toolTwinPhysicsSpecValidate, toolTwinPhysicsSpecCompile, toolTwinSnapshotCreate, toolTwinTrialRun, toolMpcOptimize, toolTwinGateEvaluate, toolTwinBayesOptimize, toolTwinCalibrationRequest, toolAnalysisSave, toolAnalysisQuery } from '../../industrial'
13
13
 
14
14
  import { toolExpCollect } from '../../industrial/exp-tools'
15
15
  import { toolRecipePropose } from '../../industrial/recipe-propose-tools'
@@ -78,6 +78,9 @@ const INDUSTRIAL_HANDLERS = new Map<string, IndustrialToolHandler>([
78
78
  ['line_stop', (agentId, args, channelId) => toolLineStop(agentId, args as Parameters<typeof toolLineStop>[1], channelId)],
79
79
  ['line_status', (agentId, args, channelId) => toolLineStatus(agentId, args as Parameters<typeof toolLineStatus>[1], channelId)],
80
80
  ['aml_activity', (agentId, args) => toolAmlActivity(agentId, args as { line_id?: string })],
81
+ // 数据分析系统:分析结果留痕台账(save 可写台账(非产线写);query 查历史留痕)
82
+ ['analysis_save', (agentId, args, channelId) => toolAnalysisSave(agentId, args as Parameters<typeof toolAnalysisSave>[1], channelId)],
83
+ ['analysis_query', (agentId, args) => toolAnalysisQuery(agentId, args as Parameters<typeof toolAnalysisQuery>[1])],
81
84
  ])
82
85
 
83
86
  /** 工业工具名集合(与 INDUSTRIAL_HANDLERS 同源;dispatch 据此在 workspace 门控前分流) */