@specific.dev/cli 0.1.75 → 0.1.77

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 (68) hide show
  1. package/dist/admin/404/index.html +1 -1
  2. package/dist/admin/404.html +1 -1
  3. package/dist/admin/__next.!KGRlZmF1bHQp.__PAGE__.txt +1 -1
  4. package/dist/admin/__next.!KGRlZmF1bHQp.txt +1 -1
  5. package/dist/admin/__next._full.txt +1 -1
  6. package/dist/admin/__next._head.txt +1 -1
  7. package/dist/admin/__next._index.txt +1 -1
  8. package/dist/admin/__next._tree.txt +1 -1
  9. package/dist/admin/_not-found/__next._full.txt +1 -1
  10. package/dist/admin/_not-found/__next._head.txt +1 -1
  11. package/dist/admin/_not-found/__next._index.txt +1 -1
  12. package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
  13. package/dist/admin/_not-found/__next._not-found.txt +1 -1
  14. package/dist/admin/_not-found/__next._tree.txt +1 -1
  15. package/dist/admin/_not-found/index.html +1 -1
  16. package/dist/admin/_not-found/index.txt +1 -1
  17. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +1 -1
  18. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +1 -1
  19. package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +1 -1
  20. package/dist/admin/databases/__next._full.txt +1 -1
  21. package/dist/admin/databases/__next._head.txt +1 -1
  22. package/dist/admin/databases/__next._index.txt +1 -1
  23. package/dist/admin/databases/__next._tree.txt +1 -1
  24. package/dist/admin/databases/index.html +1 -1
  25. package/dist/admin/databases/index.txt +1 -1
  26. package/dist/admin/fullscreen/__next._full.txt +1 -1
  27. package/dist/admin/fullscreen/__next._head.txt +1 -1
  28. package/dist/admin/fullscreen/__next._index.txt +1 -1
  29. package/dist/admin/fullscreen/__next._tree.txt +1 -1
  30. package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +1 -1
  31. package/dist/admin/fullscreen/__next.fullscreen.txt +1 -1
  32. package/dist/admin/fullscreen/databases/__next._full.txt +1 -1
  33. package/dist/admin/fullscreen/databases/__next._head.txt +1 -1
  34. package/dist/admin/fullscreen/databases/__next._index.txt +1 -1
  35. package/dist/admin/fullscreen/databases/__next._tree.txt +1 -1
  36. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +1 -1
  37. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +1 -1
  38. package/dist/admin/fullscreen/databases/__next.fullscreen.txt +1 -1
  39. package/dist/admin/fullscreen/databases/index.html +1 -1
  40. package/dist/admin/fullscreen/databases/index.txt +1 -1
  41. package/dist/admin/fullscreen/index.html +1 -1
  42. package/dist/admin/fullscreen/index.txt +1 -1
  43. package/dist/admin/index.html +1 -1
  44. package/dist/admin/index.txt +1 -1
  45. package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.__PAGE__.txt +1 -1
  46. package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.txt +1 -1
  47. package/dist/admin/mail/__next.!KGRlZmF1bHQp.txt +1 -1
  48. package/dist/admin/mail/__next._full.txt +1 -1
  49. package/dist/admin/mail/__next._head.txt +1 -1
  50. package/dist/admin/mail/__next._index.txt +1 -1
  51. package/dist/admin/mail/__next._tree.txt +1 -1
  52. package/dist/admin/mail/index.html +1 -1
  53. package/dist/admin/mail/index.txt +1 -1
  54. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +1 -1
  55. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +1 -1
  56. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +1 -1
  57. package/dist/admin/workflows/__next._full.txt +1 -1
  58. package/dist/admin/workflows/__next._head.txt +1 -1
  59. package/dist/admin/workflows/__next._index.txt +1 -1
  60. package/dist/admin/workflows/__next._tree.txt +1 -1
  61. package/dist/admin/workflows/index.html +1 -1
  62. package/dist/admin/workflows/index.txt +1 -1
  63. package/dist/cli.js +260 -291
  64. package/dist/postinstall.js +1 -1
  65. package/package.json +1 -1
  66. /package/dist/admin/_next/static/{ntsk0waJiBFcaeQ8sbm0K → P2MjAcNNtToSRrG27euV4}/_buildManifest.js +0 -0
  67. /package/dist/admin/_next/static/{ntsk0waJiBFcaeQ8sbm0K → P2MjAcNNtToSRrG27euV4}/_clientMiddlewareManifest.json +0 -0
  68. /package/dist/admin/_next/static/{ntsk0waJiBFcaeQ8sbm0K → P2MjAcNNtToSRrG27euV4}/_ssgManifest.js +0 -0
package/dist/cli.js CHANGED
@@ -39,10 +39,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
39
39
  ));
40
40
 
41
41
  // node_modules/.pnpm/is-docker@3.0.0/node_modules/is-docker/index.js
42
- import fs6 from "node:fs";
42
+ import fs5 from "node:fs";
43
43
  function hasDockerEnv() {
44
44
  try {
45
- fs6.statSync("/.dockerenv");
45
+ fs5.statSync("/.dockerenv");
46
46
  return true;
47
47
  } catch {
48
48
  return false;
@@ -50,7 +50,7 @@ function hasDockerEnv() {
50
50
  }
51
51
  function hasDockerCGroup() {
52
52
  try {
53
- return fs6.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
53
+ return fs5.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
54
54
  } catch {
55
55
  return false;
56
56
  }
@@ -68,7 +68,7 @@ var init_is_docker = __esm({
68
68
  });
69
69
 
70
70
  // node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
71
- import fs7 from "node:fs";
71
+ import fs6 from "node:fs";
72
72
  function isInsideContainer() {
73
73
  if (cachedResult === void 0) {
74
74
  cachedResult = hasContainerEnv() || isDocker();
@@ -81,7 +81,7 @@ var init_is_inside_container = __esm({
81
81
  init_is_docker();
82
82
  hasContainerEnv = () => {
83
83
  try {
84
- fs7.statSync("/run/.containerenv");
84
+ fs6.statSync("/run/.containerenv");
85
85
  return true;
86
86
  } catch {
87
87
  return false;
@@ -92,8 +92,8 @@ var init_is_inside_container = __esm({
92
92
 
93
93
  // node_modules/.pnpm/is-wsl@3.1.0/node_modules/is-wsl/index.js
94
94
  import process2 from "node:process";
95
- import os5 from "node:os";
96
- import fs8 from "node:fs";
95
+ import os4 from "node:os";
96
+ import fs7 from "node:fs";
97
97
  var isWsl, is_wsl_default;
98
98
  var init_is_wsl = __esm({
99
99
  "node_modules/.pnpm/is-wsl@3.1.0/node_modules/is-wsl/index.js"() {
@@ -102,14 +102,14 @@ var init_is_wsl = __esm({
102
102
  if (process2.platform !== "linux") {
103
103
  return false;
104
104
  }
105
- if (os5.release().toLowerCase().includes("microsoft")) {
105
+ if (os4.release().toLowerCase().includes("microsoft")) {
106
106
  if (isInsideContainer()) {
107
107
  return false;
108
108
  }
109
109
  return true;
110
110
  }
111
111
  try {
112
- return fs8.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
112
+ return fs7.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
113
113
  } catch {
114
114
  return false;
115
115
  }
@@ -179,7 +179,7 @@ var init_utilities = __esm({
179
179
  // node_modules/.pnpm/wsl-utils@0.3.1/node_modules/wsl-utils/index.js
180
180
  import { promisify as promisify2 } from "node:util";
181
181
  import childProcess2 from "node:child_process";
182
- import fs9, { constants as fsConstants } from "node:fs/promises";
182
+ import fs8, { constants as fsConstants } from "node:fs/promises";
183
183
  var execFile2, wslDrivesMountPoint, powerShellPathFromWsl, powerShellPath2, canAccessPowerShellPromise, canAccessPowerShell, wslDefaultBrowser, convertWslPathToWindows;
184
184
  var init_wsl_utils = __esm({
185
185
  "node_modules/.pnpm/wsl-utils@0.3.1/node_modules/wsl-utils/index.js"() {
@@ -198,14 +198,14 @@ var init_wsl_utils = __esm({
198
198
  const configFilePath = "/etc/wsl.conf";
199
199
  let isConfigFileExists = false;
200
200
  try {
201
- await fs9.access(configFilePath, fsConstants.F_OK);
201
+ await fs8.access(configFilePath, fsConstants.F_OK);
202
202
  isConfigFileExists = true;
203
203
  } catch {
204
204
  }
205
205
  if (!isConfigFileExists) {
206
206
  return defaultMountPoint;
207
207
  }
208
- const configContent = await fs9.readFile(configFilePath, { encoding: "utf8" });
208
+ const configContent = await fs8.readFile(configFilePath, { encoding: "utf8" });
209
209
  const parsedMountPoint = parseMountPointFromConfig(configContent);
210
210
  if (parsedMountPoint === void 0) {
211
211
  return defaultMountPoint;
@@ -224,7 +224,7 @@ var init_wsl_utils = __esm({
224
224
  canAccessPowerShellPromise ??= (async () => {
225
225
  try {
226
226
  const psPath = await powerShellPath2();
227
- await fs9.access(psPath, fsConstants.X_OK);
227
+ await fs8.access(psPath, fsConstants.X_OK);
228
228
  return true;
229
229
  } catch {
230
230
  return false;
@@ -435,7 +435,7 @@ import process8 from "node:process";
435
435
  import path5 from "node:path";
436
436
  import { fileURLToPath } from "node:url";
437
437
  import childProcess3 from "node:child_process";
438
- import fs10, { constants as fsConstants2 } from "node:fs/promises";
438
+ import fs9, { constants as fsConstants2 } from "node:fs/promises";
439
439
  function detectArchBinary(binary) {
440
440
  if (typeof binary === "string" || Array.isArray(binary)) {
441
441
  return binary;
@@ -446,16 +446,16 @@ function detectArchBinary(binary) {
446
446
  }
447
447
  return archBinary;
448
448
  }
449
- function detectPlatformBinary({ [platform4]: platformBinary }, { wsl } = {}) {
449
+ function detectPlatformBinary({ [platform3]: platformBinary }, { wsl } = {}) {
450
450
  if (wsl && is_wsl_default) {
451
451
  return detectArchBinary(wsl);
452
452
  }
453
453
  if (!platformBinary) {
454
- throw new Error(`${platform4} is not supported`);
454
+ throw new Error(`${platform3} is not supported`);
455
455
  }
456
456
  return detectArchBinary(platformBinary);
457
457
  }
458
- var fallbackAttemptSymbol, __dirname, localXdgOpenPath, platform4, arch, tryEachApp, baseOpen, open, openApp, apps, open_default;
458
+ var fallbackAttemptSymbol, __dirname, localXdgOpenPath, platform3, arch, tryEachApp, baseOpen, open, openApp, apps, open_default;
459
459
  var init_open = __esm({
460
460
  "node_modules/.pnpm/open@11.0.0/node_modules/open/index.js"() {
461
461
  init_wsl_utils();
@@ -467,7 +467,7 @@ var init_open = __esm({
467
467
  fallbackAttemptSymbol = Symbol("fallbackAttempt");
468
468
  __dirname = import.meta.url ? path5.dirname(fileURLToPath(import.meta.url)) : "";
469
469
  localXdgOpenPath = path5.join(__dirname, "xdg-open");
470
- ({ platform: platform4, arch } = process8);
470
+ ({ platform: platform3, arch } = process8);
471
471
  tryEachApp = async (apps2, opener) => {
472
472
  if (apps2.length === 0) {
473
473
  return;
@@ -564,7 +564,7 @@ var init_open = __esm({
564
564
  if (is_wsl_default && !isInsideContainer() && !is_in_ssh_default && !app) {
565
565
  shouldUseWindowsInWsl = await canAccessPowerShell();
566
566
  }
567
- if (platform4 === "darwin") {
567
+ if (platform3 === "darwin") {
568
568
  command = "open";
569
569
  if (options2.wait) {
570
570
  cliArguments.push("--wait-apps");
@@ -578,7 +578,7 @@ var init_open = __esm({
578
578
  if (app) {
579
579
  cliArguments.push("-a", app);
580
580
  }
581
- } else if (platform4 === "win32" || shouldUseWindowsInWsl) {
581
+ } else if (platform3 === "win32" || shouldUseWindowsInWsl) {
582
582
  command = await powerShellPath2();
583
583
  cliArguments.push(...executePowerShell.argumentsPrefix);
584
584
  if (!is_wsl_default) {
@@ -614,11 +614,11 @@ var init_open = __esm({
614
614
  const isBundled = !__dirname || __dirname === "/";
615
615
  let exeLocalXdgOpen = false;
616
616
  try {
617
- await fs10.access(localXdgOpenPath, fsConstants2.X_OK);
617
+ await fs9.access(localXdgOpenPath, fsConstants2.X_OK);
618
618
  exeLocalXdgOpen = true;
619
619
  } catch {
620
620
  }
621
- const useSystemXdgOpen = process8.versions.electron ?? (platform4 === "android" || isBundled || !exeLocalXdgOpen);
621
+ const useSystemXdgOpen = process8.versions.electron ?? (platform3 === "android" || isBundled || !exeLocalXdgOpen);
622
622
  command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
623
623
  }
624
624
  if (appArguments.length > 0) {
@@ -629,7 +629,7 @@ var init_open = __esm({
629
629
  childProcessOptions.detached = true;
630
630
  }
631
631
  }
632
- if (platform4 === "darwin" && appArguments.length > 0) {
632
+ if (platform3 === "darwin" && appArguments.length > 0) {
633
633
  cliArguments.push("--args", ...appArguments);
634
634
  }
635
635
  if (options2.target) {
@@ -754,8 +754,8 @@ var require_dist = __commonJS({
754
754
  var $global, $module, $NaN = NaN;
755
755
  if ("undefined" != typeof window ? $global = window : "undefined" != typeof self ? $global = self : "undefined" != typeof global ? ($global = global).require = __require : $global = this, void 0 === $global || void 0 === $global.Array) throw new Error("no global object found");
756
756
  if ("undefined" != typeof module && ($module = module), !$global.fs && $global.require) try {
757
- var fs33 = $global.require("fs");
758
- "object" == typeof fs33 && null !== fs33 && 0 !== Object.keys(fs33).length && ($global.fs = fs33);
757
+ var fs32 = $global.require("fs");
758
+ "object" == typeof fs32 && null !== fs32 && 0 !== Object.keys(fs32).length && ($global.fs = fs32);
759
759
  } catch (e) {
760
760
  }
761
761
  if (!$global.fs) {
@@ -183430,13 +183430,11 @@ import { Command } from "commander";
183430
183430
  import React2, { useState, useEffect } from "react";
183431
183431
  import { render as render2, Text as Text2, Box as Box2, useInput, useApp } from "ink";
183432
183432
  import "ink-spinner";
183433
- import * as fs12 from "fs";
183433
+ import * as fs11 from "fs";
183434
183434
  import * as path7 from "path";
183435
183435
 
183436
183436
  // src/lib/dev/system-setup.ts
183437
183437
  import { execSync as execSync2 } from "child_process";
183438
- import * as fs4 from "fs";
183439
- import * as os4 from "os";
183440
183438
  import * as path3 from "path";
183441
183439
 
183442
183440
  // src/lib/dev/local-ca.ts
@@ -183472,17 +183470,17 @@ function caInstalledInTrustStore() {
183472
183470
  if (!caFilesExist()) {
183473
183471
  return false;
183474
183472
  }
183475
- const platform6 = os.platform();
183473
+ const platform5 = os.platform();
183476
183474
  const certPath = path.join(getCADir(), "ca.crt");
183477
183475
  const diskCert = fs.readFileSync(certPath, "utf-8").replace(/\r\n/g, "\n").trim();
183478
183476
  try {
183479
- if (platform6 === "darwin") {
183477
+ if (platform5 === "darwin") {
183480
183478
  const keychainCert = execSync(
183481
183479
  'security find-certificate -c "Specific Local Development CA" -p /Library/Keychains/System.keychain',
183482
183480
  { encoding: "utf-8" }
183483
183481
  ).replace(/\r\n/g, "\n").trim();
183484
183482
  return keychainCert === diskCert;
183485
- } else if (platform6 === "linux") {
183483
+ } else if (platform5 === "linux") {
183486
183484
  const trustPaths = [
183487
183485
  "/usr/local/share/ca-certificates/specific-local-ca.crt",
183488
183486
  // Debian/Ubuntu
@@ -183594,15 +183592,15 @@ function removeCA() {
183594
183592
  }
183595
183593
  }
183596
183594
  function getCAInstallCommands(certPath) {
183597
- const platform6 = os.platform();
183598
- if (platform6 === "darwin") {
183595
+ const platform5 = os.platform();
183596
+ if (platform5 === "darwin") {
183599
183597
  return [
183600
183598
  // Remove any existing cert with the same CN first — add-trusted-cert
183601
183599
  // silently does nothing if a cert with the same subject already exists.
183602
183600
  'security delete-certificate -c "Specific Local Development CA" /Library/Keychains/System.keychain 2>/dev/null || true',
183603
183601
  `security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "${certPath}"`
183604
183602
  ];
183605
- } else if (platform6 === "linux") {
183603
+ } else if (platform5 === "linux") {
183606
183604
  if (fs.existsSync("/usr/local/share/ca-certificates")) {
183607
183605
  return [
183608
183606
  `cp "${certPath}" /usr/local/share/ca-certificates/specific-local-ca.crt`,
@@ -183621,7 +183619,7 @@ function getCAInstallCommands(certPath) {
183621
183619
  }
183622
183620
  throw new Error("Could not detect Linux certificate trust mechanism");
183623
183621
  }
183624
- throw new Error(`Unsupported platform: ${platform6}`);
183622
+ throw new Error(`Unsupported platform: ${platform5}`);
183625
183623
  }
183626
183624
  function generateCertificate(domain, keys = []) {
183627
183625
  const caDir = getCADir();
@@ -183667,23 +183665,23 @@ var RESOLVER_FILE_MACOS = "/etc/resolver/spcf.localhost";
183667
183665
  var OLD_RESOLVER_FILE_MACOS = "/etc/resolver/local.spcf.app";
183668
183666
  var RESOLVER_FILE_LINUX = "/etc/systemd/resolved.conf.d/specific-local.conf";
183669
183667
  function resolverConfigExists() {
183670
- const platform6 = os2.platform();
183671
- if (platform6 === "darwin") {
183668
+ const platform5 = os2.platform();
183669
+ if (platform5 === "darwin") {
183672
183670
  return fs2.existsSync(RESOLVER_FILE_MACOS);
183673
- } else if (platform6 === "linux") {
183671
+ } else if (platform5 === "linux") {
183674
183672
  return fs2.existsSync(RESOLVER_FILE_LINUX);
183675
183673
  }
183676
183674
  return false;
183677
183675
  }
183678
183676
  function getResolverInstallCommands(port) {
183679
- const platform6 = os2.platform();
183680
- if (platform6 === "darwin") {
183677
+ const platform5 = os2.platform();
183678
+ if (platform5 === "darwin") {
183681
183679
  return [
183682
183680
  "mkdir -p /etc/resolver",
183683
183681
  `rm -f ${OLD_RESOLVER_FILE_MACOS}`,
183684
183682
  `printf "nameserver 127.0.0.1\\nport ${port}\\n" > ${RESOLVER_FILE_MACOS}`
183685
183683
  ];
183686
- } else if (platform6 === "linux") {
183684
+ } else if (platform5 === "linux") {
183687
183685
  if (fs2.existsSync("/etc/systemd/resolved.conf.d") || fs2.existsSync("/etc/systemd")) {
183688
183686
  return [
183689
183687
  "mkdir -p /etc/systemd/resolved.conf.d",
@@ -183802,7 +183800,7 @@ function performSystemSetup() {
183802
183800
  return;
183803
183801
  }
183804
183802
  try {
183805
- execPrivileged(commands);
183803
+ execSync2(`sudo sh -c '${commands.join(" && ")}'`, { stdio: "inherit" });
183806
183804
  } catch (err) {
183807
183805
  if (needsGenerate) {
183808
183806
  removeCA();
@@ -183810,43 +183808,14 @@ function performSystemSetup() {
183810
183808
  throw err;
183811
183809
  }
183812
183810
  }
183813
- function execPrivileged(commands) {
183814
- if (commands.length === 0) return;
183815
- if (os4.platform() === "darwin") {
183816
- const scriptPath = path3.join(os4.tmpdir(), "specific-setup.sh");
183817
- const appPath = path3.join(os4.tmpdir(), "Specific.app");
183818
- try {
183819
- fs4.writeFileSync(
183820
- scriptPath,
183821
- "#!/bin/sh\nset -e\n" + commands.join("\n") + "\n",
183822
- { mode: 448 }
183823
- );
183824
- execSync2(
183825
- `osacompile -o '${appPath}' -e 'do shell script "sh ${scriptPath}" with administrator privileges'`
183826
- );
183827
- execSync2(`'${appPath}/Contents/MacOS/applet'`, { stdio: "pipe" });
183828
- } finally {
183829
- try {
183830
- fs4.unlinkSync(scriptPath);
183831
- } catch {
183832
- }
183833
- try {
183834
- fs4.rmSync(appPath, { recursive: true });
183835
- } catch {
183836
- }
183837
- }
183838
- } else {
183839
- execSync2(`sudo sh -c '${commands.join(" && ")}'`, { stdio: "inherit" });
183840
- }
183841
- }
183842
183811
 
183843
183812
  // src/lib/analytics/index.ts
183844
183813
  import { PostHog } from "posthog-node";
183845
- import * as os7 from "os";
183814
+ import * as os6 from "os";
183846
183815
  import * as crypto from "crypto";
183847
183816
 
183848
183817
  // src/lib/project/config.ts
183849
- import * as fs5 from "fs";
183818
+ import * as fs4 from "fs";
183850
183819
  import * as path4 from "path";
183851
183820
  var PROJECT_ID_FILE = ".specific/project_id";
183852
183821
  var ProjectNotLinkedError = class extends Error {
@@ -183863,10 +183832,10 @@ Run: specific deploy`
183863
183832
  };
183864
183833
  function readProjectId(projectDir = process.cwd()) {
183865
183834
  const projectIdPath = path4.join(projectDir, PROJECT_ID_FILE);
183866
- if (!fs5.existsSync(projectIdPath)) {
183835
+ if (!fs4.existsSync(projectIdPath)) {
183867
183836
  throw new ProjectNotLinkedError();
183868
183837
  }
183869
- const projectId = fs5.readFileSync(projectIdPath, "utf-8").trim();
183838
+ const projectId = fs4.readFileSync(projectIdPath, "utf-8").trim();
183870
183839
  if (!projectId) {
183871
183840
  throw new Error(`${PROJECT_ID_FILE} is empty`);
183872
183841
  }
@@ -183874,20 +183843,20 @@ function readProjectId(projectDir = process.cwd()) {
183874
183843
  }
183875
183844
  function hasProjectId(projectDir = process.cwd()) {
183876
183845
  const projectIdPath = path4.join(projectDir, PROJECT_ID_FILE);
183877
- return fs5.existsSync(projectIdPath);
183846
+ return fs4.existsSync(projectIdPath);
183878
183847
  }
183879
183848
  function writeProjectId(projectId, projectDir = process.cwd()) {
183880
183849
  const specificDir = path4.join(projectDir, ".specific");
183881
- if (!fs5.existsSync(specificDir)) {
183882
- fs5.mkdirSync(specificDir, { recursive: true });
183850
+ if (!fs4.existsSync(specificDir)) {
183851
+ fs4.mkdirSync(specificDir, { recursive: true });
183883
183852
  }
183884
- fs5.writeFileSync(path4.join(specificDir, "project_id"), projectId + "\n");
183853
+ fs4.writeFileSync(path4.join(specificDir, "project_id"), projectId + "\n");
183885
183854
  }
183886
183855
 
183887
183856
  // src/lib/auth/credentials.ts
183888
- import * as fs11 from "fs";
183857
+ import * as fs10 from "fs";
183889
183858
  import * as path6 from "path";
183890
- import * as os6 from "os";
183859
+ import * as os5 from "os";
183891
183860
 
183892
183861
  // src/lib/auth/errors.ts
183893
183862
  var RefreshTokenExpiredError = class extends Error {
@@ -184468,18 +184437,18 @@ var ApiClient = class {
184468
184437
 
184469
184438
  // src/lib/auth/credentials.ts
184470
184439
  function getUserCredentialsDir() {
184471
- return path6.join(os6.homedir(), ".specific");
184440
+ return path6.join(os5.homedir(), ".specific");
184472
184441
  }
184473
184442
  function getCredentialsPath() {
184474
184443
  return path6.join(getUserCredentialsDir(), "credentials.json");
184475
184444
  }
184476
184445
  function readUserCredentials() {
184477
184446
  const credentialsPath = getCredentialsPath();
184478
- if (!fs11.existsSync(credentialsPath)) {
184447
+ if (!fs10.existsSync(credentialsPath)) {
184479
184448
  return null;
184480
184449
  }
184481
184450
  try {
184482
- const content = fs11.readFileSync(credentialsPath, "utf-8");
184451
+ const content = fs10.readFileSync(credentialsPath, "utf-8");
184483
184452
  return JSON.parse(content);
184484
184453
  } catch {
184485
184454
  return null;
@@ -184487,18 +184456,18 @@ function readUserCredentials() {
184487
184456
  }
184488
184457
  function writeUserCredentials(credentials) {
184489
184458
  const dir = getUserCredentialsDir();
184490
- if (!fs11.existsSync(dir)) {
184491
- fs11.mkdirSync(dir, { recursive: true, mode: 448 });
184459
+ if (!fs10.existsSync(dir)) {
184460
+ fs10.mkdirSync(dir, { recursive: true, mode: 448 });
184492
184461
  }
184493
184462
  const credentialsPath = getCredentialsPath();
184494
- fs11.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {
184463
+ fs10.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {
184495
184464
  mode: 384
184496
184465
  });
184497
184466
  }
184498
184467
  function clearUserCredentials() {
184499
184468
  const credentialsPath = getCredentialsPath();
184500
- if (fs11.existsSync(credentialsPath)) {
184501
- fs11.unlinkSync(credentialsPath);
184469
+ if (fs10.existsSync(credentialsPath)) {
184470
+ fs10.unlinkSync(credentialsPath);
184502
184471
  }
184503
184472
  }
184504
184473
  function isLoggedIn() {
@@ -184577,7 +184546,7 @@ function isEnabled() {
184577
184546
  }
184578
184547
  function getAnonymousId() {
184579
184548
  if (anonymousId) return anonymousId;
184580
- const machineId = `${os7.hostname()}-${os7.userInfo().username}`;
184549
+ const machineId = `${os6.hostname()}-${os6.userInfo().username}`;
184581
184550
  anonymousId = crypto.createHash("sha256").update(machineId).digest("hex").slice(0, 16);
184582
184551
  return anonymousId;
184583
184552
  }
@@ -184624,7 +184593,7 @@ function trackEvent(event, properties) {
184624
184593
  event,
184625
184594
  properties: {
184626
184595
  ...properties,
184627
- cli_version: "0.1.75",
184596
+ cli_version: "0.1.77",
184628
184597
  platform: process.platform,
184629
184598
  node_version: process.version,
184630
184599
  project_id: getProjectId()
@@ -184661,57 +184630,57 @@ var options = [
184661
184630
  ];
184662
184631
  function isGitProject() {
184663
184632
  const gitPath = path7.join(process.cwd(), ".git");
184664
- return fs12.existsSync(gitPath);
184633
+ return fs11.existsSync(gitPath);
184665
184634
  }
184666
184635
  function detectExistingAgents() {
184667
184636
  const detected = {};
184668
184637
  const cursorDir = path7.join(process.cwd(), ".cursor");
184669
- if (fs12.existsSync(cursorDir)) {
184638
+ if (fs11.existsSync(cursorDir)) {
184670
184639
  detected["cursor"] = true;
184671
184640
  }
184672
184641
  const claudeDir = path7.join(process.cwd(), ".claude");
184673
184642
  const claudeMd = path7.join(process.cwd(), "CLAUDE.md");
184674
- if (fs12.existsSync(claudeDir) || fs12.existsSync(claudeMd)) {
184643
+ if (fs11.existsSync(claudeDir) || fs11.existsSync(claudeMd)) {
184675
184644
  detected["claude"] = true;
184676
184645
  }
184677
184646
  const agentsMd = path7.join(process.cwd(), "AGENTS.md");
184678
- if (fs12.existsSync(agentsMd)) {
184647
+ if (fs11.existsSync(agentsMd)) {
184679
184648
  detected["codex"] = true;
184680
184649
  }
184681
184650
  return detected;
184682
184651
  }
184683
184652
  function appendOrCreateFile(filePath, content) {
184684
- if (fs12.existsSync(filePath)) {
184685
- const existing = fs12.readFileSync(filePath, "utf-8");
184653
+ if (fs11.existsSync(filePath)) {
184654
+ const existing = fs11.readFileSync(filePath, "utf-8");
184686
184655
  if (existing.includes("specific docs") || existing.includes("specific check")) {
184687
184656
  return "unchanged";
184688
184657
  }
184689
184658
  const separator = existing.endsWith("\n") ? "\n" : "\n\n";
184690
- fs12.writeFileSync(filePath, existing + separator + content + "\n");
184659
+ fs11.writeFileSync(filePath, existing + separator + content + "\n");
184691
184660
  return "modified";
184692
184661
  } else {
184693
- fs12.writeFileSync(filePath, content + "\n");
184662
+ fs11.writeFileSync(filePath, content + "\n");
184694
184663
  return "created";
184695
184664
  }
184696
184665
  }
184697
184666
  function addToGitignore() {
184698
184667
  const gitignorePath = path7.join(process.cwd(), ".gitignore");
184699
184668
  const entries = [".specific", "specific.local"];
184700
- if (fs12.existsSync(gitignorePath)) {
184701
- const existing = fs12.readFileSync(gitignorePath, "utf-8");
184669
+ if (fs11.existsSync(gitignorePath)) {
184670
+ const existing = fs11.readFileSync(gitignorePath, "utf-8");
184702
184671
  const lines = existing.split("\n").map((l) => l.trim());
184703
184672
  const missingEntries = entries.filter((entry) => !lines.includes(entry));
184704
184673
  if (missingEntries.length === 0) {
184705
184674
  return "unchanged";
184706
184675
  }
184707
184676
  const separator = existing.endsWith("\n") ? "" : "\n";
184708
- fs12.writeFileSync(
184677
+ fs11.writeFileSync(
184709
184678
  gitignorePath,
184710
184679
  existing + separator + missingEntries.join("\n") + "\n"
184711
184680
  );
184712
184681
  return "modified";
184713
184682
  } else {
184714
- fs12.writeFileSync(gitignorePath, entries.join("\n") + "\n");
184683
+ fs11.writeFileSync(gitignorePath, entries.join("\n") + "\n");
184715
184684
  return "created";
184716
184685
  }
184717
184686
  }
@@ -184719,8 +184688,8 @@ function configureClaudeCodePermissions() {
184719
184688
  const claudeDir = path7.join(process.cwd(), ".claude");
184720
184689
  const settingsPath = path7.join(claudeDir, "settings.local.json");
184721
184690
  const permissions = ["Bash(specific docs:*)", "Bash(specific check:*)"];
184722
- if (fs12.existsSync(settingsPath)) {
184723
- const existing = JSON.parse(fs12.readFileSync(settingsPath, "utf-8"));
184691
+ if (fs11.existsSync(settingsPath)) {
184692
+ const existing = JSON.parse(fs11.readFileSync(settingsPath, "utf-8"));
184724
184693
  const allowList = existing?.permissions?.allow || [];
184725
184694
  const missingPermissions = permissions.filter(
184726
184695
  (p) => !allowList.includes(p)
@@ -184735,39 +184704,39 @@ function configureClaudeCodePermissions() {
184735
184704
  existing.permissions.allow = [];
184736
184705
  }
184737
184706
  existing.permissions.allow.push(...missingPermissions);
184738
- fs12.writeFileSync(settingsPath, JSON.stringify(existing, null, 2) + "\n");
184707
+ fs11.writeFileSync(settingsPath, JSON.stringify(existing, null, 2) + "\n");
184739
184708
  return "modified";
184740
184709
  }
184741
- if (!fs12.existsSync(claudeDir)) {
184742
- fs12.mkdirSync(claudeDir);
184710
+ if (!fs11.existsSync(claudeDir)) {
184711
+ fs11.mkdirSync(claudeDir);
184743
184712
  }
184744
184713
  const settings = {
184745
184714
  permissions: {
184746
184715
  allow: permissions
184747
184716
  }
184748
184717
  };
184749
- fs12.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
184718
+ fs11.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
184750
184719
  return "created";
184751
184720
  }
184752
184721
  function createCursorRule() {
184753
184722
  const cursorDir = path7.join(process.cwd(), ".cursor");
184754
184723
  const rulesDir = path7.join(cursorDir, "rules");
184755
184724
  const mdcPath = path7.join(rulesDir, "specific.mdc");
184756
- if (fs12.existsSync(mdcPath)) {
184757
- const existing = fs12.readFileSync(mdcPath, "utf-8");
184725
+ if (fs11.existsSync(mdcPath)) {
184726
+ const existing = fs11.readFileSync(mdcPath, "utf-8");
184758
184727
  if (existing.includes("specific docs") || existing.includes("specific check")) {
184759
184728
  return "unchanged";
184760
184729
  }
184761
- fs12.writeFileSync(mdcPath, CURSOR_MDC_CONTENT);
184730
+ fs11.writeFileSync(mdcPath, CURSOR_MDC_CONTENT);
184762
184731
  return "modified";
184763
184732
  }
184764
- if (!fs12.existsSync(cursorDir)) {
184765
- fs12.mkdirSync(cursorDir);
184733
+ if (!fs11.existsSync(cursorDir)) {
184734
+ fs11.mkdirSync(cursorDir);
184766
184735
  }
184767
- if (!fs12.existsSync(rulesDir)) {
184768
- fs12.mkdirSync(rulesDir);
184736
+ if (!fs11.existsSync(rulesDir)) {
184737
+ fs11.mkdirSync(rulesDir);
184769
184738
  }
184770
- fs12.writeFileSync(mdcPath, CURSOR_MDC_CONTENT);
184739
+ fs11.writeFileSync(mdcPath, CURSOR_MDC_CONTENT);
184771
184740
  return "created";
184772
184741
  }
184773
184742
  function configureAgents(checked) {
@@ -185010,7 +184979,7 @@ var BETA_REGISTRY = [
185010
184979
  ];
185011
184980
 
185012
184981
  // src/lib/beta/storage.ts
185013
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync6, existsSync as existsSync6, mkdirSync as mkdirSync6 } from "fs";
184982
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, existsSync as existsSync6, mkdirSync as mkdirSync6 } from "fs";
185014
184983
  import { join as join7 } from "path";
185015
184984
  var BETAS_FILE = ".specific/betas.json";
185016
184985
  function loadEnabledBetas(projectDir = process.cwd()) {
@@ -185043,7 +185012,7 @@ function saveBetas(enabled, projectDir) {
185043
185012
  mkdirSync6(specificDir, { recursive: true });
185044
185013
  }
185045
185014
  const data = { enabled };
185046
- writeFileSync6(
185015
+ writeFileSync5(
185047
185016
  join7(projectDir, BETAS_FILE),
185048
185017
  JSON.stringify(data, null, 2) + "\n"
185049
185018
  );
@@ -185110,7 +185079,7 @@ function resolveFilesystemDoc(path30) {
185110
185079
  import React3, { useState as useState2, useEffect as useEffect2 } from "react";
185111
185080
  import { render as render3, Text as Text3, Box as Box3 } from "ink";
185112
185081
  import Spinner3 from "ink-spinner";
185113
- import * as fs14 from "fs";
185082
+ import * as fs13 from "fs";
185114
185083
  import * as path9 from "path";
185115
185084
  import { execFile as execFile7 } from "child_process";
185116
185085
 
@@ -185982,32 +185951,32 @@ var ExtractionError = class extends Error {
185982
185951
  };
185983
185952
 
185984
185953
  // src/lib/bin/manager.ts
185985
- import * as fs13 from "fs";
185954
+ import * as fs12 from "fs";
185986
185955
  import * as path8 from "path";
185987
- import * as os8 from "os";
185956
+ import * as os7 from "os";
185988
185957
  import { createReadStream } from "fs";
185989
185958
  import { createTarExtractor, extractTo } from "tar-vern";
185990
185959
  function getLibraryEnv(binary) {
185991
185960
  if (!binary.libraryPath) {
185992
185961
  return {};
185993
185962
  }
185994
- const platform6 = os8.platform();
185995
- if (platform6 === "darwin") {
185963
+ const platform5 = os7.platform();
185964
+ if (platform5 === "darwin") {
185996
185965
  return { DYLD_LIBRARY_PATH: binary.libraryPath };
185997
- } else if (platform6 === "linux") {
185966
+ } else if (platform5 === "linux") {
185998
185967
  return { LD_LIBRARY_PATH: binary.libraryPath };
185999
185968
  }
186000
185969
  return {};
186001
185970
  }
186002
185971
  function getBinBaseDir() {
186003
- return path8.join(os8.homedir(), ".specific", "bin");
185972
+ return path8.join(os7.homedir(), ".specific", "bin");
186004
185973
  }
186005
185974
  function getPlatformInfo() {
186006
- const platform6 = os8.platform();
186007
- const arch3 = os8.arch();
186008
- if (platform6 !== "darwin" && platform6 !== "linux") {
185975
+ const platform5 = os7.platform();
185976
+ const arch3 = os7.arch();
185977
+ if (platform5 !== "darwin" && platform5 !== "linux") {
186009
185978
  throw new Error(
186010
- `Unsupported platform: ${platform6}. Only macOS and Linux are supported.`
185979
+ `Unsupported platform: ${platform5}. Only macOS and Linux are supported.`
186011
185980
  );
186012
185981
  }
186013
185982
  const archStr = arch3;
@@ -186021,7 +185990,7 @@ function getPlatformInfo() {
186021
185990
  `Unsupported architecture: ${arch3}. Only x64 and arm64 are supported.`
186022
185991
  );
186023
185992
  }
186024
- return { platform: platform6, arch: mappedArch };
185993
+ return { platform: platform5, arch: mappedArch };
186025
185994
  }
186026
185995
  function getBinaryDir(definition, version, platformInfo) {
186027
185996
  return path8.join(
@@ -186035,7 +186004,7 @@ function isBinaryInstalled(definition, version, platformInfo) {
186035
186004
  const binDir = getBinaryDir(definition, version, platformInfo);
186036
186005
  for (const execPath of definition.executables) {
186037
186006
  const fullPath = path8.join(binDir, execPath);
186038
- if (!fs13.existsSync(fullPath)) {
186007
+ if (!fs12.existsSync(fullPath)) {
186039
186008
  return false;
186040
186009
  }
186041
186010
  }
@@ -186064,11 +186033,11 @@ async function downloadFile(url, destPath, onProgress) {
186064
186033
  );
186065
186034
  let bytesDownloaded = 0;
186066
186035
  const parentDir = path8.dirname(destPath);
186067
- if (!fs13.existsSync(parentDir)) {
186068
- fs13.mkdirSync(parentDir, { recursive: true });
186036
+ if (!fs12.existsSync(parentDir)) {
186037
+ fs12.mkdirSync(parentDir, { recursive: true });
186069
186038
  }
186070
186039
  const partPath = destPath + ".part";
186071
- const fileStream = fs13.createWriteStream(partPath);
186040
+ const fileStream = fs12.createWriteStream(partPath);
186072
186041
  try {
186073
186042
  const reader = response.body.getReader();
186074
186043
  while (true) {
@@ -186091,12 +186060,12 @@ async function downloadFile(url, destPath, onProgress) {
186091
186060
  else resolve9();
186092
186061
  });
186093
186062
  });
186094
- fs13.renameSync(partPath, destPath);
186063
+ fs12.renameSync(partPath, destPath);
186095
186064
  } catch (error) {
186096
186065
  try {
186097
186066
  fileStream.close();
186098
- if (fs13.existsSync(partPath)) {
186099
- fs13.unlinkSync(partPath);
186067
+ if (fs12.existsSync(partPath)) {
186068
+ fs12.unlinkSync(partPath);
186100
186069
  }
186101
186070
  } catch {
186102
186071
  }
@@ -186105,8 +186074,8 @@ async function downloadFile(url, destPath, onProgress) {
186105
186074
  }
186106
186075
  async function extractTarball(archivePath, destDir, definition, onProgress) {
186107
186076
  onProgress?.({ phase: "extracting" });
186108
- if (!fs13.existsSync(destDir)) {
186109
- fs13.mkdirSync(destDir, { recursive: true });
186077
+ if (!fs12.existsSync(destDir)) {
186078
+ fs12.mkdirSync(destDir, { recursive: true });
186110
186079
  }
186111
186080
  try {
186112
186081
  const fileStream = createReadStream(archivePath);
@@ -186115,8 +186084,8 @@ async function extractTarball(archivePath, destDir, definition, onProgress) {
186115
186084
  onProgress?.({ phase: "finalizing" });
186116
186085
  for (const execPath of definition.executables) {
186117
186086
  const fullPath = path8.join(destDir, execPath);
186118
- if (fs13.existsSync(fullPath)) {
186119
- fs13.chmodSync(fullPath, 493);
186087
+ if (fs12.existsSync(fullPath)) {
186088
+ fs12.chmodSync(fullPath, 493);
186120
186089
  }
186121
186090
  }
186122
186091
  } catch (error) {
@@ -186140,12 +186109,12 @@ async function ensureBinary(definition, version, onProgress) {
186140
186109
  `Binary type definitions must have exactly one executable, got ${definition.executables.length}`
186141
186110
  );
186142
186111
  }
186143
- if (!fs13.existsSync(binDir)) {
186144
- fs13.mkdirSync(binDir, { recursive: true });
186112
+ if (!fs12.existsSync(binDir)) {
186113
+ fs12.mkdirSync(binDir, { recursive: true });
186145
186114
  }
186146
186115
  const execPath = path8.join(binDir, definition.executables[0]);
186147
186116
  await downloadFile(url, execPath, onProgress);
186148
- fs13.chmodSync(execPath, 493);
186117
+ fs12.chmodSync(execPath, 493);
186149
186118
  onProgress?.({ phase: "finalizing" });
186150
186119
  } else {
186151
186120
  const downloadDir = path8.join(getBinBaseDir(), "downloads");
@@ -186156,8 +186125,8 @@ async function ensureBinary(definition, version, onProgress) {
186156
186125
  await extractTarball(archivePath, binDir, definition, onProgress);
186157
186126
  } finally {
186158
186127
  try {
186159
- if (fs13.existsSync(archivePath)) {
186160
- fs13.unlinkSync(archivePath);
186128
+ if (fs12.existsSync(archivePath)) {
186129
+ fs12.unlinkSync(archivePath);
186161
186130
  }
186162
186131
  } catch {
186163
186132
  }
@@ -186333,20 +186302,20 @@ function CheckUI() {
186333
186302
  useEffect2(() => {
186334
186303
  async function load() {
186335
186304
  const configPath = path9.join(process.cwd(), "specific.hcl");
186336
- if (!fs14.existsSync(configPath)) {
186305
+ if (!fs13.existsSync(configPath)) {
186337
186306
  setState({
186338
186307
  status: "error",
186339
186308
  error: "No specific.hcl found in current directory"
186340
186309
  });
186341
186310
  return;
186342
186311
  }
186343
- const hcl = fs14.readFileSync(configPath, "utf-8");
186312
+ const hcl = fs13.readFileSync(configPath, "utf-8");
186344
186313
  try {
186345
186314
  const config2 = await parseConfig(hcl);
186346
186315
  for (const build of config2.builds) {
186347
186316
  if (build.dockerfile) {
186348
186317
  const dockerfilePath = path9.resolve(process.cwd(), build.dockerfile);
186349
- if (!fs14.existsSync(dockerfilePath)) {
186318
+ if (!fs13.existsSync(dockerfilePath)) {
186350
186319
  setState({
186351
186320
  status: "error",
186352
186321
  error: `Build "${build.name}": Dockerfile not found at "${build.dockerfile}" (resolved to ${dockerfilePath})`
@@ -186362,7 +186331,7 @@ function CheckUI() {
186362
186331
  process.cwd(),
186363
186332
  pg.reshape.migrations_dir ?? "migrations"
186364
186333
  );
186365
- if (!fs14.existsSync(migrationsDir)) {
186334
+ if (!fs13.existsSync(migrationsDir)) {
186366
186335
  reshapeChecks2.push({
186367
186336
  databaseName: pg.name,
186368
186337
  migrationsDir: pg.reshape.migrations_dir ?? "migrations",
@@ -186415,7 +186384,7 @@ function checkCommand() {
186415
186384
  import React6, { useState as useState5, useEffect as useEffect3, useRef } from "react";
186416
186385
  import { render as render4, Text as Text6, Box as Box6, useApp as useApp2, Static, useInput as useInput4 } from "ink";
186417
186386
  import Spinner4 from "ink-spinner";
186418
- import * as fs24 from "fs";
186387
+ import * as fs23 from "fs";
186419
186388
  import * as path20 from "path";
186420
186389
 
186421
186390
  // node_modules/.pnpm/chokidar@5.0.0/node_modules/chokidar/index.js
@@ -188170,7 +188139,7 @@ var PortAllocator = class {
188170
188139
  };
188171
188140
 
188172
188141
  // src/lib/dev/stable-port-allocator.ts
188173
- import * as fs15 from "fs";
188142
+ import * as fs14 from "fs";
188174
188143
  import * as path10 from "path";
188175
188144
  var PORT_RANGE_START2 = 4e4;
188176
188145
  var PORT_RANGE_END2 = 49999;
@@ -188185,11 +188154,11 @@ var StablePortAllocator = class {
188185
188154
  this.loadPorts();
188186
188155
  }
188187
188156
  loadPorts() {
188188
- if (!fs15.existsSync(this.portsFilePath)) {
188157
+ if (!fs14.existsSync(this.portsFilePath)) {
188189
188158
  return;
188190
188159
  }
188191
188160
  try {
188192
- const content = fs15.readFileSync(this.portsFilePath, "utf-8");
188161
+ const content = fs14.readFileSync(this.portsFilePath, "utf-8");
188193
188162
  const data = JSON.parse(content);
188194
188163
  if (data.version === 1 && data.ports) {
188195
188164
  this.savedPorts = data.ports;
@@ -188202,14 +188171,14 @@ var StablePortAllocator = class {
188202
188171
  }
188203
188172
  }
188204
188173
  savePorts() {
188205
- if (!fs15.existsSync(this.portsDir)) {
188206
- fs15.mkdirSync(this.portsDir, { recursive: true });
188174
+ if (!fs14.existsSync(this.portsDir)) {
188175
+ fs14.mkdirSync(this.portsDir, { recursive: true });
188207
188176
  }
188208
188177
  const data = {
188209
188178
  version: 1,
188210
188179
  ports: this.savedPorts
188211
188180
  };
188212
- fs15.writeFileSync(this.portsFilePath, JSON.stringify(data, null, 2));
188181
+ fs14.writeFileSync(this.portsFilePath, JSON.stringify(data, null, 2));
188213
188182
  }
188214
188183
  allocateRandom() {
188215
188184
  const rangeSize = PORT_RANGE_END2 - PORT_RANGE_START2 + 1;
@@ -188236,7 +188205,7 @@ var StablePortAllocator = class {
188236
188205
  };
188237
188206
 
188238
188207
  // src/lib/dev/database-manager.ts
188239
- import * as fs16 from "fs";
188208
+ import * as fs15 from "fs";
188240
188209
  import * as path11 from "path";
188241
188210
  import * as net from "net";
188242
188211
  import { spawn } from "child_process";
@@ -188248,9 +188217,9 @@ async function startPostgres(pg, port, dataDir, onProgress) {
188248
188217
  const password = "postgres";
188249
188218
  const libraryEnv = getLibraryEnv(binary);
188250
188219
  const env2 = { ...process.env, ...libraryEnv };
188251
- const dataExists = fs16.existsSync(dbDataPath);
188220
+ const dataExists = fs15.existsSync(dbDataPath);
188252
188221
  if (!dataExists) {
188253
- fs16.mkdirSync(dbDataPath, { recursive: true });
188222
+ fs15.mkdirSync(dbDataPath, { recursive: true });
188254
188223
  await runCommand(
188255
188224
  binary.executables["initdb"],
188256
188225
  ["-D", dbDataPath, "-U", user, "--auth=trust", "--no-locale", "-E", "UTF8"],
@@ -188327,8 +188296,8 @@ async function startRedis(redis, port, onProgress) {
188327
188296
  async function startStorage(storage, port, dataDir) {
188328
188297
  const S3rver = (await import("s3rver")).default;
188329
188298
  const storageDataPath = path11.join(process.cwd(), dataDir, storage.name);
188330
- if (!fs16.existsSync(storageDataPath)) {
188331
- fs16.mkdirSync(storageDataPath, { recursive: true });
188299
+ if (!fs15.existsSync(storageDataPath)) {
188300
+ fs15.mkdirSync(storageDataPath, { recursive: true });
188332
188301
  }
188333
188302
  const host = "127.0.0.1";
188334
188303
  const accessKey = "S3RVER";
@@ -188971,7 +188940,7 @@ function startService(service, resources, secrets, configs, endpointPorts, servi
188971
188940
  }
188972
188941
 
188973
188942
  // src/lib/dev/instance-state.ts
188974
- import * as fs17 from "fs";
188943
+ import * as fs16 from "fs";
188975
188944
  import * as path12 from "path";
188976
188945
  var InstanceStateManager = class {
188977
188946
  stateDir;
@@ -188989,8 +188958,8 @@ var InstanceStateManager = class {
188989
188958
  return this.key;
188990
188959
  }
188991
188960
  ensureStateDir() {
188992
- if (!fs17.existsSync(this.stateDir)) {
188993
- fs17.mkdirSync(this.stateDir, { recursive: true });
188961
+ if (!fs16.existsSync(this.stateDir)) {
188962
+ fs16.mkdirSync(this.stateDir, { recursive: true });
188994
188963
  }
188995
188964
  }
188996
188965
  isProcessRunning(pid) {
@@ -189007,15 +188976,15 @@ var InstanceStateManager = class {
189007
188976
  const startTime = Date.now();
189008
188977
  while (Date.now() - startTime < timeoutMs) {
189009
188978
  try {
189010
- const fd = fs17.openSync(
188979
+ const fd = fs16.openSync(
189011
188980
  this.lockPath,
189012
- fs17.constants.O_CREAT | fs17.constants.O_EXCL | fs17.constants.O_WRONLY
188981
+ fs16.constants.O_CREAT | fs16.constants.O_EXCL | fs16.constants.O_WRONLY
189013
188982
  );
189014
- fs17.writeSync(fd, String(process.pid));
189015
- fs17.closeSync(fd);
188983
+ fs16.writeSync(fd, String(process.pid));
188984
+ fs16.closeSync(fd);
189016
188985
  return () => {
189017
188986
  try {
189018
- fs17.unlinkSync(this.lockPath);
188987
+ fs16.unlinkSync(this.lockPath);
189019
188988
  } catch {
189020
188989
  }
189021
188990
  };
@@ -189024,16 +188993,16 @@ var InstanceStateManager = class {
189024
188993
  if (err.code === "EEXIST") {
189025
188994
  try {
189026
188995
  const lockPid = parseInt(
189027
- fs17.readFileSync(this.lockPath, "utf-8").trim(),
188996
+ fs16.readFileSync(this.lockPath, "utf-8").trim(),
189028
188997
  10
189029
188998
  );
189030
188999
  if (!this.isProcessRunning(lockPid)) {
189031
- fs17.unlinkSync(this.lockPath);
189000
+ fs16.unlinkSync(this.lockPath);
189032
189001
  continue;
189033
189002
  }
189034
189003
  } catch {
189035
189004
  try {
189036
- fs17.unlinkSync(this.lockPath);
189005
+ fs16.unlinkSync(this.lockPath);
189037
189006
  } catch {
189038
189007
  }
189039
189008
  continue;
@@ -189047,12 +189016,12 @@ var InstanceStateManager = class {
189047
189016
  throw new Error("Failed to acquire state lock (timeout)");
189048
189017
  }
189049
189018
  async getExistingInstances() {
189050
- if (!fs17.existsSync(this.statePath)) {
189019
+ if (!fs16.existsSync(this.statePath)) {
189051
189020
  return null;
189052
189021
  }
189053
189022
  const releaseLock = await this.acquireLock();
189054
189023
  try {
189055
- const content = fs17.readFileSync(this.statePath, "utf-8");
189024
+ const content = fs16.readFileSync(this.statePath, "utf-8");
189056
189025
  const state = JSON.parse(content);
189057
189026
  if (!this.isProcessRunning(state.owner.pid)) {
189058
189027
  return null;
@@ -189065,21 +189034,21 @@ var InstanceStateManager = class {
189065
189034
  }
189066
189035
  }
189067
189036
  async cleanStaleState() {
189068
- if (!fs17.existsSync(this.statePath)) {
189037
+ if (!fs16.existsSync(this.statePath)) {
189069
189038
  return false;
189070
189039
  }
189071
189040
  const releaseLock = await this.acquireLock();
189072
189041
  try {
189073
- const content = fs17.readFileSync(this.statePath, "utf-8");
189042
+ const content = fs16.readFileSync(this.statePath, "utf-8");
189074
189043
  const state = JSON.parse(content);
189075
189044
  if (!this.isProcessRunning(state.owner.pid)) {
189076
- fs17.unlinkSync(this.statePath);
189045
+ fs16.unlinkSync(this.statePath);
189077
189046
  return true;
189078
189047
  }
189079
189048
  return false;
189080
189049
  } catch {
189081
189050
  try {
189082
- fs17.unlinkSync(this.statePath);
189051
+ fs16.unlinkSync(this.statePath);
189083
189052
  return true;
189084
189053
  } catch {
189085
189054
  }
@@ -189091,8 +189060,8 @@ var InstanceStateManager = class {
189091
189060
  async claimOwnership(command) {
189092
189061
  const releaseLock = await this.acquireLock();
189093
189062
  try {
189094
- if (fs17.existsSync(this.statePath)) {
189095
- const content = fs17.readFileSync(this.statePath, "utf-8");
189063
+ if (fs16.existsSync(this.statePath)) {
189064
+ const content = fs16.readFileSync(this.statePath, "utf-8");
189096
189065
  const state2 = JSON.parse(content);
189097
189066
  if (this.isProcessRunning(state2.owner.pid)) {
189098
189067
  throw new Error(`Instances already owned by PID ${state2.owner.pid}`);
@@ -189161,8 +189130,8 @@ var InstanceStateManager = class {
189161
189130
  }
189162
189131
  const releaseLock = await this.acquireLock();
189163
189132
  try {
189164
- if (fs17.existsSync(this.statePath)) {
189165
- fs17.unlinkSync(this.statePath);
189133
+ if (fs16.existsSync(this.statePath)) {
189134
+ fs16.unlinkSync(this.statePath);
189166
189135
  }
189167
189136
  this.ownsInstances = false;
189168
189137
  } finally {
@@ -189170,21 +189139,21 @@ var InstanceStateManager = class {
189170
189139
  }
189171
189140
  }
189172
189141
  readState() {
189173
- const content = fs17.readFileSync(this.statePath, "utf-8");
189142
+ const content = fs16.readFileSync(this.statePath, "utf-8");
189174
189143
  return JSON.parse(content);
189175
189144
  }
189176
189145
  writeStateAtomic(state) {
189177
189146
  this.ensureStateDir();
189178
189147
  const tmpPath = this.statePath + ".tmp";
189179
- fs17.writeFileSync(tmpPath, JSON.stringify(state, null, 2));
189180
- fs17.renameSync(tmpPath, this.statePath);
189148
+ fs16.writeFileSync(tmpPath, JSON.stringify(state, null, 2));
189149
+ fs16.renameSync(tmpPath, this.statePath);
189181
189150
  }
189182
189151
  };
189183
189152
 
189184
189153
  // src/lib/dev/http-proxy.ts
189185
189154
  import * as http from "http";
189186
189155
  import * as https from "https";
189187
- import * as fs18 from "fs";
189156
+ import * as fs17 from "fs";
189188
189157
  import * as path13 from "path";
189189
189158
  import { fileURLToPath as fileURLToPath3 } from "url";
189190
189159
  import httpProxy from "http-proxy";
@@ -189592,10 +189561,10 @@ function serveFilesystemFile(res, pathname) {
189592
189561
  res.end("<h1>Forbidden</h1>");
189593
189562
  return;
189594
189563
  }
189595
- if (fs18.existsSync(resolvedPath)) {
189596
- if (fs18.statSync(resolvedPath).isDirectory()) {
189564
+ if (fs17.existsSync(resolvedPath)) {
189565
+ if (fs17.statSync(resolvedPath).isDirectory()) {
189597
189566
  const indexPath2 = path13.join(resolvedPath, "index.html");
189598
- if (fs18.existsSync(indexPath2)) {
189567
+ if (fs17.existsSync(indexPath2)) {
189599
189568
  return serveFile(res, indexPath2);
189600
189569
  }
189601
189570
  } else {
@@ -189603,15 +189572,15 @@ function serveFilesystemFile(res, pathname) {
189603
189572
  }
189604
189573
  }
189605
189574
  const htmlPath = resolvedPath + ".html";
189606
- if (fs18.existsSync(htmlPath)) {
189575
+ if (fs17.existsSync(htmlPath)) {
189607
189576
  return serveFile(res, htmlPath);
189608
189577
  }
189609
189578
  const indexPath = path13.join(resolvedPath, "index.html");
189610
- if (fs18.existsSync(indexPath)) {
189579
+ if (fs17.existsSync(indexPath)) {
189611
189580
  return serveFile(res, indexPath);
189612
189581
  }
189613
189582
  const notFoundPath = path13.join(adminDir, "404.html");
189614
- if (fs18.existsSync(notFoundPath)) {
189583
+ if (fs17.existsSync(notFoundPath)) {
189615
189584
  return serveFileContent(res, notFoundPath, "text/html", 404);
189616
189585
  }
189617
189586
  res.writeHead(404, { "Content-Type": "text/html" });
@@ -189624,7 +189593,7 @@ function serveFile(res, filePath) {
189624
189593
  }
189625
189594
  function serveFileContent(res, filePath, contentType, statusCode = 200) {
189626
189595
  try {
189627
- const content = fs18.readFileSync(filePath);
189596
+ const content = fs17.readFileSync(filePath);
189628
189597
  res.writeHead(statusCode, { "Content-Type": contentType });
189629
189598
  res.end(content);
189630
189599
  } catch (err) {
@@ -189999,7 +189968,7 @@ async function startMailServer(mail, smtpPort, apiPort) {
189999
189968
 
190000
189969
  // src/lib/dev/drizzle-gateway-manager.ts
190001
189970
  import * as net3 from "net";
190002
- import * as fs19 from "fs";
189971
+ import * as fs18 from "fs";
190003
189972
  import * as path15 from "path";
190004
189973
  import { spawn as spawn4 } from "child_process";
190005
189974
  import { randomUUID as randomUUID2 } from "crypto";
@@ -190033,12 +190002,12 @@ async function startDrizzleGateway(postgresInstances, port, configDir, options2)
190033
190002
  );
190034
190003
  const host = "127.0.0.1";
190035
190004
  const drizzleConfigDir = path15.join(configDir, "drizzle-gateway");
190036
- if (!fs19.existsSync(drizzleConfigDir)) {
190037
- fs19.mkdirSync(drizzleConfigDir, { recursive: true });
190005
+ if (!fs18.existsSync(drizzleConfigDir)) {
190006
+ fs18.mkdirSync(drizzleConfigDir, { recursive: true });
190038
190007
  }
190039
190008
  const storeJson = generateStoreJson(postgresInstances);
190040
190009
  const storeJsonPath = path15.join(drizzleConfigDir, "store.json");
190041
- fs19.writeFileSync(storeJsonPath, JSON.stringify(storeJson, null, 2));
190010
+ fs18.writeFileSync(storeJsonPath, JSON.stringify(storeJson, null, 2));
190042
190011
  writeLog("drizzle-gateway", `Starting Drizzle Gateway`);
190043
190012
  writeLog("drizzle-gateway", `STORE_PATH: ${drizzleConfigDir}`);
190044
190013
  writeLog("drizzle-gateway", `PORT: ${port}`);
@@ -190140,16 +190109,16 @@ function detectSyncDatabases(config) {
190140
190109
  }
190141
190110
 
190142
190111
  // src/lib/dev/reshape-watcher.ts
190143
- import * as fs20 from "fs";
190112
+ import * as fs19 from "fs";
190144
190113
  import * as path16 from "path";
190145
190114
  import { spawnSync } from "child_process";
190146
190115
  function getMigrationFiles(dir, log) {
190147
190116
  log(`Scanning migrations directory: ${dir}`);
190148
- if (!fs20.existsSync(dir)) {
190117
+ if (!fs19.existsSync(dir)) {
190149
190118
  log(`Migrations directory does not exist: ${dir}`);
190150
190119
  return [];
190151
190120
  }
190152
- const files = fs20.readdirSync(dir);
190121
+ const files = fs19.readdirSync(dir);
190153
190122
  log(`Found ${files.length} files in directory`);
190154
190123
  const tomlFiles = files.filter((f) => f.endsWith(".toml")).sort((a, b) => a.localeCompare(b));
190155
190124
  log(`Found ${tomlFiles.length} .toml migration files: ${tomlFiles.join(", ") || "(none)"}`);
@@ -190199,7 +190168,7 @@ function runReshape(args, databaseUrl, migrationsDir, reshapeBinaryPath, log) {
190199
190168
  }
190200
190169
  function makeReadOnly(filePath, log) {
190201
190170
  try {
190202
- fs20.chmodSync(filePath, 292);
190171
+ fs19.chmodSync(filePath, 292);
190203
190172
  log(`Set file permissions to read-only (444): ${filePath}`);
190204
190173
  } catch (err) {
190205
190174
  const message = err instanceof Error ? err.message : String(err);
@@ -190285,9 +190254,9 @@ function createReshapeWatcher(options2) {
190285
190254
  };
190286
190255
  const startWatching = () => {
190287
190256
  log(`Starting file watcher for migrations directory...`);
190288
- if (!fs20.existsSync(migrationsDir)) {
190257
+ if (!fs19.existsSync(migrationsDir)) {
190289
190258
  log(`Migrations directory does not exist, creating: ${migrationsDir}`);
190290
- fs20.mkdirSync(migrationsDir, { recursive: true });
190259
+ fs19.mkdirSync(migrationsDir, { recursive: true });
190291
190260
  }
190292
190261
  log(`Watching directory: ${migrationsDir}`);
190293
190262
  watcher = chokidar_default.watch(migrationsDir, {
@@ -190422,7 +190391,7 @@ function createReshapeWatcher(options2) {
190422
190391
  }
190423
190392
 
190424
190393
  // src/lib/dev/temporal-manager.ts
190425
- import * as fs21 from "fs";
190394
+ import * as fs20 from "fs";
190426
190395
  import * as path17 from "path";
190427
190396
  import * as net4 from "net";
190428
190397
  import { spawn as spawn5 } from "child_process";
@@ -190430,8 +190399,8 @@ async function startTemporalDevServer(temporals, grpcPort, uiPort, dataDir, onPr
190430
190399
  const binary = await ensureBinary(temporalBinary, void 0, onProgress);
190431
190400
  const dbPath = path17.join(process.cwd(), dataDir, "temporal.db");
190432
190401
  const dbDir = path17.dirname(dbPath);
190433
- if (!fs21.existsSync(dbDir)) {
190434
- fs21.mkdirSync(dbDir, { recursive: true });
190402
+ if (!fs20.existsSync(dbDir)) {
190403
+ fs20.mkdirSync(dbDir, { recursive: true });
190435
190404
  }
190436
190405
  const host = "127.0.0.1";
190437
190406
  const namespaceArgs = temporals.flatMap((t) => ["--namespace", t.name]);
@@ -190760,7 +190729,7 @@ function watchConfigFile(configPath, debounceMs, onChange) {
190760
190729
  }
190761
190730
 
190762
190731
  // src/lib/dev/subdomain-generator.ts
190763
- import * as fs22 from "fs";
190732
+ import * as fs21 from "fs";
190764
190733
  import * as path18 from "path";
190765
190734
  import { generateSlug } from "random-word-slugs";
190766
190735
  var StableSubdomainAllocator = class {
@@ -190773,11 +190742,11 @@ var StableSubdomainAllocator = class {
190773
190742
  this.loadTunnels();
190774
190743
  }
190775
190744
  loadTunnels() {
190776
- if (!fs22.existsSync(this.tunnelsFilePath)) {
190745
+ if (!fs21.existsSync(this.tunnelsFilePath)) {
190777
190746
  return;
190778
190747
  }
190779
190748
  try {
190780
- const content = fs22.readFileSync(this.tunnelsFilePath, "utf-8");
190749
+ const content = fs21.readFileSync(this.tunnelsFilePath, "utf-8");
190781
190750
  const data = JSON.parse(content);
190782
190751
  if (data.version === 1 && data.baseSlug) {
190783
190752
  this.baseSlug = data.baseSlug;
@@ -190787,14 +190756,14 @@ var StableSubdomainAllocator = class {
190787
190756
  }
190788
190757
  }
190789
190758
  saveTunnels() {
190790
- if (!fs22.existsSync(this.tunnelsDir)) {
190791
- fs22.mkdirSync(this.tunnelsDir, { recursive: true });
190759
+ if (!fs21.existsSync(this.tunnelsDir)) {
190760
+ fs21.mkdirSync(this.tunnelsDir, { recursive: true });
190792
190761
  }
190793
190762
  const data = {
190794
190763
  version: 1,
190795
190764
  baseSlug: this.baseSlug
190796
190765
  };
190797
- fs22.writeFileSync(this.tunnelsFilePath, JSON.stringify(data, null, 2));
190766
+ fs21.writeFileSync(this.tunnelsFilePath, JSON.stringify(data, null, 2));
190798
190767
  }
190799
190768
  generateBaseSlug() {
190800
190769
  return generateSlug(2, {
@@ -190950,9 +190919,9 @@ async function startTunnel(serviceName, endpointName, port, subdomain, callbacks
190950
190919
  }
190951
190920
 
190952
190921
  // src/lib/dev/proxy-registry.ts
190953
- import * as fs23 from "fs";
190922
+ import * as fs22 from "fs";
190954
190923
  import * as path19 from "path";
190955
- import * as os9 from "os";
190924
+ import * as os8 from "os";
190956
190925
  import * as net6 from "net";
190957
190926
  var ProxyRegistryManager = class {
190958
190927
  proxyDir;
@@ -190962,14 +190931,14 @@ var ProxyRegistryManager = class {
190962
190931
  isOwner = false;
190963
190932
  registryWatcher = null;
190964
190933
  constructor() {
190965
- this.proxyDir = path19.join(os9.homedir(), ".specific", "proxy");
190934
+ this.proxyDir = path19.join(os8.homedir(), ".specific", "proxy");
190966
190935
  this.ownerPath = path19.join(this.proxyDir, "owner.json");
190967
190936
  this.registryPath = path19.join(this.proxyDir, "registry.json");
190968
190937
  this.lockPath = path19.join(this.proxyDir, "registry.lock");
190969
190938
  }
190970
190939
  ensureProxyDir() {
190971
- if (!fs23.existsSync(this.proxyDir)) {
190972
- fs23.mkdirSync(this.proxyDir, { recursive: true });
190940
+ if (!fs22.existsSync(this.proxyDir)) {
190941
+ fs22.mkdirSync(this.proxyDir, { recursive: true });
190973
190942
  }
190974
190943
  }
190975
190944
  isProcessRunning(pid) {
@@ -191026,15 +190995,15 @@ var ProxyRegistryManager = class {
191026
190995
  const startTime = Date.now();
191027
190996
  while (Date.now() - startTime < timeoutMs) {
191028
190997
  try {
191029
- const fd = fs23.openSync(
190998
+ const fd = fs22.openSync(
191030
190999
  this.lockPath,
191031
- fs23.constants.O_CREAT | fs23.constants.O_EXCL | fs23.constants.O_WRONLY
191000
+ fs22.constants.O_CREAT | fs22.constants.O_EXCL | fs22.constants.O_WRONLY
191032
191001
  );
191033
- fs23.writeSync(fd, String(process.pid));
191034
- fs23.closeSync(fd);
191002
+ fs22.writeSync(fd, String(process.pid));
191003
+ fs22.closeSync(fd);
191035
191004
  return () => {
191036
191005
  try {
191037
- fs23.unlinkSync(this.lockPath);
191006
+ fs22.unlinkSync(this.lockPath);
191038
191007
  } catch {
191039
191008
  }
191040
191009
  };
@@ -191043,16 +191012,16 @@ var ProxyRegistryManager = class {
191043
191012
  if (err.code === "EEXIST") {
191044
191013
  try {
191045
191014
  const lockPid = parseInt(
191046
- fs23.readFileSync(this.lockPath, "utf-8").trim(),
191015
+ fs22.readFileSync(this.lockPath, "utf-8").trim(),
191047
191016
  10
191048
191017
  );
191049
191018
  if (!this.isProcessRunning(lockPid)) {
191050
- fs23.unlinkSync(this.lockPath);
191019
+ fs22.unlinkSync(this.lockPath);
191051
191020
  continue;
191052
191021
  }
191053
191022
  } catch {
191054
191023
  try {
191055
- fs23.unlinkSync(this.lockPath);
191024
+ fs22.unlinkSync(this.lockPath);
191056
191025
  } catch {
191057
191026
  }
191058
191027
  continue;
@@ -191072,8 +191041,8 @@ var ProxyRegistryManager = class {
191072
191041
  async claimProxyOwnership(key) {
191073
191042
  const releaseLock = await this.acquireLock();
191074
191043
  try {
191075
- if (fs23.existsSync(this.ownerPath)) {
191076
- const content = fs23.readFileSync(this.ownerPath, "utf-8");
191044
+ if (fs22.existsSync(this.ownerPath)) {
191045
+ const content = fs22.readFileSync(this.ownerPath, "utf-8");
191077
191046
  const ownerFile2 = JSON.parse(content);
191078
191047
  if (await this.isProxyOwnerHealthy(ownerFile2.owner.pid)) {
191079
191048
  return false;
@@ -191103,11 +191072,11 @@ var ProxyRegistryManager = class {
191103
191072
  }
191104
191073
  const releaseLock = await this.acquireLock();
191105
191074
  try {
191106
- if (fs23.existsSync(this.ownerPath)) {
191107
- const content = fs23.readFileSync(this.ownerPath, "utf-8");
191075
+ if (fs22.existsSync(this.ownerPath)) {
191076
+ const content = fs22.readFileSync(this.ownerPath, "utf-8");
191108
191077
  const ownerFile = JSON.parse(content);
191109
191078
  if (ownerFile.owner.pid === process.pid) {
191110
- fs23.unlinkSync(this.ownerPath);
191079
+ fs22.unlinkSync(this.ownerPath);
191111
191080
  }
191112
191081
  }
191113
191082
  this.isOwner = false;
@@ -191119,12 +191088,12 @@ var ProxyRegistryManager = class {
191119
191088
  * Get the current proxy owner.
191120
191089
  */
191121
191090
  async getProxyOwner() {
191122
- if (!fs23.existsSync(this.ownerPath)) {
191091
+ if (!fs22.existsSync(this.ownerPath)) {
191123
191092
  return null;
191124
191093
  }
191125
191094
  const releaseLock = await this.acquireLock();
191126
191095
  try {
191127
- const content = fs23.readFileSync(this.ownerPath, "utf-8");
191096
+ const content = fs22.readFileSync(this.ownerPath, "utf-8");
191128
191097
  const ownerFile = JSON.parse(content);
191129
191098
  if (!await this.isProxyOwnerHealthy(ownerFile.owner.pid)) {
191130
191099
  return null;
@@ -191221,7 +191190,7 @@ var ProxyRegistryManager = class {
191221
191190
  */
191222
191191
  watchRegistry(onChange) {
191223
191192
  this.ensureProxyDir();
191224
- if (!fs23.existsSync(this.registryPath)) {
191193
+ if (!fs22.existsSync(this.registryPath)) {
191225
191194
  const emptyRegistry = {
191226
191195
  version: 1,
191227
191196
  keys: {},
@@ -191264,13 +191233,13 @@ var ProxyRegistryManager = class {
191264
191233
  async attemptElection(key) {
191265
191234
  const releaseLock = await this.acquireLock();
191266
191235
  try {
191267
- if (fs23.existsSync(this.ownerPath)) {
191268
- const content = fs23.readFileSync(this.ownerPath, "utf-8");
191236
+ if (fs22.existsSync(this.ownerPath)) {
191237
+ const content = fs22.readFileSync(this.ownerPath, "utf-8");
191269
191238
  const ownerFile2 = JSON.parse(content);
191270
191239
  if (await this.isProxyOwnerHealthy(ownerFile2.owner.pid)) {
191271
191240
  return false;
191272
191241
  }
191273
- fs23.unlinkSync(this.ownerPath);
191242
+ fs22.unlinkSync(this.ownerPath);
191274
191243
  }
191275
191244
  const ownerFile = {
191276
191245
  version: 1,
@@ -191288,7 +191257,7 @@ var ProxyRegistryManager = class {
191288
191257
  }
191289
191258
  }
191290
191259
  readRegistry() {
191291
- if (!fs23.existsSync(this.registryPath)) {
191260
+ if (!fs22.existsSync(this.registryPath)) {
191292
191261
  return {
191293
191262
  version: 1,
191294
191263
  keys: {},
@@ -191296,7 +191265,7 @@ var ProxyRegistryManager = class {
191296
191265
  };
191297
191266
  }
191298
191267
  try {
191299
- const content = fs23.readFileSync(this.registryPath, "utf-8");
191268
+ const content = fs22.readFileSync(this.registryPath, "utf-8");
191300
191269
  return JSON.parse(content);
191301
191270
  } catch {
191302
191271
  return {
@@ -191309,8 +191278,8 @@ var ProxyRegistryManager = class {
191309
191278
  writeFileAtomic(filePath, data) {
191310
191279
  this.ensureProxyDir();
191311
191280
  const tmpPath = filePath + ".tmp";
191312
- fs23.writeFileSync(tmpPath, JSON.stringify(data, null, 2));
191313
- fs23.renameSync(tmpPath, filePath);
191281
+ fs22.writeFileSync(tmpPath, JSON.stringify(data, null, 2));
191282
+ fs22.renameSync(tmpPath, filePath);
191314
191283
  }
191315
191284
  };
191316
191285
 
@@ -191436,10 +191405,10 @@ function DevUI({ instanceKey, tunnelEnabled }) {
191436
191405
  }
191437
191406
  }, [state.status, state.caInstallPhase]);
191438
191407
  useInput4((_input, key) => {
191439
- if (state.status === "installing-ca" && state.caInstallPhase === "prompt" && key.return) {
191408
+ if (key.return) {
191440
191409
  setState((s) => ({ ...s, caInstallPhase: "installing" }));
191441
191410
  }
191442
- });
191411
+ }, { isActive: state.status === "installing-ca" && state.caInstallPhase === "prompt" });
191443
191412
  async function installSystemConfig() {
191444
191413
  try {
191445
191414
  performSystemSetup();
@@ -191633,7 +191602,7 @@ function DevUI({ instanceKey, tunnelEnabled }) {
191633
191602
  const configPath = path20.join(process.cwd(), "specific.hcl");
191634
191603
  const watcher = watchConfigFile(configPath, 1e3, () => {
191635
191604
  try {
191636
- const hcl = fs24.readFileSync(configPath, "utf-8");
191605
+ const hcl = fs23.readFileSync(configPath, "utf-8");
191637
191606
  parseConfig(hcl).then(() => {
191638
191607
  triggerReload();
191639
191608
  }).catch((err) => {
@@ -191759,7 +191728,7 @@ function DevUI({ instanceKey, tunnelEnabled }) {
191759
191728
  return;
191760
191729
  }
191761
191730
  const configPath = path20.join(process.cwd(), "specific.hcl");
191762
- if (!fs24.existsSync(configPath)) {
191731
+ if (!fs23.existsSync(configPath)) {
191763
191732
  writeLog("system", "Waiting for specific.hcl to appear");
191764
191733
  setState((s) => ({
191765
191734
  ...s,
@@ -191777,7 +191746,7 @@ function DevUI({ instanceKey, tunnelEnabled }) {
191777
191746
  return;
191778
191747
  }
191779
191748
  let config2;
191780
- const hcl = fs24.readFileSync(configPath, "utf-8");
191749
+ const hcl = fs23.readFileSync(configPath, "utf-8");
191781
191750
  try {
191782
191751
  config2 = await parseConfig(hcl);
191783
191752
  } catch (err) {
@@ -192104,7 +192073,7 @@ Add them to the config block in specific.local`);
192104
192073
  if (service.volumes) {
192105
192074
  for (const vol of service.volumes) {
192106
192075
  const volumeDir = path20.resolve(`.specific/keys/${instanceKey}/data/volumes/${service.name}/${vol.name}`);
192107
- fs24.mkdirSync(volumeDir, { recursive: true });
192076
+ fs23.mkdirSync(volumeDir, { recursive: true });
192108
192077
  volumePaths.set(vol.name, volumeDir);
192109
192078
  }
192110
192079
  }
@@ -192160,7 +192129,7 @@ Add them to the config block in specific.local`);
192160
192129
  if (service.volumes) {
192161
192130
  for (const vol of service.volumes) {
192162
192131
  const volumeDir = path20.resolve(`.specific/keys/${instanceKey}/data/volumes/${service.name}/${vol.name}`);
192163
- fs24.mkdirSync(volumeDir, { recursive: true });
192132
+ fs23.mkdirSync(volumeDir, { recursive: true });
192164
192133
  volumePaths.set(vol.name, volumeDir);
192165
192134
  }
192166
192135
  }
@@ -192731,12 +192700,12 @@ init_open();
192731
192700
  import React7, { useState as useState6, useEffect as useEffect4, useCallback } from "react";
192732
192701
  import { render as render5, Text as Text7, Box as Box7, useApp as useApp3, useInput as useInput5 } from "ink";
192733
192702
  import Spinner5 from "ink-spinner";
192734
- import * as fs26 from "fs";
192703
+ import * as fs25 from "fs";
192735
192704
  import * as path23 from "path";
192736
192705
 
192737
192706
  // src/lib/tarball/create.ts
192738
192707
  import { execSync as execSync4 } from "child_process";
192739
- import * as fs25 from "fs";
192708
+ import * as fs24 from "fs";
192740
192709
  import * as path22 from "path";
192741
192710
  import { createTarPacker, createEntryItemGenerator } from "tar-vern";
192742
192711
  function isInsideGitRepository(dir) {
@@ -192794,7 +192763,7 @@ var EXCLUDED_DIRS = [
192794
192763
  ];
192795
192764
  async function collectPaths(baseDir, currentDir, exclude) {
192796
192765
  const results = [];
192797
- const entries = await fs25.promises.readdir(currentDir, { withFileTypes: true });
192766
+ const entries = await fs24.promises.readdir(currentDir, { withFileTypes: true });
192798
192767
  for (const entry of entries) {
192799
192768
  const fullPath = path22.join(currentDir, entry.name);
192800
192769
  const relativePath = path22.relative(baseDir, fullPath);
@@ -192813,7 +192782,7 @@ async function collectPaths(baseDir, currentDir, exclude) {
192813
192782
  async function createTarArchive(projectDir) {
192814
192783
  writeLog("tarball", "Creating tarball using tar-vern (non-git project)");
192815
192784
  const configPath = path22.join(projectDir, "specific.hcl");
192816
- if (!fs25.existsSync(configPath)) {
192785
+ if (!fs24.existsSync(configPath)) {
192817
192786
  throw new Error("specific.hcl not found in project directory");
192818
192787
  }
192819
192788
  const relativePaths = await collectPaths(projectDir, projectDir, EXCLUDED_DIRS);
@@ -193735,12 +193704,12 @@ function DeployUI({ environment, config }) {
193735
193704
  }
193736
193705
  async function deployCommand(environment) {
193737
193706
  const configPath = path23.join(process.cwd(), "specific.hcl");
193738
- if (!fs26.existsSync(configPath)) {
193707
+ if (!fs25.existsSync(configPath)) {
193739
193708
  console.error("Error: No specific.hcl found in current directory");
193740
193709
  process.exit(1);
193741
193710
  }
193742
193711
  let config;
193743
- const hcl = fs26.readFileSync(configPath, "utf-8");
193712
+ const hcl = fs25.readFileSync(configPath, "utf-8");
193744
193713
  try {
193745
193714
  config = await parseConfig(hcl);
193746
193715
  } catch (err) {
@@ -193761,7 +193730,7 @@ async function deployCommand(environment) {
193761
193730
 
193762
193731
  // src/commands/exec.tsx
193763
193732
  import { spawn as spawn6 } from "child_process";
193764
- import * as fs27 from "fs";
193733
+ import * as fs26 from "fs";
193765
193734
  import * as path24 from "path";
193766
193735
  async function execCommand(serviceName, command, instanceKey = "default") {
193767
193736
  if (command.length === 0) {
@@ -193791,12 +193760,12 @@ async function execCommand(serviceName, command, instanceKey = "default") {
193791
193760
  }
193792
193761
  };
193793
193762
  const configPath = path24.join(process.cwd(), "specific.hcl");
193794
- if (!fs27.existsSync(configPath)) {
193763
+ if (!fs26.existsSync(configPath)) {
193795
193764
  console.error("Error: No specific.hcl found in current directory");
193796
193765
  process.exit(1);
193797
193766
  }
193798
193767
  let config;
193799
- const hcl = fs27.readFileSync(configPath, "utf-8");
193768
+ const hcl = fs26.readFileSync(configPath, "utf-8");
193800
193769
  try {
193801
193770
  config = await parseConfig(hcl);
193802
193771
  } catch (err) {
@@ -193946,7 +193915,7 @@ async function execCommand(serviceName, command, instanceKey = "default") {
193946
193915
 
193947
193916
  // src/commands/psql.tsx
193948
193917
  import { spawn as spawn7 } from "child_process";
193949
- import * as fs28 from "fs";
193918
+ import * as fs27 from "fs";
193950
193919
  import * as path25 from "path";
193951
193920
  async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []) {
193952
193921
  let startedResources = [];
@@ -193965,12 +193934,12 @@ async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []
193965
193934
  }
193966
193935
  };
193967
193936
  const configPath = path25.join(process.cwd(), "specific.hcl");
193968
- if (!fs28.existsSync(configPath)) {
193937
+ if (!fs27.existsSync(configPath)) {
193969
193938
  console.error("Error: No specific.hcl found in current directory");
193970
193939
  process.exit(1);
193971
193940
  }
193972
193941
  let config;
193973
- const hcl = fs28.readFileSync(configPath, "utf-8");
193942
+ const hcl = fs27.readFileSync(configPath, "utf-8");
193974
193943
  try {
193975
193944
  config = await parseConfig(hcl);
193976
193945
  } catch (err) {
@@ -194094,7 +194063,7 @@ async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []
194094
194063
 
194095
194064
  // src/commands/reshape.tsx
194096
194065
  import { spawn as spawn8 } from "child_process";
194097
- import * as fs29 from "fs";
194066
+ import * as fs28 from "fs";
194098
194067
  import * as path26 from "path";
194099
194068
  var VALID_ACTIONS = ["start", "complete", "status", "abort", "check"];
194100
194069
  var MIGRATION_SUBCOMMANDS = ["start", "complete", "abort"];
@@ -194112,8 +194081,8 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
194112
194081
  let migrationsDir = "migrations";
194113
194082
  let targetDb;
194114
194083
  try {
194115
- if (fs29.existsSync(configPath)) {
194116
- const configContent = fs29.readFileSync(configPath, "utf-8");
194084
+ if (fs28.existsSync(configPath)) {
194085
+ const configContent = fs28.readFileSync(configPath, "utf-8");
194117
194086
  config = await parseConfig(configContent);
194118
194087
  if (databaseName) {
194119
194088
  const postgresConfig = config.postgres.find((p) => p.name === databaseName);
@@ -194249,7 +194218,7 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
194249
194218
  const reshapeArgs = isMigrationSubcommand ? ["migration", action] : [action];
194250
194219
  const fullMigrationsPath = path26.join(process.cwd(), migrationsDir);
194251
194220
  if (action === "check" || action === "start") {
194252
- if (fs29.existsSync(fullMigrationsPath)) {
194221
+ if (fs28.existsSync(fullMigrationsPath)) {
194253
194222
  reshapeArgs.push("--dirs", fullMigrationsPath);
194254
194223
  } else if (action === "check") {
194255
194224
  console.error(`Error: Migrations directory not found: ${fullMigrationsPath}`);
@@ -194299,7 +194268,7 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
194299
194268
  import React8, { useState as useState7, useEffect as useEffect5 } from "react";
194300
194269
  import { render as render6, Text as Text8, Box as Box8 } from "ink";
194301
194270
  import Spinner6 from "ink-spinner";
194302
- import * as fs30 from "fs";
194271
+ import * as fs29 from "fs";
194303
194272
  import * as path27 from "path";
194304
194273
  function CleanUI({ instanceKey }) {
194305
194274
  const [state, setState] = useState7({ status: "checking" });
@@ -194307,13 +194276,13 @@ function CleanUI({ instanceKey }) {
194307
194276
  async function clean() {
194308
194277
  const projectRoot = process.cwd();
194309
194278
  const specificDir = path27.join(projectRoot, ".specific");
194310
- if (!fs30.existsSync(specificDir)) {
194279
+ if (!fs29.existsSync(specificDir)) {
194311
194280
  setState({ status: "nothing" });
194312
194281
  return;
194313
194282
  }
194314
194283
  if (instanceKey) {
194315
194284
  const keyDir = path27.join(specificDir, "keys", instanceKey);
194316
- if (!fs30.existsSync(keyDir)) {
194285
+ if (!fs29.existsSync(keyDir)) {
194317
194286
  setState({ status: "nothing" });
194318
194287
  return;
194319
194288
  }
@@ -194329,7 +194298,7 @@ function CleanUI({ instanceKey }) {
194329
194298
  await stateManager.cleanStaleState();
194330
194299
  setState({ status: "cleaning" });
194331
194300
  try {
194332
- fs30.rmSync(keyDir, { recursive: true, force: true });
194301
+ fs29.rmSync(keyDir, { recursive: true, force: true });
194333
194302
  setState({ status: "success" });
194334
194303
  } catch (err) {
194335
194304
  setState({
@@ -194339,12 +194308,12 @@ function CleanUI({ instanceKey }) {
194339
194308
  }
194340
194309
  } else {
194341
194310
  const keysDir = path27.join(specificDir, "keys");
194342
- if (!fs30.existsSync(keysDir)) {
194311
+ if (!fs29.existsSync(keysDir)) {
194343
194312
  setState({ status: "nothing" });
194344
194313
  return;
194345
194314
  }
194346
- const keys = fs30.readdirSync(keysDir).filter(
194347
- (f) => fs30.statSync(path27.join(keysDir, f)).isDirectory()
194315
+ const keys = fs29.readdirSync(keysDir).filter(
194316
+ (f) => fs29.statSync(path27.join(keysDir, f)).isDirectory()
194348
194317
  );
194349
194318
  for (const key of keys) {
194350
194319
  const stateManager2 = new InstanceStateManager(projectRoot, key);
@@ -194368,7 +194337,7 @@ function CleanUI({ instanceKey }) {
194368
194337
  }
194369
194338
  setState({ status: "cleaning" });
194370
194339
  try {
194371
- fs30.rmSync(keysDir, { recursive: true, force: true });
194340
+ fs29.rmSync(keysDir, { recursive: true, force: true });
194372
194341
  setState({ status: "success" });
194373
194342
  } catch (err) {
194374
194343
  setState({
@@ -194533,7 +194502,7 @@ import { render as render9, Text as Text11, Box as Box10, useApp as useApp6 } fr
194533
194502
  import Spinner7 from "ink-spinner";
194534
194503
 
194535
194504
  // src/lib/update.ts
194536
- import * as fs31 from "fs";
194505
+ import * as fs30 from "fs";
194537
194506
  import * as path28 from "path";
194538
194507
  var BINARIES_BASE_URL = "https://binaries.specific.dev/cli";
194539
194508
  function compareVersions(a, b) {
@@ -194548,7 +194517,7 @@ function compareVersions(a, b) {
194548
194517
  return 0;
194549
194518
  }
194550
194519
  async function checkForUpdate() {
194551
- const currentVersion = "0.1.75";
194520
+ const currentVersion = "0.1.77";
194552
194521
  const response = await fetch(`${BINARIES_BASE_URL}/latest?t=${Date.now()}`);
194553
194522
  if (!response.ok) {
194554
194523
  throw new Error(`Failed to check for updates: HTTP ${response.status}`);
@@ -194564,7 +194533,7 @@ function isBinaryWritable() {
194564
194533
  const binaryPath = getCurrentBinaryPath();
194565
194534
  const dir = path28.dirname(binaryPath);
194566
194535
  try {
194567
- fs31.accessSync(dir, fs31.constants.W_OK);
194536
+ fs30.accessSync(dir, fs30.constants.W_OK);
194568
194537
  return true;
194569
194538
  } catch {
194570
194539
  return false;
@@ -194575,21 +194544,21 @@ async function performUpdate(version, onProgress) {
194575
194544
  const binaryDir = path28.dirname(binaryPath);
194576
194545
  const tempPath = path28.join(binaryDir, `.specific-update-${process.pid}`);
194577
194546
  try {
194578
- const { platform: platform6, arch: arch3 } = getPlatformInfo();
194579
- const url = `${BINARIES_BASE_URL}/${version}/specific-${platform6}-${arch3}`;
194547
+ const { platform: platform5, arch: arch3 } = getPlatformInfo();
194548
+ const url = `${BINARIES_BASE_URL}/${version}/specific-${platform5}-${arch3}`;
194580
194549
  await downloadFile(url, tempPath, onProgress);
194581
- const stat4 = fs31.statSync(tempPath);
194550
+ const stat4 = fs30.statSync(tempPath);
194582
194551
  if (stat4.size === 0) {
194583
194552
  throw new Error("Downloaded binary is empty");
194584
194553
  }
194585
- fs31.chmodSync(tempPath, 493);
194554
+ fs30.chmodSync(tempPath, 493);
194586
194555
  onProgress?.({ phase: "finalizing" });
194587
- fs31.unlinkSync(binaryPath);
194588
- fs31.renameSync(tempPath, binaryPath);
194556
+ fs30.unlinkSync(binaryPath);
194557
+ fs30.renameSync(tempPath, binaryPath);
194589
194558
  } catch (error) {
194590
194559
  try {
194591
- if (fs31.existsSync(tempPath)) {
194592
- fs31.unlinkSync(tempPath);
194560
+ if (fs30.existsSync(tempPath)) {
194561
+ fs30.unlinkSync(tempPath);
194593
194562
  }
194594
194563
  } catch {
194595
194564
  }
@@ -194599,21 +194568,21 @@ async function performUpdate(version, onProgress) {
194599
194568
 
194600
194569
  // src/lib/background-update.ts
194601
194570
  import { spawn as spawn9 } from "child_process";
194602
- import * as fs32 from "fs";
194571
+ import * as fs31 from "fs";
194603
194572
  import * as path29 from "path";
194604
- import * as os10 from "os";
194605
- var SPECIFIC_DIR = path29.join(os10.homedir(), ".specific");
194573
+ import * as os9 from "os";
194574
+ var SPECIFIC_DIR = path29.join(os9.homedir(), ".specific");
194606
194575
  var RATE_LIMIT_FILE = path29.join(SPECIFIC_DIR, "last-update-check");
194607
194576
  var LOCK_FILE = path29.join(SPECIFIC_DIR, "update.lock");
194608
194577
  var RATE_LIMIT_MS = 60 * 60 * 1e3;
194609
194578
  var STALE_LOCK_MS = 10 * 60 * 1e3;
194610
194579
  function writeCheckTimestamp() {
194611
- fs32.mkdirSync(SPECIFIC_DIR, { recursive: true });
194612
- fs32.writeFileSync(RATE_LIMIT_FILE, String(Date.now()), "utf-8");
194580
+ fs31.mkdirSync(SPECIFIC_DIR, { recursive: true });
194581
+ fs31.writeFileSync(RATE_LIMIT_FILE, String(Date.now()), "utf-8");
194613
194582
  }
194614
194583
  function isRateLimited() {
194615
194584
  try {
194616
- const content = fs32.readFileSync(RATE_LIMIT_FILE, "utf-8").trim();
194585
+ const content = fs31.readFileSync(RATE_LIMIT_FILE, "utf-8").trim();
194617
194586
  const lastCheck = parseInt(content, 10);
194618
194587
  if (isNaN(lastCheck)) return false;
194619
194588
  return Date.now() - lastCheck < RATE_LIMIT_MS;
@@ -194747,7 +194716,7 @@ function updateCommand() {
194747
194716
  var program = new Command();
194748
194717
  var env = "production";
194749
194718
  var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
194750
- program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.75").enablePositionalOptions();
194719
+ program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.77").enablePositionalOptions();
194751
194720
  program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").action((options2) => initCommand(options2));
194752
194721
  program.command("docs [topic]").description("Fetch LLM-optimized documentation").action(docsCommand);
194753
194722
  program.command("check").description("Validate specific.hcl configuration").action(checkCommand);