@prisma-next/cli 0.12.0-dev.5 → 0.12.0-dev.50

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/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-DC-UlBLy.mjs} +83 -58
  5. package/dist/client-DC-UlBLy.mjs.map +1 -0
  6. package/dist/{command-helpers-Bbw1GbwL.mjs → command-helpers-esJGBD4W.mjs} +317 -23
  7. package/dist/command-helpers-esJGBD4W.mjs.map +1 -0
  8. package/dist/commands/contract-emit.mjs +1 -1
  9. package/dist/commands/contract-infer.mjs +1 -1
  10. package/dist/commands/db-init.mjs +4 -5
  11. package/dist/commands/db-init.mjs.map +1 -1
  12. package/dist/commands/db-schema.mjs +3 -3
  13. package/dist/commands/db-sign.mjs +4 -4
  14. package/dist/commands/db-update.d.mts.map +1 -1
  15. package/dist/commands/db-update.mjs +10 -7
  16. package/dist/commands/db-update.mjs.map +1 -1
  17. package/dist/commands/db-verify.mjs +1 -1
  18. package/dist/commands/migrate.d.mts +2 -2
  19. package/dist/commands/migrate.d.mts.map +1 -1
  20. package/dist/commands/migrate.mjs +6 -8
  21. package/dist/commands/migrate.mjs.map +1 -1
  22. package/dist/commands/migration-check.d.mts +55 -13
  23. package/dist/commands/migration-check.d.mts.map +1 -1
  24. package/dist/commands/migration-check.mjs +3 -2
  25. package/dist/commands/migration-graph.d.mts +17 -8
  26. package/dist/commands/migration-graph.d.mts.map +1 -1
  27. package/dist/commands/migration-graph.mjs +183 -2
  28. package/dist/commands/migration-graph.mjs.map +1 -0
  29. package/dist/commands/migration-list.d.mts +25 -27
  30. package/dist/commands/migration-list.d.mts.map +1 -1
  31. package/dist/commands/migration-list.mjs +2 -190
  32. package/dist/commands/migration-log.d.mts +9 -19
  33. package/dist/commands/migration-log.d.mts.map +1 -1
  34. package/dist/commands/migration-log.mjs +1 -137
  35. package/dist/commands/migration-new.mjs +3 -3
  36. package/dist/commands/migration-plan.d.mts +1 -1
  37. package/dist/commands/migration-plan.mjs +1 -1
  38. package/dist/commands/migration-show.d.mts +17 -21
  39. package/dist/commands/migration-show.d.mts.map +1 -1
  40. package/dist/commands/migration-show.mjs +23 -35
  41. package/dist/commands/migration-show.mjs.map +1 -1
  42. package/dist/commands/migration-status.d.mts +42 -144
  43. package/dist/commands/migration-status.d.mts.map +1 -1
  44. package/dist/commands/migration-status.mjs +3 -759
  45. package/dist/commands/ref.d.mts +1 -1
  46. package/dist/commands/ref.mjs +3 -3
  47. package/dist/commands/telemetry/index.d.mts +7 -0
  48. package/dist/commands/telemetry/index.d.mts.map +1 -0
  49. package/dist/commands/telemetry/index.mjs +2 -0
  50. package/dist/{contract-at-errors-BxP-TOMl.mjs → contract-at-errors-COZAemUl.mjs} +2 -2
  51. package/dist/{contract-at-errors-BxP-TOMl.mjs.map → contract-at-errors-COZAemUl.mjs.map} +1 -1
  52. package/dist/{contract-emit-DxcGl4Uq.mjs → contract-emit-Bv46RAIO.mjs} +3 -3
  53. package/dist/{contract-emit-DxcGl4Uq.mjs.map → contract-emit-Bv46RAIO.mjs.map} +1 -1
  54. package/dist/{contract-emit-D-4jrNve.mjs → contract-emit-DIWImLqS.mjs} +5 -5
  55. package/dist/{contract-emit-D-4jrNve.mjs.map → contract-emit-DIWImLqS.mjs.map} +1 -1
  56. package/dist/{contract-infer-D8uEbJuu.mjs → contract-infer-DpGN9SAj.mjs} +3 -3
  57. package/dist/{contract-infer-D8uEbJuu.mjs.map → contract-infer-DpGN9SAj.mjs.map} +1 -1
  58. package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs → contract-space-aggregate-loader-CpNVrBqW.mjs} +63 -5
  59. package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs.map → contract-space-aggregate-loader-CpNVrBqW.mjs.map} +1 -1
  60. package/dist/{db-verify-v_vUKXTU.mjs → db-verify-Cq16Obsw.mjs} +4 -4
  61. package/dist/{db-verify-v_vUKXTU.mjs.map → db-verify-Cq16Obsw.mjs.map} +1 -1
  62. package/dist/exports/control-api.d.mts +2 -2
  63. package/dist/exports/control-api.d.mts.map +1 -1
  64. package/dist/exports/control-api.mjs +2 -2
  65. package/dist/exports/index.mjs +1 -1
  66. package/dist/exports/init-output.mjs +1 -1
  67. package/dist/{framework-components-fYXjz_in.mjs → framework-components-BO9VO43s.mjs} +2 -2
  68. package/dist/{framework-components-fYXjz_in.mjs.map → framework-components-BO9VO43s.mjs.map} +1 -1
  69. package/dist/{global-flags-DEHjV8_s.d.mts → global-flags-CV5LhrFg.d.mts} +1 -1
  70. package/dist/{global-flags-DEHjV8_s.d.mts.map → global-flags-CV5LhrFg.d.mts.map} +1 -1
  71. package/dist/{init-Cv9UzWL5.mjs → init-C0rjiQ9I.mjs} +5 -58
  72. package/dist/init-C0rjiQ9I.mjs.map +1 -0
  73. package/dist/{inspect-live-schema-C6ohV_oQ.mjs → inspect-live-schema-CRDKTNcf.mjs} +3 -3
  74. package/dist/{inspect-live-schema-C6ohV_oQ.mjs.map → inspect-live-schema-CRDKTNcf.mjs.map} +1 -1
  75. package/dist/migration-check-BxWlQBOs.mjs +573 -0
  76. package/dist/migration-check-BxWlQBOs.mjs.map +1 -0
  77. package/dist/{migration-command-scaffold-CjvwO6at.mjs → migration-command-scaffold-BDd9abqW.mjs} +3 -3
  78. package/dist/{migration-command-scaffold-CjvwO6at.mjs.map → migration-command-scaffold-BDd9abqW.mjs.map} +1 -1
  79. package/dist/migration-graph-space-render-CeNXh_Wy.mjs +1966 -0
  80. package/dist/migration-graph-space-render-CeNXh_Wy.mjs.map +1 -0
  81. package/dist/migration-list-vJWFuXca.mjs +228 -0
  82. package/dist/migration-list-vJWFuXca.mjs.map +1 -0
  83. package/dist/migration-log-6rcHQSI4.mjs +222 -0
  84. package/dist/migration-log-6rcHQSI4.mjs.map +1 -0
  85. package/dist/migration-path-target-UkxkgXnv.mjs +38 -0
  86. package/dist/migration-path-target-UkxkgXnv.mjs.map +1 -0
  87. package/dist/{migration-plan-9DJ7q7_z.mjs → migration-plan-CHu_erQ5.mjs} +5 -6
  88. package/dist/{migration-plan-9DJ7q7_z.mjs.map → migration-plan-CHu_erQ5.mjs.map} +1 -1
  89. package/dist/migration-status-Bjv91dE7.mjs +444 -0
  90. package/dist/migration-status-Bjv91dE7.mjs.map +1 -0
  91. package/dist/{output-B60Gw5fu.mjs → output-BD61elic.mjs} +1 -1
  92. package/dist/{output-B60Gw5fu.mjs.map → output-BD61elic.mjs.map} +1 -1
  93. package/dist/{ref-advancement-DUZqsue6.mjs → ref-advancement-CJY9zOv7.mjs} +1 -1
  94. package/dist/{ref-advancement-DUZqsue6.mjs.map → ref-advancement-CJY9zOv7.mjs.map} +1 -1
  95. package/dist/schemas-BL33A3i-.d.mts +193 -0
  96. package/dist/schemas-BL33A3i-.d.mts.map +1 -0
  97. package/dist/schemas-DJY2O09F.mjs +112 -0
  98. package/dist/schemas-DJY2O09F.mjs.map +1 -0
  99. package/dist/telemetry-CZkgkR_O.mjs +122 -0
  100. package/dist/telemetry-CZkgkR_O.mjs.map +1 -0
  101. package/dist/{terminal-ui-5Y6mrg93.d.mts → terminal-ui-BgLiAOYi.d.mts} +1 -1
  102. package/dist/{terminal-ui-5Y6mrg93.d.mts.map → terminal-ui-BgLiAOYi.d.mts.map} +1 -1
  103. package/dist/{types-Dt_SfqFm.d.mts → types-qV41eEXH.d.mts} +44 -31
  104. package/dist/types-qV41eEXH.d.mts.map +1 -0
  105. package/dist/{verify-DCA9Sldu.mjs → verify-IilvIk_E.mjs} +2 -2
  106. package/dist/{verify-DCA9Sldu.mjs.map → verify-IilvIk_E.mjs.map} +1 -1
  107. package/package.json +22 -19
  108. package/src/cli.ts +5 -0
  109. package/src/commands/db-update.ts +7 -1
  110. package/src/commands/init/index.ts +6 -35
  111. package/src/commands/init/init.ts +1 -14
  112. package/src/commands/init/inputs.ts +0 -75
  113. package/src/commands/json/schemas.ts +195 -0
  114. package/src/commands/migrate.ts +6 -6
  115. package/src/commands/migration-check.ts +469 -134
  116. package/src/commands/migration-graph.ts +162 -91
  117. package/src/commands/migration-list.ts +69 -39
  118. package/src/commands/migration-log.ts +52 -102
  119. package/src/commands/migration-show.ts +31 -66
  120. package/src/commands/migration-status-overlay.ts +61 -0
  121. package/src/commands/migration-status.ts +453 -1067
  122. package/src/commands/telemetry/index.ts +107 -0
  123. package/src/commands/telemetry/status.ts +67 -0
  124. package/src/control-api/client.ts +20 -9
  125. package/src/control-api/operations/contract-emit.ts +2 -2
  126. package/src/control-api/operations/db-init.ts +3 -3
  127. package/src/control-api/operations/{db-apply.ts → db-run.ts} +37 -10
  128. package/src/control-api/operations/db-update.ts +4 -4
  129. package/src/control-api/operations/{migration-apply.ts → migrate.ts} +32 -24
  130. package/src/control-api/operations/{apply.ts → run-migration.ts} +33 -27
  131. package/src/control-api/types.ts +46 -29
  132. package/src/utils/cli-errors.ts +70 -2
  133. package/src/utils/formatters/errors.ts +11 -0
  134. package/src/utils/formatters/migration-graph-lane-colors.ts +194 -0
  135. package/src/utils/formatters/migration-graph-layout.ts +51 -7
  136. package/src/utils/formatters/migration-graph-rows.ts +128 -15
  137. package/src/utils/formatters/migration-graph-space-render.ts +138 -0
  138. package/src/utils/formatters/migration-graph-tree-render.ts +405 -77
  139. package/src/utils/formatters/migration-list-data-column.ts +4 -91
  140. package/src/utils/formatters/migration-list-graph-topology.ts +72 -94
  141. package/src/utils/formatters/migration-list-render.ts +123 -71
  142. package/src/utils/formatters/migration-list-styler.ts +48 -5
  143. package/src/utils/formatters/migration-list-types.ts +5 -21
  144. package/src/utils/formatters/migration-log-table.ts +205 -0
  145. package/src/utils/formatters/migrations.ts +33 -11
  146. package/src/utils/global-flags.ts +35 -0
  147. package/src/utils/integrity-violation-to-check-failure.ts +28 -19
  148. package/src/utils/legend.ts +38 -0
  149. package/src/utils/migration-path-target.ts +60 -0
  150. package/src/utils/telemetry.ts +68 -32
  151. package/dist/client-KgJorIvG.mjs.map +0 -1
  152. package/dist/command-helpers-Bbw1GbwL.mjs.map +0 -1
  153. package/dist/commands/migration-list.mjs.map +0 -1
  154. package/dist/commands/migration-log.mjs.map +0 -1
  155. package/dist/commands/migration-status.mjs.map +0 -1
  156. package/dist/extension-pack-inputs-IDvjRCi3.mjs +0 -62
  157. package/dist/extension-pack-inputs-IDvjRCi3.mjs.map +0 -1
  158. package/dist/graph-render-rFAqZujX.mjs +0 -1081
  159. package/dist/graph-render-rFAqZujX.mjs.map +0 -1
  160. package/dist/init-Cv9UzWL5.mjs.map +0 -1
  161. package/dist/migration-check-BiBJoYYW.mjs +0 -341
  162. package/dist/migration-check-BiBJoYYW.mjs.map +0 -1
  163. package/dist/migration-graph-D7DVUElV.mjs +0 -1232
  164. package/dist/migration-graph-D7DVUElV.mjs.map +0 -1
  165. package/dist/migration-list-styler-BRwF4-gy.mjs +0 -399
  166. package/dist/migration-list-styler-BRwF4-gy.mjs.map +0 -1
  167. package/dist/migration-types-D2FW63pr.d.mts +0 -15
  168. package/dist/migration-types-D2FW63pr.d.mts.map +0 -1
  169. package/dist/migrations-Cv2jxNNK.mjs +0 -228
  170. package/dist/migrations-Cv2jxNNK.mjs.map +0 -1
  171. package/dist/types-Dt_SfqFm.d.mts.map +0 -1
  172. package/src/utils/formatters/graph-migration-mapper.ts +0 -235
  173. package/src/utils/formatters/graph-render.ts +0 -1323
  174. package/src/utils/formatters/graph-types.ts +0 -120
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Shared runner tail (`runMigration` + `buildPerSpaceBreakdown`/`collectOrdered`).
3
+ * Backs no command directly; consumed by db-run and migrate.
4
+ */
5
+
1
6
  import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';
2
7
  import type {
3
8
  ControlDriverInstance,
@@ -11,32 +16,32 @@ import { notOk, ok, type Result } from '@prisma-next/utils/result';
11
16
  import type { OnControlProgress, PerSpaceExecutionEntry } from '../types';
12
17
 
13
18
  /**
14
- * Span id emitted via `onProgress` for the apply phase. Stable
19
+ * Span id emitted via `onProgress` for the run phase. Stable
15
20
  * identifier consumed by the structured-output renderer and by tests.
16
21
  */
17
- const APPLY_SPAN_ID = 'apply' as const;
22
+ const RUN_SPAN_ID = 'apply' as const;
18
23
 
19
24
  /**
20
- * Action that originated this apply call. Threaded into `OnControlProgress`
25
+ * Action that originated this run call. Threaded into `OnControlProgress`
21
26
  * events so the parent CLI command can attribute the span correctly,
22
27
  * and used to compose action-specific summary phrasing.
23
28
  */
24
- export type ApplyAction = 'dbInit' | 'dbUpdate' | 'migrationApply';
29
+ export type RunAction = 'dbInit' | 'dbUpdate' | 'migrate';
25
30
 
26
31
  /**
27
- * Failure variant emitted by {@link applyMigration} when the runner
28
- * itself rejects the apply. Mirrors the failure shape callers
32
+ * Failure variant emitted by {@link runMigration} when the runner
33
+ * itself rejects the run. Mirrors the failure shape callers
29
34
  * already wrap into their own action-specific failure envelopes
30
- * (`DbInitFailure`, `DbUpdateFailure`, `MigrationApplyFailure`) so each
35
+ * (`DbInitFailure`, `DbUpdateFailure`, `MigrateFailure`) so each
31
36
  * caller keeps owning its own discriminated failure code.
32
37
  */
33
- export interface ApplyRunnerFailure {
38
+ export interface RunnerFailure {
34
39
  readonly summary: string;
35
40
  readonly why?: string;
36
41
  readonly meta: Record<string, unknown>;
37
42
  }
38
43
 
39
- export interface ApplyMigrationInputs<TFamilyId extends string, TTargetId extends string> {
44
+ export interface RunMigrationInputs<TFamilyId extends string, TTargetId extends string> {
40
45
  readonly aggregate: ContractSpaceAggregate;
41
46
  /**
42
47
  * Per-space plans, keyed by `spaceId`. Produced by either the full
@@ -62,22 +67,22 @@ export interface ApplyMigrationInputs<TFamilyId extends string, TTargetId extend
62
67
  >;
63
68
  readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;
64
69
  readonly policy: MigrationOperationPolicy;
65
- readonly action: ApplyAction;
70
+ readonly action: RunAction;
66
71
  readonly onProgress?: OnControlProgress;
67
72
  }
68
73
 
69
74
  /**
70
75
  * Resolved per-space plan in canonical schedule order. Surfaced from
71
- * {@link applyMigration} to callers so each one can build its own
76
+ * {@link runMigration} to callers so each one can build its own
72
77
  * action-specific success envelope (e.g. `DbInitSuccess` vs
73
- * `MigrationApplySuccess`) without re-deriving the ordering.
78
+ * `MigrateSuccess`) without re-deriving the ordering.
74
79
  */
75
80
  export interface OrderedResolution {
76
81
  readonly spaceId: string;
77
82
  readonly entry: PerSpacePlan;
78
83
  }
79
84
 
80
- export interface ApplyMigrationValue {
85
+ export interface RunMigrationValue {
81
86
  readonly orderedResolutions: readonly OrderedResolution[];
82
87
  readonly totalOpsPlanned: number;
83
88
  readonly totalOpsExecuted: number;
@@ -89,10 +94,10 @@ export interface ApplyMigrationValue {
89
94
  readonly perSpace: readonly PerSpaceExecutionEntry[];
90
95
  }
91
96
 
92
- export type ApplyMigrationResult = Result<ApplyMigrationValue, ApplyRunnerFailure>;
97
+ export type RunMigrationResult = Result<RunMigrationValue, RunnerFailure>;
93
98
 
94
99
  /**
95
- * Runner-driving tail shared by every apply caller — `db init`,
100
+ * Runner-driving tail shared by every run caller — `db init`,
96
101
  * `db update`, and `migrate`. Consumes already-resolved per-space
97
102
  * plans (the planner-vs-replay distinction is owned by the caller) and
98
103
  * dispatches them to the runner in canonical order.
@@ -107,9 +112,9 @@ export type ApplyMigrationResult = Result<ApplyMigrationValue, ApplyRunnerFailur
107
112
  * so callers don't have to duplicate it; the `action` field on each
108
113
  * progress event is taken from the caller's `action` argument.
109
114
  */
110
- export async function applyMigration<TFamilyId extends string, TTargetId extends string>(
111
- inputs: ApplyMigrationInputs<TFamilyId, TTargetId>,
112
- ): Promise<ApplyMigrationResult> {
115
+ export async function runMigration<TFamilyId extends string, TTargetId extends string>(
116
+ inputs: RunMigrationInputs<TFamilyId, TTargetId>,
117
+ ): Promise<RunMigrationResult> {
113
118
  const {
114
119
  aggregate,
115
120
  perSpacePlans,
@@ -130,7 +135,7 @@ export async function applyMigration<TFamilyId extends string, TTargetId extends
130
135
  onProgress?.({
131
136
  action,
132
137
  kind: 'spanStart',
133
- spanId: APPLY_SPAN_ID,
138
+ spanId: RUN_SPAN_ID,
134
139
  label: progressLabelForAction(action),
135
140
  });
136
141
 
@@ -141,6 +146,7 @@ export async function applyMigration<TFamilyId extends string, TTargetId extends
141
146
  destinationContract: r.entry.destinationContract,
142
147
  policy,
143
148
  frameworkComponents,
149
+ migrationEdges: r.entry.migrationEdges,
144
150
  // Per-space post-apply schema verification is non-strict: each
145
151
  // space's `destinationContract` describes only its own slice; a
146
152
  // strict verifier would treat every other space's tables as
@@ -151,7 +157,7 @@ export async function applyMigration<TFamilyId extends string, TTargetId extends
151
157
  const runnerResult = await runner.execute({ driver, perSpaceOptions });
152
158
 
153
159
  if (!runnerResult.ok) {
154
- onProgress?.({ action, kind: 'spanEnd', spanId: APPLY_SPAN_ID, outcome: 'error' });
160
+ onProgress?.({ action, kind: 'spanEnd', spanId: RUN_SPAN_ID, outcome: 'error' });
155
161
  return notOk({
156
162
  summary: runnerResult.failure.summary,
157
163
  ...ifDefined('why', runnerResult.failure.why),
@@ -162,7 +168,7 @@ export async function applyMigration<TFamilyId extends string, TTargetId extends
162
168
  },
163
169
  });
164
170
  }
165
- onProgress?.({ action, kind: 'spanEnd', spanId: APPLY_SPAN_ID, outcome: 'ok' });
171
+ onProgress?.({ action, kind: 'spanEnd', spanId: RUN_SPAN_ID, outcome: 'ok' });
166
172
 
167
173
  const totalOpsPlanned = runnerResult.value.perSpaceResults.reduce(
168
174
  (sum, r) => sum + r.value.operationsPlanned,
@@ -194,7 +200,7 @@ export async function applyMigration<TFamilyId extends string, TTargetId extends
194
200
  * advances as the last step of each space's transaction) and `false`
195
201
  * for plan-mode (no marker has been written yet).
196
202
  *
197
- * Exported alongside {@link applyMigration} so plan-mode callers can
203
+ * Exported alongside {@link runMigration} so plan-mode callers can
198
204
  * assemble the same per-space block without going through the runner.
199
205
  */
200
206
  export function buildPerSpaceBreakdown(
@@ -243,18 +249,18 @@ export function collectOrdered(
243
249
  }
244
250
 
245
251
  /**
246
- * Action-appropriate label for the `spanStart` event the apply
247
- * primitive emits. `applyMigration` is shared by `db init`, `db update`,
252
+ * Action-appropriate label for the `spanStart` event the run
253
+ * primitive emits. `runMigration` is shared by `db init`, `db update`,
248
254
  * and `migrate`; the span label tracks the user-visible action
249
255
  * so structured-progress output reads naturally for each surface.
250
256
  */
251
- export function progressLabelForAction(action: ApplyAction): string {
257
+ export function progressLabelForAction(action: RunAction): string {
252
258
  switch (action) {
253
259
  case 'dbInit':
254
260
  return 'Initialising database across spaces';
255
261
  case 'dbUpdate':
256
262
  return 'Updating database across spaces';
257
- case 'migrationApply':
258
- return 'Applying migration plan across spaces';
263
+ case 'migrate':
264
+ return 'Running migration plan across spaces';
259
265
  }
260
266
  }
@@ -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
  }