@databricks-solutions/lakebase-scm-utils 0.3.5 → 0.3.7

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 (49) hide show
  1. package/dist/scripts/index.cjs +55 -25
  2. package/dist/scripts/index.d.cts +1 -1
  3. package/dist/scripts/index.d.ts +1 -1
  4. package/dist/scripts/index.js +54 -25
  5. package/dist/scripts/lakebase/ci-resolve-branch.cli.cjs +2 -2
  6. package/dist/scripts/lakebase/ci-resolve-branch.cli.js +2 -2
  7. package/dist/scripts/lakebase/collapse-heads.cli.cjs +2 -2
  8. package/dist/scripts/lakebase/collapse-heads.cli.js +2 -2
  9. package/dist/scripts/lakebase/detect-language.cli.cjs +2 -2
  10. package/dist/scripts/lakebase/detect-language.cli.js +2 -2
  11. package/dist/scripts/lakebase/doctor.cli.cjs +2 -2
  12. package/dist/scripts/lakebase/doctor.cli.js +2 -2
  13. package/dist/scripts/lakebase/get-connection.cli.cjs +2 -2
  14. package/dist/scripts/lakebase/get-connection.cli.js +2 -2
  15. package/dist/scripts/lakebase/index.cjs +55 -25
  16. package/dist/scripts/lakebase/index.d.cts +13 -4
  17. package/dist/scripts/lakebase/index.d.ts +13 -4
  18. package/dist/scripts/lakebase/index.js +54 -25
  19. package/dist/scripts/lakebase/infra-runner.cli.cjs +2 -2
  20. package/dist/scripts/lakebase/infra-runner.cli.js +2 -2
  21. package/dist/scripts/lakebase/new-migration.cli.cjs +2 -2
  22. package/dist/scripts/lakebase/new-migration.cli.js +2 -2
  23. package/dist/scripts/lakebase/schema-diff.cli.cjs +2 -2
  24. package/dist/scripts/lakebase/schema-diff.cli.js +2 -2
  25. package/dist/scripts/lakebase/schema-migrate.cli.cjs +2 -2
  26. package/dist/scripts/lakebase/schema-migrate.cli.js +2 -2
  27. package/dist/scripts/lakebase/scm-abandon-feature.cli.cjs +37 -22
  28. package/dist/scripts/lakebase/scm-abandon-feature.cli.js +34 -22
  29. package/dist/scripts/lakebase/scm-claim-feature.cli.cjs +2 -2
  30. package/dist/scripts/lakebase/scm-claim-feature.cli.js +2 -2
  31. package/dist/scripts/lakebase/scm-doctor.cli.cjs +36 -21
  32. package/dist/scripts/lakebase/scm-doctor.cli.js +36 -21
  33. package/dist/scripts/lakebase/scm-merge.cli.cjs +2 -2
  34. package/dist/scripts/lakebase/scm-merge.cli.js +2 -2
  35. package/dist/scripts/lakebase/scm-park-feature.cli.cjs +586 -0
  36. package/dist/scripts/lakebase/scm-park-feature.cli.d.cts +4 -0
  37. package/dist/scripts/lakebase/scm-park-feature.cli.d.ts +4 -0
  38. package/dist/scripts/lakebase/scm-park-feature.cli.js +546 -0
  39. package/dist/scripts/lakebase/scm-reconcile-tier.cli.cjs +2 -2
  40. package/dist/scripts/lakebase/scm-reconcile-tier.cli.js +2 -2
  41. package/dist/scripts/util/index.cjs +2 -2
  42. package/dist/scripts/util/index.js +2 -2
  43. package/package.json +2 -1
  44. package/scripts/lakebase/enable-e2e.ts +34 -4
  45. package/scripts/lakebase/scm-abandon-feature.cli.ts +3 -3
  46. package/scripts/lakebase/scm-abandon-feature.ts +19 -83
  47. package/scripts/lakebase/scm-park-feature.cli.ts +150 -0
  48. package/scripts/lakebase/scm-park-feature.ts +71 -0
  49. package/scripts/lakebase/scm-release-claim.ts +146 -0
@@ -78155,6 +78155,9 @@ async function deletePairedBranch(args) {
78155
78155
  return { lakebaseDeleted, gitLocalDeleted, gitRemoteDeleted, warnings };
78156
78156
  }
78157
78157
 
78158
+ // scripts/lakebase/scm-release-claim.ts
78159
+ init_cjs_shims();
78160
+
78158
78161
  // scripts/lakebase/scm-workflow-state.ts
78159
78162
  init_cjs_shims();
78160
78163
  var fs6 = __toESM(require("fs"), 1);
@@ -78410,45 +78413,44 @@ function orderForOutput(state) {
78410
78413
  return out;
78411
78414
  }
78412
78415
 
78413
- // scripts/lakebase/scm-abandon-feature.ts
78414
- var ScmAbandonError = class extends Error {
78416
+ // scripts/lakebase/scm-release-claim.ts
78417
+ var ScmReleaseError = class extends Error {
78415
78418
  constructor(message, code) {
78416
78419
  super(message);
78417
78420
  this.code = code;
78418
- this.name = "ScmAbandonError";
78421
+ this.name = "ScmReleaseError";
78419
78422
  }
78420
78423
  code;
78421
78424
  };
78422
- async function abandonFeatureBranch(args) {
78425
+ async function prepareClaimRelease(args, verb) {
78423
78426
  const current = readWorkflowState(args.projectDir);
78424
78427
  if (!current) {
78425
- throw new ScmAbandonError(
78428
+ throw new ScmReleaseError(
78426
78429
  `No SCM workflow state found at ${args.projectDir}/.lakebase/workflow-state.json.`,
78427
78430
  "no-state-file"
78428
78431
  );
78429
78432
  }
78430
78433
  if (current.state !== "feature-claimed") {
78431
- throw new ScmAbandonError(
78432
- `abandon refuses state "${current.state}". Only feature-claimed is abandonable; later states must complete or be reverted via gh.`,
78434
+ throw new ScmReleaseError(
78435
+ `${verb} refuses state "${current.state}". Only feature-claimed is ${verb}able; later states must complete or be reverted via gh.`,
78433
78436
  "bad-precondition"
78434
78437
  );
78435
78438
  }
78436
78439
  if (!current.feature_id || !current.branch || !current.parent_branch || !current.lakebase_branch_uid) {
78437
- throw new ScmAbandonError(
78438
- "feature-claimed row is missing required invariants. Cannot abandon safely; consider re-adopting state first.",
78440
+ throw new ScmReleaseError(
78441
+ `feature-claimed row is missing required invariants. Cannot ${verb} safely; consider re-adopting state first.`,
78439
78442
  "missing-claim-fields"
78440
78443
  );
78441
78444
  }
78442
78445
  if (!args.force) {
78443
78446
  const dirty = await isDirty({ cwd: args.projectDir });
78444
78447
  if (dirty) {
78445
- throw new ScmAbandonError(
78446
- "Working tree has uncommitted changes; refusing to abandon (the branch delete would lose them). Commit / stash / discard first, or pass --force.",
78448
+ throw new ScmReleaseError(
78449
+ `Working tree has uncommitted changes; refusing to ${verb} (switching HEAD off the feature branch would strand them). Commit / stash / discard first, or pass --force.`,
78447
78450
  "dirty-working-tree"
78448
78451
  );
78449
78452
  }
78450
78453
  }
78451
- const instance = args.instance ?? current.project_id;
78452
78454
  const switchTo = args.switchTo ?? current.parent_branch;
78453
78455
  const warnings = [];
78454
78456
  const headBranch = await getCurrentBranch({ cwd: args.projectDir });
@@ -78460,16 +78462,13 @@ async function abandonFeatureBranch(args) {
78460
78462
  });
78461
78463
  } catch (err) {
78462
78464
  warnings.push(
78463
- `git checkout ${switchTo} failed: ${err instanceof Error ? err.message : String(err)}. Local branch delete may be skipped.`
78465
+ `git checkout ${switchTo} failed: ${err instanceof Error ? err.message : String(err)}. Local branch state may be left on the feature branch.`
78464
78466
  );
78465
78467
  }
78466
78468
  }
78467
- const del = await deletePairedBranch({
78468
- instance,
78469
- branch: current.branch,
78470
- cwd: args.projectDir
78471
- });
78472
- warnings.push(...del.warnings);
78469
+ return { current, switchTo, warnings };
78470
+ }
78471
+ function resetToScaffoldComplete(projectDir, current) {
78473
78472
  const reset = {
78474
78473
  $schema: current.$schema,
78475
78474
  version: 1,
@@ -78477,7 +78476,23 @@ async function abandonFeatureBranch(args) {
78477
78476
  tier_topology: current.tier_topology,
78478
78477
  project_id: current.project_id
78479
78478
  };
78480
- writeWorkflowState(args.projectDir, reset);
78479
+ writeWorkflowState(projectDir, reset);
78480
+ return reset;
78481
+ }
78482
+
78483
+ // scripts/lakebase/scm-abandon-feature.ts
78484
+ async function abandonFeatureBranch(args) {
78485
+ const { current, warnings } = await prepareClaimRelease(
78486
+ { projectDir: args.projectDir, force: args.force, switchTo: args.switchTo },
78487
+ "abandon"
78488
+ );
78489
+ const del = await deletePairedBranch({
78490
+ instance: args.instance ?? current.project_id,
78491
+ branch: current.branch,
78492
+ cwd: args.projectDir
78493
+ });
78494
+ warnings.push(...del.warnings);
78495
+ const reset = resetToScaffoldComplete(args.projectDir, current);
78481
78496
  return {
78482
78497
  state: reset,
78483
78498
  lakebaseDeleted: del.lakebaseDeleted,
@@ -78564,7 +78579,7 @@ function renderHuman(report) {
78564
78579
  return lines.join("\n");
78565
78580
  }
78566
78581
  function exitCodeForError(err) {
78567
- if (err instanceof ScmAbandonError) {
78582
+ if (err instanceof ScmReleaseError) {
78568
78583
  if (err.code === "no-state-file") return 1;
78569
78584
  return 2;
78570
78585
  }
@@ -78597,7 +78612,7 @@ async function runScmAbandonFeatureCli(argv) {
78597
78612
  return 0;
78598
78613
  } catch (e2) {
78599
78614
  const err = e2;
78600
- const code = err instanceof ScmAbandonError ? err.code : "substrate-failure";
78615
+ const code = err instanceof ScmReleaseError ? err.code : "substrate-failure";
78601
78616
  const report = {
78602
78617
  ok: false,
78603
78618
  error: { code, message: err.message }
@@ -815,45 +815,44 @@ function orderForOutput(state) {
815
815
  return out;
816
816
  }
817
817
 
818
- // scripts/lakebase/scm-abandon-feature.ts
819
- var ScmAbandonError = class extends Error {
818
+ // scripts/lakebase/scm-release-claim.ts
819
+ var ScmReleaseError = class extends Error {
820
820
  constructor(message, code) {
821
821
  super(message);
822
822
  this.code = code;
823
- this.name = "ScmAbandonError";
823
+ this.name = "ScmReleaseError";
824
824
  }
825
825
  code;
826
826
  };
827
- async function abandonFeatureBranch(args) {
827
+ async function prepareClaimRelease(args, verb) {
828
828
  const current = readWorkflowState(args.projectDir);
829
829
  if (!current) {
830
- throw new ScmAbandonError(
830
+ throw new ScmReleaseError(
831
831
  `No SCM workflow state found at ${args.projectDir}/.lakebase/workflow-state.json.`,
832
832
  "no-state-file"
833
833
  );
834
834
  }
835
835
  if (current.state !== "feature-claimed") {
836
- throw new ScmAbandonError(
837
- `abandon refuses state "${current.state}". Only feature-claimed is abandonable; later states must complete or be reverted via gh.`,
836
+ throw new ScmReleaseError(
837
+ `${verb} refuses state "${current.state}". Only feature-claimed is ${verb}able; later states must complete or be reverted via gh.`,
838
838
  "bad-precondition"
839
839
  );
840
840
  }
841
841
  if (!current.feature_id || !current.branch || !current.parent_branch || !current.lakebase_branch_uid) {
842
- throw new ScmAbandonError(
843
- "feature-claimed row is missing required invariants. Cannot abandon safely; consider re-adopting state first.",
842
+ throw new ScmReleaseError(
843
+ `feature-claimed row is missing required invariants. Cannot ${verb} safely; consider re-adopting state first.`,
844
844
  "missing-claim-fields"
845
845
  );
846
846
  }
847
847
  if (!args.force) {
848
848
  const dirty = await isDirty({ cwd: args.projectDir });
849
849
  if (dirty) {
850
- throw new ScmAbandonError(
851
- "Working tree has uncommitted changes; refusing to abandon (the branch delete would lose them). Commit / stash / discard first, or pass --force.",
850
+ throw new ScmReleaseError(
851
+ `Working tree has uncommitted changes; refusing to ${verb} (switching HEAD off the feature branch would strand them). Commit / stash / discard first, or pass --force.`,
852
852
  "dirty-working-tree"
853
853
  );
854
854
  }
855
855
  }
856
- const instance = args.instance ?? current.project_id;
857
856
  const switchTo = args.switchTo ?? current.parent_branch;
858
857
  const warnings = [];
859
858
  const headBranch = await getCurrentBranch({ cwd: args.projectDir });
@@ -865,16 +864,13 @@ async function abandonFeatureBranch(args) {
865
864
  });
866
865
  } catch (err) {
867
866
  warnings.push(
868
- `git checkout ${switchTo} failed: ${err instanceof Error ? err.message : String(err)}. Local branch delete may be skipped.`
867
+ `git checkout ${switchTo} failed: ${err instanceof Error ? err.message : String(err)}. Local branch state may be left on the feature branch.`
869
868
  );
870
869
  }
871
870
  }
872
- const del = await deletePairedBranch({
873
- instance,
874
- branch: current.branch,
875
- cwd: args.projectDir
876
- });
877
- warnings.push(...del.warnings);
871
+ return { current, switchTo, warnings };
872
+ }
873
+ function resetToScaffoldComplete(projectDir, current) {
878
874
  const reset = {
879
875
  $schema: current.$schema,
880
876
  version: 1,
@@ -882,7 +878,23 @@ async function abandonFeatureBranch(args) {
882
878
  tier_topology: current.tier_topology,
883
879
  project_id: current.project_id
884
880
  };
885
- writeWorkflowState(args.projectDir, reset);
881
+ writeWorkflowState(projectDir, reset);
882
+ return reset;
883
+ }
884
+
885
+ // scripts/lakebase/scm-abandon-feature.ts
886
+ async function abandonFeatureBranch(args) {
887
+ const { current, warnings } = await prepareClaimRelease(
888
+ { projectDir: args.projectDir, force: args.force, switchTo: args.switchTo },
889
+ "abandon"
890
+ );
891
+ const del = await deletePairedBranch({
892
+ instance: args.instance ?? current.project_id,
893
+ branch: current.branch,
894
+ cwd: args.projectDir
895
+ });
896
+ warnings.push(...del.warnings);
897
+ const reset = resetToScaffoldComplete(args.projectDir, current);
886
898
  return {
887
899
  state: reset,
888
900
  lakebaseDeleted: del.lakebaseDeleted,
@@ -969,7 +981,7 @@ function renderHuman(report) {
969
981
  return lines.join("\n");
970
982
  }
971
983
  function exitCodeForError(err) {
972
- if (err instanceof ScmAbandonError) {
984
+ if (err instanceof ScmReleaseError) {
973
985
  if (err.code === "no-state-file") return 1;
974
986
  return 2;
975
987
  }
@@ -1002,7 +1014,7 @@ async function runScmAbandonFeatureCli(argv) {
1002
1014
  return 0;
1003
1015
  } catch (e) {
1004
1016
  const err = e;
1005
- const code = err instanceof ScmAbandonError ? err.code : "substrate-failure";
1017
+ const code = err instanceof ScmReleaseError ? err.code : "substrate-failure";
1006
1018
  const report = {
1007
1019
  ok: false,
1008
1020
  error: { code, message: err.message }
@@ -79783,8 +79783,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
79783
79783
  var cached;
79784
79784
  function substrateSelfVersion() {
79785
79785
  if (cached !== void 0) return cached;
79786
- if ("0.3.5".length > 0) {
79787
- cached = "0.3.5";
79786
+ if ("0.3.7".length > 0) {
79787
+ cached = "0.3.7";
79788
79788
  return cached;
79789
79789
  }
79790
79790
  cached = "unknown";
@@ -864,8 +864,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
864
864
  var cached;
865
865
  function substrateSelfVersion() {
866
866
  if (cached !== void 0) return cached;
867
- if ("0.3.5".length > 0) {
868
- cached = "0.3.5";
867
+ if ("0.3.7".length > 0) {
868
+ cached = "0.3.7";
869
869
  return cached;
870
870
  }
871
871
  cached = "unknown";
@@ -88240,8 +88240,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
88240
88240
  var cached;
88241
88241
  function substrateSelfVersion() {
88242
88242
  if (cached !== void 0) return cached;
88243
- if ("0.3.5".length > 0) {
88244
- cached = "0.3.5";
88243
+ if ("0.3.7".length > 0) {
88244
+ cached = "0.3.7";
88245
88245
  return cached;
88246
88246
  }
88247
88247
  cached = "unknown";
@@ -88892,44 +88892,46 @@ function parentForTopology(t2, defaultLeaf) {
88892
88892
 
88893
88893
  // scripts/lakebase/scm-abandon-feature.ts
88894
88894
  init_cjs_shims();
88895
- var ScmAbandonError = class extends Error {
88895
+
88896
+ // scripts/lakebase/scm-release-claim.ts
88897
+ init_cjs_shims();
88898
+ var ScmReleaseError = class extends Error {
88896
88899
  constructor(message, code) {
88897
88900
  super(message);
88898
88901
  this.code = code;
88899
- this.name = "ScmAbandonError";
88902
+ this.name = "ScmReleaseError";
88900
88903
  }
88901
88904
  code;
88902
88905
  };
88903
- async function abandonFeatureBranch(args) {
88906
+ async function prepareClaimRelease(args, verb) {
88904
88907
  const current = readWorkflowState(args.projectDir);
88905
88908
  if (!current) {
88906
- throw new ScmAbandonError(
88909
+ throw new ScmReleaseError(
88907
88910
  `No SCM workflow state found at ${args.projectDir}/.lakebase/workflow-state.json.`,
88908
88911
  "no-state-file"
88909
88912
  );
88910
88913
  }
88911
88914
  if (current.state !== "feature-claimed") {
88912
- throw new ScmAbandonError(
88913
- `abandon refuses state "${current.state}". Only feature-claimed is abandonable; later states must complete or be reverted via gh.`,
88915
+ throw new ScmReleaseError(
88916
+ `${verb} refuses state "${current.state}". Only feature-claimed is ${verb}able; later states must complete or be reverted via gh.`,
88914
88917
  "bad-precondition"
88915
88918
  );
88916
88919
  }
88917
88920
  if (!current.feature_id || !current.branch || !current.parent_branch || !current.lakebase_branch_uid) {
88918
- throw new ScmAbandonError(
88919
- "feature-claimed row is missing required invariants. Cannot abandon safely; consider re-adopting state first.",
88921
+ throw new ScmReleaseError(
88922
+ `feature-claimed row is missing required invariants. Cannot ${verb} safely; consider re-adopting state first.`,
88920
88923
  "missing-claim-fields"
88921
88924
  );
88922
88925
  }
88923
88926
  if (!args.force) {
88924
88927
  const dirty = await isDirty({ cwd: args.projectDir });
88925
88928
  if (dirty) {
88926
- throw new ScmAbandonError(
88927
- "Working tree has uncommitted changes; refusing to abandon (the branch delete would lose them). Commit / stash / discard first, or pass --force.",
88929
+ throw new ScmReleaseError(
88930
+ `Working tree has uncommitted changes; refusing to ${verb} (switching HEAD off the feature branch would strand them). Commit / stash / discard first, or pass --force.`,
88928
88931
  "dirty-working-tree"
88929
88932
  );
88930
88933
  }
88931
88934
  }
88932
- const instance = args.instance ?? current.project_id;
88933
88935
  const switchTo = args.switchTo ?? current.parent_branch;
88934
88936
  const warnings = [];
88935
88937
  const headBranch = await getCurrentBranch({ cwd: args.projectDir });
@@ -88941,16 +88943,13 @@ async function abandonFeatureBranch(args) {
88941
88943
  });
88942
88944
  } catch (err) {
88943
88945
  warnings.push(
88944
- `git checkout ${switchTo} failed: ${err instanceof Error ? err.message : String(err)}. Local branch delete may be skipped.`
88946
+ `git checkout ${switchTo} failed: ${err instanceof Error ? err.message : String(err)}. Local branch state may be left on the feature branch.`
88945
88947
  );
88946
88948
  }
88947
88949
  }
88948
- const del = await deletePairedBranch({
88949
- instance,
88950
- branch: current.branch,
88951
- cwd: args.projectDir
88952
- });
88953
- warnings.push(...del.warnings);
88950
+ return { current, switchTo, warnings };
88951
+ }
88952
+ function resetToScaffoldComplete(projectDir, current) {
88954
88953
  const reset = {
88955
88954
  $schema: current.$schema,
88956
88955
  version: 1,
@@ -88958,7 +88957,23 @@ async function abandonFeatureBranch(args) {
88958
88957
  tier_topology: current.tier_topology,
88959
88958
  project_id: current.project_id
88960
88959
  };
88961
- writeWorkflowState(args.projectDir, reset);
88960
+ writeWorkflowState(projectDir, reset);
88961
+ return reset;
88962
+ }
88963
+
88964
+ // scripts/lakebase/scm-abandon-feature.ts
88965
+ async function abandonFeatureBranch(args) {
88966
+ const { current, warnings } = await prepareClaimRelease(
88967
+ { projectDir: args.projectDir, force: args.force, switchTo: args.switchTo },
88968
+ "abandon"
88969
+ );
88970
+ const del = await deletePairedBranch({
88971
+ instance: args.instance ?? current.project_id,
88972
+ branch: current.branch,
88973
+ cwd: args.projectDir
88974
+ });
88975
+ warnings.push(...del.warnings);
88976
+ const reset = resetToScaffoldComplete(args.projectDir, current);
88962
88977
  return {
88963
88978
  state: reset,
88964
88979
  lakebaseDeleted: del.lakebaseDeleted,
@@ -9393,8 +9393,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
9393
9393
  var cached;
9394
9394
  function substrateSelfVersion() {
9395
9395
  if (cached !== void 0) return cached;
9396
- if ("0.3.5".length > 0) {
9397
- cached = "0.3.5";
9396
+ if ("0.3.7".length > 0) {
9397
+ cached = "0.3.7";
9398
9398
  return cached;
9399
9399
  }
9400
9400
  cached = "unknown";
@@ -10045,44 +10045,46 @@ function parentForTopology(t, defaultLeaf) {
10045
10045
 
10046
10046
  // scripts/lakebase/scm-abandon-feature.ts
10047
10047
  init_esm_shims();
10048
- var ScmAbandonError = class extends Error {
10048
+
10049
+ // scripts/lakebase/scm-release-claim.ts
10050
+ init_esm_shims();
10051
+ var ScmReleaseError = class extends Error {
10049
10052
  constructor(message, code) {
10050
10053
  super(message);
10051
10054
  this.code = code;
10052
- this.name = "ScmAbandonError";
10055
+ this.name = "ScmReleaseError";
10053
10056
  }
10054
10057
  code;
10055
10058
  };
10056
- async function abandonFeatureBranch(args) {
10059
+ async function prepareClaimRelease(args, verb) {
10057
10060
  const current = readWorkflowState(args.projectDir);
10058
10061
  if (!current) {
10059
- throw new ScmAbandonError(
10062
+ throw new ScmReleaseError(
10060
10063
  `No SCM workflow state found at ${args.projectDir}/.lakebase/workflow-state.json.`,
10061
10064
  "no-state-file"
10062
10065
  );
10063
10066
  }
10064
10067
  if (current.state !== "feature-claimed") {
10065
- throw new ScmAbandonError(
10066
- `abandon refuses state "${current.state}". Only feature-claimed is abandonable; later states must complete or be reverted via gh.`,
10068
+ throw new ScmReleaseError(
10069
+ `${verb} refuses state "${current.state}". Only feature-claimed is ${verb}able; later states must complete or be reverted via gh.`,
10067
10070
  "bad-precondition"
10068
10071
  );
10069
10072
  }
10070
10073
  if (!current.feature_id || !current.branch || !current.parent_branch || !current.lakebase_branch_uid) {
10071
- throw new ScmAbandonError(
10072
- "feature-claimed row is missing required invariants. Cannot abandon safely; consider re-adopting state first.",
10074
+ throw new ScmReleaseError(
10075
+ `feature-claimed row is missing required invariants. Cannot ${verb} safely; consider re-adopting state first.`,
10073
10076
  "missing-claim-fields"
10074
10077
  );
10075
10078
  }
10076
10079
  if (!args.force) {
10077
10080
  const dirty = await isDirty({ cwd: args.projectDir });
10078
10081
  if (dirty) {
10079
- throw new ScmAbandonError(
10080
- "Working tree has uncommitted changes; refusing to abandon (the branch delete would lose them). Commit / stash / discard first, or pass --force.",
10082
+ throw new ScmReleaseError(
10083
+ `Working tree has uncommitted changes; refusing to ${verb} (switching HEAD off the feature branch would strand them). Commit / stash / discard first, or pass --force.`,
10081
10084
  "dirty-working-tree"
10082
10085
  );
10083
10086
  }
10084
10087
  }
10085
- const instance = args.instance ?? current.project_id;
10086
10088
  const switchTo = args.switchTo ?? current.parent_branch;
10087
10089
  const warnings = [];
10088
10090
  const headBranch = await getCurrentBranch({ cwd: args.projectDir });
@@ -10094,16 +10096,13 @@ async function abandonFeatureBranch(args) {
10094
10096
  });
10095
10097
  } catch (err) {
10096
10098
  warnings.push(
10097
- `git checkout ${switchTo} failed: ${err instanceof Error ? err.message : String(err)}. Local branch delete may be skipped.`
10099
+ `git checkout ${switchTo} failed: ${err instanceof Error ? err.message : String(err)}. Local branch state may be left on the feature branch.`
10098
10100
  );
10099
10101
  }
10100
10102
  }
10101
- const del = await deletePairedBranch({
10102
- instance,
10103
- branch: current.branch,
10104
- cwd: args.projectDir
10105
- });
10106
- warnings.push(...del.warnings);
10103
+ return { current, switchTo, warnings };
10104
+ }
10105
+ function resetToScaffoldComplete(projectDir, current) {
10107
10106
  const reset = {
10108
10107
  $schema: current.$schema,
10109
10108
  version: 1,
@@ -10111,7 +10110,23 @@ async function abandonFeatureBranch(args) {
10111
10110
  tier_topology: current.tier_topology,
10112
10111
  project_id: current.project_id
10113
10112
  };
10114
- writeWorkflowState(args.projectDir, reset);
10113
+ writeWorkflowState(projectDir, reset);
10114
+ return reset;
10115
+ }
10116
+
10117
+ // scripts/lakebase/scm-abandon-feature.ts
10118
+ async function abandonFeatureBranch(args) {
10119
+ const { current, warnings } = await prepareClaimRelease(
10120
+ { projectDir: args.projectDir, force: args.force, switchTo: args.switchTo },
10121
+ "abandon"
10122
+ );
10123
+ const del = await deletePairedBranch({
10124
+ instance: args.instance ?? current.project_id,
10125
+ branch: current.branch,
10126
+ cwd: args.projectDir
10127
+ });
10128
+ warnings.push(...del.warnings);
10129
+ const reset = resetToScaffoldComplete(args.projectDir, current);
10115
10130
  return {
10116
10131
  state: reset,
10117
10132
  lakebaseDeleted: del.lakebaseDeleted,
@@ -88825,8 +88825,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
88825
88825
  var cached;
88826
88826
  function substrateSelfVersion() {
88827
88827
  if (cached !== void 0) return cached;
88828
- if ("0.3.5".length > 0) {
88829
- cached = "0.3.5";
88828
+ if ("0.3.7".length > 0) {
88829
+ cached = "0.3.7";
88830
88830
  return cached;
88831
88831
  }
88832
88832
  cached = "unknown";
@@ -9978,8 +9978,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
9978
9978
  var cached;
9979
9979
  function substrateSelfVersion() {
9980
9980
  if (cached !== void 0) return cached;
9981
- if ("0.3.5".length > 0) {
9982
- cached = "0.3.5";
9981
+ if ("0.3.7".length > 0) {
9982
+ cached = "0.3.7";
9983
9983
  return cached;
9984
9984
  }
9985
9985
  cached = "unknown";