@specific.dev/cli 0.1.140 → 0.1.142

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 (95) 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 +2 -2
  4. package/dist/admin/__next.!KGRlZmF1bHQp.txt +5 -5
  5. package/dist/admin/__next._full.txt +7 -7
  6. package/dist/admin/__next._head.txt +1 -1
  7. package/dist/admin/__next._index.txt +2 -2
  8. package/dist/admin/__next._tree.txt +2 -2
  9. package/dist/admin/_next/static/chunks/{2dac1d24dcd83b5f.js → 00ed768604f00dc4.js} +2 -2
  10. package/dist/admin/_next/static/chunks/051b91c534cf9f23.js +1 -0
  11. package/dist/admin/_next/static/chunks/05dca3efccd1ccf3.js +1 -0
  12. package/dist/admin/_next/static/chunks/1437c65d19a610ec.js +5 -0
  13. package/dist/admin/_next/static/chunks/16e0c1b704eededd.js +2 -0
  14. package/dist/admin/_next/static/chunks/4bd3607000957431.js +1 -0
  15. package/dist/admin/_next/static/chunks/5953d56a33f0b7ea.js +4 -0
  16. package/dist/admin/_next/static/chunks/65ce370ab86b6df6.js +1 -0
  17. package/dist/admin/_next/static/chunks/99a055acecd950e9.js +1 -0
  18. package/dist/admin/_next/static/chunks/a088825647b58cc9.css +4 -0
  19. package/dist/admin/_next/static/chunks/ab7b22d870fdc67c.js +1 -0
  20. package/dist/admin/_next/static/chunks/turbopack-ea5c59f39d53507e.js +4 -0
  21. package/dist/admin/_not-found/__next._full.txt +2 -2
  22. package/dist/admin/_not-found/__next._head.txt +1 -1
  23. package/dist/admin/_not-found/__next._index.txt +2 -2
  24. package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
  25. package/dist/admin/_not-found/__next._not-found.txt +1 -1
  26. package/dist/admin/_not-found/__next._tree.txt +2 -2
  27. package/dist/admin/_not-found/index.html +1 -1
  28. package/dist/admin/_not-found/index.txt +2 -2
  29. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +2 -2
  30. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +1 -1
  31. package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +5 -5
  32. package/dist/admin/databases/__next._full.txt +7 -7
  33. package/dist/admin/databases/__next._head.txt +1 -1
  34. package/dist/admin/databases/__next._index.txt +2 -2
  35. package/dist/admin/databases/__next._tree.txt +2 -2
  36. package/dist/admin/databases/index.html +1 -1
  37. package/dist/admin/databases/index.txt +7 -7
  38. package/dist/admin/fullscreen/__next._full.txt +3 -3
  39. package/dist/admin/fullscreen/__next._head.txt +1 -1
  40. package/dist/admin/fullscreen/__next._index.txt +2 -2
  41. package/dist/admin/fullscreen/__next._tree.txt +2 -2
  42. package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +2 -2
  43. package/dist/admin/fullscreen/__next.fullscreen.txt +1 -1
  44. package/dist/admin/fullscreen/databases/__next._full.txt +2 -2
  45. package/dist/admin/fullscreen/databases/__next._head.txt +1 -1
  46. package/dist/admin/fullscreen/databases/__next._index.txt +2 -2
  47. package/dist/admin/fullscreen/databases/__next._tree.txt +2 -2
  48. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +1 -1
  49. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +1 -1
  50. package/dist/admin/fullscreen/databases/__next.fullscreen.txt +1 -1
  51. package/dist/admin/fullscreen/databases/index.html +1 -1
  52. package/dist/admin/fullscreen/databases/index.txt +2 -2
  53. package/dist/admin/fullscreen/index.html +1 -1
  54. package/dist/admin/fullscreen/index.txt +3 -3
  55. package/dist/admin/index.html +1 -1
  56. package/dist/admin/index.txt +7 -7
  57. package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.__PAGE__.txt +2 -2
  58. package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.txt +1 -1
  59. package/dist/admin/mail/__next.!KGRlZmF1bHQp.txt +5 -5
  60. package/dist/admin/mail/__next._full.txt +7 -7
  61. package/dist/admin/mail/__next._head.txt +1 -1
  62. package/dist/admin/mail/__next._index.txt +2 -2
  63. package/dist/admin/mail/__next._tree.txt +2 -2
  64. package/dist/admin/mail/index.html +1 -1
  65. package/dist/admin/mail/index.txt +7 -7
  66. package/dist/admin/services/__next.!KGRlZmF1bHQp.services.__PAGE__.txt +9 -0
  67. package/dist/admin/services/__next.!KGRlZmF1bHQp.services.txt +4 -0
  68. package/dist/admin/services/__next.!KGRlZmF1bHQp.txt +8 -0
  69. package/dist/admin/services/__next._full.txt +27 -0
  70. package/dist/admin/services/__next._head.txt +6 -0
  71. package/dist/admin/services/__next._index.txt +7 -0
  72. package/dist/admin/services/__next._tree.txt +5 -0
  73. package/dist/admin/services/index.html +1 -0
  74. package/dist/admin/services/index.txt +27 -0
  75. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +5 -5
  76. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +2 -2
  77. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +1 -1
  78. package/dist/admin/workflows/__next._full.txt +7 -7
  79. package/dist/admin/workflows/__next._head.txt +1 -1
  80. package/dist/admin/workflows/__next._index.txt +2 -2
  81. package/dist/admin/workflows/__next._tree.txt +2 -2
  82. package/dist/admin/workflows/index.html +1 -1
  83. package/dist/admin/workflows/index.txt +7 -7
  84. package/dist/cli.js +596 -430
  85. package/package.json +1 -1
  86. package/dist/admin/_next/static/chunks/48f1de3af928e439.js +0 -1
  87. package/dist/admin/_next/static/chunks/63473a6cb811ed42.js +0 -5
  88. package/dist/admin/_next/static/chunks/6877369fbd84f127.js +0 -1
  89. package/dist/admin/_next/static/chunks/71775bad64b386a3.js +0 -5
  90. package/dist/admin/_next/static/chunks/ad9c416be88c8c33.js +0 -1
  91. package/dist/admin/_next/static/chunks/bac545c7353852cd.css +0 -4
  92. package/dist/admin/_next/static/chunks/turbopack-2830c15bd3d8f58b.js +0 -4
  93. /package/dist/admin/_next/static/{dIbCgE-_TKsqFpoght8OM → 0m_Df0WwF7T1e25BA6Bff}/_buildManifest.js +0 -0
  94. /package/dist/admin/_next/static/{dIbCgE-_TKsqFpoght8OM → 0m_Df0WwF7T1e25BA6Bff}/_clientMiddlewareManifest.json +0 -0
  95. /package/dist/admin/_next/static/{dIbCgE-_TKsqFpoght8OM → 0m_Df0WwF7T1e25BA6Bff}/_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
  }
@@ -370449,6 +370451,23 @@ function killTrackedProcess(pid, detached, isProcessRunning) {
370449
370451
  var __dirname = path7.dirname(fileURLToPath(import.meta.url));
370450
370452
  var adminDir = path7.join(__dirname, "admin");
370451
370453
  var _embeddedAdmin = null;
370454
+ var LOG_LINE_REGEX = /^\[([^\]]+)\] \[([^\]]+)\] (.*)$/;
370455
+ function parseLogLines(buf) {
370456
+ const text = buf.toString("utf8");
370457
+ if (text.length === 0) return [];
370458
+ const trimmed = text.endsWith("\n") ? text.slice(0, -1) : text;
370459
+ if (trimmed.length === 0) return [];
370460
+ return trimmed.split("\n").map((line) => {
370461
+ const m = LOG_LINE_REGEX.exec(line);
370462
+ if (m) {
370463
+ return { timestamp: m[1], stream: m[2], text: m[3] };
370464
+ }
370465
+ return { timestamp: "", stream: "raw", text: line };
370466
+ });
370467
+ }
370468
+ function isSafeServiceName(name) {
370469
+ return name.length > 0 && !name.includes("/") && !name.includes("\\") && !name.includes("..") && !name.includes("\0");
370470
+ }
370452
370471
  var MIME_TYPES = {
370453
370472
  ".html": "text/html",
370454
370473
  ".css": "text/css",
@@ -370590,8 +370609,8 @@ function proxyRequest(req, res, targetPort) {
370590
370609
  });
370591
370610
  req.pipe(proxyReq, { end: true });
370592
370611
  }
370593
- async function startAdminServer(getState, listenPort = 0) {
370594
- return new Promise((resolve52, reject) => {
370612
+ async function startAdminServer(getState, listenPort = 0, getLogsDir = () => null) {
370613
+ return new Promise((resolve62, reject) => {
370595
370614
  const server = http.createServer((req, res) => {
370596
370615
  const url = new URL(req.url || "/", "http://localhost");
370597
370616
  res.setHeader("Access-Control-Allow-Origin", "*");
@@ -370610,6 +370629,65 @@ async function startAdminServer(getState, listenPort = 0) {
370610
370629
  res.end(JSON.stringify(state));
370611
370630
  return;
370612
370631
  }
370632
+ const logsMatch = /^\/api\/services\/([^/]+)\/logs$/.exec(pathname);
370633
+ if (logsMatch) {
370634
+ const serviceName = decodeURIComponent(logsMatch[1]);
370635
+ if (!isSafeServiceName(serviceName)) {
370636
+ res.writeHead(400, { "Content-Type": "text/plain" });
370637
+ res.end("Invalid service name");
370638
+ return;
370639
+ }
370640
+ const logsDir = getLogsDir();
370641
+ if (!logsDir) {
370642
+ res.writeHead(404, { "Content-Type": "text/plain" });
370643
+ res.end("Logs not available");
370644
+ return;
370645
+ }
370646
+ const filePath = path7.join(logsDir, `${serviceName}.log`);
370647
+ let stat4;
370648
+ try {
370649
+ stat4 = fs7.statSync(filePath);
370650
+ } catch {
370651
+ res.writeHead(404, { "Content-Type": "application/json" });
370652
+ res.end(JSON.stringify({ size: 0, rotated: false, lines: [] }));
370653
+ return;
370654
+ }
370655
+ const offsetParam = url.searchParams.get("offset");
370656
+ const requestedOffset = offsetParam ? parseInt(offsetParam, 10) : 0;
370657
+ const offset = Number.isFinite(requestedOffset) && requestedOffset >= 0 ? requestedOffset : 0;
370658
+ const rotated = offset > stat4.size;
370659
+ const start = rotated ? 0 : offset;
370660
+ let buf;
370661
+ try {
370662
+ const fd = fs7.openSync(filePath, "r");
370663
+ try {
370664
+ const length = Math.max(0, stat4.size - start);
370665
+ buf = Buffer.alloc(length);
370666
+ if (length > 0) {
370667
+ fs7.readSync(fd, buf, 0, length, start);
370668
+ }
370669
+ } finally {
370670
+ fs7.closeSync(fd);
370671
+ }
370672
+ } catch (err) {
370673
+ writeLog("admin:logs", `Failed to read ${filePath}: ${err}`);
370674
+ res.writeHead(500, { "Content-Type": "text/plain" });
370675
+ res.end("Failed to read logs");
370676
+ return;
370677
+ }
370678
+ const lastNl = buf.lastIndexOf(10);
370679
+ const complete = lastNl >= 0 ? buf.subarray(0, lastNl + 1) : Buffer.alloc(0);
370680
+ const newOffset = start + complete.length;
370681
+ const body = {
370682
+ size: newOffset,
370683
+ rotated,
370684
+ lines: parseLogLines(complete)
370685
+ };
370686
+ res.setHeader("Content-Type", "application/json");
370687
+ res.writeHead(200);
370688
+ res.end(JSON.stringify(body));
370689
+ return;
370690
+ }
370613
370691
  if (pathname.startsWith("/temporal-ui")) {
370614
370692
  const state = getState();
370615
370693
  if (state.temporalUiPort) {
@@ -370631,7 +370709,7 @@ async function startAdminServer(getState, listenPort = 0) {
370631
370709
  }
370632
370710
  const port = addr.port;
370633
370711
  writeLog("admin", `Admin server started on port ${port}`);
370634
- resolve52({
370712
+ resolve62({
370635
370713
  port,
370636
370714
  stop: () => new Promise((res, rej) => {
370637
370715
  server.close((err) => err ? rej(err) : res());
@@ -370799,26 +370877,26 @@ async function waitForTcpPort2(host, port, timeoutMs = 3e4) {
370799
370877
  throw new Error(`Electric port ${port} did not become available within timeout`);
370800
370878
  }
370801
370879
  function checkTcpPort2(host, port) {
370802
- return new Promise((resolve52) => {
370880
+ return new Promise((resolve62) => {
370803
370881
  const socket = new net3.Socket();
370804
370882
  socket.setTimeout(1e3);
370805
370883
  socket.on("connect", () => {
370806
370884
  socket.destroy();
370807
- resolve52(true);
370885
+ resolve62(true);
370808
370886
  });
370809
370887
  socket.on("timeout", () => {
370810
370888
  socket.destroy();
370811
- resolve52(false);
370889
+ resolve62(false);
370812
370890
  });
370813
370891
  socket.on("error", () => {
370814
370892
  socket.destroy();
370815
- resolve52(false);
370893
+ resolve62(false);
370816
370894
  });
370817
370895
  socket.connect(port, host);
370818
370896
  });
370819
370897
  }
370820
370898
  function sleep2(ms) {
370821
- return new Promise((resolve52) => setTimeout(resolve52, ms));
370899
+ return new Promise((resolve62) => setTimeout(resolve62, ms));
370822
370900
  }
370823
370901
  async function startMailServer(mail, smtpPort, apiPort) {
370824
370902
  const emails = [];
@@ -370909,19 +370987,19 @@ async function startMailServer(mail, smtpPort, apiPort) {
370909
370987
  res.writeHead(404);
370910
370988
  res.end();
370911
370989
  });
370912
- await new Promise((resolve52, reject) => {
370913
- smtpServer.listen(smtpPort, "127.0.0.1", () => resolve52());
370990
+ await new Promise((resolve62, reject) => {
370991
+ smtpServer.listen(smtpPort, "127.0.0.1", () => resolve62());
370914
370992
  smtpServer.on("error", reject);
370915
370993
  });
370916
- await new Promise((resolve52, reject) => {
370917
- httpServer.listen(apiPort, "127.0.0.1", () => resolve52());
370994
+ await new Promise((resolve62, reject) => {
370995
+ httpServer.listen(apiPort, "127.0.0.1", () => resolve62());
370918
370996
  httpServer.on("error", reject);
370919
370997
  });
370920
370998
  const stop = async () => {
370921
370999
  httpServer.closeAllConnections();
370922
371000
  await Promise.all([
370923
- new Promise((resolve52) => smtpServer.close(() => resolve52())),
370924
- new Promise((resolve52) => httpServer.close(() => resolve52()))
371001
+ new Promise((resolve62) => smtpServer.close(() => resolve62())),
371002
+ new Promise((resolve62) => httpServer.close(() => resolve62()))
370925
371003
  ]);
370926
371004
  };
370927
371005
  const resource = {
@@ -371026,26 +371104,26 @@ async function waitForTcpPort3(host, port, timeoutMs = 3e4) {
371026
371104
  );
371027
371105
  }
371028
371106
  function checkTcpPort3(host, port) {
371029
- return new Promise((resolve52) => {
371107
+ return new Promise((resolve62) => {
371030
371108
  const socket = new net4.Socket();
371031
371109
  socket.setTimeout(1e3);
371032
371110
  socket.on("connect", () => {
371033
371111
  socket.destroy();
371034
- resolve52(true);
371112
+ resolve62(true);
371035
371113
  });
371036
371114
  socket.on("timeout", () => {
371037
371115
  socket.destroy();
371038
- resolve52(false);
371116
+ resolve62(false);
371039
371117
  });
371040
371118
  socket.on("error", () => {
371041
371119
  socket.destroy();
371042
- resolve52(false);
371120
+ resolve62(false);
371043
371121
  });
371044
371122
  socket.connect(port, host);
371045
371123
  });
371046
371124
  }
371047
371125
  function sleep3(ms) {
371048
- return new Promise((resolve52) => setTimeout(resolve52, ms));
371126
+ return new Promise((resolve62) => setTimeout(resolve62, ms));
371049
371127
  }
371050
371128
  function detectSyncDatabases(config) {
371051
371129
  const needsSync = /* @__PURE__ */ new Set();
@@ -371483,25 +371561,25 @@ async function waitForTcpPort4(host, port, timeoutMs = 3e4) {
371483
371561
  if (isOpen) {
371484
371562
  return;
371485
371563
  }
371486
- await new Promise((resolve52) => setTimeout(resolve52, 100));
371564
+ await new Promise((resolve62) => setTimeout(resolve62, 100));
371487
371565
  }
371488
371566
  throw new Error(`Temporal port ${port} did not become available within timeout`);
371489
371567
  }
371490
371568
  function checkTcpPort4(host, port) {
371491
- return new Promise((resolve52) => {
371569
+ return new Promise((resolve62) => {
371492
371570
  const socket = new net5.Socket();
371493
371571
  socket.setTimeout(1e3);
371494
371572
  socket.on("connect", () => {
371495
371573
  socket.destroy();
371496
- resolve52(true);
371574
+ resolve62(true);
371497
371575
  });
371498
371576
  socket.on("timeout", () => {
371499
371577
  socket.destroy();
371500
- resolve52(false);
371578
+ resolve62(false);
371501
371579
  });
371502
371580
  socket.on("error", () => {
371503
371581
  socket.destroy();
371504
- resolve52(false);
371582
+ resolve62(false);
371505
371583
  });
371506
371584
  socket.connect(port, host);
371507
371585
  });
@@ -371763,6 +371841,80 @@ function watchConfigFile(configPath, debounceMs, onChange) {
371763
371841
  }
371764
371842
  };
371765
371843
  }
371844
+ var MAX_BYTES = 1024 * 1024;
371845
+ var TAIL_BYTES = 512 * 1024;
371846
+ var ServiceLogFiles = class {
371847
+ _logsDir;
371848
+ files = /* @__PURE__ */ new Map();
371849
+ constructor(projectDir, instanceKey) {
371850
+ this._logsDir = path13.resolve(
371851
+ projectDir,
371852
+ ".specific",
371853
+ "keys",
371854
+ instanceKey,
371855
+ "logs"
371856
+ );
371857
+ fs12.mkdirSync(this._logsDir, { recursive: true });
371858
+ }
371859
+ get logsDir() {
371860
+ return this._logsDir;
371861
+ }
371862
+ write(line) {
371863
+ const file = this.getOrCreate(line.service);
371864
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
371865
+ const text = `[${timestamp}] [${line.stream}] ${line.text}
371866
+ `;
371867
+ const bytes = Buffer.byteLength(text);
371868
+ file.stream.write(text);
371869
+ file.bytes += bytes;
371870
+ if (file.bytes > MAX_BYTES) {
371871
+ this.rotate(line.service, file);
371872
+ }
371873
+ }
371874
+ close() {
371875
+ for (const file of this.files.values()) {
371876
+ file.stream.end();
371877
+ }
371878
+ this.files.clear();
371879
+ }
371880
+ getOrCreate(service) {
371881
+ const existing = this.files.get(service);
371882
+ if (existing) return existing;
371883
+ const filePath = path13.join(this._logsDir, `${service}.log`);
371884
+ let initialBytes = 0;
371885
+ try {
371886
+ initialBytes = fs12.statSync(filePath).size;
371887
+ } catch {
371888
+ }
371889
+ const file = {
371890
+ filePath,
371891
+ stream: fs12.createWriteStream(filePath, { flags: "a" }),
371892
+ bytes: initialBytes
371893
+ };
371894
+ this.files.set(service, file);
371895
+ return file;
371896
+ }
371897
+ rotate(service, file) {
371898
+ file.stream.end();
371899
+ this.files.delete(service);
371900
+ try {
371901
+ const buf = fs12.readFileSync(file.filePath);
371902
+ const start = Math.max(0, buf.length - TAIL_BYTES);
371903
+ let cut = start;
371904
+ if (start > 0) {
371905
+ const nl = buf.indexOf(10, start);
371906
+ cut = nl >= 0 ? nl + 1 : buf.length;
371907
+ }
371908
+ const tail = buf.subarray(cut);
371909
+ fs12.writeFileSync(file.filePath, tail);
371910
+ } catch {
371911
+ try {
371912
+ fs12.unlinkSync(file.filePath);
371913
+ } catch {
371914
+ }
371915
+ }
371916
+ }
371917
+ };
371766
371918
  var BLOCK_SIZE = 100;
371767
371919
  var FIRST_BLOCK_START = 3e3;
371768
371920
  var MAX_BLOCKS = 100;
@@ -371821,11 +371973,11 @@ var BlockPortAllocator = class _BlockPortAllocator {
371821
371973
  }
371822
371974
  };
371823
371975
  function isPortAvailable(port) {
371824
- return new Promise((resolve52) => {
371976
+ return new Promise((resolve62) => {
371825
371977
  const server = net6.createServer();
371826
- server.once("error", () => resolve52(false));
371978
+ server.once("error", () => resolve62(false));
371827
371979
  server.once("listening", () => {
371828
- server.close(() => resolve52(true));
371980
+ server.close(() => resolve62(true));
371829
371981
  });
371830
371982
  server.listen(port, "127.0.0.1");
371831
371983
  });
@@ -371835,16 +371987,16 @@ var StableSubdomainAllocator = class {
371835
371987
  tunnelsFilePath;
371836
371988
  baseSlug = null;
371837
371989
  constructor(projectRoot, key = "default") {
371838
- this.tunnelsDir = path13.join(projectRoot, ".specific", "keys", key);
371839
- this.tunnelsFilePath = path13.join(this.tunnelsDir, "tunnels.json");
371990
+ this.tunnelsDir = path14.join(projectRoot, ".specific", "keys", key);
371991
+ this.tunnelsFilePath = path14.join(this.tunnelsDir, "tunnels.json");
371840
371992
  this.loadTunnels();
371841
371993
  }
371842
371994
  loadTunnels() {
371843
- if (!fs12.existsSync(this.tunnelsFilePath)) {
371995
+ if (!fs13.existsSync(this.tunnelsFilePath)) {
371844
371996
  return;
371845
371997
  }
371846
371998
  try {
371847
- const content = fs12.readFileSync(this.tunnelsFilePath, "utf-8");
371999
+ const content = fs13.readFileSync(this.tunnelsFilePath, "utf-8");
371848
372000
  const data = JSON.parse(content);
371849
372001
  if (data.version === 1 && data.baseSlug) {
371850
372002
  this.baseSlug = data.baseSlug;
@@ -371854,14 +372006,14 @@ var StableSubdomainAllocator = class {
371854
372006
  }
371855
372007
  }
371856
372008
  saveTunnels() {
371857
- if (!fs12.existsSync(this.tunnelsDir)) {
371858
- fs12.mkdirSync(this.tunnelsDir, { recursive: true });
372009
+ if (!fs13.existsSync(this.tunnelsDir)) {
372010
+ fs13.mkdirSync(this.tunnelsDir, { recursive: true });
371859
372011
  }
371860
372012
  const data = {
371861
372013
  version: 1,
371862
372014
  baseSlug: this.baseSlug
371863
372015
  };
371864
- fs12.writeFileSync(this.tunnelsFilePath, JSON.stringify(data, null, 2));
372016
+ fs13.writeFileSync(this.tunnelsFilePath, JSON.stringify(data, null, 2));
371865
372017
  }
371866
372018
  generateBaseSlug() {
371867
372019
  return generateSlug(2, {
@@ -372147,6 +372299,7 @@ var DevEnvironment = class extends TypedEventEmitter {
372147
372299
  startTime = null;
372148
372300
  // Core managers
372149
372301
  stateManager = null;
372302
+ serviceLogFiles = null;
372150
372303
  // Running instances
372151
372304
  adminServer = null;
372152
372305
  services = [];
@@ -372201,6 +372354,7 @@ var DevEnvironment = class extends TypedEventEmitter {
372201
372354
  }
372202
372355
  // ── Log helper ─────────────────────────────────────────────────────────────
372203
372356
  addLog(line) {
372357
+ this.serviceLogFiles?.write(line);
372204
372358
  this.emit("log", { service: line.service, text: line.text });
372205
372359
  }
372206
372360
  // ── Public methods ─────────────────────────────────────────────────────────
@@ -372213,8 +372367,8 @@ var DevEnvironment = class extends TypedEventEmitter {
372213
372367
  this.started = true;
372214
372368
  this.shuttingDown = false;
372215
372369
  this.cancelled = false;
372216
- return new Promise((resolve52) => {
372217
- this.startResolve = resolve52;
372370
+ return new Promise((resolve62) => {
372371
+ this.startResolve = resolve62;
372218
372372
  this.startInternal().then(() => {
372219
372373
  if (this.startResolve) {
372220
372374
  this.startResolve();
@@ -372395,6 +372549,8 @@ var DevEnvironment = class extends TypedEventEmitter {
372395
372549
  this.restartServices = null;
372396
372550
  this.removeExitHandler();
372397
372551
  this.systemLog("Shutdown complete");
372552
+ this.serviceLogFiles?.close();
372553
+ this.serviceLogFiles = null;
372398
372554
  closeDebugLog();
372399
372555
  this.setStatus("idle");
372400
372556
  this.emit("stopped");
@@ -372466,10 +372622,10 @@ var DevEnvironment = class extends TypedEventEmitter {
372466
372622
  }
372467
372623
  // ── Private: config file watcher ───────────────────────────────────────────
372468
372624
  startConfigWatcher() {
372469
- const configPath = path14.join(this.projectDir, "specific.hcl");
372625
+ const configPath = path15.join(this.projectDir, "specific.hcl");
372470
372626
  this.configWatcher = watchConfigFile(configPath, 1e3, () => {
372471
372627
  try {
372472
- const hcl = fs13.readFileSync(configPath, "utf-8");
372628
+ const hcl = fs14.readFileSync(configPath, "utf-8");
372473
372629
  parseConfig(hcl).then(() => {
372474
372630
  this.reload();
372475
372631
  }).catch((err) => {
@@ -372490,6 +372646,12 @@ var DevEnvironment = class extends TypedEventEmitter {
372490
372646
  this.instanceKey
372491
372647
  );
372492
372648
  this.stateManager = stateManager;
372649
+ if (!this.serviceLogFiles) {
372650
+ this.serviceLogFiles = new ServiceLogFiles(
372651
+ this.projectDir,
372652
+ this.instanceKey
372653
+ );
372654
+ }
372493
372655
  this.systemLog("Starting dev server");
372494
372656
  this.setStatus("loading");
372495
372657
  await stateManager.cleanStaleState();
@@ -372508,8 +372670,8 @@ var DevEnvironment = class extends TypedEventEmitter {
372508
372670
  this.emit("error", new Error(msg));
372509
372671
  return;
372510
372672
  }
372511
- const configPath = path14.join(this.projectDir, "specific.hcl");
372512
- if (!fs13.existsSync(configPath)) {
372673
+ const configPath = path15.join(this.projectDir, "specific.hcl");
372674
+ if (!fs14.existsSync(configPath)) {
372513
372675
  this.systemLog("Waiting for specific.hcl to appear");
372514
372676
  this.setStatus("waiting");
372515
372677
  const dirWatcher = chokidar_default.watch(configPath, {
@@ -372530,7 +372692,7 @@ var DevEnvironment = class extends TypedEventEmitter {
372530
372692
  return;
372531
372693
  }
372532
372694
  let config;
372533
- const hcl = fs13.readFileSync(configPath, "utf-8");
372695
+ const hcl = fs14.readFileSync(configPath, "utf-8");
372534
372696
  try {
372535
372697
  config = await parseConfig(hcl);
372536
372698
  } catch (err) {
@@ -372540,9 +372702,9 @@ var DevEnvironment = class extends TypedEventEmitter {
372540
372702
  return;
372541
372703
  }
372542
372704
  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");
372705
+ const localFilePath = path15.join(this.projectDir, "specific.local");
372706
+ if (fs14.existsSync(localFilePath)) {
372707
+ const localContent = fs14.readFileSync(localFilePath, "utf-8");
372546
372708
  try {
372547
372709
  await parseLocalFile(localContent);
372548
372710
  } catch (err) {
@@ -372660,7 +372822,7 @@ var DevEnvironment = class extends TypedEventEmitter {
372660
372822
  const drizzleGateway = await startDrizzleGateway(
372661
372823
  postgresResources,
372662
372824
  drizzlePort,
372663
- path14.join(this.projectDir, ".specific", "keys", this.instanceKey)
372825
+ path15.join(this.projectDir, ".specific", "keys", this.instanceKey)
372664
372826
  );
372665
372827
  this.drizzleGateway = drizzleGateway;
372666
372828
  this.systemLog(`Database viewer ready at ${drizzleGateway.url}`);
@@ -372687,14 +372849,14 @@ var DevEnvironment = class extends TypedEventEmitter {
372687
372849
  if (pg.reshape?.enabled) {
372688
372850
  const resource = resources.get(pg.name);
372689
372851
  if (!resource) continue;
372690
- const migrationsDir = path14.resolve(
372852
+ const migrationsDir = path15.resolve(
372691
372853
  this.projectDir,
372692
372854
  pg.reshape.migrations_dir ?? "migrations"
372693
372855
  );
372694
372856
  this.systemLog(
372695
372857
  `Initializing Reshape migrations for "${pg.name}" from ${migrationsDir}`
372696
372858
  );
372697
- const reshapeStateFile = path14.join(
372859
+ const reshapeStateFile = path15.join(
372698
372860
  this.projectDir,
372699
372861
  ".specific",
372700
372862
  "keys",
@@ -372798,8 +372960,8 @@ var DevEnvironment = class extends TypedEventEmitter {
372798
372960
  if (missingConfigs.length > 0) {
372799
372961
  this.emit("inputRequired", "configs", missingConfigs);
372800
372962
  }
372801
- await new Promise((resolve52) => {
372802
- this.inputResolve = resolve52;
372963
+ await new Promise((resolve62) => {
372964
+ this.inputResolve = resolve62;
372803
372965
  this.checkInputComplete();
372804
372966
  });
372805
372967
  for (const [name, value] of Object.entries(this.collectedSecrets)) {
@@ -372907,13 +373069,13 @@ Add them to the config block in specific.local`
372907
373069
  const runningServices = [];
372908
373070
  const resolveServiceCwd = (service) => {
372909
373071
  if (service.root)
372910
- return path14.resolve(this.projectDir, service.root);
373072
+ return path15.resolve(this.projectDir, service.root);
372911
373073
  if (service.build) {
372912
373074
  const build = config.builds.find(
372913
373075
  (b) => b.name === service.build.name
372914
373076
  );
372915
373077
  if (build?.root)
372916
- return path14.resolve(this.projectDir, build.root);
373078
+ return path15.resolve(this.projectDir, build.root);
372917
373079
  }
372918
373080
  return this.projectDir;
372919
373081
  };
@@ -372933,7 +373095,7 @@ Add them to the config block in specific.local`
372933
373095
  const volumePaths = /* @__PURE__ */ new Map();
372934
373096
  if (service.volumes) {
372935
373097
  for (const vol of service.volumes) {
372936
- const volumeDir = path14.resolve(
373098
+ const volumeDir = path15.resolve(
372937
373099
  this.projectDir,
372938
373100
  ".specific",
372939
373101
  "keys",
@@ -372943,7 +373105,7 @@ Add them to the config block in specific.local`
372943
373105
  service.name,
372944
373106
  vol.name
372945
373107
  );
372946
- fs13.mkdirSync(volumeDir, { recursive: true });
373108
+ fs14.mkdirSync(volumeDir, { recursive: true });
372947
373109
  volumePaths.set(vol.name, volumeDir);
372948
373110
  }
372949
373111
  }
@@ -372993,7 +373155,7 @@ Add them to the config block in specific.local`
372993
373155
  const volumePaths = /* @__PURE__ */ new Map();
372994
373156
  if (service.volumes) {
372995
373157
  for (const vol of service.volumes) {
372996
- const volumeDir = path14.resolve(
373158
+ const volumeDir = path15.resolve(
372997
373159
  this.projectDir,
372998
373160
  ".specific",
372999
373161
  "keys",
@@ -373003,7 +373165,7 @@ Add them to the config block in specific.local`
373003
373165
  service.name,
373004
373166
  vol.name
373005
373167
  );
373006
- fs13.mkdirSync(volumeDir, { recursive: true });
373168
+ fs14.mkdirSync(volumeDir, { recursive: true });
373007
373169
  volumePaths.set(vol.name, volumeDir);
373008
373170
  }
373009
373171
  }
@@ -373150,7 +373312,11 @@ Add them to the config block in specific.local`
373150
373312
  ...temporalUiPort !== void 0 ? { temporalUiPort } : {}
373151
373313
  });
373152
373314
  const adminPort = portAllocator.getAdminPort();
373153
- const adminServer = await startAdminServer(getState, adminPort);
373315
+ const adminServer = await startAdminServer(
373316
+ getState,
373317
+ adminPort,
373318
+ () => this.serviceLogFiles?.logsDir ?? null
373319
+ );
373154
373320
  this.adminServer = adminServer;
373155
373321
  this.systemLog(
373156
373322
  `Admin server started on port ${adminServer.port}`
@@ -373173,8 +373339,8 @@ function isInWorktree() {
373173
373339
  encoding: "utf-8",
373174
373340
  stdio: ["pipe", "pipe", "pipe"]
373175
373341
  }).trim();
373176
- const resolvedCommonDir = path15.resolve(commonDir);
373177
- const resolvedGitDir = path15.resolve(gitDir);
373342
+ const resolvedCommonDir = path16.resolve(commonDir);
373343
+ const resolvedGitDir = path16.resolve(gitDir);
373178
373344
  return resolvedCommonDir !== resolvedGitDir;
373179
373345
  } catch {
373180
373346
  return false;
@@ -373189,7 +373355,7 @@ function getWorktreeName() {
373189
373355
  encoding: "utf-8",
373190
373356
  stdio: ["pipe", "pipe", "pipe"]
373191
373357
  }).trim();
373192
- return path15.basename(gitDir);
373358
+ return path16.basename(gitDir);
373193
373359
  } catch {
373194
373360
  return null;
373195
373361
  }
@@ -373288,8 +373454,8 @@ function findEnvironmentByNameOrId(environments, flag) {
373288
373454
  }
373289
373455
 
373290
373456
  // src/lib/auth/credentials.ts
373291
- import * as fs19 from "fs";
373292
- import * as path17 from "path";
373457
+ import * as fs20 from "fs";
373458
+ import * as path18 from "path";
373293
373459
  import * as os4 from "os";
373294
373460
 
373295
373461
  // src/lib/auth/errors.ts
@@ -373459,7 +373625,7 @@ async function pollUntilToken(deviceAuth, isCancelled) {
373459
373625
  return null;
373460
373626
  }
373461
373627
  function sleep4(ms) {
373462
- return new Promise((resolve9) => setTimeout(resolve9, ms));
373628
+ return new Promise((resolve10) => setTimeout(resolve10, ms));
373463
373629
  }
373464
373630
 
373465
373631
  // src/lib/auth/login.tsx
@@ -373476,7 +373642,7 @@ function LoginUI({
373476
373642
  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...")));
373477
373643
  }
373478
373644
  function performLogin(options2 = {}) {
373479
- return new Promise((resolve9) => {
373645
+ return new Promise((resolve10) => {
373480
373646
  let currentState = { phase: "initiating" };
373481
373647
  let flowHandle;
373482
373648
  const instance = render(
@@ -373516,14 +373682,14 @@ function performLogin(options2 = {}) {
373516
373682
  process.off("SIGINT", handleExit);
373517
373683
  process.off("SIGTERM", handleExit);
373518
373684
  instance.unmount();
373519
- resolve9({ success: true, userEmail: newState.email });
373685
+ resolve10({ success: true, userEmail: newState.email });
373520
373686
  }, 100);
373521
373687
  } else if (newState.phase === "error") {
373522
373688
  setTimeout(() => {
373523
373689
  process.off("SIGINT", handleExit);
373524
373690
  process.off("SIGTERM", handleExit);
373525
373691
  instance.unmount();
373526
- resolve9({ success: false, error: new Error(newState.message) });
373692
+ resolve10({ success: false, error: new Error(newState.message) });
373527
373693
  }, 100);
373528
373694
  }
373529
373695
  }
@@ -373614,18 +373780,18 @@ async function fetchGithubActionsIdToken() {
373614
373780
 
373615
373781
  // src/lib/auth/credentials.ts
373616
373782
  function getUserCredentialsDir() {
373617
- return path17.join(os4.homedir(), ".specific");
373783
+ return path18.join(os4.homedir(), ".specific");
373618
373784
  }
373619
373785
  function getCredentialsPath() {
373620
- return path17.join(getUserCredentialsDir(), "credentials.json");
373786
+ return path18.join(getUserCredentialsDir(), "credentials.json");
373621
373787
  }
373622
373788
  function readUserCredentials() {
373623
373789
  const credentialsPath = getCredentialsPath();
373624
- if (!fs19.existsSync(credentialsPath)) {
373790
+ if (!fs20.existsSync(credentialsPath)) {
373625
373791
  return null;
373626
373792
  }
373627
373793
  try {
373628
- const content = fs19.readFileSync(credentialsPath, "utf-8");
373794
+ const content = fs20.readFileSync(credentialsPath, "utf-8");
373629
373795
  return JSON.parse(content);
373630
373796
  } catch {
373631
373797
  return null;
@@ -373633,18 +373799,18 @@ function readUserCredentials() {
373633
373799
  }
373634
373800
  function writeUserCredentials(credentials) {
373635
373801
  const dir = getUserCredentialsDir();
373636
- if (!fs19.existsSync(dir)) {
373637
- fs19.mkdirSync(dir, { recursive: true, mode: 448 });
373802
+ if (!fs20.existsSync(dir)) {
373803
+ fs20.mkdirSync(dir, { recursive: true, mode: 448 });
373638
373804
  }
373639
373805
  const credentialsPath = getCredentialsPath();
373640
- fs19.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {
373806
+ fs20.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {
373641
373807
  mode: 384
373642
373808
  });
373643
373809
  }
373644
373810
  function clearUserCredentials() {
373645
373811
  const credentialsPath = getCredentialsPath();
373646
- if (fs19.existsSync(credentialsPath)) {
373647
- fs19.unlinkSync(credentialsPath);
373812
+ if (fs20.existsSync(credentialsPath)) {
373813
+ fs20.unlinkSync(credentialsPath);
373648
373814
  }
373649
373815
  }
373650
373816
  function isLoggedIn() {
@@ -373773,7 +373939,7 @@ function trackEvent(event, properties) {
373773
373939
  event,
373774
373940
  properties: {
373775
373941
  ...properties,
373776
- cli_version: "0.1.140",
373942
+ cli_version: "0.1.142",
373777
373943
  platform: process.platform,
373778
373944
  node_version: process.version,
373779
373945
  project_id: getProjectId()
@@ -373804,67 +373970,67 @@ var options = [
373804
373970
  { id: "other", label: "Other / Manual" }
373805
373971
  ];
373806
373972
  function isGitProject() {
373807
- const gitPath = path18.join(process.cwd(), ".git");
373808
- return fs20.existsSync(gitPath);
373973
+ const gitPath = path19.join(process.cwd(), ".git");
373974
+ return fs21.existsSync(gitPath);
373809
373975
  }
373810
373976
  function detectExistingAgents() {
373811
373977
  const detected = {};
373812
- const cursorDir = path18.join(process.cwd(), ".cursor");
373813
- if (fs20.existsSync(cursorDir)) {
373978
+ const cursorDir = path19.join(process.cwd(), ".cursor");
373979
+ if (fs21.existsSync(cursorDir)) {
373814
373980
  detected["cursor"] = true;
373815
373981
  }
373816
- const claudeDir = path18.join(process.cwd(), ".claude");
373817
- const claudeMd = path18.join(process.cwd(), "CLAUDE.md");
373818
- if (fs20.existsSync(claudeDir) || fs20.existsSync(claudeMd)) {
373982
+ const claudeDir = path19.join(process.cwd(), ".claude");
373983
+ const claudeMd = path19.join(process.cwd(), "CLAUDE.md");
373984
+ if (fs21.existsSync(claudeDir) || fs21.existsSync(claudeMd)) {
373819
373985
  detected["claude"] = true;
373820
373986
  }
373821
- const agentsMd = path18.join(process.cwd(), "AGENTS.md");
373822
- if (fs20.existsSync(agentsMd)) {
373987
+ const agentsMd = path19.join(process.cwd(), "AGENTS.md");
373988
+ if (fs21.existsSync(agentsMd)) {
373823
373989
  detected["codex"] = true;
373824
373990
  }
373825
373991
  return detected;
373826
373992
  }
373827
373993
  function appendOrCreateFile(filePath, content) {
373828
- if (fs20.existsSync(filePath)) {
373829
- const existing = fs20.readFileSync(filePath, "utf-8");
373994
+ if (fs21.existsSync(filePath)) {
373995
+ const existing = fs21.readFileSync(filePath, "utf-8");
373830
373996
  if (existing.includes("specific docs") || existing.includes("specific check")) {
373831
373997
  return "unchanged";
373832
373998
  }
373833
373999
  const separator = existing.endsWith("\n") ? "\n" : "\n\n";
373834
- fs20.writeFileSync(filePath, existing + separator + content + "\n");
374000
+ fs21.writeFileSync(filePath, existing + separator + content + "\n");
373835
374001
  return "modified";
373836
374002
  } else {
373837
- fs20.writeFileSync(filePath, content + "\n");
374003
+ fs21.writeFileSync(filePath, content + "\n");
373838
374004
  return "created";
373839
374005
  }
373840
374006
  }
373841
374007
  function addToGitignore() {
373842
- const gitignorePath = path18.join(process.cwd(), ".gitignore");
374008
+ const gitignorePath = path19.join(process.cwd(), ".gitignore");
373843
374009
  const entries = [".specific", "specific.local"];
373844
- if (fs20.existsSync(gitignorePath)) {
373845
- const existing = fs20.readFileSync(gitignorePath, "utf-8");
374010
+ if (fs21.existsSync(gitignorePath)) {
374011
+ const existing = fs21.readFileSync(gitignorePath, "utf-8");
373846
374012
  const lines = existing.split("\n").map((l) => l.trim());
373847
374013
  const missingEntries = entries.filter((entry) => !lines.includes(entry));
373848
374014
  if (missingEntries.length === 0) {
373849
374015
  return "unchanged";
373850
374016
  }
373851
374017
  const separator = existing.endsWith("\n") ? "" : "\n";
373852
- fs20.writeFileSync(
374018
+ fs21.writeFileSync(
373853
374019
  gitignorePath,
373854
374020
  existing + separator + missingEntries.join("\n") + "\n"
373855
374021
  );
373856
374022
  return "modified";
373857
374023
  } else {
373858
- fs20.writeFileSync(gitignorePath, entries.join("\n") + "\n");
374024
+ fs21.writeFileSync(gitignorePath, entries.join("\n") + "\n");
373859
374025
  return "created";
373860
374026
  }
373861
374027
  }
373862
374028
  function configureClaudeCodePermissions() {
373863
- const claudeDir = path18.join(process.cwd(), ".claude");
373864
- const settingsPath = path18.join(claudeDir, "settings.local.json");
374029
+ const claudeDir = path19.join(process.cwd(), ".claude");
374030
+ const settingsPath = path19.join(claudeDir, "settings.local.json");
373865
374031
  const permissions = ["Bash(specific docs:*)", "Bash(specific check:*)"];
373866
- if (fs20.existsSync(settingsPath)) {
373867
- const existing = JSON.parse(fs20.readFileSync(settingsPath, "utf-8"));
374032
+ if (fs21.existsSync(settingsPath)) {
374033
+ const existing = JSON.parse(fs21.readFileSync(settingsPath, "utf-8"));
373868
374034
  const allowList = existing?.permissions?.allow || [];
373869
374035
  const missingPermissions = permissions.filter(
373870
374036
  (p) => !allowList.includes(p)
@@ -373879,39 +374045,39 @@ function configureClaudeCodePermissions() {
373879
374045
  existing.permissions.allow = [];
373880
374046
  }
373881
374047
  existing.permissions.allow.push(...missingPermissions);
373882
- fs20.writeFileSync(settingsPath, JSON.stringify(existing, null, 2) + "\n");
374048
+ fs21.writeFileSync(settingsPath, JSON.stringify(existing, null, 2) + "\n");
373883
374049
  return "modified";
373884
374050
  }
373885
- if (!fs20.existsSync(claudeDir)) {
373886
- fs20.mkdirSync(claudeDir);
374051
+ if (!fs21.existsSync(claudeDir)) {
374052
+ fs21.mkdirSync(claudeDir);
373887
374053
  }
373888
374054
  const settings = {
373889
374055
  permissions: {
373890
374056
  allow: permissions
373891
374057
  }
373892
374058
  };
373893
- fs20.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
374059
+ fs21.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
373894
374060
  return "created";
373895
374061
  }
373896
374062
  function createCursorRule() {
373897
- const cursorDir = path18.join(process.cwd(), ".cursor");
373898
- const rulesDir = path18.join(cursorDir, "rules");
373899
- const mdcPath = path18.join(rulesDir, "specific.mdc");
373900
- if (fs20.existsSync(mdcPath)) {
373901
- const existing = fs20.readFileSync(mdcPath, "utf-8");
374063
+ const cursorDir = path19.join(process.cwd(), ".cursor");
374064
+ const rulesDir = path19.join(cursorDir, "rules");
374065
+ const mdcPath = path19.join(rulesDir, "specific.mdc");
374066
+ if (fs21.existsSync(mdcPath)) {
374067
+ const existing = fs21.readFileSync(mdcPath, "utf-8");
373902
374068
  if (existing.includes("specific docs") || existing.includes("specific check")) {
373903
374069
  return "unchanged";
373904
374070
  }
373905
- fs20.writeFileSync(mdcPath, CURSOR_MDC_CONTENT);
374071
+ fs21.writeFileSync(mdcPath, CURSOR_MDC_CONTENT);
373906
374072
  return "modified";
373907
374073
  }
373908
- if (!fs20.existsSync(cursorDir)) {
373909
- fs20.mkdirSync(cursorDir);
374074
+ if (!fs21.existsSync(cursorDir)) {
374075
+ fs21.mkdirSync(cursorDir);
373910
374076
  }
373911
- if (!fs20.existsSync(rulesDir)) {
373912
- fs20.mkdirSync(rulesDir);
374077
+ if (!fs21.existsSync(rulesDir)) {
374078
+ fs21.mkdirSync(rulesDir);
373913
374079
  }
373914
- fs20.writeFileSync(mdcPath, CURSOR_MDC_CONTENT);
374080
+ fs21.writeFileSync(mdcPath, CURSOR_MDC_CONTENT);
373915
374081
  return "created";
373916
374082
  }
373917
374083
  function configureAgents(checked) {
@@ -373927,7 +374093,7 @@ function configureAgents(checked) {
373927
374093
  agents.filesModified.push(".cursor/rules/specific.mdc");
373928
374094
  }
373929
374095
  if (checked["claude"]) {
373930
- const claudeMdPath = path18.join(process.cwd(), "CLAUDE.md");
374096
+ const claudeMdPath = path19.join(process.cwd(), "CLAUDE.md");
373931
374097
  const status = appendOrCreateFile(claudeMdPath, SPECIFIC_INSTRUCTIONS);
373932
374098
  if (status === "created") agents.filesCreated.push("CLAUDE.md");
373933
374099
  else if (status === "modified") agents.filesModified.push("CLAUDE.md");
@@ -373938,7 +374104,7 @@ function configureAgents(checked) {
373938
374104
  agents.filesModified.push(".claude/settings.local.json");
373939
374105
  }
373940
374106
  if (checked["codex"]) {
373941
- const agentsMdPath = path18.join(process.cwd(), "AGENTS.md");
374107
+ const agentsMdPath = path19.join(process.cwd(), "AGENTS.md");
373942
374108
  const status = appendOrCreateFile(agentsMdPath, SPECIFIC_INSTRUCTIONS);
373943
374109
  if (status === "created") agents.filesCreated.push("AGENTS.md");
373944
374110
  else if (status === "modified") agents.filesModified.push("AGENTS.md");
@@ -374091,9 +374257,9 @@ Valid agents: ${VALID_AGENT_IDS.join(", ")}`
374091
374257
  }
374092
374258
 
374093
374259
  // src/commands/docs.tsx
374094
- import { readFileSync as readFileSync11, existsSync as existsSync17 } from "fs";
374260
+ import { readFileSync as readFileSync12, existsSync as existsSync17 } from "fs";
374095
374261
  import { spawn as spawn6 } from "child_process";
374096
- import { join as join19, dirname as dirname9 } from "path";
374262
+ import { join as join20, dirname as dirname9 } from "path";
374097
374263
  import { fileURLToPath as fileURLToPath3 } from "url";
374098
374264
 
374099
374265
  // src/lib/beta/registry.ts
@@ -374105,16 +374271,16 @@ var BETA_REGISTRY = [
374105
374271
  ];
374106
374272
 
374107
374273
  // src/lib/beta/storage.ts
374108
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync8, existsSync as existsSync16, mkdirSync as mkdirSync13 } from "fs";
374109
- import { join as join18 } from "path";
374274
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync9, existsSync as existsSync16, mkdirSync as mkdirSync14 } from "fs";
374275
+ import { join as join19 } from "path";
374110
374276
  var BETAS_FILE = ".specific/betas.json";
374111
374277
  function loadEnabledBetas(projectDir = process.cwd()) {
374112
- const filePath = join18(projectDir, BETAS_FILE);
374278
+ const filePath = join19(projectDir, BETAS_FILE);
374113
374279
  if (!existsSync16(filePath)) {
374114
374280
  return [];
374115
374281
  }
374116
374282
  try {
374117
- const content = readFileSync10(filePath, "utf-8");
374283
+ const content = readFileSync11(filePath, "utf-8");
374118
374284
  const data = JSON.parse(content);
374119
374285
  return data.enabled ?? [];
374120
374286
  } catch {
@@ -374133,30 +374299,30 @@ function disableBeta(name, projectDir = process.cwd()) {
374133
374299
  saveBetas(enabled, projectDir);
374134
374300
  }
374135
374301
  function saveBetas(enabled, projectDir) {
374136
- const specificDir = join18(projectDir, ".specific");
374302
+ const specificDir = join19(projectDir, ".specific");
374137
374303
  if (!existsSync16(specificDir)) {
374138
- mkdirSync13(specificDir, { recursive: true });
374304
+ mkdirSync14(specificDir, { recursive: true });
374139
374305
  }
374140
374306
  const data = { enabled };
374141
- writeFileSync8(
374142
- join18(projectDir, BETAS_FILE),
374307
+ writeFileSync9(
374308
+ join19(projectDir, BETAS_FILE),
374143
374309
  JSON.stringify(data, null, 2) + "\n"
374144
374310
  );
374145
374311
  }
374146
374312
 
374147
374313
  // src/commands/docs.tsx
374148
374314
  var __dirname3 = dirname9(fileURLToPath3(import.meta.url));
374149
- var docsDir = join19(__dirname3, "docs");
374315
+ var docsDir = join20(__dirname3, "docs");
374150
374316
  var _embeddedDocs = null;
374151
374317
  var RESHAPE_DOCS_PREFIX = "postgres/reshape/";
374152
- async function docsCommand(path27) {
374153
- let content = resolveDocContent(path27);
374154
- if (!content && path27) {
374155
- content = await resolveReshapeDoc(path27);
374318
+ async function docsCommand(path28) {
374319
+ let content = resolveDocContent(path28);
374320
+ if (!content && path28) {
374321
+ content = await resolveReshapeDoc(path28);
374156
374322
  }
374157
374323
  if (!content) {
374158
374324
  console.error(
374159
- `Documentation not found: ${path27 || "index"}
374325
+ `Documentation not found: ${path28 || "index"}
374160
374326
 
374161
374327
  Run 'specific docs' to see available topics.`
374162
374328
  );
@@ -374166,25 +374332,25 @@ Run 'specific docs' to see available topics.`
374166
374332
  const filtered = filterBetaTags(content, enabledBetas);
374167
374333
  console.log(filtered);
374168
374334
  }
374169
- async function resolveReshapeDoc(path27) {
374170
- const normalized = path27.replace(/^\/+|\/+$/g, "");
374335
+ async function resolveReshapeDoc(path28) {
374336
+ const normalized = path28.replace(/^\/+|\/+$/g, "");
374171
374337
  if (!normalized.startsWith(RESHAPE_DOCS_PREFIX)) return null;
374172
374338
  const reshapePath = "/" + normalized.slice(RESHAPE_DOCS_PREFIX.length);
374173
374339
  try {
374174
374340
  const binary = await ensureBinary(reshapeBinary);
374175
374341
  const reshapeExe = binary.executables["reshape"];
374176
- const output = await new Promise((resolve9) => {
374342
+ const output = await new Promise((resolve10) => {
374177
374343
  const child = spawn6(reshapeExe, ["docs", reshapePath], {
374178
374344
  stdio: ["ignore", "pipe", "ignore"]
374179
374345
  });
374180
374346
  const chunks = [];
374181
374347
  child.stdout.on("data", (chunk) => chunks.push(chunk));
374182
- child.on("error", () => resolve9(null));
374348
+ child.on("error", () => resolve10(null));
374183
374349
  child.on("close", (code) => {
374184
374350
  if (code === 0 && chunks.length > 0) {
374185
- resolve9(Buffer.concat(chunks).toString("utf-8"));
374351
+ resolve10(Buffer.concat(chunks).toString("utf-8"));
374186
374352
  } else {
374187
- resolve9(null);
374353
+ resolve10(null);
374188
374354
  }
374189
374355
  });
374190
374356
  });
@@ -374201,33 +374367,33 @@ function filterBetaTags(content, enabledBetas) {
374201
374367
  }
374202
374368
  );
374203
374369
  }
374204
- function resolveDocContent(path27) {
374205
- const normalized = path27?.replace(/^\/+|\/+$/g, "") || void 0;
374370
+ function resolveDocContent(path28) {
374371
+ const normalized = path28?.replace(/^\/+|\/+$/g, "") || void 0;
374206
374372
  if (_embeddedDocs) {
374207
374373
  return resolveEmbeddedDoc(normalized);
374208
374374
  }
374209
374375
  return resolveFilesystemDoc(normalized);
374210
374376
  }
374211
- function resolveEmbeddedDoc(path27) {
374212
- if (!path27) {
374377
+ function resolveEmbeddedDoc(path28) {
374378
+ if (!path28) {
374213
374379
  return _embeddedDocs.get("index.md") ?? null;
374214
374380
  }
374215
- const direct = _embeddedDocs.get(`${path27}.md`);
374381
+ const direct = _embeddedDocs.get(`${path28}.md`);
374216
374382
  if (direct) return direct;
374217
- return _embeddedDocs.get(`${path27}/index.md`) ?? null;
374383
+ return _embeddedDocs.get(`${path28}/index.md`) ?? null;
374218
374384
  }
374219
- function resolveFilesystemDoc(path27) {
374220
- if (!path27) {
374221
- const indexPath2 = join19(docsDir, "index.md");
374222
- return existsSync17(indexPath2) ? readFileSync11(indexPath2, "utf-8") : null;
374385
+ function resolveFilesystemDoc(path28) {
374386
+ if (!path28) {
374387
+ const indexPath2 = join20(docsDir, "index.md");
374388
+ return existsSync17(indexPath2) ? readFileSync12(indexPath2, "utf-8") : null;
374223
374389
  }
374224
- const directPath = join19(docsDir, `${path27}.md`);
374390
+ const directPath = join20(docsDir, `${path28}.md`);
374225
374391
  if (existsSync17(directPath)) {
374226
- return readFileSync11(directPath, "utf-8");
374392
+ return readFileSync12(directPath, "utf-8");
374227
374393
  }
374228
- const indexPath = join19(docsDir, path27, "index.md");
374394
+ const indexPath = join20(docsDir, path28, "index.md");
374229
374395
  if (existsSync17(indexPath)) {
374230
- return readFileSync11(indexPath, "utf-8");
374396
+ return readFileSync12(indexPath, "utf-8");
374231
374397
  }
374232
374398
  return null;
374233
374399
  }
@@ -374236,8 +374402,8 @@ function resolveFilesystemDoc(path27) {
374236
374402
  import React3, { useState as useState2, useEffect as useEffect2 } from "react";
374237
374403
  import { render as render3, Text as Text3, Box as Box3 } from "ink";
374238
374404
  import Spinner2 from "ink-spinner";
374239
- import * as fs21 from "fs";
374240
- import * as path19 from "path";
374405
+ import * as fs22 from "fs";
374406
+ import * as path20 from "path";
374241
374407
  import { execFile as execFile8 } from "child_process";
374242
374408
 
374243
374409
  // node_modules/.pnpm/@specific+config@file+..+config/node_modules/@specific/config/dist/parser.js
@@ -374891,13 +375057,13 @@ async function runReshapeCheck(migrationsDir) {
374891
375057
  try {
374892
375058
  const binary = await ensureBinary(reshapeBinary);
374893
375059
  const reshapePath = binary.executables["reshape"];
374894
- return new Promise((resolve9) => {
375060
+ return new Promise((resolve10) => {
374895
375061
  execFile8(reshapePath, ["check", "--dirs", migrationsDir], (err, _stdout, stderr) => {
374896
375062
  if (err) {
374897
375063
  const errorMsg = stderr.trim() || err.message;
374898
- resolve9({ success: false, error: errorMsg });
375064
+ resolve10({ success: false, error: errorMsg });
374899
375065
  } else {
374900
- resolve9({ success: true });
375066
+ resolve10({ success: true });
374901
375067
  }
374902
375068
  });
374903
375069
  });
@@ -374909,20 +375075,20 @@ function CheckUI() {
374909
375075
  const [state, setState] = useState2({ status: "loading" });
374910
375076
  useEffect2(() => {
374911
375077
  async function load() {
374912
- const configPath = path19.join(process.cwd(), "specific.hcl");
374913
- if (!fs21.existsSync(configPath)) {
375078
+ const configPath = path20.join(process.cwd(), "specific.hcl");
375079
+ if (!fs22.existsSync(configPath)) {
374914
375080
  setState({
374915
375081
  status: "error",
374916
375082
  error: "No specific.hcl found in current directory"
374917
375083
  });
374918
375084
  return;
374919
375085
  }
374920
- const hcl = fs21.readFileSync(configPath, "utf-8");
375086
+ const hcl = fs22.readFileSync(configPath, "utf-8");
374921
375087
  try {
374922
375088
  const config2 = await parseConfig2(hcl);
374923
- const localPath = path19.join(process.cwd(), LOCAL_FILE);
374924
- if (fs21.existsSync(localPath)) {
374925
- const localContent = fs21.readFileSync(localPath, "utf-8");
375089
+ const localPath = path20.join(process.cwd(), LOCAL_FILE);
375090
+ if (fs22.existsSync(localPath)) {
375091
+ const localContent = fs22.readFileSync(localPath, "utf-8");
374926
375092
  try {
374927
375093
  await parseLocalFile(localContent);
374928
375094
  } catch (localErr) {
@@ -374935,8 +375101,8 @@ function CheckUI() {
374935
375101
  }
374936
375102
  for (const build of config2.builds) {
374937
375103
  if (build.dockerfile) {
374938
- const dockerfilePath = path19.resolve(process.cwd(), build.dockerfile);
374939
- if (!fs21.existsSync(dockerfilePath)) {
375104
+ const dockerfilePath = path20.resolve(process.cwd(), build.dockerfile);
375105
+ if (!fs22.existsSync(dockerfilePath)) {
374940
375106
  setState({
374941
375107
  status: "error",
374942
375108
  error: `Build "${build.name}": Dockerfile not found at "${build.dockerfile}" (resolved to ${dockerfilePath})`
@@ -374948,11 +375114,11 @@ function CheckUI() {
374948
375114
  const reshapeChecks2 = [];
374949
375115
  for (const pg of config2.postgres) {
374950
375116
  if (pg.reshape?.enabled) {
374951
- const migrationsDir = path19.resolve(
375117
+ const migrationsDir = path20.resolve(
374952
375118
  process.cwd(),
374953
375119
  pg.reshape.migrations_dir ?? "migrations"
374954
375120
  );
374955
- if (!fs21.existsSync(migrationsDir)) {
375121
+ if (!fs22.existsSync(migrationsDir)) {
374956
375122
  reshapeChecks2.push({
374957
375123
  databaseName: pg.name,
374958
375124
  migrationsDir: pg.reshape.migrations_dir ?? "migrations",
@@ -375621,8 +375787,8 @@ init_open();
375621
375787
  import React7, { useState as useState6, useEffect as useEffect6, useCallback as useCallback3 } from "react";
375622
375788
  import { render as render5, Text as Text7, Box as Box7, useApp as useApp3, useInput as useInput4 } from "ink";
375623
375789
  import Spinner4 from "ink-spinner";
375624
- import * as fs22 from "fs";
375625
- import * as path20 from "path";
375790
+ import * as fs23 from "fs";
375791
+ import * as path21 from "path";
375626
375792
  import { execFileSync as execFileSync2 } from "child_process";
375627
375793
  function getGitInfo(cwd) {
375628
375794
  try {
@@ -376861,7 +377027,7 @@ async function runDeployPipeline(options2) {
376861
377027
  }
376862
377028
  console.log("Waiting for build...");
376863
377029
  while (true) {
376864
- await new Promise((resolve9) => setTimeout(resolve9, 2e3));
377030
+ await new Promise((resolve10) => setTimeout(resolve10, 2e3));
376865
377031
  const status = await client2.getDeployment(deployment.id);
376866
377032
  deployment = status;
376867
377033
  if (status.state === "failed") {
@@ -376936,7 +377102,7 @@ ${failedBuild.output}`);
376936
377102
  }
376937
377103
  console.log("Deploying...");
376938
377104
  while (true) {
376939
- await new Promise((resolve9) => setTimeout(resolve9, 2e3));
377105
+ await new Promise((resolve10) => setTimeout(resolve10, 2e3));
376940
377106
  const status = await client2.getDeployment(deployment.id);
376941
377107
  deployment = status;
376942
377108
  if (status.state === "failed") {
@@ -376970,13 +377136,13 @@ ${status.error.output}`);
376970
377136
  }
376971
377137
  }
376972
377138
  async function deployCommand(options2) {
376973
- const configPath = path20.join(process.cwd(), "specific.hcl");
376974
- if (!fs22.existsSync(configPath)) {
377139
+ const configPath = path21.join(process.cwd(), "specific.hcl");
377140
+ if (!fs23.existsSync(configPath)) {
376975
377141
  console.error("Error: No specific.hcl found in current directory");
376976
377142
  process.exit(1);
376977
377143
  }
376978
377144
  let config;
376979
- const hcl = fs22.readFileSync(configPath, "utf-8");
377145
+ const hcl = fs23.readFileSync(configPath, "utf-8");
376980
377146
  try {
376981
377147
  config = await parseConfig2(hcl);
376982
377148
  } catch (err) {
@@ -377009,8 +377175,8 @@ async function deployCommand(options2) {
377009
377175
 
377010
377176
  // src/commands/exec.tsx
377011
377177
  import { spawn as spawn7 } from "child_process";
377012
- import * as fs23 from "fs";
377013
- import * as path21 from "path";
377178
+ import * as fs24 from "fs";
377179
+ import * as path22 from "path";
377014
377180
  function startSpinner(text) {
377015
377181
  const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
377016
377182
  let i = 0;
@@ -377051,13 +377217,13 @@ async function execCommand(serviceName, command, instanceKey = "default", option
377051
377217
  }
377052
377218
  }
377053
377219
  };
377054
- const configPath = path21.join(process.cwd(), "specific.hcl");
377055
- if (!fs23.existsSync(configPath)) {
377220
+ const configPath = path22.join(process.cwd(), "specific.hcl");
377221
+ if (!fs24.existsSync(configPath)) {
377056
377222
  console.error("Error: No specific.hcl found in current directory");
377057
377223
  process.exit(1);
377058
377224
  }
377059
377225
  let config;
377060
- const hcl = fs23.readFileSync(configPath, "utf-8");
377226
+ const hcl = fs24.readFileSync(configPath, "utf-8");
377061
377227
  try {
377062
377228
  config = await parseConfig2(hcl);
377063
377229
  } catch (err) {
@@ -377223,13 +377389,13 @@ async function execCommand(serviceName, command, instanceKey = "default", option
377223
377389
  process.on("SIGTERM", () => handleSignal("SIGTERM"));
377224
377390
  let effectiveCwd = process.cwd();
377225
377391
  if (options2.cwd) {
377226
- effectiveCwd = path21.resolve(process.cwd(), options2.cwd);
377392
+ effectiveCwd = path22.resolve(process.cwd(), options2.cwd);
377227
377393
  } else if (service.root) {
377228
- effectiveCwd = path21.resolve(process.cwd(), service.root);
377394
+ effectiveCwd = path22.resolve(process.cwd(), service.root);
377229
377395
  } else if (service.build) {
377230
377396
  const build = config.builds.find((b) => b.name === service.build.name);
377231
377397
  if (build?.root) {
377232
- effectiveCwd = path21.resolve(process.cwd(), build.root);
377398
+ effectiveCwd = path22.resolve(process.cwd(), build.root);
377233
377399
  }
377234
377400
  }
377235
377401
  spinner?.stop();
@@ -377258,8 +377424,8 @@ async function execCommand(serviceName, command, instanceKey = "default", option
377258
377424
 
377259
377425
  // src/commands/psql.tsx
377260
377426
  import { spawn as spawn8 } from "child_process";
377261
- import * as fs24 from "fs";
377262
- import * as path22 from "path";
377427
+ import * as fs25 from "fs";
377428
+ import * as path23 from "path";
377263
377429
  async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []) {
377264
377430
  let startedResources = [];
377265
377431
  let ownsInstances = false;
@@ -377276,13 +377442,13 @@ async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []
377276
377442
  }
377277
377443
  }
377278
377444
  };
377279
- const configPath = path22.join(process.cwd(), "specific.hcl");
377280
- if (!fs24.existsSync(configPath)) {
377445
+ const configPath = path23.join(process.cwd(), "specific.hcl");
377446
+ if (!fs25.existsSync(configPath)) {
377281
377447
  console.error("Error: No specific.hcl found in current directory");
377282
377448
  process.exit(1);
377283
377449
  }
377284
377450
  let config;
377285
- const hcl = fs24.readFileSync(configPath, "utf-8");
377451
+ const hcl = fs25.readFileSync(configPath, "utf-8");
377286
377452
  try {
377287
377453
  config = await parseConfig2(hcl);
377288
377454
  } catch (err) {
@@ -377407,8 +377573,8 @@ async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []
377407
377573
 
377408
377574
  // src/commands/reshape.tsx
377409
377575
  import { spawn as spawn9 } from "child_process";
377410
- import * as fs25 from "fs";
377411
- import * as path23 from "path";
377576
+ import * as fs26 from "fs";
377577
+ import * as path24 from "path";
377412
377578
  var VALID_ACTIONS = ["start", "complete", "status", "abort", "check"];
377413
377579
  var MIGRATION_SUBCOMMANDS = ["start", "complete", "abort"];
377414
377580
  var OFFLINE_ACTIONS = ["check"];
@@ -377428,13 +377594,13 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
377428
377594
  process.exit(1);
377429
377595
  }
377430
377596
  const isOfflineAction = OFFLINE_ACTIONS.includes(action);
377431
- const configPath = path23.join(process.cwd(), "specific.hcl");
377597
+ const configPath = path24.join(process.cwd(), "specific.hcl");
377432
377598
  let config;
377433
377599
  let migrationsDir = "migrations";
377434
377600
  let targetDb;
377435
377601
  try {
377436
- if (fs25.existsSync(configPath)) {
377437
- const configContent = fs25.readFileSync(configPath, "utf-8");
377602
+ if (fs26.existsSync(configPath)) {
377603
+ const configContent = fs26.readFileSync(configPath, "utf-8");
377438
377604
  config = await parseConfig2(configContent);
377439
377605
  if (databaseName) {
377440
377606
  const postgresConfig = config.postgres.find((p) => p.name === databaseName);
@@ -377569,9 +377735,9 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
377569
377735
  }
377570
377736
  const isMigrationSubcommand = MIGRATION_SUBCOMMANDS.includes(action);
377571
377737
  const reshapeArgs = isMigrationSubcommand ? ["migration", action] : [action];
377572
- const fullMigrationsPath = path23.join(process.cwd(), migrationsDir);
377738
+ const fullMigrationsPath = path24.join(process.cwd(), migrationsDir);
377573
377739
  if (action === "check" || action === "start") {
377574
- if (fs25.existsSync(fullMigrationsPath)) {
377740
+ if (fs26.existsSync(fullMigrationsPath)) {
377575
377741
  reshapeArgs.push("--dirs", fullMigrationsPath);
377576
377742
  } else if (action === "check") {
377577
377743
  console.error(`Error: Migrations directory not found: ${fullMigrationsPath}`);
@@ -377621,21 +377787,21 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
377621
377787
  import React8, { useState as useState7, useEffect as useEffect7 } from "react";
377622
377788
  import { render as render6, Text as Text8, Box as Box8 } from "ink";
377623
377789
  import Spinner5 from "ink-spinner";
377624
- import * as fs26 from "fs";
377625
- import * as path24 from "path";
377790
+ import * as fs27 from "fs";
377791
+ import * as path25 from "path";
377626
377792
  function CleanUI({ instanceKey }) {
377627
377793
  const [state, setState] = useState7({ status: "checking" });
377628
377794
  useEffect7(() => {
377629
377795
  async function clean() {
377630
377796
  const projectRoot = process.cwd();
377631
- const specificDir = path24.join(projectRoot, ".specific");
377632
- if (!fs26.existsSync(specificDir)) {
377797
+ const specificDir = path25.join(projectRoot, ".specific");
377798
+ if (!fs27.existsSync(specificDir)) {
377633
377799
  setState({ status: "nothing" });
377634
377800
  return;
377635
377801
  }
377636
377802
  if (instanceKey) {
377637
- const keyDir = path24.join(specificDir, "keys", instanceKey);
377638
- if (!fs26.existsSync(keyDir)) {
377803
+ const keyDir = path25.join(specificDir, "keys", instanceKey);
377804
+ if (!fs27.existsSync(keyDir)) {
377639
377805
  setState({ status: "nothing" });
377640
377806
  return;
377641
377807
  }
@@ -377651,7 +377817,7 @@ function CleanUI({ instanceKey }) {
377651
377817
  await stateManager.cleanStaleState();
377652
377818
  setState({ status: "cleaning" });
377653
377819
  try {
377654
- fs26.rmSync(keyDir, { recursive: true, force: true });
377820
+ fs27.rmSync(keyDir, { recursive: true, force: true });
377655
377821
  setState({ status: "success" });
377656
377822
  } catch (err) {
377657
377823
  setState({
@@ -377660,13 +377826,13 @@ function CleanUI({ instanceKey }) {
377660
377826
  });
377661
377827
  }
377662
377828
  } else {
377663
- const keysDir = path24.join(specificDir, "keys");
377664
- if (!fs26.existsSync(keysDir)) {
377829
+ const keysDir = path25.join(specificDir, "keys");
377830
+ if (!fs27.existsSync(keysDir)) {
377665
377831
  setState({ status: "nothing" });
377666
377832
  return;
377667
377833
  }
377668
- const keys = fs26.readdirSync(keysDir).filter(
377669
- (f) => fs26.statSync(path24.join(keysDir, f)).isDirectory()
377834
+ const keys = fs27.readdirSync(keysDir).filter(
377835
+ (f) => fs27.statSync(path25.join(keysDir, f)).isDirectory()
377670
377836
  );
377671
377837
  for (const key of keys) {
377672
377838
  const stateManager2 = new InstanceStateManager(projectRoot, key);
@@ -377690,7 +377856,7 @@ function CleanUI({ instanceKey }) {
377690
377856
  }
377691
377857
  setState({ status: "cleaning" });
377692
377858
  try {
377693
- fs26.rmSync(keysDir, { recursive: true, force: true });
377859
+ fs27.rmSync(keysDir, { recursive: true, force: true });
377694
377860
  setState({ status: "success" });
377695
377861
  } catch (err) {
377696
377862
  setState({
@@ -377869,8 +378035,8 @@ import { render as render9, Text as Text11, Box as Box10, useApp as useApp6 } fr
377869
378035
  import Spinner6 from "ink-spinner";
377870
378036
 
377871
378037
  // src/lib/update.ts
377872
- import * as fs27 from "fs";
377873
- import * as path25 from "path";
378038
+ import * as fs28 from "fs";
378039
+ import * as path26 from "path";
377874
378040
  var BINARIES_BASE_URL = "https://binaries.specific.dev/cli";
377875
378041
  function compareVersions(a, b) {
377876
378042
  const partsA = a.split(".").map(Number);
@@ -377884,7 +378050,7 @@ function compareVersions(a, b) {
377884
378050
  return 0;
377885
378051
  }
377886
378052
  async function checkForUpdate() {
377887
- const currentVersion = "0.1.140";
378053
+ const currentVersion = "0.1.142";
377888
378054
  const response = await fetch(`${BINARIES_BASE_URL}/latest?t=${Date.now()}`);
377889
378055
  if (!response.ok) {
377890
378056
  throw new Error(`Failed to check for updates: HTTP ${response.status}`);
@@ -377898,9 +378064,9 @@ function getCurrentBinaryPath() {
377898
378064
  }
377899
378065
  function isBinaryWritable() {
377900
378066
  const binaryPath = getCurrentBinaryPath();
377901
- const dir = path25.dirname(binaryPath);
378067
+ const dir = path26.dirname(binaryPath);
377902
378068
  try {
377903
- fs27.accessSync(dir, fs27.constants.W_OK);
378069
+ fs28.accessSync(dir, fs28.constants.W_OK);
377904
378070
  return true;
377905
378071
  } catch {
377906
378072
  return false;
@@ -377908,24 +378074,24 @@ function isBinaryWritable() {
377908
378074
  }
377909
378075
  async function performUpdate(version, onProgress) {
377910
378076
  const binaryPath = getCurrentBinaryPath();
377911
- const binaryDir = path25.dirname(binaryPath);
377912
- const tempPath = path25.join(binaryDir, `.specific-update-${process.pid}`);
378077
+ const binaryDir = path26.dirname(binaryPath);
378078
+ const tempPath = path26.join(binaryDir, `.specific-update-${process.pid}`);
377913
378079
  try {
377914
378080
  const { platform: platform3, arch: arch3 } = getPlatformInfo();
377915
378081
  const url = `${BINARIES_BASE_URL}/${version}/specific-${platform3}-${arch3}`;
377916
378082
  await downloadFile(url, tempPath, onProgress);
377917
- const stat4 = fs27.statSync(tempPath);
378083
+ const stat4 = fs28.statSync(tempPath);
377918
378084
  if (stat4.size === 0) {
377919
378085
  throw new Error("Downloaded binary is empty");
377920
378086
  }
377921
- fs27.chmodSync(tempPath, 493);
378087
+ fs28.chmodSync(tempPath, 493);
377922
378088
  onProgress?.({ phase: "finalizing" });
377923
- fs27.unlinkSync(binaryPath);
377924
- fs27.renameSync(tempPath, binaryPath);
378089
+ fs28.unlinkSync(binaryPath);
378090
+ fs28.renameSync(tempPath, binaryPath);
377925
378091
  } catch (error) {
377926
378092
  try {
377927
- if (fs27.existsSync(tempPath)) {
377928
- fs27.unlinkSync(tempPath);
378093
+ if (fs28.existsSync(tempPath)) {
378094
+ fs28.unlinkSync(tempPath);
377929
378095
  }
377930
378096
  } catch {
377931
378097
  }
@@ -377935,21 +378101,21 @@ async function performUpdate(version, onProgress) {
377935
378101
 
377936
378102
  // src/lib/background-update.ts
377937
378103
  import { spawn as spawn10 } from "child_process";
377938
- import * as fs28 from "fs";
377939
- import * as path26 from "path";
378104
+ import * as fs29 from "fs";
378105
+ import * as path27 from "path";
377940
378106
  import * as os6 from "os";
377941
- var SPECIFIC_DIR = path26.join(os6.homedir(), ".specific");
377942
- var RATE_LIMIT_FILE = path26.join(SPECIFIC_DIR, "last-update-check");
377943
- var LOCK_FILE = path26.join(SPECIFIC_DIR, "update.lock");
378107
+ var SPECIFIC_DIR = path27.join(os6.homedir(), ".specific");
378108
+ var RATE_LIMIT_FILE = path27.join(SPECIFIC_DIR, "last-update-check");
378109
+ var LOCK_FILE = path27.join(SPECIFIC_DIR, "update.lock");
377944
378110
  var RATE_LIMIT_MS = 60 * 60 * 1e3;
377945
378111
  var STALE_LOCK_MS = 10 * 60 * 1e3;
377946
378112
  function writeCheckTimestamp() {
377947
- fs28.mkdirSync(SPECIFIC_DIR, { recursive: true });
377948
- fs28.writeFileSync(RATE_LIMIT_FILE, String(Date.now()), "utf-8");
378113
+ fs29.mkdirSync(SPECIFIC_DIR, { recursive: true });
378114
+ fs29.writeFileSync(RATE_LIMIT_FILE, String(Date.now()), "utf-8");
377949
378115
  }
377950
378116
  function isRateLimited() {
377951
378117
  try {
377952
- const content = fs28.readFileSync(RATE_LIMIT_FILE, "utf-8").trim();
378118
+ const content = fs29.readFileSync(RATE_LIMIT_FILE, "utf-8").trim();
377953
378119
  const lastCheck = parseInt(content, 10);
377954
378120
  if (isNaN(lastCheck)) return false;
377955
378121
  return Date.now() - lastCheck < RATE_LIMIT_MS;
@@ -378351,11 +378517,11 @@ async function resolveSql(arg) {
378351
378517
  return await readStdin();
378352
378518
  }
378353
378519
  async function readStdin() {
378354
- return new Promise((resolve9, reject) => {
378520
+ return new Promise((resolve10, reject) => {
378355
378521
  let data = "";
378356
378522
  process.stdin.setEncoding("utf-8");
378357
378523
  process.stdin.on("data", (chunk) => data += chunk);
378358
- process.stdin.on("end", () => resolve9(data.trim()));
378524
+ process.stdin.on("end", () => resolve10(data.trim()));
378359
378525
  process.stdin.on("error", reject);
378360
378526
  });
378361
378527
  }
@@ -378399,7 +378565,7 @@ function friendlyErrorMessage(raw) {
378399
378565
  var program = new Command();
378400
378566
  var env = "production";
378401
378567
  var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
378402
- program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.140").enablePositionalOptions();
378568
+ program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.142").enablePositionalOptions();
378403
378569
  program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").addHelpText("after", `
378404
378570
  Examples:
378405
378571
  $ specific init