@prisma-next/cli 0.15.0 → 0.16.0-dev.2

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 (148) hide show
  1. package/dist/cli.d.mts +1 -1
  2. package/dist/cli.mjs +13 -13
  3. package/dist/{client-DigVI8zX.mjs → client-KuBQftxz.mjs} +67 -36
  4. package/dist/client-KuBQftxz.mjs.map +1 -0
  5. package/dist/{command-helpers-CUoKYTlG.mjs → command-helpers-Cpq44aVa.mjs} +21 -5
  6. package/dist/command-helpers-Cpq44aVa.mjs.map +1 -0
  7. package/dist/commands/contract-emit.d.mts +0 -1
  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 +0 -1
  11. package/dist/commands/contract-infer.d.mts.map +1 -1
  12. package/dist/commands/contract-infer.mjs +1 -1
  13. package/dist/commands/db-init.d.mts +0 -1
  14. package/dist/commands/db-init.d.mts.map +1 -1
  15. package/dist/commands/db-init.mjs +6 -6
  16. package/dist/commands/db-init.mjs.map +1 -1
  17. package/dist/commands/db-schema.d.mts +0 -1
  18. package/dist/commands/db-schema.d.mts.map +1 -1
  19. package/dist/commands/db-schema.mjs +3 -3
  20. package/dist/commands/db-sign.d.mts +0 -1
  21. package/dist/commands/db-sign.d.mts.map +1 -1
  22. package/dist/commands/db-sign.mjs +4 -4
  23. package/dist/commands/db-update.d.mts +0 -1
  24. package/dist/commands/db-update.d.mts.map +1 -1
  25. package/dist/commands/db-update.mjs +5 -5
  26. package/dist/commands/db-update.mjs.map +1 -1
  27. package/dist/commands/db-verify.d.mts +0 -1
  28. package/dist/commands/db-verify.d.mts.map +1 -1
  29. package/dist/commands/db-verify.mjs +1 -1
  30. package/dist/commands/migrate.d.mts +1 -2
  31. package/dist/commands/migrate.d.mts.map +1 -1
  32. package/dist/commands/migrate.mjs +5 -5
  33. package/dist/commands/migration-check.d.mts +1 -2
  34. package/dist/commands/migration-check.d.mts.map +1 -1
  35. package/dist/commands/migration-check.mjs +1 -1
  36. package/dist/commands/migration-graph.d.mts +2 -3
  37. package/dist/commands/migration-graph.d.mts.map +1 -1
  38. package/dist/commands/migration-graph.mjs +3 -3
  39. package/dist/commands/migration-list.d.mts +2 -3
  40. package/dist/commands/migration-list.d.mts.map +1 -1
  41. package/dist/commands/migration-list.mjs +1 -1
  42. package/dist/commands/migration-log.d.mts +2 -3
  43. package/dist/commands/migration-log.d.mts.map +1 -1
  44. package/dist/commands/migration-log.mjs +1 -1
  45. package/dist/commands/migration-new.d.mts +0 -1
  46. package/dist/commands/migration-new.d.mts.map +1 -1
  47. package/dist/commands/migration-new.mjs +3 -3
  48. package/dist/commands/migration-plan.d.mts +0 -1
  49. package/dist/commands/migration-plan.d.mts.map +1 -1
  50. package/dist/commands/migration-plan.mjs +1 -1
  51. package/dist/commands/migration-show.d.mts +0 -1
  52. package/dist/commands/migration-show.d.mts.map +1 -1
  53. package/dist/commands/migration-show.mjs +3 -3
  54. package/dist/commands/migration-status.d.mts +2 -3
  55. package/dist/commands/migration-status.d.mts.map +1 -1
  56. package/dist/commands/migration-status.mjs +1 -1
  57. package/dist/commands/ref.d.mts +1 -2
  58. package/dist/commands/ref.d.mts.map +1 -1
  59. package/dist/commands/ref.mjs +2 -2
  60. package/dist/commands/telemetry/index.d.mts +0 -1
  61. package/dist/commands/telemetry/index.d.mts.map +1 -1
  62. package/dist/commands/telemetry/index.mjs +1 -1
  63. package/dist/{contract-at-errors-D8CNDD7g.mjs → contract-at-errors-D9gEjYtg.mjs} +2 -2
  64. package/dist/{contract-at-errors-D8CNDD7g.mjs.map → contract-at-errors-D9gEjYtg.mjs.map} +1 -1
  65. package/dist/{contract-emit-wgqrOXUI.mjs → contract-emit-CgnXSANN.mjs} +3 -3
  66. package/dist/{contract-emit-wgqrOXUI.mjs.map → contract-emit-CgnXSANN.mjs.map} +1 -1
  67. package/dist/{contract-emit-sYrqzsdN.mjs → contract-emit-cJQBlvGb.mjs} +3 -3
  68. package/dist/{contract-emit-sYrqzsdN.mjs.map → contract-emit-cJQBlvGb.mjs.map} +1 -1
  69. package/dist/{contract-infer-6SQnnVj7.mjs → contract-infer-Cg8evbeg.mjs} +3 -3
  70. package/dist/{contract-infer-6SQnnVj7.mjs.map → contract-infer-Cg8evbeg.mjs.map} +1 -1
  71. package/dist/{contract-space-aggregate-loader-DpB4x97a.mjs → contract-space-aggregate-loader-D_3VeHVb.mjs} +14 -15
  72. package/dist/contract-space-aggregate-loader-D_3VeHVb.mjs.map +1 -0
  73. package/dist/{db-verify-CEsG5Gek.mjs → db-verify-BEclUzki.mjs} +6 -7
  74. package/dist/db-verify-BEclUzki.mjs.map +1 -0
  75. package/dist/exports/control-api.d.mts +1 -2
  76. package/dist/exports/control-api.d.mts.map +1 -1
  77. package/dist/exports/control-api.mjs +2 -2
  78. package/dist/exports/index.d.mts +0 -1
  79. package/dist/exports/index.d.mts.map +1 -1
  80. package/dist/exports/index.mjs +2 -2
  81. package/dist/exports/init-output.d.mts +1 -0
  82. package/dist/exports/init-output.d.mts.map +1 -1
  83. package/dist/{format-CjongNb1.mjs → format-DAUAZqPt.mjs} +2 -2
  84. package/dist/{format-CjongNb1.mjs.map → format-DAUAZqPt.mjs.map} +1 -1
  85. package/dist/{framework-components-BbnM1RYm.mjs → framework-components-CnbUbiJw.mjs} +2 -2
  86. package/dist/{framework-components-BbnM1RYm.mjs.map → framework-components-CnbUbiJw.mjs.map} +1 -1
  87. package/dist/global-flags-BpoOYtNZ.d.mts.map +1 -1
  88. package/dist/{init-D8YFfaD6.mjs → init-C3JhkHg-.mjs} +33 -46
  89. package/dist/init-C3JhkHg-.mjs.map +1 -0
  90. package/dist/{inspect-live-schema-CEt_ztBJ.mjs → inspect-live-schema-CX7EA5C3.mjs} +3 -3
  91. package/dist/{inspect-live-schema-CEt_ztBJ.mjs.map → inspect-live-schema-CX7EA5C3.mjs.map} +1 -1
  92. package/dist/{migration-check-ByeQHOhK.mjs → migration-check-VqN-iTcx.mjs} +25 -24
  93. package/dist/migration-check-VqN-iTcx.mjs.map +1 -0
  94. package/dist/migration-cli.d.mts +0 -1
  95. package/dist/migration-cli.d.mts.map +1 -1
  96. package/dist/migration-cli.mjs +3 -3
  97. package/dist/migration-cli.mjs.map +1 -1
  98. package/dist/{migration-command-scaffold-CJO3tjiR.mjs → migration-command-scaffold-CRyYrHZ9.mjs} +3 -3
  99. package/dist/{migration-command-scaffold-CJO3tjiR.mjs.map → migration-command-scaffold-CRyYrHZ9.mjs.map} +1 -1
  100. package/dist/{migration-list-DTYM8xvm.mjs → migration-list-BAKujUjh.mjs} +3 -3
  101. package/dist/{migration-list-DTYM8xvm.mjs.map → migration-list-BAKujUjh.mjs.map} +1 -1
  102. package/dist/{migration-log-qZ8LpQIl.mjs → migration-log-C_xam2HZ.mjs} +3 -3
  103. package/dist/{migration-log-qZ8LpQIl.mjs.map → migration-log-C_xam2HZ.mjs.map} +1 -1
  104. package/dist/{migration-path-target-DmNwsDgs.mjs → migration-path-target-DpPTsRCg.mjs} +2 -2
  105. package/dist/{migration-path-target-DmNwsDgs.mjs.map → migration-path-target-DpPTsRCg.mjs.map} +1 -1
  106. package/dist/{migration-plan-CfPrB80t.mjs → migration-plan-CreSVtWZ.mjs} +6 -6
  107. package/dist/migration-plan-CreSVtWZ.mjs.map +1 -0
  108. package/dist/{migration-status-DRuS-rP5.mjs → migration-status-DYErXpyF.mjs} +6 -5
  109. package/dist/{migration-status-DRuS-rP5.mjs.map → migration-status-DYErXpyF.mjs.map} +1 -1
  110. package/dist/schemas-CeGMYFYX.d.mts.map +1 -1
  111. package/dist/{telemetry-DHBBq5wT.mjs → telemetry-DVr6RFnq.mjs} +2 -2
  112. package/dist/{telemetry-DHBBq5wT.mjs.map → telemetry-DVr6RFnq.mjs.map} +1 -1
  113. package/dist/{terminal-ui-DGRNFWna.d.mts → terminal-ui-BN4QOsm5.d.mts} +1 -2
  114. package/dist/terminal-ui-BN4QOsm5.d.mts.map +1 -0
  115. package/dist/{types-DFoqNIcQ.d.mts → types-D4r_HI9-.d.mts} +8 -4
  116. package/dist/types-D4r_HI9-.d.mts.map +1 -0
  117. package/dist/{verify-DDCb0R2r.mjs → verify-CgDVZjhc.mjs} +9 -8
  118. package/dist/verify-CgDVZjhc.mjs.map +1 -0
  119. package/package.json +25 -25
  120. package/src/commands/db-init.ts +3 -3
  121. package/src/commands/db-update.ts +1 -1
  122. package/src/commands/db-verify.ts +2 -3
  123. package/src/commands/init/errors.ts +62 -58
  124. package/src/commands/init/init.ts +29 -26
  125. package/src/commands/migration-check.ts +7 -7
  126. package/src/commands/migration-plan.ts +1 -1
  127. package/src/control-api/operations/db-run.ts +4 -4
  128. package/src/control-api/operations/db-verify.ts +12 -9
  129. package/src/control-api/operations/migrate.ts +70 -26
  130. package/src/control-api/types.ts +4 -1
  131. package/src/migration-cli.ts +5 -5
  132. package/src/utils/cli-errors.ts +15 -2
  133. package/src/utils/combine-verify-results.ts +1 -1
  134. package/src/utils/contract-space-aggregate-loader.ts +12 -13
  135. package/src/utils/formatters/errors.ts +24 -3
  136. package/src/utils/formatters/verify.ts +7 -6
  137. package/src/utils/integrity-violation-to-check-failure.ts +14 -14
  138. package/src/utils/result-handler.ts +4 -2
  139. package/dist/client-DigVI8zX.mjs.map +0 -1
  140. package/dist/command-helpers-CUoKYTlG.mjs.map +0 -1
  141. package/dist/contract-space-aggregate-loader-DpB4x97a.mjs.map +0 -1
  142. package/dist/db-verify-CEsG5Gek.mjs.map +0 -1
  143. package/dist/init-D8YFfaD6.mjs.map +0 -1
  144. package/dist/migration-check-ByeQHOhK.mjs.map +0 -1
  145. package/dist/migration-plan-CfPrB80t.mjs.map +0 -1
  146. package/dist/terminal-ui-DGRNFWna.d.mts.map +0 -1
  147. package/dist/types-DFoqNIcQ.d.mts.map +0 -1
  148. package/dist/verify-DDCb0R2r.mjs.map +0 -1
@@ -6,8 +6,7 @@ import { CliStructuredError } from '../../utils/cli-errors';
6
6
  * the user was never given the choice — `--force` is the contract.
7
7
  */
8
8
  export function errorInitReinitNeedsForce(): CliStructuredError {
9
- return new CliStructuredError('5002', 'Project is already initialized', {
10
- domain: 'CLI',
9
+ return new CliStructuredError('CLI.INIT_REINIT_NEEDS_FORCE', 'Project is already initialized', {
11
10
  why: 'A `prisma-next.config.ts` already exists in this directory. Re-running `init` would overwrite the scaffolded files; in non-interactive mode `init` will not do that without `--force`.',
12
11
  fix: 'Pass `--force` to overwrite the existing scaffold, or run `init` interactively to confirm.',
13
12
  docsUrl: 'https://prisma-next.dev/docs/cli/init',
@@ -42,8 +41,7 @@ export function errorInitMissingFlags(options: {
42
41
  }
43
42
  })
44
43
  .join(' ');
45
- return new CliStructuredError('5003', 'Missing required flags', {
46
- domain: 'CLI',
44
+ return new CliStructuredError('CLI.INIT_MISSING_FLAGS', 'Missing required flags', {
47
45
  why: `${options.why} Missing required flag(s): ${flagList}.`,
48
46
  fix: `Re-run with the missing flag(s) supplied, e.g. \`prisma-next init --yes ${fixList}\`. Use \`prisma-next init --help\` to see every flag.`,
49
47
  docsUrl: 'https://prisma-next.dev/docs/cli/init',
@@ -60,13 +58,16 @@ export function errorInitInvalidFlagValue(options: {
60
58
  readonly value: string;
61
59
  readonly allowed: readonly string[];
62
60
  }): CliStructuredError {
63
- return new CliStructuredError('5004', `Invalid value for --${options.flag}`, {
64
- domain: 'CLI',
65
- why: `\`--${options.flag} ${options.value}\` is not one of: ${options.allowed.join(', ')}.`,
66
- fix: `Use one of: ${options.allowed.map((v) => `--${options.flag} ${v}`).join(', ')}.`,
67
- docsUrl: 'https://prisma-next.dev/docs/cli/init',
68
- meta: { flag: options.flag, value: options.value, allowed: options.allowed },
69
- });
61
+ return new CliStructuredError(
62
+ 'CLI.INIT_INVALID_FLAG_VALUE',
63
+ `Invalid value for --${options.flag}`,
64
+ {
65
+ why: `\`--${options.flag} ${options.value}\` is not one of: ${options.allowed.join(', ')}.`,
66
+ fix: `Use one of: ${options.allowed.map((v) => `--${options.flag} ${v}`).join(', ')}.`,
67
+ docsUrl: 'https://prisma-next.dev/docs/cli/init',
68
+ meta: { flag: options.flag, value: options.value, allowed: options.allowed },
69
+ },
70
+ );
70
71
  }
71
72
 
72
73
  /**
@@ -81,23 +82,26 @@ export function errorInitAuthoringSchemaPathMismatch(options: {
81
82
  readonly expectedExtension: string;
82
83
  }): CliStructuredError {
83
84
  const expectedAuthoring = options.expectedExtension === '.ts' ? 'typescript' : 'psl';
84
- return new CliStructuredError('5014', 'Authoring and schema path do not match', {
85
- domain: 'CLI',
86
- why:
87
- `\`--authoring ${options.authoring}\` requires a schema file ending in ${options.expectedExtension}, ` +
88
- `but \`--schema-path ${options.schemaPath}\` ends in ${options.actualExtension}.`,
89
- fix:
90
- `Use a matching pair, for example \`--authoring ${expectedAuthoring} --schema-path <path>${options.expectedExtension}\`, ` +
91
- 'or change `--authoring` to match the path you supplied. ' +
92
- 'You can also omit `--schema-path` to use the default for the chosen authoring.',
93
- docsUrl: 'https://prisma-next.dev/docs/cli/init',
94
- meta: {
95
- authoring: options.authoring,
96
- schemaPath: options.schemaPath,
97
- actualExtension: options.actualExtension,
98
- expectedExtension: options.expectedExtension,
85
+ return new CliStructuredError(
86
+ 'CLI.INIT_AUTHORING_SCHEMA_PATH_MISMATCH',
87
+ 'Authoring and schema path do not match',
88
+ {
89
+ why:
90
+ `\`--authoring ${options.authoring}\` requires a schema file ending in ${options.expectedExtension}, ` +
91
+ `but \`--schema-path ${options.schemaPath}\` ends in ${options.actualExtension}.`,
92
+ fix:
93
+ `Use a matching pair, for example \`--authoring ${expectedAuthoring} --schema-path <path>${options.expectedExtension}\`, ` +
94
+ 'or change `--authoring` to match the path you supplied. ' +
95
+ 'You can also omit `--schema-path` to use the default for the chosen authoring.',
96
+ docsUrl: 'https://prisma-next.dev/docs/cli/init',
97
+ meta: {
98
+ authoring: options.authoring,
99
+ schemaPath: options.schemaPath,
100
+ actualExtension: options.actualExtension,
101
+ expectedExtension: options.expectedExtension,
102
+ },
99
103
  },
100
- });
104
+ );
101
105
  }
102
106
 
103
107
  /**
@@ -108,8 +112,7 @@ export function errorInitAuthoringSchemaPathMismatch(options: {
108
112
  * 3 (USER_ABORTED).
109
113
  */
110
114
  export function errorInitUserAborted(): CliStructuredError {
111
- return new CliStructuredError('5006', 'Init cancelled', {
112
- domain: 'CLI',
115
+ return new CliStructuredError('CLI.INIT_USER_ABORTED', 'Init cancelled', {
113
116
  why: 'The interactive prompt was cancelled before all required inputs were supplied. No files were modified.',
114
117
  fix: 'Re-run `prisma-next init` and complete the prompts, or pass the required inputs as flags (see `--help`) for a non-interactive run.',
115
118
  severity: 'info',
@@ -125,12 +128,15 @@ export function errorInitUserAborted(): CliStructuredError {
125
128
  * mode is supposed to prevent.
126
129
  */
127
130
  export function errorInitStrictProbeWithoutProbe(): CliStructuredError {
128
- return new CliStructuredError('5005', '`--strict-probe` requires `--probe-db`', {
129
- domain: 'CLI',
130
- why: '`--strict-probe` only changes how a *failed* probe is reported; without `--probe-db` no probe is attempted in the first place. (`init` is offline-by-default — it never opens a connection to your database without explicit consent.)',
131
- fix: 'Add `--probe-db` to opt in to the probe, or drop `--strict-probe` if you do not need the version check.',
132
- docsUrl: 'https://prisma-next.dev/docs/cli/init',
133
- });
131
+ return new CliStructuredError(
132
+ 'CLI.INIT_STRICT_PROBE_WITHOUT_PROBE',
133
+ '`--strict-probe` requires `--probe-db`',
134
+ {
135
+ why: '`--strict-probe` only changes how a *failed* probe is reported; without `--probe-db` no probe is attempted in the first place. (`init` is offline-by-default — it never opens a connection to your database without explicit consent.)',
136
+ fix: 'Add `--probe-db` to opt in to the probe, or drop `--strict-probe` if you do not need the version check.',
137
+ docsUrl: 'https://prisma-next.dev/docs/cli/init',
138
+ },
139
+ );
134
140
  }
135
141
 
136
142
  /**
@@ -152,8 +158,7 @@ export function errorInitInstallFailed(options: {
152
158
  trimmed.length === 0
153
159
  ? 'The package manager exited with an error and no recoverable fallback applied.'
154
160
  : `The package manager exited with: ${trimmed[0]}`;
155
- return new CliStructuredError('5007', 'Failed to install dependencies', {
156
- domain: 'CLI',
161
+ return new CliStructuredError('CLI.INIT_INSTALL_FAILED', 'Failed to install dependencies', {
157
162
  why,
158
163
  fix: `Install manually:\n ${options.addCommand}\n ${options.addDevCommand}\nThen run \`${options.emitCommand}\` to emit the contract.`,
159
164
  docsUrl: 'https://prisma-next.dev/docs/cli/init',
@@ -179,8 +184,7 @@ export function errorInitInvalidManifest(options: {
179
184
  readonly path: string;
180
185
  readonly cause: string;
181
186
  }): CliStructuredError {
182
- return new CliStructuredError('5010', `Failed to parse ${options.path}`, {
183
- domain: 'CLI',
187
+ return new CliStructuredError('CLI.INIT_INVALID_MANIFEST', `Failed to parse ${options.path}`, {
184
188
  why: `\`${options.path}\` is not valid JSON: ${options.cause}`,
185
189
  fix: `Fix the JSON syntax in \`${options.path}\` (a missing comma or unbalanced brace is the most common cause), then re-run \`prisma-next init\`.`,
186
190
  docsUrl: 'https://prisma-next.dev/docs/cli/init',
@@ -206,8 +210,7 @@ export function errorInitInvalidTsconfig(options: {
206
210
  readonly path: string;
207
211
  readonly cause: string;
208
212
  }): CliStructuredError {
209
- return new CliStructuredError('5011', `Failed to parse ${options.path}`, {
210
- domain: 'CLI',
213
+ return new CliStructuredError('CLI.INIT_INVALID_TSCONFIG', `Failed to parse ${options.path}`, {
211
214
  why: `\`${options.path}\` is not valid JSON or JSONC: ${options.cause}`,
212
215
  fix: `Fix the syntax in \`${options.path}\` and re-run \`prisma-next init\`. \`init\` accepts JSONC (comments and trailing commas) but cannot recover from unbalanced braces or missing commas.`,
213
216
  docsUrl: 'https://prisma-next.dev/docs/cli/init',
@@ -233,8 +236,7 @@ export function errorInitProbeFailed(options: {
233
236
  readonly cause: string;
234
237
  readonly filesWritten: readonly string[];
235
238
  }): CliStructuredError {
236
- return new CliStructuredError('5012', 'Database probe failed', {
237
- domain: 'CLI',
239
+ return new CliStructuredError('CLI.INIT_PROBE_FAILED', 'Database probe failed', {
238
240
  why: `\`--probe-db\` could not complete and \`--strict-probe\` was set: ${options.cause}`,
239
241
  fix: 'Confirm `DATABASE_URL` points at a reachable server, or drop `--strict-probe` to treat probe failures as warnings.',
240
242
  docsUrl: 'https://prisma-next.dev/docs/cli/init',
@@ -256,8 +258,7 @@ export function errorInitEmitFailed(options: {
256
258
  readonly filesWritten: readonly string[];
257
259
  readonly cause: string;
258
260
  }): CliStructuredError {
259
- return new CliStructuredError('5008', 'Failed to emit contract', {
260
- domain: 'CLI',
261
+ return new CliStructuredError('CLI.INIT_EMIT_FAILED', 'Failed to emit contract', {
261
262
  why: `\`prisma-next contract emit\` failed: ${options.cause}`,
262
263
  fix: `Inspect your contract file, fix the underlying issue, then re-run \`${options.emitCommand}\`. Pass \`-v\` for the full error envelope.`,
263
264
  docsUrl: 'https://prisma-next.dev/docs/cli/contract-emit',
@@ -284,18 +285,21 @@ export function errorInitSkillInstallFailed(options: {
284
285
  readonly filesWritten: readonly string[];
285
286
  readonly cause: string;
286
287
  }): CliStructuredError {
287
- return new CliStructuredError('5013', 'Failed to install Prisma Next skills', {
288
- domain: 'CLI',
289
- why: `\`${options.skillInstallCommand}\` exited with an error: ${options.cause}`,
290
- fix:
291
- 'Either:\n' +
292
- ` - Re-run \`prisma-next init --no-skill${options.filesWritten.length > 0 ? ' --force' : ''}\` to skip the skill install for this run, or\n` +
293
- ` - Fix the underlying issue (network, npm registry, \`npx skills\` on PATH) and install manually:\n ${options.skillInstallCommand}`,
294
- docsUrl: 'https://prisma-next.dev/docs/cli/init#skills',
295
- meta: {
296
- filesWritten: options.filesWritten,
297
- skillInstallCommand: options.skillInstallCommand,
298
- cause: options.cause,
288
+ return new CliStructuredError(
289
+ 'CLI.INIT_SKILL_INSTALL_FAILED',
290
+ 'Failed to install Prisma Next skills',
291
+ {
292
+ why: `\`${options.skillInstallCommand}\` exited with an error: ${options.cause}`,
293
+ fix:
294
+ 'Either:\n' +
295
+ ` - Re-run \`prisma-next init --no-skill${options.filesWritten.length > 0 ? ' --force' : ''}\` to skip the skill install for this run, or\n` +
296
+ ` - Fix the underlying issue (network, npm registry, \`npx skills\` on PATH) and install manually:\n ${options.skillInstallCommand}`,
297
+ docsUrl: 'https://prisma-next.dev/docs/cli/init#skills',
298
+ meta: {
299
+ filesWritten: options.filesWritten,
300
+ skillInstallCommand: options.skillInstallCommand,
301
+ cause: options.cause,
302
+ },
299
303
  },
300
- });
304
+ );
301
305
  }
@@ -534,18 +534,21 @@ export async function runInit(
534
534
  if (validated instanceof Error || (validated as { problems?: unknown }).problems !== undefined) {
535
535
  // Route through `emitError` rather than throwing: the bare throw
536
536
  // bypassed `--json` envelope formatting and `exitCodeForError`, so a
537
- // 5009 regression would surface as an uncaught exception in
538
- // commander instead of the documented `INTERNAL_ERROR` envelope on
539
- // the right channel.
537
+ // CLI.INIT_INVALID_OUTPUT_DOCUMENT regression would surface as an
538
+ // uncaught exception in commander instead of the documented
539
+ // `INTERNAL_ERROR` envelope on the right channel.
540
540
  return emitError(
541
541
  ui,
542
542
  flags,
543
- new CliStructuredError('5009', 'Init produced an invalid output document', {
544
- domain: 'CLI',
545
- why: `The success document failed schema validation: ${String(validated)}`,
546
- fix: 'This is a bug in prisma-next. Please report it with the full `-v` output.',
547
- docsUrl: 'https://prisma-next.dev/docs/cli/init',
548
- }),
543
+ new CliStructuredError(
544
+ 'CLI.INIT_INVALID_OUTPUT_DOCUMENT',
545
+ 'Init produced an invalid output document',
546
+ {
547
+ why: `The success document failed schema validation: ${String(validated)}`,
548
+ fix: 'This is a bug in prisma-next. Please report it with the full `-v` output.',
549
+ docsUrl: 'https://prisma-next.dev/docs/cli/init',
550
+ },
551
+ ),
549
552
  );
550
553
  }
551
554
 
@@ -582,10 +585,10 @@ function emitError(ui: TerminalUI, flags: GlobalFlags, error: CliStructuredError
582
585
  * Maps a structured init error to its documented exit code. Centralised so
583
586
  * the error → exit-code contract lives next to the codes themselves.
584
587
  *
585
- * `5009` (and the unknown-code default branch) routes to
586
- * `INIT_EXIT_INTERNAL_ERROR` because those represent prisma-next bugs the
587
- * user did not cause — surfacing them as `PRECONDITION` would mislead
588
- * automation into thinking the caller mis-invoked the CLI.
588
+ * `CLI.INIT_INVALID_OUTPUT_DOCUMENT` (and the unknown-code default branch)
589
+ * routes to `INIT_EXIT_INTERNAL_ERROR` because those represent prisma-next
590
+ * bugs the user did not cause — surfacing them as `PRECONDITION` would
591
+ * mislead automation into thinking the caller mis-invoked the CLI.
589
592
  *
590
593
  * See [exit-codes.ts](./exit-codes.ts) for the canonical list and
591
594
  * [Style Guide § Exit Codes](../../../../../../../docs/CLI%20Style%20Guide.md#exit-codes)
@@ -596,24 +599,24 @@ function emitError(ui: TerminalUI, flags: GlobalFlags, error: CliStructuredError
596
599
  */
597
600
  export function exitCodeForError(error: { readonly code: string }): number {
598
601
  switch (error.code) {
599
- case '5002': // re-init needs --force — precondition
600
- case '5003': // missing flags — precondition
601
- case '5004': // invalid flag value — precondition
602
- case '5005': // --strict-probe without --probe-db — precondition
603
- case '5010': // invalid manifest (malformed package.json) — precondition
604
- case '5011': // invalid tsconfig (unparseable JSONC) — precondition
605
- case '5012': // probe failed under --strict-probe — precondition
606
- case '5014': // --authoring / --schema-path extension mismatch — precondition
602
+ case 'CLI.INIT_REINIT_NEEDS_FORCE': // re-init needs --force — precondition
603
+ case 'CLI.INIT_MISSING_FLAGS': // missing flags — precondition
604
+ case 'CLI.INIT_INVALID_FLAG_VALUE': // invalid flag value — precondition
605
+ case 'CLI.INIT_STRICT_PROBE_WITHOUT_PROBE': // --strict-probe without --probe-db — precondition
606
+ case 'CLI.INIT_INVALID_MANIFEST': // invalid manifest (malformed package.json) — precondition
607
+ case 'CLI.INIT_INVALID_TSCONFIG': // invalid tsconfig (unparseable JSONC) — precondition
608
+ case 'CLI.INIT_PROBE_FAILED': // probe failed under --strict-probe — precondition
609
+ case 'CLI.INIT_AUTHORING_SCHEMA_PATH_MISMATCH': // --authoring / --schema-path extension mismatch — precondition
607
610
  return INIT_EXIT_PRECONDITION;
608
- case '5006': // user aborted interactive prompt
611
+ case 'CLI.INIT_USER_ABORTED': // user aborted interactive prompt
609
612
  return INIT_EXIT_USER_ABORTED;
610
- case '5007': // install failed
613
+ case 'CLI.INIT_INSTALL_FAILED': // install failed
611
614
  return INIT_EXIT_INSTALL_FAILED;
612
- case '5008': // emit failed
615
+ case 'CLI.INIT_EMIT_FAILED': // emit failed
613
616
  return INIT_EXIT_EMIT_FAILED;
614
- case '5009': // invalid output document — internal bug in prisma-next
617
+ case 'CLI.INIT_INVALID_OUTPUT_DOCUMENT': // invalid output document — internal bug in prisma-next
615
618
  return INIT_EXIT_INTERNAL_ERROR;
616
- case '5013': // skill install failed
619
+ case 'CLI.INIT_SKILL_INSTALL_FAILED': // skill install failed
617
620
  return INIT_EXIT_SKILL_INSTALL_FAILED;
618
621
  default:
619
622
  // Any unexpected code is treated as an internal bug rather than
@@ -83,7 +83,7 @@ function checkFileExists(
83
83
  if (!existsSync(join(dirPath, fileName))) {
84
84
  return {
85
85
  space: spaceId,
86
- code: 'PN-MIG-CHECK-002',
86
+ code: 'MIGRATION.CHECK_FILE_MISSING',
87
87
  where: migrationFileRelative(dirPath, fileName),
88
88
  why: `${fileName} is missing from ${dirName}`,
89
89
  fix: 'Re-emit the migration package or restore from version control.',
@@ -105,7 +105,7 @@ function checkSnapshotConsistency(
105
105
  if (typeof snapshotHash === 'string' && snapshotHash !== pkg.metadata.to) {
106
106
  return {
107
107
  space: spaceId,
108
- code: 'PN-MIG-CHECK-005',
108
+ code: 'MIGRATION.CHECK_SNAPSHOT_HASH_MISMATCH',
109
109
  where: migrationPathRelative(pkg.dirPath),
110
110
  why: `Migration "${pkg.dirName}" declares to=${pkg.metadata.to} but end-contract.json has storageHash=${snapshotHash}`,
111
111
  fix: 'Re-emit the migration package so migration.json and end-contract.json agree.',
@@ -114,7 +114,7 @@ function checkSnapshotConsistency(
114
114
  } catch {
115
115
  return {
116
116
  space: spaceId,
117
- code: 'PN-MIG-CHECK-006',
117
+ code: 'MIGRATION.CHECK_SNAPSHOT_UNPARSEABLE',
118
118
  where: migrationPathRelative(pkg.dirPath),
119
119
  why: `Migration "${pkg.dirName}" has an unparseable end-contract.json.`,
120
120
  fix: 'Re-emit the migration package to repair the snapshot file.',
@@ -212,7 +212,7 @@ function checkReachability(space: CheckSpace): readonly CheckFailure[] {
212
212
  if (!isReachable) {
213
213
  failures.push({
214
214
  space: space.spaceId,
215
- code: 'PN-MIG-CHECK-003',
215
+ code: 'MIGRATION.CHECK_UNREACHABLE_MIGRATION',
216
216
  where: migrationPathRelative(pkg.dirPath),
217
217
  why: `Migration "${pkg.dirName}" starts from ${pkg.metadata.from} which no other migration produces`,
218
218
  fix: 'This migration is unreachable in the graph. Delete it or re-emit a connecting migration.',
@@ -228,7 +228,7 @@ function checkDanglingRefs(space: CheckSpace): readonly CheckFailure[] {
228
228
  if (!space.graph.nodes.has(entry.hash)) {
229
229
  failures.push({
230
230
  space: space.spaceId,
231
- code: 'PN-MIG-CHECK-004',
231
+ code: 'MIGRATION.CHECK_DANGLING_REF',
232
232
  where: relative(process.cwd(), join(space.refsDir, `${name}.json`)),
233
233
  why: `Ref "${name}" points at ${entry.hash} which does not exist in the migration graph`,
234
234
  fix: `Update the ref with \`prisma-next ref set ${name} <valid-hash>\` or delete it.`,
@@ -522,7 +522,7 @@ async function checkSingleTarget(
522
522
  matchedPkg = hits[0]!.pkg;
523
523
  } else if (bestParseFailure !== undefined) {
524
524
  // The ref didn't resolve in any in-scope space — surface the most informative
525
- // parse failure through the shared ref-resolution envelope (PN-RUN-3000) the
525
+ // parse failure through the shared ref-resolution envelope (CONTRACT.VERIFY_FAILED) the
526
526
  // earlier work established, rather than a bespoke string. (Ref-resolved-but-
527
527
  // no-package falls through to the "not found on disk" result below.)
528
528
  return { error: mapRefResolutionError(bestParseFailure), exitCode: PRECONDITION };
@@ -551,7 +551,7 @@ async function checkSingleTarget(
551
551
  if (!verification.ok) {
552
552
  failures.push({
553
553
  space: matchedSpace.spaceId,
554
- code: 'PN-MIG-CHECK-001',
554
+ code: 'MIGRATION.CHECK_HASH_MISMATCH',
555
555
  where: migrationFileRelative(matchedPkg.dirPath, 'migration.json'),
556
556
  why: `Stored hash ${verification.storedHash} does not match recomputed hash ${verification.computedHash}`,
557
557
  fix: 'Re-emit the migration package or restore from version control.',
@@ -142,7 +142,7 @@ async function runPlannerLeg(
142
142
  );
143
143
  }
144
144
  } catch (e) {
145
- if (CliStructuredError.is(e) && e.domain === 'MIG' && e.code === '2001') {
145
+ if (CliStructuredError.is(e) && e.code === 'MIGRATION.UNFILLED_PLACEHOLDER') {
146
146
  hasPlaceholders = true;
147
147
  } else {
148
148
  throw e;
@@ -286,8 +286,9 @@ function aggregatePlannerWarnings(
286
286
  * an extension that was removed from `extensionPacks` without first
287
287
  * cleaning up its on-disk migrations / database tables.
288
288
  *
289
- * Returns a {@link CliStructuredError} envelope (code `5002`,
290
- * `kind: 'orphanMarker'`) for the first orphan it finds, or `null`
289
+ * Returns a {@link CliStructuredError} envelope (code
290
+ * `MIGRATION.CONTRACT_SPACE_VIOLATION`, `kind: 'orphanMarker'`) for the
291
+ * first orphan it finds, or `null`
291
292
  * when every marker row maps to a declared contract space. Mirrors the M2
292
293
  * `runContractSpaceVerifierMarkerCheck` envelope so downstream
293
294
  * tooling (integration tests, JSON consumers) keeps asserting on the
@@ -313,8 +314,7 @@ function detectOrphanMarkers(
313
314
  orphans.length === 1
314
315
  ? `Orphan contract-space marker detected for "${orphans[0]}"`
315
316
  : `Orphan contract-space markers detected for ${orphans.length} spaces`;
316
- return new CliStructuredError('5002', summary, {
317
- domain: 'MIG',
317
+ return new CliStructuredError('MIGRATION.CONTRACT_SPACE_VIOLATION', summary, {
318
318
  why: `The database has \`_prisma_marker\` rows for spaces (${orphans
319
319
  .map((s) => `"${s}"`)
320
320
  .join(
@@ -254,12 +254,15 @@ function finaliseVerifyResult(args: {
254
254
  if (!verifyResult.ok) {
255
255
  emitVerifySpan(onProgress, 'spanEndError');
256
256
  return notOk(
257
- new CliStructuredError('5002', 'Aggregate verifier introspection failed', {
258
- domain: 'MIG',
259
- why: verifyResult.failure.detail,
260
- fix: 'Check database connectivity and the introspection tooling.',
261
- docsUrl: 'https://pris.ly/contract-spaces',
262
- }),
257
+ new CliStructuredError(
258
+ 'MIGRATION.CONTRACT_SPACE_VIOLATION',
259
+ 'Aggregate verifier introspection failed',
260
+ {
261
+ why: verifyResult.failure.detail,
262
+ fix: 'Check database connectivity and the introspection tooling.',
263
+ docsUrl: 'https://pris.ly/contract-spaces',
264
+ },
265
+ ),
263
266
  );
264
267
  }
265
268
  const markerError = skipMarker
@@ -300,7 +303,8 @@ function buildSkippedSchemaResult(space: AggregateContractSpace): VerifyDatabase
300
303
  /**
301
304
  * Translate per-space marker check failures and orphan markers into a
302
305
  * single CLI structured error envelope. Preserves the legacy code
303
- * `5002` (was emitted by `runContractSpaceVerifierMarkerCheck`).
306
+ * `MIGRATION.CONTRACT_SPACE_VIOLATION` (was emitted by
307
+ * `runContractSpaceVerifierMarkerCheck`).
304
308
  */
305
309
  function mapMarkerCheckFailures(
306
310
  appSpaceId: string,
@@ -354,8 +358,7 @@ function mapMarkerCheckFailures(
354
358
  violations.length === 1
355
359
  ? 'Contract-space verifier found a violation'
356
360
  : `Contract-space verifier found violations (${violations.length})`;
357
- return new CliStructuredError('5002', summary, {
358
- domain: 'MIG',
361
+ return new CliStructuredError('MIGRATION.CONTRACT_SPACE_VIOLATION', summary, {
359
362
  why: `The on-disk \`migrations/\` directory, the \`extensionPacks\` declaration, and the live database marker rows are not in agreement.\n${lines.join('\n')}`,
360
363
  fix: violations[0]?.remediation ?? 'Review and reconcile the violations listed above.',
361
364
  docsUrl: 'https://pris.ly/contract-spaces',
@@ -12,6 +12,7 @@ import type {
12
12
  } from '@prisma-next/framework-components/control';
13
13
  import {
14
14
  type AggregateContractSpace,
15
+ allStorageElementsExternal,
15
16
  buildFabricatedMigrationEdge,
16
17
  type ContractMarkerRecordLike,
17
18
  type ContractSpaceAggregate,
@@ -98,13 +99,17 @@ export interface ExecuteMigrateOptions<TFamilyId extends string, TTargetId exten
98
99
  * 2. Read live marker rows per space (`familyInstance.readAllMarkers`).
99
100
  * 3. Per space: `resolveRecordedPath` plots the path from the live
100
101
  * marker to `space.headRef.hash` (or `refHash` for the app
101
- * space when provided). Empty-graph spaces fail loudly a
102
- * "never planned" space is a user-error condition for replay.
102
+ * space when provided). An empty-graph space whose elements are ALL
103
+ * externally managed resolves declaratively (marker to head, zero
104
+ * ops), mirroring the db-init aggregate planner: such a space ships
105
+ * no DDL and has nothing to author. Every other empty-graph space
106
+ * fails loudly — "never planned" is a user-error condition for
107
+ * replay.
103
108
  * 4. Hand off to {@link runMigration} (the runner-driving tail
104
109
  * shared with `db init` / `db update`). Marker advancement is
105
110
  * inside the per-space transaction.
106
111
  *
107
- * Encodes the replay-only contract: every contract space must have an
112
+ * Encodes the replay-only contract: the app contract space must have an
108
113
  * authored migration graph on disk before this operation can advance it.
109
114
  */
110
115
  export async function executeMigrate<TFamilyId extends string, TTargetId extends string>(
@@ -230,8 +235,13 @@ export async function executeMigrate<TFamilyId extends string, TTargetId extends
230
235
  // plans). Surfaces every loaded space — including at-head empty-
231
236
  // graph extensions — in `perSpace[]` so the result reflects the
232
237
  // full aggregate, not just the spaces the runner would have touched.
233
- const totalPlannedOps = sumPlannedOps(applyOrder, perSpacePlans);
234
- if (totalPlannedOps === 0) {
238
+ // A zero-op plan still counts as pending when it advances a marker
239
+ // (declared-state resolution for an all-external extension space).
240
+ const hasPendingWork = applyOrder.some((spaceId) => {
241
+ const entry = perSpacePlans.get(spaceId);
242
+ return entry !== undefined && planRequiresExecution(entry);
243
+ });
244
+ if (!hasPendingWork) {
235
245
  const ordered = canonicalOrder
236
246
  .filter((spaceId) => perSpacePlans.has(spaceId) || atHeadResolutions.has(spaceId))
237
247
  .map((spaceId) => {
@@ -397,6 +407,39 @@ export function planSpacePath({
397
407
  }),
398
408
  };
399
409
  }
410
+ // Empty-graph extension space not yet at head: the space ships no
411
+ // migration packages at all. Advancing the marker without migrations
412
+ // (the db-init aggregate planner's declared-state strategy, mirrored
413
+ // here) is valid exclusively when every element the space declares is
414
+ // externally managed — nothing Prisma Next owns exists in such a space
415
+ // (e.g. Supabase's auth/storage), so its declared state needs no
416
+ // migration to be true, and there is no command that could author an
417
+ // edge for it. A space that declares a managed element but ships no
418
+ // migration graph is an authoring bug: it falls through to the
419
+ // never-planned failure, like an app space with no authored graph.
420
+ if (!isAppSpace && allStorageElementsExternal(space.contract())) {
421
+ if (headRef.invariants.length > 0) {
422
+ return {
423
+ kind: 'unsatisfiable',
424
+ spaceId: space.spaceId,
425
+ isAppSpace,
426
+ missing: [...headRef.invariants].sort(),
427
+ targetInvariants: headRef.invariants,
428
+ targetSpace: space,
429
+ liveHash: liveHash ?? EMPTY_CONTRACT_HASH,
430
+ refName: undefined,
431
+ };
432
+ }
433
+ return {
434
+ kind: 'ok',
435
+ plan: buildAtHeadResolution({
436
+ aggregateTargetId: aggregate.targetId,
437
+ space,
438
+ targetHash,
439
+ liveMarker,
440
+ }),
441
+ };
442
+ }
400
443
  return { kind: 'never-planned', spaceId: space.spaceId, targetHash };
401
444
  }
402
445
 
@@ -434,11 +477,13 @@ export function planSpacePath({
434
477
  }
435
478
 
436
479
  /**
437
- * Build a zero-op {@link PerSpacePlan} for an empty-graph
438
- * space whose live marker already matches the target. Lets the apply
439
- * pipeline thread the space through `perSpacePlans` -> `applyOrder`
440
- * -> the success envelope's `perSpace[]` block so the result reflects
441
- * every loaded space, even when there is nothing to execute.
480
+ * Build a zero-op {@link PerSpacePlan} for an empty-graph space —
481
+ * either one whose live marker already matches the target (at-head), or
482
+ * an all-external extension space whose marker must advance to the head
483
+ * ref with no DDL (declared-state). Lets the apply pipeline thread the
484
+ * space through `perSpacePlans` -> `applyOrder` -> the success
485
+ * envelope's `perSpace[]` block so the result reflects every loaded
486
+ * space, even when there is nothing to execute.
442
487
  */
443
488
  function buildAtHeadResolution(args: {
444
489
  readonly aggregateTargetId: string;
@@ -469,17 +514,14 @@ function buildAtHeadResolution(args: {
469
514
  };
470
515
  }
471
516
 
472
- function sumPlannedOps(
473
- applyOrder: readonly string[],
474
- perSpacePlans: ReadonlyMap<string, PerSpacePlan>,
475
- ): number {
476
- let total = 0;
477
- for (const spaceId of applyOrder) {
478
- const entry = perSpacePlans.get(spaceId);
479
- if (!entry) continue;
480
- total += entry.plan.operations.length;
481
- }
482
- return total;
517
+ /**
518
+ * A plan needs the runner when it executes operations or advances the
519
+ * space's marker (a declared-state resolution has zero operations but a
520
+ * destination hash the live marker doesn't carry yet).
521
+ */
522
+ function planRequiresExecution(entry: PerSpacePlan): boolean {
523
+ if (entry.plan.operations.length > 0) return true;
524
+ return entry.plan.origin?.storageHash !== entry.plan.destination.storageHash;
483
525
  }
484
526
 
485
527
  interface BuildSuccessArgs {
@@ -552,10 +594,12 @@ function buildSuccess(args: BuildSuccessArgs): MigrateSuccess {
552
594
  }
553
595
 
554
596
  /**
555
- * Build the `neverPlanned` failure raised when a contract space has no on-disk
556
- * migration graph but migrate was asked to reach a target hash. The `why`
557
- * states only the condition; the recovery sequence is composed by
558
- * `errorPathUnreachable`'s `fix`.
597
+ * Build the `neverPlanned` failure raised when a contract space that
598
+ * declares managed storage elements has no on-disk migration graph but
599
+ * migrate was asked to reach a target hash. All-external spaces never reach
600
+ * this: they resolve declaratively (marker advances to the head ref with
601
+ * zero operations). The `why` states only the condition; the recovery
602
+ * sequence is composed by `errorPathUnreachable`'s `fix`.
559
603
  *
560
604
  * @internal Exported for testing only.
561
605
  */
@@ -563,7 +607,7 @@ export function buildNeverPlannedFailure(spaceId: string, targetHash: string): M
563
607
  return {
564
608
  code: 'MIGRATION_PATH_NOT_FOUND',
565
609
  summary: `No on-disk migrations for contract space "${spaceId}"`,
566
- why: `migrate is replay-only: every contract space must have an authored migration graph on disk. Space "${spaceId}" has no migrations under \`migrations/${spaceId}/\` but its head ref targets "${targetHash}".`,
610
+ why: `migrate is replay-only: a contract space that declares managed storage elements must have an authored migration graph on disk. Space "${spaceId}" has no migrations under \`migrations/${spaceId}/\` but its head ref targets "${targetHash}".`,
567
611
  meta: { spaceId, target: targetHash, kind: 'neverPlanned' },
568
612
  };
569
613
  }
@@ -402,7 +402,10 @@ export interface DbInitSuccess {
402
402
  /**
403
403
  * Failure codes for dbInit operation.
404
404
  */
405
- export type DbInitFailureCode = 'PLANNING_FAILED' | 'MARKER_ORIGIN_MISMATCH' | 'RUNNER_FAILED';
405
+ export type DbInitFailureCode =
406
+ | 'PLANNING_FAILED'
407
+ | 'MIGRATION.MARKER_ORIGIN_MISMATCH'
408
+ | 'RUNNER_FAILED';
406
409
 
407
410
  /**
408
411
  * Failure details for dbInit operation.
@@ -21,7 +21,7 @@
21
21
  * the CLI commands use, walking up from the migration file's directory.
22
22
  * 4. Probe-instantiates the migration class without a stack so it can read
23
23
  * `targetId` and verify it matches `config.target.targetId`
24
- * (`PN-MIG-2006` on mismatch) before any stack-driven adapter
24
+ * (`MIGRATION.TARGET_MISMATCH` on mismatch) before any stack-driven adapter
25
25
  * construction runs.
26
26
  * 5. Assembles a `ControlStack` from the loaded config descriptors and
27
27
  * constructs the migration with that stack.
@@ -269,7 +269,7 @@ async function orchestrate(
269
269
 
270
270
  // Pre-scan for malformed `--config` (no value, or value-shaped-as-flag)
271
271
  // before delegating to clipanion. The legacy parser surfaced both as
272
- // `errorMigrationCliInvalidConfigArg` (`PN-CLI-4012`); pre-scanning
272
+ // `errorMigrationCliInvalidConfigArg` (`CLI.CONFIG_ARG_MISSING_PATH`); pre-scanning
273
273
  // here keeps that contract independent of how clipanion classifies
274
274
  // the error internally (it variably throws `UnknownSyntaxError` or
275
275
  // accepts the flag-shaped token as the value depending on what other
@@ -337,7 +337,7 @@ async function orchestrate(
337
337
  * - `--config <empty>` where the value is the empty string. Shells
338
338
  * expand `--config ""` (or `--config "$UNSET_VAR"`) into a real
339
339
  * empty argv token; treating that as a usage error here surfaces
340
- * `PN-CLI-4012` instead of a less actionable loader error on an
340
+ * `CLI.CONFIG_ARG_MISSING_PATH` instead of a less actionable loader error on an
341
341
  * empty path.
342
342
  * - `--config=` (the equals form with an empty value). Same shape as
343
343
  * the empty-string case above; the user expressed intent to override
@@ -425,7 +425,7 @@ function isUnknownSyntaxError(err: unknown): err is Error {
425
425
  /**
426
426
  * Best-effort: pull the first input token that doesn't match a known
427
427
  * flag. Falls back to the first token when we can't pinpoint it. The
428
- * returned name is rendered into the user-visible PN-CLI-4013 envelope
428
+ * returned name is rendered into the user-visible CLI.UNKNOWN_FLAG envelope
429
429
  * (`Unknown flag \`<name>\``) and round-tripped via `meta.flag` so
430
430
  * agent consumers can render their own "did you mean" suggestions.
431
431
  */
@@ -556,7 +556,7 @@ async function runMigration(
556
556
  // subclasses are required to accept the no-arg form; the abstract
557
557
  // `Migration` constructor declares `stack?` and target subclasses
558
558
  // (Postgres, Mongo) propagate that optionality. This makes the
559
- // target-mismatch guard fail fast with `PN-MIG-2006` before any
559
+ // target-mismatch guard fail fast with `MIGRATION.TARGET_MISMATCH` before any
560
560
  // stack-driven adapter construction begins, even if the wrong-target
561
561
  // adapter's `create` would otherwise succeed and silently misshapen
562
562
  // the stored adapter cast.