agentworkshop 0.8.5 → 0.8.6

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 (349) hide show
  1. package/.AgentWorkShop/prompts/host-tools.en.json +3 -3
  2. package/.AgentWorkShop/prompts/host-tools.json +14 -4
  3. package/.output/.AgentWorkShop/prompts/host-tools.en.json +3 -3
  4. package/.output/.AgentWorkShop/prompts/host-tools.json +14 -4
  5. package/.output/nitro.json +1 -1
  6. package/.output/public/_nuxt/{U_n8pryv2.js → 7op-BMk82.js} +1 -1
  7. package/.output/public/_nuxt/{zWZ26UWi.js → B1SIgyrl.js} +1 -1
  8. package/.output/public/_nuxt/{C4tXwpSt.js → BA2lmfW4.js} +1 -1
  9. package/.output/public/_nuxt/{EJkmXP432.js → BDXQqSkl2.js} +1 -1
  10. package/.output/public/_nuxt/{CY_7u1ST2.js → BI9jj13f2.js} +1 -1
  11. package/.output/public/_nuxt/{CGf9neEK2.js → BiXqyYNw2.js} +1 -1
  12. package/.output/public/_nuxt/{D9GoOkyP2.js → BlOm8JIs2.js} +1 -1
  13. package/.output/public/_nuxt/{CQ31GiJU2.js → BoXKUOiN2.js} +1 -1
  14. package/.output/public/_nuxt/{DZzbCFY2.js → BuLoPmcf.js} +1 -1
  15. package/.output/public/_nuxt/{D9ppMCbw.js → BwOK42JQ.js} +1 -1
  16. package/.output/public/_nuxt/{CZJ5cw6r2.js → C1RMfPoB2.js} +1 -1
  17. package/.output/public/_nuxt/{CGviZq4E.js → COfo_Bg3.js} +1 -1
  18. package/.output/public/_nuxt/CTGJHZ8X2.js +1 -0
  19. package/.output/public/_nuxt/{SgsmmrsZ.js → CY2NkFvI.js} +1 -1
  20. package/.output/public/_nuxt/{B4GOTVfN.js → C_4mzQ5X.js} +1 -1
  21. package/.output/public/_nuxt/{DGmFHb7m.js → CdvMP3lv.js} +1 -1
  22. package/.output/public/_nuxt/{iqxZGXsY.js → CooauJ7D.js} +1 -1
  23. package/.output/public/_nuxt/{C3vxePED.js → D1eVi1zr.js} +1 -1
  24. package/.output/public/_nuxt/{DnuJ66Jy.js → D6PUmBb0.js} +1 -1
  25. package/.output/public/_nuxt/{BBhroEeN.js → DC8sMA36.js} +1 -1
  26. package/.output/public/_nuxt/{DOUuGOQR2.js → DDHh85c42.js} +1 -1
  27. package/.output/public/_nuxt/{Cy_HDgSl.js → DDXOfmo2.js} +2 -2
  28. package/.output/public/_nuxt/{Cr2xJ_CY.js → DMFwLxfu.js} +1 -1
  29. package/.output/public/_nuxt/{BZg_MIK42.js → DoprKJ5a2.js} +1 -1
  30. package/.output/public/_nuxt/{BzBBEE-o2.js → Dr1FVeQG2.js} +1 -1
  31. package/.output/public/_nuxt/{W0sNnJQh.js → DtnsTW7e.js} +1 -1
  32. package/.output/public/_nuxt/{gUYi1hLJ2.js → DxDqd6T42.js} +1 -1
  33. package/.output/public/_nuxt/{B0UUODeh.js → DzU3zEKX.js} +1 -1
  34. package/.output/public/_nuxt/{BkO5WdX5.js → EgO70wrE.js} +1 -1
  35. package/.output/public/_nuxt/{7OZQiw002.js → HJKu4eEV2.js} +1 -1
  36. package/.output/public/_nuxt/{ChF6qLpY2.js → K5Xen0wZ2.js} +1 -1
  37. package/.output/public/_nuxt/{CNrRZmSx2.js → Rb4o4o-82.js} +1 -1
  38. package/.output/public/_nuxt/{BqBTlfiz.js → Tf6SJSDj.js} +1 -1
  39. package/.output/public/_nuxt/{DJaGVY4v2.js → ZzOyoXex2.js} +1 -1
  40. package/.output/public/_nuxt/{PbzVdCTA2.js → azOGy_tU2.js} +1 -1
  41. package/.output/public/_nuxt/{D1thFC3z.js → be-4wyTo.js} +1 -1
  42. package/.output/public/_nuxt/builds/latest.json +1 -1
  43. package/.output/public/_nuxt/builds/meta/593b65bd-cf1d-4b7f-a993-57e939c38f36.json +1 -0
  44. package/.output/public/_nuxt/{8b9CKi6F.js → dcjPjLPI.js} +1 -1
  45. package/.output/public/_nuxt/{ae2-5ZPt.js → h-Fn7pRD.js} +1 -1
  46. package/.output/public/_nuxt/{-gy9k_TE2.js → hyLdZsOd2.js} +1 -1
  47. package/.output/public/_nuxt/{BHxG41IQ2.js → o8sYG6xx2.js} +1 -1
  48. package/.output/server/chunks/_/access.mjs +1 -1
  49. package/.output/server/chunks/_/agent-dto.mjs +26 -0
  50. package/.output/server/chunks/_/agent-dto.mjs.map +1 -0
  51. package/.output/server/chunks/_/data-export.mjs +6 -6
  52. package/.output/server/chunks/_/data-query.mjs +3 -3
  53. package/.output/server/chunks/_/eda-run.repo.mjs +2 -2
  54. package/.output/server/chunks/_/features.mjs +5 -5
  55. package/.output/server/chunks/_/golden.mjs +3 -3
  56. package/.output/server/chunks/_/harness-spawn-policy.mjs +77 -0
  57. package/.output/server/chunks/_/harness-spawn-policy.mjs.map +1 -0
  58. package/.output/server/chunks/_/index.mjs +1 -1
  59. package/.output/server/chunks/_/line-scope.mjs +32 -0
  60. package/.output/server/chunks/_/line-scope.mjs.map +1 -0
  61. package/.output/server/chunks/_/mes-console.mjs +1 -1
  62. package/.output/server/chunks/_/nitro.mjs +2429 -1726
  63. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  64. package/.output/server/chunks/_/ocap.mjs +1 -1
  65. package/.output/server/chunks/_/rest-auth.mjs +1 -1
  66. package/.output/server/chunks/_/spc.mjs +1 -1
  67. package/.output/server/chunks/build/TownView-BWMDbosY.mjs +1 -1
  68. package/.output/server/chunks/build/daq-CdxcfY_G.mjs +1 -1
  69. package/.output/server/chunks/build/dcw-BlDQtS4q.mjs +1 -1
  70. package/.output/server/chunks/build/types-D6J7slEa.mjs +1 -1
  71. package/.output/server/chunks/build/useDaqAddNode-D_Rkju0f.mjs +1 -1
  72. package/.output/server/chunks/build/useDaqDetailNode-DeOsDxK5.mjs +1 -1
  73. package/.output/server/chunks/build/useDaqDetailParams-Cm9a9r5G.mjs +1 -1
  74. package/.output/server/chunks/build/useDaqFilters-CctmO03p.mjs +1 -1
  75. package/.output/server/chunks/build/useDaqStream-B9ZBVQrI.mjs +1 -1
  76. package/.output/server/chunks/build/useDaqTemplates-CK37sMfi.mjs +1 -1
  77. package/.output/server/chunks/build/useDcwAddNode-DACVcEHs.mjs +1 -1
  78. package/.output/server/chunks/build/useDcwStream-Dir5ufAU.mjs +1 -1
  79. package/.output/server/chunks/routes/api/mcp/workshop.mjs +1 -1
  80. package/.output/server/chunks/routes/api/system/backup/run.post.mjs +2 -2
  81. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +17 -9
  82. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs.map +1 -1
  83. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +3 -0
  84. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs.map +1 -1
  85. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  86. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +6 -0
  87. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs.map +1 -1
  88. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +5 -0
  89. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs.map +1 -1
  90. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +5 -2
  91. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs.map +1 -1
  92. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +7 -1
  93. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs.map +1 -1
  94. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +3 -1
  95. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs.map +1 -1
  96. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +8 -6
  97. package/.output/server/chunks/routes/api/workshop/channels.post.mjs.map +1 -1
  98. package/.output/server/chunks/routes/api/workshop/daq/_id/ingest.post.mjs +29 -49
  99. package/.output/server/chunks/routes/api/workshop/daq/_id/ingest.post.mjs.map +1 -1
  100. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +1 -1
  101. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +6 -1
  102. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs.map +1 -1
  103. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +4 -2
  104. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs.map +1 -1
  105. package/.output/server/chunks/routes/api/workshop/daq/index2.post.mjs +1 -1
  106. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +14 -5
  107. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs.map +1 -1
  108. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +1 -1
  109. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +1 -1
  110. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +1 -1
  111. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +7 -4
  112. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs.map +1 -1
  113. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +1 -1
  114. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +1 -1
  115. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +6 -2
  116. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs.map +1 -1
  117. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +6 -2
  118. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs.map +1 -1
  119. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +1 -1
  120. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +1 -1
  121. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +1 -1
  122. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +6 -1
  123. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs.map +1 -1
  124. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +1 -1
  125. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +7 -4
  126. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs.map +1 -1
  127. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -1
  128. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +1 -1
  129. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +1 -1
  130. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +6 -2
  131. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs.map +1 -1
  132. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +1 -1
  133. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +7 -4
  134. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs.map +1 -1
  135. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
  136. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +1 -1
  137. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +1 -1
  138. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +6 -2
  139. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs.map +1 -1
  140. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +1 -1
  141. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +1 -1
  142. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  143. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  144. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
  145. package/.output/server/chunks/routes/api/workshop/dcw/mes-artifacts/file.get.mjs +6 -2
  146. package/.output/server/chunks/routes/api/workshop/dcw/mes-artifacts/file.get.mjs.map +1 -1
  147. package/.output/server/chunks/routes/api/workshop/dcw/mes-hook-test.post.mjs +1 -1
  148. package/.output/server/chunks/routes/api/workshop/dcw/mes-test-read.post.mjs +1 -1
  149. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +1 -1
  150. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +1 -1
  151. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +6 -2
  152. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs.map +1 -1
  153. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +4 -2
  154. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs.map +1 -1
  155. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +5 -2
  156. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs.map +1 -1
  157. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +1 -1
  158. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +1 -1
  159. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +1 -1
  160. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +1 -1
  161. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +1 -1
  162. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +1 -1
  163. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +1 -1
  164. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs +7 -3
  165. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs.map +1 -1
  166. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +8 -1
  167. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs.map +1 -1
  168. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +6 -2
  169. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs.map +1 -1
  170. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
  171. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +1 -1
  172. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  173. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  174. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +7 -4
  175. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs.map +1 -1
  176. package/.output/server/chunks/routes/api/workshop/eda/commonality.get.mjs +1 -1
  177. package/.output/server/chunks/routes/api/workshop/eda/vm/predict.post.mjs +1 -1
  178. package/.output/server/chunks/routes/api/workshop/exp/confirmations/_id/decide.post.mjs +1 -1
  179. package/.output/server/chunks/routes/api/workshop/exp/index.get.mjs +1 -1
  180. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +1 -1
  181. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  182. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  183. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  184. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  185. package/.output/server/chunks/routes/api/workshop/index.mjs +1 -1
  186. package/.output/server/chunks/routes/api/workshop/index.post.mjs +2 -0
  187. package/.output/server/chunks/routes/api/workshop/index.post.mjs.map +1 -1
  188. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  189. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +8 -3
  190. package/.output/server/chunks/routes/api/workshop/index3.post.mjs.map +1 -1
  191. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +1 -1
  192. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +1 -1
  193. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +1 -1
  194. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +1 -1
  195. package/.output/server/chunks/routes/api/workshop/mes/datasets.get.mjs +1 -1
  196. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/autofix.mjs +1 -1
  197. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/compile.mjs +1 -1
  198. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/evidence.mjs +1 -1
  199. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/publish.mjs +1 -1
  200. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/approval-decision.mjs +1 -1
  201. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/approval.mjs +1 -1
  202. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/transition.mjs +1 -1
  203. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/subgraph.mjs +1 -1
  204. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/validate.mjs +1 -1
  205. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId_.mjs +1 -1
  206. package/.output/server/chunks/routes/api/workshop/ontology/export/_ontologyId_.mjs +1 -1
  207. package/.output/server/chunks/routes/api/workshop/ontology/index.mjs +1 -1
  208. package/.output/server/chunks/routes/api/workshop/ontology/scene.mjs +1 -1
  209. package/.output/server/chunks/routes/api/workshop/ontology/traces/_ontologyId_.mjs +1 -1
  210. package/.output/server/chunks/routes/api/workshop/ontology/versions/_ontologyId/compare.mjs +1 -1
  211. package/.output/server/chunks/routes/api/workshop/ontology/versions/_ontologyId_.mjs +1 -1
  212. package/.output/server/chunks/routes/api/workshop/optimization/capabilities.get.mjs +1 -1
  213. package/.output/server/chunks/routes/api/workshop/optimization/index.get.mjs +1 -1
  214. package/.output/server/chunks/routes/api/workshop/optimization/index.mjs +1 -1
  215. package/.output/server/chunks/routes/api/workshop/optimization/index2.mjs +1 -1
  216. package/.output/server/chunks/routes/api/workshop/optimization/profiles/_id/publish.post.mjs +1 -1
  217. package/.output/server/chunks/routes/api/workshop/optimization/recommendations/_id/crosscheck.post.mjs +1 -1
  218. package/.output/server/chunks/routes/api/workshop/optimization/recommendations/_id/dispatch.post.mjs +1 -1
  219. package/.output/server/chunks/routes/api/workshop/optimization/solve.post.mjs +1 -1
  220. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  221. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  222. package/.output/server/chunks/routes/api/workshop/process-model/datasets.post.mjs +1 -1
  223. package/.output/server/chunks/routes/api/workshop/process-model/eligibility.mjs +1 -1
  224. package/.output/server/chunks/routes/api/workshop/process-model/index.mjs +1 -1
  225. package/.output/server/chunks/routes/api/workshop/process-model/specs/_id/publish.post.mjs +1 -1
  226. package/.output/server/chunks/routes/api/workshop/process-model/train.post.mjs +1 -1
  227. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  228. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  229. package/.output/server/chunks/routes/api/workshop/tools/sync.post.mjs +1 -1
  230. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  231. package/.output/server/chunks/routes/renderer.mjs +2 -2
  232. package/.output/server/chunks/virtual/entry.mjs +1 -1
  233. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  234. package/.output/server/package.json +1 -1
  235. package/README-zh.md +4 -2
  236. package/README.md +9 -2
  237. package/config.yml +1 -1
  238. package/docker-compose.yml +4 -2
  239. package/docs/cli.en.md +2 -2
  240. package/docs/cli.md +2 -2
  241. package/docs/plugins.en.md +1 -1
  242. package/docs/plugins.md +1 -1
  243. package/docs/sdk.en.md +1 -1
  244. package/docs/sdk.md +1 -1
  245. package/package.json +1 -1
  246. package/scripts/_audit/_live-mqtt-e2e-20261028.mjs +219 -0
  247. package/scripts/_audit/prompt-injection-probe.mts +76 -0
  248. package/scripts/api-live-e2e.mjs +9 -3
  249. package/scripts/e2e-multiexpert-remediation-real.mjs +453 -0
  250. package/scripts/e2e-node-binding-3mode-real.mjs +697 -0
  251. package/scripts/e2e-node-binding-authz.mjs +332 -0
  252. package/scripts/security-acceptance.mjs +218 -0
  253. package/server/api/workshop/agent-tools/bindings/index.post.ts +33 -17
  254. package/server/api/workshop/agents/[id].patch.ts +3 -0
  255. package/server/api/workshop/agents/index.post.ts +3 -0
  256. package/server/api/workshop/channel-templates/[id].patch.ts +5 -0
  257. package/server/api/workshop/channel-templates/index.post.ts +6 -0
  258. package/server/api/workshop/channels/[id]/agents/[agentId].patch.ts +5 -0
  259. package/server/api/workshop/channels/[id]/agents/index.get.ts +8 -2
  260. package/server/api/workshop/channels/[id]/agents/index.post.ts +7 -0
  261. package/server/api/workshop/channels/[id]/index.get.ts +10 -4
  262. package/server/api/workshop/channels.post.ts +3 -0
  263. package/server/api/workshop/daq/[id]/ingest.post.ts +26 -22
  264. package/server/api/workshop/daq/[id].patch.ts +8 -0
  265. package/server/api/workshop/daq/alarms.get.ts +18 -16
  266. package/server/api/workshop/daq/infra/reconnect.post.ts +21 -5
  267. package/server/api/workshop/daq/test-driver.post.ts +10 -3
  268. package/server/api/workshop/dcw/[id]/param-ledger.get.ts +7 -1
  269. package/server/api/workshop/dcw/[id]/read.post.ts +6 -1
  270. package/server/api/workshop/dcw/[id].patch.ts +49 -40
  271. package/server/api/workshop/dcw/journal/index.get.ts +7 -3
  272. package/server/api/workshop/dcw/mes-artifacts/file.get.ts +7 -1
  273. package/server/api/workshop/dcw/mes-artifacts/index.get.ts +7 -1
  274. package/server/api/workshop/dcw/optimizations/[id]/series.get.ts +6 -1
  275. package/server/api/workshop/dcw/optimizations/[id].get.ts +3 -1
  276. package/server/api/workshop/dcw/optimizations/index.get.ts +6 -3
  277. package/server/api/workshop/dcw/params/[id]/read.post.ts +22 -17
  278. package/server/api/workshop/dcw/recipes/[id]/versions.get.ts +20 -14
  279. package/server/api/workshop/dcw/recipes/[id].delete.ts +33 -25
  280. package/server/api/workshop/dcw/recipes/index.get.ts +17 -12
  281. package/server/api/workshop/dcw/runs/[id]/close.post.ts +21 -15
  282. package/server/api/workshop/dcw/test-driver.post.ts +21 -16
  283. package/server/api/workshop/ws/hub.ts +2 -1
  284. package/server/plugins/01-instance-guard.ts +82 -0
  285. package/server/plugins/daq.ts +40 -8
  286. package/server/plugins/workshop.ts +12 -0
  287. package/server/services/workshop/agents/adapters/line-spawn.ts +24 -1
  288. package/server/services/workshop/agents/agent-dto.ts +54 -0
  289. package/server/services/workshop/agents/harness-spawn-policy.ts +114 -0
  290. package/server/services/workshop/agents/host-tool-bridge/dispatch.ts +22 -0
  291. package/server/services/workshop/agents/host-tool-bridge/index.ts +1 -1
  292. package/server/services/workshop/agents/host-tool-bridge/per-agent.ts +17 -3
  293. package/server/services/workshop/agents/host-tool-bridge/tools/tasks.ts +1 -1
  294. package/server/services/workshop/agents/host-tool-bridge/tools/team-delegation.ts +5 -1
  295. package/server/services/workshop/agents/industrial/dcw-tools.ts +6 -2
  296. package/server/services/workshop/agents/industrial/ops-tools.ts +54 -12
  297. package/server/services/workshop/agents/industrial/recipe-gate.ts +68 -15
  298. package/server/services/workshop/agents/industrial/tool-verify-legacy-specs.ts +2 -2
  299. package/server/services/workshop/agents/industrial/tool-verify.ts +31 -2
  300. package/server/services/workshop/agents/node-bindings.repo.ts +4 -3
  301. package/server/services/workshop/agents/node-delegation.ts +49 -4
  302. package/server/services/workshop/agents/tool-approvals.ts +23 -0
  303. package/server/services/workshop/agents/tool-reference-spec.ts +3 -0
  304. package/server/services/workshop/daq/bus/mqtt.adapter.ts +12 -0
  305. package/server/services/workshop/daq/daq-controller/crud.ts +5 -3
  306. package/server/services/workshop/daq/daq-controller/ingest.ts +23 -0
  307. package/server/services/workshop/daq/daq-controller/push.ts +24 -3
  308. package/server/services/workshop/daq/daq-controller/runtime-control.ts +6 -0
  309. package/server/services/workshop/daq/daq-controller/sweep-alarms.ts +3 -1
  310. package/server/services/workshop/daq/daq-controller/tsdb-twin.ts +21 -1
  311. package/server/services/workshop/daq/daq-node.repo.ts +10 -7
  312. package/server/services/workshop/daq/daq-node.ts +2 -0
  313. package/server/services/workshop/daq/daq-runtime.ts +10 -2
  314. package/server/services/workshop/daq/drivers/modbus-tcp.ts +8 -5
  315. package/server/services/workshop/daq/drivers/registry.ts +5 -4
  316. package/server/services/workshop/daq/infra.ts +13 -0
  317. package/server/services/workshop/daq/ingest-policy.ts +24 -1
  318. package/server/services/workshop/daq/storage/timescale.adapter.ts +42 -3
  319. package/server/services/workshop/db/database/migrations.ts +83 -68
  320. package/server/services/workshop/dcw/dcw-controller/crud.ts +27 -2
  321. package/server/services/workshop/dcw/dcw-controller/lines.ts +14 -3
  322. package/server/services/workshop/dcw/dcw-controller/recipes.ts +63 -5
  323. package/server/services/workshop/dcw/dcw-recipe.repo.ts +10 -1
  324. package/server/services/workshop/dcw/dcw-runtime.ts +37 -14
  325. package/server/services/workshop/dcw/drivers/shared.ts +62 -6
  326. package/server/services/workshop/dcw/recipe-op-anchor.ts +28 -0
  327. package/server/services/workshop/dcw/recipe-rollback-manager/rollback.ts +204 -190
  328. package/server/services/workshop/dcw/recipe-rollback-manager/sweep.ts +97 -77
  329. package/server/services/workshop/line-scope.ts +80 -0
  330. package/server/services/workshop/optimization/dispatch.service.ts +18 -2
  331. package/server/services/workshop/permissions.ts +2 -0
  332. package/server/services/workshop/runtime/agent-runtime/message.ts +17 -0
  333. package/server/services/workshop/runtime/agent-runtime/state.ts +9 -3
  334. package/server/services/workshop/runtime/agent-runtime/types.ts +2 -1
  335. package/server/services/workshop/runtime/channel-runtime.ts +3 -1
  336. package/server/services/workshop/runtime/mailbox.ts +6 -3
  337. package/server/services/workshop/runtime/manager/a2a.ts +4 -2
  338. package/server/services/workshop/runtime/manager/admin-channel.ts +1 -1
  339. package/server/services/workshop/runtime/manager/chat.ts +3 -1
  340. package/server/services/workshop/runtime/manager/host-tools.ts +1 -1
  341. package/server/services/workshop/runtime/manager/runtime-wiring.ts +31 -19
  342. package/server/services/workshop/runtime/manager/state.ts +43 -1
  343. package/server/services/workshop/runtime/permission-scope.ts +21 -0
  344. package/server/services/workshop/runtime/scheduler-loop/tick.ts +16 -4
  345. package/server/services/workshop/scene-events.ts +19 -0
  346. package/shared/daq-protocol.ts +24 -5
  347. package/shared/dcw-protocol/catalog.ts +4 -4
  348. package/.output/public/_nuxt/CCI-fwcS2.js +0 -1
  349. package/.output/public/_nuxt/builds/meta/5cd11284-05bf-4fcd-9a69-56a01c9f56dd.json +0 -1
@@ -8,13 +8,19 @@ import { statSync } from 'node:fs'
8
8
  import { resolveUser } from '@/server/api/workshop/caller'
9
9
  import { defineApiHandler } from '@/server/utils/response'
10
10
  import { listMesArtifacts } from '@/server/services/workshop/mes/mes-hook'
11
+ import { getDcwController } from '@/server/services/workshop/dcw/dcw-controller'
12
+ import { AppError, ErrorCodes } from '@/server/utils/errors'
13
+ import { requireLineForResource } from '@/server/services/workshop/line-scope'
11
14
 
12
15
  export default defineApiHandler(async (event) => {
13
- resolveUser(event)
16
+ const user = resolveUser(event)
14
17
  const q = getQuery(event)
15
18
  const nodeId = String(q.node_id ?? '').trim()
16
19
  const limit = Math.max(1, Math.min(Number(q.limit) || 50, 200))
17
20
  if (!nodeId) return { artifacts: [], message: '缺少 node_id' }
21
+ const node = getDcwController().byId(nodeId)
22
+ if (!node) throw new AppError(404, ErrorCodes.NOT_FOUND, `控制节点不存在: ${nodeId}`)
23
+ requireLineForResource(user, node.lineId, 'MES 点位', 'readonly')
18
24
  const artifacts = listMesArtifacts(nodeId, limit).map((a) => {
19
25
  let mtime: string | null = null
20
26
  try {
@@ -7,10 +7,15 @@ import { getQuery, getRouterParam } from 'h3'
7
7
  import { resolveUser } from '@/server/api/workshop/caller'
8
8
  import { defineApiHandler } from '@/server/utils/response'
9
9
  import { getRecipeRollBackManager } from '@/server/services/workshop/dcw/recipe-rollback-manager'
10
+ import { AppError, ErrorCodes } from '@/server/utils/errors'
11
+ import { requireLineForResource } from '@/server/services/workshop/line-scope'
10
12
 
11
13
  export default defineApiHandler(async (event) => {
12
- resolveUser(event)
14
+ const user = resolveUser(event)
13
15
  const id = getRouterParam(event, 'id') ?? ''
16
+ const record = getRecipeRollBackManager().recordById(id)
17
+ if (!record) throw new AppError(404, ErrorCodes.NOT_FOUND, `优化记录不存在: ${id}`)
18
+ requireLineForResource(user, record.lineId, '优化记录', 'readonly')
14
19
  const q = getQuery(event)
15
20
  const windowMs = q.windowMs ? Number(q.windowMs) : undefined
16
21
  const result = await getRecipeRollBackManager().series(id, Number.isFinite(windowMs) ? windowMs : undefined)
@@ -6,12 +6,14 @@ import { resolveUser } from '@/server/api/workshop/caller'
6
6
  import { defineApiHandler } from '@/server/utils/response'
7
7
  import { AppError, ErrorCodes } from '@/server/utils/errors'
8
8
  import { getRecipeRollBackManager } from '@/server/services/workshop/dcw/recipe-rollback-manager'
9
+ import { requireLineForResource } from '@/server/services/workshop/line-scope'
9
10
 
10
11
  export default defineApiHandler(async (event) => {
11
- resolveUser(event)
12
+ const user = resolveUser(event)
12
13
  const id = getRouterParam(event, 'id') ?? ''
13
14
  const record = getRecipeRollBackManager().recordById(id)
14
15
  if (!record)
15
16
  throw new AppError(404, ErrorCodes.NOT_FOUND, `优化记录不存在: ${id}`)
17
+ requireLineForResource(user, record.lineId, '优化记录', 'readonly')
16
18
  return { record }
17
19
  })
@@ -6,18 +6,21 @@ import { getQuery } from 'h3'
6
6
  import { resolveUser } from '@/server/api/workshop/caller'
7
7
  import { defineApiHandler } from '@/server/utils/response'
8
8
  import { getRecipeRollBackManager } from '@/server/services/workshop/dcw/recipe-rollback-manager'
9
+ import { filterRowsByLine, requireLineForResource } from '@/server/services/workshop/line-scope'
9
10
 
10
11
  export default defineApiHandler(async (event) => {
11
- resolveUser(event)
12
+ const user = resolveUser(event)
12
13
  const q = getQuery(event)
13
14
  const limit = Number(q.limit ?? 100)
15
+ const lineId = q.lineId ? String(q.lineId) : undefined
16
+ if (lineId) requireLineForResource(user, lineId, '产线', 'readonly')
14
17
  const records = getRecipeRollBackManager().records({
15
- lineId: q.lineId ? String(q.lineId) : undefined,
18
+ lineId,
16
19
  recipeId: q.recipeId ? String(q.recipeId) : undefined,
17
20
  nodeId: q.nodeId ? String(q.nodeId) : undefined,
18
21
  status: q.status ? String(q.status) : undefined,
19
22
  agentId: q.agentId ? String(q.agentId) : undefined,
20
23
  limit: Number.isFinite(limit) ? Math.min(limit, 500) : 100,
21
24
  })
22
- return { records }
25
+ return { records: filterRowsByLine(user, records, r => r.lineId) }
23
26
  })
@@ -1,17 +1,22 @@
1
- /**
2
- * POST /api/workshop/dcw/params/:id/read —— 工艺参数读取(读执行节点 PLC 值,物理量纲)。
3
- * 被动观测免审批;返回 PLC 实时读数 + 当前设定值。
4
- */
5
- import { getRouterParam } from 'h3'
6
- import { resolveUser } from '@/server/api/workshop/caller'
7
- import { defineApiHandler } from '@/server/utils/response'
8
- import { bindDcwBroadcast, getDcwController } from '@/server/services/workshop/dcw/dcw-controller'
9
- import { broadcastSceneEvent } from '@/server/services/workshop/scene-events'
10
-
11
- export default defineApiHandler(async (event) => {
12
- resolveUser(event)
13
- bindDcwBroadcast(broadcastSceneEvent)
14
- const id = getRouterParam(event, 'id') ?? ''
15
- const read = await getDcwController().readParam(id)
16
- return { read }
17
- })
1
+ /**
2
+ * POST /api/workshop/dcw/params/:id/read —— 工艺参数读取(读执行节点 PLC 值,物理量纲)。
3
+ * 被动观测免审批;返回 PLC 实时读数 + 当前设定值。
4
+ */
5
+ import { getRouterParam } from 'h3'
6
+ import { resolveUser } from '@/server/api/workshop/caller'
7
+ import { defineApiHandler } from '@/server/utils/response'
8
+ import { bindDcwBroadcast, getDcwController } from '@/server/services/workshop/dcw/dcw-controller'
9
+ import { broadcastSceneEvent } from '@/server/services/workshop/scene-events'
10
+ import { getDcwParamRepo } from '@/server/services/workshop/dcw/param-map.repo'
11
+ import { AppError, ErrorCodes } from '@/server/utils/errors'
12
+ import { paramLineId, requireLineForResource } from '@/server/services/workshop/line-scope'
13
+
14
+ export default defineApiHandler(async (event) => {
15
+ const user = resolveUser(event)
16
+ bindDcwBroadcast(broadcastSceneEvent)
17
+ const id = getRouterParam(event, 'id') ?? ''
18
+ if (!getDcwParamRepo().byId(id)) throw new AppError(404, ErrorCodes.NOT_FOUND, `工艺参数不存在: ${id}`)
19
+ requireLineForResource(user, paramLineId(id), '工艺参数', 'readonly')
20
+ const read = await getDcwController().readParam(id)
21
+ return { read }
22
+ })
@@ -1,14 +1,20 @@
1
- /**
2
- * GET /api/workshop/dcw/recipes/:id/versions —— 配方参数版本历史(旧→新,尾行=当前版)。
3
- * 每条:version/at/by(来源)/actorName(人话操作者)/description(变更原因)/params。
4
- */
5
- import { getRouterParam } from 'h3'
6
- import { resolveUser } from '@/server/api/workshop/caller'
7
- import { defineApiHandler } from '@/server/utils/response'
8
- import { getDcwController } from '@/server/services/workshop/dcw/dcw-controller'
9
-
10
- export default defineApiHandler(async (event) => {
11
- resolveUser(event)
12
- const id = getRouterParam(event, 'id') ?? ''
13
- return { versions: getDcwController().recipeVersions(id) }
14
- })
1
+ /**
2
+ * GET /api/workshop/dcw/recipes/:id/versions —— 配方参数版本历史(旧→新,尾行=当前版)。
3
+ * 每条:version/at/by(来源)/actorName(人话操作者)/description(变更原因)/params。
4
+ * 2026-10-28:按配方所属产线校验只读授权。
5
+ */
6
+ import { getRouterParam } from 'h3'
7
+ import { resolveUser } from '@/server/api/workshop/caller'
8
+ import { defineApiHandler } from '@/server/utils/response'
9
+ import { AppError, ErrorCodes } from '@/server/utils/errors'
10
+ import { getDcwController } from '@/server/services/workshop/dcw/dcw-controller'
11
+ import { recipeLineId, requireLineForResource } from '@/server/services/workshop/line-scope'
12
+
13
+ export default defineApiHandler(async (event) => {
14
+ const user = resolveUser(event)
15
+ const id = getRouterParam(event, 'id') ?? ''
16
+ const recipe = getDcwController().listRecipes().find(r => r.id === id)
17
+ if (!recipe) throw new AppError(404, ErrorCodes.NOT_FOUND, `Recipe 不存在: ${id}`)
18
+ requireLineForResource(user, recipeLineId(id) ?? recipe.lineId, '配方', 'readonly')
19
+ return { versions: getDcwController().recipeVersions(id) }
20
+ })
@@ -1,25 +1,33 @@
1
- /**
2
- * DELETE /api/workshop/dcw/recipes/:id —— 删除配方。
3
- */
4
- import { getRouterParam } from 'h3'
5
- import { resolveUser } from '@/server/api/workshop/caller'
6
- import { defineApiHandler } from '@/server/utils/response'
7
- import { getDcwRecipeRepo } from '@/server/services/workshop/dcw/dcw-recipe.repo'
8
- import { recordOps } from '@/server/services/workshop/ops/ops'
9
-
10
- export default defineApiHandler(async (event) => {
11
- const user = resolveUser(event)
12
- const id = getRouterParam(event, 'id') ?? ''
13
- // 删除前取归属维度(remove 后不可读),产线日志按线/配方归档
14
- const recipe = getDcwRecipeRepo().byId(id)
15
- getDcwRecipeRepo().remove(id)
16
- recordOps({
17
- actor: user.id, actorName: user.name, actorKind: 'user',
18
- action: 'recipe.delete', kind: 'recipe', targetKind: 'recipe', targetId: id,
19
- lineId: recipe?.lineId ?? '',
20
- productId: recipe?.productId ?? '',
21
- recipeId: id,
22
- summary: `删除配方「${recipe?.name ?? id}」${recipe?.lineId ? `(产线 ${recipe.lineId})` : ''}`,
23
- })
24
- return { deleted: true }
25
- })
1
+ /**
2
+ * DELETE /api/workshop/dcw/recipes/:id —— 删除配方。
3
+ */
4
+ import { getRouterParam } from 'h3'
5
+ import { resolveUser } from '@/server/api/workshop/caller'
6
+ import { defineApiHandler } from '@/server/utils/response'
7
+ import { getDcwRecipeRepo } from '@/server/services/workshop/dcw/dcw-recipe.repo'
8
+ import { recordOps } from '@/server/services/workshop/ops/ops'
9
+ import { AppError, ErrorCodes } from '@/server/utils/errors'
10
+ import { requireLineForResource } from '@/server/services/workshop/line-scope'
11
+
12
+ export default defineApiHandler(async (event) => {
13
+ const user = resolveUser(event)
14
+ const id = getRouterParam(event, 'id') ?? ''
15
+ // 删除前取归属维度(remove 后不可读),产线日志按线/配方归档
16
+ const recipe = getDcwRecipeRepo().byId(id)
17
+ if (!recipe) throw new AppError(404, ErrorCodes.NOT_FOUND, `Recipe 不存在: ${id}`)
18
+ requireLineForResource(user, recipe.lineId, '配方', 'operate')
19
+ const activeRun = getDcwRecipeRepo().listRuns().find(r => r.recipeId === id && !r.endedAt)
20
+ if (activeRun) {
21
+ throw new AppError(409, ErrorCodes.CONFLICT, `配方「${recipe.name}」仍在批次 ${activeRun.id.slice(0, 8)} 中执行,请先停线/关批次后再删除`)
22
+ }
23
+ getDcwRecipeRepo().remove(id)
24
+ recordOps({
25
+ actor: user.id, actorName: user.name, actorKind: 'user',
26
+ action: 'recipe.delete', kind: 'recipe', targetKind: 'recipe', targetId: id,
27
+ lineId: recipe?.lineId ?? '',
28
+ productId: recipe?.productId ?? '',
29
+ recipeId: id,
30
+ summary: `删除配方「${recipe?.name ?? id}」${recipe?.lineId ? `(产线 ${recipe.lineId})` : ''}`,
31
+ })
32
+ return { deleted: true }
33
+ })
@@ -1,12 +1,17 @@
1
- /**
2
- * GET /api/workshop/dcw/recipes —— 配方 + 批次列表。
3
- */
4
- import { resolveUser } from '@/server/api/workshop/caller'
5
- import { defineApiHandler } from '@/server/utils/response'
6
- import { getDcwRecipeRepo } from '@/server/services/workshop/dcw/dcw-recipe.repo'
7
-
8
- export default defineApiHandler(async (event) => {
9
- resolveUser(event)
10
- const repo = getDcwRecipeRepo()
11
- return { recipes: repo.list(), runs: repo.listRuns() }
12
- })
1
+ /**
2
+ * GET /api/workshop/dcw/recipes —— 配方 + 批次列表。
3
+ * 2026-10-28:按调用者产线授权过滤(admin/特权见全集)。
4
+ */
5
+ import { resolveUser } from '@/server/api/workshop/caller'
6
+ import { defineApiHandler } from '@/server/utils/response'
7
+ import { getDcwRecipeRepo } from '@/server/services/workshop/dcw/dcw-recipe.repo'
8
+ import { filterRowsByLine } from '@/server/services/workshop/line-scope'
9
+
10
+ export default defineApiHandler(async (event) => {
11
+ const user = resolveUser(event)
12
+ const repo = getDcwRecipeRepo()
13
+ return {
14
+ recipes: filterRowsByLine(user, repo.list(), r => r.lineId),
15
+ runs: filterRowsByLine(user, repo.listRuns(), r => r.lineId),
16
+ }
17
+ })
@@ -1,15 +1,21 @@
1
- /**
2
- * POST /api/workshop/dcw/runs/:id/close —— 关闭批次(结束数据隔离窗口)。
3
- */
4
- import { getRouterParam } from 'h3'
5
- import { resolveUser } from '@/server/api/workshop/caller'
6
- import { defineApiHandler } from '@/server/utils/response'
7
- import { bindDcwBroadcast, getDcwController } from '@/server/services/workshop/dcw/dcw-controller'
8
- import { broadcastSceneEvent } from '@/server/services/workshop/scene-events'
9
-
10
- export default defineApiHandler(async (event) => {
11
- resolveUser(event)
12
- bindDcwBroadcast(broadcastSceneEvent)
13
- const id = getRouterParam(event, 'id') ?? ''
14
- return { run: getDcwController().closeRun(id) }
15
- })
1
+ /**
2
+ * POST /api/workshop/dcw/runs/:id/close —— 关闭批次(结束数据隔离窗口)。
3
+ */
4
+ import { getRouterParam } from 'h3'
5
+ import { resolveUser } from '@/server/api/workshop/caller'
6
+ import { defineApiHandler } from '@/server/utils/response'
7
+ import { bindDcwBroadcast, getDcwController } from '@/server/services/workshop/dcw/dcw-controller'
8
+ import { broadcastSceneEvent } from '@/server/services/workshop/scene-events'
9
+ import { getDcwRecipeRepo } from '@/server/services/workshop/dcw/dcw-recipe.repo'
10
+ import { AppError, ErrorCodes } from '@/server/utils/errors'
11
+ import { requireLineForResource } from '@/server/services/workshop/line-scope'
12
+
13
+ export default defineApiHandler(async (event) => {
14
+ const user = resolveUser(event)
15
+ bindDcwBroadcast(broadcastSceneEvent)
16
+ const id = getRouterParam(event, 'id') ?? ''
17
+ const run = getDcwRecipeRepo().runById(id)
18
+ if (!run) throw new AppError(404, ErrorCodes.NOT_FOUND, `批次不存在: ${id}`)
19
+ requireLineForResource(user, run.lineId, '批次', 'operate')
20
+ return { run: getDcwController().closeRun(id) }
21
+ })
@@ -1,16 +1,21 @@
1
- /**
2
- * POST /api/workshop/dcw/test-driver —— 连接测试(body: { driver, driverConfig })。
3
- */
4
- import { readBody } from 'h3'
5
- import type { DcwDriverKind } from '#shared/dcw-protocol'
6
- import { resolveUser } from '@/server/api/workshop/caller'
7
- import { defineApiHandler } from '@/server/utils/response'
8
- import { bindDcwBroadcast, getDcwController } from '@/server/services/workshop/dcw/dcw-controller'
9
- import { broadcastSceneEvent } from '@/server/services/workshop/scene-events'
10
-
11
- export default defineApiHandler(async (event) => {
12
- resolveUser(event)
13
- bindDcwBroadcast(broadcastSceneEvent)
14
- const body = await readBody<{ driver?: DcwDriverKind, driverConfig?: Record<string, unknown> }>(event) ?? {}
15
- return { test: await getDcwController().testDriver(body.driver ?? 'mock', body.driverConfig ?? {}) }
16
- })
1
+ /**
2
+ * POST /api/workshop/dcw/test-driver —— 连接测试(body: { driver, driverConfig })。
3
+ *
4
+ * 2026-10-28 安全修复:仅 admin/editor 可调用;allowPrivateHost 只认服务端开关。
5
+ */
6
+ import { readBody } from 'h3'
7
+ import type { DcwDriverKind } from '#shared/dcw-protocol'
8
+ import { requireRole } from '@/server/api/workshop/caller'
9
+ import { defineApiHandler } from '@/server/utils/response'
10
+ import { bindDcwBroadcast, getDcwController } from '@/server/services/workshop/dcw/dcw-controller'
11
+ import { broadcastSceneEvent } from '@/server/services/workshop/scene-events'
12
+
13
+ export default defineApiHandler(async (event) => {
14
+ requireRole(event, ['admin', 'editor'])
15
+ bindDcwBroadcast(broadcastSceneEvent)
16
+ const body = await readBody<{ driver?: DcwDriverKind, driverConfig?: Record<string, unknown> }>(event) ?? {}
17
+ const cfg: Record<string, unknown> = { ...(body.driverConfig ?? {}) }
18
+ delete cfg.allowPrivateHost
19
+ if (process.env.AW_TEST_DRIVER_ALLOW_PRIVATE === '1') cfg.allowPrivateHost = 'true'
20
+ return { test: await getDcwController().testDriver(body.driver ?? 'mock', cfg) }
21
+ })
@@ -9,7 +9,7 @@ import { PEER_SEND_BUDGET_BYTES, hub, streams } from './shared'
9
9
  import { ensureStream } from './streams'
10
10
  import { flushDbBuffer } from './db-buffer'
11
11
  import { getWorkshopManager } from '../../../plugins/workshop'
12
- import { registerScenePeer, setPeerVisibleLines } from '../../../services/workshop/scene-events'
12
+ import { registerScenePeer, setPeerIdentity, setPeerVisibleLines } from '../../../services/workshop/scene-events'
13
13
  import { visibleLineIds } from '../../../services/workshop/permissions'
14
14
 
15
15
  export function ensureHubBound(manager: AgentChannelManager): void {
@@ -87,6 +87,7 @@ export function resolveChannelIdFromUrl(peer: WsPeer): string | undefined {
87
87
  /** 场景事件注册(鉴权后):按用户产线可见集挂 per-peer 过滤,未经鉴权的 peer 不注册 */
88
88
  export function attachScenePeer(peer: WsPeer, user: { id: string, role: string }): void {
89
89
  setPeerVisibleLines(peer, visibleLineIds(user))
90
+ setPeerIdentity(peer, user)
90
91
  registerScenePeer(peer)
91
92
  }
92
93
 
@@ -0,0 +1,82 @@
1
+ /**
2
+ * 数据目录单实例守卫(S16,2026-10-28)。
3
+ *
4
+ * `scripts/start.mjs`/`dev-guard.mjs` 已有 <configRoot>/.runtime/aw.lock,但直接
5
+ * `node .output/server/index.mjs` 的启动路径绕过它 —— 两个进程共享同一份 JSON 仓储/
6
+ * writeLocks 时会互相覆盖、绕过 60s/保持窗。本插件在配置根再取一把数据锁
7
+ * (<configRoot>/.runtime/data.lock),覆盖所有启动方式:
8
+ * - 已存在且 PID 存活 → fail-fast(退出码 1);
9
+ * - PID 已死(崩溃残留) → 接管重写;
10
+ * - 进程退出/信号 → 释放。
11
+ * 显式豁免:AW_SKIP_DATA_LOCK=1(仅测试/受控多实例编排,默认禁止)。
12
+ */
13
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
14
+ import { join, resolve } from 'node:path'
15
+
16
+ const SKIP = process.env.AW_SKIP_DATA_LOCK === '1'
17
+ const ROOT = resolve(process.env.AW_HOME ?? process.cwd())
18
+ const DIR = join(ROOT, '.runtime')
19
+ const LOCK = join(DIR, 'data.lock')
20
+
21
+ interface LockFile { pid?: number, at?: string }
22
+
23
+ function pidAlive(pid: number): boolean {
24
+ if (!Number.isInteger(pid) || pid <= 0) return false
25
+ try {
26
+ process.kill(pid, 0)
27
+ return true
28
+ }
29
+ catch (err) {
30
+ return (err as NodeJS.ErrnoException)?.code === 'EPERM'
31
+ }
32
+ }
33
+
34
+ function readLock(): LockFile | null {
35
+ try {
36
+ return JSON.parse(readFileSync(LOCK, 'utf8')) as LockFile
37
+ }
38
+ catch {
39
+ return null
40
+ }
41
+ }
42
+
43
+ function release(): void {
44
+ try {
45
+ const cur = readLock()
46
+ if (cur?.pid === process.pid && existsSync(LOCK)) rmSync(LOCK, { force: true })
47
+ }
48
+ catch { /* 退出路径尽力而为 */ }
49
+ }
50
+
51
+ export default async function instanceGuardPlugin(): Promise<void> {
52
+ if (SKIP) {
53
+ console.warn('[instance-guard] AW_SKIP_DATA_LOCK=1:已跳过数据目录单实例锁(仅限测试/受控编排)')
54
+ return
55
+ }
56
+ try {
57
+ mkdirSync(DIR, { recursive: true })
58
+ }
59
+ catch (err) {
60
+ console.error('[instance-guard] 无法创建 .runtime 目录:', err instanceof Error ? err.message : err)
61
+ process.exit(1)
62
+ }
63
+ const existing = readLock()
64
+ if (existing?.pid && existing.pid !== process.pid && pidAlive(existing.pid)) {
65
+ console.error(`[instance-guard] 数据目录已被进程 ${existing.pid} 占用:${ROOT}。同一数据目录只允许一个写者;请先停止该实例,或设置 AW_HOME 指向独立目录。`)
66
+ process.exit(1)
67
+ }
68
+ try {
69
+ writeFileSync(LOCK, JSON.stringify({ pid: process.pid, at: new Date().toISOString() }), { flag: 'w' })
70
+ }
71
+ catch (err) {
72
+ console.error('[instance-guard] 无法写入数据锁:', err instanceof Error ? err.message : err)
73
+ process.exit(1)
74
+ }
75
+ process.once('exit', release)
76
+ for (const sig of ['SIGINT', 'SIGTERM'] as const) {
77
+ process.once(sig, () => {
78
+ release()
79
+ process.exit(0)
80
+ })
81
+ }
82
+ }
@@ -4,25 +4,43 @@
4
4
  * 启动时:探测配置地址(MQTT/Timescale)→ 不通且策略允许则 docker compose 自动拉起
5
5
  * → 依判定结果装配真实/降级后端 → 降级则停采并警告;后台 30s 自动重连,
6
6
  * 恢复后重建真实后端 + 重挂消费者 + 恢复采集。
7
+ *
8
+ * 2026-10-28(S10):启动屏障 —— 后端装配完成前不 resolve `__daqInfraReady`,
9
+ * workshop 插件的 resumeAll 必须等待它,避免采样先落到占位 SQLite/进程内队列;
10
+ * 后端初始化失败时显式置 degraded 并停采(不再"端口通=健康")。
7
11
  */
8
12
  import { useRuntimeConfig } from '#imports'
9
- import { daqUrls, ensureDaqInfrastructure, scheduleAutoReconnect, type DaqInfraConfig } from '../services/workshop/daq/infra'
13
+ import { daqInfraStatus, daqUrls, ensureDaqInfrastructure, markDaqInfraFailure, scheduleAutoReconnect, type DaqInfraConfig } from '../services/workshop/daq/infra'
10
14
  import { rebuildTsdb } from '../services/workshop/daq/storage'
11
15
  import { rebuildObjectStore } from '../services/workshop/daq/objectstore'
12
16
  import { startDaqObjectGc } from '../services/workshop/daq/objectstore/gc'
13
17
  import { rebuildDaqQueue } from '../services/workshop/daq/bus'
14
18
  import { getDaqController } from '../services/workshop/daq/daq-controller'
15
19
 
20
+ interface DaqBootState {
21
+ __daqInfraReady?: Promise<void>
22
+ __daqInfraStatus?: () => ReturnType<typeof daqInfraStatus>
23
+ }
24
+
16
25
  /** 按最新 infra 状态装配后端 + 控制器(启动/重连共用) */
17
26
  async function applyInfra(cfg: DaqInfraConfig): Promise<void> {
18
27
  const status = await ensureDaqInfrastructure(cfg, process.cwd())
19
28
  const urls = daqUrls(cfg)
20
- await rebuildTsdb(status.tsdbOnline, urls.tsdbUrl)
21
- await rebuildObjectStore(status.objectStoreOnline, urls.objectStoreUrl)
22
- await rebuildDaqQueue(status.mqttOnline, urls.mqttUrl)
29
+ try {
30
+ await rebuildTsdb(status.tsdbOnline, urls.tsdbUrl)
31
+ await rebuildObjectStore(status.objectStoreOnline, urls.objectStoreUrl)
32
+ await rebuildDaqQueue(status.mqttOnline, urls.mqttUrl)
33
+ }
34
+ catch (err) {
35
+ // 端口可达 ≠ 后端可用(密码错/库缺失/扩展未装)。装配失败一律降级并停采,
36
+ // 由 30s 重连继续尝试;绝不让采样写进占位后端后"看起来正常"。
37
+ markDaqInfraFailure(err)
38
+ getDaqController().stopAll()
39
+ return
40
+ }
23
41
  const ctrl = getDaqController()
24
42
  await ctrl.reattachQueue()
25
- if (status.degraded) {
43
+ if (daqInfraStatus().degraded) {
26
44
  ctrl.stopAll() // 在线数采停用(降级可见)
27
45
  }
28
46
  else {
@@ -55,22 +73,36 @@ export default async function daqPlugin() {
55
73
  objectstore: raw?.objectstore
56
74
  ? {
57
75
  host: raw.objectstore.host ?? '127.0.0.1',
58
- port: Number(raw.objectstore.port ?? 9000),
76
+ port: raw.objectstore.port ?? 9000,
59
77
  accessKey: raw.objectstore.accessKey ?? 'awshop',
60
78
  secretKey: raw.objectstore.secretKey ?? 'awshop-secret',
61
79
  bucket: raw.objectstore.bucket ?? 'daq',
62
80
  }
63
81
  : undefined,
64
82
  }
83
+ // 启动屏障:先挂 promise,再执行装配;失败也 resolve(状态里 degraded=true),由消费方决定是否停采
84
+ const g = globalThis as unknown as DaqBootState
85
+ let resolveReady!: () => void
86
+ g.__daqInfraReady = new Promise<void>((resolve) => {
87
+ resolveReady = resolve
88
+ })
89
+ g.__daqInfraStatus = daqInfraStatus
65
90
  try {
66
91
  await applyInfra(cfg)
67
92
  }
68
93
  catch (err) {
69
- console.error('[daq-infra] 启动装配失败(保持降级,重连可恢复):', err instanceof Error ? err.message : err)
94
+ markDaqInfraFailure(err)
95
+ try {
96
+ getDaqController().stopAll()
97
+ }
98
+ catch { /* 控制器未就绪 */ }
99
+ }
100
+ finally {
101
+ resolveReady()
70
102
  }
71
103
  // 后台自动重连:恢复后重走装配路径
72
104
  scheduleAutoReconnect(() => {
73
- void applyInfra(cfg).catch(() => {})
105
+ void applyInfra(cfg).catch(markDaqInfraFailure)
74
106
  })
75
107
  // P0-2 对象存储 GC:帧行出清后像素文件孤儿回收(90s 首轮 + 24h 周期;disk 后端)
76
108
  startDaqObjectGc()
@@ -232,6 +232,18 @@ export default function workshopPlugin(nitroApp: {
232
232
  ])
233
233
  const { broadcastSceneEvent } = await import('../services/workshop/scene-events')
234
234
  bindDaqHost(broadcastSceneEvent)
235
+ // S10 启动屏障:等 daq 插件把后端装配完(成功或明确降级),再决定是否开采。
236
+ // 此前直接 resumeAll 会让采样先写进占位 SQLite/进程内队列,切库后不迁移。
237
+ const g = globalThis as unknown as {
238
+ __daqInfraReady?: Promise<void>
239
+ __daqInfraStatus?: () => { degraded: boolean, warning?: string }
240
+ }
241
+ if (g.__daqInfraReady) await g.__daqInfraReady
242
+ const infra = g.__daqInfraStatus?.()
243
+ if (infra?.degraded) {
244
+ console.warn(`[workshop] DAQ 基础设施降级,跳过 resumeAll:${infra.warning ?? '后端不可用'}`)
245
+ return
246
+ }
235
247
  const st = getDaqController().resumeAll()
236
248
  console.log(`[workshop] DAQ 采集补挂完成(running=${st.running},宿主端口已装配)`)
237
249
  }
@@ -16,6 +16,29 @@ import { join } from 'node:path'
16
16
 
17
17
  const SHELL_META = /[\r\n;&|`<>$]/
18
18
 
19
+ /**
20
+ * 平台自身凭据:不得随 process.env 继承给 harness 子进程。
21
+ * 引擎需要的 provider key 与 AW_ 身份变量由各 impl 的显式 env 传入(cleanEnv 或 bridgeEnv),
22
+ * 这里只剥离"平台会话/管理员口令/隧道令牌"这类与引擎无关的秘密。
23
+ */
24
+ const PLATFORM_SECRET_ENV = [
25
+ 'NUXT_SESSION_PASSWORD',
26
+ 'AW_ADMIN_PASSWORD',
27
+ 'AW_E2E_ADMIN_PASSWORD',
28
+ 'AW_E2E_PASSWORD',
29
+ 'AW_E2E_TOKEN',
30
+ 'AW_E2E_ADMIN_TOKEN',
31
+ 'SCHED_E2E_PASSWORD',
32
+ 'AW_TUI_PASSWORD',
33
+ 'ADMIN_TOKEN',
34
+ 'CLOUDFLARE_TUNNEL_TOKEN',
35
+ ] as const
36
+
37
+ function scrubPlatformSecrets(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
38
+ const deny = new Set<string>(PLATFORM_SECRET_ENV)
39
+ return Object.fromEntries(Object.entries(env).filter(([k]) => !deny.has(k)))
40
+ }
41
+
19
42
  /** 拒绝 shell 元字符(命令只能是纯可执行路径) */
20
43
  export function assertPlainExecutable(command: string): string {
21
44
  if (!command || SHELL_META.test(command)) {
@@ -87,7 +110,7 @@ export function spawnLineProcess(command: string, args: string[], options: LineS
87
110
  const { file, needsCmd } = resolveExecutable(command)
88
111
  const env = options.cleanEnv
89
112
  ? { ...options.env }
90
- : { ...process.env, ...options.env }
113
+ : scrubPlatformSecrets({ ...process.env, ...options.env })
91
114
  if (needsCmd) {
92
115
  // Windows .cmd shim:固定包装器 'cmd.exe' + /d /s /c。
93
116
  // 可执行文件路径无条件引号包裹:无空格路径裸奔时,/s 模式的 cmd 会吞掉
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Agent 对外 DTO —— HTTP 响应不得回显 token 与敏感 config。
3
+ *
4
+ * 背景(2026-10-28 审计):`instanceToAgentInfo` 直出 `token` 与完整 `config`,
5
+ * `/channels/:id/agents` 对"本 channel 任意成员(含 agent token)"放行 →
6
+ * worker Agent 可读取 lead 的 token,再以 lead 身份调用 agent-tools/invoke,
7
+ * 完整继承 lead 的工业绑定与 lead 专属权限。
8
+ *
9
+ * 约定:
10
+ * - token 永不进列表/详情;只在 rotate-token 一次性返回。
11
+ * - config 仅 channel 属主/admin 可见(UI 的成员编辑/专长展示需要),
12
+ * 且剔除启动类敏感键(command/args/cwd/env)。
13
+ * - 其余调用方只拿 summary(id/name/role/harness/enabled/templateId)。
14
+ */
15
+ import type { AgentInfo } from './agent-interface'
16
+
17
+ const SENSITIVE_CONFIG_KEYS = ['command', 'args', 'cwd', 'env'] as const
18
+
19
+ export interface ChannelAgentSummary {
20
+ id: string
21
+ channelId: string
22
+ name: string
23
+ harness: string
24
+ role: string
25
+ enabled: number
26
+ templateId: string | null
27
+ config?: Record<string, unknown>
28
+ }
29
+
30
+ function safeConfig(config: Record<string, unknown> | undefined | null): Record<string, unknown> {
31
+ if (!config || typeof config !== 'object') return {}
32
+ const deny = new Set<string>(SENSITIVE_CONFIG_KEYS)
33
+ return Object.fromEntries(Object.entries(config).filter(([k]) => !deny.has(k)))
34
+ }
35
+
36
+ /** 名册投影(token 永远不出现) */
37
+ export function channelAgentSummary(agent: AgentInfo, opts: { includeConfig?: boolean } = {}): ChannelAgentSummary {
38
+ const summary: ChannelAgentSummary = {
39
+ id: agent.id,
40
+ channelId: agent.channelId,
41
+ name: agent.name,
42
+ harness: agent.harness,
43
+ role: agent.role,
44
+ enabled: agent.enabled ?? 1,
45
+ templateId: agent.templateId ?? null,
46
+ }
47
+ if (opts.includeConfig) summary.config = safeConfig(agent.config)
48
+ return summary
49
+ }
50
+
51
+ /** 批量投影 */
52
+ export function channelAgentSummaries(agents: AgentInfo[], opts: { includeConfig?: boolean } = {}): ChannelAgentSummary[] {
53
+ return agents.map(a => channelAgentSummary(a, opts))
54
+ }