create-windy 0.4.0 → 0.5.0

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 (194) hide show
  1. package/dist/cli.js +263 -121
  2. package/package.json +1 -1
  3. package/template/.windy-template.json +2 -2
  4. package/template/apps/agent-server/adk_web_agents/canonical_debug/agent.py +29 -9
  5. package/template/apps/agent-server/adk_web_agents/services.py +25 -0
  6. package/template/apps/agent-server/src/southwind_agent_server/adk_adapter.py +40 -11
  7. package/template/apps/agent-server/src/southwind_agent_server/adk_debug_sessions.py +325 -0
  8. package/template/apps/agent-server/src/southwind_agent_server/adk_model.py +70 -6
  9. package/template/apps/agent-server/src/southwind_agent_server/adk_tools.py +1 -1
  10. package/template/apps/agent-server/src/southwind_agent_server/app.py +16 -4
  11. package/template/apps/agent-server/src/southwind_agent_server/approval_resolution.py +30 -0
  12. package/template/apps/agent-server/src/southwind_agent_server/contracts.py +9 -0
  13. package/template/apps/agent-server/src/southwind_agent_server/deterministic.py +2 -1
  14. package/template/apps/agent-server/src/southwind_agent_server/engine.py +3 -1
  15. package/template/apps/agent-server/src/southwind_agent_server/openai_engine.py +95 -130
  16. package/template/apps/agent-server/src/southwind_agent_server/openai_engine_validation.py +133 -0
  17. package/template/apps/agent-server/src/southwind_agent_server/openai_provider.py +89 -20
  18. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_insert.py +34 -0
  19. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_queries.py +234 -0
  20. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_replay.py +44 -0
  21. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_status.py +83 -0
  22. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_store.py +331 -0
  23. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_summary.py +304 -0
  24. package/template/apps/agent-server/src/southwind_agent_server/report_lifecycle.py +217 -0
  25. package/template/apps/agent-server/src/southwind_agent_server/report_metrics.py +149 -0
  26. package/template/apps/agent-server/src/southwind_agent_server/report_presenter.py +280 -0
  27. package/template/apps/agent-server/src/southwind_agent_server/report_routes.py +126 -0
  28. package/template/apps/agent-server/src/southwind_agent_server/report_store.py +344 -0
  29. package/template/apps/agent-server/src/southwind_agent_server/report_types.py +111 -0
  30. package/template/apps/agent-server/src/southwind_agent_server/runtime_factory.py +31 -2
  31. package/template/apps/agent-server/src/southwind_agent_server/service.py +56 -51
  32. package/template/apps/agent-server/src/southwind_agent_server/signal_events.py +18 -1
  33. package/template/apps/agent-server/tests/test_adk_adapter.py +7 -9
  34. package/template/apps/agent-server/tests/test_adk_debug_sessions.py +215 -0
  35. package/template/apps/agent-server/tests/test_adk_web_canonical_debug.py +48 -1
  36. package/template/apps/agent-server/tests/test_openai_provider.py +58 -6
  37. package/template/apps/agent-server/tests/test_postgres_report_status.py +59 -0
  38. package/template/apps/agent-server/tests/test_postgres_report_summary.py +298 -0
  39. package/template/apps/agent-server/tests/test_provider_attempt_reporting.py +152 -0
  40. package/template/apps/agent-server/tests/test_report_attempt_lifecycle.py +126 -0
  41. package/template/apps/agent-server/tests/test_report_resilience.py +181 -0
  42. package/template/apps/agent-server/tests/test_report_store.py +286 -0
  43. package/template/apps/agent-server/tests/test_report_summary_parity.py +115 -0
  44. package/template/apps/agent-server/tests/test_report_terminal_sync.py +177 -0
  45. package/template/apps/server/src/agent/debug-session-facade-provider-failure.test.ts +269 -0
  46. package/template/apps/server/src/agent/debug-session-facade.test.ts +335 -0
  47. package/template/apps/server/src/agent/debug-session-facade.ts +302 -0
  48. package/template/apps/server/src/agent/debug-session-id.test.ts +37 -0
  49. package/template/apps/server/src/agent/debug-session-id.ts +37 -0
  50. package/template/apps/server/src/agent/debug-session-provider-reader.ts +54 -0
  51. package/template/apps/server/src/agent/debug-session-routes.test.ts +64 -0
  52. package/template/apps/server/src/agent/debug-session-routes.ts +73 -0
  53. package/template/apps/server/src/agent/debug-session-validation.ts +106 -0
  54. package/template/apps/server/src/agent/drizzle-run-binding-repository.ts +2 -0
  55. package/template/apps/server/src/agent/provider-input-governance.test.ts +18 -0
  56. package/template/apps/server/src/agent/provider-input-governance.ts +37 -1
  57. package/template/apps/server/src/agent/remote-runtime.test.ts +7 -0
  58. package/template/apps/server/src/agent/remote-runtime.ts +1 -0
  59. package/template/apps/server/src/agent/run-authorization.test.ts +98 -0
  60. package/template/apps/server/src/agent/run-authorization.ts +32 -1
  61. package/template/apps/server/src/agent/run-binding-repository.ts +1 -0
  62. package/template/apps/server/src/agent/run-contracts.ts +5 -0
  63. package/template/apps/server/src/agent/run-facade-adk-debug.test.ts +39 -0
  64. package/template/apps/server/src/agent/run-facade.test.ts +78 -0
  65. package/template/apps/server/src/agent/run-facade.ts +33 -3
  66. package/template/apps/server/src/agent/run-input-commitment.ts +50 -0
  67. package/template/apps/server/src/agent/run-input-verification.ts +41 -0
  68. package/template/apps/server/src/agent/runtime-bootstrap-report.test.ts +136 -0
  69. package/template/apps/server/src/agent/runtime-bootstrap.ts +66 -1
  70. package/template/apps/server/src/agent/tool-host.test.ts +1 -0
  71. package/template/apps/server/src/agent/unavailable-routes.ts +4 -0
  72. package/template/apps/server/src/ai-runtime-report/actor-directory.ts +94 -0
  73. package/template/apps/server/src/ai-runtime-report/actor-handle.test.ts +27 -0
  74. package/template/apps/server/src/ai-runtime-report/actor-handle.ts +81 -0
  75. package/template/apps/server/src/ai-runtime-report/contracts.ts +91 -0
  76. package/template/apps/server/src/ai-runtime-report/remote-parser.ts +212 -0
  77. package/template/apps/server/src/ai-runtime-report/remote-port.ts +138 -0
  78. package/template/apps/server/src/ai-runtime-report/routes.ts +172 -0
  79. package/template/apps/server/src/ai-runtime-report/scope.ts +63 -0
  80. package/template/apps/server/src/ai-runtime-report/service.test.ts +271 -0
  81. package/template/apps/server/src/ai-runtime-report/service.ts +206 -0
  82. package/template/apps/server/src/license/runtime-audit-reliability.test.ts +2 -0
  83. package/template/apps/server/src/license/runtime-service.test.ts +6 -0
  84. package/template/apps/server/src/module-host/ai-operation-port.test.ts +63 -0
  85. package/template/apps/server/src/module-host/ai-operation-port.ts +30 -5
  86. package/template/apps/server/src/module-host/debug-session-provider-registration.test.ts +162 -0
  87. package/template/apps/server/src/module-host/debug-session-provider-registration.ts +84 -0
  88. package/template/apps/server/src/module-host/initialize-contracts.ts +7 -0
  89. package/template/apps/server/src/module-host/initialize.ts +6 -197
  90. package/template/apps/server/src/module-host/request-context.ts +1 -0
  91. package/template/apps/server/src/module-host/scoped-host.ts +214 -0
  92. package/template/apps/server/src/module-host.ts +1 -0
  93. package/template/apps/server/src/runtime-adk-debug.test.ts +25 -1
  94. package/template/apps/server/src/runtime-adk-debug.ts +8 -2
  95. package/template/apps/server/src/settings/drizzle-watermark-repository.integration.test.ts +4 -0
  96. package/template/apps/server/src/settings/drizzle-watermark-repository.ts +11 -3
  97. package/template/apps/server/src/settings/watermark-routes.test.ts +54 -1
  98. package/template/apps/server/src/settings/watermark-routes.ts +29 -1
  99. package/template/apps/server/src/system/operations.test.ts +54 -0
  100. package/template/apps/server/src/system/operations.ts +23 -1
  101. package/template/apps/server/src/system/seed.test.ts +4 -0
  102. package/template/apps/server/src/system/system-resource-monitoring.test.ts +82 -0
  103. package/template/apps/server/src/system/system-resource-monitoring.ts +300 -0
  104. package/template/apps/web/src/composables/useWatermarkSettings.webtest.ts +14 -0
  105. package/template/apps/web/src/composables/watermark-settings.ts +40 -11
  106. package/template/apps/web/src/composables/watermark-settings.webtest.ts +19 -6
  107. package/template/apps/web/src/layout/AppSidebar.vue +6 -1
  108. package/template/apps/web/src/layout/AppSidebar.webtest.ts +2 -0
  109. package/template/apps/web/src/layout/GlobalWatermark.layering.webtest.ts +2 -0
  110. package/template/apps/web/src/layout/GlobalWatermark.vue +4 -8
  111. package/template/apps/web/src/layout/GlobalWatermark.webtest.ts +12 -5
  112. package/template/apps/web/src/pages/auth/LoginPage.vue +6 -1
  113. package/template/apps/web/src/pages/settings/BrandingSettingsSection.vue +20 -3
  114. package/template/apps/web/src/pages/settings/BrandingSettingsSection.webtest.ts +80 -0
  115. package/template/apps/web/src/pages/settings/WatermarkPreview.vue +72 -0
  116. package/template/apps/web/src/pages/settings/WatermarkPreview.webtest.ts +55 -0
  117. package/template/apps/web/src/pages/settings/WatermarkSettingsSection.vue +80 -24
  118. package/template/apps/web/src/pages/settings/WatermarkSettingsSection.webtest.ts +115 -0
  119. package/template/apps/web/src/pages/system/AiRuntimePage.vue +129 -0
  120. package/template/apps/web/src/pages/system/SystemOperationsPage.vue +2 -1
  121. package/template/apps/web/src/pages/system/ai-runtime-presenter.ts +60 -0
  122. package/template/apps/web/src/pages/system/ai-runtime-presenter.webtest.ts +48 -0
  123. package/template/apps/web/src/pages/system/audit-time-range.ts +34 -2
  124. package/template/apps/web/src/pages/system/components/AuditLogFilters.vue +4 -3
  125. package/template/apps/web/src/pages/system/components/AuditLogFilters.webtest.ts +26 -1
  126. package/template/apps/web/src/pages/system/components/OperationGpuMonitor.vue +98 -0
  127. package/template/apps/web/src/pages/system/components/OperationGpuMonitor.webtest.ts +61 -0
  128. package/template/apps/web/src/pages/system/components/OperationServiceMonitor.vue +53 -0
  129. package/template/apps/web/src/pages/system/components/OperationServiceMonitor.webtest.ts +20 -1
  130. package/template/apps/web/src/pages/system/components/SystemResourcePage.webtest.ts +14 -1
  131. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeActivityChart.vue +85 -0
  132. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeCharts.webtest.ts +82 -0
  133. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeFilters.vue +98 -0
  134. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeFilters.webtest.ts +27 -0
  135. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeRunDetailDialog.vue +168 -0
  136. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeRunTable.vue +130 -0
  137. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeSummaryCards.vue +82 -0
  138. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeSummaryCards.webtest.ts +102 -0
  139. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeTokenByModelChart.vue +101 -0
  140. package/template/apps/web/src/pages/system/composables/useAiRuntimeReport.ts +185 -0
  141. package/template/apps/web/src/pages/system/composables/useAiRuntimeReport.webtest.ts +158 -0
  142. package/template/apps/web/src/pages/system/composables/useSystemResource.ts +21 -7
  143. package/template/apps/web/src/router/error-navigation.ts +22 -0
  144. package/template/apps/web/src/router/index.ts +12 -23
  145. package/template/apps/web/src/router/platform-admin-route-bindings.ts +4 -0
  146. package/template/apps/web/src/services/ai-runtime-api.ts +164 -0
  147. package/template/apps/web/src/services/ai-runtime-api.webtest.ts +111 -0
  148. package/template/apps/web/src/services/operations-api.ts +28 -0
  149. package/template/docker-compose.agent-debug.yml +1 -1
  150. package/template/docs/architecture/ai-runtime.md +2 -1
  151. package/template/docs/architecture/module-host.md +3 -0
  152. package/template/docs/platform/agent-run-attestation.md +65 -0
  153. package/template/docs/platform/agent-runtime-observability.md +135 -0
  154. package/template/docs/platform/agent-runtime.md +47 -3
  155. package/template/docs/platform/operations-overview.md +13 -0
  156. package/template/docs/platform/platform-authentication.md +4 -3
  157. package/template/docs/platform/platform-shell-settings.md +15 -10
  158. package/template/docs/platform/web-system-crud.md +1 -1
  159. package/template/packages/config/package.json +1 -1
  160. package/template/packages/database/drizzle/0044_sweet_tarantula.sql +6 -0
  161. package/template/packages/database/drizzle/0045_tiny_cassandra_nova.sql +65 -0
  162. package/template/packages/database/drizzle/0046_tranquil_living_mummy.sql +6 -0
  163. package/template/packages/database/drizzle/0047_oval_luke_cage.sql +18 -0
  164. package/template/packages/database/drizzle/meta/0044_snapshot.json +8349 -0
  165. package/template/packages/database/drizzle/meta/0045_snapshot.json +8814 -0
  166. package/template/packages/database/drizzle/meta/0046_snapshot.json +8820 -0
  167. package/template/packages/database/drizzle/meta/0047_snapshot.json +8835 -0
  168. package/template/packages/database/drizzle/meta/_journal.json +28 -0
  169. package/template/packages/database/package.json +1 -1
  170. package/template/packages/database/src/agent-runtime-schema.test.ts +54 -0
  171. package/template/packages/database/src/schema/agent-runtime.ts +114 -0
  172. package/template/packages/database/src/schema/platform-settings.ts +3 -0
  173. package/template/packages/jobs/package.json +1 -1
  174. package/template/packages/modules/package.json +1 -1
  175. package/template/packages/modules/src/system-admin-routes.ts +10 -0
  176. package/template/packages/modules/src/system-admin-ui-catalog.ts +1 -1
  177. package/template/packages/modules/src/system-api-control-plane.ts +17 -1
  178. package/template/packages/modules/src/system-audit-actions.ts +10 -0
  179. package/template/packages/modules/src/system-features.ts +8 -0
  180. package/template/packages/modules/src/system-module-catalog.test.ts +35 -0
  181. package/template/packages/modules/src/system-module-catalog.ts +15 -4
  182. package/template/packages/modules/src/system-modules-access.test.ts +69 -0
  183. package/template/packages/modules/src/system-modules.ts +13 -0
  184. package/template/packages/modules/src/system-permissions.ts +2 -0
  185. package/template/packages/server-sdk/index.ts +11 -0
  186. package/template/packages/server-sdk/package.json +2 -1
  187. package/template/packages/server-sdk/src/ai-operation-port.ts +5 -0
  188. package/template/packages/server-sdk/src/debug-session-provider.ts +63 -0
  189. package/template/packages/server-sdk/src/module-host.ts +5 -0
  190. package/template/packages/shared/index.ts +3 -0
  191. package/template/packages/shared/package.json +1 -1
  192. package/template/packages/shared/src/ai-runtime-report.ts +134 -0
  193. package/template/packages/shared/src/platform-settings.ts +17 -0
  194. package/template/scripts/lib/postgres-regression.ts +201 -0
package/dist/cli.js CHANGED
@@ -286,6 +286,7 @@ var optionalModuleManifests = [
286
286
  "apps/speech-server",
287
287
  "apps/embedding-server",
288
288
  "apps/server/src/agent",
289
+ "apps/server/src/ai-runtime-report",
289
290
  "apps/server/src/ai-artifact",
290
291
  "apps/server/src/document",
291
292
  "apps/server/src/speech",
@@ -293,17 +294,30 @@ var optionalModuleManifests = [
293
294
  "apps/server/src/mcp",
294
295
  "apps/server/src/runtime-adk-debug.ts",
295
296
  "apps/server/src/runtime-adk-debug.test.ts",
297
+ "apps/server/src/module-host/ai-operation-port.ts",
298
+ "apps/server/src/module-host/ai-operation-port.test.ts",
296
299
  "apps/server/src/module-host/tool-handlers.ts",
297
300
  "apps/server/src/module-host/tool-handlers.test.ts",
301
+ "apps/web/src/pages/system/AiRuntimePage.vue",
302
+ "apps/web/src/pages/system/ai-runtime-presenter.ts",
303
+ "apps/web/src/pages/system/ai-runtime-presenter.webtest.ts",
304
+ "apps/web/src/pages/system/components/ai-runtime",
305
+ "apps/web/src/pages/system/composables/useAiRuntimeReport.ts",
306
+ "apps/web/src/pages/system/composables/useAiRuntimeReport.webtest.ts",
307
+ "apps/web/src/services/ai-runtime-api.ts",
308
+ "apps/web/src/services/ai-runtime-api.webtest.ts",
298
309
  "docker-compose.agent-debug.yml",
299
310
  "scripts/dev-adk-web.ts",
300
311
  "packages/modules/src/system-agent-tools.ts",
301
- "packages/database/src/agent-runtime-schema.test.ts"
312
+ "packages/database/src/agent-runtime-schema.test.ts",
313
+ "packages/shared/src/ai-runtime-report.ts"
302
314
  ],
303
315
  documentation: [
304
316
  "docs/architecture/ai-runtime.md",
305
317
  "docs/architecture/mcp-business-capabilities.md",
318
+ "docs/platform/agent-run-attestation.md",
306
319
  "docs/platform/agent-runtime.md",
320
+ "docs/platform/agent-runtime-observability.md",
307
321
  "docs/platform/agent-tools.md",
308
322
  "docs/platform/agent-tool-approval.md",
309
323
  "docs/platform/agent-tool-sandbox.md",
@@ -320,7 +334,9 @@ var optionalModuleManifests = [
320
334
  "agent_runtime_runs",
321
335
  "agent_runtime_events",
322
336
  "agent_evaluation_results",
323
- "agent_run_bindings"
337
+ "agent_run_bindings",
338
+ "agent_runtime_report_runs",
339
+ "agent_runtime_report_attempts"
324
340
  ]
325
341
  },
326
342
  {
@@ -400,6 +416,7 @@ var optionalModuleManifests = [
400
416
  "apps/web/src/pages/system/composables/useNotificationPermissions.ts",
401
417
  "apps/web/src/services/notification-api.webtest.ts",
402
418
  "scripts/notification-postgres-regression.ts",
419
+ "scripts/lib/postgres-regression.ts",
403
420
  "packages/database/src/schema-notification-delivery.test.ts"
404
421
  ],
405
422
  documentation: ["docs/platform/notifications.md"],
@@ -520,7 +537,7 @@ function module(name, label, description, dependencies) {
520
537
  return {
521
538
  name,
522
539
  version: "0.1.0",
523
- windyRange: "^0.4.0",
540
+ windyRange: "^0.5.0",
524
541
  label,
525
542
  description,
526
543
  selection,
@@ -679,10 +696,14 @@ var platformModules = [
679
696
  "apps/server/src/system/operations.ts",
680
697
  "apps/server/src/system/operations.test.ts",
681
698
  "apps/server/src/system/postgres-monitoring.ts",
699
+ "apps/server/src/system/system-resource-monitoring.ts",
700
+ "apps/server/src/system/system-resource-monitoring.test.ts",
682
701
  "apps/web/src/pages/system/SystemOperationsPage.vue",
683
702
  "apps/web/src/pages/system/SystemOperationsPage.webtest.ts",
684
703
  "apps/web/src/pages/system/components/OperationCacheMonitor.vue",
685
704
  "apps/web/src/pages/system/components/DiskUsageChart.vue",
705
+ "apps/web/src/pages/system/components/OperationGpuMonitor.vue",
706
+ "apps/web/src/pages/system/components/OperationGpuMonitor.webtest.ts",
686
707
  "apps/web/src/pages/system/components/OperationOnlineUsers.vue",
687
708
  "apps/web/src/pages/system/components/OperationOnlineUsers.webtest.ts",
688
709
  "apps/web/src/pages/system/components/OperationServiceMonitor.vue",
@@ -748,7 +769,7 @@ function module2(name, label, description, selection, dependencies = []) {
748
769
  return {
749
770
  name,
750
771
  version: "0.1.0",
751
- windyRange: "^0.4.0",
772
+ windyRange: "^0.5.0",
752
773
  label,
753
774
  description,
754
775
  selection,
@@ -3445,6 +3466,7 @@ var templateRootFiles = [
3445
3466
  "module-schema.lineages.json",
3446
3467
  "package.json",
3447
3468
  "scripts/notification-postgres-regression.ts",
3469
+ "scripts/lib/postgres-regression.ts",
3448
3470
  "scripts/dev-adk-web.ts"
3449
3471
  ];
3450
3472
  var templateDirectories = [
@@ -3491,8 +3513,10 @@ var templateDocumentationFiles = [
3491
3513
  "docs/development/module-lifecycle.md",
3492
3514
  "docs/license/license-offline-activation-code.md",
3493
3515
  "docs/operations/observability.md",
3516
+ "docs/platform/agent-run-attestation.md",
3494
3517
  "docs/platform/agent-tools.md",
3495
3518
  "docs/platform/agent-runtime.md",
3519
+ "docs/platform/agent-runtime-observability.md",
3496
3520
  "docs/platform/agent-tool-sandbox.md",
3497
3521
  "docs/platform/audit-reliability.md",
3498
3522
  "docs/platform/bulk-data-jobs.md",
@@ -7524,6 +7548,16 @@ var recipes = [
7524
7548
  id: "starter-0.3.19-to-0.4.0",
7525
7549
  from: "0.3.19",
7526
7550
  to: "0.4.0"
7551
+ },
7552
+ {
7553
+ id: "starter-0.4.0-to-0.4.1",
7554
+ from: "0.4.0",
7555
+ to: "0.4.1"
7556
+ },
7557
+ {
7558
+ id: "starter-0.4.1-to-0.5.0",
7559
+ from: "0.4.1",
7560
+ to: "0.5.0"
7527
7561
  }
7528
7562
  ];
7529
7563
  function resolveRecipeChain(sourceVersion, targetVersion) {
@@ -7569,8 +7603,8 @@ function parseVersion2(version) {
7569
7603
  }
7570
7604
 
7571
7605
  // src/update/updater.ts
7572
- import { readFile as readFile21, rm as rm8 } from "fs/promises";
7573
- import { join as join26 } from "path";
7606
+ import { readFile as readFile23, rm as rm8 } from "fs/promises";
7607
+ import { join as join27 } from "path";
7574
7608
 
7575
7609
  // src/update/artifacts.ts
7576
7610
  import { mkdtemp, readFile as readFile14 } from "fs/promises";
@@ -7931,8 +7965,8 @@ async function readProjectName2(projectDirectory) {
7931
7965
  }
7932
7966
 
7933
7967
  // src/update/planner.ts
7934
- import { readFile as readFile19 } from "fs/promises";
7935
- import { dirname as dirname7, join as join24 } from "path";
7968
+ import { readFile as readFile21 } from "fs/promises";
7969
+ import { dirname as dirname7, join as join25 } from "path";
7936
7970
 
7937
7971
  // src/update/docker-copy-update-plan.ts
7938
7972
  async function deriveDockerfilePlans(files, snapshots, paths, targetWorkspaceManifests) {
@@ -8020,7 +8054,11 @@ function matchesWorkspace(pattern, directory) {
8020
8054
  }
8021
8055
 
8022
8056
  // src/update/migration-reconciler.ts
8023
- import { readFile as readFile16 } from "fs/promises";
8057
+ import { readFile as readFile18 } from "fs/promises";
8058
+ import { join as join21 } from "path";
8059
+
8060
+ // src/update/migration-adoption.ts
8061
+ import { readFile as readFile17 } from "fs/promises";
8024
8062
  import { join as join20 } from "path";
8025
8063
 
8026
8064
  // src/update/migration-project-file.ts
@@ -8055,6 +8093,60 @@ function isMissingFileError(error) {
8055
8093
  return error instanceof Error && "code" in error && error.code === "ENOENT";
8056
8094
  }
8057
8095
 
8096
+ // src/update/migration-history.ts
8097
+ import { readFile as readFile16 } from "fs/promises";
8098
+ var drizzleRoot = "packages/database/drizzle";
8099
+ var journalPath = `${drizzleRoot}/meta/_journal.json`;
8100
+ var migrationPattern = /^(\d{4})_(.+)$/;
8101
+ function snapshotPath(tag) {
8102
+ const match = migrationPattern.exec(tag);
8103
+ if (!match) {
8104
+ throw new Error(`${journalPath}\uFF1Amigration tag \u683C\u5F0F\u65E0\u6548\uFF1A${tag}`);
8105
+ }
8106
+ return `${drizzleRoot}/meta/${match[1]}_snapshot.json`;
8107
+ }
8108
+ function validateUniqueNames(journal, label, conflicts) {
8109
+ const seen = new Set;
8110
+ for (const { tag } of journal.entries) {
8111
+ const name = stableName(tag);
8112
+ if (seen.has(name)) {
8113
+ conflicts.push(`${journalPath}\uFF1A${label}\u5B58\u5728\u91CD\u590D migration \u540D\u79F0 ${name}`);
8114
+ }
8115
+ seen.add(name);
8116
+ }
8117
+ }
8118
+ function stableName(tag) {
8119
+ return migrationPattern.exec(tag)?.[2] ?? tag;
8120
+ }
8121
+ function highestPrefix(journal) {
8122
+ return Math.max(-1, ...journal.entries.map(({ tag }) => Number(migrationPattern.exec(tag)?.[1] ?? -1)));
8123
+ }
8124
+ function highestIndex(journal) {
8125
+ return Math.max(-1, ...journal.entries.map(({ idx }) => idx));
8126
+ }
8127
+ function isDrizzleHistoryPath(path2) {
8128
+ return path2 === journalPath || isMigrationArtifact(path2);
8129
+ }
8130
+ function isMigrationArtifact(path2) {
8131
+ return isSqlMigration(path2) || new RegExp(`^${drizzleRoot}/meta/\\d{4}_snapshot\\.json$`).test(path2);
8132
+ }
8133
+ function isSqlMigration(path2) {
8134
+ return new RegExp(`^${drizzleRoot}/\\d{4}_.+\\.sql$`).test(path2);
8135
+ }
8136
+ function managedEntry(path2, content) {
8137
+ return { path: path2, ownership: "windy-managed", hash: hashContent(content) };
8138
+ }
8139
+ function deduplicate(files) {
8140
+ return [...new Map(files.map((entry) => [entry.path, entry])).values()];
8141
+ }
8142
+ function encodeJson(value) {
8143
+ return new TextEncoder().encode(`${JSON.stringify(value, null, 2)}
8144
+ `);
8145
+ }
8146
+ async function readJson(path2) {
8147
+ return JSON.parse(await readFile16(path2, "utf8"));
8148
+ }
8149
+
8058
8150
  // src/update/snapshot-delta.ts
8059
8151
  function applySnapshotDelta(before, after, current, path2, conflicts, conflictPath) {
8060
8152
  if (deepEqual(before, after))
@@ -8100,10 +8192,99 @@ function deepEqual(left, right) {
8100
8192
  return JSON.stringify(left) === JSON.stringify(right);
8101
8193
  }
8102
8194
 
8195
+ // src/update/migration-adoption.ts
8196
+ async function inspectPreexistingMigrationAdoptions(input) {
8197
+ const conflicts = [];
8198
+ const adoptions = [];
8199
+ const projectByName = new Map(input.project.entries.map((entry) => [stableName(entry.tag), entry]));
8200
+ for (const candidate of input.candidates) {
8201
+ const name = stableName(candidate.tag);
8202
+ const projectEntry = projectByName.get(name);
8203
+ if (!projectEntry || input.managedNames.has(name))
8204
+ continue;
8205
+ const targetPosition = input.target.entries.indexOf(candidate);
8206
+ const projectPosition = input.project.entries.indexOf(projectEntry);
8207
+ const previousTarget = input.target.entries[targetPosition - 1];
8208
+ const previousProject = input.project.entries[projectPosition - 1];
8209
+ if (!previousTarget || !previousProject) {
8210
+ conflicts.push(`${journalPath}\uFF1A\u65E0\u6CD5\u91C7\u7EB3\u73B0\u6709\u5E73\u53F0 migration ${name}\uFF0C\u7F3A\u5C11\u524D\u7F6E\u5386\u53F2`);
8211
+ continue;
8212
+ }
8213
+ const projectSqlPath = `${drizzleRoot}/${projectEntry.tag}.sql`;
8214
+ const projectSnapshotPath = snapshotPath(projectEntry.tag);
8215
+ const [
8216
+ targetSql,
8217
+ projectSql,
8218
+ targetBefore,
8219
+ targetAfter,
8220
+ projectBeforeBytes,
8221
+ projectAfterBytes
8222
+ ] = await Promise.all([
8223
+ readFile17(join20(input.targetDirectory, `${drizzleRoot}/${candidate.tag}.sql`)),
8224
+ readProjectFile(input, projectSqlPath),
8225
+ readJson(join20(input.targetDirectory, snapshotPath(previousTarget.tag))),
8226
+ readJson(join20(input.targetDirectory, snapshotPath(candidate.tag))),
8227
+ readProjectFile(input, snapshotPath(previousProject.tag)),
8228
+ readProjectFile(input, projectSnapshotPath)
8229
+ ]);
8230
+ if (!projectSql || !projectBeforeBytes || !projectAfterBytes) {
8231
+ conflicts.push(`${journalPath}\uFF1A\u65E0\u6CD5\u91C7\u7EB3\u73B0\u6709\u5E73\u53F0 migration ${name}\uFF0C\u9879\u76EE migration \u6587\u4EF6\u4E0D\u5B8C\u6574`);
8232
+ continue;
8233
+ }
8234
+ const projectBefore = decodeSnapshot(projectBeforeBytes);
8235
+ const projectAfter = decodeSnapshot(projectAfterBytes);
8236
+ const reason = validateAdoption({
8237
+ targetSql,
8238
+ projectSql,
8239
+ targetBefore,
8240
+ targetAfter,
8241
+ projectBefore,
8242
+ projectAfter
8243
+ });
8244
+ if (reason) {
8245
+ conflicts.push(`${journalPath}\uFF1A\u65E0\u6CD5\u91C7\u7EB3\u73B0\u6709\u5E73\u53F0 migration ${name}\uFF0C${reason}`);
8246
+ continue;
8247
+ }
8248
+ adoptions.push({
8249
+ sqlPath: projectSqlPath,
8250
+ snapshotPath: projectSnapshotPath,
8251
+ sql: projectSql,
8252
+ snapshot: projectAfterBytes
8253
+ });
8254
+ }
8255
+ return { adoptions, conflicts };
8256
+ }
8257
+ function validateAdoption(input) {
8258
+ if (!equalBytes(input.targetSql, input.projectSql)) {
8259
+ return "SQL \u5185\u5BB9\u4E0D\u4E00\u81F4";
8260
+ }
8261
+ if (input.projectAfter.prevId !== input.projectBefore.id) {
8262
+ return "\u9879\u76EE snapshot lineage \u4E0D\u8FDE\u7EED";
8263
+ }
8264
+ const deltaConflicts = [];
8265
+ const expected = applySnapshotDelta(input.targetBefore, input.targetAfter, input.projectBefore, [], deltaConflicts, journalPath);
8266
+ if (deltaConflicts.length || canonicalSnapshot(expected) !== canonicalSnapshot(input.projectAfter)) {
8267
+ return "snapshot delta \u4E0E\u9879\u76EE\u5386\u53F2\u4E0D\u4E00\u81F4";
8268
+ }
8269
+ }
8270
+ function decodeSnapshot(content) {
8271
+ return JSON.parse(new TextDecoder().decode(content));
8272
+ }
8273
+ function equalBytes(left, right) {
8274
+ return left.byteLength === right.byteLength && left.every((value, index) => value === right[index]);
8275
+ }
8276
+ function canonicalSnapshot(value) {
8277
+ return JSON.stringify(canonicalize(value, true));
8278
+ }
8279
+ function canonicalize(value, root = false) {
8280
+ if (Array.isArray(value))
8281
+ return value.map((item) => canonicalize(item));
8282
+ if (!value || typeof value !== "object")
8283
+ return value;
8284
+ return Object.fromEntries(Object.entries(value).filter(([key]) => !root || key !== "id" && key !== "prevId").sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => [key, canonicalize(item)]));
8285
+ }
8286
+
8103
8287
  // src/update/migration-reconciler.ts
8104
- var drizzleRoot = "packages/database/drizzle";
8105
- var journalPath = `${drizzleRoot}/meta/_journal.json`;
8106
- var migrationPattern = /^(\d{4})_(.+)$/;
8107
8288
  async function reconcileDrizzleMigrations(input) {
8108
8289
  const journals = await readJournals(input);
8109
8290
  if (!journals) {
@@ -8121,16 +8302,25 @@ async function reconcileDrizzleMigrations(input) {
8121
8302
  const projectNames = new Set(project.entries.map(({ tag }) => stableName(tag)));
8122
8303
  const managedNames = new Set(input.sourceManifest.files.filter(({ path: path2 }) => isSqlMigration(path2)).map(({ path: path2 }) => stableName(path2.slice(drizzleRoot.length + 1, -4))));
8123
8304
  const candidates = target.entries.filter(({ tag }) => !baseNames.has(stableName(tag)));
8124
- for (const { tag } of candidates) {
8125
- const name = stableName(tag);
8126
- if (projectNames.has(name) && !managedNames.has(name)) {
8127
- conflicts.push(`${journalPath}\uFF1A\u5E73\u53F0 migration \u540D\u79F0\u4E0E\u4E0B\u6E38\u4E1A\u52A1\u5386\u53F2\u51B2\u7A81 ${name}`);
8128
- }
8129
- }
8305
+ const adoption = await inspectPreexistingMigrationAdoptions({
8306
+ ...input,
8307
+ project,
8308
+ target,
8309
+ candidates,
8310
+ managedNames
8311
+ });
8312
+ conflicts.push(...adoption.conflicts);
8130
8313
  const additions = candidates.filter(({ tag }) => !projectNames.has(stableName(tag)));
8131
8314
  const contentOverrides = new Map;
8132
8315
  const files = await preservePublishedHistory(input.sourceManifest, input, contentOverrides);
8133
8316
  const publishedPaths = new Set(files.map(({ path: path2 }) => path2));
8317
+ for (const adopted of adoption.adoptions) {
8318
+ contentOverrides.set(adopted.sqlPath, adopted.sql);
8319
+ contentOverrides.set(adopted.snapshotPath, adopted.snapshot);
8320
+ files.push(managedEntry(adopted.sqlPath, adopted.sql), managedEntry(adopted.snapshotPath, adopted.snapshot));
8321
+ publishedPaths.add(adopted.sqlPath);
8322
+ publishedPaths.add(adopted.snapshotPath);
8323
+ }
8134
8324
  files.push(...input.targetManifest.files.filter(({ path: path2 }) => !isDrizzleHistoryPath(path2)));
8135
8325
  if (!additions.length) {
8136
8326
  const journalContent2 = encodeJson(project);
@@ -8159,14 +8349,14 @@ async function reconcileDrizzleMigrations(input) {
8159
8349
  const name = stableName(addition.tag);
8160
8350
  const tag = `${prefix}_${name}`;
8161
8351
  const sqlPath = `${drizzleRoot}/${tag}.sql`;
8162
- const snapshotPath = `${drizzleRoot}/meta/${prefix}_snapshot.json`;
8163
- const sql = await readFile16(join20(input.targetDirectory, `${drizzleRoot}/${addition.tag}.sql`));
8352
+ const snapshotPath2 = `${drizzleRoot}/meta/${prefix}_snapshot.json`;
8353
+ const sql = await readFile18(join21(input.targetDirectory, `${drizzleRoot}/${addition.tag}.sql`));
8164
8354
  merged.id = targetAfter.id;
8165
8355
  merged.prevId = currentSnapshot.id;
8166
8356
  const snapshot = encodeJson(merged);
8167
8357
  contentOverrides.set(sqlPath, sql);
8168
- contentOverrides.set(snapshotPath, snapshot);
8169
- files.push(managedEntry(sqlPath, sql), managedEntry(snapshotPath, snapshot));
8358
+ contentOverrides.set(snapshotPath2, snapshot);
8359
+ files.push(managedEntry(sqlPath, sql), managedEntry(snapshotPath2, snapshot));
8170
8360
  previousWhen = Math.max(previousWhen + 1, addition.when);
8171
8361
  mergedJournal.entries.push({
8172
8362
  ...addition,
@@ -8207,9 +8397,9 @@ function unchanged(targetManifest) {
8207
8397
  async function readJournals(input) {
8208
8398
  try {
8209
8399
  const [base, project, target] = await Promise.all([
8210
- readJson(join20(input.baseDirectory, journalPath)),
8400
+ readJson(join21(input.baseDirectory, journalPath)),
8211
8401
  readProjectJson(input, journalPath),
8212
- readJson(join20(input.targetDirectory, journalPath))
8402
+ readJson(join21(input.targetDirectory, journalPath))
8213
8403
  ]);
8214
8404
  return { base, project, target };
8215
8405
  } catch (error) {
@@ -8232,79 +8422,31 @@ async function readLatestSnapshot(input, journal) {
8232
8422
  const latest = journal.entries.at(-1);
8233
8423
  if (!latest)
8234
8424
  throw new Error(`${journalPath}\uFF1A\u5F53\u524D\u9879\u76EE\u6CA1\u6709 migration`);
8235
- const match = migrationPattern.exec(latest.tag);
8236
- if (!match) {
8237
- throw new Error(`${journalPath}\uFF1Amigration tag \u683C\u5F0F\u65E0\u6548\uFF1A${latest.tag}`);
8238
- }
8239
- const snapshotPath = `${drizzleRoot}/meta/${match[1]}_snapshot.json`;
8240
- const content = await readProjectFile(input, snapshotPath);
8425
+ const path2 = snapshotPath(latest.tag);
8426
+ const content = await readProjectFile(input, path2);
8241
8427
  if (!content) {
8242
- throw new Error(`\u5F53\u524D\u9879\u76EE migration \u6587\u4EF6\u7F3A\u5931\uFF1A${snapshotPath}`);
8428
+ throw new Error(`\u5F53\u524D\u9879\u76EE migration \u6587\u4EF6\u7F3A\u5931\uFF1A${path2}`);
8243
8429
  }
8244
8430
  return JSON.parse(new TextDecoder().decode(content));
8245
8431
  }
8246
8432
  async function readSnapshot(root, tag) {
8247
- const match = migrationPattern.exec(tag);
8248
- if (!match)
8249
- throw new Error(`${journalPath}\uFF1Amigration tag \u683C\u5F0F\u65E0\u6548\uFF1A${tag}`);
8250
- return await readJson(join20(root, `${drizzleRoot}/meta/${match[1]}_snapshot.json`));
8251
- }
8252
- function validateUniqueNames(journal, label, conflicts) {
8253
- const seen = new Set;
8254
- for (const { tag } of journal.entries) {
8255
- const name = stableName(tag);
8256
- if (seen.has(name)) {
8257
- conflicts.push(`${journalPath}\uFF1A${label}\u5B58\u5728\u91CD\u590D migration \u540D\u79F0 ${name}`);
8258
- }
8259
- seen.add(name);
8260
- }
8261
- }
8262
- function stableName(tag) {
8263
- return migrationPattern.exec(tag)?.[2] ?? tag;
8264
- }
8265
- function highestPrefix(journal) {
8266
- return Math.max(-1, ...journal.entries.map(({ tag }) => Number(migrationPattern.exec(tag)?.[1] ?? -1)));
8267
- }
8268
- function highestIndex(journal) {
8269
- return Math.max(-1, ...journal.entries.map(({ idx }) => idx));
8270
- }
8271
- function isDrizzleHistoryPath(path2) {
8272
- return path2 === journalPath || isMigrationArtifact(path2);
8273
- }
8274
- function isMigrationArtifact(path2) {
8275
- return isSqlMigration(path2) || new RegExp(`^${drizzleRoot}/meta/\\d{4}_snapshot\\.json$`).test(path2);
8276
- }
8277
- function isSqlMigration(path2) {
8278
- return new RegExp(`^${drizzleRoot}/\\d{4}_.+\\.sql$`).test(path2);
8279
- }
8280
- function managedEntry(path2, content) {
8281
- return { path: path2, ownership: "windy-managed", hash: hashContent(content) };
8282
- }
8283
- function deduplicate(files) {
8284
- return [...new Map(files.map((entry) => [entry.path, entry])).values()];
8285
- }
8286
- function encodeJson(value) {
8287
- return new TextEncoder().encode(`${JSON.stringify(value, null, 2)}
8288
- `);
8289
- }
8290
- async function readJson(path2) {
8291
- return JSON.parse(await readFile16(path2, "utf8"));
8433
+ return await readJson(join21(root, snapshotPath(tag)));
8292
8434
  }
8293
8435
 
8294
8436
  // src/update/planner-file.ts
8295
- import { readFile as readFile17 } from "fs/promises";
8296
- import { join as join22 } from "path";
8437
+ import { readFile as readFile19 } from "fs/promises";
8438
+ import { join as join23 } from "path";
8297
8439
 
8298
8440
  // src/update/merge.ts
8299
8441
  import { mkdtemp as mkdtemp2, rm as rm6, writeFile as writeFile12 } from "fs/promises";
8300
8442
  import { tmpdir as tmpdir2 } from "os";
8301
- import { join as join21 } from "path";
8443
+ import { join as join22 } from "path";
8302
8444
  async function mergeTextFile(base, ours, theirs) {
8303
- const root = await mkdtemp2(join21(tmpdir2(), "windy-merge-"));
8445
+ const root = await mkdtemp2(join22(tmpdir2(), "windy-merge-"));
8304
8446
  try {
8305
- const oursPath = join21(root, "ours");
8306
- const basePath = join21(root, "base");
8307
- const theirsPath = join21(root, "theirs");
8447
+ const oursPath = join22(root, "ours");
8448
+ const basePath = join22(root, "base");
8449
+ const theirsPath = join22(root, "theirs");
8308
8450
  await Promise.all([
8309
8451
  writeFile12(oursPath, ours),
8310
8452
  writeFile12(basePath, base),
@@ -8562,8 +8704,8 @@ function conflict(path2, reason, expectedProjectContent) {
8562
8704
  // src/update/planner-file.ts
8563
8705
  async function planFile(path2, baseRoot, targetRoot, source, target, ours, provenance, targetContentOverride, manageGeneratedProjectOwned = false, forcePlatformBaseline = false) {
8564
8706
  const [base, theirs] = await Promise.all([
8565
- readOptional(join22(baseRoot, path2)),
8566
- targetContentOverride ? Promise.resolve(targetContentOverride) : readOptional(join22(targetRoot, path2))
8707
+ readOptional(join23(baseRoot, path2)),
8708
+ targetContentOverride ? Promise.resolve(targetContentOverride) : readOptional(join23(targetRoot, path2))
8567
8709
  ]);
8568
8710
  const ownership = source?.ownership ?? target?.ownership ?? classifyOwnership(path2);
8569
8711
  const expected = expectationForSnapshot(ours);
@@ -8670,7 +8812,7 @@ function conflict2(path2, ownership, reason, expectedProjectContent) {
8670
8812
  }
8671
8813
  async function readOptional(path2) {
8672
8814
  try {
8673
- return await readFile17(path2);
8815
+ return await readFile19(path2);
8674
8816
  } catch (error) {
8675
8817
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
8676
8818
  return;
@@ -8695,27 +8837,27 @@ function resolveModuleRecipeIds(request) {
8695
8837
  }
8696
8838
 
8697
8839
  // src/update/planner-snapshots.ts
8698
- import { readFile as readFile18, stat as stat2 } from "fs/promises";
8699
- import { join as join23 } from "path";
8840
+ import { readFile as readFile20, stat as stat2 } from "fs/promises";
8841
+ import { join as join24 } from "path";
8700
8842
  async function snapshotProjectFiles(project, paths, seed) {
8701
8843
  const snapshots = new Map(seed);
8702
8844
  await Promise.all([...paths].filter((path2) => !snapshots.has(path2)).map(async (path2) => {
8703
- snapshots.set(path2, await readOptional2(join23(project, path2)));
8845
+ snapshots.set(path2, await readOptional2(join24(project, path2)));
8704
8846
  }));
8705
8847
  return snapshots;
8706
8848
  }
8707
8849
  async function snapshotProjectModes(project, paths) {
8708
- return new Map(await Promise.all([...paths].map(async (path2) => [path2, await readModeOptional(join23(project, path2))])));
8850
+ return new Map(await Promise.all([...paths].map(async (path2) => [path2, await readModeOptional(join24(project, path2))])));
8709
8851
  }
8710
8852
  async function assertPlanSnapshots(project, expectations) {
8711
8853
  const changed = [];
8712
8854
  for (const expectation2 of expectations) {
8713
- const actual = expectationForSnapshot(await readOptional2(join23(project, expectation2.path)));
8855
+ const actual = expectationForSnapshot(await readOptional2(join24(project, expectation2.path)));
8714
8856
  if (JSON.stringify(actual) !== JSON.stringify(expectation2.expected)) {
8715
8857
  changed.push(expectation2.path);
8716
8858
  continue;
8717
8859
  }
8718
- if ("mode" in expectation2 && await readModeOptional(join23(project, expectation2.path)) !== expectation2.mode) {
8860
+ if ("mode" in expectation2 && await readModeOptional(join24(project, expectation2.path)) !== expectation2.mode) {
8719
8861
  changed.push(expectation2.path);
8720
8862
  }
8721
8863
  }
@@ -8747,7 +8889,7 @@ async function readSourceParentMode(path2) {
8747
8889
  }
8748
8890
  async function readOptional2(path2) {
8749
8891
  try {
8750
- return await readFile18(path2);
8892
+ return await readFile20(path2);
8751
8893
  } catch (error) {
8752
8894
  if (isMissing7(error))
8753
8895
  return;
@@ -8791,8 +8933,8 @@ var oxcManagedPaths = new Set([
8791
8933
  ]);
8792
8934
  async function createUpdatePlan(request, artifacts) {
8793
8935
  await assertProjectReadyForUpdate(request.projectDirectory);
8794
- const manifestPath = join24(request.projectDirectory, ".windy/files.json");
8795
- const expectedManifestHash = hashContent(await readFile19(manifestPath));
8936
+ const manifestPath = join25(request.projectDirectory, ".windy/files.json");
8937
+ const expectedManifestHash = hashContent(await readFile21(manifestPath));
8796
8938
  const generationSnapshot = await readGenerationProvenanceSnapshot(request.projectDirectory);
8797
8939
  const provenance = generationSnapshot.provenance;
8798
8940
  const targetModules = resolveUpdateTargetModules(provenance.modules.map(({ name }) => name), request.targetModules);
@@ -8838,8 +8980,8 @@ async function createUpdatePlan(request, artifacts) {
8838
8980
  const paths = new Set([...sourceEntries.keys(), ...targetEntries.keys()]);
8839
8981
  for (const path2 of paths) {
8840
8982
  if (!projectSnapshots.has(path2)) {
8841
- projectSnapshots.set(path2, await readOptional2(join24(request.projectDirectory, path2)));
8842
- projectModes.set(path2, await readModeOptional(join24(request.projectDirectory, path2)));
8983
+ projectSnapshots.set(path2, await readOptional2(join25(request.projectDirectory, path2)));
8984
+ projectModes.set(path2, await readModeOptional(join25(request.projectDirectory, path2)));
8843
8985
  }
8844
8986
  }
8845
8987
  const files = await planFiles({
@@ -8861,10 +9003,10 @@ async function createUpdatePlan(request, artifacts) {
8861
9003
  for (const file of files) {
8862
9004
  file.expectedProjectMode = projectModes.get(file.path);
8863
9005
  if (file.action === "create" || file.action === "update") {
8864
- file.mode = file.expectedProjectMode ?? await readModeOptional(join24(artifactSet.targetDirectory, file.path));
9006
+ file.mode = file.expectedProjectMode ?? await readModeOptional(join25(artifactSet.targetDirectory, file.path));
8865
9007
  }
8866
9008
  if (file.action === "create") {
8867
- file.parentMode = await readSourceParentMode(join24(artifactSet.targetDirectory, dirname7(file.path)));
9009
+ file.parentMode = await readSourceParentMode(join25(artifactSet.targetDirectory, dirname7(file.path)));
8868
9010
  }
8869
9011
  }
8870
9012
  const plannedPaths = new Set(files.map(({ path: path2 }) => path2));
@@ -8884,7 +9026,7 @@ async function createUpdatePlan(request, artifacts) {
8884
9026
  ...migrations.conflicts,
8885
9027
  ...files.flatMap((file) => file.conflict ? [`${file.path}\uFF1A${file.conflict}`] : [])
8886
9028
  ];
8887
- if (hashContent(await readFile19(manifestPath)) !== expectedManifestHash) {
9029
+ if (hashContent(await readFile21(manifestPath)) !== expectedManifestHash) {
8888
9030
  throw new Error("\u751F\u6210\u66F4\u65B0\u8BA1\u5212\u671F\u95F4\u53D7\u7BA1\u6E05\u5355\u53D1\u751F\u53D8\u5316");
8889
9031
  }
8890
9032
  await assertPlanSnapshots(request.projectDirectory, [
@@ -9009,9 +9151,9 @@ function frozenManifestHash(file, finalizedHashes) {
9009
9151
  }
9010
9152
 
9011
9153
  // src/update/format-stabilizer.ts
9012
- import { mkdir as mkdir8, mkdtemp as mkdtemp3, readFile as readFile20, rm as rm7, writeFile as writeFile13 } from "fs/promises";
9154
+ import { mkdir as mkdir8, mkdtemp as mkdtemp3, readFile as readFile22, rm as rm7, writeFile as writeFile13 } from "fs/promises";
9013
9155
  import { tmpdir as tmpdir3 } from "os";
9014
- import { dirname as dirname8, extname as extname4, join as join25, resolve as resolve6, sep as sep5 } from "path";
9156
+ import { dirname as dirname8, extname as extname4, join as join26, resolve as resolve6, sep as sep5 } from "path";
9015
9157
  var formattedExtensions = new Set([
9016
9158
  ".cjs",
9017
9159
  ".css",
@@ -9050,7 +9192,7 @@ async function stabilizeManagedContent(result2, execute, writeProjectFile) {
9050
9192
  }
9051
9193
  }
9052
9194
  inputs.set(".windy/generation.json", new TextEncoder().encode(generationContent));
9053
- const temporaryRoot = await mkdtemp3(join25(tmpdir3(), "windy-update-format-"));
9195
+ const temporaryRoot = await mkdtemp3(join26(tmpdir3(), "windy-update-format-"));
9054
9196
  try {
9055
9197
  const stagedPaths = await stageInputs(temporaryRoot, inputs);
9056
9198
  for (let offset = 0;offset < stagedPaths.length; offset += 80) {
@@ -9058,14 +9200,14 @@ async function stabilizeManagedContent(result2, execute, writeProjectFile) {
9058
9200
  "x",
9059
9201
  "oxfmt",
9060
9202
  "--write",
9061
- `--config=${join25(result2.plan.projectDirectory, ".oxfmtrc.json")}`,
9203
+ `--config=${join26(result2.plan.projectDirectory, ".oxfmtrc.json")}`,
9062
9204
  ...stagedPaths.slice(offset, offset + 80)
9063
9205
  ], result2.plan.projectDirectory);
9064
9206
  }
9065
9207
  const hashes = plannedContentHashes(result2);
9066
9208
  let formattedGeneration = generationContent;
9067
9209
  for (const [path2, original] of inputs) {
9068
- const formatted = await readFile20(safeTemporaryPath(temporaryRoot, path2));
9210
+ const formatted = await readFile22(safeTemporaryPath(temporaryRoot, path2));
9069
9211
  if (path2 === ".windy/generation.json") {
9070
9212
  formattedGeneration = formatted.toString();
9071
9213
  continue;
@@ -9219,7 +9361,7 @@ class DefaultStarterUpdater {
9219
9361
  const plannedPaths = new Set(result2.plan.files.map(({ path: path2 }) => path2));
9220
9362
  replaceExpectations(result2, verificationSnapshot.filter(({ path: path2 }) => !metadataPaths2.has(path2) && !plannedPaths.has(path2)));
9221
9363
  verificationExpectationsFrozen = true;
9222
- const packageJson = JSON.parse(await readFile21(join26(result2.plan.projectDirectory, "package.json"), "utf8"));
9364
+ const packageJson = JSON.parse(await readFile23(join27(result2.plan.projectDirectory, "package.json"), "utf8"));
9223
9365
  for (const name of ["lint", "typecheck", "test", "build"]) {
9224
9366
  if (!packageJson.scripts?.[name]) {
9225
9367
  steps.push({ name: `bun run ${name}`, status: "skipped" });
@@ -10137,20 +10279,20 @@ import {
10137
10279
  cp,
10138
10280
  mkdir as mkdir9,
10139
10281
  mkdtemp as mkdtemp4,
10140
- readFile as readFile23,
10282
+ readFile as readFile25,
10141
10283
  readdir as readdir9,
10142
10284
  rename as rename2,
10143
10285
  rm as rm11,
10144
10286
  writeFile as writeFile14
10145
10287
  } from "fs/promises";
10146
- import { dirname as dirname9, join as join27, relative as relative6 } from "path";
10288
+ import { dirname as dirname9, join as join28, relative as relative6 } from "path";
10147
10289
 
10148
10290
  // src/module-schema/config.ts
10149
- import { readFile as readFile22 } from "fs/promises";
10291
+ import { readFile as readFile24 } from "fs/promises";
10150
10292
  import { isAbsolute as isAbsolute2, relative as relative5, resolve as resolve9 } from "path";
10151
10293
  async function readModuleSchemaLineageConfig(projectDirectory, configPath) {
10152
10294
  const absolutePath = resolveProjectPath(projectDirectory, configPath);
10153
- const parsed = JSON.parse(await readFile22(absolutePath, "utf8"));
10295
+ const parsed = JSON.parse(await readFile24(absolutePath, "utf8"));
10154
10296
  if (!isConfig(parsed)) {
10155
10297
  throw new Error("Module schema lineage \u914D\u7F6E\u65E0\u6548");
10156
10298
  }
@@ -10284,17 +10426,17 @@ async function handoffModuleSchemaLineages(options) {
10284
10426
  async function stageModuleLineages(project, temporaryRoot, config, execute) {
10285
10427
  const outputs = [];
10286
10428
  for (const [index, module3] of config.modules.entries()) {
10287
- const output = join27(temporaryRoot, `module-${index}`);
10429
+ const output = join28(temporaryRoot, `module-${index}`);
10288
10430
  await mkdir9(output, { recursive: true });
10289
- const generatedConfig = join27(temporaryRoot, `module-${index}.config.ts`);
10431
+ const generatedConfig = join28(temporaryRoot, `module-${index}.config.ts`);
10290
10432
  await writeDrizzleConfig(generatedConfig, project, module3.schema, relative6(temporaryRoot, output));
10291
10433
  await execute(generatedConfig, temporaryRoot);
10292
10434
  const sqlFiles = await listSqlFiles(output);
10293
10435
  if (sqlFiles.length !== 1) {
10294
10436
  throw new Error(`${module3.key} baseline \u5FC5\u987B\u6070\u597D\u751F\u6210\u4E00\u4E2A migration`);
10295
10437
  }
10296
- await writeFile14(join27(output, sqlFiles[0]), metadataOnlySql("module"));
10297
- await writeFile14(join27(output, "lineage.json"), `${JSON.stringify({
10438
+ await writeFile14(join28(output, sqlFiles[0]), metadataOnlySql("module"));
10439
+ await writeFile14(join28(output, "lineage.json"), `${JSON.stringify({
10298
10440
  schemaVersion: 1,
10299
10441
  moduleKey: module3.key,
10300
10442
  schema: module3.schema,
@@ -10308,25 +10450,25 @@ async function stageModuleLineages(project, temporaryRoot, config, execute) {
10308
10450
  }
10309
10451
  async function stagePlatformLineage(project, temporaryRoot, config, execute) {
10310
10452
  const source = resolveProjectPath(project, config.platform.out);
10311
- const output = join27(temporaryRoot, "platform");
10453
+ const output = join28(temporaryRoot, "platform");
10312
10454
  await cp(source, output, { recursive: true });
10313
10455
  const before = new Set(await listSqlFiles(output));
10314
- const generatedConfig = join27(temporaryRoot, "platform.config.ts");
10456
+ const generatedConfig = join28(temporaryRoot, "platform.config.ts");
10315
10457
  await writeDrizzleConfig(generatedConfig, project, config.platform.schema, relative6(temporaryRoot, output));
10316
10458
  await execute(generatedConfig, temporaryRoot);
10317
10459
  const created = (await listSqlFiles(output)).filter((path2) => !before.has(path2));
10318
10460
  if (created.length !== 1) {
10319
10461
  throw new Error("\u5E73\u53F0 lineage handoff \u5FC5\u987B\u6070\u597D\u751F\u6210\u4E00\u4E2A migration");
10320
10462
  }
10321
- const sqlPath = join27(output, created[0]);
10463
+ const sqlPath = join28(output, created[0]);
10322
10464
  const allowed = config.modules.flatMap(({ legacyPlatformTables }) => legacyPlatformTables);
10323
- validatePlatformHandoffSql(await readFile23(sqlPath, "utf8"), allowed);
10465
+ validatePlatformHandoffSql(await readFile25(sqlPath, "utf8"), allowed);
10324
10466
  await writeFile14(sqlPath, metadataOnlySql("platform"));
10325
10467
  return output;
10326
10468
  }
10327
10469
  async function installStagedLineages(project, temporaryRoot, config, stagedModules, stagedPlatform) {
10328
10470
  const platform = resolveProjectPath(project, config.platform.out);
10329
- const backup = join27(temporaryRoot, "platform-backup");
10471
+ const backup = join28(temporaryRoot, "platform-backup");
10330
10472
  const installed = [];
10331
10473
  await rename2(platform, backup);
10332
10474
  try {
@@ -10373,9 +10515,9 @@ async function validateSchemaSources(project, config) {
10373
10515
  }
10374
10516
  }
10375
10517
  async function createTemporaryRoot(project) {
10376
- const windy = join27(project, ".windy");
10518
+ const windy = join28(project, ".windy");
10377
10519
  await mkdir9(windy, { recursive: true });
10378
- return await mkdtemp4(join27(windy, "module-schema-handoff-"));
10520
+ return await mkdtemp4(join28(windy, "module-schema-handoff-"));
10379
10521
  }
10380
10522
  async function listSqlFiles(root) {
10381
10523
  return (await readdir9(root)).filter((path2) => path2.endsWith(".sql")).sort();