agentworkshop 0.7.9 → 0.7.12

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 (534) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{BUPj10t4.js → 6vYobj4F.js} +1 -1
  3. package/.output/public/_nuxt/{BCJFMBQ6.js → B-xskWta.js} +1 -1
  4. package/.output/public/_nuxt/{BC8s1Guv.js → B3Psw_sL.js} +1 -1
  5. package/.output/public/_nuxt/B53Mp7lD.js +1 -0
  6. package/.output/public/_nuxt/{BDASpD_i.js → BBwMH_hG.js} +1 -1
  7. package/.output/public/_nuxt/BNXfwXpE.js +1 -0
  8. package/.output/public/_nuxt/BbZAzXjZ2.js +1 -0
  9. package/.output/public/_nuxt/{CFn4vHwD.js → Bc3PiGGr.js} +1 -1
  10. package/.output/public/_nuxt/BcrN7QEl2.js +1 -0
  11. package/.output/public/_nuxt/BgOhoDTI.js +1 -0
  12. package/.output/public/_nuxt/Bmpvki7M.js +1 -0
  13. package/.output/public/_nuxt/BxPPAkGA.js +3 -0
  14. package/.output/public/_nuxt/{u7KWCGSb.js → BxtpDtzC.js} +1 -1
  15. package/.output/public/_nuxt/{DxrgFxIr2.js → C4OAdbVK2.js} +1 -1
  16. package/.output/public/_nuxt/C6m-kenn.js +1 -0
  17. package/.output/public/_nuxt/CcwJ2mrD2.js +1 -0
  18. package/.output/public/_nuxt/Cj6139IM.js +1 -0
  19. package/.output/public/_nuxt/{6PZPfFcO.js → Cor9siSf.js} +1 -1
  20. package/.output/public/_nuxt/CvYfzHYz.js +1 -0
  21. package/.output/public/_nuxt/D2JyEL28.js +14 -0
  22. package/.output/public/_nuxt/{DDdEnkdw.js → D8xY-Yjc.js} +2 -2
  23. package/.output/public/_nuxt/{Ct68Z0232.js → DA4lxCWC2.js} +1 -1
  24. package/.output/public/_nuxt/{MyA0Oeqd.js → DNxVTfhe.js} +1 -1
  25. package/.output/public/_nuxt/DT-Wg8r1.js +1 -0
  26. package/.output/public/_nuxt/DTYBfjRY.js +1 -0
  27. package/.output/public/_nuxt/{DvgKXPgu2.js → DWcEk1ur2.js} +1 -1
  28. package/.output/public/_nuxt/DaE5saZg.js +1 -0
  29. package/.output/public/_nuxt/Dhqra7NB.js +1 -0
  30. package/.output/public/_nuxt/DlRO_q5L.js +1 -0
  31. package/.output/public/_nuxt/{D8EfUxO2.js → Ds8JbqGB.js} +1 -1
  32. package/.output/public/_nuxt/Dsdy4Ua-.js +1 -0
  33. package/.output/public/_nuxt/{DN5RuZ8k.js → DyisHHzD.js} +1 -1
  34. package/.output/public/_nuxt/{91DZTUMJ.js → E88a-JCG.js} +1 -1
  35. package/.output/public/_nuxt/ORt9oDIy2.js +1 -0
  36. package/.output/public/_nuxt/{By8BpbKH.js → QoCzfpo2.js} +1 -1
  37. package/.output/public/_nuxt/RzXYI9FM.js +23 -0
  38. package/.output/public/_nuxt/{BuktKVqK2.js → arUY5dyq2.js} +2 -2
  39. package/.output/public/_nuxt/bAFueD6a.js +1 -0
  40. package/.output/public/_nuxt/builds/latest.json +1 -1
  41. package/.output/public/_nuxt/builds/meta/54e22640-4fd0-4fee-9077-31d4d4bb7969.json +1 -0
  42. package/.output/public/_nuxt/dcw.rpqpOYQ8.css +1 -0
  43. package/.output/public/_nuxt/{default.BR3e5fPY.css → default.BbgdTDCk.css} +1 -1
  44. package/.output/public/_nuxt/{C9cU_Ujd.js → eHYnGew0.js} +1 -1
  45. package/.output/public/_nuxt/{DM4CNkXz.js → eUGyJdiT.js} +1 -1
  46. package/.output/public/_nuxt/{entry.5qf6EqfN.css → entry.Bv_GCmPP.css} +1 -1
  47. package/.output/public/_nuxt/hb_ceMJP.js +1 -0
  48. package/.output/public/_nuxt/{B1g8pJmr.js → kkEthL84.js} +1 -1
  49. package/.output/public/_nuxt/logs.BS1sb41K.css +1 -0
  50. package/.output/public/_nuxt/pages.BkE-AfIb.css +1 -0
  51. package/.output/public/_nuxt/permissions.DTRtZeTw.css +1 -0
  52. package/.output/public/_nuxt/plugins.BcSEwwGb.css +1 -0
  53. package/.output/public/_nuxt/settings.BqMF2nfj.css +1 -0
  54. package/.output/public/_nuxt/tokens.rW1xHxRW.css +1 -0
  55. package/.output/public/_nuxt/workshop.CbymC2LY.css +1 -0
  56. package/.output/public/_nuxt/zVkqCZ78.js +1 -0
  57. package/.output/server/chunks/_/LeftOutlined.mjs +1 -1
  58. package/.output/server/chunks/_/SearchOutlined.mjs +1 -1
  59. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  60. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  61. package/.output/server/chunks/_/nitro.mjs +1549 -1228
  62. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  63. package/.output/server/chunks/_/scene-layout.repo.mjs +1 -1
  64. package/.output/server/chunks/build/Col-biaNnEPf.mjs +1 -1
  65. package/.output/server/chunks/build/{OmpTerminalPanel-COphA1br.mjs → OmpTerminalPanel-Ban3yJZ4.mjs} +4 -5
  66. package/.output/server/chunks/build/OmpTerminalPanel-Ban3yJZ4.mjs.map +1 -0
  67. package/.output/server/chunks/build/{TownView-D8DSdO3H.mjs → TownView-CunmEMzS.mjs} +8 -9
  68. package/.output/server/chunks/build/{TownView-D8DSdO3H.mjs.map → TownView-CunmEMzS.mjs.map} +1 -1
  69. package/.output/server/chunks/build/{_id_-BV4FfiYd.mjs → _id_-CVnMdSeG.mjs} +7 -7
  70. package/.output/server/chunks/build/{_id_-BV4FfiYd.mjs.map → _id_-CVnMdSeG.mjs.map} +1 -1
  71. package/.output/server/chunks/build/{_id_-TP9hvnBM.mjs → _id_-D265Wh_k.mjs} +7 -7
  72. package/.output/server/chunks/build/{_id_-TP9hvnBM.mjs.map → _id_-D265Wh_k.mjs.map} +1 -1
  73. package/.output/server/chunks/build/{_wsId_-Mm9sQSz2.mjs → _wsId_-eNJmBp05.mjs} +17 -17
  74. package/.output/server/chunks/build/{_wsId_-Mm9sQSz2.mjs.map → _wsId_-eNJmBp05.mjs.map} +1 -1
  75. package/.output/server/chunks/build/{agents-To3a5xcZ.mjs → agents-B10wmFri.mjs} +9 -9
  76. package/.output/server/chunks/build/{agents-To3a5xcZ.mjs.map → agents-B10wmFri.mjs.map} +1 -1
  77. package/.output/server/chunks/build/alert-qJnjyRcP.mjs +1 -1
  78. package/.output/server/chunks/build/api-error-dul30BYQ.mjs +1 -1
  79. package/.output/server/chunks/build/button-DEcZFcqN.mjs +2 -2
  80. package/.output/server/chunks/build/{card-Dipvaykh.mjs → card-CCPQoKlh.mjs} +4 -4
  81. package/.output/server/chunks/build/{card-Dipvaykh.mjs.map → card-CCPQoKlh.mjs.map} +1 -1
  82. package/.output/server/chunks/build/{channel-templates-DRsP-qxl.mjs → channel-templates-CpWxVk5A.mjs} +7 -7
  83. package/.output/server/chunks/build/{channel-templates-DRsP-qxl.mjs.map → channel-templates-CpWxVk5A.mjs.map} +1 -1
  84. package/.output/server/chunks/build/{checkbox-dzcpU_Cd.mjs → checkbox-Dv1kjaUZ.mjs} +3 -3
  85. package/.output/server/chunks/build/{checkbox-dzcpU_Cd.mjs.map → checkbox-Dv1kjaUZ.mjs.map} +1 -1
  86. package/.output/server/chunks/build/client-only-D5BzSQc6.mjs +1 -1
  87. package/.output/server/chunks/build/{daq-_hCEaYLd.mjs → daq-DxaXk_8N.mjs} +9 -10
  88. package/.output/server/chunks/build/daq-DxaXk_8N.mjs.map +1 -0
  89. package/.output/server/chunks/build/{dcw-C7pJ4Y0p.mjs → dcw-B0dtiHFG.mjs} +47 -47
  90. package/.output/server/chunks/build/dcw-B0dtiHFG.mjs.map +1 -0
  91. package/.output/server/chunks/build/{default-Dnjs36e8.mjs → default-DdV642BY.mjs} +41 -13
  92. package/.output/server/chunks/build/{default-Dnjs36e8.mjs.map → default-DdV642BY.mjs.map} +1 -1
  93. package/.output/server/chunks/build/drawer-Cmh90erI.mjs +1 -1
  94. package/.output/server/chunks/build/dropdown-vhn1NPFs.mjs +2 -2
  95. package/.output/server/chunks/build/hasIn-vQ9LWt-J.mjs +554 -0
  96. package/.output/server/chunks/build/hasIn-vQ9LWt-J.mjs.map +1 -0
  97. package/.output/server/chunks/build/initDefaultProps-DIbWwP4R.mjs +1 -1
  98. package/.output/server/chunks/build/{input-sf_BT6o6.mjs → input-DxDqeyQW.mjs} +5 -553
  99. package/.output/server/chunks/build/input-DxDqeyQW.mjs.map +1 -0
  100. package/.output/server/chunks/build/{input-number-Bd55elNN.mjs → input-number-CZ3ZrCsy.mjs} +3 -3
  101. package/.output/server/chunks/build/{input-number-Bd55elNN.mjs.map → input-number-CZ3ZrCsy.mjs.map} +1 -1
  102. package/.output/server/chunks/build/{logs-C039TFW1.mjs → logs-Crf6f1IC.mjs} +39 -40
  103. package/.output/server/chunks/build/logs-Crf6f1IC.mjs.map +1 -0
  104. package/.output/server/chunks/build/menu-WCrlpYVh.mjs +2 -2
  105. package/.output/server/chunks/build/modal-yvUquPj5.mjs +2 -2
  106. package/.output/server/chunks/build/{monitor-MIOvsyLa.mjs → monitor-miqq9xHB.mjs} +11 -11
  107. package/.output/server/chunks/build/{monitor-MIOvsyLa.mjs.map → monitor-miqq9xHB.mjs.map} +1 -1
  108. package/.output/server/chunks/build/{pages-C_VSGSGo.mjs → pages-BmRUbGUi.mjs} +32 -22
  109. package/.output/server/chunks/build/pages-BmRUbGUi.mjs.map +1 -0
  110. package/.output/server/chunks/build/permissions-CxEgXic0.mjs +534 -0
  111. package/.output/server/chunks/build/permissions-CxEgXic0.mjs.map +1 -0
  112. package/.output/server/chunks/build/{plugins-4FMWkN8d.mjs → plugins-wLIKHcIE.mjs} +19 -20
  113. package/.output/server/chunks/build/{plugins-4FMWkN8d.mjs.map → plugins-wLIKHcIE.mjs.map} +1 -1
  114. package/.output/server/chunks/build/popconfirm-CRaHcz5O.mjs +2 -2
  115. package/.output/server/chunks/build/responsiveObserve-CS0UB6wQ.mjs +1 -1
  116. package/.output/server/chunks/build/{segmented-DPe9ZzLO.mjs → segmented-ChmQZwz6.mjs} +5 -4
  117. package/.output/server/chunks/build/{segmented-DPe9ZzLO.mjs.map → segmented-ChmQZwz6.mjs.map} +1 -1
  118. package/.output/server/chunks/build/select-D-CeE5vY.mjs +1 -1
  119. package/.output/server/chunks/build/{settings-DA8IkGLo.mjs → settings-BPBll_7K.mjs} +28 -26
  120. package/.output/server/chunks/build/settings-BPBll_7K.mjs.map +1 -0
  121. package/.output/server/chunks/build/space-CCBYAkXt.mjs +2 -2
  122. package/.output/server/chunks/build/spin-HVY81X_L.mjs +1 -1
  123. package/.output/server/chunks/build/switch-CelRXpcy.mjs +2 -2
  124. package/.output/server/chunks/build/{table-Cswq-l2r.mjs → table-BtksyDlQ.mjs} +5 -5
  125. package/.output/server/chunks/build/{table-Cswq-l2r.mjs.map → table-BtksyDlQ.mjs.map} +1 -1
  126. package/.output/server/chunks/build/{tabs-BM3tAh_J.mjs → tabs-DQv-_-R6.mjs} +3 -3
  127. package/.output/server/chunks/build/{tabs-BM3tAh_J.mjs.map → tabs-DQv-_-R6.mjs.map} +1 -1
  128. package/.output/server/chunks/build/{tag-NO9jEqKy.mjs → tag-A0tZ2Ouq.mjs} +4 -4
  129. package/.output/server/chunks/build/{tag-NO9jEqKy.mjs.map → tag-A0tZ2Ouq.mjs.map} +1 -1
  130. package/.output/server/chunks/build/{teams-DA1lkf1n.mjs → teams-CNflUtPh.mjs} +7 -7
  131. package/.output/server/chunks/build/{teams-DA1lkf1n.mjs.map → teams-CNflUtPh.mjs.map} +1 -1
  132. package/.output/server/chunks/build/{tokens-DKMvvk3e.mjs → tokens-BKLzcdMg.mjs} +53 -84
  133. package/.output/server/chunks/build/tokens-BKLzcdMg.mjs.map +1 -0
  134. package/.output/server/chunks/build/town-BUqRobze.mjs +1 -1
  135. package/.output/server/chunks/build/{town-D0thZ7PK.mjs → town-BbaR-8io.mjs} +9 -10
  136. package/.output/server/chunks/build/town-BbaR-8io.mjs.map +1 -0
  137. package/.output/server/chunks/build/{useDaqStream-BVTRw8_H.mjs → useDaqStream-BkmyQT06.mjs} +34 -23
  138. package/.output/server/chunks/build/useDaqStream-BkmyQT06.mjs.map +1 -0
  139. package/.output/server/chunks/build/{useDcwStream-DNsivqI_.mjs → useDcwStream-DWVoU96J.mjs} +60 -46
  140. package/.output/server/chunks/build/useDcwStream-DWVoU96J.mjs.map +1 -0
  141. package/.output/server/chunks/build/{useDeviceTwins-WeIom7A6.mjs → useDeviceTwins-34WGk9aN.mjs} +2 -2
  142. package/.output/server/chunks/build/{useDeviceTwins-WeIom7A6.mjs.map → useDeviceTwins-34WGk9aN.mjs.map} +1 -1
  143. package/.output/server/chunks/build/useLocalTime-9a4B-aHv.mjs +1 -1
  144. package/.output/server/chunks/build/{useOpsLog-DcKnPO43.mjs → useOpsLog-C9zTzYof.mjs} +27 -15
  145. package/.output/server/chunks/build/useOpsLog-C9zTzYof.mjs.map +1 -0
  146. package/.output/server/chunks/build/useSiteConfig-DJe_KMVr.mjs +1 -1
  147. package/.output/server/chunks/build/useWorkshopApi-D2gq06N2.mjs +1 -1
  148. package/.output/server/chunks/build/{useWorkshopWs-B3j5wIAK.mjs → useWorkshopWs-CprkZEdq.mjs} +2 -3
  149. package/.output/server/chunks/build/useWorkshopWs-CprkZEdq.mjs.map +1 -0
  150. package/.output/server/chunks/build/{users-CmVvb1oq.mjs → users-D6RNylrW.mjs} +10 -10
  151. package/.output/server/chunks/build/{users-CmVvb1oq.mjs.map → users-D6RNylrW.mjs.map} +1 -1
  152. package/.output/server/chunks/build/{workshop-BhWnJMWs.mjs → workshop-CTcYDq2i.mjs} +29 -24
  153. package/.output/server/chunks/build/{workshop-BhWnJMWs.mjs.map → workshop-CTcYDq2i.mjs.map} +1 -1
  154. package/.output/server/chunks/build/{workspaces-IfORCDJE.mjs → workspaces-BuydxM-3.mjs} +2 -3
  155. package/.output/server/chunks/build/workspaces-BuydxM-3.mjs.map +1 -0
  156. package/.output/server/chunks/routes/api/health.get.mjs +1 -1
  157. package/.output/server/chunks/routes/api/index.get.mjs +1 -1
  158. package/.output/server/chunks/routes/api/index.post.mjs +1 -1
  159. package/.output/server/chunks/routes/api/mcp/workshop.mjs +1 -1
  160. package/.output/server/chunks/routes/api/metrics.mjs +1 -1
  161. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +1 -1
  162. package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs +1 -1
  163. package/.output/server/chunks/routes/api/plugins/manifest.get.mjs +1 -1
  164. package/.output/server/chunks/routes/api/system/config.get.mjs +1 -1
  165. package/.output/server/chunks/routes/api/system/index.get.mjs +1 -1
  166. package/.output/server/chunks/routes/api/system/index.patch.mjs +1 -1
  167. package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs +1 -1
  168. package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs +1 -1
  169. package/.output/server/chunks/routes/api/system/monitor.get.mjs +1 -1
  170. package/.output/server/chunks/routes/api/system/settings/events.get.mjs +1 -1
  171. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs +1 -1
  172. package/.output/server/chunks/routes/api/users/_id_.delete.mjs +1 -1
  173. package/.output/server/chunks/routes/api/users/_id_.get.mjs +1 -1
  174. package/.output/server/chunks/routes/api/users/_id_.put.mjs +1 -1
  175. package/.output/server/chunks/routes/api/users/index.get.mjs +1 -1
  176. package/.output/server/chunks/routes/api/users/index.post.mjs +1 -1
  177. package/.output/server/chunks/routes/api/users/login.post.mjs +1 -1
  178. package/.output/server/chunks/routes/api/users/logout.post.mjs +1 -1
  179. package/.output/server/chunks/routes/api/users/me.get.mjs +1 -1
  180. package/.output/server/chunks/routes/api/users/register.post.mjs +1 -1
  181. package/.output/server/chunks/routes/api/users/setup-status.get.mjs +1 -1
  182. package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs +1 -1
  183. package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs +1 -1
  184. package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs +1 -1
  185. package/.output/server/chunks/routes/api/workshop/_...path_.mjs +1 -1
  186. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs +1 -1
  187. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs +1 -1
  188. package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs +1 -1
  189. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +1 -1
  190. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs +1 -1
  191. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +1 -1
  192. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +1 -1
  193. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +19 -8
  194. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs.map +1 -1
  195. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +1 -1
  196. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +2 -2
  197. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs +2 -2
  198. package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs +1 -1
  199. package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs +1 -1
  200. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +1 -1
  201. package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs +1 -1
  202. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +1 -1
  203. package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs +1 -1
  204. package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs +1 -1
  205. package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs +1 -1
  206. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +2 -2
  207. package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs +1 -1
  208. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +2 -2
  209. package/.output/server/chunks/routes/api/workshop/audit.get.mjs +1 -1
  210. package/.output/server/chunks/routes/api/workshop/caller.mjs +1 -1
  211. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +3 -3
  212. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs +1 -1
  213. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs +1 -1
  214. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +1 -1
  215. package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs +1 -1
  216. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +2 -2
  217. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs +1 -1
  218. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs +1 -1
  219. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs +1 -1
  220. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs +1 -1
  221. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs +1 -1
  222. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs +1 -1
  223. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs +1 -1
  224. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs +1 -1
  225. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs +1 -1
  226. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +1 -1
  227. package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs +1 -1
  228. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +1 -1
  229. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +2 -2
  230. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs +1 -1
  231. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs +1 -1
  232. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.mjs +1 -1
  233. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
  234. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +1 -1
  235. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
  236. package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs +1 -1
  237. package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs +1 -1
  238. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +2 -2
  239. package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs +1 -1
  240. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +2 -2
  241. package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs +1 -1
  242. package/.output/server/chunks/routes/api/workshop/channels.get.mjs +1 -1
  243. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +3 -3
  244. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +7 -6
  245. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs.map +1 -1
  246. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +5 -4
  247. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs.map +1 -1
  248. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +5 -4
  249. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs.map +1 -1
  250. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +5 -4
  251. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs.map +1 -1
  252. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +2 -2
  253. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +2 -2
  254. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +5 -4
  255. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs.map +1 -1
  256. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +5 -2
  257. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs.map +1 -1
  258. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +2 -2
  259. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +3 -2
  260. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs.map +1 -1
  261. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +2 -2
  262. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +2 -2
  263. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +2 -2
  264. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +2 -2
  265. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +2 -2
  266. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +2 -2
  267. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +7 -6
  268. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs.map +1 -1
  269. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +2 -2
  270. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +2 -2
  271. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +5 -4
  272. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs.map +1 -1
  273. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +4 -3
  274. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs.map +1 -1
  275. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +2 -2
  276. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +2 -2
  277. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +2 -2
  278. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +2 -2
  279. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +4 -4
  280. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs.map +1 -1
  281. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +8 -4
  282. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs.map +1 -1
  283. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +4 -4
  284. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs.map +1 -1
  285. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +2 -2
  286. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +2 -2
  287. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +2 -2
  288. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +2 -2
  289. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +4 -4
  290. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs.map +1 -1
  291. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +2 -2
  292. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +7 -3
  293. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs.map +1 -1
  294. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +3 -2
  295. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs.map +1 -1
  296. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +3 -2
  297. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs.map +1 -1
  298. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +2 -2
  299. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs +2 -2
  300. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +2 -2
  301. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +2 -2
  302. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +2 -2
  303. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +2 -2
  304. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +2 -2
  305. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +2 -2
  306. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +2 -2
  307. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +2 -2
  308. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +2 -2
  309. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +2 -2
  310. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.patch.mjs +2 -2
  311. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +2 -2
  312. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +5 -3
  313. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs.map +1 -1
  314. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +2 -2
  315. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +2 -2
  316. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +2 -2
  317. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +2 -2
  318. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +1 -1
  319. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +1 -1
  320. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +2 -2
  321. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +2 -2
  322. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +1 -1
  323. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +2 -2
  324. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +2 -2
  325. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +2 -2
  326. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +2 -2
  327. package/.output/server/chunks/routes/api/workshop/index.get.mjs +1 -1
  328. package/.output/server/chunks/routes/api/workshop/index.post.mjs +1 -1
  329. package/.output/server/chunks/routes/api/workshop/index.put.mjs +41 -0
  330. package/.output/server/chunks/routes/api/workshop/index.put.mjs.map +1 -0
  331. package/.output/server/chunks/routes/api/workshop/index10.get.mjs +4 -3
  332. package/.output/server/chunks/routes/api/workshop/index10.get.mjs.map +1 -1
  333. package/.output/server/chunks/routes/api/workshop/index11.get.mjs +27 -0
  334. package/.output/server/chunks/routes/api/workshop/index11.get.mjs.map +1 -0
  335. package/.output/server/chunks/routes/api/workshop/index2.get.mjs +1 -1
  336. package/.output/server/chunks/routes/api/workshop/index2.post.mjs +1 -1
  337. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +1 -1
  338. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +4 -4
  339. package/.output/server/chunks/routes/api/workshop/index3.post.mjs.map +1 -1
  340. package/.output/server/chunks/routes/api/workshop/index4.get.mjs +5 -4
  341. package/.output/server/chunks/routes/api/workshop/index4.get.mjs.map +1 -1
  342. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +2 -2
  343. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +18 -11
  344. package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
  345. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +2 -2
  346. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +1 -1
  347. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +2 -2
  348. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +1 -1
  349. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +1 -1
  350. package/.output/server/chunks/routes/api/workshop/index8.get.mjs +24 -12
  351. package/.output/server/chunks/routes/api/workshop/index8.get.mjs.map +1 -1
  352. package/.output/server/chunks/routes/api/workshop/index8.post.mjs +1 -1
  353. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +12 -7
  354. package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
  355. package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs +1 -1
  356. package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs +1 -1
  357. package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs +1 -1
  358. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +2 -2
  359. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +2 -2
  360. package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs +1 -1
  361. package/.output/server/chunks/routes/api/workshop/runtime.get.mjs +1 -1
  362. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +2 -2
  363. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +2 -2
  364. package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs +1 -1
  365. package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs +1 -1
  366. package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs +1 -1
  367. package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs +1 -1
  368. package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs +1 -1
  369. package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs +1 -1
  370. package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs +1 -1
  371. package/.output/server/chunks/routes/api/workshop/tasks.get.mjs +1 -1
  372. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +2 -2
  373. package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs +1 -1
  374. package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs +1 -1
  375. package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs +1 -1
  376. package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs +1 -1
  377. package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs +1 -1
  378. package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs +1 -1
  379. package/.output/server/chunks/routes/api/workshop/users/me.get.mjs +1 -1
  380. package/.output/server/chunks/routes/api/workshop/users/register.post.mjs +1 -1
  381. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +3 -3
  382. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs +1 -1
  383. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs +1 -1
  384. package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs +1 -1
  385. package/.output/server/chunks/routes/renderer.mjs +3 -3
  386. package/.output/server/chunks/virtual/entry.mjs +275 -33
  387. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  388. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  389. package/.output/server/index.mjs +1 -1
  390. package/.output/server/package.json +1 -1
  391. package/README-zh.md +15 -0
  392. package/README.md +20 -0
  393. package/app/assets/css/main.css +161 -0
  394. package/app/components/AppSidebar.vue +7 -1
  395. package/app/components/AwChart.vue +12 -2
  396. package/app/composables/useRouteMeta.ts +8 -1
  397. package/app/composables/workshop/apiClient.ts +103 -95
  398. package/app/composables/workshop/useDaqStream.ts +35 -21
  399. package/app/composables/workshop/useDcwStream.ts +22 -5
  400. package/app/composables/workshop/useOpsLog.ts +26 -13
  401. package/app/composables/workshop/useWorkshopWs.ts +11 -2
  402. package/app/pages/dcw/index.vue +1079 -1079
  403. package/app/pages/index.vue +7 -2
  404. package/app/pages/logs/index.vue +621 -621
  405. package/app/pages/permissions/index.vue +330 -0
  406. package/app/pages/plugins/index.vue +6 -3
  407. package/app/pages/settings.vue +4 -2
  408. package/app/pages/tokens.vue +9 -13
  409. package/app/pages/workshop/index.vue +3 -1
  410. package/app/plugins/http.ts +18 -2
  411. package/app/plugins/session-restore.client.ts +7 -2
  412. package/app/stores/workshop/user.ts +14 -1
  413. package/i18n/locales/en.ts +1944 -1906
  414. package/i18n/locales/zh-CN.ts +1943 -1905
  415. package/package.json +1 -1
  416. package/scripts/_dbg-acc-1-setup.mjs +57 -0
  417. package/scripts/_dbg-acc-2-diag.mjs +14 -0
  418. package/scripts/_dbg-acc-2-intervals.mjs +81 -0
  419. package/scripts/_dbg-acc-3-daq.mjs +48 -0
  420. package/scripts/_dbg-acc-4-team.mjs +92 -0
  421. package/scripts/_dbg-acc-5-visual.mjs +63 -0
  422. package/scripts/_dbg-acc-5b-ws-town.mjs +18 -0
  423. package/scripts/_dbg-acc-5c-town.mjs +12 -0
  424. package/scripts/_dbg-acc-6-i18n.mjs +19 -0
  425. package/scripts/_dbg-audit-neg-e2e.mjs +64 -0
  426. package/scripts/_dbg-final-features.mjs +155 -0
  427. package/scripts/_dbg-final-fixups.mjs +62 -0
  428. package/scripts/_dbg-final-visual.mjs +29 -0
  429. package/scripts/_dbg-kicker-check.mjs +11 -0
  430. package/scripts/_dbg-perms-e2e.mjs +102 -0
  431. package/scripts/_dbg-perms-visual.mjs +36 -0
  432. package/scripts/_dbg-plugins-e2e.mjs +1 -1
  433. package/scripts/_dbg-protocol-matrix.mjs +16 -0
  434. package/scripts/_dbg-swatch-check.mjs +10 -0
  435. package/scripts/_dbg-ui-shots.mjs +28 -0
  436. package/sdk/api.mjs +117 -101
  437. package/sdk/context.mjs +240 -219
  438. package/sdk/hooks.mjs +105 -103
  439. package/sdk/index.d.mts +142 -135
  440. package/sdk/lifecycle.mjs +26 -25
  441. package/server/api/workshop/agent-tools/bindings/index.post.ts +40 -20
  442. package/server/api/workshop/daq/[id]/bind.post.ts +5 -2
  443. package/server/api/workshop/daq/[id]/frames/content.get.ts +4 -1
  444. package/server/api/workshop/daq/[id]/frames.get.ts +4 -1
  445. package/server/api/workshop/daq/[id]/samples.get.ts +4 -1
  446. package/server/api/workshop/daq/[id].patch.ts +3 -0
  447. package/server/api/workshop/daq/alarms/[id]/ack.post.ts +20 -15
  448. package/server/api/workshop/daq/controller.post.ts +2 -0
  449. package/server/api/workshop/daq/index.get.ts +5 -3
  450. package/server/api/workshop/daq/index.post.ts +2 -2
  451. package/server/api/workshop/dcw/[id]/bind.post.ts +20 -17
  452. package/server/api/workshop/dcw/[id]/test.post.ts +18 -15
  453. package/server/api/workshop/dcw/[id]/write.post.ts +3 -0
  454. package/server/api/workshop/dcw/index.get.ts +22 -9
  455. package/server/api/workshop/dcw/line/query.get.ts +38 -31
  456. package/server/api/workshop/dcw/lines/[id]/start.post.ts +3 -0
  457. package/server/api/workshop/dcw/lines/[id]/stop.post.ts +3 -0
  458. package/server/api/workshop/dcw/lines/index.get.ts +8 -2
  459. package/server/api/workshop/dcw/lines/index.post.ts +2 -2
  460. package/server/api/workshop/dcw/products/index.post.ts +16 -16
  461. package/server/api/workshop/dcw/runs/[id]/data.get.ts +20 -15
  462. package/server/api/workshop/dcw/runs/index.get.ts +13 -11
  463. package/server/api/workshop/permissions/index.get.ts +30 -0
  464. package/server/api/workshop/permissions/index.put.ts +29 -0
  465. package/server/api/workshop/ws.ts +18 -6
  466. package/server/data/daqs.json +48 -48
  467. package/server/data/dcw-products.json +21 -0
  468. package/server/data/dcw-recipes.json +84 -0
  469. package/server/data/dcw-rollback.json +94 -6
  470. package/server/data/dcw-runs.json +81 -75
  471. package/server/data/dcw-writes.json +108 -0
  472. package/server/data/dcws.json +791 -528
  473. package/server/data/line-runs.json +8 -8
  474. package/server/plugins/backup.ts +119 -116
  475. package/server/repositories/user.repository.ts +86 -6
  476. package/server/services/user.service.ts +5 -3
  477. package/server/services/workshop/daq/bus/index.ts +5 -3
  478. package/server/services/workshop/daq/bus/inproc.adapter.ts +12 -3
  479. package/server/services/workshop/daq/bus/mqtt.adapter.ts +13 -0
  480. package/server/services/workshop/daq/bus/queue-port.ts +2 -0
  481. package/server/services/workshop/daq/daq-controller.ts +18 -1
  482. package/server/services/workshop/db/ops.repo.ts +6 -0
  483. package/server/services/workshop/dcw/dcw-controller.ts +10 -2
  484. package/server/services/workshop/permissions.ts +79 -0
  485. package/server/services/workshop/plugins/host.mjs +38 -1
  486. package/server/services/workshop/scene-events.ts +25 -1
  487. package/shared/config/single-instance.mjs +24 -0
  488. package/shared/daq-protocol.ts +2 -0
  489. package/.output/public/_nuxt/B0HpdCKS.js +0 -1
  490. package/.output/public/_nuxt/B1kA8LhC.js +0 -14
  491. package/.output/public/_nuxt/B9MUiDFl.js +0 -1
  492. package/.output/public/_nuxt/B9dLFSYI.js +0 -1
  493. package/.output/public/_nuxt/BaMkWl5i2.js +0 -1
  494. package/.output/public/_nuxt/BmHvC_OU.js +0 -1
  495. package/.output/public/_nuxt/CBciOiTQ.js +0 -1
  496. package/.output/public/_nuxt/CUMdhxg9.js +0 -1
  497. package/.output/public/_nuxt/CgvGu2IO.js +0 -1
  498. package/.output/public/_nuxt/CjDQPXfv.js +0 -1
  499. package/.output/public/_nuxt/CmHzfVc5.js +0 -3
  500. package/.output/public/_nuxt/Cn3J3NXR.js +0 -23
  501. package/.output/public/_nuxt/Cst47G4-.js +0 -1
  502. package/.output/public/_nuxt/D0Szyn_D.js +0 -1
  503. package/.output/public/_nuxt/D3VJ3lex.js +0 -1
  504. package/.output/public/_nuxt/D8wyHvcz2.js +0 -1
  505. package/.output/public/_nuxt/Dqj2h40U.js +0 -1
  506. package/.output/public/_nuxt/OV6PBW2z.js +0 -1
  507. package/.output/public/_nuxt/builds/meta/92d6bd39-dbc5-46d5-90d8-8387f36715fa.json +0 -1
  508. package/.output/public/_nuxt/dcw.DcDjwvqv.css +0 -1
  509. package/.output/public/_nuxt/logs.BO-BSyjm.css +0 -1
  510. package/.output/public/_nuxt/pKv_VWR4.js +0 -1
  511. package/.output/public/_nuxt/pages.CytEOfUs.css +0 -1
  512. package/.output/public/_nuxt/plugins.Clsky_kl.css +0 -1
  513. package/.output/public/_nuxt/settings.DeRNNUcP.css +0 -1
  514. package/.output/public/_nuxt/tokens.BPLe9ioQ.css +0 -1
  515. package/.output/public/_nuxt/wirVyscc.js +0 -1
  516. package/.output/public/_nuxt/workshop.BIdoGfoC.css +0 -1
  517. package/.output/server/chunks/build/OmpTerminalPanel-COphA1br.mjs.map +0 -1
  518. package/.output/server/chunks/build/daq-_hCEaYLd.mjs.map +0 -1
  519. package/.output/server/chunks/build/dcw-C7pJ4Y0p.mjs.map +0 -1
  520. package/.output/server/chunks/build/input-sf_BT6o6.mjs.map +0 -1
  521. package/.output/server/chunks/build/logs-C039TFW1.mjs.map +0 -1
  522. package/.output/server/chunks/build/pages-C_VSGSGo.mjs.map +0 -1
  523. package/.output/server/chunks/build/settings-DA8IkGLo.mjs.map +0 -1
  524. package/.output/server/chunks/build/tokens-DKMvvk3e.mjs.map +0 -1
  525. package/.output/server/chunks/build/town-D0thZ7PK.mjs.map +0 -1
  526. package/.output/server/chunks/build/useDaqStream-BVTRw8_H.mjs.map +0 -1
  527. package/.output/server/chunks/build/useDcwStream-DNsivqI_.mjs.map +0 -1
  528. package/.output/server/chunks/build/useOpsLog-DcKnPO43.mjs.map +0 -1
  529. package/.output/server/chunks/build/useWorkshopWs-B3j5wIAK.mjs.map +0 -1
  530. package/.output/server/chunks/build/user-Dk-ytEUV.mjs +0 -140
  531. package/.output/server/chunks/build/user-Dk-ytEUV.mjs.map +0 -1
  532. package/.output/server/chunks/build/workspaces-IfORCDJE.mjs.map +0 -1
  533. /package/.output/public/_nuxt/{CNs_Ozdc2.js → CNs_Ozdc.js} +0 -0
  534. /package/.output/public/_nuxt/{Cno6kYiO2.js → Cno6kYiO.js} +0 -0
@@ -17,6 +17,7 @@ import 'node:buffer';
17
17
  import 'node:fs';
18
18
  import 'node:path';
19
19
  import 'node:url';
20
+ import 'node:fs/promises';
20
21
  import 'node:os';
21
22
  import 'js-yaml';
22
23
  import 'node:child_process';
@@ -24,7 +25,6 @@ import 'node:net';
24
25
  import 'node:util';
25
26
  import 'node:sqlite';
26
27
  import 'node:module';
27
- import 'node:fs/promises';
28
28
  import 'node:zlib';
29
29
 
30
30
  const kNodeInspect = /* @__PURE__ */ Symbol.for(
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentworkshop-prod",
3
- "version": "0.7.9",
3
+ "version": "0.7.12",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "dependencies": {
package/README-zh.md CHANGED
@@ -309,6 +309,21 @@ curl http://localhost:3000/api/workshop/channels \
309
309
  -H 'authorization: Bearer <token>'
310
310
  ```
311
311
 
312
+ ### 产线级权限
313
+
314
+ 工业数据按**产线**三态管控,由管理员在内置「权限管理」页(`/permissions`,仅 admin 侧栏可见)维护:
315
+
316
+ | 状态 | 数采节点 | 数控(写控)节点 | 可见性 |
317
+ |---|---|---|---|
318
+ | **无权**(普通用户默认) | 隐藏 | 隐藏 | 后端不返回该产线数据——产线运营/数采中心/数字孪生均不可见 |
319
+ | **仅查看** | 只读 | ✕ | 产线可见、实时值可看,但不可写/不可下发/不可绑定设备 |
320
+ | **可操控** | 读取 | 读取+写入 | 全量能力:设定值下发、参数下发、设备绑定 |
321
+
322
+ - `admin` / `editor` 为运营角色,不受授权约束(全量全权)。
323
+ - 普通用户**默认无权**——未授权前看不到任何产线数据。
324
+ - 强制点在数据面:列表接口按授权过滤,写控/下发接口返回人话 403,Agent↔节点绑定校验产线授权(数采需仅查看+,写控需可操控)。
325
+ - 插件经 `ctx.permissions`(`lineMode` / `visibleLineIds` / `listGrants` / `setGrants`)获得同一能力面,并有 `permissions:changed` 生命周期钩子;SDK REST 客户端提供 `client.permissions.overview()` / `client.permissions.set(...)`。
326
+
312
327
  ### 执行模式
313
328
 
314
329
  在任务描述中使用模式前缀(或在 composer UI 中选择):
package/README.md CHANGED
@@ -310,6 +310,26 @@ curl http://localhost:3000/api/workshop/channels \
310
310
  -H 'authorization: Bearer <token>'
311
311
  ```
312
312
 
313
+ ### Line-level permissions
314
+
315
+ Industrial data is gated **per production line** with three states, managed by an admin
316
+ in the built-in **Permissions** page (`/permissions`, admin-only in the sidebar):
317
+
318
+ | State | DAQ nodes | DCW (write) nodes | Visibility |
319
+ | --- | --- | --- | --- |
320
+ | **none** (default for regular users) | hidden | hidden | line data withheld server-side — invisible in Line Ops, DAQ center and the digital twin |
321
+ | **read-only** | read | ✕ | line visible, values stream, no writes / dispatch / device binding |
322
+ | **operate** | read | read + write | full access incl. setpoint writes, dispatch, binding |
323
+
324
+ - `admin` / `editor` roles are unrestricted (operations roles).
325
+ - Regular users **default to none** — they see no line data until granted.
326
+ - Enforcement lives in the data plane: list endpoints filter by grant, write/dispatch
327
+ endpoints return a human-readable 403, and Agent↔node bindings validate the line grant
328
+ (DAQ needs read-only+, DCW needs operate).
329
+ - Plugins get the same surface via `ctx.permissions` (`lineMode` / `visibleLineIds` /
330
+ `listGrants` / `setGrants`) plus a `permissions:changed` lifecycle hook; the SDK REST
331
+ client exposes `client.permissions.overview()` / `client.permissions.set(...)`.
332
+
313
333
  ### Execution modes
314
334
 
315
335
  Prefix the task description (or pick in the composer UI):
@@ -1255,3 +1255,164 @@ ul.task-list {
1255
1255
  animation-duration: 200ms !important;
1256
1256
  }
1257
1257
  }
1258
+
1259
+ /* ============================================================
1260
+ * Warm Editorial · v2 polish(0.7.12)
1261
+ * 评审驱动的五笔:图表色板归位 / 表格系统细化 / 空态组件 / 页眉归队 / 动效补全。
1262
+ * 原则不变:transform/opacity only;reduced-motion 收敛;反 AI 味。
1263
+ * ============================================================ */
1264
+
1265
+ :root {
1266
+ /* 图表调色板:暖纸体系的同类色序(替代 ECharts 默认荧光绿/蓝绿琥珀三连) */
1267
+ --chart-1: #4a6b57; /* 墨绿 —— 首序 */
1268
+ --chart-2: #8aa07c; /* 苔绿 */
1269
+ --chart-3: #c9a26a; /* 琥珀纸 */
1270
+ --chart-4: #b3714f; /* 陶赭 */
1271
+ --chart-5: #6f8296; /* 青灰 */
1272
+ --chart-track: color-mix(in srgb, var(--ink) 8%, transparent);
1273
+
1274
+ /* 动效时长刻度(animate 规范:UI <300ms;hover 100-160;浮层 150-250) */
1275
+ --dur-press: 120ms;
1276
+ --dur-control: 160ms;
1277
+ --dur-overlay: 220ms;
1278
+ }
1279
+
1280
+ /* ── 图表:坐标轴/图例融入油墨体系;数据序用暖纸色板 ── */
1281
+ .aw-chart .ant-table,
1282
+ .aw-chart text {
1283
+ font-family: var(--font-body);
1284
+ }
1285
+
1286
+ /* ── 表格系统细化:数字等宽 / 行内操作渐显 / 表头字距 ── */
1287
+ .ant-table .ant-table-cell {
1288
+ font-variant-numeric: tabular-nums;
1289
+ }
1290
+
1291
+ .ant-table .ant-table-tbody > tr {
1292
+ transition: background-color var(--transition-fast);
1293
+ }
1294
+
1295
+ /* 行内操作默认半隐,行悬停渐显(降低常驻视觉噪音;触屏/键盘可达性不受影响) */
1296
+ @media (hover: hover) and (pointer: fine) {
1297
+ .ant-table .ant-table-tbody .row-quiet {
1298
+ opacity: 0.45;
1299
+ transition: opacity var(--transition-fast);
1300
+ }
1301
+
1302
+ .ant-table .ant-table-tbody > tr:hover .row-quiet,
1303
+ .ant-table .ant-table-tbody > tr:focus-within .row-quiet {
1304
+ opacity: 1;
1305
+ }
1306
+ }
1307
+
1308
+ /* ── 空态:细线一道 + 衬线一句 + 导语(拒绝大块剪影图形) ── */
1309
+ .aw-empty {
1310
+ display: flex;
1311
+ flex-direction: column;
1312
+ gap: 10px;
1313
+ align-items: center;
1314
+ padding: 72px 0;
1315
+ text-align: center;
1316
+ }
1317
+
1318
+ .aw-empty::before {
1319
+ content: '';
1320
+ width: 44px;
1321
+ height: 1px;
1322
+ background: var(--ink-fainter);
1323
+ }
1324
+
1325
+ .aw-empty .aw-empty-title {
1326
+ font-family: var(--font-display);
1327
+ font-size: 19px;
1328
+ color: var(--ink-soft);
1329
+ }
1330
+
1331
+ .aw-empty .aw-empty-sub {
1332
+ max-width: 46ch;
1333
+ font-size: 12.5px;
1334
+ color: var(--ink-faint);
1335
+ }
1336
+
1337
+ /* ── 状态呼吸点:运行中/live 信号(2s 缓呼吸;reduced-motion 静止) ── */
1338
+ .aw-live-dot {
1339
+ display: inline-block;
1340
+ width: 7px;
1341
+ height: 7px;
1342
+ margin-right: 6px;
1343
+ vertical-align: 1px;
1344
+ border-radius: 50%;
1345
+ background: var(--tone-live-dot, #b9770e);
1346
+ }
1347
+
1348
+ @media (prefers-reduced-motion: no-preference) {
1349
+ .aw-live-dot {
1350
+ animation: aw-breathe 2.2s ease-in-out infinite;
1351
+ }
1352
+
1353
+ @keyframes aw-breathe {
1354
+ 0%, 100% { opacity: 1; }
1355
+ 50% { opacity: 0.35; }
1356
+ }
1357
+ }
1358
+
1359
+ /* ── 卡片悬停抬升:统一递给所有 .aw-liftable(4px 上移 + hairline 转墨) ── */
1360
+ @media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
1361
+ .aw-liftable {
1362
+ transition:
1363
+ transform var(--dur-control) var(--ease-out-quart),
1364
+ border-color var(--transition-fast),
1365
+ box-shadow var(--dur-control) var(--ease-out-quart);
1366
+ }
1367
+
1368
+ .aw-liftable:hover {
1369
+ transform: translateY(-3px);
1370
+ border-color: color-mix(in srgb, var(--ink) 24%, transparent);
1371
+ box-shadow: 0 6px 18px rgb(12 10 9 / 7%);
1372
+ }
1373
+ }
1374
+
1375
+ /* ── 页面进场编排的网格扩展:stagger 之前只覆盖 6 个子元素,补到 12(卡片墙/表格页) ── */
1376
+ @media (prefers-reduced-motion: no-preference) {
1377
+ .aw-stagger > :nth-child(7) { animation-delay: 0.3s; }
1378
+ .aw-stagger > :nth-child(8) { animation-delay: 0.35s; }
1379
+ .aw-stagger > :nth-child(9) { animation-delay: 0.4s; }
1380
+ .aw-stagger > :nth-child(10) { animation-delay: 0.45s; }
1381
+ .aw-stagger > :nth-child(11) { animation-delay: 0.5s; }
1382
+ .aw-stagger > :nth-child(12) { animation-delay: 0.55s; }
1383
+ }
1384
+
1385
+ /* ── 表头对齐:左对齐与正文一致(数字列右对齐由页面按列声明) ── */
1386
+ .ant-table .ant-table-thead > tr > th {
1387
+ text-align: left;
1388
+ }
1389
+
1390
+ /* ── 空表占位:替换 ant 默认黑色团状图形为细线风格 ── */
1391
+ .ant-empty-image {
1392
+ display: flex;
1393
+ justify-content: center;
1394
+ }
1395
+
1396
+ .ant-empty-image svg {
1397
+ width: 44px;
1398
+ height: 44px;
1399
+ fill: none;
1400
+ stroke: var(--ink-fainter);
1401
+ stroke-width: 1.25;
1402
+ opacity: 0.8;
1403
+ }
1404
+
1405
+ .ant-empty-description {
1406
+ color: var(--ink-faint);
1407
+ font-size: 12.5px;
1408
+ }
1409
+
1410
+ /* ── tokens 吊销:安静墨灰,悬停转红(红色只留给确认瞬间) ── */
1411
+ .tok-revoke {
1412
+ color: var(--ink-faint) !important;
1413
+ transition: color var(--transition-fast);
1414
+ }
1415
+
1416
+ .tok-revoke:hover {
1417
+ color: var(--tone-danger-dot, #c25a4e) !important;
1418
+ }
@@ -1,4 +1,7 @@
1
1
  <script setup lang="ts">
2
+ import { useUserStore } from '~/stores/workshop/user'
3
+
4
+ const userStore = useUserStore()
2
5
  const { t } = useI18n()
3
6
  const route = useRoute()
4
7
  const site = useSiteConfig()
@@ -10,6 +13,8 @@ interface MenuItem {
10
13
  label: string
11
14
  /** 图标微动效类(im-*) */
12
15
  motion?: string
16
+ /** 仅 admin 可见(权限管理) */
17
+ adminOnly?: boolean
13
18
  }
14
19
 
15
20
  const menuItems = computed<MenuItem[]>(() => [
@@ -21,10 +26,11 @@ const menuItems = computed<MenuItem[]>(() => [
21
26
  { key: '/dcw', icon: 'i-tabler-settings-automation', label: t('menu.dcw'), motion: 'im-pop' },
22
27
  { key: '/logs', icon: 'i-tabler-list-details', label: t('menu.logs'), motion: 'im-pop' },
23
28
  { key: '/users', icon: 'i-tabler-users-group', label: t('menu.users'), motion: 'im-pop' },
29
+ { key: '/permissions', icon: 'i-tabler-shield-lock', label: t('menu.permissions'), motion: 'im-pop', adminOnly: true },
24
30
  { key: '/monitor', icon: 'i-tabler-cpu', label: t('menu.monitor'), motion: 'im-pulse' },
25
31
  { key: '/plugins', icon: 'i-tabler-puzzle', label: t('menu.plugins'), motion: 'im-pop' },
26
32
  { key: '/settings', icon: 'i-tabler-settings', label: t('menu.settings'), motion: 'im-rotate' },
27
- ])
33
+ ].filter(m => !m.adminOnly || userStore.isAdmin))
28
34
 
29
35
  const isActive = (key: string): boolean =>
30
36
  key === '/' ? route.path === '/' : route.path.startsWith(key)
@@ -10,6 +10,7 @@ import {
10
10
  TooltipComponent,
11
11
  } from 'echarts/components'
12
12
  import VChart from 'vue-echarts'
13
+ import { computed } from 'vue'
13
14
  import type { PropType } from 'vue'
14
15
  import type { EChartsOption } from 'echarts'
15
16
 
@@ -27,18 +28,27 @@ use([
27
28
  DataZoomComponent,
28
29
  ])
29
30
 
30
- defineProps({
31
+ /** Warm Editorial 图表色序(替代 ECharts 默认荧光绿/蓝;与 main.css --chart-* 同源) */
32
+ const EDITORIAL_PALETTE = ['#4a6b57', '#8aa07c', '#c9a26a', '#b3714f', '#6f8296', '#4e4e4e']
33
+
34
+ const props = defineProps({
31
35
  option: {
32
36
  type: Object as PropType<EChartsOption>,
33
37
  required: true,
34
38
  },
35
39
  })
40
+
41
+ // 未显式给 color 的图表统一走编辑色板;给了的尊重页面意图
42
+ const merged = computed<EChartsOption>(() => ({
43
+ color: EDITORIAL_PALETTE,
44
+ ...props.option,
45
+ }))
36
46
  </script>
37
47
 
38
48
  <template>
39
49
  <VChart
40
50
  v-bind="$attrs"
41
- :option="option"
51
+ :option="merged"
42
52
  autoresize
43
53
  />
44
54
  </template>
@@ -26,6 +26,11 @@ export function useRouteMeta() {
26
26
  '/workshop/channel-templates': { key: 'meta.ctpl', icon: 'i-tabler-layout-grid-add' },
27
27
  '/town': { key: 'menu.town', icon: 'i-tabler-map-2' },
28
28
  '/tokens': { key: 'menu.tokens', icon: 'i-tabler-key' },
29
+ '/daq': { key: 'menu.daq', icon: 'i-tabler-activity' },
30
+ '/dcw': { key: 'menu.dcw', icon: 'i-tabler-settings-automation' },
31
+ '/logs': { key: 'menu.logs', icon: 'i-tabler-list-details' },
32
+ '/permissions': { key: 'menu.permissions', icon: 'i-tabler-shield-lock' },
33
+ '/plugins': { key: 'menu.plugins', icon: 'i-tabler-puzzle' },
29
34
  '/users': { key: 'menu.users', icon: 'i-tabler-users-group' },
30
35
  '/monitor': { key: 'menu.monitor', icon: 'i-tabler-cpu' },
31
36
  '/settings': { key: 'menu.settings', icon: 'i-tabler-settings' },
@@ -43,7 +48,9 @@ export function useRouteMeta() {
43
48
  return { title: name ?? `${t('header.workspace')} ${id.slice(0, 6)}`, icon: 'i-tabler-console' }
44
49
  }
45
50
 
46
- return { title: path.split('/').filter(Boolean).pop() ?? '·', icon: 'i-tabler-point' }
51
+ // 单段动态路径(daqs/dcws 等)取末段;纯 slug 至少首字母大写,不再裸显示
52
+ const last = path.split('/').filter(Boolean).pop() ?? '·'
53
+ return { title: last.charAt(0).toUpperCase() + last.slice(1), icon: 'i-tabler-point' }
47
54
  }
48
55
 
49
56
  return { metaFor }
@@ -1,95 +1,103 @@
1
- /**
2
- * 统一 API 客户端 —— 全部手写 fetch 的单一收口。
3
- * - 信封解析:{code, message, data};code !== 0 或非 2xx 一律抛 ApiError
4
- * - ApiError 保留业务码与 HTTP 状态(调用方可分支),message 为后端可读文案
5
- * - 网络层失败(TypeError/断网)→ ApiError('NETWORK'),不再裸奔 "Failed to fetch"
6
- * - 幂等 GET 可选自动重试(5xx/网络错误;400ms 起退避);写操作永不重试
7
- */
8
-
9
- export class ApiError extends Error {
10
- readonly code: string | number
11
- readonly status: number
12
-
13
- constructor(code: string | number, status: number, message: string) {
14
- super(message)
15
- this.name = 'ApiError'
16
- this.code = code
17
- this.status = status
18
- }
19
- }
20
-
21
- /** 鉴权头(cookie token → Bearer;与既有会话契约同源) */
22
- function authHeaders(json = true): Record<string, string> {
23
- const cookieToken = typeof document !== 'undefined'
24
- ? (document.cookie.match(/(?:^|;\s*)token=([^;]+)/)?.[1] ?? '')
25
- : ''
26
- const h: Record<string, string> = {}
27
- if (cookieToken) h.authorization = `Bearer ${decodeURIComponent(cookieToken)}`
28
- if (json) h['content-type'] = 'application/json'
29
- return h
30
- }
31
-
32
- const sleep = (ms: number) => new Promise(r => setTimeout(r, ms))
33
-
34
- function isIdempotent(init?: RequestInit): boolean {
35
- const method = (init?.method ?? 'GET').toUpperCase()
36
- return method === 'GET' || method === 'HEAD'
37
- }
38
-
39
- /** 单次请求:信封解析 + 错误归一化(所有失败路径都抛 ApiError) */
40
- async function attemptOnce<T>(base: string, path: string, init?: RequestInit): Promise<T> {
41
- let res: Response
42
- try {
43
- res = await fetch(base + path, { ...init, headers: { ...authHeaders(!!init?.body), ...init?.headers } })
44
- }
45
- catch {
46
- throw new ApiError('NETWORK', 0, '无法连接服务器,请检查网络或服务状态')
47
- }
48
- let json: { code?: string | number, message?: string, data?: T } | null = null
49
- try {
50
- json = await res.json()
51
- }
52
- catch {
53
- // 非 JSON 响应(代理/网关 HTML 错误页等)——按状态码归一化
54
- }
55
- if (!res.ok) {
56
- throw new ApiError(
57
- json?.code ?? `HTTP_${res.status}`,
58
- res.status,
59
- json?.message || `请求失败(HTTP ${res.status})`,
60
- )
61
- }
62
- if (json?.code !== 0) {
63
- throw new ApiError(json?.code ?? 'REQUEST_ERROR', res.status, json?.message || '请求失败')
64
- }
65
- return json.data as T
66
- }
67
-
68
- /**
69
- * 统一请求入口。
70
- * @param opts.base API 前缀(如 '/api/workshop/daq')
71
- * @param opts.path 路径后缀(如 '/:id/bind')
72
- * @param opts.init fetch RequestInit(body 由调用方 JSON.stringify)
73
- * @param opts.retries 幂等请求额外重试次数(仅 5xx/网络错误;默认 0)
74
- */
75
- export async function apiFetch<T>(opts: { base: string, path?: string, init?: RequestInit, retries?: number }): Promise<T> {
76
- const { base, path = '', init, retries = 0 } = opts
77
- const idempotent = isIdempotent(init)
78
- const attempts = idempotent ? retries + 1 : 1
79
- let lastError: ApiError | undefined
80
- for (let attempt = 0; attempt < attempts; attempt++) {
81
- try {
82
- return await attemptOnce<T>(base, path, init)
83
- }
84
- catch (err) {
85
- const apiErr = err instanceof ApiError
86
- ? err
87
- : new ApiError('INTERNAL_ERROR', 0, apiErrorMessage(err))
88
- const retryable = idempotent && (apiErr.code === 'NETWORK' || apiErr.status >= 500)
89
- lastError = apiErr
90
- if (!retryable || attempt === attempts - 1) throw apiErr
91
- await sleep(400 * (attempt + 1))
92
- }
93
- }
94
- throw lastError ?? new ApiError('INTERNAL_ERROR', 0, '请求失败')
95
- }
1
+ /**
2
+ * 统一 API 客户端 —— 全部手写 fetch 的单一收口。
3
+ * - 信封解析:{code, message, data};code !== 0 或非 2xx 一律抛 ApiError
4
+ * - ApiError 保留业务码与 HTTP 状态(调用方可分支),message 为后端可读文案
5
+ * - 网络层失败(TypeError/断网)→ ApiError('NETWORK'),不再裸奔 "Failed to fetch"
6
+ * - 幂等 GET 可选自动重试(5xx/网络错误;400ms 起退避);写操作永不重试
7
+ */
8
+
9
+ export class ApiError extends Error {
10
+ readonly code: string | number
11
+ readonly status: number
12
+
13
+ constructor(code: string | number, status: number, message: string) {
14
+ super(message)
15
+ this.name = 'ApiError'
16
+ this.code = code
17
+ this.status = status
18
+ }
19
+ }
20
+
21
+ /** 鉴权头(cookie token → Bearer;与既有会话契约同源) */
22
+ function authHeaders(json = true): Record<string, string> {
23
+ const cookieToken = typeof document !== 'undefined'
24
+ ? (document.cookie.match(/(?:^|;\s*)token=([^;]+)/)?.[1] ?? '')
25
+ : ''
26
+ const h: Record<string, string> = {}
27
+ if (cookieToken) h.authorization = `Bearer ${decodeURIComponent(cookieToken)}`
28
+ if (json) h['content-type'] = 'application/json'
29
+ return h
30
+ }
31
+
32
+ const sleep = (ms: number) => new Promise(r => setTimeout(r, ms))
33
+
34
+ function isIdempotent(init?: RequestInit): boolean {
35
+ const method = (init?.method ?? 'GET').toUpperCase()
36
+ return method === 'GET' || method === 'HEAD'
37
+ }
38
+
39
+ /** 单次请求:信封解析 + 错误归一化(所有失败路径都抛 ApiError) */
40
+ async function attemptOnce<T>(base: string, path: string, init?: RequestInit): Promise<T> {
41
+ let res: Response
42
+ try {
43
+ // 超时防挂起:无 AbortSignal 的 fetch 在连接黑洞时 promise 永不 settle,loading 永卡
44
+ res = await fetch(base + path, {
45
+ ...init,
46
+ headers: { ...authHeaders(!!init?.body), ...init?.headers },
47
+ signal: init?.signal ?? AbortSignal.timeout(init?.method && init.method.toUpperCase() !== 'GET' ? 30_000 : 15_000),
48
+ })
49
+ }
50
+ catch (err) {
51
+ if (err instanceof Error && (err.name === 'TimeoutError' || err.name === 'AbortError')) {
52
+ throw new ApiError('TIMEOUT', 0, '请求超时,请检查网络或服务状态')
53
+ }
54
+ throw new ApiError('NETWORK', 0, '无法连接服务器,请检查网络或服务状态')
55
+ }
56
+ let json: { code?: string | number, message?: string, data?: T } | null = null
57
+ try {
58
+ json = await res.json()
59
+ }
60
+ catch {
61
+ // 非 JSON 响应(代理/网关 HTML 错误页等)——按状态码归一化
62
+ }
63
+ if (!res.ok) {
64
+ throw new ApiError(
65
+ json?.code ?? `HTTP_${res.status}`,
66
+ res.status,
67
+ json?.message || `请求失败(HTTP ${res.status})`,
68
+ )
69
+ }
70
+ if (json?.code !== 0) {
71
+ throw new ApiError(json?.code ?? 'REQUEST_ERROR', res.status, json?.message || '请求失败')
72
+ }
73
+ return json.data as T
74
+ }
75
+
76
+ /**
77
+ * 统一请求入口。
78
+ * @param opts.base API 前缀(如 '/api/workshop/daq')
79
+ * @param opts.path 路径后缀(如 '/:id/bind')
80
+ * @param opts.init fetch RequestInit(body 由调用方 JSON.stringify)
81
+ * @param opts.retries 幂等请求额外重试次数(仅 5xx/网络错误;默认 0)
82
+ */
83
+ export async function apiFetch<T>(opts: { base: string, path?: string, init?: RequestInit, retries?: number }): Promise<T> {
84
+ const { base, path = '', init, retries = 0 } = opts
85
+ const idempotent = isIdempotent(init)
86
+ const attempts = idempotent ? retries + 1 : 1
87
+ let lastError: ApiError | undefined
88
+ for (let attempt = 0; attempt < attempts; attempt++) {
89
+ try {
90
+ return await attemptOnce<T>(base, path, init)
91
+ }
92
+ catch (err) {
93
+ const apiErr = err instanceof ApiError
94
+ ? err
95
+ : new ApiError('INTERNAL_ERROR', 0, apiErrorMessage(err))
96
+ const retryable = idempotent && (apiErr.code === 'NETWORK' || apiErr.status >= 500)
97
+ lastError = apiErr
98
+ if (!retryable || attempt === attempts - 1) throw apiErr
99
+ await sleep(400 * (attempt + 1))
100
+ }
101
+ }
102
+ throw lastError ?? new ApiError('INTERNAL_ERROR', 0, '请求失败')
103
+ }
@@ -204,30 +204,44 @@ const createStore = () => {
204
204
  }
205
205
  }
206
206
 
207
- /** 挂 WS 帧(townBus);幂等(globalThis 防重复订阅)。返回退订函数。 */
207
+ /** 挂 WS 帧(townBus)。引用计数:首个调用建立真实订阅,计数归零才退订
208
+ * (修复一次性守卫导致首个页面卸载后实时流永久死亡的缺陷)。返回退订函数。 */
209
+ let feedConsumers = 0
210
+ let feedUnsub: (() => void) | null = null
208
211
  function ensureWsFeed(): () => void {
209
- const g = globalThis as typeof globalThis & { __daqBusFed?: boolean }
210
- if (g.__daqBusFed) return () => {}
211
- g.__daqBusFed = true
212
- return useTownBus().subscribe((e: AepEnvelope) => {
213
- if (e.type === 'daq.reading') applyReading(e.payload as AepDaqReading)
214
- else if (e.type === 'daq.frame') applyFrame(e.payload as unknown as AepDaqFrame)
215
- else if (e.type === 'daq.node.changed') applyChange(e.payload as AepDaqNodeChange)
216
- else if (e.type === 'daq.controller') Object.assign(controller, e.payload as AepDaqControllerState)
217
- else if (e.type === 'daq.template.changed') applyTemplateChange(e.payload as AepDaqTemplateChange)
218
- // S5 实时告警:server 权威事件直推(报警进入轨插入;ack 确认后移出未确认列表)
219
- else if (e.type === 'daq.alarm') {
220
- const p = e.payload as unknown as DaqAlarmRow
221
- if (!alarms.some(a => a.id === p.id)) alarms.unshift(p)
212
+ feedConsumers++
213
+ if (feedConsumers === 1) {
214
+ feedUnsub = useTownBus().subscribe(handler)
215
+ }
216
+ let done = false
217
+ return () => {
218
+ if (done) return
219
+ done = true
220
+ if (--feedConsumers === 0) {
221
+ feedUnsub?.()
222
+ feedUnsub = null
222
223
  }
223
- else if (e.type === 'daq.alarm.changed') {
224
- const p = e.payload as unknown as { id: string, ackedAt?: string, recovered?: boolean }
225
- if (p.ackedAt) {
226
- const i = alarms.findIndex(a => a.id === p.id)
227
- if (i >= 0) alarms.splice(i, 1)
228
- }
224
+ }
225
+ }
226
+
227
+ function handler(e: AepEnvelope) {
228
+ if (e.type === 'daq.reading') applyReading(e.payload as AepDaqReading)
229
+ else if (e.type === 'daq.frame') applyFrame(e.payload as unknown as AepDaqFrame)
230
+ else if (e.type === 'daq.node.changed') applyChange(e.payload as AepDaqNodeChange)
231
+ else if (e.type === 'daq.controller') Object.assign(controller, e.payload as AepDaqControllerState)
232
+ else if (e.type === 'daq.template.changed') applyTemplateChange(e.payload as AepDaqTemplateChange)
233
+ // S5 实时告警:server 权威事件直推(报警进入轨插入;ack 确认后移出未确认列表)
234
+ else if (e.type === 'daq.alarm') {
235
+ const p = e.payload as unknown as DaqAlarmRow
236
+ if (!alarms.some(a => a.id === p.id)) alarms.unshift(p)
237
+ }
238
+ else if (e.type === 'daq.alarm.changed') {
239
+ const p = e.payload as unknown as { id: string, ackedAt?: string, recovered?: boolean }
240
+ if (p.ackedAt) {
241
+ const i = alarms.findIndex(a => a.id === p.id)
242
+ if (i >= 0) alarms.splice(i, 1)
229
243
  }
230
- })
244
+ }
231
245
  }
232
246
 
233
247
  async function load(): Promise<void> {
@@ -50,11 +50,27 @@ function createStore() {
50
50
  upsert(p.node)
51
51
  }
52
52
 
53
+ /** 引用计数订阅(同 useDaqStream):首个调用建订阅,归零才退订 */
54
+ let feedConsumers = 0
55
+ let feedUnsub: (() => void) | null = null
53
56
  function ensureWsFeed(): () => void {
54
- const g = globalThis as typeof globalThis & { __dcwBusFed?: boolean }
55
- if (g.__dcwBusFed) return () => {}
56
- g.__dcwBusFed = true
57
- return useTownBus().subscribe((e: AepEnvelope) => {
57
+ feedConsumers++
58
+ if (feedConsumers === 1) {
59
+ feedUnsub = useTownBus().subscribe(handler)
60
+ }
61
+ let done = false
62
+ return () => {
63
+ if (done) return
64
+ done = true
65
+ if (--feedConsumers === 0) {
66
+ feedUnsub?.()
67
+ feedUnsub = null
68
+ }
69
+ }
70
+ }
71
+
72
+ function handler(e: AepEnvelope) {
73
+ {
58
74
  if (e.type === 'dcw.written') {
59
75
  const p = e.payload as AepDcwWritten
60
76
  const n = nodes.find(x => x.id === p.nodeId)
@@ -83,8 +99,9 @@ function createStore() {
83
99
  const i = optimizations.findIndex(x => x.id === p.id)
84
100
  if (i >= 0) optimizations[i] = p
85
101
  else optimizations.unshift(p)
102
+ if (optimizations.length > 200) optimizations.length = 200
86
103
  }
87
- })
104
+ }
88
105
  }
89
106
 
90
107
  async function load(): Promise<void> {