create-windy 0.8.3 → 0.9.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 (505) hide show
  1. package/dist/cli.js +838 -560
  2. package/package.json +1 -1
  3. package/template/.windy-template.json +2 -2
  4. package/template/apps/agent-server/Dockerfile +92 -22
  5. package/template/apps/agent-server/README.md +47 -85
  6. package/template/apps/agent-server/documents/office.py +216 -0
  7. package/template/apps/agent-server/documents/query_report.py +136 -0
  8. package/template/apps/agent-server/documents/smoke.py +177 -0
  9. package/template/apps/agent-server/documents/test_boundaries.py +185 -0
  10. package/template/apps/agent-server/host-contracts.ts +56 -0
  11. package/template/apps/agent-server/install-native.ts +167 -0
  12. package/template/apps/agent-server/main.ts +179 -0
  13. package/template/apps/agent-server/native/EXTENSIONS.md +46 -0
  14. package/template/apps/agent-server/native/admission.ts +73 -0
  15. package/template/apps/agent-server/native/authorization.test.ts +176 -0
  16. package/template/apps/agent-server/native/authorization.ts +118 -0
  17. package/template/apps/agent-server/native/boundary-io.ts +93 -0
  18. package/template/apps/agent-server/native/boundary-product.ts +107 -0
  19. package/template/apps/agent-server/native/boundary-project.test.ts +247 -0
  20. package/template/apps/agent-server/native/boundary-project.ts +188 -0
  21. package/template/apps/agent-server/native/boundary.ts +188 -0
  22. package/template/apps/agent-server/native/compaction-policy.test.ts +175 -0
  23. package/template/apps/agent-server/native/config.ts +95 -0
  24. package/template/apps/agent-server/native/conversation-instructions.ts +9 -0
  25. package/template/apps/agent-server/native/extensions.test.ts +190 -0
  26. package/template/apps/agent-server/native/extensions.ts +31 -0
  27. package/template/apps/agent-server/native/host-profile.test.ts +91 -0
  28. package/template/apps/agent-server/native/host-profile.ts +33 -0
  29. package/template/apps/agent-server/native/host-test-fixture.ts +13 -0
  30. package/template/apps/agent-server/native/http.ts +129 -0
  31. package/template/apps/agent-server/native/lifecycle.test.ts +285 -0
  32. package/template/apps/agent-server/native/lifecycle.ts +136 -0
  33. package/template/apps/agent-server/native/manager.ts +292 -0
  34. package/template/apps/agent-server/native/native.test.ts +207 -0
  35. package/template/apps/agent-server/native/office-preview.test.ts +50 -0
  36. package/template/apps/agent-server/native/office-preview.ts +25 -0
  37. package/template/apps/agent-server/native/parallel-harness.ts +242 -0
  38. package/template/apps/agent-server/native/parallel-mcp-fixture.ts +97 -0
  39. package/template/apps/agent-server/native/parallel.test.ts +256 -0
  40. package/template/apps/agent-server/native/profile-composition.test.ts +147 -0
  41. package/template/apps/agent-server/native/profile.ts +307 -0
  42. package/template/apps/agent-server/native/request.ts +61 -0
  43. package/template/apps/agent-server/native/session-conflict.test.ts +235 -0
  44. package/template/apps/agent-server/native/session-conflict.ts +21 -0
  45. package/template/apps/agent-server/native/shared-skills.test.ts +128 -0
  46. package/template/apps/agent-server/native/shared-skills.ts +240 -0
  47. package/template/apps/agent-server/native/socket-lifecycle.test.ts +48 -0
  48. package/template/apps/agent-server/native/socket.ts +130 -0
  49. package/template/apps/agent-server/native/storage-lifecycle.test.ts +217 -0
  50. package/template/apps/agent-server/native/storage.ts +188 -0
  51. package/template/apps/agent-server/native/stream-authorization.test.ts +89 -0
  52. package/template/apps/agent-server/native/worker.ts +77 -0
  53. package/template/apps/agent-server/native-download.test.ts +119 -0
  54. package/template/apps/agent-server/native-download.ts +145 -0
  55. package/template/apps/agent-server/package.json +63 -0
  56. package/template/apps/agent-server/plugins/access.mjs +126 -0
  57. package/template/apps/agent-server/plugins/branding/README.md +9 -0
  58. package/template/apps/agent-server/plugins/branding/brand.css +85 -0
  59. package/template/apps/agent-server/plugins/branding/client.js +338 -0
  60. package/template/apps/agent-server/plugins/branding/index.mjs +35 -0
  61. package/template/apps/agent-server/plugins/branding/loading.d.mts +2 -0
  62. package/template/apps/agent-server/plugins/branding/loading.mjs +66 -0
  63. package/template/apps/agent-server/plugins/branding/loading.test.ts +89 -0
  64. package/template/apps/agent-server/plugins/branding/package.json +21 -0
  65. package/template/apps/agent-server/plugins/branding.test.ts +294 -0
  66. package/template/apps/agent-server/plugins/compaction.mjs +83 -0
  67. package/template/apps/agent-server/plugins/compaction.test.ts +91 -0
  68. package/template/apps/agent-server/plugins/confine-network.py +57 -0
  69. package/template/apps/agent-server/plugins/default-skills.test.ts +62 -0
  70. package/template/apps/agent-server/plugins/downloads/README.md +28 -0
  71. package/template/apps/agent-server/plugins/downloads/client.js +126 -0
  72. package/template/apps/agent-server/plugins/downloads/downloads.test.ts +222 -0
  73. package/template/apps/agent-server/plugins/downloads/index.d.mts +19 -0
  74. package/template/apps/agent-server/plugins/downloads/index.mjs +180 -0
  75. package/template/apps/agent-server/plugins/downloads/package.json +20 -0
  76. package/template/apps/agent-server/plugins/drop-overlay/README.md +24 -0
  77. package/template/apps/agent-server/plugins/drop-overlay/drop-overlay.test.ts +199 -0
  78. package/template/apps/agent-server/plugins/drop-overlay/index.d.mts +8 -0
  79. package/template/apps/agent-server/plugins/drop-overlay/index.mjs +12 -0
  80. package/template/apps/agent-server/plugins/drop-overlay/style.css +102 -0
  81. package/template/apps/agent-server/plugins/locale/client.js +61 -0
  82. package/template/apps/agent-server/plugins/locale/index.d.mts +9 -0
  83. package/template/apps/agent-server/plugins/locale/index.mjs +16 -0
  84. package/template/apps/agent-server/plugins/locale/locale.test.ts +217 -0
  85. package/template/apps/agent-server/plugins/locale/package.json +19 -0
  86. package/template/apps/agent-server/plugins/parallel.mjs +146 -0
  87. package/template/apps/agent-server/plugins/preset-registry.d.mts +2 -0
  88. package/template/apps/agent-server/plugins/preset-registry.mjs +41 -0
  89. package/template/apps/agent-server/plugins/preset-registry.test.ts +46 -0
  90. package/template/apps/agent-server/plugins/questions.d.mts +25 -0
  91. package/template/apps/agent-server/plugins/questions.mjs +142 -0
  92. package/template/apps/agent-server/plugins/questions.test.ts +105 -0
  93. package/template/apps/agent-server/plugins/settings/README.md +17 -0
  94. package/template/apps/agent-server/plugins/settings/client.js +102 -0
  95. package/template/apps/agent-server/plugins/settings/index.mjs +17 -0
  96. package/template/apps/agent-server/plugins/settings/package.json +19 -0
  97. package/template/apps/agent-server/plugins/settings/settings.test.ts +129 -0
  98. package/template/apps/agent-server/plugins/settings-controller.d.mts +4 -0
  99. package/template/apps/agent-server/plugins/settings-controller.mjs +31 -0
  100. package/template/apps/agent-server/plugins/settings-controller.test.ts +17 -0
  101. package/template/apps/agent-server/plugins/settings-dispatch.test.ts +34 -0
  102. package/template/apps/agent-server/plugins/shared-skills.d.mts +15 -0
  103. package/template/apps/agent-server/plugins/shared-skills.mjs +82 -0
  104. package/template/apps/agent-server/plugins/shared-skills.test.ts +51 -0
  105. package/template/apps/agent-server/plugins/skill-library/README.md +11 -0
  106. package/template/apps/agent-server/plugins/skill-library/archive.test.ts +43 -0
  107. package/template/apps/agent-server/plugins/skill-library/bundle.mjs +234 -0
  108. package/template/apps/agent-server/plugins/skill-library/client-chunks.test.ts +107 -0
  109. package/template/apps/agent-server/plugins/skill-library/client-form-mount.test.ts +139 -0
  110. package/template/apps/agent-server/plugins/skill-library/client-form.test.ts +261 -0
  111. package/template/apps/agent-server/plugins/skill-library/client-ui.test.ts +268 -0
  112. package/template/apps/agent-server/plugins/skill-library/client-use.test.ts +158 -0
  113. package/template/apps/agent-server/plugins/skill-library/client.editor.js +93 -0
  114. package/template/apps/agent-server/plugins/skill-library/client.form.js +316 -0
  115. package/template/apps/agent-server/plugins/skill-library/client.js +348 -0
  116. package/template/apps/agent-server/plugins/skill-library/client.request.js +52 -0
  117. package/template/apps/agent-server/plugins/skill-library/client.transfer.js +48 -0
  118. package/template/apps/agent-server/plugins/skill-library/client.use.js +46 -0
  119. package/template/apps/agent-server/plugins/skill-library/default-roots.test.ts +84 -0
  120. package/template/apps/agent-server/plugins/skill-library/draft.d.mts +17 -0
  121. package/template/apps/agent-server/plugins/skill-library/draft.mjs +152 -0
  122. package/template/apps/agent-server/plugins/skill-library/draft.test.ts +287 -0
  123. package/template/apps/agent-server/plugins/skill-library/index.d.mts +49 -0
  124. package/template/apps/agent-server/plugins/skill-library/index.mjs +226 -0
  125. package/template/apps/agent-server/plugins/skill-library/package.json +24 -0
  126. package/template/apps/agent-server/plugins/skill-library/presentation/README.md +27 -0
  127. package/template/apps/agent-server/plugins/skill-library/presentation/UPSTREAM.md +54 -0
  128. package/template/apps/agent-server/plugins/skill-library/presentation/boot.test.ts +150 -0
  129. package/template/apps/agent-server/plugins/skill-library/presentation/client.js +146 -0
  130. package/template/apps/agent-server/plugins/skill-library/presentation/client.test.ts +195 -0
  131. package/template/apps/agent-server/plugins/skill-library/presentation/index.d.mts +9 -0
  132. package/template/apps/agent-server/plugins/skill-library/presentation/index.mjs +30 -0
  133. package/template/apps/agent-server/plugins/skill-library/presentation/metadata.test.ts +82 -0
  134. package/template/apps/agent-server/plugins/skill-library/presentation/package.json +21 -0
  135. package/template/apps/agent-server/plugins/skill-library/presentation/react-boot.test.ts +162 -0
  136. package/template/apps/agent-server/plugins/skill-library/skills.test.ts +342 -0
  137. package/template/apps/agent-server/plugins/skill-library/storage.mjs +293 -0
  138. package/template/apps/agent-server/plugins/skill-library/style.css +229 -0
  139. package/template/apps/agent-server/plugins/skill-library/test-fixture.ts +77 -0
  140. package/template/apps/agent-server/plugins/skill-library/workflow.d.mts +18 -0
  141. package/template/apps/agent-server/plugins/skill-library/workflow.mjs +189 -0
  142. package/template/apps/agent-server/plugins/skill-library/workflow.test.ts +164 -0
  143. package/template/apps/agent-server/plugins/skills/README.md +5 -0
  144. package/template/apps/agent-server/plugins/skills/windy-data-summary/SKILL.md +14 -0
  145. package/template/apps/agent-server/plugins/skills/windy-extension-guide/SKILL.md +14 -0
  146. package/template/apps/agent-server/plugins/skills/windy-office/SKILL.md +14 -0
  147. package/template/apps/agent-server/plugins/skills/windy-skill-capture/SKILL.md +14 -0
  148. package/template/apps/agent-server/plugins/skills/windy-source-compare/SKILL.md +14 -0
  149. package/template/apps/agent-server/plugins/subprocess.mjs +40 -0
  150. package/template/apps/agent-server/plugins/theme/README.md +18 -0
  151. package/template/apps/agent-server/plugins/theme/client.js +18 -0
  152. package/template/apps/agent-server/plugins/theme/index.d.mts +9 -0
  153. package/template/apps/agent-server/plugins/theme/index.mjs +18 -0
  154. package/template/apps/agent-server/plugins/theme/package.json +19 -0
  155. package/template/apps/agent-server/plugins/theme/source-tokens.ts +82 -0
  156. package/template/apps/agent-server/plugins/theme/sync-tokens.ts +12 -0
  157. package/template/apps/agent-server/plugins/theme/theme.test.ts +193 -0
  158. package/template/apps/agent-server/plugins/theme/tokens.json +166 -0
  159. package/template/apps/agent-server/plugins/tool-catalog/README.md +79 -0
  160. package/template/apps/agent-server/plugins/tool-catalog/categories.mjs +111 -0
  161. package/template/apps/agent-server/plugins/tool-catalog/categories.test.ts +118 -0
  162. package/template/apps/agent-server/plugins/tool-catalog/client-cache.test.ts +264 -0
  163. package/template/apps/agent-server/plugins/tool-catalog/client.js +333 -0
  164. package/template/apps/agent-server/plugins/tool-catalog/client.test.ts +136 -0
  165. package/template/apps/agent-server/plugins/tool-catalog/discovery.d.mts +42 -0
  166. package/template/apps/agent-server/plugins/tool-catalog/discovery.mjs +242 -0
  167. package/template/apps/agent-server/plugins/tool-catalog/discovery.test.ts +229 -0
  168. package/template/apps/agent-server/plugins/tool-catalog/index.d.mts +5 -0
  169. package/template/apps/agent-server/plugins/tool-catalog/index.mjs +91 -0
  170. package/template/apps/agent-server/plugins/tool-catalog/package.json +23 -0
  171. package/template/apps/agent-server/plugins/tool-catalog/presentation.d.mts +21 -0
  172. package/template/apps/agent-server/plugins/tool-catalog/presentation.mjs +153 -0
  173. package/template/apps/agent-server/plugins/tool-catalog/presentation.test.ts +166 -0
  174. package/template/apps/agent-server/plugins/tool-catalog/routes.test.ts +209 -0
  175. package/template/apps/agent-server/plugins/tool-catalog/style.css +155 -0
  176. package/template/apps/agent-server/plugins/tool-catalog/use-tool.test.ts +160 -0
  177. package/template/apps/agent-server/plugins/tool-presentation/README.md +7 -0
  178. package/template/apps/agent-server/plugins/tool-presentation/build-client.ts +29 -0
  179. package/template/apps/agent-server/plugins/tool-presentation/client.js +312 -0
  180. package/template/apps/agent-server/plugins/tool-presentation/client.results.js +9 -0
  181. package/template/apps/agent-server/plugins/tool-presentation/client.test.ts +178 -0
  182. package/template/apps/agent-server/plugins/tool-presentation/index.mjs +10 -0
  183. package/template/apps/agent-server/plugins/tool-presentation/package.json +24 -0
  184. package/template/apps/agent-server/plugins/tool-presentation/result-discovery.mjs +43 -0
  185. package/template/apps/agent-server/plugins/tool-presentation/result-model.d.mts +51 -0
  186. package/template/apps/agent-server/plugins/tool-presentation/result-model.mjs +96 -0
  187. package/template/apps/agent-server/plugins/workspace/README.md +5 -0
  188. package/template/apps/agent-server/plugins/workspace/index.mjs +8 -0
  189. package/template/apps/agent-server/plugins/workspace/package.json +10 -0
  190. package/template/apps/agent-server/plugins/workspace/style.css +124 -0
  191. package/template/apps/agent-server/project/host.ts +13 -0
  192. package/template/apps/agent-server/runtime/artifacts.ts +115 -0
  193. package/template/apps/agent-server/runtime/audit.nodecheck.ts +60 -0
  194. package/template/apps/agent-server/runtime/capacity.ts +61 -0
  195. package/template/apps/agent-server/runtime/client-completion-budget.nodecheck.ts +92 -0
  196. package/template/apps/agent-server/runtime/compatibility.ts +33 -0
  197. package/template/apps/agent-server/runtime/completions.ts +320 -0
  198. package/template/apps/agent-server/runtime/config.ts +246 -0
  199. package/template/apps/agent-server/runtime/context-budget.ts +70 -0
  200. package/template/apps/agent-server/runtime/context-plugin.ts +306 -0
  201. package/template/apps/agent-server/runtime/context.nodecheck.ts +241 -0
  202. package/template/apps/agent-server/runtime/contracts.ts +201 -0
  203. package/template/apps/agent-server/runtime/dsh-engine.ts +196 -0
  204. package/template/apps/agent-server/runtime/evaluation-plugin.ts +115 -0
  205. package/template/apps/agent-server/runtime/evaluation.nodecheck.ts +194 -0
  206. package/template/apps/agent-server/runtime/events.ts +71 -0
  207. package/template/apps/agent-server/runtime/governance.ts +194 -0
  208. package/template/apps/agent-server/runtime/index.ts +339 -0
  209. package/template/apps/agent-server/runtime/internal-output.ts +37 -0
  210. package/template/apps/agent-server/runtime/isolation.nodecheck.ts +287 -0
  211. package/template/apps/agent-server/runtime/model-payload.ts +97 -0
  212. package/template/apps/agent-server/runtime/model-plugin.ts +308 -0
  213. package/template/apps/agent-server/runtime/model-route.ts +34 -0
  214. package/template/apps/agent-server/runtime/model-usage.ts +51 -0
  215. package/template/apps/agent-server/runtime/model-wire.ts +45 -0
  216. package/template/apps/agent-server/runtime/native-authorization.nodecheck.ts +126 -0
  217. package/template/apps/agent-server/runtime/native-completion.nodecheck.ts +81 -0
  218. package/template/apps/agent-server/runtime/output-validation.ts +66 -0
  219. package/template/apps/agent-server/runtime/production-capacity.nodecheck.ts +121 -0
  220. package/template/apps/agent-server/runtime/questions-workflow.nodecheck.ts +249 -0
  221. package/template/apps/agent-server/runtime/report-breakdown.ts +79 -0
  222. package/template/apps/agent-server/runtime/reporting.ts +219 -0
  223. package/template/apps/agent-server/runtime/run-completion.ts +39 -0
  224. package/template/apps/agent-server/runtime/run-request-digest.ts +18 -0
  225. package/template/apps/agent-server/runtime/runtime-test-fixtures.ts +264 -0
  226. package/template/apps/agent-server/runtime/runtime.nodecheck.ts +150 -0
  227. package/template/apps/agent-server/runtime/store-idempotency.nodecheck.ts +74 -0
  228. package/template/apps/agent-server/runtime/store.ts +324 -0
  229. package/template/apps/agent-server/runtime/structured-output-mode.nodecheck.ts +51 -0
  230. package/template/apps/agent-server/runtime/tool-name.ts +6 -0
  231. package/template/apps/agent-server/runtime/tool-plugin.ts +201 -0
  232. package/template/apps/agent-server/runtime/vision-readiness.ts +200 -0
  233. package/template/apps/agent-server/scripts/confinement-check.mjs +103 -0
  234. package/template/apps/agent-server/scripts/coordinator-check.mjs +344 -0
  235. package/template/apps/agent-server/scripts/documents-delivery-check.mjs +309 -0
  236. package/template/apps/agent-server/scripts/office-preview-check.mjs +92 -0
  237. package/template/apps/agent-server/scripts/test-confinement.ts +58 -0
  238. package/template/apps/agent-server/scripts/test-coordinator.ts +36 -0
  239. package/template/apps/agent-server/scripts/test-runtime.ts +46 -0
  240. package/template/apps/agent-server/tsconfig.json +21 -0
  241. package/template/apps/server/Dockerfile +3 -0
  242. package/template/apps/server/package.json +5 -1
  243. package/template/apps/server/scripts/check-dsh-platform-example.ts +251 -0
  244. package/template/apps/server/src/agent/dsh-runtime-wire.test.ts +33 -0
  245. package/template/apps/server/src/agent/governance-runtime.ts +41 -0
  246. package/template/apps/server/src/agent/remote-runtime-response.ts +1 -1
  247. package/template/apps/server/src/agent/run-contracts.ts +1 -0
  248. package/template/apps/server/src/agent/run-definition-support.ts +9 -0
  249. package/template/apps/server/src/agent/runtime-tool-composition.ts +2 -0
  250. package/template/apps/server/src/agent/workflow-runtime-bootstrap.ts +9 -0
  251. package/template/apps/server/src/agent-skills/access.ts +88 -0
  252. package/template/apps/server/src/agent-skills/bootstrap.ts +49 -0
  253. package/template/apps/server/src/agent-skills/builtin-registration.ts +83 -0
  254. package/template/apps/server/src/agent-skills/builtins.ts +19 -0
  255. package/template/apps/server/src/agent-skills/bundle-zip.ts +163 -0
  256. package/template/apps/server/src/agent-skills/bundle.test.ts +79 -0
  257. package/template/apps/server/src/agent-skills/bundle.ts +133 -0
  258. package/template/apps/server/src/agent-skills/contracts.ts +46 -0
  259. package/template/apps/server/src/agent-skills/drizzle-repository.ts +125 -0
  260. package/template/apps/server/src/agent-skills/input.ts +29 -0
  261. package/template/apps/server/src/agent-skills/postgres.integration.test.ts +348 -0
  262. package/template/apps/server/src/agent-skills/read-routes.test.ts +116 -0
  263. package/template/apps/server/src/agent-skills/reader.ts +108 -0
  264. package/template/apps/server/src/agent-skills/repository.ts +105 -0
  265. package/template/apps/server/src/agent-skills/routes.ts +176 -0
  266. package/template/apps/server/src/agent-skills/service.test.ts +295 -0
  267. package/template/apps/server/src/agent-skills/service.ts +301 -0
  268. package/template/apps/server/src/agent-workflow/preset-registry.test.ts +137 -0
  269. package/template/apps/server/src/agent-workflow/preset-registry.ts +191 -0
  270. package/template/apps/server/src/agent-workflow/preset-routes.test.ts +94 -0
  271. package/template/apps/server/src/agent-workflow/preset-routes.ts +45 -0
  272. package/template/apps/server/src/ai-runtime-report/service.test.ts +10 -7
  273. package/template/apps/server/src/ai-runtime-report/service.ts +1 -1
  274. package/template/apps/server/src/app/agent-workflow-presets.ts +4 -0
  275. package/template/apps/server/src/app/dsh-skill-draft-audit.test.ts +195 -0
  276. package/template/apps/server/src/app/dsh-skill-draft-audit.ts +115 -0
  277. package/template/apps/server/src/app/dsh-workbench-audit.test.ts +71 -0
  278. package/template/apps/server/src/app/dsh-workbench-audit.ts +34 -0
  279. package/template/apps/server/src/app/dsh-workbench-handshake.test.ts +63 -0
  280. package/template/apps/server/src/app/dsh-workbench-handshake.ts +48 -0
  281. package/template/apps/server/src/app/dsh-workbench-http.test.ts +96 -0
  282. package/template/apps/server/src/app/dsh-workbench-lan-origin.test.ts +114 -0
  283. package/template/apps/server/src/app/dsh-workbench-launch.test.ts +70 -0
  284. package/template/apps/server/src/app/dsh-workbench-origin.test.ts +54 -0
  285. package/template/apps/server/src/app/dsh-workbench-proxy.ts +205 -0
  286. package/template/apps/server/src/app/dsh-workbench-session-conflict.test.ts +61 -0
  287. package/template/apps/server/src/app/dsh-workbench-session.ts +59 -0
  288. package/template/apps/server/src/app/dsh-workbench-socket-audit.test.ts +115 -0
  289. package/template/apps/server/src/app/dsh-workbench-socket.test.ts +246 -0
  290. package/template/apps/server/src/app/dsh-workbench-socket.ts +272 -0
  291. package/template/apps/server/src/app/dsh-workbench-test-support.ts +158 -0
  292. package/template/apps/server/src/app/dsh-workbench.test.ts +213 -0
  293. package/template/apps/server/src/app/dsh-workbench.ts +279 -0
  294. package/template/apps/server/src/app/workbench-public-origin.ts +16 -0
  295. package/template/apps/server/src/data-governance/user-plaintext-routes.test.ts +3 -0
  296. package/template/apps/server/src/http-app.ts +31 -0
  297. package/template/apps/server/src/mcp/adapter.ts +1 -0
  298. package/template/apps/server/src/module-composition.test.ts +23 -0
  299. package/template/apps/server/src/module-composition.ts +9 -2
  300. package/template/apps/server/src/observability/bootstrap.ts +12 -0
  301. package/template/apps/server/src/observability/diagnostic-failure-recorder.ts +94 -0
  302. package/template/apps/server/src/observability/diagnostic-http-contract.test.ts +42 -0
  303. package/template/apps/server/src/observability/diagnostic-index.test.ts +89 -0
  304. package/template/apps/server/src/observability/diagnostic-index.ts +88 -0
  305. package/template/apps/server/src/observability/diagnostic-repository.ts +67 -0
  306. package/template/apps/server/src/platform-app-bootstrap.ts +42 -0
  307. package/template/apps/server/src/platform-http-runtime.ts +6 -0
  308. package/template/apps/server/src/runtime-development.test.ts +25 -0
  309. package/template/apps/server/src/runtime-development.ts +6 -44
  310. package/template/apps/server/src/system/diagnostic-routes.test.ts +78 -0
  311. package/template/apps/server/src/system/diagnostic-routes.ts +66 -0
  312. package/template/apps/web/Dockerfile +9 -1
  313. package/template/apps/web/dev/start.ts +21 -10
  314. package/template/apps/web/dsh-workbench-location.ts +21 -0
  315. package/template/apps/web/dsh-workbench-proxy.test.ts +121 -0
  316. package/template/apps/web/dsh-workbench-proxy.ts +194 -0
  317. package/template/apps/web/package.json +3 -1
  318. package/template/apps/web/server.ts +27 -6
  319. package/template/apps/web/src/composables/useLoginFlow.ts +13 -1
  320. package/template/apps/web/src/pages/errors/PlatformErrorPage.vue +6 -0
  321. package/template/apps/web/src/pages/errors/PlatformErrorPage.webtest.ts +14 -1
  322. package/template/apps/web/src/pages/errors/error-page-extension.ts +1 -0
  323. package/template/apps/web/src/pages/system/AgentNativePage.vue +44 -0
  324. package/template/apps/web/src/pages/system/AgentWorkflowPage.vue +20 -7
  325. package/template/apps/web/src/pages/system/DiagnosticLookupPage.vue +56 -0
  326. package/template/apps/web/src/pages/system/DiagnosticLookupPage.webtest.ts +99 -0
  327. package/template/apps/web/src/pages/system/SystemAgentSkillsPage.vue +88 -0
  328. package/template/apps/web/src/pages/system/components/DiagnosticRecordDetails.vue +52 -0
  329. package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillDetailDialog.vue +166 -0
  330. package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillGovernanceActionDialog.vue +51 -0
  331. package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillImportDialog.vue +320 -0
  332. package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillImportDialog.webtest.ts +96 -0
  333. package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillsTable.vue +69 -0
  334. package/template/apps/web/src/pages/system/components/agent-workflow/WorkflowPresetCatalog.vue +82 -0
  335. package/template/apps/web/src/pages/system/components/agent-workflow/WorkflowPresetCatalog.webtest.ts +57 -0
  336. package/template/apps/web/src/pages/system/composables/useAgentSkillsGovernance.ts +105 -0
  337. package/template/apps/web/src/pages/system/composables/useAgentWorkflowPresets.ts +44 -0
  338. package/template/apps/web/src/pages/system/composables/useDiagnosticLookup.ts +64 -0
  339. package/template/apps/web/src/router/error-navigation.ts +3 -1
  340. package/template/apps/web/src/router/error-navigation.webtest.ts +14 -2
  341. package/template/apps/web/src/router/index.ts +8 -49
  342. package/template/apps/web/src/router/platform-admin-pages.ts +79 -0
  343. package/template/apps/web/src/router/platform-admin-route-bindings.ts +8 -0
  344. package/template/apps/web/src/services/agent-skills-api.ts +55 -0
  345. package/template/apps/web/src/services/agent-workflow-api.ts +12 -0
  346. package/template/apps/web/src/services/diagnostics-api.ts +12 -0
  347. package/template/apps/web/src/services/http.ts +18 -0
  348. package/template/apps/web/src/services/http.webtest.ts +51 -0
  349. package/template/apps/web/vite.config.ts +39 -0
  350. package/template/deploy/dsh/README.md +5 -0
  351. package/template/deploy/dsh/documents/README.md +9 -0
  352. package/template/deploy/dsh/documents/requirements.in +6 -0
  353. package/template/deploy/dsh/documents/requirements.lock +72 -0
  354. package/template/docker-compose.yml +24 -10
  355. package/template/docs/adr/0004-embedded-dsh-runtime.md +9 -0
  356. package/template/docs/architecture/agent-admin-workbench-implementation.md +73 -0
  357. package/template/docs/architecture/agent-admin-workbench-plan.md +41 -0
  358. package/template/docs/architecture/agent-harness.md +2 -0
  359. package/template/docs/architecture/agent-runtime-compatibility.md +2 -0
  360. package/template/docs/architecture/embedded-dsh-integration.md +44 -0
  361. package/template/docs/development/dsh-plugins.md +55 -0
  362. package/template/docs/operations/dsh-agent-migration.md +98 -0
  363. package/template/docs/platform/agent-production-store.md +5 -78
  364. package/template/docs/platform/agent-runtime-observability.md +2 -0
  365. package/template/docs/platform/agent-runtime.md +2 -0
  366. package/template/docs/platform/agent-skills.md +25 -0
  367. package/template/package.json +4 -3
  368. package/template/packages/database/drizzle/0064_dsh_skills_diagnostics.sql +42 -0
  369. package/template/packages/database/drizzle/meta/0064_snapshot.json +15349 -0
  370. package/template/packages/database/drizzle/meta/_journal.json +7 -0
  371. package/template/packages/database/package.json +2 -2
  372. package/template/packages/database/src/schema/agent-skills.ts +65 -0
  373. package/template/packages/database/src/schema/diagnostics.ts +27 -0
  374. package/template/packages/database/src/schema/index.ts +8 -0
  375. package/template/packages/modules/package.json +1 -1
  376. package/template/packages/modules/src/system-admin-routes.ts +24 -0
  377. package/template/packages/modules/src/system-admin-ui-catalog.ts +17 -10
  378. package/template/packages/modules/src/system-agent-admin-bindings.ts +2 -0
  379. package/template/packages/modules/src/system-agent-admin-menus.ts +20 -0
  380. package/template/packages/modules/src/system-agent-audit-actions.ts +3 -0
  381. package/template/packages/modules/src/system-agent-dsh.ts +119 -0
  382. package/template/packages/modules/src/system-api-permissions.ts +9 -0
  383. package/template/packages/modules/src/system-audit-actions.ts +11 -0
  384. package/template/packages/modules/src/system-features.ts +5 -0
  385. package/template/packages/modules/src/system-module-audit-selection.ts +25 -0
  386. package/template/packages/modules/src/system-module-catalog.ts +12 -32
  387. package/template/packages/modules/src/system-modules.ts +14 -3
  388. package/template/packages/modules/src/system-permissions.ts +10 -0
  389. package/template/packages/server-sdk/package.json +2 -2
  390. package/template/packages/shared/index.ts +12 -0
  391. package/template/packages/shared/package.json +1 -1
  392. package/template/packages/shared/src/agent-skills.ts +68 -0
  393. package/template/packages/shared/src/agent-workflow-presets.ts +26 -0
  394. package/template/packages/shared/src/diagnostics.ts +13 -0
  395. package/template/packages/shared/src/rbac.ts +1 -0
  396. package/template/apps/agent-server/install-python-dependencies.sh +0 -92
  397. package/template/apps/agent-server/pyproject.toml +0 -51
  398. package/template/apps/agent-server/src/southwind_agent_server/__init__.py +0 -5
  399. package/template/apps/agent-server/src/southwind_agent_server/app.py +0 -344
  400. package/template/apps/agent-server/src/southwind_agent_server/approval_resolution.py +0 -30
  401. package/template/apps/agent-server/src/southwind_agent_server/artifact_input.py +0 -153
  402. package/template/apps/agent-server/src/southwind_agent_server/asgi.py +0 -8
  403. package/template/apps/agent-server/src/southwind_agent_server/attempt_context.py +0 -199
  404. package/template/apps/agent-server/src/southwind_agent_server/attempt_context_projection.py +0 -203
  405. package/template/apps/agent-server/src/southwind_agent_server/client_completion_contracts.py +0 -61
  406. package/template/apps/agent-server/src/southwind_agent_server/client_completion_governance.py +0 -82
  407. package/template/apps/agent-server/src/southwind_agent_server/client_completion_routes.py +0 -121
  408. package/template/apps/agent-server/src/southwind_agent_server/client_completion_runtime.py +0 -158
  409. package/template/apps/agent-server/src/southwind_agent_server/config.py +0 -267
  410. package/template/apps/agent-server/src/southwind_agent_server/context_message_digest.py +0 -24
  411. package/template/apps/agent-server/src/southwind_agent_server/context_version_contracts.py +0 -71
  412. package/template/apps/agent-server/src/southwind_agent_server/context_version_port.py +0 -307
  413. package/template/apps/agent-server/src/southwind_agent_server/contracts.py +0 -297
  414. package/template/apps/agent-server/src/southwind_agent_server/deterministic.py +0 -63
  415. package/template/apps/agent-server/src/southwind_agent_server/engine.py +0 -134
  416. package/template/apps/agent-server/src/southwind_agent_server/engine_capacity.py +0 -31
  417. package/template/apps/agent-server/src/southwind_agent_server/engine_identity.py +0 -2
  418. package/template/apps/agent-server/src/southwind_agent_server/fingerprint.py +0 -61
  419. package/template/apps/agent-server/src/southwind_agent_server/health_routes.py +0 -93
  420. package/template/apps/agent-server/src/southwind_agent_server/http_helpers.py +0 -62
  421. package/template/apps/agent-server/src/southwind_agent_server/lease.py +0 -15
  422. package/template/apps/agent-server/src/southwind_agent_server/multimodal.py +0 -76
  423. package/template/apps/agent-server/src/southwind_agent_server/openai_engine.py +0 -329
  424. package/template/apps/agent-server/src/southwind_agent_server/openai_engine_validation.py +0 -165
  425. package/template/apps/agent-server/src/southwind_agent_server/openai_provider.py +0 -345
  426. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_insert.py +0 -37
  427. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_queries.py +0 -235
  428. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_replay.py +0 -44
  429. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_status.py +0 -83
  430. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_store.py +0 -336
  431. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_summary.py +0 -304
  432. package/template/apps/agent-server/src/southwind_agent_server/postgres_store.py +0 -335
  433. package/template/apps/agent-server/src/southwind_agent_server/postgres_store_backend.py +0 -333
  434. package/template/apps/agent-server/src/southwind_agent_server/provider_audit.py +0 -144
  435. package/template/apps/agent-server/src/southwind_agent_server/provider_governance.py +0 -309
  436. package/template/apps/agent-server/src/southwind_agent_server/provider_output_guidance.py +0 -34
  437. package/template/apps/agent-server/src/southwind_agent_server/readiness_pin.py +0 -37
  438. package/template/apps/agent-server/src/southwind_agent_server/report_lifecycle.py +0 -218
  439. package/template/apps/agent-server/src/southwind_agent_server/report_metrics.py +0 -149
  440. package/template/apps/agent-server/src/southwind_agent_server/report_presenter.py +0 -300
  441. package/template/apps/agent-server/src/southwind_agent_server/report_routes.py +0 -132
  442. package/template/apps/agent-server/src/southwind_agent_server/report_store.py +0 -298
  443. package/template/apps/agent-server/src/southwind_agent_server/report_store_protocol.py +0 -75
  444. package/template/apps/agent-server/src/southwind_agent_server/report_types.py +0 -118
  445. package/template/apps/agent-server/src/southwind_agent_server/run_admission.py +0 -64
  446. package/template/apps/agent-server/src/southwind_agent_server/run_capacity.py +0 -59
  447. package/template/apps/agent-server/src/southwind_agent_server/runtime_budget.py +0 -74
  448. package/template/apps/agent-server/src/southwind_agent_server/runtime_compatibility.py +0 -89
  449. package/template/apps/agent-server/src/southwind_agent_server/runtime_factory.py +0 -105
  450. package/template/apps/agent-server/src/southwind_agent_server/runtime_logging.py +0 -57
  451. package/template/apps/agent-server/src/southwind_agent_server/service.py +0 -325
  452. package/template/apps/agent-server/src/southwind_agent_server/service_control.py +0 -64
  453. package/template/apps/agent-server/src/southwind_agent_server/service_errors.py +0 -4
  454. package/template/apps/agent-server/src/southwind_agent_server/service_execution.py +0 -34
  455. package/template/apps/agent-server/src/southwind_agent_server/service_tasks.py +0 -34
  456. package/template/apps/agent-server/src/southwind_agent_server/signal_events.py +0 -53
  457. package/template/apps/agent-server/src/southwind_agent_server/sqlite_catalog.py +0 -118
  458. package/template/apps/agent-server/src/southwind_agent_server/sqlite_errors.py +0 -2
  459. package/template/apps/agent-server/src/southwind_agent_server/sqlite_schema.py +0 -73
  460. package/template/apps/agent-server/src/southwind_agent_server/sqlite_serialization.py +0 -16
  461. package/template/apps/agent-server/src/southwind_agent_server/sqlite_store.py +0 -350
  462. package/template/apps/agent-server/src/southwind_agent_server/sse.py +0 -41
  463. package/template/apps/agent-server/src/southwind_agent_server/store.py +0 -255
  464. package/template/apps/agent-server/src/southwind_agent_server/store_cipher.py +0 -40
  465. package/template/apps/agent-server/src/southwind_agent_server/structured_logging.py +0 -145
  466. package/template/apps/agent-server/src/southwind_agent_server/telemetry.py +0 -93
  467. package/template/apps/agent-server/src/southwind_agent_server/tool_host.py +0 -152
  468. package/template/apps/agent-server/src/southwind_agent_server/trajectory.py +0 -137
  469. package/template/apps/agent-server/src/southwind_agent_server/unavailable_engine.py +0 -58
  470. package/template/apps/agent-server/src/southwind_agent_server/vision_probe.py +0 -87
  471. package/template/apps/agent-server/src/southwind_agent_server/vision_requirement.py +0 -28
  472. package/template/apps/agent-server/src/southwind_agent_server/vlm_readiness.py +0 -247
  473. package/template/apps/agent-server/tests/__init__.py +0 -1
  474. package/template/apps/agent-server/tests/openai_provider_test_support.py +0 -131
  475. package/template/apps/agent-server/tests/test_api.py +0 -305
  476. package/template/apps/agent-server/tests/test_artifact_input.py +0 -110
  477. package/template/apps/agent-server/tests/test_client_completion.py +0 -230
  478. package/template/apps/agent-server/tests/test_config.py +0 -106
  479. package/template/apps/agent-server/tests/test_fingerprint.py +0 -10
  480. package/template/apps/agent-server/tests/test_multimodal.py +0 -81
  481. package/template/apps/agent-server/tests/test_openai_provider.py +0 -320
  482. package/template/apps/agent-server/tests/test_postgres_report_status.py +0 -59
  483. package/template/apps/agent-server/tests/test_postgres_report_summary.py +0 -298
  484. package/template/apps/agent-server/tests/test_postgres_store.py +0 -135
  485. package/template/apps/agent-server/tests/test_provider_attempt_reporting.py +0 -140
  486. package/template/apps/agent-server/tests/test_provider_governance.py +0 -276
  487. package/template/apps/agent-server/tests/test_report_attempt_lifecycle.py +0 -126
  488. package/template/apps/agent-server/tests/test_report_resilience.py +0 -183
  489. package/template/apps/agent-server/tests/test_report_routes.py +0 -143
  490. package/template/apps/agent-server/tests/test_report_store.py +0 -347
  491. package/template/apps/agent-server/tests/test_report_summary_parity.py +0 -116
  492. package/template/apps/agent-server/tests/test_report_terminal_sync.py +0 -177
  493. package/template/apps/agent-server/tests/test_run_capacity.py +0 -112
  494. package/template/apps/agent-server/tests/test_run_operational_logging.py +0 -114
  495. package/template/apps/agent-server/tests/test_runtime_compatibility.py +0 -119
  496. package/template/apps/agent-server/tests/test_runtime_factory_readiness.py +0 -52
  497. package/template/apps/agent-server/tests/test_sqlite_store.py +0 -182
  498. package/template/apps/agent-server/tests/test_structured_logging.py +0 -142
  499. package/template/apps/agent-server/tests/test_telemetry.py +0 -25
  500. package/template/apps/agent-server/tests/test_tool_approval.py +0 -28
  501. package/template/apps/agent-server/tests/test_tool_structured_output.py +0 -347
  502. package/template/apps/agent-server/tests/test_trajectory.py +0 -91
  503. package/template/apps/agent-server/tests/test_vision_readiness_enforcement.py +0 -72
  504. package/template/apps/agent-server/tests/test_vlm_readiness.py +0 -106
  505. package/template/apps/agent-server/uv.lock +0 -831
package/dist/cli.js CHANGED
@@ -206,6 +206,45 @@ var starterProfile = {
206
206
  };
207
207
  var projectLicenseKeys = ["UNLICENSED", "MIT", "Apache-2.0"];
208
208
 
209
+ // src/module-distribution-audit.ts
210
+ var auditDistribution = {
211
+ fileRoots: [
212
+ "apps/server/src/audit/drizzle-log-store.ts",
213
+ "apps/server/src/audit/recovery-queue.ts",
214
+ "apps/server/src/audit/recovery-queue.test.ts",
215
+ "apps/server/src/audit/reliable-writer.ts",
216
+ "apps/server/src/audit/reliable-writer.test.ts",
217
+ "apps/server/src/persistence.integration.test.ts",
218
+ "apps/server/src/system/audit-routes.ts",
219
+ "apps/server/src/observability/diagnostic-index.ts",
220
+ "apps/server/src/observability/diagnostic-index.test.ts",
221
+ "apps/server/src/observability/diagnostic-http-contract.test.ts",
222
+ "apps/server/src/observability/diagnostic-repository.ts",
223
+ "apps/server/src/observability/diagnostic-failure-recorder.ts",
224
+ "apps/server/src/system/diagnostic-routes.ts",
225
+ "apps/server/src/system/diagnostic-routes.test.ts",
226
+ "apps/web/src/pages/system/DiagnosticLookupPage.vue",
227
+ "apps/web/src/pages/system/DiagnosticLookupPage.webtest.ts",
228
+ "apps/web/src/pages/system/components/DiagnosticRecordDetails.vue",
229
+ "apps/web/src/pages/system/composables/useDiagnosticLookup.ts",
230
+ "apps/web/src/services/diagnostics-api.ts",
231
+ "packages/shared/src/diagnostics.ts",
232
+ "apps/server/src/system/audit-routes.test.ts",
233
+ "apps/web/src/pages/system/audit-log-presenter.ts",
234
+ "apps/web/src/pages/system/audit-time-range.ts",
235
+ "apps/web/src/pages/system/components/AuditActionCell.vue",
236
+ "apps/web/src/pages/system/components/AuditActionCell.webtest.ts",
237
+ "apps/web/src/pages/system/components/AuditLogDetailDialog.vue",
238
+ "apps/web/src/pages/system/components/AuditLogDetailDialog.webtest.ts",
239
+ "apps/web/src/pages/system/components/AuditLogFilters.vue",
240
+ "apps/web/src/pages/system/components/AuditLogFilters.webtest.ts"
241
+ ],
242
+ documentation: ["docs/platform/audit-reliability.md"],
243
+ schemaFiles: ["packages/database/src/schema/diagnostics.ts"],
244
+ databaseTables: ["audit_logs", "diagnostic_events"],
245
+ databaseStatementTokens: ["idx_audit_logs_", "idx_diagnostic_events_"]
246
+ };
247
+
209
248
  // src/module-distribution-validation.ts
210
249
  function validateModuleDistributionCatalog(manifests) {
211
250
  const names = new Set;
@@ -281,6 +320,8 @@ var agentOptionalModule = {
281
320
  "system.workflow"
282
321
  ]),
283
322
  registryDependencies: [
323
+ { sourceName: "fflate", name: "fflate", version: "0.8.3" },
324
+ { sourceName: "yaml", name: "yaml", version: "2.9.0" },
284
325
  {
285
326
  sourceName: "@modelcontextprotocol/sdk",
286
327
  name: "@modelcontextprotocol/sdk",
@@ -294,15 +335,39 @@ var agentOptionalModule = {
294
335
  ],
295
336
  fileRoots: [
296
337
  "apps/agent-server",
338
+ "apps/server/scripts/check-dsh-platform-example.ts",
297
339
  "apps/document-server",
298
340
  "apps/speech-server",
299
341
  "apps/embedding-server",
300
342
  "apps/server/src/agent",
343
+ "apps/server/src/agent-skills",
344
+ "deploy/dsh",
301
345
  "apps/server/src/agent-workflow",
302
346
  "apps/server/src/ai-runtime-report",
303
347
  "apps/server/src/ai-runtime-readiness",
304
348
  "apps/server/src/app/ai-screenshot-intake-binding.ts",
305
349
  "apps/server/src/app/agent-runtime-composition.ts",
350
+ "apps/server/src/app/workbench-public-origin.ts",
351
+ "apps/server/src/app/agent-workflow-presets.ts",
352
+ "apps/server/src/app/dsh-skill-draft-audit.test.ts",
353
+ "apps/server/src/app/dsh-skill-draft-audit.ts",
354
+ "apps/server/src/app/dsh-workbench-handshake.test.ts",
355
+ "apps/server/src/app/dsh-workbench-audit.ts",
356
+ "apps/server/src/app/dsh-workbench-audit.test.ts",
357
+ "apps/server/src/app/dsh-workbench-socket-audit.test.ts",
358
+ "apps/server/src/app/dsh-workbench-handshake.ts",
359
+ "apps/server/src/app/dsh-workbench-http.test.ts",
360
+ "apps/server/src/app/dsh-workbench-lan-origin.test.ts",
361
+ "apps/server/src/app/dsh-workbench-launch.test.ts",
362
+ "apps/server/src/app/dsh-workbench-origin.test.ts",
363
+ "apps/server/src/app/dsh-workbench-proxy.ts",
364
+ "apps/server/src/app/dsh-workbench-session-conflict.test.ts",
365
+ "apps/server/src/app/dsh-workbench-session.ts",
366
+ "apps/server/src/app/dsh-workbench-socket.test.ts",
367
+ "apps/server/src/app/dsh-workbench-socket.ts",
368
+ "apps/server/src/app/dsh-workbench-test-support.ts",
369
+ "apps/server/src/app/dsh-workbench.test.ts",
370
+ "apps/server/src/app/dsh-workbench.ts",
306
371
  "apps/server/src/app/client-agent-host-auth-binding.ts",
307
372
  "apps/server/src/app/client-agent-workflow-artifact-binding.ts",
308
373
  "apps/server/src/app/document-output-artifact-bindings.ts",
@@ -324,8 +389,17 @@ var agentOptionalModule = {
324
389
  "apps/server/src/module-host/tool-handlers.ts",
325
390
  "apps/server/src/module-host/tool-handlers.test.ts",
326
391
  "apps/server/src/module-host/module-secret-tool-boundary.test.ts",
392
+ "apps/web/dsh-workbench-proxy.ts",
393
+ "apps/web/dsh-workbench-proxy.test.ts",
394
+ "apps/web/dsh-workbench-location.ts",
327
395
  "apps/web/src/pages/system/AiRuntimePage.vue",
328
396
  "apps/web/src/pages/system/AgentToolsPage.vue",
397
+ "apps/web/src/pages/system/SystemAgentSkillsPage.vue",
398
+ "apps/web/src/pages/system/SystemAgentSkillsPage.webtest.ts",
399
+ "apps/web/src/pages/system/components/agent-skills",
400
+ "apps/web/src/pages/system/composables/useAgentSkillsGovernance.ts",
401
+ "apps/web/src/pages/system/composables/useAgentWorkflowPresets.ts",
402
+ "apps/web/src/services/agent-skills-api.ts",
329
403
  "apps/web/src/pages/system/AgentDebugPage.vue",
330
404
  "apps/web/src/pages/system/components/agent-workbench",
331
405
  "apps/web/src/pages/system/composables/useAgentWorkbench.ts",
@@ -358,6 +432,7 @@ var agentOptionalModule = {
358
432
  "packages/modules/src/system-agent-admin-bindings.ts",
359
433
  "packages/modules/src/system-agent-audit-actions.ts",
360
434
  "packages/modules/src/system-agent-tools.ts",
435
+ "packages/modules/src/system-agent-dsh.ts",
361
436
  "packages/modules/src/system-agent-supervisor.ts",
362
437
  "packages/modules/src/system-agent-supervisor.test.ts",
363
438
  "packages/modules/src/system-ai-api-bindings.ts",
@@ -373,6 +448,8 @@ var agentOptionalModule = {
373
448
  "packages/database/src/ai-output-artifacts.test.ts",
374
449
  "packages/shared/src/agent-admin-catalog.ts",
375
450
  "packages/shared/src/agent-workbench.ts",
451
+ "packages/shared/src/agent-skills.ts",
452
+ "packages/shared/src/agent-workflow-presets.ts",
376
453
  "packages/shared/src/agent-workflow-definition.ts",
377
454
  "packages/shared/src/agent-workflow-delegation.ts",
378
455
  "packages/shared/src/agent-workflow-evaluation.ts",
@@ -385,9 +462,14 @@ var agentOptionalModule = {
385
462
  ],
386
463
  documentation: [
387
464
  "docs/adr/0003-agent-session-event-source.md",
465
+ "docs/adr/0004-embedded-dsh-runtime.md",
388
466
  "docs/architecture/agent-admin-workbench-plan.md",
389
467
  "docs/architecture/agent-admin-workbench-implementation.md",
390
468
  "docs/architecture/agent-harness.md",
469
+ "docs/architecture/embedded-dsh-integration.md",
470
+ "docs/platform/agent-skills.md",
471
+ "docs/operations/dsh-agent-migration.md",
472
+ "docs/development/dsh-plugins.md",
391
473
  "docs/architecture/agent-runtime-compatibility.md",
392
474
  "docs/architecture/agent-workflow.md",
393
475
  "docs/architecture/durable-jobs.md",
@@ -417,6 +499,7 @@ var agentOptionalModule = {
417
499
  ],
418
500
  schemaFiles: [
419
501
  "packages/database/src/schema/agent-runtime.ts",
502
+ "packages/database/src/schema/agent-skills.ts",
420
503
  "packages/database/src/schema/agent-context-message.ts",
421
504
  "packages/database/src/schema/agent-session-receipt.ts",
422
505
  "packages/database/src/schema/agent-session.ts",
@@ -431,6 +514,8 @@ var agentOptionalModule = {
431
514
  ],
432
515
  databaseTables: [
433
516
  "agent_operation_releases",
517
+ "agent_skill_versions",
518
+ "agent_skill_mutations",
434
519
  "agent_runtime_runs",
435
520
  "agent_runtime_events",
436
521
  "agent_evaluation_results",
@@ -468,6 +553,9 @@ var agentOptionalModule = {
468
553
  ],
469
554
  databaseStatementTokens: [
470
555
  "idx_agent_context_sources_origin",
556
+ "idx_agent_skill_",
557
+ "uk_agent_skill_",
558
+ "ck_agent_skill_",
471
559
  "idx_agent_memory_sources_origin",
472
560
  "uk_agent_source_invalidations_sequence",
473
561
  "agent_workflow_",
@@ -826,27 +914,7 @@ var platformModules = [
826
914
  },
827
915
  {
828
916
  ...module("system.audit", "\u5BA1\u8BA1\u65E5\u5FD7", "\u5BA1\u8BA1\u67E5\u8BE2\u3001\u53EF\u9760\u5199\u5165\u548C\u6062\u590D\u3002", "recommended", ["system"]),
829
- fileRoots: [
830
- "apps/server/src/audit/drizzle-log-store.ts",
831
- "apps/server/src/audit/recovery-queue.ts",
832
- "apps/server/src/audit/recovery-queue.test.ts",
833
- "apps/server/src/audit/reliable-writer.ts",
834
- "apps/server/src/audit/reliable-writer.test.ts",
835
- "apps/server/src/persistence.integration.test.ts",
836
- "apps/server/src/system/audit-routes.ts",
837
- "apps/server/src/system/audit-routes.test.ts",
838
- "apps/web/src/pages/system/audit-log-presenter.ts",
839
- "apps/web/src/pages/system/audit-time-range.ts",
840
- "apps/web/src/pages/system/components/AuditActionCell.vue",
841
- "apps/web/src/pages/system/components/AuditActionCell.webtest.ts",
842
- "apps/web/src/pages/system/components/AuditLogDetailDialog.vue",
843
- "apps/web/src/pages/system/components/AuditLogDetailDialog.webtest.ts",
844
- "apps/web/src/pages/system/components/AuditLogFilters.vue",
845
- "apps/web/src/pages/system/components/AuditLogFilters.webtest.ts"
846
- ],
847
- documentation: ["docs/platform/audit-reliability.md"],
848
- databaseTables: ["audit_logs"],
849
- databaseStatementTokens: ["idx_audit_logs_"]
917
+ ...auditDistribution
850
918
  },
851
919
  {
852
920
  ...module("system.operations", "\u8FD0\u7EF4\u76D1\u63A7", "\u670D\u52A1\u3001\u6570\u636E\u5E93\u3001\u7F13\u5B58\u3001\u78C1\u76D8\u548C\u4F1A\u8BDD\u76D1\u63A7\u3002", "recommended", ["system", "system.configuration"]),
@@ -868,6 +936,8 @@ var platformModules = [
868
936
  "apps/web/src/pages/system/components/OperationOnlineUsers.webtest.ts",
869
937
  "apps/web/src/pages/system/components/OperationServiceMonitor.vue",
870
938
  "apps/web/src/pages/system/components/OperationServiceMonitor.webtest.ts",
939
+ "apps/web/src/pages/system/composables/useSchedulerOperations.ts",
940
+ "apps/web/src/pages/system/composables/useSchedulerOperations.webtest.ts",
871
941
  "apps/web/src/services/operations-api.ts"
872
942
  ],
873
943
  documentation: ["docs/platform/operations-overview.md"]
@@ -1218,7 +1288,7 @@ import { lstat, open, readFile, rename, rm } from "fs/promises";
1218
1288
  import { join } from "path";
1219
1289
  var managedSecretKeys = [
1220
1290
  "AGENT_SERVER_INTERNAL_TOKEN",
1221
- "AGENT_RUN_ENCRYPTION_SECRET",
1291
+ "AGENT_INTERNAL_OUTPUT_ENCRYPTION_SECRET",
1222
1292
  "AI_ARTIFACT_ENCRYPTION_SECRET",
1223
1293
  "EMBEDDING_RUN_ENCRYPTION_SECRET",
1224
1294
  "AI_OUTPUT_ARTIFACT_REFERENCE_SECRET"
@@ -1236,8 +1306,8 @@ async function initializeLocalEnvironment(projectRoot, generateSecret = defaultS
1236
1306
  if (/^AGENT_SERVER_INTERNAL_TOKEN=[ \t\r]*$/m.test(content)) {
1237
1307
  content = setEmptyVariable(content, "AGENT_SERVER_INTERNAL_TOKEN", generateSecret());
1238
1308
  }
1239
- if (/^AGENT_RUN_ENCRYPTION_SECRET=[ \t\r]*$/m.test(content)) {
1240
- content = setEmptyVariable(content, "AGENT_RUN_ENCRYPTION_SECRET", generateSecret());
1309
+ if (/^AGENT_INTERNAL_OUTPUT_ENCRYPTION_SECRET=[ \t\r]*$/m.test(content)) {
1310
+ content = setEmptyVariable(content, "AGENT_INTERNAL_OUTPUT_ENCRYPTION_SECRET", generateSecret());
1241
1311
  }
1242
1312
  if (/^AI_ARTIFACT_ENCRYPTION_SECRET=[ \t\r]*$/m.test(content)) {
1243
1313
  content = setEmptyVariable(content, "AI_ARTIFACT_ENCRYPTION_SECRET", generateSecret());
@@ -2711,7 +2781,8 @@ function isMissing2(error) {
2711
2781
  return error instanceof Error && "code" in error && error.code === "ENOENT";
2712
2782
  }
2713
2783
 
2714
- // src/docker-copy-sync.ts
2784
+ // src/docker-copy-targets.ts
2785
+ var agentDockerfilePath = "apps/agent-server/Dockerfile";
2715
2786
  var webDockerfilePath = "apps/web/Dockerfile";
2716
2787
  var webEntryDirectory = "apps/web";
2717
2788
  var serverDockerfilePath = "apps/server/Dockerfile";
@@ -2728,8 +2799,14 @@ var dockerfileCopyTargets = [
2728
2799
  dockerfilePath: webDockerfilePath,
2729
2800
  entryDirectory: webEntryDirectory,
2730
2801
  includeBuildClosure: true
2802
+ },
2803
+ {
2804
+ dockerfilePath: agentDockerfilePath,
2805
+ entryDirectory: "apps/agent-server",
2806
+ includeBuildClosure: false
2731
2807
  }
2732
2808
  ];
2809
+ // src/docker-copy-sync.ts
2733
2810
  async function snapshotWorkspacePackages(root, options = {}) {
2734
2811
  const rootContent = await readSafeOptional(root, "package.json");
2735
2812
  if (!rootContent) {
@@ -3240,31 +3317,6 @@ Skill \u4ECD\u53EF\u7528\u4E8E\u666E\u901A\u4E1A\u52A1\u6A21\u5757\u5F00\u53D1\u
3240
3317
  `;
3241
3318
  }
3242
3319
 
3243
- // src/runtime-profile-opensearch.ts
3244
- var openSearchComposeService = ` opensearch:
3245
- profiles: ["search"]
3246
- image: opensearchproject/opensearch:2.19.3
3247
- environment:
3248
- discovery.type: single-node
3249
- DISABLE_INSTALL_DEMO_CONFIG: "true"
3250
- DISABLE_SECURITY_PLUGIN: "true"
3251
- OPENSEARCH_JAVA_OPTS: "-Xms512m -Xmx512m"
3252
- ports:
3253
- - "127.0.0.1:19200:9200"
3254
- volumes:
3255
- - opensearch-data:/usr/share/opensearch/data
3256
- healthcheck:
3257
- test:
3258
- [
3259
- "CMD-SHELL",
3260
- "curl -fsS http://127.0.0.1:9200/_cluster/health?wait_for_status=yellow",
3261
- ]
3262
- interval: 10s
3263
- timeout: 5s
3264
- retries: 12
3265
-
3266
- `;
3267
-
3268
3320
  // src/runtime-profile-compose-build.ts
3269
3321
  var starterServerBuild = ` build:
3270
3322
  context: .
@@ -3290,112 +3342,7 @@ function optionalComposeVolumes(includeAgent, includeSearch, includeStorage) {
3290
3342
  `);
3291
3343
  }
3292
3344
 
3293
- // src/runtime-profile-files.ts
3294
- var starterComposeBase = `services:
3295
- postgres:
3296
- image: pgvector/pgvector:pg18
3297
- environment:
3298
- POSTGRES_DB: windy
3299
- POSTGRES_USER: windy
3300
- POSTGRES_PASSWORD: \${POSTGRES_PASSWORD:?\u8BF7\u5728 .env \u4E2D\u8BBE\u7F6E POSTGRES_PASSWORD}
3301
- ports:
3302
- - "15432:5432"
3303
- volumes:
3304
- - postgres18-data:/var/lib/postgresql
3305
- healthcheck:
3306
- test: ["CMD-SHELL", "pg_isready -U windy -d windy"]
3307
- interval: 10s
3308
- timeout: 5s
3309
- retries: 5
3310
-
3311
- migrate:
3312
- ${starterServerBuild}
3313
- command: ["bun", "run", "db:migrate"]
3314
- environment:
3315
- DATABASE_URL: postgresql://windy:\${POSTGRES_PASSWORD}@postgres:5432/windy
3316
- volumes:
3317
- - ./packages:/app/packages
3318
- depends_on:
3319
- postgres:
3320
- condition: service_healthy
3321
-
3322
- server:
3323
- ${starterServerBuild}
3324
- command: ["bun", "run", "--cwd", "apps/server", "dev"]
3325
- environment:
3326
- NODE_ENV: development
3327
- PORT: 9747
3328
- DATABASE_URL: postgresql://windy:\${POSTGRES_PASSWORD}@postgres:5432/windy
3329
- WINDY_BOOTSTRAP_ADMIN_PASSWORD: \${WINDY_BOOTSTRAP_ADMIN_PASSWORD:?\u8BF7\u5728 .env \u4E2D\u8BBE\u7F6E\u7BA1\u7406\u5458\u521D\u59CB\u5BC6\u7801}
3330
- WINDY_AUDIT_QUEUE_FILE: /app/data/audit/recovery-queue.json
3331
- __STORAGE_SERVER_ENV__
3332
- WINDY_CONTAINERIZED: "1"
3333
- BUN_CONFIG_NO_CLEAR_TERMINAL_ON_RELOAD: "true"
3334
- WINDY_SYSTEM_USAGE_PATHS: /app/data/audit
3335
- PLATFORM_ENABLE_AI: \${PLATFORM_ENABLE_AI:-false}
3336
- AGENT_SERVER_URL: http://agent-server:8080
3337
- WINDY_PUBLIC_BASE_URL: \${WINDY_PUBLIC_BASE_URL:-http://localhost:9747}
3338
- AGENT_TOOL_HOST_URL: http://server:9747
3339
- __TOOL_SANDBOX_SERVER_ENV__
3340
- AGENT_SERVER_INTERNAL_TOKEN: \${AGENT_SERVER_INTERNAL_TOKEN:-}
3341
- __AGENT_WORKFLOW_SERVER_ENV__
3342
- AI_ARTIFACT_URL: http://server:9747/api/internal/ai/artifacts
3343
- AI_ARTIFACT_ENCRYPTION_SECRET: \${AI_ARTIFACT_ENCRYPTION_SECRET:-}
3344
- DOCUMENT_SERVER_URL: \${DOCUMENT_SERVER_URL:-}
3345
- AI_OUTPUT_ARTIFACT_REFERENCE_SECRET: \${AI_OUTPUT_ARTIFACT_REFERENCE_SECRET:-}
3346
- DOCUMENT_OUTPUT_ARTIFACT_SINK_IDENTITY: \${DOCUMENT_OUTPUT_ARTIFACT_SINK_IDENTITY:-}
3347
- DOCUMENT_OUTPUT_ARTIFACT_SINK_RELEASE_DIGEST: \${DOCUMENT_OUTPUT_ARTIFACT_SINK_RELEASE_DIGEST:-}
3348
- SPEECH_SERVER_URL: \${SPEECH_SERVER_URL:-}
3349
- EMBEDDING_SERVER_URL: \${EMBEDDING_SERVER_URL:-}
3350
- __OPENSEARCH_SERVER_ENV__
3351
- ports:
3352
- - "9747:9747"
3353
- volumes:
3354
- - ./apps/server:/app/apps/server
3355
- - ./packages:/app/packages
3356
- - server-audit-data:/app/data/audit
3357
- __STORAGE_SERVER_VOLUME__
3358
- __TOOL_SANDBOX_SERVER_VOLUME__
3359
- depends_on:
3360
- migrate:
3361
- condition: service_completed_successfully
3362
-
3363
- __OPENSEARCH_SERVICE__
3364
- web:
3365
- build:
3366
- context: .
3367
- dockerfile: apps/web/Dockerfile
3368
- command: ["bun", "run", "--cwd", "apps/web", "dev"]
3369
- environment:
3370
- NODE_ENV: development
3371
- WINDY_DEV_PORT: 18746
3372
- WINDY_DEV_USE_POLLING: "1"
3373
- API_UPSTREAM: http://server:9747
3374
- VITE_DEV_HOST: 0.0.0.0
3375
- ports:
3376
- - "18746:18746"
3377
- volumes:
3378
- - ./apps/web:/app/apps/web
3379
- - ./packages:/app/packages
3380
- healthcheck:
3381
- test:
3382
- [
3383
- "CMD",
3384
- "bun",
3385
- "-e",
3386
- "const r=await fetch('http://127.0.0.1:18746/-/windy-dev');process.exit(r.ok?0:1)",
3387
- ]
3388
- interval: 5s
3389
- timeout: 3s
3390
- retries: 6
3391
- depends_on:
3392
- - server
3393
-
3394
- volumes:
3395
- postgres18-data:
3396
- server-audit-data:
3397
- __OPTIONAL_VOLUMES__
3398
- `;
3345
+ // src/runtime-profile-agent.ts
3399
3346
  var agentComposeService = ` tool-sandbox-init:
3400
3347
  profiles: ["agent"]
3401
3348
  ${starterServerBuild}
@@ -3444,23 +3391,38 @@ ${starterServerBuild}
3444
3391
  context: .
3445
3392
  dockerfile: apps/agent-server/Dockerfile
3446
3393
  args:
3447
- WINDY_PYPI_INDEX_URL: \${WINDY_PYPI_INDEX_URL:-http://mirrors.cloud.tencent.com/pypi/simple}
3394
+ WINDY_AGENT_NATIVE_REGISTRY: \${WINDY_AGENT_NATIVE_REGISTRY:-https://registry.npmjs.org}
3395
+ WINDY_PYPI_INDEX_URL: \${WINDY_PYPI_INDEX_URL:-https://pypi.org/simple}
3396
+ cap_drop: ["ALL"]
3397
+ cap_add: ["SETUID", "SETGID", "CHOWN", "DAC_OVERRIDE", "KILL"]
3398
+ security_opt:
3399
+ - no-new-privileges:true
3400
+ pids_limit: 512
3401
+ mem_limit: \${AGENT_SERVER_MEMORY_LIMIT:-4g}
3402
+ cpus: \${AGENT_SERVER_CPU_LIMIT:-2}
3448
3403
  environment:
3449
3404
  AGENT_SERVER_INTERNAL_TOKEN: \${AGENT_SERVER_INTERNAL_TOKEN:-}
3450
3405
  AGENT_CONTEXT_HOST_URL: http://server:9747
3451
- AGENT_RUN_STORE_PATH: /app/data/agent/runs.sqlite3
3452
- AGENT_DATABASE_URL: postgresql://windy:\${POSTGRES_PASSWORD}@postgres:5432/windy
3453
- AGENT_RUN_ENCRYPTION_SECRET: \${AGENT_RUN_ENCRYPTION_SECRET:-}
3454
- OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: \${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT:-}
3455
- OTEL_EXPORTER_OTLP_HEADERS: \${OTEL_EXPORTER_OTLP_HEADERS:-}
3456
- AI_PROVIDER_AUDIT_STORE_PATH: /app/data/agent/provider-audit.sqlite3
3406
+ AGENT_INTERNAL_OUTPUT_ENCRYPTION_SECRET: \${AGENT_INTERNAL_OUTPUT_ENCRYPTION_SECRET:-}
3407
+ AGENT_RUNTIME_DATABASE_PATH: /app/data/agent/embedded-dsh.sqlite
3408
+ AI_TOOL_HOST_URL: http://server:9747
3409
+ AI_ARTIFACT_URL: http://server:9747/api/internal/ai/artifacts
3410
+ AGENT_DSH_HOME: /app/data/agent/dsh
3411
+ AGENT_DSH_MAX_USERS: \${AGENT_DSH_MAX_USERS:-2}
3412
+ AGENT_DSH_USER_EXTENSIONS: \${AGENT_DSH_USER_EXTENSIONS:-1}
3413
+ AGENT_DSH_MAX_ACTIVE_RUNS: \${AGENT_DSH_MAX_ACTIVE_RUNS:-2}
3414
+ AGENT_DSH_WORKSPACE_MAX_BYTES: \${AGENT_DSH_WORKSPACE_MAX_BYTES:-536870912}
3457
3415
  AI_PROVIDER_AUDIT_RETENTION_DAYS: \${AI_PROVIDER_AUDIT_RETENTION_DAYS:-90}
3458
3416
  QWEN_API_URL: \${QWEN_API_URL:-}
3459
3417
  QWEN_API_KEY: \${QWEN_API_KEY:-}
3460
3418
  QWEN_MODEL: \${QWEN_MODEL:-}
3419
+ QWEN_STRUCTURED_OUTPUT_MODE: \${QWEN_STRUCTURED_OUTPUT_MODE:-json_schema}
3461
3420
  AI_PROVIDER_HTTPS_HOST_ALLOWLIST: \${AI_PROVIDER_HTTPS_HOST_ALLOWLIST:-}
3462
- AI_PROVIDER_CONNECT_TIMEOUT_MS: \${AI_PROVIDER_CONNECT_TIMEOUT_MS:-5000}
3463
3421
  AI_PROVIDER_REQUEST_TIMEOUT_MS: \${AI_PROVIDER_REQUEST_TIMEOUT_MS:-60000}
3422
+ AI_PROVIDER_CONTEXT_TOKENS: \${AI_PROVIDER_CONTEXT_TOKENS:-}
3423
+ AI_PROVIDER_TOKENIZE_PATH: \${AI_PROVIDER_TOKENIZE_PATH:-}
3424
+ AI_PROVIDER_OUTPUT_RESERVE_TOKENS: \${AI_PROVIDER_OUTPUT_RESERVE_TOKENS:-4096}
3425
+ AI_PROVIDER_CONTEXT_SAFETY_TOKENS: \${AI_PROVIDER_CONTEXT_SAFETY_TOKENS:-512}
3464
3426
  AI_PROVIDER_MAX_RESPONSE_BYTES: \${AI_PROVIDER_MAX_RESPONSE_BYTES:-2097152}
3465
3427
  AI_PROVIDER_MAX_DURATION_SECONDS: \${AI_PROVIDER_MAX_DURATION_SECONDS:-300}
3466
3428
  AI_PROVIDER_MAX_INPUT_BYTES: \${AI_PROVIDER_MAX_INPUT_BYTES:-67108864}
@@ -3480,7 +3442,6 @@ ${starterServerBuild}
3480
3442
  condition: service_completed_successfully
3481
3443
  server:
3482
3444
  condition: service_started
3483
-
3484
3445
  document-server:
3485
3446
  profiles: ["document"]
3486
3447
  build:
@@ -3577,122 +3538,268 @@ ${starterServerBuild}
3577
3538
  condition: service_started
3578
3539
 
3579
3540
  `;
3580
- function starterComposeFor(includeAgent, includeSearch = true, includeStorage = true) {
3581
- return starterComposeBase.replace(` web:
3582
- `, `${includeAgent ? agentComposeService : ""} web:
3583
- `).replace("__TOOL_SANDBOX_SERVER_ENV__", includeAgent ? " TOOL_SANDBOX_SOCKET: /run/windy-tool-sandbox/worker.sock" : "").replace("__AGENT_WORKFLOW_SERVER_ENV__", agentWorkflowServerEnvironment(includeAgent)).replace("__TOOL_SANDBOX_SERVER_VOLUME__", includeAgent ? " - tool-sandbox-ipc:/run/windy-tool-sandbox" : "").replace("__STORAGE_SERVER_ENV__", includeStorage ? " WINDY_STORAGE_ROOT: /app/data/storage" : "").replace("__STORAGE_SERVER_VOLUME__", includeStorage ? " - server-storage-data:/app/data/storage" : "").replace("__OPENSEARCH_SERVER_ENV__", includeSearch ? ` OPENSEARCH_URL: \${OPENSEARCH_URL:-}
3584
- OPENSEARCH_USERNAME: \${OPENSEARCH_USERNAME:-}
3585
- OPENSEARCH_PASSWORD: \${OPENSEARCH_PASSWORD:-}
3586
- OPENSEARCH_WORK_ORDER_INDEX: \${OPENSEARCH_WORK_ORDER_INDEX:-windy-work-orders-v1}` : "").replace("__OPENSEARCH_SERVICE__", includeSearch ? openSearchComposeService : "").replace("__OPTIONAL_VOLUMES__", optionalComposeVolumes(includeAgent, includeSearch, includeStorage));
3587
- }
3588
- var starterCompose = starterComposeFor(true);
3589
- // src/runtime-environment-example.ts
3590
- function environmentExample(includeExample, includeAgent = true, includeSearch = true, includeStorage = true) {
3591
- return `# \u590D\u5236\u4E3A .env \u540E\u586B\u5199\u3002\u4E0D\u8981\u63D0\u4EA4\u771F\u5B9E\u5BC6\u7801\u3002
3592
- POSTGRES_PASSWORD=
3593
- WINDY_BOOTSTRAP_ADMIN_PASSWORD=
3594
- ${includeStorage ? `
3595
- # Compose \u9ED8\u8BA4\u628A Storage \u4E0E\u62A5\u544A\u6682\u5B58\u6301\u4E45\u5316\u5230 /app/data/storage\u3002
3596
- # \u5982\u9700\u72EC\u7ACB\u6302\u8F7D\u62A5\u544A\u6682\u5B58\u76EE\u5F55\uFF0C\u8BF7\u540C\u65F6\u4FEE\u6539 Compose volume\u3002
3597
- # WINDY_REPORT_STAGING_ROOT=/app/data/storage/report-staging
3598
- ` : ""}
3599
- ${includeAgent ? `
3600
- # Agent profile \u4EC5\u7531\u670D\u52A1\u7AEF Agent Runtime \u8BFB\u53D6\uFF1B\u4E0D\u8981\u4F7F\u7528 VITE_ \u524D\u7F00\u3002
3601
- PLATFORM_ENABLE_AI=false
3602
- AGENT_SERVER_INTERNAL_TOKEN=
3603
- AGENT_RUN_ENCRYPTION_SECRET=
3604
- # Model \u8282\u70B9\u542F\u7528\u524D\u5FC5\u987B\u586B\u5165\u7531\u8FD0\u7EF4\u51BB\u7ED3\u7684 deployment/model \u4EF7\u683C\u76EE\u5F55\uFF1B\u7F3A\u5931\u65F6 readiness \u660E\u786E unavailable\u3002
3605
- WINDY_AGENT_WORKFLOW_MODEL_PRICING_JSON=
3606
- # \u975E Compose \u90E8\u7F72\u9700\u6307\u5411 Windy Server\uFF1B\u957F\u671F Session \u7684\u6A21\u578B\u8C03\u7528\u4F1A fail closed\u3002
3607
- # AGENT_CONTEXT_HOST_URL=http://server:9747
3608
- # \u591A\u526F\u672C\u751F\u4EA7\u9ED8\u8BA4\u4F7F\u7528 Compose \u6CE8\u5165\u7684 PostgreSQL\uFF1B\u7559\u7A7A\u624D\u56DE\u9000\u5355\u526F\u672C SQLite\u3002
3609
- AGENT_DATABASE_URL=
3610
- # \u53EF\u9009\uFF1A\u53EA\u53D1\u9001\u65E0 Prompt/\u8F93\u5165/\u8F93\u51FA\u7684 Agent Run \u5143\u6570\u636E Span\u3002
3611
- OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=
3612
- OTEL_EXPORTER_OTLP_HEADERS=
3613
- AI_ARTIFACT_ENCRYPTION_SECRET=
3614
- WINDY_PUBLIC_BASE_URL=http://localhost:9747
3615
- DOCUMENT_SERVER_URL=
3616
- DOCUMENT_ARTIFACT_URL=
3617
- DOCUMENT_OUTPUT_ARTIFACT_URL=
3618
- DOCUMENT_ADAPTER_URL=
3619
- DOCUMENT_ADAPTER_TOKEN=
3620
- DOCUMENT_DEPLOYMENT_KEY=
3621
- DOCUMENT_DEPLOYMENT_IDENTITY=
3622
- DOCUMENT_RELEASE_DIGEST=
3623
- DOCUMENT_OFFERS_DIGEST=
3624
- AI_OUTPUT_ARTIFACT_REFERENCE_SECRET=
3625
- DOCUMENT_OUTPUT_ARTIFACT_SINK_IDENTITY=
3626
- DOCUMENT_OUTPUT_ARTIFACT_SINK_RELEASE_DIGEST=
3627
- # DOCUMENT_ADAPTER_CAPABILITIES=document.ocr,document.layout,document.table
3628
- # DOCUMENT_MAX_UNITS=500
3629
- SPEECH_SERVER_URL=
3630
- SPEECH_ARTIFACT_URL=
3631
- SPEECH_OUTPUT_ARTIFACT_URL=
3632
- SPEECH_ADAPTER_URL=
3633
- SPEECH_ADAPTER_TOKEN=
3634
- SPEECH_DEPLOYMENT_KEY=
3635
- SPEECH_DEPLOYMENT_IDENTITY=
3636
- SPEECH_RELEASE_DIGEST=
3637
- SPEECH_OFFERS_DIGEST=
3638
- # SPEECH_ADAPTER_CAPABILITIES=speech.transcribe.batch,speech.translate,speech.vad,speech.timestamps
3639
- # SPEECH_MAX_UNITS=100000
3640
- # SPEECH_MAX_MEDIA_DURATION_SECONDS=86400
3641
- # SPEECH_MAX_INPUT_ARTIFACT_BYTES=2147483648
3642
- # SPEECH_MAX_INLINE_OUTPUT_BYTES=67108864
3643
- # SPEECH_MAX_OUTPUT_ARTIFACT_BYTES=536870912
3644
- # SPEECH_MAX_CONCURRENT_RUNS=1
3645
- # SPEECH_MAX_QUEUE_DEPTH=0
3646
- # SPEECH_READINESS_TIMEOUT_SECONDS=5
3647
- # SPEECH_READINESS_TTL_SECONDS=60
3648
- EMBEDDING_SERVER_URL=
3649
- EMBEDDING_ARTIFACT_URL=
3650
- EMBEDDING_RUN_ARTIFACT_URL=
3651
- EMBEDDING_ADAPTER_URL=
3652
- EMBEDDING_ADAPTER_TOKEN=
3653
- EMBEDDING_DEPLOYMENT_KEY=
3654
- EMBEDDING_DEPLOYMENT_IDENTITY=
3655
- EMBEDDING_RELEASE_DIGEST=
3656
- EMBEDDING_OFFERS_DIGEST=
3657
- EMBEDDING_DEPLOYMENT_ALIAS=
3658
- EMBEDDING_MODEL=
3659
- EMBEDDING_MODEL_VERSION=
3660
- EMBEDDING_DIMENSIONS=
3661
- # EMBEDDING_NORMALIZED=true
3662
- # EMBEDDING_CAPABILITIES=embedding.text,embedding.image
3663
- # EMBEDDING_MAX_UNITS=256
3664
- # EMBEDDING_MAX_DURATION_SECONDS=600
3665
- # EMBEDDING_MAX_INPUT_BYTES=268435456
3666
- # EMBEDDING_MAX_OUTPUT_BYTES=268435456
3667
- # EMBEDDING_MAX_ARTIFACTS=16
3668
- # EMBEDDING_MAX_PIXELS_PER_ARTIFACT=100000000
3669
- EMBEDDING_RUN_ENCRYPTION_SECRET=
3670
- # EMBEDDING_MAX_CONCURRENT_RUNS=1
3671
- # EMBEDDING_MAX_QUEUE_DEPTH=0
3672
- # EMBEDDING_READINESS_TIMEOUT_SECONDS=5
3673
- # EMBEDDING_READINESS_TTL_SECONDS=60
3674
- # EMBEDDING_RUN_TERMINAL_TTL_SECONDS=604800
3675
- QWEN_API_URL=
3676
- QWEN_API_KEY=
3677
- QWEN_MODEL=
3678
- AI_PROVIDER_HTTPS_HOST_ALLOWLIST=
3679
- # VLM Deployment \u793A\u4F8B\uFF1Atext-generation,vision\uFF1B\u8F93\u5165\u6A21\u6001\uFF1Atext,image
3680
- # AI_PROVIDER_CAPABILITIES=text-generation
3681
- # AI_PROVIDER_INPUT_MODALITIES=text
3682
- # AI_PROVIDER_DEPLOYMENT_IDENTITY=
3683
- # AI_PROVIDER_RELEASE_DIGEST=
3684
- # AI_PROVIDER_READINESS_TTL_SECONDS=60
3685
- # AI_PROVIDER_MAX_CONCURRENT_RUNS=1
3686
- # AI_PROVIDER_MAX_QUEUE_DEPTH=0
3687
- # AI_PROVIDER_AUDIT_RETENTION_DAYS=90
3688
- # AI_PROVIDER_CONNECT_TIMEOUT_MS=5000
3689
- # AI_PROVIDER_REQUEST_TIMEOUT_MS=60000
3690
- # AI_PROVIDER_MAX_RESPONSE_BYTES=2097152
3691
- # AI_PROVIDER_MAX_DURATION_SECONDS=300
3692
- # AI_PROVIDER_MAX_INPUT_BYTES=67108864
3693
- # AI_PROVIDER_MAX_ARTIFACTS=16
3694
- # AI_PROVIDER_MAX_PIXELS_PER_ARTIFACT=100000000
3695
- ` : ""}
3541
+
3542
+ // src/runtime-profile-opensearch.ts
3543
+ var openSearchComposeService = ` opensearch:
3544
+ profiles: ["search"]
3545
+ image: opensearchproject/opensearch:2.19.3
3546
+ environment:
3547
+ discovery.type: single-node
3548
+ DISABLE_INSTALL_DEMO_CONFIG: "true"
3549
+ DISABLE_SECURITY_PLUGIN: "true"
3550
+ OPENSEARCH_JAVA_OPTS: "-Xms512m -Xmx512m"
3551
+ ports:
3552
+ - "127.0.0.1:19200:9200"
3553
+ volumes:
3554
+ - opensearch-data:/usr/share/opensearch/data
3555
+ healthcheck:
3556
+ test:
3557
+ [
3558
+ "CMD-SHELL",
3559
+ "curl -fsS http://127.0.0.1:9200/_cluster/health?wait_for_status=yellow",
3560
+ ]
3561
+ interval: 10s
3562
+ timeout: 5s
3563
+ retries: 12
3564
+
3565
+ `;
3566
+
3567
+ // src/runtime-profile-files.ts
3568
+ var starterComposeBase = `services:
3569
+ postgres:
3570
+ image: pgvector/pgvector:pg18
3571
+ environment:
3572
+ POSTGRES_DB: windy
3573
+ POSTGRES_USER: windy
3574
+ POSTGRES_PASSWORD: \${POSTGRES_PASSWORD:?\u8BF7\u5728 .env \u4E2D\u8BBE\u7F6E POSTGRES_PASSWORD}
3575
+ ports:
3576
+ - "15432:5432"
3577
+ volumes:
3578
+ - postgres18-data:/var/lib/postgresql
3579
+ healthcheck:
3580
+ test: ["CMD-SHELL", "pg_isready -U windy -d windy"]
3581
+ interval: 10s
3582
+ timeout: 5s
3583
+ retries: 5
3584
+
3585
+ migrate:
3586
+ ${starterServerBuild}
3587
+ command: ["bun", "run", "db:migrate"]
3588
+ environment:
3589
+ DATABASE_URL: postgresql://windy:\${POSTGRES_PASSWORD}@postgres:5432/windy
3590
+ volumes:
3591
+ - ./packages:/app/packages
3592
+ depends_on:
3593
+ postgres:
3594
+ condition: service_healthy
3595
+
3596
+ server:
3597
+ ${starterServerBuild}
3598
+ command: ["bun", "run", "--cwd", "apps/server", "dev"]
3599
+ environment:
3600
+ NODE_ENV: development
3601
+ PORT: 9747
3602
+ DATABASE_URL: postgresql://windy:\${POSTGRES_PASSWORD}@postgres:5432/windy
3603
+ WINDY_BOOTSTRAP_ADMIN_PASSWORD: \${WINDY_BOOTSTRAP_ADMIN_PASSWORD:?\u8BF7\u5728 .env \u4E2D\u8BBE\u7F6E\u7BA1\u7406\u5458\u521D\u59CB\u5BC6\u7801}
3604
+ WINDY_AUDIT_QUEUE_FILE: /app/data/audit/recovery-queue.json
3605
+ __STORAGE_SERVER_ENV__
3606
+ WINDY_CONTAINERIZED: "1"
3607
+ BUN_CONFIG_NO_CLEAR_TERMINAL_ON_RELOAD: "true"
3608
+ WINDY_SYSTEM_USAGE_PATHS: /app/data/audit
3609
+ PLATFORM_ENABLE_AI: \${PLATFORM_ENABLE_AI:-false}
3610
+ AGENT_SERVER_URL: http://agent-server:8080
3611
+ WINDY_PUBLIC_BASE_URL: "\${WINDY_PUBLIC_BASE_URL:-}"
3612
+ AGENT_TOOL_HOST_URL: http://server:9747
3613
+ __TOOL_SANDBOX_SERVER_ENV__
3614
+ AGENT_SERVER_INTERNAL_TOKEN: \${AGENT_SERVER_INTERNAL_TOKEN:-}
3615
+ __AGENT_WORKFLOW_SERVER_ENV__
3616
+ AI_ARTIFACT_URL: http://server:9747/api/internal/ai/artifacts
3617
+ AI_ARTIFACT_ENCRYPTION_SECRET: \${AI_ARTIFACT_ENCRYPTION_SECRET:-}
3618
+ DOCUMENT_SERVER_URL: \${DOCUMENT_SERVER_URL:-}
3619
+ AI_OUTPUT_ARTIFACT_REFERENCE_SECRET: \${AI_OUTPUT_ARTIFACT_REFERENCE_SECRET:-}
3620
+ DOCUMENT_OUTPUT_ARTIFACT_SINK_IDENTITY: \${DOCUMENT_OUTPUT_ARTIFACT_SINK_IDENTITY:-}
3621
+ DOCUMENT_OUTPUT_ARTIFACT_SINK_RELEASE_DIGEST: \${DOCUMENT_OUTPUT_ARTIFACT_SINK_RELEASE_DIGEST:-}
3622
+ SPEECH_SERVER_URL: \${SPEECH_SERVER_URL:-}
3623
+ EMBEDDING_SERVER_URL: \${EMBEDDING_SERVER_URL:-}
3624
+ __OPENSEARCH_SERVER_ENV__
3625
+ ports:
3626
+ - "9747:9747"
3627
+ volumes:
3628
+ - ./apps/server:/app/apps/server
3629
+ - ./packages:/app/packages
3630
+ - server-audit-data:/app/data/audit
3631
+ __STORAGE_SERVER_VOLUME__
3632
+ __TOOL_SANDBOX_SERVER_VOLUME__
3633
+ depends_on:
3634
+ migrate:
3635
+ condition: service_completed_successfully
3636
+
3637
+ __OPENSEARCH_SERVICE__
3638
+ web:
3639
+ build:
3640
+ context: .
3641
+ dockerfile: apps/web/Dockerfile
3642
+ command: ["bun", "run", "--cwd", "apps/web", "dev"]
3643
+ environment:
3644
+ NODE_ENV: development
3645
+ WINDY_DEV_PORT: 18746
3646
+ WINDY_DEV_USE_POLLING: "1"
3647
+ API_UPSTREAM: http://server:9747
3648
+ VITE_DEV_HOST: 0.0.0.0
3649
+ ports:
3650
+ - "18746:18746"
3651
+ volumes:
3652
+ - ./apps/web:/app/apps/web
3653
+ - ./packages:/app/packages
3654
+ healthcheck:
3655
+ test:
3656
+ [
3657
+ "CMD",
3658
+ "bun",
3659
+ "-e",
3660
+ "const r=await fetch('http://127.0.0.1:18746/-/windy-dev');process.exit(r.ok?0:1)",
3661
+ ]
3662
+ interval: 5s
3663
+ timeout: 3s
3664
+ retries: 6
3665
+ depends_on:
3666
+ - server
3667
+
3668
+ volumes:
3669
+ postgres18-data:
3670
+ server-audit-data:
3671
+ __OPTIONAL_VOLUMES__
3672
+ `;
3673
+ function starterComposeFor(includeAgent, includeSearch = true, includeStorage = true) {
3674
+ return starterComposeBase.replace(` web:
3675
+ `, `${includeAgent ? agentComposeService : ""} web:
3676
+ `).replace("__TOOL_SANDBOX_SERVER_ENV__", includeAgent ? " TOOL_SANDBOX_SOCKET: /run/windy-tool-sandbox/worker.sock" : "").replace("__AGENT_WORKFLOW_SERVER_ENV__", agentWorkflowServerEnvironment(includeAgent)).replace("__TOOL_SANDBOX_SERVER_VOLUME__", includeAgent ? " - tool-sandbox-ipc:/run/windy-tool-sandbox" : "").replace("__STORAGE_SERVER_ENV__", includeStorage ? " WINDY_STORAGE_ROOT: /app/data/storage" : "").replace("__STORAGE_SERVER_VOLUME__", includeStorage ? " - server-storage-data:/app/data/storage" : "").replace("__OPENSEARCH_SERVER_ENV__", includeSearch ? ` OPENSEARCH_URL: \${OPENSEARCH_URL:-}
3677
+ OPENSEARCH_USERNAME: \${OPENSEARCH_USERNAME:-}
3678
+ OPENSEARCH_PASSWORD: \${OPENSEARCH_PASSWORD:-}
3679
+ OPENSEARCH_WORK_ORDER_INDEX: \${OPENSEARCH_WORK_ORDER_INDEX:-windy-work-orders-v1}` : "").replace("__OPENSEARCH_SERVICE__", includeSearch ? openSearchComposeService : "").replace("__OPTIONAL_VOLUMES__", optionalComposeVolumes(includeAgent, includeSearch, includeStorage));
3680
+ }
3681
+ var starterCompose = starterComposeFor(true);
3682
+ // src/runtime-environment-example.ts
3683
+ function environmentExample(includeExample, includeAgent = true, includeSearch = true, includeStorage = true) {
3684
+ return `# \u590D\u5236\u4E3A .env \u540E\u586B\u5199\u3002\u4E0D\u8981\u63D0\u4EA4\u771F\u5B9E\u5BC6\u7801\u3002
3685
+ POSTGRES_PASSWORD=
3686
+ WINDY_BOOTSTRAP_ADMIN_PASSWORD=
3687
+ ${includeStorage ? `
3688
+ # Compose \u9ED8\u8BA4\u628A Storage \u4E0E\u62A5\u544A\u6682\u5B58\u6301\u4E45\u5316\u5230 /app/data/storage\u3002
3689
+ # \u5982\u9700\u72EC\u7ACB\u6302\u8F7D\u62A5\u544A\u6682\u5B58\u76EE\u5F55\uFF0C\u8BF7\u540C\u65F6\u4FEE\u6539 Compose volume\u3002
3690
+ # WINDY_REPORT_STAGING_ROOT=/app/data/storage/report-staging
3691
+ ` : ""}
3692
+ ${includeAgent ? `
3693
+ # Agent profile \u4EC5\u7531\u670D\u52A1\u7AEF Agent Runtime \u8BFB\u53D6\uFF1B\u4E0D\u8981\u4F7F\u7528 VITE_ \u524D\u7F00\u3002
3694
+ PLATFORM_ENABLE_AI=false
3695
+ AGENT_SERVER_INTERNAL_TOKEN=
3696
+ AGENT_INTERNAL_OUTPUT_ENCRYPTION_SECRET=
3697
+ # Model \u8282\u70B9\u542F\u7528\u524D\u5FC5\u987B\u586B\u5165\u7531\u8FD0\u7EF4\u51BB\u7ED3\u7684 deployment/model \u4EF7\u683C\u76EE\u5F55\uFF1B\u7F3A\u5931\u65F6 readiness \u660E\u786E unavailable\u3002
3698
+ WINDY_AGENT_WORKFLOW_MODEL_PRICING_JSON=
3699
+ # \u975E Compose \u90E8\u7F72\u9700\u6307\u5411 Windy Server\uFF1B\u957F\u671F Session \u7684\u6A21\u578B\u8C03\u7528\u4F1A fail closed\u3002
3700
+ # AGENT_CONTEXT_HOST_URL=http://server:9747
3701
+ # DSH \u534F\u8C03\u5668\u5F53\u524D\u4EC5\u652F\u6301\u5355\u526F\u672C\uFF1B\u4F7F\u7528\u65B0\u7684Agent\u4E13\u7528\u76EE\u5F55\uFF0C\u4E0D\u8BFB\u53D6\u65E7Python\u8FD0\u884C\u5E93\u3002
3702
+ # AGENT_RUNTIME_DATABASE_PATH=/app/data/agent/embedded-dsh.sqlite
3703
+ # AGENT_DSH_HOME=/app/data/agent/dsh
3704
+ AGENT_DSH_USER_EXTENSIONS=1
3705
+ # AGENT_DSH_MAX_USERS=2
3706
+ # AGENT_DSH_MAX_ACTIVE_RUNS=2
3707
+ # AGENT_DSH_WORKSPACE_MAX_BYTES=536870912
3708
+ # AGENT_SERVER_MEMORY_LIMIT=4g
3709
+ # AGENT_SERVER_CPU_LIMIT=2
3710
+ # \u6784\u5EFA\u671F\u955C\u50CF\u6E90\u4ECD\u9700\u7B26\u5408\u9501\u6587\u4EF6\u7684hash\uFF1B\u8FD0\u884C\u65F6\u4E0D\u4E0B\u8F7D\u539F\u751F\u4F9D\u8D56\u3002
3711
+ # WINDY_AGENT_NATIVE_REGISTRY=https://registry.npmjs.org
3712
+ # WINDY_PYPI_INDEX_URL=https://pypi.org/simple
3713
+ AI_ARTIFACT_ENCRYPTION_SECRET=
3714
+ # \u5F00\u53D1\u7559\u7A7A\u65F6\u5DE5\u4F5C\u53F0\u8DDF\u968F\u6D4F\u89C8\u5668\u540C\u6E90 Host\uFF0C\u652F\u6301 Web \u7AEF\u53E3\u548C\u52A8\u6001\u5C40\u57DF\u7F51\u5730\u5740\u3002
3715
+ # HTTPS \u53CD\u5411\u4EE3\u7406\u6216\u751F\u4EA7 Client Agent Session \u5FC5\u987B\u586B\u5199\u7528\u6237\u5B9E\u9645\u8BBF\u95EE\u7684 Web origin\u3002
3716
+ # WINDY_PUBLIC_BASE_URL=https://windy.example
3717
+ WINDY_PUBLIC_BASE_URL=
3718
+ DOCUMENT_SERVER_URL=
3719
+ DOCUMENT_ARTIFACT_URL=
3720
+ DOCUMENT_OUTPUT_ARTIFACT_URL=
3721
+ DOCUMENT_ADAPTER_URL=
3722
+ DOCUMENT_ADAPTER_TOKEN=
3723
+ DOCUMENT_DEPLOYMENT_KEY=
3724
+ DOCUMENT_DEPLOYMENT_IDENTITY=
3725
+ DOCUMENT_RELEASE_DIGEST=
3726
+ DOCUMENT_OFFERS_DIGEST=
3727
+ AI_OUTPUT_ARTIFACT_REFERENCE_SECRET=
3728
+ DOCUMENT_OUTPUT_ARTIFACT_SINK_IDENTITY=
3729
+ DOCUMENT_OUTPUT_ARTIFACT_SINK_RELEASE_DIGEST=
3730
+ # DOCUMENT_ADAPTER_CAPABILITIES=document.ocr,document.layout,document.table
3731
+ # DOCUMENT_MAX_UNITS=500
3732
+ SPEECH_SERVER_URL=
3733
+ SPEECH_ARTIFACT_URL=
3734
+ SPEECH_OUTPUT_ARTIFACT_URL=
3735
+ SPEECH_ADAPTER_URL=
3736
+ SPEECH_ADAPTER_TOKEN=
3737
+ SPEECH_DEPLOYMENT_KEY=
3738
+ SPEECH_DEPLOYMENT_IDENTITY=
3739
+ SPEECH_RELEASE_DIGEST=
3740
+ SPEECH_OFFERS_DIGEST=
3741
+ # SPEECH_ADAPTER_CAPABILITIES=speech.transcribe.batch,speech.translate,speech.vad,speech.timestamps
3742
+ # SPEECH_MAX_UNITS=100000
3743
+ # SPEECH_MAX_MEDIA_DURATION_SECONDS=86400
3744
+ # SPEECH_MAX_INPUT_ARTIFACT_BYTES=2147483648
3745
+ # SPEECH_MAX_INLINE_OUTPUT_BYTES=67108864
3746
+ # SPEECH_MAX_OUTPUT_ARTIFACT_BYTES=536870912
3747
+ # SPEECH_MAX_CONCURRENT_RUNS=1
3748
+ # SPEECH_MAX_QUEUE_DEPTH=0
3749
+ # SPEECH_READINESS_TIMEOUT_SECONDS=5
3750
+ # SPEECH_READINESS_TTL_SECONDS=60
3751
+ EMBEDDING_SERVER_URL=
3752
+ EMBEDDING_ARTIFACT_URL=
3753
+ EMBEDDING_RUN_ARTIFACT_URL=
3754
+ EMBEDDING_ADAPTER_URL=
3755
+ EMBEDDING_ADAPTER_TOKEN=
3756
+ EMBEDDING_DEPLOYMENT_KEY=
3757
+ EMBEDDING_DEPLOYMENT_IDENTITY=
3758
+ EMBEDDING_RELEASE_DIGEST=
3759
+ EMBEDDING_OFFERS_DIGEST=
3760
+ EMBEDDING_DEPLOYMENT_ALIAS=
3761
+ EMBEDDING_MODEL=
3762
+ EMBEDDING_MODEL_VERSION=
3763
+ EMBEDDING_DIMENSIONS=
3764
+ # EMBEDDING_NORMALIZED=true
3765
+ # EMBEDDING_CAPABILITIES=embedding.text,embedding.image
3766
+ # EMBEDDING_MAX_UNITS=256
3767
+ # EMBEDDING_MAX_DURATION_SECONDS=600
3768
+ # EMBEDDING_MAX_INPUT_BYTES=268435456
3769
+ # EMBEDDING_MAX_OUTPUT_BYTES=268435456
3770
+ # EMBEDDING_MAX_ARTIFACTS=16
3771
+ # EMBEDDING_MAX_PIXELS_PER_ARTIFACT=100000000
3772
+ EMBEDDING_RUN_ENCRYPTION_SECRET=
3773
+ # EMBEDDING_MAX_CONCURRENT_RUNS=1
3774
+ # EMBEDDING_MAX_QUEUE_DEPTH=0
3775
+ # EMBEDDING_READINESS_TIMEOUT_SECONDS=5
3776
+ # EMBEDDING_READINESS_TTL_SECONDS=60
3777
+ # EMBEDDING_RUN_TERMINAL_TTL_SECONDS=604800
3778
+ QWEN_API_URL=
3779
+ QWEN_API_KEY=
3780
+ QWEN_MODEL=
3781
+ # QWEN_STRUCTURED_OUTPUT_MODE=json_schema
3782
+ AI_PROVIDER_HTTPS_HOST_ALLOWLIST=
3783
+ # VLM Deployment \u793A\u4F8B\uFF1Atext-generation,vision\uFF1B\u8F93\u5165\u6A21\u6001\uFF1Atext,image
3784
+ # AI_PROVIDER_CAPABILITIES=text-generation
3785
+ # AI_PROVIDER_INPUT_MODALITIES=text
3786
+ # AI_PROVIDER_DEPLOYMENT_IDENTITY=
3787
+ # AI_PROVIDER_RELEASE_DIGEST=
3788
+ # AI_PROVIDER_READINESS_TTL_SECONDS=60
3789
+ # AI_PROVIDER_MAX_CONCURRENT_RUNS=1
3790
+ # AI_PROVIDER_MAX_QUEUE_DEPTH=0
3791
+ # AI_PROVIDER_AUDIT_RETENTION_DAYS=90
3792
+ # AI_PROVIDER_CONTEXT_TOKENS=
3793
+ # AI_PROVIDER_OUTPUT_RESERVE_TOKENS=4096
3794
+ # AI_PROVIDER_CONTEXT_SAFETY_TOKENS=512
3795
+ # AI_PROVIDER_TOKENIZE_PATH=
3796
+ # AI_PROVIDER_REQUEST_TIMEOUT_MS=60000
3797
+ # AI_PROVIDER_MAX_RESPONSE_BYTES=2097152
3798
+ # AI_PROVIDER_MAX_DURATION_SECONDS=300
3799
+ # AI_PROVIDER_MAX_INPUT_BYTES=67108864
3800
+ # AI_PROVIDER_MAX_ARTIFACTS=16
3801
+ # AI_PROVIDER_MAX_PIXELS_PER_ARTIFACT=100000000
3802
+ ` : ""}
3696
3803
 
3697
3804
  ${includeSearch ? `# OpenSearch profile \u9ED8\u8BA4\u4E0D\u542F\u52A8\uFF1Bbun run dev:search \u4F1A\u53EA\u5411 Server \u6CE8\u5165\u5BB9\u5668\u5185\u5730\u5740\u3002
3698
3805
  OPENSEARCH_URL=
@@ -3809,7 +3916,7 @@ bun run dev:server
3809
3916
 
3810
3917
  ${starterMcpAndSkillGuidance(includeAgent)}
3811
3918
  ${includeAgent ? `
3812
- ## OpenAI-compatible Agent profile
3919
+ ## DSH Agent profile
3813
3920
 
3814
3921
  Agent Runtime \u9ED8\u8BA4\u4E0D\u542F\u52A8\u3002\u5148\u5728\u4EC5\u4F9B\u672C\u673A\u4F7F\u7528\u7684 \`.env\` \u4E2D\u8BBE\u7F6E
3815
3922
  \`PLATFORM_ENABLE_AI=true\`\u3001\`AGENT_SERVER_INTERNAL_TOKEN\`\u3001\`QWEN_API_URL\`\u3001
@@ -3823,7 +3930,10 @@ bun run dev:agent
3823
3930
  \`QWEN_API_KEY\`\u3001Endpoint \u548C Host allowlist \u53EA\u8FDB\u5165 Agent Server\uFF0C\u4E0D\u4F1A\u8FDB\u5165 Web
3824
3931
  \u73AF\u5883\u6216\u8FD4\u56DE\u7ED9\u5BA2\u6237\u7AEF\u3002\u516C\u7F51 HTTPS Endpoint \u7684\u4E3B\u673A\u5FC5\u987B\u663E\u5F0F\u52A0\u5165
3825
3932
  \`AI_PROVIDER_HTTPS_HOST_ALLOWLIST\`\u3002\u8FD0\u884C\u4E0E\u6A21\u5757
3826
- \u63A5\u5165\u7EC6\u8282\u89C1 [Agent Runtime \u63A5\u5165](./docs/platform/agent-runtime.md)\u3002
3933
+ \u63A5\u5165\u7EC6\u8282\u89C1 [Agent Runtime \u63A5\u5165](./docs/platform/agent-runtime.md)\u53CA
3934
+ [DSH \u90E8\u7F72\u4E0E\u8FC1\u79FB](./docs/operations/dsh-agent-migration.md)\u3002Agent Server \u4EE5 Node 24.7+
3935
+ \u6267\u884C\uFF0C\u4F7F\u7528\u65B0 SQLite \u6570\u636E\u8DEF\u5F84\uFF1B\u539F\u751F\u5DE5\u4F5C\u53F0\u9700\u8981 Linux \u9694\u79BB\u80FD\u529B\u3002\u5168\u5C40\u5BB9\u91CF\u9ED8\u8BA4 1 \u65F6\u4E3A\u65E2\u6709
3936
+ \u8C03\u7528\u94FE\u9884\u7559\uFF0C\u5DE5\u4F5C\u53F0\u4F1A\u660E\u786E\u663E\u793A\u5BB9\u91CF\u672A\u5F00\u653E\u3002\u4E2A\u4EBA\u6269\u5C55\u9ED8\u8BA4\u5F00\u653E\uFF0C\u7531\u90E8\u7F72\u5F00\u5173\u63A7\u5236\u3002
3827
3937
 
3828
3938
  Document Runtime \u540C\u6837\u9ED8\u8BA4\u5173\u95ED\u3002\u914D\u7F6E\u81F3\u5C11 32 \u5B57\u7B26\u7684
3829
3939
  \`AI_ARTIFACT_ENCRYPTION_SECRET\`\u3001\u672C\u5730\u6216\u5185\u7F51 \`DOCUMENT_ADAPTER_URL\` \u53CA\u5176
@@ -4019,7 +4129,7 @@ function createStarterPackage(source, projectName, includeOxc = true, projectLic
4019
4129
  private: true,
4020
4130
  license: projectLicense,
4021
4131
  packageManager: "bun@1.3.14",
4022
- engines: { ...source.engines, bun: ">=1.3.14" },
4132
+ engines: { ...source.engines, bun: ">=1.3.14", node: ">=24.7.0" },
4023
4133
  ...includeOxc ? { "lint-staged": sourceLintStaged ?? defaultLintStaged } : {},
4024
4134
  scripts: {
4025
4135
  ...includeOxc ? {
@@ -4032,20 +4142,23 @@ function createStarterPackage(source, projectName, includeOxc = true, projectLic
4032
4142
  "dev:search": "OPENSEARCH_URL=http://opensearch:9200 docker compose --profile search up --build"
4033
4143
  } : {},
4034
4144
  ...selectedModules.includes("system.agent") ? {
4035
- "dev:agent": "docker compose --profile agent up --build",
4145
+ "dev:agent": "bun run docker:sync && docker compose --profile agent up --build",
4146
+ "check:agent": "bun run --cwd apps/agent-server typecheck",
4147
+ "test:agent": "bun run --cwd apps/agent-server test",
4036
4148
  "dev:speech": "PLATFORM_ENABLE_AI=true SPEECH_SERVER_URL=http://speech-server:8091 docker compose --profile agent --profile speech up --build",
4037
4149
  "speech:pins": "bun run scripts/provision-speech-readiness.ts"
4038
4150
  } : {},
4039
4151
  ...generatorVersion ? { windy: "create-windy" } : {},
4040
4152
  "dev:web": "bun run --cwd apps/web dev",
4041
4153
  "dev:server": "bun run --cwd apps/server dev",
4042
- build: "bun run --cwd apps/web build",
4154
+ build: selectedModules.includes("system.agent") ? "bun run --cwd apps/agent-server build && bun run --cwd apps/web build" : "bun run --cwd apps/web build",
4043
4155
  "db:generate": "drizzle-kit generate --config drizzle.config.ts",
4044
4156
  "db:migrate": "drizzle-kit migrate --config drizzle.config.ts",
4045
4157
  "generate:crud": "bun run packages/crud-generator/src/cli.ts",
4046
4158
  typecheck: [
4047
4159
  "bun run --cwd apps/web typecheck",
4048
4160
  "bun run --cwd apps/server typecheck",
4161
+ ...selectedModules.includes("system.agent") ? ["bun run --cwd apps/agent-server typecheck"] : [],
4049
4162
  "bun run --cwd packages/ai-client typecheck",
4050
4163
  "bun run --cwd packages/jobs typecheck",
4051
4164
  "bun run --cwd packages/shared typecheck",
@@ -4059,7 +4172,7 @@ function createStarterPackage(source, projectName, includeOxc = true, projectLic
4059
4172
  format: "oxfmt",
4060
4173
  "format:staged": "lint-staged"
4061
4174
  } : {},
4062
- test: "bun test && bun run --cwd apps/web test"
4175
+ test: "bun test && bun run --cwd apps/web test" + (selectedModules.includes("system.agent") ? " && bun run test:agent" : "")
4063
4176
  },
4064
4177
  devDependencies: {
4065
4178
  ...migrationCliDependencies,
@@ -4091,6 +4204,7 @@ var templateDirectories = [
4091
4204
  ".agents/skills/windy-business-module",
4092
4205
  "apps/server",
4093
4206
  "apps/agent-server",
4207
+ "deploy/dsh",
4094
4208
  "apps/document-server",
4095
4209
  "apps/speech-server",
4096
4210
  "apps/embedding-server",
@@ -4111,8 +4225,15 @@ var templateDirectories = [
4111
4225
  var templateDocumentationFiles = [
4112
4226
  "docs/operations/legacy-data-migration.md",
4113
4227
  "docs/adr/0003-agent-session-event-source.md",
4228
+ "docs/adr/0004-embedded-dsh-runtime.md",
4114
4229
  "docs/architecture/admin-surface-boundary.md",
4115
4230
  "docs/architecture/agent-harness.md",
4231
+ "docs/architecture/agent-admin-workbench-plan.md",
4232
+ "docs/architecture/agent-admin-workbench-implementation.md",
4233
+ "docs/architecture/embedded-dsh-integration.md",
4234
+ "docs/platform/agent-skills.md",
4235
+ "docs/operations/dsh-agent-migration.md",
4236
+ "docs/development/dsh-plugins.md",
4116
4237
  "docs/architecture/agent-runtime-compatibility.md",
4117
4238
  "docs/architecture/agent-workflow.md",
4118
4239
  "docs/architecture/ai-egress.md",
@@ -6432,62 +6553,8 @@ function sentenceWithoutStop(value) {
6432
6553
  import { rm as rm10 } from "fs/promises";
6433
6554
  import { resolve as resolve8 } from "path";
6434
6555
 
6435
- // src/update/doctor.ts
6436
- import { readFile as readFile12 } from "fs/promises";
6437
- import { join as join17 } from "path";
6438
-
6439
- // src/update/process.ts
6440
- import { spawn as spawn2 } from "child_process";
6441
- var LOCAL_GIT_ENVIRONMENT_VARIABLES = [
6442
- "GIT_ALTERNATE_OBJECT_DIRECTORIES",
6443
- "GIT_CONFIG",
6444
- "GIT_CONFIG_PARAMETERS",
6445
- "GIT_CONFIG_COUNT",
6446
- "GIT_OBJECT_DIRECTORY",
6447
- "GIT_DIR",
6448
- "GIT_WORK_TREE",
6449
- "GIT_IMPLICIT_WORK_TREE",
6450
- "GIT_GRAFT_FILE",
6451
- "GIT_INDEX_FILE",
6452
- "GIT_NO_REPLACE_OBJECTS",
6453
- "GIT_REPLACE_REF_BASE",
6454
- "GIT_PREFIX",
6455
- "GIT_SHALLOW_FILE",
6456
- "GIT_COMMON_DIR"
6457
- ];
6458
- async function captureProcess(command, args, cwd, inherit = false) {
6459
- return await new Promise((resolve6, reject) => {
6460
- const child = spawn2(command, args, {
6461
- cwd,
6462
- env: withoutParentGitRepository(process.env),
6463
- stdio: inherit ? "inherit" : ["ignore", "pipe", "pipe"]
6464
- });
6465
- let stdout2 = "";
6466
- let stderr = "";
6467
- child.stdout?.on("data", (chunk) => stdout2 += chunk.toString());
6468
- child.stderr?.on("data", (chunk) => stderr += chunk.toString());
6469
- child.once("error", reject);
6470
- child.once("close", (code) => resolve6({ code: code ?? 1, stdout: stdout2, stderr }));
6471
- });
6472
- }
6473
- async function assertProcess(command, args, cwd, inherit = false) {
6474
- const result = await captureProcess(command, args, cwd, inherit);
6475
- if (result.code !== 0) {
6476
- const detail = result.stderr.trim() || result.stdout.trim();
6477
- throw new Error(`${command} ${args.join(" ")} \u6267\u884C\u5931\u8D25${detail ? `\uFF1A${detail}` : ""}`);
6478
- }
6479
- return result;
6480
- }
6481
- function withoutParentGitRepository(source) {
6482
- const environment = { ...source };
6483
- for (const key of LOCAL_GIT_ENVIRONMENT_VARIABLES) {
6484
- delete environment[key];
6485
- }
6486
- return environment;
6487
- }
6488
-
6489
- // src/update/transaction-cas.ts
6490
- import { basename as basename8, dirname as dirname7 } from "path";
6556
+ // src/update/transaction-cas.ts
6557
+ import { basename as basename8, dirname as dirname7 } from "path";
6491
6558
 
6492
6559
  // src/update/transaction-native-cas.ts
6493
6560
  import { ptr as ptr3, read as read3, dlopen as dlopen4, FFIType as FFIType4 } from "bun:ffi";
@@ -8334,6 +8401,105 @@ async function applyTransaction(plan) {
8334
8401
  };
8335
8402
  }
8336
8403
 
8404
+ // src/update/sync-docker-command.ts
8405
+ async function synchronizeDockerfiles(projectDirectory) {
8406
+ const workspace = await snapshotWorkspacePackages(projectDirectory);
8407
+ const targets = dockerfileCopyTargets.filter((target) => target.entryDirectory !== "apps/agent-server" || workspace.packages.some(({ directory }) => directory === target.entryDirectory));
8408
+ const plans = await Promise.all(targets.map((target) => planDockerfileInProject(projectDirectory, target, {
8409
+ requireAnchors: true
8410
+ }).then((result) => ({ target, result }))));
8411
+ if (plans.some(({ result }) => !result.synced)) {
8412
+ throw new Error("\u9879\u76EE\u7F3A\u5C11\u53D7\u652F\u6301\u7684 Dockerfile\uFF0C\u65E0\u6CD5\u540C\u6B65 COPY \u6E05\u5355");
8413
+ }
8414
+ const changed = plans.filter(({ result }) => result.changed && result.content !== undefined);
8415
+ if (changed.length) {
8416
+ const membershipExpectations = [
8417
+ ...workspace.membershipExpectations,
8418
+ ...plans.flatMap(({ result }) => result.membershipExpectations)
8419
+ ];
8420
+ await assertWorkspaceMembership(projectDirectory, membershipExpectations);
8421
+ const state = await applyMetadataTransaction({
8422
+ id: `sync-docker-${Date.now()}`,
8423
+ projectDirectory,
8424
+ guards: [
8425
+ ...workspace.expectations,
8426
+ ...plans.flatMap(({ result }) => result.expectations)
8427
+ ],
8428
+ writes: changed.map(({ target, result }) => ({
8429
+ path: target.dockerfilePath,
8430
+ content: result.content
8431
+ }))
8432
+ });
8433
+ await finalizeOwnedTransaction({
8434
+ projectDirectory,
8435
+ ownerToken: state.ownerToken,
8436
+ expectations: changed.map(({ target, result }) => ({
8437
+ path: target.dockerfilePath,
8438
+ expected: {
8439
+ kind: "hash",
8440
+ value: hashContent(result.content)
8441
+ }
8442
+ })),
8443
+ workspaceMembershipExpectations: membershipExpectations
8444
+ });
8445
+ }
8446
+ console.log(changed.length ? "\u5DF2\u540C\u6B65 Server \u4E0E Web Dockerfile workspace COPY \u6E05\u5355" : "Server \u4E0E Web Dockerfile workspace COPY \u6E05\u5355\u5DF2\u662F\u6700\u65B0");
8447
+ }
8448
+
8449
+ // src/update/doctor.ts
8450
+ import { readFile as readFile12 } from "fs/promises";
8451
+ import { join as join17 } from "path";
8452
+
8453
+ // src/update/process.ts
8454
+ import { spawn as spawn2 } from "child_process";
8455
+ var LOCAL_GIT_ENVIRONMENT_VARIABLES = [
8456
+ "GIT_ALTERNATE_OBJECT_DIRECTORIES",
8457
+ "GIT_CONFIG",
8458
+ "GIT_CONFIG_PARAMETERS",
8459
+ "GIT_CONFIG_COUNT",
8460
+ "GIT_OBJECT_DIRECTORY",
8461
+ "GIT_DIR",
8462
+ "GIT_WORK_TREE",
8463
+ "GIT_IMPLICIT_WORK_TREE",
8464
+ "GIT_GRAFT_FILE",
8465
+ "GIT_INDEX_FILE",
8466
+ "GIT_NO_REPLACE_OBJECTS",
8467
+ "GIT_REPLACE_REF_BASE",
8468
+ "GIT_PREFIX",
8469
+ "GIT_SHALLOW_FILE",
8470
+ "GIT_COMMON_DIR"
8471
+ ];
8472
+ async function captureProcess(command, args, cwd, inherit = false) {
8473
+ return await new Promise((resolve6, reject) => {
8474
+ const child = spawn2(command, args, {
8475
+ cwd,
8476
+ env: withoutParentGitRepository(process.env),
8477
+ stdio: inherit ? "inherit" : ["ignore", "pipe", "pipe"]
8478
+ });
8479
+ let stdout2 = "";
8480
+ let stderr = "";
8481
+ child.stdout?.on("data", (chunk) => stdout2 += chunk.toString());
8482
+ child.stderr?.on("data", (chunk) => stderr += chunk.toString());
8483
+ child.once("error", reject);
8484
+ child.once("close", (code) => resolve6({ code: code ?? 1, stdout: stdout2, stderr }));
8485
+ });
8486
+ }
8487
+ async function assertProcess(command, args, cwd, inherit = false) {
8488
+ const result = await captureProcess(command, args, cwd, inherit);
8489
+ if (result.code !== 0) {
8490
+ const detail = result.stderr.trim() || result.stdout.trim();
8491
+ throw new Error(`${command} ${args.join(" ")} \u6267\u884C\u5931\u8D25${detail ? `\uFF1A${detail}` : ""}`);
8492
+ }
8493
+ return result;
8494
+ }
8495
+ function withoutParentGitRepository(source) {
8496
+ const environment = { ...source };
8497
+ for (const key of LOCAL_GIT_ENVIRONMENT_VARIABLES) {
8498
+ delete environment[key];
8499
+ }
8500
+ return environment;
8501
+ }
8502
+
8337
8503
  // src/update/legacy-adk-retirement.ts
8338
8504
  import { lstat as lstat6, readFile as readFile11 } from "fs/promises";
8339
8505
  import { join as join16 } from "path";
@@ -8547,7 +8713,9 @@ var recipes = [
8547
8713
  },
8548
8714
  { id: "starter-0.8.0-to-0.8.1", from: "0.8.0", to: "0.8.1" },
8549
8715
  { id: "starter-0.8.1-to-0.8.2", from: "0.8.1", to: "0.8.2" },
8550
- { id: "starter-0.8.2-to-0.8.3", from: "0.8.2", to: "0.8.3" }
8716
+ { id: "starter-0.8.2-to-0.8.3", from: "0.8.2", to: "0.8.3" },
8717
+ { id: "starter-0.8.3-to-0.9.0", from: "0.8.3", to: "0.9.0" },
8718
+ { id: "starter-0.9.0-to-0.9.1", from: "0.9.0", to: "0.9.1" }
8551
8719
  ];
8552
8720
  function resolveRecipeChain(sourceVersion, targetVersion) {
8553
8721
  if (compareVersions2(sourceVersion, minimumSupportedUpdateVersion) < 0) {
@@ -8953,8 +9121,8 @@ async function readProjectName2(projectDirectory) {
8953
9121
  }
8954
9122
 
8955
9123
  // src/update/planner.ts
8956
- import { readFile as readFile22 } from "fs/promises";
8957
- import { dirname as dirname9, join as join27 } from "path";
9124
+ import { readFile as readFile23 } from "fs/promises";
9125
+ import { dirname as dirname9, join as join29 } from "path";
8958
9126
 
8959
9127
  // src/update/docker-copy-update-plan.ts
8960
9128
  async function deriveDockerfilePlans(files, snapshots, paths, targetWorkspaceManifests) {
@@ -9422,9 +9590,33 @@ async function readSnapshot(root, tag) {
9422
9590
  }
9423
9591
 
9424
9592
  // src/update/planner-file.ts
9425
- import { readFile as readFile20 } from "fs/promises";
9426
- import { join as join25 } from "path";
9593
+ import { readFile as readFile21 } from "fs/promises";
9594
+ import { join as join27 } from "path";
9427
9595
 
9596
+ // src/update/planner-file-support.ts
9597
+ function readyPlannedFile(path2, ownership, action, reason, expectedProjectContent, content) {
9598
+ return {
9599
+ path: path2,
9600
+ ownership,
9601
+ action,
9602
+ reason,
9603
+ expectedProjectContent,
9604
+ content
9605
+ };
9606
+ }
9607
+ function expectationForSnapshot(content) {
9608
+ return content ? { kind: "hash", value: hashContent(content) } : { kind: "missing" };
9609
+ }
9610
+ function conflict(path2, ownership, reason, expectedProjectContent) {
9611
+ return {
9612
+ path: path2,
9613
+ ownership,
9614
+ action: "preserve",
9615
+ reason: "\u5BA2\u6237\u5DF2\u4FEE\u6539",
9616
+ expectedProjectContent,
9617
+ conflict: reason
9618
+ };
9619
+ }
9428
9620
  // src/update/merge.ts
9429
9621
  import { mkdtemp as mkdtemp2, rm as rm6, writeFile as writeFile12 } from "fs/promises";
9430
9622
  import { tmpdir as tmpdir2 } from "os";
@@ -9867,13 +10059,13 @@ function isObject(value) {
9867
10059
  // src/update/planner-project-owned.ts
9868
10060
  function planGeneratedProjectOwned(path2, source, target, ours, theirs, expected) {
9869
10061
  if (!source && target) {
9870
- return !ours && theirs ? ready(path2, "create", "\u6A21\u5757\u5B89\u88C5\u65B0\u589E\u9879\u76EE\u6269\u5C55\u70B9", expected, theirs) : conflict(path2, "\u6A21\u5757\u65B0\u589E\u8DEF\u5F84\u5DF2\u88AB\u9879\u76EE\u5360\u7528", expected);
10062
+ return !ours && theirs ? ready(path2, "create", "\u6A21\u5757\u5B89\u88C5\u65B0\u589E\u9879\u76EE\u6269\u5C55\u70B9", expected, theirs) : conflict2(path2, "\u6A21\u5757\u65B0\u589E\u8DEF\u5F84\u5DF2\u88AB\u9879\u76EE\u5360\u7528", expected);
9871
10063
  }
9872
10064
  if (source && !target) {
9873
10065
  if (!ours) {
9874
10066
  return ready(path2, "preserve", "\u6A21\u5757\u8DEF\u5F84\u5DF2\u79FB\u9664", expected);
9875
10067
  }
9876
- return hashContent(ours) === source.hash ? ready(path2, "delete", "\u6A21\u5757\u5378\u8F7D\u79FB\u9664\u672A\u4FEE\u6539\u6269\u5C55\u70B9", expected) : conflict(path2, "\u5BA2\u6237\u4FEE\u6539\u8FC7\u6A21\u5757\u6269\u5C55\u70B9\uFF0C\u62D2\u7EDD\u5378\u8F7D", expected);
10068
+ return hashContent(ours) === source.hash ? ready(path2, "delete", "\u6A21\u5757\u5378\u8F7D\u79FB\u9664\u672A\u4FEE\u6539\u6269\u5C55\u70B9", expected) : conflict2(path2, "\u5BA2\u6237\u4FEE\u6539\u8FC7\u6A21\u5757\u6269\u5C55\u70B9\uFF0C\u62D2\u7EDD\u5378\u8F7D", expected);
9877
10069
  }
9878
10070
  if (!source || !target || !ours || !theirs) {
9879
10071
  return ready(path2, "preserve", "\u9879\u76EE\u62E5\u6709\uFF0C\u6A21\u5757\u7EC4\u5408\u672A\u6539\u53D8", expected);
@@ -9884,7 +10076,7 @@ function planGeneratedProjectOwned(path2, source, target, ours, theirs, expected
9884
10076
  if (source.hash === target.hash) {
9885
10077
  return ready(path2, "preserve", "\u6A21\u5757\u7EC4\u5408\u672A\u6539\u53D8", expected);
9886
10078
  }
9887
- return hashContent(ours) === source.hash ? ready(path2, "update", "\u66F4\u65B0\u672A\u4FEE\u6539\u7684\u6A21\u5757\u7EC4\u5408\u6269\u5C55\u70B9", expected, theirs) : conflict(path2, "\u5BA2\u6237\u4FEE\u6539\u8FC7\u6A21\u5757\u7EC4\u5408\u6269\u5C55\u70B9", expected);
10079
+ return hashContent(ours) === source.hash ? ready(path2, "update", "\u66F4\u65B0\u672A\u4FEE\u6539\u7684\u6A21\u5757\u7EC4\u5408\u6269\u5C55\u70B9", expected, theirs) : conflict2(path2, "\u5BA2\u6237\u4FEE\u6539\u8FC7\u6A21\u5757\u7EC4\u5408\u6269\u5C55\u70B9", expected);
9888
10080
  }
9889
10081
  function ready(path2, action, reason, expectedProjectContent, content) {
9890
10082
  return {
@@ -9896,7 +10088,7 @@ function ready(path2, action, reason, expectedProjectContent, content) {
9896
10088
  content
9897
10089
  };
9898
10090
  }
9899
- function conflict(path2, reason, expectedProjectContent) {
10091
+ function conflict2(path2, reason, expectedProjectContent) {
9900
10092
  return {
9901
10093
  path: path2,
9902
10094
  ownership: "project-owned",
@@ -9949,10 +10141,10 @@ function planClientWorkflowProjectOwned(input) {
9949
10141
  }
9950
10142
  function planBinding(input) {
9951
10143
  if (!input.target)
9952
- return conflict2(input, "\u76EE\u6807\u7248\u672C\u7F3A\u5C11 Workflow binding seam");
10144
+ return conflict3(input, "\u76EE\u6807\u7248\u672C\u7F3A\u5C11 Workflow binding seam");
9953
10145
  const target = decode(input.target);
9954
10146
  if (target !== immutableReleaseDefaultBinding) {
9955
- return conflict2(input, "\u76EE\u6807\u7248\u672C Workflow binding seam \u5951\u7EA6\u65E0\u6548");
10147
+ return conflict3(input, "\u76EE\u6807\u7248\u672C Workflow binding seam \u5951\u7EA6\u65E0\u6548");
9956
10148
  }
9957
10149
  if (!input.ours) {
9958
10150
  return ready2(input, "create", "\u65B0\u589E\u9ED8\u8BA4\u5173\u95ED\u7684 Workflow binding seam", input.target);
@@ -9962,17 +10154,17 @@ function planBinding(input) {
9962
10154
  return ready2(input, "preserve", "\u5DF2\u5305\u542B immutable release binding seam");
9963
10155
  }
9964
10156
  if (source !== legacyDefaultBinding) {
9965
- return conflict2(input, "Workflow binding seam \u4E0D\u662F 0.6.14 \u9ED8\u8BA4\u7A7A\u7248\u672C");
10157
+ return conflict3(input, "Workflow binding seam \u4E0D\u662F 0.6.14 \u9ED8\u8BA4\u7A7A\u7248\u672C");
9966
10158
  }
9967
10159
  return ready2(input, "update", "\u5347\u7EA7\u9ED8\u8BA4\u7A7A Workflow binding seam", input.target);
9968
10160
  }
9969
10161
  function planComposition(input) {
9970
10162
  if (!input.target) {
9971
- return conflict2(input, "\u76EE\u6807\u7248\u672C\u7F3A\u5C11 Agent Runtime Composition");
10163
+ return conflict3(input, "\u76EE\u6807\u7248\u672C\u7F3A\u5C11 Agent Runtime Composition");
9972
10164
  }
9973
10165
  const target = decode(input.target);
9974
10166
  if (hashContent(target) !== immutableReleaseCompositionHash) {
9975
- return conflict2(input, "\u76EE\u6807\u7248\u672C Agent Runtime Composition \u5951\u7EA6\u65E0\u6548");
10167
+ return conflict3(input, "\u76EE\u6807\u7248\u672C Agent Runtime Composition \u5951\u7EA6\u65E0\u6548");
9976
10168
  }
9977
10169
  if (!input.ours) {
9978
10170
  return ready2(input, "create", "\u65B0\u589E Agent Runtime Composition", input.target);
@@ -9982,11 +10174,11 @@ function planComposition(input) {
9982
10174
  return ready2(input, "preserve", "\u5DF2\u88C5\u914D Workflow Artifact binding");
9983
10175
  }
9984
10176
  if ([workflowArtifactImport, newOmit, workflowArtifactProperty].some((value) => source.includes(value))) {
9985
- return conflict2(input, "Agent Runtime Composition \u53EA\u5305\u542B\u90E8\u5206\u76EE\u6807\u88C5\u914D");
10177
+ return conflict3(input, "Agent Runtime Composition \u53EA\u5305\u542B\u90E8\u5206\u76EE\u6807\u88C5\u914D");
9986
10178
  }
9987
10179
  const runtimeConflict = validateLegacyRuntimeObject(source);
9988
10180
  if (runtimeConflict)
9989
- return conflict2(input, runtimeConflict);
10181
+ return conflict3(input, runtimeConflict);
9990
10182
  const replacements2 = [
9991
10183
  {
9992
10184
  anchor: hostAuthImport,
@@ -10006,7 +10198,7 @@ ${workflowArtifactProperty}`
10006
10198
  let content = source;
10007
10199
  for (const replacement of replacements2) {
10008
10200
  if (occurrences(content, replacement.anchor) !== 1) {
10009
- return conflict2(input, `Agent Runtime Composition \u951A\u70B9\u4E0D\u552F\u4E00\uFF1A${replacement.anchor}`);
10201
+ return conflict3(input, `Agent Runtime Composition \u951A\u70B9\u4E0D\u552F\u4E00\uFF1A${replacement.anchor}`);
10010
10202
  }
10011
10203
  content = content.replace(replacement.anchor, replacement.value);
10012
10204
  }
@@ -10022,7 +10214,7 @@ function ready2(input, action, reason, content) {
10022
10214
  content
10023
10215
  };
10024
10216
  }
10025
- function conflict2(input, message) {
10217
+ function conflict3(input, message) {
10026
10218
  return {
10027
10219
  path: input.path,
10028
10220
  ownership: "project-owned",
@@ -10120,18 +10312,18 @@ function recipeCanManageMissingProjectOwnedPath(path2) {
10120
10312
  async function planRecipeProjectOwned(input) {
10121
10313
  if (input.path === clientWorkflowCompositionPath || input.path === clientWorkflowBindingPath) {
10122
10314
  if (!input.target) {
10123
- return conflict3(input, "\u7248\u672C recipe \u6240\u9700\u7684\u76EE\u6807\u6587\u4EF6\u7F3A\u5931");
10315
+ return conflict4(input, "\u7248\u672C recipe \u6240\u9700\u7684\u76EE\u6807\u6587\u4EF6\u7F3A\u5931");
10124
10316
  }
10125
10317
  return planClientWorkflowProjectOwned({ ...input, target: input.target });
10126
10318
  }
10127
10319
  if (!input.ours) {
10128
- return conflict3(input, "\u7248\u672C recipe \u6240\u9700\u7684\u9879\u76EE\u951A\u70B9\u7F3A\u5931");
10320
+ return conflict4(input, "\u7248\u672C recipe \u6240\u9700\u7684\u9879\u76EE\u951A\u70B9\u7F3A\u5931");
10129
10321
  }
10130
10322
  const source = new TextDecoder().decode(input.ours);
10131
10323
  const target = input.target ? new TextDecoder().decode(input.target) : undefined;
10132
10324
  const transformed = transformProjectOwnedAnchor(input.path, source, target);
10133
10325
  if ("error" in transformed)
10134
- return conflict3(input, transformed.error);
10326
+ return conflict4(input, transformed.error);
10135
10327
  if (transformed.content === source) {
10136
10328
  return preserve(input, "\u5DF2\u5305\u542B\u7248\u672C recipe \u76EE\u6807\u5185\u5BB9");
10137
10329
  }
@@ -10317,7 +10509,7 @@ function update(input, content) {
10317
10509
  content
10318
10510
  };
10319
10511
  }
10320
- function conflict3(input, message) {
10512
+ function conflict4(input, message) {
10321
10513
  return {
10322
10514
  path: input.path,
10323
10515
  ownership: "project-owned",
@@ -10328,14 +10520,163 @@ function conflict3(input, message) {
10328
10520
  };
10329
10521
  }
10330
10522
 
10523
+ // src/update/dsh-platform-recipe.ts
10524
+ import { join as join26 } from "path";
10525
+
10526
+ // src/update/planner-snapshots.ts
10527
+ import { readFile as readFile20, stat as stat2 } from "fs/promises";
10528
+ import { join as join25 } from "path";
10529
+ async function snapshotProjectFiles(project, paths, seed) {
10530
+ const snapshots = new Map(seed);
10531
+ await Promise.all([...paths].filter((path2) => !snapshots.has(path2)).map(async (path2) => {
10532
+ snapshots.set(path2, await readOptional(join25(project, path2)));
10533
+ }));
10534
+ return snapshots;
10535
+ }
10536
+ async function snapshotProjectModes(project, paths) {
10537
+ return new Map(await Promise.all([...paths].map(async (path2) => [path2, await readModeOptional(join25(project, path2))])));
10538
+ }
10539
+ async function assertPlanSnapshots(project, expectations) {
10540
+ const changed = [];
10541
+ for (const expectation2 of expectations) {
10542
+ const actual = expectationForSnapshot(await readOptional(join25(project, expectation2.path)));
10543
+ if (JSON.stringify(actual) !== JSON.stringify(expectation2.expected)) {
10544
+ changed.push(expectation2.path);
10545
+ continue;
10546
+ }
10547
+ if ("mode" in expectation2 && await readModeOptional(join25(project, expectation2.path)) !== expectation2.mode) {
10548
+ changed.push(expectation2.path);
10549
+ }
10550
+ }
10551
+ if (changed.length) {
10552
+ throw new Error(`\u751F\u6210\u66F4\u65B0\u8BA1\u5212\u671F\u95F4\u5019\u9009\u6587\u4EF6\u53D1\u751F\u53D8\u5316\uFF1A${changed.join("\u3001")}`);
10553
+ }
10554
+ }
10555
+ async function readModeOptional(path2) {
10556
+ try {
10557
+ return (await stat2(path2)).mode & 511;
10558
+ } catch (error) {
10559
+ if (isMissing7(error))
10560
+ return;
10561
+ throw error;
10562
+ }
10563
+ }
10564
+ async function readSourceParentMode(path2) {
10565
+ try {
10566
+ const info = await stat2(path2);
10567
+ if (!info.isDirectory()) {
10568
+ throw new Error(`artifact \u6E90\u7801\u7236\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${path2}`);
10569
+ }
10570
+ return info.mode & 493 | 493;
10571
+ } catch (error) {
10572
+ if (isMissing7(error))
10573
+ return 493;
10574
+ throw error;
10575
+ }
10576
+ }
10577
+ async function readOptional(path2) {
10578
+ try {
10579
+ return await readFile20(path2);
10580
+ } catch (error) {
10581
+ if (isMissing7(error))
10582
+ return;
10583
+ throw error;
10584
+ }
10585
+ }
10586
+ function isMissing7(error) {
10587
+ return error instanceof Error && "code" in error && error.code === "ENOENT";
10588
+ }
10589
+
10590
+ // src/update/dsh-platform-recipe.ts
10591
+ var dshPlatformRecipeId = "dsh-platform-v1";
10592
+ var dshPlatformRecipePaths = new Set([
10593
+ "apps/server/src/app/agent-workflow-presets.ts",
10594
+ "apps/server/src/app/workbench-public-origin.ts",
10595
+ "apps/web/src/router/index.ts",
10596
+ "apps/web/src/router/platform-admin-pages.ts",
10597
+ "apps/web/src/router/platform-admin-route-bindings.ts",
10598
+ "apps/web/src/composables/useLoginFlow.ts",
10599
+ "apps/web/src/pages/system/AgentWorkflowPage.vue",
10600
+ "apps/web/src/services/agent-workflow-api.ts",
10601
+ "apps/web/vite.config.ts",
10602
+ "apps/web/server.ts",
10603
+ "apps/web/runtime-server.ts",
10604
+ "apps/web/dev/start.ts"
10605
+ ]);
10606
+ function isDshPlatformRecipePath(path2) {
10607
+ return dshPlatformRecipePaths.has(path2) || path2.startsWith("apps/server/src/app/dsh-") && path2.endsWith(".ts");
10608
+ }
10609
+ async function isDshPlatformTransition(input) {
10610
+ if (!input.sourceModules.includes("system.agent") || !input.targetModules.includes("system.agent"))
10611
+ return false;
10612
+ const path2 = "apps/agent-server/package.json";
10613
+ const [base, target] = await Promise.all([
10614
+ readOptional(join26(input.baseDirectory, path2)),
10615
+ readOptional(join26(input.targetDirectory, path2))
10616
+ ]);
10617
+ return hasDsh(target) && !hasDsh(base);
10618
+ }
10619
+ function planDshPlatformFile(input) {
10620
+ const common2 = {
10621
+ path: input.path,
10622
+ ownership: input.ownership,
10623
+ expectedProjectContent: input.expected
10624
+ };
10625
+ if (input.target && input.ours && hashContent(input.ours) === hashContent(input.target)) {
10626
+ return {
10627
+ ...common2,
10628
+ action: "preserve",
10629
+ reason: "\u5DF2\u5305\u542B DSH \u5E73\u53F0\u63A5\u7EBF\u76EE\u6807\u5185\u5BB9"
10630
+ };
10631
+ }
10632
+ if (input.target && !input.ours && !input.base) {
10633
+ return {
10634
+ ...common2,
10635
+ action: "create",
10636
+ reason: "DSH \u5E73\u53F0\u65B0\u589E\u9879\u76EE\u6269\u5C55\u70B9",
10637
+ content: input.target
10638
+ };
10639
+ }
10640
+ if (input.target && input.base && input.ours && hashContent(input.ours) === hashContent(input.base)) {
10641
+ return {
10642
+ ...common2,
10643
+ action: "update",
10644
+ reason: "DSH \u5E73\u53F0\u5347\u7EA7\u7CBE\u786E\u6765\u6E90\u63A5\u7EBF",
10645
+ content: input.target
10646
+ };
10647
+ }
10648
+ return {
10649
+ ...common2,
10650
+ action: "preserve",
10651
+ reason: "\u4FDD\u7559\u5BA2\u6237 DSH \u63A5\u7EBF",
10652
+ conflict: "DSH \u5E73\u53F0\u63A5\u7EBF\u4E0E\u7CBE\u786E\u6765\u6E90\u6216\u76EE\u6807\u4E0D\u4E00\u81F4\uFF1B\u8BF7\u5BA1\u6838\u9879\u76EE\u4FEE\u6539\u540E\u663E\u5F0F\u96C6\u6210\uFF0C\u7981\u6B62\u731C\u6D4B\u8986\u76D6"
10653
+ };
10654
+ }
10655
+ function hasDsh(content) {
10656
+ if (!content)
10657
+ return false;
10658
+ const value = JSON.parse(new TextDecoder().decode(content));
10659
+ return typeof value.dependencies?.["@deepseek-ai/dsh"] === "string";
10660
+ }
10661
+
10331
10662
  // src/update/planner-file.ts
10332
- async function planFile(path2, baseRoot, targetRoot, source, target, ours, provenance, targetContentOverride, manageGeneratedProjectOwned = false, forcePlatformBaseline = false, manageRecipeProjectOwned = false) {
10663
+ async function planFile(path2, baseRoot, targetRoot, source, target, ours, provenance, targetContentOverride, manageGeneratedProjectOwned = false, forcePlatformBaseline = false, manageRecipeProjectOwned = false, migrateDshPlatform = false) {
10333
10664
  const [base, theirs] = await Promise.all([
10334
- readOptional(join25(baseRoot, path2)),
10335
- targetContentOverride ? Promise.resolve(targetContentOverride) : readOptional(join25(targetRoot, path2))
10665
+ readOptional2(join27(baseRoot, path2)),
10666
+ targetContentOverride ? Promise.resolve(targetContentOverride) : readOptional2(join27(targetRoot, path2))
10336
10667
  ]);
10337
10668
  const ownership = source?.ownership ?? target?.ownership ?? classifyOwnership(path2);
10338
10669
  const expected = expectationForSnapshot(ours);
10670
+ if (migrateDshPlatform && isDshPlatformRecipePath(path2)) {
10671
+ return planDshPlatformFile({
10672
+ path: path2,
10673
+ ownership,
10674
+ ours,
10675
+ base,
10676
+ target: theirs,
10677
+ expected
10678
+ });
10679
+ }
10339
10680
  if (ownership === "project-owned") {
10340
10681
  const hasExistingRecipeSource = source !== undefined && source.state !== "missing" && ours !== undefined;
10341
10682
  if (manageRecipeProjectOwned && target && (hasExistingRecipeSource || recipeCanManageMissingProjectOwnedPath(path2))) {
@@ -10348,29 +10689,29 @@ async function planFile(path2, baseRoot, targetRoot, source, target, ours, prove
10348
10689
  }
10349
10690
  if (path2.startsWith("packages/database/drizzle/") && path2.endsWith(".sql")) {
10350
10691
  if (source && !target) {
10351
- return conflict4(path2, ownership, "\u5DF2\u53D1\u5E03 migration \u4E0D\u53EF\u5220\u9664", expected);
10692
+ return conflict(path2, ownership, "\u5DF2\u53D1\u5E03 migration \u4E0D\u53EF\u5220\u9664", expected);
10352
10693
  }
10353
10694
  if (source && target && source.hash !== target.hash) {
10354
- return conflict4(path2, ownership, "\u5DF2\u53D1\u5E03 migration \u4E0D\u53EF\u6539\u5199\uFF0C\u53EA\u80FD\u8FFD\u52A0\u65B0\u6587\u4EF6", expected);
10695
+ return conflict(path2, ownership, "\u5DF2\u53D1\u5E03 migration \u4E0D\u53EF\u6539\u5199\uFF0C\u53EA\u80FD\u8FFD\u52A0\u65B0\u6587\u4EF6", expected);
10355
10696
  }
10356
10697
  }
10357
10698
  if (!source && target) {
10358
10699
  if (!ours) {
10359
10700
  return readyPlannedFile(path2, ownership, "create", "\u76EE\u6807\u7248\u672C\u65B0\u589E", expected, theirs);
10360
10701
  }
10361
- return theirs && hashContent(ours) === target.hash ? readyPlannedFile(path2, ownership, "preserve", "\u5DF2\u5305\u542B\u76EE\u6807\u5185\u5BB9", expected) : conflict4(path2, ownership, "\u76EE\u6807\u7248\u672C\u65B0\u589E\u8DEF\u5F84\u5DF2\u88AB\u9879\u76EE\u5360\u7528", expected);
10702
+ return theirs && hashContent(ours) === target.hash ? readyPlannedFile(path2, ownership, "preserve", "\u5DF2\u5305\u542B\u76EE\u6807\u5185\u5BB9", expected) : conflict(path2, ownership, "\u76EE\u6807\u7248\u672C\u65B0\u589E\u8DEF\u5F84\u5DF2\u88AB\u9879\u76EE\u5360\u7528", expected);
10362
10703
  }
10363
10704
  if (source && !target) {
10364
10705
  if (!ours) {
10365
10706
  return readyPlannedFile(path2, ownership, "preserve", "\u9879\u76EE\u5DF2\u5220\u9664", expected);
10366
10707
  }
10367
- return hashContent(ours) === source.hash ? readyPlannedFile(path2, ownership, "delete", "\u76EE\u6807\u7248\u672C\u5220\u9664", expected) : conflict4(path2, ownership, "\u5BA2\u6237\u4FEE\u6539\u540E Windy \u53C8\u5220\u9664", expected);
10708
+ return hashContent(ours) === source.hash ? readyPlannedFile(path2, ownership, "delete", "\u76EE\u6807\u7248\u672C\u5220\u9664", expected) : conflict(path2, ownership, "\u5BA2\u6237\u4FEE\u6539\u540E Windy \u53C8\u5220\u9664", expected);
10368
10709
  }
10369
10710
  if (source && target && !ours) {
10370
10711
  return readyPlannedFile(path2, "project-owned", "preserve", "\u9879\u76EE\u5DF2\u5220\u9664", expected);
10371
10712
  }
10372
10713
  if (!source || !target || !ours || !theirs) {
10373
- return conflict4(path2, ownership, "\u6587\u4EF6\u72B6\u6001\u4E0D\u5B8C\u6574\uFF0C\u4E0D\u80FD\u5B89\u5168\u63A8\u65AD", expected);
10714
+ return conflict(path2, ownership, "\u6587\u4EF6\u72B6\u6001\u4E0D\u5B8C\u6574\uFF0C\u4E0D\u80FD\u5B89\u5168\u63A8\u65AD", expected);
10374
10715
  }
10375
10716
  const oursChanged = hashContent(ours) !== source.hash;
10376
10717
  const sourceArtifactHash = artifactHashOf(source);
@@ -10384,7 +10725,7 @@ async function planFile(path2, baseRoot, targetRoot, source, target, ours, prove
10384
10725
  });
10385
10726
  if (forceTargetBaseline && path2.endsWith("package.json") && base) {
10386
10727
  const merged = mergePackageJson(base, ours, theirs);
10387
- return merged.content ? readyPlannedFile(path2, ownership, "update", "package.json \u5B57\u6BB5\u7EA7\u5408\u5E76", expected, merged.content) : conflict4(path2, ownership, `\u5B57\u6BB5\u51B2\u7A81\uFF1A${merged.conflicts.join("\u3001")}`, expected);
10728
+ return merged.content ? readyPlannedFile(path2, ownership, "update", "package.json \u5B57\u6BB5\u7EA7\u5408\u5E76", expected, merged.content) : conflict(path2, ownership, `\u5B57\u6BB5\u51B2\u7A81\uFF1A${merged.conflicts.join("\u3001")}`, expected);
10388
10729
  }
10389
10730
  if (forceTargetBaseline) {
10390
10731
  return readyPlannedFile(path2, ownership, "update", "\u5F3A\u5236\u91C7\u7528\u76EE\u6807\u5E73\u53F0\u57FA\u7EBF", expected, theirs);
@@ -10394,11 +10735,11 @@ async function planFile(path2, baseRoot, targetRoot, source, target, ours, prove
10394
10735
  }
10395
10736
  if (targetChanged && path2.endsWith("package.json") && base) {
10396
10737
  const merged = mergePackageJson(base, ours, theirs);
10397
- return merged.content ? readyPlannedFile(path2, ownership, "update", "package.json \u5B57\u6BB5\u7EA7\u5408\u5E76", expected, merged.content) : conflict4(path2, ownership, `\u5B57\u6BB5\u51B2\u7A81\uFF1A${merged.conflicts.join("\u3001")}`, expected);
10738
+ return merged.content ? readyPlannedFile(path2, ownership, "update", "package.json \u5B57\u6BB5\u7EA7\u5408\u5E76", expected, merged.content) : conflict(path2, ownership, `\u5B57\u6BB5\u51B2\u7A81\uFF1A${merged.conflicts.join("\u3001")}`, expected);
10398
10739
  }
10399
10740
  if (!oursChanged && targetChanged && adoptedProjectDelta && base) {
10400
10741
  const merged = await mergeTextFile(base, ours, theirs);
10401
- return merged.content ? readyPlannedFile(path2, ownership, "update", "\u4E09\u65B9\u5408\u5E76\u5DF2\u91C7\u7EB3\u9879\u76EE\u589E\u91CF", expected, merged.content) : conflict4(path2, ownership, merged.conflict || "\u4E09\u65B9\u5408\u5E76\u5931\u8D25", expected);
10742
+ return merged.content ? readyPlannedFile(path2, ownership, "update", "\u4E09\u65B9\u5408\u5E76\u5DF2\u91C7\u7EB3\u9879\u76EE\u589E\u91CF", expected, merged.content) : conflict(path2, ownership, merged.conflict || "\u4E09\u65B9\u5408\u5E76\u5931\u8D25", expected);
10402
10743
  }
10403
10744
  if (!oursChanged) {
10404
10745
  return readyPlannedFile(path2, ownership, "update", "\u4EC5 Windy \u4FEE\u6539", expected, theirs);
@@ -10411,9 +10752,9 @@ async function planFile(path2, baseRoot, targetRoot, source, target, ours, prove
10411
10752
  }
10412
10753
  if (base) {
10413
10754
  const merged = await mergeTextFile(base, ours, theirs);
10414
- return merged.content ? readyPlannedFile(path2, ownership, "update", "\u4E09\u65B9\u5408\u5E76", expected, merged.content) : conflict4(path2, ownership, merged.conflict || "\u4E09\u65B9\u5408\u5E76\u5931\u8D25", expected);
10755
+ return merged.content ? readyPlannedFile(path2, ownership, "update", "\u4E09\u65B9\u5408\u5E76", expected, merged.content) : conflict(path2, ownership, merged.conflict || "\u4E09\u65B9\u5408\u5E76\u5931\u8D25", expected);
10415
10756
  }
10416
- return conflict4(path2, ownership, "\u5BA2\u6237\u548C Windy \u5747\u5DF2\u4FEE\u6539", expected);
10757
+ return conflict(path2, ownership, "\u5BA2\u6237\u548C Windy \u5747\u5DF2\u4FEE\u6539", expected);
10417
10758
  }
10418
10759
  function shouldForcePlatformBaseline(input) {
10419
10760
  return input.forcePlatformBaseline && !input.oursChanged && input.base !== undefined && hashContent(input.base) !== input.sourceArtifactHash;
@@ -10421,32 +10762,9 @@ function shouldForcePlatformBaseline(input) {
10421
10762
  function targetChangedSinceBase(sourceHash, base, target) {
10422
10763
  return base && target ? hashContent(base) !== hashContent(target) : !!target && hashContent(target) !== sourceHash;
10423
10764
  }
10424
- function readyPlannedFile(path2, ownership, action, reason, expectedProjectContent, content) {
10425
- return {
10426
- path: path2,
10427
- ownership,
10428
- action,
10429
- reason,
10430
- expectedProjectContent,
10431
- content
10432
- };
10433
- }
10434
- function expectationForSnapshot(content) {
10435
- return content ? { kind: "hash", value: hashContent(content) } : { kind: "missing" };
10436
- }
10437
- function conflict4(path2, ownership, reason, expectedProjectContent) {
10438
- return {
10439
- path: path2,
10440
- ownership,
10441
- action: "preserve",
10442
- reason: "\u5BA2\u6237\u5DF2\u4FEE\u6539",
10443
- expectedProjectContent,
10444
- conflict: reason
10445
- };
10446
- }
10447
- async function readOptional(path2) {
10765
+ async function readOptional2(path2) {
10448
10766
  try {
10449
- return await readFile20(path2);
10767
+ return await readFile21(path2);
10450
10768
  } catch (error) {
10451
10769
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
10452
10770
  return;
@@ -10455,6 +10773,31 @@ async function readOptional(path2) {
10455
10773
  }
10456
10774
  }
10457
10775
 
10776
+ // src/update/planner-files.ts
10777
+ var metadataPaths = new Set([
10778
+ ".windy/generation.json",
10779
+ ".windy/files.json",
10780
+ ".windy-template.json"
10781
+ ]);
10782
+ async function planFiles(input) {
10783
+ const files = [];
10784
+ for (const path2 of [...input.paths].sort()) {
10785
+ if (metadataPaths.has(path2))
10786
+ continue;
10787
+ const forcedContent = input.migrations.forceUpdates.has(path2) ? input.migrations.contentOverrides.get(path2) : undefined;
10788
+ const ours = input.projectSnapshots.get(path2);
10789
+ const expected = expectationForSnapshot(ours);
10790
+ if (input.migrations.forcePreserves.has(path2)) {
10791
+ files.push(readyPlannedFile(path2, input.sourceEntries.get(path2)?.ownership ?? classifyOwnership(path2), "preserve", "\u4FDD\u7559\u9879\u76EE\u5DF2\u53D1\u5E03 migration \u5386\u53F2", expected));
10792
+ } else if (forcedContent) {
10793
+ files.push(readyPlannedFile(path2, input.targetEntries.get(path2)?.ownership ?? input.sourceEntries.get(path2)?.ownership ?? classifyOwnership(path2), "update", "\u5408\u5E76\u5E73\u53F0\u4E0E\u4E0B\u6E38 migration \u5386\u53F2", expected, forcedContent));
10794
+ } else {
10795
+ files.push(await planFile(path2, input.artifactSet.baseDirectory, input.artifactSet.targetDirectory, input.sourceEntries.get(path2), input.targetEntries.get(path2), ours, input.provenance, input.migrations.contentOverrides.get(path2), input.manageGeneratedProjectOwned, input.forcePlatformBaseline, input.recipeProjectOwnedPaths.has(path2), input.migrateDshPlatform));
10796
+ }
10797
+ }
10798
+ return files;
10799
+ }
10800
+
10458
10801
  // src/update/planner-modules.ts
10459
10802
  function resolveModuleRecipeIds(request) {
10460
10803
  const lifecycle = request.lifecycle;
@@ -10497,70 +10840,6 @@ function hasExistingSourceForTest(path2, sourcePaths) {
10497
10840
  return sourceExtensions.some((extension) => sourcePaths.has(`${stem}${extension}`));
10498
10841
  }
10499
10842
 
10500
- // src/update/planner-snapshots.ts
10501
- import { readFile as readFile21, stat as stat2 } from "fs/promises";
10502
- import { join as join26 } from "path";
10503
- async function snapshotProjectFiles(project, paths, seed) {
10504
- const snapshots = new Map(seed);
10505
- await Promise.all([...paths].filter((path2) => !snapshots.has(path2)).map(async (path2) => {
10506
- snapshots.set(path2, await readOptional2(join26(project, path2)));
10507
- }));
10508
- return snapshots;
10509
- }
10510
- async function snapshotProjectModes(project, paths) {
10511
- return new Map(await Promise.all([...paths].map(async (path2) => [path2, await readModeOptional(join26(project, path2))])));
10512
- }
10513
- async function assertPlanSnapshots(project, expectations) {
10514
- const changed = [];
10515
- for (const expectation2 of expectations) {
10516
- const actual = expectationForSnapshot(await readOptional2(join26(project, expectation2.path)));
10517
- if (JSON.stringify(actual) !== JSON.stringify(expectation2.expected)) {
10518
- changed.push(expectation2.path);
10519
- continue;
10520
- }
10521
- if ("mode" in expectation2 && await readModeOptional(join26(project, expectation2.path)) !== expectation2.mode) {
10522
- changed.push(expectation2.path);
10523
- }
10524
- }
10525
- if (changed.length) {
10526
- throw new Error(`\u751F\u6210\u66F4\u65B0\u8BA1\u5212\u671F\u95F4\u5019\u9009\u6587\u4EF6\u53D1\u751F\u53D8\u5316\uFF1A${changed.join("\u3001")}`);
10527
- }
10528
- }
10529
- async function readModeOptional(path2) {
10530
- try {
10531
- return (await stat2(path2)).mode & 511;
10532
- } catch (error) {
10533
- if (isMissing7(error))
10534
- return;
10535
- throw error;
10536
- }
10537
- }
10538
- async function readSourceParentMode(path2) {
10539
- try {
10540
- const info = await stat2(path2);
10541
- if (!info.isDirectory()) {
10542
- throw new Error(`artifact \u6E90\u7801\u7236\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${path2}`);
10543
- }
10544
- return info.mode & 493 | 493;
10545
- } catch (error) {
10546
- if (isMissing7(error))
10547
- return 493;
10548
- throw error;
10549
- }
10550
- }
10551
- async function readOptional2(path2) {
10552
- try {
10553
- return await readFile21(path2);
10554
- } catch (error) {
10555
- if (isMissing7(error))
10556
- return;
10557
- throw error;
10558
- }
10559
- }
10560
- function isMissing7(error) {
10561
- return error instanceof Error && "code" in error && error.code === "ENOENT";
10562
- }
10563
-
10564
10843
  // src/update/preflight.ts
10565
10844
  async function assertProjectReadyForUpdate(projectDirectory) {
10566
10845
  await assertNoPendingUpdate(projectDirectory);
@@ -10581,12 +10860,45 @@ function resolveUpdateTargetModules(sourceModules, explicitTarget) {
10581
10860
  });
10582
10861
  }
10583
10862
 
10863
+ // src/update/legacy-python-agent-retirement.ts
10864
+ import { lstat as lstat8, readFile as readFile22 } from "fs/promises";
10865
+ import { join as join28 } from "path";
10866
+ var retiredKeys = [
10867
+ "AGENT_DATABASE_URL",
10868
+ "AGENT_RUN_STORE_PATH",
10869
+ "AGENT_RUN_ENCRYPTION_SECRET",
10870
+ "AI_PROVIDER_AUDIT_STORE_PATH",
10871
+ "AI_PROVIDER_CONNECT_TIMEOUT_MS",
10872
+ "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
10873
+ "OTEL_EXPORTER_OTLP_HEADERS"
10874
+ ];
10875
+ async function inspectPythonAgentRetirement(projectDirectory) {
10876
+ const path2 = join28(projectDirectory, ".env");
10877
+ try {
10878
+ const stat3 = await lstat8(path2);
10879
+ if (stat3.isSymbolicLink() || !stat3.isFile())
10880
+ return [
10881
+ {
10882
+ kind: "external-environment",
10883
+ path: ".env",
10884
+ message: "\u672A\u8BFB\u53D6\u5916\u90E8\u6258\u7BA1\u6216\u975E\u5E38\u89C4 .env\uFF1B\u8BF7\u6838\u5BF9\u65E7 Python Agent \u4E13\u7528\u914D\u7F6E\uFF0C\u4F7F\u7528\u65B0 DSH \u5B58\u50A8\u4E0E\u52A0\u5BC6\u914D\u7F6E\u3002"
10885
+ }
10886
+ ];
10887
+ const content = await readFile22(path2, "utf8");
10888
+ return retiredKeys.filter((key) => new RegExp(`^(?:export\\s+)?${key}\\s*=`, "m").test(content)).map((key) => ({
10889
+ kind: "environment-key",
10890
+ path: ".env",
10891
+ key,
10892
+ message: `${key} \u4E0D\u518D\u7531\u65B0 Agent Server \u8BFB\u53D6\uFF1B\u73AF\u5883\u4E0E\u65E7 Agent \u6570\u636E\u7531\u9879\u76EE\u6240\u6709\u8005\u5907\u4EFD\u540E\u4EBA\u5DE5\u6E05\u7406\uFF0C\u4E0D\u5F71\u54CD\u5176\u5B83\u670D\u52A1\u540C\u540D\u914D\u7F6E\u3002`
10893
+ }));
10894
+ } catch (error) {
10895
+ if (error instanceof Error && "code" in error && error.code === "ENOENT")
10896
+ return [];
10897
+ throw error;
10898
+ }
10899
+ }
10900
+
10584
10901
  // src/update/planner.ts
10585
- var metadataPaths = new Set([
10586
- ".windy/generation.json",
10587
- ".windy/files.json",
10588
- ".windy-template.json"
10589
- ]);
10590
10902
  var oxcManagedPaths = new Set([
10591
10903
  ".oxfmtrc.json",
10592
10904
  ".oxlintrc.json",
@@ -10594,8 +10906,8 @@ var oxcManagedPaths = new Set([
10594
10906
  ]);
10595
10907
  async function createUpdatePlan(request, artifacts, dependencies = {}) {
10596
10908
  await assertProjectReadyForUpdate(request.projectDirectory);
10597
- const manifestPath = join27(request.projectDirectory, ".windy/files.json");
10598
- const expectedManifestHash = hashContent(await readFile22(manifestPath));
10909
+ const manifestPath = join29(request.projectDirectory, ".windy/files.json");
10910
+ const expectedManifestHash = hashContent(await readFile23(manifestPath));
10599
10911
  const generationSnapshot = await readGenerationProvenanceSnapshot(request.projectDirectory);
10600
10912
  const provenance = generationSnapshot.provenance;
10601
10913
  const targetModules = resolveUpdateTargetModules(provenance.modules.map(({ name }) => name), request.targetModules);
@@ -10607,7 +10919,17 @@ async function createUpdatePlan(request, artifacts, dependencies = {}) {
10607
10919
  }
10608
10920
  const versionRecipes = (dependencies.resolveVersionRecipes ?? resolveRecipeChain)(provenance.windyVersion, targetVersion);
10609
10921
  const moduleRecipes = resolveModuleRecipeIds(request);
10610
- const recipes2 = [...versionRecipes.map(({ id }) => id), ...moduleRecipes];
10922
+ const migrateDshPlatform = await isDshPlatformTransition({
10923
+ baseDirectory: artifactSet.baseDirectory,
10924
+ targetDirectory: artifactSet.targetDirectory,
10925
+ sourceModules: provenance.modules.map(({ name }) => name),
10926
+ targetModules
10927
+ });
10928
+ const recipes2 = [
10929
+ ...versionRecipes.map(({ id }) => id),
10930
+ ...moduleRecipes,
10931
+ ...migrateDshPlatform ? [dshPlatformRecipeId] : []
10932
+ ];
10611
10933
  const recipeProjectOwnedPaths = recipeManagedProjectOwnedPaths(recipes2);
10612
10934
  const [rawSourceManifest, rawTargetManifest] = await Promise.all([
10613
10935
  readManagedFilesManifest(request.projectDirectory),
@@ -10642,8 +10964,10 @@ async function createUpdatePlan(request, artifacts, dependencies = {}) {
10642
10964
  const paths = new Set([...sourceEntries.keys(), ...targetEntries.keys()]);
10643
10965
  for (const path2 of paths) {
10644
10966
  if (!projectSnapshots.has(path2)) {
10645
- projectSnapshots.set(path2, await readOptional2(join27(request.projectDirectory, path2)));
10646
- projectModes.set(path2, await readModeOptional(join27(request.projectDirectory, path2)));
10967
+ projectSnapshots.set(path2, await readOptional(join29(request.projectDirectory, path2)));
10968
+ }
10969
+ if (!projectModes.has(path2)) {
10970
+ projectModes.set(path2, await readModeOptional(join29(request.projectDirectory, path2)));
10647
10971
  }
10648
10972
  }
10649
10973
  const files = await planFiles({
@@ -10656,7 +10980,8 @@ async function createUpdatePlan(request, artifacts, dependencies = {}) {
10656
10980
  provenance,
10657
10981
  manageGeneratedProjectOwned: request.targetModules !== undefined,
10658
10982
  forcePlatformBaseline: request.forcePlatformBaseline === true,
10659
- recipeProjectOwnedPaths
10983
+ recipeProjectOwnedPaths,
10984
+ migrateDshPlatform
10660
10985
  });
10661
10986
  preserveTestsForExistingProjectOwnedSources(files, sourceEntries);
10662
10987
  await deriveDockerfilePlans(files, projectSnapshots, new Set([
@@ -10667,10 +10992,10 @@ async function createUpdatePlan(request, artifacts, dependencies = {}) {
10667
10992
  for (const file of files) {
10668
10993
  file.expectedProjectMode = projectModes.get(file.path);
10669
10994
  if (file.action === "create" || file.action === "update") {
10670
- file.mode = file.expectedProjectMode ?? await readModeOptional(join27(artifactSet.targetDirectory, file.path));
10995
+ file.mode = file.expectedProjectMode ?? await readModeOptional(join29(artifactSet.targetDirectory, file.path));
10671
10996
  }
10672
10997
  if (file.action === "create") {
10673
- file.parentMode = await readSourceParentMode(join27(artifactSet.targetDirectory, dirname9(file.path)));
10998
+ file.parentMode = await readSourceParentMode(join29(artifactSet.targetDirectory, dirname9(file.path)));
10674
10999
  }
10675
11000
  }
10676
11001
  const plannedPaths = new Set(files.map(({ path: path2 }) => path2));
@@ -10690,8 +11015,11 @@ async function createUpdatePlan(request, artifacts, dependencies = {}) {
10690
11015
  ...migrations.conflicts,
10691
11016
  ...files.flatMap((file) => file.conflict ? [`${file.path}\uFF1A${file.conflict}`] : [])
10692
11017
  ];
10693
- const manualCleanup = await inspectAdkRetirement(request.projectDirectory);
10694
- if (hashContent(await readFile22(manifestPath)) !== expectedManifestHash) {
11018
+ const manualCleanup = [
11019
+ ...await inspectAdkRetirement(request.projectDirectory),
11020
+ ...migrateDshPlatform ? await inspectPythonAgentRetirement(request.projectDirectory) : []
11021
+ ];
11022
+ if (hashContent(await readFile23(manifestPath)) !== expectedManifestHash) {
10695
11023
  throw new Error("\u751F\u6210\u66F4\u65B0\u8BA1\u5212\u671F\u95F4\u53D7\u7BA1\u6E05\u5355\u53D1\u751F\u53D8\u5316");
10696
11024
  }
10697
11025
  await assertPlanSnapshots(request.projectDirectory, [
@@ -10724,24 +11052,6 @@ async function createUpdatePlan(request, artifacts, dependencies = {}) {
10724
11052
  lifecycle: request.lifecycle
10725
11053
  };
10726
11054
  }
10727
- async function planFiles(input) {
10728
- const files = [];
10729
- for (const path2 of [...input.paths].sort()) {
10730
- if (metadataPaths.has(path2))
10731
- continue;
10732
- const forcedContent = input.migrations.forceUpdates.has(path2) ? input.migrations.contentOverrides.get(path2) : undefined;
10733
- const ours = input.projectSnapshots.get(path2);
10734
- const expected = expectationForSnapshot(ours);
10735
- if (input.migrations.forcePreserves.has(path2)) {
10736
- files.push(readyPlannedFile(path2, input.sourceEntries.get(path2)?.ownership ?? classifyOwnership(path2), "preserve", "\u4FDD\u7559\u9879\u76EE\u5DF2\u53D1\u5E03 migration \u5386\u53F2", expected));
10737
- } else if (forcedContent) {
10738
- files.push(readyPlannedFile(path2, input.targetEntries.get(path2)?.ownership ?? input.sourceEntries.get(path2)?.ownership ?? classifyOwnership(path2), "update", "\u5408\u5E76\u5E73\u53F0\u4E0E\u4E0B\u6E38 migration \u5386\u53F2", expected, forcedContent));
10739
- } else {
10740
- files.push(await planFile(path2, input.artifactSet.baseDirectory, input.artifactSet.targetDirectory, input.sourceEntries.get(path2), input.targetEntries.get(path2), ours, input.provenance, input.migrations.contentOverrides.get(path2), input.manageGeneratedProjectOwned, input.forcePlatformBaseline, input.recipeProjectOwnedPaths.has(path2)));
10741
- }
10742
- }
10743
- return files;
10744
- }
10745
11055
  function createUpdateId(from, to) {
10746
11056
  return `${new Date().toISOString().replaceAll(/[:.]/g, "-")}-${from}-to-${to}`;
10747
11057
  }
@@ -10817,9 +11127,9 @@ function frozenManifestHash(file, finalizedHashes) {
10817
11127
  }
10818
11128
 
10819
11129
  // src/update/format-stabilizer.ts
10820
- import { mkdir as mkdir8, mkdtemp as mkdtemp3, readFile as readFile23, rm as rm7, writeFile as writeFile13 } from "fs/promises";
11130
+ import { mkdir as mkdir8, mkdtemp as mkdtemp3, readFile as readFile24, rm as rm7, writeFile as writeFile13 } from "fs/promises";
10821
11131
  import { tmpdir as tmpdir3 } from "os";
10822
- import { dirname as dirname10, extname as extname4, join as join28, resolve as resolve6, sep as sep5 } from "path";
11132
+ import { dirname as dirname10, extname as extname4, join as join30, resolve as resolve6, sep as sep5 } from "path";
10823
11133
  var formattedExtensions = new Set([
10824
11134
  ".cjs",
10825
11135
  ".css",
@@ -10858,7 +11168,7 @@ async function stabilizeManagedContent(result2, execute, writeProjectFile) {
10858
11168
  }
10859
11169
  }
10860
11170
  inputs.set(".windy/generation.json", new TextEncoder().encode(generationContent));
10861
- const temporaryRoot = await mkdtemp3(join28(tmpdir3(), "windy-update-format-"));
11171
+ const temporaryRoot = await mkdtemp3(join30(tmpdir3(), "windy-update-format-"));
10862
11172
  try {
10863
11173
  const stagedPaths = await stageInputs(temporaryRoot, inputs);
10864
11174
  for (let offset = 0;offset < stagedPaths.length; offset += 80) {
@@ -10866,14 +11176,14 @@ async function stabilizeManagedContent(result2, execute, writeProjectFile) {
10866
11176
  "x",
10867
11177
  "oxfmt",
10868
11178
  "--write",
10869
- `--config=${join28(result2.plan.projectDirectory, ".oxfmtrc.json")}`,
11179
+ `--config=${join30(result2.plan.projectDirectory, ".oxfmtrc.json")}`,
10870
11180
  ...stagedPaths.slice(offset, offset + 80)
10871
11181
  ], result2.plan.projectDirectory);
10872
11182
  }
10873
11183
  const hashes = plannedContentHashes(result2);
10874
11184
  let formattedGeneration = generationContent;
10875
11185
  for (const [path2, original] of inputs) {
10876
- const formatted = await readFile23(safeTemporaryPath(temporaryRoot, path2));
11186
+ const formatted = await readFile24(safeTemporaryPath(temporaryRoot, path2));
10877
11187
  if (path2 === ".windy/generation.json") {
10878
11188
  formattedGeneration = formatted.toString();
10879
11189
  continue;
@@ -10914,8 +11224,8 @@ function safeTemporaryPath(root, path2) {
10914
11224
  }
10915
11225
 
10916
11226
  // src/update/project-quality-verification.ts
10917
- import { readFile as readFile24 } from "fs/promises";
10918
- import { join as join29 } from "path";
11227
+ import { readFile as readFile25 } from "fs/promises";
11228
+ import { join as join31 } from "path";
10919
11229
  var qualityScriptNames = ["lint", "typecheck", "test", "build"];
10920
11230
  function skippedProjectQualityVerification() {
10921
11231
  return {
@@ -10929,7 +11239,7 @@ function skippedProjectQualityVerification() {
10929
11239
  };
10930
11240
  }
10931
11241
  async function runProjectQualityVerification(projectDirectory, execute) {
10932
- const packageJson = JSON.parse(await readFile24(join29(projectDirectory, "package.json"), "utf8"));
11242
+ const packageJson = JSON.parse(await readFile25(join31(projectDirectory, "package.json"), "utf8"));
10933
11243
  const steps = [];
10934
11244
  for (const name of qualityScriptNames) {
10935
11245
  const stepName = `bun run ${name}`;
@@ -11807,39 +12117,7 @@ async function runLifecycleCommand(args, dependencies = {}) {
11807
12117
  console.log("\u7528\u6CD5\uFF1Acreate-windy sync-docker [--cwd <project-directory>]");
11808
12118
  return true;
11809
12119
  }
11810
- const plans = await Promise.all(dockerfileCopyTargets.map((target) => planDockerfileInProject(projectDirectory, target, {
11811
- requireAnchors: true
11812
- }).then((result2) => ({ target, result: result2 }))));
11813
- if (plans.some(({ result: result2 }) => !result2.synced)) {
11814
- throw new Error("\u9879\u76EE\u7F3A\u5C11\u53D7\u652F\u6301\u7684 Dockerfile\uFF0C\u65E0\u6CD5\u540C\u6B65 COPY \u6E05\u5355");
11815
- }
11816
- const changed = plans.filter(({ result: result2 }) => result2.changed && result2.content !== undefined);
11817
- if (changed.length) {
11818
- const membershipExpectations = plans.flatMap(({ result: result2 }) => result2.membershipExpectations);
11819
- await assertWorkspaceMembership(projectDirectory, membershipExpectations);
11820
- const state = await applyMetadataTransaction({
11821
- id: `sync-docker-${Date.now()}`,
11822
- projectDirectory,
11823
- guards: plans.flatMap(({ result: result2 }) => result2.expectations),
11824
- writes: changed.map(({ target, result: result2 }) => ({
11825
- path: target.dockerfilePath,
11826
- content: result2.content
11827
- }))
11828
- });
11829
- await finalizeOwnedTransaction({
11830
- projectDirectory,
11831
- ownerToken: state.ownerToken,
11832
- expectations: changed.map(({ target, result: result2 }) => ({
11833
- path: target.dockerfilePath,
11834
- expected: {
11835
- kind: "hash",
11836
- value: hashContent(result2.content)
11837
- }
11838
- })),
11839
- workspaceMembershipExpectations: membershipExpectations
11840
- });
11841
- }
11842
- console.log(changed.length ? "\u5DF2\u540C\u6B65 Server \u4E0E Web Dockerfile workspace COPY \u6E05\u5355" : "Server \u4E0E Web Dockerfile workspace COPY \u6E05\u5355\u5DF2\u662F\u6700\u65B0");
12120
+ await synchronizeDockerfiles(projectDirectory);
11843
12121
  return true;
11844
12122
  }
11845
12123
  if (command === "doctor") {
@@ -12038,20 +12316,20 @@ import {
12038
12316
  cp,
12039
12317
  mkdir as mkdir9,
12040
12318
  mkdtemp as mkdtemp4,
12041
- readFile as readFile26,
12319
+ readFile as readFile27,
12042
12320
  readdir as readdir9,
12043
12321
  rename as rename2,
12044
12322
  rm as rm11,
12045
12323
  writeFile as writeFile14
12046
12324
  } from "fs/promises";
12047
- import { dirname as dirname11, join as join30, relative as relative7 } from "path";
12325
+ import { dirname as dirname11, join as join32, relative as relative7 } from "path";
12048
12326
 
12049
12327
  // src/module-schema/config.ts
12050
- import { readFile as readFile25 } from "fs/promises";
12328
+ import { readFile as readFile26 } from "fs/promises";
12051
12329
  import { isAbsolute as isAbsolute2, relative as relative6, resolve as resolve9 } from "path";
12052
12330
  async function readModuleSchemaLineageConfig(projectDirectory, configPath) {
12053
12331
  const absolutePath = resolveProjectPath(projectDirectory, configPath);
12054
- const parsed = JSON.parse(await readFile25(absolutePath, "utf8"));
12332
+ const parsed = JSON.parse(await readFile26(absolutePath, "utf8"));
12055
12333
  if (!isConfig(parsed)) {
12056
12334
  throw new Error("Module schema lineage \u914D\u7F6E\u65E0\u6548");
12057
12335
  }
@@ -12185,17 +12463,17 @@ async function handoffModuleSchemaLineages(options) {
12185
12463
  async function stageModuleLineages(project, temporaryRoot, config, execute) {
12186
12464
  const outputs = [];
12187
12465
  for (const [index, module2] of config.modules.entries()) {
12188
- const output = join30(temporaryRoot, `module-${index}`);
12466
+ const output = join32(temporaryRoot, `module-${index}`);
12189
12467
  await mkdir9(output, { recursive: true });
12190
- const generatedConfig = join30(temporaryRoot, `module-${index}.config.ts`);
12468
+ const generatedConfig = join32(temporaryRoot, `module-${index}.config.ts`);
12191
12469
  await writeDrizzleConfig(generatedConfig, project, module2.schema, relative7(temporaryRoot, output));
12192
12470
  await execute(generatedConfig, temporaryRoot);
12193
12471
  const sqlFiles = await listSqlFiles(output);
12194
12472
  if (sqlFiles.length !== 1) {
12195
12473
  throw new Error(`${module2.key} baseline \u5FC5\u987B\u6070\u597D\u751F\u6210\u4E00\u4E2A migration`);
12196
12474
  }
12197
- await writeFile14(join30(output, sqlFiles[0]), metadataOnlySql("module"));
12198
- await writeFile14(join30(output, "lineage.json"), `${JSON.stringify({
12475
+ await writeFile14(join32(output, sqlFiles[0]), metadataOnlySql("module"));
12476
+ await writeFile14(join32(output, "lineage.json"), `${JSON.stringify({
12199
12477
  schemaVersion: 1,
12200
12478
  moduleKey: module2.key,
12201
12479
  schema: module2.schema,
@@ -12209,25 +12487,25 @@ async function stageModuleLineages(project, temporaryRoot, config, execute) {
12209
12487
  }
12210
12488
  async function stagePlatformLineage(project, temporaryRoot, config, execute) {
12211
12489
  const source = resolveProjectPath(project, config.platform.out);
12212
- const output = join30(temporaryRoot, "platform");
12490
+ const output = join32(temporaryRoot, "platform");
12213
12491
  await cp(source, output, { recursive: true });
12214
12492
  const before = new Set(await listSqlFiles(output));
12215
- const generatedConfig = join30(temporaryRoot, "platform.config.ts");
12493
+ const generatedConfig = join32(temporaryRoot, "platform.config.ts");
12216
12494
  await writeDrizzleConfig(generatedConfig, project, config.platform.schema, relative7(temporaryRoot, output));
12217
12495
  await execute(generatedConfig, temporaryRoot);
12218
12496
  const created = (await listSqlFiles(output)).filter((path2) => !before.has(path2));
12219
12497
  if (created.length !== 1) {
12220
12498
  throw new Error("\u5E73\u53F0 lineage handoff \u5FC5\u987B\u6070\u597D\u751F\u6210\u4E00\u4E2A migration");
12221
12499
  }
12222
- const sqlPath = join30(output, created[0]);
12500
+ const sqlPath = join32(output, created[0]);
12223
12501
  const allowed = config.modules.flatMap(({ legacyPlatformTables }) => legacyPlatformTables);
12224
- validatePlatformHandoffSql(await readFile26(sqlPath, "utf8"), allowed);
12502
+ validatePlatformHandoffSql(await readFile27(sqlPath, "utf8"), allowed);
12225
12503
  await writeFile14(sqlPath, metadataOnlySql("platform"));
12226
12504
  return output;
12227
12505
  }
12228
12506
  async function installStagedLineages(project, temporaryRoot, config, stagedModules, stagedPlatform) {
12229
12507
  const platform = resolveProjectPath(project, config.platform.out);
12230
- const backup = join30(temporaryRoot, "platform-backup");
12508
+ const backup = join32(temporaryRoot, "platform-backup");
12231
12509
  const installed = [];
12232
12510
  await rename2(platform, backup);
12233
12511
  try {
@@ -12274,9 +12552,9 @@ async function validateSchemaSources(project, config) {
12274
12552
  }
12275
12553
  }
12276
12554
  async function createTemporaryRoot(project) {
12277
- const windy = join30(project, ".windy");
12555
+ const windy = join32(project, ".windy");
12278
12556
  await mkdir9(windy, { recursive: true });
12279
- return await mkdtemp4(join30(windy, "module-schema-handoff-"));
12557
+ return await mkdtemp4(join32(windy, "module-schema-handoff-"));
12280
12558
  }
12281
12559
  async function listSqlFiles(root) {
12282
12560
  return (await readdir9(root)).filter((path2) => path2.endsWith(".sql")).sort();
@@ -12324,7 +12602,7 @@ import { resolve as resolve14 } from "path";
12324
12602
 
12325
12603
  // src/package-configuration.ts
12326
12604
  import { createHash as createHash5 } from "crypto";
12327
- import { readFile as readFile27 } from "fs/promises";
12605
+ import { readFile as readFile28 } from "fs/promises";
12328
12606
  import { isAbsolute as isAbsolute3, normalize, relative as relative8, resolve as resolve11, sep as sep6 } from "path";
12329
12607
 
12330
12608
  // src/package-types.ts
@@ -12348,7 +12626,7 @@ async function readPackageConfiguration(projectDirectory) {
12348
12626
  const path2 = resolve11(projectDirectory, configurationFile);
12349
12627
  let source;
12350
12628
  try {
12351
- source = await readFile27(path2, "utf8");
12629
+ source = await readFile28(path2, "utf8");
12352
12630
  } catch (error) {
12353
12631
  if (error.code === "ENOENT") {
12354
12632
  throw new Error("\u672A\u58F0\u660E\u6253\u5305\u9002\u914D\u5668\uFF1A\u9879\u76EE\u6839\u76EE\u5F55\u7F3A\u5C11 windy.build.json", {
@@ -12679,7 +12957,7 @@ function failed(sourceRevision, diagnostic, artifacts2 = []) {
12679
12957
  }
12680
12958
 
12681
12959
  // src/package-plan.ts
12682
- import { readFile as readFile28, realpath as realpath3, writeFile as writeFile15 } from "fs/promises";
12960
+ import { readFile as readFile29, realpath as realpath3, writeFile as writeFile15 } from "fs/promises";
12683
12961
  import { dirname as dirname12, relative as relative10, resolve as resolve13 } from "path";
12684
12962
  function resolvePackageProfile(configuration, profileKey) {
12685
12963
  const profile = configuration.profiles.find(({ key }) => key === profileKey);
@@ -12759,7 +13037,7 @@ function assertFrozenPlanCurrent(input) {
12759
13037
  }
12760
13038
  async function readFrozenPackagePlan(path2) {
12761
13039
  try {
12762
- return parseFrozenPackagePlan(JSON.parse(await readFile28(path2, "utf8")));
13040
+ return parseFrozenPackagePlan(JSON.parse(await readFile29(path2, "utf8")));
12763
13041
  } catch (error) {
12764
13042
  if (error instanceof Error && error.message.startsWith("\u51BB\u7ED3\u6253\u5305\u8BA1\u5212"))
12765
13043
  throw error;