create-windy 0.4.1 → 0.5.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 (174) hide show
  1. package/dist/cli.js +292 -125
  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/system/operations.test.ts +54 -0
  96. package/template/apps/server/src/system/operations.ts +23 -1
  97. package/template/apps/server/src/system/seed.test.ts +4 -0
  98. package/template/apps/server/src/system/system-resource-monitoring.test.ts +82 -0
  99. package/template/apps/server/src/system/system-resource-monitoring.ts +300 -0
  100. package/template/apps/web/src/layout/AppSidebar.vue +6 -1
  101. package/template/apps/web/src/layout/AppSidebar.webtest.ts +2 -0
  102. package/template/apps/web/src/pages/auth/LoginPage.vue +6 -1
  103. package/template/apps/web/src/pages/settings/BrandingSettingsSection.vue +20 -3
  104. package/template/apps/web/src/pages/settings/BrandingSettingsSection.webtest.ts +80 -0
  105. package/template/apps/web/src/pages/system/AiRuntimePage.vue +129 -0
  106. package/template/apps/web/src/pages/system/SystemOperationsPage.vue +2 -1
  107. package/template/apps/web/src/pages/system/ai-runtime-presenter.ts +60 -0
  108. package/template/apps/web/src/pages/system/ai-runtime-presenter.webtest.ts +48 -0
  109. package/template/apps/web/src/pages/system/audit-time-range.ts +34 -2
  110. package/template/apps/web/src/pages/system/components/AuditLogFilters.vue +4 -3
  111. package/template/apps/web/src/pages/system/components/AuditLogFilters.webtest.ts +26 -1
  112. package/template/apps/web/src/pages/system/components/OperationGpuMonitor.vue +98 -0
  113. package/template/apps/web/src/pages/system/components/OperationGpuMonitor.webtest.ts +61 -0
  114. package/template/apps/web/src/pages/system/components/OperationServiceMonitor.vue +53 -0
  115. package/template/apps/web/src/pages/system/components/OperationServiceMonitor.webtest.ts +20 -1
  116. package/template/apps/web/src/pages/system/components/SystemResourcePage.webtest.ts +14 -1
  117. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeActivityChart.vue +85 -0
  118. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeCharts.webtest.ts +82 -0
  119. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeFilters.vue +98 -0
  120. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeFilters.webtest.ts +27 -0
  121. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeRunDetailDialog.vue +168 -0
  122. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeRunTable.vue +130 -0
  123. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeSummaryCards.vue +82 -0
  124. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeSummaryCards.webtest.ts +102 -0
  125. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeTokenByModelChart.vue +101 -0
  126. package/template/apps/web/src/pages/system/composables/useAiRuntimeReport.ts +185 -0
  127. package/template/apps/web/src/pages/system/composables/useAiRuntimeReport.webtest.ts +158 -0
  128. package/template/apps/web/src/pages/system/composables/useSystemResource.ts +21 -7
  129. package/template/apps/web/src/router/error-navigation.ts +22 -0
  130. package/template/apps/web/src/router/index.ts +12 -23
  131. package/template/apps/web/src/router/platform-admin-route-bindings.ts +4 -0
  132. package/template/apps/web/src/services/ai-runtime-api.ts +164 -0
  133. package/template/apps/web/src/services/ai-runtime-api.webtest.ts +111 -0
  134. package/template/apps/web/src/services/operations-api.ts +28 -0
  135. package/template/docker-compose.agent-debug.yml +1 -1
  136. package/template/docs/architecture/ai-runtime.md +2 -1
  137. package/template/docs/architecture/module-host.md +3 -0
  138. package/template/docs/platform/agent-run-attestation.md +65 -0
  139. package/template/docs/platform/agent-runtime-observability.md +135 -0
  140. package/template/docs/platform/agent-runtime.md +47 -3
  141. package/template/docs/platform/operations-overview.md +13 -0
  142. package/template/docs/platform/platform-authentication.md +4 -3
  143. package/template/packages/config/package.json +1 -1
  144. package/template/packages/database/drizzle/0045_tiny_cassandra_nova.sql +65 -0
  145. package/template/packages/database/drizzle/0046_tranquil_living_mummy.sql +6 -0
  146. package/template/packages/database/drizzle/0047_oval_luke_cage.sql +18 -0
  147. package/template/packages/database/drizzle/meta/0045_snapshot.json +8814 -0
  148. package/template/packages/database/drizzle/meta/0046_snapshot.json +8820 -0
  149. package/template/packages/database/drizzle/meta/0047_snapshot.json +8835 -0
  150. package/template/packages/database/drizzle/meta/_journal.json +21 -0
  151. package/template/packages/database/package.json +1 -1
  152. package/template/packages/database/src/agent-runtime-schema.test.ts +54 -0
  153. package/template/packages/database/src/schema/agent-runtime.ts +114 -0
  154. package/template/packages/jobs/package.json +1 -1
  155. package/template/packages/modules/package.json +1 -1
  156. package/template/packages/modules/src/system-admin-routes.ts +10 -0
  157. package/template/packages/modules/src/system-admin-ui-catalog.ts +1 -1
  158. package/template/packages/modules/src/system-api-control-plane.ts +17 -1
  159. package/template/packages/modules/src/system-audit-actions.ts +10 -0
  160. package/template/packages/modules/src/system-features.ts +8 -0
  161. package/template/packages/modules/src/system-module-catalog.test.ts +35 -0
  162. package/template/packages/modules/src/system-module-catalog.ts +15 -4
  163. package/template/packages/modules/src/system-modules-access.test.ts +69 -0
  164. package/template/packages/modules/src/system-modules.ts +13 -0
  165. package/template/packages/modules/src/system-permissions.ts +2 -0
  166. package/template/packages/server-sdk/index.ts +11 -0
  167. package/template/packages/server-sdk/package.json +2 -1
  168. package/template/packages/server-sdk/src/ai-operation-port.ts +5 -0
  169. package/template/packages/server-sdk/src/debug-session-provider.ts +63 -0
  170. package/template/packages/server-sdk/src/module-host.ts +5 -0
  171. package/template/packages/shared/index.ts +3 -0
  172. package/template/packages/shared/package.json +1 -1
  173. package/template/packages/shared/src/ai-runtime-report.ts +134 -0
  174. 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,
@@ -2640,16 +2661,27 @@ async function pruneDatabaseArtifacts(root, tableNames, statementTokens) {
2640
2661
  for (const path of await collectFiles2(drizzleRoot)) {
2641
2662
  if (path.endsWith(".sql")) {
2642
2663
  const source = await readFile6(path, "utf8");
2643
- const statements = source.split("--> statement-breakpoint").map((statement) => statement.trim()).filter(Boolean).filter((statement) => !tablePatterns.some((pattern) => pattern.test(statement)) && !statementTokens.some((token) => statement.includes(token)));
2644
- await writeFile5(path, statements.length ? `${statements.join(`
2664
+ const statements = source.split("--> statement-breakpoint").map((statement) => statement.trim()).filter(Boolean);
2665
+ const retained = statements.filter((statement) => !tablePatterns.some((pattern) => pattern.test(statement)) && !statementTokens.some((token) => statement.includes(token)));
2666
+ if (retained.length === statements.length)
2667
+ continue;
2668
+ await writeFile5(path, retained.length ? `${retained.join(`
2645
2669
  --> statement-breakpoint
2646
2670
  `)}
2647
2671
  ` : `-- \u6B64 migration \u7684\u6A21\u5757\u672A\u88AB\u5F53\u524D\u9879\u76EE\u9009\u62E9\u3002
2648
2672
  `);
2649
2673
  } else if (path.endsWith("_snapshot.json")) {
2650
2674
  const snapshot = JSON.parse(await readFile6(path, "utf8"));
2651
- for (const name of tableNames)
2652
- delete snapshot.tables?.[`public.${name}`];
2675
+ let changed = false;
2676
+ for (const name of tableNames) {
2677
+ const key = `public.${name}`;
2678
+ if (!Object.hasOwn(snapshot.tables ?? {}, key))
2679
+ continue;
2680
+ delete snapshot.tables?.[key];
2681
+ changed = true;
2682
+ }
2683
+ if (!changed)
2684
+ continue;
2653
2685
  await writeFile5(path, `${JSON.stringify(snapshot, null, 2)}
2654
2686
  `);
2655
2687
  }
@@ -3445,6 +3477,7 @@ var templateRootFiles = [
3445
3477
  "module-schema.lineages.json",
3446
3478
  "package.json",
3447
3479
  "scripts/notification-postgres-regression.ts",
3480
+ "scripts/lib/postgres-regression.ts",
3448
3481
  "scripts/dev-adk-web.ts"
3449
3482
  ];
3450
3483
  var templateDirectories = [
@@ -3491,8 +3524,10 @@ var templateDocumentationFiles = [
3491
3524
  "docs/development/module-lifecycle.md",
3492
3525
  "docs/license/license-offline-activation-code.md",
3493
3526
  "docs/operations/observability.md",
3527
+ "docs/platform/agent-run-attestation.md",
3494
3528
  "docs/platform/agent-tools.md",
3495
3529
  "docs/platform/agent-runtime.md",
3530
+ "docs/platform/agent-runtime-observability.md",
3496
3531
  "docs/platform/agent-tool-sandbox.md",
3497
3532
  "docs/platform/audit-reliability.md",
3498
3533
  "docs/platform/bulk-data-jobs.md",
@@ -7529,6 +7564,16 @@ var recipes = [
7529
7564
  id: "starter-0.4.0-to-0.4.1",
7530
7565
  from: "0.4.0",
7531
7566
  to: "0.4.1"
7567
+ },
7568
+ {
7569
+ id: "starter-0.4.1-to-0.5.0",
7570
+ from: "0.4.1",
7571
+ to: "0.5.0"
7572
+ },
7573
+ {
7574
+ id: "starter-0.5.0-to-0.5.1",
7575
+ from: "0.5.0",
7576
+ to: "0.5.1"
7532
7577
  }
7533
7578
  ];
7534
7579
  function resolveRecipeChain(sourceVersion, targetVersion) {
@@ -7574,8 +7619,8 @@ function parseVersion2(version) {
7574
7619
  }
7575
7620
 
7576
7621
  // src/update/updater.ts
7577
- import { readFile as readFile21, rm as rm8 } from "fs/promises";
7578
- import { join as join26 } from "path";
7622
+ import { readFile as readFile23, rm as rm8 } from "fs/promises";
7623
+ import { join as join27 } from "path";
7579
7624
 
7580
7625
  // src/update/artifacts.ts
7581
7626
  import { mkdtemp, readFile as readFile14 } from "fs/promises";
@@ -7936,8 +7981,8 @@ async function readProjectName2(projectDirectory) {
7936
7981
  }
7937
7982
 
7938
7983
  // src/update/planner.ts
7939
- import { readFile as readFile19 } from "fs/promises";
7940
- import { dirname as dirname7, join as join24 } from "path";
7984
+ import { readFile as readFile21 } from "fs/promises";
7985
+ import { dirname as dirname7, join as join25 } from "path";
7941
7986
 
7942
7987
  // src/update/docker-copy-update-plan.ts
7943
7988
  async function deriveDockerfilePlans(files, snapshots, paths, targetWorkspaceManifests) {
@@ -8025,7 +8070,11 @@ function matchesWorkspace(pattern, directory) {
8025
8070
  }
8026
8071
 
8027
8072
  // src/update/migration-reconciler.ts
8028
- import { readFile as readFile16 } from "fs/promises";
8073
+ import { readFile as readFile18 } from "fs/promises";
8074
+ import { join as join21 } from "path";
8075
+
8076
+ // src/update/migration-adoption.ts
8077
+ import { readFile as readFile17 } from "fs/promises";
8029
8078
  import { join as join20 } from "path";
8030
8079
 
8031
8080
  // src/update/migration-project-file.ts
@@ -8060,6 +8109,60 @@ function isMissingFileError(error) {
8060
8109
  return error instanceof Error && "code" in error && error.code === "ENOENT";
8061
8110
  }
8062
8111
 
8112
+ // src/update/migration-history.ts
8113
+ import { readFile as readFile16 } from "fs/promises";
8114
+ var drizzleRoot = "packages/database/drizzle";
8115
+ var journalPath = `${drizzleRoot}/meta/_journal.json`;
8116
+ var migrationPattern = /^(\d{4})_(.+)$/;
8117
+ function snapshotPath(tag) {
8118
+ const match = migrationPattern.exec(tag);
8119
+ if (!match) {
8120
+ throw new Error(`${journalPath}\uFF1Amigration tag \u683C\u5F0F\u65E0\u6548\uFF1A${tag}`);
8121
+ }
8122
+ return `${drizzleRoot}/meta/${match[1]}_snapshot.json`;
8123
+ }
8124
+ function validateUniqueNames(journal, label, conflicts) {
8125
+ const seen = new Set;
8126
+ for (const { tag } of journal.entries) {
8127
+ const name = stableName(tag);
8128
+ if (seen.has(name)) {
8129
+ conflicts.push(`${journalPath}\uFF1A${label}\u5B58\u5728\u91CD\u590D migration \u540D\u79F0 ${name}`);
8130
+ }
8131
+ seen.add(name);
8132
+ }
8133
+ }
8134
+ function stableName(tag) {
8135
+ return migrationPattern.exec(tag)?.[2] ?? tag;
8136
+ }
8137
+ function highestPrefix(journal) {
8138
+ return Math.max(-1, ...journal.entries.map(({ tag }) => Number(migrationPattern.exec(tag)?.[1] ?? -1)));
8139
+ }
8140
+ function highestIndex(journal) {
8141
+ return Math.max(-1, ...journal.entries.map(({ idx }) => idx));
8142
+ }
8143
+ function isDrizzleHistoryPath(path2) {
8144
+ return path2 === journalPath || isMigrationArtifact(path2);
8145
+ }
8146
+ function isMigrationArtifact(path2) {
8147
+ return isSqlMigration(path2) || new RegExp(`^${drizzleRoot}/meta/\\d{4}_snapshot\\.json$`).test(path2);
8148
+ }
8149
+ function isSqlMigration(path2) {
8150
+ return new RegExp(`^${drizzleRoot}/\\d{4}_.+\\.sql$`).test(path2);
8151
+ }
8152
+ function managedEntry(path2, content) {
8153
+ return { path: path2, ownership: "windy-managed", hash: hashContent(content) };
8154
+ }
8155
+ function deduplicate(files) {
8156
+ return [...new Map(files.map((entry) => [entry.path, entry])).values()];
8157
+ }
8158
+ function encodeJson(value) {
8159
+ return new TextEncoder().encode(`${JSON.stringify(value, null, 2)}
8160
+ `);
8161
+ }
8162
+ async function readJson(path2) {
8163
+ return JSON.parse(await readFile16(path2, "utf8"));
8164
+ }
8165
+
8063
8166
  // src/update/snapshot-delta.ts
8064
8167
  function applySnapshotDelta(before, after, current, path2, conflicts, conflictPath) {
8065
8168
  if (deepEqual(before, after))
@@ -8105,10 +8208,99 @@ function deepEqual(left, right) {
8105
8208
  return JSON.stringify(left) === JSON.stringify(right);
8106
8209
  }
8107
8210
 
8211
+ // src/update/migration-adoption.ts
8212
+ async function inspectPreexistingMigrationAdoptions(input) {
8213
+ const conflicts = [];
8214
+ const adoptions = [];
8215
+ const projectByName = new Map(input.project.entries.map((entry) => [stableName(entry.tag), entry]));
8216
+ for (const candidate of input.candidates) {
8217
+ const name = stableName(candidate.tag);
8218
+ const projectEntry = projectByName.get(name);
8219
+ if (!projectEntry || input.managedNames.has(name))
8220
+ continue;
8221
+ const targetPosition = input.target.entries.indexOf(candidate);
8222
+ const projectPosition = input.project.entries.indexOf(projectEntry);
8223
+ const previousTarget = input.target.entries[targetPosition - 1];
8224
+ const previousProject = input.project.entries[projectPosition - 1];
8225
+ if (!previousTarget || !previousProject) {
8226
+ conflicts.push(`${journalPath}\uFF1A\u65E0\u6CD5\u91C7\u7EB3\u73B0\u6709\u5E73\u53F0 migration ${name}\uFF0C\u7F3A\u5C11\u524D\u7F6E\u5386\u53F2`);
8227
+ continue;
8228
+ }
8229
+ const projectSqlPath = `${drizzleRoot}/${projectEntry.tag}.sql`;
8230
+ const projectSnapshotPath = snapshotPath(projectEntry.tag);
8231
+ const [
8232
+ targetSql,
8233
+ projectSql,
8234
+ targetBefore,
8235
+ targetAfter,
8236
+ projectBeforeBytes,
8237
+ projectAfterBytes
8238
+ ] = await Promise.all([
8239
+ readFile17(join20(input.targetDirectory, `${drizzleRoot}/${candidate.tag}.sql`)),
8240
+ readProjectFile(input, projectSqlPath),
8241
+ readJson(join20(input.targetDirectory, snapshotPath(previousTarget.tag))),
8242
+ readJson(join20(input.targetDirectory, snapshotPath(candidate.tag))),
8243
+ readProjectFile(input, snapshotPath(previousProject.tag)),
8244
+ readProjectFile(input, projectSnapshotPath)
8245
+ ]);
8246
+ if (!projectSql || !projectBeforeBytes || !projectAfterBytes) {
8247
+ conflicts.push(`${journalPath}\uFF1A\u65E0\u6CD5\u91C7\u7EB3\u73B0\u6709\u5E73\u53F0 migration ${name}\uFF0C\u9879\u76EE migration \u6587\u4EF6\u4E0D\u5B8C\u6574`);
8248
+ continue;
8249
+ }
8250
+ const projectBefore = decodeSnapshot(projectBeforeBytes);
8251
+ const projectAfter = decodeSnapshot(projectAfterBytes);
8252
+ const reason = validateAdoption({
8253
+ targetSql,
8254
+ projectSql,
8255
+ targetBefore,
8256
+ targetAfter,
8257
+ projectBefore,
8258
+ projectAfter
8259
+ });
8260
+ if (reason) {
8261
+ conflicts.push(`${journalPath}\uFF1A\u65E0\u6CD5\u91C7\u7EB3\u73B0\u6709\u5E73\u53F0 migration ${name}\uFF0C${reason}`);
8262
+ continue;
8263
+ }
8264
+ adoptions.push({
8265
+ sqlPath: projectSqlPath,
8266
+ snapshotPath: projectSnapshotPath,
8267
+ sql: projectSql,
8268
+ snapshot: projectAfterBytes
8269
+ });
8270
+ }
8271
+ return { adoptions, conflicts };
8272
+ }
8273
+ function validateAdoption(input) {
8274
+ if (!equalBytes(input.targetSql, input.projectSql)) {
8275
+ return "SQL \u5185\u5BB9\u4E0D\u4E00\u81F4";
8276
+ }
8277
+ if (input.projectAfter.prevId !== input.projectBefore.id) {
8278
+ return "\u9879\u76EE snapshot lineage \u4E0D\u8FDE\u7EED";
8279
+ }
8280
+ const deltaConflicts = [];
8281
+ const expected = applySnapshotDelta(input.targetBefore, input.targetAfter, input.projectBefore, [], deltaConflicts, journalPath);
8282
+ if (deltaConflicts.length || canonicalSnapshot(expected) !== canonicalSnapshot(input.projectAfter)) {
8283
+ return "snapshot delta \u4E0E\u9879\u76EE\u5386\u53F2\u4E0D\u4E00\u81F4";
8284
+ }
8285
+ }
8286
+ function decodeSnapshot(content) {
8287
+ return JSON.parse(new TextDecoder().decode(content));
8288
+ }
8289
+ function equalBytes(left, right) {
8290
+ return left.byteLength === right.byteLength && left.every((value, index) => value === right[index]);
8291
+ }
8292
+ function canonicalSnapshot(value) {
8293
+ return JSON.stringify(canonicalize(value, true));
8294
+ }
8295
+ function canonicalize(value, root = false) {
8296
+ if (Array.isArray(value))
8297
+ return value.map((item) => canonicalize(item));
8298
+ if (!value || typeof value !== "object")
8299
+ return value;
8300
+ 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)]));
8301
+ }
8302
+
8108
8303
  // src/update/migration-reconciler.ts
8109
- var drizzleRoot = "packages/database/drizzle";
8110
- var journalPath = `${drizzleRoot}/meta/_journal.json`;
8111
- var migrationPattern = /^(\d{4})_(.+)$/;
8112
8304
  async function reconcileDrizzleMigrations(input) {
8113
8305
  const journals = await readJournals(input);
8114
8306
  if (!journals) {
@@ -8126,16 +8318,25 @@ async function reconcileDrizzleMigrations(input) {
8126
8318
  const projectNames = new Set(project.entries.map(({ tag }) => stableName(tag)));
8127
8319
  const managedNames = new Set(input.sourceManifest.files.filter(({ path: path2 }) => isSqlMigration(path2)).map(({ path: path2 }) => stableName(path2.slice(drizzleRoot.length + 1, -4))));
8128
8320
  const candidates = target.entries.filter(({ tag }) => !baseNames.has(stableName(tag)));
8129
- for (const { tag } of candidates) {
8130
- const name = stableName(tag);
8131
- if (projectNames.has(name) && !managedNames.has(name)) {
8132
- conflicts.push(`${journalPath}\uFF1A\u5E73\u53F0 migration \u540D\u79F0\u4E0E\u4E0B\u6E38\u4E1A\u52A1\u5386\u53F2\u51B2\u7A81 ${name}`);
8133
- }
8134
- }
8321
+ const adoption = await inspectPreexistingMigrationAdoptions({
8322
+ ...input,
8323
+ project,
8324
+ target,
8325
+ candidates,
8326
+ managedNames
8327
+ });
8328
+ conflicts.push(...adoption.conflicts);
8135
8329
  const additions = candidates.filter(({ tag }) => !projectNames.has(stableName(tag)));
8136
8330
  const contentOverrides = new Map;
8137
8331
  const files = await preservePublishedHistory(input.sourceManifest, input, contentOverrides);
8138
8332
  const publishedPaths = new Set(files.map(({ path: path2 }) => path2));
8333
+ for (const adopted of adoption.adoptions) {
8334
+ contentOverrides.set(adopted.sqlPath, adopted.sql);
8335
+ contentOverrides.set(adopted.snapshotPath, adopted.snapshot);
8336
+ files.push(managedEntry(adopted.sqlPath, adopted.sql), managedEntry(adopted.snapshotPath, adopted.snapshot));
8337
+ publishedPaths.add(adopted.sqlPath);
8338
+ publishedPaths.add(adopted.snapshotPath);
8339
+ }
8139
8340
  files.push(...input.targetManifest.files.filter(({ path: path2 }) => !isDrizzleHistoryPath(path2)));
8140
8341
  if (!additions.length) {
8141
8342
  const journalContent2 = encodeJson(project);
@@ -8164,14 +8365,14 @@ async function reconcileDrizzleMigrations(input) {
8164
8365
  const name = stableName(addition.tag);
8165
8366
  const tag = `${prefix}_${name}`;
8166
8367
  const sqlPath = `${drizzleRoot}/${tag}.sql`;
8167
- const snapshotPath = `${drizzleRoot}/meta/${prefix}_snapshot.json`;
8168
- const sql = await readFile16(join20(input.targetDirectory, `${drizzleRoot}/${addition.tag}.sql`));
8368
+ const snapshotPath2 = `${drizzleRoot}/meta/${prefix}_snapshot.json`;
8369
+ const sql = await readFile18(join21(input.targetDirectory, `${drizzleRoot}/${addition.tag}.sql`));
8169
8370
  merged.id = targetAfter.id;
8170
8371
  merged.prevId = currentSnapshot.id;
8171
8372
  const snapshot = encodeJson(merged);
8172
8373
  contentOverrides.set(sqlPath, sql);
8173
- contentOverrides.set(snapshotPath, snapshot);
8174
- files.push(managedEntry(sqlPath, sql), managedEntry(snapshotPath, snapshot));
8374
+ contentOverrides.set(snapshotPath2, snapshot);
8375
+ files.push(managedEntry(sqlPath, sql), managedEntry(snapshotPath2, snapshot));
8175
8376
  previousWhen = Math.max(previousWhen + 1, addition.when);
8176
8377
  mergedJournal.entries.push({
8177
8378
  ...addition,
@@ -8212,9 +8413,9 @@ function unchanged(targetManifest) {
8212
8413
  async function readJournals(input) {
8213
8414
  try {
8214
8415
  const [base, project, target] = await Promise.all([
8215
- readJson(join20(input.baseDirectory, journalPath)),
8416
+ readJson(join21(input.baseDirectory, journalPath)),
8216
8417
  readProjectJson(input, journalPath),
8217
- readJson(join20(input.targetDirectory, journalPath))
8418
+ readJson(join21(input.targetDirectory, journalPath))
8218
8419
  ]);
8219
8420
  return { base, project, target };
8220
8421
  } catch (error) {
@@ -8237,79 +8438,31 @@ async function readLatestSnapshot(input, journal) {
8237
8438
  const latest = journal.entries.at(-1);
8238
8439
  if (!latest)
8239
8440
  throw new Error(`${journalPath}\uFF1A\u5F53\u524D\u9879\u76EE\u6CA1\u6709 migration`);
8240
- const match = migrationPattern.exec(latest.tag);
8241
- if (!match) {
8242
- throw new Error(`${journalPath}\uFF1Amigration tag \u683C\u5F0F\u65E0\u6548\uFF1A${latest.tag}`);
8243
- }
8244
- const snapshotPath = `${drizzleRoot}/meta/${match[1]}_snapshot.json`;
8245
- const content = await readProjectFile(input, snapshotPath);
8441
+ const path2 = snapshotPath(latest.tag);
8442
+ const content = await readProjectFile(input, path2);
8246
8443
  if (!content) {
8247
- throw new Error(`\u5F53\u524D\u9879\u76EE migration \u6587\u4EF6\u7F3A\u5931\uFF1A${snapshotPath}`);
8444
+ throw new Error(`\u5F53\u524D\u9879\u76EE migration \u6587\u4EF6\u7F3A\u5931\uFF1A${path2}`);
8248
8445
  }
8249
8446
  return JSON.parse(new TextDecoder().decode(content));
8250
8447
  }
8251
8448
  async function readSnapshot(root, tag) {
8252
- const match = migrationPattern.exec(tag);
8253
- if (!match)
8254
- throw new Error(`${journalPath}\uFF1Amigration tag \u683C\u5F0F\u65E0\u6548\uFF1A${tag}`);
8255
- return await readJson(join20(root, `${drizzleRoot}/meta/${match[1]}_snapshot.json`));
8256
- }
8257
- function validateUniqueNames(journal, label, conflicts) {
8258
- const seen = new Set;
8259
- for (const { tag } of journal.entries) {
8260
- const name = stableName(tag);
8261
- if (seen.has(name)) {
8262
- conflicts.push(`${journalPath}\uFF1A${label}\u5B58\u5728\u91CD\u590D migration \u540D\u79F0 ${name}`);
8263
- }
8264
- seen.add(name);
8265
- }
8266
- }
8267
- function stableName(tag) {
8268
- return migrationPattern.exec(tag)?.[2] ?? tag;
8269
- }
8270
- function highestPrefix(journal) {
8271
- return Math.max(-1, ...journal.entries.map(({ tag }) => Number(migrationPattern.exec(tag)?.[1] ?? -1)));
8272
- }
8273
- function highestIndex(journal) {
8274
- return Math.max(-1, ...journal.entries.map(({ idx }) => idx));
8275
- }
8276
- function isDrizzleHistoryPath(path2) {
8277
- return path2 === journalPath || isMigrationArtifact(path2);
8278
- }
8279
- function isMigrationArtifact(path2) {
8280
- return isSqlMigration(path2) || new RegExp(`^${drizzleRoot}/meta/\\d{4}_snapshot\\.json$`).test(path2);
8281
- }
8282
- function isSqlMigration(path2) {
8283
- return new RegExp(`^${drizzleRoot}/\\d{4}_.+\\.sql$`).test(path2);
8284
- }
8285
- function managedEntry(path2, content) {
8286
- return { path: path2, ownership: "windy-managed", hash: hashContent(content) };
8287
- }
8288
- function deduplicate(files) {
8289
- return [...new Map(files.map((entry) => [entry.path, entry])).values()];
8290
- }
8291
- function encodeJson(value) {
8292
- return new TextEncoder().encode(`${JSON.stringify(value, null, 2)}
8293
- `);
8294
- }
8295
- async function readJson(path2) {
8296
- return JSON.parse(await readFile16(path2, "utf8"));
8449
+ return await readJson(join21(root, snapshotPath(tag)));
8297
8450
  }
8298
8451
 
8299
8452
  // src/update/planner-file.ts
8300
- import { readFile as readFile17 } from "fs/promises";
8301
- import { join as join22 } from "path";
8453
+ import { readFile as readFile19 } from "fs/promises";
8454
+ import { join as join23 } from "path";
8302
8455
 
8303
8456
  // src/update/merge.ts
8304
8457
  import { mkdtemp as mkdtemp2, rm as rm6, writeFile as writeFile12 } from "fs/promises";
8305
8458
  import { tmpdir as tmpdir2 } from "os";
8306
- import { join as join21 } from "path";
8459
+ import { join as join22 } from "path";
8307
8460
  async function mergeTextFile(base, ours, theirs) {
8308
- const root = await mkdtemp2(join21(tmpdir2(), "windy-merge-"));
8461
+ const root = await mkdtemp2(join22(tmpdir2(), "windy-merge-"));
8309
8462
  try {
8310
- const oursPath = join21(root, "ours");
8311
- const basePath = join21(root, "base");
8312
- const theirsPath = join21(root, "theirs");
8463
+ const oursPath = join22(root, "ours");
8464
+ const basePath = join22(root, "base");
8465
+ const theirsPath = join22(root, "theirs");
8313
8466
  await Promise.all([
8314
8467
  writeFile12(oursPath, ours),
8315
8468
  writeFile12(basePath, base),
@@ -8497,6 +8650,11 @@ function mergeValue(base, ours, theirs, path2, conflicts) {
8497
8650
  return theirs;
8498
8651
  if (equal(theirs, base))
8499
8652
  return ours;
8653
+ if (path2 === "package.json.files") {
8654
+ const files = mergeAppendOnlyStringSet(base, ours, theirs);
8655
+ if (files)
8656
+ return files;
8657
+ }
8500
8658
  if (isObject(base) && isObject(ours) && isObject(theirs)) {
8501
8659
  const output = {};
8502
8660
  const keys = new Set([
@@ -8517,6 +8675,15 @@ function mergeValue(base, ours, theirs, path2, conflicts) {
8517
8675
  function equal(left, right) {
8518
8676
  return JSON.stringify(left) === JSON.stringify(right);
8519
8677
  }
8678
+ function mergeAppendOnlyStringSet(base, ours, theirs) {
8679
+ if (!isStringArray(base) || !isStringArray(ours) || !isStringArray(theirs) || !base.every((value) => ours.includes(value) && theirs.includes(value))) {
8680
+ return;
8681
+ }
8682
+ return [...new Set([...ours, ...theirs])].sort();
8683
+ }
8684
+ function isStringArray(value) {
8685
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
8686
+ }
8520
8687
  function isObject(value) {
8521
8688
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
8522
8689
  }
@@ -8567,8 +8734,8 @@ function conflict(path2, reason, expectedProjectContent) {
8567
8734
  // src/update/planner-file.ts
8568
8735
  async function planFile(path2, baseRoot, targetRoot, source, target, ours, provenance, targetContentOverride, manageGeneratedProjectOwned = false, forcePlatformBaseline = false) {
8569
8736
  const [base, theirs] = await Promise.all([
8570
- readOptional(join22(baseRoot, path2)),
8571
- targetContentOverride ? Promise.resolve(targetContentOverride) : readOptional(join22(targetRoot, path2))
8737
+ readOptional(join23(baseRoot, path2)),
8738
+ targetContentOverride ? Promise.resolve(targetContentOverride) : readOptional(join23(targetRoot, path2))
8572
8739
  ]);
8573
8740
  const ownership = source?.ownership ?? target?.ownership ?? classifyOwnership(path2);
8574
8741
  const expected = expectationForSnapshot(ours);
@@ -8675,7 +8842,7 @@ function conflict2(path2, ownership, reason, expectedProjectContent) {
8675
8842
  }
8676
8843
  async function readOptional(path2) {
8677
8844
  try {
8678
- return await readFile17(path2);
8845
+ return await readFile19(path2);
8679
8846
  } catch (error) {
8680
8847
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
8681
8848
  return;
@@ -8700,27 +8867,27 @@ function resolveModuleRecipeIds(request) {
8700
8867
  }
8701
8868
 
8702
8869
  // src/update/planner-snapshots.ts
8703
- import { readFile as readFile18, stat as stat2 } from "fs/promises";
8704
- import { join as join23 } from "path";
8870
+ import { readFile as readFile20, stat as stat2 } from "fs/promises";
8871
+ import { join as join24 } from "path";
8705
8872
  async function snapshotProjectFiles(project, paths, seed) {
8706
8873
  const snapshots = new Map(seed);
8707
8874
  await Promise.all([...paths].filter((path2) => !snapshots.has(path2)).map(async (path2) => {
8708
- snapshots.set(path2, await readOptional2(join23(project, path2)));
8875
+ snapshots.set(path2, await readOptional2(join24(project, path2)));
8709
8876
  }));
8710
8877
  return snapshots;
8711
8878
  }
8712
8879
  async function snapshotProjectModes(project, paths) {
8713
- return new Map(await Promise.all([...paths].map(async (path2) => [path2, await readModeOptional(join23(project, path2))])));
8880
+ return new Map(await Promise.all([...paths].map(async (path2) => [path2, await readModeOptional(join24(project, path2))])));
8714
8881
  }
8715
8882
  async function assertPlanSnapshots(project, expectations) {
8716
8883
  const changed = [];
8717
8884
  for (const expectation2 of expectations) {
8718
- const actual = expectationForSnapshot(await readOptional2(join23(project, expectation2.path)));
8885
+ const actual = expectationForSnapshot(await readOptional2(join24(project, expectation2.path)));
8719
8886
  if (JSON.stringify(actual) !== JSON.stringify(expectation2.expected)) {
8720
8887
  changed.push(expectation2.path);
8721
8888
  continue;
8722
8889
  }
8723
- if ("mode" in expectation2 && await readModeOptional(join23(project, expectation2.path)) !== expectation2.mode) {
8890
+ if ("mode" in expectation2 && await readModeOptional(join24(project, expectation2.path)) !== expectation2.mode) {
8724
8891
  changed.push(expectation2.path);
8725
8892
  }
8726
8893
  }
@@ -8752,7 +8919,7 @@ async function readSourceParentMode(path2) {
8752
8919
  }
8753
8920
  async function readOptional2(path2) {
8754
8921
  try {
8755
- return await readFile18(path2);
8922
+ return await readFile20(path2);
8756
8923
  } catch (error) {
8757
8924
  if (isMissing7(error))
8758
8925
  return;
@@ -8796,8 +8963,8 @@ var oxcManagedPaths = new Set([
8796
8963
  ]);
8797
8964
  async function createUpdatePlan(request, artifacts) {
8798
8965
  await assertProjectReadyForUpdate(request.projectDirectory);
8799
- const manifestPath = join24(request.projectDirectory, ".windy/files.json");
8800
- const expectedManifestHash = hashContent(await readFile19(manifestPath));
8966
+ const manifestPath = join25(request.projectDirectory, ".windy/files.json");
8967
+ const expectedManifestHash = hashContent(await readFile21(manifestPath));
8801
8968
  const generationSnapshot = await readGenerationProvenanceSnapshot(request.projectDirectory);
8802
8969
  const provenance = generationSnapshot.provenance;
8803
8970
  const targetModules = resolveUpdateTargetModules(provenance.modules.map(({ name }) => name), request.targetModules);
@@ -8843,8 +9010,8 @@ async function createUpdatePlan(request, artifacts) {
8843
9010
  const paths = new Set([...sourceEntries.keys(), ...targetEntries.keys()]);
8844
9011
  for (const path2 of paths) {
8845
9012
  if (!projectSnapshots.has(path2)) {
8846
- projectSnapshots.set(path2, await readOptional2(join24(request.projectDirectory, path2)));
8847
- projectModes.set(path2, await readModeOptional(join24(request.projectDirectory, path2)));
9013
+ projectSnapshots.set(path2, await readOptional2(join25(request.projectDirectory, path2)));
9014
+ projectModes.set(path2, await readModeOptional(join25(request.projectDirectory, path2)));
8848
9015
  }
8849
9016
  }
8850
9017
  const files = await planFiles({
@@ -8866,10 +9033,10 @@ async function createUpdatePlan(request, artifacts) {
8866
9033
  for (const file of files) {
8867
9034
  file.expectedProjectMode = projectModes.get(file.path);
8868
9035
  if (file.action === "create" || file.action === "update") {
8869
- file.mode = file.expectedProjectMode ?? await readModeOptional(join24(artifactSet.targetDirectory, file.path));
9036
+ file.mode = file.expectedProjectMode ?? await readModeOptional(join25(artifactSet.targetDirectory, file.path));
8870
9037
  }
8871
9038
  if (file.action === "create") {
8872
- file.parentMode = await readSourceParentMode(join24(artifactSet.targetDirectory, dirname7(file.path)));
9039
+ file.parentMode = await readSourceParentMode(join25(artifactSet.targetDirectory, dirname7(file.path)));
8873
9040
  }
8874
9041
  }
8875
9042
  const plannedPaths = new Set(files.map(({ path: path2 }) => path2));
@@ -8889,7 +9056,7 @@ async function createUpdatePlan(request, artifacts) {
8889
9056
  ...migrations.conflicts,
8890
9057
  ...files.flatMap((file) => file.conflict ? [`${file.path}\uFF1A${file.conflict}`] : [])
8891
9058
  ];
8892
- if (hashContent(await readFile19(manifestPath)) !== expectedManifestHash) {
9059
+ if (hashContent(await readFile21(manifestPath)) !== expectedManifestHash) {
8893
9060
  throw new Error("\u751F\u6210\u66F4\u65B0\u8BA1\u5212\u671F\u95F4\u53D7\u7BA1\u6E05\u5355\u53D1\u751F\u53D8\u5316");
8894
9061
  }
8895
9062
  await assertPlanSnapshots(request.projectDirectory, [
@@ -9014,9 +9181,9 @@ function frozenManifestHash(file, finalizedHashes) {
9014
9181
  }
9015
9182
 
9016
9183
  // src/update/format-stabilizer.ts
9017
- import { mkdir as mkdir8, mkdtemp as mkdtemp3, readFile as readFile20, rm as rm7, writeFile as writeFile13 } from "fs/promises";
9184
+ import { mkdir as mkdir8, mkdtemp as mkdtemp3, readFile as readFile22, rm as rm7, writeFile as writeFile13 } from "fs/promises";
9018
9185
  import { tmpdir as tmpdir3 } from "os";
9019
- import { dirname as dirname8, extname as extname4, join as join25, resolve as resolve6, sep as sep5 } from "path";
9186
+ import { dirname as dirname8, extname as extname4, join as join26, resolve as resolve6, sep as sep5 } from "path";
9020
9187
  var formattedExtensions = new Set([
9021
9188
  ".cjs",
9022
9189
  ".css",
@@ -9055,7 +9222,7 @@ async function stabilizeManagedContent(result2, execute, writeProjectFile) {
9055
9222
  }
9056
9223
  }
9057
9224
  inputs.set(".windy/generation.json", new TextEncoder().encode(generationContent));
9058
- const temporaryRoot = await mkdtemp3(join25(tmpdir3(), "windy-update-format-"));
9225
+ const temporaryRoot = await mkdtemp3(join26(tmpdir3(), "windy-update-format-"));
9059
9226
  try {
9060
9227
  const stagedPaths = await stageInputs(temporaryRoot, inputs);
9061
9228
  for (let offset = 0;offset < stagedPaths.length; offset += 80) {
@@ -9063,14 +9230,14 @@ async function stabilizeManagedContent(result2, execute, writeProjectFile) {
9063
9230
  "x",
9064
9231
  "oxfmt",
9065
9232
  "--write",
9066
- `--config=${join25(result2.plan.projectDirectory, ".oxfmtrc.json")}`,
9233
+ `--config=${join26(result2.plan.projectDirectory, ".oxfmtrc.json")}`,
9067
9234
  ...stagedPaths.slice(offset, offset + 80)
9068
9235
  ], result2.plan.projectDirectory);
9069
9236
  }
9070
9237
  const hashes = plannedContentHashes(result2);
9071
9238
  let formattedGeneration = generationContent;
9072
9239
  for (const [path2, original] of inputs) {
9073
- const formatted = await readFile20(safeTemporaryPath(temporaryRoot, path2));
9240
+ const formatted = await readFile22(safeTemporaryPath(temporaryRoot, path2));
9074
9241
  if (path2 === ".windy/generation.json") {
9075
9242
  formattedGeneration = formatted.toString();
9076
9243
  continue;
@@ -9224,7 +9391,7 @@ class DefaultStarterUpdater {
9224
9391
  const plannedPaths = new Set(result2.plan.files.map(({ path: path2 }) => path2));
9225
9392
  replaceExpectations(result2, verificationSnapshot.filter(({ path: path2 }) => !metadataPaths2.has(path2) && !plannedPaths.has(path2)));
9226
9393
  verificationExpectationsFrozen = true;
9227
- const packageJson = JSON.parse(await readFile21(join26(result2.plan.projectDirectory, "package.json"), "utf8"));
9394
+ const packageJson = JSON.parse(await readFile23(join27(result2.plan.projectDirectory, "package.json"), "utf8"));
9228
9395
  for (const name of ["lint", "typecheck", "test", "build"]) {
9229
9396
  if (!packageJson.scripts?.[name]) {
9230
9397
  steps.push({ name: `bun run ${name}`, status: "skipped" });
@@ -10142,20 +10309,20 @@ import {
10142
10309
  cp,
10143
10310
  mkdir as mkdir9,
10144
10311
  mkdtemp as mkdtemp4,
10145
- readFile as readFile23,
10312
+ readFile as readFile25,
10146
10313
  readdir as readdir9,
10147
10314
  rename as rename2,
10148
10315
  rm as rm11,
10149
10316
  writeFile as writeFile14
10150
10317
  } from "fs/promises";
10151
- import { dirname as dirname9, join as join27, relative as relative6 } from "path";
10318
+ import { dirname as dirname9, join as join28, relative as relative6 } from "path";
10152
10319
 
10153
10320
  // src/module-schema/config.ts
10154
- import { readFile as readFile22 } from "fs/promises";
10321
+ import { readFile as readFile24 } from "fs/promises";
10155
10322
  import { isAbsolute as isAbsolute2, relative as relative5, resolve as resolve9 } from "path";
10156
10323
  async function readModuleSchemaLineageConfig(projectDirectory, configPath) {
10157
10324
  const absolutePath = resolveProjectPath(projectDirectory, configPath);
10158
- const parsed = JSON.parse(await readFile22(absolutePath, "utf8"));
10325
+ const parsed = JSON.parse(await readFile24(absolutePath, "utf8"));
10159
10326
  if (!isConfig(parsed)) {
10160
10327
  throw new Error("Module schema lineage \u914D\u7F6E\u65E0\u6548");
10161
10328
  }
@@ -10289,17 +10456,17 @@ async function handoffModuleSchemaLineages(options) {
10289
10456
  async function stageModuleLineages(project, temporaryRoot, config, execute) {
10290
10457
  const outputs = [];
10291
10458
  for (const [index, module3] of config.modules.entries()) {
10292
- const output = join27(temporaryRoot, `module-${index}`);
10459
+ const output = join28(temporaryRoot, `module-${index}`);
10293
10460
  await mkdir9(output, { recursive: true });
10294
- const generatedConfig = join27(temporaryRoot, `module-${index}.config.ts`);
10461
+ const generatedConfig = join28(temporaryRoot, `module-${index}.config.ts`);
10295
10462
  await writeDrizzleConfig(generatedConfig, project, module3.schema, relative6(temporaryRoot, output));
10296
10463
  await execute(generatedConfig, temporaryRoot);
10297
10464
  const sqlFiles = await listSqlFiles(output);
10298
10465
  if (sqlFiles.length !== 1) {
10299
10466
  throw new Error(`${module3.key} baseline \u5FC5\u987B\u6070\u597D\u751F\u6210\u4E00\u4E2A migration`);
10300
10467
  }
10301
- await writeFile14(join27(output, sqlFiles[0]), metadataOnlySql("module"));
10302
- await writeFile14(join27(output, "lineage.json"), `${JSON.stringify({
10468
+ await writeFile14(join28(output, sqlFiles[0]), metadataOnlySql("module"));
10469
+ await writeFile14(join28(output, "lineage.json"), `${JSON.stringify({
10303
10470
  schemaVersion: 1,
10304
10471
  moduleKey: module3.key,
10305
10472
  schema: module3.schema,
@@ -10313,25 +10480,25 @@ async function stageModuleLineages(project, temporaryRoot, config, execute) {
10313
10480
  }
10314
10481
  async function stagePlatformLineage(project, temporaryRoot, config, execute) {
10315
10482
  const source = resolveProjectPath(project, config.platform.out);
10316
- const output = join27(temporaryRoot, "platform");
10483
+ const output = join28(temporaryRoot, "platform");
10317
10484
  await cp(source, output, { recursive: true });
10318
10485
  const before = new Set(await listSqlFiles(output));
10319
- const generatedConfig = join27(temporaryRoot, "platform.config.ts");
10486
+ const generatedConfig = join28(temporaryRoot, "platform.config.ts");
10320
10487
  await writeDrizzleConfig(generatedConfig, project, config.platform.schema, relative6(temporaryRoot, output));
10321
10488
  await execute(generatedConfig, temporaryRoot);
10322
10489
  const created = (await listSqlFiles(output)).filter((path2) => !before.has(path2));
10323
10490
  if (created.length !== 1) {
10324
10491
  throw new Error("\u5E73\u53F0 lineage handoff \u5FC5\u987B\u6070\u597D\u751F\u6210\u4E00\u4E2A migration");
10325
10492
  }
10326
- const sqlPath = join27(output, created[0]);
10493
+ const sqlPath = join28(output, created[0]);
10327
10494
  const allowed = config.modules.flatMap(({ legacyPlatformTables }) => legacyPlatformTables);
10328
- validatePlatformHandoffSql(await readFile23(sqlPath, "utf8"), allowed);
10495
+ validatePlatformHandoffSql(await readFile25(sqlPath, "utf8"), allowed);
10329
10496
  await writeFile14(sqlPath, metadataOnlySql("platform"));
10330
10497
  return output;
10331
10498
  }
10332
10499
  async function installStagedLineages(project, temporaryRoot, config, stagedModules, stagedPlatform) {
10333
10500
  const platform = resolveProjectPath(project, config.platform.out);
10334
- const backup = join27(temporaryRoot, "platform-backup");
10501
+ const backup = join28(temporaryRoot, "platform-backup");
10335
10502
  const installed = [];
10336
10503
  await rename2(platform, backup);
10337
10504
  try {
@@ -10378,9 +10545,9 @@ async function validateSchemaSources(project, config) {
10378
10545
  }
10379
10546
  }
10380
10547
  async function createTemporaryRoot(project) {
10381
- const windy = join27(project, ".windy");
10548
+ const windy = join28(project, ".windy");
10382
10549
  await mkdir9(windy, { recursive: true });
10383
- return await mkdtemp4(join27(windy, "module-schema-handoff-"));
10550
+ return await mkdtemp4(join28(windy, "module-schema-handoff-"));
10384
10551
  }
10385
10552
  async function listSqlFiles(root) {
10386
10553
  return (await readdir9(root)).filter((path2) => path2.endsWith(".sql")).sort();