@factiii/runner 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -961,7 +961,7 @@ var require_suggestSimilar = __commonJS({
961
961
  // node_modules/commander/lib/command.js
962
962
  var require_command = __commonJS({
963
963
  "node_modules/commander/lib/command.js"(exports2) {
964
- var EventEmitter = require("node:events").EventEmitter;
964
+ var EventEmitter2 = require("node:events").EventEmitter;
965
965
  var childProcess = require("node:child_process");
966
966
  var path15 = require("node:path");
967
967
  var fs13 = require("node:fs");
@@ -971,7 +971,7 @@ var require_command = __commonJS({
971
971
  var { Help: Help2 } = require_help();
972
972
  var { Option: Option2, DualOptions } = require_option();
973
973
  var { suggestSimilar } = require_suggestSimilar();
974
- var Command2 = class _Command extends EventEmitter {
974
+ var Command2 = class _Command extends EventEmitter2 {
975
975
  /**
976
976
  * Initialize a new `Command`.
977
977
  *
@@ -6503,13 +6503,13 @@ var require_extension = __commonJS({
6503
6503
  var require_websocket = __commonJS({
6504
6504
  "../../node_modules/ws/lib/websocket.js"(exports2, module2) {
6505
6505
  "use strict";
6506
- var EventEmitter = require("events");
6506
+ var EventEmitter2 = require("events");
6507
6507
  var https = require("https");
6508
6508
  var http = require("http");
6509
6509
  var net2 = require("net");
6510
6510
  var tls = require("tls");
6511
6511
  var { randomBytes, createHash: createHash2 } = require("crypto");
6512
- var { Duplex, Readable } = require("stream");
6512
+ var { Duplex, Readable: Readable2 } = require("stream");
6513
6513
  var { URL: URL2 } = require("url");
6514
6514
  var PerMessageDeflate2 = require_permessage_deflate();
6515
6515
  var Receiver2 = require_receiver();
@@ -6535,7 +6535,7 @@ var require_websocket = __commonJS({
6535
6535
  var protocolVersions = [8, 13];
6536
6536
  var readyStates = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"];
6537
6537
  var subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
6538
- var WebSocket2 = class _WebSocket extends EventEmitter {
6538
+ var WebSocket2 = class _WebSocket extends EventEmitter2 {
6539
6539
  /**
6540
6540
  * Create a new `WebSocket`.
6541
6541
  *
@@ -7457,7 +7457,7 @@ var require_stream = __commonJS({
7457
7457
  };
7458
7458
  duplex._final = function(callback) {
7459
7459
  if (ws.readyState === ws.CONNECTING) {
7460
- ws.once("open", function open() {
7460
+ ws.once("open", function open2() {
7461
7461
  duplex._final(callback);
7462
7462
  });
7463
7463
  return;
@@ -7478,7 +7478,7 @@ var require_stream = __commonJS({
7478
7478
  };
7479
7479
  duplex._write = function(chunk, encoding, callback) {
7480
7480
  if (ws.readyState === ws.CONNECTING) {
7481
- ws.once("open", function open() {
7481
+ ws.once("open", function open2() {
7482
7482
  duplex._write(chunk, encoding, callback);
7483
7483
  });
7484
7484
  return;
@@ -7542,7 +7542,7 @@ var require_subprotocol = __commonJS({
7542
7542
  var require_websocket_server = __commonJS({
7543
7543
  "../../node_modules/ws/lib/websocket-server.js"(exports2, module2) {
7544
7544
  "use strict";
7545
- var EventEmitter = require("events");
7545
+ var EventEmitter2 = require("events");
7546
7546
  var http = require("http");
7547
7547
  var { Duplex } = require("stream");
7548
7548
  var { createHash: createHash2 } = require("crypto");
@@ -7555,7 +7555,7 @@ var require_websocket_server = __commonJS({
7555
7555
  var RUNNING = 0;
7556
7556
  var CLOSING = 1;
7557
7557
  var CLOSED = 2;
7558
- var WebSocketServer2 = class extends EventEmitter {
7558
+ var WebSocketServer2 = class extends EventEmitter2 {
7559
7559
  /**
7560
7560
  * Create a `WebSocketServer` instance.
7561
7561
  *
@@ -7967,10 +7967,10 @@ function prompt(msg) {
7967
7967
  input: process.stdin,
7968
7968
  output: process.stdout
7969
7969
  });
7970
- return new Promise((resolve2) => {
7970
+ return new Promise((resolve4) => {
7971
7971
  rl.question(msg, (answer) => {
7972
7972
  rl.close();
7973
- resolve2(answer.trim());
7973
+ resolve4(answer.trim());
7974
7974
  });
7975
7975
  });
7976
7976
  }
@@ -8779,11 +8779,11 @@ function promptPassword(label) {
8779
8779
  rl._writeToOutput = (text) => {
8780
8780
  if (!muted) write(text);
8781
8781
  };
8782
- return new Promise((resolve2) => {
8782
+ return new Promise((resolve4) => {
8783
8783
  rl.question(label, (answer) => {
8784
8784
  rl.close();
8785
8785
  process.stdout.write("\n");
8786
- resolve2(answer);
8786
+ resolve4(answer);
8787
8787
  });
8788
8788
  muted = true;
8789
8789
  });
@@ -13603,7 +13603,7 @@ async function markOnboardingComplete(target) {
13603
13603
  await target.sh(`node -e "${script}"`);
13604
13604
  }
13605
13605
  function runAgentProc(proc, prompt2, stream, label, errorPrefix) {
13606
- return new Promise((resolve2, reject) => {
13606
+ return new Promise((resolve4, reject) => {
13607
13607
  let errorOutput = "";
13608
13608
  proc.stderr?.on("data", (chunk) => {
13609
13609
  errorOutput += chunk.toString();
@@ -13618,7 +13618,7 @@ function runAgentProc(proc, prompt2, stream, label, errorPrefix) {
13618
13618
  } else if (code !== 0 && !text) {
13619
13619
  reject(new Error(errorOutput || `${label} exited with code ${code}`));
13620
13620
  } else {
13621
- resolve2({ text, sessionId });
13621
+ resolve4({ text, sessionId });
13622
13622
  }
13623
13623
  });
13624
13624
  proc.on("error", (err) => {
@@ -13767,8 +13767,14 @@ function hostSpacePaths(spaceDir) {
13767
13767
  bin: import_path6.default.join(spaceDir, "bin")
13768
13768
  };
13769
13769
  }
13770
- function worktreeFor(paths, taskId) {
13771
- return `${paths.worktrees}/${taskId.replace(/[^a-zA-Z0-9._-]/g, "_")}`;
13770
+ function worktreeFor(paths, workName) {
13771
+ return `${paths.worktrees}/${workName.replace(/[^a-zA-Z0-9._-]/g, "_")}`;
13772
+ }
13773
+
13774
+ // ../../shared/all/helpers/board-agent-core/workName.ts
13775
+ var WORK_NAME_MAX = 48;
13776
+ function slugifyWorkName(name) {
13777
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, WORK_NAME_MAX).replace(/^-+|-+$/g, "");
13772
13778
  }
13773
13779
 
13774
13780
  // ../../shared/all/helpers/board-agent-core/git.ts
@@ -13784,8 +13790,37 @@ function buildCloneUrl(repoUrl, githubToken) {
13784
13790
  async function gitInDir(target, workdir, ...args) {
13785
13791
  return target.run(["git", "-C", workdir, ...args]);
13786
13792
  }
13787
- function cardWorkBranch(taskId) {
13788
- return `factiii/card-${taskId.replace(/[^a-zA-Z0-9._-]/g, "-")}`;
13793
+ var WORK_BRANCH_PREFIX = "factiii/card-";
13794
+ function cardWorkBranch(workName) {
13795
+ return `${WORK_BRANCH_PREFIX}${workName.replace(/[^a-zA-Z0-9._-]/g, "-")}`;
13796
+ }
13797
+ async function listWorkNames(target) {
13798
+ const dirs = await target.sh(`ls -1 ${target.paths.worktrees} 2>/dev/null || true`).catch(() => "");
13799
+ const branches = await gitInDir(
13800
+ target,
13801
+ target.paths.repo,
13802
+ "for-each-ref",
13803
+ "--format=%(refname:short)",
13804
+ "refs/heads/"
13805
+ ).catch(() => "");
13806
+ const names = new Set(dirs.split("\n").map((line) => line.trim()));
13807
+ for (const line of branches.split("\n")) {
13808
+ const name = line.trim();
13809
+ if (name.startsWith(WORK_BRANCH_PREFIX)) {
13810
+ names.add(name.slice(WORK_BRANCH_PREFIX.length));
13811
+ }
13812
+ }
13813
+ names.delete("");
13814
+ return [...names];
13815
+ }
13816
+ async function claimWorkName(target, desired, extraTaken = []) {
13817
+ const name = slugifyWorkName(desired);
13818
+ if (!name) throw new Error("Name this terminal before starting it.");
13819
+ const taken = /* @__PURE__ */ new Set([...await listWorkNames(target), ...extraTaken]);
13820
+ if (taken.has(name)) {
13821
+ throw new Error(`"${name}" is already in use. Pick another name.`);
13822
+ }
13823
+ return name;
13789
13824
  }
13790
13825
  async function ensurePrimaryClone(target, cloneUrl, branch) {
13791
13826
  const repo = target.paths.repo;
@@ -13807,9 +13842,9 @@ async function ensurePrimaryClone(target, cloneUrl, branch) {
13807
13842
  });
13808
13843
  await target.sh(`mkdir -p ${target.paths.worktrees}`);
13809
13844
  }
13810
- async function addWorktree(target, taskId, baseBranch) {
13811
- const path15 = worktreeFor(target.paths, taskId);
13812
- const branch = cardWorkBranch(taskId);
13845
+ async function addWorktree(target, workName, baseBranch) {
13846
+ const path15 = worktreeFor(target.paths, workName);
13847
+ const branch = cardWorkBranch(workName);
13813
13848
  await removeWorktree(target, path15).catch(() => {
13814
13849
  });
13815
13850
  await gitInDir(
@@ -14066,14 +14101,14 @@ function killTree(proc, signal = "SIGKILL") {
14066
14101
  function execLogin(command, opts) {
14067
14102
  const [bin, args] = isWindows ? ["bash", ["-c", command]] : [process.env.SHELL || "/bin/bash", ["-lc", command]];
14068
14103
  const cap = opts.maxBuffer ?? 4 * 1024 * 1024;
14069
- return new Promise((resolve2) => {
14104
+ return new Promise((resolve4) => {
14070
14105
  let output = "";
14071
14106
  let settled = false;
14072
14107
  const done = (code, extra = "") => {
14073
14108
  if (settled) return;
14074
14109
  settled = true;
14075
14110
  clearTimeout(timer);
14076
- resolve2({ code, output: (output + extra).slice(-cap) });
14111
+ resolve4({ code, output: (output + extra).slice(-cap) });
14077
14112
  };
14078
14113
  let proc;
14079
14114
  try {
@@ -14143,7 +14178,7 @@ async function allocateSpacePorts(spaceDir) {
14143
14178
  const ports = [];
14144
14179
  const seen = /* @__PURE__ */ new Set();
14145
14180
  while (ports.length < NUM_PORTS) {
14146
- const port = await new Promise((resolve2, reject) => {
14181
+ const port = await new Promise((resolve4, reject) => {
14147
14182
  const srv = import_net.default.createServer();
14148
14183
  srv.unref();
14149
14184
  srv.on("error", reject);
@@ -14151,7 +14186,7 @@ async function allocateSpacePorts(spaceDir) {
14151
14186
  const addr = srv.address();
14152
14187
  if (typeof addr === "object" && addr) {
14153
14188
  const p = addr.port;
14154
- srv.close(() => resolve2(p));
14189
+ srv.close(() => resolve4(p));
14155
14190
  } else {
14156
14191
  srv.close(() => reject(new Error("Failed to get a free port")));
14157
14192
  }
@@ -14221,7 +14256,7 @@ function hostTarget(spaceDir, extraEnv) {
14221
14256
  async runWithStdin(argv, input, label) {
14222
14257
  const [bin, ...rest] = argv;
14223
14258
  const env = await spawnEnv();
14224
- return new Promise((resolve2, reject) => {
14259
+ return new Promise((resolve4, reject) => {
14225
14260
  const proc = (0, import_child_process4.spawn)(bin, rest, { cwd: usableCwd(paths.root), env });
14226
14261
  let stderr = "";
14227
14262
  proc.stderr?.on("data", (d) => {
@@ -14229,7 +14264,7 @@ function hostTarget(spaceDir, extraEnv) {
14229
14264
  });
14230
14265
  proc.on("error", reject);
14231
14266
  proc.on("close", (code) => {
14232
- if (code === 0) resolve2();
14267
+ if (code === 0) resolve4();
14233
14268
  else reject(new Error(`${label}: ${stderr.trim()}`));
14234
14269
  });
14235
14270
  proc.stdin?.on("error", () => {
@@ -14398,6 +14433,9 @@ function createEventSink(send, spaceSlug, notify) {
14398
14433
  },
14399
14434
  emitDeployEnv(payload) {
14400
14435
  send(channel("deploy-env"), payload);
14436
+ },
14437
+ emitBareFsChange(postId, change) {
14438
+ send(channel(`bare-fs:${postId}`), change);
14401
14439
  }
14402
14440
  };
14403
14441
  }
@@ -14779,8 +14817,8 @@ var ClaudeModeEngine = class _ClaudeModeEngine {
14779
14817
  "system",
14780
14818
  "The agent has a question - waiting for your input."
14781
14819
  );
14782
- const answer = await new Promise((resolve2) => {
14783
- session.answerResolver = resolve2;
14820
+ const answer = await new Promise((resolve4) => {
14821
+ session.answerResolver = resolve4;
14784
14822
  });
14785
14823
  if (this.stopped(session)) return;
14786
14824
  session.phase = "research";
@@ -15242,6 +15280,15 @@ ${buildPrompt(prompts_default.implement)}`;
15242
15280
  // ../../shared/all/helpers/terminal-ai/terminal-mode.ts
15243
15281
  var import_crypto4 = require("crypto");
15244
15282
 
15283
+ // ../../shared/all/helpers/board-agent-core/boardTerminal.ts
15284
+ function boardTerminalKey(spaceSlug) {
15285
+ return `board-${spaceSlug}`;
15286
+ }
15287
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
15288
+ function isCardPostId(id) {
15289
+ return UUID_RE.test(id);
15290
+ }
15291
+
15245
15292
  // ../../shared/all/helpers/board-agent-core/tmux.ts
15246
15293
  var TMUX_CONF = [
15247
15294
  // Wheel scrolls, drag selects in copy mode.
@@ -15331,6 +15378,1865 @@ async function startTmuxSession(opts) {
15331
15378
  };
15332
15379
  }
15333
15380
 
15381
+ // ../../node_modules/chokidar/esm/index.js
15382
+ var import_fs8 = require("fs");
15383
+ var import_promises5 = require("fs/promises");
15384
+ var import_events = require("events");
15385
+ var sysPath2 = __toESM(require("path"), 1);
15386
+
15387
+ // ../../node_modules/readdirp/esm/index.js
15388
+ var import_promises3 = require("node:fs/promises");
15389
+ var import_node_stream = require("node:stream");
15390
+ var import_node_path = require("node:path");
15391
+ var EntryTypes = {
15392
+ FILE_TYPE: "files",
15393
+ DIR_TYPE: "directories",
15394
+ FILE_DIR_TYPE: "files_directories",
15395
+ EVERYTHING_TYPE: "all"
15396
+ };
15397
+ var defaultOptions = {
15398
+ root: ".",
15399
+ fileFilter: (_entryInfo) => true,
15400
+ directoryFilter: (_entryInfo) => true,
15401
+ type: EntryTypes.FILE_TYPE,
15402
+ lstat: false,
15403
+ depth: 2147483648,
15404
+ alwaysStat: false,
15405
+ highWaterMark: 4096
15406
+ };
15407
+ Object.freeze(defaultOptions);
15408
+ var RECURSIVE_ERROR_CODE = "READDIRP_RECURSIVE_ERROR";
15409
+ var NORMAL_FLOW_ERRORS = /* @__PURE__ */ new Set(["ENOENT", "EPERM", "EACCES", "ELOOP", RECURSIVE_ERROR_CODE]);
15410
+ var ALL_TYPES = [
15411
+ EntryTypes.DIR_TYPE,
15412
+ EntryTypes.EVERYTHING_TYPE,
15413
+ EntryTypes.FILE_DIR_TYPE,
15414
+ EntryTypes.FILE_TYPE
15415
+ ];
15416
+ var DIR_TYPES = /* @__PURE__ */ new Set([
15417
+ EntryTypes.DIR_TYPE,
15418
+ EntryTypes.EVERYTHING_TYPE,
15419
+ EntryTypes.FILE_DIR_TYPE
15420
+ ]);
15421
+ var FILE_TYPES = /* @__PURE__ */ new Set([
15422
+ EntryTypes.EVERYTHING_TYPE,
15423
+ EntryTypes.FILE_DIR_TYPE,
15424
+ EntryTypes.FILE_TYPE
15425
+ ]);
15426
+ var isNormalFlowError = (error) => NORMAL_FLOW_ERRORS.has(error.code);
15427
+ var wantBigintFsStats = process.platform === "win32";
15428
+ var emptyFn = (_entryInfo) => true;
15429
+ var normalizeFilter = (filter) => {
15430
+ if (filter === void 0)
15431
+ return emptyFn;
15432
+ if (typeof filter === "function")
15433
+ return filter;
15434
+ if (typeof filter === "string") {
15435
+ const fl = filter.trim();
15436
+ return (entry) => entry.basename === fl;
15437
+ }
15438
+ if (Array.isArray(filter)) {
15439
+ const trItems = filter.map((item) => item.trim());
15440
+ return (entry) => trItems.some((f) => entry.basename === f);
15441
+ }
15442
+ return emptyFn;
15443
+ };
15444
+ var ReaddirpStream = class extends import_node_stream.Readable {
15445
+ constructor(options = {}) {
15446
+ super({
15447
+ objectMode: true,
15448
+ autoDestroy: true,
15449
+ highWaterMark: options.highWaterMark
15450
+ });
15451
+ const opts = { ...defaultOptions, ...options };
15452
+ const { root, type } = opts;
15453
+ this._fileFilter = normalizeFilter(opts.fileFilter);
15454
+ this._directoryFilter = normalizeFilter(opts.directoryFilter);
15455
+ const statMethod = opts.lstat ? import_promises3.lstat : import_promises3.stat;
15456
+ if (wantBigintFsStats) {
15457
+ this._stat = (path15) => statMethod(path15, { bigint: true });
15458
+ } else {
15459
+ this._stat = statMethod;
15460
+ }
15461
+ this._maxDepth = opts.depth ?? defaultOptions.depth;
15462
+ this._wantsDir = type ? DIR_TYPES.has(type) : false;
15463
+ this._wantsFile = type ? FILE_TYPES.has(type) : false;
15464
+ this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
15465
+ this._root = (0, import_node_path.resolve)(root);
15466
+ this._isDirent = !opts.alwaysStat;
15467
+ this._statsProp = this._isDirent ? "dirent" : "stats";
15468
+ this._rdOptions = { encoding: "utf8", withFileTypes: this._isDirent };
15469
+ this.parents = [this._exploreDir(root, 1)];
15470
+ this.reading = false;
15471
+ this.parent = void 0;
15472
+ }
15473
+ async _read(batch) {
15474
+ if (this.reading)
15475
+ return;
15476
+ this.reading = true;
15477
+ try {
15478
+ while (!this.destroyed && batch > 0) {
15479
+ const par = this.parent;
15480
+ const fil = par && par.files;
15481
+ if (fil && fil.length > 0) {
15482
+ const { path: path15, depth } = par;
15483
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path15));
15484
+ const awaited = await Promise.all(slice);
15485
+ for (const entry of awaited) {
15486
+ if (!entry)
15487
+ continue;
15488
+ if (this.destroyed)
15489
+ return;
15490
+ const entryType = await this._getEntryType(entry);
15491
+ if (entryType === "directory" && this._directoryFilter(entry)) {
15492
+ if (depth <= this._maxDepth) {
15493
+ this.parents.push(this._exploreDir(entry.fullPath, depth + 1));
15494
+ }
15495
+ if (this._wantsDir) {
15496
+ this.push(entry);
15497
+ batch--;
15498
+ }
15499
+ } else if ((entryType === "file" || this._includeAsFile(entry)) && this._fileFilter(entry)) {
15500
+ if (this._wantsFile) {
15501
+ this.push(entry);
15502
+ batch--;
15503
+ }
15504
+ }
15505
+ }
15506
+ } else {
15507
+ const parent = this.parents.pop();
15508
+ if (!parent) {
15509
+ this.push(null);
15510
+ break;
15511
+ }
15512
+ this.parent = await parent;
15513
+ if (this.destroyed)
15514
+ return;
15515
+ }
15516
+ }
15517
+ } catch (error) {
15518
+ this.destroy(error);
15519
+ } finally {
15520
+ this.reading = false;
15521
+ }
15522
+ }
15523
+ async _exploreDir(path15, depth) {
15524
+ let files;
15525
+ try {
15526
+ files = await (0, import_promises3.readdir)(path15, this._rdOptions);
15527
+ } catch (error) {
15528
+ this._onError(error);
15529
+ }
15530
+ return { files, depth, path: path15 };
15531
+ }
15532
+ async _formatEntry(dirent, path15) {
15533
+ let entry;
15534
+ const basename3 = this._isDirent ? dirent.name : dirent;
15535
+ try {
15536
+ const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path15, basename3));
15537
+ entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename3 };
15538
+ entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
15539
+ } catch (err) {
15540
+ this._onError(err);
15541
+ return;
15542
+ }
15543
+ return entry;
15544
+ }
15545
+ _onError(err) {
15546
+ if (isNormalFlowError(err) && !this.destroyed) {
15547
+ this.emit("warn", err);
15548
+ } else {
15549
+ this.destroy(err);
15550
+ }
15551
+ }
15552
+ async _getEntryType(entry) {
15553
+ if (!entry && this._statsProp in entry) {
15554
+ return "";
15555
+ }
15556
+ const stats = entry[this._statsProp];
15557
+ if (stats.isFile())
15558
+ return "file";
15559
+ if (stats.isDirectory())
15560
+ return "directory";
15561
+ if (stats && stats.isSymbolicLink()) {
15562
+ const full = entry.fullPath;
15563
+ try {
15564
+ const entryRealPath = await (0, import_promises3.realpath)(full);
15565
+ const entryRealPathStats = await (0, import_promises3.lstat)(entryRealPath);
15566
+ if (entryRealPathStats.isFile()) {
15567
+ return "file";
15568
+ }
15569
+ if (entryRealPathStats.isDirectory()) {
15570
+ const len = entryRealPath.length;
15571
+ if (full.startsWith(entryRealPath) && full.substr(len, 1) === import_node_path.sep) {
15572
+ const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`);
15573
+ recursiveError.code = RECURSIVE_ERROR_CODE;
15574
+ return this._onError(recursiveError);
15575
+ }
15576
+ return "directory";
15577
+ }
15578
+ } catch (error) {
15579
+ this._onError(error);
15580
+ return "";
15581
+ }
15582
+ }
15583
+ }
15584
+ _includeAsFile(entry) {
15585
+ const stats = entry && entry[this._statsProp];
15586
+ return stats && this._wantsEverything && !stats.isDirectory();
15587
+ }
15588
+ };
15589
+ function readdirp(root, options = {}) {
15590
+ let type = options.entryType || options.type;
15591
+ if (type === "both")
15592
+ type = EntryTypes.FILE_DIR_TYPE;
15593
+ if (type)
15594
+ options.type = type;
15595
+ if (!root) {
15596
+ throw new Error("readdirp: root argument is required. Usage: readdirp(root, options)");
15597
+ } else if (typeof root !== "string") {
15598
+ throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");
15599
+ } else if (type && !ALL_TYPES.includes(type)) {
15600
+ throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(", ")}`);
15601
+ }
15602
+ options.root = root;
15603
+ return new ReaddirpStream(options);
15604
+ }
15605
+
15606
+ // ../../node_modules/chokidar/esm/handler.js
15607
+ var import_fs7 = require("fs");
15608
+ var import_promises4 = require("fs/promises");
15609
+ var sysPath = __toESM(require("path"), 1);
15610
+ var import_os4 = require("os");
15611
+ var STR_DATA = "data";
15612
+ var STR_END = "end";
15613
+ var STR_CLOSE = "close";
15614
+ var EMPTY_FN = () => {
15615
+ };
15616
+ var pl = process.platform;
15617
+ var isWindows2 = pl === "win32";
15618
+ var isMacos = pl === "darwin";
15619
+ var isLinux = pl === "linux";
15620
+ var isFreeBSD = pl === "freebsd";
15621
+ var isIBMi = (0, import_os4.type)() === "OS400";
15622
+ var EVENTS = {
15623
+ ALL: "all",
15624
+ READY: "ready",
15625
+ ADD: "add",
15626
+ CHANGE: "change",
15627
+ ADD_DIR: "addDir",
15628
+ UNLINK: "unlink",
15629
+ UNLINK_DIR: "unlinkDir",
15630
+ RAW: "raw",
15631
+ ERROR: "error"
15632
+ };
15633
+ var EV = EVENTS;
15634
+ var THROTTLE_MODE_WATCH = "watch";
15635
+ var statMethods = { lstat: import_promises4.lstat, stat: import_promises4.stat };
15636
+ var KEY_LISTENERS = "listeners";
15637
+ var KEY_ERR = "errHandlers";
15638
+ var KEY_RAW = "rawEmitters";
15639
+ var HANDLER_KEYS = [KEY_LISTENERS, KEY_ERR, KEY_RAW];
15640
+ var binaryExtensions = /* @__PURE__ */ new Set([
15641
+ "3dm",
15642
+ "3ds",
15643
+ "3g2",
15644
+ "3gp",
15645
+ "7z",
15646
+ "a",
15647
+ "aac",
15648
+ "adp",
15649
+ "afdesign",
15650
+ "afphoto",
15651
+ "afpub",
15652
+ "ai",
15653
+ "aif",
15654
+ "aiff",
15655
+ "alz",
15656
+ "ape",
15657
+ "apk",
15658
+ "appimage",
15659
+ "ar",
15660
+ "arj",
15661
+ "asf",
15662
+ "au",
15663
+ "avi",
15664
+ "bak",
15665
+ "baml",
15666
+ "bh",
15667
+ "bin",
15668
+ "bk",
15669
+ "bmp",
15670
+ "btif",
15671
+ "bz2",
15672
+ "bzip2",
15673
+ "cab",
15674
+ "caf",
15675
+ "cgm",
15676
+ "class",
15677
+ "cmx",
15678
+ "cpio",
15679
+ "cr2",
15680
+ "cur",
15681
+ "dat",
15682
+ "dcm",
15683
+ "deb",
15684
+ "dex",
15685
+ "djvu",
15686
+ "dll",
15687
+ "dmg",
15688
+ "dng",
15689
+ "doc",
15690
+ "docm",
15691
+ "docx",
15692
+ "dot",
15693
+ "dotm",
15694
+ "dra",
15695
+ "DS_Store",
15696
+ "dsk",
15697
+ "dts",
15698
+ "dtshd",
15699
+ "dvb",
15700
+ "dwg",
15701
+ "dxf",
15702
+ "ecelp4800",
15703
+ "ecelp7470",
15704
+ "ecelp9600",
15705
+ "egg",
15706
+ "eol",
15707
+ "eot",
15708
+ "epub",
15709
+ "exe",
15710
+ "f4v",
15711
+ "fbs",
15712
+ "fh",
15713
+ "fla",
15714
+ "flac",
15715
+ "flatpak",
15716
+ "fli",
15717
+ "flv",
15718
+ "fpx",
15719
+ "fst",
15720
+ "fvt",
15721
+ "g3",
15722
+ "gh",
15723
+ "gif",
15724
+ "graffle",
15725
+ "gz",
15726
+ "gzip",
15727
+ "h261",
15728
+ "h263",
15729
+ "h264",
15730
+ "icns",
15731
+ "ico",
15732
+ "ief",
15733
+ "img",
15734
+ "ipa",
15735
+ "iso",
15736
+ "jar",
15737
+ "jpeg",
15738
+ "jpg",
15739
+ "jpgv",
15740
+ "jpm",
15741
+ "jxr",
15742
+ "key",
15743
+ "ktx",
15744
+ "lha",
15745
+ "lib",
15746
+ "lvp",
15747
+ "lz",
15748
+ "lzh",
15749
+ "lzma",
15750
+ "lzo",
15751
+ "m3u",
15752
+ "m4a",
15753
+ "m4v",
15754
+ "mar",
15755
+ "mdi",
15756
+ "mht",
15757
+ "mid",
15758
+ "midi",
15759
+ "mj2",
15760
+ "mka",
15761
+ "mkv",
15762
+ "mmr",
15763
+ "mng",
15764
+ "mobi",
15765
+ "mov",
15766
+ "movie",
15767
+ "mp3",
15768
+ "mp4",
15769
+ "mp4a",
15770
+ "mpeg",
15771
+ "mpg",
15772
+ "mpga",
15773
+ "mxu",
15774
+ "nef",
15775
+ "npx",
15776
+ "numbers",
15777
+ "nupkg",
15778
+ "o",
15779
+ "odp",
15780
+ "ods",
15781
+ "odt",
15782
+ "oga",
15783
+ "ogg",
15784
+ "ogv",
15785
+ "otf",
15786
+ "ott",
15787
+ "pages",
15788
+ "pbm",
15789
+ "pcx",
15790
+ "pdb",
15791
+ "pdf",
15792
+ "pea",
15793
+ "pgm",
15794
+ "pic",
15795
+ "png",
15796
+ "pnm",
15797
+ "pot",
15798
+ "potm",
15799
+ "potx",
15800
+ "ppa",
15801
+ "ppam",
15802
+ "ppm",
15803
+ "pps",
15804
+ "ppsm",
15805
+ "ppsx",
15806
+ "ppt",
15807
+ "pptm",
15808
+ "pptx",
15809
+ "psd",
15810
+ "pya",
15811
+ "pyc",
15812
+ "pyo",
15813
+ "pyv",
15814
+ "qt",
15815
+ "rar",
15816
+ "ras",
15817
+ "raw",
15818
+ "resources",
15819
+ "rgb",
15820
+ "rip",
15821
+ "rlc",
15822
+ "rmf",
15823
+ "rmvb",
15824
+ "rpm",
15825
+ "rtf",
15826
+ "rz",
15827
+ "s3m",
15828
+ "s7z",
15829
+ "scpt",
15830
+ "sgi",
15831
+ "shar",
15832
+ "snap",
15833
+ "sil",
15834
+ "sketch",
15835
+ "slk",
15836
+ "smv",
15837
+ "snk",
15838
+ "so",
15839
+ "stl",
15840
+ "suo",
15841
+ "sub",
15842
+ "swf",
15843
+ "tar",
15844
+ "tbz",
15845
+ "tbz2",
15846
+ "tga",
15847
+ "tgz",
15848
+ "thmx",
15849
+ "tif",
15850
+ "tiff",
15851
+ "tlz",
15852
+ "ttc",
15853
+ "ttf",
15854
+ "txz",
15855
+ "udf",
15856
+ "uvh",
15857
+ "uvi",
15858
+ "uvm",
15859
+ "uvp",
15860
+ "uvs",
15861
+ "uvu",
15862
+ "viv",
15863
+ "vob",
15864
+ "war",
15865
+ "wav",
15866
+ "wax",
15867
+ "wbmp",
15868
+ "wdp",
15869
+ "weba",
15870
+ "webm",
15871
+ "webp",
15872
+ "whl",
15873
+ "wim",
15874
+ "wm",
15875
+ "wma",
15876
+ "wmv",
15877
+ "wmx",
15878
+ "woff",
15879
+ "woff2",
15880
+ "wrm",
15881
+ "wvx",
15882
+ "xbm",
15883
+ "xif",
15884
+ "xla",
15885
+ "xlam",
15886
+ "xls",
15887
+ "xlsb",
15888
+ "xlsm",
15889
+ "xlsx",
15890
+ "xlt",
15891
+ "xltm",
15892
+ "xltx",
15893
+ "xm",
15894
+ "xmind",
15895
+ "xpi",
15896
+ "xpm",
15897
+ "xwd",
15898
+ "xz",
15899
+ "z",
15900
+ "zip",
15901
+ "zipx"
15902
+ ]);
15903
+ var isBinaryPath = (filePath) => binaryExtensions.has(sysPath.extname(filePath).slice(1).toLowerCase());
15904
+ var foreach = (val, fn) => {
15905
+ if (val instanceof Set) {
15906
+ val.forEach(fn);
15907
+ } else {
15908
+ fn(val);
15909
+ }
15910
+ };
15911
+ var addAndConvert = (main, prop, item) => {
15912
+ let container = main[prop];
15913
+ if (!(container instanceof Set)) {
15914
+ main[prop] = container = /* @__PURE__ */ new Set([container]);
15915
+ }
15916
+ container.add(item);
15917
+ };
15918
+ var clearItem = (cont) => (key) => {
15919
+ const set = cont[key];
15920
+ if (set instanceof Set) {
15921
+ set.clear();
15922
+ } else {
15923
+ delete cont[key];
15924
+ }
15925
+ };
15926
+ var delFromSet = (main, prop, item) => {
15927
+ const container = main[prop];
15928
+ if (container instanceof Set) {
15929
+ container.delete(item);
15930
+ } else if (container === item) {
15931
+ delete main[prop];
15932
+ }
15933
+ };
15934
+ var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
15935
+ var FsWatchInstances = /* @__PURE__ */ new Map();
15936
+ function createFsWatchInstance(path15, options, listener, errHandler, emitRaw) {
15937
+ const handleEvent = (rawEvent, evPath) => {
15938
+ listener(path15);
15939
+ emitRaw(rawEvent, evPath, { watchedPath: path15 });
15940
+ if (evPath && path15 !== evPath) {
15941
+ fsWatchBroadcast(sysPath.resolve(path15, evPath), KEY_LISTENERS, sysPath.join(path15, evPath));
15942
+ }
15943
+ };
15944
+ try {
15945
+ return (0, import_fs7.watch)(path15, {
15946
+ persistent: options.persistent
15947
+ }, handleEvent);
15948
+ } catch (error) {
15949
+ errHandler(error);
15950
+ return void 0;
15951
+ }
15952
+ }
15953
+ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
15954
+ const cont = FsWatchInstances.get(fullPath);
15955
+ if (!cont)
15956
+ return;
15957
+ foreach(cont[listenerType], (listener) => {
15958
+ listener(val1, val2, val3);
15959
+ });
15960
+ };
15961
+ var setFsWatchListener = (path15, fullPath, options, handlers) => {
15962
+ const { listener, errHandler, rawEmitter } = handlers;
15963
+ let cont = FsWatchInstances.get(fullPath);
15964
+ let watcher;
15965
+ if (!options.persistent) {
15966
+ watcher = createFsWatchInstance(path15, options, listener, errHandler, rawEmitter);
15967
+ if (!watcher)
15968
+ return;
15969
+ return watcher.close.bind(watcher);
15970
+ }
15971
+ if (cont) {
15972
+ addAndConvert(cont, KEY_LISTENERS, listener);
15973
+ addAndConvert(cont, KEY_ERR, errHandler);
15974
+ addAndConvert(cont, KEY_RAW, rawEmitter);
15975
+ } else {
15976
+ watcher = createFsWatchInstance(
15977
+ path15,
15978
+ options,
15979
+ fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
15980
+ errHandler,
15981
+ // no need to use broadcast here
15982
+ fsWatchBroadcast.bind(null, fullPath, KEY_RAW)
15983
+ );
15984
+ if (!watcher)
15985
+ return;
15986
+ watcher.on(EV.ERROR, async (error) => {
15987
+ const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR);
15988
+ if (cont)
15989
+ cont.watcherUnusable = true;
15990
+ if (isWindows2 && error.code === "EPERM") {
15991
+ try {
15992
+ const fd = await (0, import_promises4.open)(path15, "r");
15993
+ await fd.close();
15994
+ broadcastErr(error);
15995
+ } catch (err) {
15996
+ }
15997
+ } else {
15998
+ broadcastErr(error);
15999
+ }
16000
+ });
16001
+ cont = {
16002
+ listeners: listener,
16003
+ errHandlers: errHandler,
16004
+ rawEmitters: rawEmitter,
16005
+ watcher
16006
+ };
16007
+ FsWatchInstances.set(fullPath, cont);
16008
+ }
16009
+ return () => {
16010
+ delFromSet(cont, KEY_LISTENERS, listener);
16011
+ delFromSet(cont, KEY_ERR, errHandler);
16012
+ delFromSet(cont, KEY_RAW, rawEmitter);
16013
+ if (isEmptySet(cont.listeners)) {
16014
+ cont.watcher.close();
16015
+ FsWatchInstances.delete(fullPath);
16016
+ HANDLER_KEYS.forEach(clearItem(cont));
16017
+ cont.watcher = void 0;
16018
+ Object.freeze(cont);
16019
+ }
16020
+ };
16021
+ };
16022
+ var FsWatchFileInstances = /* @__PURE__ */ new Map();
16023
+ var setFsWatchFileListener = (path15, fullPath, options, handlers) => {
16024
+ const { listener, rawEmitter } = handlers;
16025
+ let cont = FsWatchFileInstances.get(fullPath);
16026
+ const copts = cont && cont.options;
16027
+ if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
16028
+ (0, import_fs7.unwatchFile)(fullPath);
16029
+ cont = void 0;
16030
+ }
16031
+ if (cont) {
16032
+ addAndConvert(cont, KEY_LISTENERS, listener);
16033
+ addAndConvert(cont, KEY_RAW, rawEmitter);
16034
+ } else {
16035
+ cont = {
16036
+ listeners: listener,
16037
+ rawEmitters: rawEmitter,
16038
+ options,
16039
+ watcher: (0, import_fs7.watchFile)(fullPath, options, (curr, prev) => {
16040
+ foreach(cont.rawEmitters, (rawEmitter2) => {
16041
+ rawEmitter2(EV.CHANGE, fullPath, { curr, prev });
16042
+ });
16043
+ const currmtime = curr.mtimeMs;
16044
+ if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
16045
+ foreach(cont.listeners, (listener2) => listener2(path15, curr));
16046
+ }
16047
+ })
16048
+ };
16049
+ FsWatchFileInstances.set(fullPath, cont);
16050
+ }
16051
+ return () => {
16052
+ delFromSet(cont, KEY_LISTENERS, listener);
16053
+ delFromSet(cont, KEY_RAW, rawEmitter);
16054
+ if (isEmptySet(cont.listeners)) {
16055
+ FsWatchFileInstances.delete(fullPath);
16056
+ (0, import_fs7.unwatchFile)(fullPath);
16057
+ cont.options = cont.watcher = void 0;
16058
+ Object.freeze(cont);
16059
+ }
16060
+ };
16061
+ };
16062
+ var NodeFsHandler = class {
16063
+ constructor(fsW) {
16064
+ this.fsw = fsW;
16065
+ this._boundHandleError = (error) => fsW._handleError(error);
16066
+ }
16067
+ /**
16068
+ * Watch file for changes with fs_watchFile or fs_watch.
16069
+ * @param path to file or dir
16070
+ * @param listener on fs change
16071
+ * @returns closer for the watcher instance
16072
+ */
16073
+ _watchWithNodeFs(path15, listener) {
16074
+ const opts = this.fsw.options;
16075
+ const directory = sysPath.dirname(path15);
16076
+ const basename3 = sysPath.basename(path15);
16077
+ const parent = this.fsw._getWatchedDir(directory);
16078
+ parent.add(basename3);
16079
+ const absolutePath = sysPath.resolve(path15);
16080
+ const options = {
16081
+ persistent: opts.persistent
16082
+ };
16083
+ if (!listener)
16084
+ listener = EMPTY_FN;
16085
+ let closer;
16086
+ if (opts.usePolling) {
16087
+ const enableBin = opts.interval !== opts.binaryInterval;
16088
+ options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
16089
+ closer = setFsWatchFileListener(path15, absolutePath, options, {
16090
+ listener,
16091
+ rawEmitter: this.fsw._emitRaw
16092
+ });
16093
+ } else {
16094
+ closer = setFsWatchListener(path15, absolutePath, options, {
16095
+ listener,
16096
+ errHandler: this._boundHandleError,
16097
+ rawEmitter: this.fsw._emitRaw
16098
+ });
16099
+ }
16100
+ return closer;
16101
+ }
16102
+ /**
16103
+ * Watch a file and emit add event if warranted.
16104
+ * @returns closer for the watcher instance
16105
+ */
16106
+ _handleFile(file, stats, initialAdd) {
16107
+ if (this.fsw.closed) {
16108
+ return;
16109
+ }
16110
+ const dirname4 = sysPath.dirname(file);
16111
+ const basename3 = sysPath.basename(file);
16112
+ const parent = this.fsw._getWatchedDir(dirname4);
16113
+ let prevStats = stats;
16114
+ if (parent.has(basename3))
16115
+ return;
16116
+ const listener = async (path15, newStats) => {
16117
+ if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
16118
+ return;
16119
+ if (!newStats || newStats.mtimeMs === 0) {
16120
+ try {
16121
+ const newStats2 = await (0, import_promises4.stat)(file);
16122
+ if (this.fsw.closed)
16123
+ return;
16124
+ const at = newStats2.atimeMs;
16125
+ const mt = newStats2.mtimeMs;
16126
+ if (!at || at <= mt || mt !== prevStats.mtimeMs) {
16127
+ this.fsw._emit(EV.CHANGE, file, newStats2);
16128
+ }
16129
+ if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
16130
+ this.fsw._closeFile(path15);
16131
+ prevStats = newStats2;
16132
+ const closer2 = this._watchWithNodeFs(file, listener);
16133
+ if (closer2)
16134
+ this.fsw._addPathCloser(path15, closer2);
16135
+ } else {
16136
+ prevStats = newStats2;
16137
+ }
16138
+ } catch (error) {
16139
+ this.fsw._remove(dirname4, basename3);
16140
+ }
16141
+ } else if (parent.has(basename3)) {
16142
+ const at = newStats.atimeMs;
16143
+ const mt = newStats.mtimeMs;
16144
+ if (!at || at <= mt || mt !== prevStats.mtimeMs) {
16145
+ this.fsw._emit(EV.CHANGE, file, newStats);
16146
+ }
16147
+ prevStats = newStats;
16148
+ }
16149
+ };
16150
+ const closer = this._watchWithNodeFs(file, listener);
16151
+ if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) {
16152
+ if (!this.fsw._throttle(EV.ADD, file, 0))
16153
+ return;
16154
+ this.fsw._emit(EV.ADD, file, stats);
16155
+ }
16156
+ return closer;
16157
+ }
16158
+ /**
16159
+ * Handle symlinks encountered while reading a dir.
16160
+ * @param entry returned by readdirp
16161
+ * @param directory path of dir being read
16162
+ * @param path of this item
16163
+ * @param item basename of this item
16164
+ * @returns true if no more processing is needed for this entry.
16165
+ */
16166
+ async _handleSymlink(entry, directory, path15, item) {
16167
+ if (this.fsw.closed) {
16168
+ return;
16169
+ }
16170
+ const full = entry.fullPath;
16171
+ const dir = this.fsw._getWatchedDir(directory);
16172
+ if (!this.fsw.options.followSymlinks) {
16173
+ this.fsw._incrReadyCount();
16174
+ let linkPath;
16175
+ try {
16176
+ linkPath = await (0, import_promises4.realpath)(path15);
16177
+ } catch (e) {
16178
+ this.fsw._emitReady();
16179
+ return true;
16180
+ }
16181
+ if (this.fsw.closed)
16182
+ return;
16183
+ if (dir.has(item)) {
16184
+ if (this.fsw._symlinkPaths.get(full) !== linkPath) {
16185
+ this.fsw._symlinkPaths.set(full, linkPath);
16186
+ this.fsw._emit(EV.CHANGE, path15, entry.stats);
16187
+ }
16188
+ } else {
16189
+ dir.add(item);
16190
+ this.fsw._symlinkPaths.set(full, linkPath);
16191
+ this.fsw._emit(EV.ADD, path15, entry.stats);
16192
+ }
16193
+ this.fsw._emitReady();
16194
+ return true;
16195
+ }
16196
+ if (this.fsw._symlinkPaths.has(full)) {
16197
+ return true;
16198
+ }
16199
+ this.fsw._symlinkPaths.set(full, true);
16200
+ }
16201
+ _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) {
16202
+ directory = sysPath.join(directory, "");
16203
+ throttler = this.fsw._throttle("readdir", directory, 1e3);
16204
+ if (!throttler)
16205
+ return;
16206
+ const previous = this.fsw._getWatchedDir(wh.path);
16207
+ const current = /* @__PURE__ */ new Set();
16208
+ let stream = this.fsw._readdirp(directory, {
16209
+ fileFilter: (entry) => wh.filterPath(entry),
16210
+ directoryFilter: (entry) => wh.filterDir(entry)
16211
+ });
16212
+ if (!stream)
16213
+ return;
16214
+ stream.on(STR_DATA, async (entry) => {
16215
+ if (this.fsw.closed) {
16216
+ stream = void 0;
16217
+ return;
16218
+ }
16219
+ const item = entry.path;
16220
+ let path15 = sysPath.join(directory, item);
16221
+ current.add(item);
16222
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path15, item)) {
16223
+ return;
16224
+ }
16225
+ if (this.fsw.closed) {
16226
+ stream = void 0;
16227
+ return;
16228
+ }
16229
+ if (item === target || !target && !previous.has(item)) {
16230
+ this.fsw._incrReadyCount();
16231
+ path15 = sysPath.join(dir, sysPath.relative(dir, path15));
16232
+ this._addToNodeFs(path15, initialAdd, wh, depth + 1);
16233
+ }
16234
+ }).on(EV.ERROR, this._boundHandleError);
16235
+ return new Promise((resolve4, reject) => {
16236
+ if (!stream)
16237
+ return reject();
16238
+ stream.once(STR_END, () => {
16239
+ if (this.fsw.closed) {
16240
+ stream = void 0;
16241
+ return;
16242
+ }
16243
+ const wasThrottled = throttler ? throttler.clear() : false;
16244
+ resolve4(void 0);
16245
+ previous.getChildren().filter((item) => {
16246
+ return item !== directory && !current.has(item);
16247
+ }).forEach((item) => {
16248
+ this.fsw._remove(directory, item);
16249
+ });
16250
+ stream = void 0;
16251
+ if (wasThrottled)
16252
+ this._handleRead(directory, false, wh, target, dir, depth, throttler);
16253
+ });
16254
+ });
16255
+ }
16256
+ /**
16257
+ * Read directory to add / remove files from `@watched` list and re-read it on change.
16258
+ * @param dir fs path
16259
+ * @param stats
16260
+ * @param initialAdd
16261
+ * @param depth relative to user-supplied path
16262
+ * @param target child path targeted for watch
16263
+ * @param wh Common watch helpers for this path
16264
+ * @param realpath
16265
+ * @returns closer for the watcher instance.
16266
+ */
16267
+ async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath2) {
16268
+ const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir));
16269
+ const tracked = parentDir.has(sysPath.basename(dir));
16270
+ if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) {
16271
+ this.fsw._emit(EV.ADD_DIR, dir, stats);
16272
+ }
16273
+ parentDir.add(sysPath.basename(dir));
16274
+ this.fsw._getWatchedDir(dir);
16275
+ let throttler;
16276
+ let closer;
16277
+ const oDepth = this.fsw.options.depth;
16278
+ if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath2)) {
16279
+ if (!target) {
16280
+ await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler);
16281
+ if (this.fsw.closed)
16282
+ return;
16283
+ }
16284
+ closer = this._watchWithNodeFs(dir, (dirPath, stats2) => {
16285
+ if (stats2 && stats2.mtimeMs === 0)
16286
+ return;
16287
+ this._handleRead(dirPath, false, wh, target, dir, depth, throttler);
16288
+ });
16289
+ }
16290
+ return closer;
16291
+ }
16292
+ /**
16293
+ * Handle added file, directory, or glob pattern.
16294
+ * Delegates call to _handleFile / _handleDir after checks.
16295
+ * @param path to file or ir
16296
+ * @param initialAdd was the file added at watch instantiation?
16297
+ * @param priorWh depth relative to user-supplied path
16298
+ * @param depth Child path actually targeted for watch
16299
+ * @param target Child path actually targeted for watch
16300
+ */
16301
+ async _addToNodeFs(path15, initialAdd, priorWh, depth, target) {
16302
+ const ready = this.fsw._emitReady;
16303
+ if (this.fsw._isIgnored(path15) || this.fsw.closed) {
16304
+ ready();
16305
+ return false;
16306
+ }
16307
+ const wh = this.fsw._getWatchHelpers(path15);
16308
+ if (priorWh) {
16309
+ wh.filterPath = (entry) => priorWh.filterPath(entry);
16310
+ wh.filterDir = (entry) => priorWh.filterDir(entry);
16311
+ }
16312
+ try {
16313
+ const stats = await statMethods[wh.statMethod](wh.watchPath);
16314
+ if (this.fsw.closed)
16315
+ return;
16316
+ if (this.fsw._isIgnored(wh.watchPath, stats)) {
16317
+ ready();
16318
+ return false;
16319
+ }
16320
+ const follow = this.fsw.options.followSymlinks;
16321
+ let closer;
16322
+ if (stats.isDirectory()) {
16323
+ const absPath = sysPath.resolve(path15);
16324
+ const targetPath = follow ? await (0, import_promises4.realpath)(path15) : path15;
16325
+ if (this.fsw.closed)
16326
+ return;
16327
+ closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
16328
+ if (this.fsw.closed)
16329
+ return;
16330
+ if (absPath !== targetPath && targetPath !== void 0) {
16331
+ this.fsw._symlinkPaths.set(absPath, targetPath);
16332
+ }
16333
+ } else if (stats.isSymbolicLink()) {
16334
+ const targetPath = follow ? await (0, import_promises4.realpath)(path15) : path15;
16335
+ if (this.fsw.closed)
16336
+ return;
16337
+ const parent = sysPath.dirname(wh.watchPath);
16338
+ this.fsw._getWatchedDir(parent).add(wh.watchPath);
16339
+ this.fsw._emit(EV.ADD, wh.watchPath, stats);
16340
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path15, wh, targetPath);
16341
+ if (this.fsw.closed)
16342
+ return;
16343
+ if (targetPath !== void 0) {
16344
+ this.fsw._symlinkPaths.set(sysPath.resolve(path15), targetPath);
16345
+ }
16346
+ } else {
16347
+ closer = this._handleFile(wh.watchPath, stats, initialAdd);
16348
+ }
16349
+ ready();
16350
+ if (closer)
16351
+ this.fsw._addPathCloser(path15, closer);
16352
+ return false;
16353
+ } catch (error) {
16354
+ if (this.fsw._handleError(error)) {
16355
+ ready();
16356
+ return path15;
16357
+ }
16358
+ }
16359
+ }
16360
+ };
16361
+
16362
+ // ../../node_modules/chokidar/esm/index.js
16363
+ var SLASH = "/";
16364
+ var SLASH_SLASH = "//";
16365
+ var ONE_DOT = ".";
16366
+ var TWO_DOTS = "..";
16367
+ var STRING_TYPE = "string";
16368
+ var BACK_SLASH_RE = /\\/g;
16369
+ var DOUBLE_SLASH_RE = /\/\//;
16370
+ var DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/;
16371
+ var REPLACER_RE = /^\.[/\\]/;
16372
+ function arrify(item) {
16373
+ return Array.isArray(item) ? item : [item];
16374
+ }
16375
+ var isMatcherObject = (matcher) => typeof matcher === "object" && matcher !== null && !(matcher instanceof RegExp);
16376
+ function createPattern(matcher) {
16377
+ if (typeof matcher === "function")
16378
+ return matcher;
16379
+ if (typeof matcher === "string")
16380
+ return (string) => matcher === string;
16381
+ if (matcher instanceof RegExp)
16382
+ return (string) => matcher.test(string);
16383
+ if (typeof matcher === "object" && matcher !== null) {
16384
+ return (string) => {
16385
+ if (matcher.path === string)
16386
+ return true;
16387
+ if (matcher.recursive) {
16388
+ const relative3 = sysPath2.relative(matcher.path, string);
16389
+ if (!relative3) {
16390
+ return false;
16391
+ }
16392
+ return !relative3.startsWith("..") && !sysPath2.isAbsolute(relative3);
16393
+ }
16394
+ return false;
16395
+ };
16396
+ }
16397
+ return () => false;
16398
+ }
16399
+ function normalizePath(path15) {
16400
+ if (typeof path15 !== "string")
16401
+ throw new Error("string expected");
16402
+ path15 = sysPath2.normalize(path15);
16403
+ path15 = path15.replace(/\\/g, "/");
16404
+ let prepend = false;
16405
+ if (path15.startsWith("//"))
16406
+ prepend = true;
16407
+ const DOUBLE_SLASH_RE2 = /\/\//;
16408
+ while (path15.match(DOUBLE_SLASH_RE2))
16409
+ path15 = path15.replace(DOUBLE_SLASH_RE2, "/");
16410
+ if (prepend)
16411
+ path15 = "/" + path15;
16412
+ return path15;
16413
+ }
16414
+ function matchPatterns(patterns, testString, stats) {
16415
+ const path15 = normalizePath(testString);
16416
+ for (let index = 0; index < patterns.length; index++) {
16417
+ const pattern = patterns[index];
16418
+ if (pattern(path15, stats)) {
16419
+ return true;
16420
+ }
16421
+ }
16422
+ return false;
16423
+ }
16424
+ function anymatch(matchers, testString) {
16425
+ if (matchers == null) {
16426
+ throw new TypeError("anymatch: specify first argument");
16427
+ }
16428
+ const matchersArray = arrify(matchers);
16429
+ const patterns = matchersArray.map((matcher) => createPattern(matcher));
16430
+ if (testString == null) {
16431
+ return (testString2, stats) => {
16432
+ return matchPatterns(patterns, testString2, stats);
16433
+ };
16434
+ }
16435
+ return matchPatterns(patterns, testString);
16436
+ }
16437
+ var unifyPaths = (paths_) => {
16438
+ const paths = arrify(paths_).flat();
16439
+ if (!paths.every((p) => typeof p === STRING_TYPE)) {
16440
+ throw new TypeError(`Non-string provided as watch path: ${paths}`);
16441
+ }
16442
+ return paths.map(normalizePathToUnix);
16443
+ };
16444
+ var toUnix = (string) => {
16445
+ let str = string.replace(BACK_SLASH_RE, SLASH);
16446
+ let prepend = false;
16447
+ if (str.startsWith(SLASH_SLASH)) {
16448
+ prepend = true;
16449
+ }
16450
+ while (str.match(DOUBLE_SLASH_RE)) {
16451
+ str = str.replace(DOUBLE_SLASH_RE, SLASH);
16452
+ }
16453
+ if (prepend) {
16454
+ str = SLASH + str;
16455
+ }
16456
+ return str;
16457
+ };
16458
+ var normalizePathToUnix = (path15) => toUnix(sysPath2.normalize(toUnix(path15)));
16459
+ var normalizeIgnored = (cwd = "") => (path15) => {
16460
+ if (typeof path15 === "string") {
16461
+ return normalizePathToUnix(sysPath2.isAbsolute(path15) ? path15 : sysPath2.join(cwd, path15));
16462
+ } else {
16463
+ return path15;
16464
+ }
16465
+ };
16466
+ var getAbsolutePath = (path15, cwd) => {
16467
+ if (sysPath2.isAbsolute(path15)) {
16468
+ return path15;
16469
+ }
16470
+ return sysPath2.join(cwd, path15);
16471
+ };
16472
+ var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
16473
+ var DirEntry = class {
16474
+ constructor(dir, removeWatcher) {
16475
+ this.path = dir;
16476
+ this._removeWatcher = removeWatcher;
16477
+ this.items = /* @__PURE__ */ new Set();
16478
+ }
16479
+ add(item) {
16480
+ const { items } = this;
16481
+ if (!items)
16482
+ return;
16483
+ if (item !== ONE_DOT && item !== TWO_DOTS)
16484
+ items.add(item);
16485
+ }
16486
+ async remove(item) {
16487
+ const { items } = this;
16488
+ if (!items)
16489
+ return;
16490
+ items.delete(item);
16491
+ if (items.size > 0)
16492
+ return;
16493
+ const dir = this.path;
16494
+ try {
16495
+ await (0, import_promises5.readdir)(dir);
16496
+ } catch (err) {
16497
+ if (this._removeWatcher) {
16498
+ this._removeWatcher(sysPath2.dirname(dir), sysPath2.basename(dir));
16499
+ }
16500
+ }
16501
+ }
16502
+ has(item) {
16503
+ const { items } = this;
16504
+ if (!items)
16505
+ return;
16506
+ return items.has(item);
16507
+ }
16508
+ getChildren() {
16509
+ const { items } = this;
16510
+ if (!items)
16511
+ return [];
16512
+ return [...items.values()];
16513
+ }
16514
+ dispose() {
16515
+ this.items.clear();
16516
+ this.path = "";
16517
+ this._removeWatcher = EMPTY_FN;
16518
+ this.items = EMPTY_SET;
16519
+ Object.freeze(this);
16520
+ }
16521
+ };
16522
+ var STAT_METHOD_F = "stat";
16523
+ var STAT_METHOD_L = "lstat";
16524
+ var WatchHelper = class {
16525
+ constructor(path15, follow, fsw) {
16526
+ this.fsw = fsw;
16527
+ const watchPath = path15;
16528
+ this.path = path15 = path15.replace(REPLACER_RE, "");
16529
+ this.watchPath = watchPath;
16530
+ this.fullWatchPath = sysPath2.resolve(watchPath);
16531
+ this.dirParts = [];
16532
+ this.dirParts.forEach((parts2) => {
16533
+ if (parts2.length > 1)
16534
+ parts2.pop();
16535
+ });
16536
+ this.followSymlinks = follow;
16537
+ this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;
16538
+ }
16539
+ entryPath(entry) {
16540
+ return sysPath2.join(this.watchPath, sysPath2.relative(this.watchPath, entry.fullPath));
16541
+ }
16542
+ filterPath(entry) {
16543
+ const { stats } = entry;
16544
+ if (stats && stats.isSymbolicLink())
16545
+ return this.filterDir(entry);
16546
+ const resolvedPath = this.entryPath(entry);
16547
+ return this.fsw._isntIgnored(resolvedPath, stats) && this.fsw._hasReadPermissions(stats);
16548
+ }
16549
+ filterDir(entry) {
16550
+ return this.fsw._isntIgnored(this.entryPath(entry), entry.stats);
16551
+ }
16552
+ };
16553
+ var FSWatcher = class extends import_events.EventEmitter {
16554
+ // Not indenting methods for history sake; for now.
16555
+ constructor(_opts = {}) {
16556
+ super();
16557
+ this.closed = false;
16558
+ this._closers = /* @__PURE__ */ new Map();
16559
+ this._ignoredPaths = /* @__PURE__ */ new Set();
16560
+ this._throttled = /* @__PURE__ */ new Map();
16561
+ this._streams = /* @__PURE__ */ new Set();
16562
+ this._symlinkPaths = /* @__PURE__ */ new Map();
16563
+ this._watched = /* @__PURE__ */ new Map();
16564
+ this._pendingWrites = /* @__PURE__ */ new Map();
16565
+ this._pendingUnlinks = /* @__PURE__ */ new Map();
16566
+ this._readyCount = 0;
16567
+ this._readyEmitted = false;
16568
+ const awf = _opts.awaitWriteFinish;
16569
+ const DEF_AWF = { stabilityThreshold: 2e3, pollInterval: 100 };
16570
+ const opts = {
16571
+ // Defaults
16572
+ persistent: true,
16573
+ ignoreInitial: false,
16574
+ ignorePermissionErrors: false,
16575
+ interval: 100,
16576
+ binaryInterval: 300,
16577
+ followSymlinks: true,
16578
+ usePolling: false,
16579
+ // useAsync: false,
16580
+ atomic: true,
16581
+ // NOTE: overwritten later (depends on usePolling)
16582
+ ..._opts,
16583
+ // Change format
16584
+ ignored: _opts.ignored ? arrify(_opts.ignored) : arrify([]),
16585
+ awaitWriteFinish: awf === true ? DEF_AWF : typeof awf === "object" ? { ...DEF_AWF, ...awf } : false
16586
+ };
16587
+ if (isIBMi)
16588
+ opts.usePolling = true;
16589
+ if (opts.atomic === void 0)
16590
+ opts.atomic = !opts.usePolling;
16591
+ const envPoll = process.env.CHOKIDAR_USEPOLLING;
16592
+ if (envPoll !== void 0) {
16593
+ const envLower = envPoll.toLowerCase();
16594
+ if (envLower === "false" || envLower === "0")
16595
+ opts.usePolling = false;
16596
+ else if (envLower === "true" || envLower === "1")
16597
+ opts.usePolling = true;
16598
+ else
16599
+ opts.usePolling = !!envLower;
16600
+ }
16601
+ const envInterval = process.env.CHOKIDAR_INTERVAL;
16602
+ if (envInterval)
16603
+ opts.interval = Number.parseInt(envInterval, 10);
16604
+ let readyCalls = 0;
16605
+ this._emitReady = () => {
16606
+ readyCalls++;
16607
+ if (readyCalls >= this._readyCount) {
16608
+ this._emitReady = EMPTY_FN;
16609
+ this._readyEmitted = true;
16610
+ process.nextTick(() => this.emit(EVENTS.READY));
16611
+ }
16612
+ };
16613
+ this._emitRaw = (...args) => this.emit(EVENTS.RAW, ...args);
16614
+ this._boundRemove = this._remove.bind(this);
16615
+ this.options = opts;
16616
+ this._nodeFsHandler = new NodeFsHandler(this);
16617
+ Object.freeze(opts);
16618
+ }
16619
+ _addIgnoredPath(matcher) {
16620
+ if (isMatcherObject(matcher)) {
16621
+ for (const ignored of this._ignoredPaths) {
16622
+ if (isMatcherObject(ignored) && ignored.path === matcher.path && ignored.recursive === matcher.recursive) {
16623
+ return;
16624
+ }
16625
+ }
16626
+ }
16627
+ this._ignoredPaths.add(matcher);
16628
+ }
16629
+ _removeIgnoredPath(matcher) {
16630
+ this._ignoredPaths.delete(matcher);
16631
+ if (typeof matcher === "string") {
16632
+ for (const ignored of this._ignoredPaths) {
16633
+ if (isMatcherObject(ignored) && ignored.path === matcher) {
16634
+ this._ignoredPaths.delete(ignored);
16635
+ }
16636
+ }
16637
+ }
16638
+ }
16639
+ // Public methods
16640
+ /**
16641
+ * Adds paths to be watched on an existing FSWatcher instance.
16642
+ * @param paths_ file or file list. Other arguments are unused
16643
+ */
16644
+ add(paths_, _origAdd, _internal) {
16645
+ const { cwd } = this.options;
16646
+ this.closed = false;
16647
+ this._closePromise = void 0;
16648
+ let paths = unifyPaths(paths_);
16649
+ if (cwd) {
16650
+ paths = paths.map((path15) => {
16651
+ const absPath = getAbsolutePath(path15, cwd);
16652
+ return absPath;
16653
+ });
16654
+ }
16655
+ paths.forEach((path15) => {
16656
+ this._removeIgnoredPath(path15);
16657
+ });
16658
+ this._userIgnored = void 0;
16659
+ if (!this._readyCount)
16660
+ this._readyCount = 0;
16661
+ this._readyCount += paths.length;
16662
+ Promise.all(paths.map(async (path15) => {
16663
+ const res = await this._nodeFsHandler._addToNodeFs(path15, !_internal, void 0, 0, _origAdd);
16664
+ if (res)
16665
+ this._emitReady();
16666
+ return res;
16667
+ })).then((results) => {
16668
+ if (this.closed)
16669
+ return;
16670
+ results.forEach((item) => {
16671
+ if (item)
16672
+ this.add(sysPath2.dirname(item), sysPath2.basename(_origAdd || item));
16673
+ });
16674
+ });
16675
+ return this;
16676
+ }
16677
+ /**
16678
+ * Close watchers or start ignoring events from specified paths.
16679
+ */
16680
+ unwatch(paths_) {
16681
+ if (this.closed)
16682
+ return this;
16683
+ const paths = unifyPaths(paths_);
16684
+ const { cwd } = this.options;
16685
+ paths.forEach((path15) => {
16686
+ if (!sysPath2.isAbsolute(path15) && !this._closers.has(path15)) {
16687
+ if (cwd)
16688
+ path15 = sysPath2.join(cwd, path15);
16689
+ path15 = sysPath2.resolve(path15);
16690
+ }
16691
+ this._closePath(path15);
16692
+ this._addIgnoredPath(path15);
16693
+ if (this._watched.has(path15)) {
16694
+ this._addIgnoredPath({
16695
+ path: path15,
16696
+ recursive: true
16697
+ });
16698
+ }
16699
+ this._userIgnored = void 0;
16700
+ });
16701
+ return this;
16702
+ }
16703
+ /**
16704
+ * Close watchers and remove all listeners from watched paths.
16705
+ */
16706
+ close() {
16707
+ if (this._closePromise) {
16708
+ return this._closePromise;
16709
+ }
16710
+ this.closed = true;
16711
+ this.removeAllListeners();
16712
+ const closers = [];
16713
+ this._closers.forEach((closerList) => closerList.forEach((closer) => {
16714
+ const promise = closer();
16715
+ if (promise instanceof Promise)
16716
+ closers.push(promise);
16717
+ }));
16718
+ this._streams.forEach((stream) => stream.destroy());
16719
+ this._userIgnored = void 0;
16720
+ this._readyCount = 0;
16721
+ this._readyEmitted = false;
16722
+ this._watched.forEach((dirent) => dirent.dispose());
16723
+ this._closers.clear();
16724
+ this._watched.clear();
16725
+ this._streams.clear();
16726
+ this._symlinkPaths.clear();
16727
+ this._throttled.clear();
16728
+ this._closePromise = closers.length ? Promise.all(closers).then(() => void 0) : Promise.resolve();
16729
+ return this._closePromise;
16730
+ }
16731
+ /**
16732
+ * Expose list of watched paths
16733
+ * @returns for chaining
16734
+ */
16735
+ getWatched() {
16736
+ const watchList = {};
16737
+ this._watched.forEach((entry, dir) => {
16738
+ const key = this.options.cwd ? sysPath2.relative(this.options.cwd, dir) : dir;
16739
+ const index = key || ONE_DOT;
16740
+ watchList[index] = entry.getChildren().sort();
16741
+ });
16742
+ return watchList;
16743
+ }
16744
+ emitWithAll(event, args) {
16745
+ this.emit(event, ...args);
16746
+ if (event !== EVENTS.ERROR)
16747
+ this.emit(EVENTS.ALL, event, ...args);
16748
+ }
16749
+ // Common helpers
16750
+ // --------------
16751
+ /**
16752
+ * Normalize and emit events.
16753
+ * Calling _emit DOES NOT MEAN emit() would be called!
16754
+ * @param event Type of event
16755
+ * @param path File or directory path
16756
+ * @param stats arguments to be passed with event
16757
+ * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
16758
+ */
16759
+ async _emit(event, path15, stats) {
16760
+ if (this.closed)
16761
+ return;
16762
+ const opts = this.options;
16763
+ if (isWindows2)
16764
+ path15 = sysPath2.normalize(path15);
16765
+ if (opts.cwd)
16766
+ path15 = sysPath2.relative(opts.cwd, path15);
16767
+ const args = [path15];
16768
+ if (stats != null)
16769
+ args.push(stats);
16770
+ const awf = opts.awaitWriteFinish;
16771
+ let pw;
16772
+ if (awf && (pw = this._pendingWrites.get(path15))) {
16773
+ pw.lastChange = /* @__PURE__ */ new Date();
16774
+ return this;
16775
+ }
16776
+ if (opts.atomic) {
16777
+ if (event === EVENTS.UNLINK) {
16778
+ this._pendingUnlinks.set(path15, [event, ...args]);
16779
+ setTimeout(() => {
16780
+ this._pendingUnlinks.forEach((entry, path16) => {
16781
+ this.emit(...entry);
16782
+ this.emit(EVENTS.ALL, ...entry);
16783
+ this._pendingUnlinks.delete(path16);
16784
+ });
16785
+ }, typeof opts.atomic === "number" ? opts.atomic : 100);
16786
+ return this;
16787
+ }
16788
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path15)) {
16789
+ event = EVENTS.CHANGE;
16790
+ this._pendingUnlinks.delete(path15);
16791
+ }
16792
+ }
16793
+ if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
16794
+ const awfEmit = (err, stats2) => {
16795
+ if (err) {
16796
+ event = EVENTS.ERROR;
16797
+ args[0] = err;
16798
+ this.emitWithAll(event, args);
16799
+ } else if (stats2) {
16800
+ if (args.length > 1) {
16801
+ args[1] = stats2;
16802
+ } else {
16803
+ args.push(stats2);
16804
+ }
16805
+ this.emitWithAll(event, args);
16806
+ }
16807
+ };
16808
+ this._awaitWriteFinish(path15, awf.stabilityThreshold, event, awfEmit);
16809
+ return this;
16810
+ }
16811
+ if (event === EVENTS.CHANGE) {
16812
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path15, 50);
16813
+ if (isThrottled)
16814
+ return this;
16815
+ }
16816
+ if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
16817
+ const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path15) : path15;
16818
+ let stats2;
16819
+ try {
16820
+ stats2 = await (0, import_promises5.stat)(fullPath);
16821
+ } catch (err) {
16822
+ }
16823
+ if (!stats2 || this.closed)
16824
+ return;
16825
+ args.push(stats2);
16826
+ }
16827
+ this.emitWithAll(event, args);
16828
+ return this;
16829
+ }
16830
+ /**
16831
+ * Common handler for errors
16832
+ * @returns The error if defined, otherwise the value of the FSWatcher instance's `closed` flag
16833
+ */
16834
+ _handleError(error) {
16835
+ const code = error && error.code;
16836
+ if (error && code !== "ENOENT" && code !== "ENOTDIR" && (!this.options.ignorePermissionErrors || code !== "EPERM" && code !== "EACCES")) {
16837
+ this.emit(EVENTS.ERROR, error);
16838
+ }
16839
+ return error || this.closed;
16840
+ }
16841
+ /**
16842
+ * Helper utility for throttling
16843
+ * @param actionType type being throttled
16844
+ * @param path being acted upon
16845
+ * @param timeout duration of time to suppress duplicate actions
16846
+ * @returns tracking object or false if action should be suppressed
16847
+ */
16848
+ _throttle(actionType, path15, timeout) {
16849
+ if (!this._throttled.has(actionType)) {
16850
+ this._throttled.set(actionType, /* @__PURE__ */ new Map());
16851
+ }
16852
+ const action = this._throttled.get(actionType);
16853
+ if (!action)
16854
+ throw new Error("invalid throttle");
16855
+ const actionPath = action.get(path15);
16856
+ if (actionPath) {
16857
+ actionPath.count++;
16858
+ return false;
16859
+ }
16860
+ let timeoutObject;
16861
+ const clear = () => {
16862
+ const item = action.get(path15);
16863
+ const count = item ? item.count : 0;
16864
+ action.delete(path15);
16865
+ clearTimeout(timeoutObject);
16866
+ if (item)
16867
+ clearTimeout(item.timeoutObject);
16868
+ return count;
16869
+ };
16870
+ timeoutObject = setTimeout(clear, timeout);
16871
+ const thr = { timeoutObject, clear, count: 0 };
16872
+ action.set(path15, thr);
16873
+ return thr;
16874
+ }
16875
+ _incrReadyCount() {
16876
+ return this._readyCount++;
16877
+ }
16878
+ /**
16879
+ * Awaits write operation to finish.
16880
+ * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback.
16881
+ * @param path being acted upon
16882
+ * @param threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished
16883
+ * @param event
16884
+ * @param awfEmit Callback to be called when ready for event to be emitted.
16885
+ */
16886
+ _awaitWriteFinish(path15, threshold, event, awfEmit) {
16887
+ const awf = this.options.awaitWriteFinish;
16888
+ if (typeof awf !== "object")
16889
+ return;
16890
+ const pollInterval = awf.pollInterval;
16891
+ let timeoutHandler;
16892
+ let fullPath = path15;
16893
+ if (this.options.cwd && !sysPath2.isAbsolute(path15)) {
16894
+ fullPath = sysPath2.join(this.options.cwd, path15);
16895
+ }
16896
+ const now = /* @__PURE__ */ new Date();
16897
+ const writes = this._pendingWrites;
16898
+ function awaitWriteFinishFn(prevStat) {
16899
+ (0, import_fs8.stat)(fullPath, (err, curStat) => {
16900
+ if (err || !writes.has(path15)) {
16901
+ if (err && err.code !== "ENOENT")
16902
+ awfEmit(err);
16903
+ return;
16904
+ }
16905
+ const now2 = Number(/* @__PURE__ */ new Date());
16906
+ if (prevStat && curStat.size !== prevStat.size) {
16907
+ writes.get(path15).lastChange = now2;
16908
+ }
16909
+ const pw = writes.get(path15);
16910
+ const df = now2 - pw.lastChange;
16911
+ if (df >= threshold) {
16912
+ writes.delete(path15);
16913
+ awfEmit(void 0, curStat);
16914
+ } else {
16915
+ timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
16916
+ }
16917
+ });
16918
+ }
16919
+ if (!writes.has(path15)) {
16920
+ writes.set(path15, {
16921
+ lastChange: now,
16922
+ cancelWait: () => {
16923
+ writes.delete(path15);
16924
+ clearTimeout(timeoutHandler);
16925
+ return event;
16926
+ }
16927
+ });
16928
+ timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
16929
+ }
16930
+ }
16931
+ /**
16932
+ * Determines whether user has asked to ignore this path.
16933
+ */
16934
+ _isIgnored(path15, stats) {
16935
+ if (this.options.atomic && DOT_RE.test(path15))
16936
+ return true;
16937
+ if (!this._userIgnored) {
16938
+ const { cwd } = this.options;
16939
+ const ign = this.options.ignored;
16940
+ const ignored = (ign || []).map(normalizeIgnored(cwd));
16941
+ const ignoredPaths = [...this._ignoredPaths];
16942
+ const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
16943
+ this._userIgnored = anymatch(list, void 0);
16944
+ }
16945
+ return this._userIgnored(path15, stats);
16946
+ }
16947
+ _isntIgnored(path15, stat4) {
16948
+ return !this._isIgnored(path15, stat4);
16949
+ }
16950
+ /**
16951
+ * Provides a set of common helpers and properties relating to symlink handling.
16952
+ * @param path file or directory pattern being watched
16953
+ */
16954
+ _getWatchHelpers(path15) {
16955
+ return new WatchHelper(path15, this.options.followSymlinks, this);
16956
+ }
16957
+ // Directory helpers
16958
+ // -----------------
16959
+ /**
16960
+ * Provides directory tracking objects
16961
+ * @param directory path of the directory
16962
+ */
16963
+ _getWatchedDir(directory) {
16964
+ const dir = sysPath2.resolve(directory);
16965
+ if (!this._watched.has(dir))
16966
+ this._watched.set(dir, new DirEntry(dir, this._boundRemove));
16967
+ return this._watched.get(dir);
16968
+ }
16969
+ // File helpers
16970
+ // ------------
16971
+ /**
16972
+ * Check for read permissions: https://stackoverflow.com/a/11781404/1358405
16973
+ */
16974
+ _hasReadPermissions(stats) {
16975
+ if (this.options.ignorePermissionErrors)
16976
+ return true;
16977
+ return Boolean(Number(stats.mode) & 256);
16978
+ }
16979
+ /**
16980
+ * Handles emitting unlink events for
16981
+ * files and directories, and via recursion, for
16982
+ * files and directories within directories that are unlinked
16983
+ * @param directory within which the following item is located
16984
+ * @param item base path of item/directory
16985
+ */
16986
+ _remove(directory, item, isDirectory) {
16987
+ const path15 = sysPath2.join(directory, item);
16988
+ const fullPath = sysPath2.resolve(path15);
16989
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path15) || this._watched.has(fullPath);
16990
+ if (!this._throttle("remove", path15, 100))
16991
+ return;
16992
+ if (!isDirectory && this._watched.size === 1) {
16993
+ this.add(directory, item, true);
16994
+ }
16995
+ const wp = this._getWatchedDir(path15);
16996
+ const nestedDirectoryChildren = wp.getChildren();
16997
+ nestedDirectoryChildren.forEach((nested) => this._remove(path15, nested));
16998
+ const parent = this._getWatchedDir(directory);
16999
+ const wasTracked = parent.has(item);
17000
+ parent.remove(item);
17001
+ if (this._symlinkPaths.has(fullPath)) {
17002
+ this._symlinkPaths.delete(fullPath);
17003
+ }
17004
+ let relPath = path15;
17005
+ if (this.options.cwd)
17006
+ relPath = sysPath2.relative(this.options.cwd, path15);
17007
+ if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
17008
+ const event = this._pendingWrites.get(relPath).cancelWait();
17009
+ if (event === EVENTS.ADD)
17010
+ return;
17011
+ }
17012
+ this._watched.delete(path15);
17013
+ this._watched.delete(fullPath);
17014
+ const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
17015
+ if (wasTracked && !this._isIgnored(path15))
17016
+ this._emit(eventName, path15);
17017
+ this._closePath(path15);
17018
+ }
17019
+ /**
17020
+ * Closes all watchers for a path
17021
+ */
17022
+ _closePath(path15) {
17023
+ this._closeFile(path15);
17024
+ const dir = sysPath2.dirname(path15);
17025
+ this._getWatchedDir(dir).remove(sysPath2.basename(path15));
17026
+ }
17027
+ /**
17028
+ * Closes only file-specific watchers
17029
+ */
17030
+ _closeFile(path15) {
17031
+ const closers = this._closers.get(path15);
17032
+ if (!closers)
17033
+ return;
17034
+ closers.forEach((closer) => closer());
17035
+ this._closers.delete(path15);
17036
+ }
17037
+ _addPathCloser(path15, closer) {
17038
+ if (!closer)
17039
+ return;
17040
+ let list = this._closers.get(path15);
17041
+ if (!list) {
17042
+ list = [];
17043
+ this._closers.set(path15, list);
17044
+ }
17045
+ list.push(closer);
17046
+ }
17047
+ _readdirp(root, opts) {
17048
+ if (this.closed)
17049
+ return;
17050
+ const options = { type: EVENTS.ALL, alwaysStat: true, lstat: true, ...opts, depth: 0 };
17051
+ let stream = readdirp(root, options);
17052
+ this._streams.add(stream);
17053
+ stream.once(STR_CLOSE, () => {
17054
+ stream = void 0;
17055
+ });
17056
+ stream.once(STR_END, () => {
17057
+ if (stream) {
17058
+ this._streams.delete(stream);
17059
+ stream = void 0;
17060
+ }
17061
+ });
17062
+ return stream;
17063
+ }
17064
+ };
17065
+ function watch(paths, options = {}) {
17066
+ const watcher = new FSWatcher(options);
17067
+ watcher.add(paths);
17068
+ return watcher;
17069
+ }
17070
+
17071
+ // ../../shared/all/helpers/terminal-ai/watcher.ts
17072
+ var PRUNED_DIRS = /* @__PURE__ */ new Set([
17073
+ ".git",
17074
+ "node_modules",
17075
+ ".next",
17076
+ ".turbo",
17077
+ ".expo",
17078
+ "dist",
17079
+ "build",
17080
+ "out",
17081
+ "coverage",
17082
+ ".cache",
17083
+ ".venv",
17084
+ "venv",
17085
+ "__pycache__",
17086
+ ".gradle",
17087
+ "Pods",
17088
+ "DerivedData"
17089
+ ]);
17090
+ function isNoiseFile(name) {
17091
+ return name === ".DS_Store" || name === "4913" || name.startsWith(".#") || name.startsWith("#") && name.endsWith("#");
17092
+ }
17093
+ var MAX_BATCH = 200;
17094
+ var FLUSH_MS = 120;
17095
+ var SELF_WRITE_MS = 2e3;
17096
+ var emptyPending = () => ({
17097
+ added: /* @__PURE__ */ new Set(),
17098
+ changed: /* @__PURE__ */ new Set(),
17099
+ removed: /* @__PURE__ */ new Set(),
17100
+ resync: false
17101
+ });
17102
+ var WorkspaceWatcher = class {
17103
+ /**
17104
+ * @param root Absolute path of the working tree. Every emitted path is
17105
+ * repo-relative and `/`-prefixed, matching `bareFsList`.
17106
+ * @param emit Called with a coalesced batch, never with an empty one.
17107
+ * @param exclude Absolute subtrees to skip on top of the name-based pruning.
17108
+ * A no-git card's root is the space dir itself, which also
17109
+ * holds the runner's own bookkeeping.
17110
+ */
17111
+ constructor(root, emit, exclude = []) {
17112
+ this.root = root;
17113
+ this.emit = emit;
17114
+ this.exclude = exclude;
17115
+ this.watcher = null;
17116
+ this.pending = emptyPending();
17117
+ this.flushTimer = null;
17118
+ /** path -> expiry. Events for these paths are ours (the editor just saved)
17119
+ * and must not come back as "changed on disk". */
17120
+ this.selfWrites = /* @__PURE__ */ new Map();
17121
+ this.closed = false;
17122
+ }
17123
+ start() {
17124
+ if (this.watcher || this.closed) return;
17125
+ const watcher = watch(this.root, {
17126
+ // `ignored` prunes: returning true for a directory stops the walk there,
17127
+ // so a pruned tree is never even enumerated.
17128
+ ignored: (absPath) => this.shouldIgnore(absPath),
17129
+ ignoreInitial: true,
17130
+ // A symlink to $HOME (or a sibling checkout) would pull the whole machine
17131
+ // into the watch set.
17132
+ followSymlinks: false,
17133
+ // Report a write only once it stops growing - otherwise a large file
17134
+ // fires while it's still half on disk and the editor reads a torn read.
17135
+ awaitWriteFinish: { stabilityThreshold: 100, pollInterval: 30 },
17136
+ // Recognise the unlink+rename that editors use to save atomically as a
17137
+ // single change rather than a delete followed by a create.
17138
+ atomic: true,
17139
+ ignorePermissionErrors: true,
17140
+ cwd: this.root
17141
+ });
17142
+ this.watcher = watcher;
17143
+ watcher.on("add", (p) => this.record("added", p));
17144
+ watcher.on("addDir", (p) => this.record("added", p));
17145
+ watcher.on("change", (p) => this.record("changed", p));
17146
+ watcher.on("unlink", (p) => this.record("removed", p));
17147
+ watcher.on("unlinkDir", (p) => this.record("removed", p));
17148
+ watcher.on("error", () => {
17149
+ if (this.closed) return;
17150
+ void this.close();
17151
+ this.emit({
17152
+ added: [],
17153
+ changed: [],
17154
+ removed: [],
17155
+ resync: false,
17156
+ stopped: true
17157
+ });
17158
+ });
17159
+ }
17160
+ /**
17161
+ * Mark a path as about to be written by us. The event the write produces is
17162
+ * dropped, so the editor doesn't get told its own save was an outside edit.
17163
+ */
17164
+ expectWrite(repoPath) {
17165
+ this.selfWrites.set(repoPath, Date.now() + SELF_WRITE_MS);
17166
+ }
17167
+ async close() {
17168
+ this.closed = true;
17169
+ if (this.flushTimer) {
17170
+ clearTimeout(this.flushTimer);
17171
+ this.flushTimer = null;
17172
+ }
17173
+ this.pending = emptyPending();
17174
+ this.selfWrites.clear();
17175
+ const watcher = this.watcher;
17176
+ this.watcher = null;
17177
+ if (watcher) await watcher.close().catch(() => void 0);
17178
+ }
17179
+ /** chokidar tests absolute paths, always under the watch root. Matching is
17180
+ * done on the part BELOW the root, so a runner whose space dir happens to
17181
+ * sit under a `build/` or `dist/` of its own doesn't prune everything. */
17182
+ shouldIgnore(absPath) {
17183
+ if (absPath === this.root) return false;
17184
+ for (const excluded of this.exclude) {
17185
+ if (absPath === excluded || absPath.startsWith(excluded + "/")) {
17186
+ return true;
17187
+ }
17188
+ }
17189
+ const segments = absPath.slice(this.root.length + 1).split("/");
17190
+ for (const segment of segments) {
17191
+ if (PRUNED_DIRS.has(segment)) return true;
17192
+ }
17193
+ return isNoiseFile(segments[segments.length - 1] ?? "");
17194
+ }
17195
+ record(kind, relPath) {
17196
+ if (this.closed || !relPath) return;
17197
+ const path15 = "/" + relPath;
17198
+ const expiry = this.selfWrites.get(path15);
17199
+ if (expiry !== void 0) {
17200
+ if (expiry > Date.now()) return;
17201
+ this.selfWrites.delete(path15);
17202
+ }
17203
+ const { added, changed, removed } = this.pending;
17204
+ added.delete(path15);
17205
+ changed.delete(path15);
17206
+ removed.delete(path15);
17207
+ if (kind === "added") added.add(path15);
17208
+ else if (kind === "changed") changed.add(path15);
17209
+ else removed.add(path15);
17210
+ if (added.size + changed.size + removed.size > MAX_BATCH) {
17211
+ this.pending = { ...emptyPending(), resync: true };
17212
+ }
17213
+ this.scheduleFlush();
17214
+ }
17215
+ scheduleFlush() {
17216
+ if (this.flushTimer) return;
17217
+ this.flushTimer = setTimeout(() => {
17218
+ this.flushTimer = null;
17219
+ this.flush();
17220
+ }, FLUSH_MS);
17221
+ }
17222
+ flush() {
17223
+ if (this.closed) return;
17224
+ const { added, changed, removed, resync } = this.pending;
17225
+ this.pending = emptyPending();
17226
+ if (!resync && !added.size && !changed.size && !removed.size) return;
17227
+ const now = Date.now();
17228
+ for (const [path15, expiry] of this.selfWrites) {
17229
+ if (expiry <= now) this.selfWrites.delete(path15);
17230
+ }
17231
+ this.emit({
17232
+ added: resync ? [] : [...added],
17233
+ changed: resync ? [] : [...changed],
17234
+ removed: resync ? [] : [...removed],
17235
+ resync
17236
+ });
17237
+ }
17238
+ };
17239
+
15334
17240
  // ../../shared/all/helpers/terminal-ai/terminal-mode.ts
15335
17241
  function posixNormalize(p) {
15336
17242
  const parts2 = p.split("/").filter(Boolean);
@@ -15358,6 +17264,54 @@ var TerminalModeEngine = class {
15358
17264
  this.core = core;
15359
17265
  this.emitter = emitter;
15360
17266
  this.sessions = /* @__PURE__ */ new Map();
17267
+ /** One working-tree watcher per live bare session, keyed by postId. */
17268
+ this.watchers = /* @__PURE__ */ new Map();
17269
+ /** Worktree name each session claimed, keyed by postId. Covers the window
17270
+ * `claimWorkName`'s disk scan cannot: a name taken but not yet created. */
17271
+ this.reservedNames = /* @__PURE__ */ new Map();
17272
+ }
17273
+ // ── working-tree watching ──
17274
+ /** Start watching a session's tree. Idempotent: re-entering a session (the
17275
+ * modal reopening, a hydrate after restart) must not stack watchers. */
17276
+ startWatching(session) {
17277
+ const postId = session.postId;
17278
+ if (this.watchers.has(postId)) return;
17279
+ const paths = this.core.target().paths;
17280
+ const root = session.workspacePath || paths.root;
17281
+ if (!root) return;
17282
+ const exclude = session.workspacePath ? [] : [
17283
+ paths.state,
17284
+ paths.backups,
17285
+ paths.builds,
17286
+ paths.bin,
17287
+ paths.worktrees,
17288
+ paths.repo,
17289
+ `${paths.root}/drops`
17290
+ ];
17291
+ const watcher = new WorkspaceWatcher(
17292
+ root,
17293
+ (change) => {
17294
+ this.emitter.emitBareFsChange(postId, change);
17295
+ },
17296
+ exclude
17297
+ );
17298
+ this.watchers.set(postId, watcher);
17299
+ watcher.start();
17300
+ }
17301
+ /** Silent by design: a session that ends also emits session-update, and a
17302
+ * re-point stops then starts. The one `stopped` the client cares about is
17303
+ * the watcher failing under a live session, which the watcher emits itself. */
17304
+ stopWatching(postId) {
17305
+ const watcher = this.watchers.get(postId);
17306
+ if (!watcher) return;
17307
+ this.watchers.delete(postId);
17308
+ void watcher.close();
17309
+ }
17310
+ /** Suppress the change event our own write is about to produce, so a save
17311
+ * never comes back to the editor as an outside edit. Normalized to the form
17312
+ * the watcher emits, since callers spell the path either way. */
17313
+ expectWrite(postId, path15) {
17314
+ this.watchers.get(postId)?.expectWrite(posixNormalize(path15));
15361
17315
  }
15362
17316
  // ── Lifecycle / ModeEngine ──
15363
17317
  start(base, args) {
@@ -15401,6 +17355,8 @@ var TerminalModeEngine = class {
15401
17355
  return !!s && (s.phase === "starting" || s.phase === "bare-active");
15402
17356
  }
15403
17357
  remove(postId) {
17358
+ this.stopWatching(postId);
17359
+ this.reservedNames.delete(postId);
15404
17360
  this.sessions.delete(postId);
15405
17361
  }
15406
17362
  async kill(postId) {
@@ -15414,12 +17370,17 @@ var TerminalModeEngine = class {
15414
17370
  }
15415
17371
  }
15416
17372
  if (!session) return;
17373
+ this.stopWatching(session.postId);
15417
17374
  await this.teardown(session);
15418
17375
  const removedPostId = session.postId;
17376
+ this.reservedNames.delete(removedPostId);
15419
17377
  this.sessions.delete(removedPostId);
15420
17378
  this.emitter.emitSessionRemoved(removedPostId);
15421
17379
  }
15422
17380
  destroy() {
17381
+ for (const watcher of this.watchers.values()) void watcher.close();
17382
+ this.watchers.clear();
17383
+ this.reservedNames.clear();
15423
17384
  this.sessions.clear();
15424
17385
  }
15425
17386
  teardown(session) {
@@ -15464,6 +17425,7 @@ var TerminalModeEngine = class {
15464
17425
  exposed: []
15465
17426
  };
15466
17427
  this.sessions.set(r.postId, session);
17428
+ this.startWatching(session);
15467
17429
  this.emitter.emitSessionUpdate(session);
15468
17430
  }
15469
17431
  }
@@ -15506,6 +17468,8 @@ var TerminalModeEngine = class {
15506
17468
  exposed: []
15507
17469
  };
15508
17470
  this.sessions.set(args.postId, session);
17471
+ this.stopWatching(args.postId);
17472
+ this.startWatching(session);
15509
17473
  this.emitter.emitSessionUpdate(session);
15510
17474
  }
15511
17475
  // ── workspace + Claude CLI, user drives ──
@@ -15515,11 +17479,13 @@ var TerminalModeEngine = class {
15515
17479
  await this.core.ensureSpaceWorkspace();
15516
17480
  if (config.repoUrl && config.githubToken) {
15517
17481
  const branch = baseBranch || config.mainBranch || "main";
15518
- const { path: path15 } = await addWorktree(
17482
+ const workName = isCardPostId(session.postId) ? session.taskId : await claimWorkName(
15519
17483
  this.core.target(),
15520
- session.taskId,
15521
- branch
17484
+ session.taskTitle,
17485
+ this.reservedNames.values()
15522
17486
  );
17487
+ this.reservedNames.set(session.postId, workName);
17488
+ const { path: path15 } = await addWorktree(this.core.target(), workName, branch);
15523
17489
  session.workspacePath = path15;
15524
17490
  await setGitIdentity(
15525
17491
  this.core.target(),
@@ -15549,6 +17515,7 @@ var TerminalModeEngine = class {
15549
17515
  }
15550
17516
  }
15551
17517
  session.phase = "bare-active";
17518
+ this.startWatching(session);
15552
17519
  this.emitter.emitSessionUpdate(session);
15553
17520
  this.emitter.addLog(
15554
17521
  session,
@@ -15656,6 +17623,7 @@ var TerminalModeEngine = class {
15656
17623
  if (!/^[A-Za-z0-9+/=\n\r]*$/.test(b64)) {
15657
17624
  throw new Error("Invalid base64 payload.");
15658
17625
  }
17626
+ this.expectWrite(String(postId), path15);
15659
17627
  await target.sh(
15660
17628
  `mkdir -p ${shEscape(posixDirname(abs))} && printf %s ${shEscape(b64)} | base64 -d > ${shEscape(abs)}`
15661
17629
  );
@@ -15907,11 +17875,6 @@ var TerminalModeEngine = class {
15907
17875
  }
15908
17876
  };
15909
17877
 
15910
- // ../../shared/all/helpers/board-agent-core/boardTerminal.ts
15911
- function boardTerminalKey(spaceSlug) {
15912
- return `board-${spaceSlug}`;
15913
- }
15914
-
15915
17878
  // ../../shared/all/helpers/board-agent-core/ansi.ts
15916
17879
  var CSI = String.raw`\x1b\[[0-?]*[ -/]*[@-~]`;
15917
17880
  var OSC = String.raw`\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)`;
@@ -15988,8 +17951,8 @@ var ClaudeLoginFlow = class {
15988
17951
  if (this.active) throw new Error("A Claude sign-in is already running.");
15989
17952
  this.reset();
15990
17953
  this.inFlight = true;
15991
- const urlPromise = new Promise((resolve2, reject) => {
15992
- this.urlResolver = resolve2;
17954
+ const urlPromise = new Promise((resolve4, reject) => {
17955
+ this.urlResolver = resolve4;
15993
17956
  this.urlRejecter = reject;
15994
17957
  });
15995
17958
  urlPromise.catch(() => {
@@ -16050,10 +18013,10 @@ var ClaudeLoginFlow = class {
16050
18013
  /https:\/\/[^\s\x00-\x1f]*oauth[^\s\x00-\x1f]*/
16051
18014
  )?.[0];
16052
18015
  if (url2) {
16053
- const resolve2 = this.urlResolver;
18016
+ const resolve4 = this.urlResolver;
16054
18017
  this.urlResolver = null;
16055
18018
  this.urlRejecter = null;
16056
- resolve2(url2.replace(/[.,;)\]]+$/, ""));
18019
+ resolve4(url2.replace(/[.,;)\]]+$/, ""));
16057
18020
  }
16058
18021
  }
16059
18022
  if (this.submitMark < 0 || this.settled) return;
@@ -16149,8 +18112,8 @@ var CodexLoginFlow = class {
16149
18112
  this.reset();
16150
18113
  this.inFlight = true;
16151
18114
  const startPromise = new Promise(
16152
- (resolve2, reject) => {
16153
- this.startResolver = resolve2;
18115
+ (resolve4, reject) => {
18116
+ this.startResolver = resolve4;
16154
18117
  this.startRejecter = reject;
16155
18118
  }
16156
18119
  );
@@ -16196,10 +18159,10 @@ var CodexLoginFlow = class {
16196
18159
  const url2 = this.output.match(/https:\/\/[^\s\x00-\x1f]+/)?.[0];
16197
18160
  const code = this.output.match(CODE_LINE_RE)?.[1] ?? this.output.match(CODE_TOKEN_RE)?.[1];
16198
18161
  if (url2 && code) {
16199
- const resolve2 = this.startResolver;
18162
+ const resolve4 = this.startResolver;
16200
18163
  this.startResolver = null;
16201
18164
  this.startRejecter = null;
16202
- resolve2({ url: url2.replace(/[.,;)\]]+$/, ""), code });
18165
+ resolve4({ url: url2.replace(/[.,;)\]]+$/, ""), code });
16203
18166
  }
16204
18167
  return;
16205
18168
  }
@@ -16378,7 +18341,7 @@ async function listGithubBranches(token, fullName) {
16378
18341
 
16379
18342
  // ../../shared/all/helpers/board-agent-core/host-deploy.ts
16380
18343
  var import_child_process5 = require("child_process");
16381
- var import_promises3 = __toESM(require("fs/promises"));
18344
+ var import_promises6 = __toESM(require("fs/promises"));
16382
18345
  var import_path9 = __toESM(require("path"));
16383
18346
  var import_util5 = require("util");
16384
18347
  var execFileAsync2 = (0, import_util5.promisify)(import_child_process5.execFile);
@@ -16391,12 +18354,12 @@ var CLAUDE_LINK = `${CLAUDE_SKILLS_DIR}/deploy`;
16391
18354
  async function ensureClaudeSkillLink(workspace) {
16392
18355
  const linkPath = import_path9.default.join(workspace, CLAUDE_LINK);
16393
18356
  try {
16394
- await import_promises3.default.lstat(linkPath);
18357
+ await import_promises6.default.lstat(linkPath);
16395
18358
  return;
16396
18359
  } catch {
16397
18360
  }
16398
- await import_promises3.default.mkdir(import_path9.default.join(workspace, CLAUDE_SKILLS_DIR), { recursive: true });
16399
- await import_promises3.default.symlink("../../.agents/skills/deploy", linkPath, "dir");
18361
+ await import_promises6.default.mkdir(import_path9.default.join(workspace, CLAUDE_SKILLS_DIR), { recursive: true });
18362
+ await import_promises6.default.symlink("../../.agents/skills/deploy", linkPath, "dir");
16400
18363
  }
16401
18364
  var GIT_NO_HELPER = ["-c", "credential.helper="];
16402
18365
  var GIT_ENV = { ...process.env, GIT_TERMINAL_PROMPT: "0" };
@@ -16505,15 +18468,15 @@ function spaceEnv(spaceDir) {
16505
18468
  };
16506
18469
  }
16507
18470
  async function readContract(workspace) {
16508
- const skill = await import_promises3.default.readFile(import_path9.default.join(workspace, SKILL_PATH), "utf-8").catch(() => {
18471
+ const skill = await import_promises6.default.readFile(import_path9.default.join(workspace, SKILL_PATH), "utf-8").catch(() => {
16509
18472
  throw new Error("The creator wrote no SKILL.md.");
16510
18473
  });
16511
- const checker = await import_promises3.default.readFile(import_path9.default.join(workspace, CHECKER_PATH), "utf-8").catch(() => {
18474
+ const checker = await import_promises6.default.readFile(import_path9.default.join(workspace, CHECKER_PATH), "utf-8").catch(() => {
16512
18475
  throw new Error("The creator wrote no check-environment.sh.");
16513
18476
  });
16514
18477
  try {
16515
18478
  const raw = JSON.parse(
16516
- await import_promises3.default.readFile(import_path9.default.join(workspace, VARIABLES_PATH), "utf-8")
18479
+ await import_promises6.default.readFile(import_path9.default.join(workspace, VARIABLES_PATH), "utf-8")
16517
18480
  );
16518
18481
  return {
16519
18482
  skill,
@@ -16666,7 +18629,7 @@ async function runEnvironmentCheck(opts) {
16666
18629
  `origin/${status.branch}:${CHECKER_PATH}`
16667
18630
  );
16668
18631
  const tmp = import_path9.default.join(opts.spaceDir, `.env-check.${process.pid}.sh`);
16669
- await import_promises3.default.writeFile(tmp, script, { mode: 448 });
18632
+ await import_promises6.default.writeFile(tmp, script, { mode: 448 });
16670
18633
  let ok = true;
16671
18634
  let output = "";
16672
18635
  try {
@@ -16679,7 +18642,7 @@ async function runEnvironmentCheck(opts) {
16679
18642
  output = res.output;
16680
18643
  if (res.code !== 0) ok = false;
16681
18644
  } finally {
16682
- await import_promises3.default.rm(tmp, { force: true });
18645
+ await import_promises6.default.rm(tmp, { force: true });
16683
18646
  }
16684
18647
  const checks = [];
16685
18648
  for (const line of output.split("\n")) {
@@ -16749,7 +18712,7 @@ var import_path11 = __toESM(require("path"));
16749
18712
  // ../../shared/all/helpers/board-agent-core/host-secrets.ts
16750
18713
  var import_child_process6 = require("child_process");
16751
18714
  var import_crypto5 = __toESM(require("crypto"));
16752
- var import_promises4 = __toESM(require("fs/promises"));
18715
+ var import_promises7 = __toESM(require("fs/promises"));
16753
18716
  var import_path10 = __toESM(require("path"));
16754
18717
  var import_util6 = require("util");
16755
18718
  var execFileAsync3 = (0, import_util6.promisify)(import_child_process6.execFile);
@@ -16783,7 +18746,7 @@ function deriveKey(password, salt) {
16783
18746
  }
16784
18747
  async function secretsInitialized(configDir) {
16785
18748
  try {
16786
- await import_promises4.default.access(import_path10.default.join(configDir, IDENTITY_FILE));
18749
+ await import_promises7.default.access(import_path10.default.join(configDir, IDENTITY_FILE));
16787
18750
  return true;
16788
18751
  } catch {
16789
18752
  return false;
@@ -16822,10 +18785,10 @@ async function initSecrets(configDir, password) {
16822
18785
  tag: cipher.getAuthTag().toString("base64"),
16823
18786
  data: data.toString("base64")
16824
18787
  };
16825
- await import_promises4.default.writeFile(import_path10.default.join(configDir, IDENTITY_FILE), JSON.stringify(box), {
18788
+ await import_promises7.default.writeFile(import_path10.default.join(configDir, IDENTITY_FILE), JSON.stringify(box), {
16826
18789
  mode: 384
16827
18790
  });
16828
- await import_promises4.default.writeFile(import_path10.default.join(configDir, RECIPIENT_FILE), `${recipient}
18791
+ await import_promises7.default.writeFile(import_path10.default.join(configDir, RECIPIENT_FILE), `${recipient}
16829
18792
  `, {
16830
18793
  mode: 384
16831
18794
  });
@@ -16852,13 +18815,13 @@ function envPath(spaceDir) {
16852
18815
  }
16853
18816
  async function identityFor(configDir, password) {
16854
18817
  const box = JSON.parse(
16855
- await import_promises4.default.readFile(import_path10.default.join(configDir, IDENTITY_FILE), "utf-8")
18818
+ await import_promises7.default.readFile(import_path10.default.join(configDir, IDENTITY_FILE), "utf-8")
16856
18819
  );
16857
18820
  return decryptIdentity(box, password);
16858
18821
  }
16859
18822
  async function readEnv(spaceDir, identity) {
16860
18823
  try {
16861
- await import_promises4.default.access(envPath(spaceDir));
18824
+ await import_promises7.default.access(envPath(spaceDir));
16862
18825
  } catch {
16863
18826
  return {};
16864
18827
  }
@@ -16887,14 +18850,14 @@ async function readEnv(spaceDir, identity) {
16887
18850
  return values;
16888
18851
  }
16889
18852
  async function writeEnv(configDir, spaceDir, identity, values) {
16890
- const recipient = (await import_promises4.default.readFile(import_path10.default.join(configDir, RECIPIENT_FILE), "utf-8")).trim();
18853
+ const recipient = (await import_promises7.default.readFile(import_path10.default.join(configDir, RECIPIENT_FILE), "utf-8")).trim();
16891
18854
  const plain = `${Object.entries(values).map(([k, v]) => `${k}=${v}`).join("\n")}
16892
18855
  `;
16893
18856
  const tmp = envPath(spaceDir).replace(
16894
18857
  /\.enc\.env$/,
16895
18858
  `.${process.pid}.tmp.env`
16896
18859
  );
16897
- await import_promises4.default.writeFile(tmp, plain, { mode: 384 });
18860
+ await import_promises7.default.writeFile(tmp, plain, { mode: 384 });
16898
18861
  try {
16899
18862
  const { stdout } = await execFileAsync3(
16900
18863
  "sops",
@@ -16913,9 +18876,9 @@ async function writeEnv(configDir, spaceDir, identity, values) {
16913
18876
  maxBuffer: 4 * 1024 * 1024
16914
18877
  }
16915
18878
  );
16916
- await import_promises4.default.writeFile(envPath(spaceDir), stdout, { mode: 384 });
18879
+ await import_promises7.default.writeFile(envPath(spaceDir), stdout, { mode: 384 });
16917
18880
  } finally {
16918
- await import_promises4.default.rm(tmp, { force: true });
18881
+ await import_promises7.default.rm(tmp, { force: true });
16919
18882
  }
16920
18883
  }
16921
18884
  async function listSecretKeys(configDir, spaceDir, password) {
@@ -17650,6 +19613,12 @@ var SpaceCore = class {
17650
19613
  await this.ensureSpaceWorkspace();
17651
19614
  return { ready: true };
17652
19615
  }
19616
+ async bareWorkNames() {
19617
+ const config = this.configProvider.readConfig(this.spaceSlug);
19618
+ if (!config.githubToken || !config.repoUrl) return [];
19619
+ await this.ensureSpaceWorkspace();
19620
+ return listWorkNames(this.target());
19621
+ }
17653
19622
  async cardRemoteBranches() {
17654
19623
  const config = this.configProvider.readConfig(this.spaceSlug);
17655
19624
  if (!config.githubToken || !config.repoUrl) return [];
@@ -17768,6 +19737,9 @@ var BoardAgentEngine = class _BoardAgentEngine {
17768
19737
  cardRemoteBranches() {
17769
19738
  return this.core.cardRemoteBranches();
17770
19739
  }
19740
+ bareWorkNames() {
19741
+ return this.core.bareWorkNames();
19742
+ }
17771
19743
  // Deploy button entry: is the repo's deploy contract (SKILL.md +
17772
19744
  // required-variables.json) on the default branch? See .specs/deploy.md.
17773
19745
  async deployStatus() {
@@ -17837,18 +19809,18 @@ var BoardAgentEngine = class _BoardAgentEngine {
17837
19809
  * setup-status channel. A second request cancels the pending one. */
17838
19810
  askSudo(reason) {
17839
19811
  this.sudoResolver?.(null);
17840
- return new Promise((resolve2) => {
17841
- this.sudoResolver = resolve2;
19812
+ return new Promise((resolve4) => {
19813
+ this.sudoResolver = resolve4;
17842
19814
  this.emitter.emitSetupStatus(`${SETUP_AUTH_PREFIX}${reason}`);
17843
19815
  });
17844
19816
  }
17845
19817
  /** Answer a pending sudo request. An empty password denies it, so setup
17846
19818
  * fails with a message rather than hanging. */
17847
19819
  setupAuthorize(p) {
17848
- const resolve2 = this.sudoResolver;
17849
- if (!resolve2) return { success: false };
19820
+ const resolve4 = this.sudoResolver;
19821
+ if (!resolve4) return { success: false };
17850
19822
  this.sudoResolver = null;
17851
- resolve2(p.password || null);
19823
+ resolve4(p.password || null);
17852
19824
  return { success: true };
17853
19825
  }
17854
19826
  deployRunState() {
@@ -17902,12 +19874,12 @@ var BoardAgentEngine = class _BoardAgentEngine {
17902
19874
  hooks: {
17903
19875
  sendLog: bufferLog,
17904
19876
  onTodos: (todos) => this.setRun({ todos }),
17905
- requestHuman: (question) => new Promise((resolve2) => {
17906
- this.runResolvers.human = resolve2;
19877
+ requestHuman: (question) => new Promise((resolve4) => {
19878
+ this.runResolvers.human = resolve4;
17907
19879
  this.setRun({ phase: "awaiting-input", question });
17908
19880
  }),
17909
- requestAuth: (command, errorNote) => new Promise((resolve2) => {
17910
- this.runResolvers.auth = resolve2;
19881
+ requestAuth: (command, errorNote) => new Promise((resolve4) => {
19882
+ this.runResolvers.auth = resolve4;
17911
19883
  this.setRun({
17912
19884
  phase: "awaiting-auth",
17913
19885
  pendingCommand: command,
@@ -17940,35 +19912,35 @@ var BoardAgentEngine = class _BoardAgentEngine {
17940
19912
  return { started: true };
17941
19913
  }
17942
19914
  deployRunAnswer(payload) {
17943
- const resolve2 = this.runResolvers.human;
17944
- if (!resolve2 || this.runState.phase !== "awaiting-input") {
19915
+ const resolve4 = this.runResolvers.human;
19916
+ if (!resolve4 || this.runState.phase !== "awaiting-input") {
17945
19917
  throw new Error("No step is awaiting input.");
17946
19918
  }
17947
19919
  this.runResolvers.human = void 0;
17948
19920
  this.setRun({ phase: "running", question: "", error: "" });
17949
- resolve2(payload.answer);
19921
+ resolve4(payload.answer);
17950
19922
  return { success: true };
17951
19923
  }
17952
19924
  // The password arrives RUNNER-DIRECT here and only feeds decryption; it
17953
19925
  // never enters the agent session (see .specs/deploy.md).
17954
19926
  deployRunAuthorize(payload) {
17955
- const resolve2 = this.runResolvers.auth;
17956
- if (!resolve2 || this.runState.phase !== "awaiting-auth") {
19927
+ const resolve4 = this.runResolvers.auth;
19928
+ if (!resolve4 || this.runState.phase !== "awaiting-auth") {
17957
19929
  throw new Error("No command is awaiting authorization.");
17958
19930
  }
17959
19931
  this.runResolvers.auth = void 0;
17960
19932
  this.setRun({ phase: "running", pendingCommand: "", error: "" });
17961
- resolve2({ password: payload.password });
19933
+ resolve4({ password: payload.password });
17962
19934
  return { success: true };
17963
19935
  }
17964
19936
  deployRunDeny() {
17965
- const resolve2 = this.runResolvers.auth;
17966
- if (!resolve2 || this.runState.phase !== "awaiting-auth") {
19937
+ const resolve4 = this.runResolvers.auth;
19938
+ if (!resolve4 || this.runState.phase !== "awaiting-auth") {
17967
19939
  throw new Error("No command is awaiting authorization.");
17968
19940
  }
17969
19941
  this.runResolvers.auth = void 0;
17970
19942
  this.setRun({ phase: "running", pendingCommand: "" });
17971
- resolve2({ denied: true });
19943
+ resolve4({ denied: true });
17972
19944
  return { success: true };
17973
19945
  }
17974
19946
  deployRunCancel() {
@@ -18856,6 +20828,8 @@ ${c.content.trim() || "(no description)"}`
18856
20828
  return await this.ensureSetup();
18857
20829
  case "cardRemoteBranches":
18858
20830
  return await this.cardRemoteBranches();
20831
+ case "bareWorkNames":
20832
+ return await this.bareWorkNames();
18859
20833
  case "deployStatus":
18860
20834
  return await this.deployStatus();
18861
20835
  case "deployCreateSkill":
@@ -19068,8 +21042,8 @@ ${c.content.trim() || "(no description)"}`
19068
21042
  // ../../shared/all/helpers/board-agent-core/index-service.ts
19069
21043
  var import_child_process7 = require("child_process");
19070
21044
  var import_crypto6 = require("crypto");
19071
- var import_fs7 = require("fs");
19072
- var import_promises5 = __toESM(require("fs/promises"));
21045
+ var import_fs9 = require("fs");
21046
+ var import_promises8 = __toESM(require("fs/promises"));
19073
21047
  var import_net2 = require("net");
19074
21048
  var import_path13 = require("path");
19075
21049
  var import_util7 = require("util");
@@ -19158,8 +21132,8 @@ var IndexService = class {
19158
21132
  * opened (a missing log must never stop the service from starting). */
19159
21133
  async openLog() {
19160
21134
  try {
19161
- await import_promises5.default.mkdir(this.opts.dataDir, { recursive: true });
19162
- return (0, import_fs7.openSync)((0, import_path13.join)(this.opts.dataDir, "index.log"), "a");
21135
+ await import_promises8.default.mkdir(this.opts.dataDir, { recursive: true });
21136
+ return (0, import_fs9.openSync)((0, import_path13.join)(this.opts.dataDir, "index.log"), "a");
19163
21137
  } catch {
19164
21138
  return null;
19165
21139
  }
@@ -19168,8 +21142,8 @@ var IndexService = class {
19168
21142
  * platform needing node-gyp fails here rather than at query time. */
19169
21143
  async installDeps() {
19170
21144
  const dir = this.opts.indexDir;
19171
- if ((0, import_fs7.existsSync)((0, import_path13.join)(dir, "node_modules"))) return;
19172
- await import_promises5.default.copyFile(
21145
+ if ((0, import_fs9.existsSync)((0, import_path13.join)(dir, "node_modules"))) return;
21146
+ await import_promises8.default.copyFile(
19173
21147
  (0, import_path13.join)(dir, "image-package.json"),
19174
21148
  (0, import_path13.join)(dir, "package.json")
19175
21149
  );
@@ -19184,14 +21158,14 @@ var IndexService = class {
19184
21158
  * registration pointing at a dead one. */
19185
21159
  async stablePort() {
19186
21160
  const file = (0, import_path13.join)(this.opts.dataDir, ".port");
19187
- const saved = Number(await import_promises5.default.readFile(file, "utf-8").catch(() => ""));
21161
+ const saved = Number(await import_promises8.default.readFile(file, "utf-8").catch(() => ""));
19188
21162
  if (Number.isInteger(saved) && saved > 0 && await isFree(saved)) {
19189
21163
  return saved;
19190
21164
  }
19191
21165
  const port = await freePort();
19192
- await import_promises5.default.mkdir(this.opts.dataDir, { recursive: true }).catch(() => {
21166
+ await import_promises8.default.mkdir(this.opts.dataDir, { recursive: true }).catch(() => {
19193
21167
  });
19194
- await import_promises5.default.writeFile(file, String(port), "utf-8").catch(() => {
21168
+ await import_promises8.default.writeFile(file, String(port), "utf-8").catch(() => {
19195
21169
  });
19196
21170
  return port;
19197
21171
  }
@@ -19284,20 +21258,20 @@ var IndexService = class {
19284
21258
  }
19285
21259
  };
19286
21260
  function isFree(port) {
19287
- return new Promise((resolve2) => {
21261
+ return new Promise((resolve4) => {
19288
21262
  const srv = (0, import_net2.createServer)();
19289
- srv.once("error", () => resolve2(false));
19290
- srv.listen(port, "127.0.0.1", () => srv.close(() => resolve2(true)));
21263
+ srv.once("error", () => resolve4(false));
21264
+ srv.listen(port, "127.0.0.1", () => srv.close(() => resolve4(true)));
19291
21265
  });
19292
21266
  }
19293
21267
  function freePort() {
19294
- return new Promise((resolve2, reject) => {
21268
+ return new Promise((resolve4, reject) => {
19295
21269
  const srv = (0, import_net2.createServer)();
19296
21270
  srv.on("error", reject);
19297
21271
  srv.listen(0, "127.0.0.1", () => {
19298
21272
  const addr = srv.address();
19299
21273
  const port = typeof addr === "object" && addr ? addr.port : 0;
19300
- srv.close(() => resolve2(port));
21274
+ srv.close(() => resolve4(port));
19301
21275
  });
19302
21276
  });
19303
21277
  }
@@ -19348,7 +21322,7 @@ async function setup(serverUrl) {
19348
21322
  // src/selfUpdate.ts
19349
21323
  var import_node_child_process = require("node:child_process");
19350
21324
  var import_node_fs = __toESM(require("node:fs"));
19351
- var import_node_path = __toESM(require("node:path"));
21325
+ var import_node_path2 = __toESM(require("node:path"));
19352
21326
  var PACKAGE_NAME = "@factiii/runner";
19353
21327
  var RESTART_FOR_UPDATE = 75;
19354
21328
  var WORKER_ENV = "FACTIII_RUNNER_WORKER";
@@ -19361,7 +21335,7 @@ function isWorker() {
19361
21335
  function currentVersion() {
19362
21336
  try {
19363
21337
  const pkg = JSON.parse(
19364
- import_node_fs.default.readFileSync(import_node_path.default.join(__dirname, "..", "package.json"), "utf-8")
21338
+ import_node_fs.default.readFileSync(import_node_path2.default.join(__dirname, "..", "package.json"), "utf-8")
19365
21339
  );
19366
21340
  return pkg.version ?? "0.0.0";
19367
21341
  } catch {
@@ -19437,7 +21411,7 @@ function makeChunkReassembler() {
19437
21411
 
19438
21412
  // src/daemon.ts
19439
21413
  var import_crypto7 = require("crypto");
19440
- var import_fs9 = __toESM(require("fs"));
21414
+ var import_fs11 = __toESM(require("fs"));
19441
21415
  var import_node_datachannel = require("node-datachannel");
19442
21416
  var import_path15 = __toESM(require("path"));
19443
21417
 
@@ -21936,9 +23910,9 @@ var Socket2 = class extends import_component_emitter5.Emitter {
21936
23910
  * @return a Promise that will be fulfilled when the server acknowledges the event
21937
23911
  */
21938
23912
  emitWithAck(ev, ...args) {
21939
- return new Promise((resolve2, reject) => {
23913
+ return new Promise((resolve4, reject) => {
21940
23914
  const fn = (arg1, arg2) => {
21941
- return arg1 ? reject(arg1) : resolve2(arg2);
23915
+ return arg1 ? reject(arg1) : resolve4(arg2);
21942
23916
  };
21943
23917
  fn.withError = true;
21944
23918
  args.push(fn);
@@ -23119,7 +25093,7 @@ var TerminalManager = class {
23119
25093
  };
23120
25094
 
23121
25095
  // src/agent-adapter.ts
23122
- var import_fs8 = __toESM(require("fs"));
25096
+ var import_fs10 = __toESM(require("fs"));
23123
25097
  var import_path14 = __toESM(require("path"));
23124
25098
  var RUNNER_CONFIG_PATH = import_path14.default.join(CONFIG_DIR, "runner-config.json");
23125
25099
  function connectionPath(spaceSlug) {
@@ -23150,7 +25124,7 @@ function migrateLegacyConfigs() {
23150
25124
  const file = { boards: {} };
23151
25125
  let legacy = [];
23152
25126
  try {
23153
- legacy = import_fs8.default.readdirSync(CONFIG_DIR).filter((f) => f.startsWith("space-") && f.endsWith(".json")).filter((f) => !f.endsWith(".onedrive.json"));
25127
+ legacy = import_fs10.default.readdirSync(CONFIG_DIR).filter((f) => f.startsWith("space-") && f.endsWith(".json")).filter((f) => !f.endsWith(".onedrive.json"));
23154
25128
  } catch {
23155
25129
  return file;
23156
25130
  }
@@ -23177,14 +25151,14 @@ function encryptStrayPlaintextConfigs() {
23177
25151
  const OURS = /^(config|runner-config|space-.*)\.json(\.bak-\d+)?$/;
23178
25152
  let names = [];
23179
25153
  try {
23180
- names = import_fs8.default.readdirSync(CONFIG_DIR).filter((f) => OURS.test(f));
25154
+ names = import_fs10.default.readdirSync(CONFIG_DIR).filter((f) => OURS.test(f));
23181
25155
  } catch {
23182
25156
  return;
23183
25157
  }
23184
25158
  for (const name of names) {
23185
25159
  const filePath = import_path14.default.join(CONFIG_DIR, name);
23186
25160
  try {
23187
- const raw = import_fs8.default.readFileSync(filePath, "utf-8");
25161
+ const raw = import_fs10.default.readFileSync(filePath, "utf-8");
23188
25162
  if (!raw.startsWith("{")) continue;
23189
25163
  writeSecureJson(filePath, JSON.parse(raw));
23190
25164
  } catch {
@@ -23215,7 +25189,7 @@ async function getConfiguredConnections() {
23215
25189
  }
23216
25190
  if (await isSignedIn(hostTarget(CONFIG_DIR), "claude")) kinds.add("claude");
23217
25191
  try {
23218
- const hasOneDrive = import_fs8.default.readdirSync(CONFIG_DIR).some((f) => f.endsWith(".onedrive.json"));
25192
+ const hasOneDrive = import_fs10.default.readdirSync(CONFIG_DIR).some((f) => f.endsWith(".onedrive.json"));
23219
25193
  if (hasOneDrive) kinds.add("onedrive");
23220
25194
  } catch {
23221
25195
  }
@@ -23286,7 +25260,7 @@ var localConfigProvider = {
23286
25260
  writeOneDriveConnection(spaceSlug, connection) {
23287
25261
  const filePath = connectionPath(spaceSlug);
23288
25262
  if (!connection) {
23289
- import_fs8.default.rmSync(filePath, { force: true });
25263
+ import_fs10.default.rmSync(filePath, { force: true });
23290
25264
  return;
23291
25265
  }
23292
25266
  writeJson(filePath, connection);
@@ -23311,7 +25285,7 @@ var localConfigProvider = {
23311
25285
  "claude",
23312
25286
  "codex"
23313
25287
  ]) {
23314
- import_fs8.default.mkdirSync(import_path14.default.join(dir, sub), { recursive: true });
25288
+ import_fs10.default.mkdirSync(import_path14.default.join(dir, sub), { recursive: true });
23315
25289
  }
23316
25290
  return dir;
23317
25291
  }
@@ -23435,17 +25409,17 @@ async function startDaemon(config) {
23435
25409
  }
23436
25410
  };
23437
25411
  const mintWebhook = (spaceSlug) => new Promise(
23438
- (resolve2) => {
25412
+ (resolve4) => {
23439
25413
  if (!socket.connected) {
23440
- resolve2(null);
25414
+ resolve4(null);
23441
25415
  return;
23442
25416
  }
23443
25417
  socket.timeout(8e3).emit("onedriveWebhookRegister", { spaceSlug }, (err, res) => {
23444
25418
  if (err || !res || "error" in res) {
23445
- resolve2(null);
25419
+ resolve4(null);
23446
25420
  return;
23447
25421
  }
23448
- resolve2({
25422
+ resolve4({
23449
25423
  notificationUrl: `${config.serverUrl.replace(/\/$/, "")}/onedrive/webhook`,
23450
25424
  clientState: res.clientState
23451
25425
  });
@@ -23456,7 +25430,7 @@ async function startDaemon(config) {
23456
25430
  import_path15.default.join(__dirname, "..", "index"),
23457
25431
  import_path15.default.join(__dirname, "..", "..", "index", "image")
23458
25432
  ];
23459
- const indexDir = indexCandidates.find((p) => import_fs9.default.existsSync(p)) ?? indexCandidates[0];
25433
+ const indexDir = indexCandidates.find((p) => import_fs11.default.existsSync(p)) ?? indexCandidates[0];
23460
25434
  const odIndex = new IndexService({
23461
25435
  controlToken: (0, import_crypto7.createHash)("sha256").update(config.authToken).digest("hex"),
23462
25436
  embedUrl: () => config.serverUrl,
@@ -24111,5 +26085,8 @@ xmlhttprequest-ssl/lib/XMLHttpRequest.js:
24111
26085
  * @contributor David Ellis <d.f.ellis@ieee.org>
24112
26086
  * @license MIT
24113
26087
  *)
26088
+
26089
+ chokidar/esm/index.js:
26090
+ (*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) *)
24114
26091
  */
24115
26092
  //# sourceMappingURL=cli.js.map