@databricks-solutions/lakebase-scm-utils 0.2.41 → 0.2.42

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 (71) hide show
  1. package/dist/scripts/github/index.cjs +3 -1
  2. package/dist/scripts/github/index.js +3 -1
  3. package/dist/scripts/github/pr.cli.cjs +3 -1
  4. package/dist/scripts/github/pr.cli.js +3 -1
  5. package/dist/scripts/index.cjs +66 -21
  6. package/dist/scripts/index.d.cts +1 -1
  7. package/dist/scripts/index.d.ts +1 -1
  8. package/dist/scripts/index.js +59 -15
  9. package/dist/scripts/lakebase/branch.cli.cjs +3 -1
  10. package/dist/scripts/lakebase/branch.cli.js +3 -1
  11. package/dist/scripts/lakebase/ci-app-endpoint.cli.cjs +3 -1
  12. package/dist/scripts/lakebase/ci-app-endpoint.cli.js +3 -1
  13. package/dist/scripts/lakebase/ci-resolve-branch.cli.cjs +5 -3
  14. package/dist/scripts/lakebase/ci-resolve-branch.cli.js +5 -3
  15. package/dist/scripts/lakebase/collapse-heads.cli.cjs +5 -3
  16. package/dist/scripts/lakebase/collapse-heads.cli.js +5 -3
  17. package/dist/scripts/lakebase/cut-backup.cli.cjs +3 -1
  18. package/dist/scripts/lakebase/cut-backup.cli.js +3 -1
  19. package/dist/scripts/lakebase/cut-tier.cli.cjs +3 -1
  20. package/dist/scripts/lakebase/cut-tier.cli.js +3 -1
  21. package/dist/scripts/lakebase/detect-language.cli.cjs +5 -3
  22. package/dist/scripts/lakebase/detect-language.cli.js +5 -3
  23. package/dist/scripts/lakebase/doctor.cli.cjs +5 -3
  24. package/dist/scripts/lakebase/doctor.cli.js +5 -3
  25. package/dist/scripts/lakebase/get-connection.cli.cjs +5 -3
  26. package/dist/scripts/lakebase/get-connection.cli.js +5 -3
  27. package/dist/scripts/lakebase/index.cjs +66 -21
  28. package/dist/scripts/lakebase/index.d.cts +5 -1
  29. package/dist/scripts/lakebase/index.d.ts +5 -1
  30. package/dist/scripts/lakebase/index.js +59 -15
  31. package/dist/scripts/lakebase/infra-runner.cli.cjs +5 -3
  32. package/dist/scripts/lakebase/infra-runner.cli.js +5 -3
  33. package/dist/scripts/lakebase/new-migration.cli.cjs +5 -3
  34. package/dist/scripts/lakebase/new-migration.cli.js +5 -3
  35. package/dist/scripts/lakebase/schema-diff.cli.cjs +5 -3
  36. package/dist/scripts/lakebase/schema-diff.cli.js +5 -3
  37. package/dist/scripts/lakebase/schema-migrate.cli.cjs +5 -3
  38. package/dist/scripts/lakebase/schema-migrate.cli.js +5 -3
  39. package/dist/scripts/lakebase/scm-abandon-feature.cli.cjs +37 -1
  40. package/dist/scripts/lakebase/scm-abandon-feature.cli.js +37 -1
  41. package/dist/scripts/lakebase/scm-adopt-state.cli.cjs +37 -1
  42. package/dist/scripts/lakebase/scm-adopt-state.cli.js +37 -1
  43. package/dist/scripts/lakebase/scm-claim-feature.cli.cjs +45 -9
  44. package/dist/scripts/lakebase/scm-claim-feature.cli.js +39 -3
  45. package/dist/scripts/lakebase/scm-cleanup.cli.cjs +3 -1
  46. package/dist/scripts/lakebase/scm-cleanup.cli.js +3 -1
  47. package/dist/scripts/lakebase/scm-doctor.cli.cjs +56 -29
  48. package/dist/scripts/lakebase/scm-doctor.cli.js +50 -23
  49. package/dist/scripts/lakebase/scm-feature-branch.cli.cjs +1 -0
  50. package/dist/scripts/lakebase/scm-feature-branch.cli.js +1 -0
  51. package/dist/scripts/lakebase/scm-merge.cli.cjs +45 -9
  52. package/dist/scripts/lakebase/scm-merge.cli.js +39 -3
  53. package/dist/scripts/lakebase/scm-prepare-pr.cli.cjs +34 -0
  54. package/dist/scripts/lakebase/scm-prepare-pr.cli.js +34 -0
  55. package/dist/scripts/lakebase/scm-reconcile-tier.cli.cjs +6 -3
  56. package/dist/scripts/lakebase/scm-reconcile-tier.cli.js +6 -3
  57. package/dist/scripts/lakebase/scm-recover-orphans.cli.cjs +37 -1
  58. package/dist/scripts/lakebase/scm-recover-orphans.cli.js +37 -1
  59. package/dist/scripts/lakebase/scm-state.cli.cjs +5 -4
  60. package/dist/scripts/lakebase/scm-state.cli.js +4 -3
  61. package/dist/scripts/lakebase/scm-wait-ci.cli.cjs +34 -0
  62. package/dist/scripts/lakebase/scm-wait-ci.cli.js +34 -0
  63. package/dist/scripts/util/index.cjs +5 -3
  64. package/dist/scripts/util/index.js +5 -3
  65. package/package.json +1 -1
  66. package/scripts/lakebase/databricks-cli.ts +7 -1
  67. package/scripts/lakebase/enable-e2e.ts +19 -3
  68. package/scripts/lakebase/scm-doctor.ts +1 -12
  69. package/scripts/lakebase/scm-workflow-state.ts +49 -0
  70. package/templates/project/common/.gitignore.base +8 -0
  71. package/templates/project/common/scripts/run-tests.sh +18 -1
@@ -77826,7 +77826,9 @@ function resolveProfile(opts) {
77826
77826
  function buildInvocation(args, opts) {
77827
77827
  const base = opts.env ?? process.env;
77828
77828
  const trimmedHost = effectiveHost(opts)?.replace(/\/+$/, "");
77829
- const env = trimmedHost ? { ...base, DATABRICKS_HOST: trimmedHost } : base;
77829
+ const env = { ...base };
77830
+ if (trimmedHost) env.DATABRICKS_HOST = trimmedHost;
77831
+ delete env.DATABRICKS_WORKSPACE_ID;
77830
77832
  const profile = resolveProfile(opts);
77831
77833
  const argv = profile && !opts.noProfile && !args.includes("--profile") ? [...args, "--profile", profile] : args;
77832
77834
  return { argv, env, profile };
@@ -79763,8 +79765,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
79763
79765
  var cached;
79764
79766
  function substrateSelfVersion() {
79765
79767
  if (cached !== void 0) return cached;
79766
- if ("0.2.41".length > 0) {
79767
- cached = "0.2.41";
79768
+ if ("0.2.42".length > 0) {
79769
+ cached = "0.2.42";
79768
79770
  return cached;
79769
79771
  }
79770
79772
  cached = "unknown";
@@ -80225,6 +80227,39 @@ async function createFeaturePairedBranch(args) {
80225
80227
  init_cjs_shims();
80226
80228
  var fs6 = __toESM(require("fs"), 1);
80227
80229
  var path4 = __toESM(require("path"), 1);
80230
+ var import_node_child_process4 = require("child_process");
80231
+ function isGitTracked(projectDir, rel) {
80232
+ try {
80233
+ (0, import_node_child_process4.execFileSync)("git", ["ls-files", "--error-unmatch", "--", rel], { cwd: projectDir, stdio: "ignore" });
80234
+ return true;
80235
+ } catch {
80236
+ return false;
80237
+ }
80238
+ }
80239
+ function ensureWorkflowStateUntracked(projectDir) {
80240
+ const rel = ".lakebase/workflow-state.json";
80241
+ try {
80242
+ if (isGitTracked(projectDir, rel)) {
80243
+ (0, import_node_child_process4.execFileSync)("git", ["rm", "--cached", "--quiet", "--ignore-unmatch", "--", rel], { cwd: projectDir, stdio: "ignore" });
80244
+ }
80245
+ } catch {
80246
+ }
80247
+ try {
80248
+ const gitignore = path4.join(projectDir, ".gitignore");
80249
+ const existing = fs6.existsSync(gitignore) ? fs6.readFileSync(gitignore, "utf8") : "";
80250
+ if (!existing.split("\n").some((l) => l.trim() === rel)) {
80251
+ const sep2 = existing === "" || existing.endsWith("\n") ? "" : "\n";
80252
+ fs6.appendFileSync(
80253
+ gitignore,
80254
+ `${sep2}# Runtime SCM claim state (per working tree): a branch checkout must never restore
80255
+ # a stale committed claim over the live one (issue #203 / Finding 28).
80256
+ ${rel}
80257
+ `
80258
+ );
80259
+ }
80260
+ } catch {
80261
+ }
80262
+ }
80228
80263
  var SCM_STATES = [
80229
80264
  "scaffold-complete",
80230
80265
  "feature-claimed",
@@ -80271,6 +80306,7 @@ function writeWorkflowState(projectDir, state) {
80271
80306
  throw new Error(`Refusing to write invalid SCM state:
80272
80307
  ${summary}`);
80273
80308
  }
80309
+ ensureWorkflowStateUntracked(projectDir);
80274
80310
  const dir = path4.join(projectDir, ".lakebase");
80275
80311
  fs6.mkdirSync(dir, { recursive: true });
80276
80312
  const target = stateFilePath(projectDir);
@@ -80681,7 +80717,7 @@ var path8 = __toESM(require("path"), 1);
80681
80717
 
80682
80718
  // scripts/lakebase/schema-migrate-runners/alembic.ts
80683
80719
  init_cjs_shims();
80684
- var import_node_child_process4 = require("child_process");
80720
+ var import_node_child_process5 = require("child_process");
80685
80721
  var fs9 = __toESM(require("fs"), 1);
80686
80722
  var path7 = __toESM(require("path"), 1);
80687
80723
  function resolveAlembicBin(projectDir) {
@@ -80703,7 +80739,7 @@ function spawnAlembic(projectDir, args, dsn) {
80703
80739
  const env = { ...process.env };
80704
80740
  env.PYTHONPATH = [projectDir, process.env.PYTHONPATH].filter(Boolean).join(path7.delimiter);
80705
80741
  if (dsn) env.DATABASE_URL = dsn;
80706
- const child = (0, import_node_child_process4.spawn)(bin, args, {
80742
+ const child = (0, import_node_child_process5.spawn)(bin, args, {
80707
80743
  cwd: projectDir,
80708
80744
  env,
80709
80745
  stdio: ["ignore", "pipe", "pipe"]
@@ -81065,7 +81101,7 @@ var path10 = __toESM(require("path"), 1);
81065
81101
 
81066
81102
  // scripts/lakebase/schema-migrate-runners/flyway.ts
81067
81103
  init_cjs_shims();
81068
- var import_node_child_process5 = require("child_process");
81104
+ var import_node_child_process6 = require("child_process");
81069
81105
  var path9 = __toESM(require("path"), 1);
81070
81106
  function dsnToFlywayEnv(dsn) {
81071
81107
  const u = new URL(dsn);
@@ -81081,7 +81117,7 @@ function migrationsLocation(projectDir) {
81081
81117
  function runFlyway(ctx, args) {
81082
81118
  const { url, user, password } = dsnToFlywayEnv(ctx.dsn);
81083
81119
  return new Promise((resolve3, reject) => {
81084
- const child = (0, import_node_child_process5.spawn)(
81120
+ const child = (0, import_node_child_process6.spawn)(
81085
81121
  "flyway",
81086
81122
  ["-outputType=json", `-locations=${migrationsLocation(ctx.projectDir)}`, ...args],
81087
81123
  {
@@ -81318,7 +81354,7 @@ var path12 = __toESM(require("path"), 1);
81318
81354
 
81319
81355
  // scripts/lakebase/schema-migrate-runners/knex.ts
81320
81356
  init_cjs_shims();
81321
- var import_node_child_process6 = require("child_process");
81357
+ var import_node_child_process7 = require("child_process");
81322
81358
  var fs12 = __toESM(require("fs"), 1);
81323
81359
  var path11 = __toESM(require("path"), 1);
81324
81360
  var KNEXFILE_VARIANTS = ["knexfile.js", "knexfile.ts", "knexfile.mjs", "knexfile.cjs"];
@@ -81340,7 +81376,7 @@ function spawnKnex(projectDir, args, dsn) {
81340
81376
  );
81341
81377
  return;
81342
81378
  }
81343
- const child = (0, import_node_child_process6.spawn)("npx", ["--no-install", "knex", "--knexfile", knexfile, ...args], {
81379
+ const child = (0, import_node_child_process7.spawn)("npx", ["--no-install", "knex", "--knexfile", knexfile, ...args], {
81344
81380
  cwd: projectDir,
81345
81381
  env: dsn ? { ...process.env, DATABASE_URL: dsn } : { ...process.env },
81346
81382
  stdio: ["ignore", "pipe", "pipe"]
@@ -296,7 +296,9 @@ function resolveProfile(opts) {
296
296
  function buildInvocation(args, opts) {
297
297
  const base = opts.env ?? process.env;
298
298
  const trimmedHost = effectiveHost(opts)?.replace(/\/+$/, "");
299
- const env = trimmedHost ? { ...base, DATABRICKS_HOST: trimmedHost } : base;
299
+ const env = { ...base };
300
+ if (trimmedHost) env.DATABRICKS_HOST = trimmedHost;
301
+ delete env.DATABRICKS_WORKSPACE_ID;
300
302
  const profile = resolveProfile(opts);
301
303
  const argv = profile && !opts.noProfile && !args.includes("--profile") ? [...args, "--profile", profile] : args;
302
304
  return { argv, env, profile };
@@ -844,8 +846,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
844
846
  var cached;
845
847
  function substrateSelfVersion() {
846
848
  if (cached !== void 0) return cached;
847
- if ("0.2.41".length > 0) {
848
- cached = "0.2.41";
849
+ if ("0.2.42".length > 0) {
850
+ cached = "0.2.42";
849
851
  return cached;
850
852
  }
851
853
  cached = "unknown";
@@ -1304,6 +1306,39 @@ async function createFeaturePairedBranch(args) {
1304
1306
  // scripts/lakebase/scm-workflow-state.ts
1305
1307
  import * as fs5 from "fs";
1306
1308
  import * as path4 from "path";
1309
+ import { execFileSync as execFileSync4 } from "child_process";
1310
+ function isGitTracked(projectDir, rel) {
1311
+ try {
1312
+ execFileSync4("git", ["ls-files", "--error-unmatch", "--", rel], { cwd: projectDir, stdio: "ignore" });
1313
+ return true;
1314
+ } catch {
1315
+ return false;
1316
+ }
1317
+ }
1318
+ function ensureWorkflowStateUntracked(projectDir) {
1319
+ const rel = ".lakebase/workflow-state.json";
1320
+ try {
1321
+ if (isGitTracked(projectDir, rel)) {
1322
+ execFileSync4("git", ["rm", "--cached", "--quiet", "--ignore-unmatch", "--", rel], { cwd: projectDir, stdio: "ignore" });
1323
+ }
1324
+ } catch {
1325
+ }
1326
+ try {
1327
+ const gitignore = path4.join(projectDir, ".gitignore");
1328
+ const existing = fs5.existsSync(gitignore) ? fs5.readFileSync(gitignore, "utf8") : "";
1329
+ if (!existing.split("\n").some((l) => l.trim() === rel)) {
1330
+ const sep2 = existing === "" || existing.endsWith("\n") ? "" : "\n";
1331
+ fs5.appendFileSync(
1332
+ gitignore,
1333
+ `${sep2}# Runtime SCM claim state (per working tree): a branch checkout must never restore
1334
+ # a stale committed claim over the live one (issue #203 / Finding 28).
1335
+ ${rel}
1336
+ `
1337
+ );
1338
+ }
1339
+ } catch {
1340
+ }
1341
+ }
1307
1342
  var SCM_STATES = [
1308
1343
  "scaffold-complete",
1309
1344
  "feature-claimed",
@@ -1350,6 +1385,7 @@ function writeWorkflowState(projectDir, state) {
1350
1385
  throw new Error(`Refusing to write invalid SCM state:
1351
1386
  ${summary}`);
1352
1387
  }
1388
+ ensureWorkflowStateUntracked(projectDir);
1353
1389
  const dir = path4.join(projectDir, ".lakebase");
1354
1390
  fs5.mkdirSync(dir, { recursive: true });
1355
1391
  const target = stateFilePath(projectDir);
@@ -239,7 +239,9 @@ function resolveProfile(opts) {
239
239
  function buildInvocation(args, opts) {
240
240
  const base = opts.env ?? process.env;
241
241
  const trimmedHost = effectiveHost(opts)?.replace(/\/+$/, "");
242
- const env = trimmedHost ? { ...base, DATABRICKS_HOST: trimmedHost } : base;
242
+ const env = { ...base };
243
+ if (trimmedHost) env.DATABRICKS_HOST = trimmedHost;
244
+ delete env.DATABRICKS_WORKSPACE_ID;
243
245
  const profile = resolveProfile(opts);
244
246
  const argv = profile && !opts.noProfile && !args.includes("--profile") ? [...args, "--profile", profile] : args;
245
247
  return { argv, env, profile };
@@ -199,7 +199,9 @@ function resolveProfile(opts) {
199
199
  function buildInvocation(args, opts) {
200
200
  const base = opts.env ?? process.env;
201
201
  const trimmedHost = effectiveHost(opts)?.replace(/\/+$/, "");
202
- const env = trimmedHost ? { ...base, DATABRICKS_HOST: trimmedHost } : base;
202
+ const env = { ...base };
203
+ if (trimmedHost) env.DATABRICKS_HOST = trimmedHost;
204
+ delete env.DATABRICKS_WORKSPACE_ID;
203
205
  const profile = resolveProfile(opts);
204
206
  const argv = profile && !opts.noProfile && !args.includes("--profile") ? [...args, "--profile", profile] : args;
205
207
  return { argv, env, profile };
@@ -78963,7 +78963,6 @@ function isCliEntry(importMetaUrl2) {
78963
78963
  // scripts/lakebase/scm-doctor.ts
78964
78964
  init_cjs_shims();
78965
78965
  var fs14 = __toESM(require("fs"), 1);
78966
- var import_node_child_process8 = require("child_process");
78967
78966
  var path13 = __toESM(require("path"), 1);
78968
78967
 
78969
78968
  // scripts/lakebase/branch-utils.ts
@@ -79237,7 +79236,9 @@ function resolveProfile(opts) {
79237
79236
  function buildInvocation(args, opts) {
79238
79237
  const base = opts.env ?? process.env;
79239
79238
  const trimmedHost = effectiveHost(opts)?.replace(/\/+$/, "");
79240
- const env = trimmedHost ? { ...base, DATABRICKS_HOST: trimmedHost } : base;
79239
+ const env = { ...base };
79240
+ if (trimmedHost) env.DATABRICKS_HOST = trimmedHost;
79241
+ delete env.DATABRICKS_WORKSPACE_ID;
79241
79242
  const profile = resolveProfile(opts);
79242
79243
  const argv = profile && !opts.noProfile && !args.includes("--profile") ? [...args, "--profile", profile] : args;
79243
79244
  return { argv, env, profile };
@@ -86158,6 +86159,39 @@ init_cjs_shims();
86158
86159
  init_cjs_shims();
86159
86160
  var fs3 = __toESM(require("fs"), 1);
86160
86161
  var path2 = __toESM(require("path"), 1);
86162
+ var import_node_child_process4 = require("child_process");
86163
+ function isGitTracked(projectDir, rel) {
86164
+ try {
86165
+ (0, import_node_child_process4.execFileSync)("git", ["ls-files", "--error-unmatch", "--", rel], { cwd: projectDir, stdio: "ignore" });
86166
+ return true;
86167
+ } catch {
86168
+ return false;
86169
+ }
86170
+ }
86171
+ function ensureWorkflowStateUntracked(projectDir) {
86172
+ const rel = ".lakebase/workflow-state.json";
86173
+ try {
86174
+ if (isGitTracked(projectDir, rel)) {
86175
+ (0, import_node_child_process4.execFileSync)("git", ["rm", "--cached", "--quiet", "--ignore-unmatch", "--", rel], { cwd: projectDir, stdio: "ignore" });
86176
+ }
86177
+ } catch {
86178
+ }
86179
+ try {
86180
+ const gitignore = path2.join(projectDir, ".gitignore");
86181
+ const existing = fs3.existsSync(gitignore) ? fs3.readFileSync(gitignore, "utf8") : "";
86182
+ if (!existing.split("\n").some((l) => l.trim() === rel)) {
86183
+ const sep3 = existing === "" || existing.endsWith("\n") ? "" : "\n";
86184
+ fs3.appendFileSync(
86185
+ gitignore,
86186
+ `${sep3}# Runtime SCM claim state (per working tree): a branch checkout must never restore
86187
+ # a stale committed claim over the live one (issue #203 / Finding 28).
86188
+ ${rel}
86189
+ `
86190
+ );
86191
+ }
86192
+ } catch {
86193
+ }
86194
+ }
86161
86195
  var SCM_STATES = [
86162
86196
  "scaffold-complete",
86163
86197
  "feature-claimed",
@@ -86204,6 +86238,7 @@ function writeWorkflowState(projectDir, state) {
86204
86238
  throw new Error(`Refusing to write invalid SCM state:
86205
86239
  ${summary}`);
86206
86240
  }
86241
+ ensureWorkflowStateUntracked(projectDir);
86207
86242
  const dir = path2.join(projectDir, ".lakebase");
86208
86243
  fs3.mkdirSync(dir, { recursive: true });
86209
86244
  const target = stateFilePath(projectDir);
@@ -86497,7 +86532,7 @@ init_cjs_shims();
86497
86532
  init_cjs_shims();
86498
86533
  var fs6 = __toESM(require("fs"), 1);
86499
86534
  var path4 = __toESM(require("path"), 1);
86500
- var import_node_child_process4 = require("child_process");
86535
+ var import_node_child_process5 = require("child_process");
86501
86536
 
86502
86537
  // scripts/lakebase/branch-create.ts
86503
86538
  init_cjs_shims();
@@ -88187,8 +88222,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
88187
88222
  var cached;
88188
88223
  function substrateSelfVersion() {
88189
88224
  if (cached !== void 0) return cached;
88190
- if ("0.2.41".length > 0) {
88191
- cached = "0.2.41";
88225
+ if ("0.2.42".length > 0) {
88226
+ cached = "0.2.42";
88192
88227
  return cached;
88193
88228
  }
88194
88229
  cached = "unknown";
@@ -88377,7 +88412,7 @@ async function isDirty(args) {
88377
88412
 
88378
88413
  // scripts/lakebase/paired-branch.ts
88379
88414
  function gitCurrentBranch(cwd) {
88380
- return (0, import_node_child_process4.execFileSync)("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
88415
+ return (0, import_node_child_process5.execFileSync)("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
88381
88416
  cwd,
88382
88417
  encoding: "utf8",
88383
88418
  stdio: ["ignore", "pipe", "pipe"],
@@ -88386,7 +88421,7 @@ function gitCurrentBranch(cwd) {
88386
88421
  }
88387
88422
  function gitHasLocalBranch(cwd, branch) {
88388
88423
  try {
88389
- (0, import_node_child_process4.execFileSync)("git", ["rev-parse", "--verify", "--quiet", `refs/heads/${branch}`], {
88424
+ (0, import_node_child_process5.execFileSync)("git", ["rev-parse", "--verify", "--quiet", `refs/heads/${branch}`], {
88390
88425
  cwd,
88391
88426
  stdio: "ignore",
88392
88427
  timeout: KIT_TIMEOUTS.gitDefault
@@ -88398,7 +88433,7 @@ function gitHasLocalBranch(cwd, branch) {
88398
88433
  }
88399
88434
  function gitCheckoutNewBranch(cwd, branch, startPoint) {
88400
88435
  const argv = startPoint ? ["checkout", "-b", branch, startPoint] : ["checkout", "-b", branch];
88401
- (0, import_node_child_process4.execFileSync)("git", argv, {
88436
+ (0, import_node_child_process5.execFileSync)("git", argv, {
88402
88437
  cwd,
88403
88438
  stdio: ["ignore", "pipe", "pipe"],
88404
88439
  timeout: KIT_TIMEOUTS.gitCheckout
@@ -88406,7 +88441,7 @@ function gitCheckoutNewBranch(cwd, branch, startPoint) {
88406
88441
  }
88407
88442
  function gitFetchBranch(cwd, remote, branch) {
88408
88443
  try {
88409
- (0, import_node_child_process4.execFileSync)("git", ["fetch", remote, branch], {
88444
+ (0, import_node_child_process5.execFileSync)("git", ["fetch", remote, branch], {
88410
88445
  cwd,
88411
88446
  stdio: ["ignore", "pipe", "pipe"],
88412
88447
  timeout: KIT_TIMEOUTS.gitNetwork
@@ -88416,7 +88451,7 @@ function gitFetchBranch(cwd, remote, branch) {
88416
88451
  }
88417
88452
  function gitRefExists(cwd, ref) {
88418
88453
  try {
88419
- (0, import_node_child_process4.execFileSync)("git", ["rev-parse", "--verify", "--quiet", ref], {
88454
+ (0, import_node_child_process5.execFileSync)("git", ["rev-parse", "--verify", "--quiet", ref], {
88420
88455
  cwd,
88421
88456
  stdio: ["ignore", "pipe", "pipe"],
88422
88457
  timeout: KIT_TIMEOUTS.gitDefault
@@ -88428,7 +88463,7 @@ function gitRefExists(cwd, ref) {
88428
88463
  }
88429
88464
  function gitIsAncestor(cwd, ancestor, descendant) {
88430
88465
  try {
88431
- (0, import_node_child_process4.execFileSync)("git", ["merge-base", "--is-ancestor", ancestor, descendant], {
88466
+ (0, import_node_child_process5.execFileSync)("git", ["merge-base", "--is-ancestor", ancestor, descendant], {
88432
88467
  cwd,
88433
88468
  stdio: ["ignore", "pipe", "pipe"],
88434
88469
  timeout: KIT_TIMEOUTS.gitDefault
@@ -88461,14 +88496,14 @@ async function assertCleanForFork(cwd, startPoint) {
88461
88496
  }
88462
88497
  function gitCheckoutExistingBranch(cwd, branch, force = false) {
88463
88498
  const argv = force ? ["checkout", "-f", branch] : ["checkout", branch];
88464
- (0, import_node_child_process4.execFileSync)("git", argv, {
88499
+ (0, import_node_child_process5.execFileSync)("git", argv, {
88465
88500
  cwd,
88466
88501
  stdio: ["ignore", "pipe", "pipe"],
88467
88502
  timeout: KIT_TIMEOUTS.gitCheckout
88468
88503
  });
88469
88504
  }
88470
88505
  function gitDeleteLocalBranch(cwd, branch, force = true) {
88471
- (0, import_node_child_process4.execFileSync)("git", ["branch", force ? "-D" : "-d", branch], {
88506
+ (0, import_node_child_process5.execFileSync)("git", ["branch", force ? "-D" : "-d", branch], {
88472
88507
  cwd,
88473
88508
  stdio: ["ignore", "pipe", "pipe"],
88474
88509
  timeout: KIT_TIMEOUTS.gitDefault
@@ -88476,7 +88511,7 @@ function gitDeleteLocalBranch(cwd, branch, force = true) {
88476
88511
  }
88477
88512
  function gitHasRemoteBranch(cwd, remote, branch) {
88478
88513
  try {
88479
- const out = (0, import_node_child_process4.execFileSync)(
88514
+ const out = (0, import_node_child_process5.execFileSync)(
88480
88515
  "git",
88481
88516
  ["ls-remote", "--exit-code", "--heads", remote, branch],
88482
88517
  { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], timeout: KIT_TIMEOUTS.gitNetwork }
@@ -88487,7 +88522,7 @@ function gitHasRemoteBranch(cwd, remote, branch) {
88487
88522
  }
88488
88523
  }
88489
88524
  function gitDeleteRemoteBranch(cwd, remote, branch) {
88490
- (0, import_node_child_process4.execFileSync)("git", ["push", remote, "--delete", branch], {
88525
+ (0, import_node_child_process5.execFileSync)("git", ["push", remote, "--delete", branch], {
88491
88526
  cwd,
88492
88527
  stdio: ["ignore", "pipe", "pipe"],
88493
88528
  timeout: KIT_TIMEOUTS.gitPush
@@ -88985,7 +89020,7 @@ var path7 = __toESM(require("path"), 1);
88985
89020
 
88986
89021
  // scripts/lakebase/schema-migrate-runners/alembic.ts
88987
89022
  init_cjs_shims();
88988
- var import_node_child_process5 = require("child_process");
89023
+ var import_node_child_process6 = require("child_process");
88989
89024
  var fs8 = __toESM(require("fs"), 1);
88990
89025
  var path6 = __toESM(require("path"), 1);
88991
89026
  function resolveAlembicBin(projectDir) {
@@ -89007,7 +89042,7 @@ function spawnAlembic(projectDir, args, dsn) {
89007
89042
  const env = { ...process.env };
89008
89043
  env.PYTHONPATH = [projectDir, process.env.PYTHONPATH].filter(Boolean).join(path6.delimiter);
89009
89044
  if (dsn) env.DATABASE_URL = dsn;
89010
- const child = (0, import_node_child_process5.spawn)(bin, args, {
89045
+ const child = (0, import_node_child_process6.spawn)(bin, args, {
89011
89046
  cwd: projectDir,
89012
89047
  env,
89013
89048
  stdio: ["ignore", "pipe", "pipe"]
@@ -89369,7 +89404,7 @@ var path9 = __toESM(require("path"), 1);
89369
89404
 
89370
89405
  // scripts/lakebase/schema-migrate-runners/flyway.ts
89371
89406
  init_cjs_shims();
89372
- var import_node_child_process6 = require("child_process");
89407
+ var import_node_child_process7 = require("child_process");
89373
89408
  var path8 = __toESM(require("path"), 1);
89374
89409
  function dsnToFlywayEnv(dsn) {
89375
89410
  const u = new URL(dsn);
@@ -89385,7 +89420,7 @@ function migrationsLocation(projectDir) {
89385
89420
  function runFlyway(ctx, args) {
89386
89421
  const { url, user, password } = dsnToFlywayEnv(ctx.dsn);
89387
89422
  return new Promise((resolve3, reject) => {
89388
- const child = (0, import_node_child_process6.spawn)(
89423
+ const child = (0, import_node_child_process7.spawn)(
89389
89424
  "flyway",
89390
89425
  ["-outputType=json", `-locations=${migrationsLocation(ctx.projectDir)}`, ...args],
89391
89426
  {
@@ -89622,7 +89657,7 @@ var path11 = __toESM(require("path"), 1);
89622
89657
 
89623
89658
  // scripts/lakebase/schema-migrate-runners/knex.ts
89624
89659
  init_cjs_shims();
89625
- var import_node_child_process7 = require("child_process");
89660
+ var import_node_child_process8 = require("child_process");
89626
89661
  var fs11 = __toESM(require("fs"), 1);
89627
89662
  var path10 = __toESM(require("path"), 1);
89628
89663
  var KNEXFILE_VARIANTS = ["knexfile.js", "knexfile.ts", "knexfile.mjs", "knexfile.cjs"];
@@ -89644,7 +89679,7 @@ function spawnKnex(projectDir, args, dsn) {
89644
89679
  );
89645
89680
  return;
89646
89681
  }
89647
- const child = (0, import_node_child_process7.spawn)("npx", ["--no-install", "knex", "--knexfile", knexfile, ...args], {
89682
+ const child = (0, import_node_child_process8.spawn)("npx", ["--no-install", "knex", "--knexfile", knexfile, ...args], {
89648
89683
  cwd: projectDir,
89649
89684
  env: dsn ? { ...process.env, DATABASE_URL: dsn } : { ...process.env },
89650
89685
  stdio: ["ignore", "pipe", "pipe"]
@@ -90054,14 +90089,6 @@ function readEnv(projectDir) {
90054
90089
  function leafOf2(b) {
90055
90090
  return b.name.split("/").pop() ?? b.name;
90056
90091
  }
90057
- function isGitTracked(projectDir, rel) {
90058
- try {
90059
- (0, import_node_child_process8.execFileSync)("git", ["ls-files", "--error-unmatch", "--", rel], { cwd: projectDir, stdio: "ignore" });
90060
- return true;
90061
- } catch {
90062
- return false;
90063
- }
90064
- }
90065
90092
  function worstOf(a, b) {
90066
90093
  const order = ["ok", "warn", "fail"];
90067
90094
  return order[Math.max(order.indexOf(a), order.indexOf(b))];
@@ -1485,7 +1485,6 @@ function isCliEntry(importMetaUrl) {
1485
1485
  // scripts/lakebase/scm-doctor.ts
1486
1486
  init_esm_shims();
1487
1487
  import * as fs13 from "fs";
1488
- import { execFileSync as execFileSync5 } from "child_process";
1489
1488
  import * as path14 from "path";
1490
1489
 
1491
1490
  // scripts/lakebase/branch-utils.ts
@@ -1759,7 +1758,9 @@ function resolveProfile(opts) {
1759
1758
  function buildInvocation(args, opts) {
1760
1759
  const base = opts.env ?? process.env;
1761
1760
  const trimmedHost = effectiveHost(opts)?.replace(/\/+$/, "");
1762
- const env = trimmedHost ? { ...base, DATABRICKS_HOST: trimmedHost } : base;
1761
+ const env = { ...base };
1762
+ if (trimmedHost) env.DATABRICKS_HOST = trimmedHost;
1763
+ delete env.DATABRICKS_WORKSPACE_ID;
1763
1764
  const profile = resolveProfile(opts);
1764
1765
  const argv = profile && !opts.noProfile && !args.includes("--profile") ? [...args, "--profile", profile] : args;
1765
1766
  return { argv, env, profile };
@@ -8680,6 +8681,39 @@ init_esm_shims();
8680
8681
  init_esm_shims();
8681
8682
  import * as fs3 from "fs";
8682
8683
  import * as path3 from "path";
8684
+ import { execFileSync as execFileSync4 } from "child_process";
8685
+ function isGitTracked(projectDir, rel) {
8686
+ try {
8687
+ execFileSync4("git", ["ls-files", "--error-unmatch", "--", rel], { cwd: projectDir, stdio: "ignore" });
8688
+ return true;
8689
+ } catch {
8690
+ return false;
8691
+ }
8692
+ }
8693
+ function ensureWorkflowStateUntracked(projectDir) {
8694
+ const rel = ".lakebase/workflow-state.json";
8695
+ try {
8696
+ if (isGitTracked(projectDir, rel)) {
8697
+ execFileSync4("git", ["rm", "--cached", "--quiet", "--ignore-unmatch", "--", rel], { cwd: projectDir, stdio: "ignore" });
8698
+ }
8699
+ } catch {
8700
+ }
8701
+ try {
8702
+ const gitignore = path3.join(projectDir, ".gitignore");
8703
+ const existing = fs3.existsSync(gitignore) ? fs3.readFileSync(gitignore, "utf8") : "";
8704
+ if (!existing.split("\n").some((l) => l.trim() === rel)) {
8705
+ const sep3 = existing === "" || existing.endsWith("\n") ? "" : "\n";
8706
+ fs3.appendFileSync(
8707
+ gitignore,
8708
+ `${sep3}# Runtime SCM claim state (per working tree): a branch checkout must never restore
8709
+ # a stale committed claim over the live one (issue #203 / Finding 28).
8710
+ ${rel}
8711
+ `
8712
+ );
8713
+ }
8714
+ } catch {
8715
+ }
8716
+ }
8683
8717
  var SCM_STATES = [
8684
8718
  "scaffold-complete",
8685
8719
  "feature-claimed",
@@ -8726,6 +8760,7 @@ function writeWorkflowState(projectDir, state) {
8726
8760
  throw new Error(`Refusing to write invalid SCM state:
8727
8761
  ${summary}`);
8728
8762
  }
8763
+ ensureWorkflowStateUntracked(projectDir);
8729
8764
  const dir = path3.join(projectDir, ".lakebase");
8730
8765
  fs3.mkdirSync(dir, { recursive: true });
8731
8766
  const target = stateFilePath(projectDir);
@@ -9019,7 +9054,7 @@ init_esm_shims();
9019
9054
  init_esm_shims();
9020
9055
  import * as fs5 from "fs";
9021
9056
  import * as path5 from "path";
9022
- import { execFileSync as execFileSync4 } from "child_process";
9057
+ import { execFileSync as execFileSync5 } from "child_process";
9023
9058
 
9024
9059
  // scripts/lakebase/branch-create.ts
9025
9060
  init_esm_shims();
@@ -9340,8 +9375,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
9340
9375
  var cached;
9341
9376
  function substrateSelfVersion() {
9342
9377
  if (cached !== void 0) return cached;
9343
- if ("0.2.41".length > 0) {
9344
- cached = "0.2.41";
9378
+ if ("0.2.42".length > 0) {
9379
+ cached = "0.2.42";
9345
9380
  return cached;
9346
9381
  }
9347
9382
  cached = "unknown";
@@ -9530,7 +9565,7 @@ async function isDirty(args) {
9530
9565
 
9531
9566
  // scripts/lakebase/paired-branch.ts
9532
9567
  function gitCurrentBranch(cwd) {
9533
- return execFileSync4("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
9568
+ return execFileSync5("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
9534
9569
  cwd,
9535
9570
  encoding: "utf8",
9536
9571
  stdio: ["ignore", "pipe", "pipe"],
@@ -9539,7 +9574,7 @@ function gitCurrentBranch(cwd) {
9539
9574
  }
9540
9575
  function gitHasLocalBranch(cwd, branch) {
9541
9576
  try {
9542
- execFileSync4("git", ["rev-parse", "--verify", "--quiet", `refs/heads/${branch}`], {
9577
+ execFileSync5("git", ["rev-parse", "--verify", "--quiet", `refs/heads/${branch}`], {
9543
9578
  cwd,
9544
9579
  stdio: "ignore",
9545
9580
  timeout: KIT_TIMEOUTS.gitDefault
@@ -9551,7 +9586,7 @@ function gitHasLocalBranch(cwd, branch) {
9551
9586
  }
9552
9587
  function gitCheckoutNewBranch(cwd, branch, startPoint) {
9553
9588
  const argv = startPoint ? ["checkout", "-b", branch, startPoint] : ["checkout", "-b", branch];
9554
- execFileSync4("git", argv, {
9589
+ execFileSync5("git", argv, {
9555
9590
  cwd,
9556
9591
  stdio: ["ignore", "pipe", "pipe"],
9557
9592
  timeout: KIT_TIMEOUTS.gitCheckout
@@ -9559,7 +9594,7 @@ function gitCheckoutNewBranch(cwd, branch, startPoint) {
9559
9594
  }
9560
9595
  function gitFetchBranch(cwd, remote, branch) {
9561
9596
  try {
9562
- execFileSync4("git", ["fetch", remote, branch], {
9597
+ execFileSync5("git", ["fetch", remote, branch], {
9563
9598
  cwd,
9564
9599
  stdio: ["ignore", "pipe", "pipe"],
9565
9600
  timeout: KIT_TIMEOUTS.gitNetwork
@@ -9569,7 +9604,7 @@ function gitFetchBranch(cwd, remote, branch) {
9569
9604
  }
9570
9605
  function gitRefExists(cwd, ref) {
9571
9606
  try {
9572
- execFileSync4("git", ["rev-parse", "--verify", "--quiet", ref], {
9607
+ execFileSync5("git", ["rev-parse", "--verify", "--quiet", ref], {
9573
9608
  cwd,
9574
9609
  stdio: ["ignore", "pipe", "pipe"],
9575
9610
  timeout: KIT_TIMEOUTS.gitDefault
@@ -9581,7 +9616,7 @@ function gitRefExists(cwd, ref) {
9581
9616
  }
9582
9617
  function gitIsAncestor(cwd, ancestor, descendant) {
9583
9618
  try {
9584
- execFileSync4("git", ["merge-base", "--is-ancestor", ancestor, descendant], {
9619
+ execFileSync5("git", ["merge-base", "--is-ancestor", ancestor, descendant], {
9585
9620
  cwd,
9586
9621
  stdio: ["ignore", "pipe", "pipe"],
9587
9622
  timeout: KIT_TIMEOUTS.gitDefault
@@ -9614,14 +9649,14 @@ async function assertCleanForFork(cwd, startPoint) {
9614
9649
  }
9615
9650
  function gitCheckoutExistingBranch(cwd, branch, force = false) {
9616
9651
  const argv = force ? ["checkout", "-f", branch] : ["checkout", branch];
9617
- execFileSync4("git", argv, {
9652
+ execFileSync5("git", argv, {
9618
9653
  cwd,
9619
9654
  stdio: ["ignore", "pipe", "pipe"],
9620
9655
  timeout: KIT_TIMEOUTS.gitCheckout
9621
9656
  });
9622
9657
  }
9623
9658
  function gitDeleteLocalBranch(cwd, branch, force = true) {
9624
- execFileSync4("git", ["branch", force ? "-D" : "-d", branch], {
9659
+ execFileSync5("git", ["branch", force ? "-D" : "-d", branch], {
9625
9660
  cwd,
9626
9661
  stdio: ["ignore", "pipe", "pipe"],
9627
9662
  timeout: KIT_TIMEOUTS.gitDefault
@@ -9629,7 +9664,7 @@ function gitDeleteLocalBranch(cwd, branch, force = true) {
9629
9664
  }
9630
9665
  function gitHasRemoteBranch(cwd, remote, branch) {
9631
9666
  try {
9632
- const out = execFileSync4(
9667
+ const out = execFileSync5(
9633
9668
  "git",
9634
9669
  ["ls-remote", "--exit-code", "--heads", remote, branch],
9635
9670
  { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], timeout: KIT_TIMEOUTS.gitNetwork }
@@ -9640,7 +9675,7 @@ function gitHasRemoteBranch(cwd, remote, branch) {
9640
9675
  }
9641
9676
  }
9642
9677
  function gitDeleteRemoteBranch(cwd, remote, branch) {
9643
- execFileSync4("git", ["push", remote, "--delete", branch], {
9678
+ execFileSync5("git", ["push", remote, "--delete", branch], {
9644
9679
  cwd,
9645
9680
  stdio: ["ignore", "pipe", "pipe"],
9646
9681
  timeout: KIT_TIMEOUTS.gitPush
@@ -11207,14 +11242,6 @@ function readEnv(projectDir) {
11207
11242
  function leafOf2(b) {
11208
11243
  return b.name.split("/").pop() ?? b.name;
11209
11244
  }
11210
- function isGitTracked(projectDir, rel) {
11211
- try {
11212
- execFileSync5("git", ["ls-files", "--error-unmatch", "--", rel], { cwd: projectDir, stdio: "ignore" });
11213
- return true;
11214
- } catch {
11215
- return false;
11216
- }
11217
- }
11218
11245
  function worstOf(a, b) {
11219
11246
  const order = ["ok", "warn", "fail"];
11220
11247
  return order[Math.max(order.indexOf(a), order.indexOf(b))];
@@ -77726,6 +77726,7 @@ var CONVENTION_TIER_DEFAULTS = {
77726
77726
  init_cjs_shims();
77727
77727
  var fs6 = __toESM(require("fs"), 1);
77728
77728
  var path4 = __toESM(require("path"), 1);
77729
+ var import_node_child_process4 = require("child_process");
77729
77730
  var SCM_STATES = [
77730
77731
  "scaffold-complete",
77731
77732
  "feature-claimed",
@@ -120,6 +120,7 @@ var CONVENTION_TIER_DEFAULTS = {
120
120
  // scripts/lakebase/scm-workflow-state.ts
121
121
  import * as fs5 from "fs";
122
122
  import * as path4 from "path";
123
+ import { execFileSync as execFileSync4 } from "child_process";
123
124
  var SCM_STATES = [
124
125
  "scaffold-complete",
125
126
  "feature-claimed",