@databricks-solutions/lakebase-scm-utils 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +10 -4
  2. package/dist/scripts/index.cjs +2336 -2262
  3. package/dist/scripts/index.js +395 -321
  4. package/dist/scripts/lakebase/ci-resolve-branch.cli.cjs +26 -9
  5. package/dist/scripts/lakebase/ci-resolve-branch.cli.js +27 -10
  6. package/dist/scripts/lakebase/collapse-heads.cli.cjs +26 -9
  7. package/dist/scripts/lakebase/collapse-heads.cli.js +27 -10
  8. package/dist/scripts/lakebase/detect-language.cli.cjs +26 -9
  9. package/dist/scripts/lakebase/detect-language.cli.js +27 -10
  10. package/dist/scripts/lakebase/doctor.cli.cjs +26 -9
  11. package/dist/scripts/lakebase/doctor.cli.js +27 -10
  12. package/dist/scripts/lakebase/get-connection.cli.cjs +2 -2
  13. package/dist/scripts/lakebase/get-connection.cli.js +2 -2
  14. package/dist/scripts/lakebase/index.cjs +2333 -2223
  15. package/dist/scripts/lakebase/index.js +389 -279
  16. package/dist/scripts/lakebase/infra-runner.cli.cjs +26 -9
  17. package/dist/scripts/lakebase/infra-runner.cli.js +27 -10
  18. package/dist/scripts/lakebase/new-migration.cli.cjs +26 -9
  19. package/dist/scripts/lakebase/new-migration.cli.js +27 -10
  20. package/dist/scripts/lakebase/schema-diff.cli.cjs +2 -2
  21. package/dist/scripts/lakebase/schema-diff.cli.js +2 -2
  22. package/dist/scripts/lakebase/schema-migrate.cli.cjs +26 -9
  23. package/dist/scripts/lakebase/schema-migrate.cli.js +27 -10
  24. package/dist/scripts/lakebase/scm-claim-feature.cli.cjs +26 -9
  25. package/dist/scripts/lakebase/scm-claim-feature.cli.js +27 -10
  26. package/dist/scripts/lakebase/scm-doctor.cli.cjs +26 -9
  27. package/dist/scripts/lakebase/scm-doctor.cli.js +27 -10
  28. package/dist/scripts/lakebase/scm-merge.cli.cjs +26 -9
  29. package/dist/scripts/lakebase/scm-merge.cli.js +27 -10
  30. package/dist/scripts/lakebase/scm-reconcile-tier.cli.cjs +26 -9
  31. package/dist/scripts/lakebase/scm-reconcile-tier.cli.js +28 -11
  32. package/dist/scripts/util/index.cjs +2 -2
  33. package/dist/scripts/util/index.js +2 -2
  34. package/package.json +1 -1
  35. package/scripts/lakebase/client-lockfile.ts +102 -0
  36. package/scripts/lakebase/create-project.ts +19 -0
  37. package/scripts/lakebase/schema-migrate-runners/alembic.ts +58 -14
  38. package/templates/project/client/playwright.config.ts +35 -10
@@ -2581,7 +2581,7 @@ paginateRest.VERSION = VERSION5;
2581
2581
 
2582
2582
  // node_modules/@octokit/plugin-paginate-graphql/dist-bundle/index.js
2583
2583
  init_esm_shims();
2584
- var generateMessage = (path37, cursorValue) => `The cursor at "${path37.join(
2584
+ var generateMessage = (path38, cursorValue) => `The cursor at "${path38.join(
2585
2585
  ","
2586
2586
  )}" did not change its value "${cursorValue}" after a page transition. Please make sure your that your query is set up correctly.`;
2587
2587
  var MissingCursorChange = class extends Error {
@@ -2622,9 +2622,9 @@ function findPaginatedResourcePath(responseData) {
2622
2622
  }
2623
2623
  return paginatedResourcePath;
2624
2624
  }
2625
- var deepFindPathToProperty = (object, searchProp, path37 = []) => {
2625
+ var deepFindPathToProperty = (object, searchProp, path38 = []) => {
2626
2626
  for (const key of Object.keys(object)) {
2627
- const currentPath = [...path37, key];
2627
+ const currentPath = [...path38, key];
2628
2628
  const currentValue = object[key];
2629
2629
  if (isObject(currentValue)) {
2630
2630
  if (currentValue.hasOwnProperty(searchProp)) {
@@ -2642,12 +2642,12 @@ var deepFindPathToProperty = (object, searchProp, path37 = []) => {
2642
2642
  }
2643
2643
  return [];
2644
2644
  };
2645
- var get = (object, path37) => {
2646
- return path37.reduce((current, nextProperty) => current[nextProperty], object);
2645
+ var get = (object, path38) => {
2646
+ return path38.reduce((current, nextProperty) => current[nextProperty], object);
2647
2647
  };
2648
- var set = (object, path37, mutator) => {
2649
- const lastProperty = path37[path37.length - 1];
2650
- const parentPath = [...path37].slice(0, -1);
2648
+ var set = (object, path38, mutator) => {
2649
+ const lastProperty = path38[path38.length - 1];
2650
+ const parentPath = [...path38].slice(0, -1);
2651
2651
  const parent = get(object, parentPath);
2652
2652
  if (typeof mutator === "function") {
2653
2653
  parent[lastProperty] = mutator(parent[lastProperty]);
@@ -2699,22 +2699,22 @@ var mergeResponses = (response1, response2) => {
2699
2699
  if (Object.keys(response1).length === 0) {
2700
2700
  return Object.assign(response1, response2);
2701
2701
  }
2702
- const path37 = findPaginatedResourcePath(response1);
2703
- const nodesPath = [...path37, "nodes"];
2702
+ const path38 = findPaginatedResourcePath(response1);
2703
+ const nodesPath = [...path38, "nodes"];
2704
2704
  const newNodes = get(response2, nodesPath);
2705
2705
  if (newNodes) {
2706
2706
  set(response1, nodesPath, (values) => {
2707
2707
  return [...values, ...newNodes];
2708
2708
  });
2709
2709
  }
2710
- const edgesPath = [...path37, "edges"];
2710
+ const edgesPath = [...path38, "edges"];
2711
2711
  const newEdges = get(response2, edgesPath);
2712
2712
  if (newEdges) {
2713
2713
  set(response1, edgesPath, (values) => {
2714
2714
  return [...values, ...newEdges];
2715
2715
  });
2716
2716
  }
2717
- const pageInfoPath = [...path37, "pageInfo"];
2717
+ const pageInfoPath = [...path38, "pageInfo"];
2718
2718
  set(response1, pageInfoPath, get(response2, pageInfoPath));
2719
2719
  return response1;
2720
2720
  };
@@ -5135,7 +5135,7 @@ var triggers_notification_paths_default = [
5135
5135
  ];
5136
5136
  function routeMatcher(paths) {
5137
5137
  const regexes = paths.map(
5138
- (path37) => path37.split("/").map((c) => c.startsWith("{") ? "(?:.+?)" : c).join("/")
5138
+ (path38) => path38.split("/").map((c) => c.startsWith("{") ? "(?:.+?)" : c).join("/")
5139
5139
  );
5140
5140
  const regex2 = `^(?:${regexes.map((r) => `(?:${r})`).join("|")})[^/]*$`;
5141
5141
  return new RegExp(regex2, "i");
@@ -8715,9 +8715,9 @@ function asBranchUid(s) {
8715
8715
  }
8716
8716
  return s;
8717
8717
  }
8718
- function branchNameFromResourcePath(path37) {
8719
- if (!path37.includes("/branches/")) return null;
8720
- const leaf = path37.split("/branches/").pop();
8718
+ function branchNameFromResourcePath(path38) {
8719
+ if (!path38.includes("/branches/")) return null;
8720
+ const leaf = path38.split("/branches/").pop();
8721
8721
  if (!leaf) return null;
8722
8722
  try {
8723
8723
  return asBranchName(leaf);
@@ -9725,8 +9725,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
9725
9725
  var cached;
9726
9726
  function substrateSelfVersion() {
9727
9727
  if (cached !== void 0) return cached;
9728
- if ("0.3.0".length > 0) {
9729
- cached = "0.3.0";
9728
+ if ("0.3.2".length > 0) {
9729
+ cached = "0.3.2";
9730
9730
  return cached;
9731
9731
  }
9732
9732
  cached = "unknown";
@@ -11314,16 +11314,16 @@ function isAllSchemas(schema) {
11314
11314
  }
11315
11315
  function buildSchemaQuery(schema) {
11316
11316
  const cols = "c.table_schema, c.table_name, c.column_name, c.data_type";
11317
- const join37 = "FROM information_schema.columns c JOIN pg_tables t ON c.table_name = t.tablename AND c.table_schema = t.schemaname ";
11317
+ const join38 = "FROM information_schema.columns c JOIN pg_tables t ON c.table_name = t.tablename AND c.table_schema = t.schemaname ";
11318
11318
  if (isAllSchemas(schema)) {
11319
11319
  return {
11320
- text: `SELECT ${cols} ` + join37 + `WHERE ${SYSTEM_SCHEMA_FILTER} ORDER BY c.table_schema, c.table_name, c.ordinal_position`,
11320
+ text: `SELECT ${cols} ` + join38 + `WHERE ${SYSTEM_SCHEMA_FILTER} ORDER BY c.table_schema, c.table_name, c.ordinal_position`,
11321
11321
  values: []
11322
11322
  };
11323
11323
  }
11324
11324
  const one = (schema ?? "").trim() || "public";
11325
11325
  return {
11326
- text: `SELECT ${cols} ` + join37 + "WHERE c.table_schema = $1 ORDER BY c.table_name, c.ordinal_position",
11326
+ text: `SELECT ${cols} ` + join38 + "WHERE c.table_schema = $1 ORDER BY c.table_name, c.ordinal_position",
11327
11327
  values: [one]
11328
11328
  };
11329
11329
  }
@@ -11483,8 +11483,8 @@ async function withLakebaseRollback(opts, fn) {
11483
11483
 
11484
11484
  // scripts/lakebase/create-project.ts
11485
11485
  init_esm_shims();
11486
- import * as fs18 from "fs";
11487
- import * as path18 from "path";
11486
+ import * as fs19 from "fs";
11487
+ import * as path19 from "path";
11488
11488
 
11489
11489
  // scripts/lakebase/project-verify.ts
11490
11490
  init_esm_shims();
@@ -12754,18 +12754,100 @@ function enableE2eForProject(args) {
12754
12754
  };
12755
12755
  }
12756
12756
 
12757
- // scripts/lakebase/enable-infra.ts
12757
+ // scripts/lakebase/client-lockfile.ts
12758
12758
  init_esm_shims();
12759
12759
  import * as fs15 from "fs";
12760
12760
  import * as path14 from "path";
12761
+
12762
+ // scripts/util/proxy-env.ts
12763
+ init_esm_shims();
12764
+ var PROXY_ENV_KEYS = [
12765
+ "HTTP_PROXY",
12766
+ "HTTPS_PROXY",
12767
+ "NO_PROXY",
12768
+ "http_proxy",
12769
+ "https_proxy",
12770
+ "no_proxy",
12771
+ "npm_config_proxy",
12772
+ "npm_config_https_proxy",
12773
+ "npm_config_no_proxy",
12774
+ "npm_config_registry"
12775
+ ];
12776
+ function proxyEnvSubset(source = process.env) {
12777
+ const out = {};
12778
+ for (const key of PROXY_ENV_KEYS) {
12779
+ const v = source[key];
12780
+ if (v !== void 0 && v !== "") {
12781
+ out[key] = v;
12782
+ }
12783
+ }
12784
+ return out;
12785
+ }
12786
+ function withProxyEnv(base = {}) {
12787
+ const out = {};
12788
+ const inherited = proxyEnvSubset();
12789
+ for (const [k, v] of Object.entries(inherited)) {
12790
+ out[k] = v;
12791
+ }
12792
+ for (const [k, v] of Object.entries(base)) {
12793
+ if (v !== void 0) out[k] = v;
12794
+ }
12795
+ return out;
12796
+ }
12797
+
12798
+ // scripts/lakebase/client-lockfile.ts
12799
+ var PROXY_HOST = "npm-proxy.cloud.databricks.com";
12800
+ var PUBLIC_HOST = "registry.npmjs.org";
12801
+ function normalizeLockfileRegistry(lockText) {
12802
+ let swaps = 0;
12803
+ const text = lockText.replace(new RegExp(PROXY_HOST.replace(/\./g, "\\."), "g"), () => {
12804
+ swaps++;
12805
+ return PUBLIC_HOST;
12806
+ });
12807
+ return { text, swaps };
12808
+ }
12809
+ async function ensureClientLockfile(args) {
12810
+ const clientDir = path14.join(args.projectDir, args.clientDir ?? "client");
12811
+ const pkg = path14.join(clientDir, "package.json");
12812
+ if (!fs15.existsSync(pkg)) {
12813
+ return { generated: false, swaps: 0, reason: "no client package.json" };
12814
+ }
12815
+ const lockPath = path14.join(clientDir, "package-lock.json");
12816
+ try {
12817
+ await exec2("npm install --package-lock-only", {
12818
+ cwd: clientDir,
12819
+ env: withProxyEnv(),
12820
+ timeout: 18e4
12821
+ });
12822
+ } catch (err) {
12823
+ const msg = err instanceof Error ? err.message : String(err);
12824
+ return { generated: fs15.existsSync(lockPath), swaps: 0, reason: `npm resolve failed: ${msg}` };
12825
+ }
12826
+ if (!fs15.existsSync(lockPath)) {
12827
+ return { generated: false, swaps: 0, reason: "npm wrote no package-lock.json" };
12828
+ }
12829
+ try {
12830
+ const { text, swaps } = normalizeLockfileRegistry(fs15.readFileSync(lockPath, "utf8"));
12831
+ if (swaps > 0) fs15.writeFileSync(lockPath, text);
12832
+ return { generated: true, swaps };
12833
+ } catch (err) {
12834
+ const msg = err instanceof Error ? err.message : String(err);
12835
+ return { generated: true, swaps: 0, reason: `lock normalize failed: ${msg}` };
12836
+ }
12837
+ }
12838
+
12839
+ // scripts/lakebase/enable-infra.ts
12840
+ init_esm_shims();
12841
+ import * as fs16 from "fs";
12842
+ import * as path15 from "path";
12761
12843
  var RUN_TESTS_INFRA_MARKER = "# Run Lakebase [Infra]-tag suite when wired";
12762
12844
  function addInfraToPackageJson(args) {
12763
- const pkgPath = path14.join(args.projectDir, "package.json");
12764
- if (!fs15.existsSync(pkgPath)) {
12845
+ const pkgPath = path15.join(args.projectDir, "package.json");
12846
+ if (!fs16.existsSync(pkgPath)) {
12765
12847
  return { patched: false, scriptAdded: false };
12766
12848
  }
12767
12849
  const scriptValue = args.scriptValue ?? "npx --yes lakebase-infra-runner";
12768
- const raw = fs15.readFileSync(pkgPath, "utf8");
12850
+ const raw = fs16.readFileSync(pkgPath, "utf8");
12769
12851
  const pkg = JSON.parse(raw);
12770
12852
  const scripts = pkg.scripts ?? {};
12771
12853
  let scriptAdded = false;
@@ -12776,16 +12858,16 @@ function addInfraToPackageJson(args) {
12776
12858
  pkg.scripts = scripts;
12777
12859
  if (scriptAdded) {
12778
12860
  const trailing = raw.endsWith("\n") ? "\n" : "";
12779
- fs15.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + trailing, "utf8");
12861
+ fs16.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + trailing, "utf8");
12780
12862
  }
12781
12863
  return { patched: true, scriptAdded };
12782
12864
  }
12783
12865
  function addInfraToRunTestsScript(args) {
12784
- const scriptPath = path14.join(args.projectDir, "scripts", "run-tests.sh");
12785
- if (!fs15.existsSync(scriptPath)) {
12866
+ const scriptPath = path15.join(args.projectDir, "scripts", "run-tests.sh");
12867
+ if (!fs16.existsSync(scriptPath)) {
12786
12868
  return { patched: false, inserted: false };
12787
12869
  }
12788
- const original = fs15.readFileSync(scriptPath, "utf8");
12870
+ const original = fs16.readFileSync(scriptPath, "utf8");
12789
12871
  if (original.includes(RUN_TESTS_INFRA_MARKER)) {
12790
12872
  return { patched: true, inserted: false };
12791
12873
  }
@@ -12801,7 +12883,7 @@ function addInfraToRunTestsScript(args) {
12801
12883
  "fi",
12802
12884
  ""
12803
12885
  ].join("\n");
12804
- fs15.writeFileSync(scriptPath, trimmed + block, "utf8");
12886
+ fs16.writeFileSync(scriptPath, trimmed + block, "utf8");
12805
12887
  return { patched: true, inserted: true };
12806
12888
  }
12807
12889
  function enableInfraForProject(args) {
@@ -12815,9 +12897,9 @@ function enableInfraForProject(args) {
12815
12897
 
12816
12898
  // scripts/lakebase/runner-setup.ts
12817
12899
  init_esm_shims();
12818
- import * as fs16 from "fs";
12900
+ import * as fs17 from "fs";
12819
12901
  import * as os from "os";
12820
- import * as path15 from "path";
12902
+ import * as path16 from "path";
12821
12903
  import * as cp4 from "child_process";
12822
12904
  import * as tar from "tar";
12823
12905
  import findJavaHome from "find-java-home";
@@ -12828,28 +12910,28 @@ var RUNNER_OS = process.platform === "darwin" ? "osx" : "linux";
12828
12910
  var RUNNER_ARCHIVE = `actions-runner-${RUNNER_OS}-${RUNNER_ARCH}-${RUNNER_VERSION}.tar.gz`;
12829
12911
  var RUNNER_URL = `https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/${RUNNER_ARCHIVE}`;
12830
12912
  function cacheDir() {
12831
- return path15.join(os.homedir(), ".cache", "github-actions-runner");
12913
+ return path16.join(os.homedir(), ".cache", "github-actions-runner");
12832
12914
  }
12833
12915
  function runnersDir() {
12834
- return path15.join(os.homedir(), ".lakebase", "runners");
12916
+ return path16.join(os.homedir(), ".lakebase", "runners");
12835
12917
  }
12836
12918
  function runnerDir(projectName) {
12837
- return path15.join(runnersDir(), projectName);
12919
+ return path16.join(runnersDir(), projectName);
12838
12920
  }
12839
12921
  function runnerName(projectName) {
12840
12922
  return `lakebase-${projectName}`;
12841
12923
  }
12842
12924
  async function ensureCachedArchive() {
12843
12925
  const dir = cacheDir();
12844
- fs16.mkdirSync(dir, { recursive: true });
12845
- const cachedPath = path15.join(dir, RUNNER_ARCHIVE);
12846
- if (fs16.existsSync(cachedPath)) return cachedPath;
12926
+ fs17.mkdirSync(dir, { recursive: true });
12927
+ const cachedPath = path16.join(dir, RUNNER_ARCHIVE);
12928
+ if (fs17.existsSync(cachedPath)) return cachedPath;
12847
12929
  const response = await fetch(RUNNER_URL);
12848
12930
  if (!response.ok) {
12849
12931
  throw new Error(`Failed to download runner: HTTP ${response.status}`);
12850
12932
  }
12851
12933
  const buffer = Buffer.from(await response.arrayBuffer());
12852
- fs16.writeFileSync(cachedPath, buffer);
12934
+ fs17.writeFileSync(cachedPath, buffer);
12853
12935
  return cachedPath;
12854
12936
  }
12855
12937
  async function resolveJavaHome() {
@@ -12859,9 +12941,9 @@ async function resolveJavaHome() {
12859
12941
  });
12860
12942
  }
12861
12943
  function isRunning(projectName) {
12862
- const pidFile = path15.join(runnerDir(projectName), ".pid");
12863
- if (!fs16.existsSync(pidFile)) return false;
12864
- const pid = parseInt(fs16.readFileSync(pidFile, "utf-8").trim(), 10);
12944
+ const pidFile = path16.join(runnerDir(projectName), ".pid");
12945
+ if (!fs17.existsSync(pidFile)) return false;
12946
+ const pid = parseInt(fs17.readFileSync(pidFile, "utf-8").trim(), 10);
12865
12947
  if (!pid) return false;
12866
12948
  try {
12867
12949
  process.kill(pid, 0);
@@ -12872,23 +12954,23 @@ function isRunning(projectName) {
12872
12954
  }
12873
12955
  function getRunnerInfo(projectName) {
12874
12956
  const dir = runnerDir(projectName);
12875
- if (!fs16.existsSync(dir)) return void 0;
12876
- const pidFile = path15.join(dir, ".pid");
12957
+ if (!fs17.existsSync(dir)) return void 0;
12958
+ const pidFile = path16.join(dir, ".pid");
12877
12959
  let pid;
12878
- if (fs16.existsSync(pidFile)) {
12879
- pid = parseInt(fs16.readFileSync(pidFile, "utf-8").trim(), 10);
12960
+ if (fs17.existsSync(pidFile)) {
12961
+ pid = parseInt(fs17.readFileSync(pidFile, "utf-8").trim(), 10);
12880
12962
  }
12881
12963
  return { name: runnerName(projectName), dir, pid, online: isRunning(projectName) };
12882
12964
  }
12883
12965
  var lastRunnerPid;
12884
12966
  function stopRunner(projectName) {
12885
12967
  const dir = runnerDir(projectName);
12886
- const pidFile = path15.join(dir, ".pid");
12968
+ const pidFile = path16.join(dir, ".pid");
12887
12969
  let pid = lastRunnerPid;
12888
- if (fs16.existsSync(pidFile)) {
12889
- pid = parseInt(fs16.readFileSync(pidFile, "utf-8").trim(), 10);
12970
+ if (fs17.existsSync(pidFile)) {
12971
+ pid = parseInt(fs17.readFileSync(pidFile, "utf-8").trim(), 10);
12890
12972
  try {
12891
- fs16.unlinkSync(pidFile);
12973
+ fs17.unlinkSync(pidFile);
12892
12974
  } catch {
12893
12975
  }
12894
12976
  }
@@ -12901,7 +12983,7 @@ function stopRunner(projectName) {
12901
12983
  } catch {
12902
12984
  }
12903
12985
  }
12904
- } else if (fs16.existsSync(dir)) {
12986
+ } else if (fs17.existsSync(dir)) {
12905
12987
  try {
12906
12988
  cp4.execSync(`pkill -9 -f "${dir.replace(/\//g, "\\/")}.*Runner" 2>/dev/null || true`, {
12907
12989
  timeout: KIT_TIMEOUTS.cmdShort
@@ -12911,16 +12993,16 @@ function stopRunner(projectName) {
12911
12993
  }
12912
12994
  lastRunnerPid = void 0;
12913
12995
  for (const stale of ["_diag/pages", "_work/_temp", "_work/_actions"]) {
12914
- const full = path15.join(dir, stale);
12915
- if (fs16.existsSync(full)) {
12996
+ const full = path16.join(dir, stale);
12997
+ if (fs17.existsSync(full)) {
12916
12998
  try {
12917
- fs16.rmSync(full, { recursive: true, force: true });
12999
+ fs17.rmSync(full, { recursive: true, force: true });
12918
13000
  } catch {
12919
13001
  }
12920
13002
  }
12921
13003
  }
12922
13004
  try {
12923
- fs16.mkdirSync(path15.join(dir, "_diag", "pages"), { recursive: true });
13005
+ fs17.mkdirSync(path16.join(dir, "_diag", "pages"), { recursive: true });
12924
13006
  } catch {
12925
13007
  }
12926
13008
  }
@@ -12936,24 +13018,24 @@ function resetRunnerConfig(dir, projectName) {
12936
13018
  ];
12937
13019
  for (const f of stateFiles) {
12938
13020
  try {
12939
- fs16.unlinkSync(path15.join(dir, f));
13021
+ fs17.unlinkSync(path16.join(dir, f));
12940
13022
  } catch {
12941
13023
  }
12942
13024
  }
12943
13025
  if (process.platform === "darwin") {
12944
- const plist = path15.join(
13026
+ const plist = path16.join(
12945
13027
  os.homedir(),
12946
13028
  "Library",
12947
13029
  "LaunchAgents",
12948
13030
  `actions.runner.${projectName}.plist`
12949
13031
  );
12950
- if (fs16.existsSync(plist)) {
13032
+ if (fs17.existsSync(plist)) {
12951
13033
  try {
12952
13034
  cp4.execFileSync("launchctl", ["unload", plist], { stdio: "ignore" });
12953
13035
  } catch {
12954
13036
  }
12955
13037
  try {
12956
- fs16.unlinkSync(plist);
13038
+ fs17.unlinkSync(plist);
12957
13039
  } catch {
12958
13040
  }
12959
13041
  }
@@ -12967,24 +13049,24 @@ async function setupRunner(args) {
12967
13049
  stopRunner(args.projectName);
12968
13050
  report("Downloading runner binary...");
12969
13051
  const archive = await ensureCachedArchive();
12970
- fs16.mkdirSync(dir, { recursive: true });
12971
- if (!fs16.existsSync(path15.join(dir, "config.sh"))) {
13052
+ fs17.mkdirSync(dir, { recursive: true });
13053
+ if (!fs17.existsSync(path16.join(dir, "config.sh"))) {
12972
13054
  report("Extracting runner...");
12973
13055
  await tar.extract({ file: archive, cwd: dir });
12974
13056
  }
12975
- const diagPages = path15.join(dir, "_diag", "pages");
12976
- if (fs16.existsSync(diagPages)) {
12977
- fs16.rmSync(diagPages, { recursive: true, force: true });
12978
- fs16.mkdirSync(diagPages, { recursive: true });
13057
+ const diagPages = path16.join(dir, "_diag", "pages");
13058
+ if (fs17.existsSync(diagPages)) {
13059
+ fs17.rmSync(diagPages, { recursive: true, force: true });
13060
+ fs17.mkdirSync(diagPages, { recursive: true });
12979
13061
  }
12980
- const runnerFile = path15.join(dir, ".runner");
12981
- let needsConfig = !fs16.existsSync(runnerFile);
13062
+ const runnerFile = path16.join(dir, ".runner");
13063
+ let needsConfig = !fs17.existsSync(runnerFile);
12982
13064
  if (needsConfig) {
12983
13065
  resetRunnerConfig(dir, args.projectName);
12984
13066
  } else {
12985
13067
  let urlMismatch = false;
12986
13068
  try {
12987
- const runnerJson = JSON.parse(fs16.readFileSync(runnerFile, "utf-8"));
13069
+ const runnerJson = JSON.parse(fs17.readFileSync(runnerFile, "utf-8"));
12988
13070
  const configuredUrl = runnerJson.gitHubUrl || runnerJson.serverUrl || runnerJson.agentUrl || "";
12989
13071
  const expectedUrl = `https://github.com/${args.fullRepoName}`;
12990
13072
  urlMismatch = !!configuredUrl && !configuredUrl.startsWith(expectedUrl);
@@ -13045,7 +13127,7 @@ async function setupRunner(args) {
13045
13127
  child.unref();
13046
13128
  lastRunnerPid = child.pid;
13047
13129
  if (child.pid) {
13048
- fs16.writeFileSync(path15.join(dir, ".pid"), String(child.pid));
13130
+ fs17.writeFileSync(path16.join(dir, ".pid"), String(child.pid));
13049
13131
  }
13050
13132
  report("Waiting for runner to come online...");
13051
13133
  let online = false;
@@ -13077,14 +13159,14 @@ async function removeRunner(args) {
13077
13159
  } catch {
13078
13160
  }
13079
13161
  try {
13080
- fs16.rmSync(dir, { recursive: true, force: true });
13162
+ fs17.rmSync(dir, { recursive: true, force: true });
13081
13163
  } catch {
13082
13164
  }
13083
13165
  }
13084
13166
 
13085
13167
  // scripts/util/ci-secrets.ts
13086
13168
  init_esm_shims();
13087
- import * as path16 from "path";
13169
+ import * as path17 from "path";
13088
13170
 
13089
13171
  // scripts/git/remote.ts
13090
13172
  init_esm_shims();
@@ -13260,7 +13342,7 @@ async function ensureCiSecretsFresh(args) {
13260
13342
  return { action: "ok", reason: "CI token is current." };
13261
13343
  }
13262
13344
  async function ensureCiSecretsFreshFromEnv(projectDir, opts) {
13263
- const envPath = path16.join(projectDir, ".env");
13345
+ const envPath = path17.join(projectDir, ".env");
13264
13346
  const databricksHost = readEnvVar(envPath, "DATABRICKS_HOST");
13265
13347
  const lakebaseProjectId = readEnvVar(envPath, "LAKEBASE_PROJECT_ID");
13266
13348
  if (!databricksHost || !lakebaseProjectId) {
@@ -13287,8 +13369,8 @@ async function ensureCiSecretsFreshFromEnv(projectDir, opts) {
13287
13369
 
13288
13370
  // scripts/lakebase/scm-workflow-state.ts
13289
13371
  init_esm_shims();
13290
- import * as fs17 from "fs";
13291
- import * as path17 from "path";
13372
+ import * as fs18 from "fs";
13373
+ import * as path18 from "path";
13292
13374
  import { execFileSync as execFileSync6 } from "child_process";
13293
13375
  function isGitTracked(projectDir, rel) {
13294
13376
  try {
@@ -13307,11 +13389,11 @@ function ensureWorkflowStateUntracked(projectDir) {
13307
13389
  } catch {
13308
13390
  }
13309
13391
  try {
13310
- const gitignore = path17.join(projectDir, ".gitignore");
13311
- const existing = fs17.existsSync(gitignore) ? fs17.readFileSync(gitignore, "utf8") : "";
13392
+ const gitignore = path18.join(projectDir, ".gitignore");
13393
+ const existing = fs18.existsSync(gitignore) ? fs18.readFileSync(gitignore, "utf8") : "";
13312
13394
  if (!existing.split("\n").some((l) => l.trim() === rel)) {
13313
13395
  const sep4 = existing === "" || existing.endsWith("\n") ? "" : "\n";
13314
- fs17.appendFileSync(
13396
+ fs18.appendFileSync(
13315
13397
  gitignore,
13316
13398
  `${sep4}# Runtime SCM claim state (per working tree): a branch checkout must never restore
13317
13399
  # a stale committed claim over the live one (issue #203 / Finding 28).
@@ -13335,12 +13417,12 @@ var STATE_INDEX = SCM_STATES.reduce(
13335
13417
  );
13336
13418
  var STATE_FILE_REL = ".lakebase/workflow-state.json";
13337
13419
  function stateFilePath(projectDir) {
13338
- return path17.join(projectDir, STATE_FILE_REL);
13420
+ return path18.join(projectDir, STATE_FILE_REL);
13339
13421
  }
13340
13422
  function readWorkflowState(projectDir) {
13341
13423
  const p = stateFilePath(projectDir);
13342
- if (!fs17.existsSync(p)) return null;
13343
- const raw = fs17.readFileSync(p, "utf8");
13424
+ if (!fs18.existsSync(p)) return null;
13425
+ const raw = fs18.readFileSync(p, "utf8");
13344
13426
  let parsed;
13345
13427
  try {
13346
13428
  parsed = JSON.parse(raw);
@@ -13375,14 +13457,14 @@ function writeWorkflowState(projectDir, state) {
13375
13457
  ${summary}`);
13376
13458
  }
13377
13459
  ensureWorkflowStateUntracked(projectDir);
13378
- const dir = path17.join(projectDir, ".lakebase");
13379
- fs17.mkdirSync(dir, { recursive: true });
13460
+ const dir = path18.join(projectDir, ".lakebase");
13461
+ fs18.mkdirSync(dir, { recursive: true });
13380
13462
  const target = stateFilePath(projectDir);
13381
13463
  const tmp = `${target}.tmp`;
13382
13464
  const ordered = orderForOutput(result.value);
13383
- fs17.writeFileSync(tmp, `${JSON.stringify(ordered, null, 2)}
13465
+ fs18.writeFileSync(tmp, `${JSON.stringify(ordered, null, 2)}
13384
13466
  `, "utf8");
13385
- fs17.renameSync(tmp, target);
13467
+ fs18.renameSync(tmp, target);
13386
13468
  }
13387
13469
  function initWorkflowState(args) {
13388
13470
  return {
@@ -13606,7 +13688,7 @@ function orderForOutput(state) {
13606
13688
  async function createProject(input, progress) {
13607
13689
  const report = progress ?? (() => {
13608
13690
  });
13609
- const projectDir = path18.join(input.parentDir, input.projectName);
13691
+ const projectDir = path19.join(input.parentDir, input.projectName);
13610
13692
  const lakebaseProjectId = input.projectName;
13611
13693
  const host = input.databricksHost.replace(/\/+$/, "");
13612
13694
  const useGithub = input.createGithubRepo !== false;
@@ -13631,7 +13713,7 @@ async function createProject(input, progress) {
13631
13713
  useGithub,
13632
13714
  githubOwner: input.githubOwner,
13633
13715
  tiers,
13634
- dirExists: (p) => fs18.existsSync(p),
13716
+ dirExists: (p) => fs19.existsSync(p),
13635
13717
  dirIsEmpty
13636
13718
  });
13637
13719
  if (!v.ok) throw new Error(v.reason);
@@ -13700,7 +13782,7 @@ Last probe error:
13700
13782
  });
13701
13783
  } else {
13702
13784
  report("Creating local project directory...", projectDir);
13703
- fs18.mkdirSync(projectDir, { recursive: true });
13785
+ fs19.mkdirSync(projectDir, { recursive: true });
13704
13786
  await gitInit(projectDir);
13705
13787
  }
13706
13788
  report("Creating Lakebase database (provisioning Postgres)...", lakebaseProjectId);
@@ -13834,9 +13916,9 @@ Last probe error:
13834
13916
  const scmRef = envRef || (ver !== "unknown" ? `v${ver}` : "");
13835
13917
  if (scmRef) {
13836
13918
  try {
13837
- const dir = path18.join(projectDir, ".lakebase");
13838
- fs18.mkdirSync(dir, { recursive: true });
13839
- fs18.writeFileSync(path18.join(dir, "scm-utils-ref"), `${scmRef}
13919
+ const dir = path19.join(projectDir, ".lakebase");
13920
+ fs19.mkdirSync(dir, { recursive: true });
13921
+ fs19.writeFileSync(path19.join(dir, "scm-utils-ref"), `${scmRef}
13840
13922
  `, "utf8");
13841
13923
  } catch (err) {
13842
13924
  warnings.push(`Substrate ref pin failed (advisory): ${err instanceof Error ? err.message : String(err)}.`);
@@ -13847,9 +13929,9 @@ Last probe error:
13847
13929
  const kitRef = process.env.LAKEBASE_KIT_REF?.trim();
13848
13930
  if (kitRef) {
13849
13931
  try {
13850
- const dir = path18.join(projectDir, ".lakebase");
13851
- fs18.mkdirSync(dir, { recursive: true });
13852
- fs18.writeFileSync(path18.join(dir, "kit-ref"), `${kitRef}
13932
+ const dir = path19.join(projectDir, ".lakebase");
13933
+ fs19.mkdirSync(dir, { recursive: true });
13934
+ fs19.writeFileSync(path19.join(dir, "kit-ref"), `${kitRef}
13853
13935
  `, "utf8");
13854
13936
  } catch (err) {
13855
13937
  warnings.push(`Kit ref pin failed (advisory): ${err instanceof Error ? err.message : String(err)}.`);
@@ -13867,6 +13949,17 @@ Last probe error:
13867
13949
  dotnet: `.NET/ASP.NET Core (${input.migrationTool === "flyway" ? "Flyway" : "EF Core"})`
13868
13950
  };
13869
13951
  const langLabel = langLabels[language] ?? language;
13952
+ if (clientFramework !== "none") {
13953
+ report("Generating client package-lock.json (registry-normalized)...");
13954
+ const lock = await ensureClientLockfile({ projectDir });
13955
+ if (lock.generated) {
13956
+ report(` wrote client/package-lock.json${lock.swaps > 0 ? ` (normalized ${lock.swaps} proxy URL(s) to the public registry)` : ""}`);
13957
+ } else {
13958
+ const m = `Could not generate client/package-lock.json (${lock.reason ?? "unknown"}). Generate it with: (cd client && npm install) \u2014 the lock is committed on first push.`;
13959
+ warnings.push(m);
13960
+ report(`WARNING: ${m}`);
13961
+ }
13962
+ }
13870
13963
  report("Creating initial commit...");
13871
13964
  await commitAndPush({
13872
13965
  projectDir,
@@ -13931,17 +14024,17 @@ Last probe error:
13931
14024
  // scripts/lakebase/adopt-lakebase-project.ts
13932
14025
  init_esm_shims();
13933
14026
  import * as cp5 from "child_process";
13934
- import * as fs19 from "fs";
13935
- import * as path19 from "path";
14027
+ import * as fs20 from "fs";
14028
+ import * as path20 from "path";
13936
14029
  async function adoptLakebaseProject(args) {
13937
14030
  const warnings = [];
13938
14031
  const filesWritten = [];
13939
14032
  const dryRun = args.dryRun === true;
13940
14033
  const preserveExistingEnv = args.preserveExistingEnv !== false;
13941
- if (!fs19.existsSync(args.projectDir)) {
14034
+ if (!fs20.existsSync(args.projectDir)) {
13942
14035
  throw new Error(`adoptLakebaseProject: project directory does not exist: ${args.projectDir}`);
13943
14036
  }
13944
- if (!fs19.existsSync(path19.join(args.projectDir, ".git"))) {
14037
+ if (!fs20.existsSync(path20.join(args.projectDir, ".git"))) {
13945
14038
  throw new Error(
13946
14039
  `adoptLakebaseProject: ${args.projectDir} is not a git repo. Run \`git init\` first, or pass an existing repo path.`
13947
14040
  );
@@ -14007,9 +14100,9 @@ async function adoptLakebaseProject(args) {
14007
14100
  };
14008
14101
  }
14009
14102
  function assertEnvCompatibility(projectDir, expectedProjectId) {
14010
- const envPath = path19.join(projectDir, ".env");
14011
- if (!fs19.existsSync(envPath)) return;
14012
- const content = fs19.readFileSync(envPath, "utf8");
14103
+ const envPath = path20.join(projectDir, ".env");
14104
+ if (!fs20.existsSync(envPath)) return;
14105
+ const content = fs20.readFileSync(envPath, "utf8");
14013
14106
  const match = content.match(/^LAKEBASE_PROJECT_ID\s*=\s*(.+?)\s*$/m);
14014
14107
  if (!match) return;
14015
14108
  const existing = match[1].trim().replace(/^['"]|['"]$/g, "");
@@ -14020,10 +14113,10 @@ function assertEnvCompatibility(projectDir, expectedProjectId) {
14020
14113
  }
14021
14114
  }
14022
14115
  function assertAdoptionPreflight(args) {
14023
- if (!fs19.existsSync(args.projectDir)) {
14116
+ if (!fs20.existsSync(args.projectDir)) {
14024
14117
  throw new Error(`assertAdoptionPreflight: project directory does not exist: ${args.projectDir}`);
14025
14118
  }
14026
- if (!fs19.existsSync(path19.join(args.projectDir, ".git"))) {
14119
+ if (!fs20.existsSync(path20.join(args.projectDir, ".git"))) {
14027
14120
  throw new Error(
14028
14121
  `assertAdoptionPreflight: ${args.projectDir} is not a git repo.`
14029
14122
  );
@@ -14033,11 +14126,11 @@ function assertAdoptionPreflight(args) {
14033
14126
  }
14034
14127
  }
14035
14128
  function _testMakeBrownfieldFixture(opts) {
14036
- fs19.mkdirSync(opts.dir, { recursive: true });
14129
+ fs20.mkdirSync(opts.dir, { recursive: true });
14037
14130
  cp5.execSync("git init --quiet", { cwd: opts.dir, stdio: "pipe" });
14038
14131
  if (opts.packageJson) {
14039
- fs19.writeFileSync(
14040
- path19.join(opts.dir, "package.json"),
14132
+ fs20.writeFileSync(
14133
+ path20.join(opts.dir, "package.json"),
14041
14134
  JSON.stringify(opts.packageJson, null, 2) + "\n"
14042
14135
  );
14043
14136
  }
@@ -14045,8 +14138,8 @@ function _testMakeBrownfieldFixture(opts) {
14045
14138
 
14046
14139
  // scripts/lakebase/infra-runner.ts
14047
14140
  init_esm_shims();
14048
- import * as fs29 from "fs";
14049
- import * as path31 from "path";
14141
+ import * as fs30 from "fs";
14142
+ import * as path32 from "path";
14050
14143
 
14051
14144
  // scripts/lakebase/schema-diff.ts
14052
14145
  init_esm_shims();
@@ -14242,24 +14335,24 @@ function dbcli6(args) {
14242
14335
 
14243
14336
  // scripts/lakebase/schema-migrate.ts
14244
14337
  init_esm_shims();
14245
- import * as fs28 from "fs";
14246
- import * as path30 from "path";
14338
+ import * as fs29 from "fs";
14339
+ import * as path31 from "path";
14247
14340
 
14248
14341
  // scripts/lakebase/migration-layout.ts
14249
14342
  init_esm_shims();
14250
- import * as fs21 from "fs";
14251
- import * as path21 from "path";
14343
+ import * as fs22 from "fs";
14344
+ import * as path22 from "path";
14252
14345
 
14253
14346
  // scripts/lakebase/dotnet-project.ts
14254
14347
  init_esm_shims();
14255
- import * as fs20 from "fs";
14256
- import * as path20 from "path";
14348
+ import * as fs21 from "fs";
14349
+ import * as path21 from "path";
14257
14350
  var EF_DESIGN_PACKAGE = "Microsoft.EntityFrameworkCore.Design";
14258
- var DOTNET_FLYWAY_DIR = path20.join("db", "migrations");
14351
+ var DOTNET_FLYWAY_DIR = path21.join("db", "migrations");
14259
14352
  var SKIP_DIRS = /* @__PURE__ */ new Set(["bin", "obj", "node_modules", ".git", "client", "tests", "test"]);
14260
14353
  function safeReaddir(dir) {
14261
14354
  try {
14262
- return fs20.readdirSync(dir, { withFileTypes: true });
14355
+ return fs21.readdirSync(dir, { withFileTypes: true });
14263
14356
  } catch {
14264
14357
  return [];
14265
14358
  }
@@ -14273,7 +14366,7 @@ function findCsprojFiles(projectDir) {
14273
14366
  const found = [];
14274
14367
  const walk = (dir, depth) => {
14275
14368
  for (const e of safeReaddir(dir)) {
14276
- const full = path20.join(dir, e.name);
14369
+ const full = path21.join(dir, e.name);
14277
14370
  if (e.isFile() && e.name.toLowerCase().endsWith(".csproj")) {
14278
14371
  found.push(full);
14279
14372
  } else if (e.isDirectory() && depth < 2 && !SKIP_DIRS.has(e.name.toLowerCase()) && !e.name.startsWith(".")) {
@@ -14288,13 +14381,13 @@ function findEfCoreProject(projectDir) {
14288
14381
  for (const csproj of findCsprojFiles(projectDir)) {
14289
14382
  let content = "";
14290
14383
  try {
14291
- content = fs20.readFileSync(csproj, "utf-8");
14384
+ content = fs21.readFileSync(csproj, "utf-8");
14292
14385
  } catch {
14293
14386
  continue;
14294
14387
  }
14295
14388
  if (content.includes(EF_DESIGN_PACKAGE)) {
14296
- const dir = path20.dirname(csproj);
14297
- return { csproj, projectDir: dir, migrationsDir: path20.join(dir, "Migrations") };
14389
+ const dir = path21.dirname(csproj);
14390
+ return { csproj, projectDir: dir, migrationsDir: path21.join(dir, "Migrations") };
14298
14391
  }
14299
14392
  }
14300
14393
  return null;
@@ -14303,13 +14396,13 @@ function isDotnetProject(projectDir) {
14303
14396
  return hasDotnetMarker(projectDir);
14304
14397
  }
14305
14398
  function isDotnetFlywayProject(projectDir) {
14306
- return isDotnetProject(projectDir) && fs20.existsSync(path20.join(projectDir, DOTNET_FLYWAY_DIR));
14399
+ return isDotnetProject(projectDir) && fs21.existsSync(path21.join(projectDir, DOTNET_FLYWAY_DIR));
14307
14400
  }
14308
- var MAVEN_FLYWAY_DIR = path20.join("src", "main", "resources", "db", "migration");
14401
+ var MAVEN_FLYWAY_DIR = path21.join("src", "main", "resources", "db", "migration");
14309
14402
  function flywayMigrationsDir(projectDir) {
14310
- const maven = path20.join(projectDir, MAVEN_FLYWAY_DIR);
14311
- if (fs20.existsSync(maven) || fs20.existsSync(path20.join(projectDir, "pom.xml"))) return maven;
14312
- if (isDotnetFlywayProject(projectDir)) return path20.join(projectDir, DOTNET_FLYWAY_DIR);
14403
+ const maven = path21.join(projectDir, MAVEN_FLYWAY_DIR);
14404
+ if (fs21.existsSync(maven) || fs21.existsSync(path21.join(projectDir, "pom.xml"))) return maven;
14405
+ if (isDotnetFlywayProject(projectDir)) return path21.join(projectDir, DOTNET_FLYWAY_DIR);
14313
14406
  return maven;
14314
14407
  }
14315
14408
 
@@ -14333,13 +14426,13 @@ var MIGRATION_DEFAULTS = {
14333
14426
  unknown: { path: "src/main/resources/db/migration", pattern: /^V\d+.*\.sql$/i, glob: "*.sql" }
14334
14427
  };
14335
14428
  function detectLanguageAt(dir) {
14336
- if (fs21.existsSync(path21.join(dir, "pom.xml"))) {
14337
- const kotlinDir = path21.join(dir, "src", "main", "kotlin");
14338
- if (fs21.existsSync(kotlinDir)) {
14429
+ if (fs22.existsSync(path22.join(dir, "pom.xml"))) {
14430
+ const kotlinDir = path22.join(dir, "src", "main", "kotlin");
14431
+ if (fs22.existsSync(kotlinDir)) {
14339
14432
  return "kotlin";
14340
14433
  }
14341
14434
  try {
14342
- const pom = fs21.readFileSync(path21.join(dir, "pom.xml"), "utf-8");
14435
+ const pom = fs22.readFileSync(path22.join(dir, "pom.xml"), "utf-8");
14343
14436
  if (pom.includes("kotlin-maven-plugin")) {
14344
14437
  return "kotlin";
14345
14438
  }
@@ -14347,13 +14440,13 @@ function detectLanguageAt(dir) {
14347
14440
  }
14348
14441
  return "java";
14349
14442
  }
14350
- if (fs21.existsSync(path21.join(dir, "pyproject.toml")) || fs21.existsSync(path21.join(dir, "requirements.txt")) || fs21.existsSync(path21.join(dir, "alembic.ini"))) {
14443
+ if (fs22.existsSync(path22.join(dir, "pyproject.toml")) || fs22.existsSync(path22.join(dir, "requirements.txt")) || fs22.existsSync(path22.join(dir, "alembic.ini"))) {
14351
14444
  return "python";
14352
14445
  }
14353
14446
  if (hasDotnetMarker(dir)) {
14354
14447
  return "dotnet";
14355
14448
  }
14356
- if (fs21.existsSync(path21.join(dir, "package.json"))) {
14449
+ if (fs22.existsSync(path22.join(dir, "package.json"))) {
14357
14450
  return "nodejs";
14358
14451
  }
14359
14452
  return "unknown";
@@ -14374,14 +14467,14 @@ function resolveMigrationLanguage(projectDir, configuredMigrationPath, override)
14374
14467
  if (!rel) {
14375
14468
  return "unknown";
14376
14469
  }
14377
- const rootResolved = path21.resolve(projectDir);
14378
- let dir = path21.resolve(projectDir, rel);
14379
- while (dir === rootResolved || dir.startsWith(rootResolved + path21.sep)) {
14470
+ const rootResolved = path22.resolve(projectDir);
14471
+ let dir = path22.resolve(projectDir, rel);
14472
+ while (dir === rootResolved || dir.startsWith(rootResolved + path22.sep)) {
14380
14473
  const lang = detectLanguageAt(dir);
14381
14474
  if (lang !== "unknown") {
14382
14475
  return lang;
14383
14476
  }
14384
- const parent = path21.dirname(dir);
14477
+ const parent = path22.dirname(dir);
14385
14478
  if (parent === dir) {
14386
14479
  break;
14387
14480
  }
@@ -14409,14 +14502,14 @@ var DOTNET_LAYOUT_TTL_MS = 5e3;
14409
14502
  var dotnetLayoutCache = /* @__PURE__ */ new Map();
14410
14503
  function dotnetDefaults(projectDir) {
14411
14504
  if (!projectDir) return MIGRATION_DEFAULTS.dotnet;
14412
- const key = path21.resolve(projectDir);
14505
+ const key = path22.resolve(projectDir);
14413
14506
  const hit = dotnetLayoutCache.get(key);
14414
14507
  if (hit && Date.now() - hit.at < DOTNET_LAYOUT_TTL_MS) return hit.value;
14415
14508
  let value = MIGRATION_DEFAULTS.dotnet;
14416
14509
  if (!isDotnetFlywayProject(projectDir)) {
14417
14510
  const ef = findEfCoreProject(projectDir);
14418
14511
  if (ef) {
14419
- const rel = path21.relative(projectDir, ef.migrationsDir).split(path21.sep).join("/");
14512
+ const rel = path22.relative(projectDir, ef.migrationsDir).split(path22.sep).join("/");
14420
14513
  value = { ...DOTNET_EFCORE_DEFAULTS, path: rel };
14421
14514
  }
14422
14515
  }
@@ -14437,34 +14530,51 @@ function resolveMigrationLayout(args) {
14437
14530
 
14438
14531
  // scripts/lakebase/adapters/alembic-adapter.ts
14439
14532
  init_esm_shims();
14440
- import * as fs23 from "fs";
14441
- import * as path23 from "path";
14533
+ import * as fs24 from "fs";
14534
+ import * as path24 from "path";
14442
14535
 
14443
14536
  // scripts/lakebase/schema-migrate-runners/alembic.ts
14444
14537
  init_esm_shims();
14445
- import { spawn as spawn5 } from "child_process";
14446
- import * as fs22 from "fs";
14447
- import * as path22 from "path";
14448
- function resolveAlembicBin(projectDir) {
14449
- const candidates = [
14450
- path22.join(projectDir, ".venv", "bin", "alembic"),
14451
- path22.join(projectDir, "venv", "bin", "alembic")
14538
+ import { spawn as spawn5, execFileSync as execFileSync7 } from "child_process";
14539
+ import * as fs23 from "fs";
14540
+ import * as path23 from "path";
14541
+ var uvOnPath;
14542
+ function hasUv() {
14543
+ if (uvOnPath !== void 0) return uvOnPath;
14544
+ try {
14545
+ execFileSync7("uv", ["--version"], { stdio: "ignore" });
14546
+ uvOnPath = true;
14547
+ } catch {
14548
+ uvOnPath = false;
14549
+ }
14550
+ return uvOnPath;
14551
+ }
14552
+ function resolveAlembicInvocation(projectDir, uvAvailable = hasUv()) {
14553
+ const venvCandidates = [
14554
+ path23.join(projectDir, ".venv", "bin", "alembic"),
14555
+ path23.join(projectDir, "venv", "bin", "alembic")
14452
14556
  ];
14453
- for (const candidate of candidates) {
14557
+ for (const candidate of venvCandidates) {
14454
14558
  try {
14455
- if (fs22.existsSync(candidate)) return candidate;
14559
+ if (fs23.existsSync(candidate)) return { bin: candidate, prefixArgs: [] };
14456
14560
  } catch {
14457
14561
  }
14458
14562
  }
14459
- return "alembic";
14563
+ try {
14564
+ if (uvAvailable && fs23.existsSync(path23.join(projectDir, "pyproject.toml"))) {
14565
+ return { bin: "uv", prefixArgs: ["run", "alembic"] };
14566
+ }
14567
+ } catch {
14568
+ }
14569
+ return { bin: "alembic", prefixArgs: [] };
14460
14570
  }
14461
14571
  function spawnAlembic(projectDir, args, dsn) {
14462
14572
  return new Promise((resolve2, reject) => {
14463
- const bin = resolveAlembicBin(projectDir);
14573
+ const { bin, prefixArgs } = resolveAlembicInvocation(projectDir);
14464
14574
  const env = { ...process.env };
14465
- env.PYTHONPATH = [projectDir, process.env.PYTHONPATH].filter(Boolean).join(path22.delimiter);
14575
+ env.PYTHONPATH = [projectDir, process.env.PYTHONPATH].filter(Boolean).join(path23.delimiter);
14466
14576
  if (dsn) env.DATABASE_URL = dsn;
14467
- const child = spawn5(bin, args, {
14577
+ const child = spawn5(bin, [...prefixArgs, ...args], {
14468
14578
  cwd: projectDir,
14469
14579
  env,
14470
14580
  stdio: ["ignore", "pipe", "pipe"]
@@ -14510,10 +14620,10 @@ async function createAlembicRevision(opts) {
14510
14620
  const m = stdout.match(/Generating\s+(\S+\.py)/);
14511
14621
  if (m) return m[1].trim();
14512
14622
  for (const rel of ["migrations/versions", "alembic/versions"]) {
14513
- const dir = path22.join(opts.projectDir, rel);
14514
- if (!fs22.existsSync(dir)) continue;
14515
- const hit = fs22.readdirSync(dir).find((f) => f.startsWith(`${opts.revId}_`) && f.endsWith(".py"));
14516
- if (hit) return path22.join(dir, hit);
14623
+ const dir = path23.join(opts.projectDir, rel);
14624
+ if (!fs23.existsSync(dir)) continue;
14625
+ const hit = fs23.readdirSync(dir).find((f) => f.startsWith(`${opts.revId}_`) && f.endsWith(".py"));
14626
+ if (hit) return path23.join(dir, hit);
14517
14627
  }
14518
14628
  throw new SchemaMigrationError(
14519
14629
  `alembic revision succeeded but the created file could not be located.
@@ -14648,15 +14758,15 @@ async function buildDsn2(args) {
14648
14758
  }
14649
14759
  function findVersionsDir(projectDir) {
14650
14760
  const candidates = [
14651
- path23.join(projectDir, "migrations", "versions"),
14652
- path23.join(projectDir, "alembic", "versions")
14761
+ path24.join(projectDir, "migrations", "versions"),
14762
+ path24.join(projectDir, "alembic", "versions")
14653
14763
  ];
14654
- return candidates.find((p) => fs23.existsSync(p));
14764
+ return candidates.find((p) => fs24.existsSync(p));
14655
14765
  }
14656
14766
  function listAlembicFiles(projectDir) {
14657
14767
  const dir = findVersionsDir(projectDir);
14658
14768
  if (!dir) return [];
14659
- const files = fs23.readdirSync(dir).filter((f) => f.endsWith(".py") && !f.startsWith("__"));
14769
+ const files = fs24.readdirSync(dir).filter((f) => f.endsWith(".py") && !f.startsWith("__"));
14660
14770
  return files.map((filename) => {
14661
14771
  const stem = filename.replace(/\.py$/, "");
14662
14772
  const sep4 = stem.indexOf("_");
@@ -14681,9 +14791,9 @@ var AlembicAdapter = {
14681
14791
  * here. Callers can still force-select via project.yaml#migration_tool.
14682
14792
  */
14683
14793
  detect(projectDir) {
14684
- if (fs23.existsSync(path23.join(projectDir, "alembic.ini"))) return true;
14685
- if (fs23.existsSync(path23.join(projectDir, "migrations", "env.py"))) return true;
14686
- if (fs23.existsSync(path23.join(projectDir, "alembic", "env.py"))) return true;
14794
+ if (fs24.existsSync(path24.join(projectDir, "alembic.ini"))) return true;
14795
+ if (fs24.existsSync(path24.join(projectDir, "migrations", "env.py"))) return true;
14796
+ if (fs24.existsSync(path24.join(projectDir, "alembic", "env.py"))) return true;
14687
14797
  return false;
14688
14798
  },
14689
14799
  async apply(args) {
@@ -14789,7 +14899,7 @@ var AlembicAdapter = {
14789
14899
  autogenerate: !!args.autogenerate,
14790
14900
  dsn
14791
14901
  });
14792
- return { status: "ok", version: revId, filename: path23.basename(created), path: created };
14902
+ return { status: "ok", version: revId, filename: path24.basename(created), path: created };
14793
14903
  } catch (err) {
14794
14904
  return {
14795
14905
  status: "error",
@@ -14806,7 +14916,7 @@ var AlembicAdapter = {
14806
14916
  if (heads.length <= 1) return { status: "noop", headsBefore: heads };
14807
14917
  if (args.dryRun) return { status: "ok", headsBefore: heads };
14808
14918
  const created = await mergeAlembicHeads(args.projectDir, args.message ?? "merge heads");
14809
- const mergeRevision = path23.basename(created).replace(/\.py$/, "").split("_")[0];
14919
+ const mergeRevision = path24.basename(created).replace(/\.py$/, "").split("_")[0];
14810
14920
  return { status: "ok", headsBefore: heads, mergeRevision, path: created };
14811
14921
  } catch (err) {
14812
14922
  return {
@@ -14821,13 +14931,13 @@ registerSchemaMigrationAdapter(AlembicAdapter);
14821
14931
 
14822
14932
  // scripts/lakebase/adapters/flyway-adapter.ts
14823
14933
  init_esm_shims();
14824
- import * as fs24 from "fs";
14825
- import * as path25 from "path";
14934
+ import * as fs25 from "fs";
14935
+ import * as path26 from "path";
14826
14936
 
14827
14937
  // scripts/lakebase/schema-migrate-runners/flyway.ts
14828
14938
  init_esm_shims();
14829
14939
  import { spawn as spawn6 } from "child_process";
14830
- import * as path24 from "path";
14940
+ import * as path25 from "path";
14831
14941
  function dsnToFlywayEnv(dsn) {
14832
14942
  const u = new URL(dsn);
14833
14943
  const user = decodeURIComponent(u.username);
@@ -14938,7 +15048,7 @@ async function statusFlyway(ctx) {
14938
15048
  if (state === "SUCCESS" || state === "BASELINE") {
14939
15049
  current = m.version;
14940
15050
  } else if (state === "PENDING") {
14941
- const filename = m.filepath ? path24.basename(m.filepath) : `V${m.version}__migration.sql`;
15051
+ const filename = m.filepath ? path25.basename(m.filepath) : `V${m.version}__migration.sql`;
14942
15052
  pending.push({
14943
15053
  version: m.version,
14944
15054
  filename,
@@ -14962,8 +15072,8 @@ async function buildDsn3(args) {
14962
15072
  }
14963
15073
  function listFlywayFiles(projectDir) {
14964
15074
  const dir = flywayMigrationsDir(projectDir);
14965
- if (!fs24.existsSync(dir)) return [];
14966
- const files = fs24.readdirSync(dir).filter((f) => /^V\d+(\.\d+)*__.+\.sql$/.test(f));
15075
+ if (!fs25.existsSync(dir)) return [];
15076
+ const files = fs25.readdirSync(dir).filter((f) => /^V\d+(\.\d+)*__.+\.sql$/.test(f));
14967
15077
  return files.map((filename) => {
14968
15078
  const m = filename.match(/^V(\d+(?:\.\d+)*)__(.+)\.sql$/);
14969
15079
  const version = m[1];
@@ -14986,7 +15096,7 @@ var FlywayAdapter = {
14986
15096
  id: "flyway",
14987
15097
  languages: ["java", "kotlin", "dotnet"],
14988
15098
  detect(projectDir) {
14989
- return fs24.existsSync(path25.join(projectDir, "pom.xml")) || isDotnetFlywayProject(projectDir);
15099
+ return fs25.existsSync(path26.join(projectDir, "pom.xml")) || isDotnetFlywayProject(projectDir);
14990
15100
  },
14991
15101
  async apply(args) {
14992
15102
  const dsn = await buildDsn3(args);
@@ -15045,13 +15155,13 @@ var FlywayAdapter = {
15045
15155
  async newMigration(args) {
15046
15156
  try {
15047
15157
  const dir = flywayMigrationsDir(args.projectDir);
15048
- fs24.mkdirSync(dir, { recursive: true });
15158
+ fs25.mkdirSync(dir, { recursive: true });
15049
15159
  const version = migrationTimestamp();
15050
15160
  const slug = migrationSlug2(args.slug);
15051
15161
  const filename = `V${version}__${slug}.sql`;
15052
- const full = path25.join(dir, filename);
15053
- if (fs24.existsSync(full)) throw new Error(`${filename} already exists`);
15054
- fs24.writeFileSync(
15162
+ const full = path26.join(dir, filename);
15163
+ if (fs25.existsSync(full)) throw new Error(`${filename} already exists`);
15164
+ fs25.writeFileSync(
15055
15165
  full,
15056
15166
  `-- V${version}: ${args.slug}
15057
15167
  -- Flyway migration (write your DDL/DML below).
@@ -15074,19 +15184,19 @@ registerSchemaMigrationAdapter(FlywayAdapter);
15074
15184
 
15075
15185
  // scripts/lakebase/adapters/knex-adapter.ts
15076
15186
  init_esm_shims();
15077
- import * as fs26 from "fs";
15078
- import * as path27 from "path";
15187
+ import * as fs27 from "fs";
15188
+ import * as path28 from "path";
15079
15189
 
15080
15190
  // scripts/lakebase/schema-migrate-runners/knex.ts
15081
15191
  init_esm_shims();
15082
15192
  import { spawn as spawn7 } from "child_process";
15083
- import * as fs25 from "fs";
15084
- import * as path26 from "path";
15193
+ import * as fs26 from "fs";
15194
+ import * as path27 from "path";
15085
15195
  var KNEXFILE_VARIANTS = ["knexfile.js", "knexfile.ts", "knexfile.mjs", "knexfile.cjs"];
15086
15196
  function findKnexfile(projectDir) {
15087
15197
  for (const name of KNEXFILE_VARIANTS) {
15088
- const p = path26.join(projectDir, name);
15089
- if (fs25.existsSync(p)) return p;
15198
+ const p = path27.join(projectDir, name);
15199
+ if (fs26.existsSync(p)) return p;
15090
15200
  }
15091
15201
  return void 0;
15092
15202
  }
@@ -15238,9 +15348,9 @@ async function buildDsn4(args) {
15238
15348
  }
15239
15349
  var KNEXFILE_VARIANTS2 = ["knexfile.js", "knexfile.ts", "knexfile.mjs", "knexfile.cjs"];
15240
15350
  function listKnexFiles(projectDir) {
15241
- const dir = path27.join(projectDir, "migrations");
15242
- if (!fs26.existsSync(dir)) return [];
15243
- const files = fs26.readdirSync(dir).filter((f) => (f.endsWith(".js") || f.endsWith(".ts")) && !f.startsWith("."));
15351
+ const dir = path28.join(projectDir, "migrations");
15352
+ if (!fs27.existsSync(dir)) return [];
15353
+ const files = fs27.readdirSync(dir).filter((f) => (f.endsWith(".js") || f.endsWith(".ts")) && !f.startsWith("."));
15244
15354
  return files.map((filename) => {
15245
15355
  const stem = filename.replace(/\.(js|ts)$/, "");
15246
15356
  const m = stem.match(/^(\d{14})_(.+)$/);
@@ -15260,7 +15370,7 @@ var KnexAdapter = {
15260
15370
  * project.yaml#migration_tool.
15261
15371
  */
15262
15372
  detect(projectDir) {
15263
- return KNEXFILE_VARIANTS2.some((name) => fs26.existsSync(path27.join(projectDir, name)));
15373
+ return KNEXFILE_VARIANTS2.some((name) => fs27.existsSync(path28.join(projectDir, name)));
15264
15374
  },
15265
15375
  async apply(args) {
15266
15376
  const dsn = await buildDsn4(args);
@@ -15333,9 +15443,9 @@ var KnexAdapter = {
15333
15443
  async newMigration(args) {
15334
15444
  try {
15335
15445
  const created = await createKnexMigration({ projectDir: args.projectDir, slug: migrationSlug2(args.slug) });
15336
- const stem = path27.basename(created).replace(/\.(js|ts)$/, "");
15446
+ const stem = path28.basename(created).replace(/\.(js|ts)$/, "");
15337
15447
  const version = stem.match(/^(\d{14})_/)?.[1] ?? stem;
15338
- return { status: "ok", version, filename: path27.basename(created), path: created };
15448
+ return { status: "ok", version, filename: path28.basename(created), path: created };
15339
15449
  } catch (err) {
15340
15450
  return {
15341
15451
  status: "error",
@@ -15351,13 +15461,13 @@ registerSchemaMigrationAdapter(KnexAdapter);
15351
15461
 
15352
15462
  // scripts/lakebase/adapters/efcore-adapter.ts
15353
15463
  init_esm_shims();
15354
- import * as path29 from "path";
15464
+ import * as path30 from "path";
15355
15465
 
15356
15466
  // scripts/lakebase/schema-migrate-runners/efcore.ts
15357
15467
  init_esm_shims();
15358
15468
  import { spawn as spawn8 } from "child_process";
15359
- import * as fs27 from "fs";
15360
- import * as path28 from "path";
15469
+ import * as fs28 from "fs";
15470
+ import * as path29 from "path";
15361
15471
  import { Client as Client3 } from "pg";
15362
15472
  var MIGRATION_ID = /^(\d{14})_(.+)$/;
15363
15473
  function efVersion(id) {
@@ -15454,7 +15564,7 @@ stderr: ${stderr}`
15454
15564
  var restored = /* @__PURE__ */ new Set();
15455
15565
  async function ensureRestored(projectDir, csproj) {
15456
15566
  if (restored.has(projectDir)) return;
15457
- if (fs27.existsSync(path28.join(projectDir, ".config", "dotnet-tools.json"))) {
15567
+ if (fs28.existsSync(path29.join(projectDir, ".config", "dotnet-tools.json"))) {
15458
15568
  await spawnDotnet(projectDir, ["tool", "restore"], {});
15459
15569
  }
15460
15570
  await spawnDotnet(projectDir, ["restore", csproj], {});
@@ -15462,7 +15572,7 @@ async function ensureRestored(projectDir, csproj) {
15462
15572
  }
15463
15573
  async function runEf(projectDir, args, dsn, opts = {}) {
15464
15574
  const project = requireProject(projectDir);
15465
- const csproj = path28.relative(projectDir, project.csproj) || project.csproj;
15575
+ const csproj = path29.relative(projectDir, project.csproj) || project.csproj;
15466
15576
  await ensureRestored(projectDir, csproj);
15467
15577
  const full = ["ef", ...args, "--project", csproj, "--prefix-output"];
15468
15578
  if (opts.noBuild) full.push("--no-build");
@@ -15546,22 +15656,22 @@ function efMigrationName(slug) {
15546
15656
  async function createEfcoreMigration(opts) {
15547
15657
  const project = requireProject(opts.projectDir);
15548
15658
  const name = efMigrationName(opts.slug);
15549
- const existing = new Set(fs27.existsSync(project.migrationsDir) ? fs27.readdirSync(project.migrationsDir) : []);
15659
+ const existing = new Set(fs28.existsSync(project.migrationsDir) ? fs28.readdirSync(project.migrationsDir) : []);
15550
15660
  await runEf(opts.projectDir, ["migrations", "add", name]);
15551
- const created = fs27.readdirSync(project.migrationsDir).filter((f) => !existing.has(f) && MIGRATION_ID.test(f.replace(/\.cs$/, "")) && !f.endsWith(".Designer.cs"));
15661
+ const created = fs28.readdirSync(project.migrationsDir).filter((f) => !existing.has(f) && MIGRATION_ID.test(f.replace(/\.cs$/, "")) && !f.endsWith(".Designer.cs"));
15552
15662
  if (created.length !== 1) {
15553
15663
  throw new SchemaMigrationError(`Expected one new migration file for ${name}, found: ${created.join(", ") || "none"}`);
15554
15664
  }
15555
- return { id: created[0].replace(/\.cs$/, ""), path: path28.join(project.migrationsDir, created[0]) };
15665
+ return { id: created[0].replace(/\.cs$/, ""), path: path29.join(project.migrationsDir, created[0]) };
15556
15666
  }
15557
15667
  function localEfMigrationIds(projectDir) {
15558
15668
  const project = findEfCoreProject(projectDir);
15559
- if (!project || !fs27.existsSync(project.migrationsDir)) return [];
15560
- return fs27.readdirSync(project.migrationsDir).filter((f) => f.endsWith(".cs") && !f.endsWith(".Designer.cs") && MIGRATION_ID.test(f.slice(0, -3))).map((f) => f.slice(0, -3)).sort();
15669
+ if (!project || !fs28.existsSync(project.migrationsDir)) return [];
15670
+ return fs28.readdirSync(project.migrationsDir).filter((f) => f.endsWith(".cs") && !f.endsWith(".Designer.cs") && MIGRATION_ID.test(f.slice(0, -3))).map((f) => f.slice(0, -3)).sort();
15561
15671
  }
15562
15672
  function efProductVersion(project) {
15563
15673
  try {
15564
- const csproj = fs27.readFileSync(project.csproj, "utf-8");
15674
+ const csproj = fs28.readFileSync(project.csproj, "utf-8");
15565
15675
  const m = new RegExp(`${EF_DESIGN_PACKAGE.replace(/\./g, "\\.")}"\\s+Version="([^"]+)"`).exec(csproj);
15566
15676
  if (m) return m[1];
15567
15677
  } catch {
@@ -15695,7 +15805,7 @@ var EfCoreAdapter = {
15695
15805
  return {
15696
15806
  status: "ok",
15697
15807
  version: efVersion(created.id),
15698
- filename: path29.basename(created.path),
15808
+ filename: path30.basename(created.path),
15699
15809
  path: created.path
15700
15810
  };
15701
15811
  } catch (err) {
@@ -15754,8 +15864,8 @@ function listSchemaMigrations(args = {}) {
15754
15864
  }
15755
15865
  function listFlywayMigrations(projectDir) {
15756
15866
  const dir = flywayMigrationsDir(projectDir);
15757
- if (!fs28.existsSync(dir)) return [];
15758
- const files = fs28.readdirSync(dir).filter((f) => /^V\d+(\.\d+)*__.+\.sql$/.test(f));
15867
+ if (!fs29.existsSync(dir)) return [];
15868
+ const files = fs29.readdirSync(dir).filter((f) => /^V\d+(\.\d+)*__.+\.sql$/.test(f));
15759
15869
  return files.map((filename) => {
15760
15870
  const m = filename.match(/^V(\d+(?:\.\d+)*)__(.+)\.sql$/);
15761
15871
  const version = m[1];
@@ -15765,12 +15875,12 @@ function listFlywayMigrations(projectDir) {
15765
15875
  }
15766
15876
  function listAlembicMigrations(projectDir) {
15767
15877
  const candidates = [
15768
- path30.join(projectDir, "migrations", "versions"),
15769
- path30.join(projectDir, "alembic", "versions")
15878
+ path31.join(projectDir, "migrations", "versions"),
15879
+ path31.join(projectDir, "alembic", "versions")
15770
15880
  ];
15771
- const dir = candidates.find((p) => fs28.existsSync(p));
15881
+ const dir = candidates.find((p) => fs29.existsSync(p));
15772
15882
  if (!dir) return [];
15773
- const files = fs28.readdirSync(dir).filter((f) => f.endsWith(".py") && !f.startsWith("__"));
15883
+ const files = fs29.readdirSync(dir).filter((f) => f.endsWith(".py") && !f.startsWith("__"));
15774
15884
  return files.map((filename) => {
15775
15885
  const stem = filename.replace(/\.py$/, "");
15776
15886
  const sep4 = stem.indexOf("_");
@@ -15780,9 +15890,9 @@ function listAlembicMigrations(projectDir) {
15780
15890
  }).sort((a, b) => a.filename.localeCompare(b.filename));
15781
15891
  }
15782
15892
  function listKnexMigrations(projectDir) {
15783
- const dir = path30.join(projectDir, "migrations");
15784
- if (!fs28.existsSync(dir)) return [];
15785
- const files = fs28.readdirSync(dir).filter((f) => (f.endsWith(".js") || f.endsWith(".ts")) && !f.startsWith("."));
15893
+ const dir = path31.join(projectDir, "migrations");
15894
+ if (!fs29.existsSync(dir)) return [];
15895
+ const files = fs29.readdirSync(dir).filter((f) => (f.endsWith(".js") || f.endsWith(".ts")) && !f.startsWith("."));
15786
15896
  return files.map((filename) => {
15787
15897
  const stem = filename.replace(/\.(js|ts)$/, "");
15788
15898
  const m = stem.match(/^(\d{14})_(.+)$/);
@@ -15958,8 +16068,8 @@ async function runInfraSuite(args) {
15958
16068
  duration_ms: Date.now() - start
15959
16069
  };
15960
16070
  if (args.junitOutput) {
15961
- fs29.mkdirSync(path31.dirname(args.junitOutput), { recursive: true });
15962
- fs29.writeFileSync(args.junitOutput, formatJUnit(result), "utf8");
16071
+ fs30.mkdirSync(path32.dirname(args.junitOutput), { recursive: true });
16072
+ fs30.writeFileSync(args.junitOutput, formatJUnit(result), "utf8");
15963
16073
  }
15964
16074
  return result;
15965
16075
  }
@@ -16005,8 +16115,8 @@ function escapeXml(s) {
16005
16115
 
16006
16116
  // scripts/lakebase/scm-claim-feature.ts
16007
16117
  init_esm_shims();
16008
- import * as fs30 from "fs";
16009
- import * as path32 from "path";
16118
+ import * as fs31 from "fs";
16119
+ import * as path33 from "path";
16010
16120
  var ScmClaimError = class extends Error {
16011
16121
  constructor(message, code) {
16012
16122
  super(message);
@@ -16063,7 +16173,7 @@ async function claimFeatureBranch(args) {
16063
16173
  const current = readWorkflowState(args.projectDir);
16064
16174
  if (!current) {
16065
16175
  throw new ScmClaimError(
16066
- `No SCM workflow state found at ${path32.join(args.projectDir, ".lakebase/workflow-state.json")}. Run lakebase-create-project to scaffold, or re-seed via the substrate.`,
16176
+ `No SCM workflow state found at ${path33.join(args.projectDir, ".lakebase/workflow-state.json")}. Run lakebase-create-project to scaffold, or re-seed via the substrate.`,
16067
16177
  "no-state-file"
16068
16178
  );
16069
16179
  }
@@ -16167,8 +16277,8 @@ function alreadyClaimedSentinel(state) {
16167
16277
  };
16168
16278
  }
16169
16279
  function workflowStateFileExists(projectDir) {
16170
- return fs30.existsSync(
16171
- path32.join(projectDir, ".lakebase/workflow-state.json")
16280
+ return fs31.existsSync(
16281
+ path33.join(projectDir, ".lakebase/workflow-state.json")
16172
16282
  );
16173
16283
  }
16174
16284
 
@@ -16690,12 +16800,12 @@ async function sync(args) {
16690
16800
 
16691
16801
  // scripts/lakebase/workflow-drift.ts
16692
16802
  init_esm_shims();
16693
- import * as fs31 from "fs";
16694
- import * as path33 from "path";
16803
+ import * as fs32 from "fs";
16804
+ import * as path34 from "path";
16695
16805
  function findKitTemplatesDir(start) {
16696
16806
  let dir = start;
16697
16807
  for (let i = 0; i < 6; i++) {
16698
- const candidate = path33.join(
16808
+ const candidate = path34.join(
16699
16809
  dir,
16700
16810
  "templates",
16701
16811
  "project",
@@ -16703,8 +16813,8 @@ function findKitTemplatesDir(start) {
16703
16813
  ".github",
16704
16814
  "workflows"
16705
16815
  );
16706
- if (fs31.existsSync(candidate)) return candidate;
16707
- const parent = path33.dirname(dir);
16816
+ if (fs32.existsSync(candidate)) return candidate;
16817
+ const parent = path34.dirname(dir);
16708
16818
  if (parent === dir) break;
16709
16819
  dir = parent;
16710
16820
  }
@@ -16728,13 +16838,13 @@ function unifiedDiff(name, projectContent, templateContent) {
16728
16838
  return out.join("\n");
16729
16839
  }
16730
16840
  function detectWorkflowDrift(args) {
16731
- const projectWorkflowsDir = path33.join(
16841
+ const projectWorkflowsDir = path34.join(
16732
16842
  args.projectDir,
16733
16843
  ".github",
16734
16844
  "workflows"
16735
16845
  );
16736
- const here = path33.dirname(new URL(import.meta.url).pathname);
16737
- const kitWorkflowsDir = args.kitDir ? path33.join(
16846
+ const here = path34.dirname(new URL(import.meta.url).pathname);
16847
+ const kitWorkflowsDir = args.kitDir ? path34.join(
16738
16848
  args.kitDir,
16739
16849
  "templates",
16740
16850
  "project",
@@ -16742,21 +16852,21 @@ function detectWorkflowDrift(args) {
16742
16852
  ".github",
16743
16853
  "workflows"
16744
16854
  ) : findKitTemplatesDir(here);
16745
- const templateFiles = fs31.existsSync(kitWorkflowsDir) ? fs31.readdirSync(kitWorkflowsDir).filter((f) => f.endsWith(".yml")) : [];
16746
- const projectFiles = fs31.existsSync(projectWorkflowsDir) ? fs31.readdirSync(projectWorkflowsDir).filter((f) => f.endsWith(".yml")) : [];
16855
+ const templateFiles = fs32.existsSync(kitWorkflowsDir) ? fs32.readdirSync(kitWorkflowsDir).filter((f) => f.endsWith(".yml")) : [];
16856
+ const projectFiles = fs32.existsSync(projectWorkflowsDir) ? fs32.readdirSync(projectWorkflowsDir).filter((f) => f.endsWith(".yml")) : [];
16747
16857
  const version = readKitVersion(kitWorkflowsDir);
16748
16858
  const seen = /* @__PURE__ */ new Set();
16749
16859
  const files = [];
16750
16860
  for (const name of templateFiles) {
16751
16861
  seen.add(name);
16752
- const projectPath2 = path33.join(projectWorkflowsDir, name);
16753
- const templatePath = path33.join(kitWorkflowsDir, name);
16754
- if (!fs31.existsSync(projectPath2)) {
16862
+ const projectPath2 = path34.join(projectWorkflowsDir, name);
16863
+ const templatePath = path34.join(kitWorkflowsDir, name);
16864
+ if (!fs32.existsSync(projectPath2)) {
16755
16865
  files.push({ name, status: "missing" });
16756
16866
  continue;
16757
16867
  }
16758
- const projectContent = fs31.readFileSync(projectPath2, "utf8");
16759
- const templateContent = applyPlaceholders(fs31.readFileSync(templatePath, "utf8"), version);
16868
+ const projectContent = fs32.readFileSync(projectPath2, "utf8");
16869
+ const templateContent = applyPlaceholders(fs32.readFileSync(templatePath, "utf8"), version);
16760
16870
  if (projectContent === templateContent) {
16761
16871
  files.push({ name, status: "unchanged" });
16762
16872
  } else {
@@ -16787,10 +16897,10 @@ function detectWorkflowDrift(args) {
16787
16897
  function readKitVersion(kitWorkflowsDir) {
16788
16898
  let dir = kitWorkflowsDir;
16789
16899
  for (let i = 0; i < 5; i++) {
16790
- dir = path33.dirname(dir);
16900
+ dir = path34.dirname(dir);
16791
16901
  }
16792
16902
  try {
16793
- const raw = fs31.readFileSync(path33.join(dir, "package.json"), "utf-8");
16903
+ const raw = fs32.readFileSync(path34.join(dir, "package.json"), "utf-8");
16794
16904
  const pkg = JSON.parse(raw);
16795
16905
  return typeof pkg.version === "string" ? pkg.version : "unknown";
16796
16906
  } catch {
@@ -16807,7 +16917,7 @@ var COMMAND_HOOK_FILE_PATTERN = /\.(pre|post)-hook\.md$/;
16807
16917
  function findKitCommandsDir(start) {
16808
16918
  let dir = start;
16809
16919
  for (let i = 0; i < 6; i++) {
16810
- const candidate = path33.join(
16920
+ const candidate = path34.join(
16811
16921
  dir,
16812
16922
  "templates",
16813
16923
  "project",
@@ -16815,8 +16925,8 @@ function findKitCommandsDir(start) {
16815
16925
  ".claude",
16816
16926
  "commands"
16817
16927
  );
16818
- if (fs31.existsSync(candidate)) return candidate;
16819
- const parent = path33.dirname(dir);
16928
+ if (fs32.existsSync(candidate)) return candidate;
16929
+ const parent = path34.dirname(dir);
16820
16930
  if (parent === dir) break;
16821
16931
  dir = parent;
16822
16932
  }
@@ -16829,24 +16939,24 @@ function parsePinnedVersion(content) {
16829
16939
  return m ? m[1] : void 0;
16830
16940
  }
16831
16941
  function detectCommandDrift(args) {
16832
- const projectCommandsDir = path33.join(args.projectDir, ".claude", "commands");
16833
- const here = path33.dirname(new URL(import.meta.url).pathname);
16834
- const kitCommandsDir = args.kitDir ? path33.join(args.kitDir, "templates", "project", "common", ".claude", "commands") : findKitCommandsDir(here);
16942
+ const projectCommandsDir = path34.join(args.projectDir, ".claude", "commands");
16943
+ const here = path34.dirname(new URL(import.meta.url).pathname);
16944
+ const kitCommandsDir = args.kitDir ? path34.join(args.kitDir, "templates", "project", "common", ".claude", "commands") : findKitCommandsDir(here);
16835
16945
  const kitVersion = readKitVersionFromCommandsDir(kitCommandsDir);
16836
- const templateFiles = fs31.existsSync(kitCommandsDir) ? fs31.readdirSync(kitCommandsDir).filter((f) => f.endsWith(".md") && !COMMAND_HOOK_FILE_PATTERN.test(f)) : [];
16837
- const projectFiles = fs31.existsSync(projectCommandsDir) ? fs31.readdirSync(projectCommandsDir).filter((f) => f.endsWith(".md") && !COMMAND_HOOK_FILE_PATTERN.test(f)) : [];
16946
+ const templateFiles = fs32.existsSync(kitCommandsDir) ? fs32.readdirSync(kitCommandsDir).filter((f) => f.endsWith(".md") && !COMMAND_HOOK_FILE_PATTERN.test(f)) : [];
16947
+ const projectFiles = fs32.existsSync(projectCommandsDir) ? fs32.readdirSync(projectCommandsDir).filter((f) => f.endsWith(".md") && !COMMAND_HOOK_FILE_PATTERN.test(f)) : [];
16838
16948
  const seen = /* @__PURE__ */ new Set();
16839
16949
  const files = [];
16840
16950
  for (const name of templateFiles) {
16841
16951
  seen.add(name);
16842
- const projectPath2 = path33.join(projectCommandsDir, name);
16843
- const templatePath = path33.join(kitCommandsDir, name);
16844
- const templateRaw = fs31.readFileSync(templatePath, "utf8");
16845
- if (!fs31.existsSync(projectPath2)) {
16952
+ const projectPath2 = path34.join(projectCommandsDir, name);
16953
+ const templatePath = path34.join(kitCommandsDir, name);
16954
+ const templateRaw = fs32.readFileSync(templatePath, "utf8");
16955
+ if (!fs32.existsSync(projectPath2)) {
16846
16956
  files.push({ name, status: "missing", kit_version: kitVersion });
16847
16957
  continue;
16848
16958
  }
16849
- const projectContent = fs31.readFileSync(projectPath2, "utf8");
16959
+ const projectContent = fs32.readFileSync(projectPath2, "utf8");
16850
16960
  const pinned = parsePinnedVersion(projectContent);
16851
16961
  const versionForCompare = pinned ?? kitVersion;
16852
16962
  const templateContent = applyCommandPlaceholders(templateRaw, versionForCompare);
@@ -16884,10 +16994,10 @@ function detectCommandDrift(args) {
16884
16994
  function readKitVersionFromCommandsDir(kitCommandsDir) {
16885
16995
  let dir = kitCommandsDir;
16886
16996
  for (let i = 0; i < 5; i++) {
16887
- dir = path33.dirname(dir);
16997
+ dir = path34.dirname(dir);
16888
16998
  }
16889
16999
  try {
16890
- const raw = fs31.readFileSync(path33.join(dir, "package.json"), "utf-8");
17000
+ const raw = fs32.readFileSync(path34.join(dir, "package.json"), "utf-8");
16891
17001
  const pkg = JSON.parse(raw);
16892
17002
  return typeof pkg.version === "string" ? pkg.version : "unknown";
16893
17003
  } catch {
@@ -16904,13 +17014,13 @@ function detectScaffoldedDrift(args) {
16904
17014
  };
16905
17015
  }
16906
17016
  function updateWorkflows(args) {
16907
- const projectWorkflowsDir = path33.join(
17017
+ const projectWorkflowsDir = path34.join(
16908
17018
  args.projectDir,
16909
17019
  ".github",
16910
17020
  "workflows"
16911
17021
  );
16912
- const here = path33.dirname(new URL(import.meta.url).pathname);
16913
- const kitWorkflowsDir = args.kitDir ? path33.join(
17022
+ const here = path34.dirname(new URL(import.meta.url).pathname);
17023
+ const kitWorkflowsDir = args.kitDir ? path34.join(
16914
17024
  args.kitDir,
16915
17025
  "templates",
16916
17026
  "project",
@@ -16921,22 +17031,22 @@ function updateWorkflows(args) {
16921
17031
  const substitute = args.substitute !== false;
16922
17032
  const dryRun = args.dryRun === true;
16923
17033
  const pruneExtras = args.pruneExtras === true;
16924
- const templateFiles = fs31.existsSync(kitWorkflowsDir) ? fs31.readdirSync(kitWorkflowsDir).filter((f) => f.endsWith(".yml")) : [];
16925
- const projectFiles = fs31.existsSync(projectWorkflowsDir) ? fs31.readdirSync(projectWorkflowsDir).filter((f) => f.endsWith(".yml")) : [];
16926
- if (!dryRun && templateFiles.length > 0 && !fs31.existsSync(projectWorkflowsDir)) {
16927
- fs31.mkdirSync(projectWorkflowsDir, { recursive: true });
17034
+ const templateFiles = fs32.existsSync(kitWorkflowsDir) ? fs32.readdirSync(kitWorkflowsDir).filter((f) => f.endsWith(".yml")) : [];
17035
+ const projectFiles = fs32.existsSync(projectWorkflowsDir) ? fs32.readdirSync(projectWorkflowsDir).filter((f) => f.endsWith(".yml")) : [];
17036
+ if (!dryRun && templateFiles.length > 0 && !fs32.existsSync(projectWorkflowsDir)) {
17037
+ fs32.mkdirSync(projectWorkflowsDir, { recursive: true });
16928
17038
  }
16929
17039
  const version = substitute ? readKitVersion(kitWorkflowsDir) : "";
16930
17040
  const seen = /* @__PURE__ */ new Set();
16931
17041
  const files = [];
16932
17042
  for (const name of templateFiles) {
16933
17043
  seen.add(name);
16934
- const projectPath2 = path33.join(projectWorkflowsDir, name);
16935
- const templatePath = path33.join(kitWorkflowsDir, name);
16936
- const templateRaw = fs31.readFileSync(templatePath, "utf-8");
17044
+ const projectPath2 = path34.join(projectWorkflowsDir, name);
17045
+ const templatePath = path34.join(kitWorkflowsDir, name);
17046
+ const templateRaw = fs32.readFileSync(templatePath, "utf-8");
16937
17047
  const desired = substitute ? applyPlaceholders(templateRaw, version) : templateRaw;
16938
- const existed = fs31.existsSync(projectPath2);
16939
- const current = existed ? fs31.readFileSync(projectPath2, "utf-8") : "";
17048
+ const existed = fs32.existsSync(projectPath2);
17049
+ const current = existed ? fs32.readFileSync(projectPath2, "utf-8") : "";
16940
17050
  let outcome;
16941
17051
  if (!existed) {
16942
17052
  outcome = "added";
@@ -16946,16 +17056,16 @@ function updateWorkflows(args) {
16946
17056
  outcome = "updated";
16947
17057
  }
16948
17058
  if (!dryRun && outcome !== "unchanged") {
16949
- fs31.writeFileSync(projectPath2, desired);
17059
+ fs32.writeFileSync(projectPath2, desired);
16950
17060
  }
16951
17061
  files.push({ name, outcome });
16952
17062
  }
16953
17063
  if (pruneExtras) {
16954
17064
  for (const name of projectFiles) {
16955
17065
  if (seen.has(name)) continue;
16956
- const projectPath2 = path33.join(projectWorkflowsDir, name);
17066
+ const projectPath2 = path34.join(projectWorkflowsDir, name);
16957
17067
  if (!dryRun) {
16958
- fs31.unlinkSync(projectPath2);
17068
+ fs32.unlinkSync(projectPath2);
16959
17069
  }
16960
17070
  files.push({ name, outcome: "removed" });
16961
17071
  }
@@ -17588,15 +17698,15 @@ function parentForTopology(t, defaultLeaf) {
17588
17698
 
17589
17699
  // scripts/lakebase/scm-doctor.ts
17590
17700
  init_esm_shims();
17591
- import * as fs32 from "fs";
17592
- import * as path34 from "path";
17701
+ import * as fs33 from "fs";
17702
+ import * as path35 from "path";
17593
17703
  var FEATURE_PREFIX = "feature/";
17594
17704
  var TIER_LEAFS2 = DEFAULT_PROTECTED_TIER_NAMES;
17595
17705
  function readEnv(projectDir) {
17596
- const envPath = path34.join(projectDir, ".env");
17706
+ const envPath = path35.join(projectDir, ".env");
17597
17707
  const out = /* @__PURE__ */ new Map();
17598
- if (!fs32.existsSync(envPath)) return out;
17599
- const lines = fs32.readFileSync(envPath, "utf8").split("\n");
17708
+ if (!fs33.existsSync(envPath)) return out;
17709
+ const lines = fs33.readFileSync(envPath, "utf8").split("\n");
17600
17710
  for (const line of lines) {
17601
17711
  const m = line.match(/^\s*([A-Z0-9_]+)\s*=\s*(.+?)\s*$/);
17602
17712
  if (m) out.set(m[1], m[2].replace(/^["']|["']$/g, ""));
@@ -17651,9 +17761,9 @@ async function runDoctor(args, deps = {}) {
17651
17761
  }
17652
17762
  for (const wf of ["pr.yml", "merge.yml"]) {
17653
17763
  try {
17654
- const p = path34.join(projectDir, ".github", "workflows", wf);
17655
- if (!fs32.existsSync(p)) continue;
17656
- const body = fs32.readFileSync(p, "utf8");
17764
+ const p = path35.join(projectDir, ".github", "workflows", wf);
17765
+ if (!fs33.existsSync(p)) continue;
17766
+ const body = fs33.readFileSync(p, "utf8");
17657
17767
  if (/lakebase-scm-utils#v\d/.test(body)) {
17658
17768
  findings.push({
17659
17769
  id: "ci-workflow-substrate-pin",
@@ -17868,7 +17978,7 @@ async function fixFinding(args) {
17868
17978
  );
17869
17979
  }
17870
17980
  const sanitized = sanitizeBranchName(branch);
17871
- const envFile = path34.join(args.projectDir, ".env");
17981
+ const envFile = path35.join(args.projectDir, ".env");
17872
17982
  updateEnvConnection({
17873
17983
  envPath: envFile,
17874
17984
  projectId: readEnvVar(envFile, "LAKEBASE_PROJECT_ID") ?? "",
@@ -17970,14 +18080,14 @@ function shellEscape3(s) {
17970
18080
 
17971
18081
  // scripts/lakebase/doctor.ts
17972
18082
  init_esm_shims();
17973
- import * as fs33 from "fs";
17974
- import * as path35 from "path";
18083
+ import * as fs34 from "fs";
18084
+ import * as path36 from "path";
17975
18085
  import * as cp6 from "child_process";
17976
18086
  function readEnvFile(projectDir) {
17977
- const envPath = path35.join(projectDir, ".env");
17978
- if (!fs33.existsSync(envPath)) return {};
18087
+ const envPath = path36.join(projectDir, ".env");
18088
+ if (!fs34.existsSync(envPath)) return {};
17979
18089
  const out = {};
17980
- for (const line of fs33.readFileSync(envPath, "utf8").split("\n")) {
18090
+ for (const line of fs34.readFileSync(envPath, "utf8").split("\n")) {
17981
18091
  const m = line.match(/^\s*([A-Z][A-Z0-9_]*)\s*=\s*(.*)\s*$/);
17982
18092
  if (!m) continue;
17983
18093
  let val = m[2];
@@ -18249,7 +18359,7 @@ function checkEnv(projectDir) {
18249
18359
  name: "env-file",
18250
18360
  status: "warn",
18251
18361
  message: ".env not found",
18252
- detail: { projectDir, envPath: path35.join(projectDir, ".env") },
18362
+ detail: { projectDir, envPath: path36.join(projectDir, ".env") },
18253
18363
  hint: "Run `lakebase-branch sync-env`, or `git checkout <branch>` so the post-checkout hook writes .env (or copy .env.example). The kit stores connection METADATA only , no DB token (the app mints a short-lived credential at runtime)."
18254
18364
  };
18255
18365
  }
@@ -18744,8 +18854,8 @@ async function listMigrationsOnBranch(args) {
18744
18854
 
18745
18855
  // scripts/git/commits.ts
18746
18856
  init_esm_shims();
18747
- import { existsSync as existsSync32 } from "fs";
18748
- import { join as join35 } from "path";
18857
+ import { existsSync as existsSync33 } from "fs";
18858
+ import { join as join36 } from "path";
18749
18859
  var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
18750
18860
  ".py",
18751
18861
  ".ts",
@@ -18848,7 +18958,7 @@ async function commitAllIfChanged(args) {
18848
18958
  await exec2("git add -A", { cwd: args.cwd });
18849
18959
  }
18850
18960
  for (const inc of args.include ?? []) {
18851
- if (existsSync32(join35(args.cwd, inc))) {
18961
+ if (existsSync33(join36(args.cwd, inc))) {
18852
18962
  await exec2(`git add -f -- ${shq(inc)}`, { cwd: args.cwd });
18853
18963
  }
18854
18964
  }
@@ -18990,14 +19100,14 @@ async function stashDropAll(args) {
18990
19100
 
18991
19101
  // scripts/git/rebase.ts
18992
19102
  init_esm_shims();
18993
- import * as fs34 from "fs";
18994
- import * as path36 from "path";
19103
+ import * as fs35 from "fs";
19104
+ import * as path37 from "path";
18995
19105
  async function abortRebase(args) {
18996
19106
  await exec2("git rebase --abort", { cwd: args.cwd });
18997
19107
  }
18998
19108
  async function isRebasing(args) {
18999
19109
  try {
19000
- return fs34.existsSync(path36.join(args.cwd, ".git/rebase-merge")) || fs34.existsSync(path36.join(args.cwd, ".git/rebase-apply"));
19110
+ return fs35.existsSync(path37.join(args.cwd, ".git/rebase-merge")) || fs35.existsSync(path37.join(args.cwd, ".git/rebase-apply"));
19001
19111
  } catch {
19002
19112
  return false;
19003
19113
  }
@@ -19176,42 +19286,6 @@ function isCliEntry(importMetaUrl) {
19176
19286
  }
19177
19287
  return invokedResolved === moduleResolved;
19178
19288
  }
19179
-
19180
- // scripts/util/proxy-env.ts
19181
- init_esm_shims();
19182
- var PROXY_ENV_KEYS = [
19183
- "HTTP_PROXY",
19184
- "HTTPS_PROXY",
19185
- "NO_PROXY",
19186
- "http_proxy",
19187
- "https_proxy",
19188
- "no_proxy",
19189
- "npm_config_proxy",
19190
- "npm_config_https_proxy",
19191
- "npm_config_no_proxy",
19192
- "npm_config_registry"
19193
- ];
19194
- function proxyEnvSubset(source = process.env) {
19195
- const out = {};
19196
- for (const key of PROXY_ENV_KEYS) {
19197
- const v = source[key];
19198
- if (v !== void 0 && v !== "") {
19199
- out[key] = v;
19200
- }
19201
- }
19202
- return out;
19203
- }
19204
- function withProxyEnv(base = {}) {
19205
- const out = {};
19206
- const inherited = proxyEnvSubset();
19207
- for (const [k, v] of Object.entries(inherited)) {
19208
- out[k] = v;
19209
- }
19210
- for (const [k, v] of Object.entries(base)) {
19211
- if (v !== void 0) out[k] = v;
19212
- }
19213
- return out;
19214
- }
19215
19289
  export {
19216
19290
  CI_TOKEN_LIFETIME_SECONDS,
19217
19291
  CI_TOKEN_REMINT_MARGIN_SECONDS,