agentworkshop 0.6.1 → 0.7.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 (537) hide show
  1. package/.AgentWorkShop/prompts/host-tools.json +17 -0
  2. package/.env.example +37 -0
  3. package/.output/.AgentWorkShop/prompts/host-tools.json +17 -0
  4. package/.output/nitro.json +1 -1
  5. package/.output/public/_nuxt/{Bc_mM2cU.js → BH0Z05CS.js} +1 -1
  6. package/.output/public/_nuxt/Bxgaym6j.js +1 -0
  7. package/.output/public/_nuxt/{DRlJ2-4p.js → By-LNp3k.js} +1 -1
  8. package/.output/public/_nuxt/{C2QSTAWf.js → Bz40vyZS.js} +1 -1
  9. package/.output/public/_nuxt/{CwS_UHeH.js → CS8R0_J3.js} +1 -1
  10. package/.output/public/_nuxt/{ClptO7LA.js → CUxV8Bw_.js} +1 -1
  11. package/.output/public/_nuxt/CXmkVXS5.js +1 -0
  12. package/.output/public/_nuxt/DC-QMEk1.js +2 -0
  13. package/.output/public/_nuxt/{C-Y5ydB6.js → Dgp2wK2U.js} +6 -6
  14. package/.output/public/_nuxt/{Ck6tznoQ.js → DjqcbFBE.js} +1 -1
  15. package/.output/public/_nuxt/{B0haAGoq.js → GP2wXyuY.js} +1 -1
  16. package/.output/public/_nuxt/TownView.Bt33bo1M.css +1 -0
  17. package/.output/public/_nuxt/{MhK4buEJ.js → XVB9_zwP.js} +1 -1
  18. package/.output/public/_nuxt/_id_.BeqSLvl_.css +1 -0
  19. package/.output/public/_nuxt/builds/latest.json +1 -1
  20. package/.output/public/_nuxt/builds/meta/0f65fbec-c4c0-45de-9c50-bb41ada375e5.json +1 -0
  21. package/.output/public/_nuxt/{Bq_KKxCg.js → i_MKObHo.js} +1 -1
  22. package/.output/public/_nuxt/settings.DeRNNUcP.css +1 -0
  23. package/.output/public/_nuxt/{CclO6GyL.js → tpDMVY5w.js} +1 -1
  24. package/.output/public/_nuxt/{C0FogB-p.js → zwdqvGN_.js} +1 -1
  25. package/.output/server/chunks/_/nitro.mjs +2674 -2347
  26. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  27. package/.output/server/chunks/build/{TownView-D9yCQe1T.mjs → TownView-BkHxMiwZ.mjs} +168 -159
  28. package/.output/server/chunks/build/{TownView-D9yCQe1T.mjs.map → TownView-BkHxMiwZ.mjs.map} +1 -1
  29. package/.output/server/chunks/build/{_id_-xR3AChMO.mjs → _id_-Bna1_JuB.mjs} +5 -4
  30. package/.output/server/chunks/build/_id_-Bna1_JuB.mjs.map +1 -0
  31. package/.output/server/chunks/build/{_id_-CmKAEFHV.mjs → _id_-GnRJPykX.mjs} +161 -119
  32. package/.output/server/chunks/build/_id_-GnRJPykX.mjs.map +1 -0
  33. package/.output/server/chunks/build/{_wsId_-C45nVrl-.mjs → _wsId_-CzLDGT_V.mjs} +6 -5
  34. package/.output/server/chunks/build/{_wsId_-C45nVrl-.mjs.map → _wsId_-CzLDGT_V.mjs.map} +1 -1
  35. package/.output/server/chunks/build/agents-D4l1icvn.mjs +1 -0
  36. package/.output/server/chunks/build/agents-D4l1icvn.mjs.map +1 -1
  37. package/.output/server/chunks/build/channel-templates-DqjtC-R0.mjs +1 -0
  38. package/.output/server/chunks/build/channel-templates-DqjtC-R0.mjs.map +1 -1
  39. package/.output/server/chunks/build/{daq-Boz_dlAQ.mjs → daq-D_W59QOe.mjs} +6 -5
  40. package/.output/server/chunks/build/daq-D_W59QOe.mjs.map +1 -0
  41. package/.output/server/chunks/build/{dcw-wTRwBAUi.mjs → dcw-BTM5YU-B.mjs} +3 -2
  42. package/.output/server/chunks/build/dcw-BTM5YU-B.mjs.map +1 -0
  43. package/.output/server/chunks/build/default-Dt6xLdpd.mjs +1 -0
  44. package/.output/server/chunks/build/{logs-Cdi-eXlN.mjs → logs-CUQt1z7D.mjs} +4 -3
  45. package/.output/server/chunks/build/logs-CUQt1z7D.mjs.map +1 -0
  46. package/.output/server/chunks/build/monitor-yNoV98rf.mjs +1 -0
  47. package/.output/server/chunks/build/{pages-bWKy0ZsA.mjs → pages-DR2bzczM.mjs} +4 -3
  48. package/.output/server/chunks/build/pages-DR2bzczM.mjs.map +1 -0
  49. package/.output/server/chunks/build/plugins-B-ZNey0Z.mjs +1 -0
  50. package/.output/server/chunks/build/plugins-B-ZNey0Z.mjs.map +1 -1
  51. package/.output/server/chunks/build/{settings-C3T5hR2A.mjs → settings-Cr06lbRy.mjs} +26 -18
  52. package/.output/server/chunks/build/settings-Cr06lbRy.mjs.map +1 -0
  53. package/.output/server/chunks/build/teams-QR3BBF7A.mjs +1 -0
  54. package/.output/server/chunks/build/teams-QR3BBF7A.mjs.map +1 -1
  55. package/.output/server/chunks/build/tokens-DFvr_TLj.mjs +1 -0
  56. package/.output/server/chunks/build/tokens-DFvr_TLj.mjs.map +1 -1
  57. package/.output/server/chunks/build/{town-CKg6Qxba.mjs → town-BN4vQPb8.mjs} +6 -5
  58. package/.output/server/chunks/build/town-BN4vQPb8.mjs.map +1 -0
  59. package/.output/server/chunks/build/town-BUqRobze.mjs +1 -0
  60. package/.output/server/chunks/build/town-BUqRobze.mjs.map +1 -1
  61. package/.output/server/chunks/build/{useDaqStream-zHEptJQ_.mjs → useDaqStream-hwkhJHFU.mjs} +2 -2
  62. package/.output/server/chunks/build/{useDaqStream-zHEptJQ_.mjs.map → useDaqStream-hwkhJHFU.mjs.map} +1 -1
  63. package/.output/server/chunks/build/{useDcwStream-BkWDGaWp.mjs → useDcwStream-Bdew_yrr.mjs} +16 -1
  64. package/.output/server/chunks/build/useDcwStream-Bdew_yrr.mjs.map +1 -0
  65. package/.output/server/chunks/build/{useDeviceTwins-NhtXqSkU.mjs → useDeviceTwins-C6EBg9oN.mjs} +2 -2
  66. package/.output/server/chunks/build/{useDeviceTwins-NhtXqSkU.mjs.map → useDeviceTwins-C6EBg9oN.mjs.map} +1 -1
  67. package/.output/server/chunks/build/{useOpsLog-CU64VDg5.mjs → useOpsLog-DdCqKVVG.mjs} +2 -2
  68. package/.output/server/chunks/build/{useOpsLog-CU64VDg5.mjs.map → useOpsLog-DdCqKVVG.mjs.map} +1 -1
  69. package/.output/server/chunks/build/users-4FZ0yFUO.mjs +1 -0
  70. package/.output/server/chunks/build/users-4FZ0yFUO.mjs.map +1 -1
  71. package/.output/server/chunks/build/workshop-CLhwe5eo.mjs +1 -0
  72. package/.output/server/chunks/build/workshop-CLhwe5eo.mjs.map +1 -1
  73. package/.output/server/chunks/routes/api/health.get.mjs +1 -0
  74. package/.output/server/chunks/routes/api/health.get.mjs.map +1 -1
  75. package/.output/server/chunks/routes/api/index.get.mjs +1 -0
  76. package/.output/server/chunks/routes/api/index.get.mjs.map +1 -1
  77. package/.output/server/chunks/routes/api/index.post.mjs +1 -0
  78. package/.output/server/chunks/routes/api/index.post.mjs.map +1 -1
  79. package/.output/server/chunks/routes/api/mcp/workshop.mjs +1 -0
  80. package/.output/server/chunks/routes/api/mcp/workshop.mjs.map +1 -1
  81. package/.output/server/chunks/routes/api/metrics.mjs +1 -0
  82. package/.output/server/chunks/routes/api/metrics.mjs.map +1 -1
  83. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +1 -0
  84. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs.map +1 -1
  85. package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs +1 -0
  86. package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs.map +1 -1
  87. package/.output/server/chunks/routes/api/plugins/manifest.get.mjs +1 -0
  88. package/.output/server/chunks/routes/api/plugins/manifest.get.mjs.map +1 -1
  89. package/.output/server/chunks/routes/api/system/config.get.mjs +1 -0
  90. package/.output/server/chunks/routes/api/system/config.get.mjs.map +1 -1
  91. package/.output/server/chunks/routes/api/system/index.get.mjs +1 -0
  92. package/.output/server/chunks/routes/api/system/index.get.mjs.map +1 -1
  93. package/.output/server/chunks/routes/api/system/index.patch.mjs +1 -0
  94. package/.output/server/chunks/routes/api/system/index.patch.mjs.map +1 -1
  95. package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs +1 -0
  96. package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs.map +1 -1
  97. package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs +1 -0
  98. package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs.map +1 -1
  99. package/.output/server/chunks/routes/api/system/monitor.get.mjs +1 -0
  100. package/.output/server/chunks/routes/api/system/monitor.get.mjs.map +1 -1
  101. package/.output/server/chunks/routes/api/system/settings/events.get.mjs +1 -0
  102. package/.output/server/chunks/routes/api/system/settings/events.get.mjs.map +1 -1
  103. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs +1 -0
  104. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs.map +1 -1
  105. package/.output/server/chunks/routes/api/users/_id_.delete.mjs +1 -0
  106. package/.output/server/chunks/routes/api/users/_id_.delete.mjs.map +1 -1
  107. package/.output/server/chunks/routes/api/users/_id_.get.mjs +1 -0
  108. package/.output/server/chunks/routes/api/users/_id_.get.mjs.map +1 -1
  109. package/.output/server/chunks/routes/api/users/_id_.put.mjs +1 -0
  110. package/.output/server/chunks/routes/api/users/_id_.put.mjs.map +1 -1
  111. package/.output/server/chunks/routes/api/users/index.get.mjs +1 -0
  112. package/.output/server/chunks/routes/api/users/index.get.mjs.map +1 -1
  113. package/.output/server/chunks/routes/api/users/index.post.mjs +1 -0
  114. package/.output/server/chunks/routes/api/users/index.post.mjs.map +1 -1
  115. package/.output/server/chunks/routes/api/users/login.post.mjs +1 -0
  116. package/.output/server/chunks/routes/api/users/login.post.mjs.map +1 -1
  117. package/.output/server/chunks/routes/api/users/logout.post.mjs +1 -0
  118. package/.output/server/chunks/routes/api/users/logout.post.mjs.map +1 -1
  119. package/.output/server/chunks/routes/api/users/me.get.mjs +1 -0
  120. package/.output/server/chunks/routes/api/users/me.get.mjs.map +1 -1
  121. package/.output/server/chunks/routes/api/users/register.post.mjs +1 -0
  122. package/.output/server/chunks/routes/api/users/register.post.mjs.map +1 -1
  123. package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs +1 -0
  124. package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs.map +1 -1
  125. package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs +1 -0
  126. package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs.map +1 -1
  127. package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs +1 -0
  128. package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs.map +1 -1
  129. package/.output/server/chunks/routes/api/workshop/_...path_.mjs +1 -0
  130. package/.output/server/chunks/routes/api/workshop/_...path_.mjs.map +1 -1
  131. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs +1 -0
  132. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs.map +1 -1
  133. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs +1 -0
  134. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs.map +1 -1
  135. package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs +1 -0
  136. package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs.map +1 -1
  137. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +1 -0
  138. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs.map +1 -1
  139. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs +1 -0
  140. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs.map +1 -1
  141. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +1 -0
  142. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs.map +1 -1
  143. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +1 -0
  144. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs.map +1 -1
  145. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +1 -0
  146. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs.map +1 -1
  147. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +1 -0
  148. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs.map +1 -1
  149. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +1 -0
  150. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
  151. package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs +1 -0
  152. package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs.map +1 -1
  153. package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs +1 -0
  154. package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs.map +1 -1
  155. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +1 -0
  156. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs.map +1 -1
  157. package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs +1 -0
  158. package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs.map +1 -1
  159. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +1 -0
  160. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs.map +1 -1
  161. package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs +1 -0
  162. package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs.map +1 -1
  163. package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs +1 -0
  164. package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs.map +1 -1
  165. package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs +1 -0
  166. package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs.map +1 -1
  167. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +1 -0
  168. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs.map +1 -1
  169. package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs +1 -0
  170. package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs.map +1 -1
  171. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +1 -0
  172. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs.map +1 -1
  173. package/.output/server/chunks/routes/api/workshop/audit.get.mjs +1 -0
  174. package/.output/server/chunks/routes/api/workshop/audit.get.mjs.map +1 -1
  175. package/.output/server/chunks/routes/api/workshop/caller.mjs +1 -0
  176. package/.output/server/chunks/routes/api/workshop/caller.mjs.map +1 -1
  177. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -0
  178. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs.map +1 -1
  179. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs +1 -0
  180. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs.map +1 -1
  181. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs +1 -0
  182. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs.map +1 -1
  183. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +1 -0
  184. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs.map +1 -1
  185. package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs +1 -0
  186. package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs.map +1 -1
  187. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +1 -0
  188. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs.map +1 -1
  189. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs +1 -0
  190. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs.map +1 -1
  191. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs +1 -0
  192. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs.map +1 -1
  193. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs +1 -0
  194. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs.map +1 -1
  195. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs +1 -0
  196. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs.map +1 -1
  197. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs +1 -0
  198. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs.map +1 -1
  199. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs +1 -0
  200. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs.map +1 -1
  201. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs +1 -0
  202. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs.map +1 -1
  203. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs +1 -0
  204. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs.map +1 -1
  205. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs +1 -0
  206. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs.map +1 -1
  207. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +1 -0
  208. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs.map +1 -1
  209. package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs +1 -0
  210. package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs.map +1 -1
  211. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +1 -0
  212. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs.map +1 -1
  213. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -0
  214. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs.map +1 -1
  215. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs +1 -0
  216. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs.map +1 -1
  217. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs +1 -0
  218. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs.map +1 -1
  219. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.mjs +1 -0
  220. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.mjs.map +1 -1
  221. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -0
  222. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs.map +1 -1
  223. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +1 -0
  224. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs.map +1 -1
  225. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -0
  226. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs.map +1 -1
  227. package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs +1 -0
  228. package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs.map +1 -1
  229. package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs +1 -0
  230. package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs.map +1 -1
  231. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +1 -0
  232. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs.map +1 -1
  233. package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs +1 -0
  234. package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs.map +1 -1
  235. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +1 -0
  236. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs.map +1 -1
  237. package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs +1 -0
  238. package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs.map +1 -1
  239. package/.output/server/chunks/routes/api/workshop/channels.get.mjs +1 -0
  240. package/.output/server/chunks/routes/api/workshop/channels.get.mjs.map +1 -1
  241. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +1 -0
  242. package/.output/server/chunks/routes/api/workshop/channels.post.mjs.map +1 -1
  243. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +1 -0
  244. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs.map +1 -1
  245. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +1 -0
  246. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs.map +1 -1
  247. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +1 -0
  248. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs.map +1 -1
  249. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +1 -0
  250. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs.map +1 -1
  251. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +1 -0
  252. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs.map +1 -1
  253. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +1 -0
  254. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs.map +1 -1
  255. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +1 -0
  256. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs.map +1 -1
  257. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +1 -0
  258. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs.map +1 -1
  259. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +1 -0
  260. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs.map +1 -1
  261. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +1 -0
  262. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs.map +1 -1
  263. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +1 -0
  264. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs.map +1 -1
  265. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +1 -0
  266. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs.map +1 -1
  267. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +1 -0
  268. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs.map +1 -1
  269. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +1 -0
  270. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs.map +1 -1
  271. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +1 -0
  272. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs.map +1 -1
  273. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +1 -0
  274. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs.map +1 -1
  275. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +1 -0
  276. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs.map +1 -1
  277. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +1 -0
  278. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs.map +1 -1
  279. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +31 -0
  280. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs.map +1 -0
  281. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +1 -0
  282. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs.map +1 -1
  283. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +1 -0
  284. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs.map +1 -1
  285. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +1 -0
  286. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs.map +1 -1
  287. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +1 -0
  288. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs.map +1 -1
  289. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +1 -0
  290. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs.map +1 -1
  291. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +1 -0
  292. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs.map +1 -1
  293. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -0
  294. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs.map +1 -1
  295. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +1 -0
  296. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs.map +1 -1
  297. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +1 -0
  298. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs.map +1 -1
  299. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +1 -0
  300. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs.map +1 -1
  301. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +1 -0
  302. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs.map +1 -1
  303. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +1 -0
  304. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs.map +1 -1
  305. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -0
  306. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs.map +1 -1
  307. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +1 -0
  308. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs.map +1 -1
  309. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +1 -0
  310. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs.map +1 -1
  311. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +1 -0
  312. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs.map +1 -1
  313. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -0
  314. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs.map +1 -1
  315. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -0
  316. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs.map +1 -1
  317. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -0
  318. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs.map +1 -1
  319. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs +1 -0
  320. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs.map +1 -1
  321. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +1 -0
  322. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs.map +1 -1
  323. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +1 -0
  324. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs.map +1 -1
  325. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +1 -0
  326. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs.map +1 -1
  327. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +1 -0
  328. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs.map +1 -1
  329. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +1 -0
  330. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs.map +1 -1
  331. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +1 -0
  332. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs.map +1 -1
  333. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +1 -0
  334. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs.map +1 -1
  335. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +1 -0
  336. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs.map +1 -1
  337. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +1 -0
  338. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs.map +1 -1
  339. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +1 -0
  340. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs.map +1 -1
  341. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.patch.mjs +1 -0
  342. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.patch.mjs.map +1 -1
  343. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +1 -0
  344. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs.map +1 -1
  345. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -0
  346. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs.map +1 -1
  347. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +1 -0
  348. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs.map +1 -1
  349. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -0
  350. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs.map +1 -1
  351. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -0
  352. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs.map +1 -1
  353. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +1 -0
  354. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs.map +1 -1
  355. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +1 -0
  356. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs.map +1 -1
  357. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +1 -0
  358. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs.map +1 -1
  359. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +1 -0
  360. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs.map +1 -1
  361. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +1 -0
  362. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs.map +1 -1
  363. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +1 -0
  364. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs.map +1 -1
  365. package/.output/server/chunks/routes/api/workshop/index.get.mjs +1 -0
  366. package/.output/server/chunks/routes/api/workshop/index.get.mjs.map +1 -1
  367. package/.output/server/chunks/routes/api/workshop/index.post.mjs +1 -0
  368. package/.output/server/chunks/routes/api/workshop/index.post.mjs.map +1 -1
  369. package/.output/server/chunks/routes/api/workshop/index10.get.mjs +1 -0
  370. package/.output/server/chunks/routes/api/workshop/index10.get.mjs.map +1 -1
  371. package/.output/server/chunks/routes/api/workshop/index2.get.mjs +1 -0
  372. package/.output/server/chunks/routes/api/workshop/index2.get.mjs.map +1 -1
  373. package/.output/server/chunks/routes/api/workshop/index2.post.mjs +1 -0
  374. package/.output/server/chunks/routes/api/workshop/index2.post.mjs.map +1 -1
  375. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +1 -0
  376. package/.output/server/chunks/routes/api/workshop/index3.get.mjs.map +1 -1
  377. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +1 -0
  378. package/.output/server/chunks/routes/api/workshop/index3.post.mjs.map +1 -1
  379. package/.output/server/chunks/routes/api/workshop/index4.get.mjs +1 -0
  380. package/.output/server/chunks/routes/api/workshop/index4.get.mjs.map +1 -1
  381. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +1 -0
  382. package/.output/server/chunks/routes/api/workshop/index4.post.mjs.map +1 -1
  383. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +1 -0
  384. package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
  385. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +1 -0
  386. package/.output/server/chunks/routes/api/workshop/index5.post.mjs.map +1 -1
  387. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +1 -0
  388. package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
  389. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +1 -0
  390. package/.output/server/chunks/routes/api/workshop/index6.post.mjs.map +1 -1
  391. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +1 -0
  392. package/.output/server/chunks/routes/api/workshop/index7.get.mjs.map +1 -1
  393. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +1 -0
  394. package/.output/server/chunks/routes/api/workshop/index7.post.mjs.map +1 -1
  395. package/.output/server/chunks/routes/api/workshop/index8.get.mjs +1 -0
  396. package/.output/server/chunks/routes/api/workshop/index8.get.mjs.map +1 -1
  397. package/.output/server/chunks/routes/api/workshop/index8.post.mjs +1 -0
  398. package/.output/server/chunks/routes/api/workshop/index8.post.mjs.map +1 -1
  399. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +1 -0
  400. package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
  401. package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs +1 -0
  402. package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs.map +1 -1
  403. package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs +1 -0
  404. package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs.map +1 -1
  405. package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs +1 -0
  406. package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs.map +1 -1
  407. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -0
  408. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs.map +1 -1
  409. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -0
  410. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs.map +1 -1
  411. package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs +1 -0
  412. package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs.map +1 -1
  413. package/.output/server/chunks/routes/api/workshop/runtime.get.mjs +1 -0
  414. package/.output/server/chunks/routes/api/workshop/runtime.get.mjs.map +1 -1
  415. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -0
  416. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs.map +1 -1
  417. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -0
  418. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs.map +1 -1
  419. package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs +1 -0
  420. package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs.map +1 -1
  421. package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs +1 -0
  422. package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs.map +1 -1
  423. package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs +1 -0
  424. package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs.map +1 -1
  425. package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs +1 -0
  426. package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs.map +1 -1
  427. package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs +1 -0
  428. package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs.map +1 -1
  429. package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs +1 -0
  430. package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs.map +1 -1
  431. package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs +1 -0
  432. package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs.map +1 -1
  433. package/.output/server/chunks/routes/api/workshop/tasks.get.mjs +1 -0
  434. package/.output/server/chunks/routes/api/workshop/tasks.get.mjs.map +1 -1
  435. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -0
  436. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs.map +1 -1
  437. package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs +1 -0
  438. package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs.map +1 -1
  439. package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs +1 -0
  440. package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs.map +1 -1
  441. package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs +1 -0
  442. package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs.map +1 -1
  443. package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs +1 -0
  444. package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs.map +1 -1
  445. package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs +1 -0
  446. package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs.map +1 -1
  447. package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs +1 -0
  448. package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs.map +1 -1
  449. package/.output/server/chunks/routes/api/workshop/users/me.get.mjs +1 -0
  450. package/.output/server/chunks/routes/api/workshop/users/me.get.mjs.map +1 -1
  451. package/.output/server/chunks/routes/api/workshop/users/register.post.mjs +1 -0
  452. package/.output/server/chunks/routes/api/workshop/users/register.post.mjs.map +1 -1
  453. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -0
  454. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs.map +1 -1
  455. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs +1 -0
  456. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs.map +1 -1
  457. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs +1 -0
  458. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs.map +1 -1
  459. package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs +1 -0
  460. package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs.map +1 -1
  461. package/.output/server/chunks/routes/renderer.mjs +1 -1
  462. package/.output/server/chunks/virtual/entry.mjs +287 -85
  463. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  464. package/.output/server/index.mjs +1 -0
  465. package/.output/server/package.json +1 -1
  466. package/README-zh.md +434 -430
  467. package/README.md +5 -1
  468. package/app/components/workshop/DeviceTwinPanel.vue +34 -0
  469. package/app/components/workshop/town/TownView.vue +5 -0
  470. package/app/composables/workshop/useDcwStream.ts +15 -1
  471. package/app/config/schema.ts +54 -0
  472. package/app/pages/dcw/[id].vue +57 -0
  473. package/app/pages/settings.vue +2 -1
  474. package/config.yml +58 -1
  475. package/i18n/dicts/_en.json +56 -2
  476. package/i18n/dicts/dcwDetail.json +9 -1
  477. package/i18n/dicts/deviceTwinPanel.json +2 -1
  478. package/i18n/dicts/settings.json +48 -1
  479. package/i18n/locales/en.ts +139 -38
  480. package/i18n/locales/zh-CN.ts +139 -38
  481. package/package.json +1 -1
  482. package/scripts/_dbg-agent-dcw-rw.ts +131 -0
  483. package/scripts/_dbg-config-smoke.ts +28 -0
  484. package/scripts/_dbg-dcw-read-rest.mjs +103 -0
  485. package/scripts/_dbg-dcw-read-toolface.ts +13 -0
  486. package/scripts/_dbg-dcw-read-ui.mjs +74 -0
  487. package/scripts/_dbg-plugin-ui-wizard.mjs +125 -0
  488. package/scripts/test-config-precedence.ts +124 -0
  489. package/scripts/test-dcw-read.ts +153 -0
  490. package/server/api/workshop/dcw/[id]/read.post.ts +18 -0
  491. package/server/api/workshop/ws.ts +6 -4
  492. package/server/data/daqs.json +55 -9
  493. package/server/data/dcw-rollback.json +221 -1
  494. package/server/data/dcw-runs.json +41 -18
  495. package/server/data/dcw-writes.json +264 -0
  496. package/server/data/dcws.json +646 -4
  497. package/server/data/line-runs.json +12 -1
  498. package/server/plugins/backup.ts +7 -5
  499. package/server/plugins/retention.ts +59 -57
  500. package/server/plugins/workshop.ts +5 -4
  501. package/server/services/workshop/agents/industrial-tools.ts +50 -1
  502. package/server/services/workshop/agents/omp-agent.ts +10 -8
  503. package/server/services/workshop/agents/tool-approvals.ts +175 -174
  504. package/server/services/workshop/daq/alarm-notify.ts +102 -100
  505. package/server/services/workshop/daq/bus/mqtt.adapter.ts +14 -15
  506. package/server/services/workshop/daq/storage/sqlite.adapter.ts +5 -4
  507. package/server/services/workshop/daq/storage/timescale.adapter.ts +5 -4
  508. package/server/services/workshop/db/retention.ts +49 -50
  509. package/server/services/workshop/dcw/dcw-controller.ts +56 -1
  510. package/server/services/workshop/dcw/dcw-node.ts +233 -200
  511. package/server/services/workshop/dcw/dcw-runtime.ts +46 -9
  512. package/server/services/workshop/dcw/drivers.ts +98 -0
  513. package/server/services/workshop/dcw/recipe-rollback-manager.ts +16 -15
  514. package/server/services/workshop/logger.ts +65 -58
  515. package/server/services/workshop/runtime/embedding-provider.ts +9 -5
  516. package/server/services/workshop/runtime/manager.ts +16 -7
  517. package/server/services/workshop/runtime/memory.ts +14 -7
  518. package/server/services/workshop/settings.ts +143 -0
  519. package/shared/config/engine.mjs +14 -2
  520. package/shared/config/schema.json +48 -1
  521. package/shared/dcw-protocol.ts +21 -0
  522. package/.output/public/_nuxt/BD9D9pl4.js +0 -1
  523. package/.output/public/_nuxt/BxD8Fg_Z.js +0 -2
  524. package/.output/public/_nuxt/CwcOEM8m.js +0 -1
  525. package/.output/public/_nuxt/TownView.CI2Wpzty.css +0 -1
  526. package/.output/public/_nuxt/_id_.Ci4u30cR.css +0 -1
  527. package/.output/public/_nuxt/builds/meta/221de779-a113-4232-b9a1-31a614f5e3c7.json +0 -1
  528. package/.output/public/_nuxt/settings.BG0K9_MG.css +0 -1
  529. package/.output/server/chunks/build/_id_-CmKAEFHV.mjs.map +0 -1
  530. package/.output/server/chunks/build/_id_-xR3AChMO.mjs.map +0 -1
  531. package/.output/server/chunks/build/daq-Boz_dlAQ.mjs.map +0 -1
  532. package/.output/server/chunks/build/dcw-wTRwBAUi.mjs.map +0 -1
  533. package/.output/server/chunks/build/logs-Cdi-eXlN.mjs.map +0 -1
  534. package/.output/server/chunks/build/pages-bWKy0ZsA.mjs.map +0 -1
  535. package/.output/server/chunks/build/settings-C3T5hR2A.mjs.map +0 -1
  536. package/.output/server/chunks/build/town-CKg6Qxba.mjs.map +0 -1
  537. package/.output/server/chunks/build/useDcwStream-BkWDGaWp.mjs.map +0 -1
@@ -1,200 +1,233 @@
1
- /**
2
- * DcwNode —— 数据写控制节点领域对象(与 DaqNode 对称)。
3
- *
4
- * 一个实例 = 一条工艺参数写通道:模板域(物理含义/单位/工艺安全量程)+ 驱动配置
5
- * (连接 + 工程量→原始值线性换算,系统封装)+ 绑定关系 + 写状态(value/lastAckAt/
6
- * writeState)。用户只操作工程量;PLC 原始值的换算/回读校验由运行时完成。
7
- * 序列化经 toRow/fromRow 对接持久化仓库(dcws.json)。
8
- */
9
-
10
- import { dcwKeyFromRef, type DcwDriverKind, type DcwNodeState, type DcwNodeView, type DataTransform } from '../../../../shared/dcw-protocol'
11
- import { findDcwTemplate } from './dcw-templates'
12
-
13
- interface DcwNodeOptions {
14
- id: string
15
- templateRef: string
16
- name?: string
17
- driver?: DcwDriverKind
18
- enabled?: boolean
19
- /** 保写周期 ms(心跳重下发;null = 仅手动下发) */
20
- holdIntervalMs?: number | null
21
- unit?: string
22
- decimals?: number
23
- min?: number
24
- max?: number
25
- deviceBindingId?: string | null
26
- driverConfig?: Record<string, string | number | boolean>
27
- /** 数据语义标定钩子(encode:物理值 → PLC 设定值;回读经 decoder 校验) */
28
- transform?: DataTransform
29
- posX?: number
30
- posZ?: number
31
- /** 所属产线('' = 未分配) */
32
- lineId?: string
33
- /** 节点级工艺语义备注(覆盖模板 semantics;注入 Agent 上下文) */
34
- semantics?: string
35
- createdAt?: string
36
- }
37
-
38
- export class DcwNode {
39
- readonly id: string
40
- templateRef: string
41
- name: string
42
- driver: DcwDriverKind
43
- enabled: boolean
44
- holdIntervalMs: number | null
45
- unit: string
46
- decimals: number
47
- min: number
48
- max: number
49
- deviceBindingId: string | null
50
- driverConfig: Record<string, string | number | boolean>
51
- transform?: DataTransform
52
- posX?: number
53
- posZ?: number
54
- /** 当前设定值(工程量;null = 从未下发) */
55
- value: number | null = null
56
- lastAckAt: string | null = null
57
- lastWriteAt: string | null = null
58
- state: DcwNodeState = 'idle'
59
- /** 所属产线('' = 未分配;采集门控/写联锁/场景光晕按产线隔离) */
60
- lineId = ''
61
- /** 节点级工艺语义备注(覆盖模板 semantics) */
62
- semantics?: string
63
- lastError: string | null = null
64
- readonly createdAt: string
65
-
66
- constructor(o: DcwNodeOptions) {
67
- const tpl = findDcwTemplate(dcwKeyFromRef(o.templateRef))
68
- this.id = o.id
69
- this.templateRef = o.templateRef
70
- this.name = o.name ?? (tpl ? `${tpl.name}` : '控制节点')
71
- this.driver = o.driver ?? 'mock'
72
- this.enabled = o.enabled ?? true
73
- this.holdIntervalMs = o.holdIntervalMs ?? null
74
- this.unit = o.unit ?? tpl?.unit ?? ''
75
- this.decimals = o.decimals ?? tpl?.decimals ?? 2
76
- this.min = o.min ?? tpl?.min ?? 0
77
- this.max = o.max ?? tpl?.max ?? 100
78
- this.deviceBindingId = o.deviceBindingId ?? null
79
- this.driverConfig = o.driverConfig ?? {}
80
- if (o.transform) this.transform = o.transform
81
- if (o.posX !== undefined) this.posX = o.posX
82
- if (o.posZ !== undefined) this.posZ = o.posZ
83
- this.lineId = o.lineId ?? ''
84
- this.semantics = o.semantics
85
- this.createdAt = o.createdAt ?? new Date().toISOString()
86
- }
87
-
88
- get templateKey(): string {
89
- return dcwKeyFromRef(this.templateRef)
90
- }
91
-
92
- /** 写入值工艺安全校验(越界即拒绝;返回错误消息或 null) */
93
- validateEng(v: number): string | null {
94
- if (!Number.isFinite(v)) return '设定值需为数字'
95
- if (v < this.min || v > this.max) {
96
- return `设定值 ${v}${this.unit} 越出工艺安全量程 [${this.min}, ${this.max}] ${this.unit}`
97
- }
98
- return null
99
- }
100
-
101
- /** 记录一次写 ACK(成功)/失败 */
102
- applyWriteResult(eng: number, ok: boolean, message: string, at: string): void {
103
- this.value = Number(eng.toFixed(this.decimals))
104
- this.lastWriteAt = at
105
- if (ok) {
106
- this.lastAckAt = at
107
- this.state = 'ok'
108
- this.lastError = null
109
- }
110
- else {
111
- this.state = 'error'
112
- this.lastError = message
113
- }
114
- }
115
-
116
- toRow(): Record<string, unknown> {
117
- return {
118
- id: this.id,
119
- templateRef: this.templateRef,
120
- name: this.name,
121
- driver: this.driver,
122
- enabled: this.enabled,
123
- holdIntervalMs: this.holdIntervalMs,
124
- unit: this.unit,
125
- decimals: this.decimals,
126
- min: this.min,
127
- max: this.max,
128
- deviceBindingId: this.deviceBindingId,
129
- driverConfig: this.driverConfig,
130
- transform: this.transform,
131
- posX: this.posX,
132
- posZ: this.posZ,
133
- lineId: this.lineId,
134
- semantics: this.semantics,
135
- value: this.value,
136
- lastAckAt: this.lastAckAt,
137
- lastWriteAt: this.lastWriteAt,
138
- state: this.state,
139
- lastError: this.lastError,
140
- createdAt: this.createdAt,
141
- }
142
- }
143
-
144
- static fromRow(row: Record<string, unknown>): DcwNode {
145
- const node = new DcwNode({
146
- id: String(row.id),
147
- templateRef: String(row.templateRef ?? ''),
148
- name: row.name != null ? String(row.name) : undefined,
149
- driver: (row.driver as DcwDriverKind) ?? undefined,
150
- enabled: row.enabled === undefined ? undefined : Boolean(row.enabled),
151
- holdIntervalMs: row.holdIntervalMs == null ? null : Number(row.holdIntervalMs),
152
- unit: row.unit != null ? String(row.unit) : undefined,
153
- decimals: row.decimals != null ? Number(row.decimals) : undefined,
154
- min: row.min != null ? Number(row.min) : undefined,
155
- max: row.max != null ? Number(row.max) : undefined,
156
- deviceBindingId: row.deviceBindingId === undefined ? undefined : (row.deviceBindingId == null ? null : String(row.deviceBindingId)),
157
- driverConfig: (row.driverConfig as Record<string, string | number | boolean>) ?? {},
158
- transform: (row.transform as DataTransform | undefined) ?? undefined,
159
- posX: row.posX == null ? undefined : Number(row.posX),
160
- lineId: row.lineId == null ? '' : String(row.lineId),
161
- semantics: row.semantics == null ? undefined : String(row.semantics),
162
- posZ: row.posZ == null ? undefined : Number(row.posZ),
163
- createdAt: row.createdAt != null ? String(row.createdAt) : undefined,
164
- })
165
- if (row.value != null && !Number.isNaN(Number(row.value))) node.value = Number(row.value)
166
- if (row.lastAckAt != null) node.lastAckAt = String(row.lastAckAt)
167
- if (row.lastWriteAt != null) node.lastWriteAt = String(row.lastWriteAt)
168
- if (row.state != null) node.state = String(row.state) as DcwNodeState
169
- if (row.lastError != null) node.lastError = String(row.lastError)
170
- return node
171
- }
172
-
173
- toView(): DcwNodeView {
174
- return {
175
- id: this.id,
176
- templateRef: this.templateRef,
177
- name: this.name,
178
- driver: this.driver,
179
- enabled: this.enabled,
180
- holdIntervalMs: this.holdIntervalMs,
181
- unit: this.unit,
182
- decimals: this.decimals,
183
- min: this.min,
184
- max: this.max,
185
- deviceBindingId: this.deviceBindingId,
186
- driverConfig: this.driverConfig,
187
- transform: this.transform,
188
- posX: this.posX,
189
- posZ: this.posZ,
190
- lineId: this.lineId,
191
- semantics: this.semantics,
192
- value: this.value,
193
- lastAckAt: this.lastAckAt,
194
- lastWriteAt: this.lastWriteAt,
195
- state: this.state,
196
- lastError: this.lastError,
197
- createdAt: this.createdAt,
198
- }
199
- }
200
- }
1
+ /**
2
+ * DcwNode —— 数据写控制节点领域对象(与 DaqNode 对称)。
3
+ *
4
+ * 一个实例 = 一条工艺参数写通道:模板域(物理含义/单位/工艺安全量程)+ 驱动配置
5
+ * (连接 + 工程量→原始值线性换算,系统封装)+ 绑定关系 + 写状态(value/lastAckAt/
6
+ * writeState)。用户只操作工程量;PLC 原始值的换算/回读校验由运行时完成。
7
+ * 序列化经 toRow/fromRow 对接持久化仓库(dcws.json)。
8
+ */
9
+
10
+ import { dcwKeyFromRef, type DcwDriverKind, type DcwNodeState, type DcwNodeView, type DataTransform } from '../../../../shared/dcw-protocol'
11
+ import { findDcwTemplate } from './dcw-templates'
12
+
13
+ interface DcwNodeOptions {
14
+ id: string
15
+ templateRef: string
16
+ name?: string
17
+ driver?: DcwDriverKind
18
+ enabled?: boolean
19
+ /** 保写周期 ms(心跳重下发;null = 仅手动下发) */
20
+ holdIntervalMs?: number | null
21
+ unit?: string
22
+ decimals?: number
23
+ min?: number
24
+ max?: number
25
+ deviceBindingId?: string | null
26
+ driverConfig?: Record<string, string | number | boolean>
27
+ /** 数据语义标定钩子(encode:物理值 → PLC 设定值;回读经 decoder 校验) */
28
+ transform?: DataTransform
29
+ posX?: number
30
+ posZ?: number
31
+ /** 所属产线('' = 未分配) */
32
+ lineId?: string
33
+ /** 节点级工艺语义备注(覆盖模板 semantics;注入 Agent 上下文) */
34
+ semantics?: string
35
+ /** 周期读间隔 ms(null = 走网关默认;0 = 关闭周期读,仅手动读取) */
36
+ readIntervalMs?: number | null
37
+ createdAt?: string
38
+ }
39
+
40
+ export class DcwNode {
41
+ readonly id: string
42
+ templateRef: string
43
+ name: string
44
+ driver: DcwDriverKind
45
+ enabled: boolean
46
+ holdIntervalMs: number | null
47
+ unit: string
48
+ decimals: number
49
+ min: number
50
+ max: number
51
+ deviceBindingId: string | null
52
+ driverConfig: Record<string, string | number | boolean>
53
+ transform?: DataTransform
54
+ posX?: number
55
+ posZ?: number
56
+ /** 当前设定值(工程量;null = 从未下发) */
57
+ value: number | null = null
58
+ /** PLC 当前读数(工程量物理值;null = 从未读到或驱动不支持读) */
59
+ readValue: number | null = null
60
+ lastReadAt: string | null = null
61
+ lastReadError: string | null = null
62
+ /** 周期读间隔 ms(null = 走网关默认;0 = 仅手动读取) */
63
+ readIntervalMs: number | null = null
64
+ lastAckAt: string | null = null
65
+ lastWriteAt: string | null = null
66
+ state: DcwNodeState = 'idle'
67
+ /** 所属产线('' = 未分配;采集门控/写联锁/场景光晕按产线隔离) */
68
+ lineId = ''
69
+ /** 节点级工艺语义备注(覆盖模板 semantics) */
70
+ semantics?: string
71
+ lastError: string | null = null
72
+ readonly createdAt: string
73
+
74
+ constructor(o: DcwNodeOptions) {
75
+ const tpl = findDcwTemplate(dcwKeyFromRef(o.templateRef))
76
+ this.id = o.id
77
+ this.templateRef = o.templateRef
78
+ this.name = o.name ?? (tpl ? `${tpl.name}` : '控制节点')
79
+ this.driver = o.driver ?? 'mock'
80
+ this.enabled = o.enabled ?? true
81
+ this.holdIntervalMs = o.holdIntervalMs ?? null
82
+ this.unit = o.unit ?? tpl?.unit ?? ''
83
+ this.decimals = o.decimals ?? tpl?.decimals ?? 2
84
+ this.min = o.min ?? tpl?.min ?? 0
85
+ this.max = o.max ?? tpl?.max ?? 100
86
+ this.deviceBindingId = o.deviceBindingId ?? null
87
+ this.driverConfig = o.driverConfig ?? {}
88
+ if (o.transform) this.transform = o.transform
89
+ if (o.posX !== undefined) this.posX = o.posX
90
+ if (o.posZ !== undefined) this.posZ = o.posZ
91
+ this.lineId = o.lineId ?? ''
92
+ this.semantics = o.semantics
93
+ this.readIntervalMs = o.readIntervalMs ?? null
94
+ this.createdAt = o.createdAt ?? new Date().toISOString()
95
+ }
96
+
97
+ get templateKey(): string {
98
+ return dcwKeyFromRef(this.templateRef)
99
+ }
100
+
101
+ /** 写入值工艺安全校验(越界即拒绝;返回错误消息或 null) */
102
+ validateEng(v: number): string | null {
103
+ if (!Number.isFinite(v)) return '设定值需为数字'
104
+ if (v < this.min || v > this.max) {
105
+ return `设定值 ${v}${this.unit} 越出工艺安全量程 [${this.min}, ${this.max}] ${this.unit}`
106
+ }
107
+ return null
108
+ }
109
+
110
+ /** 记录一次写 ACK(成功)/失败 */
111
+ applyWriteResult(eng: number, ok: boolean, message: string, at: string): void {
112
+ this.value = Number(eng.toFixed(this.decimals))
113
+ this.lastWriteAt = at
114
+ if (ok) {
115
+ this.lastAckAt = at
116
+ this.state = 'ok'
117
+ this.lastError = null
118
+ }
119
+ else {
120
+ this.state = 'error'
121
+ this.lastError = message
122
+ }
123
+ }
124
+
125
+ /** 记录一次读数(成功回填物理值;失败仅记原因,旧读数保留供展示) */
126
+ applyReadResult(eng: number | null, raw: number | null, ok: boolean, message: string, at: string): void {
127
+ this.lastReadAt = at
128
+ if (ok && eng != null) {
129
+ this.readValue = Number(eng.toFixed(this.decimals))
130
+ this.lastReadError = null
131
+ }
132
+ else {
133
+ this.lastReadError = message
134
+ }
135
+ }
136
+
137
+ toRow(): Record<string, unknown> {
138
+ return {
139
+ id: this.id,
140
+ templateRef: this.templateRef,
141
+ name: this.name,
142
+ driver: this.driver,
143
+ enabled: this.enabled,
144
+ holdIntervalMs: this.holdIntervalMs,
145
+ readIntervalMs: this.readIntervalMs,
146
+ unit: this.unit,
147
+ decimals: this.decimals,
148
+ min: this.min,
149
+ max: this.max,
150
+ deviceBindingId: this.deviceBindingId,
151
+ driverConfig: this.driverConfig,
152
+ transform: this.transform,
153
+ posX: this.posX,
154
+ posZ: this.posZ,
155
+ lineId: this.lineId,
156
+ semantics: this.semantics,
157
+ value: this.value,
158
+ readValue: this.readValue,
159
+ lastReadAt: this.lastReadAt,
160
+ lastReadError: this.lastReadError,
161
+ lastAckAt: this.lastAckAt,
162
+ lastWriteAt: this.lastWriteAt,
163
+ state: this.state,
164
+ lastError: this.lastError,
165
+ createdAt: this.createdAt,
166
+ }
167
+ }
168
+
169
+ static fromRow(row: Record<string, unknown>): DcwNode {
170
+ const node = new DcwNode({
171
+ id: String(row.id),
172
+ templateRef: String(row.templateRef ?? ''),
173
+ name: row.name != null ? String(row.name) : undefined,
174
+ driver: (row.driver as DcwDriverKind) ?? undefined,
175
+ enabled: row.enabled === undefined ? undefined : Boolean(row.enabled),
176
+ holdIntervalMs: row.holdIntervalMs == null ? null : Number(row.holdIntervalMs),
177
+ unit: row.unit != null ? String(row.unit) : undefined,
178
+ decimals: row.decimals != null ? Number(row.decimals) : undefined,
179
+ min: row.min != null ? Number(row.min) : undefined,
180
+ max: row.max != null ? Number(row.max) : undefined,
181
+ deviceBindingId: row.deviceBindingId === undefined ? undefined : (row.deviceBindingId == null ? null : String(row.deviceBindingId)),
182
+ driverConfig: (row.driverConfig as Record<string, string | number | boolean>) ?? {},
183
+ transform: (row.transform as DataTransform | undefined) ?? undefined,
184
+ posX: row.posX == null ? undefined : Number(row.posX),
185
+ lineId: row.lineId == null ? '' : String(row.lineId),
186
+ semantics: row.semantics == null ? undefined : String(row.semantics),
187
+ readIntervalMs: row.readIntervalMs == null ? null : Number(row.readIntervalMs),
188
+ posZ: row.posZ == null ? undefined : Number(row.posZ),
189
+ createdAt: row.createdAt != null ? String(row.createdAt) : undefined,
190
+ })
191
+ if (row.value != null && !Number.isNaN(Number(row.value))) node.value = Number(row.value)
192
+ if (row.readValue != null && !Number.isNaN(Number(row.readValue))) node.readValue = Number(row.readValue)
193
+ if (row.lastReadAt != null) node.lastReadAt = String(row.lastReadAt)
194
+ if (row.lastReadError != null) node.lastReadError = String(row.lastReadError)
195
+ if (row.lastAckAt != null) node.lastAckAt = String(row.lastAckAt)
196
+ if (row.lastWriteAt != null) node.lastWriteAt = String(row.lastWriteAt)
197
+ if (row.state != null) node.state = String(row.state) as DcwNodeState
198
+ if (row.lastError != null) node.lastError = String(row.lastError)
199
+ return node
200
+ }
201
+
202
+ toView(): DcwNodeView {
203
+ return {
204
+ id: this.id,
205
+ templateRef: this.templateRef,
206
+ name: this.name,
207
+ driver: this.driver,
208
+ enabled: this.enabled,
209
+ holdIntervalMs: this.holdIntervalMs,
210
+ unit: this.unit,
211
+ decimals: this.decimals,
212
+ min: this.min,
213
+ max: this.max,
214
+ deviceBindingId: this.deviceBindingId,
215
+ driverConfig: this.driverConfig,
216
+ transform: this.transform,
217
+ posX: this.posX,
218
+ posZ: this.posZ,
219
+ lineId: this.lineId,
220
+ semantics: this.semantics,
221
+ value: this.value,
222
+ readValue: this.readValue,
223
+ lastReadAt: this.lastReadAt,
224
+ lastReadError: this.lastReadError,
225
+ readIntervalMs: this.readIntervalMs,
226
+ lastAckAt: this.lastAckAt,
227
+ lastWriteAt: this.lastWriteAt,
228
+ state: this.state,
229
+ lastError: this.lastError,
230
+ createdAt: this.createdAt,
231
+ }
232
+ }
233
+ }
@@ -27,23 +27,37 @@ export interface DcwWriteOutcome {
27
27
 
28
28
  export interface DcwRuntimeHost {
29
29
  running(): boolean
30
- defaults(): { holdIntervalMs: number }
30
+ defaults(): { holdIntervalMs: number, readIntervalMs: number }
31
31
  /** 网关执行写命令(驱动写 + ACK 记账 + 写历史 + WS 广播) */
32
32
  executeWrite(node: DcwNode, eng: number, tolerance: number, recipeRunId: string | null): Promise<DcwWriteOutcome>
33
+ /** 网关执行读数(驱动读 + 读状态记账 + WS 广播;返回物理值) */
34
+ executeRead(node: DcwNode): Promise<{ ok: boolean, value: number | null, raw: number | null, message: string, at: string }>
35
+ }
36
+
37
+ export interface DcwReadOutcome {
38
+ ok: boolean
39
+ value: number | null
40
+ raw: number | null
41
+ message: string
42
+ at: string
33
43
  }
34
44
 
35
45
  export class DcwNodeRuntime {
36
46
  private writing = false
37
47
  private lastHoldAt = 0
48
+ /** 周期读节拍 + 在飞互斥(读事务不与写事务互斥,但同节点读不重入) */
49
+ private lastReadTick = 0
50
+ private reading = false
38
51
 
39
52
  constructor(
40
53
  public readonly node: DcwNode,
41
54
  private readonly host: DcwRuntimeHost,
42
55
  ) {}
43
56
 
44
- /** 元数据变更后重置保写节拍 */
57
+ /** 元数据变更后重置保写/周期读节拍 */
45
58
  rearm(): void {
46
59
  this.lastHoldAt = 0
60
+ this.lastReadTick = 0
47
61
  }
48
62
 
49
63
  /**
@@ -69,14 +83,37 @@ export class DcwNodeRuntime {
69
83
  }
70
84
 
71
85
  /** 网关 tick:保写心跳(元数据 holdIntervalMs;null = 仅手动下发)。
72
- * 对当前设定值周期性重下发(PLC 掉电重启后的设定恢复语义)。 */
86
+ * 对当前设定值周期性重下发(PLC 掉电重启后的设定恢复语义)。
87
+ * 周期读(元数据 readIntervalMs):读是被动观测,不受产线运行/写在飞限制
88
+ * (仅与在飞读互斥),failures 只记 lastReadError 不改写状态机。 */
73
89
  tick(now: number): void {
74
90
  const node = this.node
75
- if (this.writing || !node.enabled || node.value == null || node.state === 'writing') return
76
- const hold = node.holdIntervalMs ?? this.host.defaults().holdIntervalMs
77
- if (!hold || hold <= 0) return
78
- if (now - this.lastHoldAt < hold) return
79
- this.lastHoldAt = now
80
- void this.host.executeWrite(node, node.value, writeTolerance(node), null).catch(() => {})
91
+ // 保写心跳:仅对已设定过的节点生效(尚无设定值无可保持)
92
+ if (!this.writing && node.enabled && node.value != null && node.state !== 'writing') {
93
+ const hold = node.holdIntervalMs ?? this.host.defaults().holdIntervalMs
94
+ if (hold && hold > 0 && now - this.lastHoldAt >= hold) {
95
+ this.lastHoldAt = now
96
+ void this.host.executeWrite(node, node.value, writeTolerance(node), null).catch(() => {})
97
+ }
98
+ }
99
+ // 周期读:被动观测,不依赖写过、不与写在飞互斥(仅同节点读串行)
100
+ if (this.reading || !node.enabled) return
101
+ const readInt = node.readIntervalMs ?? this.host.defaults().readIntervalMs
102
+ if (!readInt || readInt <= 0) return
103
+ if (now - this.lastReadTick < readInt) return
104
+ this.lastReadTick = now
105
+ void this.host.executeRead(node).catch(() => {})
106
+ }
107
+
108
+ /** 手动读取(on-demand;REST/Agent 工具共用;与周期读同一在飞互斥) */
109
+ async readNow(): Promise<DcwReadOutcome> {
110
+ if (this.reading) throw new AppError(409, ErrorCodes.CONFLICT, `通道「${this.node.name}」读取进行中,请稍后重试`)
111
+ this.reading = true
112
+ try {
113
+ return await this.host.executeRead(this.node)
114
+ }
115
+ finally {
116
+ this.reading = false
117
+ }
81
118
  }
82
119
  }
@@ -38,6 +38,28 @@ export interface DcwWriteDriver {
38
38
  available(): Promise<boolean>
39
39
  write(input: DcwWriteInput): Promise<DcwWriteResult>
40
40
  test(driverConfig: Record<string, unknown>): Promise<{ ok: boolean, message: string }>
41
+ /** 读当前 PLC 值(可选原语;不支持读的驱动为 undefined,网关按 supportsRead 收敛) */
42
+ read?(input: DcwReadInput): Promise<DcwReadResult>
43
+ }
44
+
45
+ export interface DcwReadInput {
46
+ /** 节点工艺量程(原始值↔工程量映射缺省域) */
47
+ domain: { min: number, max: number }
48
+ driverConfig: Record<string, unknown>
49
+ }
50
+
51
+ export interface DcwReadResult {
52
+ ok: boolean
53
+ message: string
54
+ /** 工程量(PLC 语义;寄存器驱动 = 原始值解码后映射,直写型驱动 = 节点值本身) */
55
+ eng: number | null
56
+ /** 原始值(寄存器解码;非寄存器驱动与 eng 同源) */
57
+ raw: number | null
58
+ }
59
+
60
+ /** 读能力判定(网关调度周期读前先收敛,不支持读的驱动不空转) */
61
+ export function supportsDcwRead(kind: DcwDriverKind): boolean {
62
+ return resolveDcwDriver(kind).read != null
41
63
  }
42
64
 
43
65
  const num = (v: unknown): number | undefined => {
@@ -111,11 +133,53 @@ export const mockDcwDriver: DcwWriteDriver = {
111
133
  readback: input.eng,
112
134
  }
113
135
  },
136
+ async read(input) {
137
+ const key = `${input.driverConfig.key ?? 'default'}`
138
+ const has = mockState.__dcwMockPlc!.has(key)
139
+ const eng = mockState.__dcwMockPlc!.get(key) ?? null
140
+ return has
141
+ ? { ok: true, message: `Mock PLC 读回:${eng}`, eng, raw: eng }
142
+ : { ok: false, message: `Mock PLC 无设定记录(${key};从未写入)`, eng: null, raw: null }
143
+ },
114
144
  async test() {
115
145
  return { ok: true, message: 'Mock 驱动无需连接,写入即模拟 ACK' }
116
146
  },
117
147
  }
118
148
 
149
+ // ============================================================
150
+ // Modbus 读原语(TCP/RTU 共用;读保持寄存器 → 解码 → 工程量映射)
151
+ // ============================================================
152
+
153
+ function wordsOf(dataType: string): number {
154
+ return dataType === 'int16' || dataType === 'uint16' ? 1 : 2
155
+ }
156
+
157
+ async function modbusRead(input: DcwReadInput, transport: 'tcp' | 'rtu-tcp'): Promise<DcwReadResult> {
158
+ const cfg = input.driverConfig
159
+ if (!cfg.host) throw new AppError(400, 'BAD_REQUEST', '缺少设备地址 host')
160
+ if (cfg.register == null) throw new AppError(400, 'BAD_REQUEST', '缺少寄存器地址 register')
161
+ const dataType = String(cfg.dataType ?? 'float32')
162
+ const byteOrder = String(cfg.byteOrder ?? 'big')
163
+ const offset = registerOffset(Number(cfg.register ?? 0), 'holding')
164
+ const conn = await getModbusConn(cfg, transport)
165
+ conn.lastUsed = Date.now()
166
+ return withModbusConn(conn, async (): Promise<DcwReadResult> => {
167
+ try {
168
+ const rb = await conn.client.readHoldingRegisters(offset, wordsOf(dataType))
169
+ const raw = decodeRegisters(rb.data as number[], dataType, byteOrder)
170
+ // 原始值 → 工程量(与写链路同一映射;engToRaw/rawToEng 对称)
171
+ const eng = rawToEng(raw, { eng: 0, tolerance: 0, domain: input.domain, driverConfig: cfg })
172
+ conn.errors = 0
173
+ return { ok: true, message: `读回 raw ${Number(raw.toFixed(4))} → eng ${Number(eng.toFixed(4))}`, eng, raw }
174
+ }
175
+ catch (err) {
176
+ conn.errors++
177
+ if (conn.errors >= 3) evictModbusConn(cfg, transport)
178
+ throw err
179
+ }
180
+ })
181
+ }
182
+
119
183
  // ============================================================
120
184
  // Modbus TCP 写驱动(写保持寄存器 + 同址回读校验;连接池复用数采)
121
185
  // ============================================================
@@ -183,6 +247,14 @@ export const modbusTcpDcwDriver: DcwWriteDriver = {
183
247
  return { ok: false, message: `Modbus 写入失败: ${err instanceof Error ? err.message : String(err)}`, raw: null, readback: null }
184
248
  }
185
249
  },
250
+ async read(input) {
251
+ try {
252
+ return await modbusRead(input, 'tcp')
253
+ }
254
+ catch (err) {
255
+ return { ok: false, message: `Modbus 读取失败: ${err instanceof Error ? err.message : String(err)}`, eng: null, raw: null }
256
+ }
257
+ },
186
258
  async test(driverConfig) {
187
259
  const t0 = Date.now()
188
260
  try {
@@ -258,6 +330,24 @@ export const opcUaDcwDriver: DcwWriteDriver = {
258
330
  return { ok: false, message: `OPC UA 写入失败: ${err instanceof Error ? err.message : String(err)}`, raw: null, readback: null }
259
331
  }
260
332
  },
333
+ async read(input) {
334
+ try {
335
+ const cfg = input.driverConfig
336
+ if (!cfg.endpoint) throw new AppError(400, 'BAD_REQUEST', '缺少端点 endpoint(opc.tcp://…)')
337
+ if (!cfg.nodeId) throw new AppError(400, 'BAD_REQUEST', '缺少节点 ID nodeId(ns=…;s=…)')
338
+ const conn = await getOpcUaConn(cfg)
339
+ const opcua = reqNative('node-opcua') as typeof import('node-opcua')
340
+ const dv = await conn.session.read({ nodeId: opcua.coerceNodeId(String(cfg.nodeId)), attributeId: opcua.AttributeIds.Value }) as unknown as { value?: { value?: unknown }, status?: { value?: number }, statusCode?: { value?: number } }
341
+ const code = dv.status?.value ?? dv.statusCode?.value ?? 0
342
+ if (code !== 0) return { ok: false, message: `节点读取状态异常: 0x${code.toString(16)}`, eng: null, raw: null }
343
+ const v = Number(dv.value?.value)
344
+ if (!Number.isFinite(v)) return { ok: false, message: '节点值为非数值', eng: null, raw: null }
345
+ return { ok: true, message: `读回 ${Number(v.toFixed(4))}`, eng: v, raw: v }
346
+ }
347
+ catch (err) {
348
+ return { ok: false, message: `OPC UA 读取失败: ${err instanceof Error ? err.message : String(err)}`, eng: null, raw: null }
349
+ }
350
+ },
261
351
  async test(driverConfig) {
262
352
  try {
263
353
  if (!driverConfig.endpoint) return { ok: false, message: '缺少端点 endpoint(opc.tcp://…)' }
@@ -336,6 +426,14 @@ export const modbusRtuDcwDriver: DcwWriteDriver = {
336
426
  return { ok: false, message: `Modbus RTU 写入失败: ${err instanceof Error ? err.message : String(err)}`, raw: null, readback: null }
337
427
  }
338
428
  },
429
+ async read(input) {
430
+ try {
431
+ return await modbusRead(input, 'rtu-tcp')
432
+ }
433
+ catch (err) {
434
+ return { ok: false, message: `Modbus RTU 读取失败: ${err instanceof Error ? err.message : String(err)}`, eng: null, raw: null }
435
+ }
436
+ },
339
437
  async test(driverConfig) {
340
438
  const t0 = Date.now()
341
439
  try {