agentworkshop 0.7.71 → 0.8.1

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 (629) hide show
  1. package/.AgentWorkShop/prompts/host-tools.json +455 -0
  2. package/.output/.AgentWorkShop/prompts/host-tools.json +455 -0
  3. package/.output/nitro.json +1 -1
  4. package/.output/public/_nuxt/{DJJDigim2.js → -FhgRqJl2.js} +1 -1
  5. package/.output/public/_nuxt/{CGk_VUhO2.js → 0qvcO_KM2.js} +1 -1
  6. package/.output/public/_nuxt/26OL4Ao82.js +1 -0
  7. package/.output/public/_nuxt/{sBDZymdy2.js → 2Kwo_j9G2.js} +1 -1
  8. package/.output/public/_nuxt/{BqYVLAcm.js → 2v5GdspM.js} +1 -1
  9. package/.output/public/_nuxt/{DkQBMVTs2.js → 8M7wFbEN2.js} +1 -1
  10. package/.output/public/_nuxt/{DtiY69xi2.js → 8SZLbrI42.js} +1 -1
  11. package/.output/public/_nuxt/{DF32f5EL2.js → B2NbzUau2.js} +1 -1
  12. package/.output/public/_nuxt/{CwZW1ZCe2.js → B4JlRHBB2.js} +1 -1
  13. package/.output/public/_nuxt/{BQOn0q6Y.js → B6C4WofF.js} +1 -1
  14. package/.output/public/_nuxt/{BC7W6lNm.js → B6UwtJ1a.js} +1 -1
  15. package/.output/public/_nuxt/{BfQ-ptH0.js → B8HFUsMH.js} +1 -1
  16. package/.output/public/_nuxt/{DzBbYWrw2.js → BBB_j2LU2.js} +1 -1
  17. package/.output/public/_nuxt/BCLUwdP52.js +1 -0
  18. package/.output/public/_nuxt/{CLxmY3Rh.js → BK4wbfGS.js} +1 -1
  19. package/.output/public/_nuxt/{BRMVDfPl2.js → BKidykmV2.js} +1 -1
  20. package/.output/public/_nuxt/BPUQZ9Lq2.js +8 -0
  21. package/.output/public/_nuxt/BRYBzVMJ.js +1 -0
  22. package/.output/public/_nuxt/{Bj5sjA5O.js → BRci9D_l.js} +1 -1
  23. package/.output/public/_nuxt/{Dmgqz2np2.js → BVGzwAxr2.js} +1 -1
  24. package/.output/public/_nuxt/BVg2R2VB2.js +1 -0
  25. package/.output/public/_nuxt/{C3aUN4Vp2.js → BW2uTUx52.js} +1 -1
  26. package/.output/public/_nuxt/{B5FKaMM02.js → BY3Lbz3h2.js} +1 -1
  27. package/.output/public/_nuxt/{DIwmMa_7.js → BYzim_Bn.js} +1 -1
  28. package/.output/public/_nuxt/{D8xUsQGt.js → B_Obcbiu.js} +1 -1
  29. package/.output/public/_nuxt/BaYDgyaR.js +3 -0
  30. package/.output/public/_nuxt/{DZJ11BTI.js → BbACaREb.js} +1 -1
  31. package/.output/public/_nuxt/{BJrj5JVe2.js → BcosvNXb2.js} +1 -1
  32. package/.output/public/_nuxt/{B_-vAvzb.js → BfeXib9G.js} +1 -1
  33. package/.output/public/_nuxt/{CeLqojCJ.js → BfgTar9L.js} +1 -1
  34. package/.output/public/_nuxt/BfvuWqSa.js +1 -0
  35. package/.output/public/_nuxt/{D8r8PNQa2.js → BiZWwdcD2.js} +1 -1
  36. package/.output/public/_nuxt/BkEokGX5.js +1 -0
  37. package/.output/public/_nuxt/{CJSohaqk2.js → BklGqEto2.js} +2 -2
  38. package/.output/public/_nuxt/{DkpmSnHX.js → Bko5adbu.js} +1 -1
  39. package/.output/public/_nuxt/{DTQTGA6v2.js → BmBlIIJo2.js} +1 -1
  40. package/.output/public/_nuxt/{D_NjL-Hz.js → Bmvt9ydE.js} +1 -1
  41. package/.output/public/_nuxt/{Cp4r6Eiz.js → BoyuIoSm.js} +1 -1
  42. package/.output/public/_nuxt/{62J4vljm2.js → Bq-tmkst.js} +1 -1
  43. package/.output/public/_nuxt/{BMMoqi94.js → BqFaZ4kS.js} +1 -1
  44. package/.output/public/_nuxt/BsJYieAL2.js +1 -0
  45. package/.output/public/_nuxt/{DD4J2Otc.js → BtZKe9ZV.js} +1 -1
  46. package/.output/public/_nuxt/{BnpY_zNx.js → BtumQhZK.js} +1 -1
  47. package/.output/public/_nuxt/{BjLzqWJH2.js → BwWs9EdO2.js} +1 -1
  48. package/.output/public/_nuxt/{Bx2a9cuY2.js → BxxpJxZf2.js} +1 -1
  49. package/.output/public/_nuxt/{qRXa-PM22.js → ByTnUqFw2.js} +1 -1
  50. package/.output/public/_nuxt/{DvOETuoT2.js → Byiiiwc72.js} +1 -1
  51. package/.output/public/_nuxt/{Car2lkbb.js → C1-SuwUN.js} +1 -1
  52. package/.output/public/_nuxt/{Dg81dOEO.js → C14pM5G4.js} +1 -1
  53. package/.output/public/_nuxt/{MDhaRQq_.js → C2Yp-B8m.js} +1 -1
  54. package/.output/public/_nuxt/{BJ2nJNlK2.js → C4e6_nom2.js} +1 -1
  55. package/.output/public/_nuxt/{CiCEprsp2.js → C5OStZJ62.js} +1 -1
  56. package/.output/public/_nuxt/{ByMj6e7s.js → C6lssmvl.js} +2 -2
  57. package/.output/public/_nuxt/{C6uBP0Xa.js → CC-GEjfN.js} +1 -1
  58. package/.output/public/_nuxt/CC2Pv8VL2.js +1 -0
  59. package/.output/public/_nuxt/{DKiqdYnj.js → CCcMgxV9.js} +1 -1
  60. package/.output/public/_nuxt/{5S26I34j2.js → CDL30A2z2.js} +1 -1
  61. package/.output/public/_nuxt/{B8C-QJB5.js → CDYLasP8.js} +1 -1
  62. package/.output/public/_nuxt/CElzwyXQ.js +1 -0
  63. package/.output/public/_nuxt/{2KE8xGVm.js → CEvJu-xI.js} +1 -1
  64. package/.output/public/_nuxt/{CR612R752.js → CFQRFctQ2.js} +1 -1
  65. package/.output/public/_nuxt/{DnzjxC0u.js → CHk9XxNi.js} +2 -2
  66. package/.output/public/_nuxt/{Bx4MR0jd.js → CLFmtXU7.js} +1 -1
  67. package/.output/public/_nuxt/{DW8k_0dQ.js → CMJi6yYS.js} +1 -1
  68. package/.output/public/_nuxt/{DD-r0S1p.js → CPvFGbr8.js} +1 -1
  69. package/.output/public/_nuxt/{CCgbgkid.js → CQSxS_Ek.js} +2 -2
  70. package/.output/public/_nuxt/{jGxHnjW6.js → CQuo31jF.js} +1 -1
  71. package/.output/public/_nuxt/{SoO2K-di.js → CRCrWy-6.js} +1 -1
  72. package/.output/public/_nuxt/CUCFFL9m.js +84 -0
  73. package/.output/public/_nuxt/CZYNy60j2.js +1 -0
  74. package/.output/public/_nuxt/{WPwdj9pg.js → CZsFf7ck.js} +1 -1
  75. package/.output/public/_nuxt/CfFUK6932.js +2 -0
  76. package/.output/public/_nuxt/{DAsjfdZD.js → CfIbFnJz.js} +1 -1
  77. package/.output/public/_nuxt/{Tk6TQZjU.js → CjF4QY9h.js} +1 -1
  78. package/.output/public/_nuxt/{DlUQa0wn.js → Cjo1t2IF.js} +1 -1
  79. package/.output/public/_nuxt/{CDn0eDn8.js → CmuGMxDP.js} +1 -1
  80. package/.output/public/_nuxt/Cn6EojFe.js +1 -0
  81. package/.output/public/_nuxt/{DLqSQbGv.js → CnYazk8d.js} +1 -1
  82. package/.output/public/_nuxt/{DQfy6R_2.js → CnrGVJIr.js} +1 -1
  83. package/.output/public/_nuxt/{C0YL0HKK.js → CtcBhkci.js} +1 -1
  84. package/.output/public/_nuxt/{h5gsh8E92.js → Cv-Mv7_h2.js} +1 -1
  85. package/.output/public/_nuxt/{vPcnBJsa2.js → CzlZrfq82.js} +1 -1
  86. package/.output/public/_nuxt/{C2YYOgMe.js → CznnUTZx.js} +2 -2
  87. package/.output/public/_nuxt/{csitHKnE2.js → D-80EfyA2.js} +1 -1
  88. package/.output/public/_nuxt/{BRdoISnJ2.js → D1C6qtS12.js} +1 -1
  89. package/.output/public/_nuxt/{Cnrmlixo.js → D1MkndMZ.js} +2 -2
  90. package/.output/public/_nuxt/{BLwDhlaa.js → D37gODe0.js} +1 -1
  91. package/.output/public/_nuxt/{NXY37IO62.js → D6FhDrYe2.js} +1 -1
  92. package/.output/public/_nuxt/{Btx8wL4-.js → D7TZLu4F.js} +1 -1
  93. package/.output/public/_nuxt/{qoUdVDnC.js → D7tEwf-o.js} +3 -3
  94. package/.output/public/_nuxt/D8HQPtm62.js +1 -0
  95. package/.output/public/_nuxt/D9O4L4jK.js +1 -0
  96. package/.output/public/_nuxt/{aQ1B7BZa2.js → D9lL3fJM2.js} +2 -2
  97. package/.output/public/_nuxt/{CT-vTjcG2.js → DC-2eKo62.js} +1 -1
  98. package/.output/public/_nuxt/DF9ETYJ32.js +1 -0
  99. package/.output/public/_nuxt/DGGBrc0q2.js +1 -0
  100. package/.output/public/_nuxt/DGu_fna7.js +1 -0
  101. package/.output/public/_nuxt/{BupBjt6B.js → DKOvbitt.js} +1 -1
  102. package/.output/public/_nuxt/{B1PzYsqN.js → DNxudyND.js} +1 -1
  103. package/.output/public/_nuxt/{BfX6_AjY.js → DOT-XQyi.js} +1 -1
  104. package/.output/public/_nuxt/{BsTZnkVK.js → DPPC9Teq.js} +1 -1
  105. package/.output/public/_nuxt/{HxohXQ_r.js → DRskyE7l.js} +1 -1
  106. package/.output/public/_nuxt/{B-U7E_Mc2.js → DW4ZgInh2.js} +1 -1
  107. package/.output/public/_nuxt/{BErG4kzc2.js → DWe6BMlp2.js} +1 -1
  108. package/.output/public/_nuxt/DWy0AjON.js +1 -0
  109. package/.output/public/_nuxt/{Bc_k6AVA.js → DXgw1dVL.js} +4 -4
  110. package/.output/public/_nuxt/{C3sWJ8SD2.js → DZsKIzKD2.js} +1 -1
  111. package/.output/public/_nuxt/D_59BNP1.js +14 -0
  112. package/.output/public/_nuxt/{BQIO4MkA2.js → D_FZ3KZI2.js} +1 -1
  113. package/.output/public/_nuxt/{n_Njdwii2.js → D__vJGHF2.js} +1 -1
  114. package/.output/public/_nuxt/{C9gErLQc2.js → DaizNGUm2.js} +1 -1
  115. package/.output/public/_nuxt/{C-MY-JQE2.js → DdyE0ylS.js} +1 -1
  116. package/.output/public/_nuxt/DgrK8UCQ.js +0 -0
  117. package/.output/public/_nuxt/DhLlTxQh2.js +1 -0
  118. package/.output/public/_nuxt/DhW7cFOa.js +1 -0
  119. package/.output/public/_nuxt/{Rt2i6k7C2.js → DhjgWrB62.js} +1 -1
  120. package/.output/public/_nuxt/{KwT4sN_d.js → DiWcX4gj.js} +1 -1
  121. package/.output/public/_nuxt/DiloA8vK.js +1 -0
  122. package/.output/public/_nuxt/{DX-c5laM2.js → DlS-SkQ42.js} +1 -1
  123. package/.output/public/_nuxt/{D_Zspo1y.js → DmHp9yQ3.js} +1 -1
  124. package/.output/public/_nuxt/{dq1HKoGD.js → DoL9u6wu.js} +1 -1
  125. package/.output/public/_nuxt/{CIvMT5Ic.js → DqxBCeDe.js} +1 -1
  126. package/.output/public/_nuxt/{BnNmkGJS2.js → DrlnrdvY2.js} +3 -3
  127. package/.output/public/_nuxt/{BAcjVcku2.js → Dt8TL8_X2.js} +1 -1
  128. package/.output/public/_nuxt/{BtfwbNC0.js → Du7gS8RU.js} +1 -1
  129. package/.output/public/_nuxt/DuUc4bbY2.js +1 -0
  130. package/.output/public/_nuxt/{DPUXbTg9.js → DudoisLM.js} +1 -1
  131. package/.output/public/_nuxt/{Ce5R-ZGf2.js → DwgVlehj2.js} +1 -1
  132. package/.output/public/_nuxt/Dyxf2xZw.js +1 -0
  133. package/.output/public/_nuxt/Dz9C2pTa.js +1 -0
  134. package/.output/public/_nuxt/{BYxG9Hb2.js → EMbqTHfT.js} +1 -1
  135. package/.output/public/_nuxt/{B1SzppY12.js → FsRVXpyF2.js} +1 -1
  136. package/.output/public/_nuxt/{0MLy6ogg2.js → GQrEW8nk2.js} +1 -1
  137. package/.output/public/_nuxt/{Tuz5LcLM.js → IXR1BWP5.js} +1 -1
  138. package/.output/public/_nuxt/{-jpUnM1I2.js → Iub61dX92.js} +1 -1
  139. package/.output/public/_nuxt/{CQgOzpvI.js → JegDslce.js} +2 -2
  140. package/.output/public/_nuxt/{DrF3TWoj.js → KzK37yIr.js} +1 -1
  141. package/.output/public/_nuxt/{Br3MggOL.js → N-CCmCsX.js} +1 -1
  142. package/.output/public/_nuxt/{DHhmq7s_.js → NfvZ5Lzv.js} +1 -1
  143. package/.output/public/_nuxt/{CzX_kaPL.js → POTcePF_.js} +1 -1
  144. package/.output/public/_nuxt/{D7s96J3r2.js → Q-JpBT032.js} +1 -1
  145. package/.output/public/_nuxt/{DzwIZ81f2.js → R1g64DNi2.js} +1 -1
  146. package/.output/public/_nuxt/{JgheoP3e.js → R5Pz7BqB.js} +1 -1
  147. package/.output/public/_nuxt/{yLyz0-Yz.js → SvjzWbn8.js} +1 -1
  148. package/.output/public/_nuxt/{Dd7MZc_Q.js → XqXoaoDs.js} +1 -1
  149. package/.output/public/_nuxt/{B6jtLy6z.js → YAA98rWJ.js} +11 -11
  150. package/.output/public/_nuxt/{HX4_xnak2.js → YLYSczSq2.js} +1 -1
  151. package/.output/public/_nuxt/{BBw9ylUY2.js → YNhAoK-R2.js} +1 -1
  152. package/.output/public/_nuxt/Zkbt8Uk5.js +1 -0
  153. package/.output/public/_nuxt/aml.PalMp-5n.css +1 -0
  154. package/.output/public/_nuxt/{C41CcsiD.js → b7UcqLKi.js} +1 -1
  155. package/.output/public/_nuxt/builds/latest.json +1 -1
  156. package/.output/public/_nuxt/builds/meta/fa0af8b5-3929-428d-a6de-3b5cc6b8248f.json +1 -0
  157. package/.output/public/_nuxt/{DVkFSOZi.js → cKj4vSo5.js} +1 -1
  158. package/.output/public/_nuxt/{r1CpGsFp.js → dHwWyr6b.js} +1 -1
  159. package/.output/public/_nuxt/{default.BzOcvmSE.css → default.BEXGWZFQ.css} +1 -1
  160. package/.output/public/_nuxt/{DlcA9Gxl.js → eePbiWEh.js} +1 -1
  161. package/.output/public/_nuxt/{entry.CL2i0F8o.css → entry.C7koBPom.css} +1 -1
  162. package/.output/public/_nuxt/{cjRzSvAg2.js → eymRov9Y2.js} +1 -1
  163. package/.output/public/_nuxt/{B8cViLJT.js → geMze5qw.js} +1 -1
  164. package/.output/public/_nuxt/{uu1wfdfR2.js → gh-WMxV_2.js} +1 -1
  165. package/.output/public/_nuxt/{Ce6e1mPk2.js → hCN555XP2.js} +1 -1
  166. package/.output/public/_nuxt/{rdUE8Khf.js → hZG5MLjK.js} +3 -3
  167. package/.output/public/_nuxt/{CcX_jP-d.js → hlfahYxK.js} +1 -1
  168. package/.output/public/_nuxt/{cGSl2GZp2.js → ilJHF1nA2.js} +1 -1
  169. package/.output/public/_nuxt/{D6ZcgHPz.js → jDuiDtGb.js} +1 -1
  170. package/.output/public/_nuxt/{DbeNMehP.js → k9b520K-.js} +1 -1
  171. package/.output/public/_nuxt/ontology.B_3Wn907.css +1 -0
  172. package/.output/public/_nuxt/optimizer.CLA8I1sy.css +1 -0
  173. package/.output/public/_nuxt/{DSORcpTJ.js → rDvMijKA.js} +2 -2
  174. package/.output/public/_nuxt/{CAiHhX8P2.js → rF7mggl72.js} +2 -2
  175. package/.output/public/_nuxt/ri9UF8rk.js +2 -0
  176. package/.output/public/_nuxt/{KgnxOsMr.js → toG_qAMH.js} +1 -1
  177. package/.output/public/_nuxt/{KQZmHR_K.js → u3h4pGpm.js} +2 -2
  178. package/.output/public/_nuxt/{dJ7gK7C2.js → uomnHjhM.js} +1 -1
  179. package/.output/public/_nuxt/{BUTg4W_x2.js → v77qozuJ2.js} +1 -1
  180. package/.output/public/_nuxt/{BcEr7tIB.js → v7cV7hJa.js} +1 -1
  181. package/.output/public/_nuxt/{D25dVZ822.js → vkQoYNQR2.js} +2 -2
  182. package/.output/public/_nuxt/{wR_w07322.js → vp3LtnTz2.js} +1 -1
  183. package/.output/public/_nuxt/{Bnc8HELj2.js → we7-sMSo2.js} +1 -1
  184. package/.output/public/_nuxt/{kN3ZzR1-.js → wxISMS1i.js} +1 -1
  185. package/.output/public/_nuxt/{DGrrucbG2.js → zy7efYKR.js} +1 -1
  186. package/.output/server/chunks/_/access.mjs +1 -1
  187. package/.output/server/chunks/_/binding-authz.mjs +1 -1
  188. package/.output/server/chunks/_/catalog-view.mjs +1 -1
  189. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  190. package/.output/server/chunks/_/chart-repo.mjs +1 -1
  191. package/.output/server/chunks/_/dashboard-repo.mjs +1 -1
  192. package/.output/server/chunks/_/data-export.mjs +6 -6
  193. package/.output/server/chunks/_/data-query.mjs +3 -3
  194. package/.output/server/chunks/_/eda-run.repo.mjs +2 -2
  195. package/.output/server/chunks/_/entity.mjs +1 -1
  196. package/.output/server/chunks/_/features.mjs +5 -5
  197. package/.output/server/chunks/_/golden.mjs +3 -3
  198. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  199. package/.output/server/chunks/_/index.mjs +1 -1
  200. package/.output/server/chunks/_/mes-console.mjs +1 -1
  201. package/.output/server/chunks/_/nitro.mjs +7291 -3540
  202. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  203. package/.output/server/chunks/_/ocap.mjs +1 -1
  204. package/.output/server/chunks/_/rest-auth.mjs +1 -1
  205. package/.output/server/chunks/_/scene-layout.repo.mjs +1 -1
  206. package/.output/server/chunks/_/spc.mjs +2 -2
  207. package/.output/server/chunks/build/TownView-BWMDbosY.mjs +1 -1
  208. package/.output/server/chunks/build/{_wsId_-BNKrrV1H.mjs → _wsId_-BPy-Aj9L.mjs} +3 -3
  209. package/.output/server/chunks/build/{_wsId_-BNKrrV1H.mjs.map → _wsId_-BPy-Aj9L.mjs.map} +1 -1
  210. package/.output/server/chunks/build/{agents-8tV9xL97.mjs → agents-CpNLdI8E.mjs} +6 -6
  211. package/.output/server/chunks/build/{agents-8tV9xL97.mjs.map → agents-CpNLdI8E.mjs.map} +1 -1
  212. package/.output/server/chunks/build/{aml-BNTEDOsl.mjs → aml-DRAFRcGU.mjs} +15 -12
  213. package/.output/server/chunks/build/{aml-BNTEDOsl.mjs.map → aml-DRAFRcGU.mjs.map} +1 -1
  214. package/.output/server/chunks/build/api-BEW_ebY_.mjs +64 -0
  215. package/.output/server/chunks/build/api-BEW_ebY_.mjs.map +1 -0
  216. package/.output/server/chunks/build/{channel-templates-Iot9Y3vV.mjs → channel-templates-ByHOQQkO.mjs} +2 -2
  217. package/.output/server/chunks/build/{channel-templates-Iot9Y3vV.mjs.map → channel-templates-ByHOQQkO.mjs.map} +1 -1
  218. package/.output/server/chunks/build/daq-CdxcfY_G.mjs +1 -1
  219. package/.output/server/chunks/build/dcw-BlDQtS4q.mjs +1 -1
  220. package/.output/server/chunks/build/{default-BeB88U7y.mjs → default-CNWS6NUw.mjs} +17 -11
  221. package/.output/server/chunks/build/{default-BeB88U7y.mjs.map → default-CNWS6NUw.mjs.map} +1 -1
  222. package/.output/server/chunks/build/{dropdown-CjwsxU39.mjs → dropdown-BNwTVGde.mjs} +2 -2
  223. package/.output/server/chunks/build/{dropdown-CjwsxU39.mjs.map → dropdown-BNwTVGde.mjs.map} +1 -1
  224. package/.output/server/chunks/build/{dropdown-C6YH_kSO.mjs → dropdown-Cd-xPhR6.mjs} +2 -2
  225. package/.output/server/chunks/build/{dropdown-C6YH_kSO.mjs.map → dropdown-Cd-xPhR6.mjs.map} +1 -1
  226. package/.output/server/chunks/build/input-number-BNlNDK7H.mjs +1 -1
  227. package/.output/server/chunks/build/{logs-BTfJQ6vQ.mjs → logs-pRb-TMWa.mjs} +3 -3
  228. package/.output/server/chunks/build/{logs-BTfJQ6vQ.mjs.map → logs-pRb-TMWa.mjs.map} +1 -1
  229. package/.output/server/chunks/build/{monitor-DvaR3yo8.mjs → monitor-Cq6hRFeQ.mjs} +6 -6
  230. package/.output/server/chunks/build/{monitor-DvaR3yo8.mjs.map → monitor-Cq6hRFeQ.mjs.map} +1 -1
  231. package/.output/server/chunks/build/ontology-DK0Mf0zT.mjs +1406 -0
  232. package/.output/server/chunks/build/ontology-DK0Mf0zT.mjs.map +1 -0
  233. package/.output/server/chunks/build/{operations-Cl8nVm9D.mjs → operations-SMQrRAcr.mjs} +3 -3
  234. package/.output/server/chunks/build/{operations-Cl8nVm9D.mjs.map → operations-SMQrRAcr.mjs.map} +1 -1
  235. package/.output/server/chunks/build/optimizer-BlWTsM-W.mjs +202 -0
  236. package/.output/server/chunks/build/optimizer-BlWTsM-W.mjs.map +1 -0
  237. package/.output/server/chunks/build/{pagination-KaIvHBzi.mjs → pagination-DTAconUo.mjs} +2 -2
  238. package/.output/server/chunks/build/{pagination-KaIvHBzi.mjs.map → pagination-DTAconUo.mjs.map} +1 -1
  239. package/.output/server/chunks/build/{permissions-CVTfixZj.mjs → permissions-DgXQZSyx.mjs} +6 -6
  240. package/.output/server/chunks/build/{permissions-CVTfixZj.mjs.map → permissions-DgXQZSyx.mjs.map} +1 -1
  241. package/.output/server/chunks/build/{schedules-BLhn2CLn.mjs → schedules-dSnr8url.mjs} +6 -6
  242. package/.output/server/chunks/build/{schedules-BLhn2CLn.mjs.map → schedules-dSnr8url.mjs.map} +1 -1
  243. package/.output/server/chunks/build/{select--XFl7CtY.mjs → select-B3Dsb9yq.mjs} +3 -3
  244. package/.output/server/chunks/build/{select--XFl7CtY.mjs.map → select-B3Dsb9yq.mjs.map} +1 -1
  245. package/.output/server/chunks/build/{settings-DIf_iYdu.mjs → settings-BrIhnS2Z.mjs} +2 -2
  246. package/.output/server/chunks/build/{settings-DIf_iYdu.mjs.map → settings-BrIhnS2Z.mjs.map} +1 -1
  247. package/.output/server/chunks/build/{table-DIu_YCJN.mjs → table-CmVD-cA9.mjs} +4 -4
  248. package/.output/server/chunks/build/{table-DIu_YCJN.mjs.map → table-CmVD-cA9.mjs.map} +1 -1
  249. package/.output/server/chunks/build/{teams-B2J6ouRY.mjs → teams-B1d32eHK.mjs} +4 -4
  250. package/.output/server/chunks/build/{teams-B2J6ouRY.mjs.map → teams-B1d32eHK.mjs.map} +1 -1
  251. package/.output/server/chunks/build/{tokens-DFQGaN2n.mjs → tokens-GYaGJ35Z.mjs} +6 -6
  252. package/.output/server/chunks/build/{tokens-DFQGaN2n.mjs.map → tokens-GYaGJ35Z.mjs.map} +1 -1
  253. package/.output/server/chunks/build/{tools-DWJFnU_t.mjs → tools-s_9U1Djj.mjs} +6 -6
  254. package/.output/server/chunks/build/{tools-DWJFnU_t.mjs.map → tools-s_9U1Djj.mjs.map} +1 -1
  255. package/.output/server/chunks/build/types-D6J7slEa.mjs +6 -2
  256. package/.output/server/chunks/build/useDaqAddNode-D_Rkju0f.mjs +1 -1
  257. package/.output/server/chunks/build/useDaqDetailNode-DeOsDxK5.mjs +1 -1
  258. package/.output/server/chunks/build/useDaqDetailParams-Cm9a9r5G.mjs +1 -1
  259. package/.output/server/chunks/build/useDaqFilters-CctmO03p.mjs +1 -1
  260. package/.output/server/chunks/build/useDaqStream-B9ZBVQrI.mjs +1 -1
  261. package/.output/server/chunks/build/useDaqTemplates-CK37sMfi.mjs +1 -1
  262. package/.output/server/chunks/build/useDcwAddNode-DACVcEHs.mjs +1 -1
  263. package/.output/server/chunks/build/useDcwStream-Dir5ufAU.mjs +1 -1
  264. package/.output/server/chunks/build/{users-BWw0VCr9.mjs → users-DjiVC_tS.mjs} +6 -6
  265. package/.output/server/chunks/build/{users-BWw0VCr9.mjs.map → users-DjiVC_tS.mjs.map} +1 -1
  266. package/.output/server/chunks/routes/api/mcp/workshop.mjs +1 -1
  267. package/.output/server/chunks/routes/api/system/backup/run.post.mjs +2 -2
  268. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +17 -4
  269. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs.map +1 -1
  270. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs +1 -1
  271. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +1 -1
  272. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/grant.post.mjs +1 -1
  273. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/revoke.post.mjs +1 -1
  274. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +1 -1
  275. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +1 -1
  276. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +1 -1
  277. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +1 -1
  278. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs +1 -1
  279. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs +1 -1
  280. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.delete.mjs +1 -1
  281. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +1 -1
  282. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.patch.mjs +1 -1
  283. package/.output/server/chunks/routes/api/workshop/aml/env/recheck.post.mjs +1 -1
  284. package/.output/server/chunks/routes/api/workshop/aml/env/uv.post.mjs +1 -1
  285. package/.output/server/chunks/routes/api/workshop/aml/env/venv.post.mjs +1 -1
  286. package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs +1 -1
  287. package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs +1 -1
  288. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs +1 -1
  289. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs +1 -1
  290. package/.output/server/chunks/routes/api/workshop/aml/index3.post.mjs +1 -1
  291. package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs +1 -1
  292. package/.output/server/chunks/routes/api/workshop/aml/index5.get.mjs +1 -1
  293. package/.output/server/chunks/routes/api/workshop/aml/index6.get.mjs +1 -1
  294. package/.output/server/chunks/routes/api/workshop/aml/index7.get.mjs +1 -1
  295. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs +1 -1
  296. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs +1 -1
  297. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs +1 -1
  298. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.delete.mjs +1 -1
  299. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs +1 -1
  300. package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs +1 -1
  301. package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs +1 -1
  302. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.delete.mjs +1 -1
  303. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.patch.mjs +8 -2
  304. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.patch.mjs.map +1 -1
  305. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id/train.post.mjs +1 -1
  306. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.delete.mjs +1 -1
  307. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.patch.mjs +1 -1
  308. package/.output/server/chunks/routes/api/workshop/aml/twin/providers.get.mjs +1 -1
  309. package/.output/server/chunks/routes/api/workshop/analysis/_id_.delete.mjs +1 -1
  310. package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs +1 -1
  311. package/.output/server/chunks/routes/api/workshop/analysis/_id_.patch.mjs +1 -1
  312. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +1 -1
  313. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +1 -1
  314. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +1 -1
  315. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +2 -2
  316. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +1 -1
  317. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.post.mjs +1 -1
  318. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
  319. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +1 -1
  320. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.put.mjs +1 -1
  321. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
  322. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
  323. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +1 -1
  324. package/.output/server/chunks/routes/api/workshop/channels/_id/line.put.mjs +1 -1
  325. package/.output/server/chunks/routes/api/workshop/channels/_id/members/join.post.mjs +1 -1
  326. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +1 -1
  327. package/.output/server/chunks/routes/api/workshop/channels/_id/tools/reset.post.mjs +1 -1
  328. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs +1 -1
  329. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.patch.mjs +1 -1
  330. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +1 -1
  331. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +7 -7
  332. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +1 -1
  333. package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs +1 -1
  334. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +1 -1
  335. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +1 -1
  336. package/.output/server/chunks/routes/api/workshop/daq/_id/ingest.post.mjs +2 -2
  337. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +1 -1
  338. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +1 -1
  339. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +1 -1
  340. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +1 -1
  341. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +1 -1
  342. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +1 -1
  343. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +1 -1
  344. package/.output/server/chunks/routes/api/workshop/daq/export/_id_.get.mjs +1 -1
  345. package/.output/server/chunks/routes/api/workshop/daq/index2.post.mjs +1 -1
  346. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +1 -1
  347. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +1 -1
  348. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +1 -1
  349. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +1 -1
  350. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +1 -1
  351. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +1 -1
  352. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +1 -1
  353. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +1 -1
  354. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +1 -1
  355. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +1 -1
  356. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +1 -1
  357. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +1 -1
  358. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +1 -1
  359. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +1 -1
  360. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +1 -1
  361. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -1
  362. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +1 -1
  363. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +1 -1
  364. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +1 -1
  365. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +1 -1
  366. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +1 -1
  367. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
  368. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +1 -1
  369. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +1 -1
  370. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +1 -1
  371. package/.output/server/chunks/routes/api/workshop/dcw/index7.get.mjs +1 -1
  372. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +1 -1
  373. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +1 -1
  374. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  375. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  376. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
  377. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs +1 -1
  378. package/.output/server/chunks/routes/api/workshop/dcw/mes-artifacts/file.get.mjs +1 -1
  379. package/.output/server/chunks/routes/api/workshop/dcw/mes-hook-test.post.mjs +1 -1
  380. package/.output/server/chunks/routes/api/workshop/dcw/mes-test-read.post.mjs +1 -1
  381. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +1 -1
  382. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +1 -1
  383. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +1 -1
  384. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +1 -1
  385. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +1 -1
  386. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +1 -1
  387. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +1 -1
  388. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +1 -1
  389. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +1 -1
  390. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +1 -1
  391. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +1 -1
  392. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +1 -1
  393. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs +1 -1
  394. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +1 -1
  395. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs +1 -1
  396. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +1 -1
  397. package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs +1 -1
  398. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +1 -1
  399. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
  400. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +1 -1
  401. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  402. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  403. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +1 -1
  404. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +1 -1
  405. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +1 -1
  406. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +1 -1
  407. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +1 -1
  408. package/.output/server/chunks/routes/api/workshop/eda/commonality.get.mjs +1 -1
  409. package/.output/server/chunks/routes/api/workshop/eda/features/run.post.mjs +1 -1
  410. package/.output/server/chunks/routes/api/workshop/eda/index3.get.mjs +1 -1
  411. package/.output/server/chunks/routes/api/workshop/eda/index6.get.mjs +1 -1
  412. package/.output/server/chunks/routes/api/workshop/eda/index6.post.mjs +1 -1
  413. package/.output/server/chunks/routes/api/workshop/eda/runs/_id/labels.patch.mjs +1 -1
  414. package/.output/server/chunks/routes/api/workshop/eda/runs.get.mjs +1 -1
  415. package/.output/server/chunks/routes/api/workshop/eda/vm/predict.post.mjs +1 -1
  416. package/.output/server/chunks/routes/api/workshop/exp/confirmations/_id/decide.post.mjs +1 -1
  417. package/.output/server/chunks/routes/api/workshop/exp/index.get.mjs +1 -1
  418. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +1 -1
  419. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  420. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  421. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  422. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  423. package/.output/server/chunks/routes/api/workshop/index.mjs +62 -0
  424. package/.output/server/chunks/routes/api/workshop/index.mjs.map +1 -0
  425. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  426. package/.output/server/chunks/routes/api/workshop/index10.get.mjs +1 -1
  427. package/.output/server/chunks/routes/api/workshop/index11.get.mjs +1 -1
  428. package/.output/server/chunks/routes/api/workshop/index12.get.mjs +1 -1
  429. package/.output/server/chunks/routes/api/workshop/index2.get.mjs +1 -1
  430. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +1 -1
  431. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +1 -1
  432. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +1 -1
  433. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +1 -1
  434. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +1 -1
  435. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +1 -1
  436. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +1 -1
  437. package/.output/server/chunks/routes/api/workshop/index8.get.mjs +1 -1
  438. package/.output/server/chunks/routes/api/workshop/mes/datasets.get.mjs +1 -1
  439. package/.output/server/chunks/routes/api/workshop/mes/preview.post.mjs +1 -1
  440. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/autofix.mjs +52 -0
  441. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/autofix.mjs.map +1 -0
  442. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/compile.mjs +54 -0
  443. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/compile.mjs.map +1 -0
  444. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/evidence.mjs +51 -0
  445. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/evidence.mjs.map +1 -0
  446. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/publish.mjs +67 -0
  447. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/publish.mjs.map +1 -0
  448. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/approval-decision.mjs +49 -0
  449. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/approval-decision.mjs.map +1 -0
  450. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/approval.mjs +35 -0
  451. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/approval.mjs.map +1 -0
  452. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/transition.mjs +49 -0
  453. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/transition.mjs.map +1 -0
  454. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/subgraph.mjs +38 -0
  455. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/subgraph.mjs.map +1 -0
  456. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/validate.mjs +35 -0
  457. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/validate.mjs.map +1 -0
  458. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId_.mjs +70 -0
  459. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId_.mjs.map +1 -0
  460. package/.output/server/chunks/routes/api/workshop/ontology/export/_ontologyId_.mjs +64 -0
  461. package/.output/server/chunks/routes/api/workshop/ontology/export/_ontologyId_.mjs.map +1 -0
  462. package/.output/server/chunks/routes/api/workshop/ontology/index.mjs +44 -0
  463. package/.output/server/chunks/routes/api/workshop/ontology/index.mjs.map +1 -0
  464. package/.output/server/chunks/routes/api/workshop/ontology/scene.mjs +43 -0
  465. package/.output/server/chunks/routes/api/workshop/ontology/scene.mjs.map +1 -0
  466. package/.output/server/chunks/routes/api/workshop/ontology/traces/_ontologyId_.mjs +38 -0
  467. package/.output/server/chunks/routes/api/workshop/ontology/traces/_ontologyId_.mjs.map +1 -0
  468. package/.output/server/chunks/routes/api/workshop/ontology/versions/_ontologyId/compare.mjs +40 -0
  469. package/.output/server/chunks/routes/api/workshop/ontology/versions/_ontologyId/compare.mjs.map +1 -0
  470. package/.output/server/chunks/routes/api/workshop/ontology/versions/_ontologyId_.mjs +63 -0
  471. package/.output/server/chunks/routes/api/workshop/ontology/versions/_ontologyId_.mjs.map +1 -0
  472. package/.output/server/chunks/routes/api/workshop/optimization/capabilities.get.mjs +1 -1
  473. package/.output/server/chunks/routes/api/workshop/optimization/index.get.mjs +1 -1
  474. package/.output/server/chunks/routes/api/workshop/optimization/index.mjs +1 -1
  475. package/.output/server/chunks/routes/api/workshop/optimization/index2.mjs +1 -1
  476. package/.output/server/chunks/routes/api/workshop/optimization/profiles/_id/publish.post.mjs +1 -1
  477. package/.output/server/chunks/routes/api/workshop/optimization/recommendations/_id/crosscheck.post.mjs +1 -1
  478. package/.output/server/chunks/routes/api/workshop/optimization/recommendations/_id/dispatch.post.mjs +1 -1
  479. package/.output/server/chunks/routes/api/workshop/optimization/solve.post.mjs +1 -1
  480. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  481. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  482. package/.output/server/chunks/routes/api/workshop/process-model/datasets.post.mjs +1 -1
  483. package/.output/server/chunks/routes/api/workshop/process-model/eligibility.mjs +1 -1
  484. package/.output/server/chunks/routes/api/workshop/process-model/experiments.mjs +1 -1
  485. package/.output/server/chunks/routes/api/workshop/process-model/index.mjs +1 -1
  486. package/.output/server/chunks/routes/api/workshop/process-model/specs/_id/publish.post.mjs +1 -1
  487. package/.output/server/chunks/routes/api/workshop/process-model/train.post.mjs +1 -1
  488. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  489. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  490. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -1
  491. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +1 -1
  492. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +1 -1
  493. package/.output/server/chunks/routes/api/workshop/tools/_name_.get.mjs +1 -1
  494. package/.output/server/chunks/routes/api/workshop/tools/sync.post.mjs +1 -1
  495. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -2
  496. package/.output/server/chunks/routes/renderer.mjs +2 -2
  497. package/.output/server/chunks/virtual/entry.mjs +323 -18
  498. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  499. package/.output/server/package.json +1 -1
  500. package/README-zh.md +28 -6
  501. package/README.md +26 -4
  502. package/app/components/AppSidebar.vue +1 -0
  503. package/app/components/aml/AmlModelsTable.vue +5 -0
  504. package/app/components/ontology/OntologyGraph.vue +356 -0
  505. package/app/pages/aml/styles.css +1 -0
  506. package/app/pages/ontology/api.ts +18 -0
  507. package/app/pages/ontology/index.vue +1062 -0
  508. package/app/pages/ontology/types.ts +164 -0
  509. package/app/pages/optimizer/index.vue +21 -4
  510. package/config.yml +1 -1
  511. package/docs/cli.en.md +2 -2
  512. package/docs/cli.md +2 -2
  513. package/docs/plugins.en.md +1 -1
  514. package/docs/plugins.md +1 -1
  515. package/docs/sdk.en.md +1 -1
  516. package/docs/sdk.md +1 -1
  517. package/i18n/locales/en.ts +84 -0
  518. package/i18n/locales/zh-CN.ts +84 -0
  519. package/mcp/aw-mcp-server.mjs +53 -1
  520. package/package.json +1 -1
  521. package/scripts/docs-shots.mjs +36 -0
  522. package/scripts/e2e-direct-rest-simulator-paper.mjs +624 -0
  523. package/scripts/e2e-idd-results.mjs +177 -0
  524. package/scripts/e2e-model-loop-live.mjs +785 -0
  525. package/scripts/e2e-ontology-live.mjs +909 -0
  526. package/scripts/e2e-ontology.mjs +393 -0
  527. package/scripts/e2e-pi-simulator-paper.mjs +2316 -0
  528. package/scripts/e2e-registered-harness-simulator-paper.mjs +1926 -0
  529. package/scripts/e2e-simulator-optimizer-paper.mjs +264 -0
  530. package/scripts/fixtures/omp-paper-harness.mjs +163 -0
  531. package/scripts/ontology-idd-rag-e2e.mjs +449 -0
  532. package/sdk/context.mjs +6 -0
  533. package/sdk/index.d.mts +2 -0
  534. package/server/api/workshop/agent-tools/approvals/[id]/decide.post.ts +16 -0
  535. package/server/api/workshop/aml/models/[id].patch.ts +36 -30
  536. package/server/api/workshop/ontology/drafts/[draftId]/autofix.ts +31 -0
  537. package/server/api/workshop/ontology/drafts/[draftId]/compile.ts +39 -0
  538. package/server/api/workshop/ontology/drafts/[draftId]/evidence.ts +33 -0
  539. package/server/api/workshop/ontology/drafts/[draftId]/publish.ts +44 -0
  540. package/server/api/workshop/ontology/drafts/[draftId]/rules/[ruleId]/approval-decision.ts +28 -0
  541. package/server/api/workshop/ontology/drafts/[draftId]/rules/[ruleId]/approval.ts +17 -0
  542. package/server/api/workshop/ontology/drafts/[draftId]/rules/[ruleId]/transition.ts +32 -0
  543. package/server/api/workshop/ontology/drafts/[draftId]/subgraph.ts +24 -0
  544. package/server/api/workshop/ontology/drafts/[draftId]/validate.ts +16 -0
  545. package/server/api/workshop/ontology/drafts/[draftId].ts +52 -0
  546. package/server/api/workshop/ontology/drafts/index.ts +20 -0
  547. package/server/api/workshop/ontology/export/[ontologyId].ts +50 -0
  548. package/server/api/workshop/ontology/index.ts +38 -0
  549. package/server/api/workshop/ontology/scene.ts +34 -0
  550. package/server/api/workshop/ontology/traces/[ontologyId].ts +19 -0
  551. package/server/api/workshop/ontology/versions/[ontologyId]/compare.ts +21 -0
  552. package/server/api/workshop/ontology/versions/[ontologyId].ts +42 -0
  553. package/server/plugins-builtin/diag-bridge/client.mjs +390 -239
  554. package/server/plugins-builtin/diag-bridge/host/helpers.mjs +80 -0
  555. package/server/plugins-builtin/diag-bridge/host/plugin.mjs +264 -2
  556. package/server/plugins-builtin/diag-bridge/i18n.json +84 -4
  557. package/server/services/workshop/agents/adapters/omp-rpc-client/frames.ts +129 -111
  558. package/server/services/workshop/agents/hitl-decision/dispatcher.ts +15 -0
  559. package/server/services/workshop/agents/host-tool-bridge/tools/industrial.ts +17 -2
  560. package/server/services/workshop/agents/industrial/aml-job-tools.ts +602 -569
  561. package/server/services/workshop/agents/industrial/grant-guard.ts +73 -0
  562. package/server/services/workshop/agents/industrial/index.ts +38 -32
  563. package/server/services/workshop/agents/industrial/ontology-tools.ts +380 -0
  564. package/server/services/workshop/agents/industrial/ops-tools.ts +54 -16
  565. package/server/services/workshop/agents/industrial/optimizer-tools.ts +81 -0
  566. package/server/services/workshop/agents/industrial/recipe-gate.ts +19 -6
  567. package/server/services/workshop/agents/industrial/recipe-propose-tools.ts +1 -1
  568. package/server/services/workshop/agents/industrial/tool-verify.ts +32 -2
  569. package/server/services/workshop/agents/omp-agent/supervision-history.ts +38 -0
  570. package/server/services/workshop/agents/omp-agent/tools-steer.ts +18 -1
  571. package/server/services/workshop/agents/tool-reference-spec.ts +1 -1
  572. package/server/services/workshop/aml/aml.repo.ts +16 -0
  573. package/server/services/workshop/aml/twin/physics-spec.ts +6 -22
  574. package/server/services/workshop/daq/bus/index.ts +12 -5
  575. package/server/services/workshop/daq/storage/index.ts +6 -5
  576. package/server/services/workshop/daq/storage/sqlite.adapter.ts +25 -13
  577. package/server/services/workshop/db/database/open.ts +97 -95
  578. package/server/services/workshop/db/database/schema.ts +156 -1
  579. package/server/services/workshop/ontology/autofix.ts +198 -0
  580. package/server/services/workshop/ontology/compiler.ts +474 -0
  581. package/server/services/workshop/ontology/contracts.ts +443 -0
  582. package/server/services/workshop/ontology/guards.ts +139 -0
  583. package/server/services/workshop/ontology/index.ts +12 -0
  584. package/server/services/workshop/ontology/ontology.service.ts +938 -0
  585. package/server/services/workshop/ontology/repo.ts +449 -0
  586. package/server/services/workshop/ontology/semantic-binding.service.ts +226 -0
  587. package/server/services/workshop/ontology/subgraph.core.ts +300 -0
  588. package/server/services/workshop/ontology/subgraph.service.ts +113 -0
  589. package/server/services/workshop/ontology/validator.ts +218 -0
  590. package/server/services/workshop/optimization/binding.repo.ts +7 -0
  591. package/server/services/workshop/optimization/contracts.ts +16 -0
  592. package/server/services/workshop/optimization/dispatch.service.ts +16 -0
  593. package/server/services/workshop/optimization/profile-adopt.service.ts +261 -0
  594. package/server/services/workshop/optimization/profile.repo.ts +24 -6
  595. package/server/services/workshop/optimization/python/__pycache__/problems.cpython-312.pyc +0 -0
  596. package/shared/dimensions.ts +124 -0
  597. package/.output/public/_nuxt/B3Y5bCrM.js +0 -1
  598. package/.output/public/_nuxt/B7s2qeyT.js +0 -14
  599. package/.output/public/_nuxt/B8N8nsad2.js +0 -2
  600. package/.output/public/_nuxt/BO0BJx3w.js +0 -8
  601. package/.output/public/_nuxt/BWn-lfCp2.js +0 -1
  602. package/.output/public/_nuxt/Bcs9zzO62.js +0 -1
  603. package/.output/public/_nuxt/BwO2Y5FH2.js +0 -1
  604. package/.output/public/_nuxt/C-LU6xv_.js +0 -1
  605. package/.output/public/_nuxt/CJ0bjZ6v2.js +0 -1
  606. package/.output/public/_nuxt/CJ3Vul2u.js +0 -1
  607. package/.output/public/_nuxt/CNwx04ln.js +0 -84
  608. package/.output/public/_nuxt/CVCscYzb2.js +0 -1
  609. package/.output/public/_nuxt/C_A0MCol2.js +0 -1
  610. package/.output/public/_nuxt/CnP6snIz.js +0 -3
  611. package/.output/public/_nuxt/D3buuIkE.js +0 -1
  612. package/.output/public/_nuxt/D4_INWgq.js +0 -1
  613. package/.output/public/_nuxt/D5kCimyw.js +0 -1
  614. package/.output/public/_nuxt/DBtXLkyA.js +0 -1
  615. package/.output/public/_nuxt/DHURbGkn2.js +0 -1
  616. package/.output/public/_nuxt/DaBzS-iu.js +0 -1
  617. package/.output/public/_nuxt/DnlhV7Xe.js +0 -1
  618. package/.output/public/_nuxt/GtI6PUI32.js +0 -1
  619. package/.output/public/_nuxt/LHIav-Kv.js +0 -1
  620. package/.output/public/_nuxt/Nw_6OpQZ.js +0 -1
  621. package/.output/public/_nuxt/RuMLNeQE.js +0 -1
  622. package/.output/public/_nuxt/Y4sMSPrS.js +0 -1
  623. package/.output/public/_nuxt/aml.CeLxRzvI.css +0 -1
  624. package/.output/public/_nuxt/builds/meta/0ae8cb0f-6ce5-4096-9692-9b1fc197b30d.json +0 -1
  625. package/.output/public/_nuxt/goF_oZHF.js +0 -2
  626. package/.output/public/_nuxt/optimizer.B8gCbU1b.css +0 -1
  627. package/.output/public/_nuxt/rJ7To74v2.js +0 -1
  628. package/.output/server/chunks/build/optimizer-BOtGWEtc.mjs +0 -200
  629. package/.output/server/chunks/build/optimizer-BOtGWEtc.mjs.map +0 -1
@@ -0,0 +1,449 @@
1
+ /**
2
+ * Ontology 仓储(版本快照不可变 + 草稿单活跃 + 证据/日志/溯源追加行)。
3
+ *
4
+ * 约定对齐 process_model_specs / optimizer_profiles:
5
+ * - (id, version) 主键;published 行服务层拒改;
6
+ * - 草稿是**整份 JSON 文档**(服务层不散改行),发布时物化为不可变快照;
7
+ * - 证据、发布日志、规则溯源为 append-only 追加行。
8
+ */
9
+ import type { DatabaseSync } from 'node:sqlite'
10
+ import { AppError } from '../../../utils/errors'
11
+ import { getAmlRuntime } from '../aml/runtime'
12
+ import { withTransaction } from '../db/transaction'
13
+ import type { ControlGuard, OntologyDraftDoc, OntologyEntity, OntologyRelation, OntologyRule, OntologyRuleTrace, BindingDraft } from './contracts'
14
+
15
+ export type VersionStatus = 'draft' | 'published' | 'retired'
16
+
17
+ export interface DraftRow {
18
+ id: string
19
+ ontologyId: string
20
+ baseVersion: number | null
21
+ rev: number
22
+ draftJson: string
23
+ ownerUserId: string
24
+ createdAt: string
25
+ updatedAt: string
26
+ }
27
+
28
+ export interface VersionRow {
29
+ id: string
30
+ version: number
31
+ name: string
32
+ lineId: string
33
+ parentVersion: number | null
34
+ contentHash: string
35
+ compiledJson: string
36
+ changelogJson: string
37
+ status: VersionStatus
38
+ ownerUserId: string
39
+ publishedBy: string
40
+ createdAt: string
41
+ updatedAt: string
42
+ }
43
+
44
+ export interface EvidenceRow {
45
+ id: string
46
+ ontologyId: string
47
+ targetKind: string
48
+ targetKey: string
49
+ level: string
50
+ sourceType: string
51
+ sourceRef: string
52
+ sourceRefHash: string
53
+ detailJson: string
54
+ createdBy: string
55
+ createdAt: string
56
+ }
57
+
58
+ export interface PublishLogRow {
59
+ id: string
60
+ ontologyId: string
61
+ version: number
62
+ action: string
63
+ actor: string
64
+ actorKind: string
65
+ soloOperator: number
66
+ approvalId: string | null
67
+ detailJson: string
68
+ createdAt: string
69
+ }
70
+
71
+ export interface BindingRow {
72
+ id: string
73
+ versionId: string
74
+ version: number
75
+ entityKey: string
76
+ platformKind: string
77
+ platformId: string
78
+ targetSub: string
79
+ scope: string
80
+ direction: string
81
+ unitDeclared: string
82
+ unitTarget: string
83
+ scale: number
84
+ offset: number
85
+ status: string
86
+ lastVerifiedAt: string | null
87
+ createdAt: string
88
+ }
89
+
90
+ const DRAFT_COLS = `id, ontology_id AS ontologyId, base_version AS baseVersion, rev,
91
+ draft_json AS draftJson, owner_user_id AS ownerUserId, created_at AS createdAt, updated_at AS updatedAt`
92
+
93
+ const VERSION_COLS = `id, version, name, line_id AS lineId, parent_version AS parentVersion,
94
+ content_hash AS contentHash, compiled_json AS compiledJson, changelog_json AS changelogJson,
95
+ status, owner_user_id AS ownerUserId, published_by AS publishedBy,
96
+ created_at AS createdAt, updated_at AS updatedAt`
97
+
98
+ export function createOntologyRepo(db: DatabaseSync) {
99
+ const repo = {
100
+ // ===== 草稿 =====
101
+ insertDraft(input: { id: string, ontologyId: string, baseVersion: number | null, draftJson: string, ownerUserId: string }): DraftRow {
102
+ const now = new Date().toISOString()
103
+ const existing = db.prepare(`SELECT ${DRAFT_COLS} FROM ontology_drafts WHERE ontology_id = ? AND owner_user_id = ?`)
104
+ .get(input.ontologyId, input.ownerUserId) as DraftRow | undefined
105
+ if (existing) {
106
+ throw new AppError(409, 'DRAFT_ALREADY_ACTIVE',
107
+ `本体 ${input.ontologyId} 已存在活跃草稿(${existing.id}, rev=${existing.rev});请继续编辑或先删除该草稿`)
108
+ }
109
+ db.prepare(`INSERT INTO ontology_drafts (id, ontology_id, base_version, rev, draft_json, owner_user_id, created_at, updated_at)
110
+ VALUES (?, ?, ?, 1, ?, ?, ?, ?)`)
111
+ .run(input.id, input.ontologyId, input.baseVersion, input.draftJson, input.ownerUserId, now, now)
112
+ return repo.getDraft(input.id)!
113
+ },
114
+
115
+ getDraft(id: string): DraftRow | undefined {
116
+ return db.prepare(`SELECT ${DRAFT_COLS} FROM ontology_drafts WHERE id = ?`).get(id) as DraftRow | undefined
117
+ },
118
+
119
+ getActiveDraft(ontologyId: string, ownerUserId: string): DraftRow | undefined {
120
+ return db.prepare(`SELECT ${DRAFT_COLS} FROM ontology_drafts WHERE ontology_id = ? AND owner_user_id = ?`)
121
+ .get(ontologyId, ownerUserId) as DraftRow | undefined
122
+ },
123
+
124
+ listDrafts(filter: { ownerUserId?: string, ontologyId?: string } = {}): DraftRow[] {
125
+ const where: string[] = []
126
+ const params: Array<string> = []
127
+ if (filter.ownerUserId) {
128
+ where.push('owner_user_id = ?')
129
+ params.push(filter.ownerUserId)
130
+ }
131
+ if (filter.ontologyId) {
132
+ where.push('ontology_id = ?')
133
+ params.push(filter.ontologyId)
134
+ }
135
+ const sql = `SELECT ${DRAFT_COLS} FROM ontology_drafts${where.length ? ` WHERE ${where.join(' AND ')}` : ''} ORDER BY updated_at DESC LIMIT 200`
136
+ return db.prepare(sql).all(...params) as unknown as DraftRow[]
137
+ },
138
+
139
+ /** 乐观锁:rev 不匹配 → 409(并发编辑必须显式重读) */
140
+ updateDraft(id: string, draftJson: string, expectedRev: number): DraftRow {
141
+ const current = repo.getDraft(id)
142
+ if (!current) throw new AppError(404, 'DRAFT_NOT_FOUND', `草稿 ${id} 不存在`)
143
+ if (current.rev !== expectedRev) {
144
+ throw new AppError(409, 'DRAFT_CONCURRENT_MODIFY',
145
+ `草稿 ${id} 已被修改(期望 rev=${expectedRev},当前 rev=${current.rev});请重新读取后再提交`)
146
+ }
147
+ const now = new Date().toISOString()
148
+ const changes = db.prepare('UPDATE ontology_drafts SET draft_json = ?, rev = rev + 1, updated_at = ? WHERE id = ? AND rev = ?')
149
+ .run(draftJson, now, id, expectedRev).changes
150
+ if (changes === 0) throw new AppError(409, 'DRAFT_CONCURRENT_MODIFY', `草稿 ${id} 并发修改冲突`)
151
+ return repo.getDraft(id)!
152
+ },
153
+
154
+ updateDraftMeta(id: string, patch: { baseVersion?: number | null }): void {
155
+ const now = new Date().toISOString()
156
+ if (patch.baseVersion !== undefined) {
157
+ db.prepare('UPDATE ontology_drafts SET base_version = ?, updated_at = ? WHERE id = ?').run(patch.baseVersion, now, id)
158
+ }
159
+ },
160
+
161
+ deleteDraft(id: string): boolean {
162
+ return db.prepare('DELETE FROM ontology_drafts WHERE id = ?').run(id).changes > 0
163
+ },
164
+
165
+ // ===== 版本 =====
166
+ getVersion(id: string, version: number): VersionRow | undefined {
167
+ return db.prepare(`SELECT ${VERSION_COLS} FROM ontology_versions WHERE id = ? AND version = ?`)
168
+ .get(id, version) as VersionRow | undefined
169
+ },
170
+
171
+ listVersions(id: string): VersionRow[] {
172
+ return db.prepare(`SELECT ${VERSION_COLS} FROM ontology_versions WHERE id = ? ORDER BY version DESC`)
173
+ .all(id) as unknown as VersionRow[]
174
+ },
175
+
176
+ latestVersion(id: string, status?: VersionStatus): VersionRow | undefined {
177
+ const row = status
178
+ ? db.prepare(`SELECT ${VERSION_COLS} FROM ontology_versions WHERE id = ? AND status = ? ORDER BY version DESC LIMIT 1`).get(id, status)
179
+ : db.prepare(`SELECT ${VERSION_COLS} FROM ontology_versions WHERE id = ? ORDER BY version DESC LIMIT 1`).get(id)
180
+ return row as VersionRow | undefined
181
+ },
182
+
183
+ nextVersionNumber(id: string): number {
184
+ const row = db.prepare('SELECT MAX(version) AS maxVersion FROM ontology_versions WHERE id = ?').get(id) as { maxVersion: number | null } | undefined
185
+ return (row?.maxVersion ?? 0) + 1
186
+ },
187
+
188
+ /** 某产线当前生效的已发布版本(该线最新的 published;退役版本自然被跳过) */
189
+ latestPublishedForLine(lineId: string): VersionRow | undefined {
190
+ return db.prepare(`SELECT ${VERSION_COLS} FROM ontology_versions
191
+ WHERE line_id = ? AND status = 'published' ORDER BY version DESC, updated_at DESC LIMIT 1`)
192
+ .get(lineId) as VersionRow | undefined
193
+ },
194
+
195
+ listAllOntologyIds(lineId?: string): Array<{ id: string, lineId: string, versions: number, latest: number, status: string }> {
196
+ const sql = `SELECT v.id AS id, MAX(v.line_id) AS lineId, COUNT(*) AS versions, MAX(v.version) AS latest,
197
+ (SELECT status FROM ontology_versions v2 WHERE v2.id = v.id ORDER BY v2.version DESC LIMIT 1) AS status
198
+ FROM ontology_versions v ${lineId ? 'WHERE v.line_id = ?' : ''} GROUP BY v.id ORDER BY MAX(v.updated_at) DESC LIMIT 200`
199
+ return (lineId ? db.prepare(sql).all(lineId) : db.prepare(sql).all()) as Array<{ id: string, lineId: string, versions: number, latest: number, status: string }>
200
+ },
201
+
202
+ /** 发布快照:版本行 + 实体/关系/规则/绑定 + 溯源,单事务原子落库 */
203
+ publishSnapshot(input: {
204
+ version: VersionRow
205
+ entities: OntologyEntity[]
206
+ relations: OntologyRelation[]
207
+ rules: OntologyRule[]
208
+ bindings: BindingDraft[]
209
+ traces: OntologyRuleTrace[]
210
+ guards: ControlGuard[]
211
+ createdBy: string
212
+ }): VersionRow {
213
+ return withTransaction(db, () => {
214
+ const now = new Date().toISOString()
215
+ db.prepare(`INSERT INTO ontology_versions
216
+ (id, version, name, line_id, parent_version, content_hash, compiled_json, changelog_json,
217
+ status, owner_user_id, published_by, created_at, updated_at)
218
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
219
+ .run(input.version.id, input.version.version, input.version.name, input.version.lineId,
220
+ input.version.parentVersion, input.version.contentHash, input.version.compiledJson,
221
+ input.version.changelogJson, input.version.status, input.version.ownerUserId,
222
+ input.version.publishedBy, now, now)
223
+
224
+ const entityStmt = db.prepare(`INSERT INTO ontology_entities
225
+ (version_id, version, entity_key, kind, name, description, unit, dimension, role, attributes_json, created_at)
226
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
227
+ for (const entity of input.entities) {
228
+ entityStmt.run(input.version.id, input.version.version, entity.key, entity.kind, entity.name,
229
+ entity.description, entity.unit, entity.dimension, entity.role ?? '', JSON.stringify(entity.attrs), now)
230
+ }
231
+
232
+ const relationStmt = db.prepare(`INSERT INTO ontology_relations
233
+ (id, version_id, version, src_key, dst_key, predicate, properties_json, status, created_at)
234
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
235
+ for (const rel of input.relations) {
236
+ relationStmt.run(rel.id, input.version.id, input.version.version, rel.srcKey, rel.dstKey, rel.kind,
237
+ JSON.stringify({ ...rel.properties, evidence: rel.evidence }), rel.status, now)
238
+ }
239
+
240
+ const ruleStmt = db.prepare(`INSERT INTO ontology_rules
241
+ (id, version_id, version, rule_key, kind, dsl_json, constraint_level, severity, status, description, created_at)
242
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
243
+ for (const rule of input.rules) {
244
+ ruleStmt.run(rule.id, input.version.id, input.version.version, rule.key, rule.kind,
245
+ JSON.stringify({ dsl: rule.dsl, evidence: rule.evidence, scope: rule.scope }),
246
+ rule.constraintLevel, rule.severity, rule.status, rule.description, now)
247
+ }
248
+
249
+ const bindingStmt = db.prepare(`INSERT INTO ontology_semantic_bindings
250
+ (id, version_id, version, entity_key, platform_kind, platform_id, target_sub, scope, direction,
251
+ unit_declared, unit_target, scale, offset, status, last_verified_at, created_at)
252
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', ?, ?)`)
253
+ for (const binding of input.bindings) {
254
+ bindingStmt.run(binding.id, input.version.id, input.version.version, binding.entityKey,
255
+ binding.platformKind, binding.platformId, binding.targetSub, binding.scope, binding.direction,
256
+ binding.unitDeclared, binding.unitTarget, binding.scale, binding.offset, now, now)
257
+ }
258
+
259
+ const traceStmt = db.prepare(`INSERT INTO ontology_rule_traces
260
+ (id, ontology_id, version, rule_pack_hash, rule_id, rule_revision, rule_kind, evidence_level,
261
+ constraint_level, decision, decision_code, message, bindings_json, artifacts_json, scope_json, row_hash, created_at)
262
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
263
+ for (const trace of input.traces) {
264
+ traceStmt.run(trace.id, trace.ontologyId, trace.version, trace.rulePackHash, trace.ruleId,
265
+ trace.ruleRevision, trace.ruleKind, trace.evidenceLevel, trace.constraintLevel, trace.decision,
266
+ trace.decisionCode, trace.message, JSON.stringify(trace.bindings), JSON.stringify(trace.artifacts),
267
+ JSON.stringify(trace.scope), trace.rowHash, trace.createdAt)
268
+ }
269
+ return repo.getVersion(input.version.id, input.version.version)!
270
+ })
271
+ },
272
+
273
+ /** 状态原子转移(条件 UPDATE;changes=0 → 409 由调用方判定) */
274
+ transitionVersion(id: string, version: number, to: VersionStatus, from: VersionStatus): boolean {
275
+ const now = new Date().toISOString()
276
+ return db.prepare('UPDATE ontology_versions SET status = ?, updated_at = ? WHERE id = ? AND version = ? AND status = ?')
277
+ .run(to, now, id, version, from).changes > 0
278
+ },
279
+
280
+ listEntities(versionId: string, version: number): OntologyEntity[] {
281
+ const rows = db.prepare(`SELECT entity_key AS key, kind, name, description, unit, dimension, role, attributes_json AS attrsJson
282
+ FROM ontology_entities WHERE version_id = ? AND version = ? ORDER BY entity_key`).all(versionId, version) as Array<Record<string, string>>
283
+ return rows.map(r => ({
284
+ key: r.key!, kind: r.kind as OntologyEntity['kind'], name: r.name!, description: r.description ?? '',
285
+ unit: r.unit ?? '', dimension: r.dimension ?? '',
286
+ role: (r.role || undefined) as OntologyEntity['role'],
287
+ attrs: JSON.parse(r.attrsJson || '{}') as OntologyEntity['attrs'],
288
+ }))
289
+ },
290
+
291
+ listRelations(versionId: string, version: number): OntologyRelation[] {
292
+ const rows = db.prepare(`SELECT id, src_key AS srcKey, dst_key AS dstKey, predicate, properties_json AS propsJson, status
293
+ FROM ontology_relations WHERE version_id = ? AND version = ? ORDER BY id`).all(versionId, version) as Array<Record<string, string>>
294
+ return rows.map((r) => {
295
+ const props = JSON.parse(r.propsJson || '{}') as Record<string, unknown>
296
+ return {
297
+ id: r.id!, kind: r.predicate as OntologyRelation['kind'], srcKey: r.srcKey!, dstKey: r.dstKey!,
298
+ status: (r.status ?? 'proposed') as OntologyRelation['status'],
299
+ evidence: Array.isArray(props.evidence) ? props.evidence as OntologyRelation['evidence'] : [],
300
+ properties: {
301
+ sign: props.sign as OntologyRelation['properties']['sign'],
302
+ gainPerUnit: props.gainPerUnit as number | undefined,
303
+ lagMs: props.lagMs as number | undefined,
304
+ evidenceTier: (props.evidenceTier ?? 'candidate_influence') as OntologyRelation['properties']['evidenceTier'],
305
+ variabilityChecked: !!props.variabilityChecked,
306
+ transportDistanceM: props.transportDistanceM as number | undefined,
307
+ nominalSpeedMps: props.nominalSpeedMps as number | undefined,
308
+ controlApplicability: props.controlApplicability as OntologyRelation['properties']['controlApplicability'],
309
+ },
310
+ }
311
+ })
312
+ },
313
+
314
+ listRules(versionId: string, version: number): OntologyRule[] {
315
+ const rows = db.prepare(`SELECT id, rule_key AS ruleKey, kind, dsl_json AS dslJson, constraint_level AS constraintLevel,
316
+ severity, status, description FROM ontology_rules WHERE version_id = ? AND version = ? ORDER BY id`)
317
+ .all(versionId, version) as Array<Record<string, string>>
318
+ return rows.map((r) => {
319
+ const parsed = JSON.parse(r.dslJson || '{}') as { dsl?: unknown, evidence?: OntologyRule['evidence'], scope?: OntologyRule['scope'] }
320
+ return {
321
+ id: r.id!, key: r.ruleKey!, kind: r.kind as OntologyRule['kind'],
322
+ dsl: parsed.dsl as OntologyRule['dsl'],
323
+ constraintLevel: (r.constraintLevel ?? 'soft') as OntologyRule['constraintLevel'],
324
+ severity: (r.severity ?? 'error') as OntologyRule['severity'],
325
+ status: (r.status ?? 'proposed') as OntologyRule['status'],
326
+ evidence: Array.isArray(parsed.evidence) ? parsed.evidence : [],
327
+ description: r.description ?? '',
328
+ scope: parsed.scope ?? { lineId: '', recipeId: '', conditionId: '' },
329
+ }
330
+ })
331
+ },
332
+
333
+ listBindings(versionId: string, version: number): BindingRow[] {
334
+ return db.prepare(`SELECT id, version_id AS versionId, version, entity_key AS entityKey,
335
+ platform_kind AS platformKind, platform_id AS platformId, target_sub AS targetSub, scope, direction,
336
+ unit_declared AS unitDeclared, unit_target AS unitTarget, scale, offset, status,
337
+ last_verified_at AS lastVerifiedAt, created_at AS createdAt
338
+ FROM ontology_semantic_bindings WHERE version_id = ? AND version = ? ORDER BY entity_key, platform_kind`)
339
+ .all(versionId, version) as unknown as BindingRow[]
340
+ },
341
+
342
+ listBindingsByTarget(platformKind: string, platformId: string): BindingRow[] {
343
+ return db.prepare(`SELECT id, version_id AS versionId, version, entity_key AS entityKey,
344
+ platform_kind AS platformKind, platform_id AS platformId, target_sub AS targetSub, scope, direction,
345
+ unit_declared AS unitDeclared, unit_target AS unitTarget, scale, offset, status,
346
+ last_verified_at AS lastVerifiedAt, created_at AS createdAt
347
+ FROM ontology_semantic_bindings WHERE platform_kind = ? AND platform_id = ? AND status = 'active'`)
348
+ .all(platformKind, platformId) as unknown as BindingRow[]
349
+ },
350
+
351
+ markBindingStatus(id: string, status: 'active' | 'drifted' | 'retired'): void {
352
+ const now = new Date().toISOString()
353
+ db.prepare('UPDATE ontology_semantic_bindings SET status = ?, last_verified_at = ? WHERE id = ?').run(status, now, id)
354
+ },
355
+
356
+ // ===== 证据 =====
357
+ appendEvidence(row: EvidenceRow): void {
358
+ db.prepare(`INSERT INTO ontology_evidence
359
+ (id, ontology_id, target_kind, target_key, level, source_type, source_ref, source_ref_hash, detail_json, created_by, created_at)
360
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
361
+ .run(row.id, row.ontologyId, row.targetKind, row.targetKey, row.level, row.sourceType,
362
+ row.sourceRef, row.sourceRefHash, row.detailJson, row.createdBy, row.createdAt)
363
+ },
364
+
365
+ listEvidence(ontologyId: string, filter: { targetKind?: string, targetKey?: string, limit?: number } = {}): EvidenceRow[] {
366
+ const where = ['ontology_id = ?']
367
+ const params: Array<string | number> = [ontologyId]
368
+ if (filter.targetKind) {
369
+ where.push('target_kind = ?')
370
+ params.push(filter.targetKind)
371
+ }
372
+ if (filter.targetKey) {
373
+ where.push('target_key = ?')
374
+ params.push(filter.targetKey)
375
+ }
376
+ params.push(filter.limit ?? 200)
377
+ return db.prepare(`SELECT id, ontology_id AS ontologyId, target_kind AS targetKind, target_key AS targetKey,
378
+ level, source_type AS sourceType, source_ref AS sourceRef, source_ref_hash AS sourceRefHash,
379
+ detail_json AS detailJson, created_by AS createdBy, created_at AS createdAt
380
+ FROM ontology_evidence WHERE ${where.join(' AND ')} ORDER BY created_at DESC LIMIT ?`)
381
+ .all(...params) as unknown as EvidenceRow[]
382
+ },
383
+
384
+ // ===== 发布日志 =====
385
+ appendPublishLog(row: PublishLogRow): void {
386
+ db.prepare(`INSERT INTO ontology_publish_log
387
+ (id, ontology_id, version, action, actor, actor_kind, solo_operator, approval_id, detail_json, created_at)
388
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
389
+ .run(row.id, row.ontologyId, row.version, row.action, row.actor, row.actorKind,
390
+ row.soloOperator, row.approvalId, row.detailJson, row.createdAt)
391
+ },
392
+
393
+ listPublishLog(ontologyId: string, limit = 100): PublishLogRow[] {
394
+ return db.prepare(`SELECT id, ontology_id AS ontologyId, version, action, actor, actor_kind AS actorKind,
395
+ solo_operator AS soloOperator, approval_id AS approvalId, detail_json AS detailJson, created_at AS createdAt
396
+ FROM ontology_publish_log WHERE ontology_id = ? ORDER BY created_at DESC LIMIT ?`)
397
+ .all(ontologyId, limit) as unknown as PublishLogRow[]
398
+ },
399
+
400
+ // ===== 规则溯源 =====
401
+ listTraces(ontologyId: string, version?: number, limit = 500): OntologyRuleTrace[] {
402
+ const where = ['ontology_id = ?']
403
+ const params: Array<string | number> = [ontologyId]
404
+ if (version !== undefined) {
405
+ where.push('version = ?')
406
+ params.push(version)
407
+ }
408
+ params.push(limit)
409
+ const rows = db.prepare(`SELECT id, ontology_id AS ontologyId, version, rule_pack_hash AS rulePackHash,
410
+ rule_id AS ruleId, rule_revision AS ruleRevision, rule_kind AS ruleKind, evidence_level AS evidenceLevel,
411
+ constraint_level AS constraintLevel, decision, decision_code AS decisionCode, message,
412
+ bindings_json AS bindingsJson, artifacts_json AS artifactsJson, scope_json AS scopeJson,
413
+ row_hash AS rowHash, created_at AS createdAt
414
+ FROM ontology_rule_traces WHERE ${where.join(' AND ')} ORDER BY rule_id LIMIT ?`)
415
+ .all(...params) as Array<Record<string, string | number>>
416
+ return rows.map(r => ({
417
+ id: String(r.id), ontologyId: String(r.ontologyId), version: Number(r.version),
418
+ rulePackHash: String(r.rulePackHash), ruleId: String(r.ruleId), ruleKey: String(r.ruleId),
419
+ ruleRevision: String(r.ruleRevision), ruleKind: String(r.ruleKind) as OntologyRuleTrace['ruleKind'],
420
+ evidenceLevel: String(r.evidenceLevel ?? '') as OntologyRuleTrace['evidenceLevel'],
421
+ constraintLevel: String(r.constraintLevel) as OntologyRuleTrace['constraintLevel'],
422
+ decision: String(r.decision) as OntologyRuleTrace['decision'],
423
+ decisionCode: String(r.decisionCode), message: String(r.message),
424
+ bindings: JSON.parse(String(r.bindingsJson || '[]')) as OntologyRuleTrace['bindings'],
425
+ artifacts: JSON.parse(String(r.artifactsJson || '[]')) as OntologyRuleTrace['artifacts'],
426
+ scope: JSON.parse(String(r.scopeJson || '{}')) as OntologyRuleTrace['scope'],
427
+ rowHash: String(r.rowHash), createdAt: String(r.createdAt),
428
+ }))
429
+ },
430
+ }
431
+ return repo
432
+ }
433
+
434
+ let cached: ReturnType<typeof createOntologyRepo> | null = null
435
+
436
+ /** 进程级仓储(单连接:workshop 只有一条主连接) */
437
+ export function getOntologyRepo(): ReturnType<typeof createOntologyRepo> {
438
+ if (!cached) cached = createOntologyRepo(getAmlRuntime().db)
439
+ return cached
440
+ }
441
+
442
+ /** 测试/重连后重置(单测在 fresh home 打开新库时调用) */
443
+ export function resetOntologyRepo(): void {
444
+ cached = null
445
+ }
446
+
447
+ export function parseDraftRow(row: DraftRow): OntologyDraftDoc {
448
+ return JSON.parse(row.draftJson) as OntologyDraftDoc
449
+ }
@@ -0,0 +1,226 @@
1
+ /**
2
+ * 语义绑定服务 —— 本体实体 ↔ 现有平台对象(daq_node / dcw_node / recipe_param)。
3
+ *
4
+ * 铁律:本体不复制系统对象。绑定只登记「语义 → 真实 id」的映射,存在性、归属、
5
+ * 单位、读写能力每次编辑与发布都**实时**回查活体对象(与 tool-verify 同口径)。
6
+ *
7
+ * 单位:换算唯一边界是 shared/units.ts;量纲相容性由 shared/dimensions 判定。
8
+ * 同量纲不同字面单位(degc↔k)必须显式给 scale/offset,否则 422 UNIT_TRANSFORM_REQUIRED。
9
+ */
10
+ import { AppError } from '../../../utils/errors'
11
+ import { getDaqNodeRepo } from '../daq/daq-node.repo'
12
+ import { getDcwController } from '../dcw/dcw-controller'
13
+ import type { BindingDraft, OntologyDraftDoc, OntologyEntity } from './contracts'
14
+ import { unitsCompatible } from './contracts'
15
+ import { dimensionOf, normalizeUnit, unitRelation } from '@/shared/dimensions'
16
+ import type { BindingRow } from './repo'
17
+
18
+ export interface ResolvedTarget {
19
+ platformKind: BindingDraft['platformKind']
20
+ platformId: string
21
+ targetSub: string
22
+ name: string
23
+ unit: string
24
+ min: number | null
25
+ max: number | null
26
+ stepLimit: number | null
27
+ writable: boolean
28
+ lineId: string
29
+ enabled: boolean
30
+ }
31
+
32
+ function num(value: unknown): number | null {
33
+ return typeof value === 'number' && Number.isFinite(value) ? value : null
34
+ }
35
+
36
+ /** 解析绑定目标(不存在返回 null;不抛错,便于批量报告) */
37
+ export function resolveBindingTarget(binding: Pick<BindingDraft, 'platformKind' | 'platformId' | 'targetSub'>): ResolvedTarget | null {
38
+ if (binding.platformKind === 'daq_node') {
39
+ const node = getDaqNodeRepo().byId(binding.platformId)
40
+ if (!node) return null
41
+ return {
42
+ platformKind: 'daq_node', platformId: node.id, targetSub: '',
43
+ name: node.name, unit: node.unit ?? '', min: num(node.min), max: num(node.max), stepLimit: null,
44
+ writable: false, lineId: node.lineId ?? '', enabled: node.enabled !== false,
45
+ }
46
+ }
47
+ if (binding.platformKind === 'dcw_node') {
48
+ const node = getDcwController().byId(binding.platformId)
49
+ if (!node) return null
50
+ return {
51
+ platformKind: 'dcw_node', platformId: node.id, targetSub: '',
52
+ name: node.name, unit: node.unit ?? '', min: num(node.min), max: num(node.max), stepLimit: num(node.stepLimit),
53
+ writable: true, lineId: node.lineId ?? '', enabled: node.enabled !== false,
54
+ }
55
+ }
56
+ if (binding.platformKind === 'recipe_param') {
57
+ const recipe = getDcwController().listRecipes().find(r => r.id === binding.platformId)
58
+ if (!recipe) return null
59
+ const key = binding.targetSub || ''
60
+ const param = recipe.params.find(p => p.nodeId === key)
61
+ if (!param) return null
62
+ const node = getDcwController().byId(param.nodeId)
63
+ return {
64
+ platformKind: 'recipe_param', platformId: recipe.id, targetSub: param.nodeId,
65
+ name: `${recipe.name}/${param.nodeId}`, unit: node?.unit ?? '',
66
+ min: num(param.min ?? node?.min), max: num(param.max ?? node?.max), stepLimit: num(param.stepLimit ?? node?.stepLimit),
67
+ writable: true, lineId: recipe.lineId ?? '', enabled: true,
68
+ }
69
+ }
70
+ // device / spec_variable / scene_variable / condition:无活体目录面,只做形状校验
71
+ return null
72
+ }
73
+
74
+ /** 单条绑定的形状校验(纯函数:目标已解析;可单测,不查库) */
75
+ export function assertBindingShape(
76
+ entity: OntologyEntity,
77
+ binding: BindingDraft,
78
+ target: ResolvedTarget,
79
+ opts: { lineId?: string } = {},
80
+ ): ResolvedTarget {
81
+ if (!target.enabled) {
82
+ throw new AppError(422, 'TARGET_DISABLED', `绑定 ${binding.id} 的目标「${target.name}」已停用`)
83
+ }
84
+ // 产线归属:文档有授权锚时绑定不得跨线
85
+ if (opts.lineId && target.lineId && opts.lineId !== target.lineId) {
86
+ throw new AppError(422, 'ONTOLOGY_SCOPE_MISMATCH',
87
+ `绑定 ${binding.id} 的目标「${target.name}」属于产线 ${target.lineId},与本体授权锚 ${opts.lineId} 不一致`)
88
+ }
89
+ // 读写能力
90
+ if ((binding.direction === 'write' || binding.direction === 'read_write') && !target.writable) {
91
+ throw new AppError(422, 'ACCESS_MODE_CONFLICT',
92
+ `绑定 ${binding.id} 声明 ${binding.direction},但目标 ${binding.platformKind}:${binding.platformId} 是只读通道;写入应绑定 dcw_node 或 recipe_param`)
93
+ }
94
+ // 数据类型(实体 attrs.dataType 非数值时不得绑定数值通道)
95
+ const declaredType = entity.attrs.dataType
96
+ if (typeof declaredType === 'string' && declaredType !== 'number') {
97
+ throw new AppError(422, 'TYPE_MISMATCH',
98
+ `实体「${entity.key}」声明 dataType=${declaredType},而目标「${target.name}」是数值通道;请改正实体类型`)
99
+ }
100
+ // 单位:声明单位 vs 目标单位
101
+ const declared = binding.unitDeclared || entity.unit || ''
102
+ if (declared && target.unit) {
103
+ const relation = unitRelation(declared, target.unit)
104
+ if (relation.kind === 'incompatible') {
105
+ throw new AppError(422, 'UNIT_MISMATCH',
106
+ `绑定 ${binding.id} 的声明单位「${declared}」(${relation.from})与目标单位「${target.unit}」(${relation.to})量纲不相容`)
107
+ }
108
+ if (relation.kind === 'convertible') {
109
+ const explicit = Number.isFinite(binding.scale) && binding.scale !== 0
110
+ && (binding.scale !== 1 || binding.offset !== 0)
111
+ if (!explicit) {
112
+ throw new AppError(422, 'UNIT_TRANSFORM_REQUIRED',
113
+ `绑定 ${binding.id} 的单位「${declared}」与目标单位「${target.unit}」同量纲但字面不同(${normalizeUnit(declared)}≠${normalizeUnit(target.unit)});必须显式给出 scale/offset,禁止按 1/0 兜底`)
114
+ }
115
+ }
116
+ }
117
+ if (!Number.isFinite(binding.scale) || binding.scale === 0) {
118
+ throw new AppError(422, 'UNIT_CONTRACT_INVALID', `绑定 ${binding.id} 的 scale 必须为非零有限数`)
119
+ }
120
+ return target
121
+ }
122
+
123
+ /** 单条绑定的活体校验(throw AppError:422 形状/单位/能力) */
124
+ export function assertBindingLive(entity: OntologyEntity, binding: BindingDraft, opts: { lineId?: string } = {}): ResolvedTarget {
125
+ const target = resolveBindingTarget(binding)
126
+ if (!target) {
127
+ throw new AppError(422, 'TARGET_NOT_FOUND',
128
+ `绑定 ${binding.id} 的目标 ${binding.platformKind}:${binding.platformId}${binding.targetSub ? `#${binding.targetSub}` : ''} 不存在;请先创建该节点/配方参数`)
129
+ }
130
+ return assertBindingShape(entity, binding, target, opts)
131
+ }
132
+
133
+ export interface BindingValidationReport {
134
+ ok: boolean
135
+ failures: Array<{ bindingId: string, code: string, message: string }>
136
+ resolved: ResolvedTarget[]
137
+ }
138
+
139
+ /**
140
+ * 批量活体校验(草稿期每次编辑 + 发布前复核):
141
+ * - 逐条存在性/单位/能力;
142
+ * - 同一物理目标被两个实体声明为**写** → 409 BINDING_TARGET_OWNED(一个量只有一个写语义);
143
+ * - 同一实体同目标的读写方向冲突 → 422。
144
+ */
145
+ export function validateDraftBindings(
146
+ doc: OntologyDraftDoc,
147
+ opts: { lineId?: string, resolver?: (binding: BindingDraft) => ResolvedTarget | null } = {},
148
+ ): BindingValidationReport {
149
+ const entities = new Map(doc.entities.map(e => [e.key, e]))
150
+ const failures: BindingValidationReport['failures'] = []
151
+ const resolved: ResolvedTarget[] = []
152
+ const writeOwners = new Map<string, string>()
153
+ const resolver = opts.resolver ?? resolveBindingTarget
154
+
155
+ for (const binding of doc.bindings) {
156
+ const entity = entities.get(binding.entityKey)
157
+ if (!entity) {
158
+ failures.push({ bindingId: binding.id, code: 'ONTOLOGY_UNKNOWN_ENTITY', message: `绑定 ${binding.id} 的实体「${binding.entityKey}」不存在` })
159
+ continue
160
+ }
161
+ try {
162
+ const target = resolver(binding)
163
+ if (!target) {
164
+ throw new AppError(422, 'TARGET_NOT_FOUND',
165
+ `绑定 ${binding.id} 的目标 ${binding.platformKind}:${binding.platformId}${binding.targetSub ? `#${binding.targetSub}` : ''} 不存在;请先创建该节点/配方参数`)
166
+ }
167
+ assertBindingShape(entity, binding, target, opts)
168
+ resolved.push(target)
169
+ if (binding.direction === 'write' || binding.direction === 'read_write') {
170
+ const key = `${binding.platformKind}:${binding.platformId}${binding.targetSub ? `#${binding.targetSub}` : ''}`
171
+ const owner = writeOwners.get(key)
172
+ if (owner && owner !== binding.entityKey) {
173
+ failures.push({
174
+ bindingId: binding.id, code: 'BINDING_TARGET_OWNED',
175
+ message: `目标 ${key} 已被实体「${owner}」声明为写语义,不能再由「${binding.entityKey}」写入(一个物理量只能有一个写语义)`,
176
+ })
177
+ }
178
+ else { writeOwners.set(key, binding.entityKey) }
179
+ }
180
+ }
181
+ catch (err) {
182
+ const e = err as { code?: string, message?: string }
183
+ failures.push({ bindingId: binding.id, code: e.code ?? 'ONTOLOGY_INVALID', message: e.message ?? String(err) })
184
+ }
185
+ }
186
+ return { ok: failures.length === 0, failures, resolved }
187
+ }
188
+
189
+ /** 发布前/运行时的漂移检测:目标被删/停用/单位变更 → drift */
190
+ export interface BindingDriftReport {
191
+ ok: boolean
192
+ drifted: Array<{ bindingId: string, reason: string }>
193
+ }
194
+
195
+ export function detectBindingDrift(bindings: BindingRow[]): BindingDriftReport {
196
+ const drifted: BindingDriftReport['drifted'] = []
197
+ for (const row of bindings) {
198
+ const target = resolveBindingTarget({ platformKind: row.platformKind as BindingDraft['platformKind'], platformId: row.platformId, targetSub: row.targetSub })
199
+ if (!target) {
200
+ drifted.push({ bindingId: row.id, reason: '目标不存在(节点/配方参数已删除)' })
201
+ continue
202
+ }
203
+ if (!target.enabled) {
204
+ drifted.push({ bindingId: row.id, reason: '目标已停用' })
205
+ continue
206
+ }
207
+ if (row.unitTarget && target.unit && normalizeUnit(row.unitTarget) !== normalizeUnit(target.unit)) {
208
+ drifted.push({ bindingId: row.id, reason: `目标单位已变更(${row.unitTarget} → ${target.unit})` })
209
+ continue
210
+ }
211
+ if (row.unitDeclared && target.unit && !unitsCompatible(row.unitDeclared, target.unit)) {
212
+ drifted.push({ bindingId: row.id, reason: `声明单位「${row.unitDeclared}」与目标单位「${target.unit}」量纲不相容` })
213
+ }
214
+ }
215
+ return { ok: drifted.length === 0, drifted }
216
+ }
217
+
218
+ /** 供 UI/工具展示:目标量纲注记 */
219
+ export function describeTarget(target: ResolvedTarget) {
220
+ return {
221
+ ...target,
222
+ dimension: dimensionOf(target.unit),
223
+ }
224
+ }
225
+
226
+ export { dimensionOf }