@specific.dev/cli 0.1.139 → 0.1.141

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 (67) 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 +559 -465
  64. package/package.json +1 -1
  65. /package/dist/admin/_next/static/{LO0zwxsFXZclTu0Jbig9c → nqwwIZDiCUZ_uLWlIk-a7}/_buildManifest.js +0 -0
  66. /package/dist/admin/_next/static/{LO0zwxsFXZclTu0Jbig9c → nqwwIZDiCUZ_uLWlIk-a7}/_clientMiddlewareManifest.json +0 -0
  67. /package/dist/admin/_next/static/{LO0zwxsFXZclTu0Jbig9c → nqwwIZDiCUZ_uLWlIk-a7}/_ssgManifest.js +0 -0
package/dist/cli.js CHANGED
@@ -520,10 +520,10 @@ ${frame}`;
520
520
  });
521
521
 
522
522
  // node_modules/.pnpm/is-docker@3.0.0/node_modules/is-docker/index.js
523
- import fs14 from "node:fs";
523
+ import fs15 from "node:fs";
524
524
  function hasDockerEnv() {
525
525
  try {
526
- fs14.statSync("/.dockerenv");
526
+ fs15.statSync("/.dockerenv");
527
527
  return true;
528
528
  } catch {
529
529
  return false;
@@ -531,7 +531,7 @@ function hasDockerEnv() {
531
531
  }
532
532
  function hasDockerCGroup() {
533
533
  try {
534
- return fs14.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
534
+ return fs15.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
535
535
  } catch {
536
536
  return false;
537
537
  }
@@ -549,7 +549,7 @@ var init_is_docker = __esm({
549
549
  });
550
550
 
551
551
  // node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
552
- import fs15 from "node:fs";
552
+ import fs16 from "node:fs";
553
553
  function isInsideContainer() {
554
554
  if (cachedResult === void 0) {
555
555
  cachedResult = hasContainerEnv() || isDocker();
@@ -562,7 +562,7 @@ var init_is_inside_container = __esm({
562
562
  init_is_docker();
563
563
  hasContainerEnv = () => {
564
564
  try {
565
- fs15.statSync("/run/.containerenv");
565
+ fs16.statSync("/run/.containerenv");
566
566
  return true;
567
567
  } catch {
568
568
  return false;
@@ -574,7 +574,7 @@ var init_is_inside_container = __esm({
574
574
  // node_modules/.pnpm/is-wsl@3.1.0/node_modules/is-wsl/index.js
575
575
  import process2 from "node:process";
576
576
  import os3 from "node:os";
577
- import fs16 from "node:fs";
577
+ import fs17 from "node:fs";
578
578
  var isWsl, is_wsl_default;
579
579
  var init_is_wsl = __esm({
580
580
  "node_modules/.pnpm/is-wsl@3.1.0/node_modules/is-wsl/index.js"() {
@@ -590,7 +590,7 @@ var init_is_wsl = __esm({
590
590
  return true;
591
591
  }
592
592
  try {
593
- return fs16.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
593
+ return fs17.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
594
594
  } catch {
595
595
  return false;
596
596
  }
@@ -660,7 +660,7 @@ var init_utilities = __esm({
660
660
  // node_modules/.pnpm/wsl-utils@0.3.1/node_modules/wsl-utils/index.js
661
661
  import { promisify as promisify3 } from "node:util";
662
662
  import childProcess2 from "node:child_process";
663
- import fs17, { constants as fsConstants } from "node:fs/promises";
663
+ import fs18, { constants as fsConstants } from "node:fs/promises";
664
664
  var execFile3, wslDrivesMountPoint, powerShellPathFromWsl, powerShellPath2, canAccessPowerShellPromise, canAccessPowerShell, wslDefaultBrowser, convertWslPathToWindows;
665
665
  var init_wsl_utils = __esm({
666
666
  "node_modules/.pnpm/wsl-utils@0.3.1/node_modules/wsl-utils/index.js"() {
@@ -679,14 +679,14 @@ var init_wsl_utils = __esm({
679
679
  const configFilePath = "/etc/wsl.conf";
680
680
  let isConfigFileExists = false;
681
681
  try {
682
- await fs17.access(configFilePath, fsConstants.F_OK);
682
+ await fs18.access(configFilePath, fsConstants.F_OK);
683
683
  isConfigFileExists = true;
684
684
  } catch {
685
685
  }
686
686
  if (!isConfigFileExists) {
687
687
  return defaultMountPoint;
688
688
  }
689
- const configContent = await fs17.readFile(configFilePath, { encoding: "utf8" });
689
+ const configContent = await fs18.readFile(configFilePath, { encoding: "utf8" });
690
690
  const parsedMountPoint = parseMountPointFromConfig(configContent);
691
691
  if (parsedMountPoint === void 0) {
692
692
  return defaultMountPoint;
@@ -705,7 +705,7 @@ var init_wsl_utils = __esm({
705
705
  canAccessPowerShellPromise ??= (async () => {
706
706
  try {
707
707
  const psPath = await powerShellPath2();
708
- await fs17.access(psPath, fsConstants.X_OK);
708
+ await fs18.access(psPath, fsConstants.X_OK);
709
709
  return true;
710
710
  } catch {
711
711
  return false;
@@ -719,15 +719,15 @@ var init_wsl_utils = __esm({
719
719
  const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
720
720
  return stdout.trim();
721
721
  };
722
- convertWslPathToWindows = async (path27) => {
723
- if (/^[a-z]+:\/\//i.test(path27)) {
724
- return path27;
722
+ convertWslPathToWindows = async (path28) => {
723
+ if (/^[a-z]+:\/\//i.test(path28)) {
724
+ return path28;
725
725
  }
726
726
  try {
727
- const { stdout } = await execFile3("wslpath", ["-aw", path27], { encoding: "utf8" });
727
+ const { stdout } = await execFile3("wslpath", ["-aw", path28], { encoding: "utf8" });
728
728
  return stdout.trim();
729
729
  } catch {
730
- return path27;
730
+ return path28;
731
731
  }
732
732
  };
733
733
  }
@@ -913,10 +913,10 @@ __export(open_exports, {
913
913
  openApp: () => openApp
914
914
  });
915
915
  import process8 from "node:process";
916
- import path16 from "node:path";
916
+ import path17 from "node:path";
917
917
  import { fileURLToPath as fileURLToPath2 } from "node:url";
918
918
  import childProcess3 from "node:child_process";
919
- import fs18, { constants as fsConstants2 } from "node:fs/promises";
919
+ import fs19, { constants as fsConstants2 } from "node:fs/promises";
920
920
  function detectArchBinary(binary) {
921
921
  if (typeof binary === "string" || Array.isArray(binary)) {
922
922
  return binary;
@@ -946,8 +946,8 @@ var init_open = __esm({
946
946
  init_is_inside_container();
947
947
  init_is_in_ssh();
948
948
  fallbackAttemptSymbol = Symbol("fallbackAttempt");
949
- __dirname2 = import.meta.url ? path16.dirname(fileURLToPath2(import.meta.url)) : "";
950
- localXdgOpenPath = path16.join(__dirname2, "xdg-open");
949
+ __dirname2 = import.meta.url ? path17.dirname(fileURLToPath2(import.meta.url)) : "";
950
+ localXdgOpenPath = path17.join(__dirname2, "xdg-open");
951
951
  ({ platform: platform2, arch: arch2 } = process8);
952
952
  tryEachApp = async (apps2, opener) => {
953
953
  if (apps2.length === 0) {
@@ -1095,7 +1095,7 @@ var init_open = __esm({
1095
1095
  const isBundled = !__dirname2 || __dirname2 === "/";
1096
1096
  let exeLocalXdgOpen = false;
1097
1097
  try {
1098
- await fs18.access(localXdgOpenPath, fsConstants2.X_OK);
1098
+ await fs19.access(localXdgOpenPath, fsConstants2.X_OK);
1099
1099
  exeLocalXdgOpen = true;
1100
1100
  } catch {
1101
1101
  }
@@ -1118,19 +1118,19 @@ var init_open = __esm({
1118
1118
  }
1119
1119
  const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
1120
1120
  if (options2.wait) {
1121
- return new Promise((resolve9, reject) => {
1121
+ return new Promise((resolve10, reject) => {
1122
1122
  subprocess.once("error", reject);
1123
1123
  subprocess.once("close", (exitCode) => {
1124
1124
  if (!options2.allowNonzeroExitCode && exitCode !== 0) {
1125
1125
  reject(new Error(`Exited with code ${exitCode}`));
1126
1126
  return;
1127
1127
  }
1128
- resolve9(subprocess);
1128
+ resolve10(subprocess);
1129
1129
  });
1130
1130
  });
1131
1131
  }
1132
1132
  if (isFallbackAttempt) {
1133
- return new Promise((resolve9, reject) => {
1133
+ return new Promise((resolve10, reject) => {
1134
1134
  subprocess.once("error", reject);
1135
1135
  subprocess.once("spawn", () => {
1136
1136
  subprocess.once("close", (exitCode) => {
@@ -1140,17 +1140,17 @@ var init_open = __esm({
1140
1140
  return;
1141
1141
  }
1142
1142
  subprocess.unref();
1143
- resolve9(subprocess);
1143
+ resolve10(subprocess);
1144
1144
  });
1145
1145
  });
1146
1146
  });
1147
1147
  }
1148
1148
  subprocess.unref();
1149
- return new Promise((resolve9, reject) => {
1149
+ return new Promise((resolve10, reject) => {
1150
1150
  subprocess.once("error", reject);
1151
1151
  subprocess.once("spawn", () => {
1152
1152
  subprocess.off("error", reject);
1153
- resolve9(subprocess);
1153
+ resolve10(subprocess);
1154
1154
  });
1155
1155
  });
1156
1156
  };
@@ -1235,8 +1235,8 @@ var require_dist2 = __commonJS({
1235
1235
  var $global, $module, $NaN = NaN;
1236
1236
  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");
1237
1237
  if ("undefined" != typeof module && ($module = module), !$global.fs && $global.require) try {
1238
- var fs29 = $global.require("fs");
1239
- "object" == typeof fs29 && null !== fs29 && 0 !== Object.keys(fs29).length && ($global.fs = fs29);
1238
+ var fs30 = $global.require("fs");
1239
+ "object" == typeof fs30 && null !== fs30 && 0 !== Object.keys(fs30).length && ($global.fs = fs30);
1240
1240
  } catch (e) {
1241
1241
  }
1242
1242
  if (!$global.fs) {
@@ -183429,8 +183429,8 @@ import { Command } from "commander";
183429
183429
  // src/commands/init.tsx
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
- import * as fs20 from "fs";
183433
- import * as path18 from "path";
183432
+ import * as fs21 from "fs";
183433
+ import * as path19 from "path";
183434
183434
 
183435
183435
  // node_modules/.pnpm/@specific+sdk@file+..+sdk/node_modules/@specific/sdk/dist/index.js
183436
183436
  import * as fs from "fs";
@@ -183440,8 +183440,8 @@ import { execSync } from "child_process";
183440
183440
  import * as fs2 from "fs";
183441
183441
  import * as path2 from "path";
183442
183442
  import { createTarPacker, createEntryItemGenerator } from "tar-vern";
183443
- import * as fs13 from "fs";
183444
- import * as path14 from "path";
183443
+ import * as fs14 from "fs";
183444
+ import * as path15 from "path";
183445
183445
 
183446
183446
  // node_modules/.pnpm/chokidar@5.0.0/node_modules/chokidar/index.js
183447
183447
  import { EventEmitter } from "node:events";
@@ -183533,7 +183533,7 @@ var ReaddirpStream = class extends Readable {
183533
183533
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
183534
183534
  const statMethod = opts.lstat ? lstat : stat;
183535
183535
  if (wantBigintFsStats) {
183536
- this._stat = (path27) => statMethod(path27, { bigint: true });
183536
+ this._stat = (path28) => statMethod(path28, { bigint: true });
183537
183537
  } else {
183538
183538
  this._stat = statMethod;
183539
183539
  }
@@ -183558,8 +183558,8 @@ var ReaddirpStream = class extends Readable {
183558
183558
  const par = this.parent;
183559
183559
  const fil = par && par.files;
183560
183560
  if (fil && fil.length > 0) {
183561
- const { path: path27, depth } = par;
183562
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path27));
183561
+ const { path: path28, depth } = par;
183562
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path28));
183563
183563
  const awaited = await Promise.all(slice);
183564
183564
  for (const entry of awaited) {
183565
183565
  if (!entry)
@@ -183599,20 +183599,20 @@ var ReaddirpStream = class extends Readable {
183599
183599
  this.reading = false;
183600
183600
  }
183601
183601
  }
183602
- async _exploreDir(path27, depth) {
183602
+ async _exploreDir(path28, depth) {
183603
183603
  let files;
183604
183604
  try {
183605
- files = await readdir(path27, this._rdOptions);
183605
+ files = await readdir(path28, this._rdOptions);
183606
183606
  } catch (error) {
183607
183607
  this._onError(error);
183608
183608
  }
183609
- return { files, depth, path: path27 };
183609
+ return { files, depth, path: path28 };
183610
183610
  }
183611
- async _formatEntry(dirent, path27) {
183611
+ async _formatEntry(dirent, path28) {
183612
183612
  let entry;
183613
183613
  const basename6 = this._isDirent ? dirent.name : dirent;
183614
183614
  try {
183615
- const fullPath = presolve(pjoin(path27, basename6));
183615
+ const fullPath = presolve(pjoin(path28, basename6));
183616
183616
  entry = { path: prelative(this._root, fullPath), fullPath, basename: basename6 };
183617
183617
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
183618
183618
  } catch (err) {
@@ -184012,16 +184012,16 @@ var delFromSet = (main, prop, item) => {
184012
184012
  };
184013
184013
  var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
184014
184014
  var FsWatchInstances = /* @__PURE__ */ new Map();
184015
- function createFsWatchInstance(path27, options2, listener, errHandler, emitRaw) {
184015
+ function createFsWatchInstance(path28, options2, listener, errHandler, emitRaw) {
184016
184016
  const handleEvent = (rawEvent, evPath) => {
184017
- listener(path27);
184018
- emitRaw(rawEvent, evPath, { watchedPath: path27 });
184019
- if (evPath && path27 !== evPath) {
184020
- fsWatchBroadcast(sp.resolve(path27, evPath), KEY_LISTENERS, sp.join(path27, evPath));
184017
+ listener(path28);
184018
+ emitRaw(rawEvent, evPath, { watchedPath: path28 });
184019
+ if (evPath && path28 !== evPath) {
184020
+ fsWatchBroadcast(sp.resolve(path28, evPath), KEY_LISTENERS, sp.join(path28, evPath));
184021
184021
  }
184022
184022
  };
184023
184023
  try {
184024
- return fs_watch(path27, {
184024
+ return fs_watch(path28, {
184025
184025
  persistent: options2.persistent
184026
184026
  }, handleEvent);
184027
184027
  } catch (error) {
@@ -184037,12 +184037,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
184037
184037
  listener(val1, val2, val3);
184038
184038
  });
184039
184039
  };
184040
- var setFsWatchListener = (path27, fullPath, options2, handlers) => {
184040
+ var setFsWatchListener = (path28, fullPath, options2, handlers) => {
184041
184041
  const { listener, errHandler, rawEmitter } = handlers;
184042
184042
  let cont = FsWatchInstances.get(fullPath);
184043
184043
  let watcher;
184044
184044
  if (!options2.persistent) {
184045
- watcher = createFsWatchInstance(path27, options2, listener, errHandler, rawEmitter);
184045
+ watcher = createFsWatchInstance(path28, options2, listener, errHandler, rawEmitter);
184046
184046
  if (!watcher)
184047
184047
  return;
184048
184048
  return watcher.close.bind(watcher);
@@ -184053,7 +184053,7 @@ var setFsWatchListener = (path27, fullPath, options2, handlers) => {
184053
184053
  addAndConvert(cont, KEY_RAW, rawEmitter);
184054
184054
  } else {
184055
184055
  watcher = createFsWatchInstance(
184056
- path27,
184056
+ path28,
184057
184057
  options2,
184058
184058
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
184059
184059
  errHandler,
@@ -184068,7 +184068,7 @@ var setFsWatchListener = (path27, fullPath, options2, handlers) => {
184068
184068
  cont.watcherUnusable = true;
184069
184069
  if (isWindows && error.code === "EPERM") {
184070
184070
  try {
184071
- const fd = await open(path27, "r");
184071
+ const fd = await open(path28, "r");
184072
184072
  await fd.close();
184073
184073
  broadcastErr(error);
184074
184074
  } catch (err) {
@@ -184099,7 +184099,7 @@ var setFsWatchListener = (path27, fullPath, options2, handlers) => {
184099
184099
  };
184100
184100
  };
184101
184101
  var FsWatchFileInstances = /* @__PURE__ */ new Map();
184102
- var setFsWatchFileListener = (path27, fullPath, options2, handlers) => {
184102
+ var setFsWatchFileListener = (path28, fullPath, options2, handlers) => {
184103
184103
  const { listener, rawEmitter } = handlers;
184104
184104
  let cont = FsWatchFileInstances.get(fullPath);
184105
184105
  const copts = cont && cont.options;
@@ -184121,7 +184121,7 @@ var setFsWatchFileListener = (path27, fullPath, options2, handlers) => {
184121
184121
  });
184122
184122
  const currmtime = curr.mtimeMs;
184123
184123
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
184124
- foreach(cont.listeners, (listener2) => listener2(path27, curr));
184124
+ foreach(cont.listeners, (listener2) => listener2(path28, curr));
184125
184125
  }
184126
184126
  })
184127
184127
  };
@@ -184151,13 +184151,13 @@ var NodeFsHandler = class {
184151
184151
  * @param listener on fs change
184152
184152
  * @returns closer for the watcher instance
184153
184153
  */
184154
- _watchWithNodeFs(path27, listener) {
184154
+ _watchWithNodeFs(path28, listener) {
184155
184155
  const opts = this.fsw.options;
184156
- const directory = sp.dirname(path27);
184157
- const basename6 = sp.basename(path27);
184156
+ const directory = sp.dirname(path28);
184157
+ const basename6 = sp.basename(path28);
184158
184158
  const parent = this.fsw._getWatchedDir(directory);
184159
184159
  parent.add(basename6);
184160
- const absolutePath = sp.resolve(path27);
184160
+ const absolutePath = sp.resolve(path28);
184161
184161
  const options2 = {
184162
184162
  persistent: opts.persistent
184163
184163
  };
@@ -184167,12 +184167,12 @@ var NodeFsHandler = class {
184167
184167
  if (opts.usePolling) {
184168
184168
  const enableBin = opts.interval !== opts.binaryInterval;
184169
184169
  options2.interval = enableBin && isBinaryPath(basename6) ? opts.binaryInterval : opts.interval;
184170
- closer = setFsWatchFileListener(path27, absolutePath, options2, {
184170
+ closer = setFsWatchFileListener(path28, absolutePath, options2, {
184171
184171
  listener,
184172
184172
  rawEmitter: this.fsw._emitRaw
184173
184173
  });
184174
184174
  } else {
184175
- closer = setFsWatchListener(path27, absolutePath, options2, {
184175
+ closer = setFsWatchListener(path28, absolutePath, options2, {
184176
184176
  listener,
184177
184177
  errHandler: this._boundHandleError,
184178
184178
  rawEmitter: this.fsw._emitRaw
@@ -184194,7 +184194,7 @@ var NodeFsHandler = class {
184194
184194
  let prevStats = stats;
184195
184195
  if (parent.has(basename6))
184196
184196
  return;
184197
- const listener = async (path27, newStats) => {
184197
+ const listener = async (path28, newStats) => {
184198
184198
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
184199
184199
  return;
184200
184200
  if (!newStats || newStats.mtimeMs === 0) {
@@ -184208,11 +184208,11 @@ var NodeFsHandler = class {
184208
184208
  this.fsw._emit(EV.CHANGE, file, newStats2);
184209
184209
  }
184210
184210
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
184211
- this.fsw._closeFile(path27);
184211
+ this.fsw._closeFile(path28);
184212
184212
  prevStats = newStats2;
184213
184213
  const closer2 = this._watchWithNodeFs(file, listener);
184214
184214
  if (closer2)
184215
- this.fsw._addPathCloser(path27, closer2);
184215
+ this.fsw._addPathCloser(path28, closer2);
184216
184216
  } else {
184217
184217
  prevStats = newStats2;
184218
184218
  }
@@ -184244,7 +184244,7 @@ var NodeFsHandler = class {
184244
184244
  * @param item basename of this item
184245
184245
  * @returns true if no more processing is needed for this entry.
184246
184246
  */
184247
- async _handleSymlink(entry, directory, path27, item) {
184247
+ async _handleSymlink(entry, directory, path28, item) {
184248
184248
  if (this.fsw.closed) {
184249
184249
  return;
184250
184250
  }
@@ -184254,7 +184254,7 @@ var NodeFsHandler = class {
184254
184254
  this.fsw._incrReadyCount();
184255
184255
  let linkPath;
184256
184256
  try {
184257
- linkPath = await fsrealpath(path27);
184257
+ linkPath = await fsrealpath(path28);
184258
184258
  } catch (e) {
184259
184259
  this.fsw._emitReady();
184260
184260
  return true;
@@ -184264,12 +184264,12 @@ var NodeFsHandler = class {
184264
184264
  if (dir.has(item)) {
184265
184265
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
184266
184266
  this.fsw._symlinkPaths.set(full, linkPath);
184267
- this.fsw._emit(EV.CHANGE, path27, entry.stats);
184267
+ this.fsw._emit(EV.CHANGE, path28, entry.stats);
184268
184268
  }
184269
184269
  } else {
184270
184270
  dir.add(item);
184271
184271
  this.fsw._symlinkPaths.set(full, linkPath);
184272
- this.fsw._emit(EV.ADD, path27, entry.stats);
184272
+ this.fsw._emit(EV.ADD, path28, entry.stats);
184273
184273
  }
184274
184274
  this.fsw._emitReady();
184275
184275
  return true;
@@ -184299,9 +184299,9 @@ var NodeFsHandler = class {
184299
184299
  return;
184300
184300
  }
184301
184301
  const item = entry.path;
184302
- let path27 = sp.join(directory, item);
184302
+ let path28 = sp.join(directory, item);
184303
184303
  current.add(item);
184304
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path27, item)) {
184304
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path28, item)) {
184305
184305
  return;
184306
184306
  }
184307
184307
  if (this.fsw.closed) {
@@ -184310,11 +184310,11 @@ var NodeFsHandler = class {
184310
184310
  }
184311
184311
  if (item === target || !target && !previous.has(item)) {
184312
184312
  this.fsw._incrReadyCount();
184313
- path27 = sp.join(dir, sp.relative(dir, path27));
184314
- this._addToNodeFs(path27, initialAdd, wh, depth + 1);
184313
+ path28 = sp.join(dir, sp.relative(dir, path28));
184314
+ this._addToNodeFs(path28, initialAdd, wh, depth + 1);
184315
184315
  }
184316
184316
  }).on(EV.ERROR, this._boundHandleError);
184317
- return new Promise((resolve9, reject) => {
184317
+ return new Promise((resolve10, reject) => {
184318
184318
  if (!stream)
184319
184319
  return reject();
184320
184320
  stream.once(STR_END, () => {
@@ -184323,7 +184323,7 @@ var NodeFsHandler = class {
184323
184323
  return;
184324
184324
  }
184325
184325
  const wasThrottled = throttler ? throttler.clear() : false;
184326
- resolve9(void 0);
184326
+ resolve10(void 0);
184327
184327
  previous.getChildren().filter((item) => {
184328
184328
  return item !== directory && !current.has(item);
184329
184329
  }).forEach((item) => {
@@ -184380,13 +184380,13 @@ var NodeFsHandler = class {
184380
184380
  * @param depth Child path actually targeted for watch
184381
184381
  * @param target Child path actually targeted for watch
184382
184382
  */
184383
- async _addToNodeFs(path27, initialAdd, priorWh, depth, target) {
184383
+ async _addToNodeFs(path28, initialAdd, priorWh, depth, target) {
184384
184384
  const ready = this.fsw._emitReady;
184385
- if (this.fsw._isIgnored(path27) || this.fsw.closed) {
184385
+ if (this.fsw._isIgnored(path28) || this.fsw.closed) {
184386
184386
  ready();
184387
184387
  return false;
184388
184388
  }
184389
- const wh = this.fsw._getWatchHelpers(path27);
184389
+ const wh = this.fsw._getWatchHelpers(path28);
184390
184390
  if (priorWh) {
184391
184391
  wh.filterPath = (entry) => priorWh.filterPath(entry);
184392
184392
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -184402,8 +184402,8 @@ var NodeFsHandler = class {
184402
184402
  const follow = this.fsw.options.followSymlinks;
184403
184403
  let closer;
184404
184404
  if (stats.isDirectory()) {
184405
- const absPath = sp.resolve(path27);
184406
- const targetPath = follow ? await fsrealpath(path27) : path27;
184405
+ const absPath = sp.resolve(path28);
184406
+ const targetPath = follow ? await fsrealpath(path28) : path28;
184407
184407
  if (this.fsw.closed)
184408
184408
  return;
184409
184409
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -184413,29 +184413,29 @@ var NodeFsHandler = class {
184413
184413
  this.fsw._symlinkPaths.set(absPath, targetPath);
184414
184414
  }
184415
184415
  } else if (stats.isSymbolicLink()) {
184416
- const targetPath = follow ? await fsrealpath(path27) : path27;
184416
+ const targetPath = follow ? await fsrealpath(path28) : path28;
184417
184417
  if (this.fsw.closed)
184418
184418
  return;
184419
184419
  const parent = sp.dirname(wh.watchPath);
184420
184420
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
184421
184421
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
184422
- closer = await this._handleDir(parent, stats, initialAdd, depth, path27, wh, targetPath);
184422
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path28, wh, targetPath);
184423
184423
  if (this.fsw.closed)
184424
184424
  return;
184425
184425
  if (targetPath !== void 0) {
184426
- this.fsw._symlinkPaths.set(sp.resolve(path27), targetPath);
184426
+ this.fsw._symlinkPaths.set(sp.resolve(path28), targetPath);
184427
184427
  }
184428
184428
  } else {
184429
184429
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
184430
184430
  }
184431
184431
  ready();
184432
184432
  if (closer)
184433
- this.fsw._addPathCloser(path27, closer);
184433
+ this.fsw._addPathCloser(path28, closer);
184434
184434
  return false;
184435
184435
  } catch (error) {
184436
184436
  if (this.fsw._handleError(error)) {
184437
184437
  ready();
184438
- return path27;
184438
+ return path28;
184439
184439
  }
184440
184440
  }
184441
184441
  }
@@ -184478,24 +184478,24 @@ function createPattern(matcher) {
184478
184478
  }
184479
184479
  return () => false;
184480
184480
  }
184481
- function normalizePath(path27) {
184482
- if (typeof path27 !== "string")
184481
+ function normalizePath(path28) {
184482
+ if (typeof path28 !== "string")
184483
184483
  throw new Error("string expected");
184484
- path27 = sp2.normalize(path27);
184485
- path27 = path27.replace(/\\/g, "/");
184484
+ path28 = sp2.normalize(path28);
184485
+ path28 = path28.replace(/\\/g, "/");
184486
184486
  let prepend = false;
184487
- if (path27.startsWith("//"))
184487
+ if (path28.startsWith("//"))
184488
184488
  prepend = true;
184489
- path27 = path27.replace(DOUBLE_SLASH_RE, "/");
184489
+ path28 = path28.replace(DOUBLE_SLASH_RE, "/");
184490
184490
  if (prepend)
184491
- path27 = "/" + path27;
184492
- return path27;
184491
+ path28 = "/" + path28;
184492
+ return path28;
184493
184493
  }
184494
184494
  function matchPatterns(patterns, testString, stats) {
184495
- const path27 = normalizePath(testString);
184495
+ const path28 = normalizePath(testString);
184496
184496
  for (let index = 0; index < patterns.length; index++) {
184497
184497
  const pattern = patterns[index];
184498
- if (pattern(path27, stats)) {
184498
+ if (pattern(path28, stats)) {
184499
184499
  return true;
184500
184500
  }
184501
184501
  }
@@ -184533,19 +184533,19 @@ var toUnix = (string) => {
184533
184533
  }
184534
184534
  return str;
184535
184535
  };
184536
- var normalizePathToUnix = (path27) => toUnix(sp2.normalize(toUnix(path27)));
184537
- var normalizeIgnored = (cwd = "") => (path27) => {
184538
- if (typeof path27 === "string") {
184539
- return normalizePathToUnix(sp2.isAbsolute(path27) ? path27 : sp2.join(cwd, path27));
184536
+ var normalizePathToUnix = (path28) => toUnix(sp2.normalize(toUnix(path28)));
184537
+ var normalizeIgnored = (cwd = "") => (path28) => {
184538
+ if (typeof path28 === "string") {
184539
+ return normalizePathToUnix(sp2.isAbsolute(path28) ? path28 : sp2.join(cwd, path28));
184540
184540
  } else {
184541
- return path27;
184541
+ return path28;
184542
184542
  }
184543
184543
  };
184544
- var getAbsolutePath = (path27, cwd) => {
184545
- if (sp2.isAbsolute(path27)) {
184546
- return path27;
184544
+ var getAbsolutePath = (path28, cwd) => {
184545
+ if (sp2.isAbsolute(path28)) {
184546
+ return path28;
184547
184547
  }
184548
- return sp2.join(cwd, path27);
184548
+ return sp2.join(cwd, path28);
184549
184549
  };
184550
184550
  var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
184551
184551
  var DirEntry = class {
@@ -184610,10 +184610,10 @@ var WatchHelper = class {
184610
184610
  dirParts;
184611
184611
  followSymlinks;
184612
184612
  statMethod;
184613
- constructor(path27, follow, fsw) {
184613
+ constructor(path28, follow, fsw) {
184614
184614
  this.fsw = fsw;
184615
- const watchPath = path27;
184616
- this.path = path27 = path27.replace(REPLACER_RE, "");
184615
+ const watchPath = path28;
184616
+ this.path = path28 = path28.replace(REPLACER_RE, "");
184617
184617
  this.watchPath = watchPath;
184618
184618
  this.fullWatchPath = sp2.resolve(watchPath);
184619
184619
  this.dirParts = [];
@@ -184753,20 +184753,20 @@ var FSWatcher = class extends EventEmitter {
184753
184753
  this._closePromise = void 0;
184754
184754
  let paths = unifyPaths(paths_);
184755
184755
  if (cwd) {
184756
- paths = paths.map((path27) => {
184757
- const absPath = getAbsolutePath(path27, cwd);
184756
+ paths = paths.map((path28) => {
184757
+ const absPath = getAbsolutePath(path28, cwd);
184758
184758
  return absPath;
184759
184759
  });
184760
184760
  }
184761
- paths.forEach((path27) => {
184762
- this._removeIgnoredPath(path27);
184761
+ paths.forEach((path28) => {
184762
+ this._removeIgnoredPath(path28);
184763
184763
  });
184764
184764
  this._userIgnored = void 0;
184765
184765
  if (!this._readyCount)
184766
184766
  this._readyCount = 0;
184767
184767
  this._readyCount += paths.length;
184768
- Promise.all(paths.map(async (path27) => {
184769
- const res = await this._nodeFsHandler._addToNodeFs(path27, !_internal, void 0, 0, _origAdd);
184768
+ Promise.all(paths.map(async (path28) => {
184769
+ const res = await this._nodeFsHandler._addToNodeFs(path28, !_internal, void 0, 0, _origAdd);
184770
184770
  if (res)
184771
184771
  this._emitReady();
184772
184772
  return res;
@@ -184788,17 +184788,17 @@ var FSWatcher = class extends EventEmitter {
184788
184788
  return this;
184789
184789
  const paths = unifyPaths(paths_);
184790
184790
  const { cwd } = this.options;
184791
- paths.forEach((path27) => {
184792
- if (!sp2.isAbsolute(path27) && !this._closers.has(path27)) {
184791
+ paths.forEach((path28) => {
184792
+ if (!sp2.isAbsolute(path28) && !this._closers.has(path28)) {
184793
184793
  if (cwd)
184794
- path27 = sp2.join(cwd, path27);
184795
- path27 = sp2.resolve(path27);
184794
+ path28 = sp2.join(cwd, path28);
184795
+ path28 = sp2.resolve(path28);
184796
184796
  }
184797
- this._closePath(path27);
184798
- this._addIgnoredPath(path27);
184799
- if (this._watched.has(path27)) {
184797
+ this._closePath(path28);
184798
+ this._addIgnoredPath(path28);
184799
+ if (this._watched.has(path28)) {
184800
184800
  this._addIgnoredPath({
184801
- path: path27,
184801
+ path: path28,
184802
184802
  recursive: true
184803
184803
  });
184804
184804
  }
@@ -184862,38 +184862,38 @@ var FSWatcher = class extends EventEmitter {
184862
184862
  * @param stats arguments to be passed with event
184863
184863
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
184864
184864
  */
184865
- async _emit(event, path27, stats) {
184865
+ async _emit(event, path28, stats) {
184866
184866
  if (this.closed)
184867
184867
  return;
184868
184868
  const opts = this.options;
184869
184869
  if (isWindows)
184870
- path27 = sp2.normalize(path27);
184870
+ path28 = sp2.normalize(path28);
184871
184871
  if (opts.cwd)
184872
- path27 = sp2.relative(opts.cwd, path27);
184873
- const args = [path27];
184872
+ path28 = sp2.relative(opts.cwd, path28);
184873
+ const args = [path28];
184874
184874
  if (stats != null)
184875
184875
  args.push(stats);
184876
184876
  const awf = opts.awaitWriteFinish;
184877
184877
  let pw;
184878
- if (awf && (pw = this._pendingWrites.get(path27))) {
184878
+ if (awf && (pw = this._pendingWrites.get(path28))) {
184879
184879
  pw.lastChange = /* @__PURE__ */ new Date();
184880
184880
  return this;
184881
184881
  }
184882
184882
  if (opts.atomic) {
184883
184883
  if (event === EVENTS.UNLINK) {
184884
- this._pendingUnlinks.set(path27, [event, ...args]);
184884
+ this._pendingUnlinks.set(path28, [event, ...args]);
184885
184885
  setTimeout(() => {
184886
- this._pendingUnlinks.forEach((entry, path28) => {
184886
+ this._pendingUnlinks.forEach((entry, path29) => {
184887
184887
  this.emit(...entry);
184888
184888
  this.emit(EVENTS.ALL, ...entry);
184889
- this._pendingUnlinks.delete(path28);
184889
+ this._pendingUnlinks.delete(path29);
184890
184890
  });
184891
184891
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
184892
184892
  return this;
184893
184893
  }
184894
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path27)) {
184894
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path28)) {
184895
184895
  event = EVENTS.CHANGE;
184896
- this._pendingUnlinks.delete(path27);
184896
+ this._pendingUnlinks.delete(path28);
184897
184897
  }
184898
184898
  }
184899
184899
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -184911,16 +184911,16 @@ var FSWatcher = class extends EventEmitter {
184911
184911
  this.emitWithAll(event, args);
184912
184912
  }
184913
184913
  };
184914
- this._awaitWriteFinish(path27, awf.stabilityThreshold, event, awfEmit);
184914
+ this._awaitWriteFinish(path28, awf.stabilityThreshold, event, awfEmit);
184915
184915
  return this;
184916
184916
  }
184917
184917
  if (event === EVENTS.CHANGE) {
184918
- const isThrottled = !this._throttle(EVENTS.CHANGE, path27, 50);
184918
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path28, 50);
184919
184919
  if (isThrottled)
184920
184920
  return this;
184921
184921
  }
184922
184922
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
184923
- const fullPath = opts.cwd ? sp2.join(opts.cwd, path27) : path27;
184923
+ const fullPath = opts.cwd ? sp2.join(opts.cwd, path28) : path28;
184924
184924
  let stats2;
184925
184925
  try {
184926
184926
  stats2 = await stat3(fullPath);
@@ -184951,23 +184951,23 @@ var FSWatcher = class extends EventEmitter {
184951
184951
  * @param timeout duration of time to suppress duplicate actions
184952
184952
  * @returns tracking object or false if action should be suppressed
184953
184953
  */
184954
- _throttle(actionType, path27, timeout) {
184954
+ _throttle(actionType, path28, timeout) {
184955
184955
  if (!this._throttled.has(actionType)) {
184956
184956
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
184957
184957
  }
184958
184958
  const action = this._throttled.get(actionType);
184959
184959
  if (!action)
184960
184960
  throw new Error("invalid throttle");
184961
- const actionPath = action.get(path27);
184961
+ const actionPath = action.get(path28);
184962
184962
  if (actionPath) {
184963
184963
  actionPath.count++;
184964
184964
  return false;
184965
184965
  }
184966
184966
  let timeoutObject;
184967
184967
  const clear = () => {
184968
- const item = action.get(path27);
184968
+ const item = action.get(path28);
184969
184969
  const count = item ? item.count : 0;
184970
- action.delete(path27);
184970
+ action.delete(path28);
184971
184971
  clearTimeout(timeoutObject);
184972
184972
  if (item)
184973
184973
  clearTimeout(item.timeoutObject);
@@ -184975,7 +184975,7 @@ var FSWatcher = class extends EventEmitter {
184975
184975
  };
184976
184976
  timeoutObject = setTimeout(clear, timeout);
184977
184977
  const thr = { timeoutObject, clear, count: 0 };
184978
- action.set(path27, thr);
184978
+ action.set(path28, thr);
184979
184979
  return thr;
184980
184980
  }
184981
184981
  _incrReadyCount() {
@@ -184989,44 +184989,44 @@ var FSWatcher = class extends EventEmitter {
184989
184989
  * @param event
184990
184990
  * @param awfEmit Callback to be called when ready for event to be emitted.
184991
184991
  */
184992
- _awaitWriteFinish(path27, threshold, event, awfEmit) {
184992
+ _awaitWriteFinish(path28, threshold, event, awfEmit) {
184993
184993
  const awf = this.options.awaitWriteFinish;
184994
184994
  if (typeof awf !== "object")
184995
184995
  return;
184996
184996
  const pollInterval = awf.pollInterval;
184997
184997
  let timeoutHandler;
184998
- let fullPath = path27;
184999
- if (this.options.cwd && !sp2.isAbsolute(path27)) {
185000
- fullPath = sp2.join(this.options.cwd, path27);
184998
+ let fullPath = path28;
184999
+ if (this.options.cwd && !sp2.isAbsolute(path28)) {
185000
+ fullPath = sp2.join(this.options.cwd, path28);
185001
185001
  }
185002
185002
  const now = /* @__PURE__ */ new Date();
185003
185003
  const writes = this._pendingWrites;
185004
185004
  function awaitWriteFinishFn(prevStat) {
185005
185005
  statcb(fullPath, (err, curStat) => {
185006
- if (err || !writes.has(path27)) {
185006
+ if (err || !writes.has(path28)) {
185007
185007
  if (err && err.code !== "ENOENT")
185008
185008
  awfEmit(err);
185009
185009
  return;
185010
185010
  }
185011
185011
  const now2 = Number(/* @__PURE__ */ new Date());
185012
185012
  if (prevStat && curStat.size !== prevStat.size) {
185013
- writes.get(path27).lastChange = now2;
185013
+ writes.get(path28).lastChange = now2;
185014
185014
  }
185015
- const pw = writes.get(path27);
185015
+ const pw = writes.get(path28);
185016
185016
  const df = now2 - pw.lastChange;
185017
185017
  if (df >= threshold) {
185018
- writes.delete(path27);
185018
+ writes.delete(path28);
185019
185019
  awfEmit(void 0, curStat);
185020
185020
  } else {
185021
185021
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
185022
185022
  }
185023
185023
  });
185024
185024
  }
185025
- if (!writes.has(path27)) {
185026
- writes.set(path27, {
185025
+ if (!writes.has(path28)) {
185026
+ writes.set(path28, {
185027
185027
  lastChange: now,
185028
185028
  cancelWait: () => {
185029
- writes.delete(path27);
185029
+ writes.delete(path28);
185030
185030
  clearTimeout(timeoutHandler);
185031
185031
  return event;
185032
185032
  }
@@ -185037,8 +185037,8 @@ var FSWatcher = class extends EventEmitter {
185037
185037
  /**
185038
185038
  * Determines whether user has asked to ignore this path.
185039
185039
  */
185040
- _isIgnored(path27, stats) {
185041
- if (this.options.atomic && DOT_RE.test(path27))
185040
+ _isIgnored(path28, stats) {
185041
+ if (this.options.atomic && DOT_RE.test(path28))
185042
185042
  return true;
185043
185043
  if (!this._userIgnored) {
185044
185044
  const { cwd } = this.options;
@@ -185048,17 +185048,17 @@ var FSWatcher = class extends EventEmitter {
185048
185048
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
185049
185049
  this._userIgnored = anymatch(list, void 0);
185050
185050
  }
185051
- return this._userIgnored(path27, stats);
185051
+ return this._userIgnored(path28, stats);
185052
185052
  }
185053
- _isntIgnored(path27, stat4) {
185054
- return !this._isIgnored(path27, stat4);
185053
+ _isntIgnored(path28, stat4) {
185054
+ return !this._isIgnored(path28, stat4);
185055
185055
  }
185056
185056
  /**
185057
185057
  * Provides a set of common helpers and properties relating to symlink handling.
185058
185058
  * @param path file or directory pattern being watched
185059
185059
  */
185060
- _getWatchHelpers(path27) {
185061
- return new WatchHelper(path27, this.options.followSymlinks, this);
185060
+ _getWatchHelpers(path28) {
185061
+ return new WatchHelper(path28, this.options.followSymlinks, this);
185062
185062
  }
185063
185063
  // Directory helpers
185064
185064
  // -----------------
@@ -185090,63 +185090,63 @@ var FSWatcher = class extends EventEmitter {
185090
185090
  * @param item base path of item/directory
185091
185091
  */
185092
185092
  _remove(directory, item, isDirectory) {
185093
- const path27 = sp2.join(directory, item);
185094
- const fullPath = sp2.resolve(path27);
185095
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path27) || this._watched.has(fullPath);
185096
- if (!this._throttle("remove", path27, 100))
185093
+ const path28 = sp2.join(directory, item);
185094
+ const fullPath = sp2.resolve(path28);
185095
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path28) || this._watched.has(fullPath);
185096
+ if (!this._throttle("remove", path28, 100))
185097
185097
  return;
185098
185098
  if (!isDirectory && this._watched.size === 1) {
185099
185099
  this.add(directory, item, true);
185100
185100
  }
185101
- const wp = this._getWatchedDir(path27);
185101
+ const wp = this._getWatchedDir(path28);
185102
185102
  const nestedDirectoryChildren = wp.getChildren();
185103
- nestedDirectoryChildren.forEach((nested) => this._remove(path27, nested));
185103
+ nestedDirectoryChildren.forEach((nested) => this._remove(path28, nested));
185104
185104
  const parent = this._getWatchedDir(directory);
185105
185105
  const wasTracked = parent.has(item);
185106
185106
  parent.remove(item);
185107
185107
  if (this._symlinkPaths.has(fullPath)) {
185108
185108
  this._symlinkPaths.delete(fullPath);
185109
185109
  }
185110
- let relPath = path27;
185110
+ let relPath = path28;
185111
185111
  if (this.options.cwd)
185112
- relPath = sp2.relative(this.options.cwd, path27);
185112
+ relPath = sp2.relative(this.options.cwd, path28);
185113
185113
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
185114
185114
  const event = this._pendingWrites.get(relPath).cancelWait();
185115
185115
  if (event === EVENTS.ADD)
185116
185116
  return;
185117
185117
  }
185118
- this._watched.delete(path27);
185118
+ this._watched.delete(path28);
185119
185119
  this._watched.delete(fullPath);
185120
185120
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
185121
- if (wasTracked && !this._isIgnored(path27))
185122
- this._emit(eventName, path27);
185123
- this._closePath(path27);
185121
+ if (wasTracked && !this._isIgnored(path28))
185122
+ this._emit(eventName, path28);
185123
+ this._closePath(path28);
185124
185124
  }
185125
185125
  /**
185126
185126
  * Closes all watchers for a path
185127
185127
  */
185128
- _closePath(path27) {
185129
- this._closeFile(path27);
185130
- const dir = sp2.dirname(path27);
185131
- this._getWatchedDir(dir).remove(sp2.basename(path27));
185128
+ _closePath(path28) {
185129
+ this._closeFile(path28);
185130
+ const dir = sp2.dirname(path28);
185131
+ this._getWatchedDir(dir).remove(sp2.basename(path28));
185132
185132
  }
185133
185133
  /**
185134
185134
  * Closes only file-specific watchers
185135
185135
  */
185136
- _closeFile(path27) {
185137
- const closers = this._closers.get(path27);
185136
+ _closeFile(path28) {
185137
+ const closers = this._closers.get(path28);
185138
185138
  if (!closers)
185139
185139
  return;
185140
185140
  closers.forEach((closer) => closer());
185141
- this._closers.delete(path27);
185141
+ this._closers.delete(path28);
185142
185142
  }
185143
- _addPathCloser(path27, closer) {
185143
+ _addPathCloser(path28, closer) {
185144
185144
  if (!closer)
185145
185145
  return;
185146
- let list = this._closers.get(path27);
185146
+ let list = this._closers.get(path28);
185147
185147
  if (!list) {
185148
185148
  list = [];
185149
- this._closers.set(path27, list);
185149
+ this._closers.set(path28, list);
185150
185150
  }
185151
185151
  list.push(closer);
185152
185152
  }
@@ -185221,15 +185221,17 @@ import * as fs11 from "fs";
185221
185221
  import * as path12 from "path";
185222
185222
  import * as net5 from "net";
185223
185223
  import { spawn as spawn5 } from "child_process";
185224
- import * as net6 from "net";
185225
185224
  import * as fs12 from "fs";
185226
185225
  import * as path13 from "path";
185226
+ import * as net6 from "net";
185227
+ import * as fs13 from "fs";
185228
+ import * as path14 from "path";
185227
185229
  import { generateSlug } from "random-word-slugs";
185228
185230
  import { EventEmitter as EventEmitter2 } from "node:events";
185229
185231
  import * as net7 from "node:net";
185230
185232
  import { EventEmitter as EventEmitter22 } from "events";
185231
185233
  import { execSync as execSync2 } from "child_process";
185232
- import * as path15 from "path";
185234
+ import * as path16 from "path";
185233
185235
  var __create2 = Object.create;
185234
185236
  var __defProp2 = Object.defineProperty;
185235
185237
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
@@ -185270,8 +185272,8 @@ var require_dist = __commonJS2({
185270
185272
  var $global, $module, $NaN = NaN;
185271
185273
  if ("undefined" != typeof window ? $global = window : "undefined" != typeof self ? $global = self : "undefined" != typeof global ? ($global = global).require = __require2 : $global = this, void 0 === $global || void 0 === $global.Array) throw new Error("no global object found");
185272
185274
  if ("undefined" != typeof module && ($module = module), !$global.fs && $global.require) try {
185273
- var fs142 = $global.require("fs");
185274
- "object" == typeof fs142 && null !== fs142 && 0 !== Object.keys(fs142).length && ($global.fs = fs142);
185275
+ var fs152 = $global.require("fs");
185276
+ "object" == typeof fs152 && null !== fs152 && 0 !== Object.keys(fs152).length && ($global.fs = fs152);
185275
185277
  } catch (e) {
185276
185278
  }
185277
185279
  if (!$global.fs) {
@@ -368995,10 +368997,10 @@ async function downloadFile(url, destPath, onProgress) {
368995
368997
  });
368996
368998
  }
368997
368999
  }
368998
- await new Promise((resolve52, reject) => {
369000
+ await new Promise((resolve62, reject) => {
368999
369001
  fileStream.end((err) => {
369000
369002
  if (err) reject(err);
369001
- else resolve52();
369003
+ else resolve62();
369002
369004
  });
369003
369005
  });
369004
369006
  fs4.renameSync(partPath, destPath);
@@ -369207,12 +369209,12 @@ var temporalBinary = {
369207
369209
  executables: ["temporal"]
369208
369210
  };
369209
369211
  function killProcess(proc, opts = {}) {
369210
- return new Promise((resolve52) => {
369212
+ return new Promise((resolve62) => {
369211
369213
  if (proc.killed || proc.exitCode !== null) {
369212
- resolve52();
369214
+ resolve62();
369213
369215
  return;
369214
369216
  }
369215
- proc.once("exit", () => resolve52());
369217
+ proc.once("exit", () => resolve62());
369216
369218
  if (opts.detached && proc.pid) {
369217
369219
  try {
369218
369220
  process.kill(-proc.pid, "SIGKILL");
@@ -369232,20 +369234,20 @@ function killProcessGroup(pid) {
369232
369234
  }
369233
369235
  var execFileAsync = promisify(execFile);
369234
369236
  function isPortInUse(host, port) {
369235
- return new Promise((resolve52) => {
369237
+ return new Promise((resolve62) => {
369236
369238
  const socket = new net.Socket();
369237
369239
  socket.setTimeout(1e3);
369238
369240
  socket.on("connect", () => {
369239
369241
  socket.destroy();
369240
- resolve52(true);
369242
+ resolve62(true);
369241
369243
  });
369242
369244
  socket.on("timeout", () => {
369243
369245
  socket.destroy();
369244
- resolve52(false);
369246
+ resolve62(false);
369245
369247
  });
369246
369248
  socket.on("error", () => {
369247
369249
  socket.destroy();
369248
- resolve52(false);
369250
+ resolve62(false);
369249
369251
  });
369250
369252
  socket.connect(port, host);
369251
369253
  });
@@ -369523,7 +369525,7 @@ async function startStorage(storage, port, dataDir) {
369523
369525
  };
369524
369526
  }
369525
369527
  async function runCommand(command, args, env2) {
369526
- return new Promise((resolve52, reject) => {
369528
+ return new Promise((resolve62, reject) => {
369527
369529
  const proc = spawn(command, args, {
369528
369530
  stdio: ["ignore", "pipe", "pipe"],
369529
369531
  env: env2
@@ -369534,7 +369536,7 @@ async function runCommand(command, args, env2) {
369534
369536
  });
369535
369537
  proc.on("close", (code) => {
369536
369538
  if (code === 0) {
369537
- resolve52();
369539
+ resolve62();
369538
369540
  } else {
369539
369541
  reject(new Error(`Command failed with code ${code}: ${stderr}`));
369540
369542
  }
@@ -369543,7 +369545,7 @@ async function runCommand(command, args, env2) {
369543
369545
  });
369544
369546
  }
369545
369547
  async function createPostgresDatabase(postgresPath, dataDir, dbName, env2) {
369546
- return new Promise((resolve52, reject) => {
369548
+ return new Promise((resolve62, reject) => {
369547
369549
  const proc = spawn(
369548
369550
  postgresPath,
369549
369551
  ["--single", "-D", dataDir, "postgres"],
@@ -369557,7 +369559,7 @@ async function createPostgresDatabase(postgresPath, dataDir, dbName, env2) {
369557
369559
  stderr += data.toString();
369558
369560
  });
369559
369561
  proc.on("close", (code) => {
369560
- resolve52();
369562
+ resolve62();
369561
369563
  });
369562
369564
  proc.on("error", reject);
369563
369565
  proc.stdin?.write(`CREATE DATABASE "${dbName}";
@@ -369610,26 +369612,26 @@ async function waitForTcpPort(host, port, timeoutMs = 3e4) {
369610
369612
  throw new Error(`Port ${port} did not become available within timeout`);
369611
369613
  }
369612
369614
  function checkTcpPort(host, port) {
369613
- return new Promise((resolve52) => {
369615
+ return new Promise((resolve62) => {
369614
369616
  const socket = new net2.Socket();
369615
369617
  socket.setTimeout(1e3);
369616
369618
  socket.on("connect", () => {
369617
369619
  socket.destroy();
369618
- resolve52(true);
369620
+ resolve62(true);
369619
369621
  });
369620
369622
  socket.on("timeout", () => {
369621
369623
  socket.destroy();
369622
- resolve52(false);
369624
+ resolve62(false);
369623
369625
  });
369624
369626
  socket.on("error", () => {
369625
369627
  socket.destroy();
369626
- resolve52(false);
369628
+ resolve62(false);
369627
369629
  });
369628
369630
  socket.connect(port, host);
369629
369631
  });
369630
369632
  }
369631
369633
  function sleep(ms) {
369632
- return new Promise((resolve52) => setTimeout(resolve52, ms));
369634
+ return new Promise((resolve62) => setTimeout(resolve62, ms));
369633
369635
  }
369634
369636
  var import_hcl2_json_parser2 = __toESM2(require_dist(), 1);
369635
369637
  var { parseToObject: parseToObject2 } = import_hcl2_json_parser2.default;
@@ -370126,12 +370128,12 @@ function startService(service, resources, secrets, configs, endpointPorts, servi
370126
370128
  ports: endpointPorts,
370127
370129
  process: child,
370128
370130
  async stop() {
370129
- return new Promise((resolve52) => {
370131
+ return new Promise((resolve62) => {
370130
370132
  if (child.killed || child.exitCode !== null) {
370131
- resolve52();
370133
+ resolve62();
370132
370134
  return;
370133
370135
  }
370134
- child.once("exit", () => resolve52());
370136
+ child.once("exit", () => resolve62());
370135
370137
  const pid = child.pid;
370136
370138
  if (pid) {
370137
370139
  killProcessGroup(pid);
@@ -370207,7 +370209,7 @@ var InstanceStateManager = class {
370207
370209
  }
370208
370210
  continue;
370209
370211
  }
370210
- await new Promise((resolve52) => setTimeout(resolve52, 100));
370212
+ await new Promise((resolve62) => setTimeout(resolve62, 100));
370211
370213
  } else {
370212
370214
  throw e;
370213
370215
  }
@@ -370591,7 +370593,7 @@ function proxyRequest(req, res, targetPort) {
370591
370593
  req.pipe(proxyReq, { end: true });
370592
370594
  }
370593
370595
  async function startAdminServer(getState, listenPort = 0) {
370594
- return new Promise((resolve52, reject) => {
370596
+ return new Promise((resolve62, reject) => {
370595
370597
  const server = http.createServer((req, res) => {
370596
370598
  const url = new URL(req.url || "/", "http://localhost");
370597
370599
  res.setHeader("Access-Control-Allow-Origin", "*");
@@ -370631,7 +370633,7 @@ async function startAdminServer(getState, listenPort = 0) {
370631
370633
  }
370632
370634
  const port = addr.port;
370633
370635
  writeLog("admin", `Admin server started on port ${port}`);
370634
- resolve52({
370636
+ resolve62({
370635
370637
  port,
370636
370638
  stop: () => new Promise((res, rej) => {
370637
370639
  server.close((err) => err ? rej(err) : res());
@@ -370799,26 +370801,26 @@ async function waitForTcpPort2(host, port, timeoutMs = 3e4) {
370799
370801
  throw new Error(`Electric port ${port} did not become available within timeout`);
370800
370802
  }
370801
370803
  function checkTcpPort2(host, port) {
370802
- return new Promise((resolve52) => {
370804
+ return new Promise((resolve62) => {
370803
370805
  const socket = new net3.Socket();
370804
370806
  socket.setTimeout(1e3);
370805
370807
  socket.on("connect", () => {
370806
370808
  socket.destroy();
370807
- resolve52(true);
370809
+ resolve62(true);
370808
370810
  });
370809
370811
  socket.on("timeout", () => {
370810
370812
  socket.destroy();
370811
- resolve52(false);
370813
+ resolve62(false);
370812
370814
  });
370813
370815
  socket.on("error", () => {
370814
370816
  socket.destroy();
370815
- resolve52(false);
370817
+ resolve62(false);
370816
370818
  });
370817
370819
  socket.connect(port, host);
370818
370820
  });
370819
370821
  }
370820
370822
  function sleep2(ms) {
370821
- return new Promise((resolve52) => setTimeout(resolve52, ms));
370823
+ return new Promise((resolve62) => setTimeout(resolve62, ms));
370822
370824
  }
370823
370825
  async function startMailServer(mail, smtpPort, apiPort) {
370824
370826
  const emails = [];
@@ -370909,19 +370911,19 @@ async function startMailServer(mail, smtpPort, apiPort) {
370909
370911
  res.writeHead(404);
370910
370912
  res.end();
370911
370913
  });
370912
- await new Promise((resolve52, reject) => {
370913
- smtpServer.listen(smtpPort, "127.0.0.1", () => resolve52());
370914
+ await new Promise((resolve62, reject) => {
370915
+ smtpServer.listen(smtpPort, "127.0.0.1", () => resolve62());
370914
370916
  smtpServer.on("error", reject);
370915
370917
  });
370916
- await new Promise((resolve52, reject) => {
370917
- httpServer.listen(apiPort, "127.0.0.1", () => resolve52());
370918
+ await new Promise((resolve62, reject) => {
370919
+ httpServer.listen(apiPort, "127.0.0.1", () => resolve62());
370918
370920
  httpServer.on("error", reject);
370919
370921
  });
370920
370922
  const stop = async () => {
370921
370923
  httpServer.closeAllConnections();
370922
370924
  await Promise.all([
370923
- new Promise((resolve52) => smtpServer.close(() => resolve52())),
370924
- new Promise((resolve52) => httpServer.close(() => resolve52()))
370925
+ new Promise((resolve62) => smtpServer.close(() => resolve62())),
370926
+ new Promise((resolve62) => httpServer.close(() => resolve62()))
370925
370927
  ]);
370926
370928
  };
370927
370929
  const resource = {
@@ -371026,26 +371028,26 @@ async function waitForTcpPort3(host, port, timeoutMs = 3e4) {
371026
371028
  );
371027
371029
  }
371028
371030
  function checkTcpPort3(host, port) {
371029
- return new Promise((resolve52) => {
371031
+ return new Promise((resolve62) => {
371030
371032
  const socket = new net4.Socket();
371031
371033
  socket.setTimeout(1e3);
371032
371034
  socket.on("connect", () => {
371033
371035
  socket.destroy();
371034
- resolve52(true);
371036
+ resolve62(true);
371035
371037
  });
371036
371038
  socket.on("timeout", () => {
371037
371039
  socket.destroy();
371038
- resolve52(false);
371040
+ resolve62(false);
371039
371041
  });
371040
371042
  socket.on("error", () => {
371041
371043
  socket.destroy();
371042
- resolve52(false);
371044
+ resolve62(false);
371043
371045
  });
371044
371046
  socket.connect(port, host);
371045
371047
  });
371046
371048
  }
371047
371049
  function sleep3(ms) {
371048
- return new Promise((resolve52) => setTimeout(resolve52, ms));
371050
+ return new Promise((resolve62) => setTimeout(resolve62, ms));
371049
371051
  }
371050
371052
  function detectSyncDatabases(config) {
371051
371053
  const needsSync = /* @__PURE__ */ new Set();
@@ -371483,25 +371485,25 @@ async function waitForTcpPort4(host, port, timeoutMs = 3e4) {
371483
371485
  if (isOpen) {
371484
371486
  return;
371485
371487
  }
371486
- await new Promise((resolve52) => setTimeout(resolve52, 100));
371488
+ await new Promise((resolve62) => setTimeout(resolve62, 100));
371487
371489
  }
371488
371490
  throw new Error(`Temporal port ${port} did not become available within timeout`);
371489
371491
  }
371490
371492
  function checkTcpPort4(host, port) {
371491
- return new Promise((resolve52) => {
371493
+ return new Promise((resolve62) => {
371492
371494
  const socket = new net5.Socket();
371493
371495
  socket.setTimeout(1e3);
371494
371496
  socket.on("connect", () => {
371495
371497
  socket.destroy();
371496
- resolve52(true);
371498
+ resolve62(true);
371497
371499
  });
371498
371500
  socket.on("timeout", () => {
371499
371501
  socket.destroy();
371500
- resolve52(false);
371502
+ resolve62(false);
371501
371503
  });
371502
371504
  socket.on("error", () => {
371503
371505
  socket.destroy();
371504
- resolve52(false);
371506
+ resolve62(false);
371505
371507
  });
371506
371508
  socket.connect(port, host);
371507
371509
  });
@@ -371763,6 +371765,77 @@ function watchConfigFile(configPath, debounceMs, onChange) {
371763
371765
  }
371764
371766
  };
371765
371767
  }
371768
+ var MAX_BYTES = 1024 * 1024;
371769
+ var TAIL_BYTES = 512 * 1024;
371770
+ var ServiceLogFiles = class {
371771
+ logsDir;
371772
+ files = /* @__PURE__ */ new Map();
371773
+ constructor(projectDir, instanceKey) {
371774
+ this.logsDir = path13.resolve(
371775
+ projectDir,
371776
+ ".specific",
371777
+ "keys",
371778
+ instanceKey,
371779
+ "logs"
371780
+ );
371781
+ fs12.mkdirSync(this.logsDir, { recursive: true });
371782
+ }
371783
+ write(line) {
371784
+ const file = this.getOrCreate(line.service);
371785
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
371786
+ const text = `[${timestamp}] [${line.stream}] ${line.text}
371787
+ `;
371788
+ const bytes = Buffer.byteLength(text);
371789
+ file.stream.write(text);
371790
+ file.bytes += bytes;
371791
+ if (file.bytes > MAX_BYTES) {
371792
+ this.rotate(line.service, file);
371793
+ }
371794
+ }
371795
+ close() {
371796
+ for (const file of this.files.values()) {
371797
+ file.stream.end();
371798
+ }
371799
+ this.files.clear();
371800
+ }
371801
+ getOrCreate(service) {
371802
+ const existing = this.files.get(service);
371803
+ if (existing) return existing;
371804
+ const filePath = path13.join(this.logsDir, `${service}.log`);
371805
+ let initialBytes = 0;
371806
+ try {
371807
+ initialBytes = fs12.statSync(filePath).size;
371808
+ } catch {
371809
+ }
371810
+ const file = {
371811
+ filePath,
371812
+ stream: fs12.createWriteStream(filePath, { flags: "a" }),
371813
+ bytes: initialBytes
371814
+ };
371815
+ this.files.set(service, file);
371816
+ return file;
371817
+ }
371818
+ rotate(service, file) {
371819
+ file.stream.end();
371820
+ this.files.delete(service);
371821
+ try {
371822
+ const buf = fs12.readFileSync(file.filePath);
371823
+ const start = Math.max(0, buf.length - TAIL_BYTES);
371824
+ let cut = start;
371825
+ if (start > 0) {
371826
+ const nl = buf.indexOf(10, start);
371827
+ cut = nl >= 0 ? nl + 1 : buf.length;
371828
+ }
371829
+ const tail = buf.subarray(cut);
371830
+ fs12.writeFileSync(file.filePath, tail);
371831
+ } catch {
371832
+ try {
371833
+ fs12.unlinkSync(file.filePath);
371834
+ } catch {
371835
+ }
371836
+ }
371837
+ }
371838
+ };
371766
371839
  var BLOCK_SIZE = 100;
371767
371840
  var FIRST_BLOCK_START = 3e3;
371768
371841
  var MAX_BLOCKS = 100;
@@ -371821,11 +371894,11 @@ var BlockPortAllocator = class _BlockPortAllocator {
371821
371894
  }
371822
371895
  };
371823
371896
  function isPortAvailable(port) {
371824
- return new Promise((resolve52) => {
371897
+ return new Promise((resolve62) => {
371825
371898
  const server = net6.createServer();
371826
- server.once("error", () => resolve52(false));
371899
+ server.once("error", () => resolve62(false));
371827
371900
  server.once("listening", () => {
371828
- server.close(() => resolve52(true));
371901
+ server.close(() => resolve62(true));
371829
371902
  });
371830
371903
  server.listen(port, "127.0.0.1");
371831
371904
  });
@@ -371835,16 +371908,16 @@ var StableSubdomainAllocator = class {
371835
371908
  tunnelsFilePath;
371836
371909
  baseSlug = null;
371837
371910
  constructor(projectRoot, key = "default") {
371838
- this.tunnelsDir = path13.join(projectRoot, ".specific", "keys", key);
371839
- this.tunnelsFilePath = path13.join(this.tunnelsDir, "tunnels.json");
371911
+ this.tunnelsDir = path14.join(projectRoot, ".specific", "keys", key);
371912
+ this.tunnelsFilePath = path14.join(this.tunnelsDir, "tunnels.json");
371840
371913
  this.loadTunnels();
371841
371914
  }
371842
371915
  loadTunnels() {
371843
- if (!fs12.existsSync(this.tunnelsFilePath)) {
371916
+ if (!fs13.existsSync(this.tunnelsFilePath)) {
371844
371917
  return;
371845
371918
  }
371846
371919
  try {
371847
- const content = fs12.readFileSync(this.tunnelsFilePath, "utf-8");
371920
+ const content = fs13.readFileSync(this.tunnelsFilePath, "utf-8");
371848
371921
  const data = JSON.parse(content);
371849
371922
  if (data.version === 1 && data.baseSlug) {
371850
371923
  this.baseSlug = data.baseSlug;
@@ -371854,14 +371927,14 @@ var StableSubdomainAllocator = class {
371854
371927
  }
371855
371928
  }
371856
371929
  saveTunnels() {
371857
- if (!fs12.existsSync(this.tunnelsDir)) {
371858
- fs12.mkdirSync(this.tunnelsDir, { recursive: true });
371930
+ if (!fs13.existsSync(this.tunnelsDir)) {
371931
+ fs13.mkdirSync(this.tunnelsDir, { recursive: true });
371859
371932
  }
371860
371933
  const data = {
371861
371934
  version: 1,
371862
371935
  baseSlug: this.baseSlug
371863
371936
  };
371864
- fs12.writeFileSync(this.tunnelsFilePath, JSON.stringify(data, null, 2));
371937
+ fs13.writeFileSync(this.tunnelsFilePath, JSON.stringify(data, null, 2));
371865
371938
  }
371866
371939
  generateBaseSlug() {
371867
371940
  return generateSlug(2, {
@@ -372147,6 +372220,7 @@ var DevEnvironment = class extends TypedEventEmitter {
372147
372220
  startTime = null;
372148
372221
  // Core managers
372149
372222
  stateManager = null;
372223
+ serviceLogFiles = null;
372150
372224
  // Running instances
372151
372225
  adminServer = null;
372152
372226
  services = [];
@@ -372201,6 +372275,7 @@ var DevEnvironment = class extends TypedEventEmitter {
372201
372275
  }
372202
372276
  // ── Log helper ─────────────────────────────────────────────────────────────
372203
372277
  addLog(line) {
372278
+ this.serviceLogFiles?.write(line);
372204
372279
  this.emit("log", { service: line.service, text: line.text });
372205
372280
  }
372206
372281
  // ── Public methods ─────────────────────────────────────────────────────────
@@ -372213,8 +372288,8 @@ var DevEnvironment = class extends TypedEventEmitter {
372213
372288
  this.started = true;
372214
372289
  this.shuttingDown = false;
372215
372290
  this.cancelled = false;
372216
- return new Promise((resolve52) => {
372217
- this.startResolve = resolve52;
372291
+ return new Promise((resolve62) => {
372292
+ this.startResolve = resolve62;
372218
372293
  this.startInternal().then(() => {
372219
372294
  if (this.startResolve) {
372220
372295
  this.startResolve();
@@ -372395,6 +372470,8 @@ var DevEnvironment = class extends TypedEventEmitter {
372395
372470
  this.restartServices = null;
372396
372471
  this.removeExitHandler();
372397
372472
  this.systemLog("Shutdown complete");
372473
+ this.serviceLogFiles?.close();
372474
+ this.serviceLogFiles = null;
372398
372475
  closeDebugLog();
372399
372476
  this.setStatus("idle");
372400
372477
  this.emit("stopped");
@@ -372466,10 +372543,10 @@ var DevEnvironment = class extends TypedEventEmitter {
372466
372543
  }
372467
372544
  // ── Private: config file watcher ───────────────────────────────────────────
372468
372545
  startConfigWatcher() {
372469
- const configPath = path14.join(this.projectDir, "specific.hcl");
372546
+ const configPath = path15.join(this.projectDir, "specific.hcl");
372470
372547
  this.configWatcher = watchConfigFile(configPath, 1e3, () => {
372471
372548
  try {
372472
- const hcl = fs13.readFileSync(configPath, "utf-8");
372549
+ const hcl = fs14.readFileSync(configPath, "utf-8");
372473
372550
  parseConfig(hcl).then(() => {
372474
372551
  this.reload();
372475
372552
  }).catch((err) => {
@@ -372490,6 +372567,12 @@ var DevEnvironment = class extends TypedEventEmitter {
372490
372567
  this.instanceKey
372491
372568
  );
372492
372569
  this.stateManager = stateManager;
372570
+ if (!this.serviceLogFiles) {
372571
+ this.serviceLogFiles = new ServiceLogFiles(
372572
+ this.projectDir,
372573
+ this.instanceKey
372574
+ );
372575
+ }
372493
372576
  this.systemLog("Starting dev server");
372494
372577
  this.setStatus("loading");
372495
372578
  await stateManager.cleanStaleState();
@@ -372508,8 +372591,8 @@ var DevEnvironment = class extends TypedEventEmitter {
372508
372591
  this.emit("error", new Error(msg));
372509
372592
  return;
372510
372593
  }
372511
- const configPath = path14.join(this.projectDir, "specific.hcl");
372512
- if (!fs13.existsSync(configPath)) {
372594
+ const configPath = path15.join(this.projectDir, "specific.hcl");
372595
+ if (!fs14.existsSync(configPath)) {
372513
372596
  this.systemLog("Waiting for specific.hcl to appear");
372514
372597
  this.setStatus("waiting");
372515
372598
  const dirWatcher = chokidar_default.watch(configPath, {
@@ -372530,7 +372613,7 @@ var DevEnvironment = class extends TypedEventEmitter {
372530
372613
  return;
372531
372614
  }
372532
372615
  let config;
372533
- const hcl = fs13.readFileSync(configPath, "utf-8");
372616
+ const hcl = fs14.readFileSync(configPath, "utf-8");
372534
372617
  try {
372535
372618
  config = await parseConfig(hcl);
372536
372619
  } catch (err) {
@@ -372540,9 +372623,9 @@ var DevEnvironment = class extends TypedEventEmitter {
372540
372623
  return;
372541
372624
  }
372542
372625
  if (this.cancelled) return;
372543
- const localFilePath = path14.join(this.projectDir, "specific.local");
372544
- if (fs13.existsSync(localFilePath)) {
372545
- const localContent = fs13.readFileSync(localFilePath, "utf-8");
372626
+ const localFilePath = path15.join(this.projectDir, "specific.local");
372627
+ if (fs14.existsSync(localFilePath)) {
372628
+ const localContent = fs14.readFileSync(localFilePath, "utf-8");
372546
372629
  try {
372547
372630
  await parseLocalFile(localContent);
372548
372631
  } catch (err) {
@@ -372660,7 +372743,7 @@ var DevEnvironment = class extends TypedEventEmitter {
372660
372743
  const drizzleGateway = await startDrizzleGateway(
372661
372744
  postgresResources,
372662
372745
  drizzlePort,
372663
- path14.join(this.projectDir, ".specific", "keys", this.instanceKey)
372746
+ path15.join(this.projectDir, ".specific", "keys", this.instanceKey)
372664
372747
  );
372665
372748
  this.drizzleGateway = drizzleGateway;
372666
372749
  this.systemLog(`Database viewer ready at ${drizzleGateway.url}`);
@@ -372687,14 +372770,14 @@ var DevEnvironment = class extends TypedEventEmitter {
372687
372770
  if (pg.reshape?.enabled) {
372688
372771
  const resource = resources.get(pg.name);
372689
372772
  if (!resource) continue;
372690
- const migrationsDir = path14.resolve(
372773
+ const migrationsDir = path15.resolve(
372691
372774
  this.projectDir,
372692
372775
  pg.reshape.migrations_dir ?? "migrations"
372693
372776
  );
372694
372777
  this.systemLog(
372695
372778
  `Initializing Reshape migrations for "${pg.name}" from ${migrationsDir}`
372696
372779
  );
372697
- const reshapeStateFile = path14.join(
372780
+ const reshapeStateFile = path15.join(
372698
372781
  this.projectDir,
372699
372782
  ".specific",
372700
372783
  "keys",
@@ -372798,8 +372881,8 @@ var DevEnvironment = class extends TypedEventEmitter {
372798
372881
  if (missingConfigs.length > 0) {
372799
372882
  this.emit("inputRequired", "configs", missingConfigs);
372800
372883
  }
372801
- await new Promise((resolve52) => {
372802
- this.inputResolve = resolve52;
372884
+ await new Promise((resolve62) => {
372885
+ this.inputResolve = resolve62;
372803
372886
  this.checkInputComplete();
372804
372887
  });
372805
372888
  for (const [name, value] of Object.entries(this.collectedSecrets)) {
@@ -372907,13 +372990,13 @@ Add them to the config block in specific.local`
372907
372990
  const runningServices = [];
372908
372991
  const resolveServiceCwd = (service) => {
372909
372992
  if (service.root)
372910
- return path14.resolve(this.projectDir, service.root);
372993
+ return path15.resolve(this.projectDir, service.root);
372911
372994
  if (service.build) {
372912
372995
  const build = config.builds.find(
372913
372996
  (b) => b.name === service.build.name
372914
372997
  );
372915
372998
  if (build?.root)
372916
- return path14.resolve(this.projectDir, build.root);
372999
+ return path15.resolve(this.projectDir, build.root);
372917
373000
  }
372918
373001
  return this.projectDir;
372919
373002
  };
@@ -372933,7 +373016,7 @@ Add them to the config block in specific.local`
372933
373016
  const volumePaths = /* @__PURE__ */ new Map();
372934
373017
  if (service.volumes) {
372935
373018
  for (const vol of service.volumes) {
372936
- const volumeDir = path14.resolve(
373019
+ const volumeDir = path15.resolve(
372937
373020
  this.projectDir,
372938
373021
  ".specific",
372939
373022
  "keys",
@@ -372943,7 +373026,7 @@ Add them to the config block in specific.local`
372943
373026
  service.name,
372944
373027
  vol.name
372945
373028
  );
372946
- fs13.mkdirSync(volumeDir, { recursive: true });
373029
+ fs14.mkdirSync(volumeDir, { recursive: true });
372947
373030
  volumePaths.set(vol.name, volumeDir);
372948
373031
  }
372949
373032
  }
@@ -372993,7 +373076,7 @@ Add them to the config block in specific.local`
372993
373076
  const volumePaths = /* @__PURE__ */ new Map();
372994
373077
  if (service.volumes) {
372995
373078
  for (const vol of service.volumes) {
372996
- const volumeDir = path14.resolve(
373079
+ const volumeDir = path15.resolve(
372997
373080
  this.projectDir,
372998
373081
  ".specific",
372999
373082
  "keys",
@@ -373003,7 +373086,7 @@ Add them to the config block in specific.local`
373003
373086
  service.name,
373004
373087
  vol.name
373005
373088
  );
373006
- fs13.mkdirSync(volumeDir, { recursive: true });
373089
+ fs14.mkdirSync(volumeDir, { recursive: true });
373007
373090
  volumePaths.set(vol.name, volumeDir);
373008
373091
  }
373009
373092
  }
@@ -373173,8 +373256,8 @@ function isInWorktree() {
373173
373256
  encoding: "utf-8",
373174
373257
  stdio: ["pipe", "pipe", "pipe"]
373175
373258
  }).trim();
373176
- const resolvedCommonDir = path15.resolve(commonDir);
373177
- const resolvedGitDir = path15.resolve(gitDir);
373259
+ const resolvedCommonDir = path16.resolve(commonDir);
373260
+ const resolvedGitDir = path16.resolve(gitDir);
373178
373261
  return resolvedCommonDir !== resolvedGitDir;
373179
373262
  } catch {
373180
373263
  return false;
@@ -373189,7 +373272,7 @@ function getWorktreeName() {
373189
373272
  encoding: "utf-8",
373190
373273
  stdio: ["pipe", "pipe", "pipe"]
373191
373274
  }).trim();
373192
- return path15.basename(gitDir);
373275
+ return path16.basename(gitDir);
373193
373276
  } catch {
373194
373277
  return null;
373195
373278
  }
@@ -373282,9 +373365,14 @@ function writePreviewEnvironmentId(environmentId, projectDir = process.cwd()) {
373282
373365
  fs3.writeFileSync(path3.join(specificDir, "preview_environment_id"), environmentId + "\n");
373283
373366
  }
373284
373367
 
373368
+ // src/lib/project/environment.ts
373369
+ function findEnvironmentByNameOrId(environments, flag) {
373370
+ return environments.find((e) => e.id === flag) ?? environments.find((e) => e.name === flag);
373371
+ }
373372
+
373285
373373
  // src/lib/auth/credentials.ts
373286
- import * as fs19 from "fs";
373287
- import * as path17 from "path";
373374
+ import * as fs20 from "fs";
373375
+ import * as path18 from "path";
373288
373376
  import * as os4 from "os";
373289
373377
 
373290
373378
  // src/lib/auth/errors.ts
@@ -373454,7 +373542,7 @@ async function pollUntilToken(deviceAuth, isCancelled) {
373454
373542
  return null;
373455
373543
  }
373456
373544
  function sleep4(ms) {
373457
- return new Promise((resolve9) => setTimeout(resolve9, ms));
373545
+ return new Promise((resolve10) => setTimeout(resolve10, ms));
373458
373546
  }
373459
373547
 
373460
373548
  // src/lib/auth/login.tsx
@@ -373471,7 +373559,7 @@ function LoginUI({
373471
373559
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, isReauthentication && /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "Session expired. Please log in again."), /* @__PURE__ */ React.createElement(Text, { bold: true }, "Log in to Specific"), state.phase === "waiting-for-browser" ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, "Your authentication code:", " ", /* @__PURE__ */ React.createElement(Text, { color: "cyan", bold: true }, state.userCode))), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "blue" }, /* @__PURE__ */ React.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React.createElement(Text, null, " Waiting for authentication in browser...")), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "If the browser didn't open, visit: ", state.verificationUri)) : /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "blue" }, /* @__PURE__ */ React.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React.createElement(Text, null, " Initiating login...")));
373472
373560
  }
373473
373561
  function performLogin(options2 = {}) {
373474
- return new Promise((resolve9) => {
373562
+ return new Promise((resolve10) => {
373475
373563
  let currentState = { phase: "initiating" };
373476
373564
  let flowHandle;
373477
373565
  const instance = render(
@@ -373511,14 +373599,14 @@ function performLogin(options2 = {}) {
373511
373599
  process.off("SIGINT", handleExit);
373512
373600
  process.off("SIGTERM", handleExit);
373513
373601
  instance.unmount();
373514
- resolve9({ success: true, userEmail: newState.email });
373602
+ resolve10({ success: true, userEmail: newState.email });
373515
373603
  }, 100);
373516
373604
  } else if (newState.phase === "error") {
373517
373605
  setTimeout(() => {
373518
373606
  process.off("SIGINT", handleExit);
373519
373607
  process.off("SIGTERM", handleExit);
373520
373608
  instance.unmount();
373521
- resolve9({ success: false, error: new Error(newState.message) });
373609
+ resolve10({ success: false, error: new Error(newState.message) });
373522
373610
  }, 100);
373523
373611
  }
373524
373612
  }
@@ -373609,18 +373697,18 @@ async function fetchGithubActionsIdToken() {
373609
373697
 
373610
373698
  // src/lib/auth/credentials.ts
373611
373699
  function getUserCredentialsDir() {
373612
- return path17.join(os4.homedir(), ".specific");
373700
+ return path18.join(os4.homedir(), ".specific");
373613
373701
  }
373614
373702
  function getCredentialsPath() {
373615
- return path17.join(getUserCredentialsDir(), "credentials.json");
373703
+ return path18.join(getUserCredentialsDir(), "credentials.json");
373616
373704
  }
373617
373705
  function readUserCredentials() {
373618
373706
  const credentialsPath = getCredentialsPath();
373619
- if (!fs19.existsSync(credentialsPath)) {
373707
+ if (!fs20.existsSync(credentialsPath)) {
373620
373708
  return null;
373621
373709
  }
373622
373710
  try {
373623
- const content = fs19.readFileSync(credentialsPath, "utf-8");
373711
+ const content = fs20.readFileSync(credentialsPath, "utf-8");
373624
373712
  return JSON.parse(content);
373625
373713
  } catch {
373626
373714
  return null;
@@ -373628,18 +373716,18 @@ function readUserCredentials() {
373628
373716
  }
373629
373717
  function writeUserCredentials(credentials) {
373630
373718
  const dir = getUserCredentialsDir();
373631
- if (!fs19.existsSync(dir)) {
373632
- fs19.mkdirSync(dir, { recursive: true, mode: 448 });
373719
+ if (!fs20.existsSync(dir)) {
373720
+ fs20.mkdirSync(dir, { recursive: true, mode: 448 });
373633
373721
  }
373634
373722
  const credentialsPath = getCredentialsPath();
373635
- fs19.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {
373723
+ fs20.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {
373636
373724
  mode: 384
373637
373725
  });
373638
373726
  }
373639
373727
  function clearUserCredentials() {
373640
373728
  const credentialsPath = getCredentialsPath();
373641
- if (fs19.existsSync(credentialsPath)) {
373642
- fs19.unlinkSync(credentialsPath);
373729
+ if (fs20.existsSync(credentialsPath)) {
373730
+ fs20.unlinkSync(credentialsPath);
373643
373731
  }
373644
373732
  }
373645
373733
  function isLoggedIn() {
@@ -373768,7 +373856,7 @@ function trackEvent(event, properties) {
373768
373856
  event,
373769
373857
  properties: {
373770
373858
  ...properties,
373771
- cli_version: "0.1.139",
373859
+ cli_version: "0.1.141",
373772
373860
  platform: process.platform,
373773
373861
  node_version: process.version,
373774
373862
  project_id: getProjectId()
@@ -373799,67 +373887,67 @@ var options = [
373799
373887
  { id: "other", label: "Other / Manual" }
373800
373888
  ];
373801
373889
  function isGitProject() {
373802
- const gitPath = path18.join(process.cwd(), ".git");
373803
- return fs20.existsSync(gitPath);
373890
+ const gitPath = path19.join(process.cwd(), ".git");
373891
+ return fs21.existsSync(gitPath);
373804
373892
  }
373805
373893
  function detectExistingAgents() {
373806
373894
  const detected = {};
373807
- const cursorDir = path18.join(process.cwd(), ".cursor");
373808
- if (fs20.existsSync(cursorDir)) {
373895
+ const cursorDir = path19.join(process.cwd(), ".cursor");
373896
+ if (fs21.existsSync(cursorDir)) {
373809
373897
  detected["cursor"] = true;
373810
373898
  }
373811
- const claudeDir = path18.join(process.cwd(), ".claude");
373812
- const claudeMd = path18.join(process.cwd(), "CLAUDE.md");
373813
- if (fs20.existsSync(claudeDir) || fs20.existsSync(claudeMd)) {
373899
+ const claudeDir = path19.join(process.cwd(), ".claude");
373900
+ const claudeMd = path19.join(process.cwd(), "CLAUDE.md");
373901
+ if (fs21.existsSync(claudeDir) || fs21.existsSync(claudeMd)) {
373814
373902
  detected["claude"] = true;
373815
373903
  }
373816
- const agentsMd = path18.join(process.cwd(), "AGENTS.md");
373817
- if (fs20.existsSync(agentsMd)) {
373904
+ const agentsMd = path19.join(process.cwd(), "AGENTS.md");
373905
+ if (fs21.existsSync(agentsMd)) {
373818
373906
  detected["codex"] = true;
373819
373907
  }
373820
373908
  return detected;
373821
373909
  }
373822
373910
  function appendOrCreateFile(filePath, content) {
373823
- if (fs20.existsSync(filePath)) {
373824
- const existing = fs20.readFileSync(filePath, "utf-8");
373911
+ if (fs21.existsSync(filePath)) {
373912
+ const existing = fs21.readFileSync(filePath, "utf-8");
373825
373913
  if (existing.includes("specific docs") || existing.includes("specific check")) {
373826
373914
  return "unchanged";
373827
373915
  }
373828
373916
  const separator = existing.endsWith("\n") ? "\n" : "\n\n";
373829
- fs20.writeFileSync(filePath, existing + separator + content + "\n");
373917
+ fs21.writeFileSync(filePath, existing + separator + content + "\n");
373830
373918
  return "modified";
373831
373919
  } else {
373832
- fs20.writeFileSync(filePath, content + "\n");
373920
+ fs21.writeFileSync(filePath, content + "\n");
373833
373921
  return "created";
373834
373922
  }
373835
373923
  }
373836
373924
  function addToGitignore() {
373837
- const gitignorePath = path18.join(process.cwd(), ".gitignore");
373925
+ const gitignorePath = path19.join(process.cwd(), ".gitignore");
373838
373926
  const entries = [".specific", "specific.local"];
373839
- if (fs20.existsSync(gitignorePath)) {
373840
- const existing = fs20.readFileSync(gitignorePath, "utf-8");
373927
+ if (fs21.existsSync(gitignorePath)) {
373928
+ const existing = fs21.readFileSync(gitignorePath, "utf-8");
373841
373929
  const lines = existing.split("\n").map((l) => l.trim());
373842
373930
  const missingEntries = entries.filter((entry) => !lines.includes(entry));
373843
373931
  if (missingEntries.length === 0) {
373844
373932
  return "unchanged";
373845
373933
  }
373846
373934
  const separator = existing.endsWith("\n") ? "" : "\n";
373847
- fs20.writeFileSync(
373935
+ fs21.writeFileSync(
373848
373936
  gitignorePath,
373849
373937
  existing + separator + missingEntries.join("\n") + "\n"
373850
373938
  );
373851
373939
  return "modified";
373852
373940
  } else {
373853
- fs20.writeFileSync(gitignorePath, entries.join("\n") + "\n");
373941
+ fs21.writeFileSync(gitignorePath, entries.join("\n") + "\n");
373854
373942
  return "created";
373855
373943
  }
373856
373944
  }
373857
373945
  function configureClaudeCodePermissions() {
373858
- const claudeDir = path18.join(process.cwd(), ".claude");
373859
- const settingsPath = path18.join(claudeDir, "settings.local.json");
373946
+ const claudeDir = path19.join(process.cwd(), ".claude");
373947
+ const settingsPath = path19.join(claudeDir, "settings.local.json");
373860
373948
  const permissions = ["Bash(specific docs:*)", "Bash(specific check:*)"];
373861
- if (fs20.existsSync(settingsPath)) {
373862
- const existing = JSON.parse(fs20.readFileSync(settingsPath, "utf-8"));
373949
+ if (fs21.existsSync(settingsPath)) {
373950
+ const existing = JSON.parse(fs21.readFileSync(settingsPath, "utf-8"));
373863
373951
  const allowList = existing?.permissions?.allow || [];
373864
373952
  const missingPermissions = permissions.filter(
373865
373953
  (p) => !allowList.includes(p)
@@ -373874,39 +373962,39 @@ function configureClaudeCodePermissions() {
373874
373962
  existing.permissions.allow = [];
373875
373963
  }
373876
373964
  existing.permissions.allow.push(...missingPermissions);
373877
- fs20.writeFileSync(settingsPath, JSON.stringify(existing, null, 2) + "\n");
373965
+ fs21.writeFileSync(settingsPath, JSON.stringify(existing, null, 2) + "\n");
373878
373966
  return "modified";
373879
373967
  }
373880
- if (!fs20.existsSync(claudeDir)) {
373881
- fs20.mkdirSync(claudeDir);
373968
+ if (!fs21.existsSync(claudeDir)) {
373969
+ fs21.mkdirSync(claudeDir);
373882
373970
  }
373883
373971
  const settings = {
373884
373972
  permissions: {
373885
373973
  allow: permissions
373886
373974
  }
373887
373975
  };
373888
- fs20.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
373976
+ fs21.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
373889
373977
  return "created";
373890
373978
  }
373891
373979
  function createCursorRule() {
373892
- const cursorDir = path18.join(process.cwd(), ".cursor");
373893
- const rulesDir = path18.join(cursorDir, "rules");
373894
- const mdcPath = path18.join(rulesDir, "specific.mdc");
373895
- if (fs20.existsSync(mdcPath)) {
373896
- const existing = fs20.readFileSync(mdcPath, "utf-8");
373980
+ const cursorDir = path19.join(process.cwd(), ".cursor");
373981
+ const rulesDir = path19.join(cursorDir, "rules");
373982
+ const mdcPath = path19.join(rulesDir, "specific.mdc");
373983
+ if (fs21.existsSync(mdcPath)) {
373984
+ const existing = fs21.readFileSync(mdcPath, "utf-8");
373897
373985
  if (existing.includes("specific docs") || existing.includes("specific check")) {
373898
373986
  return "unchanged";
373899
373987
  }
373900
- fs20.writeFileSync(mdcPath, CURSOR_MDC_CONTENT);
373988
+ fs21.writeFileSync(mdcPath, CURSOR_MDC_CONTENT);
373901
373989
  return "modified";
373902
373990
  }
373903
- if (!fs20.existsSync(cursorDir)) {
373904
- fs20.mkdirSync(cursorDir);
373991
+ if (!fs21.existsSync(cursorDir)) {
373992
+ fs21.mkdirSync(cursorDir);
373905
373993
  }
373906
- if (!fs20.existsSync(rulesDir)) {
373907
- fs20.mkdirSync(rulesDir);
373994
+ if (!fs21.existsSync(rulesDir)) {
373995
+ fs21.mkdirSync(rulesDir);
373908
373996
  }
373909
- fs20.writeFileSync(mdcPath, CURSOR_MDC_CONTENT);
373997
+ fs21.writeFileSync(mdcPath, CURSOR_MDC_CONTENT);
373910
373998
  return "created";
373911
373999
  }
373912
374000
  function configureAgents(checked) {
@@ -373922,7 +374010,7 @@ function configureAgents(checked) {
373922
374010
  agents.filesModified.push(".cursor/rules/specific.mdc");
373923
374011
  }
373924
374012
  if (checked["claude"]) {
373925
- const claudeMdPath = path18.join(process.cwd(), "CLAUDE.md");
374013
+ const claudeMdPath = path19.join(process.cwd(), "CLAUDE.md");
373926
374014
  const status = appendOrCreateFile(claudeMdPath, SPECIFIC_INSTRUCTIONS);
373927
374015
  if (status === "created") agents.filesCreated.push("CLAUDE.md");
373928
374016
  else if (status === "modified") agents.filesModified.push("CLAUDE.md");
@@ -373933,7 +374021,7 @@ function configureAgents(checked) {
373933
374021
  agents.filesModified.push(".claude/settings.local.json");
373934
374022
  }
373935
374023
  if (checked["codex"]) {
373936
- const agentsMdPath = path18.join(process.cwd(), "AGENTS.md");
374024
+ const agentsMdPath = path19.join(process.cwd(), "AGENTS.md");
373937
374025
  const status = appendOrCreateFile(agentsMdPath, SPECIFIC_INSTRUCTIONS);
373938
374026
  if (status === "created") agents.filesCreated.push("AGENTS.md");
373939
374027
  else if (status === "modified") agents.filesModified.push("AGENTS.md");
@@ -374086,9 +374174,9 @@ Valid agents: ${VALID_AGENT_IDS.join(", ")}`
374086
374174
  }
374087
374175
 
374088
374176
  // src/commands/docs.tsx
374089
- import { readFileSync as readFileSync11, existsSync as existsSync17 } from "fs";
374177
+ import { readFileSync as readFileSync12, existsSync as existsSync17 } from "fs";
374090
374178
  import { spawn as spawn6 } from "child_process";
374091
- import { join as join19, dirname as dirname9 } from "path";
374179
+ import { join as join20, dirname as dirname9 } from "path";
374092
374180
  import { fileURLToPath as fileURLToPath3 } from "url";
374093
374181
 
374094
374182
  // src/lib/beta/registry.ts
@@ -374100,16 +374188,16 @@ var BETA_REGISTRY = [
374100
374188
  ];
374101
374189
 
374102
374190
  // src/lib/beta/storage.ts
374103
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync8, existsSync as existsSync16, mkdirSync as mkdirSync13 } from "fs";
374104
- import { join as join18 } from "path";
374191
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync9, existsSync as existsSync16, mkdirSync as mkdirSync14 } from "fs";
374192
+ import { join as join19 } from "path";
374105
374193
  var BETAS_FILE = ".specific/betas.json";
374106
374194
  function loadEnabledBetas(projectDir = process.cwd()) {
374107
- const filePath = join18(projectDir, BETAS_FILE);
374195
+ const filePath = join19(projectDir, BETAS_FILE);
374108
374196
  if (!existsSync16(filePath)) {
374109
374197
  return [];
374110
374198
  }
374111
374199
  try {
374112
- const content = readFileSync10(filePath, "utf-8");
374200
+ const content = readFileSync11(filePath, "utf-8");
374113
374201
  const data = JSON.parse(content);
374114
374202
  return data.enabled ?? [];
374115
374203
  } catch {
@@ -374128,30 +374216,30 @@ function disableBeta(name, projectDir = process.cwd()) {
374128
374216
  saveBetas(enabled, projectDir);
374129
374217
  }
374130
374218
  function saveBetas(enabled, projectDir) {
374131
- const specificDir = join18(projectDir, ".specific");
374219
+ const specificDir = join19(projectDir, ".specific");
374132
374220
  if (!existsSync16(specificDir)) {
374133
- mkdirSync13(specificDir, { recursive: true });
374221
+ mkdirSync14(specificDir, { recursive: true });
374134
374222
  }
374135
374223
  const data = { enabled };
374136
- writeFileSync8(
374137
- join18(projectDir, BETAS_FILE),
374224
+ writeFileSync9(
374225
+ join19(projectDir, BETAS_FILE),
374138
374226
  JSON.stringify(data, null, 2) + "\n"
374139
374227
  );
374140
374228
  }
374141
374229
 
374142
374230
  // src/commands/docs.tsx
374143
374231
  var __dirname3 = dirname9(fileURLToPath3(import.meta.url));
374144
- var docsDir = join19(__dirname3, "docs");
374232
+ var docsDir = join20(__dirname3, "docs");
374145
374233
  var _embeddedDocs = null;
374146
374234
  var RESHAPE_DOCS_PREFIX = "postgres/reshape/";
374147
- async function docsCommand(path27) {
374148
- let content = resolveDocContent(path27);
374149
- if (!content && path27) {
374150
- content = await resolveReshapeDoc(path27);
374235
+ async function docsCommand(path28) {
374236
+ let content = resolveDocContent(path28);
374237
+ if (!content && path28) {
374238
+ content = await resolveReshapeDoc(path28);
374151
374239
  }
374152
374240
  if (!content) {
374153
374241
  console.error(
374154
- `Documentation not found: ${path27 || "index"}
374242
+ `Documentation not found: ${path28 || "index"}
374155
374243
 
374156
374244
  Run 'specific docs' to see available topics.`
374157
374245
  );
@@ -374161,25 +374249,25 @@ Run 'specific docs' to see available topics.`
374161
374249
  const filtered = filterBetaTags(content, enabledBetas);
374162
374250
  console.log(filtered);
374163
374251
  }
374164
- async function resolveReshapeDoc(path27) {
374165
- const normalized = path27.replace(/^\/+|\/+$/g, "");
374252
+ async function resolveReshapeDoc(path28) {
374253
+ const normalized = path28.replace(/^\/+|\/+$/g, "");
374166
374254
  if (!normalized.startsWith(RESHAPE_DOCS_PREFIX)) return null;
374167
374255
  const reshapePath = "/" + normalized.slice(RESHAPE_DOCS_PREFIX.length);
374168
374256
  try {
374169
374257
  const binary = await ensureBinary(reshapeBinary);
374170
374258
  const reshapeExe = binary.executables["reshape"];
374171
- const output = await new Promise((resolve9) => {
374259
+ const output = await new Promise((resolve10) => {
374172
374260
  const child = spawn6(reshapeExe, ["docs", reshapePath], {
374173
374261
  stdio: ["ignore", "pipe", "ignore"]
374174
374262
  });
374175
374263
  const chunks = [];
374176
374264
  child.stdout.on("data", (chunk) => chunks.push(chunk));
374177
- child.on("error", () => resolve9(null));
374265
+ child.on("error", () => resolve10(null));
374178
374266
  child.on("close", (code) => {
374179
374267
  if (code === 0 && chunks.length > 0) {
374180
- resolve9(Buffer.concat(chunks).toString("utf-8"));
374268
+ resolve10(Buffer.concat(chunks).toString("utf-8"));
374181
374269
  } else {
374182
- resolve9(null);
374270
+ resolve10(null);
374183
374271
  }
374184
374272
  });
374185
374273
  });
@@ -374196,33 +374284,33 @@ function filterBetaTags(content, enabledBetas) {
374196
374284
  }
374197
374285
  );
374198
374286
  }
374199
- function resolveDocContent(path27) {
374200
- const normalized = path27?.replace(/^\/+|\/+$/g, "") || void 0;
374287
+ function resolveDocContent(path28) {
374288
+ const normalized = path28?.replace(/^\/+|\/+$/g, "") || void 0;
374201
374289
  if (_embeddedDocs) {
374202
374290
  return resolveEmbeddedDoc(normalized);
374203
374291
  }
374204
374292
  return resolveFilesystemDoc(normalized);
374205
374293
  }
374206
- function resolveEmbeddedDoc(path27) {
374207
- if (!path27) {
374294
+ function resolveEmbeddedDoc(path28) {
374295
+ if (!path28) {
374208
374296
  return _embeddedDocs.get("index.md") ?? null;
374209
374297
  }
374210
- const direct = _embeddedDocs.get(`${path27}.md`);
374298
+ const direct = _embeddedDocs.get(`${path28}.md`);
374211
374299
  if (direct) return direct;
374212
- return _embeddedDocs.get(`${path27}/index.md`) ?? null;
374300
+ return _embeddedDocs.get(`${path28}/index.md`) ?? null;
374213
374301
  }
374214
- function resolveFilesystemDoc(path27) {
374215
- if (!path27) {
374216
- const indexPath2 = join19(docsDir, "index.md");
374217
- return existsSync17(indexPath2) ? readFileSync11(indexPath2, "utf-8") : null;
374302
+ function resolveFilesystemDoc(path28) {
374303
+ if (!path28) {
374304
+ const indexPath2 = join20(docsDir, "index.md");
374305
+ return existsSync17(indexPath2) ? readFileSync12(indexPath2, "utf-8") : null;
374218
374306
  }
374219
- const directPath = join19(docsDir, `${path27}.md`);
374307
+ const directPath = join20(docsDir, `${path28}.md`);
374220
374308
  if (existsSync17(directPath)) {
374221
- return readFileSync11(directPath, "utf-8");
374309
+ return readFileSync12(directPath, "utf-8");
374222
374310
  }
374223
- const indexPath = join19(docsDir, path27, "index.md");
374311
+ const indexPath = join20(docsDir, path28, "index.md");
374224
374312
  if (existsSync17(indexPath)) {
374225
- return readFileSync11(indexPath, "utf-8");
374313
+ return readFileSync12(indexPath, "utf-8");
374226
374314
  }
374227
374315
  return null;
374228
374316
  }
@@ -374231,8 +374319,8 @@ function resolveFilesystemDoc(path27) {
374231
374319
  import React3, { useState as useState2, useEffect as useEffect2 } from "react";
374232
374320
  import { render as render3, Text as Text3, Box as Box3 } from "ink";
374233
374321
  import Spinner2 from "ink-spinner";
374234
- import * as fs21 from "fs";
374235
- import * as path19 from "path";
374322
+ import * as fs22 from "fs";
374323
+ import * as path20 from "path";
374236
374324
  import { execFile as execFile8 } from "child_process";
374237
374325
 
374238
374326
  // node_modules/.pnpm/@specific+config@file+..+config/node_modules/@specific/config/dist/parser.js
@@ -374886,13 +374974,13 @@ async function runReshapeCheck(migrationsDir) {
374886
374974
  try {
374887
374975
  const binary = await ensureBinary(reshapeBinary);
374888
374976
  const reshapePath = binary.executables["reshape"];
374889
- return new Promise((resolve9) => {
374977
+ return new Promise((resolve10) => {
374890
374978
  execFile8(reshapePath, ["check", "--dirs", migrationsDir], (err, _stdout, stderr) => {
374891
374979
  if (err) {
374892
374980
  const errorMsg = stderr.trim() || err.message;
374893
- resolve9({ success: false, error: errorMsg });
374981
+ resolve10({ success: false, error: errorMsg });
374894
374982
  } else {
374895
- resolve9({ success: true });
374983
+ resolve10({ success: true });
374896
374984
  }
374897
374985
  });
374898
374986
  });
@@ -374904,20 +374992,20 @@ function CheckUI() {
374904
374992
  const [state, setState] = useState2({ status: "loading" });
374905
374993
  useEffect2(() => {
374906
374994
  async function load() {
374907
- const configPath = path19.join(process.cwd(), "specific.hcl");
374908
- if (!fs21.existsSync(configPath)) {
374995
+ const configPath = path20.join(process.cwd(), "specific.hcl");
374996
+ if (!fs22.existsSync(configPath)) {
374909
374997
  setState({
374910
374998
  status: "error",
374911
374999
  error: "No specific.hcl found in current directory"
374912
375000
  });
374913
375001
  return;
374914
375002
  }
374915
- const hcl = fs21.readFileSync(configPath, "utf-8");
375003
+ const hcl = fs22.readFileSync(configPath, "utf-8");
374916
375004
  try {
374917
375005
  const config2 = await parseConfig2(hcl);
374918
- const localPath = path19.join(process.cwd(), LOCAL_FILE);
374919
- if (fs21.existsSync(localPath)) {
374920
- const localContent = fs21.readFileSync(localPath, "utf-8");
375006
+ const localPath = path20.join(process.cwd(), LOCAL_FILE);
375007
+ if (fs22.existsSync(localPath)) {
375008
+ const localContent = fs22.readFileSync(localPath, "utf-8");
374921
375009
  try {
374922
375010
  await parseLocalFile(localContent);
374923
375011
  } catch (localErr) {
@@ -374930,8 +375018,8 @@ function CheckUI() {
374930
375018
  }
374931
375019
  for (const build of config2.builds) {
374932
375020
  if (build.dockerfile) {
374933
- const dockerfilePath = path19.resolve(process.cwd(), build.dockerfile);
374934
- if (!fs21.existsSync(dockerfilePath)) {
375021
+ const dockerfilePath = path20.resolve(process.cwd(), build.dockerfile);
375022
+ if (!fs22.existsSync(dockerfilePath)) {
374935
375023
  setState({
374936
375024
  status: "error",
374937
375025
  error: `Build "${build.name}": Dockerfile not found at "${build.dockerfile}" (resolved to ${dockerfilePath})`
@@ -374943,11 +375031,11 @@ function CheckUI() {
374943
375031
  const reshapeChecks2 = [];
374944
375032
  for (const pg of config2.postgres) {
374945
375033
  if (pg.reshape?.enabled) {
374946
- const migrationsDir = path19.resolve(
375034
+ const migrationsDir = path20.resolve(
374947
375035
  process.cwd(),
374948
375036
  pg.reshape.migrations_dir ?? "migrations"
374949
375037
  );
374950
- if (!fs21.existsSync(migrationsDir)) {
375038
+ if (!fs22.existsSync(migrationsDir)) {
374951
375039
  reshapeChecks2.push({
374952
375040
  databaseName: pg.name,
374953
375041
  migrationsDir: pg.reshape.migrations_dir ?? "migrations",
@@ -375616,8 +375704,8 @@ init_open();
375616
375704
  import React7, { useState as useState6, useEffect as useEffect6, useCallback as useCallback3 } from "react";
375617
375705
  import { render as render5, Text as Text7, Box as Box7, useApp as useApp3, useInput as useInput4 } from "ink";
375618
375706
  import Spinner4 from "ink-spinner";
375619
- import * as fs22 from "fs";
375620
- import * as path20 from "path";
375707
+ import * as fs23 from "fs";
375708
+ import * as path21 from "path";
375621
375709
  import { execFileSync as execFileSync2 } from "child_process";
375622
375710
  function getGitInfo(cwd) {
375623
375711
  try {
@@ -375998,12 +376086,12 @@ function DeployUI({ envFlag, preview, config }) {
375998
376086
  return;
375999
376087
  }
376000
376088
  if (envFlag) {
376001
- const match = environments.find((e) => e.name === envFlag);
376089
+ const match = findEnvironmentByNameOrId(environments, envFlag);
376002
376090
  if (!match) {
376003
376091
  setState((s) => ({
376004
376092
  ...s,
376005
376093
  phase: "error",
376006
- error: `Environment "${envFlag}" not found. Available: ${environments.map((e) => e.name).join(", ")}`
376094
+ error: `Environment "${envFlag}" not found (matched against name and ID). Available: ${environments.map((e) => e.name).join(", ")}`
376007
376095
  }));
376008
376096
  return;
376009
376097
  }
@@ -376751,39 +376839,43 @@ async function runDeployPipeline(options2) {
376751
376839
  const preview = await client2.createPreviewEnvironment(projectId);
376752
376840
  writePreviewEnvironmentId(preview.id, projectDir);
376753
376841
  console.log(`Preview environment "${preview.name}" created (expires: ${new Date(preview.expiresAt).toLocaleString()})`);
376754
- options2.env = preview.name;
376842
+ options2.environment = preview.name;
376755
376843
  }
376844
+ const projects = await client2.listProjects();
376845
+ const project = projects.find((p) => p.id === projectId);
376846
+ const environments = project?.environments ?? [];
376756
376847
  let environmentName;
376757
- if (options2.env) {
376758
- environmentName = options2.env;
376848
+ if (options2.environment) {
376849
+ const match = findEnvironmentByNameOrId(environments, options2.environment);
376850
+ if (!match) {
376851
+ console.error(
376852
+ `Error: Environment "${options2.environment}" not found (matched against name and ID).
376853
+ Available: ${environments.map((e) => e.name).join(", ") || "(none)"}`
376854
+ );
376855
+ process.exit(1);
376856
+ }
376857
+ environmentName = match.name;
376858
+ writeEnvironmentId(match.id);
376759
376859
  } else if (hasEnvironmentId(projectDir)) {
376760
376860
  const savedEnvId = readEnvironmentId(projectDir);
376761
- const projects = await client2.listProjects();
376762
- const project = projects.find((p) => p.id === projectId);
376763
- const env2 = project?.environments.find((e) => e.id === savedEnvId);
376861
+ const env2 = environments.find((e) => e.id === savedEnvId);
376764
376862
  if (env2) {
376765
376863
  environmentName = env2.name;
376864
+ } else if (environments.length === 1) {
376865
+ environmentName = environments[0].name;
376866
+ writeEnvironmentId(environments[0].id);
376867
+ } else if (environments.length === 0) {
376868
+ console.error("Error: No environments found for this project");
376869
+ process.exit(1);
376766
376870
  } else {
376767
- const environments = project?.environments ?? [];
376768
- if (environments.length === 1) {
376769
- environmentName = environments[0].name;
376770
- writeEnvironmentId(environments[0].id);
376771
- } else if (environments.length === 0) {
376772
- console.error("Error: No environments found for this project");
376773
- process.exit(1);
376774
- } else {
376775
- console.error(
376776
- `Error: Multiple environments available. Specify one with --env.
376871
+ console.error(
376872
+ `Error: Multiple environments available. Specify one with --environment.
376777
376873
  Available: ${environments.map((e) => e.name).join(", ")}
376778
- Example: specific deploy --env ${environments[0].name}`
376779
- );
376780
- process.exit(1);
376781
- }
376874
+ Example: specific deploy --environment ${environments[0].name}`
376875
+ );
376876
+ process.exit(1);
376782
376877
  }
376783
376878
  } else {
376784
- const projects = await client2.listProjects();
376785
- const project = projects.find((p) => p.id === projectId);
376786
- const environments = project?.environments ?? [];
376787
376879
  if (environments.length === 1) {
376788
376880
  environmentName = environments[0].name;
376789
376881
  writeEnvironmentId(environments[0].id);
@@ -376792,9 +376884,9 @@ async function runDeployPipeline(options2) {
376792
376884
  process.exit(1);
376793
376885
  } else {
376794
376886
  console.error(
376795
- `Error: Multiple environments available. Specify one with --env.
376887
+ `Error: Multiple environments available. Specify one with --environment.
376796
376888
  Available: ${environments.map((e) => e.name).join(", ")}
376797
- Example: specific deploy --env ${environments[0].name}`
376889
+ Example: specific deploy --environment ${environments[0].name}`
376798
376890
  );
376799
376891
  process.exit(1);
376800
376892
  }
@@ -376852,7 +376944,7 @@ async function runDeployPipeline(options2) {
376852
376944
  }
376853
376945
  console.log("Waiting for build...");
376854
376946
  while (true) {
376855
- await new Promise((resolve9) => setTimeout(resolve9, 2e3));
376947
+ await new Promise((resolve10) => setTimeout(resolve10, 2e3));
376856
376948
  const status = await client2.getDeployment(deployment.id);
376857
376949
  deployment = status;
376858
376950
  if (status.state === "failed") {
@@ -376927,7 +377019,7 @@ ${failedBuild.output}`);
376927
377019
  }
376928
377020
  console.log("Deploying...");
376929
377021
  while (true) {
376930
- await new Promise((resolve9) => setTimeout(resolve9, 2e3));
377022
+ await new Promise((resolve10) => setTimeout(resolve10, 2e3));
376931
377023
  const status = await client2.getDeployment(deployment.id);
376932
377024
  deployment = status;
376933
377025
  if (status.state === "failed") {
@@ -376961,13 +377053,13 @@ ${status.error.output}`);
376961
377053
  }
376962
377054
  }
376963
377055
  async function deployCommand(options2) {
376964
- const configPath = path20.join(process.cwd(), "specific.hcl");
376965
- if (!fs22.existsSync(configPath)) {
377056
+ const configPath = path21.join(process.cwd(), "specific.hcl");
377057
+ if (!fs23.existsSync(configPath)) {
376966
377058
  console.error("Error: No specific.hcl found in current directory");
376967
377059
  process.exit(1);
376968
377060
  }
376969
377061
  let config;
376970
- const hcl = fs22.readFileSync(configPath, "utf-8");
377062
+ const hcl = fs23.readFileSync(configPath, "utf-8");
376971
377063
  try {
376972
377064
  config = await parseConfig2(hcl);
376973
377065
  } catch (err) {
@@ -376979,7 +377071,7 @@ async function deployCommand(options2) {
376979
377071
  await runDeployPipeline({
376980
377072
  config,
376981
377073
  projectId: options2.project,
376982
- env: options2.env,
377074
+ environment: options2.environment,
376983
377075
  secrets: options2.secret,
376984
377076
  configs: options2.config,
376985
377077
  preview: options2.preview
@@ -376990,7 +377082,7 @@ async function deployCommand(options2) {
376990
377082
  /* @__PURE__ */ React7.createElement(
376991
377083
  DeployUI,
376992
377084
  {
376993
- envFlag: options2.env,
377085
+ envFlag: options2.environment,
376994
377086
  preview: options2.preview,
376995
377087
  config
376996
377088
  }
@@ -377000,8 +377092,8 @@ async function deployCommand(options2) {
377000
377092
 
377001
377093
  // src/commands/exec.tsx
377002
377094
  import { spawn as spawn7 } from "child_process";
377003
- import * as fs23 from "fs";
377004
- import * as path21 from "path";
377095
+ import * as fs24 from "fs";
377096
+ import * as path22 from "path";
377005
377097
  function startSpinner(text) {
377006
377098
  const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
377007
377099
  let i = 0;
@@ -377042,13 +377134,13 @@ async function execCommand(serviceName, command, instanceKey = "default", option
377042
377134
  }
377043
377135
  }
377044
377136
  };
377045
- const configPath = path21.join(process.cwd(), "specific.hcl");
377046
- if (!fs23.existsSync(configPath)) {
377137
+ const configPath = path22.join(process.cwd(), "specific.hcl");
377138
+ if (!fs24.existsSync(configPath)) {
377047
377139
  console.error("Error: No specific.hcl found in current directory");
377048
377140
  process.exit(1);
377049
377141
  }
377050
377142
  let config;
377051
- const hcl = fs23.readFileSync(configPath, "utf-8");
377143
+ const hcl = fs24.readFileSync(configPath, "utf-8");
377052
377144
  try {
377053
377145
  config = await parseConfig2(hcl);
377054
377146
  } catch (err) {
@@ -377214,13 +377306,13 @@ async function execCommand(serviceName, command, instanceKey = "default", option
377214
377306
  process.on("SIGTERM", () => handleSignal("SIGTERM"));
377215
377307
  let effectiveCwd = process.cwd();
377216
377308
  if (options2.cwd) {
377217
- effectiveCwd = path21.resolve(process.cwd(), options2.cwd);
377309
+ effectiveCwd = path22.resolve(process.cwd(), options2.cwd);
377218
377310
  } else if (service.root) {
377219
- effectiveCwd = path21.resolve(process.cwd(), service.root);
377311
+ effectiveCwd = path22.resolve(process.cwd(), service.root);
377220
377312
  } else if (service.build) {
377221
377313
  const build = config.builds.find((b) => b.name === service.build.name);
377222
377314
  if (build?.root) {
377223
- effectiveCwd = path21.resolve(process.cwd(), build.root);
377315
+ effectiveCwd = path22.resolve(process.cwd(), build.root);
377224
377316
  }
377225
377317
  }
377226
377318
  spinner?.stop();
@@ -377249,8 +377341,8 @@ async function execCommand(serviceName, command, instanceKey = "default", option
377249
377341
 
377250
377342
  // src/commands/psql.tsx
377251
377343
  import { spawn as spawn8 } from "child_process";
377252
- import * as fs24 from "fs";
377253
- import * as path22 from "path";
377344
+ import * as fs25 from "fs";
377345
+ import * as path23 from "path";
377254
377346
  async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []) {
377255
377347
  let startedResources = [];
377256
377348
  let ownsInstances = false;
@@ -377267,13 +377359,13 @@ async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []
377267
377359
  }
377268
377360
  }
377269
377361
  };
377270
- const configPath = path22.join(process.cwd(), "specific.hcl");
377271
- if (!fs24.existsSync(configPath)) {
377362
+ const configPath = path23.join(process.cwd(), "specific.hcl");
377363
+ if (!fs25.existsSync(configPath)) {
377272
377364
  console.error("Error: No specific.hcl found in current directory");
377273
377365
  process.exit(1);
377274
377366
  }
377275
377367
  let config;
377276
- const hcl = fs24.readFileSync(configPath, "utf-8");
377368
+ const hcl = fs25.readFileSync(configPath, "utf-8");
377277
377369
  try {
377278
377370
  config = await parseConfig2(hcl);
377279
377371
  } catch (err) {
@@ -377398,8 +377490,8 @@ async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []
377398
377490
 
377399
377491
  // src/commands/reshape.tsx
377400
377492
  import { spawn as spawn9 } from "child_process";
377401
- import * as fs25 from "fs";
377402
- import * as path23 from "path";
377493
+ import * as fs26 from "fs";
377494
+ import * as path24 from "path";
377403
377495
  var VALID_ACTIONS = ["start", "complete", "status", "abort", "check"];
377404
377496
  var MIGRATION_SUBCOMMANDS = ["start", "complete", "abort"];
377405
377497
  var OFFLINE_ACTIONS = ["check"];
@@ -377419,13 +377511,13 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
377419
377511
  process.exit(1);
377420
377512
  }
377421
377513
  const isOfflineAction = OFFLINE_ACTIONS.includes(action);
377422
- const configPath = path23.join(process.cwd(), "specific.hcl");
377514
+ const configPath = path24.join(process.cwd(), "specific.hcl");
377423
377515
  let config;
377424
377516
  let migrationsDir = "migrations";
377425
377517
  let targetDb;
377426
377518
  try {
377427
- if (fs25.existsSync(configPath)) {
377428
- const configContent = fs25.readFileSync(configPath, "utf-8");
377519
+ if (fs26.existsSync(configPath)) {
377520
+ const configContent = fs26.readFileSync(configPath, "utf-8");
377429
377521
  config = await parseConfig2(configContent);
377430
377522
  if (databaseName) {
377431
377523
  const postgresConfig = config.postgres.find((p) => p.name === databaseName);
@@ -377560,9 +377652,9 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
377560
377652
  }
377561
377653
  const isMigrationSubcommand = MIGRATION_SUBCOMMANDS.includes(action);
377562
377654
  const reshapeArgs = isMigrationSubcommand ? ["migration", action] : [action];
377563
- const fullMigrationsPath = path23.join(process.cwd(), migrationsDir);
377655
+ const fullMigrationsPath = path24.join(process.cwd(), migrationsDir);
377564
377656
  if (action === "check" || action === "start") {
377565
- if (fs25.existsSync(fullMigrationsPath)) {
377657
+ if (fs26.existsSync(fullMigrationsPath)) {
377566
377658
  reshapeArgs.push("--dirs", fullMigrationsPath);
377567
377659
  } else if (action === "check") {
377568
377660
  console.error(`Error: Migrations directory not found: ${fullMigrationsPath}`);
@@ -377612,21 +377704,21 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
377612
377704
  import React8, { useState as useState7, useEffect as useEffect7 } from "react";
377613
377705
  import { render as render6, Text as Text8, Box as Box8 } from "ink";
377614
377706
  import Spinner5 from "ink-spinner";
377615
- import * as fs26 from "fs";
377616
- import * as path24 from "path";
377707
+ import * as fs27 from "fs";
377708
+ import * as path25 from "path";
377617
377709
  function CleanUI({ instanceKey }) {
377618
377710
  const [state, setState] = useState7({ status: "checking" });
377619
377711
  useEffect7(() => {
377620
377712
  async function clean() {
377621
377713
  const projectRoot = process.cwd();
377622
- const specificDir = path24.join(projectRoot, ".specific");
377623
- if (!fs26.existsSync(specificDir)) {
377714
+ const specificDir = path25.join(projectRoot, ".specific");
377715
+ if (!fs27.existsSync(specificDir)) {
377624
377716
  setState({ status: "nothing" });
377625
377717
  return;
377626
377718
  }
377627
377719
  if (instanceKey) {
377628
- const keyDir = path24.join(specificDir, "keys", instanceKey);
377629
- if (!fs26.existsSync(keyDir)) {
377720
+ const keyDir = path25.join(specificDir, "keys", instanceKey);
377721
+ if (!fs27.existsSync(keyDir)) {
377630
377722
  setState({ status: "nothing" });
377631
377723
  return;
377632
377724
  }
@@ -377642,7 +377734,7 @@ function CleanUI({ instanceKey }) {
377642
377734
  await stateManager.cleanStaleState();
377643
377735
  setState({ status: "cleaning" });
377644
377736
  try {
377645
- fs26.rmSync(keyDir, { recursive: true, force: true });
377737
+ fs27.rmSync(keyDir, { recursive: true, force: true });
377646
377738
  setState({ status: "success" });
377647
377739
  } catch (err) {
377648
377740
  setState({
@@ -377651,13 +377743,13 @@ function CleanUI({ instanceKey }) {
377651
377743
  });
377652
377744
  }
377653
377745
  } else {
377654
- const keysDir = path24.join(specificDir, "keys");
377655
- if (!fs26.existsSync(keysDir)) {
377746
+ const keysDir = path25.join(specificDir, "keys");
377747
+ if (!fs27.existsSync(keysDir)) {
377656
377748
  setState({ status: "nothing" });
377657
377749
  return;
377658
377750
  }
377659
- const keys = fs26.readdirSync(keysDir).filter(
377660
- (f) => fs26.statSync(path24.join(keysDir, f)).isDirectory()
377751
+ const keys = fs27.readdirSync(keysDir).filter(
377752
+ (f) => fs27.statSync(path25.join(keysDir, f)).isDirectory()
377661
377753
  );
377662
377754
  for (const key of keys) {
377663
377755
  const stateManager2 = new InstanceStateManager(projectRoot, key);
@@ -377681,7 +377773,7 @@ function CleanUI({ instanceKey }) {
377681
377773
  }
377682
377774
  setState({ status: "cleaning" });
377683
377775
  try {
377684
- fs26.rmSync(keysDir, { recursive: true, force: true });
377776
+ fs27.rmSync(keysDir, { recursive: true, force: true });
377685
377777
  setState({ status: "success" });
377686
377778
  } catch (err) {
377687
377779
  setState({
@@ -377860,8 +377952,8 @@ import { render as render9, Text as Text11, Box as Box10, useApp as useApp6 } fr
377860
377952
  import Spinner6 from "ink-spinner";
377861
377953
 
377862
377954
  // src/lib/update.ts
377863
- import * as fs27 from "fs";
377864
- import * as path25 from "path";
377955
+ import * as fs28 from "fs";
377956
+ import * as path26 from "path";
377865
377957
  var BINARIES_BASE_URL = "https://binaries.specific.dev/cli";
377866
377958
  function compareVersions(a, b) {
377867
377959
  const partsA = a.split(".").map(Number);
@@ -377875,7 +377967,7 @@ function compareVersions(a, b) {
377875
377967
  return 0;
377876
377968
  }
377877
377969
  async function checkForUpdate() {
377878
- const currentVersion = "0.1.139";
377970
+ const currentVersion = "0.1.141";
377879
377971
  const response = await fetch(`${BINARIES_BASE_URL}/latest?t=${Date.now()}`);
377880
377972
  if (!response.ok) {
377881
377973
  throw new Error(`Failed to check for updates: HTTP ${response.status}`);
@@ -377889,9 +377981,9 @@ function getCurrentBinaryPath() {
377889
377981
  }
377890
377982
  function isBinaryWritable() {
377891
377983
  const binaryPath = getCurrentBinaryPath();
377892
- const dir = path25.dirname(binaryPath);
377984
+ const dir = path26.dirname(binaryPath);
377893
377985
  try {
377894
- fs27.accessSync(dir, fs27.constants.W_OK);
377986
+ fs28.accessSync(dir, fs28.constants.W_OK);
377895
377987
  return true;
377896
377988
  } catch {
377897
377989
  return false;
@@ -377899,24 +377991,24 @@ function isBinaryWritable() {
377899
377991
  }
377900
377992
  async function performUpdate(version, onProgress) {
377901
377993
  const binaryPath = getCurrentBinaryPath();
377902
- const binaryDir = path25.dirname(binaryPath);
377903
- const tempPath = path25.join(binaryDir, `.specific-update-${process.pid}`);
377994
+ const binaryDir = path26.dirname(binaryPath);
377995
+ const tempPath = path26.join(binaryDir, `.specific-update-${process.pid}`);
377904
377996
  try {
377905
377997
  const { platform: platform3, arch: arch3 } = getPlatformInfo();
377906
377998
  const url = `${BINARIES_BASE_URL}/${version}/specific-${platform3}-${arch3}`;
377907
377999
  await downloadFile(url, tempPath, onProgress);
377908
- const stat4 = fs27.statSync(tempPath);
378000
+ const stat4 = fs28.statSync(tempPath);
377909
378001
  if (stat4.size === 0) {
377910
378002
  throw new Error("Downloaded binary is empty");
377911
378003
  }
377912
- fs27.chmodSync(tempPath, 493);
378004
+ fs28.chmodSync(tempPath, 493);
377913
378005
  onProgress?.({ phase: "finalizing" });
377914
- fs27.unlinkSync(binaryPath);
377915
- fs27.renameSync(tempPath, binaryPath);
378006
+ fs28.unlinkSync(binaryPath);
378007
+ fs28.renameSync(tempPath, binaryPath);
377916
378008
  } catch (error) {
377917
378009
  try {
377918
- if (fs27.existsSync(tempPath)) {
377919
- fs27.unlinkSync(tempPath);
378010
+ if (fs28.existsSync(tempPath)) {
378011
+ fs28.unlinkSync(tempPath);
377920
378012
  }
377921
378013
  } catch {
377922
378014
  }
@@ -377926,21 +378018,21 @@ async function performUpdate(version, onProgress) {
377926
378018
 
377927
378019
  // src/lib/background-update.ts
377928
378020
  import { spawn as spawn10 } from "child_process";
377929
- import * as fs28 from "fs";
377930
- import * as path26 from "path";
378021
+ import * as fs29 from "fs";
378022
+ import * as path27 from "path";
377931
378023
  import * as os6 from "os";
377932
- var SPECIFIC_DIR = path26.join(os6.homedir(), ".specific");
377933
- var RATE_LIMIT_FILE = path26.join(SPECIFIC_DIR, "last-update-check");
377934
- var LOCK_FILE = path26.join(SPECIFIC_DIR, "update.lock");
378024
+ var SPECIFIC_DIR = path27.join(os6.homedir(), ".specific");
378025
+ var RATE_LIMIT_FILE = path27.join(SPECIFIC_DIR, "last-update-check");
378026
+ var LOCK_FILE = path27.join(SPECIFIC_DIR, "update.lock");
377935
378027
  var RATE_LIMIT_MS = 60 * 60 * 1e3;
377936
378028
  var STALE_LOCK_MS = 10 * 60 * 1e3;
377937
378029
  function writeCheckTimestamp() {
377938
- fs28.mkdirSync(SPECIFIC_DIR, { recursive: true });
377939
- fs28.writeFileSync(RATE_LIMIT_FILE, String(Date.now()), "utf-8");
378030
+ fs29.mkdirSync(SPECIFIC_DIR, { recursive: true });
378031
+ fs29.writeFileSync(RATE_LIMIT_FILE, String(Date.now()), "utf-8");
377940
378032
  }
377941
378033
  function isRateLimited() {
377942
378034
  try {
377943
- const content = fs28.readFileSync(RATE_LIMIT_FILE, "utf-8").trim();
378035
+ const content = fs29.readFileSync(RATE_LIMIT_FILE, "utf-8").trim();
377944
378036
  const lastCheck = parseInt(content, 10);
377945
378037
  if (isNaN(lastCheck)) return false;
377946
378038
  return Date.now() - lastCheck < RATE_LIMIT_MS;
@@ -378324,7 +378416,7 @@ async function queryCommand(sqlArg, options2) {
378324
378416
  const projectId = readProjectId();
378325
378417
  const token = await getValidAccessToken();
378326
378418
  const client2 = new SpecificClient({ accessToken: token });
378327
- const environmentId = await resolveEnvironment(client2, projectId, options2.env);
378419
+ const environmentId = await resolveEnvironment(client2, projectId, options2.environment);
378328
378420
  const result = await client2.runObservabilityQuery(environmentId, sql);
378329
378421
  process.stdout.write(renderTable(result));
378330
378422
  } catch (err) {
@@ -378342,11 +378434,11 @@ async function resolveSql(arg) {
378342
378434
  return await readStdin();
378343
378435
  }
378344
378436
  async function readStdin() {
378345
- return new Promise((resolve9, reject) => {
378437
+ return new Promise((resolve10, reject) => {
378346
378438
  let data = "";
378347
378439
  process.stdin.setEncoding("utf-8");
378348
378440
  process.stdin.on("data", (chunk) => data += chunk);
378349
- process.stdin.on("end", () => resolve9(data.trim()));
378441
+ process.stdin.on("end", () => resolve10(data.trim()));
378350
378442
  process.stdin.on("error", reject);
378351
378443
  });
378352
378444
  }
@@ -378354,11 +378446,11 @@ async function resolveEnvironment(client2, projectId, envFlag) {
378354
378446
  const status = await client2.getProjectStatus(projectId);
378355
378447
  const environments = status.environments;
378356
378448
  if (envFlag) {
378357
- const match = environments.find((e) => e.name === envFlag);
378449
+ const match = findEnvironmentByNameOrId(environments, envFlag);
378358
378450
  if (!match) {
378359
378451
  const available = environments.map((e) => e.name).join(", ") || "(none)";
378360
378452
  throw new Error(
378361
- `Environment "${envFlag}" not found. Available: ${available}`
378453
+ `Environment "${envFlag}" not found (matched against name and ID). Available: ${available}`
378362
378454
  );
378363
378455
  }
378364
378456
  return match.id;
@@ -378377,7 +378469,7 @@ async function resolveEnvironment(client2, projectId, envFlag) {
378377
378469
  }
378378
378470
  const names = environments.map((e) => e.name).join(", ");
378379
378471
  throw new Error(
378380
- `Project has multiple environments (${names}). Pass --env <name>.`
378472
+ `Project has multiple environments (${names}). Pass --environment <name|id>.`
378381
378473
  );
378382
378474
  }
378383
378475
  function friendlyErrorMessage(raw) {
@@ -378390,7 +378482,7 @@ function friendlyErrorMessage(raw) {
378390
378482
  var program = new Command();
378391
378483
  var env = "production";
378392
378484
  var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
378393
- program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.139").enablePositionalOptions();
378485
+ program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.141").enablePositionalOptions();
378394
378486
  program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").addHelpText("after", `
378395
378487
  Examples:
378396
378488
  $ specific init
@@ -378411,10 +378503,11 @@ Examples:
378411
378503
  const key = options2.key ?? getDefaultKey();
378412
378504
  devCommand(key, options2.tunnel ?? false);
378413
378505
  });
378414
- program.command("deploy").description("Deploy to Specific infrastructure").option("--project <id>", "Project ID to deploy to (overrides .projectid file)").option("--env <name>", "Target environment (auto-selected if only one exists)").option("--secret <key=value...>", "Secret values (repeatable)").option("--config <key=value...>", "Config values (repeatable)").option("--preview", "Deploy to an ephemeral preview environment").addHelpText("after", `
378506
+ program.command("deploy").description("Deploy to Specific infrastructure").option("--project <id>", "Project ID to deploy to (overrides .projectid file)").option("-e, --environment <name|id>", "Target environment (auto-selected if only one exists)").option("--secret <key=value...>", "Secret values (repeatable)").option("--config <key=value...>", "Config values (repeatable)").option("--preview", "Deploy to an ephemeral preview environment").addHelpText("after", `
378415
378507
  Examples:
378416
378508
  $ specific deploy
378417
- $ specific deploy --env staging
378509
+ $ specific deploy --environment staging
378510
+ $ specific deploy -e env_0abc123
378418
378511
  $ specific deploy --project proj_123
378419
378512
  $ specific deploy --preview
378420
378513
  $ specific deploy --secret db_url=postgres://... --config domain=app.com`).action((options2) => {
@@ -378467,10 +378560,11 @@ Examples:
378467
378560
  program.command("status").description("Show project, environments, and deployment status").addHelpText("after", `
378468
378561
  Examples:
378469
378562
  $ specific status`).action(statusCommand);
378470
- program.command("query [sql]").description("Run a SQL query against your environment's observability data").option("--env <name>", "Target environment (defaults to the current one)").addHelpText("after", `
378563
+ program.command("query [sql]").description("Run a SQL query against your environment's observability data").option("-e, --environment <name|id>", "Target environment (defaults to the current one)").addHelpText("after", `
378471
378564
  Examples:
378472
378565
  $ specific query "SELECT count() FROM observability.logs"
378473
- $ specific query --env staging "SELECT * FROM observability.logs LIMIT 5"
378566
+ $ specific query --environment staging "SELECT * FROM observability.logs LIMIT 5"
378567
+ $ specific query -e env_0abc123 "SELECT * FROM observability.logs LIMIT 5"
378474
378568
  $ cat queries/p99.sql | specific query
378475
378569
  $ specific query - < queries/p99.sql`).action((sql, options2) => {
378476
378570
  queryCommand(sql, options2);