@specific.dev/cli 0.1.65 → 0.1.67

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 (59) hide show
  1. package/dist/admin/404/index.html +1 -1
  2. package/dist/admin/404.html +1 -1
  3. package/dist/admin/__next.!KGRlZmF1bHQp.__PAGE__.txt +1 -1
  4. package/dist/admin/__next.!KGRlZmF1bHQp.txt +1 -1
  5. package/dist/admin/__next._full.txt +1 -1
  6. package/dist/admin/__next._head.txt +1 -1
  7. package/dist/admin/__next._index.txt +1 -1
  8. package/dist/admin/__next._tree.txt +1 -1
  9. package/dist/admin/_not-found/__next._full.txt +1 -1
  10. package/dist/admin/_not-found/__next._head.txt +1 -1
  11. package/dist/admin/_not-found/__next._index.txt +1 -1
  12. package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
  13. package/dist/admin/_not-found/__next._not-found.txt +1 -1
  14. package/dist/admin/_not-found/__next._tree.txt +1 -1
  15. package/dist/admin/_not-found/index.html +1 -1
  16. package/dist/admin/_not-found/index.txt +1 -1
  17. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +1 -1
  18. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +1 -1
  19. package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +1 -1
  20. package/dist/admin/databases/__next._full.txt +1 -1
  21. package/dist/admin/databases/__next._head.txt +1 -1
  22. package/dist/admin/databases/__next._index.txt +1 -1
  23. package/dist/admin/databases/__next._tree.txt +1 -1
  24. package/dist/admin/databases/index.html +1 -1
  25. package/dist/admin/databases/index.txt +1 -1
  26. package/dist/admin/fullscreen/__next._full.txt +1 -1
  27. package/dist/admin/fullscreen/__next._head.txt +1 -1
  28. package/dist/admin/fullscreen/__next._index.txt +1 -1
  29. package/dist/admin/fullscreen/__next._tree.txt +1 -1
  30. package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +1 -1
  31. package/dist/admin/fullscreen/__next.fullscreen.txt +1 -1
  32. package/dist/admin/fullscreen/databases/__next._full.txt +1 -1
  33. package/dist/admin/fullscreen/databases/__next._head.txt +1 -1
  34. package/dist/admin/fullscreen/databases/__next._index.txt +1 -1
  35. package/dist/admin/fullscreen/databases/__next._tree.txt +1 -1
  36. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +1 -1
  37. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +1 -1
  38. package/dist/admin/fullscreen/databases/__next.fullscreen.txt +1 -1
  39. package/dist/admin/fullscreen/databases/index.html +1 -1
  40. package/dist/admin/fullscreen/databases/index.txt +1 -1
  41. package/dist/admin/fullscreen/index.html +1 -1
  42. package/dist/admin/fullscreen/index.txt +1 -1
  43. package/dist/admin/index.html +1 -1
  44. package/dist/admin/index.txt +1 -1
  45. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +1 -1
  46. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +1 -1
  47. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +1 -1
  48. package/dist/admin/workflows/__next._full.txt +1 -1
  49. package/dist/admin/workflows/__next._head.txt +1 -1
  50. package/dist/admin/workflows/__next._index.txt +1 -1
  51. package/dist/admin/workflows/__next._tree.txt +1 -1
  52. package/dist/admin/workflows/index.html +1 -1
  53. package/dist/admin/workflows/index.txt +1 -1
  54. package/dist/cli.js +465 -191
  55. package/dist/postinstall.js +1 -1
  56. package/package.json +3 -2
  57. /package/dist/admin/_next/static/{yyxVnsTY9PirjGB7e7H6f → B_l0oWRS4jgPRx3kI3HDj}/_buildManifest.js +0 -0
  58. /package/dist/admin/_next/static/{yyxVnsTY9PirjGB7e7H6f → B_l0oWRS4jgPRx3kI3HDj}/_clientMiddlewareManifest.json +0 -0
  59. /package/dist/admin/_next/static/{yyxVnsTY9PirjGB7e7H6f → B_l0oWRS4jgPRx3kI3HDj}/_ssgManifest.js +0 -0
package/dist/cli.js CHANGED
@@ -238,15 +238,15 @@ var init_wsl_utils = __esm({
238
238
  const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
239
239
  return stdout.trim();
240
240
  };
241
- convertWslPathToWindows = async (path28) => {
242
- if (/^[a-z]+:\/\//i.test(path28)) {
243
- return path28;
241
+ convertWslPathToWindows = async (path30) => {
242
+ if (/^[a-z]+:\/\//i.test(path30)) {
243
+ return path30;
244
244
  }
245
245
  try {
246
- const { stdout } = await execFile2("wslpath", ["-aw", path28], { encoding: "utf8" });
246
+ const { stdout } = await execFile2("wslpath", ["-aw", path30], { encoding: "utf8" });
247
247
  return stdout.trim();
248
248
  } catch {
249
- return path28;
249
+ return path30;
250
250
  }
251
251
  };
252
252
  }
@@ -754,8 +754,8 @@ var require_dist = __commonJS({
754
754
  var $global, $module, $NaN = NaN;
755
755
  if ("undefined" != typeof window ? $global = window : "undefined" != typeof self ? $global = self : "undefined" != typeof global ? ($global = global).require = __require : $global = this, void 0 === $global || void 0 === $global.Array) throw new Error("no global object found");
756
756
  if ("undefined" != typeof module && ($module = module), !$global.fs && $global.require) try {
757
- var fs30 = $global.require("fs");
758
- "object" == typeof fs30 && null !== fs30 && 0 !== Object.keys(fs30).length && ($global.fs = fs30);
757
+ var fs32 = $global.require("fs");
758
+ "object" == typeof fs32 && null !== fs32 && 0 !== Object.keys(fs32).length && ($global.fs = fs32);
759
759
  } catch (e) {
760
760
  }
761
761
  if (!$global.fs) {
@@ -183423,7 +183423,7 @@ ${frame}`;
183423
183423
  }
183424
183424
  });
183425
183425
 
183426
- // src/cli.tsx
183426
+ // src/cli-program.tsx
183427
183427
  import { Command } from "commander";
183428
183428
 
183429
183429
  // src/commands/init.tsx
@@ -183909,15 +183909,16 @@ import Spinner from "ink-spinner";
183909
183909
  // src/lib/api/client.ts
183910
183910
  var ApiClient = class {
183911
183911
  baseUrl;
183912
- token;
183913
- constructor(token, baseUrl) {
183914
- this.token = token;
183915
- this.baseUrl = baseUrl || "https://api.prod.specific.dev";
183912
+ staticToken;
183913
+ constructor(options2) {
183914
+ this.staticToken = options2?.token;
183915
+ this.baseUrl = options2?.baseUrl || "https://api.prod.specific.dev";
183916
183916
  writeLog("api", `API client initialized with base URL: ${this.baseUrl}`);
183917
183917
  }
183918
- authHeaders() {
183918
+ async authHeaders() {
183919
+ const token = this.staticToken ?? await getValidAccessToken();
183919
183920
  return {
183920
- Authorization: `Bearer ${this.token}`
183921
+ Authorization: `Bearer ${token}`
183921
183922
  };
183922
183923
  }
183923
183924
  async createDeployment(projectId, environment) {
@@ -183928,7 +183929,7 @@ var ApiClient = class {
183928
183929
  method: "POST",
183929
183930
  headers: {
183930
183931
  "Content-Type": "application/json",
183931
- ...this.authHeaders()
183932
+ ...await this.authHeaders()
183932
183933
  },
183933
183934
  body: JSON.stringify(requestBody)
183934
183935
  });
@@ -183964,7 +183965,7 @@ var ApiClient = class {
183964
183965
  headers: {
183965
183966
  "Content-Type": "application/octet-stream",
183966
183967
  "X-App-Path": appPath,
183967
- ...this.authHeaders()
183968
+ ...await this.authHeaders()
183968
183969
  },
183969
183970
  body: new Uint8Array(tarball)
183970
183971
  });
@@ -183995,7 +183996,7 @@ var ApiClient = class {
183995
183996
  const url = `${this.baseUrl}/deployments/${deploymentId}`;
183996
183997
  writeLog("api", `GET ${url}`);
183997
183998
  const response = await fetch(url, {
183998
- headers: this.authHeaders()
183999
+ headers: await this.authHeaders()
183999
184000
  });
184000
184001
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
184001
184002
  if (!response.ok) {
@@ -184025,7 +184026,7 @@ var ApiClient = class {
184025
184026
  writeLog("api", `POST ${url}`);
184026
184027
  const response = await fetch(url, {
184027
184028
  method: "POST",
184028
- headers: this.authHeaders()
184029
+ headers: await this.authHeaders()
184029
184030
  });
184030
184031
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
184031
184032
  if (!response.ok) {
@@ -184058,7 +184059,7 @@ var ApiClient = class {
184058
184059
  method: "PUT",
184059
184060
  headers: {
184060
184061
  "Content-Type": "application/json",
184061
- ...this.authHeaders()
184062
+ ...await this.authHeaders()
184062
184063
  },
184063
184064
  body: JSON.stringify({ secrets })
184064
184065
  });
@@ -184094,7 +184095,7 @@ var ApiClient = class {
184094
184095
  method: "PUT",
184095
184096
  headers: {
184096
184097
  "Content-Type": "application/json",
184097
- ...this.authHeaders()
184098
+ ...await this.authHeaders()
184098
184099
  },
184099
184100
  body: JSON.stringify({ configs })
184100
184101
  });
@@ -184126,7 +184127,7 @@ var ApiClient = class {
184126
184127
  const url = `${this.baseUrl}/user/projects`;
184127
184128
  writeLog("api", `GET ${url}`);
184128
184129
  const response = await fetch(url, {
184129
- headers: this.authHeaders()
184130
+ headers: await this.authHeaders()
184130
184131
  });
184131
184132
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
184132
184133
  if (!response.ok) {
@@ -184158,7 +184159,7 @@ var ApiClient = class {
184158
184159
  method: "POST",
184159
184160
  headers: {
184160
184161
  "Content-Type": "application/json",
184161
- ...this.authHeaders()
184162
+ ...await this.authHeaders()
184162
184163
  },
184163
184164
  body: JSON.stringify(requestBody)
184164
184165
  });
@@ -184190,7 +184191,7 @@ var ApiClient = class {
184190
184191
  const url = `${this.baseUrl}/users/me`;
184191
184192
  writeLog("api", `GET ${url}`);
184192
184193
  const response = await fetch(url, {
184193
- headers: this.authHeaders(),
184194
+ headers: await this.authHeaders(),
184194
184195
  ...signal ? { signal } : {}
184195
184196
  });
184196
184197
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
@@ -184244,7 +184245,7 @@ function runLoginFlow(options2) {
184244
184245
  const token = await pollUntilToken(deviceAuth, () => cancelled);
184245
184246
  if (cancelled || !token) return;
184246
184247
  writeLog("auth", "Fetching user info from platform API...");
184247
- const client2 = new ApiClient(token.access_token);
184248
+ const client2 = new ApiClient({ token: token.access_token });
184248
184249
  const user = await client2.getMe();
184249
184250
  writeLog("auth", `User info received: id=${user.id}`);
184250
184251
  if (cancelled) return;
@@ -184495,7 +184496,7 @@ function trackEvent(event, properties) {
184495
184496
  event,
184496
184497
  properties: {
184497
184498
  ...properties,
184498
- cli_version: "0.1.65",
184499
+ cli_version: "0.1.67",
184499
184500
  platform: process.platform,
184500
184501
  node_version: process.version,
184501
184502
  project_id: getProjectId(),
@@ -184913,20 +184914,20 @@ function saveBetas(enabled, projectDir) {
184913
184914
  // src/commands/docs.tsx
184914
184915
  var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
184915
184916
  var docsDir = join8(__dirname2, "docs");
184916
- function docsCommand(path28) {
184917
- const docPath = resolveDocPath(path28);
184918
- if (!docPath) {
184917
+ var _embeddedDocs = null;
184918
+ function docsCommand(path30) {
184919
+ const content = resolveDocContent(path30);
184920
+ if (!content) {
184919
184921
  console.error(
184920
- `Documentation not found: ${path28 || "index"}
184922
+ `Documentation not found: ${path30 || "index"}
184921
184923
 
184922
184924
  Run 'specific docs' to see available topics.`
184923
184925
  );
184924
184926
  process.exit(1);
184925
184927
  }
184926
184928
  const enabledBetas = new Set(loadEnabledBetas());
184927
- let content = readFileSync6(docPath, "utf-8");
184928
- content = filterBetaTags(content, enabledBetas);
184929
- console.log(content);
184929
+ const filtered = filterBetaTags(content, enabledBetas);
184930
+ console.log(filtered);
184930
184931
  }
184931
184932
  function filterBetaTags(content, enabledBetas) {
184932
184933
  return content.replace(
@@ -184936,18 +184937,32 @@ function filterBetaTags(content, enabledBetas) {
184936
184937
  }
184937
184938
  );
184938
184939
  }
184939
- function resolveDocPath(path28) {
184940
- if (!path28) {
184940
+ function resolveDocContent(path30) {
184941
+ if (_embeddedDocs) {
184942
+ return resolveEmbeddedDoc(path30);
184943
+ }
184944
+ return resolveFilesystemDoc(path30);
184945
+ }
184946
+ function resolveEmbeddedDoc(path30) {
184947
+ if (!path30) {
184948
+ return _embeddedDocs.get("index.md") ?? null;
184949
+ }
184950
+ const direct = _embeddedDocs.get(`${path30}.md`);
184951
+ if (direct) return direct;
184952
+ return _embeddedDocs.get(`${path30}/index.md`) ?? null;
184953
+ }
184954
+ function resolveFilesystemDoc(path30) {
184955
+ if (!path30) {
184941
184956
  const indexPath2 = join8(docsDir, "index.md");
184942
- return existsSync7(indexPath2) ? indexPath2 : null;
184957
+ return existsSync7(indexPath2) ? readFileSync6(indexPath2, "utf-8") : null;
184943
184958
  }
184944
- const directPath = join8(docsDir, `${path28}.md`);
184959
+ const directPath = join8(docsDir, `${path30}.md`);
184945
184960
  if (existsSync7(directPath)) {
184946
- return directPath;
184961
+ return readFileSync6(directPath, "utf-8");
184947
184962
  }
184948
- const indexPath = join8(docsDir, path28, "index.md");
184963
+ const indexPath = join8(docsDir, path30, "index.md");
184949
184964
  if (existsSync7(indexPath)) {
184950
- return indexPath;
184965
+ return readFileSync6(indexPath, "utf-8");
184951
184966
  }
184952
184967
  return null;
184953
184968
  }
@@ -186332,7 +186347,7 @@ var ReaddirpStream = class extends Readable {
186332
186347
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
186333
186348
  const statMethod = opts.lstat ? lstat : stat;
186334
186349
  if (wantBigintFsStats) {
186335
- this._stat = (path28) => statMethod(path28, { bigint: true });
186350
+ this._stat = (path30) => statMethod(path30, { bigint: true });
186336
186351
  } else {
186337
186352
  this._stat = statMethod;
186338
186353
  }
@@ -186357,8 +186372,8 @@ var ReaddirpStream = class extends Readable {
186357
186372
  const par = this.parent;
186358
186373
  const fil = par && par.files;
186359
186374
  if (fil && fil.length > 0) {
186360
- const { path: path28, depth } = par;
186361
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path28));
186375
+ const { path: path30, depth } = par;
186376
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path30));
186362
186377
  const awaited = await Promise.all(slice);
186363
186378
  for (const entry of awaited) {
186364
186379
  if (!entry)
@@ -186398,20 +186413,20 @@ var ReaddirpStream = class extends Readable {
186398
186413
  this.reading = false;
186399
186414
  }
186400
186415
  }
186401
- async _exploreDir(path28, depth) {
186416
+ async _exploreDir(path30, depth) {
186402
186417
  let files;
186403
186418
  try {
186404
- files = await readdir(path28, this._rdOptions);
186419
+ files = await readdir(path30, this._rdOptions);
186405
186420
  } catch (error) {
186406
186421
  this._onError(error);
186407
186422
  }
186408
- return { files, depth, path: path28 };
186423
+ return { files, depth, path: path30 };
186409
186424
  }
186410
- async _formatEntry(dirent, path28) {
186425
+ async _formatEntry(dirent, path30) {
186411
186426
  let entry;
186412
186427
  const basename6 = this._isDirent ? dirent.name : dirent;
186413
186428
  try {
186414
- const fullPath = presolve(pjoin(path28, basename6));
186429
+ const fullPath = presolve(pjoin(path30, basename6));
186415
186430
  entry = { path: prelative(this._root, fullPath), fullPath, basename: basename6 };
186416
186431
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
186417
186432
  } catch (err) {
@@ -186811,16 +186826,16 @@ var delFromSet = (main, prop, item) => {
186811
186826
  };
186812
186827
  var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
186813
186828
  var FsWatchInstances = /* @__PURE__ */ new Map();
186814
- function createFsWatchInstance(path28, options2, listener, errHandler, emitRaw) {
186829
+ function createFsWatchInstance(path30, options2, listener, errHandler, emitRaw) {
186815
186830
  const handleEvent = (rawEvent, evPath) => {
186816
- listener(path28);
186817
- emitRaw(rawEvent, evPath, { watchedPath: path28 });
186818
- if (evPath && path28 !== evPath) {
186819
- fsWatchBroadcast(sp.resolve(path28, evPath), KEY_LISTENERS, sp.join(path28, evPath));
186831
+ listener(path30);
186832
+ emitRaw(rawEvent, evPath, { watchedPath: path30 });
186833
+ if (evPath && path30 !== evPath) {
186834
+ fsWatchBroadcast(sp.resolve(path30, evPath), KEY_LISTENERS, sp.join(path30, evPath));
186820
186835
  }
186821
186836
  };
186822
186837
  try {
186823
- return fs_watch(path28, {
186838
+ return fs_watch(path30, {
186824
186839
  persistent: options2.persistent
186825
186840
  }, handleEvent);
186826
186841
  } catch (error) {
@@ -186836,12 +186851,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
186836
186851
  listener(val1, val2, val3);
186837
186852
  });
186838
186853
  };
186839
- var setFsWatchListener = (path28, fullPath, options2, handlers) => {
186854
+ var setFsWatchListener = (path30, fullPath, options2, handlers) => {
186840
186855
  const { listener, errHandler, rawEmitter } = handlers;
186841
186856
  let cont = FsWatchInstances.get(fullPath);
186842
186857
  let watcher;
186843
186858
  if (!options2.persistent) {
186844
- watcher = createFsWatchInstance(path28, options2, listener, errHandler, rawEmitter);
186859
+ watcher = createFsWatchInstance(path30, options2, listener, errHandler, rawEmitter);
186845
186860
  if (!watcher)
186846
186861
  return;
186847
186862
  return watcher.close.bind(watcher);
@@ -186852,7 +186867,7 @@ var setFsWatchListener = (path28, fullPath, options2, handlers) => {
186852
186867
  addAndConvert(cont, KEY_RAW, rawEmitter);
186853
186868
  } else {
186854
186869
  watcher = createFsWatchInstance(
186855
- path28,
186870
+ path30,
186856
186871
  options2,
186857
186872
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
186858
186873
  errHandler,
@@ -186867,7 +186882,7 @@ var setFsWatchListener = (path28, fullPath, options2, handlers) => {
186867
186882
  cont.watcherUnusable = true;
186868
186883
  if (isWindows && error.code === "EPERM") {
186869
186884
  try {
186870
- const fd = await open2(path28, "r");
186885
+ const fd = await open2(path30, "r");
186871
186886
  await fd.close();
186872
186887
  broadcastErr(error);
186873
186888
  } catch (err) {
@@ -186898,7 +186913,7 @@ var setFsWatchListener = (path28, fullPath, options2, handlers) => {
186898
186913
  };
186899
186914
  };
186900
186915
  var FsWatchFileInstances = /* @__PURE__ */ new Map();
186901
- var setFsWatchFileListener = (path28, fullPath, options2, handlers) => {
186916
+ var setFsWatchFileListener = (path30, fullPath, options2, handlers) => {
186902
186917
  const { listener, rawEmitter } = handlers;
186903
186918
  let cont = FsWatchFileInstances.get(fullPath);
186904
186919
  const copts = cont && cont.options;
@@ -186920,7 +186935,7 @@ var setFsWatchFileListener = (path28, fullPath, options2, handlers) => {
186920
186935
  });
186921
186936
  const currmtime = curr.mtimeMs;
186922
186937
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
186923
- foreach(cont.listeners, (listener2) => listener2(path28, curr));
186938
+ foreach(cont.listeners, (listener2) => listener2(path30, curr));
186924
186939
  }
186925
186940
  })
186926
186941
  };
@@ -186950,13 +186965,13 @@ var NodeFsHandler = class {
186950
186965
  * @param listener on fs change
186951
186966
  * @returns closer for the watcher instance
186952
186967
  */
186953
- _watchWithNodeFs(path28, listener) {
186968
+ _watchWithNodeFs(path30, listener) {
186954
186969
  const opts = this.fsw.options;
186955
- const directory = sp.dirname(path28);
186956
- const basename6 = sp.basename(path28);
186970
+ const directory = sp.dirname(path30);
186971
+ const basename6 = sp.basename(path30);
186957
186972
  const parent = this.fsw._getWatchedDir(directory);
186958
186973
  parent.add(basename6);
186959
- const absolutePath = sp.resolve(path28);
186974
+ const absolutePath = sp.resolve(path30);
186960
186975
  const options2 = {
186961
186976
  persistent: opts.persistent
186962
186977
  };
@@ -186966,12 +186981,12 @@ var NodeFsHandler = class {
186966
186981
  if (opts.usePolling) {
186967
186982
  const enableBin = opts.interval !== opts.binaryInterval;
186968
186983
  options2.interval = enableBin && isBinaryPath(basename6) ? opts.binaryInterval : opts.interval;
186969
- closer = setFsWatchFileListener(path28, absolutePath, options2, {
186984
+ closer = setFsWatchFileListener(path30, absolutePath, options2, {
186970
186985
  listener,
186971
186986
  rawEmitter: this.fsw._emitRaw
186972
186987
  });
186973
186988
  } else {
186974
- closer = setFsWatchListener(path28, absolutePath, options2, {
186989
+ closer = setFsWatchListener(path30, absolutePath, options2, {
186975
186990
  listener,
186976
186991
  errHandler: this._boundHandleError,
186977
186992
  rawEmitter: this.fsw._emitRaw
@@ -186987,13 +187002,13 @@ var NodeFsHandler = class {
186987
187002
  if (this.fsw.closed) {
186988
187003
  return;
186989
187004
  }
186990
- const dirname9 = sp.dirname(file);
187005
+ const dirname10 = sp.dirname(file);
186991
187006
  const basename6 = sp.basename(file);
186992
- const parent = this.fsw._getWatchedDir(dirname9);
187007
+ const parent = this.fsw._getWatchedDir(dirname10);
186993
187008
  let prevStats = stats;
186994
187009
  if (parent.has(basename6))
186995
187010
  return;
186996
- const listener = async (path28, newStats) => {
187011
+ const listener = async (path30, newStats) => {
186997
187012
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
186998
187013
  return;
186999
187014
  if (!newStats || newStats.mtimeMs === 0) {
@@ -187007,16 +187022,16 @@ var NodeFsHandler = class {
187007
187022
  this.fsw._emit(EV.CHANGE, file, newStats2);
187008
187023
  }
187009
187024
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
187010
- this.fsw._closeFile(path28);
187025
+ this.fsw._closeFile(path30);
187011
187026
  prevStats = newStats2;
187012
187027
  const closer2 = this._watchWithNodeFs(file, listener);
187013
187028
  if (closer2)
187014
- this.fsw._addPathCloser(path28, closer2);
187029
+ this.fsw._addPathCloser(path30, closer2);
187015
187030
  } else {
187016
187031
  prevStats = newStats2;
187017
187032
  }
187018
187033
  } catch (error) {
187019
- this.fsw._remove(dirname9, basename6);
187034
+ this.fsw._remove(dirname10, basename6);
187020
187035
  }
187021
187036
  } else if (parent.has(basename6)) {
187022
187037
  const at = newStats.atimeMs;
@@ -187043,7 +187058,7 @@ var NodeFsHandler = class {
187043
187058
  * @param item basename of this item
187044
187059
  * @returns true if no more processing is needed for this entry.
187045
187060
  */
187046
- async _handleSymlink(entry, directory, path28, item) {
187061
+ async _handleSymlink(entry, directory, path30, item) {
187047
187062
  if (this.fsw.closed) {
187048
187063
  return;
187049
187064
  }
@@ -187053,7 +187068,7 @@ var NodeFsHandler = class {
187053
187068
  this.fsw._incrReadyCount();
187054
187069
  let linkPath;
187055
187070
  try {
187056
- linkPath = await fsrealpath(path28);
187071
+ linkPath = await fsrealpath(path30);
187057
187072
  } catch (e) {
187058
187073
  this.fsw._emitReady();
187059
187074
  return true;
@@ -187063,12 +187078,12 @@ var NodeFsHandler = class {
187063
187078
  if (dir.has(item)) {
187064
187079
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
187065
187080
  this.fsw._symlinkPaths.set(full, linkPath);
187066
- this.fsw._emit(EV.CHANGE, path28, entry.stats);
187081
+ this.fsw._emit(EV.CHANGE, path30, entry.stats);
187067
187082
  }
187068
187083
  } else {
187069
187084
  dir.add(item);
187070
187085
  this.fsw._symlinkPaths.set(full, linkPath);
187071
- this.fsw._emit(EV.ADD, path28, entry.stats);
187086
+ this.fsw._emit(EV.ADD, path30, entry.stats);
187072
187087
  }
187073
187088
  this.fsw._emitReady();
187074
187089
  return true;
@@ -187098,9 +187113,9 @@ var NodeFsHandler = class {
187098
187113
  return;
187099
187114
  }
187100
187115
  const item = entry.path;
187101
- let path28 = sp.join(directory, item);
187116
+ let path30 = sp.join(directory, item);
187102
187117
  current.add(item);
187103
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path28, item)) {
187118
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path30, item)) {
187104
187119
  return;
187105
187120
  }
187106
187121
  if (this.fsw.closed) {
@@ -187109,8 +187124,8 @@ var NodeFsHandler = class {
187109
187124
  }
187110
187125
  if (item === target || !target && !previous.has(item)) {
187111
187126
  this.fsw._incrReadyCount();
187112
- path28 = sp.join(dir, sp.relative(dir, path28));
187113
- this._addToNodeFs(path28, initialAdd, wh, depth + 1);
187127
+ path30 = sp.join(dir, sp.relative(dir, path30));
187128
+ this._addToNodeFs(path30, initialAdd, wh, depth + 1);
187114
187129
  }
187115
187130
  }).on(EV.ERROR, this._boundHandleError);
187116
187131
  return new Promise((resolve10, reject) => {
@@ -187179,13 +187194,13 @@ var NodeFsHandler = class {
187179
187194
  * @param depth Child path actually targeted for watch
187180
187195
  * @param target Child path actually targeted for watch
187181
187196
  */
187182
- async _addToNodeFs(path28, initialAdd, priorWh, depth, target) {
187197
+ async _addToNodeFs(path30, initialAdd, priorWh, depth, target) {
187183
187198
  const ready = this.fsw._emitReady;
187184
- if (this.fsw._isIgnored(path28) || this.fsw.closed) {
187199
+ if (this.fsw._isIgnored(path30) || this.fsw.closed) {
187185
187200
  ready();
187186
187201
  return false;
187187
187202
  }
187188
- const wh = this.fsw._getWatchHelpers(path28);
187203
+ const wh = this.fsw._getWatchHelpers(path30);
187189
187204
  if (priorWh) {
187190
187205
  wh.filterPath = (entry) => priorWh.filterPath(entry);
187191
187206
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -187201,8 +187216,8 @@ var NodeFsHandler = class {
187201
187216
  const follow = this.fsw.options.followSymlinks;
187202
187217
  let closer;
187203
187218
  if (stats.isDirectory()) {
187204
- const absPath = sp.resolve(path28);
187205
- const targetPath = follow ? await fsrealpath(path28) : path28;
187219
+ const absPath = sp.resolve(path30);
187220
+ const targetPath = follow ? await fsrealpath(path30) : path30;
187206
187221
  if (this.fsw.closed)
187207
187222
  return;
187208
187223
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -187212,29 +187227,29 @@ var NodeFsHandler = class {
187212
187227
  this.fsw._symlinkPaths.set(absPath, targetPath);
187213
187228
  }
187214
187229
  } else if (stats.isSymbolicLink()) {
187215
- const targetPath = follow ? await fsrealpath(path28) : path28;
187230
+ const targetPath = follow ? await fsrealpath(path30) : path30;
187216
187231
  if (this.fsw.closed)
187217
187232
  return;
187218
187233
  const parent = sp.dirname(wh.watchPath);
187219
187234
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
187220
187235
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
187221
- closer = await this._handleDir(parent, stats, initialAdd, depth, path28, wh, targetPath);
187236
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path30, wh, targetPath);
187222
187237
  if (this.fsw.closed)
187223
187238
  return;
187224
187239
  if (targetPath !== void 0) {
187225
- this.fsw._symlinkPaths.set(sp.resolve(path28), targetPath);
187240
+ this.fsw._symlinkPaths.set(sp.resolve(path30), targetPath);
187226
187241
  }
187227
187242
  } else {
187228
187243
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
187229
187244
  }
187230
187245
  ready();
187231
187246
  if (closer)
187232
- this.fsw._addPathCloser(path28, closer);
187247
+ this.fsw._addPathCloser(path30, closer);
187233
187248
  return false;
187234
187249
  } catch (error) {
187235
187250
  if (this.fsw._handleError(error)) {
187236
187251
  ready();
187237
- return path28;
187252
+ return path30;
187238
187253
  }
187239
187254
  }
187240
187255
  }
@@ -187277,24 +187292,24 @@ function createPattern(matcher) {
187277
187292
  }
187278
187293
  return () => false;
187279
187294
  }
187280
- function normalizePath(path28) {
187281
- if (typeof path28 !== "string")
187295
+ function normalizePath(path30) {
187296
+ if (typeof path30 !== "string")
187282
187297
  throw new Error("string expected");
187283
- path28 = sp2.normalize(path28);
187284
- path28 = path28.replace(/\\/g, "/");
187298
+ path30 = sp2.normalize(path30);
187299
+ path30 = path30.replace(/\\/g, "/");
187285
187300
  let prepend = false;
187286
- if (path28.startsWith("//"))
187301
+ if (path30.startsWith("//"))
187287
187302
  prepend = true;
187288
- path28 = path28.replace(DOUBLE_SLASH_RE, "/");
187303
+ path30 = path30.replace(DOUBLE_SLASH_RE, "/");
187289
187304
  if (prepend)
187290
- path28 = "/" + path28;
187291
- return path28;
187305
+ path30 = "/" + path30;
187306
+ return path30;
187292
187307
  }
187293
187308
  function matchPatterns(patterns, testString, stats) {
187294
- const path28 = normalizePath(testString);
187309
+ const path30 = normalizePath(testString);
187295
187310
  for (let index = 0; index < patterns.length; index++) {
187296
187311
  const pattern = patterns[index];
187297
- if (pattern(path28, stats)) {
187312
+ if (pattern(path30, stats)) {
187298
187313
  return true;
187299
187314
  }
187300
187315
  }
@@ -187332,19 +187347,19 @@ var toUnix = (string) => {
187332
187347
  }
187333
187348
  return str;
187334
187349
  };
187335
- var normalizePathToUnix = (path28) => toUnix(sp2.normalize(toUnix(path28)));
187336
- var normalizeIgnored = (cwd = "") => (path28) => {
187337
- if (typeof path28 === "string") {
187338
- return normalizePathToUnix(sp2.isAbsolute(path28) ? path28 : sp2.join(cwd, path28));
187350
+ var normalizePathToUnix = (path30) => toUnix(sp2.normalize(toUnix(path30)));
187351
+ var normalizeIgnored = (cwd = "") => (path30) => {
187352
+ if (typeof path30 === "string") {
187353
+ return normalizePathToUnix(sp2.isAbsolute(path30) ? path30 : sp2.join(cwd, path30));
187339
187354
  } else {
187340
- return path28;
187355
+ return path30;
187341
187356
  }
187342
187357
  };
187343
- var getAbsolutePath = (path28, cwd) => {
187344
- if (sp2.isAbsolute(path28)) {
187345
- return path28;
187358
+ var getAbsolutePath = (path30, cwd) => {
187359
+ if (sp2.isAbsolute(path30)) {
187360
+ return path30;
187346
187361
  }
187347
- return sp2.join(cwd, path28);
187362
+ return sp2.join(cwd, path30);
187348
187363
  };
187349
187364
  var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
187350
187365
  var DirEntry = class {
@@ -187409,10 +187424,10 @@ var WatchHelper = class {
187409
187424
  dirParts;
187410
187425
  followSymlinks;
187411
187426
  statMethod;
187412
- constructor(path28, follow, fsw) {
187427
+ constructor(path30, follow, fsw) {
187413
187428
  this.fsw = fsw;
187414
- const watchPath = path28;
187415
- this.path = path28 = path28.replace(REPLACER_RE, "");
187429
+ const watchPath = path30;
187430
+ this.path = path30 = path30.replace(REPLACER_RE, "");
187416
187431
  this.watchPath = watchPath;
187417
187432
  this.fullWatchPath = sp2.resolve(watchPath);
187418
187433
  this.dirParts = [];
@@ -187552,20 +187567,20 @@ var FSWatcher = class extends EventEmitter {
187552
187567
  this._closePromise = void 0;
187553
187568
  let paths = unifyPaths(paths_);
187554
187569
  if (cwd) {
187555
- paths = paths.map((path28) => {
187556
- const absPath = getAbsolutePath(path28, cwd);
187570
+ paths = paths.map((path30) => {
187571
+ const absPath = getAbsolutePath(path30, cwd);
187557
187572
  return absPath;
187558
187573
  });
187559
187574
  }
187560
- paths.forEach((path28) => {
187561
- this._removeIgnoredPath(path28);
187575
+ paths.forEach((path30) => {
187576
+ this._removeIgnoredPath(path30);
187562
187577
  });
187563
187578
  this._userIgnored = void 0;
187564
187579
  if (!this._readyCount)
187565
187580
  this._readyCount = 0;
187566
187581
  this._readyCount += paths.length;
187567
- Promise.all(paths.map(async (path28) => {
187568
- const res = await this._nodeFsHandler._addToNodeFs(path28, !_internal, void 0, 0, _origAdd);
187582
+ Promise.all(paths.map(async (path30) => {
187583
+ const res = await this._nodeFsHandler._addToNodeFs(path30, !_internal, void 0, 0, _origAdd);
187569
187584
  if (res)
187570
187585
  this._emitReady();
187571
187586
  return res;
@@ -187587,17 +187602,17 @@ var FSWatcher = class extends EventEmitter {
187587
187602
  return this;
187588
187603
  const paths = unifyPaths(paths_);
187589
187604
  const { cwd } = this.options;
187590
- paths.forEach((path28) => {
187591
- if (!sp2.isAbsolute(path28) && !this._closers.has(path28)) {
187605
+ paths.forEach((path30) => {
187606
+ if (!sp2.isAbsolute(path30) && !this._closers.has(path30)) {
187592
187607
  if (cwd)
187593
- path28 = sp2.join(cwd, path28);
187594
- path28 = sp2.resolve(path28);
187608
+ path30 = sp2.join(cwd, path30);
187609
+ path30 = sp2.resolve(path30);
187595
187610
  }
187596
- this._closePath(path28);
187597
- this._addIgnoredPath(path28);
187598
- if (this._watched.has(path28)) {
187611
+ this._closePath(path30);
187612
+ this._addIgnoredPath(path30);
187613
+ if (this._watched.has(path30)) {
187599
187614
  this._addIgnoredPath({
187600
- path: path28,
187615
+ path: path30,
187601
187616
  recursive: true
187602
187617
  });
187603
187618
  }
@@ -187661,38 +187676,38 @@ var FSWatcher = class extends EventEmitter {
187661
187676
  * @param stats arguments to be passed with event
187662
187677
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
187663
187678
  */
187664
- async _emit(event, path28, stats) {
187679
+ async _emit(event, path30, stats) {
187665
187680
  if (this.closed)
187666
187681
  return;
187667
187682
  const opts = this.options;
187668
187683
  if (isWindows)
187669
- path28 = sp2.normalize(path28);
187684
+ path30 = sp2.normalize(path30);
187670
187685
  if (opts.cwd)
187671
- path28 = sp2.relative(opts.cwd, path28);
187672
- const args = [path28];
187686
+ path30 = sp2.relative(opts.cwd, path30);
187687
+ const args = [path30];
187673
187688
  if (stats != null)
187674
187689
  args.push(stats);
187675
187690
  const awf = opts.awaitWriteFinish;
187676
187691
  let pw;
187677
- if (awf && (pw = this._pendingWrites.get(path28))) {
187692
+ if (awf && (pw = this._pendingWrites.get(path30))) {
187678
187693
  pw.lastChange = /* @__PURE__ */ new Date();
187679
187694
  return this;
187680
187695
  }
187681
187696
  if (opts.atomic) {
187682
187697
  if (event === EVENTS.UNLINK) {
187683
- this._pendingUnlinks.set(path28, [event, ...args]);
187698
+ this._pendingUnlinks.set(path30, [event, ...args]);
187684
187699
  setTimeout(() => {
187685
- this._pendingUnlinks.forEach((entry, path29) => {
187700
+ this._pendingUnlinks.forEach((entry, path31) => {
187686
187701
  this.emit(...entry);
187687
187702
  this.emit(EVENTS.ALL, ...entry);
187688
- this._pendingUnlinks.delete(path29);
187703
+ this._pendingUnlinks.delete(path31);
187689
187704
  });
187690
187705
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
187691
187706
  return this;
187692
187707
  }
187693
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path28)) {
187708
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path30)) {
187694
187709
  event = EVENTS.CHANGE;
187695
- this._pendingUnlinks.delete(path28);
187710
+ this._pendingUnlinks.delete(path30);
187696
187711
  }
187697
187712
  }
187698
187713
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -187710,16 +187725,16 @@ var FSWatcher = class extends EventEmitter {
187710
187725
  this.emitWithAll(event, args);
187711
187726
  }
187712
187727
  };
187713
- this._awaitWriteFinish(path28, awf.stabilityThreshold, event, awfEmit);
187728
+ this._awaitWriteFinish(path30, awf.stabilityThreshold, event, awfEmit);
187714
187729
  return this;
187715
187730
  }
187716
187731
  if (event === EVENTS.CHANGE) {
187717
- const isThrottled = !this._throttle(EVENTS.CHANGE, path28, 50);
187732
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path30, 50);
187718
187733
  if (isThrottled)
187719
187734
  return this;
187720
187735
  }
187721
187736
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
187722
- const fullPath = opts.cwd ? sp2.join(opts.cwd, path28) : path28;
187737
+ const fullPath = opts.cwd ? sp2.join(opts.cwd, path30) : path30;
187723
187738
  let stats2;
187724
187739
  try {
187725
187740
  stats2 = await stat3(fullPath);
@@ -187750,23 +187765,23 @@ var FSWatcher = class extends EventEmitter {
187750
187765
  * @param timeout duration of time to suppress duplicate actions
187751
187766
  * @returns tracking object or false if action should be suppressed
187752
187767
  */
187753
- _throttle(actionType, path28, timeout) {
187768
+ _throttle(actionType, path30, timeout) {
187754
187769
  if (!this._throttled.has(actionType)) {
187755
187770
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
187756
187771
  }
187757
187772
  const action = this._throttled.get(actionType);
187758
187773
  if (!action)
187759
187774
  throw new Error("invalid throttle");
187760
- const actionPath = action.get(path28);
187775
+ const actionPath = action.get(path30);
187761
187776
  if (actionPath) {
187762
187777
  actionPath.count++;
187763
187778
  return false;
187764
187779
  }
187765
187780
  let timeoutObject;
187766
187781
  const clear = () => {
187767
- const item = action.get(path28);
187782
+ const item = action.get(path30);
187768
187783
  const count = item ? item.count : 0;
187769
- action.delete(path28);
187784
+ action.delete(path30);
187770
187785
  clearTimeout(timeoutObject);
187771
187786
  if (item)
187772
187787
  clearTimeout(item.timeoutObject);
@@ -187774,7 +187789,7 @@ var FSWatcher = class extends EventEmitter {
187774
187789
  };
187775
187790
  timeoutObject = setTimeout(clear, timeout);
187776
187791
  const thr = { timeoutObject, clear, count: 0 };
187777
- action.set(path28, thr);
187792
+ action.set(path30, thr);
187778
187793
  return thr;
187779
187794
  }
187780
187795
  _incrReadyCount() {
@@ -187788,44 +187803,44 @@ var FSWatcher = class extends EventEmitter {
187788
187803
  * @param event
187789
187804
  * @param awfEmit Callback to be called when ready for event to be emitted.
187790
187805
  */
187791
- _awaitWriteFinish(path28, threshold, event, awfEmit) {
187806
+ _awaitWriteFinish(path30, threshold, event, awfEmit) {
187792
187807
  const awf = this.options.awaitWriteFinish;
187793
187808
  if (typeof awf !== "object")
187794
187809
  return;
187795
187810
  const pollInterval = awf.pollInterval;
187796
187811
  let timeoutHandler;
187797
- let fullPath = path28;
187798
- if (this.options.cwd && !sp2.isAbsolute(path28)) {
187799
- fullPath = sp2.join(this.options.cwd, path28);
187812
+ let fullPath = path30;
187813
+ if (this.options.cwd && !sp2.isAbsolute(path30)) {
187814
+ fullPath = sp2.join(this.options.cwd, path30);
187800
187815
  }
187801
187816
  const now = /* @__PURE__ */ new Date();
187802
187817
  const writes = this._pendingWrites;
187803
187818
  function awaitWriteFinishFn(prevStat) {
187804
187819
  statcb(fullPath, (err, curStat) => {
187805
- if (err || !writes.has(path28)) {
187820
+ if (err || !writes.has(path30)) {
187806
187821
  if (err && err.code !== "ENOENT")
187807
187822
  awfEmit(err);
187808
187823
  return;
187809
187824
  }
187810
187825
  const now2 = Number(/* @__PURE__ */ new Date());
187811
187826
  if (prevStat && curStat.size !== prevStat.size) {
187812
- writes.get(path28).lastChange = now2;
187827
+ writes.get(path30).lastChange = now2;
187813
187828
  }
187814
- const pw = writes.get(path28);
187829
+ const pw = writes.get(path30);
187815
187830
  const df = now2 - pw.lastChange;
187816
187831
  if (df >= threshold) {
187817
- writes.delete(path28);
187832
+ writes.delete(path30);
187818
187833
  awfEmit(void 0, curStat);
187819
187834
  } else {
187820
187835
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
187821
187836
  }
187822
187837
  });
187823
187838
  }
187824
- if (!writes.has(path28)) {
187825
- writes.set(path28, {
187839
+ if (!writes.has(path30)) {
187840
+ writes.set(path30, {
187826
187841
  lastChange: now,
187827
187842
  cancelWait: () => {
187828
- writes.delete(path28);
187843
+ writes.delete(path30);
187829
187844
  clearTimeout(timeoutHandler);
187830
187845
  return event;
187831
187846
  }
@@ -187836,8 +187851,8 @@ var FSWatcher = class extends EventEmitter {
187836
187851
  /**
187837
187852
  * Determines whether user has asked to ignore this path.
187838
187853
  */
187839
- _isIgnored(path28, stats) {
187840
- if (this.options.atomic && DOT_RE.test(path28))
187854
+ _isIgnored(path30, stats) {
187855
+ if (this.options.atomic && DOT_RE.test(path30))
187841
187856
  return true;
187842
187857
  if (!this._userIgnored) {
187843
187858
  const { cwd } = this.options;
@@ -187847,17 +187862,17 @@ var FSWatcher = class extends EventEmitter {
187847
187862
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
187848
187863
  this._userIgnored = anymatch(list, void 0);
187849
187864
  }
187850
- return this._userIgnored(path28, stats);
187865
+ return this._userIgnored(path30, stats);
187851
187866
  }
187852
- _isntIgnored(path28, stat4) {
187853
- return !this._isIgnored(path28, stat4);
187867
+ _isntIgnored(path30, stat4) {
187868
+ return !this._isIgnored(path30, stat4);
187854
187869
  }
187855
187870
  /**
187856
187871
  * Provides a set of common helpers and properties relating to symlink handling.
187857
187872
  * @param path file or directory pattern being watched
187858
187873
  */
187859
- _getWatchHelpers(path28) {
187860
- return new WatchHelper(path28, this.options.followSymlinks, this);
187874
+ _getWatchHelpers(path30) {
187875
+ return new WatchHelper(path30, this.options.followSymlinks, this);
187861
187876
  }
187862
187877
  // Directory helpers
187863
187878
  // -----------------
@@ -187889,63 +187904,63 @@ var FSWatcher = class extends EventEmitter {
187889
187904
  * @param item base path of item/directory
187890
187905
  */
187891
187906
  _remove(directory, item, isDirectory) {
187892
- const path28 = sp2.join(directory, item);
187893
- const fullPath = sp2.resolve(path28);
187894
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path28) || this._watched.has(fullPath);
187895
- if (!this._throttle("remove", path28, 100))
187907
+ const path30 = sp2.join(directory, item);
187908
+ const fullPath = sp2.resolve(path30);
187909
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path30) || this._watched.has(fullPath);
187910
+ if (!this._throttle("remove", path30, 100))
187896
187911
  return;
187897
187912
  if (!isDirectory && this._watched.size === 1) {
187898
187913
  this.add(directory, item, true);
187899
187914
  }
187900
- const wp = this._getWatchedDir(path28);
187915
+ const wp = this._getWatchedDir(path30);
187901
187916
  const nestedDirectoryChildren = wp.getChildren();
187902
- nestedDirectoryChildren.forEach((nested) => this._remove(path28, nested));
187917
+ nestedDirectoryChildren.forEach((nested) => this._remove(path30, nested));
187903
187918
  const parent = this._getWatchedDir(directory);
187904
187919
  const wasTracked = parent.has(item);
187905
187920
  parent.remove(item);
187906
187921
  if (this._symlinkPaths.has(fullPath)) {
187907
187922
  this._symlinkPaths.delete(fullPath);
187908
187923
  }
187909
- let relPath = path28;
187924
+ let relPath = path30;
187910
187925
  if (this.options.cwd)
187911
- relPath = sp2.relative(this.options.cwd, path28);
187926
+ relPath = sp2.relative(this.options.cwd, path30);
187912
187927
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
187913
187928
  const event = this._pendingWrites.get(relPath).cancelWait();
187914
187929
  if (event === EVENTS.ADD)
187915
187930
  return;
187916
187931
  }
187917
- this._watched.delete(path28);
187932
+ this._watched.delete(path30);
187918
187933
  this._watched.delete(fullPath);
187919
187934
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
187920
- if (wasTracked && !this._isIgnored(path28))
187921
- this._emit(eventName, path28);
187922
- this._closePath(path28);
187935
+ if (wasTracked && !this._isIgnored(path30))
187936
+ this._emit(eventName, path30);
187937
+ this._closePath(path30);
187923
187938
  }
187924
187939
  /**
187925
187940
  * Closes all watchers for a path
187926
187941
  */
187927
- _closePath(path28) {
187928
- this._closeFile(path28);
187929
- const dir = sp2.dirname(path28);
187930
- this._getWatchedDir(dir).remove(sp2.basename(path28));
187942
+ _closePath(path30) {
187943
+ this._closeFile(path30);
187944
+ const dir = sp2.dirname(path30);
187945
+ this._getWatchedDir(dir).remove(sp2.basename(path30));
187931
187946
  }
187932
187947
  /**
187933
187948
  * Closes only file-specific watchers
187934
187949
  */
187935
- _closeFile(path28) {
187936
- const closers = this._closers.get(path28);
187950
+ _closeFile(path30) {
187951
+ const closers = this._closers.get(path30);
187937
187952
  if (!closers)
187938
187953
  return;
187939
187954
  closers.forEach((closer) => closer());
187940
- this._closers.delete(path28);
187955
+ this._closers.delete(path30);
187941
187956
  }
187942
- _addPathCloser(path28, closer) {
187957
+ _addPathCloser(path30, closer) {
187943
187958
  if (!closer)
187944
187959
  return;
187945
- let list = this._closers.get(path28);
187960
+ let list = this._closers.get(path30);
187946
187961
  if (!list) {
187947
187962
  list = [];
187948
- this._closers.set(path28, list);
187963
+ this._closers.set(path30, list);
187949
187964
  }
187950
187965
  list.push(closer);
187951
187966
  }
@@ -188994,6 +189009,7 @@ import { fileURLToPath as fileURLToPath3 } from "url";
188994
189009
  import httpProxy from "http-proxy";
188995
189010
  var __dirname3 = path13.dirname(fileURLToPath3(import.meta.url));
188996
189011
  var adminDir = path13.join(__dirname3, "admin");
189012
+ var _embeddedAdmin = null;
188997
189013
  var HTTP_PORT = 80;
188998
189014
  var HTTPS_PORT = 443;
188999
189015
  var DOMAIN_SUFFIX = ".local.spcf.app";
@@ -189340,6 +189356,48 @@ function sendNotFound(res, requestedService, serviceMap) {
189340
189356
  </html>`);
189341
189357
  }
189342
189358
  function serveStaticFile(res, pathname) {
189359
+ if (_embeddedAdmin) {
189360
+ return serveEmbeddedFile(res, pathname);
189361
+ }
189362
+ return serveFilesystemFile(res, pathname);
189363
+ }
189364
+ function serveEmbeddedFile(res, pathname) {
189365
+ let filePath = pathname;
189366
+ if (filePath === "/" || filePath.endsWith("/")) {
189367
+ filePath = filePath + "index.html";
189368
+ }
189369
+ const relativePath = filePath.startsWith("/") ? filePath.slice(1) : filePath;
189370
+ let content = _embeddedAdmin.get(relativePath);
189371
+ if (content) {
189372
+ const ext = path13.extname(relativePath).toLowerCase();
189373
+ const contentType = MIME_TYPES[ext] || "application/octet-stream";
189374
+ res.writeHead(200, { "Content-Type": contentType });
189375
+ res.end(content);
189376
+ return;
189377
+ }
189378
+ content = _embeddedAdmin.get(relativePath + ".html");
189379
+ if (content) {
189380
+ res.writeHead(200, { "Content-Type": "text/html" });
189381
+ res.end(content);
189382
+ return;
189383
+ }
189384
+ const indexKey = relativePath.endsWith("/") ? relativePath + "index.html" : relativePath + "/index.html";
189385
+ content = _embeddedAdmin.get(indexKey);
189386
+ if (content) {
189387
+ res.writeHead(200, { "Content-Type": "text/html" });
189388
+ res.end(content);
189389
+ return;
189390
+ }
189391
+ const notFound = _embeddedAdmin.get("404.html");
189392
+ if (notFound) {
189393
+ res.writeHead(404, { "Content-Type": "text/html" });
189394
+ res.end(notFound);
189395
+ return;
189396
+ }
189397
+ res.writeHead(404, { "Content-Type": "text/html" });
189398
+ res.end("<h1>Not Found</h1>");
189399
+ }
189400
+ function serveFilesystemFile(res, pathname) {
189343
189401
  let filePath = pathname;
189344
189402
  if (filePath === "/" || filePath.endsWith("/")) {
189345
189403
  filePath = filePath + "index.html";
@@ -192846,8 +192904,7 @@ function DeployUI({ environment, config, skipBuildTest }) {
192846
192904
  let cancelled = false;
192847
192905
  async function loadProjects() {
192848
192906
  try {
192849
- const token = await getValidAccessToken();
192850
- const client2 = new ApiClient(token);
192907
+ const client2 = new ApiClient();
192851
192908
  const { projects: projects2 } = await client2.listProjects();
192852
192909
  if (cancelled) return;
192853
192910
  setState({
@@ -192893,8 +192950,7 @@ function DeployUI({ environment, config, skipBuildTest }) {
192893
192950
  let cancelled = false;
192894
192951
  async function createProject() {
192895
192952
  try {
192896
- const token = await getValidAccessToken();
192897
- const client2 = new ApiClient(token);
192953
+ const client2 = new ApiClient();
192898
192954
  const project = await client2.createProject(state.newProjectName);
192899
192955
  if (cancelled) return;
192900
192956
  writeProjectId(project.id);
@@ -193099,8 +193155,7 @@ ${errorMsg}`
193099
193155
  setState((s) => ({ ...s, phase: "creating-tarball" }));
193100
193156
  writeLog("deploy", `Starting deployment to "${environment}"`);
193101
193157
  writeLog("deploy", `Project directory: ${projectDir}`);
193102
- const authToken = await getValidAccessToken();
193103
- const client2 = new ApiClient(authToken);
193158
+ const client2 = new ApiClient();
193104
193159
  clientRef.current = client2;
193105
193160
  if (cancelled) return;
193106
193161
  const contexts = builds.map((b) => b.context || ".").filter(Boolean);
@@ -194309,11 +194364,226 @@ function betaCommand() {
194309
194364
  render8(/* @__PURE__ */ React10.createElement(BetaToggleUI, null));
194310
194365
  }
194311
194366
 
194312
- // src/cli.tsx
194367
+ // src/commands/update.tsx
194368
+ import React11, { useState as useState10, useEffect as useEffect8 } from "react";
194369
+ import { render as render9, Text as Text11, Box as Box10, useApp as useApp6 } from "ink";
194370
+ import Spinner7 from "ink-spinner";
194371
+
194372
+ // src/lib/update.ts
194373
+ import * as fs30 from "fs";
194374
+ import * as path28 from "path";
194375
+ var BINARIES_BASE_URL = "https://binaries.specific.dev/cli";
194376
+ function compareVersions(a, b) {
194377
+ const partsA = a.split(".").map(Number);
194378
+ const partsB = b.split(".").map(Number);
194379
+ const len = Math.max(partsA.length, partsB.length);
194380
+ for (let i = 0; i < len; i++) {
194381
+ const numA = partsA[i] ?? 0;
194382
+ const numB = partsB[i] ?? 0;
194383
+ if (numA !== numB) return numA - numB;
194384
+ }
194385
+ return 0;
194386
+ }
194387
+ async function checkForUpdate() {
194388
+ const currentVersion = "0.1.67";
194389
+ const response = await fetch(`${BINARIES_BASE_URL}/latest`);
194390
+ if (!response.ok) {
194391
+ throw new Error(`Failed to check for updates: HTTP ${response.status}`);
194392
+ }
194393
+ const latestVersion = (await response.text()).trim();
194394
+ const updateAvailable = compareVersions(latestVersion, currentVersion) > 0;
194395
+ return { currentVersion, latestVersion, updateAvailable };
194396
+ }
194397
+ function getCurrentBinaryPath() {
194398
+ return process.execPath;
194399
+ }
194400
+ function isBinaryWritable() {
194401
+ const binaryPath = getCurrentBinaryPath();
194402
+ const dir = path28.dirname(binaryPath);
194403
+ try {
194404
+ fs30.accessSync(dir, fs30.constants.W_OK);
194405
+ return true;
194406
+ } catch {
194407
+ return false;
194408
+ }
194409
+ }
194410
+ async function performUpdate(version, onProgress) {
194411
+ const binaryPath = getCurrentBinaryPath();
194412
+ const binaryDir = path28.dirname(binaryPath);
194413
+ const tempPath = path28.join(binaryDir, `.specific-update-${process.pid}`);
194414
+ try {
194415
+ const { platform: platform5, arch: arch3 } = getPlatformInfo();
194416
+ const url = `${BINARIES_BASE_URL}/${version}/specific-${platform5}-${arch3}`;
194417
+ await downloadFile(url, tempPath, onProgress);
194418
+ const stat4 = fs30.statSync(tempPath);
194419
+ if (stat4.size === 0) {
194420
+ throw new Error("Downloaded binary is empty");
194421
+ }
194422
+ fs30.chmodSync(tempPath, 493);
194423
+ onProgress?.({ phase: "finalizing" });
194424
+ fs30.unlinkSync(binaryPath);
194425
+ fs30.renameSync(tempPath, binaryPath);
194426
+ } catch (error) {
194427
+ try {
194428
+ if (fs30.existsSync(tempPath)) {
194429
+ fs30.unlinkSync(tempPath);
194430
+ }
194431
+ } catch {
194432
+ }
194433
+ throw error;
194434
+ }
194435
+ }
194436
+
194437
+ // src/lib/background-update.ts
194438
+ import { spawn as spawn10 } from "child_process";
194439
+ import * as fs31 from "fs";
194440
+ import * as path29 from "path";
194441
+ import * as os9 from "os";
194442
+ var SPECIFIC_DIR = path29.join(os9.homedir(), ".specific");
194443
+ var RATE_LIMIT_FILE = path29.join(SPECIFIC_DIR, "last-update-check");
194444
+ var LOCK_FILE = path29.join(SPECIFIC_DIR, "update.lock");
194445
+ var RATE_LIMIT_MS = 60 * 60 * 1e3;
194446
+ var STALE_LOCK_MS = 10 * 60 * 1e3;
194447
+ function writeCheckTimestamp() {
194448
+ fs31.mkdirSync(SPECIFIC_DIR, { recursive: true });
194449
+ fs31.writeFileSync(RATE_LIMIT_FILE, String(Date.now()), "utf-8");
194450
+ }
194451
+ function isRateLimited() {
194452
+ try {
194453
+ const content = fs31.readFileSync(RATE_LIMIT_FILE, "utf-8").trim();
194454
+ const lastCheck = parseInt(content, 10);
194455
+ if (isNaN(lastCheck)) return false;
194456
+ return Date.now() - lastCheck < RATE_LIMIT_MS;
194457
+ } catch {
194458
+ return false;
194459
+ }
194460
+ }
194461
+ function maybeStartBackgroundUpdate() {
194462
+ try {
194463
+ if (true) return;
194464
+ if (process.env.SPECIFIC_BACKGROUND_UPDATE === "1") return;
194465
+ if (isRateLimited()) return;
194466
+ if (!isBinaryWritable()) return;
194467
+ const child = spawn10(process.execPath, [], {
194468
+ detached: true,
194469
+ stdio: "ignore",
194470
+ env: {
194471
+ ...process.env,
194472
+ SPECIFIC_BACKGROUND_UPDATE: "1"
194473
+ }
194474
+ });
194475
+ child.unref();
194476
+ } catch {
194477
+ }
194478
+ }
194479
+
194480
+ // src/commands/update.tsx
194481
+ function UpdateUI() {
194482
+ const { exit } = useApp6();
194483
+ const [state, setState] = useState10({ phase: "checking" });
194484
+ useEffect8(() => {
194485
+ if (state.phase !== "checking") return;
194486
+ let cancelled = false;
194487
+ async function check() {
194488
+ try {
194489
+ const result = await checkForUpdate();
194490
+ if (cancelled) return;
194491
+ if (!result.updateAvailable) {
194492
+ setState({ phase: "up-to-date", checkResult: result });
194493
+ return;
194494
+ }
194495
+ if (!isBinaryWritable()) {
194496
+ setState({ phase: "permission-error", checkResult: result });
194497
+ return;
194498
+ }
194499
+ setState({ phase: "downloading", checkResult: result });
194500
+ } catch (err) {
194501
+ if (cancelled) return;
194502
+ setState({
194503
+ phase: "error",
194504
+ error: err instanceof Error ? err.message : String(err)
194505
+ });
194506
+ }
194507
+ }
194508
+ check();
194509
+ return () => {
194510
+ cancelled = true;
194511
+ };
194512
+ }, [state.phase]);
194513
+ useEffect8(() => {
194514
+ if (state.phase !== "downloading" || !state.checkResult) return;
194515
+ let cancelled = false;
194516
+ async function download() {
194517
+ try {
194518
+ await performUpdate(state.checkResult.latestVersion, (progress) => {
194519
+ if (!cancelled) {
194520
+ setState((s) => ({ ...s, progress }));
194521
+ }
194522
+ });
194523
+ if (cancelled) return;
194524
+ trackEvent("cli_updated", {
194525
+ from_version: state.checkResult.currentVersion,
194526
+ to_version: state.checkResult.latestVersion
194527
+ });
194528
+ writeCheckTimestamp();
194529
+ setState((s) => ({ ...s, phase: "success" }));
194530
+ } catch (err) {
194531
+ if (cancelled) return;
194532
+ setState({
194533
+ phase: "error",
194534
+ checkResult: state.checkResult,
194535
+ error: err instanceof Error ? err.message : String(err)
194536
+ });
194537
+ }
194538
+ }
194539
+ download();
194540
+ return () => {
194541
+ cancelled = true;
194542
+ };
194543
+ }, [state.phase, state.checkResult]);
194544
+ useEffect8(() => {
194545
+ if (state.phase === "up-to-date" || state.phase === "success" || state.phase === "error" || state.phase === "permission-error") {
194546
+ const timer = setTimeout(() => exit(), 100);
194547
+ return () => clearTimeout(timer);
194548
+ }
194549
+ }, [state.phase, exit]);
194550
+ if (state.phase === "checking") {
194551
+ return /* @__PURE__ */ React11.createElement(Box10, null, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, /* @__PURE__ */ React11.createElement(Spinner7, { type: "dots" })), /* @__PURE__ */ React11.createElement(Text11, null, " Checking for updates..."));
194552
+ }
194553
+ if (state.phase === "up-to-date") {
194554
+ return /* @__PURE__ */ React11.createElement(Text11, { color: "green" }, "Already up to date (v", state.checkResult.currentVersion, ")");
194555
+ }
194556
+ if (state.phase === "permission-error") {
194557
+ const { currentVersion, latestVersion } = state.checkResult;
194558
+ return /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text11, null, "Update available: v", currentVersion, " \u2192 v", latestVersion), /* @__PURE__ */ React11.createElement(Text11, { color: "yellow" }, "Permission denied. Re-run with sudo:"), /* @__PURE__ */ React11.createElement(Text11, { color: "cyan" }, " sudo specific update"));
194559
+ }
194560
+ if (state.phase === "downloading") {
194561
+ const { currentVersion, latestVersion } = state.checkResult;
194562
+ const { progress } = state;
194563
+ const progressText = progress?.percent ? ` (${progress.percent}%)` : "";
194564
+ return /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text11, null, "Updating: v", currentVersion, " \u2192 v", latestVersion), /* @__PURE__ */ React11.createElement(Box10, null, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, /* @__PURE__ */ React11.createElement(Spinner7, { type: "dots" })), /* @__PURE__ */ React11.createElement(Text11, null, " ", progress?.phase === "finalizing" ? "Installing..." : `Downloading${progressText}`)));
194565
+ }
194566
+ if (state.phase === "success") {
194567
+ const { currentVersion, latestVersion } = state.checkResult;
194568
+ return /* @__PURE__ */ React11.createElement(Text11, { color: "green" }, "Updated successfully: v", currentVersion, " \u2192 v", latestVersion);
194569
+ }
194570
+ return /* @__PURE__ */ React11.createElement(Text11, { color: "red" }, "Update failed: ", state.error);
194571
+ }
194572
+ function updateCommand() {
194573
+ const distribution = "npm";
194574
+ if (distribution !== "binary") {
194575
+ console.log("This installation was installed via npm.");
194576
+ console.log("To update, run: npm update -g @specific.dev/cli");
194577
+ return;
194578
+ }
194579
+ render9(/* @__PURE__ */ React11.createElement(UpdateUI, null));
194580
+ }
194581
+
194582
+ // src/cli-program.tsx
194313
194583
  var program = new Command();
194314
194584
  var env = "production";
194315
194585
  var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
194316
- program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.65").enablePositionalOptions();
194586
+ program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.67").enablePositionalOptions();
194317
194587
  program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").action((options2) => initCommand(options2));
194318
194588
  program.command("docs [topic]").description("Fetch LLM-optimized documentation").action(docsCommand);
194319
194589
  program.command("check").description("Validate specific.hcl configuration").action(checkCommand);
@@ -194342,13 +194612,17 @@ program.command("clean").description("Remove .specific directory for a clean sla
194342
194612
  cleanCommand(options2.key);
194343
194613
  });
194344
194614
  program.command("beta").description("Manage beta feature flags").action(betaCommand);
194615
+ program.command("update").description("Update Specific CLI to the latest version").action(updateCommand);
194345
194616
  program.command("login").description("Log in to Specific").action(loginCommand);
194346
194617
  program.command("logout").description("Log out of Specific").action(logoutCommand);
194347
194618
  var commandName = process.argv[2] || "help";
194348
194619
  trackEvent("cli_command_invoked", { command: commandName });
194620
+ maybeStartBackgroundUpdate();
194349
194621
  process.on("beforeExit", async () => {
194350
194622
  await shutdown();
194351
194623
  });
194624
+
194625
+ // src/cli.tsx
194352
194626
  program.parse();
194353
194627
  /*! Bundled license information:
194354
194628