duclaw-cli 1.9.3 → 1.9.5

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/bundle.js CHANGED
@@ -115,7 +115,7 @@ var require_package = __commonJS({
115
115
  var require_main = __commonJS({
116
116
  "node_modules/.pnpm/dotenv@17.3.1/node_modules/dotenv/lib/main.js"(exports2, module2) {
117
117
  var fs3 = require("fs");
118
- var path21 = require("path");
118
+ var path20 = require("path");
119
119
  var os = require("os");
120
120
  var crypto2 = require("crypto");
121
121
  var packageJson = require_package();
@@ -261,7 +261,7 @@ var require_main = __commonJS({
261
261
  possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
262
262
  }
263
263
  } else {
264
- possibleVaultPath = path21.resolve(process.cwd(), ".env.vault");
264
+ possibleVaultPath = path20.resolve(process.cwd(), ".env.vault");
265
265
  }
266
266
  if (fs3.existsSync(possibleVaultPath)) {
267
267
  return possibleVaultPath;
@@ -269,7 +269,7 @@ var require_main = __commonJS({
269
269
  return null;
270
270
  }
271
271
  function _resolveHome(envPath) {
272
- return envPath[0] === "~" ? path21.join(os.homedir(), envPath.slice(1)) : envPath;
272
+ return envPath[0] === "~" ? path20.join(os.homedir(), envPath.slice(1)) : envPath;
273
273
  }
274
274
  function _configVault(options) {
275
275
  const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
@@ -286,7 +286,7 @@ var require_main = __commonJS({
286
286
  return { parsed };
287
287
  }
288
288
  function configDotenv(options) {
289
- const dotenvPath = path21.resolve(process.cwd(), ".env");
289
+ const dotenvPath = path20.resolve(process.cwd(), ".env");
290
290
  let encoding = "utf8";
291
291
  let processEnv = process.env;
292
292
  if (options && options.processEnv != null) {
@@ -314,13 +314,13 @@ var require_main = __commonJS({
314
314
  }
315
315
  let lastError;
316
316
  const parsedAll = {};
317
- for (const path22 of optionPaths) {
317
+ for (const path21 of optionPaths) {
318
318
  try {
319
- const parsed = DotenvModule.parse(fs3.readFileSync(path22, { encoding }));
319
+ const parsed = DotenvModule.parse(fs3.readFileSync(path21, { encoding }));
320
320
  DotenvModule.populate(parsedAll, parsed, options);
321
321
  } catch (e) {
322
322
  if (debug) {
323
- _debug(`Failed to load ${path22} ${e.message}`);
323
+ _debug(`Failed to load ${path21} ${e.message}`);
324
324
  }
325
325
  lastError = e;
326
326
  }
@@ -333,7 +333,7 @@ var require_main = __commonJS({
333
333
  const shortPaths = [];
334
334
  for (const filePath of optionPaths) {
335
335
  try {
336
- const relative4 = path21.relative(process.cwd(), filePath);
336
+ const relative4 = path20.relative(process.cwd(), filePath);
337
337
  shortPaths.push(relative4);
338
338
  } catch (e) {
339
339
  if (debug) {
@@ -8237,8 +8237,8 @@ var require_MODULE_LOAD = __commonJS({
8237
8237
  * @param moduleArguments - Optional arguments to pass to the module
8238
8238
  * @see https://redis.io/commands/module-load/
8239
8239
  */
8240
- parseCommand(parser, path21, moduleArguments) {
8241
- parser.push("MODULE", "LOAD", path21);
8240
+ parseCommand(parser, path20, moduleArguments) {
8241
+ parser.push("MODULE", "LOAD", path20);
8242
8242
  if (moduleArguments) {
8243
8243
  parser.push(...moduleArguments);
8244
8244
  }
@@ -23539,10 +23539,10 @@ var require_ARRAPPEND = __commonJS({
23539
23539
  * @param json - The first value to append
23540
23540
  * @param jsons - Additional values to append
23541
23541
  */
23542
- parseCommand(parser, key, path21, json, ...jsons) {
23542
+ parseCommand(parser, key, path20, json, ...jsons) {
23543
23543
  parser.push("JSON.ARRAPPEND");
23544
23544
  parser.pushKey(key);
23545
- parser.push(path21, (0, generic_transformers_1.transformRedisJsonArgument)(json));
23545
+ parser.push(path20, (0, generic_transformers_1.transformRedisJsonArgument)(json));
23546
23546
  for (let i = 0; i < jsons.length; i++) {
23547
23547
  parser.push((0, generic_transformers_1.transformRedisJsonArgument)(jsons[i]));
23548
23548
  }
@@ -23572,10 +23572,10 @@ var require_ARRINDEX = __commonJS({
23572
23572
  * @param options.range.start - Starting index for the search
23573
23573
  * @param options.range.stop - Optional ending index for the search
23574
23574
  */
23575
- parseCommand(parser, key, path21, json, options) {
23575
+ parseCommand(parser, key, path20, json, options) {
23576
23576
  parser.push("JSON.ARRINDEX");
23577
23577
  parser.pushKey(key);
23578
- parser.push(path21, (0, generic_transformers_1.transformRedisJsonArgument)(json));
23578
+ parser.push(path20, (0, generic_transformers_1.transformRedisJsonArgument)(json));
23579
23579
  if (options?.range) {
23580
23580
  parser.push(options.range.start.toString());
23581
23581
  if (options.range.stop !== void 0) {
@@ -23607,10 +23607,10 @@ var require_ARRINSERT = __commonJS({
23607
23607
  * @param json - The first value to insert
23608
23608
  * @param jsons - Additional values to insert
23609
23609
  */
23610
- parseCommand(parser, key, path21, index, json, ...jsons) {
23610
+ parseCommand(parser, key, path20, index, json, ...jsons) {
23611
23611
  parser.push("JSON.ARRINSERT");
23612
23612
  parser.pushKey(key);
23613
- parser.push(path21, index.toString(), (0, generic_transformers_1.transformRedisJsonArgument)(json));
23613
+ parser.push(path20, index.toString(), (0, generic_transformers_1.transformRedisJsonArgument)(json));
23614
23614
  for (let i = 0; i < jsons.length; i++) {
23615
23615
  parser.push((0, generic_transformers_1.transformRedisJsonArgument)(jsons[i]));
23616
23616
  }
@@ -23700,10 +23700,10 @@ var require_ARRTRIM = __commonJS({
23700
23700
  * @param start - Starting index (inclusive)
23701
23701
  * @param stop - Ending index (inclusive)
23702
23702
  */
23703
- parseCommand(parser, key, path21, start, stop) {
23703
+ parseCommand(parser, key, path20, start, stop) {
23704
23704
  parser.push("JSON.ARRTRIM");
23705
23705
  parser.pushKey(key);
23706
- parser.push(path21, start.toString(), stop.toString());
23706
+ parser.push(path20, start.toString(), stop.toString());
23707
23707
  },
23708
23708
  transformReply: void 0
23709
23709
  };
@@ -23868,10 +23868,10 @@ var require_MERGE3 = __commonJS({
23868
23868
  * @param path - Path to merge into
23869
23869
  * @param value - JSON value to merge
23870
23870
  */
23871
- parseCommand(parser, key, path21, value) {
23871
+ parseCommand(parser, key, path20, value) {
23872
23872
  parser.push("JSON.MERGE");
23873
23873
  parser.pushKey(key);
23874
- parser.push(path21, (0, generic_transformers_1.transformRedisJsonArgument)(value));
23874
+ parser.push(path20, (0, generic_transformers_1.transformRedisJsonArgument)(value));
23875
23875
  },
23876
23876
  transformReply: void 0
23877
23877
  };
@@ -23894,10 +23894,10 @@ var require_MGET2 = __commonJS({
23894
23894
  * @param keys - Array of keys containing JSON documents
23895
23895
  * @param path - Path to retrieve from each document
23896
23896
  */
23897
- parseCommand(parser, keys, path21) {
23897
+ parseCommand(parser, keys, path20) {
23898
23898
  parser.push("JSON.MGET");
23899
23899
  parser.pushKeys(keys);
23900
- parser.push(path21);
23900
+ parser.push(path20);
23901
23901
  },
23902
23902
  transformReply(reply) {
23903
23903
  return reply.map((json) => (0, generic_transformers_1.transformRedisJsonNullReply)(json));
@@ -23952,10 +23952,10 @@ var require_NUMINCRBY = __commonJS({
23952
23952
  * @param path - Path to the numeric value
23953
23953
  * @param by - Amount to increment by
23954
23954
  */
23955
- parseCommand(parser, key, path21, by) {
23955
+ parseCommand(parser, key, path20, by) {
23956
23956
  parser.push("JSON.NUMINCRBY");
23957
23957
  parser.pushKey(key);
23958
- parser.push(path21, by.toString());
23958
+ parser.push(path20, by.toString());
23959
23959
  },
23960
23960
  transformReply: {
23961
23961
  2: (reply) => {
@@ -23987,10 +23987,10 @@ var require_NUMMULTBY = __commonJS({
23987
23987
  * @param path - Path to the numeric value
23988
23988
  * @param by - Amount to multiply by
23989
23989
  */
23990
- parseCommand(parser, key, path21, by) {
23990
+ parseCommand(parser, key, path20, by) {
23991
23991
  parser.push("JSON.NUMMULTBY");
23992
23992
  parser.pushKey(key);
23993
- parser.push(path21, by.toString());
23993
+ parser.push(path20, by.toString());
23994
23994
  },
23995
23995
  transformReply: NUMINCRBY_1.default.transformReply
23996
23996
  };
@@ -24074,10 +24074,10 @@ var require_SET2 = __commonJS({
24074
24074
  * @deprecated options.NX - Use options.condition instead
24075
24075
  * @deprecated options.XX - Use options.condition instead
24076
24076
  */
24077
- parseCommand(parser, key, path21, json, options) {
24077
+ parseCommand(parser, key, path20, json, options) {
24078
24078
  parser.push("JSON.SET");
24079
24079
  parser.pushKey(key);
24080
- parser.push(path21, (0, generic_transformers_1.transformRedisJsonArgument)(json));
24080
+ parser.push(path20, (0, generic_transformers_1.transformRedisJsonArgument)(json));
24081
24081
  if (options?.condition) {
24082
24082
  parser.push(options?.condition);
24083
24083
  } else if (options?.NX) {
@@ -24165,10 +24165,10 @@ var require_TOGGLE = __commonJS({
24165
24165
  * @param key - The key containing the JSON document
24166
24166
  * @param path - Path to the boolean value
24167
24167
  */
24168
- parseCommand(parser, key, path21) {
24168
+ parseCommand(parser, key, path20) {
24169
24169
  parser.push("JSON.TOGGLE");
24170
24170
  parser.pushKey(key);
24171
- parser.push(path21);
24171
+ parser.push(path20);
24172
24172
  },
24173
24173
  transformReply: void 0
24174
24174
  };
@@ -30242,7 +30242,7 @@ function printHelp() {
30242
30242
  `);
30243
30243
  }
30244
30244
  function printVersion() {
30245
- console.log(`duclaw-cli v${true ? "1.9.3" : "unknown"}`);
30245
+ console.log(`duclaw-cli v${true ? "1.9.5" : "unknown"}`);
30246
30246
  }
30247
30247
  function getDuclawTemplate() {
30248
30248
  return {
@@ -31627,7 +31627,7 @@ var ReaddirpStream = class extends import_node_stream.Readable {
31627
31627
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
31628
31628
  const statMethod = opts.lstat ? import_promises3.lstat : import_promises3.stat;
31629
31629
  if (wantBigintFsStats) {
31630
- this._stat = (path21) => statMethod(path21, { bigint: true });
31630
+ this._stat = (path20) => statMethod(path20, { bigint: true });
31631
31631
  } else {
31632
31632
  this._stat = statMethod;
31633
31633
  }
@@ -31652,8 +31652,8 @@ var ReaddirpStream = class extends import_node_stream.Readable {
31652
31652
  const par = this.parent;
31653
31653
  const fil = par && par.files;
31654
31654
  if (fil && fil.length > 0) {
31655
- const { path: path21, depth } = par;
31656
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path21));
31655
+ const { path: path20, depth } = par;
31656
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path20));
31657
31657
  const awaited = await Promise.all(slice);
31658
31658
  for (const entry of awaited) {
31659
31659
  if (!entry)
@@ -31693,20 +31693,20 @@ var ReaddirpStream = class extends import_node_stream.Readable {
31693
31693
  this.reading = false;
31694
31694
  }
31695
31695
  }
31696
- async _exploreDir(path21, depth) {
31696
+ async _exploreDir(path20, depth) {
31697
31697
  let files;
31698
31698
  try {
31699
- files = await (0, import_promises3.readdir)(path21, this._rdOptions);
31699
+ files = await (0, import_promises3.readdir)(path20, this._rdOptions);
31700
31700
  } catch (error) {
31701
31701
  this._onError(error);
31702
31702
  }
31703
- return { files, depth, path: path21 };
31703
+ return { files, depth, path: path20 };
31704
31704
  }
31705
- async _formatEntry(dirent, path21) {
31705
+ async _formatEntry(dirent, path20) {
31706
31706
  let entry;
31707
31707
  const basename4 = this._isDirent ? dirent.name : dirent;
31708
31708
  try {
31709
- const fullPath = (0, import_node_path4.resolve)((0, import_node_path4.join)(path21, basename4));
31709
+ const fullPath = (0, import_node_path4.resolve)((0, import_node_path4.join)(path20, basename4));
31710
31710
  entry = { path: (0, import_node_path4.relative)(this._root, fullPath), fullPath, basename: basename4 };
31711
31711
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
31712
31712
  } catch (err) {
@@ -32106,16 +32106,16 @@ var delFromSet = (main2, prop, item) => {
32106
32106
  };
32107
32107
  var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
32108
32108
  var FsWatchInstances = /* @__PURE__ */ new Map();
32109
- function createFsWatchInstance(path21, options, listener, errHandler, emitRaw) {
32109
+ function createFsWatchInstance(path20, options, listener, errHandler, emitRaw) {
32110
32110
  const handleEvent = (rawEvent, evPath) => {
32111
- listener(path21);
32112
- emitRaw(rawEvent, evPath, { watchedPath: path21 });
32113
- if (evPath && path21 !== evPath) {
32114
- fsWatchBroadcast(sp.resolve(path21, evPath), KEY_LISTENERS, sp.join(path21, evPath));
32111
+ listener(path20);
32112
+ emitRaw(rawEvent, evPath, { watchedPath: path20 });
32113
+ if (evPath && path20 !== evPath) {
32114
+ fsWatchBroadcast(sp.resolve(path20, evPath), KEY_LISTENERS, sp.join(path20, evPath));
32115
32115
  }
32116
32116
  };
32117
32117
  try {
32118
- return (0, import_node_fs.watch)(path21, {
32118
+ return (0, import_node_fs.watch)(path20, {
32119
32119
  persistent: options.persistent
32120
32120
  }, handleEvent);
32121
32121
  } catch (error) {
@@ -32131,12 +32131,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
32131
32131
  listener(val1, val2, val3);
32132
32132
  });
32133
32133
  };
32134
- var setFsWatchListener = (path21, fullPath, options, handlers) => {
32134
+ var setFsWatchListener = (path20, fullPath, options, handlers) => {
32135
32135
  const { listener, errHandler, rawEmitter } = handlers;
32136
32136
  let cont = FsWatchInstances.get(fullPath);
32137
32137
  let watcher;
32138
32138
  if (!options.persistent) {
32139
- watcher = createFsWatchInstance(path21, options, listener, errHandler, rawEmitter);
32139
+ watcher = createFsWatchInstance(path20, options, listener, errHandler, rawEmitter);
32140
32140
  if (!watcher)
32141
32141
  return;
32142
32142
  return watcher.close.bind(watcher);
@@ -32147,7 +32147,7 @@ var setFsWatchListener = (path21, fullPath, options, handlers) => {
32147
32147
  addAndConvert(cont, KEY_RAW, rawEmitter);
32148
32148
  } else {
32149
32149
  watcher = createFsWatchInstance(
32150
- path21,
32150
+ path20,
32151
32151
  options,
32152
32152
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
32153
32153
  errHandler,
@@ -32162,7 +32162,7 @@ var setFsWatchListener = (path21, fullPath, options, handlers) => {
32162
32162
  cont.watcherUnusable = true;
32163
32163
  if (isWindows && error.code === "EPERM") {
32164
32164
  try {
32165
- const fd = await (0, import_promises4.open)(path21, "r");
32165
+ const fd = await (0, import_promises4.open)(path20, "r");
32166
32166
  await fd.close();
32167
32167
  broadcastErr(error);
32168
32168
  } catch (err) {
@@ -32193,7 +32193,7 @@ var setFsWatchListener = (path21, fullPath, options, handlers) => {
32193
32193
  };
32194
32194
  };
32195
32195
  var FsWatchFileInstances = /* @__PURE__ */ new Map();
32196
- var setFsWatchFileListener = (path21, fullPath, options, handlers) => {
32196
+ var setFsWatchFileListener = (path20, fullPath, options, handlers) => {
32197
32197
  const { listener, rawEmitter } = handlers;
32198
32198
  let cont = FsWatchFileInstances.get(fullPath);
32199
32199
  const copts = cont && cont.options;
@@ -32215,7 +32215,7 @@ var setFsWatchFileListener = (path21, fullPath, options, handlers) => {
32215
32215
  });
32216
32216
  const currmtime = curr.mtimeMs;
32217
32217
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
32218
- foreach(cont.listeners, (listener2) => listener2(path21, curr));
32218
+ foreach(cont.listeners, (listener2) => listener2(path20, curr));
32219
32219
  }
32220
32220
  })
32221
32221
  };
@@ -32245,13 +32245,13 @@ var NodeFsHandler = class {
32245
32245
  * @param listener on fs change
32246
32246
  * @returns closer for the watcher instance
32247
32247
  */
32248
- _watchWithNodeFs(path21, listener) {
32248
+ _watchWithNodeFs(path20, listener) {
32249
32249
  const opts = this.fsw.options;
32250
- const directory = sp.dirname(path21);
32251
- const basename4 = sp.basename(path21);
32250
+ const directory = sp.dirname(path20);
32251
+ const basename4 = sp.basename(path20);
32252
32252
  const parent = this.fsw._getWatchedDir(directory);
32253
32253
  parent.add(basename4);
32254
- const absolutePath = sp.resolve(path21);
32254
+ const absolutePath = sp.resolve(path20);
32255
32255
  const options = {
32256
32256
  persistent: opts.persistent
32257
32257
  };
@@ -32261,12 +32261,12 @@ var NodeFsHandler = class {
32261
32261
  if (opts.usePolling) {
32262
32262
  const enableBin = opts.interval !== opts.binaryInterval;
32263
32263
  options.interval = enableBin && isBinaryPath(basename4) ? opts.binaryInterval : opts.interval;
32264
- closer = setFsWatchFileListener(path21, absolutePath, options, {
32264
+ closer = setFsWatchFileListener(path20, absolutePath, options, {
32265
32265
  listener,
32266
32266
  rawEmitter: this.fsw._emitRaw
32267
32267
  });
32268
32268
  } else {
32269
- closer = setFsWatchListener(path21, absolutePath, options, {
32269
+ closer = setFsWatchListener(path20, absolutePath, options, {
32270
32270
  listener,
32271
32271
  errHandler: this._boundHandleError,
32272
32272
  rawEmitter: this.fsw._emitRaw
@@ -32288,7 +32288,7 @@ var NodeFsHandler = class {
32288
32288
  let prevStats = stats;
32289
32289
  if (parent.has(basename4))
32290
32290
  return;
32291
- const listener = async (path21, newStats) => {
32291
+ const listener = async (path20, newStats) => {
32292
32292
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
32293
32293
  return;
32294
32294
  if (!newStats || newStats.mtimeMs === 0) {
@@ -32302,11 +32302,11 @@ var NodeFsHandler = class {
32302
32302
  this.fsw._emit(EV.CHANGE, file, newStats2);
32303
32303
  }
32304
32304
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
32305
- this.fsw._closeFile(path21);
32305
+ this.fsw._closeFile(path20);
32306
32306
  prevStats = newStats2;
32307
32307
  const closer2 = this._watchWithNodeFs(file, listener);
32308
32308
  if (closer2)
32309
- this.fsw._addPathCloser(path21, closer2);
32309
+ this.fsw._addPathCloser(path20, closer2);
32310
32310
  } else {
32311
32311
  prevStats = newStats2;
32312
32312
  }
@@ -32338,7 +32338,7 @@ var NodeFsHandler = class {
32338
32338
  * @param item basename of this item
32339
32339
  * @returns true if no more processing is needed for this entry.
32340
32340
  */
32341
- async _handleSymlink(entry, directory, path21, item) {
32341
+ async _handleSymlink(entry, directory, path20, item) {
32342
32342
  if (this.fsw.closed) {
32343
32343
  return;
32344
32344
  }
@@ -32348,7 +32348,7 @@ var NodeFsHandler = class {
32348
32348
  this.fsw._incrReadyCount();
32349
32349
  let linkPath;
32350
32350
  try {
32351
- linkPath = await (0, import_promises4.realpath)(path21);
32351
+ linkPath = await (0, import_promises4.realpath)(path20);
32352
32352
  } catch (e) {
32353
32353
  this.fsw._emitReady();
32354
32354
  return true;
@@ -32358,12 +32358,12 @@ var NodeFsHandler = class {
32358
32358
  if (dir.has(item)) {
32359
32359
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
32360
32360
  this.fsw._symlinkPaths.set(full, linkPath);
32361
- this.fsw._emit(EV.CHANGE, path21, entry.stats);
32361
+ this.fsw._emit(EV.CHANGE, path20, entry.stats);
32362
32362
  }
32363
32363
  } else {
32364
32364
  dir.add(item);
32365
32365
  this.fsw._symlinkPaths.set(full, linkPath);
32366
- this.fsw._emit(EV.ADD, path21, entry.stats);
32366
+ this.fsw._emit(EV.ADD, path20, entry.stats);
32367
32367
  }
32368
32368
  this.fsw._emitReady();
32369
32369
  return true;
@@ -32393,9 +32393,9 @@ var NodeFsHandler = class {
32393
32393
  return;
32394
32394
  }
32395
32395
  const item = entry.path;
32396
- let path21 = sp.join(directory, item);
32396
+ let path20 = sp.join(directory, item);
32397
32397
  current.add(item);
32398
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path21, item)) {
32398
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path20, item)) {
32399
32399
  return;
32400
32400
  }
32401
32401
  if (this.fsw.closed) {
@@ -32404,8 +32404,8 @@ var NodeFsHandler = class {
32404
32404
  }
32405
32405
  if (item === target || !target && !previous.has(item)) {
32406
32406
  this.fsw._incrReadyCount();
32407
- path21 = sp.join(dir, sp.relative(dir, path21));
32408
- this._addToNodeFs(path21, initialAdd, wh, depth + 1);
32407
+ path20 = sp.join(dir, sp.relative(dir, path20));
32408
+ this._addToNodeFs(path20, initialAdd, wh, depth + 1);
32409
32409
  }
32410
32410
  }).on(EV.ERROR, this._boundHandleError);
32411
32411
  return new Promise((resolve11, reject) => {
@@ -32474,13 +32474,13 @@ var NodeFsHandler = class {
32474
32474
  * @param depth Child path actually targeted for watch
32475
32475
  * @param target Child path actually targeted for watch
32476
32476
  */
32477
- async _addToNodeFs(path21, initialAdd, priorWh, depth, target) {
32477
+ async _addToNodeFs(path20, initialAdd, priorWh, depth, target) {
32478
32478
  const ready = this.fsw._emitReady;
32479
- if (this.fsw._isIgnored(path21) || this.fsw.closed) {
32479
+ if (this.fsw._isIgnored(path20) || this.fsw.closed) {
32480
32480
  ready();
32481
32481
  return false;
32482
32482
  }
32483
- const wh = this.fsw._getWatchHelpers(path21);
32483
+ const wh = this.fsw._getWatchHelpers(path20);
32484
32484
  if (priorWh) {
32485
32485
  wh.filterPath = (entry) => priorWh.filterPath(entry);
32486
32486
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -32496,8 +32496,8 @@ var NodeFsHandler = class {
32496
32496
  const follow = this.fsw.options.followSymlinks;
32497
32497
  let closer;
32498
32498
  if (stats.isDirectory()) {
32499
- const absPath = sp.resolve(path21);
32500
- const targetPath = follow ? await (0, import_promises4.realpath)(path21) : path21;
32499
+ const absPath = sp.resolve(path20);
32500
+ const targetPath = follow ? await (0, import_promises4.realpath)(path20) : path20;
32501
32501
  if (this.fsw.closed)
32502
32502
  return;
32503
32503
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -32507,29 +32507,29 @@ var NodeFsHandler = class {
32507
32507
  this.fsw._symlinkPaths.set(absPath, targetPath);
32508
32508
  }
32509
32509
  } else if (stats.isSymbolicLink()) {
32510
- const targetPath = follow ? await (0, import_promises4.realpath)(path21) : path21;
32510
+ const targetPath = follow ? await (0, import_promises4.realpath)(path20) : path20;
32511
32511
  if (this.fsw.closed)
32512
32512
  return;
32513
32513
  const parent = sp.dirname(wh.watchPath);
32514
32514
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
32515
32515
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
32516
- closer = await this._handleDir(parent, stats, initialAdd, depth, path21, wh, targetPath);
32516
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path20, wh, targetPath);
32517
32517
  if (this.fsw.closed)
32518
32518
  return;
32519
32519
  if (targetPath !== void 0) {
32520
- this.fsw._symlinkPaths.set(sp.resolve(path21), targetPath);
32520
+ this.fsw._symlinkPaths.set(sp.resolve(path20), targetPath);
32521
32521
  }
32522
32522
  } else {
32523
32523
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
32524
32524
  }
32525
32525
  ready();
32526
32526
  if (closer)
32527
- this.fsw._addPathCloser(path21, closer);
32527
+ this.fsw._addPathCloser(path20, closer);
32528
32528
  return false;
32529
32529
  } catch (error) {
32530
32530
  if (this.fsw._handleError(error)) {
32531
32531
  ready();
32532
- return path21;
32532
+ return path20;
32533
32533
  }
32534
32534
  }
32535
32535
  }
@@ -32572,24 +32572,24 @@ function createPattern(matcher) {
32572
32572
  }
32573
32573
  return () => false;
32574
32574
  }
32575
- function normalizePath(path21) {
32576
- if (typeof path21 !== "string")
32575
+ function normalizePath(path20) {
32576
+ if (typeof path20 !== "string")
32577
32577
  throw new Error("string expected");
32578
- path21 = sp2.normalize(path21);
32579
- path21 = path21.replace(/\\/g, "/");
32578
+ path20 = sp2.normalize(path20);
32579
+ path20 = path20.replace(/\\/g, "/");
32580
32580
  let prepend = false;
32581
- if (path21.startsWith("//"))
32581
+ if (path20.startsWith("//"))
32582
32582
  prepend = true;
32583
- path21 = path21.replace(DOUBLE_SLASH_RE, "/");
32583
+ path20 = path20.replace(DOUBLE_SLASH_RE, "/");
32584
32584
  if (prepend)
32585
- path21 = "/" + path21;
32586
- return path21;
32585
+ path20 = "/" + path20;
32586
+ return path20;
32587
32587
  }
32588
32588
  function matchPatterns(patterns, testString, stats) {
32589
- const path21 = normalizePath(testString);
32589
+ const path20 = normalizePath(testString);
32590
32590
  for (let index = 0; index < patterns.length; index++) {
32591
32591
  const pattern = patterns[index];
32592
- if (pattern(path21, stats)) {
32592
+ if (pattern(path20, stats)) {
32593
32593
  return true;
32594
32594
  }
32595
32595
  }
@@ -32627,19 +32627,19 @@ var toUnix = (string) => {
32627
32627
  }
32628
32628
  return str;
32629
32629
  };
32630
- var normalizePathToUnix = (path21) => toUnix(sp2.normalize(toUnix(path21)));
32631
- var normalizeIgnored = (cwd = "") => (path21) => {
32632
- if (typeof path21 === "string") {
32633
- return normalizePathToUnix(sp2.isAbsolute(path21) ? path21 : sp2.join(cwd, path21));
32630
+ var normalizePathToUnix = (path20) => toUnix(sp2.normalize(toUnix(path20)));
32631
+ var normalizeIgnored = (cwd = "") => (path20) => {
32632
+ if (typeof path20 === "string") {
32633
+ return normalizePathToUnix(sp2.isAbsolute(path20) ? path20 : sp2.join(cwd, path20));
32634
32634
  } else {
32635
- return path21;
32635
+ return path20;
32636
32636
  }
32637
32637
  };
32638
- var getAbsolutePath = (path21, cwd) => {
32639
- if (sp2.isAbsolute(path21)) {
32640
- return path21;
32638
+ var getAbsolutePath = (path20, cwd) => {
32639
+ if (sp2.isAbsolute(path20)) {
32640
+ return path20;
32641
32641
  }
32642
- return sp2.join(cwd, path21);
32642
+ return sp2.join(cwd, path20);
32643
32643
  };
32644
32644
  var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
32645
32645
  var DirEntry = class {
@@ -32704,10 +32704,10 @@ var WatchHelper = class {
32704
32704
  dirParts;
32705
32705
  followSymlinks;
32706
32706
  statMethod;
32707
- constructor(path21, follow, fsw) {
32707
+ constructor(path20, follow, fsw) {
32708
32708
  this.fsw = fsw;
32709
- const watchPath = path21;
32710
- this.path = path21 = path21.replace(REPLACER_RE, "");
32709
+ const watchPath = path20;
32710
+ this.path = path20 = path20.replace(REPLACER_RE, "");
32711
32711
  this.watchPath = watchPath;
32712
32712
  this.fullWatchPath = sp2.resolve(watchPath);
32713
32713
  this.dirParts = [];
@@ -32847,20 +32847,20 @@ var FSWatcher = class extends import_node_events.EventEmitter {
32847
32847
  this._closePromise = void 0;
32848
32848
  let paths = unifyPaths(paths_);
32849
32849
  if (cwd) {
32850
- paths = paths.map((path21) => {
32851
- const absPath = getAbsolutePath(path21, cwd);
32850
+ paths = paths.map((path20) => {
32851
+ const absPath = getAbsolutePath(path20, cwd);
32852
32852
  return absPath;
32853
32853
  });
32854
32854
  }
32855
- paths.forEach((path21) => {
32856
- this._removeIgnoredPath(path21);
32855
+ paths.forEach((path20) => {
32856
+ this._removeIgnoredPath(path20);
32857
32857
  });
32858
32858
  this._userIgnored = void 0;
32859
32859
  if (!this._readyCount)
32860
32860
  this._readyCount = 0;
32861
32861
  this._readyCount += paths.length;
32862
- Promise.all(paths.map(async (path21) => {
32863
- const res = await this._nodeFsHandler._addToNodeFs(path21, !_internal, void 0, 0, _origAdd);
32862
+ Promise.all(paths.map(async (path20) => {
32863
+ const res = await this._nodeFsHandler._addToNodeFs(path20, !_internal, void 0, 0, _origAdd);
32864
32864
  if (res)
32865
32865
  this._emitReady();
32866
32866
  return res;
@@ -32882,17 +32882,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
32882
32882
  return this;
32883
32883
  const paths = unifyPaths(paths_);
32884
32884
  const { cwd } = this.options;
32885
- paths.forEach((path21) => {
32886
- if (!sp2.isAbsolute(path21) && !this._closers.has(path21)) {
32885
+ paths.forEach((path20) => {
32886
+ if (!sp2.isAbsolute(path20) && !this._closers.has(path20)) {
32887
32887
  if (cwd)
32888
- path21 = sp2.join(cwd, path21);
32889
- path21 = sp2.resolve(path21);
32888
+ path20 = sp2.join(cwd, path20);
32889
+ path20 = sp2.resolve(path20);
32890
32890
  }
32891
- this._closePath(path21);
32892
- this._addIgnoredPath(path21);
32893
- if (this._watched.has(path21)) {
32891
+ this._closePath(path20);
32892
+ this._addIgnoredPath(path20);
32893
+ if (this._watched.has(path20)) {
32894
32894
  this._addIgnoredPath({
32895
- path: path21,
32895
+ path: path20,
32896
32896
  recursive: true
32897
32897
  });
32898
32898
  }
@@ -32956,38 +32956,38 @@ var FSWatcher = class extends import_node_events.EventEmitter {
32956
32956
  * @param stats arguments to be passed with event
32957
32957
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
32958
32958
  */
32959
- async _emit(event, path21, stats) {
32959
+ async _emit(event, path20, stats) {
32960
32960
  if (this.closed)
32961
32961
  return;
32962
32962
  const opts = this.options;
32963
32963
  if (isWindows)
32964
- path21 = sp2.normalize(path21);
32964
+ path20 = sp2.normalize(path20);
32965
32965
  if (opts.cwd)
32966
- path21 = sp2.relative(opts.cwd, path21);
32967
- const args = [path21];
32966
+ path20 = sp2.relative(opts.cwd, path20);
32967
+ const args = [path20];
32968
32968
  if (stats != null)
32969
32969
  args.push(stats);
32970
32970
  const awf = opts.awaitWriteFinish;
32971
32971
  let pw;
32972
- if (awf && (pw = this._pendingWrites.get(path21))) {
32972
+ if (awf && (pw = this._pendingWrites.get(path20))) {
32973
32973
  pw.lastChange = /* @__PURE__ */ new Date();
32974
32974
  return this;
32975
32975
  }
32976
32976
  if (opts.atomic) {
32977
32977
  if (event === EVENTS.UNLINK) {
32978
- this._pendingUnlinks.set(path21, [event, ...args]);
32978
+ this._pendingUnlinks.set(path20, [event, ...args]);
32979
32979
  setTimeout(() => {
32980
- this._pendingUnlinks.forEach((entry, path22) => {
32980
+ this._pendingUnlinks.forEach((entry, path21) => {
32981
32981
  this.emit(...entry);
32982
32982
  this.emit(EVENTS.ALL, ...entry);
32983
- this._pendingUnlinks.delete(path22);
32983
+ this._pendingUnlinks.delete(path21);
32984
32984
  });
32985
32985
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
32986
32986
  return this;
32987
32987
  }
32988
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path21)) {
32988
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path20)) {
32989
32989
  event = EVENTS.CHANGE;
32990
- this._pendingUnlinks.delete(path21);
32990
+ this._pendingUnlinks.delete(path20);
32991
32991
  }
32992
32992
  }
32993
32993
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -33005,16 +33005,16 @@ var FSWatcher = class extends import_node_events.EventEmitter {
33005
33005
  this.emitWithAll(event, args);
33006
33006
  }
33007
33007
  };
33008
- this._awaitWriteFinish(path21, awf.stabilityThreshold, event, awfEmit);
33008
+ this._awaitWriteFinish(path20, awf.stabilityThreshold, event, awfEmit);
33009
33009
  return this;
33010
33010
  }
33011
33011
  if (event === EVENTS.CHANGE) {
33012
- const isThrottled = !this._throttle(EVENTS.CHANGE, path21, 50);
33012
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path20, 50);
33013
33013
  if (isThrottled)
33014
33014
  return this;
33015
33015
  }
33016
33016
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
33017
- const fullPath = opts.cwd ? sp2.join(opts.cwd, path21) : path21;
33017
+ const fullPath = opts.cwd ? sp2.join(opts.cwd, path20) : path20;
33018
33018
  let stats2;
33019
33019
  try {
33020
33020
  stats2 = await (0, import_promises5.stat)(fullPath);
@@ -33045,23 +33045,23 @@ var FSWatcher = class extends import_node_events.EventEmitter {
33045
33045
  * @param timeout duration of time to suppress duplicate actions
33046
33046
  * @returns tracking object or false if action should be suppressed
33047
33047
  */
33048
- _throttle(actionType, path21, timeout) {
33048
+ _throttle(actionType, path20, timeout) {
33049
33049
  if (!this._throttled.has(actionType)) {
33050
33050
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
33051
33051
  }
33052
33052
  const action = this._throttled.get(actionType);
33053
33053
  if (!action)
33054
33054
  throw new Error("invalid throttle");
33055
- const actionPath = action.get(path21);
33055
+ const actionPath = action.get(path20);
33056
33056
  if (actionPath) {
33057
33057
  actionPath.count++;
33058
33058
  return false;
33059
33059
  }
33060
33060
  let timeoutObject;
33061
33061
  const clear = () => {
33062
- const item = action.get(path21);
33062
+ const item = action.get(path20);
33063
33063
  const count = item ? item.count : 0;
33064
- action.delete(path21);
33064
+ action.delete(path20);
33065
33065
  clearTimeout(timeoutObject);
33066
33066
  if (item)
33067
33067
  clearTimeout(item.timeoutObject);
@@ -33069,7 +33069,7 @@ var FSWatcher = class extends import_node_events.EventEmitter {
33069
33069
  };
33070
33070
  timeoutObject = setTimeout(clear, timeout);
33071
33071
  const thr = { timeoutObject, clear, count: 0 };
33072
- action.set(path21, thr);
33072
+ action.set(path20, thr);
33073
33073
  return thr;
33074
33074
  }
33075
33075
  _incrReadyCount() {
@@ -33083,44 +33083,44 @@ var FSWatcher = class extends import_node_events.EventEmitter {
33083
33083
  * @param event
33084
33084
  * @param awfEmit Callback to be called when ready for event to be emitted.
33085
33085
  */
33086
- _awaitWriteFinish(path21, threshold, event, awfEmit) {
33086
+ _awaitWriteFinish(path20, threshold, event, awfEmit) {
33087
33087
  const awf = this.options.awaitWriteFinish;
33088
33088
  if (typeof awf !== "object")
33089
33089
  return;
33090
33090
  const pollInterval = awf.pollInterval;
33091
33091
  let timeoutHandler;
33092
- let fullPath = path21;
33093
- if (this.options.cwd && !sp2.isAbsolute(path21)) {
33094
- fullPath = sp2.join(this.options.cwd, path21);
33092
+ let fullPath = path20;
33093
+ if (this.options.cwd && !sp2.isAbsolute(path20)) {
33094
+ fullPath = sp2.join(this.options.cwd, path20);
33095
33095
  }
33096
33096
  const now = /* @__PURE__ */ new Date();
33097
33097
  const writes = this._pendingWrites;
33098
33098
  function awaitWriteFinishFn(prevStat) {
33099
33099
  (0, import_node_fs2.stat)(fullPath, (err, curStat) => {
33100
- if (err || !writes.has(path21)) {
33100
+ if (err || !writes.has(path20)) {
33101
33101
  if (err && err.code !== "ENOENT")
33102
33102
  awfEmit(err);
33103
33103
  return;
33104
33104
  }
33105
33105
  const now2 = Number(/* @__PURE__ */ new Date());
33106
33106
  if (prevStat && curStat.size !== prevStat.size) {
33107
- writes.get(path21).lastChange = now2;
33107
+ writes.get(path20).lastChange = now2;
33108
33108
  }
33109
- const pw = writes.get(path21);
33109
+ const pw = writes.get(path20);
33110
33110
  const df = now2 - pw.lastChange;
33111
33111
  if (df >= threshold) {
33112
- writes.delete(path21);
33112
+ writes.delete(path20);
33113
33113
  awfEmit(void 0, curStat);
33114
33114
  } else {
33115
33115
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
33116
33116
  }
33117
33117
  });
33118
33118
  }
33119
- if (!writes.has(path21)) {
33120
- writes.set(path21, {
33119
+ if (!writes.has(path20)) {
33120
+ writes.set(path20, {
33121
33121
  lastChange: now,
33122
33122
  cancelWait: () => {
33123
- writes.delete(path21);
33123
+ writes.delete(path20);
33124
33124
  clearTimeout(timeoutHandler);
33125
33125
  return event;
33126
33126
  }
@@ -33131,8 +33131,8 @@ var FSWatcher = class extends import_node_events.EventEmitter {
33131
33131
  /**
33132
33132
  * Determines whether user has asked to ignore this path.
33133
33133
  */
33134
- _isIgnored(path21, stats) {
33135
- if (this.options.atomic && DOT_RE.test(path21))
33134
+ _isIgnored(path20, stats) {
33135
+ if (this.options.atomic && DOT_RE.test(path20))
33136
33136
  return true;
33137
33137
  if (!this._userIgnored) {
33138
33138
  const { cwd } = this.options;
@@ -33142,17 +33142,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
33142
33142
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
33143
33143
  this._userIgnored = anymatch(list, void 0);
33144
33144
  }
33145
- return this._userIgnored(path21, stats);
33145
+ return this._userIgnored(path20, stats);
33146
33146
  }
33147
- _isntIgnored(path21, stat11) {
33148
- return !this._isIgnored(path21, stat11);
33147
+ _isntIgnored(path20, stat11) {
33148
+ return !this._isIgnored(path20, stat11);
33149
33149
  }
33150
33150
  /**
33151
33151
  * Provides a set of common helpers and properties relating to symlink handling.
33152
33152
  * @param path file or directory pattern being watched
33153
33153
  */
33154
- _getWatchHelpers(path21) {
33155
- return new WatchHelper(path21, this.options.followSymlinks, this);
33154
+ _getWatchHelpers(path20) {
33155
+ return new WatchHelper(path20, this.options.followSymlinks, this);
33156
33156
  }
33157
33157
  // Directory helpers
33158
33158
  // -----------------
@@ -33184,63 +33184,63 @@ var FSWatcher = class extends import_node_events.EventEmitter {
33184
33184
  * @param item base path of item/directory
33185
33185
  */
33186
33186
  _remove(directory, item, isDirectory) {
33187
- const path21 = sp2.join(directory, item);
33188
- const fullPath = sp2.resolve(path21);
33189
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path21) || this._watched.has(fullPath);
33190
- if (!this._throttle("remove", path21, 100))
33187
+ const path20 = sp2.join(directory, item);
33188
+ const fullPath = sp2.resolve(path20);
33189
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path20) || this._watched.has(fullPath);
33190
+ if (!this._throttle("remove", path20, 100))
33191
33191
  return;
33192
33192
  if (!isDirectory && this._watched.size === 1) {
33193
33193
  this.add(directory, item, true);
33194
33194
  }
33195
- const wp = this._getWatchedDir(path21);
33195
+ const wp = this._getWatchedDir(path20);
33196
33196
  const nestedDirectoryChildren = wp.getChildren();
33197
- nestedDirectoryChildren.forEach((nested) => this._remove(path21, nested));
33197
+ nestedDirectoryChildren.forEach((nested) => this._remove(path20, nested));
33198
33198
  const parent = this._getWatchedDir(directory);
33199
33199
  const wasTracked = parent.has(item);
33200
33200
  parent.remove(item);
33201
33201
  if (this._symlinkPaths.has(fullPath)) {
33202
33202
  this._symlinkPaths.delete(fullPath);
33203
33203
  }
33204
- let relPath = path21;
33204
+ let relPath = path20;
33205
33205
  if (this.options.cwd)
33206
- relPath = sp2.relative(this.options.cwd, path21);
33206
+ relPath = sp2.relative(this.options.cwd, path20);
33207
33207
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
33208
33208
  const event = this._pendingWrites.get(relPath).cancelWait();
33209
33209
  if (event === EVENTS.ADD)
33210
33210
  return;
33211
33211
  }
33212
- this._watched.delete(path21);
33212
+ this._watched.delete(path20);
33213
33213
  this._watched.delete(fullPath);
33214
33214
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
33215
- if (wasTracked && !this._isIgnored(path21))
33216
- this._emit(eventName, path21);
33217
- this._closePath(path21);
33215
+ if (wasTracked && !this._isIgnored(path20))
33216
+ this._emit(eventName, path20);
33217
+ this._closePath(path20);
33218
33218
  }
33219
33219
  /**
33220
33220
  * Closes all watchers for a path
33221
33221
  */
33222
- _closePath(path21) {
33223
- this._closeFile(path21);
33224
- const dir = sp2.dirname(path21);
33225
- this._getWatchedDir(dir).remove(sp2.basename(path21));
33222
+ _closePath(path20) {
33223
+ this._closeFile(path20);
33224
+ const dir = sp2.dirname(path20);
33225
+ this._getWatchedDir(dir).remove(sp2.basename(path20));
33226
33226
  }
33227
33227
  /**
33228
33228
  * Closes only file-specific watchers
33229
33229
  */
33230
- _closeFile(path21) {
33231
- const closers = this._closers.get(path21);
33230
+ _closeFile(path20) {
33231
+ const closers = this._closers.get(path20);
33232
33232
  if (!closers)
33233
33233
  return;
33234
33234
  closers.forEach((closer) => closer());
33235
- this._closers.delete(path21);
33235
+ this._closers.delete(path20);
33236
33236
  }
33237
- _addPathCloser(path21, closer) {
33237
+ _addPathCloser(path20, closer) {
33238
33238
  if (!closer)
33239
33239
  return;
33240
- let list = this._closers.get(path21);
33240
+ let list = this._closers.get(path20);
33241
33241
  if (!list) {
33242
33242
  list = [];
33243
- this._closers.set(path21, list);
33243
+ this._closers.set(path20, list);
33244
33244
  }
33245
33245
  list.push(closer);
33246
33246
  }
@@ -33273,7 +33273,7 @@ var chokidar_default = { watch, FSWatcher };
33273
33273
  var import_node_cron = __toESM(require_node_cron());
33274
33274
 
33275
33275
  // src/agent/createAgent.ts
33276
- var import_node_crypto14 = require("node:crypto");
33276
+ var import_node_crypto15 = require("node:crypto");
33277
33277
  var import_node_fs7 = require("node:fs");
33278
33278
 
33279
33279
  // src/background/BackgroundManager.ts
@@ -34704,12 +34704,12 @@ function encodeURIPath(str) {
34704
34704
  return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
34705
34705
  }
34706
34706
  var EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
34707
- var createPathTagFunction = (pathEncoder = encodeURIPath) => function path21(statics, ...params) {
34707
+ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path20(statics, ...params) {
34708
34708
  if (statics.length === 1)
34709
34709
  return statics[0];
34710
34710
  let postPath = false;
34711
34711
  const invalidSegments = [];
34712
- const path22 = statics.reduce((previousValue, currentValue, index) => {
34712
+ const path21 = statics.reduce((previousValue, currentValue, index) => {
34713
34713
  if (/[?#]/.test(currentValue)) {
34714
34714
  postPath = true;
34715
34715
  }
@@ -34726,7 +34726,7 @@ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path21(sta
34726
34726
  }
34727
34727
  return previousValue + currentValue + (index === params.length ? "" : encoded);
34728
34728
  }, "");
34729
- const pathOnly = path22.split(/[?#]/, 1)[0];
34729
+ const pathOnly = path21.split(/[?#]/, 1)[0];
34730
34730
  const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
34731
34731
  let match2;
34732
34732
  while ((match2 = invalidSegmentPattern.exec(pathOnly)) !== null) {
@@ -34747,10 +34747,10 @@ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path21(sta
34747
34747
  }, "");
34748
34748
  throw new AnthropicError(`Path parameters result in path with invalid segments:
34749
34749
  ${invalidSegments.map((e) => e.error).join("\n")}
34750
- ${path22}
34750
+ ${path21}
34751
34751
  ${underline}`);
34752
34752
  }
34753
- return path22;
34753
+ return path21;
34754
34754
  };
34755
34755
  var path5 = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
34756
34756
 
@@ -37861,9 +37861,9 @@ var BaseAnthropic = class {
37861
37861
  makeStatusError(status, error, message, headers) {
37862
37862
  return APIError.generate(status, error, message, headers);
37863
37863
  }
37864
- buildURL(path21, query, defaultBaseURL) {
37864
+ buildURL(path20, query, defaultBaseURL) {
37865
37865
  const baseURL = !__classPrivateFieldGet(this, _BaseAnthropic_instances, "m", _BaseAnthropic_baseURLOverridden).call(this) && defaultBaseURL || this.baseURL;
37866
- const url = isAbsoluteURL(path21) ? new URL(path21) : new URL(baseURL + (baseURL.endsWith("/") && path21.startsWith("/") ? path21.slice(1) : path21));
37866
+ const url = isAbsoluteURL(path20) ? new URL(path20) : new URL(baseURL + (baseURL.endsWith("/") && path20.startsWith("/") ? path20.slice(1) : path20));
37867
37867
  const defaultQuery = this.defaultQuery();
37868
37868
  if (!isEmptyObj(defaultQuery)) {
37869
37869
  query = { ...defaultQuery, ...query };
@@ -37894,24 +37894,24 @@ var BaseAnthropic = class {
37894
37894
  */
37895
37895
  async prepareRequest(request, { url, options }) {
37896
37896
  }
37897
- get(path21, opts) {
37898
- return this.methodRequest("get", path21, opts);
37897
+ get(path20, opts) {
37898
+ return this.methodRequest("get", path20, opts);
37899
37899
  }
37900
- post(path21, opts) {
37901
- return this.methodRequest("post", path21, opts);
37900
+ post(path20, opts) {
37901
+ return this.methodRequest("post", path20, opts);
37902
37902
  }
37903
- patch(path21, opts) {
37904
- return this.methodRequest("patch", path21, opts);
37903
+ patch(path20, opts) {
37904
+ return this.methodRequest("patch", path20, opts);
37905
37905
  }
37906
- put(path21, opts) {
37907
- return this.methodRequest("put", path21, opts);
37906
+ put(path20, opts) {
37907
+ return this.methodRequest("put", path20, opts);
37908
37908
  }
37909
- delete(path21, opts) {
37910
- return this.methodRequest("delete", path21, opts);
37909
+ delete(path20, opts) {
37910
+ return this.methodRequest("delete", path20, opts);
37911
37911
  }
37912
- methodRequest(method, path21, opts) {
37912
+ methodRequest(method, path20, opts) {
37913
37913
  return this.request(Promise.resolve(opts).then((opts2) => {
37914
- return { method, path: path21, ...opts2 };
37914
+ return { method, path: path20, ...opts2 };
37915
37915
  }));
37916
37916
  }
37917
37917
  request(options, remainingRetries = null) {
@@ -38015,8 +38015,8 @@ var BaseAnthropic = class {
38015
38015
  }));
38016
38016
  return { response, options, controller, requestLogID, retryOfRequestLogID, startTime: startTime2 };
38017
38017
  }
38018
- getAPIList(path21, Page2, opts) {
38019
- return this.requestAPIList(Page2, opts && "then" in opts ? opts.then((opts2) => ({ method: "get", path: path21, ...opts2 })) : { method: "get", path: path21, ...opts });
38018
+ getAPIList(path20, Page2, opts) {
38019
+ return this.requestAPIList(Page2, opts && "then" in opts ? opts.then((opts2) => ({ method: "get", path: path20, ...opts2 })) : { method: "get", path: path20, ...opts });
38020
38020
  }
38021
38021
  requestAPIList(Page2, options) {
38022
38022
  const request = this.makeRequest(options, null, void 0);
@@ -38104,8 +38104,8 @@ var BaseAnthropic = class {
38104
38104
  }
38105
38105
  async buildRequest(inputOptions, { retryCount = 0 } = {}) {
38106
38106
  const options = { ...inputOptions };
38107
- const { method, path: path21, query, defaultBaseURL } = options;
38108
- const url = this.buildURL(path21, query, defaultBaseURL);
38107
+ const { method, path: path20, query, defaultBaseURL } = options;
38108
+ const url = this.buildURL(path20, query, defaultBaseURL);
38109
38109
  if ("timeout" in options)
38110
38110
  validatePositiveInteger("timeout", options.timeout);
38111
38111
  options.timeout = options.timeout ?? this.timeout;
@@ -38895,40 +38895,89 @@ var clearMessages = async (storage, userId, date, cronTitle) => {
38895
38895
  await storage.del(key);
38896
38896
  };
38897
38897
 
38898
- // src/runtime/activity.ts
38899
- async function reportRuntimeActivity(input) {
38900
- const baseUrl = process.env.DUCLAW_CONTROL_PLANE_BASE_URL?.replace(/\/$/, "");
38901
- const token = process.env.DUCLAW_CONTROL_PLANE_METERING_TOKEN;
38902
- const tenantId = process.env.DUCLAW_TENANT_ID;
38903
- if (!baseUrl || !token || !tenantId) return;
38904
- try {
38905
- const response = await fetch(`${baseUrl}/internal/runtime/activity`, {
38906
- method: "POST",
38907
- signal: AbortSignal.timeout(2500),
38908
- headers: {
38909
- authorization: `Bearer ${token}`,
38910
- "content-type": "application/json"
38911
- },
38912
- body: JSON.stringify({
38913
- tenantId,
38914
- kind: input.kind,
38915
- status: input.status,
38916
- toolName: input.toolName,
38917
- toolCallId: input.toolCallId ?? null,
38918
- occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
38919
- metadata: input.metadata ?? {}
38920
- })
38921
- });
38922
- if (!response.ok) {
38923
- console.warn(`[runtime-activity] \u4E0A\u62A5\u5931\u8D25: tool=${input.toolName} status=${input.status} http=${response.status}`);
38898
+ // src/tools/ToolExecutor.ts
38899
+ var import_node_crypto2 = require("node:crypto");
38900
+
38901
+ // src/runtime/events.ts
38902
+ var createRuntimeEventBus = () => {
38903
+ const handlers = /* @__PURE__ */ new Map();
38904
+ return {
38905
+ async emit(event) {
38906
+ const subscribers = Array.from(handlers.get(event.type) ?? []);
38907
+ for (const handler of subscribers) {
38908
+ try {
38909
+ await handler(event);
38910
+ } catch (error) {
38911
+ console.warn(`[runtime-event-bus] handler failed: type=${event.type} error=${error.message}`);
38912
+ }
38913
+ }
38914
+ },
38915
+ subscribe(type, handler) {
38916
+ const current = handlers.get(type) ?? /* @__PURE__ */ new Set();
38917
+ current.add(handler);
38918
+ handlers.set(type, current);
38919
+ return () => {
38920
+ current.delete(handler);
38921
+ if (current.size === 0) handlers.delete(type);
38922
+ };
38923
+ }
38924
+ };
38925
+ };
38926
+
38927
+ // src/runtime/toolHooks.ts
38928
+ function sortToolHookPlugins(plugins = []) {
38929
+ return [...plugins].sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
38930
+ }
38931
+ async function runPreToolUseHooks(plugins, ctx) {
38932
+ for (const plugin of plugins) {
38933
+ if (!plugin.preToolUse) continue;
38934
+ const decision = await plugin.preToolUse(ctx);
38935
+ if (decision?.metadataPatch) {
38936
+ ctx.metadata = {
38937
+ ...ctx.metadata,
38938
+ ...decision.metadataPatch
38939
+ };
38940
+ }
38941
+ if (decision?.deny || decision?.allow === false) {
38942
+ return {
38943
+ allow: false,
38944
+ deny: true,
38945
+ reason: decision.reason ?? `blocked_by_${plugin.id}`,
38946
+ userMessage: decision.userMessage,
38947
+ metadataPatch: decision.metadataPatch
38948
+ };
38924
38949
  }
38925
- } catch (err) {
38926
- console.warn(`[runtime-activity] \u4E0A\u62A5\u5F02\u5E38: tool=${input.toolName} status=${input.status} error=${err.message}`);
38927
38950
  }
38951
+ return { allow: true };
38928
38952
  }
38953
+ async function runAfterToolUseHooks(plugins, ctx) {
38954
+ for (const plugin of plugins) {
38955
+ if (plugin.afterToolUse) await plugin.afterToolUse(ctx);
38956
+ }
38957
+ }
38958
+ async function runToolUseErrorHooks(plugins, ctx) {
38959
+ for (const plugin of plugins) {
38960
+ if (plugin.onToolUseError) await plugin.onToolUseError(ctx);
38961
+ }
38962
+ }
38963
+
38964
+ // src/tools/UserRecoverableToolError.ts
38965
+ var UserRecoverableToolError = class extends Error {
38966
+ userMessage;
38967
+ code;
38968
+ constructor(code, userMessage2, detail) {
38969
+ super(detail ? `${code}: ${detail}` : code);
38970
+ this.name = "UserRecoverableToolError";
38971
+ this.code = code;
38972
+ this.userMessage = userMessage2;
38973
+ }
38974
+ };
38975
+ var isUserRecoverableToolError = (error) => error instanceof UserRecoverableToolError || typeof error === "object" && error !== null && error.name === "UserRecoverableToolError" && typeof error.userMessage === "string";
38929
38976
 
38930
38977
  // src/tools/ToolExecutor.ts
38931
- var createToolExecutor = (registry2) => {
38978
+ var createToolExecutor = (registry2, options = {}) => {
38979
+ const hookPlugins = sortToolHookPlugins(options.hookPlugins ?? []);
38980
+ const eventBus = options.eventBus ?? createRuntimeEventBus();
38932
38981
  return {
38933
38982
  async execute(name, input, userRequest) {
38934
38983
  const tool = registry2.get(name);
@@ -38940,45 +38989,84 @@ var createToolExecutor = (registry2) => {
38940
38989
  }
38941
38990
  }
38942
38991
  const toolCallId = typeof userRequest?.metadata?.toolCallId === "string" ? userRequest.metadata.toolCallId : null;
38943
- await reportRuntimeActivity({
38944
- kind: "tool_use",
38992
+ const startedAt = /* @__PURE__ */ new Date();
38993
+ const ctx = {
38945
38994
  toolName: name,
38946
- status: "started",
38947
38995
  toolCallId,
38948
- metadata: {
38949
- platform: userRequest?.platform,
38950
- requestId: userRequest?.requestId,
38951
- departmentAgentId: userRequest?.departmentAgentId
38952
- }
38996
+ input: input ?? {},
38997
+ userRequest,
38998
+ startedAt,
38999
+ metadata: requestContext(userRequest)
39000
+ };
39001
+ await eventBus.emit({
39002
+ eventId: runtimeEventId("toolUse.started", name, toolCallId, startedAt),
39003
+ type: "toolUse.started",
39004
+ occurredAt: startedAt.toISOString(),
39005
+ toolName: name,
39006
+ toolCallId,
39007
+ inputSummary: summarizeJson(ctx.input),
39008
+ requestContext: ctx.metadata
38953
39009
  });
39010
+ const preDecision = await runPreToolUseHooks(hookPlugins, ctx);
39011
+ if (preDecision.deny || preDecision.allow === false) {
39012
+ ctx.durationMs = Date.now() - startedAt.getTime();
39013
+ const reason = preDecision.reason ?? "tool_use_blocked";
39014
+ await eventBus.emit({
39015
+ eventId: runtimeEventId("toolUse.blocked", name, toolCallId, startedAt),
39016
+ type: "toolUse.blocked",
39017
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
39018
+ toolName: name,
39019
+ toolCallId,
39020
+ inputSummary: summarizeJson(ctx.input),
39021
+ durationMs: ctx.durationMs,
39022
+ errorSummary: reason,
39023
+ requestContext: ctx.metadata
39024
+ });
39025
+ throw new UserRecoverableToolError(
39026
+ "tool_use_blocked",
39027
+ preDecision.userMessage ?? "\u5F53\u524D\u5DE5\u5177\u8C03\u7528\u5DF2\u88AB\u7CFB\u7EDF\u7B56\u7565\u963B\u6B62\u3002",
39028
+ reason
39029
+ );
39030
+ }
38954
39031
  try {
38955
39032
  const result = await tool.execute(input ?? {}, userRequest);
38956
- await reportRuntimeActivity({
38957
- kind: "tool_use",
39033
+ ctx.resultText = result;
39034
+ ctx.durationMs = Date.now() - startedAt.getTime();
39035
+ await runAfterToolUseHooks(hookPlugins, ctx);
39036
+ await eventBus.emit({
39037
+ eventId: runtimeEventId("toolUse.completed", name, toolCallId, startedAt),
39038
+ type: "toolUse.completed",
39039
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
38958
39040
  toolName: name,
38959
- status: "completed",
38960
39041
  toolCallId,
38961
- metadata: {
38962
- platform: userRequest?.platform,
38963
- requestId: userRequest?.requestId,
38964
- departmentAgentId: userRequest?.departmentAgentId
38965
- }
39042
+ inputSummary: summarizeJson(ctx.input),
39043
+ durationMs: ctx.durationMs,
39044
+ resultSummary: summarizeText(result),
39045
+ requestContext: ctx.metadata
38966
39046
  });
38967
39047
  return result;
38968
39048
  } catch (error) {
38969
39049
  const err = error;
38970
- await reportRuntimeActivity({
38971
- kind: "tool_use",
39050
+ ctx.error = err;
39051
+ ctx.durationMs = Date.now() - startedAt.getTime();
39052
+ await runToolUseErrorHooks(hookPlugins, ctx);
39053
+ await eventBus.emit({
39054
+ eventId: runtimeEventId("toolUse.failed", name, toolCallId, startedAt),
39055
+ type: "toolUse.failed",
39056
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
38972
39057
  toolName: name,
38973
- status: "failed",
38974
39058
  toolCallId,
38975
- metadata: {
38976
- platform: userRequest?.platform,
38977
- requestId: userRequest?.requestId,
38978
- departmentAgentId: userRequest?.departmentAgentId,
39059
+ inputSummary: summarizeJson(ctx.input),
39060
+ durationMs: ctx.durationMs,
39061
+ errorSummary: summarizeText(err.message),
39062
+ requestContext: {
39063
+ ...ctx.metadata,
38979
39064
  error: err.message
38980
39065
  }
38981
39066
  });
39067
+ if (isUserRecoverableToolError(error)) {
39068
+ throw error;
39069
+ }
38982
39070
  return `\u5DE5\u5177\u6267\u884C\u5931\u8D25 [${name}], reason: ${err.message}`;
38983
39071
  }
38984
39072
  },
@@ -38989,6 +39077,23 @@ var createToolExecutor = (registry2) => {
38989
39077
  }
38990
39078
  };
38991
39079
  };
39080
+ function requestContext(userRequest) {
39081
+ return {
39082
+ platform: userRequest?.platform,
39083
+ requestId: userRequest?.requestId,
39084
+ departmentAgentId: userRequest?.departmentAgentId
39085
+ };
39086
+ }
39087
+ function summarizeJson(value, maxChars = 1e3) {
39088
+ return summarizeText(JSON.stringify(value ?? null), maxChars);
39089
+ }
39090
+ function summarizeText(value, maxChars = 1e3) {
39091
+ return value.length <= maxChars ? value : `${value.slice(0, maxChars)}...`;
39092
+ }
39093
+ function runtimeEventId(type, toolName, toolCallId, startedAt) {
39094
+ if (typeof import_node_crypto2.randomUUID === "function") return (0, import_node_crypto2.randomUUID)();
39095
+ return (0, import_node_crypto2.createHash)("sha256").update(type).update("\0").update(toolName).update("\0").update(toolCallId ?? "").update("\0").update(startedAt.toISOString()).digest("hex");
39096
+ }
38992
39097
 
38993
39098
  // src/tools/ToolRegistry.ts
38994
39099
  var createToolRegistry = () => {
@@ -40210,16 +40315,16 @@ var Diff = class {
40210
40315
  }
40211
40316
  }
40212
40317
  }
40213
- addToPath(path21, added, removed, oldPosInc, options) {
40214
- const last = path21.lastComponent;
40318
+ addToPath(path20, added, removed, oldPosInc, options) {
40319
+ const last = path20.lastComponent;
40215
40320
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
40216
40321
  return {
40217
- oldPos: path21.oldPos + oldPosInc,
40322
+ oldPos: path20.oldPos + oldPosInc,
40218
40323
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
40219
40324
  };
40220
40325
  } else {
40221
40326
  return {
40222
- oldPos: path21.oldPos + oldPosInc,
40327
+ oldPos: path20.oldPos + oldPosInc,
40223
40328
  lastComponent: { count: 1, added, removed, previousComponent: last }
40224
40329
  };
40225
40330
  }
@@ -41354,7 +41459,6 @@ var cronUpdate = {
41354
41459
 
41355
41460
  // src/tools/tools/ImageUnderstand.ts
41356
41461
  var import_fs9 = __toESM(require("fs"));
41357
- var import_path15 = __toESM(require("path"));
41358
41462
 
41359
41463
  // src/types/builders.ts
41360
41464
  var text = (text2) => ({
@@ -41394,7 +41498,7 @@ var isToolUseBlock = (block) => block.type === "tool_use";
41394
41498
  var extractText = (blocks) => blocks.filter(isTextBlock).map((b) => b.text).join("\n");
41395
41499
 
41396
41500
  // src/tools/tools/ImageUnderstandMetering.ts
41397
- var import_node_crypto2 = require("node:crypto");
41501
+ var import_node_crypto3 = require("node:crypto");
41398
41502
  var ImageUnderstandMeteringError = class extends Error {
41399
41503
  constructor(message, statusCode, meteringStatus) {
41400
41504
  super(message);
@@ -41484,7 +41588,7 @@ function inferImageProvider(baseUrl) {
41484
41588
  }
41485
41589
  }
41486
41590
  function fingerprintImageSource(imageSource) {
41487
- return (0, import_node_crypto2.createHash)("sha256").update(imageSource).digest("hex");
41591
+ return (0, import_node_crypto3.createHash)("sha256").update(imageSource).digest("hex");
41488
41592
  }
41489
41593
  function imageSourceKind(imageSource) {
41490
41594
  if (imageSource.startsWith("http://") || imageSource.startsWith("https://")) return "url";
@@ -41532,21 +41636,19 @@ var guessMediaTypeFromHeader = (contentType) => {
41532
41636
  if (contentType.includes("image/webp")) return "image/webp";
41533
41637
  return null;
41534
41638
  };
41535
- var guessMediaTypeFromExt = (filePath) => {
41536
- const ext = import_path15.default.extname(filePath).toLowerCase();
41537
- if (ext === ".jpg" || ext === ".jpeg") return "image/jpeg";
41538
- if (ext === ".png") return "image/png";
41539
- if (ext === ".gif") return "image/gif";
41540
- if (ext === ".webp") return "image/webp";
41541
- return null;
41542
- };
41543
41639
  var controlPlaneBaseUrl = () => {
41544
41640
  return process.env.DUCLAW_CONTROL_PLANE_BASE_URL?.replace(/\/$/, "");
41545
41641
  };
41642
+ var USER_IMAGE_REUPLOAD_MESSAGE = `\u8FD9\u5F20\u56FE\u7247\u6682\u65F6\u65E0\u6CD5\u6309\u56FE\u7247\u683C\u5F0F\u89E3\u6790\u3002\u8BF7\u91CD\u65B0\u53D1\u9001 JPG/PNG/WebP \u56FE\u7247\uFF0C\u6216\u8005\u5728\u624B\u673A\u4E0A\u622A\u56FE\u540E\u518D\u53D1\u4E00\u6B21\u3002`;
41643
+ var normalizeRuntimeAttachmentUrl = (input) => {
41644
+ return input.replace("/api/mobile/attachments/", "/internal/runtime/mobile/attachments/");
41645
+ };
41546
41646
  var resolveRemoteUrl = (input) => {
41547
- if (/^https?:\/\//i.test(input)) return input;
41647
+ if (/^https?:\/\//i.test(input)) return normalizeRuntimeAttachmentUrl(input);
41548
41648
  const baseUrl = controlPlaneBaseUrl();
41549
- if (baseUrl && input.startsWith("/internal/")) return `${baseUrl}${input}`;
41649
+ if (baseUrl && (input.startsWith("/internal/") || input.startsWith("/api/mobile/attachments/"))) {
41650
+ return `${baseUrl}${normalizeRuntimeAttachmentUrl(input)}`;
41651
+ }
41550
41652
  return void 0;
41551
41653
  };
41552
41654
  var shouldAttachRuntimeAuth = (url) => {
@@ -41558,6 +41660,20 @@ var shouldAttachRuntimeAuth = (url) => {
41558
41660
  return false;
41559
41661
  }
41560
41662
  };
41663
+ var unsupportedImageFormatError = (detail) => new UserRecoverableToolError("unsupported_image_format", USER_IMAGE_REUPLOAD_MESSAGE, detail);
41664
+ var imageBlockFromBuffer = (buffer, contentType, sourceHint) => {
41665
+ const base64Data = buffer.toString("base64");
41666
+ const mediaType = guessMediaTypeFromData(base64Data) ?? guessMediaTypeFromHeader(contentType);
41667
+ if (!mediaType) {
41668
+ throw unsupportedImageFormatError(`${sourceHint} content-type=${contentType || "unknown"}`);
41669
+ }
41670
+ console.log(`[ImageUnderstand] \u63A8\u65AD\u5A92\u4F53\u7C7B\u578B: ${mediaType} (content-type: ${contentType || "unknown"})`);
41671
+ return imageBase64(base64Data, mediaType);
41672
+ };
41673
+ var isUnsupportedProviderImageError = (error) => {
41674
+ const message = error instanceof Error ? error.message : String(error);
41675
+ return /unsupported image format|application\/octet-stream|invalid image/i.test(message);
41676
+ };
41561
41677
  var resolveImageBlock = async (input) => {
41562
41678
  const remoteUrl = resolveRemoteUrl(input);
41563
41679
  if (remoteUrl) {
@@ -41571,21 +41687,23 @@ var resolveImageBlock = async (input) => {
41571
41687
  if (!res.ok) throw new Error(`[ImageUnderstand] \u56FE\u7247\u4E0B\u8F7D\u5931\u8D25: ${res.status} ${res.statusText}`);
41572
41688
  const contentType = res.headers.get("content-type") || "";
41573
41689
  const buffer = Buffer.from(await res.arrayBuffer());
41574
- const base64Data = buffer.toString("base64");
41575
- const mediaType2 = guessMediaTypeFromData(base64Data) ?? guessMediaTypeFromHeader(contentType) ?? "image/png";
41576
- console.log(`[ImageUnderstand] \u63A8\u65AD\u5A92\u4F53\u7C7B\u578B: ${mediaType2} (content-type: ${contentType})`);
41577
- return imageBase64(base64Data, mediaType2);
41690
+ return imageBlockFromBuffer(buffer, contentType, remoteUrl);
41578
41691
  }
41579
41692
  if (input.startsWith("/") || input.startsWith(".") || /^[A-Za-z]:[\\/]/.test(input)) {
41580
41693
  if (!import_fs9.default.existsSync(input)) throw new Error(`[ImageUnderstand] \u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728: ${input}`);
41581
41694
  console.log(`[ImageUnderstand] \u8BFB\u53D6\u672C\u5730\u6587\u4EF6: ${input}`);
41582
41695
  const buffer = import_fs9.default.readFileSync(input);
41583
- const base64Data = buffer.toString("base64");
41584
- const mediaType2 = guessMediaTypeFromExt(input) ?? guessMediaTypeFromData(base64Data) ?? "image/png";
41696
+ const mediaType2 = guessMediaTypeFromData(buffer.toString("base64"));
41697
+ if (!mediaType2) {
41698
+ throw unsupportedImageFormatError(input);
41699
+ }
41585
41700
  console.log(`[ImageUnderstand] \u63A8\u65AD\u5A92\u4F53\u7C7B\u578B: ${mediaType2}`);
41586
- return imageBase64(base64Data, mediaType2);
41701
+ return imageBase64(buffer.toString("base64"), mediaType2);
41702
+ }
41703
+ const mediaType = guessMediaTypeFromData(input);
41704
+ if (!mediaType) {
41705
+ throw unsupportedImageFormatError("base64 data magic bytes not recognized");
41587
41706
  }
41588
- const mediaType = guessMediaTypeFromData(input) ?? "image/png";
41589
41707
  return imageBase64(input, mediaType);
41590
41708
  };
41591
41709
  var imageUnderstand = {
@@ -41632,7 +41750,12 @@ var imageUnderstand = {
41632
41750
  const response = await llmClient.chat(
41633
41751
  [imageMessage],
41634
41752
  system
41635
- );
41753
+ ).catch((error) => {
41754
+ if (isUnsupportedProviderImageError(error)) {
41755
+ throw unsupportedImageFormatError(error instanceof Error ? error.message : String(error));
41756
+ }
41757
+ throw error;
41758
+ });
41636
41759
  const resultText = extractText(response.content);
41637
41760
  await reportImageUnderstandUsage({
41638
41761
  baseUrl: process.env.DUCLAW_CONTROL_PLANE_BASE_URL,
@@ -41655,18 +41778,18 @@ var imageUnderstand = {
41655
41778
  // src/skill/SkillRegistry.ts
41656
41779
  var import_fs11 = require("fs");
41657
41780
  var import_os3 = require("os");
41658
- var import_path17 = __toESM(require("path"));
41781
+ var import_path16 = __toESM(require("path"));
41659
41782
 
41660
41783
  // src/runtime/paths.ts
41661
41784
  var import_fs10 = require("fs");
41662
- var import_path16 = __toESM(require("path"));
41785
+ var import_path15 = __toESM(require("path"));
41663
41786
  var findProjectRoot = (filename = "duclaw.json", startDir = process.cwd()) => {
41664
41787
  let currentDir = startDir;
41665
41788
  while (true) {
41666
- if ((0, import_fs10.existsSync)((0, import_path16.join)(currentDir, filename))) {
41789
+ if ((0, import_fs10.existsSync)((0, import_path15.join)(currentDir, filename))) {
41667
41790
  return currentDir;
41668
41791
  }
41669
- const parentDir = (0, import_path16.dirname)(currentDir);
41792
+ const parentDir = (0, import_path15.dirname)(currentDir);
41670
41793
  if (parentDir === currentDir) {
41671
41794
  return null;
41672
41795
  }
@@ -41675,12 +41798,12 @@ var findProjectRoot = (filename = "duclaw.json", startDir = process.cwd()) => {
41675
41798
  };
41676
41799
  var resolveCoreRoot = () => {
41677
41800
  const candidates = [
41678
- import_path16.default.resolve(__dirname_m, ".."),
41679
- import_path16.default.resolve(__dirname_m, "..", ".."),
41801
+ import_path15.default.resolve(__dirname_m, ".."),
41802
+ import_path15.default.resolve(__dirname_m, "..", ".."),
41680
41803
  process.cwd()
41681
41804
  ];
41682
41805
  for (const candidate of candidates) {
41683
- if ((0, import_fs10.existsSync)(import_path16.default.join(candidate, "web", "dist", "index.html"))) {
41806
+ if ((0, import_fs10.existsSync)(import_path15.default.join(candidate, "web", "dist", "index.html"))) {
41684
41807
  return candidate;
41685
41808
  }
41686
41809
  }
@@ -41689,11 +41812,11 @@ var resolveCoreRoot = () => {
41689
41812
  var resolveWebDistRoot = () => {
41690
41813
  const coreRoot = resolveCoreRoot();
41691
41814
  const candidates = [
41692
- import_path16.default.join(coreRoot, "dist", "web"),
41693
- import_path16.default.join(coreRoot, "web", "dist")
41815
+ import_path15.default.join(coreRoot, "dist", "web"),
41816
+ import_path15.default.join(coreRoot, "web", "dist")
41694
41817
  ];
41695
41818
  for (const candidate of candidates) {
41696
- if ((0, import_fs10.existsSync)(import_path16.default.join(candidate, "index.html"))) {
41819
+ if ((0, import_fs10.existsSync)(import_path15.default.join(candidate, "index.html"))) {
41697
41820
  return candidate;
41698
41821
  }
41699
41822
  }
@@ -41703,14 +41826,14 @@ var resolveWebDistRoot = () => {
41703
41826
  // src/skill/SkillRegistry.ts
41704
41827
  var getProjectSkillsPath = () => {
41705
41828
  const projectRoot = findProjectRoot();
41706
- return projectRoot ? (0, import_path17.join)(projectRoot, "skills") : null;
41829
+ return projectRoot ? (0, import_path16.join)(projectRoot, "skills") : null;
41707
41830
  };
41708
41831
  var getSkillPaths = () => {
41709
41832
  const paths = [];
41710
41833
  const seenPaths = /* @__PURE__ */ new Set();
41711
41834
  const pushPath = (candidate) => {
41712
41835
  if (!(0, import_fs11.existsSync)(candidate) || !(0, import_fs11.statSync)(candidate).isDirectory()) return;
41713
- const normalized = import_path17.default.resolve(candidate);
41836
+ const normalized = import_path16.default.resolve(candidate);
41714
41837
  if (seenPaths.has(normalized)) return;
41715
41838
  seenPaths.add(normalized);
41716
41839
  paths.push(normalized);
@@ -41719,12 +41842,12 @@ var getSkillPaths = () => {
41719
41842
  if (projectSkillsPath) {
41720
41843
  pushPath(projectSkillsPath);
41721
41844
  }
41722
- pushPath((0, import_path17.join)((0, import_os3.homedir)(), ".duclaw", "skills"));
41723
- pushPath((0, import_path17.join)((0, import_os3.homedir)(), ".agents", "skills"));
41845
+ pushPath((0, import_path16.join)((0, import_os3.homedir)(), ".duclaw", "skills"));
41846
+ pushPath((0, import_path16.join)((0, import_os3.homedir)(), ".agents", "skills"));
41724
41847
  return paths;
41725
41848
  };
41726
41849
  var getDirectories = (dirPath) => {
41727
- return (0, import_fs11.readdirSync)(dirPath).filter((name) => (0, import_fs11.statSync)((0, import_path17.join)(dirPath, name)).isDirectory());
41850
+ return (0, import_fs11.readdirSync)(dirPath).filter((name) => (0, import_fs11.statSync)((0, import_path16.join)(dirPath, name)).isDirectory());
41728
41851
  };
41729
41852
  var parseSkill = (mdPath, skillDir) => {
41730
41853
  if (!(0, import_fs11.existsSync)(mdPath)) return null;
@@ -41744,14 +41867,14 @@ var parseSkill = (mdPath, skillDir) => {
41744
41867
  }
41745
41868
  }
41746
41869
  if (!name) {
41747
- name = import_path17.default.basename(import_path17.default.dirname(mdPath));
41870
+ name = import_path16.default.basename(import_path16.default.dirname(mdPath));
41748
41871
  }
41749
41872
  if (!description && body) {
41750
41873
  description = body.split("\n")[0].replace(/^#+\s*/, "").trim();
41751
41874
  }
41752
41875
  const projectSkillsPath = getProjectSkillsPath();
41753
- const normalizedSkillDir = import_path17.default.resolve(skillDir);
41754
- const deletable = projectSkillsPath ? normalizedSkillDir === import_path17.default.resolve(projectSkillsPath, import_path17.default.basename(normalizedSkillDir)) && normalizedSkillDir.startsWith(import_path17.default.resolve(projectSkillsPath) + import_path17.default.sep) : false;
41876
+ const normalizedSkillDir = import_path16.default.resolve(skillDir);
41877
+ const deletable = projectSkillsPath ? normalizedSkillDir === import_path16.default.resolve(projectSkillsPath, import_path16.default.basename(normalizedSkillDir)) && normalizedSkillDir.startsWith(import_path16.default.resolve(projectSkillsPath) + import_path16.default.sep) : false;
41755
41878
  return {
41756
41879
  name,
41757
41880
  description,
@@ -41773,8 +41896,8 @@ var loadSkill = () => {
41773
41896
  for (const skillPath of skillPaths) {
41774
41897
  const dirs = getDirectories(skillPath);
41775
41898
  for (const skillName of dirs) {
41776
- const eachSkillPath = (0, import_path17.join)(skillPath, skillName);
41777
- const eachSkillMdPath = (0, import_path17.join)(eachSkillPath, "SKILL.md");
41899
+ const eachSkillPath = (0, import_path16.join)(skillPath, skillName);
41900
+ const eachSkillMdPath = (0, import_path16.join)(eachSkillPath, "SKILL.md");
41778
41901
  const skill = parseSkill(eachSkillMdPath, eachSkillPath);
41779
41902
  if (skill && !seen.has(skill.name)) {
41780
41903
  seen.add(skill.name);
@@ -42075,10 +42198,10 @@ var goalDelete = {
42075
42198
  };
42076
42199
 
42077
42200
  // src/tools/tools/department/DepartmentCreate.ts
42078
- var import_node_crypto7 = require("node:crypto");
42201
+ var import_node_crypto8 = require("node:crypto");
42079
42202
 
42080
42203
  // src/department/mailbox/mailbox.ts
42081
- var import_node_crypto6 = require("node:crypto");
42204
+ var import_node_crypto7 = require("node:crypto");
42082
42205
 
42083
42206
  // src/agent/interruptRegistry.ts
42084
42207
  var registry = /* @__PURE__ */ new Map();
@@ -42129,7 +42252,7 @@ var drainInterrupts = (userId) => {
42129
42252
  };
42130
42253
 
42131
42254
  // src/agent/events.ts
42132
- var import_node_crypto3 = require("node:crypto");
42255
+ var import_node_crypto4 = require("node:crypto");
42133
42256
  var rowToEvent = (row) => ({
42134
42257
  id: row.id,
42135
42258
  userId: row.userId,
@@ -42146,7 +42269,7 @@ var rowToEvent = (row) => ({
42146
42269
  var recordAgentEvent = (input) => {
42147
42270
  const db3 = createSqliteDB();
42148
42271
  const now = Date.now();
42149
- const id = `evt_${(0, import_node_crypto3.randomUUID)().slice(0, 12)}`;
42272
+ const id = `evt_${(0, import_node_crypto4.randomUUID)().slice(0, 12)}`;
42150
42273
  const payloadJson = JSON.stringify(input.payload);
42151
42274
  db3.prepare(`
42152
42275
  INSERT INTO agent_events (
@@ -42277,7 +42400,7 @@ ${ceoFollowupInstruction}
42277
42400
  };
42278
42401
 
42279
42402
  // src/department/mailbox/events.ts
42280
- var import_node_crypto4 = require("node:crypto");
42403
+ var import_node_crypto5 = require("node:crypto");
42281
42404
  var parseDetail = (detailJson) => {
42282
42405
  if (!detailJson) return void 0;
42283
42406
  try {
@@ -42318,7 +42441,7 @@ var mapMailboxEventRow = (row) => {
42318
42441
  var recordMailboxEvent = (input) => {
42319
42442
  const db3 = createSqliteDB();
42320
42443
  const event = {
42321
- id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
42444
+ id: (0, import_node_crypto5.randomUUID)().slice(0, 12),
42322
42445
  messageId: input.messageId,
42323
42446
  mailboxId: input.mailboxId,
42324
42447
  actorMailboxId: input.actorMailboxId,
@@ -42402,29 +42525,29 @@ var listMailboxEvents = (params) => {
42402
42525
 
42403
42526
  // src/department/DepartmentMember.ts
42404
42527
  var import_fs13 = require("fs");
42405
- var import_path19 = __toESM(require("path"));
42528
+ var import_path18 = __toESM(require("path"));
42406
42529
 
42407
42530
  // src/department/Department.ts
42408
- var import_path18 = __toESM(require("path"));
42531
+ var import_path17 = __toESM(require("path"));
42409
42532
  var import_fs12 = require("fs");
42410
42533
  var legacyMigrationChecked = false;
42411
42534
  var getDepartmentBaseDir = () => {
42412
- return import_path18.default.join(getDuclawHomeDir(), "department");
42535
+ return import_path17.default.join(getDuclawHomeDir(), "department");
42413
42536
  };
42414
42537
  var getLegacyTeamBaseDir = () => {
42415
- return import_path18.default.join(getDuclawHomeDir(), "team");
42538
+ return import_path17.default.join(getDuclawHomeDir(), "team");
42416
42539
  };
42417
42540
  var getDepartmentWorkSpaceDir = (departmentName) => {
42418
- return import_path18.default.join(getDepartmentBaseDir(), "workspace", departmentName);
42541
+ return import_path17.default.join(getDepartmentBaseDir(), "workspace", departmentName);
42419
42542
  };
42420
42543
  var getLegacyTeamWorkSpaceDir = (teamName) => {
42421
- return import_path18.default.join(getLegacyTeamBaseDir(), "workspace", teamName);
42544
+ return import_path17.default.join(getLegacyTeamBaseDir(), "workspace", teamName);
42422
42545
  };
42423
42546
  var getDepartmentJsonPath = (departmentName) => {
42424
- return import_path18.default.join(getDepartmentWorkSpaceDir(departmentName), "department.json");
42547
+ return import_path17.default.join(getDepartmentWorkSpaceDir(departmentName), "department.json");
42425
42548
  };
42426
42549
  var getLegacyTeamJsonPath = (teamName) => {
42427
- return import_path18.default.join(getLegacyTeamWorkSpaceDir(teamName), "team.json");
42550
+ return import_path17.default.join(getLegacyTeamWorkSpaceDir(teamName), "team.json");
42428
42551
  };
42429
42552
  var mapLegacyRole = (role) => {
42430
42553
  return role === "team_manager" ? "department_head" : "executor";
@@ -42453,7 +42576,7 @@ var mapLegacyDepartment = (legacy) => {
42453
42576
  var migrateLegacyTeamsToDepartments = () => {
42454
42577
  if (legacyMigrationChecked) return;
42455
42578
  legacyMigrationChecked = true;
42456
- const legacyWorkspaceDir = import_path18.default.join(getLegacyTeamBaseDir(), "workspace");
42579
+ const legacyWorkspaceDir = import_path17.default.join(getLegacyTeamBaseDir(), "workspace");
42457
42580
  if (!(0, import_fs12.existsSync)(legacyWorkspaceDir)) return;
42458
42581
  for (const legacyName of (0, import_fs12.readdirSync)(legacyWorkspaceDir)) {
42459
42582
  const legacyJsonPath = getLegacyTeamJsonPath(legacyName);
@@ -42486,7 +42609,7 @@ var getDepartment = (name) => {
42486
42609
  };
42487
42610
  var listDepartments = () => {
42488
42611
  migrateLegacyTeamsToDepartments();
42489
- const workspaceDir = import_path18.default.join(getDepartmentBaseDir(), "workspace");
42612
+ const workspaceDir = import_path17.default.join(getDepartmentBaseDir(), "workspace");
42490
42613
  if (!(0, import_fs12.existsSync)(workspaceDir)) return [];
42491
42614
  const departments = [];
42492
42615
  for (const departmentName of (0, import_fs12.readdirSync)(workspaceDir)) {
@@ -42531,7 +42654,7 @@ var createDepartmentMember = (departmentMemberDefinition) => {
42531
42654
  const { name, departmentId, workspaceId } = departmentMemberDefinition;
42532
42655
  const department = getDepartmentById(departmentId);
42533
42656
  if (!department) throw new Error(`[createDepartmentMember] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentId}`);
42534
- const memberPath = import_path19.default.join(getDepartmentWorkSpaceDir(department.name), name);
42657
+ const memberPath = import_path18.default.join(getDepartmentWorkSpaceDir(department.name), name);
42535
42658
  (0, import_fs13.mkdirSync)(memberPath, { recursive: true });
42536
42659
  const workspace = {
42537
42660
  id: getWorkspaceId(department.name, departmentMemberDefinition.name),
@@ -42602,7 +42725,7 @@ var deleteDepartmentMemberById = (departmentName, memberId) => {
42602
42725
  };
42603
42726
 
42604
42727
  // src/department/mailbox/ceoFollowup.ts
42605
- var import_node_crypto5 = require("node:crypto");
42728
+ var import_node_crypto6 = require("node:crypto");
42606
42729
  var rowToFollowup = (row) => ({
42607
42730
  id: row.id,
42608
42731
  sourceMessageId: row.sourceMessageId,
@@ -42649,7 +42772,7 @@ var enqueueCeoFollowupFromMailbox = (message) => {
42649
42772
  if (!message.originUserId || !message.originPlatform) return null;
42650
42773
  const db3 = createSqliteDB();
42651
42774
  const now = Date.now();
42652
- const id = `cfu_${(0, import_node_crypto5.randomUUID)().slice(0, 12)}`;
42775
+ const id = `cfu_${(0, import_node_crypto6.randomUUID)().slice(0, 12)}`;
42653
42776
  db3.prepare(`
42654
42777
  INSERT INTO ceo_followups (
42655
42778
  id,
@@ -42979,7 +43102,7 @@ var recordMailboxReceivedAgentEvent = (msg) => {
42979
43102
  };
42980
43103
  var sendMessage2 = (fromMailboxId, toMailboxId, content, options) => {
42981
43104
  const db3 = createSqliteDB();
42982
- const id = (0, import_node_crypto6.randomUUID)().slice(0, 8);
43105
+ const id = (0, import_node_crypto7.randomUUID)().slice(0, 8);
42983
43106
  const threadId = options?.threadId || id;
42984
43107
  const workItemContext = resolveWorkItemContext(fromMailboxId, toMailboxId, id, options);
42985
43108
  const stmt = db3.prepare(`insert into mailbox (
@@ -43122,7 +43245,7 @@ var departmentCreate = {
43122
43245
  return `[departmentCreate] \u4E0D\u5B58\u5728 id=${sourceGoalId} \u7684\u76EE\u6807`;
43123
43246
  }
43124
43247
  let departmentDefinition = {
43125
- id: (0, import_node_crypto7.randomUUID)().slice(0, 8),
43248
+ id: (0, import_node_crypto8.randomUUID)().slice(0, 8),
43126
43249
  name,
43127
43250
  charter,
43128
43251
  sourceGoalId,
@@ -43389,7 +43512,7 @@ var departmentList = {
43389
43512
  };
43390
43513
 
43391
43514
  // src/tools/tools/department/DepartmentMemberCreate.ts
43392
- var import_node_crypto8 = require("node:crypto");
43515
+ var import_node_crypto9 = require("node:crypto");
43393
43516
  var DESCRIPTION24 = `
43394
43517
  \u521B\u5EFA\u90E8\u95E8\u6210\u5458\u3002
43395
43518
 
@@ -43455,7 +43578,7 @@ var departmentMemberCreate = {
43455
43578
  }
43456
43579
  }
43457
43580
  let departmentMember = {
43458
- id: (0, import_node_crypto8.randomUUID)().slice(0, 8),
43581
+ id: (0, import_node_crypto9.randomUUID)().slice(0, 8),
43459
43582
  name,
43460
43583
  departmentId: department.id,
43461
43584
  mailBoxId: getMailBoxId(department.name, name),
@@ -43646,7 +43769,7 @@ ${replies}`;
43646
43769
  // src/department/learning.ts
43647
43770
  var import_node_fs4 = require("node:fs");
43648
43771
  var import_node_path13 = __toESM(require("node:path"));
43649
- var import_node_crypto9 = require("node:crypto");
43772
+ var import_node_crypto10 = require("node:crypto");
43650
43773
 
43651
43774
  // src/skill/SkillValidator.ts
43652
43775
  var import_node_fs3 = require("node:fs");
@@ -43884,7 +44007,7 @@ var listDepartmentMemories = (departmentName) => {
43884
44007
  var createDepartmentMemory = (departmentName, input) => {
43885
44008
  const now = Date.now();
43886
44009
  const memory = {
43887
- id: (0, import_node_crypto9.randomUUID)().slice(0, 8),
44010
+ id: (0, import_node_crypto10.randomUUID)().slice(0, 8),
43888
44011
  departmentName,
43889
44012
  title: input.title,
43890
44013
  content: input.content,
@@ -43935,7 +44058,7 @@ ${formatSkillValidationIssues(validation)}`);
43935
44058
  }
43936
44059
  const now = Date.now();
43937
44060
  const skill = {
43938
- id: (0, import_node_crypto9.randomUUID)().slice(0, 8),
44061
+ id: (0, import_node_crypto10.randomUUID)().slice(0, 8),
43939
44062
  departmentName,
43940
44063
  skillName: input.skillName,
43941
44064
  description: input.description,
@@ -43987,7 +44110,7 @@ var createDepartmentProposal = (input) => {
43987
44110
  const records = readJsonArray(proposalsPath());
43988
44111
  const proposal = {
43989
44112
  ...input,
43990
- id: (0, import_node_crypto9.randomUUID)().slice(0, 8),
44113
+ id: (0, import_node_crypto10.randomUUID)().slice(0, 8),
43991
44114
  status: "pending",
43992
44115
  createdAt: Date.now()
43993
44116
  };
@@ -44322,7 +44445,7 @@ var mailboxFollowup = {
44322
44445
 
44323
44446
  // src/tools/tools/Bash.ts
44324
44447
  var import_node_child_process = require("node:child_process");
44325
- var import_node_crypto10 = require("node:crypto");
44448
+ var import_node_crypto11 = require("node:crypto");
44326
44449
  var import_node_fs5 = require("node:fs");
44327
44450
  var DESCRIPTION29 = `\u5728\u7CFB\u7EDF shell \u4E2D\u6267\u884C\u547D\u4EE4\u3002
44328
44451
 
@@ -44526,7 +44649,7 @@ var bashTool = {
44526
44649
  ...options,
44527
44650
  stdio: ["pipe", "pipe", "pipe"]
44528
44651
  });
44529
- const id = (0, import_node_crypto10.randomUUID)().slice(0, 8);
44652
+ const id = (0, import_node_crypto11.randomUUID)().slice(0, 8);
44530
44653
  const session = {
44531
44654
  id,
44532
44655
  command,
@@ -44624,10 +44747,183 @@ var sendFile = {
44624
44747
  }
44625
44748
  };
44626
44749
 
44750
+ // src/runtime/activity.ts
44751
+ async function reportRuntimeActivity(input) {
44752
+ const baseUrl = process.env.DUCLAW_CONTROL_PLANE_BASE_URL?.replace(/\/$/, "");
44753
+ const token = process.env.DUCLAW_CONTROL_PLANE_METERING_TOKEN;
44754
+ const tenantId = process.env.DUCLAW_TENANT_ID;
44755
+ if (!baseUrl || !token || !tenantId) return;
44756
+ try {
44757
+ const response = await fetch(`${baseUrl}/internal/runtime/activity`, {
44758
+ method: "POST",
44759
+ signal: AbortSignal.timeout(2500),
44760
+ headers: {
44761
+ authorization: `Bearer ${token}`,
44762
+ "content-type": "application/json"
44763
+ },
44764
+ body: JSON.stringify({
44765
+ tenantId,
44766
+ kind: input.kind,
44767
+ status: input.status,
44768
+ toolName: input.toolName,
44769
+ toolCallId: input.toolCallId ?? null,
44770
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
44771
+ metadata: input.metadata ?? {}
44772
+ })
44773
+ });
44774
+ if (!response.ok) {
44775
+ console.warn(`[runtime-activity] \u4E0A\u62A5\u5931\u8D25: tool=${input.toolName} status=${input.status} http=${response.status}`);
44776
+ }
44777
+ } catch (err) {
44778
+ console.warn(`[runtime-activity] \u4E0A\u62A5\u5F02\u5E38: tool=${input.toolName} status=${input.status} error=${err.message}`);
44779
+ }
44780
+ }
44781
+
44782
+ // src/runtime/plugins/activityToolHook.ts
44783
+ var createRuntimeActivityToolHookPlugin = () => ({
44784
+ id: "runtime-activity",
44785
+ priority: 0,
44786
+ async preToolUse(ctx) {
44787
+ await reportRuntimeActivity({
44788
+ kind: "tool_use",
44789
+ toolName: ctx.toolName,
44790
+ status: "started",
44791
+ toolCallId: ctx.toolCallId,
44792
+ metadata: activityMetadata(ctx)
44793
+ });
44794
+ },
44795
+ async afterToolUse(ctx) {
44796
+ await reportRuntimeActivity({
44797
+ kind: "tool_use",
44798
+ toolName: ctx.toolName,
44799
+ status: "completed",
44800
+ toolCallId: ctx.toolCallId,
44801
+ metadata: activityMetadata(ctx)
44802
+ });
44803
+ },
44804
+ async onToolUseError(ctx) {
44805
+ await reportRuntimeActivity({
44806
+ kind: "tool_use",
44807
+ toolName: ctx.toolName,
44808
+ status: "failed",
44809
+ toolCallId: ctx.toolCallId,
44810
+ metadata: {
44811
+ ...activityMetadata(ctx),
44812
+ error: ctx.error?.message
44813
+ }
44814
+ });
44815
+ }
44816
+ });
44817
+ function activityMetadata(ctx) {
44818
+ return {
44819
+ platform: ctx.userRequest?.platform,
44820
+ requestId: ctx.userRequest?.requestId,
44821
+ departmentAgentId: ctx.userRequest?.departmentAgentId
44822
+ };
44823
+ }
44824
+
44825
+ // src/runtime/plugins/saasCreditToolHook.ts
44826
+ var DEFAULT_WEB_SEARCH_NUM_RESULTS = 8;
44827
+ var createSaasCreditToolHookPlugin = () => ({
44828
+ id: "saas-credit",
44829
+ priority: 100,
44830
+ async afterToolUse(ctx) {
44831
+ const usage = meteredToolUsage(ctx);
44832
+ if (!usage) return;
44833
+ const baseUrl = process.env.DUCLAW_CONTROL_PLANE_BASE_URL?.replace(/\/$/, "");
44834
+ const token = process.env.DUCLAW_CONTROL_PLANE_METERING_TOKEN;
44835
+ const tenantId = process.env.DUCLAW_TENANT_ID;
44836
+ if (!baseUrl || !token || !tenantId) {
44837
+ if (process.env.NODE_ENV === "production" || process.env.DUCLAW_RUNTIME_PROVIDER) {
44838
+ throw new Error("[saas-credit] runtime metering is not configured");
44839
+ }
44840
+ return;
44841
+ }
44842
+ const response = await fetch(`${baseUrl}/internal/metering/tool-usage`, {
44843
+ method: "POST",
44844
+ signal: AbortSignal.timeout(5e3),
44845
+ headers: {
44846
+ authorization: `Bearer ${token}`,
44847
+ "content-type": "application/json"
44848
+ },
44849
+ body: JSON.stringify({
44850
+ tenantId,
44851
+ toolName: ctx.toolName,
44852
+ toolCallId: ctx.toolCallId,
44853
+ requestId: ctx.userRequest?.requestId ?? null,
44854
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
44855
+ ...usage,
44856
+ metadata: {
44857
+ platform: ctx.userRequest?.platform ?? null,
44858
+ departmentAgentId: ctx.userRequest?.departmentAgentId ?? null,
44859
+ input: sanitizedWebSearchInput(ctx.input)
44860
+ }
44861
+ })
44862
+ });
44863
+ const body = await parseJson2(response);
44864
+ const status = body?.result?.status;
44865
+ if (response.status === 402 || status === "credit_exhausted") {
44866
+ throw new UserRecoverableToolError(
44867
+ "credit_exhausted",
44868
+ "Credit \u4F59\u989D\u4E0D\u8DB3\uFF0C\u65E0\u6CD5\u5B8C\u6210\u672C\u6B21\u7F51\u9875\u641C\u7D22\u3002\u8BF7\u5148\u5145\u503C\u6216\u4F7F\u7528\u6FC0\u6D3B\u7801\u589E\u52A0 Credit\u3002",
44869
+ `[saas-credit] ${ctx.toolName} credit exhausted`
44870
+ );
44871
+ }
44872
+ if (!response.ok || status === "failed") {
44873
+ throw new Error(`[saas-credit] tool metering failed: ${body?.error ?? body?.message ?? status ?? response.status}`);
44874
+ }
44875
+ }
44876
+ });
44877
+ function meteredToolUsage(ctx) {
44878
+ if (ctx.toolName !== "websearch") return null;
44879
+ if (isWebSearchErrorResult(ctx.resultText)) return null;
44880
+ return {
44881
+ meterType: "web.content_retrieval",
44882
+ provider: "exa",
44883
+ unit: "content",
44884
+ quantity: normalizeNumResults(ctx.input.numResults)
44885
+ };
44886
+ }
44887
+ function normalizeNumResults(value) {
44888
+ if (typeof value !== "number" || !Number.isFinite(value)) return DEFAULT_WEB_SEARCH_NUM_RESULTS;
44889
+ return Math.max(1, Math.floor(value));
44890
+ }
44891
+ function isWebSearchErrorResult(result) {
44892
+ if (!result) return true;
44893
+ return /Web search (请求失败|请求超时|执行失败)|未找到搜索结果/.test(result);
44894
+ }
44895
+ function sanitizedWebSearchInput(input) {
44896
+ return {
44897
+ query: typeof input.query === "string" ? input.query.slice(0, 500) : null,
44898
+ numResults: normalizeNumResults(input.numResults),
44899
+ livecrawl: typeof input.livecrawl === "string" ? input.livecrawl : null,
44900
+ type: typeof input.type === "string" ? input.type : null,
44901
+ contextMaxCharacters: typeof input.contextMaxCharacters === "number" ? input.contextMaxCharacters : null
44902
+ };
44903
+ }
44904
+ async function parseJson2(response) {
44905
+ try {
44906
+ return await response.json();
44907
+ } catch {
44908
+ return null;
44909
+ }
44910
+ }
44911
+
44912
+ // src/runtime/plugins/index.ts
44913
+ function createDefaultToolHookPlugins(extra = []) {
44914
+ return [
44915
+ createSaasCreditToolHookPlugin(),
44916
+ createRuntimeActivityToolHookPlugin(),
44917
+ ...extra
44918
+ ];
44919
+ }
44920
+
44627
44921
  // src/tools/index.ts
44628
- var createDefaultTools = (bg) => {
44922
+ var createDefaultTools = (bg, hookPlugins = []) => {
44629
44923
  const registry2 = createToolRegistry();
44630
- const executor = createToolExecutor(registry2);
44924
+ const executor = createToolExecutor(registry2, {
44925
+ hookPlugins: createDefaultToolHookPlugins(hookPlugins)
44926
+ });
44631
44927
  registerTool(registry2, dateTool);
44632
44928
  registerTool(registry2, bashTool);
44633
44929
  registerTool(registry2, globTool);
@@ -45107,7 +45403,7 @@ var readDreamHistoryLimit = () => {
45107
45403
  var import_node_fs6 = require("node:fs");
45108
45404
  var import_node_os2 = require("node:os");
45109
45405
  var import_node_path14 = require("node:path");
45110
- var import_node_crypto11 = require("node:crypto");
45406
+ var import_node_crypto12 = require("node:crypto");
45111
45407
  var SkillForgeEngine = class {
45112
45408
  proposalStorage;
45113
45409
  draftRoot;
@@ -45141,7 +45437,7 @@ ${formatSkillValidationIssues(validation)}`);
45141
45437
  if (pending.some((p) => p.skillName === skillName)) {
45142
45438
  return null;
45143
45439
  }
45144
- const id = (0, import_node_crypto11.randomBytes)(4).toString("hex");
45440
+ const id = (0, import_node_crypto12.randomBytes)(4).toString("hex");
45145
45441
  const draftDir = (0, import_node_path14.join)(this.draftRoot, userId, id);
45146
45442
  (0, import_node_fs6.mkdirSync)(draftDir, { recursive: true });
45147
45443
  (0, import_node_fs6.writeFileSync)((0, import_node_path14.join)(draftDir, "SKILL.md"), skillMd, "utf-8");
@@ -45423,7 +45719,7 @@ var skillForgeDrop = (engine) => ({
45423
45719
  });
45424
45720
 
45425
45721
  // src/memory/MemoryEngine.ts
45426
- var import_node_crypto12 = require("node:crypto");
45722
+ var import_node_crypto13 = require("node:crypto");
45427
45723
  var MemoryEngine = class {
45428
45724
  storage;
45429
45725
  recallIndexStorage;
@@ -45451,7 +45747,7 @@ var MemoryEngine = class {
45451
45747
  }
45452
45748
  const now = Date.now();
45453
45749
  const memory = {
45454
- id: (0, import_node_crypto12.randomBytes)(4).toString("hex"),
45750
+ id: (0, import_node_crypto13.randomBytes)(4).toString("hex"),
45455
45751
  userId,
45456
45752
  title,
45457
45753
  content,
@@ -46103,13 +46399,13 @@ var COMPANY_VALUES_PROMPT = `<\u516C\u53F8\u5171\u540C\u4FE1\u5FF5>
46103
46399
  </\u516C\u53F8\u5171\u540C\u4FE1\u5FF5>`;
46104
46400
 
46105
46401
  // src/agent/outboundDedup.ts
46106
- var import_node_crypto13 = require("node:crypto");
46402
+ var import_node_crypto14 = require("node:crypto");
46107
46403
  var DEFAULT_WINDOW_MS = 15e3;
46108
46404
  var recentSends = /* @__PURE__ */ new Map();
46109
46405
  var lastSweepAt = 0;
46110
46406
  var normalize3 = (text2) => text2.replace(/\s+/g, " ").trim();
46111
46407
  var keyFor = (userId, normalized) => {
46112
- const hash = (0, import_node_crypto13.createHash)("sha1").update(normalized).digest("hex");
46408
+ const hash = (0, import_node_crypto14.createHash)("sha1").update(normalized).digest("hex");
46113
46409
  return `${userId}::${hash}`;
46114
46410
  };
46115
46411
  var sweep = (now, windowMs) => {
@@ -46147,7 +46443,7 @@ var isAbortError2 = (error) => {
46147
46443
  return error.name === "AbortError" || error.message.includes("aborted") || error.message.includes("AbortError");
46148
46444
  };
46149
46445
  var llmRequestIdForTurn = (request, messages, system, tools) => {
46150
- const hash = (0, import_node_crypto14.createHash)("sha256").update(request.requestId).update("\0").update(system).update("\0").update(JSON.stringify(messages)).update("\0").update(JSON.stringify(tools.map((tool) => tool.name).sort())).digest("hex").slice(0, 40);
46446
+ const hash = (0, import_node_crypto15.createHash)("sha256").update(request.requestId).update("\0").update(system).update("\0").update(JSON.stringify(messages)).update("\0").update(JSON.stringify(tools.map((tool) => tool.name).sort())).digest("hex").slice(0, 40);
46151
46447
  return `dreq_${hash}`;
46152
46448
  };
46153
46449
  var getDefaultAgentConfig = (tools, systemPrompt) => {
@@ -46342,7 +46638,9 @@ ${getSkillMeta()}
46342
46638
  } else {
46343
46639
  finalTools = tools;
46344
46640
  const toolRegistry = createToolRegistry();
46345
- const executor = createToolExecutor(toolRegistry);
46641
+ const executor = createToolExecutor(toolRegistry, {
46642
+ hookPlugins: createDefaultToolHookPlugins()
46643
+ });
46346
46644
  for (let tool of finalTools) {
46347
46645
  registerTool(toolRegistry, tool);
46348
46646
  }
@@ -46723,6 +47021,7 @@ ${memoryInjection}` : "") + dreamInjection;
46723
47021
  if (toolUses.length > 0) {
46724
47022
  await addMessage(storage, userId, assistantMessageFromResponse(response), beijingTime, job?.title);
46725
47023
  if (toolExecutor) {
47024
+ const userRecoverableMessages = [];
46726
47025
  const toolResultPromises = toolUses.map(async (useBlock) => {
46727
47026
  if (signal.aborted) {
46728
47027
  return toolResult(useBlock.id, `\u5DE5\u5177\u6267\u884C\u88AB\u4E2D\u65AD`);
@@ -46779,6 +47078,10 @@ ${memoryInjection}` : "") + dreamInjection;
46779
47078
  return toolResult(useBlock.id, result);
46780
47079
  } catch (error) {
46781
47080
  const err = error;
47081
+ if (isUserRecoverableToolError(error)) {
47082
+ userRecoverableMessages.push(error.userMessage);
47083
+ return toolResult(useBlock.id, `${useBlock.name}\u5DE5\u5177\u9700\u8981\u7528\u6237\u8865\u5145\u8F93\u5165,reason: ${err.message}`);
47084
+ }
46782
47085
  return toolResult(useBlock.id, `${useBlock.name}\u5DE5\u5177\u6267\u884C\u9519\u8BEF,reason: ${err.message}`);
46783
47086
  }
46784
47087
  });
@@ -46786,6 +47089,30 @@ ${memoryInjection}` : "") + dreamInjection;
46786
47089
  if (toolResults.length > 0) {
46787
47090
  await addMessage(storage, userId, { role: "user", content: toolResults }, beijingTime, job?.title);
46788
47091
  }
47092
+ const userRecoverableMessage = userRecoverableMessages[0]?.trim();
47093
+ if (userRecoverableMessage) {
47094
+ let recoverableMessageSent = false;
47095
+ if (config2.channelPlugin && !internalOnly) {
47096
+ if (claimOutboundSend(request.userId, userRecoverableMessage)) {
47097
+ await config2.channelPlugin.outbound.sendText({
47098
+ cfg: {},
47099
+ to: request.userId,
47100
+ text: userRecoverableMessage,
47101
+ accountId: request.requestId,
47102
+ metadata: request.metadata
47103
+ });
47104
+ recoverableMessageSent = true;
47105
+ } else {
47106
+ console.log(`[outbound-dedup] \u8DF3\u8FC7\u5BF9\u7528\u6237 ${request.userId} \u7684\u8FD1\u91CD\u590D\u53EF\u6062\u590D\u9519\u8BEF\u63D0\u793A`);
47107
+ }
47108
+ }
47109
+ await addMessage(storage, userId, assistantMessage(text(userRecoverableMessage)), beijingTime, job?.title);
47110
+ markAgentEventsHandled([...injectedEventIds]);
47111
+ return {
47112
+ content: userRecoverableMessage,
47113
+ alreadySent: recoverableMessageSent
47114
+ };
47115
+ }
46789
47116
  }
46790
47117
  continue;
46791
47118
  }
@@ -47007,7 +47334,9 @@ var updateJobLastRunTime = (jobId) => {
47007
47334
  };
47008
47335
  var getCronTools = () => {
47009
47336
  const registry2 = createToolRegistry();
47010
- const executor = createToolExecutor(registry2);
47337
+ const executor = createToolExecutor(registry2, {
47338
+ hookPlugins: createDefaultToolHookPlugins()
47339
+ });
47011
47340
  registerTool(registry2, dateTool);
47012
47341
  registerTool(registry2, globTool);
47013
47342
  registerTool(registry2, grepTool);
@@ -48054,7 +48383,9 @@ var startMailboxPoller = (intervalMs = 3e3) => {
48054
48383
  };
48055
48384
  var createDepartmentAgentTools = () => {
48056
48385
  const registry2 = createToolRegistry();
48057
- const executor = createToolExecutor(registry2);
48386
+ const executor = createToolExecutor(registry2, {
48387
+ hookPlugins: createDefaultToolHookPlugins()
48388
+ });
48058
48389
  registerTool(registry2, dateTool);
48059
48390
  registerTool(registry2, bashTool);
48060
48391
  registerTool(registry2, globTool);
@@ -48192,7 +48523,9 @@ ${workspacePath ? `
48192
48523
  } else {
48193
48524
  finalTools = tools;
48194
48525
  const toolRegistry = createToolRegistry();
48195
- const executor = createToolExecutor(toolRegistry);
48526
+ const executor = createToolExecutor(toolRegistry, {
48527
+ hookPlugins: createDefaultToolHookPlugins()
48528
+ });
48196
48529
  for (let tool of finalTools) {
48197
48530
  registerTool(toolRegistry, tool);
48198
48531
  }
@@ -48335,26 +48668,26 @@ var handleParsingNestedValues = (form, key, value) => {
48335
48668
  };
48336
48669
 
48337
48670
  // node_modules/.pnpm/hono@4.12.9/node_modules/hono/dist/utils/url.js
48338
- var splitPath = (path21) => {
48339
- const paths = path21.split("/");
48671
+ var splitPath = (path20) => {
48672
+ const paths = path20.split("/");
48340
48673
  if (paths[0] === "") {
48341
48674
  paths.shift();
48342
48675
  }
48343
48676
  return paths;
48344
48677
  };
48345
48678
  var splitRoutingPath = (routePath) => {
48346
- const { groups, path: path21 } = extractGroupsFromPath(routePath);
48347
- const paths = splitPath(path21);
48679
+ const { groups, path: path20 } = extractGroupsFromPath(routePath);
48680
+ const paths = splitPath(path20);
48348
48681
  return replaceGroupMarks(paths, groups);
48349
48682
  };
48350
- var extractGroupsFromPath = (path21) => {
48683
+ var extractGroupsFromPath = (path20) => {
48351
48684
  const groups = [];
48352
- path21 = path21.replace(/\{[^}]+\}/g, (match2, index) => {
48685
+ path20 = path20.replace(/\{[^}]+\}/g, (match2, index) => {
48353
48686
  const mark = `@${index}`;
48354
48687
  groups.push([mark, match2]);
48355
48688
  return mark;
48356
48689
  });
48357
- return { groups, path: path21 };
48690
+ return { groups, path: path20 };
48358
48691
  };
48359
48692
  var replaceGroupMarks = (paths, groups) => {
48360
48693
  for (let i = groups.length - 1; i >= 0; i--) {
@@ -48411,8 +48744,8 @@ var getPath = (request) => {
48411
48744
  const queryIndex = url.indexOf("?", i);
48412
48745
  const hashIndex = url.indexOf("#", i);
48413
48746
  const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
48414
- const path21 = url.slice(start, end);
48415
- return tryDecodeURI(path21.includes("%25") ? path21.replace(/%25/g, "%2525") : path21);
48747
+ const path20 = url.slice(start, end);
48748
+ return tryDecodeURI(path20.includes("%25") ? path20.replace(/%25/g, "%2525") : path20);
48416
48749
  } else if (charCode === 63 || charCode === 35) {
48417
48750
  break;
48418
48751
  }
@@ -48429,11 +48762,11 @@ var mergePath = (base, sub, ...rest) => {
48429
48762
  }
48430
48763
  return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
48431
48764
  };
48432
- var checkOptionalParameter = (path21) => {
48433
- if (path21.charCodeAt(path21.length - 1) !== 63 || !path21.includes(":")) {
48765
+ var checkOptionalParameter = (path20) => {
48766
+ if (path20.charCodeAt(path20.length - 1) !== 63 || !path20.includes(":")) {
48434
48767
  return null;
48435
48768
  }
48436
- const segments = path21.split("/");
48769
+ const segments = path20.split("/");
48437
48770
  const results = [];
48438
48771
  let basePath = "";
48439
48772
  segments.forEach((segment) => {
@@ -48574,9 +48907,9 @@ var HonoRequest = class {
48574
48907
  */
48575
48908
  path;
48576
48909
  bodyCache = {};
48577
- constructor(request, path21 = "/", matchResult = [[]]) {
48910
+ constructor(request, path20 = "/", matchResult = [[]]) {
48578
48911
  this.raw = request;
48579
- this.path = path21;
48912
+ this.path = path20;
48580
48913
  this.#matchResult = matchResult;
48581
48914
  this.#validatedData = {};
48582
48915
  }
@@ -49313,8 +49646,8 @@ var Hono = class _Hono {
49313
49646
  return this;
49314
49647
  };
49315
49648
  });
49316
- this.on = (method, path21, ...handlers) => {
49317
- for (const p of [path21].flat()) {
49649
+ this.on = (method, path20, ...handlers) => {
49650
+ for (const p of [path20].flat()) {
49318
49651
  this.#path = p;
49319
49652
  for (const m of [method].flat()) {
49320
49653
  handlers.map((handler) => {
@@ -49371,8 +49704,8 @@ var Hono = class _Hono {
49371
49704
  * app.route("/api", app2) // GET /api/user
49372
49705
  * ```
49373
49706
  */
49374
- route(path21, app) {
49375
- const subApp = this.basePath(path21);
49707
+ route(path20, app) {
49708
+ const subApp = this.basePath(path20);
49376
49709
  app.routes.map((r) => {
49377
49710
  let handler;
49378
49711
  if (app.errorHandler === errorHandler) {
@@ -49398,9 +49731,9 @@ var Hono = class _Hono {
49398
49731
  * const api = new Hono().basePath('/api')
49399
49732
  * ```
49400
49733
  */
49401
- basePath(path21) {
49734
+ basePath(path20) {
49402
49735
  const subApp = this.#clone();
49403
- subApp._basePath = mergePath(this._basePath, path21);
49736
+ subApp._basePath = mergePath(this._basePath, path20);
49404
49737
  return subApp;
49405
49738
  }
49406
49739
  /**
@@ -49474,7 +49807,7 @@ var Hono = class _Hono {
49474
49807
  * })
49475
49808
  * ```
49476
49809
  */
49477
- mount(path21, applicationHandler, options) {
49810
+ mount(path20, applicationHandler, options) {
49478
49811
  let replaceRequest;
49479
49812
  let optionHandler;
49480
49813
  if (options) {
@@ -49501,7 +49834,7 @@ var Hono = class _Hono {
49501
49834
  return [c.env, executionContext];
49502
49835
  };
49503
49836
  replaceRequest ||= (() => {
49504
- const mergedPath = mergePath(this._basePath, path21);
49837
+ const mergedPath = mergePath(this._basePath, path20);
49505
49838
  const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
49506
49839
  return (request) => {
49507
49840
  const url = new URL(request.url);
@@ -49516,14 +49849,14 @@ var Hono = class _Hono {
49516
49849
  }
49517
49850
  await next();
49518
49851
  };
49519
- this.#addRoute(METHOD_NAME_ALL, mergePath(path21, "*"), handler);
49852
+ this.#addRoute(METHOD_NAME_ALL, mergePath(path20, "*"), handler);
49520
49853
  return this;
49521
49854
  }
49522
- #addRoute(method, path21, handler) {
49855
+ #addRoute(method, path20, handler) {
49523
49856
  method = method.toUpperCase();
49524
- path21 = mergePath(this._basePath, path21);
49525
- const r = { basePath: this._basePath, path: path21, method, handler };
49526
- this.router.add(method, path21, [handler, r]);
49857
+ path20 = mergePath(this._basePath, path20);
49858
+ const r = { basePath: this._basePath, path: path20, method, handler };
49859
+ this.router.add(method, path20, [handler, r]);
49527
49860
  this.routes.push(r);
49528
49861
  }
49529
49862
  #handleError(err, c) {
@@ -49536,10 +49869,10 @@ var Hono = class _Hono {
49536
49869
  if (method === "HEAD") {
49537
49870
  return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))();
49538
49871
  }
49539
- const path21 = this.getPath(request, { env });
49540
- const matchResult = this.router.match(method, path21);
49872
+ const path20 = this.getPath(request, { env });
49873
+ const matchResult = this.router.match(method, path20);
49541
49874
  const c = new Context(request, {
49542
- path: path21,
49875
+ path: path20,
49543
49876
  matchResult,
49544
49877
  env,
49545
49878
  executionCtx,
@@ -49639,7 +49972,7 @@ var Hono = class _Hono {
49639
49972
 
49640
49973
  // node_modules/.pnpm/hono@4.12.9/node_modules/hono/dist/router/reg-exp-router/matcher.js
49641
49974
  var emptyParam = [];
49642
- function match(method, path21) {
49975
+ function match(method, path20) {
49643
49976
  const matchers = this.buildAllMatchers();
49644
49977
  const match2 = ((method2, path22) => {
49645
49978
  const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
@@ -49655,7 +49988,7 @@ function match(method, path21) {
49655
49988
  return [matcher[1][index], match3];
49656
49989
  });
49657
49990
  this.match = match2;
49658
- return match2(method, path21);
49991
+ return match2(method, path20);
49659
49992
  }
49660
49993
 
49661
49994
  // node_modules/.pnpm/hono@4.12.9/node_modules/hono/dist/router/reg-exp-router/node.js
@@ -49770,12 +50103,12 @@ var Node = class _Node {
49770
50103
  var Trie = class {
49771
50104
  #context = { varIndex: 0 };
49772
50105
  #root = new Node();
49773
- insert(path21, index, pathErrorCheckOnly) {
50106
+ insert(path20, index, pathErrorCheckOnly) {
49774
50107
  const paramAssoc = [];
49775
50108
  const groups = [];
49776
50109
  for (let i = 0; ; ) {
49777
50110
  let replaced = false;
49778
- path21 = path21.replace(/\{[^}]+\}/g, (m) => {
50111
+ path20 = path20.replace(/\{[^}]+\}/g, (m) => {
49779
50112
  const mark = `@\\${i}`;
49780
50113
  groups[i] = [mark, m];
49781
50114
  i++;
@@ -49786,7 +50119,7 @@ var Trie = class {
49786
50119
  break;
49787
50120
  }
49788
50121
  }
49789
- const tokens = path21.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
50122
+ const tokens = path20.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
49790
50123
  for (let i = groups.length - 1; i >= 0; i--) {
49791
50124
  const [mark] = groups[i];
49792
50125
  for (let j = tokens.length - 1; j >= 0; j--) {
@@ -49825,9 +50158,9 @@ var Trie = class {
49825
50158
  // node_modules/.pnpm/hono@4.12.9/node_modules/hono/dist/router/reg-exp-router/router.js
49826
50159
  var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
49827
50160
  var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
49828
- function buildWildcardRegExp(path21) {
49829
- return wildcardRegExpCache[path21] ??= new RegExp(
49830
- path21 === "*" ? "" : `^${path21.replace(
50161
+ function buildWildcardRegExp(path20) {
50162
+ return wildcardRegExpCache[path20] ??= new RegExp(
50163
+ path20 === "*" ? "" : `^${path20.replace(
49831
50164
  /\/\*$|([.\\+*[^\]$()])/g,
49832
50165
  (_, metaChar) => metaChar ? `\\${metaChar}` : "(?:|/.*)"
49833
50166
  )}$`
@@ -49849,17 +50182,17 @@ function buildMatcherFromPreprocessedRoutes(routes) {
49849
50182
  );
49850
50183
  const staticMap = /* @__PURE__ */ Object.create(null);
49851
50184
  for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
49852
- const [pathErrorCheckOnly, path21, handlers] = routesWithStaticPathFlag[i];
50185
+ const [pathErrorCheckOnly, path20, handlers] = routesWithStaticPathFlag[i];
49853
50186
  if (pathErrorCheckOnly) {
49854
- staticMap[path21] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
50187
+ staticMap[path20] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
49855
50188
  } else {
49856
50189
  j++;
49857
50190
  }
49858
50191
  let paramAssoc;
49859
50192
  try {
49860
- paramAssoc = trie.insert(path21, j, pathErrorCheckOnly);
50193
+ paramAssoc = trie.insert(path20, j, pathErrorCheckOnly);
49861
50194
  } catch (e) {
49862
- throw e === PATH_ERROR ? new UnsupportedPathError(path21) : e;
50195
+ throw e === PATH_ERROR ? new UnsupportedPathError(path20) : e;
49863
50196
  }
49864
50197
  if (pathErrorCheckOnly) {
49865
50198
  continue;
@@ -49893,12 +50226,12 @@ function buildMatcherFromPreprocessedRoutes(routes) {
49893
50226
  }
49894
50227
  return [regexp, handlerMap, staticMap];
49895
50228
  }
49896
- function findMiddleware(middleware, path21) {
50229
+ function findMiddleware(middleware, path20) {
49897
50230
  if (!middleware) {
49898
50231
  return void 0;
49899
50232
  }
49900
50233
  for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
49901
- if (buildWildcardRegExp(k).test(path21)) {
50234
+ if (buildWildcardRegExp(k).test(path20)) {
49902
50235
  return [...middleware[k]];
49903
50236
  }
49904
50237
  }
@@ -49912,7 +50245,7 @@ var RegExpRouter = class {
49912
50245
  this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
49913
50246
  this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
49914
50247
  }
49915
- add(method, path21, handler) {
50248
+ add(method, path20, handler) {
49916
50249
  const middleware = this.#middleware;
49917
50250
  const routes = this.#routes;
49918
50251
  if (!middleware || !routes) {
@@ -49927,18 +50260,18 @@ var RegExpRouter = class {
49927
50260
  });
49928
50261
  });
49929
50262
  }
49930
- if (path21 === "/*") {
49931
- path21 = "*";
50263
+ if (path20 === "/*") {
50264
+ path20 = "*";
49932
50265
  }
49933
- const paramCount = (path21.match(/\/:/g) || []).length;
49934
- if (/\*$/.test(path21)) {
49935
- const re = buildWildcardRegExp(path21);
50266
+ const paramCount = (path20.match(/\/:/g) || []).length;
50267
+ if (/\*$/.test(path20)) {
50268
+ const re = buildWildcardRegExp(path20);
49936
50269
  if (method === METHOD_NAME_ALL) {
49937
50270
  Object.keys(middleware).forEach((m) => {
49938
- middleware[m][path21] ||= findMiddleware(middleware[m], path21) || findMiddleware(middleware[METHOD_NAME_ALL], path21) || [];
50271
+ middleware[m][path20] ||= findMiddleware(middleware[m], path20) || findMiddleware(middleware[METHOD_NAME_ALL], path20) || [];
49939
50272
  });
49940
50273
  } else {
49941
- middleware[method][path21] ||= findMiddleware(middleware[method], path21) || findMiddleware(middleware[METHOD_NAME_ALL], path21) || [];
50274
+ middleware[method][path20] ||= findMiddleware(middleware[method], path20) || findMiddleware(middleware[METHOD_NAME_ALL], path20) || [];
49942
50275
  }
49943
50276
  Object.keys(middleware).forEach((m) => {
49944
50277
  if (method === METHOD_NAME_ALL || method === m) {
@@ -49956,7 +50289,7 @@ var RegExpRouter = class {
49956
50289
  });
49957
50290
  return;
49958
50291
  }
49959
- const paths = checkOptionalParameter(path21) || [path21];
50292
+ const paths = checkOptionalParameter(path20) || [path20];
49960
50293
  for (let i = 0, len = paths.length; i < len; i++) {
49961
50294
  const path22 = paths[i];
49962
50295
  Object.keys(routes).forEach((m) => {
@@ -49983,13 +50316,13 @@ var RegExpRouter = class {
49983
50316
  const routes = [];
49984
50317
  let hasOwnRoute = method === METHOD_NAME_ALL;
49985
50318
  [this.#middleware, this.#routes].forEach((r) => {
49986
- const ownRoute = r[method] ? Object.keys(r[method]).map((path21) => [path21, r[method][path21]]) : [];
50319
+ const ownRoute = r[method] ? Object.keys(r[method]).map((path20) => [path20, r[method][path20]]) : [];
49987
50320
  if (ownRoute.length !== 0) {
49988
50321
  hasOwnRoute ||= true;
49989
50322
  routes.push(...ownRoute);
49990
50323
  } else if (method !== METHOD_NAME_ALL) {
49991
50324
  routes.push(
49992
- ...Object.keys(r[METHOD_NAME_ALL]).map((path21) => [path21, r[METHOD_NAME_ALL][path21]])
50325
+ ...Object.keys(r[METHOD_NAME_ALL]).map((path20) => [path20, r[METHOD_NAME_ALL][path20]])
49993
50326
  );
49994
50327
  }
49995
50328
  });
@@ -50009,13 +50342,13 @@ var SmartRouter = class {
50009
50342
  constructor(init) {
50010
50343
  this.#routers = init.routers;
50011
50344
  }
50012
- add(method, path21, handler) {
50345
+ add(method, path20, handler) {
50013
50346
  if (!this.#routes) {
50014
50347
  throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
50015
50348
  }
50016
- this.#routes.push([method, path21, handler]);
50349
+ this.#routes.push([method, path20, handler]);
50017
50350
  }
50018
- match(method, path21) {
50351
+ match(method, path20) {
50019
50352
  if (!this.#routes) {
50020
50353
  throw new Error("Fatal error");
50021
50354
  }
@@ -50030,7 +50363,7 @@ var SmartRouter = class {
50030
50363
  for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {
50031
50364
  router.add(...routes[i2]);
50032
50365
  }
50033
- res = router.match(method, path21);
50366
+ res = router.match(method, path20);
50034
50367
  } catch (e) {
50035
50368
  if (e instanceof UnsupportedPathError) {
50036
50369
  continue;
@@ -50080,10 +50413,10 @@ var Node2 = class _Node2 {
50080
50413
  }
50081
50414
  this.#patterns = [];
50082
50415
  }
50083
- insert(method, path21, handler) {
50416
+ insert(method, path20, handler) {
50084
50417
  this.#order = ++this.#order;
50085
50418
  let curNode = this;
50086
- const parts = splitRoutingPath(path21);
50419
+ const parts = splitRoutingPath(path20);
50087
50420
  const possibleKeys = [];
50088
50421
  for (let i = 0, len = parts.length; i < len; i++) {
50089
50422
  const p = parts[i];
@@ -50132,12 +50465,12 @@ var Node2 = class _Node2 {
50132
50465
  }
50133
50466
  }
50134
50467
  }
50135
- search(method, path21) {
50468
+ search(method, path20) {
50136
50469
  const handlerSets = [];
50137
50470
  this.#params = emptyParams;
50138
50471
  const curNode = this;
50139
50472
  let curNodes = [curNode];
50140
- const parts = splitPath(path21);
50473
+ const parts = splitPath(path20);
50141
50474
  const curNodesQueue = [];
50142
50475
  const len = parts.length;
50143
50476
  let partOffsets = null;
@@ -50179,13 +50512,13 @@ var Node2 = class _Node2 {
50179
50512
  if (matcher instanceof RegExp) {
50180
50513
  if (partOffsets === null) {
50181
50514
  partOffsets = new Array(len);
50182
- let offset = path21[0] === "/" ? 1 : 0;
50515
+ let offset = path20[0] === "/" ? 1 : 0;
50183
50516
  for (let p = 0; p < len; p++) {
50184
50517
  partOffsets[p] = offset;
50185
50518
  offset += parts[p].length + 1;
50186
50519
  }
50187
50520
  }
50188
- const restPathString = path21.substring(partOffsets[i]);
50521
+ const restPathString = path20.substring(partOffsets[i]);
50189
50522
  const m = matcher.exec(restPathString);
50190
50523
  if (m) {
50191
50524
  params[name] = m[0];
@@ -50238,18 +50571,18 @@ var TrieRouter = class {
50238
50571
  constructor() {
50239
50572
  this.#node = new Node2();
50240
50573
  }
50241
- add(method, path21, handler) {
50242
- const results = checkOptionalParameter(path21);
50574
+ add(method, path20, handler) {
50575
+ const results = checkOptionalParameter(path20);
50243
50576
  if (results) {
50244
50577
  for (let i = 0, len = results.length; i < len; i++) {
50245
50578
  this.#node.insert(method, results[i], handler);
50246
50579
  }
50247
50580
  return;
50248
50581
  }
50249
- this.#node.insert(method, path21, handler);
50582
+ this.#node.insert(method, path20, handler);
50250
50583
  }
50251
- match(method, path21) {
50252
- return this.#node.search(method, path21);
50584
+ match(method, path20) {
50585
+ return this.#node.search(method, path20);
50253
50586
  }
50254
50587
  };
50255
50588
 
@@ -50914,7 +51247,7 @@ var baseMimes = _baseMimes;
50914
51247
 
50915
51248
  // node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.9/node_modules/@hono/node-server/dist/serve-static.mjs
50916
51249
  var import_fs15 = require("fs");
50917
- var import_path20 = require("path");
51250
+ var import_path19 = require("path");
50918
51251
  var import_process = require("process");
50919
51252
  var import_stream2 = require("stream");
50920
51253
  var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
@@ -50951,10 +51284,10 @@ var createStreamBody = (stream) => {
50951
51284
  });
50952
51285
  return body;
50953
51286
  };
50954
- var getStats = (path21) => {
51287
+ var getStats = (path20) => {
50955
51288
  let stats;
50956
51289
  try {
50957
- stats = (0, import_fs15.statSync)(path21);
51290
+ stats = (0, import_fs15.statSync)(path20);
50958
51291
  } catch {
50959
51292
  }
50960
51293
  return stats;
@@ -50997,21 +51330,21 @@ var serveStatic = (options = { root: "" }) => {
50997
51330
  return next();
50998
51331
  }
50999
51332
  }
51000
- let path21 = (0, import_path20.join)(
51333
+ let path20 = (0, import_path19.join)(
51001
51334
  root,
51002
51335
  !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename
51003
51336
  );
51004
- let stats = getStats(path21);
51337
+ let stats = getStats(path20);
51005
51338
  if (stats && stats.isDirectory()) {
51006
51339
  const indexFile = options.index ?? "index.html";
51007
- path21 = (0, import_path20.join)(path21, indexFile);
51008
- stats = getStats(path21);
51340
+ path20 = (0, import_path19.join)(path20, indexFile);
51341
+ stats = getStats(path20);
51009
51342
  }
51010
51343
  if (!stats) {
51011
- await options.onNotFound?.(path21, c);
51344
+ await options.onNotFound?.(path20, c);
51012
51345
  return next();
51013
51346
  }
51014
- const mimeType = getMimeType(path21);
51347
+ const mimeType = getMimeType(path20);
51015
51348
  c.header("Content-Type", mimeType || "application/octet-stream");
51016
51349
  if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
51017
51350
  const acceptEncodingSet = new Set(
@@ -51021,12 +51354,12 @@ var serveStatic = (options = { root: "" }) => {
51021
51354
  if (!acceptEncodingSet.has(encoding)) {
51022
51355
  continue;
51023
51356
  }
51024
- const precompressedStats = getStats(path21 + ENCODINGS[encoding]);
51357
+ const precompressedStats = getStats(path20 + ENCODINGS[encoding]);
51025
51358
  if (precompressedStats) {
51026
51359
  c.header("Content-Encoding", encoding);
51027
51360
  c.header("Vary", "Accept-Encoding", { append: true });
51028
51361
  stats = precompressedStats;
51029
- path21 = path21 + ENCODINGS[encoding];
51362
+ path20 = path20 + ENCODINGS[encoding];
51030
51363
  break;
51031
51364
  }
51032
51365
  }
@@ -51040,7 +51373,7 @@ var serveStatic = (options = { root: "" }) => {
51040
51373
  result = c.body(null);
51041
51374
  } else if (!range) {
51042
51375
  c.header("Content-Length", size.toString());
51043
- result = c.body(createStreamBody((0, import_fs15.createReadStream)(path21)), 200);
51376
+ result = c.body(createStreamBody((0, import_fs15.createReadStream)(path20)), 200);
51044
51377
  } else {
51045
51378
  c.header("Accept-Ranges", "bytes");
51046
51379
  c.header("Date", stats.birthtime.toUTCString());
@@ -51051,12 +51384,12 @@ var serveStatic = (options = { root: "" }) => {
51051
51384
  end = size - 1;
51052
51385
  }
51053
51386
  const chunksize = end - start + 1;
51054
- const stream = (0, import_fs15.createReadStream)(path21, { start, end });
51387
+ const stream = (0, import_fs15.createReadStream)(path20, { start, end });
51055
51388
  c.header("Content-Length", chunksize.toString());
51056
51389
  c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`);
51057
51390
  result = c.body(createStreamBody(stream), 206);
51058
51391
  }
51059
- await options.onFound?.(path21, c);
51392
+ await options.onFound?.(path20, c);
51060
51393
  return result;
51061
51394
  };
51062
51395
  };
@@ -51156,13 +51489,13 @@ var import_node_path17 = __toESM(require("node:path"));
51156
51489
  // src/git/worktree.ts
51157
51490
  var import_child_process2 = require("child_process");
51158
51491
  var import_util = require("util");
51159
- var import_path21 = __toESM(require("path"));
51492
+ var import_path20 = __toESM(require("path"));
51160
51493
  var import_fs16 = require("fs");
51161
51494
  var execFileAsync = (0, import_util.promisify)(import_child_process2.execFile);
51162
51495
  var getProjectRoot = () => process.cwd();
51163
51496
  var getWorktreeBaseDir = () => getDuclawWorktreesDir();
51164
51497
  var getDisplayWorktreePath = (goalId, taskId) => `~/.duclaw/worktrees/${goalId}/${taskId}`;
51165
- var getWorktreePath = (goalId, taskId) => import_path21.default.join(getWorktreeBaseDir(), goalId, taskId);
51498
+ var getWorktreePath = (goalId, taskId) => import_path20.default.join(getWorktreeBaseDir(), goalId, taskId);
51166
51499
  var getBranchName = (taskId) => `task/${taskId}`;
51167
51500
  async function git(args, cwd) {
51168
51501
  const { stdout } = await execFileAsync("git", args, {
@@ -51174,7 +51507,7 @@ async function git(args, cwd) {
51174
51507
  async function createWorktree(taskId, goalId, baseBranch = "main") {
51175
51508
  const wtPath = getWorktreePath(goalId, taskId);
51176
51509
  const branch = getBranchName(taskId);
51177
- const parentDir = import_path21.default.dirname(wtPath);
51510
+ const parentDir = import_path20.default.dirname(wtPath);
51178
51511
  if (!(0, import_fs16.existsSync)(parentDir)) {
51179
51512
  (0, import_fs16.mkdirSync)(parentDir, { recursive: true });
51180
51513
  }
@@ -51280,8 +51613,8 @@ async function listWorktrees() {
51280
51613
  const fullBranch = branchLine.replace("branch refs/heads/", "");
51281
51614
  if (!fullBranch.startsWith("task/")) continue;
51282
51615
  const taskId = fullBranch.replace("task/", "");
51283
- const relPath = import_path21.default.relative(getProjectRoot(), wtPath);
51284
- const parts = relPath.split(import_path21.default.sep);
51616
+ const relPath = import_path20.default.relative(getProjectRoot(), wtPath);
51617
+ const parts = relPath.split(import_path20.default.sep);
51285
51618
  const worktreeIdx = parts.indexOf(".worktrees");
51286
51619
  const goalId = worktreeIdx >= 0 && parts.length > worktreeIdx + 1 ? parts[worktreeIdx + 1] : "";
51287
51620
  worktrees.push({
@@ -53110,7 +53443,7 @@ var systemRoutes = new Hono2();
53110
53443
  var startTime = Date.now();
53111
53444
  systemRoutes.get("/system/info", (c) => {
53112
53445
  return c.json({
53113
- version: true ? "1.9.3" : "unknown",
53446
+ version: true ? "1.9.5" : "unknown",
53114
53447
  uptime: Math.floor((Date.now() - startTime) / 1e3),
53115
53448
  env: process.env.NODE_ENV || "development",
53116
53449
  nodeVersion: process.version
@@ -53118,7 +53451,7 @@ systemRoutes.get("/system/info", (c) => {
53118
53451
  });
53119
53452
 
53120
53453
  // src/server/routes/mobile.ts
53121
- var import_node_crypto15 = require("node:crypto");
53454
+ var import_node_crypto16 = require("node:crypto");
53122
53455
  var import_promises12 = require("node:fs/promises");
53123
53456
  var import_node_path16 = __toESM(require("node:path"));
53124
53457
  var mobileRoutes = new Hono2();
@@ -53222,7 +53555,7 @@ mobileRoutes.post("/mobile/attachments", async (c) => {
53222
53555
  const fileName = sanitizeFileName(body.fileName || `attachment-${Date.now()}`);
53223
53556
  const mimeType = body.mimeType || "application/octet-stream";
53224
53557
  const type = inferAttachmentType2(mimeType, fileName);
53225
- const attachmentId = (0, import_node_crypto15.randomUUID)();
53558
+ const attachmentId = (0, import_node_crypto16.randomUUID)();
53226
53559
  const buffer = Buffer.from(dataBase64, "base64");
53227
53560
  const dir = import_node_path16.default.join(getDuclawWorkspaceDir(), mobileUserId, "mobile", type === "image" ? "images" : "files");
53228
53561
  await (0, import_promises12.mkdir)(dir, { recursive: true });
@@ -53254,7 +53587,7 @@ mobileRoutes.post("/mobile/messages", async (c) => {
53254
53587
  }
53255
53588
  const mobileUserId = resolveMobileUserId(body, c.req.header("x-user-id"));
53256
53589
  const threadId = resolveThreadId(body.goalId, mobileUserId);
53257
- const requestId = body.clientMessageId?.trim() || (0, import_node_crypto15.randomUUID)();
53590
+ const requestId = body.clientMessageId?.trim() || (0, import_node_crypto16.randomUUID)();
53258
53591
  const agentText = body.contextText?.trim() || text2;
53259
53592
  const attachmentContent = buildContentWithAttachments(agentText, attachments);
53260
53593
  const content = buildGoalPrompt(body.goalId, attachmentContent.content);