@carllee1983/dbcli 1.58.0 → 2.0.0

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.
@@ -51,7 +51,7 @@ var package_default;
51
51
  var init_package = __esm(() => {
52
52
  package_default = {
53
53
  name: "@carllee1983/dbcli",
54
- version: "1.58.0",
54
+ version: "2.0.0",
55
55
  description: "Database CLI for AI agents",
56
56
  type: "module",
57
57
  publishConfig: {
@@ -9473,6 +9473,23 @@ var init_ceremony = __esm(() => {
9473
9473
  confirm_destructive_warning_ddl: "\u26A0\uFE0F Warning: this schema change is destructive and cannot be undone!",
9474
9474
  confirm_ddl_prompt: "Are you sure you want to run this {operation}? This cannot be undone.",
9475
9475
  confirm_prompt: "Proceed with this operation?",
9476
+ gate_summary: "This will {operation} rows in {table}.",
9477
+ gate_summary_untargeted: "This will run a {operation} statement.",
9478
+ gate_statement: "Statement:",
9479
+ gate_cancelled: "Cancelled. Nothing was run.",
9480
+ gate_full_table_warning: "\u26A0\uFE0F This affects EVERY row in {table} and cannot be undone.",
9481
+ gate_ddl_warning: "\u26A0\uFE0F This destroys {table} and cannot be undone.",
9482
+ gate_ddl_warning_untargeted: "\u26A0\uFE0F This is a destructive schema change and cannot be undone.",
9483
+ gate_unparseable_warning: "\u26A0\uFE0F dbcli could not parse this statement, so it is treated as affecting everything.",
9484
+ gate_multiple_statements_warning: "\u26A0\uFE0F This is more than one statement, and dbcli will not judge them one at a time.",
9485
+ gate_typed_prompt: "Type {phrase} to run it",
9486
+ gate_typed_mismatch: "That did not match {phrase}. Nothing was run.",
9487
+ gate_refused: "Refused: this statement is not limited to specific rows and nobody is here to confirm it (reason={reason}).",
9488
+ gate_remedy_no_where: "Add a WHERE clause \u2014 WHERE 1=1 if you really do mean every row \u2014 or a LIMIT, then run it again.",
9489
+ gate_remedy_ddl_destruction: "No flag skips this. Run it from an interactive terminal, or apply the schema change through a reviewed migration.",
9490
+ gate_remedy_unparseable: "dbcli could not parse this statement and will not guess. Simplify it, or run it from an interactive terminal.",
9491
+ gate_remedy_multiple_statements: "Run one statement per command.",
9492
+ gate_remedy_non_unique_where: "Match on a primary key or a uniquely indexed column, or run it from an interactive terminal.",
9476
9493
  recovery_none: "This cannot be undone automatically \u2014 restore from a backup to get the previous values back.",
9477
9494
  recovery_retry: "Re-run with --recovery to write a recovery plan, then read it with: dbcli recover",
9478
9495
  blacklist_hint: "Run `dbcli blacklist list` to see what is protected"
@@ -9500,6 +9517,23 @@ var init_ceremony2 = __esm(() => {
9500
9517
  confirm_destructive_warning_ddl: "\u26A0\uFE0F \u8B66\u544A\uFF1A\u9019\u500B schema \u8B8A\u66F4\u5177\u7834\u58DE\u6027\uFF0C\u57F7\u884C\u5F8C\u7121\u6CD5\u5FA9\u539F\uFF01",
9501
9518
  confirm_ddl_prompt: "\u78BA\u5B9A\u8981\u57F7\u884C\u9019\u500B {operation} \u55CE\uFF1F\u6B64\u64CD\u4F5C\u7121\u6CD5\u5FA9\u539F\u3002",
9502
9519
  confirm_prompt: "\u8981\u7E7C\u7E8C\u57F7\u884C\u9019\u500B\u64CD\u4F5C\u55CE\uFF1F",
9520
+ gate_summary: "\u9019\u53E5\u6703\u5C0D {table} \u57F7\u884C {operation}\u3002",
9521
+ gate_summary_untargeted: "\u9019\u53E5\u6703\u57F7\u884C {operation}\u3002",
9522
+ gate_statement: "\u8A9E\u53E5\uFF1A",
9523
+ gate_cancelled: "\u5DF2\u53D6\u6D88\uFF0C\u6C92\u6709\u57F7\u884C\u4EFB\u4F55\u8A9E\u53E5\u3002",
9524
+ gate_full_table_warning: "\u26A0\uFE0F \u9019\u53E5\u6703\u5F71\u97FF {table} \u7684\u6BCF\u4E00\u5217\uFF0C\u57F7\u884C\u5F8C\u7121\u6CD5\u5FA9\u539F\u3002",
9525
+ gate_ddl_warning: "\u26A0\uFE0F \u9019\u53E5\u6703\u6467\u6BC0 {table}\uFF0C\u57F7\u884C\u5F8C\u7121\u6CD5\u5FA9\u539F\u3002",
9526
+ gate_ddl_warning_untargeted: "\u26A0\uFE0F \u9019\u662F\u7834\u58DE\u6027\u7684 schema \u8B8A\u66F4\uFF0C\u57F7\u884C\u5F8C\u7121\u6CD5\u5FA9\u539F\u3002",
9527
+ gate_unparseable_warning: "\u26A0\uFE0F dbcli \u7121\u6CD5\u89E3\u6790\u9019\u53E5\uFF0C\u56E0\u6B64\u4E00\u5F8B\u8996\u70BA\u6703\u5F71\u97FF\u5168\u90E8\u8CC7\u6599\u3002",
9528
+ gate_multiple_statements_warning: "\u26A0\uFE0F \u9019\u88E1\u4E0D\u53EA\u4E00\u53E5\u8A9E\u53E5\uFF0Cdbcli \u4E0D\u6703\u9010\u53E5\u5224\u65B7\u3002",
9529
+ gate_typed_prompt: "\u8F38\u5165 {phrase} \u624D\u6703\u57F7\u884C",
9530
+ gate_typed_mismatch: "\u8F38\u5165\u7684\u5167\u5BB9\u8207 {phrase} \u4E0D\u7B26\uFF0C\u6C92\u6709\u57F7\u884C\u4EFB\u4F55\u8A9E\u53E5\u3002",
9531
+ gate_refused: "\u5DF2\u62D2\u7D55\uFF1A\u9019\u53E5\u6C92\u6709\u9650\u5B9A\u8981\u52D5\u54EA\u4E9B\u5217\uFF0C\u800C\u73FE\u5728\u6C92\u6709\u4EBA\u80FD\u78BA\u8A8D\uFF08reason={reason}\uFF09\u3002",
9532
+ gate_remedy_no_where: "\u88DC\u4E0A WHERE\uFF08\u771F\u7684\u8981\u5168\u8868\u5C31\u5BEB WHERE 1=1\uFF09\u6216 LIMIT\uFF0C\u7136\u5F8C\u91CD\u8DD1\u3002",
9533
+ gate_remedy_ddl_destruction: "\u6C92\u6709\u4EFB\u4F55\u65D7\u6A19\u53EF\u4EE5\u8DF3\u904E\u9019\u4E00\u95DC\u3002\u8ACB\u5728\u4E92\u52D5\u7D42\u7AEF\u4E0B\u57F7\u884C\uFF0C\u6216\u6539\u8D70\u7D93\u904E\u5BE9\u67E5\u7684 migration\u3002",
9534
+ gate_remedy_unparseable: "dbcli \u7121\u6CD5\u89E3\u6790\u9019\u53E5\uFF0C\u4E5F\u4E0D\u6703\u7528\u731C\u7684\u3002\u8ACB\u7C21\u5316\u8A9E\u53E5\uFF0C\u6216\u5728\u4E92\u52D5\u7D42\u7AEF\u4E0B\u57F7\u884C\u3002",
9535
+ gate_remedy_multiple_statements: "\u4E00\u6B21\u53EA\u57F7\u884C\u4E00\u53E5\u8A9E\u53E5\u3002",
9536
+ gate_remedy_non_unique_where: "\u6539\u7528\u4E3B\u9375\u6216\u552F\u4E00\u7D22\u5F15\u6B04\u4F4D\u7576\u689D\u4EF6\uFF0C\u6216\u5728\u4E92\u52D5\u7D42\u7AEF\u4E0B\u57F7\u884C\u3002",
9503
9537
  recovery_none: "\u6B64\u64CD\u4F5C\u7121\u6CD5\u81EA\u52D5\u9084\u539F\uFF0C\u8981\u53D6\u56DE\u5148\u524D\u7684\u8CC7\u6599\u8ACB\u5F9E\u5099\u4EFD\u56DE\u5FA9\u3002",
9504
9538
  recovery_retry: "\u52A0\u4E0A --recovery \u91CD\u8DD1\u53EF\u7522\u751F\u56DE\u5FA9\u8A08\u756B\uFF0C\u518D\u7528 dbcli recover \u8B80\u53D6",
9505
9539
  blacklist_hint: "\u57F7\u884C `dbcli blacklist list` \u67E5\u770B\u53D7\u4FDD\u8B77\u7684\u9805\u76EE"
@@ -9730,7 +9764,8 @@ async function readLineFromStdin(prompt = "") {
9730
9764
  }
9731
9765
  async function textFallback(message, defaultValue) {
9732
9766
  const displayMessage = defaultValue ? `${message} [${defaultValue}]: ` : `${message}: `;
9733
- const answer = await readLineFromStdin(displayMessage);
9767
+ process.stderr.write(displayMessage);
9768
+ const answer = await readLineFromStdin();
9734
9769
  return answer.trim() || defaultValue || "";
9735
9770
  }
9736
9771
  async function selectFallback(message, choices) {
@@ -9756,7 +9791,7 @@ async function text(message, defaultValue) {
9756
9791
  const inquirer = await loadInquirer();
9757
9792
  if (!inquirer)
9758
9793
  return textFallback(message, defaultValue);
9759
- return await inquirer.input({ message, default: defaultValue });
9794
+ return await inquirer.input({ message, default: defaultValue }, { output: process.stderr });
9760
9795
  }
9761
9796
  async function select(message, choices) {
9762
9797
  if (!process.stdin.isTTY)
@@ -22202,6 +22237,360 @@ var init_elasticsearch = __esm(() => {
22202
22237
  ES_DOCUMENT_PATH = /\/(?:_doc|_source)\/[^/?]+/;
22203
22238
  });
22204
22239
 
22240
+ // src/commands/mutation-outcome.ts
22241
+ var exports_mutation_outcome = {};
22242
+ __export(exports_mutation_outcome, {
22243
+ shouldRenderForHuman: () => shouldRenderForHuman,
22244
+ renderMutationOutcome: () => renderMutationOutcome,
22245
+ printMutationOutcome: () => printMutationOutcome,
22246
+ printMutationFailure: () => printMutationFailure,
22247
+ humanOutputContext: () => humanOutputContext,
22248
+ cancelledOutcome: () => cancelledOutcome
22249
+ });
22250
+ function shouldRenderForHuman(context) {
22251
+ if (context.format === "json")
22252
+ return false;
22253
+ return context.isTTY;
22254
+ }
22255
+ function humanOutputContext(options) {
22256
+ return { isTTY: process.stdout.isTTY === true, ...options.format && { format: options.format } };
22257
+ }
22258
+ function renderMutationOutcome(result, table, elapsedMs) {
22259
+ if (result.status === "error") {
22260
+ return [
22261
+ t_vars("ceremony.failed", { reason: result.error ?? t("ceremony.unknown_error") }),
22262
+ t("ceremony.recovery_retry")
22263
+ ];
22264
+ }
22265
+ if (result.status === "cancelled") {
22266
+ return [t_vars("ceremony.cancelled", { table })];
22267
+ }
22268
+ if (result.status === "dry_run") {
22269
+ return [t_vars("ceremony.dry_run", { table })];
22270
+ }
22271
+ const elapsed = t_vars("ceremony.elapsed", { seconds: (elapsedMs / 1000).toFixed(2) });
22272
+ if (result.rows_affected === 0) {
22273
+ return [t_vars("ceremony.matched_nothing", { table }), elapsed];
22274
+ }
22275
+ return [
22276
+ t_vars(VERB_KEY[result.operation], { count: result.rows_affected, table }),
22277
+ elapsed,
22278
+ t("ceremony.recovery_none")
22279
+ ];
22280
+ }
22281
+ function printMutationOutcome(result, table, elapsedMs, context, envelopeExtras = {}) {
22282
+ if (shouldRenderForHuman(context)) {
22283
+ const writeLine = result.status === "error" ? console.error : console.log;
22284
+ for (const line of renderMutationOutcome(result, table, elapsedMs))
22285
+ writeLine(line);
22286
+ return;
22287
+ }
22288
+ console.log(JSON.stringify({ ...mutationEnvelope(result), ...envelopeExtras }, null, 2));
22289
+ }
22290
+ function printMutationFailure(error, operation, context) {
22291
+ if (shouldRenderForHuman(context)) {
22292
+ console.error(t_vars("ceremony.failed", { reason: error.message }));
22293
+ if (error instanceof BlacklistError) {
22294
+ console.error(t("ceremony.blacklist_hint"));
22295
+ }
22296
+ return;
22297
+ }
22298
+ console.log(JSON.stringify({ status: "error", operation, rows_affected: 0, error: error.message }, null, 2));
22299
+ }
22300
+ function cancelledOutcome(operation, preview) {
22301
+ return {
22302
+ status: "cancelled",
22303
+ operation,
22304
+ rows_affected: 0,
22305
+ sql: preview,
22306
+ timestamp: new Date().toISOString()
22307
+ };
22308
+ }
22309
+ function mutationEnvelope(result) {
22310
+ return {
22311
+ status: result.status,
22312
+ operation: result.operation,
22313
+ rows_affected: result.rows_affected,
22314
+ ...result.timestamp && { timestamp: result.timestamp },
22315
+ ...result.sql && { sql: result.sql },
22316
+ ...result.error && { error: result.error }
22317
+ };
22318
+ }
22319
+ var VERB_KEY;
22320
+ var init_mutation_outcome = __esm(() => {
22321
+ init_message_loader();
22322
+ init_blacklist();
22323
+ VERB_KEY = {
22324
+ insert: "ceremony.inserted",
22325
+ update: "ceremony.updated",
22326
+ delete: "ceremony.deleted"
22327
+ };
22328
+ });
22329
+
22330
+ // src/commands/write-gate-prompt.ts
22331
+ var exports_write_gate_prompt = {};
22332
+ __export(exports_write_gate_prompt, {
22333
+ enforceWriteGate: () => enforceWriteGate,
22334
+ WriteGateRefusal: () => WriteGateRefusal
22335
+ });
22336
+ async function enforceWriteGate(request) {
22337
+ const { verdict, human } = request;
22338
+ if (verdict.tier === "none")
22339
+ return true;
22340
+ const attended = isAttended(human);
22341
+ if (verdict.tier === "two")
22342
+ return await enforceTierTwo(request, attended);
22343
+ if (request.yes === true)
22344
+ return true;
22345
+ if (!attended)
22346
+ return true;
22347
+ writeSummary(request);
22348
+ const proceed = await promptUser.confirm(t("ceremony.confirm_prompt"));
22349
+ if (!proceed)
22350
+ process.stderr.write(`${t("ceremony.gate_cancelled")}
22351
+ `);
22352
+ return proceed;
22353
+ }
22354
+ function isAttended(human) {
22355
+ return shouldRenderForHuman(human) && process.stdin.isTTY === true;
22356
+ }
22357
+ async function enforceTierTwo(request, attended) {
22358
+ const { verdict } = request;
22359
+ const reason = verdict.reason ?? "no_where";
22360
+ if (!attended) {
22361
+ throw new WriteGateRefusal(`${t_vars("ceremony.gate_refused", { reason })} ${t(REMEDY_KEY[reason])}`, reason, verdict.table);
22362
+ }
22363
+ writeSummary(request);
22364
+ const warning = verdict.table === undefined && reason === "ddl_destruction" ? t("ceremony.gate_ddl_warning_untargeted") : t_vars(WARNING_KEY[reason], { table: verdict.table ?? "" });
22365
+ process.stderr.write(`
22366
+ ${warning}
22367
+ ${t(REMEDY_KEY[reason])}
22368
+ `);
22369
+ const typed = await promptUser.text(t_vars("ceremony.gate_typed_prompt", { phrase: verdict.confirmationPhrase }));
22370
+ const matched = typed.trim().toLowerCase() === verdict.confirmationPhrase.toLowerCase();
22371
+ if (!matched) {
22372
+ process.stderr.write(`${t_vars("ceremony.gate_typed_mismatch", { phrase: verdict.confirmationPhrase })}
22373
+ `);
22374
+ }
22375
+ return matched;
22376
+ }
22377
+ function writeSummary(request) {
22378
+ const { verdict, operation, statement } = request;
22379
+ const summary = verdict.table ? t_vars("ceremony.gate_summary", { operation, table: verdict.table }) : t_vars("ceremony.gate_summary_untargeted", { operation });
22380
+ process.stderr.write(`
22381
+ ${summary}
22382
+ ${t("ceremony.gate_statement")}
22383
+ ${statement}
22384
+ `);
22385
+ }
22386
+ var WriteGateRefusal, REMEDY_KEY, WARNING_KEY;
22387
+ var init_write_gate_prompt = __esm(() => {
22388
+ init_message_loader();
22389
+ init_prompts();
22390
+ init_mutation_outcome();
22391
+ WriteGateRefusal = class WriteGateRefusal extends Error {
22392
+ code = "WRITE_GATE_REFUSED";
22393
+ reason;
22394
+ table;
22395
+ constructor(message, reason, table) {
22396
+ super(message);
22397
+ this.name = "WriteGateRefusal";
22398
+ this.reason = reason;
22399
+ this.table = table;
22400
+ }
22401
+ };
22402
+ REMEDY_KEY = {
22403
+ no_where: "ceremony.gate_remedy_no_where",
22404
+ ddl_destruction: "ceremony.gate_remedy_ddl_destruction",
22405
+ unparseable: "ceremony.gate_remedy_unparseable",
22406
+ non_unique_where: "ceremony.gate_remedy_non_unique_where",
22407
+ multiple_statements: "ceremony.gate_remedy_multiple_statements"
22408
+ };
22409
+ WARNING_KEY = {
22410
+ no_where: "ceremony.gate_full_table_warning",
22411
+ ddl_destruction: "ceremony.gate_ddl_warning",
22412
+ unparseable: "ceremony.gate_unparseable_warning",
22413
+ non_unique_where: "ceremony.gate_full_table_warning",
22414
+ multiple_statements: "ceremony.gate_multiple_statements_warning"
22415
+ };
22416
+ });
22417
+
22418
+ // src/core/sql-parser.ts
22419
+ var exports_sql_parser = {};
22420
+ __export(exports_sql_parser, {
22421
+ sqlParser: () => sqlParser
22422
+ });
22423
+ function sqlParser() {
22424
+ if (!cached2) {
22425
+ const { Parser } = __require("node-sql-parser");
22426
+ cached2 = new Parser;
22427
+ }
22428
+ return cached2;
22429
+ }
22430
+ var cached2 = null;
22431
+
22432
+ // src/commands/write-gate.ts
22433
+ var exports_write_gate = {};
22434
+ __export(exports_write_gate, {
22435
+ classifyStructuredWriteGate: () => classifyStructuredWriteGate,
22436
+ classifySqlWriteGate: () => classifySqlWriteGate,
22437
+ WRITE_GATE_FALLBACK_PHRASE: () => WRITE_GATE_FALLBACK_PHRASE
22438
+ });
22439
+ async function classifySqlWriteGate(sql, options = {}) {
22440
+ const { dialect } = options;
22441
+ const classification = classifyStatement(sql);
22442
+ const hiddenWrite = findWriteKeyword(sql, dialect ? [dialect] : undefined);
22443
+ const type = WRITE_TYPES.has(classification.type) ? classification.type : hiddenWrite ? keywordToType(hiddenWrite) : undefined;
22444
+ if (type === undefined)
22445
+ return { tier: "none", confirmationPhrase: WRITE_GATE_FALLBACK_PHRASE };
22446
+ if (containsMultipleStatements(sql, dialect)) {
22447
+ return verdict("two", "multiple_statements", undefined, type);
22448
+ }
22449
+ if (type === "DROP" || type === "TRUNCATE") {
22450
+ const matched = DDL_TARGET.exec(sql)?.[1];
22451
+ const table = matched ? matched.replace(/[`"[\]]/g, "") : undefined;
22452
+ return verdict("two", "ddl_destruction", table, type);
22453
+ }
22454
+ if (type !== "UPDATE" && type !== "DELETE")
22455
+ return verdict("one", undefined, undefined, type);
22456
+ return await classifyQualification(sql, dialect, type);
22457
+ }
22458
+ async function classifyQualification(sql, dialect, type) {
22459
+ const { sqlParser: sqlParser2 } = await Promise.resolve().then(() => exports_sql_parser);
22460
+ let ast;
22461
+ try {
22462
+ ast = sqlParser2().astify(sql, { database: PARSER_DIALECTS[dialect ?? "mysql"] });
22463
+ } catch {
22464
+ return unparseable(sql, dialect, type);
22465
+ }
22466
+ const statement = Array.isArray(ast) ? ast[0] : ast;
22467
+ if (!statement)
22468
+ return unparseable(sql, dialect, type);
22469
+ const table = tableName(statement.from?.[0] ?? statement.table?.[0]);
22470
+ if (statement.where != null || statement.limit != null) {
22471
+ return verdict("one", undefined, table, type);
22472
+ }
22473
+ return verdict("two", "no_where", table, type);
22474
+ }
22475
+ function unparseable(sql, dialect, type) {
22476
+ const executable = stripCommentsAndStrings(sql, dialect ? { dialect } : {});
22477
+ if (/\bWHERE\b|\bLIMIT\b/i.test(executable))
22478
+ return verdict("one", undefined, undefined, type);
22479
+ return verdict("two", "unparseable", undefined, type);
22480
+ }
22481
+ function classifyStructuredWriteGate(request) {
22482
+ const conditions = new Set(Object.keys(request.where).map((key) => key.toLowerCase()));
22483
+ const identifies = uniqueSelectors(request.schema).some((selector) => selector.length > 0 && selector.every((column) => conditions.has(column.toLowerCase())));
22484
+ if (identifies)
22485
+ return verdict("one", undefined, request.table);
22486
+ return verdict("two", "non_unique_where", request.table);
22487
+ }
22488
+ function uniqueSelectors(schema) {
22489
+ const declared = schema.primaryKey;
22490
+ const primaryKey = Array.isArray(declared) ? declared : typeof declared === "string" ? [declared] : (schema.columns ?? []).filter((column) => column.primaryKey).map((column) => column.name);
22491
+ const unique = (schema.indexes ?? []).filter((index) => index.unique).map((index) => index.columns);
22492
+ return [primaryKey, ...unique];
22493
+ }
22494
+ function tableName(ref) {
22495
+ if (!ref?.table)
22496
+ return;
22497
+ return ref.db ? `${ref.db}.${ref.table}` : ref.table;
22498
+ }
22499
+ function keywordToType(keyword) {
22500
+ const upper = keyword.toUpperCase();
22501
+ if (WRITE_TYPES.has(upper))
22502
+ return upper;
22503
+ return "INSERT";
22504
+ }
22505
+ function verdict(tier, reason, table, operation) {
22506
+ return {
22507
+ tier,
22508
+ ...reason && { reason },
22509
+ ...table && { table },
22510
+ ...operation && { operation },
22511
+ confirmationPhrase: table ?? WRITE_GATE_FALLBACK_PHRASE
22512
+ };
22513
+ }
22514
+ var WRITE_GATE_FALLBACK_PHRASE = "CONFIRM", PARSER_DIALECTS, WRITE_TYPES, DDL_TARGET;
22515
+ var init_write_gate = __esm(() => {
22516
+ init_permission_guard();
22517
+ init_sql_analysis();
22518
+ PARSER_DIALECTS = {
22519
+ mysql: "MySQL",
22520
+ mariadb: "MariaDB",
22521
+ postgresql: "Postgresql"
22522
+ };
22523
+ WRITE_TYPES = new Set([
22524
+ "INSERT",
22525
+ "UPDATE",
22526
+ "DELETE",
22527
+ "TRUNCATE",
22528
+ "DROP",
22529
+ "ALTER",
22530
+ "CREATE"
22531
+ ]);
22532
+ DDL_TARGET = /\b(?:DROP\s+TABLE|TRUNCATE(?:\s+TABLE)?)\s+(?:IF\s+EXISTS\s+)?([`"[\]\w$.]+)\s*;?\s*$/i;
22533
+ });
22534
+
22535
+ // src/commands/write-gate-guard.ts
22536
+ var exports_write_gate_guard = {};
22537
+ __export(exports_write_gate_guard, {
22538
+ recordGateDecision: () => recordGateDecision,
22539
+ guardStructuredWrite: () => guardStructuredWrite
22540
+ });
22541
+ async function recordGateDecision(request) {
22542
+ await writeAuditEntry(request.config, request.command, request.options, {
22543
+ success: request.outcome === "allowed",
22544
+ ...request.sql && { sql: request.sql },
22545
+ ...request.verdict.table && { target: request.verdict.table },
22546
+ metadata: {
22547
+ write_gate_tier: request.tier,
22548
+ write_gate_outcome: request.outcome,
22549
+ write_gate_reason: request.verdict.reason ?? "no_where"
22550
+ }
22551
+ });
22552
+ }
22553
+ async function guardStructuredWrite(request) {
22554
+ const verdict2 = classifyStructuredWriteGate({
22555
+ table: request.table,
22556
+ where: request.where,
22557
+ schema: request.schema
22558
+ });
22559
+ if (verdict2.tier !== "two")
22560
+ return true;
22561
+ const operation = request.operation.toUpperCase();
22562
+ const preview = `${operation} ${request.table} WHERE ${Object.keys(request.where).join(", ")}`;
22563
+ const record = (outcome) => recordGateDecision({
22564
+ config: request.config,
22565
+ command: request.operation,
22566
+ options: request.options,
22567
+ verdict: verdict2,
22568
+ outcome,
22569
+ tier: "two",
22570
+ sql: preview
22571
+ });
22572
+ try {
22573
+ const proceed = await enforceWriteGate({
22574
+ verdict: verdict2,
22575
+ statement: preview,
22576
+ operation,
22577
+ human: humanOutputContext(request.options)
22578
+ });
22579
+ await record(proceed ? "allowed" : "declined");
22580
+ return proceed;
22581
+ } catch (error) {
22582
+ if (error instanceof WriteGateRefusal)
22583
+ await record("refused");
22584
+ throw error;
22585
+ }
22586
+ }
22587
+ var init_write_gate_guard = __esm(() => {
22588
+ init_integration_helper();
22589
+ init_mutation_outcome();
22590
+ init_write_gate();
22591
+ init_write_gate_prompt();
22592
+ });
22593
+
22205
22594
  // src/core/permission/redis.ts
22206
22595
  var exports_redis = {};
22207
22596
  __export(exports_redis, {
@@ -22528,10 +22917,24 @@ async function executeQueryCommand(sql, options, command, runtimeOverrides = {})
22528
22917
  connectionName = connectionNames[0];
22529
22918
  config = await runtime.loadConfig(configPath, connectionName);
22530
22919
  const context = { config, configPath, connectionName };
22920
+ if (!await runtime.enforceGate(resolvedSql, options, context))
22921
+ return;
22531
22922
  await runtime.preflight(resolvedSql, options, context, fieldSelection, false);
22532
22923
  const execution = await runtime.executeConnection(resolvedSql, options, context, fieldSelection);
22533
22924
  await runtime.presentResult(resolvedSql, options, execution, tableCellLimit);
22534
22925
  } catch (error) {
22926
+ const { WriteGateRefusal: WriteGateRefusal2 } = await Promise.resolve().then(() => (init_write_gate_prompt(), exports_write_gate_prompt));
22927
+ if (error instanceof WriteGateRefusal2) {
22928
+ if (options.format === "json") {
22929
+ console.log(JSON.stringify({
22930
+ status: "refused",
22931
+ code: error.code,
22932
+ reason: error.reason,
22933
+ ...error.table && { table: error.table }
22934
+ }, null, 2));
22935
+ }
22936
+ throw error;
22937
+ }
22535
22938
  let auditId = null;
22536
22939
  let envelopeId;
22537
22940
  if (options.recovery === true && !multiConnectionRequest) {
@@ -22618,6 +23021,48 @@ function scopeMultiConnectionNotices(execution) {
22618
23021
  notices: []
22619
23022
  };
22620
23023
  }
23024
+ async function enforceQueryWriteGate(query, options, context) {
23025
+ const { config } = context;
23026
+ const { toSqlDialect: toSqlDialect2, enforcePermission: enforcePermission2 } = await Promise.resolve().then(() => (init_permission_guard(), exports_permission_guard));
23027
+ const dialect = toSqlDialect2(config.connection?.system);
23028
+ if (!dialect)
23029
+ return true;
23030
+ const { classifySqlWriteGate: classifySqlWriteGate2 } = await Promise.resolve().then(() => (init_write_gate(), exports_write_gate));
23031
+ const verdict2 = await classifySqlWriteGate2(query, { dialect });
23032
+ if (verdict2.tier === "none")
23033
+ return true;
23034
+ enforcePermission2(query, config.permission, dialect);
23035
+ const { enforceWriteGate: enforceWriteGate2, WriteGateRefusal: WriteGateRefusal2 } = await Promise.resolve().then(() => (init_write_gate_prompt(), exports_write_gate_prompt));
23036
+ const { humanOutputContext: humanOutputContext2 } = await Promise.resolve().then(() => (init_mutation_outcome(), exports_mutation_outcome));
23037
+ const { recordGateDecision: recordGateDecision2 } = await Promise.resolve().then(() => (init_write_gate_guard(), exports_write_gate_guard));
23038
+ const record = (outcome) => recordGateDecision2({
23039
+ config,
23040
+ command: "query",
23041
+ options: { ...options, config: context.configPath, connectionName: context.connectionName },
23042
+ verdict: verdict2,
23043
+ outcome,
23044
+ tier: verdict2.tier === "two" ? "two" : "one",
23045
+ sql: query
23046
+ });
23047
+ try {
23048
+ const proceed = await enforceWriteGate2({
23049
+ verdict: verdict2,
23050
+ statement: query,
23051
+ operation: verdict2.operation ?? "WRITE",
23052
+ human: humanOutputContext2(options),
23053
+ ...options.yes !== undefined && { yes: options.yes }
23054
+ });
23055
+ if (verdict2.tier === "two")
23056
+ await record(proceed ? "allowed" : "declined");
23057
+ else if (!proceed)
23058
+ await record("declined");
23059
+ return proceed;
23060
+ } catch (error) {
23061
+ if (error instanceof WriteGateRefusal2)
23062
+ await record("refused");
23063
+ throw error;
23064
+ }
23065
+ }
22621
23066
  async function preflightQuery(query, options, context, fieldSelection, multiConnection) {
22622
23067
  const { config } = context;
22623
23068
  if (!config.connection)
@@ -23061,6 +23506,7 @@ var init_query = __esm(() => {
23061
23506
  executeConnection: executeConnectionQuery,
23062
23507
  presentResult: presentSingleResult,
23063
23508
  writeAudit: writeAuditEntry,
23509
+ enforceGate: enforceQueryWriteGate,
23064
23510
  randomUUID: () => crypto3.randomUUID(),
23065
23511
  emitRecovery: async (error, context, options) => {
23066
23512
  const { emitRecoveryEnvelope: emitRecoveryEnvelope2 } = await Promise.resolve().then(() => (init_recovery(), exports_recovery));
@@ -23085,7 +23531,7 @@ __export(exports_inline_registrars, {
23085
23531
  registerDeleteCommand: () => registerDeleteCommand
23086
23532
  });
23087
23533
  function registerQueryCommand(program2, run) {
23088
- program2.command("query [sql]").description(t("query.description")).option("-f, --query-file <path>", "Read query text from a UTF-8 file, or - for stdin").option("--format <type>", "Output format: table, json, csv, html", "table").option("--ui", "Show interactive dashboard in browser", false).option("--limit <number>", "Limit result rows (overrides auto-limit)", parsePositiveInteger).option("--no-limit", "Disable auto-limit in query-only mode").option("--collection <name>", "MongoDB collection name; Elasticsearch index name").option("--index <name>", "Elasticsearch index name (alias for --collection)").option("--fields <list>", "Include fields, or exclude them with --fields=-field_a,-field_b").option("--truncate <number>", "Limit serialized table cells to N Unicode characters", parsePositiveInteger).option("--no-truncate", "Disable the default table-cell truncation").option("--slow-ms <number>", "Emit a passive performance hint at or above this execution time; 0 disables it", parseSlowMs, 1000).addOption(createConnectionSelectorOption()).option("--recovery", "On failure, emit a structured recovery envelope to stdout (suppresses human stderr message)", false).action(async (sql, options, command) => {
23534
+ program2.command("query [sql]").description(t("query.description")).option("-f, --query-file <path>", "Read query text from a UTF-8 file, or - for stdin").option("--format <type>", "Output format: table, json, csv, html", "table").option("--ui", "Show interactive dashboard in browser", false).option("--limit <number>", "Limit result rows (overrides auto-limit)", parsePositiveInteger).option("--no-limit", "Disable auto-limit in query-only mode").option("--collection <name>", "MongoDB collection name; Elasticsearch index name").option("--index <name>", "Elasticsearch index name (alias for --collection)").option("--fields <list>", "Include fields, or exclude them with --fields=-field_a,-field_b").option("--truncate <number>", "Limit serialized table cells to N Unicode characters", parsePositiveInteger).option("--no-truncate", "Disable the default table-cell truncation").option("--slow-ms <number>", "Emit a passive performance hint at or above this execution time; 0 disables it", parseSlowMs, 1000).addOption(createConnectionSelectorOption()).option("--yes", "Skip the confirmation shown before an ordinary write; statements that are not limited to specific rows ignore it", false).option("--recovery", "On failure, emit a structured recovery envelope to stdout (suppresses human stderr message)", false).action(async (sql, options, command) => {
23089
23535
  const rawArgs = command.parent?.rawArgs ?? [];
23090
23536
  const rawTruncate = findLongOptionValue(rawArgs, "--truncate");
23091
23537
  const rootUse = command.parent?.opts().use;
@@ -23401,8 +23847,8 @@ function applyBlacklistRules(facts, blacklist, factors) {
23401
23847
  }
23402
23848
  function findBlacklistedColumnsForTable(blacklist, table) {
23403
23849
  const columns = blacklist.columns ?? {};
23404
- for (const [tableName, columnNames] of Object.entries(columns)) {
23405
- if (tableName.toLowerCase() === table.toLowerCase()) {
23850
+ for (const [tableName2, columnNames] of Object.entries(columns)) {
23851
+ if (tableName2.toLowerCase() === table.toLowerCase()) {
23406
23852
  return new Set(columnNames);
23407
23853
  }
23408
23854
  }
@@ -25366,12 +25812,12 @@ class DataExecutor {
25366
25812
  this.dbSystem = dbSystem;
25367
25813
  this.blacklistValidator = blacklistValidator;
25368
25814
  }
25369
- buildInsertSql(tableName, data, schema) {
25815
+ buildInsertSql(tableName2, data, schema) {
25370
25816
  const columnNames = schema.columns.map((col) => col.name);
25371
25817
  const dataKeys = Object.keys(data);
25372
25818
  for (const key of dataKeys) {
25373
25819
  if (!columnNames.includes(key)) {
25374
- throw new Error(`Column "${key}" not found in table "${tableName}". Valid columns: ${columnNames.join(", ")}`);
25820
+ throw new Error(`Column "${key}" not found in table "${tableName2}". Valid columns: ${columnNames.join(", ")}`);
25375
25821
  }
25376
25822
  }
25377
25823
  const columns = dataKeys;
@@ -25379,38 +25825,38 @@ class DataExecutor {
25379
25825
  const systemType = this.getSystemType();
25380
25826
  const placeholders = systemType === "postgresql" ? dataKeys.map((_, index) => `$${index + 1}`).join(", ") : dataKeys.map(() => "?").join(", ");
25381
25827
  const quote = this.getQuoteChar();
25382
- const sql = `INSERT INTO ${quote}${tableName}${quote} (${columns.map((col) => `${quote}${col}${quote}`).join(", ")}) VALUES (${placeholders})`;
25828
+ const sql = `INSERT INTO ${quote}${tableName2}${quote} (${columns.map((col) => `${quote}${col}${quote}`).join(", ")}) VALUES (${placeholders})`;
25383
25829
  return {
25384
25830
  sql,
25385
25831
  params: values
25386
25832
  };
25387
25833
  }
25388
- async executeInsert(tableName, data, schema, options) {
25834
+ async executeInsert(tableName2, data, schema, options) {
25389
25835
  const timestamp = new Date().toISOString();
25390
25836
  try {
25391
- this.checkBlacklist("INSERT", tableName);
25837
+ this.checkBlacklist("INSERT", tableName2);
25392
25838
  enforcePermissionForType("INSERT", this.permission);
25393
- return await this.executeMutation("insert", this.buildInsertSql(tableName, data, schema), timestamp, options, { destructive: false });
25839
+ return await this.executeMutation("insert", this.buildInsertSql(tableName2, data, schema), timestamp, options, { destructive: false });
25394
25840
  } catch (error) {
25395
25841
  return this.handleMutationError("insert", timestamp, error);
25396
25842
  }
25397
25843
  }
25398
- async executeUpdate(tableName, data, where, schema, options) {
25844
+ async executeUpdate(tableName2, data, where, schema, options) {
25399
25845
  const timestamp = new Date().toISOString();
25400
25846
  try {
25401
- this.checkBlacklist("UPDATE", tableName);
25847
+ this.checkBlacklist("UPDATE", tableName2);
25402
25848
  enforcePermissionForType("UPDATE", this.permission);
25403
- return await this.executeMutation("update", this.buildUpdateSql(tableName, data, where, schema), timestamp, options, { destructive: false });
25849
+ return await this.executeMutation("update", this.buildUpdateSql(tableName2, data, where, schema), timestamp, options, { destructive: false });
25404
25850
  } catch (error) {
25405
25851
  return this.handleMutationError("update", timestamp, error);
25406
25852
  }
25407
25853
  }
25408
- async executeDelete(tableName, where, schema, options) {
25854
+ async executeDelete(tableName2, where, schema, options) {
25409
25855
  const timestamp = new Date().toISOString();
25410
25856
  try {
25411
- this.checkBlacklist("DELETE", tableName);
25857
+ this.checkBlacklist("DELETE", tableName2);
25412
25858
  enforcePermissionForType("DELETE", this.permission);
25413
- return await this.executeMutation("delete", this.buildDeleteSql(tableName, where, schema), timestamp, options, { destructive: true });
25859
+ return await this.executeMutation("delete", this.buildDeleteSql(tableName2, where, schema), timestamp, options, { destructive: true });
25414
25860
  } catch (error) {
25415
25861
  return this.handleMutationError("delete", timestamp, error);
25416
25862
  }
@@ -25421,8 +25867,8 @@ class DataExecutor {
25421
25867
  getQuoteChar() {
25422
25868
  return this.dbSystem === "mysql" ? "`" : '"';
25423
25869
  }
25424
- checkBlacklist(operation, tableName) {
25425
- this.blacklistValidator?.checkTableBlacklist(operation, tableName, []);
25870
+ checkBlacklist(operation, tableName2) {
25871
+ this.blacklistValidator?.checkTableBlacklist(operation, tableName2, []);
25426
25872
  }
25427
25873
  async executeMutation(operation, statement, timestamp, options, { destructive }) {
25428
25874
  if (options?.dryRun) {
@@ -25477,13 +25923,13 @@ class DataExecutor {
25477
25923
  error: `${operation.toUpperCase()} failed: ${errorMessage2}`
25478
25924
  };
25479
25925
  }
25480
- buildUpdateSql(tableName, data, where, schema) {
25926
+ buildUpdateSql(tableName2, data, where, schema) {
25481
25927
  const dataKeys = Object.keys(data);
25482
25928
  const whereKeys = Object.keys(where);
25483
25929
  const columnNames = schema.columns.map((col) => col.name);
25484
25930
  for (const key of [...dataKeys, ...whereKeys]) {
25485
25931
  if (!columnNames.includes(key)) {
25486
- throw new Error(`Column "${key}" not found in table "${tableName}"`);
25932
+ throw new Error(`Column "${key}" not found in table "${tableName2}"`);
25487
25933
  }
25488
25934
  }
25489
25935
  const systemType = this.getSystemType();
@@ -25497,16 +25943,16 @@ class DataExecutor {
25497
25943
  const placeholder = systemType === "postgresql" ? `$${paramIndex++}` : "?";
25498
25944
  return `${quote}${key}${quote} = ${placeholder}`;
25499
25945
  }).join(" AND ");
25500
- const sql = `UPDATE ${quote}${tableName}${quote} SET ${setClause} WHERE ${whereClause}`;
25946
+ const sql = `UPDATE ${quote}${tableName2}${quote} SET ${setClause} WHERE ${whereClause}`;
25501
25947
  const params = [...dataKeys.map((key) => data[key]), ...whereKeys.map((key) => where[key])];
25502
25948
  return { sql, params };
25503
25949
  }
25504
- buildDeleteSql(tableName, where, schema) {
25950
+ buildDeleteSql(tableName2, where, schema) {
25505
25951
  const whereKeys = Object.keys(where);
25506
25952
  const columnNames = schema.columns.map((col) => col.name);
25507
25953
  for (const key of whereKeys) {
25508
25954
  if (!columnNames.includes(key)) {
25509
- throw new Error(`Column "${key}" not found in table "${tableName}"`);
25955
+ throw new Error(`Column "${key}" not found in table "${tableName2}"`);
25510
25956
  }
25511
25957
  }
25512
25958
  const systemType = this.getSystemType();
@@ -25516,7 +25962,7 @@ class DataExecutor {
25516
25962
  const placeholder = systemType === "postgresql" ? `$${paramIndex++}` : "?";
25517
25963
  return `${quote}${key}${quote} = ${placeholder}`;
25518
25964
  }).join(" AND ");
25519
- const sql = `DELETE FROM ${quote}${tableName}${quote} WHERE ${whereClause}`;
25965
+ const sql = `DELETE FROM ${quote}${tableName2}${quote} WHERE ${whereClause}`;
25520
25966
  const params = whereKeys.map((key) => where[key]);
25521
25967
  return { sql, params };
25522
25968
  }
@@ -25590,87 +26036,6 @@ function auditOutcomeForMutation(result, table, recoveryRef) {
25590
26036
  };
25591
26037
  }
25592
26038
 
25593
- // src/commands/mutation-outcome.ts
25594
- function shouldRenderForHuman(context) {
25595
- if (context.format === "json")
25596
- return false;
25597
- return context.isTTY;
25598
- }
25599
- function humanOutputContext(options) {
25600
- return { isTTY: process.stdout.isTTY === true, ...options.format && { format: options.format } };
25601
- }
25602
- function renderMutationOutcome(result, table, elapsedMs) {
25603
- if (result.status === "error") {
25604
- return [
25605
- t_vars("ceremony.failed", { reason: result.error ?? t("ceremony.unknown_error") }),
25606
- t("ceremony.recovery_retry")
25607
- ];
25608
- }
25609
- if (result.status === "cancelled") {
25610
- return [t_vars("ceremony.cancelled", { table })];
25611
- }
25612
- if (result.status === "dry_run") {
25613
- return [t_vars("ceremony.dry_run", { table })];
25614
- }
25615
- const elapsed = t_vars("ceremony.elapsed", { seconds: (elapsedMs / 1000).toFixed(2) });
25616
- if (result.rows_affected === 0) {
25617
- return [t_vars("ceremony.matched_nothing", { table }), elapsed];
25618
- }
25619
- return [
25620
- t_vars(VERB_KEY[result.operation], { count: result.rows_affected, table }),
25621
- elapsed,
25622
- t("ceremony.recovery_none")
25623
- ];
25624
- }
25625
- function printMutationOutcome(result, table, elapsedMs, context, envelopeExtras = {}) {
25626
- if (shouldRenderForHuman(context)) {
25627
- const writeLine = result.status === "error" ? console.error : console.log;
25628
- for (const line of renderMutationOutcome(result, table, elapsedMs))
25629
- writeLine(line);
25630
- return;
25631
- }
25632
- console.log(JSON.stringify({ ...mutationEnvelope(result), ...envelopeExtras }, null, 2));
25633
- }
25634
- function printMutationFailure(error, operation, context) {
25635
- if (shouldRenderForHuman(context)) {
25636
- console.error(t_vars("ceremony.failed", { reason: error.message }));
25637
- if (error instanceof BlacklistError) {
25638
- console.error(t("ceremony.blacklist_hint"));
25639
- }
25640
- return;
25641
- }
25642
- console.log(JSON.stringify({ status: "error", operation, rows_affected: 0, error: error.message }, null, 2));
25643
- }
25644
- function cancelledOutcome(operation, preview) {
25645
- return {
25646
- status: "cancelled",
25647
- operation,
25648
- rows_affected: 0,
25649
- sql: preview,
25650
- timestamp: new Date().toISOString()
25651
- };
25652
- }
25653
- function mutationEnvelope(result) {
25654
- return {
25655
- status: result.status,
25656
- operation: result.operation,
25657
- rows_affected: result.rows_affected,
25658
- ...result.timestamp && { timestamp: result.timestamp },
25659
- ...result.sql && { sql: result.sql },
25660
- ...result.error && { error: result.error }
25661
- };
25662
- }
25663
- var VERB_KEY;
25664
- var init_mutation_outcome = __esm(() => {
25665
- init_message_loader();
25666
- init_blacklist();
25667
- VERB_KEY = {
25668
- insert: "ceremony.inserted",
25669
- update: "ceremony.updated",
25670
- delete: "ceremony.deleted"
25671
- };
25672
- });
25673
-
25674
26039
  // src/core/mongo/dry-run-formatter.ts
25675
26040
  function pretty(value) {
25676
26041
  return JSON.stringify(value, null, INDENT);
@@ -26974,6 +27339,20 @@ async function updateCommand(table, options, command) {
26974
27339
  await adapter.connect();
26975
27340
  try {
26976
27341
  const schema = await adapter.getTableSchema(table);
27342
+ const { guardStructuredWrite: guardStructuredWrite2 } = await Promise.resolve().then(() => (init_write_gate_guard(), exports_write_gate_guard));
27343
+ if (options.dryRun !== true && !await guardStructuredWrite2({
27344
+ operation: "update",
27345
+ table,
27346
+ where: whereConditions,
27347
+ schema,
27348
+ config,
27349
+ options
27350
+ })) {
27351
+ const cancelled = cancelledOutcome("update", `UPDATE ${table}`);
27352
+ printMutationOutcome(cancelled, table, 0, humanOutputContext(options));
27353
+ await writeAuditEntry(config, "update", options, auditOutcomeForMutation(cancelled, table));
27354
+ return;
27355
+ }
26977
27356
  const dbSystem = config.connection.system === "postgresql" ? "postgresql" : "mysql";
26978
27357
  const blacklistManager = new BlacklistManager(config);
26979
27358
  const blacklistValidator = new BlacklistValidator(blacklistManager);
@@ -26999,6 +27378,11 @@ async function updateCommand(table, options, command) {
26999
27378
  await adapter.disconnect();
27000
27379
  }
27001
27380
  } catch (error) {
27381
+ const { WriteGateRefusal: WriteGateRefusal2 } = await Promise.resolve().then(() => (init_write_gate_prompt(), exports_write_gate_prompt));
27382
+ if (error instanceof WriteGateRefusal2) {
27383
+ printMutationFailure(error, "update", humanOutputContext(options));
27384
+ process.exit(1);
27385
+ }
27002
27386
  let auditId = null;
27003
27387
  let envelopeId;
27004
27388
  if (options.recovery === true) {
@@ -27254,6 +27638,20 @@ async function deleteCommand(table, options, command) {
27254
27638
  await adapter.connect();
27255
27639
  try {
27256
27640
  const schema = await adapter.getTableSchema(table);
27641
+ const { guardStructuredWrite: guardStructuredWrite2 } = await Promise.resolve().then(() => (init_write_gate_guard(), exports_write_gate_guard));
27642
+ if (options.dryRun !== true && !await guardStructuredWrite2({
27643
+ operation: "delete",
27644
+ table,
27645
+ where: whereConditions,
27646
+ schema,
27647
+ config,
27648
+ options
27649
+ })) {
27650
+ const cancelled = cancelledOutcome("delete", `DELETE FROM ${table}`);
27651
+ printMutationOutcome(cancelled, table, 0, humanOutputContext(options));
27652
+ await writeAuditEntry(config, "delete", options, auditOutcomeForMutation(cancelled, table));
27653
+ return;
27654
+ }
27257
27655
  const dbSystem = config.connection.system === "postgresql" ? "postgresql" : "mysql";
27258
27656
  const blacklistManager = new BlacklistManager(config);
27259
27657
  const blacklistValidator = new BlacklistValidator(blacklistManager);
@@ -27279,6 +27677,11 @@ async function deleteCommand(table, options, command) {
27279
27677
  await adapter.disconnect();
27280
27678
  }
27281
27679
  } catch (error) {
27680
+ const { WriteGateRefusal: WriteGateRefusal2 } = await Promise.resolve().then(() => (init_write_gate_prompt(), exports_write_gate_prompt));
27681
+ if (error instanceof WriteGateRefusal2) {
27682
+ printMutationFailure(error, "delete", humanOutputContext(options));
27683
+ process.exit(1);
27684
+ }
27282
27685
  let auditId = null;
27283
27686
  let envelopeId;
27284
27687
  if (options.recovery === true) {
@@ -27777,16 +28180,6 @@ var init_export = __esm(() => {
27777
28180
  SQL_PATTERN = /^\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|SHOW|DESCRIBE)\b/i;
27778
28181
  });
27779
28182
 
27780
- // src/core/sql-parser.ts
27781
- function sqlParser() {
27782
- if (!cached2) {
27783
- const { Parser } = __require("node-sql-parser");
27784
- cached2 = new Parser;
27785
- }
27786
- return cached2;
27787
- }
27788
- var cached2 = null;
27789
-
27790
28183
  // src/core/explain/read-only.ts
27791
28184
  function containsAnalyzeUnsafeNode(node) {
27792
28185
  if (!node || typeof node !== "object")
@@ -28891,12 +29284,12 @@ function compactVisibleSchema(config) {
28891
29284
  const blacklistManager = new BlacklistManager(config);
28892
29285
  const compactSchema = {};
28893
29286
  const rawSchema = config.schema ?? {};
28894
- for (const [tableName, tableSchema] of Object.entries(rawSchema)) {
28895
- if (blacklistManager.isTableBlacklisted(tableName))
29287
+ for (const [tableName2, tableSchema] of Object.entries(rawSchema)) {
29288
+ if (blacklistManager.isTableBlacklisted(tableName2))
28896
29289
  continue;
28897
29290
  const columns = [];
28898
29291
  for (const col of tableSchema.columns || []) {
28899
- if (blacklistManager.isColumnBlacklisted(tableName, col.name))
29292
+ if (blacklistManager.isColumnBlacklisted(tableName2, col.name))
28900
29293
  continue;
28901
29294
  const compactCol = {
28902
29295
  name: col.name,
@@ -28916,7 +29309,7 @@ function compactVisibleSchema(config) {
28916
29309
  columns.push(compactCol);
28917
29310
  }
28918
29311
  const compactTable = {
28919
- name: tableSchema.name || tableName,
29312
+ name: tableSchema.name || tableName2,
28920
29313
  columns
28921
29314
  };
28922
29315
  const rowCount = tableSchema.estimatedRowCount ?? tableSchema.rowCount;
@@ -28932,7 +29325,7 @@ function compactVisibleSchema(config) {
28932
29325
  refColumns: fk.refColumns
28933
29326
  }));
28934
29327
  }
28935
- compactSchema[tableName] = compactTable;
29328
+ compactSchema[tableName2] = compactTable;
28936
29329
  }
28937
29330
  return compactSchema;
28938
29331
  }
@@ -29040,10 +29433,10 @@ function serializeXml(payload) {
29040
29433
  }
29041
29434
  if (Object.keys(payload.schema).length > 0) {
29042
29435
  parts.push(" <tables>");
29043
- for (const [tableName, table] of Object.entries(payload.schema)) {
29436
+ for (const [tableName2, table] of Object.entries(payload.schema)) {
29044
29437
  const rowsAttr = table.rowCount !== undefined ? ` rows="${table.rowCount}"` : "";
29045
29438
  const pkAttr = table.primaryKey ? ` primary_key="${table.primaryKey.join(",")}"` : "";
29046
- parts.push(` <table name="${escapeXml(tableName)}"${rowsAttr}${pkAttr}>`);
29439
+ parts.push(` <table name="${escapeXml(tableName2)}"${rowsAttr}${pkAttr}>`);
29047
29440
  for (const col of table.columns) {
29048
29441
  const pk = col.primaryKey ? ' primary_key="true"' : "";
29049
29442
  const nulls = col.nullable ? ' nullable="true"' : ' nullable="false"';
@@ -29154,9 +29547,9 @@ function serializeMarkdown(payload) {
29154
29547
  parts.push(`*No table schemas cached or active.*`);
29155
29548
  parts.push(``);
29156
29549
  } else {
29157
- for (const [tableName, table] of Object.entries(payload.schema)) {
29550
+ for (const [tableName2, table] of Object.entries(payload.schema)) {
29158
29551
  const rows = table.rowCount !== undefined ? ` (~${table.rowCount.toLocaleString()} rows)` : "";
29159
- parts.push(`### \`${tableName}\`${rows}`);
29552
+ parts.push(`### \`${tableName2}\`${rows}`);
29160
29553
  parts.push(``);
29161
29554
  parts.push(`| Column | Type | Nullable | Primary Key | Default | References |`);
29162
29555
  parts.push(`| :--- | :--- | :---: | :---: | :--- | :--- |`);
@@ -30289,37 +30682,37 @@ async function blacklistList(configPath, format = "text") {
30289
30682
  console.error(`\u26A0 blacklist.columns["${w2.collection}"]: '${w2.raw}' is ignored on mongo connections (${w2.reason}).`);
30290
30683
  }
30291
30684
  }
30292
- async function blacklistTableAdd(tableName, configPath) {
30293
- if (!isValidTableName(tableName)) {
30294
- throw new Error(t_vars("errors.invalid_table_name", { table: tableName }));
30685
+ async function blacklistTableAdd(tableName2, configPath) {
30686
+ if (!isValidTableName(tableName2)) {
30687
+ throw new Error(t_vars("errors.invalid_table_name", { table: tableName2 }));
30295
30688
  }
30296
30689
  const config = await configModule.read(configPath);
30297
30690
  const blacklist = getOrInitBlacklist(config);
30298
- if (blacklist.tables.includes(tableName)) {
30299
- throw new Error(t_vars("errors.table_already_blacklisted", { table: tableName }));
30691
+ if (blacklist.tables.includes(tableName2)) {
30692
+ throw new Error(t_vars("errors.table_already_blacklisted", { table: tableName2 }));
30300
30693
  }
30301
30694
  const newBlacklist = {
30302
30695
  ...blacklist,
30303
- tables: [...blacklist.tables, tableName]
30696
+ tables: [...blacklist.tables, tableName2]
30304
30697
  };
30305
30698
  await configModule.write(configPath, { ...config, blacklist: newBlacklist });
30306
- console.log(t_vars("blacklist.table_added", { table: tableName }));
30699
+ console.log(t_vars("blacklist.table_added", { table: tableName2 }));
30307
30700
  }
30308
- async function blacklistTableRemove(tableName, configPath) {
30309
- if (!isValidTableName(tableName)) {
30310
- throw new Error(t_vars("errors.invalid_table_name", { table: tableName }));
30701
+ async function blacklistTableRemove(tableName2, configPath) {
30702
+ if (!isValidTableName(tableName2)) {
30703
+ throw new Error(t_vars("errors.invalid_table_name", { table: tableName2 }));
30311
30704
  }
30312
30705
  const config = await configModule.read(configPath);
30313
30706
  const blacklist = getOrInitBlacklist(config);
30314
- if (!blacklist.tables.includes(tableName)) {
30315
- throw new Error(t_vars("errors.table_not_in_blacklist", { table: tableName }));
30707
+ if (!blacklist.tables.includes(tableName2)) {
30708
+ throw new Error(t_vars("errors.table_not_in_blacklist", { table: tableName2 }));
30316
30709
  }
30317
30710
  const newBlacklist = {
30318
30711
  ...blacklist,
30319
- tables: blacklist.tables.filter((t2) => t2 !== tableName)
30712
+ tables: blacklist.tables.filter((t2) => t2 !== tableName2)
30320
30713
  };
30321
30714
  await configModule.write(configPath, { ...config, blacklist: newBlacklist });
30322
- console.log(t_vars("blacklist.table_removed", { table: tableName }));
30715
+ console.log(t_vars("blacklist.table_removed", { table: tableName2 }));
30323
30716
  }
30324
30717
  async function blacklistColumnAdd(identifier, configPath) {
30325
30718
  const parsed = parseColumnIdentifier(identifier);
@@ -30389,17 +30782,17 @@ var init_blacklist2 = __esm(() => {
30389
30782
  }
30390
30783
  });
30391
30784
  tableCmd = blacklistCommand.command("table").description(t("blacklist.tables_label"));
30392
- tableCmd.command("add <table>").description("Add table to blacklist").option("--config <path>", "Path to .dbcli config file", DEFAULT_CONFIG_PATH).action(async (tableName, options) => {
30785
+ tableCmd.command("add <table>").description("Add table to blacklist").option("--config <path>", "Path to .dbcli config file", DEFAULT_CONFIG_PATH).action(async (tableName2, options) => {
30393
30786
  try {
30394
- await blacklistTableAdd(tableName, options.config || DEFAULT_CONFIG_PATH);
30787
+ await blacklistTableAdd(tableName2, options.config || DEFAULT_CONFIG_PATH);
30395
30788
  } catch (error) {
30396
30789
  console.error(error.message);
30397
30790
  process.exit(1);
30398
30791
  }
30399
30792
  });
30400
- tableCmd.command("remove <table>").description("Remove table from blacklist").option("--config <path>", "Path to .dbcli config file", DEFAULT_CONFIG_PATH).action(async (tableName, options) => {
30793
+ tableCmd.command("remove <table>").description("Remove table from blacklist").option("--config <path>", "Path to .dbcli config file", DEFAULT_CONFIG_PATH).action(async (tableName2, options) => {
30401
30794
  try {
30402
- await blacklistTableRemove(tableName, options.config || DEFAULT_CONFIG_PATH);
30795
+ await blacklistTableRemove(tableName2, options.config || DEFAULT_CONFIG_PATH);
30403
30796
  } catch (error) {
30404
30797
  console.error(error.message);
30405
30798
  process.exit(1);
@@ -31033,7 +31426,7 @@ function consumeCreateTable(node, statement, context) {
31033
31426
  return;
31034
31427
  }
31035
31428
  const identity = resolveTableIdentifier(parsedIdentifier);
31036
- const tableName = qualifiedTableName(identity);
31429
+ const tableName2 = qualifiedTableName(identity);
31037
31430
  const unsupportedTableField = firstMeaningfulUnsupportedField(node, [
31038
31431
  "type",
31039
31432
  "keyword",
@@ -31043,14 +31436,14 @@ function consumeCreateTable(node, statement, context) {
31043
31436
  ]);
31044
31437
  if (unsupportedTableField) {
31045
31438
  context.unparsed.push({
31046
- location: tableName,
31439
+ location: tableName2,
31047
31440
  reason: `blocked: unsupported CREATE TABLE ${unsupportedTableField}`
31048
31441
  });
31049
31442
  return;
31050
31443
  }
31051
31444
  if (!Array.isArray(node.create_definitions)) {
31052
31445
  context.unparsed.push({
31053
- location: tableName,
31446
+ location: tableName2,
31054
31447
  reason: "blocked: unsupported CREATE TABLE without column definitions"
31055
31448
  });
31056
31449
  return;
@@ -31065,7 +31458,7 @@ function consumeCreateTable(node, statement, context) {
31065
31458
  const definitions = [];
31066
31459
  for (const value of node.create_definitions) {
31067
31460
  if (!isAst(value)) {
31068
- pushUnsupportedDefinition(tableName, "malformed", context.unparsed);
31461
+ pushUnsupportedDefinition(tableName2, "malformed", context.unparsed);
31069
31462
  continue;
31070
31463
  }
31071
31464
  definitions.push(value);
@@ -31091,14 +31484,14 @@ function consumeCreateTable(node, statement, context) {
31091
31484
  consumeTablePrimaryKey(definition, table, context.unparsed);
31092
31485
  continue;
31093
31486
  }
31094
- pushUnsupportedDefinition(tableName, stringValue2(definition.constraint_type) ?? stringValue2(definition.resource) ?? "malformed", context.unparsed);
31487
+ pushUnsupportedDefinition(tableName2, stringValue2(definition.constraint_type) ?? stringValue2(definition.resource) ?? "malformed", context.unparsed);
31095
31488
  }
31096
31489
  const key = tableIdentityKey(identity);
31097
31490
  if (context.tablesByIdentity.has(key)) {
31098
- context.duplicateTableIdentity ??= tableName;
31491
+ context.duplicateTableIdentity ??= tableName2;
31099
31492
  context.unparsed.push({
31100
- location: tableName,
31101
- reason: `blocked: duplicate table identity '${tableName}'`
31493
+ location: tableName2,
31494
+ reason: `blocked: duplicate table identity '${tableName2}'`
31102
31495
  });
31103
31496
  return;
31104
31497
  }
@@ -31241,12 +31634,12 @@ function consumeCreateIndex(node, statement, context) {
31241
31634
  return;
31242
31635
  }
31243
31636
  const identity = resolveTableIdentifier(parsedIdentifier);
31244
- const tableName = qualifiedTableName(identity);
31637
+ const tableName2 = qualifiedTableName(identity);
31245
31638
  const target = context.tablesByIdentity.get(tableIdentityKey(identity));
31246
31639
  if (!target) {
31247
31640
  context.unparsed.push({
31248
31641
  location: indexName ?? "index",
31249
- reason: `blocked: CREATE INDEX targets unknown table '${tableName}'`
31642
+ reason: `blocked: CREATE INDEX targets unknown table '${tableName2}'`
31250
31643
  });
31251
31644
  return;
31252
31645
  }
@@ -31279,7 +31672,7 @@ function consumeCreateIndex(node, statement, context) {
31279
31672
  }
31280
31673
  if (columns.value.length === 0) {
31281
31674
  context.unparsed.push({
31282
- location: indexName ?? `${tableName} index`,
31675
+ location: indexName ?? `${tableName2} index`,
31283
31676
  reason: "blocked: malformed CREATE INDEX without columns"
31284
31677
  });
31285
31678
  return;
@@ -31727,9 +32120,9 @@ function firstMeaningfulUnsupportedField(value, allowed) {
31727
32120
  }
31728
32121
  return null;
31729
32122
  }
31730
- function pushUnsupportedDefinition(tableName, definition, unparsed) {
32123
+ function pushUnsupportedDefinition(tableName2, definition, unparsed) {
31731
32124
  unparsed.push({
31732
- location: `${tableName} (${definition})`,
32125
+ location: `${tableName2} (${definition})`,
31733
32126
  reason: `blocked: unsupported table definition '${definition}'`
31734
32127
  });
31735
32128
  }
@@ -31855,7 +32248,7 @@ function collectBlocks(text3, unparsed) {
31855
32248
  function parseModel2(block, unparsed) {
31856
32249
  const fields = [];
31857
32250
  const pendingIndexes = [];
31858
- let tableName = block.name;
32251
+ let tableName2 = block.name;
31859
32252
  let hasTableMap = false;
31860
32253
  for (const sourceLine of block.lines) {
31861
32254
  const line = stripLineComment(sourceLine.text).trim();
@@ -31874,7 +32267,7 @@ function parseModel2(block, unparsed) {
31874
32267
  addBlocked2(unparsed, block.name, `malformed or duplicate '@@map' attribute`);
31875
32268
  continue;
31876
32269
  }
31877
- tableName = mapped;
32270
+ tableName2 = mapped;
31878
32271
  hasTableMap = true;
31879
32272
  continue;
31880
32273
  }
@@ -31900,12 +32293,12 @@ function parseModel2(block, unparsed) {
31900
32293
  }
31901
32294
  return {
31902
32295
  name: block.name,
31903
- tableName,
32296
+ tableName: tableName2,
31904
32297
  fields,
31905
32298
  pendingIndexes,
31906
32299
  pendingRelations: [],
31907
32300
  columnNames: new Map,
31908
- table: { identity: { table: tableName }, columns: [], indexes: [], foreignKeys: [] }
32301
+ table: { identity: { table: tableName2 }, columns: [], indexes: [], foreignKeys: [] }
31909
32302
  };
31910
32303
  }
31911
32304
  function parseField2(line, modelName, lineNumber, unparsed) {
@@ -32964,31 +33357,31 @@ function compareSnapshots(before, after) {
32964
33357
  const removedColumns = [];
32965
33358
  const modifiedColumns = [];
32966
33359
  const indexChanges = [];
32967
- for (const tableName of addedTables) {
32968
- const added = after.tables[tableName];
33360
+ for (const tableName2 of addedTables) {
33361
+ const added = after.tables[tableName2];
32969
33362
  if (!added)
32970
33363
  continue;
32971
33364
  for (const col of added.columns) {
32972
33365
  addedColumns.push({
32973
- table: tableName,
33366
+ table: tableName2,
32974
33367
  column: col.name,
32975
33368
  type: col.type,
32976
33369
  nullable: col.nullable
32977
33370
  });
32978
33371
  }
32979
33372
  }
32980
- for (const tableName of removedTables) {
32981
- const removed = before.tables[tableName];
33373
+ for (const tableName2 of removedTables) {
33374
+ const removed = before.tables[tableName2];
32982
33375
  if (!removed)
32983
33376
  continue;
32984
33377
  for (const col of removed.columns) {
32985
- removedColumns.push({ table: tableName, column: col.name, type: col.type });
33378
+ removedColumns.push({ table: tableName2, column: col.name, type: col.type });
32986
33379
  }
32987
33380
  }
32988
33381
  const commonTables = Array.from(afterTables).filter((t2) => beforeTables.has(t2));
32989
- for (const tableName of commonTables) {
32990
- const beforeTable = before.tables[tableName];
32991
- const afterTable = after.tables[tableName];
33382
+ for (const tableName2 of commonTables) {
33383
+ const beforeTable = before.tables[tableName2];
33384
+ const afterTable = after.tables[tableName2];
32992
33385
  if (!beforeTable || !afterTable)
32993
33386
  continue;
32994
33387
  const beforeColMap = new Map(beforeTable.columns.map((c) => [c.name, c]));
@@ -32996,7 +33389,7 @@ function compareSnapshots(before, after) {
32996
33389
  for (const [name, col] of afterColMap) {
32997
33390
  if (!beforeColMap.has(name)) {
32998
33391
  addedColumns.push({
32999
- table: tableName,
33392
+ table: tableName2,
33000
33393
  column: name,
33001
33394
  type: col.type,
33002
33395
  nullable: col.nullable
@@ -33005,7 +33398,7 @@ function compareSnapshots(before, after) {
33005
33398
  }
33006
33399
  for (const [name, col] of beforeColMap) {
33007
33400
  if (!afterColMap.has(name)) {
33008
- removedColumns.push({ table: tableName, column: name, type: col.type });
33401
+ removedColumns.push({ table: tableName2, column: name, type: col.type });
33009
33402
  }
33010
33403
  }
33011
33404
  for (const [name, afterCol] of afterColMap) {
@@ -33014,7 +33407,7 @@ function compareSnapshots(before, after) {
33014
33407
  continue;
33015
33408
  if (beforeCol.type.toLowerCase() !== afterCol.type.toLowerCase() || beforeCol.nullable !== afterCol.nullable) {
33016
33409
  modifiedColumns.push({
33017
- table: tableName,
33410
+ table: tableName2,
33018
33411
  column: name,
33019
33412
  before: { type: beforeCol.type, nullable: beforeCol.nullable },
33020
33413
  after: { type: afterCol.type, nullable: afterCol.nullable }
@@ -33025,12 +33418,12 @@ function compareSnapshots(before, after) {
33025
33418
  const afterIndexes = new Map((afterTable.indexes || []).map((i) => [i.name, i]));
33026
33419
  for (const name of afterIndexes.keys()) {
33027
33420
  if (!beforeIndexes.has(name)) {
33028
- indexChanges.push({ table: tableName, name, change: "added" });
33421
+ indexChanges.push({ table: tableName2, name, change: "added" });
33029
33422
  }
33030
33423
  }
33031
33424
  for (const name of beforeIndexes.keys()) {
33032
33425
  if (!afterIndexes.has(name)) {
33033
- indexChanges.push({ table: tableName, name, change: "removed" });
33426
+ indexChanges.push({ table: tableName2, name, change: "removed" });
33034
33427
  }
33035
33428
  }
33036
33429
  }
@@ -38623,10 +39016,10 @@ async function loadSchemaContext(dbcliPath, connectionName) {
38623
39016
  const loader3 = new SchemaLayeredLoader(dbcliPath, { connectionName });
38624
39017
  const { cache, index } = await loader3.initialize();
38625
39018
  const schema = {};
38626
- for (const tableName of Object.keys(index?.tables ?? {})) {
38627
- const table = await cache.getTableSchema(tableName);
39019
+ for (const tableName2 of Object.keys(index?.tables ?? {})) {
39020
+ const table = await cache.getTableSchema(tableName2);
38628
39021
  if (table) {
38629
- schema[tableName] = table;
39022
+ schema[tableName2] = table;
38630
39023
  }
38631
39024
  }
38632
39025
  return buildSchemaContext(schema);
@@ -40062,9 +40455,9 @@ var init_select_star = __esm(() => {
40062
40455
  span: findingSpan(ctx.sql, "select *"),
40063
40456
  schemaVerified: false
40064
40457
  };
40065
- const tableName = singlePhysicalTable(ctx.ast);
40066
- if (ctx.schema.available && tableName && isSoleUnqualifiedStar(ctx.ast)) {
40067
- const table = ctx.schema.getTable(tableName);
40458
+ const tableName2 = singlePhysicalTable(ctx.ast);
40459
+ if (ctx.schema.available && tableName2 && isSoleUnqualifiedStar(ctx.ast)) {
40460
+ const table = ctx.schema.getTable(tableName2);
40068
40461
  if (table && table.columns.length > 0) {
40069
40462
  if (wildcardIndexes.length === 1) {
40070
40463
  const wildcardIndex = wildcardIndexes[0];
@@ -40973,17 +41366,17 @@ function canonicalizeEvidenceReceiptCommand(command, operation = "assert") {
40973
41366
  function sha2563(value) {
40974
41367
  return `sha256:${createHash5("sha256").update(value).digest("hex")}`;
40975
41368
  }
40976
- function verdictFingerprint(verdict) {
40977
- if (!record3(verdict) || typeof verdict.pass !== "boolean" || !Array.isArray(verdict.checks) || verdict.checks.length > 1000) {
41369
+ function verdictFingerprint(verdict2) {
41370
+ if (!record3(verdict2) || typeof verdict2.pass !== "boolean" || !Array.isArray(verdict2.checks) || verdict2.checks.length > 1000) {
40978
41371
  throw new EvidenceReceiptValidationError("verdict must contain bounded pass bits");
40979
41372
  }
40980
- const bits = verdict.checks.map((check) => {
41373
+ const bits = verdict2.checks.map((check) => {
40981
41374
  if (!record3(check) || Object.keys(check).some((key) => key !== "pass") || typeof check.pass !== "boolean") {
40982
41375
  throw new EvidenceReceiptValidationError("verdict checks must contain only pass bits");
40983
41376
  }
40984
41377
  return check.pass;
40985
41378
  });
40986
- return sha2563(JSON.stringify({ pass: verdict.pass, checks: bits }));
41379
+ return sha2563(JSON.stringify({ pass: verdict2.pass, checks: bits }));
40987
41380
  }
40988
41381
  function verificationOutcomeFingerprint(status2, artifactPersisted) {
40989
41382
  if (!isVerificationStatus(status2)) {
@@ -41281,7 +41674,7 @@ var init_assert = __esm(() => {
41281
41674
  const adapter = AdapterFactory.createSqlAdapter(requireSqlConnection11(config.connection));
41282
41675
  await adapter.connect();
41283
41676
  let auditRef = null;
41284
- let verdict;
41677
+ let verdict2;
41285
41678
  try {
41286
41679
  const blacklistManager = new BlacklistManager(config);
41287
41680
  const blacklistValidator = new BlacklistValidator(blacklistManager);
@@ -41308,9 +41701,9 @@ var init_assert = __esm(() => {
41308
41701
  });
41309
41702
  checks.push(...compareAgainst(current, baseline, options.tolerance));
41310
41703
  }
41311
- verdict = { pass: checks.every((c) => c.pass), checks };
41704
+ verdict2 = { pass: checks.every((c) => c.pass), checks };
41312
41705
  auditRef = await writeAuditEntry(config, "assert", options, {
41313
- success: verdict.pass,
41706
+ success: verdict2.pass,
41314
41707
  sql: query
41315
41708
  });
41316
41709
  } finally {
@@ -41320,7 +41713,7 @@ var init_assert = __esm(() => {
41320
41713
  if (options.writeVerificationArtifact === true && verificationSubject) {
41321
41714
  try {
41322
41715
  const artifact2 = buildAssertVerificationArtifact({
41323
- verdict,
41716
+ verdict: verdict2,
41324
41717
  subject: verificationSubject,
41325
41718
  summary: options.verificationSummary,
41326
41719
  argv: process.argv,
@@ -41339,7 +41732,7 @@ var init_assert = __esm(() => {
41339
41732
  context: await buildEvidenceReceiptContext(config, process.cwd()),
41340
41733
  auditRef,
41341
41734
  verificationArtifactRef: verificationArtifactPath ? basename7(verificationArtifactPath) : null,
41342
- verdict
41735
+ verdict: verdict2
41343
41736
  });
41344
41737
  evidenceReceiptPath = await writeEvidenceReceipt(process.cwd(), options.evidenceReceipt, receipt);
41345
41738
  } catch {
@@ -41349,23 +41742,23 @@ var init_assert = __esm(() => {
41349
41742
  }
41350
41743
  if (options.format === "json") {
41351
41744
  console.log(JSON.stringify({
41352
- ...verdict,
41745
+ ...verdict2,
41353
41746
  ...verificationArtifactPath ? { verificationArtifactPath } : {},
41354
41747
  ...evidenceReceiptPath ? { evidenceReceiptPath } : {}
41355
41748
  }, null, 2));
41356
41749
  } else {
41357
- for (const c of verdict.checks) {
41750
+ for (const c of verdict2.checks) {
41358
41751
  console.log(`${c.pass ? "PASS" : "FAIL"} ${c.name} expected=${c.expected} actual=${c.actual}`);
41359
41752
  }
41360
41753
  console.log(`
41361
- Verdict: ${verdict.pass ? "PASS" : "FAIL"}`);
41754
+ Verdict: ${verdict2.pass ? "PASS" : "FAIL"}`);
41362
41755
  if (verificationArtifactPath) {
41363
41756
  console.log(`Verification artifact: ${verificationArtifactPath}`);
41364
41757
  }
41365
41758
  if (evidenceReceiptPath)
41366
41759
  console.log(`Evidence receipt: ${evidenceReceiptPath}`);
41367
41760
  }
41368
- process.exit(verdict.pass || options.fail === false ? 0 : 1);
41761
+ process.exit(verdict2.pass || options.fail === false ? 0 : 1);
41369
41762
  } catch (error) {
41370
41763
  if (error instanceof Error) {
41371
41764
  console.error(error.message);
@@ -44399,9 +44792,9 @@ function createCompleter(ctx) {
44399
44792
  const sqlHits = matchWithSuffix([...SQL_KEYWORDS_FOR_COMPLETION], lastWord);
44400
44793
  const tableHits = matchWithSuffix(allTableNames, lastWord);
44401
44794
  const colHits = isColumnPosition(upperLine) ? (() => {
44402
- const tableName = extractTableFromLine(trimmed, allTableNames);
44403
- if (tableName && ctx.columnsByTable[tableName]) {
44404
- return matchWithSuffix([...ctx.columnsByTable[tableName]], lastWord);
44795
+ const tableName2 = extractTableFromLine(trimmed, allTableNames);
44796
+ if (tableName2 && ctx.columnsByTable[tableName2]) {
44797
+ return matchWithSuffix([...ctx.columnsByTable[tableName2]], lastWord);
44405
44798
  }
44406
44799
  return matchWithSuffix(uniqueColumns, lastWord);
44407
44800
  })() : [[], lastWord];