@runa-ai/runa-cli 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/{build-V66FAQXB.js → build-HUDIP6KU.js} +1 -1
  2. package/dist/{chunk-AIP6MR42.js → chunk-AFY3TX4I.js} +1 -1
  3. package/dist/{chunk-KWX3JHCY.js → chunk-AKZAN4BC.js} +6 -1
  4. package/dist/{chunk-SGJG3BKD.js → chunk-CCW3PLQY.js} +1 -1
  5. package/dist/{chunk-IBVVGH6X.js → chunk-EMB6IZFT.js} +17 -4
  6. package/dist/{ci-ZWRVWNFX.js → ci-XY6IKEDC.js} +844 -120
  7. package/dist/{cli-2JNBJUBB.js → cli-UZA4RBNQ.js} +13 -13
  8. package/dist/commands/ci/machine/actors/db/collect-schema-stats.d.ts +4 -1
  9. package/dist/commands/ci/machine/actors/db/production-preview.d.ts +10 -0
  10. package/dist/commands/ci/machine/actors/db/schema-canonical-diff.d.ts +22 -0
  11. package/dist/commands/ci/machine/commands/machine-runner.d.ts +2 -0
  12. package/dist/commands/ci/machine/formatters/sections/production-schema-status.d.ts +30 -0
  13. package/dist/commands/ci/machine/helpers.d.ts +8 -0
  14. package/dist/commands/ci/machine/machine.d.ts +57 -4
  15. package/dist/commands/template-check/commands/template-check.d.ts +1 -0
  16. package/dist/commands/template-check/contract.d.ts +1 -0
  17. package/dist/constants/versions.d.ts +1 -1
  18. package/dist/{db-XULCILOU.js → db-Q3GF7JWP.js} +78 -18
  19. package/dist/{env-SS66PZ4B.js → env-GMB3THRG.js} +1 -1
  20. package/dist/{hotfix-YA3DGLOM.js → hotfix-NDTPY2T4.js} +1 -1
  21. package/dist/index.js +3 -3
  22. package/dist/{init-ZIL6LRFO.js → init-U4VCRHTD.js} +1 -1
  23. package/dist/{template-check-3P4HZXVY.js → template-check-FFJVDLBF.js} +23 -6
  24. package/dist/{upgrade-NUK3ZBCL.js → upgrade-7TWORWBV.js} +1 -1
  25. package/dist/{vuln-check-2W7N5TA2.js → vuln-check-6CMNPSBR.js} +1 -1
  26. package/dist/{vuln-checker-IQJ56RUV.js → vuln-checker-EJJTNDNE.js} +1 -1
  27. package/package.json +2 -2
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'module';
3
3
  import { enableNonInteractiveMode } from './chunk-6Y3LAUGL.js';
4
4
  import { getRequestedCommandNameFromArgv } from './chunk-UWWSAPDR.js';
5
- import { CLI_VERSION, HAS_ADMIN_COMMAND } from './chunk-AIP6MR42.js';
5
+ import { CLI_VERSION, HAS_ADMIN_COMMAND } from './chunk-AFY3TX4I.js';
6
6
  import { emitDefaultSuccessIfNeeded } from './chunk-WJXC4MVY.js';
7
7
  import { parseOutputFormat, setOutputFormat, getOutputFormatFromEnv } from './chunk-HKUWEGUX.js';
8
8
  import { init_esm_shims } from './chunk-VRXHCR5K.js';
@@ -145,7 +145,7 @@ function isTestCommand(requested) {
145
145
  async function registerProjectLifecycleCommands(program, requested, loadAllCommands) {
146
146
  if (!loadAllCommands && requested) {
147
147
  if (requested === "init") {
148
- const { initCommand: initCommand2 } = await import('./init-ZIL6LRFO.js');
148
+ const { initCommand: initCommand2 } = await import('./init-U4VCRHTD.js');
149
149
  program.addCommand(initCommand2);
150
150
  return;
151
151
  }
@@ -155,7 +155,7 @@ async function registerProjectLifecycleCommands(program, requested, loadAllComma
155
155
  return;
156
156
  }
157
157
  if (requested === "upgrade") {
158
- const { upgradeCommand: upgradeCommand2 } = await import('./upgrade-NUK3ZBCL.js');
158
+ const { upgradeCommand: upgradeCommand2 } = await import('./upgrade-7TWORWBV.js');
159
159
  program.addCommand(upgradeCommand2);
160
160
  return;
161
161
  }
@@ -165,7 +165,7 @@ async function registerProjectLifecycleCommands(program, requested, loadAllComma
165
165
  return;
166
166
  }
167
167
  if (requested === "build") {
168
- const { buildCommand: buildCommand2 } = await import('./build-V66FAQXB.js');
168
+ const { buildCommand: buildCommand2 } = await import('./build-HUDIP6KU.js');
169
169
  program.addCommand(buildCommand2);
170
170
  return;
171
171
  }
@@ -183,11 +183,11 @@ async function registerProjectLifecycleCommands(program, requested, loadAllComma
183
183
  { buildCommand },
184
184
  { devCommand }
185
185
  ] = await Promise.all([
186
- import('./init-ZIL6LRFO.js'),
186
+ import('./init-U4VCRHTD.js'),
187
187
  import('./prepare-32DOVHTE.js'),
188
- import('./upgrade-NUK3ZBCL.js'),
188
+ import('./upgrade-7TWORWBV.js'),
189
189
  import('./validate-CAAW4Y44.js'),
190
- import('./build-V66FAQXB.js'),
190
+ import('./build-HUDIP6KU.js'),
191
191
  import('./dev-5YXNPTCJ.js')
192
192
  ]);
193
193
  program.addCommand(initCommand);
@@ -444,11 +444,11 @@ async function registerStatusCheckAndUtilityCommands(program, requested, loadAll
444
444
  program.addCommand(unlinkCommand);
445
445
  }
446
446
  async function registerCiCommand(program) {
447
- const { ciCommand } = await import('./ci-ZWRVWNFX.js');
447
+ const { ciCommand } = await import('./ci-XY6IKEDC.js');
448
448
  program.addCommand(ciCommand);
449
449
  }
450
450
  async function registerDbCommand(program) {
451
- const { dbCommand } = await import('./db-XULCILOU.js');
451
+ const { dbCommand } = await import('./db-Q3GF7JWP.js');
452
452
  program.addCommand(dbCommand);
453
453
  }
454
454
  async function registerServicesCommand(program) {
@@ -456,11 +456,11 @@ async function registerServicesCommand(program) {
456
456
  program.addCommand(servicesCommand);
457
457
  }
458
458
  async function registerEnvCommand(program) {
459
- const { envCommand } = await import('./env-SS66PZ4B.js');
459
+ const { envCommand } = await import('./env-GMB3THRG.js');
460
460
  program.addCommand(envCommand);
461
461
  }
462
462
  async function registerHotfixCommand(program) {
463
- const { hotfixCommand } = await import('./hotfix-YA3DGLOM.js');
463
+ const { hotfixCommand } = await import('./hotfix-NDTPY2T4.js');
464
464
  program.addCommand(hotfixCommand);
465
465
  }
466
466
  async function registerSdkCommand(program) {
@@ -480,11 +480,11 @@ async function registerWorkflowCommand(program) {
480
480
  program.addCommand(workflowCommand);
481
481
  }
482
482
  async function registerVulnCheckCommand(program) {
483
- const { vulnCheckCommand } = await import('./vuln-check-2W7N5TA2.js');
483
+ const { vulnCheckCommand } = await import('./vuln-check-6CMNPSBR.js');
484
484
  program.addCommand(vulnCheckCommand);
485
485
  }
486
486
  async function registerTemplateCheckCommand(program) {
487
- const { templateCheckCommand } = await import('./template-check-3P4HZXVY.js');
487
+ const { templateCheckCommand } = await import('./template-check-FFJVDLBF.js');
488
488
  program.addCommand(templateCheckCommand);
489
489
  }
490
490
  async function registerSessionCommands(program) {
@@ -5,7 +5,7 @@
5
5
  * Pattern: Fine-grained actor for single step
6
6
  *
7
7
  * Comparison strategy:
8
- * - Reference stats: Build a temporary reference DB from repo SQL, then query it
8
+ * - Reference stats: Build a temporary reference DB from repo SQL, or reuse the synced CI DB
9
9
  * - CI stats: Query CI database (Docker Supabase or Branch DB)
10
10
  * - Production stats: Query Production DB (if GH_DATABASE_URL_ADMIN set)
11
11
  *
@@ -16,6 +16,7 @@
16
16
  * Results are used for PR comment Schema Status table.
17
17
  */
18
18
  import { type SchemaStatsSnapshot } from './schema-stats.js';
19
+ export type ReferenceStatsStrategy = 'rebuild' | 'reuse-ci';
19
20
  export interface CollectSchemaStatsInput {
20
21
  /** Repository root (used to build a reference DB from repo SQL) */
21
22
  repoRoot: string;
@@ -23,6 +24,8 @@ export interface CollectSchemaStatsInput {
23
24
  referenceDbUrl: string | null;
24
25
  /** CI database URL (Docker Supabase or Branch DB) */
25
26
  ciDbUrl: string | null;
27
+ /** How to resolve the reference schema snapshot */
28
+ referenceStrategy?: ReferenceStatsStrategy;
26
29
  /** Whether to query production (requires GH_DATABASE_URL_ADMIN) */
27
30
  queryProduction: boolean;
28
31
  /** Temporary directory for logs */
@@ -21,6 +21,16 @@ export interface ProductionPreviewInput {
21
21
  export interface ProductionPreviewOutput {
22
22
  preview: ProductionPreview;
23
23
  }
24
+ export type SchemaChangeState = 'changes' | 'no-changes' | 'unknown';
25
+ /**
26
+ * Detect whether db apply --check output indicates schema changes.
27
+ *
28
+ * Important:
29
+ * - "No changes were applied (check mode)" is always true in check mode and MUST NOT
30
+ * be treated as "schema changes = none".
31
+ * - We prefer explicit change/no-change summary lines from db apply output.
32
+ */
33
+ export declare function detectSchemaChangeState(fullOutput: string): SchemaChangeState;
24
34
  /**
25
35
  * Run production schema preview (dry-run).
26
36
  *
@@ -48,8 +48,30 @@ export interface SchemaSemanticSummary {
48
48
  }
49
49
  export type CanonicalDiffBySchema = Record<string, SchemaSemanticSummary>;
50
50
  export declare function createUnavailableCanonicalSnapshot(error: string): CanonicalSchemaSnapshot;
51
+ interface TableColumnRow {
52
+ schema_name: string;
53
+ table_name: string;
54
+ attnum: number;
55
+ column_name: string;
56
+ data_type: string;
57
+ not_null: boolean;
58
+ default_expr?: string | null;
59
+ identity_kind?: string | null;
60
+ generated_kind?: string | null;
61
+ }
62
+ interface CanonicalTableColumnPayload {
63
+ name: string;
64
+ type: string;
65
+ notNull: boolean;
66
+ default: string;
67
+ identity: string;
68
+ generated: string;
69
+ }
70
+ export declare function createCanonicalTableColumnPayload(row: Pick<TableColumnRow, 'column_name' | 'data_type' | 'not_null' | 'default_expr' | 'identity_kind' | 'generated_kind'>): CanonicalTableColumnPayload;
71
+ export declare function sortCanonicalTableColumns(columns: readonly CanonicalTableColumnPayload[]): CanonicalTableColumnPayload[];
51
72
  export declare function getCanonicalSchemaSnapshot(databaseUrl: string): Promise<CanonicalSchemaSnapshot>;
52
73
  export declare function compareCanonicalSnapshots(reference: CanonicalSchemaSnapshot, target: CanonicalSchemaSnapshot): CanonicalSchemaDiff;
53
74
  export declare function summarizeCanonicalDiffBySchema(diff: CanonicalSchemaDiff): CanonicalDiffBySchema;
54
75
  export declare function hasCanonicalChanges(diff: CanonicalSchemaDiff): boolean;
76
+ export {};
55
77
  //# sourceMappingURL=schema-canonical-diff.d.ts.map
@@ -10,8 +10,10 @@
10
10
  * - Fire-and-forget pattern (non-blocking)
11
11
  */
12
12
  import type { CLILogger } from '@runa-ai/runa';
13
+ import { type CiStep } from '../formatters/github-comment.js';
13
14
  import { type CiSnapshot } from '../machine.js';
14
15
  import type { CiInput, CiOutput, LayerResult } from '../types.js';
16
+ export declare function resolveStepForState(state: string): CiStep | undefined;
15
17
  /**
16
18
  * State change callback type.
17
19
  */
@@ -0,0 +1,30 @@
1
+ import { type ExpectedDriftEntry, type IndexDiff, type SchemaStats, type SchemaStatsSnapshot } from '../../actors/db/schema-stats.js';
2
+ import { type CanonicalSchemaDiff } from '../../actors/db/schema-canonical-diff.js';
3
+ import type { ProductionPreview } from '../../types.js';
4
+ export interface ProductionSchemaSignals {
5
+ previewHasChanges: boolean;
6
+ indexDiff: IndexDiff | null;
7
+ semanticDiff: CanonicalSchemaDiff | null;
8
+ countDiffs: CountDiffEntry[];
9
+ hasIndexChanges: boolean;
10
+ hasUnexpectedIndexChanges: boolean;
11
+ hasSemanticChanges: boolean;
12
+ hasCountChanges: boolean;
13
+ hasUnexpectedCountChanges: boolean;
14
+ hasKnownDriftOnly: boolean;
15
+ knownDriftReasons: string[];
16
+ requiresDeploy: boolean;
17
+ previewMissedChanges: boolean;
18
+ previewOnlyChanges: boolean;
19
+ }
20
+ export interface CountDiffEntry {
21
+ schema: string;
22
+ field: keyof SchemaStats;
23
+ value: number;
24
+ reference: number;
25
+ delta: number;
26
+ expected: boolean;
27
+ reason?: string;
28
+ }
29
+ export declare function getProductionSchemaSignals(productionPreview: ProductionPreview | null, schemaStats: SchemaStatsSnapshot | null, expectedDrift?: ExpectedDriftEntry[]): ProductionSchemaSignals;
30
+ //# sourceMappingURL=production-schema-status.d.ts.map
@@ -29,6 +29,14 @@ export declare function getLayersForCorePhase(selectedLayers: number[], mode: st
29
29
  * Check if E2E layer (4) is selected.
30
30
  */
31
31
  export declare function hasE2ELayer(selectedLayers: number[]): boolean;
32
+ /**
33
+ * Determine whether schema stats can safely reuse the synced CI database
34
+ * instead of rebuilding a temporary reference database.
35
+ *
36
+ * This optimization is only valid for PR CI runs where local-only overlays
37
+ * such as ci.custom.sql are never applied.
38
+ */
39
+ export declare function shouldReuseCiReferenceStats(context: CiContext): boolean;
32
40
  /** Layer result status type */
33
41
  export type LayerStatus = 'passed' | 'failed' | 'skipped' | 'timeout' | 'killed';
34
42
  /**
@@ -8,9 +8,10 @@
8
8
  * 1. idle → START → setup (mode-aware: localSetup or prLocalSetup)
9
9
  * 2. [ci-local] setup → dbReset → pullProduction? → syncSchema → applySeeds
10
10
  * → productionPreview → collectSchemaStats → installPgTap → runCoreTests → done
11
- * 3. [ci-pr] setup → initialComment → syncSchema → applySeeds → productionPreview
12
- * collectSchemaStatssetupRolesstaticChecksbuildAndPlaywright
13
- * appStart → capabilities → runCoreTests → e2ePhase → finalize → done
11
+ * 3. [ci-pr] setup → initialComment → syncSchema → applySeeds → postSeedPr
12
+ * execution: setupRolesstaticChecksbuildAndPlaywrightappStart
13
+ * → capabilities → runCoreTests → e2ePhase → finalize → done
14
+ * observability: productionPreview ∥ collectSchemaStats
14
15
  *
15
16
  * State Flow (detailed):
16
17
  * idle → setup → initialComment? → dbReset? → pullProduction? → syncSchema → applySeeds
@@ -168,10 +169,20 @@ export declare const ciMachine: import("xstate").StateMachine<CiContext, CiEvent
168
169
  } | {
169
170
  type: "allTestsPassed";
170
171
  params: unknown;
171
- }, never, "done" | "failed" | "staticChecks" | "idle" | "capabilities" | "appStart" | "syncSchema" | "applySeeds" | "productionPreview" | "pullProduction" | "collectSchemaStats" | "setupRoles" | "installPgTap" | "buildAndPlaywright" | "initialComment" | "dbReset" | "decidePath" | "runCoreTests" | "coreTestsFailed" | "coreTestsComplete" | {
172
+ }, never, "done" | "failed" | "staticChecks" | "idle" | "capabilities" | "appStart" | "syncSchema" | "applySeeds" | "productionPreview" | "pullProduction" | "collectSchemaStats" | "setupRoles" | "installPgTap" | "buildAndPlaywright" | "initialComment" | "dbReset" | "runCoreTests" | "coreTestsFailed" | "coreTestsComplete" | "decidePath" | {
172
173
  setup: "local" | "resolving" | "prLocal" | "complete";
173
174
  } | {
174
175
  finalize: "writeSummary" | "complete" | "postComment";
176
+ } | {
177
+ postSeedPr: {
178
+ execution: "done" | "failed" | "staticChecks" | "capabilities" | "appStart" | "setupRoles" | "buildAndPlaywright" | "runCoreTests" | "coreTestsFailed" | "coreTestsComplete" | {
179
+ e2ePhase: {
180
+ intermediateComment: "done" | "checking" | "posting";
181
+ e2eTests: "done" | "running";
182
+ };
183
+ };
184
+ observability: "done" | "productionPreview" | "collectSchemaStats";
185
+ };
175
186
  } | {
176
187
  e2ePhase: {
177
188
  intermediateComment: "done" | "checking" | "posting";
@@ -257,6 +268,48 @@ export declare const ciMachine: import("xstate").StateMachine<CiContext, CiEvent
257
268
  readonly pullProduction: {};
258
269
  readonly syncSchema: {};
259
270
  readonly applySeeds: {};
271
+ readonly postSeedPr: {
272
+ states: {
273
+ readonly execution: {
274
+ states: {
275
+ readonly setupRoles: {};
276
+ readonly staticChecks: {};
277
+ readonly buildAndPlaywright: {};
278
+ readonly appStart: {};
279
+ readonly capabilities: {};
280
+ readonly runCoreTests: {};
281
+ readonly coreTestsComplete: {};
282
+ readonly coreTestsFailed: {};
283
+ readonly e2ePhase: {
284
+ states: {
285
+ readonly intermediateComment: {
286
+ states: {
287
+ readonly checking: {};
288
+ readonly posting: {};
289
+ readonly done: {};
290
+ };
291
+ };
292
+ readonly e2eTests: {
293
+ states: {
294
+ readonly running: {};
295
+ readonly done: {};
296
+ };
297
+ };
298
+ };
299
+ };
300
+ readonly failed: {};
301
+ readonly done: {};
302
+ };
303
+ };
304
+ readonly observability: {
305
+ states: {
306
+ readonly productionPreview: {};
307
+ readonly collectSchemaStats: {};
308
+ readonly done: {};
309
+ };
310
+ };
311
+ };
312
+ };
260
313
  readonly productionPreview: {};
261
314
  readonly collectSchemaStats: {};
262
315
  readonly decidePath: {};
@@ -9,6 +9,7 @@
9
9
  * - runa template-check --verbose # Show all files including identical
10
10
  * - runa template-check --diff # Show unified diff for differences
11
11
  * - runa template-check --category rules # Filter by category
12
+ * - runa template-check --path <file> # Restrict to specific paths
12
13
  * - runa template-check --json # Output as JSON (for CI)
13
14
  * - runa template-check --quiet # Only summary + actions (for pre-commit)
14
15
  */
@@ -17,6 +17,7 @@ export declare const SyncCheckInputSchema: z.ZodObject<{
17
17
  verbose: z.ZodDefault<z.ZodBoolean>;
18
18
  diff: z.ZodDefault<z.ZodBoolean>;
19
19
  category: z.ZodOptional<z.ZodString>;
20
+ paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
20
21
  json: z.ZodDefault<z.ZodBoolean>;
21
22
  targetDir: z.ZodOptional<z.ZodString>;
22
23
  quiet: z.ZodDefault<z.ZodBoolean>;
@@ -20,7 +20,7 @@
20
20
  *
21
21
  * Sync strategy: Keep this in sync with packages/runa-templates/package.json version.
22
22
  */
23
- export declare const COMPATIBLE_TEMPLATES_VERSION = "0.5.71";
23
+ export declare const COMPATIBLE_TEMPLATES_VERSION = "0.7.1";
24
24
  /**
25
25
  * Templates package name on GitHub Packages.
26
26
  * Published to npm.pkg.github.com (requires NODE_AUTH_TOKEN).
@@ -3,8 +3,8 @@ import { createRequire } from 'module';
3
3
  import { detectDatabaseStack, getStackPaths } from './chunk-CCKG5R4Y.js';
4
4
  import './chunk-ZZOXM6Q4.js';
5
5
  import { createError } from './chunk-JQXOVCOP.js';
6
- import { resolveDatabaseUrl, tryResolveDatabaseUrl } from './chunk-KWX3JHCY.js';
7
- export { resolveDatabaseUrl, tryResolveDatabaseUrl } from './chunk-KWX3JHCY.js';
6
+ import { resolveDatabaseUrl, tryResolveDatabaseUrl } from './chunk-AKZAN4BC.js';
7
+ export { resolveDatabaseUrl, tryResolveDatabaseUrl } from './chunk-AKZAN4BC.js';
8
8
  import { detectAppSchemas, normalizeDatabaseUrlForDdl, formatSchemasForSql } from './chunk-XDCHRVE3.js';
9
9
  import './chunk-NPSRD26F.js';
10
10
  import { categorizeRisks, detectSchemaRisks } from './chunk-H2AHNI75.js';
@@ -12,7 +12,7 @@ import { loadEnvFiles } from './chunk-644FVGIQ.js';
12
12
  import { diagnoseSupabaseStart } from './chunk-AAIE4F2U.js';
13
13
  import { validateUserFilePath, filterSafePaths, resolveSafePath } from './chunk-DRSUEMAK.js';
14
14
  import { runMachine } from './chunk-QDF7QXBL.js';
15
- import './chunk-IBVVGH6X.js';
15
+ import './chunk-EMB6IZFT.js';
16
16
  import { extractSchemaTablesAndEnums, fetchDbTablesAndEnums, extractTablesFromIdempotentSql, diffSchema, generateTablesManifest, writeEnvLocalBridge, removeEnvLocalBridge } from './chunk-FHG3ILE4.js';
17
17
  import { parsePostgresUrl, buildPsqlEnv, buildPsqlArgs, psqlSyncQuery, blankDollarQuotedBodies, stripSqlComments, psqlSyncFile, psqlExec, psqlQuery } from './chunk-7B5C6U2K.js';
18
18
  import { redactSecrets } from './chunk-II7VYQEM.js';
@@ -223,11 +223,39 @@ function flushStatement(current, results) {
223
223
  if (!sql) return;
224
224
  results.push({ index: current.index, sql, hazards: current.hazards });
225
225
  }
226
+ function stripBlockComments(line, inBlockComment) {
227
+ let index = 0;
228
+ let text = "";
229
+ let isInsideBlockComment = inBlockComment;
230
+ while (index < line.length) {
231
+ if (isInsideBlockComment) {
232
+ const endIndex = line.indexOf("*/", index);
233
+ if (endIndex === -1) {
234
+ return { text, inBlockComment: true };
235
+ }
236
+ index = endIndex + 2;
237
+ isInsideBlockComment = false;
238
+ continue;
239
+ }
240
+ const startIndex = line.indexOf("/*", index);
241
+ if (startIndex === -1) {
242
+ text += line.slice(index);
243
+ break;
244
+ }
245
+ text += line.slice(index, startIndex);
246
+ index = startIndex + 2;
247
+ isInsideBlockComment = true;
248
+ }
249
+ return { text, inBlockComment: isInsideBlockComment };
250
+ }
226
251
  function parseWithStatementMarkers(lines) {
227
252
  const results = [];
228
253
  let current = null;
254
+ let inBlockComment = false;
229
255
  for (const line of lines) {
230
- const trimmed = line.trim();
256
+ const stripped = stripBlockComments(line, inBlockComment);
257
+ inBlockComment = stripped.inBlockComment;
258
+ const trimmed = stripped.text.trim();
231
259
  const idxMatch = trimmed.match(STATEMENT_IDX_REGEX);
232
260
  if (idxMatch) {
233
261
  flushStatement(current, results);
@@ -240,7 +268,7 @@ function parseWithStatementMarkers(lines) {
240
268
  continue;
241
269
  }
242
270
  if (current && trimmed && !trimmed.startsWith("--")) {
243
- current.sqlLines.push(line);
271
+ current.sqlLines.push(stripped.text);
244
272
  }
245
273
  }
246
274
  flushStatement(current, results);
@@ -249,15 +277,18 @@ function parseWithStatementMarkers(lines) {
249
277
  function parseAsSingleStatement(lines) {
250
278
  const sqlLines = [];
251
279
  const hazards = [];
280
+ let inBlockComment = false;
252
281
  for (const line of lines) {
253
- const trimmed = line.trim();
282
+ const stripped = stripBlockComments(line, inBlockComment);
283
+ inBlockComment = stripped.inBlockComment;
284
+ const trimmed = stripped.text.trim();
254
285
  const hazardMatch = trimmed.match(HAZARD_REGEX);
255
286
  if (hazardMatch) {
256
287
  hazards.push({ type: hazardMatch[1], message: hazardMatch[2] });
257
288
  continue;
258
289
  }
259
290
  if (trimmed && !trimmed.startsWith("--")) {
260
- sqlLines.push(line);
291
+ sqlLines.push(stripped.text);
261
292
  }
262
293
  }
263
294
  const sql = sqlLines.join("\n").trim();
@@ -9228,8 +9259,8 @@ var seedValidateCommand = new Command("validate").description("Validate seed SQL
9228
9259
  const output = await dbSeedValidate({});
9229
9260
  emitJsonSuccess(seedValidateCommand, DbSeedValidateOutputSchema, output);
9230
9261
  if (!output.valid) {
9231
- const missing = output.missingFiles ? `Missing: ${output.missingFiles.join(", ")}` : "Invalid SQL content";
9232
- throw new CLIError("Seed validation failed", "SEED_VALIDATION_FAILED", [missing]);
9262
+ const details = output.missingFiles ? [`Missing: ${output.missingFiles.join(", ")}`] : output.violations && output.violations.length > 0 ? output.violations : ["Invalid SQL content"];
9263
+ throw new CLIError("Seed validation failed", "SEED_VALIDATION_FAILED", details);
9233
9264
  }
9234
9265
  } catch (error) {
9235
9266
  if (error instanceof CLIError) {
@@ -13028,9 +13059,9 @@ function formatCollectedDeclarativeRisks(collected, allowlist) {
13028
13059
  allowlist: dedupeAndSort(allowlist)
13029
13060
  };
13030
13061
  }
13031
- function formatCollectedIdempotentRisks(collected) {
13062
+ function formatCollectedIdempotentRisks(collected, allowlist) {
13032
13063
  if (collected.length === 0) {
13033
- return { blockers: [], warnings: [] };
13064
+ return { blockers: [], warnings: [], allowlist: dedupeAndSort(allowlist) };
13034
13065
  }
13035
13066
  const high = collected.filter((r) => r.level === "high");
13036
13067
  const medium = collected.filter((r) => r.level === "medium");
@@ -13044,7 +13075,8 @@ function formatCollectedIdempotentRisks(collected) {
13044
13075
  }
13045
13076
  return {
13046
13077
  blockers: dedupeAndSort(blockers),
13047
- warnings: dedupeAndSort(warnings)
13078
+ warnings: dedupeAndSort(warnings),
13079
+ allowlist: dedupeAndSort(allowlist)
13048
13080
  };
13049
13081
  }
13050
13082
  function collectDeclarativeRiskItemsForFile(params) {
@@ -13138,11 +13170,13 @@ async function collectDeclarativeRiskReport() {
13138
13170
  async function collectIdempotentRiskReport() {
13139
13171
  const idempotentDir = path6.join(process.cwd(), "supabase", "schemas", "idempotent");
13140
13172
  if (!existsSync(idempotentDir)) {
13141
- return { blockers: [], warnings: [] };
13173
+ return { blockers: [], warnings: [], allowlist: [] };
13142
13174
  }
13175
+ const policy = getBoundaryPolicy();
13143
13176
  const sqlFiles = collectSqlFilesRecursively(idempotentDir);
13144
13177
  let hasSqlFile = false;
13145
13178
  const collected = [];
13179
+ const allowlist = [];
13146
13180
  let detectSchemaRisks2;
13147
13181
  const scanBudget = createSchemaPrecheckBudgetState();
13148
13182
  for (const file of sqlFiles) {
@@ -13151,7 +13185,9 @@ async function collectIdempotentRiskReport() {
13151
13185
  reason: shouldAbortSchemaPrecheckForBudget(scanBudget, file) ?? void 0,
13152
13186
  scanBudget
13153
13187
  });
13154
- if (budgetAbortReport) return budgetAbortReport;
13188
+ if (budgetAbortReport) {
13189
+ return { ...budgetAbortReport, allowlist: budgetAbortReport.allowlist ?? [] };
13190
+ }
13155
13191
  hasSqlFile = true;
13156
13192
  const detectorResult = await ensureRiskDetectorOrReport({
13157
13193
  detector: detectSchemaRisks2,
@@ -13159,7 +13195,7 @@ async function collectIdempotentRiskReport() {
13159
13195
  onUninitialized: buildIdempotentRiskUninitializedReport
13160
13196
  });
13161
13197
  if (detectorResult.kind === "report") {
13162
- return detectorResult.report;
13198
+ return { ...detectorResult.report, allowlist: detectorResult.report.allowlist ?? [] };
13163
13199
  }
13164
13200
  detectSchemaRisks2 = detectorResult.detector;
13165
13201
  const risks = await detectSchemaRisks2(file);
@@ -13167,13 +13203,28 @@ async function collectIdempotentRiskReport() {
13167
13203
  const relPath = path6.relative(process.cwd(), file);
13168
13204
  for (const risk of risks) {
13169
13205
  const level = correctIdempotentRiskLevel(risk.level, risk.reasonCode);
13170
- collected.push({ ...risk, level, file: relPath });
13206
+ const scopedRisk = { ...risk, level, file: relPath };
13207
+ const matched = findDeclarativeRiskAllowlistMatch(scopedRisk, policy);
13208
+ if (matched) {
13209
+ if (SHOW_ALLOWLIST_REPORT) {
13210
+ allowlist.push(
13211
+ formatAllowlistReason({
13212
+ label: "idempotent-risk",
13213
+ ruleId: matched.id,
13214
+ rule: matched,
13215
+ reason: `${scopedRisk.file}: ${scopedRisk.description} (${matched.reason})`
13216
+ })
13217
+ );
13218
+ }
13219
+ continue;
13220
+ }
13221
+ collected.push(scopedRisk);
13171
13222
  }
13172
13223
  }
13173
13224
  if (!hasSqlFile || collected.length === 0) {
13174
- return { blockers: [], warnings: [] };
13225
+ return { blockers: [], warnings: [], allowlist: dedupeAndSort(allowlist) };
13175
13226
  }
13176
- return formatCollectedIdempotentRisks(collected);
13227
+ return formatCollectedIdempotentRisks(collected, allowlist);
13177
13228
  }
13178
13229
  function countSyncIssues(diff) {
13179
13230
  return diff.missingTables.length + diff.orphanTables.length + diff.missingEnums.length + diff.extraEnums.length + diff.enumValueMismatches.length;
@@ -13875,6 +13926,15 @@ function printResults(result, logger15) {
13875
13926
  console.log("");
13876
13927
  return;
13877
13928
  }
13929
+ if (result.error) {
13930
+ console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
13931
+ logger15.error("DATA QUALITY CHECK COULD NOT BE COMPLETED");
13932
+ console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
13933
+ console.log("");
13934
+ logger15.error(result.error);
13935
+ console.log("");
13936
+ return;
13937
+ }
13878
13938
  console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
13879
13939
  logger15.error("DATA QUALITY CHECK FAILED");
13880
13940
  console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'module';
3
- import { tryResolveDatabaseUrl } from './chunk-KWX3JHCY.js';
3
+ import { tryResolveDatabaseUrl } from './chunk-AKZAN4BC.js';
4
4
  import { registerCleanup } from './chunk-TYIAD6SB.js';
5
5
  import { isNonInteractiveEnabled } from './chunk-6Y3LAUGL.js';
6
6
  import './chunk-NPSRD26F.js';
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'module';
3
3
  import './chunk-ZZOXM6Q4.js';
4
4
  import { createError } from './chunk-JQXOVCOP.js';
5
- import { tryResolveDatabaseUrl } from './chunk-KWX3JHCY.js';
5
+ import { tryResolveDatabaseUrl } from './chunk-AKZAN4BC.js';
6
6
  import './chunk-NPSRD26F.js';
7
7
  import { loadEnvFiles } from './chunk-644FVGIQ.js';
8
8
  import { isPathContained } from './chunk-DRSUEMAK.js';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'module';
3
3
  import { getRequestedCommandNameFromArgv } from './chunk-UWWSAPDR.js';
4
- import { CLI_VERSION } from './chunk-AIP6MR42.js';
4
+ import { CLI_VERSION } from './chunk-AFY3TX4I.js';
5
5
  import { init_esm_shims } from './chunk-VRXHCR5K.js';
6
6
  import { realpathSync } from 'fs';
7
7
  import { fileURLToPath } from 'url';
@@ -36,7 +36,7 @@ async function getProgram(options) {
36
36
  };
37
37
  const nextKey = getProgramCacheKey(resolvedOptions);
38
38
  if (!programInstance || programCacheKey !== nextKey) {
39
- const { createProgram } = await import('./cli-2JNBJUBB.js');
39
+ const { createProgram } = await import('./cli-UZA4RBNQ.js');
40
40
  programInstance = await createProgram(resolvedOptions);
41
41
  programCacheKey = nextKey;
42
42
  }
@@ -60,7 +60,7 @@ async function runCliFromProcessArgv() {
60
60
  return;
61
61
  }
62
62
  const { setupSignalHandlers } = await import('./signal-handler-DO3OANW5.js');
63
- const { executeProgram } = await import('./cli-2JNBJUBB.js');
63
+ const { executeProgram } = await import('./cli-UZA4RBNQ.js');
64
64
  setupSignalHandlers();
65
65
  const options = getProgramLoadOptions(argv);
66
66
  const program = await getProgram(options);
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'module';
3
3
  import { diagnoseInitFailure } from './chunk-AAIE4F2U.js';
4
4
  import { getVercelRootDirectory } from './chunk-MXRWBNIY.js';
5
- import { fetchTemplates } from './chunk-SGJG3BKD.js';
5
+ import { fetchTemplates } from './chunk-CCW3PLQY.js';
6
6
  import { syncRunaConfigWithVercel } from './chunk-6AALH2ED.js';
7
7
  import './chunk-DRSUEMAK.js';
8
8
  import './chunk-RZLYEO4U.js';