@prisma-next/cli 0.12.0-dev.6 → 0.12.0-dev.60

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 (201) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.mjs +180 -163
  3. package/dist/cli.mjs.map +1 -1
  4. package/dist/{client-KgJorIvG.mjs → client-DQvxtihf.mjs} +194 -105
  5. package/dist/client-DQvxtihf.mjs.map +1 -0
  6. package/dist/{command-helpers-Bbw1GbwL.mjs → command-helpers-CxHSiwEg.mjs} +318 -25
  7. package/dist/command-helpers-CxHSiwEg.mjs.map +1 -0
  8. package/dist/commands/contract-emit.d.mts.map +1 -1
  9. package/dist/commands/contract-emit.mjs +1 -1
  10. package/dist/commands/contract-infer.d.mts.map +1 -1
  11. package/dist/commands/contract-infer.mjs +1 -1
  12. package/dist/commands/db-init.d.mts.map +1 -1
  13. package/dist/commands/db-init.mjs +4 -5
  14. package/dist/commands/db-init.mjs.map +1 -1
  15. package/dist/commands/db-schema.d.mts.map +1 -1
  16. package/dist/commands/db-schema.mjs +3 -3
  17. package/dist/commands/db-schema.mjs.map +1 -1
  18. package/dist/commands/db-sign.d.mts.map +1 -1
  19. package/dist/commands/db-sign.mjs +6 -6
  20. package/dist/commands/db-sign.mjs.map +1 -1
  21. package/dist/commands/db-update.d.mts.map +1 -1
  22. package/dist/commands/db-update.mjs +10 -7
  23. package/dist/commands/db-update.mjs.map +1 -1
  24. package/dist/commands/db-verify.d.mts.map +1 -1
  25. package/dist/commands/db-verify.mjs +1 -1
  26. package/dist/commands/migrate.d.mts +37 -3
  27. package/dist/commands/migrate.d.mts.map +1 -1
  28. package/dist/commands/migrate.mjs +291 -12
  29. package/dist/commands/migrate.mjs.map +1 -1
  30. package/dist/commands/migration-check.d.mts +55 -13
  31. package/dist/commands/migration-check.d.mts.map +1 -1
  32. package/dist/commands/migration-check.mjs +3 -2
  33. package/dist/commands/migration-graph.d.mts +17 -8
  34. package/dist/commands/migration-graph.d.mts.map +1 -1
  35. package/dist/commands/migration-graph.mjs +185 -2
  36. package/dist/commands/migration-graph.mjs.map +1 -0
  37. package/dist/commands/migration-list.d.mts +26 -27
  38. package/dist/commands/migration-list.d.mts.map +1 -1
  39. package/dist/commands/migration-list.mjs +2 -190
  40. package/dist/commands/migration-log.d.mts +9 -19
  41. package/dist/commands/migration-log.d.mts.map +1 -1
  42. package/dist/commands/migration-log.mjs +1 -137
  43. package/dist/commands/migration-new.d.mts.map +1 -1
  44. package/dist/commands/migration-new.mjs +4 -4
  45. package/dist/commands/migration-new.mjs.map +1 -1
  46. package/dist/commands/migration-plan.d.mts +1 -1
  47. package/dist/commands/migration-plan.d.mts.map +1 -1
  48. package/dist/commands/migration-plan.mjs +1 -1
  49. package/dist/commands/migration-show.d.mts +17 -21
  50. package/dist/commands/migration-show.d.mts.map +1 -1
  51. package/dist/commands/migration-show.mjs +24 -36
  52. package/dist/commands/migration-show.mjs.map +1 -1
  53. package/dist/commands/migration-status.d.mts +42 -144
  54. package/dist/commands/migration-status.d.mts.map +1 -1
  55. package/dist/commands/migration-status.mjs +3 -759
  56. package/dist/commands/ref.d.mts +1 -1
  57. package/dist/commands/ref.d.mts.map +1 -1
  58. package/dist/commands/ref.mjs +4 -4
  59. package/dist/commands/ref.mjs.map +1 -1
  60. package/dist/commands/telemetry/index.d.mts +7 -0
  61. package/dist/commands/telemetry/index.d.mts.map +1 -0
  62. package/dist/commands/telemetry/index.mjs +2 -0
  63. package/dist/{config-loader-B6sJjXTv.mjs → config-loader-p9JMrekQ.mjs} +1 -1
  64. package/dist/{config-loader-B6sJjXTv.mjs.map → config-loader-p9JMrekQ.mjs.map} +1 -1
  65. package/dist/config-loader.mjs +1 -1
  66. package/dist/{contract-at-errors-BxP-TOMl.mjs → contract-at-errors-gBvfOS8r.mjs} +2 -2
  67. package/dist/{contract-at-errors-BxP-TOMl.mjs.map → contract-at-errors-gBvfOS8r.mjs.map} +1 -1
  68. package/dist/{contract-emit-DxcGl4Uq.mjs → contract-emit-By59Nmmn.mjs} +5 -5
  69. package/dist/{contract-emit-DxcGl4Uq.mjs.map → contract-emit-By59Nmmn.mjs.map} +1 -1
  70. package/dist/{contract-emit-D-4jrNve.mjs → contract-emit-OpMbysHj.mjs} +7 -7
  71. package/dist/{contract-emit-D-4jrNve.mjs.map → contract-emit-OpMbysHj.mjs.map} +1 -1
  72. package/dist/{contract-enrichment-a0V5Y_mL.mjs → contract-enrichment-gn9sWbPw.mjs} +1 -1
  73. package/dist/{contract-enrichment-a0V5Y_mL.mjs.map → contract-enrichment-gn9sWbPw.mjs.map} +1 -1
  74. package/dist/{contract-infer-D8uEbJuu.mjs → contract-infer-BkyyYGDf.mjs} +3 -3
  75. package/dist/{contract-infer-D8uEbJuu.mjs.map → contract-infer-BkyyYGDf.mjs.map} +1 -1
  76. package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs → contract-space-aggregate-loader-Bup14UkI.mjs} +63 -5
  77. package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs.map → contract-space-aggregate-loader-Bup14UkI.mjs.map} +1 -1
  78. package/dist/{db-verify-v_vUKXTU.mjs → db-verify-DbmfgeYc.mjs} +6 -6
  79. package/dist/{db-verify-v_vUKXTU.mjs.map → db-verify-DbmfgeYc.mjs.map} +1 -1
  80. package/dist/exports/control-api.d.mts +2 -2
  81. package/dist/exports/control-api.d.mts.map +1 -1
  82. package/dist/exports/control-api.mjs +3 -3
  83. package/dist/exports/index.mjs +1 -1
  84. package/dist/exports/index.mjs.map +1 -1
  85. package/dist/exports/init-output.d.mts +1 -3
  86. package/dist/exports/init-output.d.mts.map +1 -1
  87. package/dist/exports/init-output.mjs +1 -1
  88. package/dist/{framework-components-fYXjz_in.mjs → framework-components-CmBpbvzV.mjs} +2 -2
  89. package/dist/{framework-components-fYXjz_in.mjs.map → framework-components-CmBpbvzV.mjs.map} +1 -1
  90. package/dist/{global-flags-DEHjV8_s.d.mts → global-flags-BpoOYtNZ.d.mts} +1 -1
  91. package/dist/{global-flags-DEHjV8_s.d.mts.map → global-flags-BpoOYtNZ.d.mts.map} +1 -1
  92. package/dist/{init-Cv9UzWL5.mjs → init-tidQpK21.mjs} +5 -58
  93. package/dist/init-tidQpK21.mjs.map +1 -0
  94. package/dist/{inspect-live-schema-C6ohV_oQ.mjs → inspect-live-schema-CUvD_9uF.mjs} +5 -5
  95. package/dist/{inspect-live-schema-C6ohV_oQ.mjs.map → inspect-live-schema-CUvD_9uF.mjs.map} +1 -1
  96. package/dist/migration-check-BjNlXTGF.mjs +572 -0
  97. package/dist/migration-check-BjNlXTGF.mjs.map +1 -0
  98. package/dist/migration-cli.mjs +1 -1
  99. package/dist/migration-cli.mjs.map +1 -1
  100. package/dist/{migration-command-scaffold-CjvwO6at.mjs → migration-command-scaffold-DWlpBp98.mjs} +5 -5
  101. package/dist/{migration-command-scaffold-CjvwO6at.mjs.map → migration-command-scaffold-DWlpBp98.mjs.map} +1 -1
  102. package/dist/migration-graph-space-render-Cpg0ql8v.mjs +2370 -0
  103. package/dist/migration-graph-space-render-Cpg0ql8v.mjs.map +1 -0
  104. package/dist/migration-list-zP59uUBC.mjs +230 -0
  105. package/dist/migration-list-zP59uUBC.mjs.map +1 -0
  106. package/dist/migration-log-DoytJNuF.mjs +222 -0
  107. package/dist/migration-log-DoytJNuF.mjs.map +1 -0
  108. package/dist/migration-path-target-DjbhWi_5.mjs +38 -0
  109. package/dist/migration-path-target-DjbhWi_5.mjs.map +1 -0
  110. package/dist/{migration-plan-9DJ7q7_z.mjs → migration-plan-CgCXpjYD.mjs} +6 -7
  111. package/dist/{migration-plan-9DJ7q7_z.mjs.map → migration-plan-CgCXpjYD.mjs.map} +1 -1
  112. package/dist/migration-status-ByptVtRZ.mjs +446 -0
  113. package/dist/migration-status-ByptVtRZ.mjs.map +1 -0
  114. package/dist/{output-B60Gw5fu.mjs → output-mEQ74_nd.mjs} +1 -1
  115. package/dist/{output-B60Gw5fu.mjs.map → output-mEQ74_nd.mjs.map} +1 -1
  116. package/dist/{progress-adapter-C644QK8l.mjs → progress-adapter-CjAeTxY_.mjs} +1 -1
  117. package/dist/{progress-adapter-C644QK8l.mjs.map → progress-adapter-CjAeTxY_.mjs.map} +1 -1
  118. package/dist/{ref-advancement-DUZqsue6.mjs → ref-advancement-BkXlikCA.mjs} +1 -1
  119. package/dist/{ref-advancement-DUZqsue6.mjs.map → ref-advancement-BkXlikCA.mjs.map} +1 -1
  120. package/dist/schemas-CeGMYFYX.d.mts +191 -0
  121. package/dist/schemas-CeGMYFYX.d.mts.map +1 -0
  122. package/dist/schemas-KhXMzNA_.mjs +112 -0
  123. package/dist/schemas-KhXMzNA_.mjs.map +1 -0
  124. package/dist/telemetry-DVv3V0gj.mjs +122 -0
  125. package/dist/telemetry-DVv3V0gj.mjs.map +1 -0
  126. package/dist/{terminal-ui-5Y6mrg93.d.mts → terminal-ui-DGRNFWna.d.mts} +1 -1
  127. package/dist/terminal-ui-DGRNFWna.d.mts.map +1 -0
  128. package/dist/{types-Dt_SfqFm.d.mts → types-BepB6ydp.d.mts} +44 -31
  129. package/dist/types-BepB6ydp.d.mts.map +1 -0
  130. package/dist/{verify-DCA9Sldu.mjs → verify-CJpG9m7-.mjs} +2 -2
  131. package/dist/{verify-DCA9Sldu.mjs.map → verify-CJpG9m7-.mjs.map} +1 -1
  132. package/package.json +25 -22
  133. package/src/cli.ts +5 -0
  134. package/src/commands/db-update.ts +7 -1
  135. package/src/commands/init/index.ts +6 -35
  136. package/src/commands/init/init.ts +1 -14
  137. package/src/commands/init/inputs.ts +0 -75
  138. package/src/commands/json/schemas.ts +195 -0
  139. package/src/commands/migrate.ts +518 -8
  140. package/src/commands/migration-check.ts +469 -134
  141. package/src/commands/migration-graph.ts +164 -91
  142. package/src/commands/migration-list.ts +72 -39
  143. package/src/commands/migration-log.ts +52 -102
  144. package/src/commands/migration-show.ts +31 -66
  145. package/src/commands/migration-status-overlay.ts +61 -0
  146. package/src/commands/migration-status.ts +457 -1067
  147. package/src/commands/telemetry/index.ts +107 -0
  148. package/src/commands/telemetry/status.ts +67 -0
  149. package/src/control-api/client.ts +20 -9
  150. package/src/control-api/operations/contract-emit.ts +2 -2
  151. package/src/control-api/operations/db-init.ts +3 -3
  152. package/src/control-api/operations/{db-apply.ts → db-run.ts} +51 -13
  153. package/src/control-api/operations/db-update.ts +4 -4
  154. package/src/control-api/operations/db-verify.ts +15 -5
  155. package/src/control-api/operations/{migration-apply.ts → migrate.ts} +181 -80
  156. package/src/control-api/operations/{apply.ts → run-migration.ts} +33 -27
  157. package/src/control-api/types.ts +46 -29
  158. package/src/utils/cli-errors.ts +70 -2
  159. package/src/utils/formatters/errors.ts +11 -0
  160. package/src/utils/formatters/migration-graph-lane-colors.ts +194 -0
  161. package/src/utils/formatters/migration-graph-layout.ts +227 -38
  162. package/src/utils/formatters/migration-graph-rows.ts +128 -15
  163. package/src/utils/formatters/migration-graph-space-render.ts +148 -0
  164. package/src/utils/formatters/migration-graph-tree-render.ts +959 -81
  165. package/src/utils/formatters/migration-list-data-column.ts +4 -91
  166. package/src/utils/formatters/migration-list-graph-topology.ts +72 -94
  167. package/src/utils/formatters/migration-list-render.ts +135 -71
  168. package/src/utils/formatters/migration-list-styler.ts +46 -5
  169. package/src/utils/formatters/migration-list-types.ts +5 -21
  170. package/src/utils/formatters/migration-log-table.ts +205 -0
  171. package/src/utils/formatters/migrations.ts +33 -11
  172. package/src/utils/global-flags.ts +35 -0
  173. package/src/utils/integrity-violation-to-check-failure.ts +28 -19
  174. package/src/utils/legend.ts +38 -0
  175. package/src/utils/migration-path-target.ts +60 -0
  176. package/src/utils/telemetry.ts +68 -32
  177. package/dist/client-KgJorIvG.mjs.map +0 -1
  178. package/dist/command-helpers-Bbw1GbwL.mjs.map +0 -1
  179. package/dist/commands/migration-list.mjs.map +0 -1
  180. package/dist/commands/migration-log.mjs.map +0 -1
  181. package/dist/commands/migration-status.mjs.map +0 -1
  182. package/dist/extension-pack-inputs-IDvjRCi3.mjs +0 -62
  183. package/dist/extension-pack-inputs-IDvjRCi3.mjs.map +0 -1
  184. package/dist/graph-render-rFAqZujX.mjs +0 -1081
  185. package/dist/graph-render-rFAqZujX.mjs.map +0 -1
  186. package/dist/init-Cv9UzWL5.mjs.map +0 -1
  187. package/dist/migration-check-BiBJoYYW.mjs +0 -341
  188. package/dist/migration-check-BiBJoYYW.mjs.map +0 -1
  189. package/dist/migration-graph-D7DVUElV.mjs +0 -1232
  190. package/dist/migration-graph-D7DVUElV.mjs.map +0 -1
  191. package/dist/migration-list-styler-BRwF4-gy.mjs +0 -399
  192. package/dist/migration-list-styler-BRwF4-gy.mjs.map +0 -1
  193. package/dist/migration-types-D2FW63pr.d.mts +0 -15
  194. package/dist/migration-types-D2FW63pr.d.mts.map +0 -1
  195. package/dist/migrations-Cv2jxNNK.mjs +0 -228
  196. package/dist/migrations-Cv2jxNNK.mjs.map +0 -1
  197. package/dist/terminal-ui-5Y6mrg93.d.mts.map +0 -1
  198. package/dist/types-Dt_SfqFm.d.mts.map +0 -1
  199. package/src/utils/formatters/graph-migration-mapper.ts +0 -235
  200. package/src/utils/formatters/graph-render.ts +0 -1323
  201. package/src/utils/formatters/graph-types.ts +0 -120
@@ -2,7 +2,11 @@ import type {
2
2
  ContractSourceDiagnostics,
3
3
  ContractSourceProvider,
4
4
  } from '@prisma-next/config/config-types';
5
- import type { Contract, ContractMarkerRecord } from '@prisma-next/contract/types';
5
+ import type {
6
+ Contract,
7
+ ContractMarkerRecord,
8
+ LedgerEntryRecord,
9
+ } from '@prisma-next/contract/types';
6
10
  import type {
7
11
  ControlAdapterDescriptor,
8
12
  ControlDriverDescriptor,
@@ -67,7 +71,7 @@ export type ControlActionName =
67
71
  | 'dbInit'
68
72
  | 'dbUpdate'
69
73
  | 'dbVerify'
70
- | 'migrationApply'
74
+ | 'migrate'
71
75
  | 'verify'
72
76
  | 'schemaVerify'
73
77
  | 'sign'
@@ -391,6 +395,7 @@ export interface DbInitSuccess {
391
395
  */
392
396
  readonly perSpace?: ReadonlyArray<PerSpaceExecutionEntry>;
393
397
  readonly summary: string;
398
+ readonly warnings?: ReadonlyArray<MigrationPlannerConflict>;
394
399
  }
395
400
 
396
401
  /**
@@ -406,6 +411,7 @@ export interface DbInitFailure {
406
411
  readonly summary: string;
407
412
  readonly why: string | undefined;
408
413
  readonly conflicts: ReadonlyArray<MigrationPlannerConflict> | undefined;
414
+ readonly warnings?: ReadonlyArray<MigrationPlannerConflict>;
409
415
  readonly meta: Record<string, unknown> | undefined;
410
416
  readonly marker?: {
411
417
  readonly storageHash?: string;
@@ -461,6 +467,7 @@ export interface DbUpdateSuccess {
461
467
  */
462
468
  readonly perSpace?: ReadonlyArray<PerSpaceExecutionEntry>;
463
469
  readonly summary: string;
470
+ readonly warnings?: ReadonlyArray<MigrationPlannerConflict>;
464
471
  }
465
472
 
466
473
  /**
@@ -476,6 +483,7 @@ export interface DbUpdateFailure {
476
483
  readonly summary: string;
477
484
  readonly why: string | undefined;
478
485
  readonly conflicts: ReadonlyArray<MigrationPlannerConflict> | undefined;
486
+ readonly warnings?: ReadonlyArray<MigrationPlannerConflict>;
479
487
  readonly meta: Record<string, unknown> | undefined;
480
488
  }
481
489
 
@@ -532,17 +540,17 @@ export type EmitResult = Result<EmitSuccess, EmitFailure>;
532
540
  // ============================================================================
533
541
 
534
542
  /**
535
- * Options for the aggregate-walking `migrationApply` operation.
543
+ * Options for the aggregate-walking `migrate` operation.
536
544
  *
537
545
  * The control-api operation is responsible for: loading the
538
546
  * contract-space aggregate, reading per-space marker rows from the
539
547
  * live database, plotting per-space paths via `graphWalkStrategy`
540
548
  * (replay-only — no synth, no introspection), and dispatching
541
- * through the shared `applyMigration` primitive. The CLI command
549
+ * through the shared `runMigration` primitive. The CLI command
542
550
  * just resolves the descriptor surface (config, refs, contract
543
551
  * envelope, app-space migration packages) and hands the inputs in.
544
552
  */
545
- export interface MigrationApplyOptions {
553
+ export interface MigrateOptions {
546
554
  /** Already-validated app contract (the canonical "where we are heading" hash). */
547
555
  readonly contract: unknown;
548
556
  /** Migrations root directory (`migrations/` under the project). */
@@ -567,7 +575,7 @@ export interface MigrationApplyOptions {
567
575
  */
568
576
  readonly refName?: string;
569
577
  /**
570
- * Database connection. If provided, migrationApply will connect before executing.
578
+ * Database connection. If provided, migrate will connect before executing.
571
579
  * If omitted, the client must already be connected.
572
580
  */
573
581
  readonly connection?: unknown;
@@ -611,7 +619,7 @@ export interface MigrationApplyStep {
611
619
  * Per-space aggregate detail (markers, ops grouped by space) lives
612
620
  * on `perSpace[]`; this list is the per-edge view.
613
621
  */
614
- export interface MigrationApplyAppliedEntry {
622
+ export interface MigrateRanEntry {
615
623
  readonly spaceId: string;
616
624
  readonly dirName: string;
617
625
  readonly migrationHash: string;
@@ -621,13 +629,13 @@ export interface MigrationApplyAppliedEntry {
621
629
  }
622
630
 
623
631
  /**
624
- * Successful migrationApply result. Carries both the top-level fields
625
- * (`markerHash` is the **app member's** post-apply marker) and the
632
+ * Successful migrate result. Carries both the top-level fields
633
+ * (`markerHash` is the **app member's** post-migrate marker) and the
626
634
  * per-space breakdown (`perSpace` — markers / operations in canonical
627
635
  * schedule order).
628
636
  */
629
637
  /**
630
- * Path-decision summary for the **app member** post-apply. Surfaced
638
+ * Path-decision summary for the **app member** post-migrate. Surfaced
631
639
  * at the top level (and consumed by the cli-journeys suite, which
632
640
  * inspects `requiredInvariants`/`satisfiedInvariants`/
633
641
  * `selectedPath` to validate invariant routing).
@@ -635,7 +643,7 @@ export interface MigrationApplyAppliedEntry {
635
643
  * Per-space path decisions for extension members are not surfaced —
636
644
  * extensions own their own ref/invariant control.
637
645
  */
638
- export interface MigrationApplyPathDecision {
646
+ export interface MigratePathDecision {
639
647
  readonly fromHash: string;
640
648
  readonly toHash: string;
641
649
  readonly alternativeCount: number;
@@ -652,10 +660,10 @@ export interface MigrationApplyPathDecision {
652
660
  }[];
653
661
  }
654
662
 
655
- export interface MigrationApplySuccess {
663
+ export interface MigrateSuccess {
656
664
  readonly migrationsApplied: number;
657
665
  readonly markerHash: string;
658
- readonly applied: readonly MigrationApplyAppliedEntry[];
666
+ readonly applied: readonly MigrateRanEntry[];
659
667
  readonly summary: string;
660
668
  /**
661
669
  * Per-space breakdown in canonical schedule order (extensions
@@ -666,31 +674,31 @@ export interface MigrationApplySuccess {
666
674
  /**
667
675
  * Path-decision data for the app member. Present whenever the
668
676
  * graph-walk strategy ran for the app (i.e. always for the
669
- * aggregate-walking apply path). Absent only for the no-op
677
+ * aggregate-walking migrate path). Absent only for the no-op
670
678
  * "Already up to date" early return when the app has no plan.
671
679
  */
672
- readonly pathDecision?: MigrationApplyPathDecision;
680
+ readonly pathDecision?: MigratePathDecision;
673
681
  }
674
682
 
675
683
  /**
676
- * Failure codes for migrationApply operation.
684
+ * Failure codes for migrate operation.
677
685
  */
678
- export type MigrationApplyFailureCode = 'RUNNER_FAILED' | 'MIGRATION_PATH_NOT_FOUND';
686
+ export type MigrateFailureCode = 'RUNNER_FAILED' | 'MIGRATION_PATH_NOT_FOUND';
679
687
 
680
688
  /**
681
- * Failure details for migrationApply operation.
689
+ * Failure details for migrate operation.
682
690
  */
683
- export interface MigrationApplyFailure {
684
- readonly code: MigrationApplyFailureCode;
691
+ export interface MigrateFailure {
692
+ readonly code: MigrateFailureCode;
685
693
  readonly summary: string;
686
694
  readonly why: string | undefined;
687
695
  readonly meta: Record<string, unknown> | undefined;
688
696
  }
689
697
 
690
698
  /**
691
- * Result type for migrationApply operation.
699
+ * Result type for migrate operation.
692
700
  */
693
- export type MigrationApplyResult = Result<MigrationApplySuccess, MigrationApplyFailure>;
701
+ export type MigrateResult = Result<MigrateSuccess, MigrateFailure>;
694
702
 
695
703
  // ============================================================================
696
704
  // Standalone Contract Emit Types
@@ -877,17 +885,26 @@ export interface ControlClient {
877
885
  readAllMarkers(): Promise<ReadonlyMap<string, ContractMarkerRecord>>;
878
886
 
879
887
  /**
880
- * Applies pre-planned on-disk migrations to the database.
888
+ * Reads the per-migration ledger journal for `space` in apply order.
889
+ * Returns an empty array when the ledger store does not yet exist or
890
+ * has no rows for that space.
891
+ */
892
+ readLedger(space?: string): Promise<readonly LedgerEntryRecord[]>;
893
+
894
+ /**
895
+ * Advances the database along the migration graph to the target contract.
881
896
  * Each migration runs in its own transaction with full execution checks.
882
- * Resume-safe: re-running after failure picks up from the last applied migration.
897
+ * Resume-safe: re-running after failure picks up from the last run migration.
883
898
  *
884
- * @param options.originHash - Explicit source hash for the apply path
885
- * @param options.destinationHash - Explicit destination hash for the apply path
886
- * @param options.pendingMigrations - Ordered migrations to execute
887
- * @returns Result pattern: Ok with applied details, NotOk with failure details
899
+ * @param options.contract - The target contract to migrate to
900
+ * @param options.migrationsDir - Root migrations directory (`migrations/` under the project)
901
+ * @param options.refHash - Optional app-space ref override hash
902
+ * @param options.refInvariants - Required invariants on the user-supplied ref
903
+ * @param options.refName - Resolved name of the user-supplied app-space ref
904
+ * @returns Result pattern: Ok with migration details, NotOk with failure details
888
905
  * @throws If not connected, target doesn't support migrations, or infrastructure failure
889
906
  */
890
- migrationApply(options: MigrationApplyOptions): Promise<MigrationApplyResult>;
907
+ migrate(options: MigrateOptions): Promise<MigrateResult>;
891
908
 
892
909
  /**
893
910
  * Introspects the database schema.
@@ -28,7 +28,8 @@ import {
28
28
  import { errorRuntime } from '@prisma-next/errors/execution';
29
29
  import type { MigrationToolsError } from '@prisma-next/migration-tools/errors';
30
30
  import type { RefResolutionError } from '@prisma-next/migration-tools/ref-resolution';
31
- import type { MigrationApplyFailure } from '../control-api/types';
31
+ import { ifDefined } from '@prisma-next/utils/defined';
32
+ import type { MigrateFailure } from '../control-api/types';
32
33
 
33
34
  export {
34
35
  ERROR_CODE_DESTRUCTIVE_CHANGES,
@@ -108,6 +109,23 @@ export function errorRefSetEmptySentinel(hash: string): CliStructuredError {
108
109
  });
109
110
  }
110
111
 
112
+ /**
113
+ * `--legend` was combined with a machine-readable or silent output flag.
114
+ * The legend is human-only decoration on stderr.
115
+ */
116
+ export function errorLegendHumanOnly(
117
+ conflictingFlag: '--json' | '--dot' | '--quiet',
118
+ ): CliStructuredError {
119
+ return errorRuntime('`--legend` is only available for human-readable output', {
120
+ why: `\`--legend\` prints a glyph key to stderr and cannot be combined with ${conflictingFlag}.`,
121
+ fix: `Omit ${conflictingFlag} to print the legend alongside the tree, or omit --legend when using ${conflictingFlag}.`,
122
+ meta: {
123
+ code: 'MIGRATION.LEGEND_HUMAN_ONLY',
124
+ conflictingFlag,
125
+ },
126
+ });
127
+ }
128
+
111
129
  /**
112
130
  * `--space <id>` was given a value that doesn't satisfy the contract-space
113
131
  * naming rule (`[a-z][a-z0-9_-]{0,63}` per `isValidSpaceId`). Fires before
@@ -250,7 +268,7 @@ export function errorMarkerMismatch(
250
268
  });
251
269
  }
252
270
 
253
- export function errorPathUnreachable(failure: MigrationApplyFailure): CliStructuredError {
271
+ export function errorPathUnreachable(failure: MigrateFailure): CliStructuredError {
254
272
  const meta = failure.meta ?? {};
255
273
  const fromHashMeta = typeof meta['fromHash'] === 'string' ? meta['fromHash'] : null;
256
274
  // `buildPathNotFoundFailure` uses this sentinel in meta when the live marker is null.
@@ -325,10 +343,60 @@ export function mapMigrationToolsError(error: MigrationToolsError): CliStructure
325
343
  });
326
344
  }
327
345
 
346
+ /**
347
+ * Shared "needs a live database" precondition for read verbs that consult the
348
+ * marker/ledger (`migration log`, `migration status`). A command needs both a
349
+ * connection string and a control-plane driver; either missing yields the same
350
+ * `PN-CLI-4005` envelope with `meta.missingFlags` (canonical long-form flags
351
+ * per CLI Style Guide §Errors) so callers can react programmatically. Returns
352
+ * `null` when both are present.
353
+ */
354
+ export function requireLiveDatabase(args: {
355
+ readonly dbConnection: unknown;
356
+ readonly hasDriver: boolean;
357
+ readonly why: string;
358
+ readonly commandName?: string;
359
+ readonly retryCommand?: string;
360
+ }): CliStructuredError | null {
361
+ if (args.dbConnection && args.hasDriver) {
362
+ return null;
363
+ }
364
+ const missingFlags = args.dbConnection ? [] : ['--db'];
365
+ return errorDatabaseConnectionRequired({
366
+ why: args.why,
367
+ missingFlags,
368
+ ...ifDefined('commandName', args.commandName),
369
+ ...ifDefined('retryCommand', args.retryCommand),
370
+ });
371
+ }
372
+
328
373
  /**
329
374
  * Maps a `RefResolutionError` from the contract/migration reference
330
375
  * resolver into a CLI structured error envelope.
331
376
  */
377
+ /**
378
+ * A migration ref (dirName or hash-prefix) resolves in more than one contract
379
+ * space. The user must qualify with `--space <id>` to disambiguate.
380
+ */
381
+ export function errorAmbiguousMigrationRef(
382
+ ref: string,
383
+ spaceIds: readonly string[],
384
+ ): CliStructuredError {
385
+ const spaceList = spaceIds.join(', ');
386
+ return errorRuntime(
387
+ `Ambiguous migration reference: "${ref}" resolves in multiple spaces — qualify with --space <id>`,
388
+ {
389
+ why: `"${ref}" matches migrations in spaces: ${spaceList}.`,
390
+ fix: `Qualify with --space <id> to select one space. Available matching spaces: ${spaceList}.`,
391
+ meta: {
392
+ code: 'MIGRATION.AMBIGUOUS_MIGRATION_REF',
393
+ ref,
394
+ spaceIds: [...spaceIds],
395
+ },
396
+ },
397
+ );
398
+ }
399
+
332
400
  export function mapRefResolutionError(error: RefResolutionError): CliStructuredError {
333
401
  switch (error.kind) {
334
402
  case 'not-found':
@@ -1,8 +1,11 @@
1
+ import type { MigrationPlannerConflict } from '@prisma-next/framework-components/control';
2
+ import { blindCast } from '@prisma-next/utils/casts';
1
3
  import { red } from 'colorette';
2
4
 
3
5
  import type { CliErrorConflict, CliErrorEnvelope } from '../cli-errors';
4
6
  import type { GlobalFlags } from '../global-flags';
5
7
  import { createColorFormatter, formatDim, isVerbose } from './helpers';
8
+ import { formatPlannerWarningsBlock } from './migrations';
6
9
 
7
10
  /**
8
11
  * Formats error output for human-readable display.
@@ -67,6 +70,14 @@ export function formatErrorOutput(error: CliErrorEnvelope, flags: GlobalFlags):
67
70
  if (error.docsUrl && isVerbose(flags, 1)) {
68
71
  lines.push(formatDimText(error.docsUrl));
69
72
  }
73
+ const plannerWarnings = error.meta?.['plannerWarnings'];
74
+ if (Array.isArray(plannerWarnings) && plannerWarnings.length > 0) {
75
+ const typedWarnings = blindCast<
76
+ readonly MigrationPlannerConflict[],
77
+ 'mapDbUpdateFailure (db-update.ts) writes meta.plannerWarnings as MigrationPlannerConflict[]; meta is typed Record<string, unknown> so the channel erases the element type'
78
+ >(plannerWarnings);
79
+ lines.push(...formatPlannerWarningsBlock(typedWarnings, useColor));
80
+ }
70
81
  if (isVerbose(flags, 2) && error.meta) {
71
82
  lines.push(`${formatDimText(` Meta: ${JSON.stringify(error.meta, null, 2)}`)}`);
72
83
  }
@@ -0,0 +1,194 @@
1
+ import { createColors } from 'colorette';
2
+ import type { StructuralCell } from './migration-graph-layout';
3
+
4
+ export type LaneColorizer = (text: string) => string;
5
+
6
+ const { magenta, cyan, green, yellow, blueBright, red } = createColors({ useColor: true });
7
+
8
+ export const LANE_COLOR_CYCLE: readonly LaneColorizer[] = [
9
+ magenta,
10
+ cyan,
11
+ green,
12
+ yellow,
13
+ blueBright,
14
+ red,
15
+ ];
16
+
17
+ /**
18
+ * The leftmost lane (column 0) renders neutral — no palette hue. Columns ≥ 1
19
+ * rotate through {@link LANE_COLOR_CYCLE}.
20
+ */
21
+ export const NEUTRAL_LANE_COLUMN = 0;
22
+
23
+ /**
24
+ * The hue for a gutter column. The leftmost lane (column 0) is **neutral** — it
25
+ * has nothing to be told apart from in the common single-lane linear case, so
26
+ * the renderer dims it rather than tinting it; the rotating palette is reserved
27
+ * for columns ≥ 1 (where a second lane exists to distinguish). Callers must dim
28
+ * column 0 themselves; this returns identity for it as a guard. A lane freed and
29
+ * reused by a later branch keeps its column's hue — coloring is by position, not
30
+ * branch identity, exactly like `git log --graph`.
31
+ */
32
+ export function laneColorForColumn(column: number): LaneColorizer {
33
+ if (column <= NEUTRAL_LANE_COLUMN) {
34
+ return (text) => text;
35
+ }
36
+ const colorizer = LANE_COLOR_CYCLE[(column - 1) % LANE_COLOR_CYCLE.length];
37
+ return colorizer ?? ((text) => text);
38
+ }
39
+
40
+ /**
41
+ * Style a structural glyph by its resolved colour column. Column 0 and the
42
+ * neutral sentinel render dim (`dimLane`); columns ≥ 1 take a palette hue.
43
+ */
44
+ export function stylerForLaneColumn(
45
+ colorColumn: number,
46
+ colorize: boolean,
47
+ dimLane: (text: string) => string,
48
+ ): LaneColorizer {
49
+ if (!colorize || colorColumn <= NEUTRAL_LANE_COLUMN) {
50
+ return dimLane;
51
+ }
52
+ return laneColorForColumn(colorColumn);
53
+ }
54
+
55
+ /**
56
+ * The colour-source column for each cell of a row, resolved together because a
57
+ * routed back-arc spans columns and must read as **one hue** rather than a
58
+ * per-column "rainbow".
59
+ */
60
+ export interface RowArcLaneColors {
61
+ /** Colour column for a cell's structural glyph (lane / spine / arc body). */
62
+ readonly lane: readonly number[];
63
+ /** Colour column for a node arc-pair's connector half (`◂` / `─`). */
64
+ readonly connector: readonly number[];
65
+ /**
66
+ * Colour column for the trailing `─` of a landing tee (`┴─`). The junction
67
+ * (`lane`) keeps its own column; the dash leads into the next converging arc.
68
+ */
69
+ readonly dash: readonly number[];
70
+ }
71
+
72
+ /**
73
+ * Resolve per-cell colour columns for a node/arc row. Scanning right-to-left
74
+ * lets each arc segment inherit the hue of the arc it leads into.
75
+ */
76
+ export function resolveRowArcLaneColors(cells: readonly StructuralCell[]): RowArcLaneColors {
77
+ const lane = new Array<number>(cells.length);
78
+ const connector = new Array<number>(cells.length);
79
+ const dash = new Array<number>(cells.length);
80
+ let arcCorner = NEUTRAL_LANE_COLUMN;
81
+ let landingAnchor = NEUTRAL_LANE_COLUMN;
82
+ for (let column = cells.length - 1; column >= 0; column--) {
83
+ const cell = cells[column];
84
+ connector[column] = landingAnchor !== NEUTRAL_LANE_COLUMN ? landingAnchor : arcCorner;
85
+ switch (cell?.kind) {
86
+ case 'arc-branch-corner':
87
+ arcCorner = column;
88
+ lane[column] = column;
89
+ dash[column] = column;
90
+ break;
91
+ case 'arc-land-corner':
92
+ arcCorner = column;
93
+ landingAnchor = column;
94
+ lane[column] = column;
95
+ dash[column] = column;
96
+ break;
97
+ case 'arc-branch-tee':
98
+ lane[column] = column;
99
+ dash[column] = column;
100
+ break;
101
+ case 'arc-land-tee':
102
+ lane[column] = column;
103
+ dash[column] = landingAnchor === NEUTRAL_LANE_COLUMN ? column : landingAnchor;
104
+ landingAnchor = column;
105
+ break;
106
+ case 'arc-crossing':
107
+ case 'arc-land-bridge': {
108
+ const served = landingAnchor !== NEUTRAL_LANE_COLUMN ? landingAnchor : arcCorner;
109
+ lane[column] = served;
110
+ dash[column] = served;
111
+ break;
112
+ }
113
+ case 'horizontal-pass':
114
+ lane[column] = arcCorner === NEUTRAL_LANE_COLUMN ? column : arcCorner;
115
+ dash[column] = lane[column] ?? column;
116
+ break;
117
+ case 'node':
118
+ lane[column] = column;
119
+ dash[column] = column;
120
+ arcCorner = NEUTRAL_LANE_COLUMN;
121
+ landingAnchor = NEUTRAL_LANE_COLUMN;
122
+ break;
123
+ default:
124
+ lane[column] = column;
125
+ dash[column] = column;
126
+ arcCorner = NEUTRAL_LANE_COLUMN;
127
+ landingAnchor = NEUTRAL_LANE_COLUMN;
128
+ }
129
+ }
130
+ return { lane, connector, dash };
131
+ }
132
+
133
+ /**
134
+ * Per-cell colour for a forward branch/merge connector row, split into the
135
+ * cell's junction `glyph` and its trailing `dash`.
136
+ */
137
+ export interface ConnectorLaneColors {
138
+ /** Colour column for a cell's junction glyph (`├` / `┬` / `┴` / `╮` / `╯`). */
139
+ readonly glyph: readonly number[];
140
+ /** Colour column for a tee's trailing `─` — the branch it leads into. */
141
+ readonly dash: readonly number[];
142
+ }
143
+
144
+ /**
145
+ * Resolve per-cell connector colours. Scanning right-to-left, a corner or an
146
+ * intermediate tee anchors its own lane, but a tee's trailing dash leads into
147
+ * the branch on its right.
148
+ */
149
+ export function resolveConnectorLaneColors(
150
+ cells: readonly StructuralCell[],
151
+ startLane: number,
152
+ ): ConnectorLaneColors {
153
+ const glyph = new Array<number>(cells.length);
154
+ const dash = new Array<number>(cells.length);
155
+ let owner = NEUTRAL_LANE_COLUMN;
156
+ for (let column = cells.length - 1; column >= 0; column--) {
157
+ const cell = cells[column];
158
+ switch (cell?.kind) {
159
+ case 'branch-corner':
160
+ case 'merge-corner':
161
+ owner = column;
162
+ glyph[column] = column;
163
+ dash[column] = column;
164
+ break;
165
+ case 'branch-tee':
166
+ case 'merge-tee':
167
+ if (column === startLane) {
168
+ const served = owner === NEUTRAL_LANE_COLUMN ? column : owner;
169
+ glyph[column] = column;
170
+ dash[column] = served;
171
+ } else {
172
+ dash[column] = owner === NEUTRAL_LANE_COLUMN ? column : owner;
173
+ glyph[column] = column;
174
+ owner = column;
175
+ }
176
+ break;
177
+ case 'arc-crossing':
178
+ glyph[column] = column;
179
+ dash[column] = owner === NEUTRAL_LANE_COLUMN ? column : owner;
180
+ owner = column;
181
+ break;
182
+ case 'horizontal-pass': {
183
+ const served = owner === NEUTRAL_LANE_COLUMN ? column : owner;
184
+ glyph[column] = served;
185
+ dash[column] = served;
186
+ break;
187
+ }
188
+ default:
189
+ glyph[column] = column;
190
+ dash[column] = column;
191
+ }
192
+ }
193
+ return { glyph, dash };
194
+ }