chat-logbook 0.4.2 → 0.6.0

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/api/dist/index.js CHANGED
@@ -439,7 +439,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
439
439
  });
440
440
  if (!chunk) {
441
441
  if (i === 1) {
442
- await new Promise((resolve) => setTimeout(resolve));
442
+ await new Promise((resolve3) => setTimeout(resolve3));
443
443
  maxReadCount = 3;
444
444
  continue;
445
445
  }
@@ -3062,12 +3062,12 @@ var ForeignKeyBuilder = class {
3062
3062
  this._onDelete = actions.onDelete;
3063
3063
  }
3064
3064
  }
3065
- onUpdate(action) {
3066
- this._onUpdate = action === void 0 ? "no action" : action;
3065
+ onUpdate(action2) {
3066
+ this._onUpdate = action2 === void 0 ? "no action" : action2;
3067
3067
  return this;
3068
3068
  }
3069
- onDelete(action) {
3070
- this._onDelete = action === void 0 ? "no action" : action;
3069
+ onDelete(action2) {
3070
+ this._onDelete = action2 === void 0 ? "no action" : action2;
3071
3071
  return this;
3072
3072
  }
3073
3073
  /** @internal */
@@ -3890,7 +3890,7 @@ function sql(strings, ...params) {
3890
3890
  return new SQL([new StringChunk(str)]);
3891
3891
  }
3892
3892
  sql2.raw = raw2;
3893
- function join2(chunks, separator) {
3893
+ function join4(chunks, separator) {
3894
3894
  const result = [];
3895
3895
  for (const [i, chunk] of chunks.entries()) {
3896
3896
  if (i > 0 && separator !== void 0) {
@@ -3900,7 +3900,7 @@ function sql(strings, ...params) {
3900
3900
  }
3901
3901
  return new SQL(result);
3902
3902
  }
3903
- sql2.join = join2;
3903
+ sql2.join = join4;
3904
3904
  function identifier(value) {
3905
3905
  return new Name(value);
3906
3906
  }
@@ -4785,12 +4785,12 @@ var ForeignKeyBuilder2 = class {
4785
4785
  this._onDelete = actions.onDelete;
4786
4786
  }
4787
4787
  }
4788
- onUpdate(action) {
4789
- this._onUpdate = action;
4788
+ onUpdate(action2) {
4789
+ this._onUpdate = action2;
4790
4790
  return this;
4791
4791
  }
4792
- onDelete(action) {
4793
- this._onDelete = action;
4792
+ onDelete(action2) {
4793
+ this._onDelete = action2;
4794
4794
  return this;
4795
4795
  }
4796
4796
  /** @internal */
@@ -6450,7 +6450,7 @@ var SQLiteSelectQueryBuilderBase = class extends TypedQueryBuilder {
6450
6450
  const baseTableName = this.tableName;
6451
6451
  const tableName = getTableLikeName(table);
6452
6452
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
6453
- if (typeof tableName === "string" && this.config.joins?.some((join2) => join2.alias === tableName)) {
6453
+ if (typeof tableName === "string" && this.config.joins?.some((join4) => join4.alias === tableName)) {
6454
6454
  throw new Error(`Alias "${tableName}" is already used in this query`);
6455
6455
  }
6456
6456
  if (!this.isPartialSelect) {
@@ -7309,7 +7309,7 @@ var SQLiteUpdateBase = class extends QueryPromise {
7309
7309
  createJoin(joinType) {
7310
7310
  return (table, on) => {
7311
7311
  const tableName = getTableLikeName(table);
7312
- if (typeof tableName === "string" && this.config.joins.some((join2) => join2.alias === tableName)) {
7312
+ if (typeof tableName === "string" && this.config.joins.some((join4) => join4.alias === tableName)) {
7313
7313
  throw new Error(`Alias "${tableName}" is already used in this query`);
7314
7314
  }
7315
7315
  if (typeof on === "function") {
@@ -7629,13 +7629,13 @@ var SQLiteSyncRelationalQuery = class extends SQLiteRelationalQuery {
7629
7629
 
7630
7630
  // ../node_modules/.pnpm/drizzle-orm@0.45.2_@types+better-sqlite3@7.6.13_better-sqlite3@12.9.0/node_modules/drizzle-orm/sqlite-core/query-builders/raw.js
7631
7631
  var SQLiteRaw = class extends QueryPromise {
7632
- constructor(execute, getSQL, action, dialect, mapBatchResult) {
7632
+ constructor(execute, getSQL, action2, dialect, mapBatchResult) {
7633
7633
  super();
7634
7634
  this.execute = execute;
7635
7635
  this.getSQL = getSQL;
7636
7636
  this.dialect = dialect;
7637
7637
  this.mapBatchResult = mapBatchResult;
7638
- this.config = { action };
7638
+ this.config = { action: action2 };
7639
7639
  }
7640
7640
  static [entityKind] = "SQLiteRaw";
7641
7641
  /** @internal */
@@ -8771,7 +8771,7 @@ async function runIngestion(opts) {
8771
8771
  for (const plugin of opts.plugins) {
8772
8772
  for await (const ref of plugin.discover(opts.env)) {
8773
8773
  result.scanned += 1;
8774
- const stat = safeStat(ref.sourcePath);
8774
+ const stat4 = safeStat(ref.sourcePath);
8775
8775
  const prior = opts.archive.db.select().from(sessionScanState).where(
8776
8776
  and(
8777
8777
  eq(sessionScanState.agent, plugin.id),
@@ -8779,7 +8779,7 @@ async function runIngestion(opts) {
8779
8779
  )
8780
8780
  ).get();
8781
8781
  ensureSession(opts.archive, plugin.id, ref.sessionId, now(), ref.project);
8782
- if (stat && prior && prior.lastMtimeMs === stat.mtimeMs && prior.lastSizeBytes === stat.size) {
8782
+ if (stat4 && prior && prior.lastMtimeMs === stat4.mtimeMs && prior.lastSizeBytes === stat4.size) {
8783
8783
  result.skippedByMtime += 1;
8784
8784
  continue;
8785
8785
  }
@@ -8820,13 +8820,13 @@ async function runIngestion(opts) {
8820
8820
  );
8821
8821
  if (upserted) result.canonicalUpserted += 1;
8822
8822
  }
8823
- if (stat) {
8823
+ if (stat4) {
8824
8824
  recordScanState(
8825
8825
  opts.archive,
8826
8826
  plugin.id,
8827
8827
  ref.sessionId,
8828
8828
  ref.sourcePath,
8829
- stat,
8829
+ stat4,
8830
8830
  now()
8831
8831
  );
8832
8832
  }
@@ -8841,7 +8841,7 @@ function safeStat(p) {
8841
8841
  return null;
8842
8842
  }
8843
8843
  }
8844
- function recordScanState(archive2, agent, sessionId, sourcePath, stat, scannedAt) {
8844
+ function recordScanState(archive2, agent, sessionId, sourcePath, stat4, scannedAt) {
8845
8845
  const existing = archive2.db.select({ id: sessionScanState.id }).from(sessionScanState).where(
8846
8846
  and(
8847
8847
  eq(sessionScanState.agent, agent),
@@ -8851,8 +8851,8 @@ function recordScanState(archive2, agent, sessionId, sourcePath, stat, scannedAt
8851
8851
  if (existing) {
8852
8852
  archive2.db.update(sessionScanState).set({
8853
8853
  sourcePath,
8854
- lastMtimeMs: stat.mtimeMs,
8855
- lastSizeBytes: stat.size,
8854
+ lastMtimeMs: stat4.mtimeMs,
8855
+ lastSizeBytes: stat4.size,
8856
8856
  lastScannedAt: scannedAt
8857
8857
  }).where(eq(sessionScanState.id, existing.id)).run();
8858
8858
  } else {
@@ -8860,8 +8860,8 @@ function recordScanState(archive2, agent, sessionId, sourcePath, stat, scannedAt
8860
8860
  agent,
8861
8861
  sessionId,
8862
8862
  sourcePath,
8863
- lastMtimeMs: stat.mtimeMs,
8864
- lastSizeBytes: stat.size,
8863
+ lastMtimeMs: stat4.mtimeMs,
8864
+ lastSizeBytes: stat4.size,
8865
8865
  lastScannedAt: scannedAt
8866
8866
  }).run();
8867
8867
  }
@@ -8944,6 +8944,1815 @@ function startIngestionInBackground(opts, bg = {}) {
8944
8944
  return { done };
8945
8945
  }
8946
8946
 
8947
+ // ../node_modules/.pnpm/chokidar@5.0.0/node_modules/chokidar/index.js
8948
+ import { EventEmitter } from "events";
8949
+ import { stat as statcb, Stats } from "fs";
8950
+ import { readdir as readdir2, stat as stat3 } from "fs/promises";
8951
+ import * as sp2 from "path";
8952
+
8953
+ // ../node_modules/.pnpm/readdirp@5.0.0/node_modules/readdirp/index.js
8954
+ import { lstat, readdir, realpath, stat } from "fs/promises";
8955
+ import { join as pjoin, relative as prelative, resolve as presolve, sep as psep } from "path";
8956
+ import { Readable as Readable3 } from "stream";
8957
+ var EntryTypes = {
8958
+ FILE_TYPE: "files",
8959
+ DIR_TYPE: "directories",
8960
+ FILE_DIR_TYPE: "files_directories",
8961
+ EVERYTHING_TYPE: "all"
8962
+ };
8963
+ var defaultOptions = {
8964
+ root: ".",
8965
+ fileFilter: (_entryInfo) => true,
8966
+ directoryFilter: (_entryInfo) => true,
8967
+ type: EntryTypes.FILE_TYPE,
8968
+ lstat: false,
8969
+ depth: 2147483648,
8970
+ alwaysStat: false,
8971
+ highWaterMark: 4096
8972
+ };
8973
+ Object.freeze(defaultOptions);
8974
+ var RECURSIVE_ERROR_CODE = "READDIRP_RECURSIVE_ERROR";
8975
+ var NORMAL_FLOW_ERRORS = /* @__PURE__ */ new Set(["ENOENT", "EPERM", "EACCES", "ELOOP", RECURSIVE_ERROR_CODE]);
8976
+ var ALL_TYPES = [
8977
+ EntryTypes.DIR_TYPE,
8978
+ EntryTypes.EVERYTHING_TYPE,
8979
+ EntryTypes.FILE_DIR_TYPE,
8980
+ EntryTypes.FILE_TYPE
8981
+ ];
8982
+ var DIR_TYPES = /* @__PURE__ */ new Set([
8983
+ EntryTypes.DIR_TYPE,
8984
+ EntryTypes.EVERYTHING_TYPE,
8985
+ EntryTypes.FILE_DIR_TYPE
8986
+ ]);
8987
+ var FILE_TYPES = /* @__PURE__ */ new Set([
8988
+ EntryTypes.EVERYTHING_TYPE,
8989
+ EntryTypes.FILE_DIR_TYPE,
8990
+ EntryTypes.FILE_TYPE
8991
+ ]);
8992
+ var isNormalFlowError = (error) => NORMAL_FLOW_ERRORS.has(error.code);
8993
+ var wantBigintFsStats = process.platform === "win32";
8994
+ var emptyFn = (_entryInfo) => true;
8995
+ var normalizeFilter = (filter) => {
8996
+ if (filter === void 0)
8997
+ return emptyFn;
8998
+ if (typeof filter === "function")
8999
+ return filter;
9000
+ if (typeof filter === "string") {
9001
+ const fl = filter.trim();
9002
+ return (entry) => entry.basename === fl;
9003
+ }
9004
+ if (Array.isArray(filter)) {
9005
+ const trItems = filter.map((item) => item.trim());
9006
+ return (entry) => trItems.some((f) => entry.basename === f);
9007
+ }
9008
+ return emptyFn;
9009
+ };
9010
+ var ReaddirpStream = class extends Readable3 {
9011
+ parents;
9012
+ reading;
9013
+ parent;
9014
+ _stat;
9015
+ _maxDepth;
9016
+ _wantsDir;
9017
+ _wantsFile;
9018
+ _wantsEverything;
9019
+ _root;
9020
+ _isDirent;
9021
+ _statsProp;
9022
+ _rdOptions;
9023
+ _fileFilter;
9024
+ _directoryFilter;
9025
+ constructor(options = {}) {
9026
+ super({
9027
+ objectMode: true,
9028
+ autoDestroy: true,
9029
+ highWaterMark: options.highWaterMark
9030
+ });
9031
+ const opts = { ...defaultOptions, ...options };
9032
+ const { root, type } = opts;
9033
+ this._fileFilter = normalizeFilter(opts.fileFilter);
9034
+ this._directoryFilter = normalizeFilter(opts.directoryFilter);
9035
+ const statMethod = opts.lstat ? lstat : stat;
9036
+ if (wantBigintFsStats) {
9037
+ this._stat = (path5) => statMethod(path5, { bigint: true });
9038
+ } else {
9039
+ this._stat = statMethod;
9040
+ }
9041
+ this._maxDepth = opts.depth != null && Number.isSafeInteger(opts.depth) ? opts.depth : defaultOptions.depth;
9042
+ this._wantsDir = type ? DIR_TYPES.has(type) : false;
9043
+ this._wantsFile = type ? FILE_TYPES.has(type) : false;
9044
+ this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
9045
+ this._root = presolve(root);
9046
+ this._isDirent = !opts.alwaysStat;
9047
+ this._statsProp = this._isDirent ? "dirent" : "stats";
9048
+ this._rdOptions = { encoding: "utf8", withFileTypes: this._isDirent };
9049
+ this.parents = [this._exploreDir(root, 1)];
9050
+ this.reading = false;
9051
+ this.parent = void 0;
9052
+ }
9053
+ async _read(batch) {
9054
+ if (this.reading)
9055
+ return;
9056
+ this.reading = true;
9057
+ try {
9058
+ while (!this.destroyed && batch > 0) {
9059
+ const par = this.parent;
9060
+ const fil = par && par.files;
9061
+ if (fil && fil.length > 0) {
9062
+ const { path: path5, depth } = par;
9063
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path5));
9064
+ const awaited = await Promise.all(slice);
9065
+ for (const entry of awaited) {
9066
+ if (!entry)
9067
+ continue;
9068
+ if (this.destroyed)
9069
+ return;
9070
+ const entryType = await this._getEntryType(entry);
9071
+ if (entryType === "directory" && this._directoryFilter(entry)) {
9072
+ if (depth <= this._maxDepth) {
9073
+ this.parents.push(this._exploreDir(entry.fullPath, depth + 1));
9074
+ }
9075
+ if (this._wantsDir) {
9076
+ this.push(entry);
9077
+ batch--;
9078
+ }
9079
+ } else if ((entryType === "file" || this._includeAsFile(entry)) && this._fileFilter(entry)) {
9080
+ if (this._wantsFile) {
9081
+ this.push(entry);
9082
+ batch--;
9083
+ }
9084
+ }
9085
+ }
9086
+ } else {
9087
+ const parent = this.parents.pop();
9088
+ if (!parent) {
9089
+ this.push(null);
9090
+ break;
9091
+ }
9092
+ this.parent = await parent;
9093
+ if (this.destroyed)
9094
+ return;
9095
+ }
9096
+ }
9097
+ } catch (error) {
9098
+ this.destroy(error);
9099
+ } finally {
9100
+ this.reading = false;
9101
+ }
9102
+ }
9103
+ async _exploreDir(path5, depth) {
9104
+ let files;
9105
+ try {
9106
+ files = await readdir(path5, this._rdOptions);
9107
+ } catch (error) {
9108
+ this._onError(error);
9109
+ }
9110
+ return { files, depth, path: path5 };
9111
+ }
9112
+ async _formatEntry(dirent, path5) {
9113
+ let entry;
9114
+ const basename3 = this._isDirent ? dirent.name : dirent;
9115
+ try {
9116
+ const fullPath = presolve(pjoin(path5, basename3));
9117
+ entry = { path: prelative(this._root, fullPath), fullPath, basename: basename3 };
9118
+ entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
9119
+ } catch (err) {
9120
+ this._onError(err);
9121
+ return;
9122
+ }
9123
+ return entry;
9124
+ }
9125
+ _onError(err) {
9126
+ if (isNormalFlowError(err) && !this.destroyed) {
9127
+ this.emit("warn", err);
9128
+ } else {
9129
+ this.destroy(err);
9130
+ }
9131
+ }
9132
+ async _getEntryType(entry) {
9133
+ if (!entry && this._statsProp in entry) {
9134
+ return "";
9135
+ }
9136
+ const stats = entry[this._statsProp];
9137
+ if (stats.isFile())
9138
+ return "file";
9139
+ if (stats.isDirectory())
9140
+ return "directory";
9141
+ if (stats && stats.isSymbolicLink()) {
9142
+ const full = entry.fullPath;
9143
+ try {
9144
+ const entryRealPath = await realpath(full);
9145
+ const entryRealPathStats = await lstat(entryRealPath);
9146
+ if (entryRealPathStats.isFile()) {
9147
+ return "file";
9148
+ }
9149
+ if (entryRealPathStats.isDirectory()) {
9150
+ const len = entryRealPath.length;
9151
+ if (full.startsWith(entryRealPath) && full.substr(len, 1) === psep) {
9152
+ const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`);
9153
+ recursiveError.code = RECURSIVE_ERROR_CODE;
9154
+ return this._onError(recursiveError);
9155
+ }
9156
+ return "directory";
9157
+ }
9158
+ } catch (error) {
9159
+ this._onError(error);
9160
+ return "";
9161
+ }
9162
+ }
9163
+ }
9164
+ _includeAsFile(entry) {
9165
+ const stats = entry && entry[this._statsProp];
9166
+ return stats && this._wantsEverything && !stats.isDirectory();
9167
+ }
9168
+ };
9169
+ function readdirp(root, options = {}) {
9170
+ let type = options.entryType || options.type;
9171
+ if (type === "both")
9172
+ type = EntryTypes.FILE_DIR_TYPE;
9173
+ if (type)
9174
+ options.type = type;
9175
+ if (!root) {
9176
+ throw new Error("readdirp: root argument is required. Usage: readdirp(root, options)");
9177
+ } else if (typeof root !== "string") {
9178
+ throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");
9179
+ } else if (type && !ALL_TYPES.includes(type)) {
9180
+ throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(", ")}`);
9181
+ }
9182
+ options.root = root;
9183
+ return new ReaddirpStream(options);
9184
+ }
9185
+
9186
+ // ../node_modules/.pnpm/chokidar@5.0.0/node_modules/chokidar/handler.js
9187
+ import { watch as fs_watch, unwatchFile, watchFile } from "fs";
9188
+ import { realpath as fsrealpath, lstat as lstat2, open, stat as stat2 } from "fs/promises";
9189
+ import { type as osType } from "os";
9190
+ import * as sp from "path";
9191
+ var STR_DATA = "data";
9192
+ var STR_END = "end";
9193
+ var STR_CLOSE = "close";
9194
+ var EMPTY_FN = () => {
9195
+ };
9196
+ var pl = process.platform;
9197
+ var isWindows = pl === "win32";
9198
+ var isMacos = pl === "darwin";
9199
+ var isLinux = pl === "linux";
9200
+ var isFreeBSD = pl === "freebsd";
9201
+ var isIBMi = osType() === "OS400";
9202
+ var EVENTS = {
9203
+ ALL: "all",
9204
+ READY: "ready",
9205
+ ADD: "add",
9206
+ CHANGE: "change",
9207
+ ADD_DIR: "addDir",
9208
+ UNLINK: "unlink",
9209
+ UNLINK_DIR: "unlinkDir",
9210
+ RAW: "raw",
9211
+ ERROR: "error"
9212
+ };
9213
+ var EV = EVENTS;
9214
+ var THROTTLE_MODE_WATCH = "watch";
9215
+ var statMethods = { lstat: lstat2, stat: stat2 };
9216
+ var KEY_LISTENERS = "listeners";
9217
+ var KEY_ERR = "errHandlers";
9218
+ var KEY_RAW = "rawEmitters";
9219
+ var HANDLER_KEYS = [KEY_LISTENERS, KEY_ERR, KEY_RAW];
9220
+ var binaryExtensions = /* @__PURE__ */ new Set([
9221
+ "3dm",
9222
+ "3ds",
9223
+ "3g2",
9224
+ "3gp",
9225
+ "7z",
9226
+ "a",
9227
+ "aac",
9228
+ "adp",
9229
+ "afdesign",
9230
+ "afphoto",
9231
+ "afpub",
9232
+ "ai",
9233
+ "aif",
9234
+ "aiff",
9235
+ "alz",
9236
+ "ape",
9237
+ "apk",
9238
+ "appimage",
9239
+ "ar",
9240
+ "arj",
9241
+ "asf",
9242
+ "au",
9243
+ "avi",
9244
+ "bak",
9245
+ "baml",
9246
+ "bh",
9247
+ "bin",
9248
+ "bk",
9249
+ "bmp",
9250
+ "btif",
9251
+ "bz2",
9252
+ "bzip2",
9253
+ "cab",
9254
+ "caf",
9255
+ "cgm",
9256
+ "class",
9257
+ "cmx",
9258
+ "cpio",
9259
+ "cr2",
9260
+ "cur",
9261
+ "dat",
9262
+ "dcm",
9263
+ "deb",
9264
+ "dex",
9265
+ "djvu",
9266
+ "dll",
9267
+ "dmg",
9268
+ "dng",
9269
+ "doc",
9270
+ "docm",
9271
+ "docx",
9272
+ "dot",
9273
+ "dotm",
9274
+ "dra",
9275
+ "DS_Store",
9276
+ "dsk",
9277
+ "dts",
9278
+ "dtshd",
9279
+ "dvb",
9280
+ "dwg",
9281
+ "dxf",
9282
+ "ecelp4800",
9283
+ "ecelp7470",
9284
+ "ecelp9600",
9285
+ "egg",
9286
+ "eol",
9287
+ "eot",
9288
+ "epub",
9289
+ "exe",
9290
+ "f4v",
9291
+ "fbs",
9292
+ "fh",
9293
+ "fla",
9294
+ "flac",
9295
+ "flatpak",
9296
+ "fli",
9297
+ "flv",
9298
+ "fpx",
9299
+ "fst",
9300
+ "fvt",
9301
+ "g3",
9302
+ "gh",
9303
+ "gif",
9304
+ "graffle",
9305
+ "gz",
9306
+ "gzip",
9307
+ "h261",
9308
+ "h263",
9309
+ "h264",
9310
+ "icns",
9311
+ "ico",
9312
+ "ief",
9313
+ "img",
9314
+ "ipa",
9315
+ "iso",
9316
+ "jar",
9317
+ "jpeg",
9318
+ "jpg",
9319
+ "jpgv",
9320
+ "jpm",
9321
+ "jxr",
9322
+ "key",
9323
+ "ktx",
9324
+ "lha",
9325
+ "lib",
9326
+ "lvp",
9327
+ "lz",
9328
+ "lzh",
9329
+ "lzma",
9330
+ "lzo",
9331
+ "m3u",
9332
+ "m4a",
9333
+ "m4v",
9334
+ "mar",
9335
+ "mdi",
9336
+ "mht",
9337
+ "mid",
9338
+ "midi",
9339
+ "mj2",
9340
+ "mka",
9341
+ "mkv",
9342
+ "mmr",
9343
+ "mng",
9344
+ "mobi",
9345
+ "mov",
9346
+ "movie",
9347
+ "mp3",
9348
+ "mp4",
9349
+ "mp4a",
9350
+ "mpeg",
9351
+ "mpg",
9352
+ "mpga",
9353
+ "mxu",
9354
+ "nef",
9355
+ "npx",
9356
+ "numbers",
9357
+ "nupkg",
9358
+ "o",
9359
+ "odp",
9360
+ "ods",
9361
+ "odt",
9362
+ "oga",
9363
+ "ogg",
9364
+ "ogv",
9365
+ "otf",
9366
+ "ott",
9367
+ "pages",
9368
+ "pbm",
9369
+ "pcx",
9370
+ "pdb",
9371
+ "pdf",
9372
+ "pea",
9373
+ "pgm",
9374
+ "pic",
9375
+ "png",
9376
+ "pnm",
9377
+ "pot",
9378
+ "potm",
9379
+ "potx",
9380
+ "ppa",
9381
+ "ppam",
9382
+ "ppm",
9383
+ "pps",
9384
+ "ppsm",
9385
+ "ppsx",
9386
+ "ppt",
9387
+ "pptm",
9388
+ "pptx",
9389
+ "psd",
9390
+ "pya",
9391
+ "pyc",
9392
+ "pyo",
9393
+ "pyv",
9394
+ "qt",
9395
+ "rar",
9396
+ "ras",
9397
+ "raw",
9398
+ "resources",
9399
+ "rgb",
9400
+ "rip",
9401
+ "rlc",
9402
+ "rmf",
9403
+ "rmvb",
9404
+ "rpm",
9405
+ "rtf",
9406
+ "rz",
9407
+ "s3m",
9408
+ "s7z",
9409
+ "scpt",
9410
+ "sgi",
9411
+ "shar",
9412
+ "snap",
9413
+ "sil",
9414
+ "sketch",
9415
+ "slk",
9416
+ "smv",
9417
+ "snk",
9418
+ "so",
9419
+ "stl",
9420
+ "suo",
9421
+ "sub",
9422
+ "swf",
9423
+ "tar",
9424
+ "tbz",
9425
+ "tbz2",
9426
+ "tga",
9427
+ "tgz",
9428
+ "thmx",
9429
+ "tif",
9430
+ "tiff",
9431
+ "tlz",
9432
+ "ttc",
9433
+ "ttf",
9434
+ "txz",
9435
+ "udf",
9436
+ "uvh",
9437
+ "uvi",
9438
+ "uvm",
9439
+ "uvp",
9440
+ "uvs",
9441
+ "uvu",
9442
+ "viv",
9443
+ "vob",
9444
+ "war",
9445
+ "wav",
9446
+ "wax",
9447
+ "wbmp",
9448
+ "wdp",
9449
+ "weba",
9450
+ "webm",
9451
+ "webp",
9452
+ "whl",
9453
+ "wim",
9454
+ "wm",
9455
+ "wma",
9456
+ "wmv",
9457
+ "wmx",
9458
+ "woff",
9459
+ "woff2",
9460
+ "wrm",
9461
+ "wvx",
9462
+ "xbm",
9463
+ "xif",
9464
+ "xla",
9465
+ "xlam",
9466
+ "xls",
9467
+ "xlsb",
9468
+ "xlsm",
9469
+ "xlsx",
9470
+ "xlt",
9471
+ "xltm",
9472
+ "xltx",
9473
+ "xm",
9474
+ "xmind",
9475
+ "xpi",
9476
+ "xpm",
9477
+ "xwd",
9478
+ "xz",
9479
+ "z",
9480
+ "zip",
9481
+ "zipx"
9482
+ ]);
9483
+ var isBinaryPath = (filePath) => binaryExtensions.has(sp.extname(filePath).slice(1).toLowerCase());
9484
+ var foreach = (val, fn) => {
9485
+ if (val instanceof Set) {
9486
+ val.forEach(fn);
9487
+ } else {
9488
+ fn(val);
9489
+ }
9490
+ };
9491
+ var addAndConvert = (main, prop, item) => {
9492
+ let container = main[prop];
9493
+ if (!(container instanceof Set)) {
9494
+ main[prop] = container = /* @__PURE__ */ new Set([container]);
9495
+ }
9496
+ container.add(item);
9497
+ };
9498
+ var clearItem = (cont) => (key) => {
9499
+ const set = cont[key];
9500
+ if (set instanceof Set) {
9501
+ set.clear();
9502
+ } else {
9503
+ delete cont[key];
9504
+ }
9505
+ };
9506
+ var delFromSet = (main, prop, item) => {
9507
+ const container = main[prop];
9508
+ if (container instanceof Set) {
9509
+ container.delete(item);
9510
+ } else if (container === item) {
9511
+ delete main[prop];
9512
+ }
9513
+ };
9514
+ var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
9515
+ var FsWatchInstances = /* @__PURE__ */ new Map();
9516
+ function createFsWatchInstance(path5, options, listener, errHandler, emitRaw) {
9517
+ const handleEvent = (rawEvent, evPath) => {
9518
+ listener(path5);
9519
+ emitRaw(rawEvent, evPath, { watchedPath: path5 });
9520
+ if (evPath && path5 !== evPath) {
9521
+ fsWatchBroadcast(sp.resolve(path5, evPath), KEY_LISTENERS, sp.join(path5, evPath));
9522
+ }
9523
+ };
9524
+ try {
9525
+ return fs_watch(path5, {
9526
+ persistent: options.persistent
9527
+ }, handleEvent);
9528
+ } catch (error) {
9529
+ errHandler(error);
9530
+ return void 0;
9531
+ }
9532
+ }
9533
+ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
9534
+ const cont = FsWatchInstances.get(fullPath);
9535
+ if (!cont)
9536
+ return;
9537
+ foreach(cont[listenerType], (listener) => {
9538
+ listener(val1, val2, val3);
9539
+ });
9540
+ };
9541
+ var setFsWatchListener = (path5, fullPath, options, handlers) => {
9542
+ const { listener, errHandler, rawEmitter } = handlers;
9543
+ let cont = FsWatchInstances.get(fullPath);
9544
+ let watcher2;
9545
+ if (!options.persistent) {
9546
+ watcher2 = createFsWatchInstance(path5, options, listener, errHandler, rawEmitter);
9547
+ if (!watcher2)
9548
+ return;
9549
+ return watcher2.close.bind(watcher2);
9550
+ }
9551
+ if (cont) {
9552
+ addAndConvert(cont, KEY_LISTENERS, listener);
9553
+ addAndConvert(cont, KEY_ERR, errHandler);
9554
+ addAndConvert(cont, KEY_RAW, rawEmitter);
9555
+ } else {
9556
+ watcher2 = createFsWatchInstance(
9557
+ path5,
9558
+ options,
9559
+ fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
9560
+ errHandler,
9561
+ // no need to use broadcast here
9562
+ fsWatchBroadcast.bind(null, fullPath, KEY_RAW)
9563
+ );
9564
+ if (!watcher2)
9565
+ return;
9566
+ watcher2.on(EV.ERROR, async (error) => {
9567
+ const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR);
9568
+ if (cont)
9569
+ cont.watcherUnusable = true;
9570
+ if (isWindows && error.code === "EPERM") {
9571
+ try {
9572
+ const fd = await open(path5, "r");
9573
+ await fd.close();
9574
+ broadcastErr(error);
9575
+ } catch (err) {
9576
+ }
9577
+ } else {
9578
+ broadcastErr(error);
9579
+ }
9580
+ });
9581
+ cont = {
9582
+ listeners: listener,
9583
+ errHandlers: errHandler,
9584
+ rawEmitters: rawEmitter,
9585
+ watcher: watcher2
9586
+ };
9587
+ FsWatchInstances.set(fullPath, cont);
9588
+ }
9589
+ return () => {
9590
+ delFromSet(cont, KEY_LISTENERS, listener);
9591
+ delFromSet(cont, KEY_ERR, errHandler);
9592
+ delFromSet(cont, KEY_RAW, rawEmitter);
9593
+ if (isEmptySet(cont.listeners)) {
9594
+ cont.watcher.close();
9595
+ FsWatchInstances.delete(fullPath);
9596
+ HANDLER_KEYS.forEach(clearItem(cont));
9597
+ cont.watcher = void 0;
9598
+ Object.freeze(cont);
9599
+ }
9600
+ };
9601
+ };
9602
+ var FsWatchFileInstances = /* @__PURE__ */ new Map();
9603
+ var setFsWatchFileListener = (path5, fullPath, options, handlers) => {
9604
+ const { listener, rawEmitter } = handlers;
9605
+ let cont = FsWatchFileInstances.get(fullPath);
9606
+ const copts = cont && cont.options;
9607
+ if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
9608
+ unwatchFile(fullPath);
9609
+ cont = void 0;
9610
+ }
9611
+ if (cont) {
9612
+ addAndConvert(cont, KEY_LISTENERS, listener);
9613
+ addAndConvert(cont, KEY_RAW, rawEmitter);
9614
+ } else {
9615
+ cont = {
9616
+ listeners: listener,
9617
+ rawEmitters: rawEmitter,
9618
+ options,
9619
+ watcher: watchFile(fullPath, options, (curr, prev) => {
9620
+ foreach(cont.rawEmitters, (rawEmitter2) => {
9621
+ rawEmitter2(EV.CHANGE, fullPath, { curr, prev });
9622
+ });
9623
+ const currmtime = curr.mtimeMs;
9624
+ if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
9625
+ foreach(cont.listeners, (listener2) => listener2(path5, curr));
9626
+ }
9627
+ })
9628
+ };
9629
+ FsWatchFileInstances.set(fullPath, cont);
9630
+ }
9631
+ return () => {
9632
+ delFromSet(cont, KEY_LISTENERS, listener);
9633
+ delFromSet(cont, KEY_RAW, rawEmitter);
9634
+ if (isEmptySet(cont.listeners)) {
9635
+ FsWatchFileInstances.delete(fullPath);
9636
+ unwatchFile(fullPath);
9637
+ cont.options = cont.watcher = void 0;
9638
+ Object.freeze(cont);
9639
+ }
9640
+ };
9641
+ };
9642
+ var NodeFsHandler = class {
9643
+ fsw;
9644
+ _boundHandleError;
9645
+ constructor(fsW) {
9646
+ this.fsw = fsW;
9647
+ this._boundHandleError = (error) => fsW._handleError(error);
9648
+ }
9649
+ /**
9650
+ * Watch file for changes with fs_watchFile or fs_watch.
9651
+ * @param path to file or dir
9652
+ * @param listener on fs change
9653
+ * @returns closer for the watcher instance
9654
+ */
9655
+ _watchWithNodeFs(path5, listener) {
9656
+ const opts = this.fsw.options;
9657
+ const directory = sp.dirname(path5);
9658
+ const basename3 = sp.basename(path5);
9659
+ const parent = this.fsw._getWatchedDir(directory);
9660
+ parent.add(basename3);
9661
+ const absolutePath = sp.resolve(path5);
9662
+ const options = {
9663
+ persistent: opts.persistent
9664
+ };
9665
+ if (!listener)
9666
+ listener = EMPTY_FN;
9667
+ let closer;
9668
+ if (opts.usePolling) {
9669
+ const enableBin = opts.interval !== opts.binaryInterval;
9670
+ options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
9671
+ closer = setFsWatchFileListener(path5, absolutePath, options, {
9672
+ listener,
9673
+ rawEmitter: this.fsw._emitRaw
9674
+ });
9675
+ } else {
9676
+ closer = setFsWatchListener(path5, absolutePath, options, {
9677
+ listener,
9678
+ errHandler: this._boundHandleError,
9679
+ rawEmitter: this.fsw._emitRaw
9680
+ });
9681
+ }
9682
+ return closer;
9683
+ }
9684
+ /**
9685
+ * Watch a file and emit add event if warranted.
9686
+ * @returns closer for the watcher instance
9687
+ */
9688
+ _handleFile(file, stats, initialAdd) {
9689
+ if (this.fsw.closed) {
9690
+ return;
9691
+ }
9692
+ const dirname3 = sp.dirname(file);
9693
+ const basename3 = sp.basename(file);
9694
+ const parent = this.fsw._getWatchedDir(dirname3);
9695
+ let prevStats = stats;
9696
+ if (parent.has(basename3))
9697
+ return;
9698
+ const listener = async (path5, newStats) => {
9699
+ if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
9700
+ return;
9701
+ if (!newStats || newStats.mtimeMs === 0) {
9702
+ try {
9703
+ const newStats2 = await stat2(file);
9704
+ if (this.fsw.closed)
9705
+ return;
9706
+ const at = newStats2.atimeMs;
9707
+ const mt = newStats2.mtimeMs;
9708
+ if (!at || at <= mt || mt !== prevStats.mtimeMs) {
9709
+ this.fsw._emit(EV.CHANGE, file, newStats2);
9710
+ }
9711
+ if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
9712
+ this.fsw._closeFile(path5);
9713
+ prevStats = newStats2;
9714
+ const closer2 = this._watchWithNodeFs(file, listener);
9715
+ if (closer2)
9716
+ this.fsw._addPathCloser(path5, closer2);
9717
+ } else {
9718
+ prevStats = newStats2;
9719
+ }
9720
+ } catch (error) {
9721
+ this.fsw._remove(dirname3, basename3);
9722
+ }
9723
+ } else if (parent.has(basename3)) {
9724
+ const at = newStats.atimeMs;
9725
+ const mt = newStats.mtimeMs;
9726
+ if (!at || at <= mt || mt !== prevStats.mtimeMs) {
9727
+ this.fsw._emit(EV.CHANGE, file, newStats);
9728
+ }
9729
+ prevStats = newStats;
9730
+ }
9731
+ };
9732
+ const closer = this._watchWithNodeFs(file, listener);
9733
+ if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) {
9734
+ if (!this.fsw._throttle(EV.ADD, file, 0))
9735
+ return;
9736
+ this.fsw._emit(EV.ADD, file, stats);
9737
+ }
9738
+ return closer;
9739
+ }
9740
+ /**
9741
+ * Handle symlinks encountered while reading a dir.
9742
+ * @param entry returned by readdirp
9743
+ * @param directory path of dir being read
9744
+ * @param path of this item
9745
+ * @param item basename of this item
9746
+ * @returns true if no more processing is needed for this entry.
9747
+ */
9748
+ async _handleSymlink(entry, directory, path5, item) {
9749
+ if (this.fsw.closed) {
9750
+ return;
9751
+ }
9752
+ const full = entry.fullPath;
9753
+ const dir = this.fsw._getWatchedDir(directory);
9754
+ if (!this.fsw.options.followSymlinks) {
9755
+ this.fsw._incrReadyCount();
9756
+ let linkPath;
9757
+ try {
9758
+ linkPath = await fsrealpath(path5);
9759
+ } catch (e) {
9760
+ this.fsw._emitReady();
9761
+ return true;
9762
+ }
9763
+ if (this.fsw.closed)
9764
+ return;
9765
+ if (dir.has(item)) {
9766
+ if (this.fsw._symlinkPaths.get(full) !== linkPath) {
9767
+ this.fsw._symlinkPaths.set(full, linkPath);
9768
+ this.fsw._emit(EV.CHANGE, path5, entry.stats);
9769
+ }
9770
+ } else {
9771
+ dir.add(item);
9772
+ this.fsw._symlinkPaths.set(full, linkPath);
9773
+ this.fsw._emit(EV.ADD, path5, entry.stats);
9774
+ }
9775
+ this.fsw._emitReady();
9776
+ return true;
9777
+ }
9778
+ if (this.fsw._symlinkPaths.has(full)) {
9779
+ return true;
9780
+ }
9781
+ this.fsw._symlinkPaths.set(full, true);
9782
+ }
9783
+ _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) {
9784
+ directory = sp.join(directory, "");
9785
+ const throttleKey = target ? `${directory}:${target}` : directory;
9786
+ throttler = this.fsw._throttle("readdir", throttleKey, 1e3);
9787
+ if (!throttler)
9788
+ return;
9789
+ const previous = this.fsw._getWatchedDir(wh.path);
9790
+ const current = /* @__PURE__ */ new Set();
9791
+ let stream = this.fsw._readdirp(directory, {
9792
+ fileFilter: (entry) => wh.filterPath(entry),
9793
+ directoryFilter: (entry) => wh.filterDir(entry)
9794
+ });
9795
+ if (!stream)
9796
+ return;
9797
+ stream.on(STR_DATA, async (entry) => {
9798
+ if (this.fsw.closed) {
9799
+ stream = void 0;
9800
+ return;
9801
+ }
9802
+ const item = entry.path;
9803
+ let path5 = sp.join(directory, item);
9804
+ current.add(item);
9805
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path5, item)) {
9806
+ return;
9807
+ }
9808
+ if (this.fsw.closed) {
9809
+ stream = void 0;
9810
+ return;
9811
+ }
9812
+ if (item === target || !target && !previous.has(item)) {
9813
+ this.fsw._incrReadyCount();
9814
+ path5 = sp.join(dir, sp.relative(dir, path5));
9815
+ this._addToNodeFs(path5, initialAdd, wh, depth + 1);
9816
+ }
9817
+ }).on(EV.ERROR, this._boundHandleError);
9818
+ return new Promise((resolve3, reject) => {
9819
+ if (!stream)
9820
+ return reject();
9821
+ stream.once(STR_END, () => {
9822
+ if (this.fsw.closed) {
9823
+ stream = void 0;
9824
+ return;
9825
+ }
9826
+ const wasThrottled = throttler ? throttler.clear() : false;
9827
+ resolve3(void 0);
9828
+ previous.getChildren().filter((item) => {
9829
+ return item !== directory && !current.has(item);
9830
+ }).forEach((item) => {
9831
+ this.fsw._remove(directory, item);
9832
+ });
9833
+ stream = void 0;
9834
+ if (wasThrottled)
9835
+ this._handleRead(directory, false, wh, target, dir, depth, throttler);
9836
+ });
9837
+ });
9838
+ }
9839
+ /**
9840
+ * Read directory to add / remove files from `@watched` list and re-read it on change.
9841
+ * @param dir fs path
9842
+ * @param stats
9843
+ * @param initialAdd
9844
+ * @param depth relative to user-supplied path
9845
+ * @param target child path targeted for watch
9846
+ * @param wh Common watch helpers for this path
9847
+ * @param realpath
9848
+ * @returns closer for the watcher instance.
9849
+ */
9850
+ async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath2) {
9851
+ const parentDir = this.fsw._getWatchedDir(sp.dirname(dir));
9852
+ const tracked = parentDir.has(sp.basename(dir));
9853
+ if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) {
9854
+ this.fsw._emit(EV.ADD_DIR, dir, stats);
9855
+ }
9856
+ parentDir.add(sp.basename(dir));
9857
+ this.fsw._getWatchedDir(dir);
9858
+ let throttler;
9859
+ let closer;
9860
+ const oDepth = this.fsw.options.depth;
9861
+ if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath2)) {
9862
+ if (!target) {
9863
+ await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler);
9864
+ if (this.fsw.closed)
9865
+ return;
9866
+ }
9867
+ closer = this._watchWithNodeFs(dir, (dirPath, stats2) => {
9868
+ if (stats2 && stats2.mtimeMs === 0)
9869
+ return;
9870
+ this._handleRead(dirPath, false, wh, target, dir, depth, throttler);
9871
+ });
9872
+ }
9873
+ return closer;
9874
+ }
9875
+ /**
9876
+ * Handle added file, directory, or glob pattern.
9877
+ * Delegates call to _handleFile / _handleDir after checks.
9878
+ * @param path to file or ir
9879
+ * @param initialAdd was the file added at watch instantiation?
9880
+ * @param priorWh depth relative to user-supplied path
9881
+ * @param depth Child path actually targeted for watch
9882
+ * @param target Child path actually targeted for watch
9883
+ */
9884
+ async _addToNodeFs(path5, initialAdd, priorWh, depth, target) {
9885
+ const ready = this.fsw._emitReady;
9886
+ if (this.fsw._isIgnored(path5) || this.fsw.closed) {
9887
+ ready();
9888
+ return false;
9889
+ }
9890
+ const wh = this.fsw._getWatchHelpers(path5);
9891
+ if (priorWh) {
9892
+ wh.filterPath = (entry) => priorWh.filterPath(entry);
9893
+ wh.filterDir = (entry) => priorWh.filterDir(entry);
9894
+ }
9895
+ try {
9896
+ const stats = await statMethods[wh.statMethod](wh.watchPath);
9897
+ if (this.fsw.closed)
9898
+ return;
9899
+ if (this.fsw._isIgnored(wh.watchPath, stats)) {
9900
+ ready();
9901
+ return false;
9902
+ }
9903
+ const follow = this.fsw.options.followSymlinks;
9904
+ let closer;
9905
+ if (stats.isDirectory()) {
9906
+ const absPath = sp.resolve(path5);
9907
+ const targetPath = follow ? await fsrealpath(path5) : path5;
9908
+ if (this.fsw.closed)
9909
+ return;
9910
+ closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
9911
+ if (this.fsw.closed)
9912
+ return;
9913
+ if (absPath !== targetPath && targetPath !== void 0) {
9914
+ this.fsw._symlinkPaths.set(absPath, targetPath);
9915
+ }
9916
+ } else if (stats.isSymbolicLink()) {
9917
+ const targetPath = follow ? await fsrealpath(path5) : path5;
9918
+ if (this.fsw.closed)
9919
+ return;
9920
+ const parent = sp.dirname(wh.watchPath);
9921
+ this.fsw._getWatchedDir(parent).add(wh.watchPath);
9922
+ this.fsw._emit(EV.ADD, wh.watchPath, stats);
9923
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path5, wh, targetPath);
9924
+ if (this.fsw.closed)
9925
+ return;
9926
+ if (targetPath !== void 0) {
9927
+ this.fsw._symlinkPaths.set(sp.resolve(path5), targetPath);
9928
+ }
9929
+ } else {
9930
+ closer = this._handleFile(wh.watchPath, stats, initialAdd);
9931
+ }
9932
+ ready();
9933
+ if (closer)
9934
+ this.fsw._addPathCloser(path5, closer);
9935
+ return false;
9936
+ } catch (error) {
9937
+ if (this.fsw._handleError(error)) {
9938
+ ready();
9939
+ return path5;
9940
+ }
9941
+ }
9942
+ }
9943
+ };
9944
+
9945
+ // ../node_modules/.pnpm/chokidar@5.0.0/node_modules/chokidar/index.js
9946
+ var SLASH = "/";
9947
+ var SLASH_SLASH = "//";
9948
+ var ONE_DOT = ".";
9949
+ var TWO_DOTS = "..";
9950
+ var STRING_TYPE = "string";
9951
+ var BACK_SLASH_RE = /\\/g;
9952
+ var DOUBLE_SLASH_RE = /\/\//g;
9953
+ var DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/;
9954
+ var REPLACER_RE = /^\.[/\\]/;
9955
+ function arrify(item) {
9956
+ return Array.isArray(item) ? item : [item];
9957
+ }
9958
+ var isMatcherObject = (matcher) => typeof matcher === "object" && matcher !== null && !(matcher instanceof RegExp);
9959
+ function createPattern(matcher) {
9960
+ if (typeof matcher === "function")
9961
+ return matcher;
9962
+ if (typeof matcher === "string")
9963
+ return (string) => matcher === string;
9964
+ if (matcher instanceof RegExp)
9965
+ return (string) => matcher.test(string);
9966
+ if (typeof matcher === "object" && matcher !== null) {
9967
+ return (string) => {
9968
+ if (matcher.path === string)
9969
+ return true;
9970
+ if (matcher.recursive) {
9971
+ const relative3 = sp2.relative(matcher.path, string);
9972
+ if (!relative3) {
9973
+ return false;
9974
+ }
9975
+ return !relative3.startsWith("..") && !sp2.isAbsolute(relative3);
9976
+ }
9977
+ return false;
9978
+ };
9979
+ }
9980
+ return () => false;
9981
+ }
9982
+ function normalizePath(path5) {
9983
+ if (typeof path5 !== "string")
9984
+ throw new Error("string expected");
9985
+ path5 = sp2.normalize(path5);
9986
+ path5 = path5.replace(/\\/g, "/");
9987
+ let prepend = false;
9988
+ if (path5.startsWith("//"))
9989
+ prepend = true;
9990
+ path5 = path5.replace(DOUBLE_SLASH_RE, "/");
9991
+ if (prepend)
9992
+ path5 = "/" + path5;
9993
+ return path5;
9994
+ }
9995
+ function matchPatterns(patterns, testString, stats) {
9996
+ const path5 = normalizePath(testString);
9997
+ for (let index = 0; index < patterns.length; index++) {
9998
+ const pattern = patterns[index];
9999
+ if (pattern(path5, stats)) {
10000
+ return true;
10001
+ }
10002
+ }
10003
+ return false;
10004
+ }
10005
+ function anymatch(matchers, testString) {
10006
+ if (matchers == null) {
10007
+ throw new TypeError("anymatch: specify first argument");
10008
+ }
10009
+ const matchersArray = arrify(matchers);
10010
+ const patterns = matchersArray.map((matcher) => createPattern(matcher));
10011
+ if (testString == null) {
10012
+ return (testString2, stats) => {
10013
+ return matchPatterns(patterns, testString2, stats);
10014
+ };
10015
+ }
10016
+ return matchPatterns(patterns, testString);
10017
+ }
10018
+ var unifyPaths = (paths_) => {
10019
+ const paths = arrify(paths_).flat();
10020
+ if (!paths.every((p) => typeof p === STRING_TYPE)) {
10021
+ throw new TypeError(`Non-string provided as watch path: ${paths}`);
10022
+ }
10023
+ return paths.map(normalizePathToUnix);
10024
+ };
10025
+ var toUnix = (string) => {
10026
+ let str = string.replace(BACK_SLASH_RE, SLASH);
10027
+ let prepend = false;
10028
+ if (str.startsWith(SLASH_SLASH)) {
10029
+ prepend = true;
10030
+ }
10031
+ str = str.replace(DOUBLE_SLASH_RE, SLASH);
10032
+ if (prepend) {
10033
+ str = SLASH + str;
10034
+ }
10035
+ return str;
10036
+ };
10037
+ var normalizePathToUnix = (path5) => toUnix(sp2.normalize(toUnix(path5)));
10038
+ var normalizeIgnored = (cwd = "") => (path5) => {
10039
+ if (typeof path5 === "string") {
10040
+ return normalizePathToUnix(sp2.isAbsolute(path5) ? path5 : sp2.join(cwd, path5));
10041
+ } else {
10042
+ return path5;
10043
+ }
10044
+ };
10045
+ var getAbsolutePath = (path5, cwd) => {
10046
+ if (sp2.isAbsolute(path5)) {
10047
+ return path5;
10048
+ }
10049
+ return sp2.join(cwd, path5);
10050
+ };
10051
+ var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
10052
+ var DirEntry = class {
10053
+ path;
10054
+ _removeWatcher;
10055
+ items;
10056
+ constructor(dir, removeWatcher) {
10057
+ this.path = dir;
10058
+ this._removeWatcher = removeWatcher;
10059
+ this.items = /* @__PURE__ */ new Set();
10060
+ }
10061
+ add(item) {
10062
+ const { items } = this;
10063
+ if (!items)
10064
+ return;
10065
+ if (item !== ONE_DOT && item !== TWO_DOTS)
10066
+ items.add(item);
10067
+ }
10068
+ async remove(item) {
10069
+ const { items } = this;
10070
+ if (!items)
10071
+ return;
10072
+ items.delete(item);
10073
+ if (items.size > 0)
10074
+ return;
10075
+ const dir = this.path;
10076
+ try {
10077
+ await readdir2(dir);
10078
+ } catch (err) {
10079
+ if (this._removeWatcher) {
10080
+ this._removeWatcher(sp2.dirname(dir), sp2.basename(dir));
10081
+ }
10082
+ }
10083
+ }
10084
+ has(item) {
10085
+ const { items } = this;
10086
+ if (!items)
10087
+ return;
10088
+ return items.has(item);
10089
+ }
10090
+ getChildren() {
10091
+ const { items } = this;
10092
+ if (!items)
10093
+ return [];
10094
+ return [...items.values()];
10095
+ }
10096
+ dispose() {
10097
+ this.items.clear();
10098
+ this.path = "";
10099
+ this._removeWatcher = EMPTY_FN;
10100
+ this.items = EMPTY_SET;
10101
+ Object.freeze(this);
10102
+ }
10103
+ };
10104
+ var STAT_METHOD_F = "stat";
10105
+ var STAT_METHOD_L = "lstat";
10106
+ var WatchHelper = class {
10107
+ fsw;
10108
+ path;
10109
+ watchPath;
10110
+ fullWatchPath;
10111
+ dirParts;
10112
+ followSymlinks;
10113
+ statMethod;
10114
+ constructor(path5, follow, fsw) {
10115
+ this.fsw = fsw;
10116
+ const watchPath = path5;
10117
+ this.path = path5 = path5.replace(REPLACER_RE, "");
10118
+ this.watchPath = watchPath;
10119
+ this.fullWatchPath = sp2.resolve(watchPath);
10120
+ this.dirParts = [];
10121
+ this.dirParts.forEach((parts) => {
10122
+ if (parts.length > 1)
10123
+ parts.pop();
10124
+ });
10125
+ this.followSymlinks = follow;
10126
+ this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;
10127
+ }
10128
+ entryPath(entry) {
10129
+ return sp2.join(this.watchPath, sp2.relative(this.watchPath, entry.fullPath));
10130
+ }
10131
+ filterPath(entry) {
10132
+ const { stats } = entry;
10133
+ if (stats && stats.isSymbolicLink())
10134
+ return this.filterDir(entry);
10135
+ const resolvedPath = this.entryPath(entry);
10136
+ return this.fsw._isntIgnored(resolvedPath, stats) && this.fsw._hasReadPermissions(stats);
10137
+ }
10138
+ filterDir(entry) {
10139
+ return this.fsw._isntIgnored(this.entryPath(entry), entry.stats);
10140
+ }
10141
+ };
10142
+ var FSWatcher = class extends EventEmitter {
10143
+ closed;
10144
+ options;
10145
+ _closers;
10146
+ _ignoredPaths;
10147
+ _throttled;
10148
+ _streams;
10149
+ _symlinkPaths;
10150
+ _watched;
10151
+ _pendingWrites;
10152
+ _pendingUnlinks;
10153
+ _readyCount;
10154
+ _emitReady;
10155
+ _closePromise;
10156
+ _userIgnored;
10157
+ _readyEmitted;
10158
+ _emitRaw;
10159
+ _boundRemove;
10160
+ _nodeFsHandler;
10161
+ // Not indenting methods for history sake; for now.
10162
+ constructor(_opts = {}) {
10163
+ super();
10164
+ this.closed = false;
10165
+ this._closers = /* @__PURE__ */ new Map();
10166
+ this._ignoredPaths = /* @__PURE__ */ new Set();
10167
+ this._throttled = /* @__PURE__ */ new Map();
10168
+ this._streams = /* @__PURE__ */ new Set();
10169
+ this._symlinkPaths = /* @__PURE__ */ new Map();
10170
+ this._watched = /* @__PURE__ */ new Map();
10171
+ this._pendingWrites = /* @__PURE__ */ new Map();
10172
+ this._pendingUnlinks = /* @__PURE__ */ new Map();
10173
+ this._readyCount = 0;
10174
+ this._readyEmitted = false;
10175
+ const awf = _opts.awaitWriteFinish;
10176
+ const DEF_AWF = { stabilityThreshold: 2e3, pollInterval: 100 };
10177
+ const opts = {
10178
+ // Defaults
10179
+ persistent: true,
10180
+ ignoreInitial: false,
10181
+ ignorePermissionErrors: false,
10182
+ interval: 100,
10183
+ binaryInterval: 300,
10184
+ followSymlinks: true,
10185
+ usePolling: false,
10186
+ // useAsync: false,
10187
+ atomic: true,
10188
+ // NOTE: overwritten later (depends on usePolling)
10189
+ ..._opts,
10190
+ // Change format
10191
+ ignored: _opts.ignored ? arrify(_opts.ignored) : arrify([]),
10192
+ awaitWriteFinish: awf === true ? DEF_AWF : typeof awf === "object" ? { ...DEF_AWF, ...awf } : false
10193
+ };
10194
+ if (isIBMi)
10195
+ opts.usePolling = true;
10196
+ if (opts.atomic === void 0)
10197
+ opts.atomic = !opts.usePolling;
10198
+ const envPoll = process.env.CHOKIDAR_USEPOLLING;
10199
+ if (envPoll !== void 0) {
10200
+ const envLower = envPoll.toLowerCase();
10201
+ if (envLower === "false" || envLower === "0")
10202
+ opts.usePolling = false;
10203
+ else if (envLower === "true" || envLower === "1")
10204
+ opts.usePolling = true;
10205
+ else
10206
+ opts.usePolling = !!envLower;
10207
+ }
10208
+ const envInterval = process.env.CHOKIDAR_INTERVAL;
10209
+ if (envInterval)
10210
+ opts.interval = Number.parseInt(envInterval, 10);
10211
+ let readyCalls = 0;
10212
+ this._emitReady = () => {
10213
+ readyCalls++;
10214
+ if (readyCalls >= this._readyCount) {
10215
+ this._emitReady = EMPTY_FN;
10216
+ this._readyEmitted = true;
10217
+ process.nextTick(() => this.emit(EVENTS.READY));
10218
+ }
10219
+ };
10220
+ this._emitRaw = (...args) => this.emit(EVENTS.RAW, ...args);
10221
+ this._boundRemove = this._remove.bind(this);
10222
+ this.options = opts;
10223
+ this._nodeFsHandler = new NodeFsHandler(this);
10224
+ Object.freeze(opts);
10225
+ }
10226
+ _addIgnoredPath(matcher) {
10227
+ if (isMatcherObject(matcher)) {
10228
+ for (const ignored of this._ignoredPaths) {
10229
+ if (isMatcherObject(ignored) && ignored.path === matcher.path && ignored.recursive === matcher.recursive) {
10230
+ return;
10231
+ }
10232
+ }
10233
+ }
10234
+ this._ignoredPaths.add(matcher);
10235
+ }
10236
+ _removeIgnoredPath(matcher) {
10237
+ this._ignoredPaths.delete(matcher);
10238
+ if (typeof matcher === "string") {
10239
+ for (const ignored of this._ignoredPaths) {
10240
+ if (isMatcherObject(ignored) && ignored.path === matcher) {
10241
+ this._ignoredPaths.delete(ignored);
10242
+ }
10243
+ }
10244
+ }
10245
+ }
10246
+ // Public methods
10247
+ /**
10248
+ * Adds paths to be watched on an existing FSWatcher instance.
10249
+ * @param paths_ file or file list. Other arguments are unused
10250
+ */
10251
+ add(paths_, _origAdd, _internal) {
10252
+ const { cwd } = this.options;
10253
+ this.closed = false;
10254
+ this._closePromise = void 0;
10255
+ let paths = unifyPaths(paths_);
10256
+ if (cwd) {
10257
+ paths = paths.map((path5) => {
10258
+ const absPath = getAbsolutePath(path5, cwd);
10259
+ return absPath;
10260
+ });
10261
+ }
10262
+ paths.forEach((path5) => {
10263
+ this._removeIgnoredPath(path5);
10264
+ });
10265
+ this._userIgnored = void 0;
10266
+ if (!this._readyCount)
10267
+ this._readyCount = 0;
10268
+ this._readyCount += paths.length;
10269
+ Promise.all(paths.map(async (path5) => {
10270
+ const res = await this._nodeFsHandler._addToNodeFs(path5, !_internal, void 0, 0, _origAdd);
10271
+ if (res)
10272
+ this._emitReady();
10273
+ return res;
10274
+ })).then((results) => {
10275
+ if (this.closed)
10276
+ return;
10277
+ results.forEach((item) => {
10278
+ if (item)
10279
+ this.add(sp2.dirname(item), sp2.basename(_origAdd || item));
10280
+ });
10281
+ });
10282
+ return this;
10283
+ }
10284
+ /**
10285
+ * Close watchers or start ignoring events from specified paths.
10286
+ */
10287
+ unwatch(paths_) {
10288
+ if (this.closed)
10289
+ return this;
10290
+ const paths = unifyPaths(paths_);
10291
+ const { cwd } = this.options;
10292
+ paths.forEach((path5) => {
10293
+ if (!sp2.isAbsolute(path5) && !this._closers.has(path5)) {
10294
+ if (cwd)
10295
+ path5 = sp2.join(cwd, path5);
10296
+ path5 = sp2.resolve(path5);
10297
+ }
10298
+ this._closePath(path5);
10299
+ this._addIgnoredPath(path5);
10300
+ if (this._watched.has(path5)) {
10301
+ this._addIgnoredPath({
10302
+ path: path5,
10303
+ recursive: true
10304
+ });
10305
+ }
10306
+ this._userIgnored = void 0;
10307
+ });
10308
+ return this;
10309
+ }
10310
+ /**
10311
+ * Close watchers and remove all listeners from watched paths.
10312
+ */
10313
+ close() {
10314
+ if (this._closePromise) {
10315
+ return this._closePromise;
10316
+ }
10317
+ this.closed = true;
10318
+ this.removeAllListeners();
10319
+ const closers = [];
10320
+ this._closers.forEach((closerList) => closerList.forEach((closer) => {
10321
+ const promise = closer();
10322
+ if (promise instanceof Promise)
10323
+ closers.push(promise);
10324
+ }));
10325
+ this._streams.forEach((stream) => stream.destroy());
10326
+ this._userIgnored = void 0;
10327
+ this._readyCount = 0;
10328
+ this._readyEmitted = false;
10329
+ this._watched.forEach((dirent) => dirent.dispose());
10330
+ this._closers.clear();
10331
+ this._watched.clear();
10332
+ this._streams.clear();
10333
+ this._symlinkPaths.clear();
10334
+ this._throttled.clear();
10335
+ this._closePromise = closers.length ? Promise.all(closers).then(() => void 0) : Promise.resolve();
10336
+ return this._closePromise;
10337
+ }
10338
+ /**
10339
+ * Expose list of watched paths
10340
+ * @returns for chaining
10341
+ */
10342
+ getWatched() {
10343
+ const watchList = {};
10344
+ this._watched.forEach((entry, dir) => {
10345
+ const key = this.options.cwd ? sp2.relative(this.options.cwd, dir) : dir;
10346
+ const index = key || ONE_DOT;
10347
+ watchList[index] = entry.getChildren().sort();
10348
+ });
10349
+ return watchList;
10350
+ }
10351
+ emitWithAll(event, args) {
10352
+ this.emit(event, ...args);
10353
+ if (event !== EVENTS.ERROR)
10354
+ this.emit(EVENTS.ALL, event, ...args);
10355
+ }
10356
+ // Common helpers
10357
+ // --------------
10358
+ /**
10359
+ * Normalize and emit events.
10360
+ * Calling _emit DOES NOT MEAN emit() would be called!
10361
+ * @param event Type of event
10362
+ * @param path File or directory path
10363
+ * @param stats arguments to be passed with event
10364
+ * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
10365
+ */
10366
+ async _emit(event, path5, stats) {
10367
+ if (this.closed)
10368
+ return;
10369
+ const opts = this.options;
10370
+ if (isWindows)
10371
+ path5 = sp2.normalize(path5);
10372
+ if (opts.cwd)
10373
+ path5 = sp2.relative(opts.cwd, path5);
10374
+ const args = [path5];
10375
+ if (stats != null)
10376
+ args.push(stats);
10377
+ const awf = opts.awaitWriteFinish;
10378
+ let pw;
10379
+ if (awf && (pw = this._pendingWrites.get(path5))) {
10380
+ pw.lastChange = /* @__PURE__ */ new Date();
10381
+ return this;
10382
+ }
10383
+ if (opts.atomic) {
10384
+ if (event === EVENTS.UNLINK) {
10385
+ this._pendingUnlinks.set(path5, [event, ...args]);
10386
+ setTimeout(() => {
10387
+ this._pendingUnlinks.forEach((entry, path6) => {
10388
+ this.emit(...entry);
10389
+ this.emit(EVENTS.ALL, ...entry);
10390
+ this._pendingUnlinks.delete(path6);
10391
+ });
10392
+ }, typeof opts.atomic === "number" ? opts.atomic : 100);
10393
+ return this;
10394
+ }
10395
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path5)) {
10396
+ event = EVENTS.CHANGE;
10397
+ this._pendingUnlinks.delete(path5);
10398
+ }
10399
+ }
10400
+ if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
10401
+ const awfEmit = (err, stats2) => {
10402
+ if (err) {
10403
+ event = EVENTS.ERROR;
10404
+ args[0] = err;
10405
+ this.emitWithAll(event, args);
10406
+ } else if (stats2) {
10407
+ if (args.length > 1) {
10408
+ args[1] = stats2;
10409
+ } else {
10410
+ args.push(stats2);
10411
+ }
10412
+ this.emitWithAll(event, args);
10413
+ }
10414
+ };
10415
+ this._awaitWriteFinish(path5, awf.stabilityThreshold, event, awfEmit);
10416
+ return this;
10417
+ }
10418
+ if (event === EVENTS.CHANGE) {
10419
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path5, 50);
10420
+ if (isThrottled)
10421
+ return this;
10422
+ }
10423
+ if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
10424
+ const fullPath = opts.cwd ? sp2.join(opts.cwd, path5) : path5;
10425
+ let stats2;
10426
+ try {
10427
+ stats2 = await stat3(fullPath);
10428
+ } catch (err) {
10429
+ }
10430
+ if (!stats2 || this.closed)
10431
+ return;
10432
+ args.push(stats2);
10433
+ }
10434
+ this.emitWithAll(event, args);
10435
+ return this;
10436
+ }
10437
+ /**
10438
+ * Common handler for errors
10439
+ * @returns The error if defined, otherwise the value of the FSWatcher instance's `closed` flag
10440
+ */
10441
+ _handleError(error) {
10442
+ const code = error && error.code;
10443
+ if (error && code !== "ENOENT" && code !== "ENOTDIR" && (!this.options.ignorePermissionErrors || code !== "EPERM" && code !== "EACCES")) {
10444
+ this.emit(EVENTS.ERROR, error);
10445
+ }
10446
+ return error || this.closed;
10447
+ }
10448
+ /**
10449
+ * Helper utility for throttling
10450
+ * @param actionType type being throttled
10451
+ * @param path being acted upon
10452
+ * @param timeout duration of time to suppress duplicate actions
10453
+ * @returns tracking object or false if action should be suppressed
10454
+ */
10455
+ _throttle(actionType, path5, timeout) {
10456
+ if (!this._throttled.has(actionType)) {
10457
+ this._throttled.set(actionType, /* @__PURE__ */ new Map());
10458
+ }
10459
+ const action2 = this._throttled.get(actionType);
10460
+ if (!action2)
10461
+ throw new Error("invalid throttle");
10462
+ const actionPath = action2.get(path5);
10463
+ if (actionPath) {
10464
+ actionPath.count++;
10465
+ return false;
10466
+ }
10467
+ let timeoutObject;
10468
+ const clear = () => {
10469
+ const item = action2.get(path5);
10470
+ const count = item ? item.count : 0;
10471
+ action2.delete(path5);
10472
+ clearTimeout(timeoutObject);
10473
+ if (item)
10474
+ clearTimeout(item.timeoutObject);
10475
+ return count;
10476
+ };
10477
+ timeoutObject = setTimeout(clear, timeout);
10478
+ const thr = { timeoutObject, clear, count: 0 };
10479
+ action2.set(path5, thr);
10480
+ return thr;
10481
+ }
10482
+ _incrReadyCount() {
10483
+ return this._readyCount++;
10484
+ }
10485
+ /**
10486
+ * Awaits write operation to finish.
10487
+ * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback.
10488
+ * @param path being acted upon
10489
+ * @param threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished
10490
+ * @param event
10491
+ * @param awfEmit Callback to be called when ready for event to be emitted.
10492
+ */
10493
+ _awaitWriteFinish(path5, threshold, event, awfEmit) {
10494
+ const awf = this.options.awaitWriteFinish;
10495
+ if (typeof awf !== "object")
10496
+ return;
10497
+ const pollInterval = awf.pollInterval;
10498
+ let timeoutHandler;
10499
+ let fullPath = path5;
10500
+ if (this.options.cwd && !sp2.isAbsolute(path5)) {
10501
+ fullPath = sp2.join(this.options.cwd, path5);
10502
+ }
10503
+ const now = /* @__PURE__ */ new Date();
10504
+ const writes = this._pendingWrites;
10505
+ function awaitWriteFinishFn(prevStat) {
10506
+ statcb(fullPath, (err, curStat) => {
10507
+ if (err || !writes.has(path5)) {
10508
+ if (err && err.code !== "ENOENT")
10509
+ awfEmit(err);
10510
+ return;
10511
+ }
10512
+ const now2 = Number(/* @__PURE__ */ new Date());
10513
+ if (prevStat && curStat.size !== prevStat.size) {
10514
+ writes.get(path5).lastChange = now2;
10515
+ }
10516
+ const pw = writes.get(path5);
10517
+ const df = now2 - pw.lastChange;
10518
+ if (df >= threshold) {
10519
+ writes.delete(path5);
10520
+ awfEmit(void 0, curStat);
10521
+ } else {
10522
+ timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
10523
+ }
10524
+ });
10525
+ }
10526
+ if (!writes.has(path5)) {
10527
+ writes.set(path5, {
10528
+ lastChange: now,
10529
+ cancelWait: () => {
10530
+ writes.delete(path5);
10531
+ clearTimeout(timeoutHandler);
10532
+ return event;
10533
+ }
10534
+ });
10535
+ timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
10536
+ }
10537
+ }
10538
+ /**
10539
+ * Determines whether user has asked to ignore this path.
10540
+ */
10541
+ _isIgnored(path5, stats) {
10542
+ if (this.options.atomic && DOT_RE.test(path5))
10543
+ return true;
10544
+ if (!this._userIgnored) {
10545
+ const { cwd } = this.options;
10546
+ const ign = this.options.ignored;
10547
+ const ignored = (ign || []).map(normalizeIgnored(cwd));
10548
+ const ignoredPaths = [...this._ignoredPaths];
10549
+ const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
10550
+ this._userIgnored = anymatch(list, void 0);
10551
+ }
10552
+ return this._userIgnored(path5, stats);
10553
+ }
10554
+ _isntIgnored(path5, stat4) {
10555
+ return !this._isIgnored(path5, stat4);
10556
+ }
10557
+ /**
10558
+ * Provides a set of common helpers and properties relating to symlink handling.
10559
+ * @param path file or directory pattern being watched
10560
+ */
10561
+ _getWatchHelpers(path5) {
10562
+ return new WatchHelper(path5, this.options.followSymlinks, this);
10563
+ }
10564
+ // Directory helpers
10565
+ // -----------------
10566
+ /**
10567
+ * Provides directory tracking objects
10568
+ * @param directory path of the directory
10569
+ */
10570
+ _getWatchedDir(directory) {
10571
+ const dir = sp2.resolve(directory);
10572
+ if (!this._watched.has(dir))
10573
+ this._watched.set(dir, new DirEntry(dir, this._boundRemove));
10574
+ return this._watched.get(dir);
10575
+ }
10576
+ // File helpers
10577
+ // ------------
10578
+ /**
10579
+ * Check for read permissions: https://stackoverflow.com/a/11781404/1358405
10580
+ */
10581
+ _hasReadPermissions(stats) {
10582
+ if (this.options.ignorePermissionErrors)
10583
+ return true;
10584
+ return Boolean(Number(stats.mode) & 256);
10585
+ }
10586
+ /**
10587
+ * Handles emitting unlink events for
10588
+ * files and directories, and via recursion, for
10589
+ * files and directories within directories that are unlinked
10590
+ * @param directory within which the following item is located
10591
+ * @param item base path of item/directory
10592
+ */
10593
+ _remove(directory, item, isDirectory) {
10594
+ const path5 = sp2.join(directory, item);
10595
+ const fullPath = sp2.resolve(path5);
10596
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path5) || this._watched.has(fullPath);
10597
+ if (!this._throttle("remove", path5, 100))
10598
+ return;
10599
+ if (!isDirectory && this._watched.size === 1) {
10600
+ this.add(directory, item, true);
10601
+ }
10602
+ const wp = this._getWatchedDir(path5);
10603
+ const nestedDirectoryChildren = wp.getChildren();
10604
+ nestedDirectoryChildren.forEach((nested) => this._remove(path5, nested));
10605
+ const parent = this._getWatchedDir(directory);
10606
+ const wasTracked = parent.has(item);
10607
+ parent.remove(item);
10608
+ if (this._symlinkPaths.has(fullPath)) {
10609
+ this._symlinkPaths.delete(fullPath);
10610
+ }
10611
+ let relPath = path5;
10612
+ if (this.options.cwd)
10613
+ relPath = sp2.relative(this.options.cwd, path5);
10614
+ if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
10615
+ const event = this._pendingWrites.get(relPath).cancelWait();
10616
+ if (event === EVENTS.ADD)
10617
+ return;
10618
+ }
10619
+ this._watched.delete(path5);
10620
+ this._watched.delete(fullPath);
10621
+ const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
10622
+ if (wasTracked && !this._isIgnored(path5))
10623
+ this._emit(eventName, path5);
10624
+ this._closePath(path5);
10625
+ }
10626
+ /**
10627
+ * Closes all watchers for a path
10628
+ */
10629
+ _closePath(path5) {
10630
+ this._closeFile(path5);
10631
+ const dir = sp2.dirname(path5);
10632
+ this._getWatchedDir(dir).remove(sp2.basename(path5));
10633
+ }
10634
+ /**
10635
+ * Closes only file-specific watchers
10636
+ */
10637
+ _closeFile(path5) {
10638
+ const closers = this._closers.get(path5);
10639
+ if (!closers)
10640
+ return;
10641
+ closers.forEach((closer) => closer());
10642
+ this._closers.delete(path5);
10643
+ }
10644
+ _addPathCloser(path5, closer) {
10645
+ if (!closer)
10646
+ return;
10647
+ let list = this._closers.get(path5);
10648
+ if (!list) {
10649
+ list = [];
10650
+ this._closers.set(path5, list);
10651
+ }
10652
+ list.push(closer);
10653
+ }
10654
+ _readdirp(root, opts) {
10655
+ if (this.closed)
10656
+ return;
10657
+ const options = { type: EVENTS.ALL, alwaysStat: true, lstat: true, ...opts, depth: 0 };
10658
+ let stream = readdirp(root, options);
10659
+ this._streams.add(stream);
10660
+ stream.once(STR_CLOSE, () => {
10661
+ stream = void 0;
10662
+ });
10663
+ stream.once(STR_END, () => {
10664
+ if (stream) {
10665
+ this._streams.delete(stream);
10666
+ stream = void 0;
10667
+ }
10668
+ });
10669
+ return stream;
10670
+ }
10671
+ };
10672
+ function watch(paths, options = {}) {
10673
+ const watcher2 = new FSWatcher(options);
10674
+ watcher2.add(paths);
10675
+ return watcher2;
10676
+ }
10677
+ var chokidar_default = { watch, FSWatcher };
10678
+
10679
+ // src/ingestion/watcher.ts
10680
+ function startWatcher(opts) {
10681
+ const debounceMs = opts.debounceMs ?? 150;
10682
+ const onError = opts.onError ?? ((err) => {
10683
+ console.warn("[watcher] error:", err);
10684
+ });
10685
+ const pathBindings = /* @__PURE__ */ new Map();
10686
+ const pendingTimers = /* @__PURE__ */ new Map();
10687
+ let watcher2 = null;
10688
+ let closed = false;
10689
+ const ready = (async () => {
10690
+ const watchPathSet = /* @__PURE__ */ new Set();
10691
+ for (const plugin of opts.plugins) {
10692
+ for await (const ref of plugin.discover(opts.env)) {
10693
+ for (const p of ref.watchPaths) {
10694
+ pathBindings.set(p, { plugin, ref });
10695
+ watchPathSet.add(p);
10696
+ }
10697
+ }
10698
+ }
10699
+ const paths = Array.from(watchPathSet);
10700
+ if (paths.length === 0) return;
10701
+ watcher2 = chokidar_default.watch(paths, {
10702
+ ignoreInitial: true,
10703
+ awaitWriteFinish: { stabilityThreshold: 50, pollInterval: 25 },
10704
+ ...opts.chokidarOptions
10705
+ });
10706
+ watcher2.on("change", (p) => scheduleIngest(p));
10707
+ watcher2.on("add", (p) => scheduleIngest(p));
10708
+ watcher2.on("unlink", (p) => recordUnlink(p));
10709
+ watcher2.on("error", (err) => onError(err));
10710
+ await new Promise((resolve3) => {
10711
+ watcher2.once("ready", () => resolve3());
10712
+ });
10713
+ })();
10714
+ function recordUnlink(removedPath) {
10715
+ if (closed) return;
10716
+ const binding = pathBindings.get(removedPath);
10717
+ if (!binding) return;
10718
+ try {
10719
+ opts.archive.db.insert(ingestionEvents).values({
10720
+ agent: binding.plugin.id,
10721
+ sessionId: binding.ref.sessionId,
10722
+ sourcePath: removedPath,
10723
+ eventType: "unlink_observed",
10724
+ detail: { path: removedPath },
10725
+ observedAt: /* @__PURE__ */ new Date()
10726
+ }).run();
10727
+ } catch (err) {
10728
+ onError(err);
10729
+ }
10730
+ }
10731
+ function scheduleIngest(changedPath) {
10732
+ if (closed) return;
10733
+ const existing = pendingTimers.get(changedPath);
10734
+ if (existing) clearTimeout(existing);
10735
+ const timer = setTimeout(() => {
10736
+ pendingTimers.delete(changedPath);
10737
+ void runIngestion({
10738
+ plugins: opts.plugins,
10739
+ archive: opts.archive,
10740
+ env: opts.env
10741
+ }).catch((err) => onError(err));
10742
+ }, debounceMs);
10743
+ pendingTimers.set(changedPath, timer);
10744
+ }
10745
+ return {
10746
+ ready,
10747
+ async close() {
10748
+ closed = true;
10749
+ for (const t of pendingTimers.values()) clearTimeout(t);
10750
+ pendingTimers.clear();
10751
+ if (watcher2) await watcher2.close();
10752
+ }
10753
+ };
10754
+ }
10755
+
8947
10756
  // src/plugins/claude-code/plugin.ts
8948
10757
  import fs5 from "fs";
8949
10758
  import path3 from "path";
@@ -9081,22 +10890,102 @@ function normalizeBlock(raw2) {
9081
10890
  // src/plugins/registry.ts
9082
10891
  var plugins = [new ClaudeCodePlugin()];
9083
10892
 
10893
+ // src/cli/argv.ts
10894
+ var DEFAULT_PORT = 3100;
10895
+ function parseCliArgs(argv, env = {}) {
10896
+ if (argv.includes("--version") || argv.includes("-v")) {
10897
+ return { kind: "version" };
10898
+ }
10899
+ if (argv.includes("--help") || argv.includes("-h")) {
10900
+ return { kind: "help" };
10901
+ }
10902
+ const portIdx = argv.findIndex((a) => a === "--port" || a === "-p");
10903
+ if (portIdx !== -1) {
10904
+ const raw2 = argv[portIdx + 1];
10905
+ if (raw2 === void 0) {
10906
+ return {
10907
+ kind: "error",
10908
+ message: `${argv[portIdx]} requires a value (e.g. --port 8080)`
10909
+ };
10910
+ }
10911
+ const port2 = Number(raw2);
10912
+ if (!Number.isInteger(port2)) {
10913
+ return {
10914
+ kind: "error",
10915
+ message: `Invalid port "${raw2}": must be an integer`
10916
+ };
10917
+ }
10918
+ if (port2 < 1 || port2 > 65535) {
10919
+ return {
10920
+ kind: "error",
10921
+ message: `Invalid port "${raw2}": must be between 1 and 65535`
10922
+ };
10923
+ }
10924
+ return { kind: "run", port: port2 };
10925
+ }
10926
+ if (env.PORT) {
10927
+ return { kind: "run", port: Number(env.PORT) };
10928
+ }
10929
+ return { kind: "run", port: DEFAULT_PORT };
10930
+ }
10931
+
10932
+ // src/cli/help.ts
10933
+ var helpText = `Usage: chat-log [options]
10934
+
10935
+ Start the chat-logbook server and open the web UI in your browser.
10936
+
10937
+ Options:
10938
+ -v, --version Print the version and exit
10939
+ -h, --help Show this help message and exit
10940
+ -p, --port <n> Set the HTTP port (default: 3100)
10941
+
10942
+ Environment:
10943
+ PORT=<n> Set the HTTP port (overridden by --port)
10944
+ `;
10945
+
9084
10946
  // src/index.ts
9085
10947
  var __dirname = path4.dirname(fileURLToPath3(import.meta.url));
9086
10948
  var pkgPath = path4.join(__dirname, "../../package.json");
9087
10949
  var pkg = JSON.parse(fs6.readFileSync(pkgPath, "utf-8"));
9088
- updateNotifier({ pkg }).notify();
10950
+ var action = parseCliArgs(process.argv.slice(2), {
10951
+ PORT: process.env.PORT
10952
+ });
10953
+ if (action.kind === "version") {
10954
+ console.log(pkg.version);
10955
+ process.exit(0);
10956
+ }
10957
+ if (action.kind === "help") {
10958
+ process.stdout.write(helpText);
10959
+ process.exit(0);
10960
+ }
10961
+ if (action.kind === "error") {
10962
+ console.error(action.message);
10963
+ process.exit(1);
10964
+ }
10965
+ updateNotifier({ pkg }).notify({ defer: false, isGlobal: true });
9089
10966
  var dataDir = path4.join(os.homedir(), ".chat-logbook");
9090
10967
  var webDistDir = path4.join(__dirname, "../../web/dist");
9091
- var port = Number(process.env.PORT) || 3100;
10968
+ var port = action.port;
9092
10969
  var archive = createArchiveRepository({ dataDir });
9093
10970
  var metadata = createMetadataRepository({ dataDir });
9094
10971
  var app = createApp({ archive, metadata, webDistDir });
9095
- startIngestionInBackground({
10972
+ var initialIngest = startIngestionInBackground({
10973
+ plugins,
10974
+ archive,
10975
+ env: { homeDir: os.homedir() }
10976
+ });
10977
+ var watcher = startWatcher({
9096
10978
  plugins,
9097
10979
  archive,
9098
10980
  env: { homeDir: os.homedir() }
9099
10981
  });
10982
+ void initialIngest.done.then(() => watcher.ready).catch(() => {
10983
+ });
10984
+ function shutdown() {
10985
+ void watcher.close().finally(() => process.exit(0));
10986
+ }
10987
+ process.on("SIGINT", shutdown);
10988
+ process.on("SIGTERM", shutdown);
9100
10989
  function openBrowser(url) {
9101
10990
  const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
9102
10991
  exec(`${cmd} ${url}`);
@@ -9111,6 +11000,7 @@ server.on("error", (err) => {
9111
11000
  console.error(
9112
11001
  `Port ${port} is already in use. Try a different port:
9113
11002
 
11003
+ chat-log --port 8080
9114
11004
  PORT=8080 chat-log
9115
11005
  `
9116
11006
  );
@@ -9118,3 +11008,8 @@ server.on("error", (err) => {
9118
11008
  }
9119
11009
  throw err;
9120
11010
  });
11011
+ /*! Bundled license information:
11012
+
11013
+ chokidar/index.js:
11014
+ (*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) *)
11015
+ */