duclaw-cli 1.7.3 → 1.7.4

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 path9 = require("path");
118
+ var path10 = 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 = path9.resolve(process.cwd(), ".env.vault");
264
+ possibleVaultPath = path10.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] === "~" ? path9.join(os.homedir(), envPath.slice(1)) : envPath;
272
+ return envPath[0] === "~" ? path10.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 = path9.resolve(process.cwd(), ".env");
289
+ const dotenvPath = path10.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 path10 of optionPaths) {
317
+ for (const path11 of optionPaths) {
318
318
  try {
319
- const parsed = DotenvModule.parse(fs3.readFileSync(path10, { encoding }));
319
+ const parsed = DotenvModule.parse(fs3.readFileSync(path11, { encoding }));
320
320
  DotenvModule.populate(parsedAll, parsed, options);
321
321
  } catch (e) {
322
322
  if (debug) {
323
- _debug(`Failed to load ${path10} ${e.message}`);
323
+ _debug(`Failed to load ${path11} ${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 = path9.relative(process.cwd(), filePath);
336
+ const relative4 = path10.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, path9, moduleArguments) {
8241
- parser.push("MODULE", "LOAD", path9);
8240
+ parseCommand(parser, path10, moduleArguments) {
8241
+ parser.push("MODULE", "LOAD", path10);
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, path9, json, ...jsons) {
23542
+ parseCommand(parser, key, path10, json, ...jsons) {
23543
23543
  parser.push("JSON.ARRAPPEND");
23544
23544
  parser.pushKey(key);
23545
- parser.push(path9, (0, generic_transformers_1.transformRedisJsonArgument)(json));
23545
+ parser.push(path10, (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, path9, json, options) {
23575
+ parseCommand(parser, key, path10, json, options) {
23576
23576
  parser.push("JSON.ARRINDEX");
23577
23577
  parser.pushKey(key);
23578
- parser.push(path9, (0, generic_transformers_1.transformRedisJsonArgument)(json));
23578
+ parser.push(path10, (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, path9, index, json, ...jsons) {
23610
+ parseCommand(parser, key, path10, index, json, ...jsons) {
23611
23611
  parser.push("JSON.ARRINSERT");
23612
23612
  parser.pushKey(key);
23613
- parser.push(path9, index.toString(), (0, generic_transformers_1.transformRedisJsonArgument)(json));
23613
+ parser.push(path10, 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, path9, start, stop) {
23703
+ parseCommand(parser, key, path10, start, stop) {
23704
23704
  parser.push("JSON.ARRTRIM");
23705
23705
  parser.pushKey(key);
23706
- parser.push(path9, start.toString(), stop.toString());
23706
+ parser.push(path10, 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, path9, value) {
23871
+ parseCommand(parser, key, path10, value) {
23872
23872
  parser.push("JSON.MERGE");
23873
23873
  parser.pushKey(key);
23874
- parser.push(path9, (0, generic_transformers_1.transformRedisJsonArgument)(value));
23874
+ parser.push(path10, (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, path9) {
23897
+ parseCommand(parser, keys, path10) {
23898
23898
  parser.push("JSON.MGET");
23899
23899
  parser.pushKeys(keys);
23900
- parser.push(path9);
23900
+ parser.push(path10);
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, path9, by) {
23955
+ parseCommand(parser, key, path10, by) {
23956
23956
  parser.push("JSON.NUMINCRBY");
23957
23957
  parser.pushKey(key);
23958
- parser.push(path9, by.toString());
23958
+ parser.push(path10, 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, path9, by) {
23990
+ parseCommand(parser, key, path10, by) {
23991
23991
  parser.push("JSON.NUMMULTBY");
23992
23992
  parser.pushKey(key);
23993
- parser.push(path9, by.toString());
23993
+ parser.push(path10, 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, path9, json, options) {
24077
+ parseCommand(parser, key, path10, json, options) {
24078
24078
  parser.push("JSON.SET");
24079
24079
  parser.pushKey(key);
24080
- parser.push(path9, (0, generic_transformers_1.transformRedisJsonArgument)(json));
24080
+ parser.push(path10, (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, path9) {
24168
+ parseCommand(parser, key, path10) {
24169
24169
  parser.push("JSON.TOGGLE");
24170
24170
  parser.pushKey(key);
24171
- parser.push(path9);
24171
+ parser.push(path10);
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.7.3" : "unknown"}`);
30245
+ console.log(`duclaw-cli v${true ? "1.7.4" : "unknown"}`);
30246
30246
  }
30247
30247
  function getDuclawTemplate() {
30248
30248
  return {
@@ -30332,9 +30332,9 @@ var getChannel = (registry2, id) => {
30332
30332
  };
30333
30333
 
30334
30334
  // src/agent/createAgent.ts
30335
- var import_node_path9 = require("node:path");
30336
- var import_node_os3 = require("node:os");
30337
- var import_node_fs4 = require("node:fs");
30335
+ var import_node_path10 = require("node:path");
30336
+ var import_node_os4 = require("node:os");
30337
+ var import_node_fs5 = require("node:fs");
30338
30338
 
30339
30339
  // src/background/BackgroundManager.ts
30340
30340
  var import_child_process = require("child_process");
@@ -31736,12 +31736,12 @@ function encodeURIPath(str) {
31736
31736
  return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
31737
31737
  }
31738
31738
  var EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
31739
- var createPathTagFunction = (pathEncoder = encodeURIPath) => function path9(statics, ...params) {
31739
+ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path10(statics, ...params) {
31740
31740
  if (statics.length === 1)
31741
31741
  return statics[0];
31742
31742
  let postPath = false;
31743
31743
  const invalidSegments = [];
31744
- const path10 = statics.reduce((previousValue, currentValue, index) => {
31744
+ const path11 = statics.reduce((previousValue, currentValue, index) => {
31745
31745
  if (/[?#]/.test(currentValue)) {
31746
31746
  postPath = true;
31747
31747
  }
@@ -31758,7 +31758,7 @@ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path9(stat
31758
31758
  }
31759
31759
  return previousValue + currentValue + (index === params.length ? "" : encoded);
31760
31760
  }, "");
31761
- const pathOnly = path10.split(/[?#]/, 1)[0];
31761
+ const pathOnly = path11.split(/[?#]/, 1)[0];
31762
31762
  const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
31763
31763
  let match2;
31764
31764
  while ((match2 = invalidSegmentPattern.exec(pathOnly)) !== null) {
@@ -31779,10 +31779,10 @@ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path9(stat
31779
31779
  }, "");
31780
31780
  throw new AnthropicError(`Path parameters result in path with invalid segments:
31781
31781
  ${invalidSegments.map((e) => e.error).join("\n")}
31782
- ${path10}
31782
+ ${path11}
31783
31783
  ${underline}`);
31784
31784
  }
31785
- return path10;
31785
+ return path11;
31786
31786
  };
31787
31787
  var path = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
31788
31788
 
@@ -34893,9 +34893,9 @@ var BaseAnthropic = class {
34893
34893
  makeStatusError(status, error, message, headers) {
34894
34894
  return APIError.generate(status, error, message, headers);
34895
34895
  }
34896
- buildURL(path9, query, defaultBaseURL) {
34896
+ buildURL(path10, query, defaultBaseURL) {
34897
34897
  const baseURL = !__classPrivateFieldGet(this, _BaseAnthropic_instances, "m", _BaseAnthropic_baseURLOverridden).call(this) && defaultBaseURL || this.baseURL;
34898
- const url = isAbsoluteURL(path9) ? new URL(path9) : new URL(baseURL + (baseURL.endsWith("/") && path9.startsWith("/") ? path9.slice(1) : path9));
34898
+ const url = isAbsoluteURL(path10) ? new URL(path10) : new URL(baseURL + (baseURL.endsWith("/") && path10.startsWith("/") ? path10.slice(1) : path10));
34899
34899
  const defaultQuery = this.defaultQuery();
34900
34900
  if (!isEmptyObj(defaultQuery)) {
34901
34901
  query = { ...defaultQuery, ...query };
@@ -34926,24 +34926,24 @@ var BaseAnthropic = class {
34926
34926
  */
34927
34927
  async prepareRequest(request, { url, options }) {
34928
34928
  }
34929
- get(path9, opts) {
34930
- return this.methodRequest("get", path9, opts);
34929
+ get(path10, opts) {
34930
+ return this.methodRequest("get", path10, opts);
34931
34931
  }
34932
- post(path9, opts) {
34933
- return this.methodRequest("post", path9, opts);
34932
+ post(path10, opts) {
34933
+ return this.methodRequest("post", path10, opts);
34934
34934
  }
34935
- patch(path9, opts) {
34936
- return this.methodRequest("patch", path9, opts);
34935
+ patch(path10, opts) {
34936
+ return this.methodRequest("patch", path10, opts);
34937
34937
  }
34938
- put(path9, opts) {
34939
- return this.methodRequest("put", path9, opts);
34938
+ put(path10, opts) {
34939
+ return this.methodRequest("put", path10, opts);
34940
34940
  }
34941
- delete(path9, opts) {
34942
- return this.methodRequest("delete", path9, opts);
34941
+ delete(path10, opts) {
34942
+ return this.methodRequest("delete", path10, opts);
34943
34943
  }
34944
- methodRequest(method, path9, opts) {
34944
+ methodRequest(method, path10, opts) {
34945
34945
  return this.request(Promise.resolve(opts).then((opts2) => {
34946
- return { method, path: path9, ...opts2 };
34946
+ return { method, path: path10, ...opts2 };
34947
34947
  }));
34948
34948
  }
34949
34949
  request(options, remainingRetries = null) {
@@ -35047,8 +35047,8 @@ var BaseAnthropic = class {
35047
35047
  }));
35048
35048
  return { response, options, controller, requestLogID, retryOfRequestLogID, startTime: startTime2 };
35049
35049
  }
35050
- getAPIList(path9, Page2, opts) {
35051
- return this.requestAPIList(Page2, opts && "then" in opts ? opts.then((opts2) => ({ method: "get", path: path9, ...opts2 })) : { method: "get", path: path9, ...opts });
35050
+ getAPIList(path10, Page2, opts) {
35051
+ return this.requestAPIList(Page2, opts && "then" in opts ? opts.then((opts2) => ({ method: "get", path: path10, ...opts2 })) : { method: "get", path: path10, ...opts });
35052
35052
  }
35053
35053
  requestAPIList(Page2, options) {
35054
35054
  const request = this.makeRequest(options, null, void 0);
@@ -35136,8 +35136,8 @@ var BaseAnthropic = class {
35136
35136
  }
35137
35137
  async buildRequest(inputOptions, { retryCount = 0 } = {}) {
35138
35138
  const options = { ...inputOptions };
35139
- const { method, path: path9, query, defaultBaseURL } = options;
35140
- const url = this.buildURL(path9, query, defaultBaseURL);
35139
+ const { method, path: path10, query, defaultBaseURL } = options;
35140
+ const url = this.buildURL(path10, query, defaultBaseURL);
35141
35141
  if ("timeout" in options)
35142
35142
  validatePositiveInteger("timeout", options.timeout);
35143
35143
  options.timeout = options.timeout ?? this.timeout;
@@ -35312,6 +35312,9 @@ var toSDKMessage = (msg) => {
35312
35312
  };
35313
35313
  }
35314
35314
  const blocks = msg.content.map((block) => toSDKBlock(block)).filter((b) => b.type !== "text" || b.text);
35315
+ if (blocks.length === 0) {
35316
+ blocks.push({ type: "text", text: "(ok)" });
35317
+ }
35315
35318
  return {
35316
35319
  role: `assistant`,
35317
35320
  content: blocks
@@ -35422,7 +35425,7 @@ var createRedisStorage = (options = {}) => {
35422
35425
  };
35423
35426
 
35424
35427
  // src/storage/utils.ts
35425
- var getMessages = async (storage, userId, limit = 100, date, cronTitle) => {
35428
+ var getMessages = async (storage, userId, limit = 300, date, cronTitle) => {
35426
35429
  let key = `mem:${userId}`;
35427
35430
  if (date) {
35428
35431
  key = key + `:${date}`;
@@ -35453,6 +35456,7 @@ var sanitizeMessages = (messages) => {
35453
35456
  for (let i = 0; i < messages.length; i++) {
35454
35457
  const msg = messages[i];
35455
35458
  if (!msg.content || msg.content.length === 0) continue;
35459
+ if (msg.content.every((b) => b.type === "text" && !b.text?.trim())) continue;
35456
35460
  if (msg.role === "assistant") {
35457
35461
  const toolUses = msg.content.filter((b) => b.type === "tool_use");
35458
35462
  if (toolUses.length > 0) {
@@ -35504,6 +35508,19 @@ var addTopicIndex = async (storage, userId, date, messageIndex, snippet, cronTit
35504
35508
  });
35505
35509
  await storage.set(key, data);
35506
35510
  };
35511
+ var updateTopicSummary = async (storage, userId, date, summary, cronTitle) => {
35512
+ const key = `topics:${userId}`;
35513
+ const data = await storage.get(key);
35514
+ if (!data || data.length === 0) return;
35515
+ for (let i = data.length - 1; i >= 0; i--) {
35516
+ const entry = data[i];
35517
+ if (entry.d === date && (entry.c || void 0) === (cronTitle || void 0)) {
35518
+ entry.s = summary.slice(0, 80);
35519
+ await storage.set(key, data);
35520
+ return;
35521
+ }
35522
+ }
35523
+ };
35507
35524
  var searchTopicIndex = async (topicStorage, userId, query, date, limit = 8) => {
35508
35525
  const key = `topics:${userId}`;
35509
35526
  const data = await topicStorage.get(key) || [];
@@ -35574,6 +35591,16 @@ var searchChatHistory = async (messageStorage, topicStorage, userId, query, date
35574
35591
  }
35575
35592
  return { matches: results, total, matchCount: matches.length };
35576
35593
  };
35594
+ var clearMessages = async (storage, userId, date, cronTitle) => {
35595
+ let key = `mem:${userId}`;
35596
+ if (date) {
35597
+ key = key + `:${date}`;
35598
+ }
35599
+ if (cronTitle) {
35600
+ key = key + `:${cronTitle}`;
35601
+ }
35602
+ await storage.del(key);
35603
+ };
35577
35604
 
35578
35605
  // src/tools/ToolExecutor.ts
35579
35606
  var createToolExecutor = (registry2) => {
@@ -35657,7 +35684,9 @@ var import_path11 = __toESM(require("path"));
35657
35684
  import_dayjs.default.extend(import_utc.default);
35658
35685
  import_dayjs.default.extend(import_timezone.default);
35659
35686
  var getGoalDir = () => {
35660
- return import_path11.default.join(process.cwd(), ".tasks");
35687
+ const goalDir = import_path11.default.join(process.cwd(), ".tasks");
35688
+ (0, import_fs4.mkdirSync)(goalDir, { recursive: true });
35689
+ return goalDir;
35661
35690
  };
35662
35691
  var getGoalPath = (goalId) => {
35663
35692
  return import_path11.default.join(getGoalDir(), `${goalId}.json`);
@@ -36730,16 +36759,16 @@ var Diff = class {
36730
36759
  }
36731
36760
  }
36732
36761
  }
36733
- addToPath(path9, added, removed, oldPosInc, options) {
36734
- const last = path9.lastComponent;
36762
+ addToPath(path10, added, removed, oldPosInc, options) {
36763
+ const last = path10.lastComponent;
36735
36764
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
36736
36765
  return {
36737
- oldPos: path9.oldPos + oldPosInc,
36766
+ oldPos: path10.oldPos + oldPosInc,
36738
36767
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
36739
36768
  };
36740
36769
  } else {
36741
36770
  return {
36742
- oldPos: path9.oldPos + oldPosInc,
36771
+ oldPos: path10.oldPos + oldPosInc,
36743
36772
  lastComponent: { count: 1, added, removed, previousComponent: last }
36744
36773
  };
36745
36774
  }
@@ -37984,7 +38013,7 @@ var ReaddirpStream = class extends import_node_stream.Readable {
37984
38013
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
37985
38014
  const statMethod = opts.lstat ? import_promises6.lstat : import_promises6.stat;
37986
38015
  if (wantBigintFsStats) {
37987
- this._stat = (path9) => statMethod(path9, { bigint: true });
38016
+ this._stat = (path10) => statMethod(path10, { bigint: true });
37988
38017
  } else {
37989
38018
  this._stat = statMethod;
37990
38019
  }
@@ -38009,8 +38038,8 @@ var ReaddirpStream = class extends import_node_stream.Readable {
38009
38038
  const par = this.parent;
38010
38039
  const fil = par && par.files;
38011
38040
  if (fil && fil.length > 0) {
38012
- const { path: path9, depth } = par;
38013
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path9));
38041
+ const { path: path10, depth } = par;
38042
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path10));
38014
38043
  const awaited = await Promise.all(slice);
38015
38044
  for (const entry of awaited) {
38016
38045
  if (!entry)
@@ -38050,20 +38079,20 @@ var ReaddirpStream = class extends import_node_stream.Readable {
38050
38079
  this.reading = false;
38051
38080
  }
38052
38081
  }
38053
- async _exploreDir(path9, depth) {
38082
+ async _exploreDir(path10, depth) {
38054
38083
  let files;
38055
38084
  try {
38056
- files = await (0, import_promises6.readdir)(path9, this._rdOptions);
38085
+ files = await (0, import_promises6.readdir)(path10, this._rdOptions);
38057
38086
  } catch (error) {
38058
38087
  this._onError(error);
38059
38088
  }
38060
- return { files, depth, path: path9 };
38089
+ return { files, depth, path: path10 };
38061
38090
  }
38062
- async _formatEntry(dirent, path9) {
38091
+ async _formatEntry(dirent, path10) {
38063
38092
  let entry;
38064
38093
  const basename4 = this._isDirent ? dirent.name : dirent;
38065
38094
  try {
38066
- const fullPath = (0, import_node_path7.resolve)((0, import_node_path7.join)(path9, basename4));
38095
+ const fullPath = (0, import_node_path7.resolve)((0, import_node_path7.join)(path10, basename4));
38067
38096
  entry = { path: (0, import_node_path7.relative)(this._root, fullPath), fullPath, basename: basename4 };
38068
38097
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
38069
38098
  } catch (err) {
@@ -38463,16 +38492,16 @@ var delFromSet = (main2, prop, item) => {
38463
38492
  };
38464
38493
  var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
38465
38494
  var FsWatchInstances = /* @__PURE__ */ new Map();
38466
- function createFsWatchInstance(path9, options, listener, errHandler, emitRaw) {
38495
+ function createFsWatchInstance(path10, options, listener, errHandler, emitRaw) {
38467
38496
  const handleEvent = (rawEvent, evPath) => {
38468
- listener(path9);
38469
- emitRaw(rawEvent, evPath, { watchedPath: path9 });
38470
- if (evPath && path9 !== evPath) {
38471
- fsWatchBroadcast(sp.resolve(path9, evPath), KEY_LISTENERS, sp.join(path9, evPath));
38497
+ listener(path10);
38498
+ emitRaw(rawEvent, evPath, { watchedPath: path10 });
38499
+ if (evPath && path10 !== evPath) {
38500
+ fsWatchBroadcast(sp.resolve(path10, evPath), KEY_LISTENERS, sp.join(path10, evPath));
38472
38501
  }
38473
38502
  };
38474
38503
  try {
38475
- return (0, import_node_fs.watch)(path9, {
38504
+ return (0, import_node_fs.watch)(path10, {
38476
38505
  persistent: options.persistent
38477
38506
  }, handleEvent);
38478
38507
  } catch (error) {
@@ -38488,12 +38517,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
38488
38517
  listener(val1, val2, val3);
38489
38518
  });
38490
38519
  };
38491
- var setFsWatchListener = (path9, fullPath, options, handlers) => {
38520
+ var setFsWatchListener = (path10, fullPath, options, handlers) => {
38492
38521
  const { listener, errHandler, rawEmitter } = handlers;
38493
38522
  let cont = FsWatchInstances.get(fullPath);
38494
38523
  let watcher;
38495
38524
  if (!options.persistent) {
38496
- watcher = createFsWatchInstance(path9, options, listener, errHandler, rawEmitter);
38525
+ watcher = createFsWatchInstance(path10, options, listener, errHandler, rawEmitter);
38497
38526
  if (!watcher)
38498
38527
  return;
38499
38528
  return watcher.close.bind(watcher);
@@ -38504,7 +38533,7 @@ var setFsWatchListener = (path9, fullPath, options, handlers) => {
38504
38533
  addAndConvert(cont, KEY_RAW, rawEmitter);
38505
38534
  } else {
38506
38535
  watcher = createFsWatchInstance(
38507
- path9,
38536
+ path10,
38508
38537
  options,
38509
38538
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
38510
38539
  errHandler,
@@ -38519,7 +38548,7 @@ var setFsWatchListener = (path9, fullPath, options, handlers) => {
38519
38548
  cont.watcherUnusable = true;
38520
38549
  if (isWindows && error.code === "EPERM") {
38521
38550
  try {
38522
- const fd = await (0, import_promises7.open)(path9, "r");
38551
+ const fd = await (0, import_promises7.open)(path10, "r");
38523
38552
  await fd.close();
38524
38553
  broadcastErr(error);
38525
38554
  } catch (err) {
@@ -38550,7 +38579,7 @@ var setFsWatchListener = (path9, fullPath, options, handlers) => {
38550
38579
  };
38551
38580
  };
38552
38581
  var FsWatchFileInstances = /* @__PURE__ */ new Map();
38553
- var setFsWatchFileListener = (path9, fullPath, options, handlers) => {
38582
+ var setFsWatchFileListener = (path10, fullPath, options, handlers) => {
38554
38583
  const { listener, rawEmitter } = handlers;
38555
38584
  let cont = FsWatchFileInstances.get(fullPath);
38556
38585
  const copts = cont && cont.options;
@@ -38572,7 +38601,7 @@ var setFsWatchFileListener = (path9, fullPath, options, handlers) => {
38572
38601
  });
38573
38602
  const currmtime = curr.mtimeMs;
38574
38603
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
38575
- foreach(cont.listeners, (listener2) => listener2(path9, curr));
38604
+ foreach(cont.listeners, (listener2) => listener2(path10, curr));
38576
38605
  }
38577
38606
  })
38578
38607
  };
@@ -38602,13 +38631,13 @@ var NodeFsHandler = class {
38602
38631
  * @param listener on fs change
38603
38632
  * @returns closer for the watcher instance
38604
38633
  */
38605
- _watchWithNodeFs(path9, listener) {
38634
+ _watchWithNodeFs(path10, listener) {
38606
38635
  const opts = this.fsw.options;
38607
- const directory = sp.dirname(path9);
38608
- const basename4 = sp.basename(path9);
38636
+ const directory = sp.dirname(path10);
38637
+ const basename4 = sp.basename(path10);
38609
38638
  const parent = this.fsw._getWatchedDir(directory);
38610
38639
  parent.add(basename4);
38611
- const absolutePath = sp.resolve(path9);
38640
+ const absolutePath = sp.resolve(path10);
38612
38641
  const options = {
38613
38642
  persistent: opts.persistent
38614
38643
  };
@@ -38618,12 +38647,12 @@ var NodeFsHandler = class {
38618
38647
  if (opts.usePolling) {
38619
38648
  const enableBin = opts.interval !== opts.binaryInterval;
38620
38649
  options.interval = enableBin && isBinaryPath(basename4) ? opts.binaryInterval : opts.interval;
38621
- closer = setFsWatchFileListener(path9, absolutePath, options, {
38650
+ closer = setFsWatchFileListener(path10, absolutePath, options, {
38622
38651
  listener,
38623
38652
  rawEmitter: this.fsw._emitRaw
38624
38653
  });
38625
38654
  } else {
38626
- closer = setFsWatchListener(path9, absolutePath, options, {
38655
+ closer = setFsWatchListener(path10, absolutePath, options, {
38627
38656
  listener,
38628
38657
  errHandler: this._boundHandleError,
38629
38658
  rawEmitter: this.fsw._emitRaw
@@ -38645,7 +38674,7 @@ var NodeFsHandler = class {
38645
38674
  let prevStats = stats;
38646
38675
  if (parent.has(basename4))
38647
38676
  return;
38648
- const listener = async (path9, newStats) => {
38677
+ const listener = async (path10, newStats) => {
38649
38678
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
38650
38679
  return;
38651
38680
  if (!newStats || newStats.mtimeMs === 0) {
@@ -38659,11 +38688,11 @@ var NodeFsHandler = class {
38659
38688
  this.fsw._emit(EV.CHANGE, file, newStats2);
38660
38689
  }
38661
38690
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
38662
- this.fsw._closeFile(path9);
38691
+ this.fsw._closeFile(path10);
38663
38692
  prevStats = newStats2;
38664
38693
  const closer2 = this._watchWithNodeFs(file, listener);
38665
38694
  if (closer2)
38666
- this.fsw._addPathCloser(path9, closer2);
38695
+ this.fsw._addPathCloser(path10, closer2);
38667
38696
  } else {
38668
38697
  prevStats = newStats2;
38669
38698
  }
@@ -38695,7 +38724,7 @@ var NodeFsHandler = class {
38695
38724
  * @param item basename of this item
38696
38725
  * @returns true if no more processing is needed for this entry.
38697
38726
  */
38698
- async _handleSymlink(entry, directory, path9, item) {
38727
+ async _handleSymlink(entry, directory, path10, item) {
38699
38728
  if (this.fsw.closed) {
38700
38729
  return;
38701
38730
  }
@@ -38705,7 +38734,7 @@ var NodeFsHandler = class {
38705
38734
  this.fsw._incrReadyCount();
38706
38735
  let linkPath;
38707
38736
  try {
38708
- linkPath = await (0, import_promises7.realpath)(path9);
38737
+ linkPath = await (0, import_promises7.realpath)(path10);
38709
38738
  } catch (e) {
38710
38739
  this.fsw._emitReady();
38711
38740
  return true;
@@ -38715,12 +38744,12 @@ var NodeFsHandler = class {
38715
38744
  if (dir.has(item)) {
38716
38745
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
38717
38746
  this.fsw._symlinkPaths.set(full, linkPath);
38718
- this.fsw._emit(EV.CHANGE, path9, entry.stats);
38747
+ this.fsw._emit(EV.CHANGE, path10, entry.stats);
38719
38748
  }
38720
38749
  } else {
38721
38750
  dir.add(item);
38722
38751
  this.fsw._symlinkPaths.set(full, linkPath);
38723
- this.fsw._emit(EV.ADD, path9, entry.stats);
38752
+ this.fsw._emit(EV.ADD, path10, entry.stats);
38724
38753
  }
38725
38754
  this.fsw._emitReady();
38726
38755
  return true;
@@ -38750,9 +38779,9 @@ var NodeFsHandler = class {
38750
38779
  return;
38751
38780
  }
38752
38781
  const item = entry.path;
38753
- let path9 = sp.join(directory, item);
38782
+ let path10 = sp.join(directory, item);
38754
38783
  current.add(item);
38755
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path9, item)) {
38784
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path10, item)) {
38756
38785
  return;
38757
38786
  }
38758
38787
  if (this.fsw.closed) {
@@ -38761,8 +38790,8 @@ var NodeFsHandler = class {
38761
38790
  }
38762
38791
  if (item === target || !target && !previous.has(item)) {
38763
38792
  this.fsw._incrReadyCount();
38764
- path9 = sp.join(dir, sp.relative(dir, path9));
38765
- this._addToNodeFs(path9, initialAdd, wh, depth + 1);
38793
+ path10 = sp.join(dir, sp.relative(dir, path10));
38794
+ this._addToNodeFs(path10, initialAdd, wh, depth + 1);
38766
38795
  }
38767
38796
  }).on(EV.ERROR, this._boundHandleError);
38768
38797
  return new Promise((resolve11, reject) => {
@@ -38831,13 +38860,13 @@ var NodeFsHandler = class {
38831
38860
  * @param depth Child path actually targeted for watch
38832
38861
  * @param target Child path actually targeted for watch
38833
38862
  */
38834
- async _addToNodeFs(path9, initialAdd, priorWh, depth, target) {
38863
+ async _addToNodeFs(path10, initialAdd, priorWh, depth, target) {
38835
38864
  const ready = this.fsw._emitReady;
38836
- if (this.fsw._isIgnored(path9) || this.fsw.closed) {
38865
+ if (this.fsw._isIgnored(path10) || this.fsw.closed) {
38837
38866
  ready();
38838
38867
  return false;
38839
38868
  }
38840
- const wh = this.fsw._getWatchHelpers(path9);
38869
+ const wh = this.fsw._getWatchHelpers(path10);
38841
38870
  if (priorWh) {
38842
38871
  wh.filterPath = (entry) => priorWh.filterPath(entry);
38843
38872
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -38853,8 +38882,8 @@ var NodeFsHandler = class {
38853
38882
  const follow = this.fsw.options.followSymlinks;
38854
38883
  let closer;
38855
38884
  if (stats.isDirectory()) {
38856
- const absPath = sp.resolve(path9);
38857
- const targetPath = follow ? await (0, import_promises7.realpath)(path9) : path9;
38885
+ const absPath = sp.resolve(path10);
38886
+ const targetPath = follow ? await (0, import_promises7.realpath)(path10) : path10;
38858
38887
  if (this.fsw.closed)
38859
38888
  return;
38860
38889
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -38864,29 +38893,29 @@ var NodeFsHandler = class {
38864
38893
  this.fsw._symlinkPaths.set(absPath, targetPath);
38865
38894
  }
38866
38895
  } else if (stats.isSymbolicLink()) {
38867
- const targetPath = follow ? await (0, import_promises7.realpath)(path9) : path9;
38896
+ const targetPath = follow ? await (0, import_promises7.realpath)(path10) : path10;
38868
38897
  if (this.fsw.closed)
38869
38898
  return;
38870
38899
  const parent = sp.dirname(wh.watchPath);
38871
38900
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
38872
38901
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
38873
- closer = await this._handleDir(parent, stats, initialAdd, depth, path9, wh, targetPath);
38902
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path10, wh, targetPath);
38874
38903
  if (this.fsw.closed)
38875
38904
  return;
38876
38905
  if (targetPath !== void 0) {
38877
- this.fsw._symlinkPaths.set(sp.resolve(path9), targetPath);
38906
+ this.fsw._symlinkPaths.set(sp.resolve(path10), targetPath);
38878
38907
  }
38879
38908
  } else {
38880
38909
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
38881
38910
  }
38882
38911
  ready();
38883
38912
  if (closer)
38884
- this.fsw._addPathCloser(path9, closer);
38913
+ this.fsw._addPathCloser(path10, closer);
38885
38914
  return false;
38886
38915
  } catch (error) {
38887
38916
  if (this.fsw._handleError(error)) {
38888
38917
  ready();
38889
- return path9;
38918
+ return path10;
38890
38919
  }
38891
38920
  }
38892
38921
  }
@@ -38929,24 +38958,24 @@ function createPattern(matcher) {
38929
38958
  }
38930
38959
  return () => false;
38931
38960
  }
38932
- function normalizePath(path9) {
38933
- if (typeof path9 !== "string")
38961
+ function normalizePath(path10) {
38962
+ if (typeof path10 !== "string")
38934
38963
  throw new Error("string expected");
38935
- path9 = sp2.normalize(path9);
38936
- path9 = path9.replace(/\\/g, "/");
38964
+ path10 = sp2.normalize(path10);
38965
+ path10 = path10.replace(/\\/g, "/");
38937
38966
  let prepend = false;
38938
- if (path9.startsWith("//"))
38967
+ if (path10.startsWith("//"))
38939
38968
  prepend = true;
38940
- path9 = path9.replace(DOUBLE_SLASH_RE, "/");
38969
+ path10 = path10.replace(DOUBLE_SLASH_RE, "/");
38941
38970
  if (prepend)
38942
- path9 = "/" + path9;
38943
- return path9;
38971
+ path10 = "/" + path10;
38972
+ return path10;
38944
38973
  }
38945
38974
  function matchPatterns(patterns, testString, stats) {
38946
- const path9 = normalizePath(testString);
38975
+ const path10 = normalizePath(testString);
38947
38976
  for (let index = 0; index < patterns.length; index++) {
38948
38977
  const pattern = patterns[index];
38949
- if (pattern(path9, stats)) {
38978
+ if (pattern(path10, stats)) {
38950
38979
  return true;
38951
38980
  }
38952
38981
  }
@@ -38984,19 +39013,19 @@ var toUnix = (string) => {
38984
39013
  }
38985
39014
  return str;
38986
39015
  };
38987
- var normalizePathToUnix = (path9) => toUnix(sp2.normalize(toUnix(path9)));
38988
- var normalizeIgnored = (cwd = "") => (path9) => {
38989
- if (typeof path9 === "string") {
38990
- return normalizePathToUnix(sp2.isAbsolute(path9) ? path9 : sp2.join(cwd, path9));
39016
+ var normalizePathToUnix = (path10) => toUnix(sp2.normalize(toUnix(path10)));
39017
+ var normalizeIgnored = (cwd = "") => (path10) => {
39018
+ if (typeof path10 === "string") {
39019
+ return normalizePathToUnix(sp2.isAbsolute(path10) ? path10 : sp2.join(cwd, path10));
38991
39020
  } else {
38992
- return path9;
39021
+ return path10;
38993
39022
  }
38994
39023
  };
38995
- var getAbsolutePath = (path9, cwd) => {
38996
- if (sp2.isAbsolute(path9)) {
38997
- return path9;
39024
+ var getAbsolutePath = (path10, cwd) => {
39025
+ if (sp2.isAbsolute(path10)) {
39026
+ return path10;
38998
39027
  }
38999
- return sp2.join(cwd, path9);
39028
+ return sp2.join(cwd, path10);
39000
39029
  };
39001
39030
  var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
39002
39031
  var DirEntry = class {
@@ -39061,10 +39090,10 @@ var WatchHelper = class {
39061
39090
  dirParts;
39062
39091
  followSymlinks;
39063
39092
  statMethod;
39064
- constructor(path9, follow, fsw) {
39093
+ constructor(path10, follow, fsw) {
39065
39094
  this.fsw = fsw;
39066
- const watchPath = path9;
39067
- this.path = path9 = path9.replace(REPLACER_RE, "");
39095
+ const watchPath = path10;
39096
+ this.path = path10 = path10.replace(REPLACER_RE, "");
39068
39097
  this.watchPath = watchPath;
39069
39098
  this.fullWatchPath = sp2.resolve(watchPath);
39070
39099
  this.dirParts = [];
@@ -39204,20 +39233,20 @@ var FSWatcher = class extends import_node_events.EventEmitter {
39204
39233
  this._closePromise = void 0;
39205
39234
  let paths = unifyPaths(paths_);
39206
39235
  if (cwd) {
39207
- paths = paths.map((path9) => {
39208
- const absPath = getAbsolutePath(path9, cwd);
39236
+ paths = paths.map((path10) => {
39237
+ const absPath = getAbsolutePath(path10, cwd);
39209
39238
  return absPath;
39210
39239
  });
39211
39240
  }
39212
- paths.forEach((path9) => {
39213
- this._removeIgnoredPath(path9);
39241
+ paths.forEach((path10) => {
39242
+ this._removeIgnoredPath(path10);
39214
39243
  });
39215
39244
  this._userIgnored = void 0;
39216
39245
  if (!this._readyCount)
39217
39246
  this._readyCount = 0;
39218
39247
  this._readyCount += paths.length;
39219
- Promise.all(paths.map(async (path9) => {
39220
- const res = await this._nodeFsHandler._addToNodeFs(path9, !_internal, void 0, 0, _origAdd);
39248
+ Promise.all(paths.map(async (path10) => {
39249
+ const res = await this._nodeFsHandler._addToNodeFs(path10, !_internal, void 0, 0, _origAdd);
39221
39250
  if (res)
39222
39251
  this._emitReady();
39223
39252
  return res;
@@ -39239,17 +39268,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
39239
39268
  return this;
39240
39269
  const paths = unifyPaths(paths_);
39241
39270
  const { cwd } = this.options;
39242
- paths.forEach((path9) => {
39243
- if (!sp2.isAbsolute(path9) && !this._closers.has(path9)) {
39271
+ paths.forEach((path10) => {
39272
+ if (!sp2.isAbsolute(path10) && !this._closers.has(path10)) {
39244
39273
  if (cwd)
39245
- path9 = sp2.join(cwd, path9);
39246
- path9 = sp2.resolve(path9);
39274
+ path10 = sp2.join(cwd, path10);
39275
+ path10 = sp2.resolve(path10);
39247
39276
  }
39248
- this._closePath(path9);
39249
- this._addIgnoredPath(path9);
39250
- if (this._watched.has(path9)) {
39277
+ this._closePath(path10);
39278
+ this._addIgnoredPath(path10);
39279
+ if (this._watched.has(path10)) {
39251
39280
  this._addIgnoredPath({
39252
- path: path9,
39281
+ path: path10,
39253
39282
  recursive: true
39254
39283
  });
39255
39284
  }
@@ -39313,38 +39342,38 @@ var FSWatcher = class extends import_node_events.EventEmitter {
39313
39342
  * @param stats arguments to be passed with event
39314
39343
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
39315
39344
  */
39316
- async _emit(event, path9, stats) {
39345
+ async _emit(event, path10, stats) {
39317
39346
  if (this.closed)
39318
39347
  return;
39319
39348
  const opts = this.options;
39320
39349
  if (isWindows)
39321
- path9 = sp2.normalize(path9);
39350
+ path10 = sp2.normalize(path10);
39322
39351
  if (opts.cwd)
39323
- path9 = sp2.relative(opts.cwd, path9);
39324
- const args = [path9];
39352
+ path10 = sp2.relative(opts.cwd, path10);
39353
+ const args = [path10];
39325
39354
  if (stats != null)
39326
39355
  args.push(stats);
39327
39356
  const awf = opts.awaitWriteFinish;
39328
39357
  let pw;
39329
- if (awf && (pw = this._pendingWrites.get(path9))) {
39358
+ if (awf && (pw = this._pendingWrites.get(path10))) {
39330
39359
  pw.lastChange = /* @__PURE__ */ new Date();
39331
39360
  return this;
39332
39361
  }
39333
39362
  if (opts.atomic) {
39334
39363
  if (event === EVENTS.UNLINK) {
39335
- this._pendingUnlinks.set(path9, [event, ...args]);
39364
+ this._pendingUnlinks.set(path10, [event, ...args]);
39336
39365
  setTimeout(() => {
39337
- this._pendingUnlinks.forEach((entry, path10) => {
39366
+ this._pendingUnlinks.forEach((entry, path11) => {
39338
39367
  this.emit(...entry);
39339
39368
  this.emit(EVENTS.ALL, ...entry);
39340
- this._pendingUnlinks.delete(path10);
39369
+ this._pendingUnlinks.delete(path11);
39341
39370
  });
39342
39371
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
39343
39372
  return this;
39344
39373
  }
39345
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path9)) {
39374
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path10)) {
39346
39375
  event = EVENTS.CHANGE;
39347
- this._pendingUnlinks.delete(path9);
39376
+ this._pendingUnlinks.delete(path10);
39348
39377
  }
39349
39378
  }
39350
39379
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -39362,16 +39391,16 @@ var FSWatcher = class extends import_node_events.EventEmitter {
39362
39391
  this.emitWithAll(event, args);
39363
39392
  }
39364
39393
  };
39365
- this._awaitWriteFinish(path9, awf.stabilityThreshold, event, awfEmit);
39394
+ this._awaitWriteFinish(path10, awf.stabilityThreshold, event, awfEmit);
39366
39395
  return this;
39367
39396
  }
39368
39397
  if (event === EVENTS.CHANGE) {
39369
- const isThrottled = !this._throttle(EVENTS.CHANGE, path9, 50);
39398
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path10, 50);
39370
39399
  if (isThrottled)
39371
39400
  return this;
39372
39401
  }
39373
39402
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
39374
- const fullPath = opts.cwd ? sp2.join(opts.cwd, path9) : path9;
39403
+ const fullPath = opts.cwd ? sp2.join(opts.cwd, path10) : path10;
39375
39404
  let stats2;
39376
39405
  try {
39377
39406
  stats2 = await (0, import_promises8.stat)(fullPath);
@@ -39402,23 +39431,23 @@ var FSWatcher = class extends import_node_events.EventEmitter {
39402
39431
  * @param timeout duration of time to suppress duplicate actions
39403
39432
  * @returns tracking object or false if action should be suppressed
39404
39433
  */
39405
- _throttle(actionType, path9, timeout) {
39434
+ _throttle(actionType, path10, timeout) {
39406
39435
  if (!this._throttled.has(actionType)) {
39407
39436
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
39408
39437
  }
39409
39438
  const action = this._throttled.get(actionType);
39410
39439
  if (!action)
39411
39440
  throw new Error("invalid throttle");
39412
- const actionPath = action.get(path9);
39441
+ const actionPath = action.get(path10);
39413
39442
  if (actionPath) {
39414
39443
  actionPath.count++;
39415
39444
  return false;
39416
39445
  }
39417
39446
  let timeoutObject;
39418
39447
  const clear = () => {
39419
- const item = action.get(path9);
39448
+ const item = action.get(path10);
39420
39449
  const count = item ? item.count : 0;
39421
- action.delete(path9);
39450
+ action.delete(path10);
39422
39451
  clearTimeout(timeoutObject);
39423
39452
  if (item)
39424
39453
  clearTimeout(item.timeoutObject);
@@ -39426,7 +39455,7 @@ var FSWatcher = class extends import_node_events.EventEmitter {
39426
39455
  };
39427
39456
  timeoutObject = setTimeout(clear, timeout);
39428
39457
  const thr = { timeoutObject, clear, count: 0 };
39429
- action.set(path9, thr);
39458
+ action.set(path10, thr);
39430
39459
  return thr;
39431
39460
  }
39432
39461
  _incrReadyCount() {
@@ -39440,44 +39469,44 @@ var FSWatcher = class extends import_node_events.EventEmitter {
39440
39469
  * @param event
39441
39470
  * @param awfEmit Callback to be called when ready for event to be emitted.
39442
39471
  */
39443
- _awaitWriteFinish(path9, threshold, event, awfEmit) {
39472
+ _awaitWriteFinish(path10, threshold, event, awfEmit) {
39444
39473
  const awf = this.options.awaitWriteFinish;
39445
39474
  if (typeof awf !== "object")
39446
39475
  return;
39447
39476
  const pollInterval = awf.pollInterval;
39448
39477
  let timeoutHandler;
39449
- let fullPath = path9;
39450
- if (this.options.cwd && !sp2.isAbsolute(path9)) {
39451
- fullPath = sp2.join(this.options.cwd, path9);
39478
+ let fullPath = path10;
39479
+ if (this.options.cwd && !sp2.isAbsolute(path10)) {
39480
+ fullPath = sp2.join(this.options.cwd, path10);
39452
39481
  }
39453
39482
  const now = /* @__PURE__ */ new Date();
39454
39483
  const writes = this._pendingWrites;
39455
39484
  function awaitWriteFinishFn(prevStat) {
39456
39485
  (0, import_node_fs2.stat)(fullPath, (err, curStat) => {
39457
- if (err || !writes.has(path9)) {
39486
+ if (err || !writes.has(path10)) {
39458
39487
  if (err && err.code !== "ENOENT")
39459
39488
  awfEmit(err);
39460
39489
  return;
39461
39490
  }
39462
39491
  const now2 = Number(/* @__PURE__ */ new Date());
39463
39492
  if (prevStat && curStat.size !== prevStat.size) {
39464
- writes.get(path9).lastChange = now2;
39493
+ writes.get(path10).lastChange = now2;
39465
39494
  }
39466
- const pw = writes.get(path9);
39495
+ const pw = writes.get(path10);
39467
39496
  const df = now2 - pw.lastChange;
39468
39497
  if (df >= threshold) {
39469
- writes.delete(path9);
39498
+ writes.delete(path10);
39470
39499
  awfEmit(void 0, curStat);
39471
39500
  } else {
39472
39501
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
39473
39502
  }
39474
39503
  });
39475
39504
  }
39476
- if (!writes.has(path9)) {
39477
- writes.set(path9, {
39505
+ if (!writes.has(path10)) {
39506
+ writes.set(path10, {
39478
39507
  lastChange: now,
39479
39508
  cancelWait: () => {
39480
- writes.delete(path9);
39509
+ writes.delete(path10);
39481
39510
  clearTimeout(timeoutHandler);
39482
39511
  return event;
39483
39512
  }
@@ -39488,8 +39517,8 @@ var FSWatcher = class extends import_node_events.EventEmitter {
39488
39517
  /**
39489
39518
  * Determines whether user has asked to ignore this path.
39490
39519
  */
39491
- _isIgnored(path9, stats) {
39492
- if (this.options.atomic && DOT_RE.test(path9))
39520
+ _isIgnored(path10, stats) {
39521
+ if (this.options.atomic && DOT_RE.test(path10))
39493
39522
  return true;
39494
39523
  if (!this._userIgnored) {
39495
39524
  const { cwd } = this.options;
@@ -39499,17 +39528,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
39499
39528
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
39500
39529
  this._userIgnored = anymatch(list, void 0);
39501
39530
  }
39502
- return this._userIgnored(path9, stats);
39531
+ return this._userIgnored(path10, stats);
39503
39532
  }
39504
- _isntIgnored(path9, stat9) {
39505
- return !this._isIgnored(path9, stat9);
39533
+ _isntIgnored(path10, stat9) {
39534
+ return !this._isIgnored(path10, stat9);
39506
39535
  }
39507
39536
  /**
39508
39537
  * Provides a set of common helpers and properties relating to symlink handling.
39509
39538
  * @param path file or directory pattern being watched
39510
39539
  */
39511
- _getWatchHelpers(path9) {
39512
- return new WatchHelper(path9, this.options.followSymlinks, this);
39540
+ _getWatchHelpers(path10) {
39541
+ return new WatchHelper(path10, this.options.followSymlinks, this);
39513
39542
  }
39514
39543
  // Directory helpers
39515
39544
  // -----------------
@@ -39541,63 +39570,63 @@ var FSWatcher = class extends import_node_events.EventEmitter {
39541
39570
  * @param item base path of item/directory
39542
39571
  */
39543
39572
  _remove(directory, item, isDirectory) {
39544
- const path9 = sp2.join(directory, item);
39545
- const fullPath = sp2.resolve(path9);
39546
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path9) || this._watched.has(fullPath);
39547
- if (!this._throttle("remove", path9, 100))
39573
+ const path10 = sp2.join(directory, item);
39574
+ const fullPath = sp2.resolve(path10);
39575
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path10) || this._watched.has(fullPath);
39576
+ if (!this._throttle("remove", path10, 100))
39548
39577
  return;
39549
39578
  if (!isDirectory && this._watched.size === 1) {
39550
39579
  this.add(directory, item, true);
39551
39580
  }
39552
- const wp = this._getWatchedDir(path9);
39581
+ const wp = this._getWatchedDir(path10);
39553
39582
  const nestedDirectoryChildren = wp.getChildren();
39554
- nestedDirectoryChildren.forEach((nested) => this._remove(path9, nested));
39583
+ nestedDirectoryChildren.forEach((nested) => this._remove(path10, nested));
39555
39584
  const parent = this._getWatchedDir(directory);
39556
39585
  const wasTracked = parent.has(item);
39557
39586
  parent.remove(item);
39558
39587
  if (this._symlinkPaths.has(fullPath)) {
39559
39588
  this._symlinkPaths.delete(fullPath);
39560
39589
  }
39561
- let relPath = path9;
39590
+ let relPath = path10;
39562
39591
  if (this.options.cwd)
39563
- relPath = sp2.relative(this.options.cwd, path9);
39592
+ relPath = sp2.relative(this.options.cwd, path10);
39564
39593
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
39565
39594
  const event = this._pendingWrites.get(relPath).cancelWait();
39566
39595
  if (event === EVENTS.ADD)
39567
39596
  return;
39568
39597
  }
39569
- this._watched.delete(path9);
39598
+ this._watched.delete(path10);
39570
39599
  this._watched.delete(fullPath);
39571
39600
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
39572
- if (wasTracked && !this._isIgnored(path9))
39573
- this._emit(eventName, path9);
39574
- this._closePath(path9);
39601
+ if (wasTracked && !this._isIgnored(path10))
39602
+ this._emit(eventName, path10);
39603
+ this._closePath(path10);
39575
39604
  }
39576
39605
  /**
39577
39606
  * Closes all watchers for a path
39578
39607
  */
39579
- _closePath(path9) {
39580
- this._closeFile(path9);
39581
- const dir = sp2.dirname(path9);
39582
- this._getWatchedDir(dir).remove(sp2.basename(path9));
39608
+ _closePath(path10) {
39609
+ this._closeFile(path10);
39610
+ const dir = sp2.dirname(path10);
39611
+ this._getWatchedDir(dir).remove(sp2.basename(path10));
39583
39612
  }
39584
39613
  /**
39585
39614
  * Closes only file-specific watchers
39586
39615
  */
39587
- _closeFile(path9) {
39588
- const closers = this._closers.get(path9);
39616
+ _closeFile(path10) {
39617
+ const closers = this._closers.get(path10);
39589
39618
  if (!closers)
39590
39619
  return;
39591
39620
  closers.forEach((closer) => closer());
39592
- this._closers.delete(path9);
39621
+ this._closers.delete(path10);
39593
39622
  }
39594
- _addPathCloser(path9, closer) {
39623
+ _addPathCloser(path10, closer) {
39595
39624
  if (!closer)
39596
39625
  return;
39597
- let list = this._closers.get(path9);
39626
+ let list = this._closers.get(path10);
39598
39627
  if (!list) {
39599
39628
  list = [];
39600
- this._closers.set(path9, list);
39629
+ this._closers.set(path10, list);
39601
39630
  }
39602
39631
  list.push(closer);
39603
39632
  }
@@ -40119,44 +40148,79 @@ var imageUnderstand = {
40119
40148
  };
40120
40149
 
40121
40150
  // src/skill/SkillRegistry.ts
40122
- var import_fs8 = require("fs");
40151
+ var import_fs9 = require("fs");
40123
40152
  var import_os3 = require("os");
40153
+ var import_path15 = __toESM(require("path"));
40154
+
40155
+ // src/runtime/paths.ts
40156
+ var import_fs8 = require("fs");
40124
40157
  var import_path14 = __toESM(require("path"));
40125
- var getSkillPaths = () => {
40126
- const paths = [];
40127
- let currentDir = __dirname_m;
40128
- let projectRoot = "";
40129
- while (currentDir !== "/") {
40130
- if ((0, import_fs8.existsSync)((0, import_path14.join)(currentDir, "duclaw.json"))) {
40131
- projectRoot = currentDir;
40132
- break;
40158
+ var findProjectRoot = (filename = "duclaw.json", startDir = process.cwd()) => {
40159
+ let currentDir = startDir;
40160
+ while (true) {
40161
+ if ((0, import_fs8.existsSync)((0, import_path14.join)(currentDir, filename))) {
40162
+ return currentDir;
40133
40163
  }
40134
40164
  const parentDir = (0, import_path14.dirname)(currentDir);
40135
- if (parentDir === currentDir) break;
40165
+ if (parentDir === currentDir) {
40166
+ return null;
40167
+ }
40136
40168
  currentDir = parentDir;
40137
40169
  }
40170
+ };
40171
+ var resolveCoreRoot = () => {
40172
+ const candidates = [
40173
+ import_path14.default.resolve(__dirname_m, ".."),
40174
+ import_path14.default.resolve(__dirname_m, "..", ".."),
40175
+ process.cwd()
40176
+ ];
40177
+ for (const candidate of candidates) {
40178
+ if ((0, import_fs8.existsSync)(import_path14.default.join(candidate, "web", "dist", "index.html"))) {
40179
+ return candidate;
40180
+ }
40181
+ }
40182
+ return candidates[0];
40183
+ };
40184
+ var resolveWebDistRoot = () => {
40185
+ const coreRoot = resolveCoreRoot();
40186
+ const candidates = [
40187
+ import_path14.default.join(coreRoot, "dist", "web"),
40188
+ import_path14.default.join(coreRoot, "web", "dist")
40189
+ ];
40190
+ for (const candidate of candidates) {
40191
+ if ((0, import_fs8.existsSync)(import_path14.default.join(candidate, "index.html"))) {
40192
+ return candidate;
40193
+ }
40194
+ }
40195
+ return candidates[0];
40196
+ };
40197
+
40198
+ // src/skill/SkillRegistry.ts
40199
+ var getSkillPaths = () => {
40200
+ const paths = [];
40201
+ const projectRoot = findProjectRoot();
40138
40202
  if (projectRoot) {
40139
- const rootSkillsPath = (0, import_path14.join)(projectRoot, "skills");
40140
- if ((0, import_fs8.existsSync)(rootSkillsPath) && (0, import_fs8.statSync)(rootSkillsPath).isDirectory()) {
40203
+ const rootSkillsPath = (0, import_path15.join)(projectRoot, "skills");
40204
+ if ((0, import_fs9.existsSync)(rootSkillsPath) && (0, import_fs9.statSync)(rootSkillsPath).isDirectory()) {
40141
40205
  paths.push(rootSkillsPath);
40142
40206
  }
40143
40207
  }
40144
- const duclawSkillsPath = (0, import_path14.join)((0, import_os3.homedir)(), ".duclaw", "skills");
40145
- if ((0, import_fs8.existsSync)(duclawSkillsPath) && (0, import_fs8.statSync)(duclawSkillsPath).isDirectory()) {
40208
+ const duclawSkillsPath = (0, import_path15.join)((0, import_os3.homedir)(), ".duclaw", "skills");
40209
+ if ((0, import_fs9.existsSync)(duclawSkillsPath) && (0, import_fs9.statSync)(duclawSkillsPath).isDirectory()) {
40146
40210
  paths.push(duclawSkillsPath);
40147
40211
  }
40148
- const agentsSkillsPath = (0, import_path14.join)((0, import_os3.homedir)(), ".agents", "skills");
40149
- if ((0, import_fs8.existsSync)(agentsSkillsPath) && (0, import_fs8.statSync)(agentsSkillsPath).isDirectory()) {
40212
+ const agentsSkillsPath = (0, import_path15.join)((0, import_os3.homedir)(), ".agents", "skills");
40213
+ if ((0, import_fs9.existsSync)(agentsSkillsPath) && (0, import_fs9.statSync)(agentsSkillsPath).isDirectory()) {
40150
40214
  paths.push(agentsSkillsPath);
40151
40215
  }
40152
40216
  return paths;
40153
40217
  };
40154
40218
  var getDirectories = (dirPath) => {
40155
- return (0, import_fs8.readdirSync)(dirPath).filter((name) => (0, import_fs8.statSync)((0, import_path14.join)(dirPath, name)).isDirectory());
40219
+ return (0, import_fs9.readdirSync)(dirPath).filter((name) => (0, import_fs9.statSync)((0, import_path15.join)(dirPath, name)).isDirectory());
40156
40220
  };
40157
40221
  var parseSkill = (mdPath, skillDir) => {
40158
- if (!(0, import_fs8.existsSync)(mdPath)) return null;
40159
- const raw2 = (0, import_fs8.readFileSync)(mdPath, "utf-8");
40222
+ if (!(0, import_fs9.existsSync)(mdPath)) return null;
40223
+ const raw2 = (0, import_fs9.readFileSync)(mdPath, "utf-8");
40160
40224
  let name = "";
40161
40225
  let description = "";
40162
40226
  let body = raw2;
@@ -40172,7 +40236,7 @@ var parseSkill = (mdPath, skillDir) => {
40172
40236
  }
40173
40237
  }
40174
40238
  if (!name) {
40175
- name = import_path14.default.basename(import_path14.default.dirname(mdPath));
40239
+ name = import_path15.default.basename(import_path15.default.dirname(mdPath));
40176
40240
  }
40177
40241
  if (!description && body) {
40178
40242
  description = body.split("\n")[0].replace(/^#+\s*/, "").trim();
@@ -40197,8 +40261,8 @@ var loadSkill = () => {
40197
40261
  for (const skillPath of skillPaths) {
40198
40262
  const dirs = getDirectories(skillPath);
40199
40263
  for (const skillName of dirs) {
40200
- const eachSkillPath = (0, import_path14.join)(skillPath, skillName);
40201
- const eachSkillMdPath = (0, import_path14.join)(eachSkillPath, "SKILL.md");
40264
+ const eachSkillPath = (0, import_path15.join)(skillPath, skillName);
40265
+ const eachSkillMdPath = (0, import_path15.join)(eachSkillPath, "SKILL.md");
40202
40266
  const skill = parseSkill(eachSkillMdPath, eachSkillPath);
40203
40267
  if (skill && !seen.has(skill.name)) {
40204
40268
  seen.add(skill.name);
@@ -40550,14 +40614,15 @@ var create_mailbox_table = () => {
40550
40614
  };
40551
40615
 
40552
40616
  // src/team/TeamMember.ts
40553
- var import_fs10 = require("fs");
40554
- var import_path16 = __toESM(require("path"));
40617
+ var import_fs11 = require("fs");
40618
+ var import_path17 = __toESM(require("path"));
40555
40619
 
40556
40620
  // src/team/Team.ts
40557
- var import_path15 = __toESM(require("path"));
40558
- var import_fs9 = require("fs");
40621
+ var import_path16 = __toESM(require("path"));
40622
+ var import_os4 = require("os");
40623
+ var import_fs10 = require("fs");
40559
40624
  var getTeamBaseDir = () => {
40560
- return `~/.duclaw/team`;
40625
+ return import_path16.default.join((0, import_os4.homedir)(), ".duclaw", "team");
40561
40626
  };
40562
40627
  var getTeamWorkSpaceDir = (teamName) => {
40563
40628
  return `${getTeamBaseDir()}/workspace/${teamName}`;
@@ -40568,22 +40633,22 @@ var getTeamJsonPath = (teamName) => {
40568
40633
  var createTeam = (teamDefinition) => {
40569
40634
  if (!teamDefinition) throw new Error(`[createTeam] teamDefinition\u4E0D\u80FD\u4E3A\u7A7A`);
40570
40635
  const { id, name, goalId, teamMembers } = teamDefinition;
40571
- const teamPath = import_path15.default.join(getTeamWorkSpaceDir(name));
40572
- (0, import_fs9.mkdirSync)(teamPath, { recursive: true });
40573
- (0, import_fs9.writeFileSync)(`${teamPath}/team.json`, JSON.stringify(teamDefinition, null, " "), "utf-8");
40636
+ const teamPath = import_path16.default.join(getTeamWorkSpaceDir(name));
40637
+ (0, import_fs10.mkdirSync)(teamPath, { recursive: true });
40638
+ (0, import_fs10.writeFileSync)(`${teamPath}/team.json`, JSON.stringify(teamDefinition, null, " "), "utf-8");
40574
40639
  return teamDefinition;
40575
40640
  };
40576
40641
  var getTeam = (name) => {
40577
40642
  const teamJsonPath = getTeamJsonPath(name);
40578
- if (!(0, import_fs9.existsSync)(teamJsonPath)) return null;
40579
- const text2 = (0, import_fs9.readFileSync)(teamJsonPath, `utf-8`);
40643
+ if (!(0, import_fs10.existsSync)(teamJsonPath)) return null;
40644
+ const text2 = (0, import_fs10.readFileSync)(teamJsonPath, `utf-8`);
40580
40645
  const obj = JSON.parse(text2) || {};
40581
40646
  const team = obj;
40582
40647
  return team;
40583
40648
  };
40584
40649
  var listTeams = () => {
40585
40650
  const baseDir = getTeamBaseDir();
40586
- const teamnames = (0, import_fs9.readdirSync)(import_path15.default.join(baseDir, `workspace`));
40651
+ const teamnames = (0, import_fs10.readdirSync)(import_path16.default.join(baseDir, `workspace`));
40587
40652
  const teams = [];
40588
40653
  for (const teamname of teamnames) {
40589
40654
  const team = getTeam(teamname);
@@ -40600,10 +40665,10 @@ var getTeamById = (id) => {
40600
40665
  return team;
40601
40666
  };
40602
40667
  var deleteTeam = (name) => {
40603
- if (!(0, import_fs9.existsSync)(getTeamJsonPath(name))) {
40668
+ if (!(0, import_fs10.existsSync)(getTeamJsonPath(name))) {
40604
40669
  throw new Error(`[deleteTeam] \u4E0D\u5B58\u5728\u5BF9\u5E94\u7684\u56E2\u961F${name}\u7684team.json\u6587\u4EF6`);
40605
40670
  }
40606
- (0, import_fs9.rmSync)(getTeamJsonPath(name));
40671
+ (0, import_fs10.rmSync)(getTeamJsonPath(name));
40607
40672
  };
40608
40673
 
40609
40674
  // src/team/workspace/workspace.ts
@@ -40631,8 +40696,8 @@ var createTeamMember = (teamMemberDefinition) => {
40631
40696
  const { id, name, teamId, mailBoxId, workspaceId } = teamMemberDefinition;
40632
40697
  const team = getTeamById(teamMemberDefinition.teamId);
40633
40698
  if (!team) throw new Error(`[createTeamMember] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684team: ${teamId}`);
40634
- const memberPath = import_path16.default.join(getTeamWorkSpaceDir(team.name), name);
40635
- (0, import_fs10.mkdirSync)(memberPath, { recursive: true });
40699
+ const memberPath = import_path17.default.join(getTeamWorkSpaceDir(team.name), name);
40700
+ (0, import_fs11.mkdirSync)(memberPath, { recursive: true });
40636
40701
  const workspace = {
40637
40702
  id: getWorkspaceId(team.name, teamMemberDefinition.name),
40638
40703
  teamName: team.name,
@@ -40644,12 +40709,13 @@ var createTeamMember = (teamMemberDefinition) => {
40644
40709
  team.teamMembers = [];
40645
40710
  }
40646
40711
  team.teamMembers.push(teamMemberDefinition);
40647
- (0, import_fs10.writeFileSync)(getTeamJsonPath(team.name), JSON.stringify(team, null, " "), "utf-8");
40712
+ (0, import_fs11.writeFileSync)(getTeamJsonPath(team.name), JSON.stringify(team, null, " "), "utf-8");
40648
40713
  return teamMemberDefinition;
40649
40714
  };
40650
40715
  var listTeamMember = (teamName) => {
40651
40716
  const teamJsonPath = getTeamJsonPath(teamName);
40652
- const text2 = (0, import_fs10.readFileSync)(teamJsonPath, `utf-8`);
40717
+ if (!(0, import_fs11.existsSync)(teamJsonPath)) return [];
40718
+ const text2 = (0, import_fs11.readFileSync)(teamJsonPath, `utf-8`);
40653
40719
  const team = JSON.parse(text2);
40654
40720
  if (!team) throw new Error(`[listTeamMember] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684team: ${teamName}`);
40655
40721
  if (!team.teamMembers) return [];
@@ -40684,7 +40750,7 @@ var deleteTeamMemberById = (teamName, memberId) => {
40684
40750
  const workspaceId = team.teamMembers[memberIdx].workspaceId;
40685
40751
  let newTeamMember = team.teamMembers.filter((_, index) => index !== memberIdx);
40686
40752
  team.teamMembers = newTeamMember;
40687
- (0, import_fs10.writeFileSync)(getTeamJsonPath(teamName), JSON.stringify(team, null, ` `));
40753
+ (0, import_fs11.writeFileSync)(getTeamJsonPath(teamName), JSON.stringify(team, null, ` `));
40688
40754
  deleteWorkspace(workspaceId);
40689
40755
  };
40690
40756
 
@@ -40871,8 +40937,8 @@ var DESCRIPTION22 = `
40871
40937
 
40872
40938
  \u5DE5\u5177\u8C03\u7528\u89C4\u5219\uFF1A
40873
40939
  - \u5F53\u7528\u6237\u8981\u6C42\u5220\u9664\u56E2\u961F\u65F6\u8C03\u7528\u6B64\u5DE5\u5177\u3002
40874
- - \u5F53\u56E2\u961F\u5DF2\u7ECF\u4E0D\u518D\u9700\u8981\u4E3A\u5BF9\u5E94\u76EE\u6807\u800C\u5DE5\u4F5C\u65F6\u3002
40875
- - \u5F53\u56E2\u961F\u5DF2\u7ECF\u6CA1\u6709\u5B58\u5728\u5FC5\u8981\u3002
40940
+ - \u5F53\u56E2\u961F\u5DF2\u7ECF\u4E0D\u518D\u9700\u8981\u4E3A\u5BF9\u5E94\u76EE\u6807\u800C\u5DE5\u4F5C\u65F6\uFF0C\u8BE2\u95EE\u7528\u6237\u662F\u5426\u89E3\u6563\u8BE5\u56E2\u961F\u3002
40941
+ - \u5F53\u56E2\u961F\u5DF2\u7ECF\u6CA1\u6709\u5B58\u5728\u5FC5\u8981\uFF0C\u8BE2\u95EE\u7528\u6237\u662F\u5426\u89E3\u6563\u8BE5\u56E2\u961F\u3002
40876
40942
  `;
40877
40943
  var teamDelete = {
40878
40944
  name: `team_delete`,
@@ -41319,11 +41385,688 @@ var drainInterrupts = (userId) => {
41319
41385
  return messages;
41320
41386
  };
41321
41387
 
41388
+ // src/dream/dreamPrompt.ts
41389
+ var DREAM_MAX_MESSAGE_CHARS = 1e4;
41390
+ var DREAM_SYSTEM_PROMPT = `\u4F60\u662F AI Agent \u7684"\u68A6\u5883\u81EA\u6211"\u3002\u4F60\u7684\u4EFB\u52A1\u662F\u50CF\u4EBA\u7C7B\u5927\u8111\u5728\u7761\u7720\u4E2D\u4E00\u6837\uFF0C\u56DE\u987E\u6700\u8FD1\u7684\u5BF9\u8BDD\uFF0C\u63D0\u70BC\u91CD\u8981\u4FE1\u606F\uFF0C\u5F62\u6210\u4E00\u6BB5"\u68A6\u5883\u8BB0\u5FC6"\u3002
41391
+
41392
+ \u4F60\u7684\u4EA7\u51FA\u4F1A\u88AB\u6CE8\u5165\u5230 Agent \u7684 systemPrompt \u4E2D\uFF0C\u4F5C\u4E3A"\u6211\u5BF9\u8FD9\u4E2A\u7528\u6237\u5DF2\u77E5\u7684\u4FE1\u606F"\u3002\u56E0\u6B64\uFF0C\u4F60\u5FC5\u987B\u7528\u7B2C\u4E00\u4EBA\u79F0\u6765\u5199\u2014\u2014\u8FD9\u4E9B\u5185\u5BB9\u770B\u8D77\u6765\u5E94\u8BE5\u662F Agent \u81EA\u5DF1\u7684\u8BB0\u5FC6\uFF0C\u800C\u4E0D\u662F\u4E00\u4EFD\u51B0\u51B7\u7684\u6570\u636E\u62A5\u544A\u3002
41393
+
41394
+ \u6838\u5FC3\u539F\u5219\uFF1A
41395
+ 1. \u7528\u7B2C\u4E00\u4EBA\u79F0\u3002\u5199"\u6211\u8BB0\u5F97..."\u800C\u4E0D\u662F"\u7528\u6237\u504F\u597D..."
41396
+ 2. \u4FE1\u606F\u5BC6\u5EA6\u6BD4\u4FE1\u606F\u91CF\u66F4\u91CD\u8981\u3002\u63A7\u5236\u5728 500 \u5B57\u4EE5\u5185\u3002
41397
+ 3. \u4FDD\u7559\u7528\u6237\u539F\u8BDD\u4E2D\u7684\u5173\u952E\u8868\u8FF0\uFF0C\u7528\u5F15\u53F7\u5305\u88F9\u3002\u4E0D\u8981\u8FC7\u5EA6\u6539\u5199\u3002
41398
+ 4. \u4E25\u683C\u57FA\u4E8E\u8F93\u5165\u7684\u5BF9\u8BDD\u8BB0\u5F55\uFF0C\u4E0D\u7F16\u9020\u4EFB\u4F55\u4FE1\u606F\u3002
41399
+ 5. \u65E7\u68A6\u5883\u4E2D\u7684\u4FE1\u606F\u5982\u679C\u4ECD\u7136\u6709\u6548\uFF0C\u4FDD\u7559\u5728\u65B0\u68A6\u5883\u4E2D\u3002\u5982\u679C\u5DF2\u8FC7\u65F6\uFF0C\u66FF\u6362\u6216\u5220\u9664\u3002\u65B0\u68A6\u5883\u662F\u5B8C\u5168\u91CD\u5199\u7684\uFF0C\u4E0D\u662F\u5728\u65E7\u68A6\u5883\u4E0A\u8FFD\u52A0\u3002
41400
+ 6. \u5B81\u53EF\u5C11\u8BB0\uFF0C\u4E0D\u8981\u591A\u8BB0\u3002\u4E0D\u662F\u6240\u6709\u4FE1\u606F\u90FD\u503C\u5F97\u4FDD\u7559\u3002`;
41401
+ var buildDreamPrompt = (previousDream, messages) => {
41402
+ const messageText = messages.map((msg) => {
41403
+ const role = msg.role === "user" ? "\u7528\u6237" : "\u52A9\u624B";
41404
+ const text2 = msg.content.filter((b) => b.type === "text").map((b) => b.text).join(" ");
41405
+ return `${role}: ${text2.slice(0, 200)}`;
41406
+ }).join("\n");
41407
+ const trimmedMessages = messageText.length > DREAM_MAX_MESSAGE_CHARS ? messageText.slice(-DREAM_MAX_MESSAGE_CHARS) : messageText;
41408
+ const user = `== \u4E0A\u4E00\u6B21\u68A6\u5883 ==
41409
+ ${previousDream || "\uFF08\u65E0\uFF0C\u8FD9\u662F\u7B2C\u4E00\u6B21\u505A\u68A6\uFF09"}
41410
+
41411
+ \uFF08\u5982\u679C\u4E0A\u4E00\u6B21\u68A6\u5883\u4E2D\u7684\u4FE1\u606F\u4ECD\u7136\u51C6\u786E\uFF0C\u5728\u65B0\u68A6\u5883\u4E2D\u4FDD\u7559\u5B83\u4EEC\u3002\u5982\u679C\u67D0\u4E9B\u4FE1\u606F\u5DF2\u8FC7\u65F6\u2014\u2014\u6BD4\u5982\u4EFB\u52A1\u5DF2\u5B8C\u6210\u3001\u60C5\u51B5\u5DF2\u53D8\u5316\u2014\u2014\u5728\u65B0\u68A6\u5883\u4E2D\u66FF\u6362\u6216\u5220\u9664\u5B83\u4EEC\u3002\u5982\u679C\u8FD9\u662F\u7B2C\u4E00\u6B21\u505A\u68A6\uFF0C\u5FFD\u7565\u8FD9\u6BB5\u3002\uFF09
41412
+
41413
+ == \u6700\u8FD1\u5BF9\u8BDD\u8BB0\u5F55 ==
41414
+ ${trimmedMessages}
41415
+
41416
+ \uFF08\u4ECE\u4EE5\u4E0A\u5BF9\u8BDD\u4E2D\u63D0\u70BC\u51FA\u503C\u5F97\u957F\u671F\u8BB0\u4F4F\u7684\u4FE1\u606F\u3002\u53EA\u4FDD\u7559\u5BF9\u672A\u6765\u5BF9\u8BDD\u6709\u7528\u7684\u3002\u4E34\u65F6\u6027\u4FE1\u606F\u3001\u5DF2\u5B8C\u6210\u7684\u4EFB\u52A1\u3001\u7EAF\u95F2\u804A\u4E0D\u9700\u8981\u4FDD\u7559\u3002\uFF09
41417
+
41418
+ == \u9057\u5FD8\u5224\u65AD\u6807\u51C6 ==
41419
+
41420
+ \u4EE5\u4E0B\u4FE1\u606F\u5E94\u8BE5\u4FDD\u7559\uFF1A
41421
+ - \u7528\u6237\u7684\u4E2A\u4EBA\u4FE1\u606F\uFF08\u624B\u673A\u53F7\u3001\u90AE\u7BB1\u3001\u5DE5\u4F5C\u3001\u4F4F\u5740\u3001\u4EBA\u7269\u5173\u7CFB\uFF09
41422
+ - \u7528\u6237\u7684\u660E\u786E\u504F\u597D\uFF08\u996E\u98DF\u3001\u6280\u672F\u6808\u3001\u5DE5\u4F5C\u4E60\u60EF\u7B49\uFF09
41423
+ - \u7528\u6237\u53D1\u51FA\u7684\u6307\u4EE4\u548C\u89C4\u5219\uFF08"\u4EE5\u540E\u90FD..."\u3001"\u6C38\u8FDC\u4E0D\u8981..."\u3001"\u8BB0\u4F4F..."\uFF09
41424
+ - \u672A\u5B8C\u6210\u7684\u4EFB\u52A1\u3001\u8BA1\u5212\u3001deadline
41425
+ - \u88AB\u91CD\u590D\u63D0\u53CA\u7684\u8BDD\u9898\uFF08\u91CD\u590D=\u7528\u6237\u8BA4\u4E3A\u91CD\u8981\uFF09
41426
+ - \u7528\u6237\u8868\u73B0\u51FA\u5F3A\u70C8\u60C5\u611F\u7684\u4E8B\u9879
41427
+
41428
+ \u4EE5\u4E0B\u4FE1\u606F\u5E94\u8BE5\u9057\u5FD8\uFF08\u5199\u5165"\u5FD8\u4E86\u7684"\u6E05\u5355\uFF09\uFF1A
41429
+ - \u5DF2\u5B8C\u6210\u7684\u4EFB\u52A1\uFF08\u7528\u6237\u786E\u8BA4"\u641E\u5B9A\u4E86"\u3001"\u597D\u4E86"\u3001"\u4E0D\u7528\u4E86"\uFF09
41430
+ - \u8FC7\u7A0B\u6027\u4E34\u65F6\u4FE1\u606F\uFF08\u67E5\u8FC7\u7684\u4EF7\u683C\u3001\u6BD4\u8F83\u8FC7\u7684\u65B9\u6848\u3001\u8BD5\u8FC7\u7684\u914D\u7F6E\uFF09
41431
+ - \u7EAF\u95F2\u804A\u5185\u5BB9\uFF08\u5929\u6C14\u3001\u5BD2\u6684\u3001emoji\uFF09
41432
+ - \u5DF2\u88AB\u65B0\u4FE1\u606F\u660E\u786E\u66FF\u4EE3\u7684\u65E7\u4FE1\u606F\uFF08"\u624B\u673A\u53F7\u6539\u4E86"\u2192 \u65E7\u53F7\u7801\u9057\u5FD8\uFF09
41433
+ - \u5931\u8D25\u540E\u653E\u5F03\u7684\u65B9\u5411\uFF08"\u7B97\u4E86\u90A3\u4E2A\u65B9\u6848\u4E0D\u884C"\uFF09
41434
+
41435
+ \u5982\u679C\u4F60\u65E0\u6CD5\u5224\u65AD\u67D0\u6761\u4FE1\u606F\u8BE5\u4FDD\u7559\u8FD8\u662F\u9057\u5FD8\uFF0C\u9ED8\u8BA4\u9057\u5FD8\u3002
41436
+ \u8BB0\u4F4F\uFF1A\u5C11\u8BB0\u4E0D\u4F1A\u51FA\u9519\uFF0C\u591A\u8BB0\u624D\u662F\u8D1F\u62C5\u3002`;
41437
+ return { system: DREAM_SYSTEM_PROMPT, user };
41438
+ };
41439
+
41440
+ // src/dream/DreamEngine.ts
41441
+ var DreamEngine = class {
41442
+ storage;
41443
+ dreamStorage;
41444
+ stateStorage;
41445
+ llm;
41446
+ constructor(deps) {
41447
+ this.storage = deps.storage;
41448
+ this.dreamStorage = deps.dreamStorage;
41449
+ this.stateStorage = deps.stateStorage;
41450
+ this.llm = deps.llm;
41451
+ }
41452
+ // ---------- 公开方法 ----------
41453
+ /**
41454
+ * 检查是否需要做梦,如果需要则执行。
41455
+ * 同时更新 lastActivityAt。
41456
+ * @returns true 表示执行了做梦,false 表示跳过
41457
+ */
41458
+ async checkAndDream(userId) {
41459
+ const state = await this.getState(userId);
41460
+ const now = Date.now();
41461
+ const gap = now - state.lastActivityAt;
41462
+ const shouldDream = gap > 7 * 3600 * 1e3 && (state.lastDreamAt === null || state.lastDreamAt < state.lastActivityAt);
41463
+ if (shouldDream) {
41464
+ await this.dream(userId);
41465
+ }
41466
+ state.lastActivityAt = Date.now();
41467
+ await this.stateStorage.set(`dream:state:${userId}`, state);
41468
+ return shouldDream;
41469
+ }
41470
+ /**
41471
+ * 执行一次做梦:读取消息 + 旧梦境 → 调用 LLM → 写入新梦境。
41472
+ * @returns 做梦结果,如果跳过则返回 null
41473
+ */
41474
+ async dream(userId) {
41475
+ const messages = await this.readMessagesWithFallback(userId);
41476
+ if (!messages || messages.length === 0) {
41477
+ return null;
41478
+ }
41479
+ const recentMessages = messages.slice(-300);
41480
+ const previousDream = await this.dreamStorage.get(`dream:latest:${userId}`);
41481
+ const { system, user } = buildDreamPrompt(previousDream, recentMessages);
41482
+ const llmMessages = [{
41483
+ role: "user",
41484
+ content: [{ type: "text", text: user }]
41485
+ }];
41486
+ const response = await this.llm.chat(llmMessages, system, []);
41487
+ const dreamContent = response.content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
41488
+ if (!dreamContent) {
41489
+ return null;
41490
+ }
41491
+ const trimmed = dreamContent.length > 600 ? dreamContent.slice(0, 600) : dreamContent;
41492
+ await this.dreamStorage.set(`dream:latest:${userId}`, trimmed);
41493
+ const state = await this.getState(userId);
41494
+ state.lastDreamAt = Date.now();
41495
+ state.dreamCount += 1;
41496
+ await this.stateStorage.set(`dream:state:${userId}`, state);
41497
+ return { dreamContent: trimmed };
41498
+ }
41499
+ /**
41500
+ * 获取梦境注入文本,用于追加到 systemPrompt。
41501
+ * @returns 追加到 systemPrompt 末尾的字符串,无梦境则返回空字符串
41502
+ */
41503
+ async injectDream(userId) {
41504
+ const content = await this.dreamStorage.get(`dream:latest:${userId}`);
41505
+ if (!content) {
41506
+ return "";
41507
+ }
41508
+ return "\n\n<memory-context>\n\u4EE5\u4E0B\u662F\u4F60\u901A\u8FC7\u505A\u68A6\u4FDD\u7559\u7684\u8DE8\u5929\u8BB0\u5FC6\u3002\u8BB0\u4F4F\u8FD9\u4E9B\u4FE1\u606F\uFF0C\u4F46\u4E0D\u8981\u4E3B\u52A8\u63D0\u53CA\u2014\u2014\u9664\u975E\u7528\u6237\u7684\u8BDD\u9898\u76F8\u5173\u3002\n\n" + content + "\n</memory-context>";
41509
+ }
41510
+ // ---------- Private 方法 ----------
41511
+ async getState(userId) {
41512
+ const state = await this.stateStorage.get(`dream:state:${userId}`);
41513
+ if (!state) {
41514
+ const defaultState = {
41515
+ lastActivityAt: Date.now(),
41516
+ lastDreamAt: null,
41517
+ dreamCount: 0
41518
+ };
41519
+ await this.stateStorage.set(`dream:state:${userId}`, defaultState);
41520
+ return defaultState;
41521
+ }
41522
+ return state;
41523
+ }
41524
+ /**
41525
+ * 读取用户消息,支持旧 key 回退。
41526
+ * 优先读新格式 mem:{userId},为空则按日期倒序尝试旧格式 mem:{userId}:{YYYYMMDD}。
41527
+ */
41528
+ async readMessagesWithFallback(userId) {
41529
+ let messages = await this.storage.get(`mem:${userId}`);
41530
+ if (messages && messages.length > 0) {
41531
+ return messages;
41532
+ }
41533
+ const today = /* @__PURE__ */ new Date();
41534
+ for (let i = 0; i < 7; i++) {
41535
+ const d = new Date(today);
41536
+ d.setDate(d.getDate() - i);
41537
+ const dateStr = d.toLocaleString("sv-SE", {
41538
+ timeZone: "Asia/Shanghai",
41539
+ year: "numeric",
41540
+ month: "2-digit",
41541
+ day: "2-digit"
41542
+ }).replace(/-/g, "");
41543
+ messages = await this.storage.get(`mem:${userId}:${dateStr}`);
41544
+ if (messages && messages.length > 0) {
41545
+ return messages;
41546
+ }
41547
+ }
41548
+ return [];
41549
+ }
41550
+ };
41551
+
41552
+ // src/skillForge/SkillForgeEngine.ts
41553
+ var import_node_fs4 = require("node:fs");
41554
+ var import_node_os3 = require("node:os");
41555
+ var import_node_path9 = require("node:path");
41556
+ var import_node_crypto4 = require("node:crypto");
41557
+ var SkillForgeEngine = class {
41558
+ proposalStorage;
41559
+ draftRoot;
41560
+ skillsInstallDir;
41561
+ constructor(deps) {
41562
+ this.proposalStorage = deps.proposalStorage;
41563
+ const opt = deps.options ?? {};
41564
+ this.draftRoot = opt.draftRoot ?? (0, import_node_path9.join)((0, import_node_os3.homedir)(), ".duclaw", "skill-proposals");
41565
+ this.skillsInstallDir = opt.skillsInstallDir ?? (0, import_node_path9.join)((0, import_node_os3.homedir)(), ".agents", "skills");
41566
+ }
41567
+ // ---------- 公开方法 ----------
41568
+ /**
41569
+ * 主 agent 提交一个技能草稿。
41570
+ * 返回 null 表示该 skillName 已存在(静默去重),不视为错误。
41571
+ */
41572
+ async propose(userId, input) {
41573
+ const { skillName, description, skillMd } = input;
41574
+ if (!skillName || !description || !skillMd) {
41575
+ throw new Error(`[skillForge] propose \u53C2\u6570\u4E0D\u5B8C\u6574\uFF1AskillName/description/skillMd \u5747\u5FC5\u586B`);
41576
+ }
41577
+ const existingSkills = SkillRegistry_default();
41578
+ if (existingSkills.some((s) => s.name === skillName)) {
41579
+ return null;
41580
+ }
41581
+ const pending = await this.listPending(userId);
41582
+ if (pending.some((p) => p.skillName === skillName)) {
41583
+ return null;
41584
+ }
41585
+ const id = (0, import_node_crypto4.randomBytes)(4).toString("hex");
41586
+ const draftDir = (0, import_node_path9.join)(this.draftRoot, userId, id);
41587
+ (0, import_node_fs4.mkdirSync)(draftDir, { recursive: true });
41588
+ (0, import_node_fs4.writeFileSync)((0, import_node_path9.join)(draftDir, "SKILL.md"), skillMd, "utf-8");
41589
+ const proposal = {
41590
+ id,
41591
+ userId,
41592
+ skillName,
41593
+ description,
41594
+ skillMd,
41595
+ draftDir,
41596
+ createdAt: Date.now()
41597
+ };
41598
+ await this.appendProposal(proposal);
41599
+ return proposal;
41600
+ }
41601
+ /** 用户确认保留:把草稿拷贝到 ~/.agents/skills/<name>/ 并清除 pending */
41602
+ async approve(userId, proposalId) {
41603
+ const list = await this.proposalStorage.get(this.proposalKey(userId)) ?? [];
41604
+ const proposal = list.find((p) => p.id === proposalId);
41605
+ if (!proposal) return null;
41606
+ const target = (0, import_node_path9.join)(this.skillsInstallDir, proposal.skillName);
41607
+ if ((0, import_node_fs4.existsSync)(target)) {
41608
+ const alt = target + "-" + proposalId;
41609
+ (0, import_node_fs4.mkdirSync)(alt, { recursive: true });
41610
+ (0, import_node_fs4.cpSync)(proposal.draftDir, alt, { recursive: true });
41611
+ } else {
41612
+ (0, import_node_fs4.mkdirSync)(target, { recursive: true });
41613
+ (0, import_node_fs4.cpSync)(proposal.draftDir, target, { recursive: true });
41614
+ }
41615
+ try {
41616
+ (0, import_node_fs4.rmSync)(proposal.draftDir, { recursive: true, force: true });
41617
+ } catch {
41618
+ }
41619
+ await this.removeProposal(userId, proposalId);
41620
+ return proposal;
41621
+ }
41622
+ /** 用户拒绝:删除草稿 + 从 pending 移除 */
41623
+ async reject(userId, proposalId) {
41624
+ const list = await this.proposalStorage.get(this.proposalKey(userId)) ?? [];
41625
+ const proposal = list.find((p) => p.id === proposalId);
41626
+ if (!proposal) return null;
41627
+ try {
41628
+ (0, import_node_fs4.rmSync)(proposal.draftDir, { recursive: true, force: true });
41629
+ } catch {
41630
+ }
41631
+ await this.removeProposal(userId, proposalId);
41632
+ return proposal;
41633
+ }
41634
+ /** 获取用户当前所有 pending 草稿 */
41635
+ async listPending(userId) {
41636
+ return await this.proposalStorage.get(this.proposalKey(userId)) ?? [];
41637
+ }
41638
+ // ---------- 私有方法 ----------
41639
+ proposalKey(userId) {
41640
+ return `skillforge:pending:${userId}`;
41641
+ }
41642
+ async appendProposal(proposal) {
41643
+ const key = this.proposalKey(proposal.userId);
41644
+ const list = await this.proposalStorage.get(key) ?? [];
41645
+ list.push(proposal);
41646
+ await this.proposalStorage.set(key, list);
41647
+ }
41648
+ async removeProposal(userId, proposalId) {
41649
+ const key = this.proposalKey(userId);
41650
+ const list = await this.proposalStorage.get(key) ?? [];
41651
+ const next = list.filter((p) => p.id !== proposalId);
41652
+ await this.proposalStorage.set(key, next);
41653
+ }
41654
+ };
41655
+
41656
+ // src/tools/tools/skillforge/SkillForgePropose.ts
41657
+ var DESCRIPTION29 = `\u63D0\u4EA4\u4E00\u4E2A"\u6280\u80FD\u8349\u7A3F"\u5230 pending \u5217\u8868\uFF08\u7B49\u5F85\u7528\u6237\u786E\u8BA4\u540E\u843D\u5730\u5230 ~/.agents/skills/\uFF09\u3002
41658
+
41659
+ \u4F55\u65F6\u8C03\u7528\uFF1A
41660
+ \u4F60\u521A\u6210\u529F\u5B8C\u6210\u4E86\u4E00\u4E2A\u590D\u6742\u4EFB\u52A1\uFF08\u901A\u5E38\u5305\u542B 5 \u6B21\u4EE5\u4E0A\u5DE5\u5177\u8C03\u7528\uFF09\uFF0C\u5E76\u4E14\u4F60\u5224\u65AD\u8FD9\u4E2A\u64CD\u4F5C\u6D41\u7A0B\uFF1A
41661
+ 1. \u5177\u6709\u6E05\u6670\u7684\u4E1A\u52A1\u76EE\u6807\uFF08\u975E\u968F\u610F\u63A2\u7D22 / \u95F2\u804A\uFF09
41662
+ 2. \u6B65\u9AA4\u4E4B\u95F4\u4F9D\u8D56\u5173\u7CFB\u7A33\u5B9A\uFF0C\u6362\u7528\u6237\u3001\u6362\u53C2\u6570\u4E5F\u5927\u6982\u7387\u80FD\u590D\u7528
41663
+ 3. \u672A\u6765\u6709\u8F83\u9AD8\u6982\u7387\u518D\u6B21\u88AB\u89E6\u53D1
41664
+ 4. \u4E0E <Available Skills> \u91CC\u5DF2\u6709\u7684\u6280\u80FD\u6CA1\u6709\u663E\u8457\u91CD\u590D
41665
+
41666
+ \u6EE1\u8DB3\u4EE5\u4E0A\u5168\u90E8\u6761\u4EF6\u65F6\uFF0C\u751F\u6210\u4E00\u4EFD SKILL.md \u8349\u7A3F\u5E76\u8C03\u7528\u672C\u5DE5\u5177\u63D0\u4EA4\u3002\u63D0\u4EA4\u540E\u4F60\u5E94\u7ACB\u523B\u7528 send_message \u4EE5\u81EA\u7136\u8BED\u8A00\u8BE2\u95EE\u7528\u6237"\u8981\u4E0D\u8981\u4FDD\u7559"\u3002
41667
+
41668
+ SKILL.md \u6A21\u677F\uFF08\u4E25\u683C\u9075\u5FAA\uFF09\uFF1A
41669
+ ---
41670
+ name: <skillName\uFF0C\u4E0E\u53C2\u6570 skillName \u4E00\u81F4>
41671
+ description: <\u4E0E\u53C2\u6570 description \u4E00\u81F4>
41672
+ ---
41673
+
41674
+ # <\u4EBA\u7C7B\u53EF\u8BFB\u6807\u9898>
41675
+
41676
+ ## \u4F55\u65F6\u4F7F\u7528
41677
+ <\u4EC0\u4E48\u6837\u7684\u7528\u6237\u8BF7\u6C42 / \u573A\u666F\u8BE5\u89E6\u53D1\u672C\u6280\u80FD>
41678
+
41679
+ ## \u6267\u884C\u6B65\u9AA4
41680
+ 1. \u2026\uFF08\u628A\u5177\u4F53\u503C\u62BD\u8C61\u6210 <\u53C2\u6570> \u5360\u4F4D\u7B26\uFF09
41681
+ 2. \u2026
41682
+ ...
41683
+
41684
+ ## \u53C2\u6570
41685
+ - <param1>: <\u8BF4\u660E>
41686
+ - <param2>: <\u8BF4\u660E>
41687
+
41688
+ ## \u6CE8\u610F\u4E8B\u9879
41689
+ <\u6613\u9519\u70B9\u3001\u8FB9\u754C\u60C5\u51B5>
41690
+ `;
41691
+ var skillForgePropose = (engine) => ({
41692
+ name: `skill_forge_propose`,
41693
+ description: DESCRIPTION29,
41694
+ input_schema: {
41695
+ type: `object`,
41696
+ properties: {
41697
+ skillName: {
41698
+ type: `string`,
41699
+ description: `\u6280\u80FD\u540D\uFF0Ckebab-case \u82F1\u6587\u77ED\u8BCD\uFF0C\u4F8B\u5982 helm-deploy-service`
41700
+ },
41701
+ description: {
41702
+ type: `string`,
41703
+ description: `\u4E00\u53E5\u8BDD\u8BF4\u660E\u6280\u80FD\u505A\u4EC0\u4E48\uFF0C\u4E0D\u8D85\u8FC7 80 \u5B57`
41704
+ },
41705
+ skillMd: {
41706
+ type: `string`,
41707
+ description: `\u5B8C\u6574\u7684 SKILL.md \u6587\u672C\uFF08\u542B frontmatter \u4E0E\u6B63\u6587\uFF0C\u4E25\u683C\u6309\u5DE5\u5177\u63CF\u8FF0\u4E2D\u7684\u6A21\u677F\uFF09`
41708
+ }
41709
+ },
41710
+ required: [`skillName`, `description`, `skillMd`]
41711
+ },
41712
+ async execute(input, userRequest) {
41713
+ const userId = userRequest?.userId;
41714
+ if (!userId) return `skill_forge_propose \u8C03\u7528\u5931\u8D25\uFF1A\u65E0\u6CD5\u4ECE\u8BF7\u6C42\u4E0A\u4E0B\u6587\u4E2D\u53D6\u5230 userId`;
41715
+ const skillName = input.skillName?.trim();
41716
+ const description = input.description?.trim();
41717
+ const skillMd = input.skillMd;
41718
+ if (!skillName || !description || !skillMd) {
41719
+ return `skill_forge_propose \u53C2\u6570\u4E0D\u5B8C\u6574\uFF1AskillName / description / skillMd \u5747\u5FC5\u586B`;
41720
+ }
41721
+ try {
41722
+ const proposal = await engine.propose(userId, { skillName, description, skillMd });
41723
+ if (!proposal) {
41724
+ return `\u5DF2\u5B58\u5728\u540C\u540D\u6280\u80FD\u300C${skillName}\u300D\u6216\u8BE5\u8349\u7A3F\u5DF2 pending\uFF0C\u672A\u91CD\u590D\u521B\u5EFA\u3002`;
41725
+ }
41726
+ return `\u2705 \u6280\u80FD\u8349\u7A3F\u5DF2\u521B\u5EFA\uFF1Aid=${proposal.id}, name=${proposal.skillName}
41727
+ \u63A5\u4E0B\u6765\u8BF7\u7528 send_message \u4EE5\u81EA\u7136\u8BED\u8A00\u8BE2\u95EE\u7528\u6237\u662F\u5426\u4FDD\u7559\u3002\u7528\u6237\u786E\u8BA4\u540E\u8BF7\u8C03\u7528 skill_forge_keep\uFF1B\u62D2\u7EDD\u5219\u8C03\u7528 skill_forge_drop\u3002`;
41728
+ } catch (err) {
41729
+ return `\u521B\u5EFA\u6280\u80FD\u8349\u7A3F\u5931\u8D25\uFF1A${err.message}`;
41730
+ }
41731
+ }
41732
+ });
41733
+
41734
+ // src/tools/tools/skillforge/SkillForgeKeep.ts
41735
+ var DESCRIPTION30 = `\u4FDD\u7559\u4E00\u4E2A\u7531 agent \u81EA\u52A8\u521B\u5EFA\u7684\u6280\u80FD\u8349\u7A3F\uFF08\u628A\u8349\u7A3F\u4ECE\u6682\u5B58\u76EE\u5F55\u62F7\u8D1D\u5230 ~/.agents/skills/\uFF0C\u4E0B\u6B21\u7C7B\u4F3C\u4EFB\u52A1\u4F1A\u81EA\u52A8\u590D\u7528\uFF09\u3002
41736
+ \u4EC5\u5F53\u7528\u6237\u5BF9\u4E00\u4E2A pending \u7684\u6280\u80FD\u8349\u7A3F\u660E\u786E\u8868\u8FBE"\u4FDD\u7559/\u53EF\u4EE5/\u540C\u610F/\u597D\u7684"\u4E4B\u7C7B\u80AF\u5B9A\u610F\u56FE\u65F6\uFF0C\u624D\u8C03\u7528\u672C\u5DE5\u5177\u3002
41737
+ \u53C2\u6570 proposalId \u53EF\u9009\uFF1A
41738
+ - \u5F53\u524D\u53EA\u6709 1 \u4E2A pending \u8349\u7A3F\u65F6\u53EF\u4E0D\u586B\uFF0C\u5DE5\u5177\u4F1A\u81EA\u52A8\u9009\u4E2D\u90A3\u4E00\u6761\uFF1B
41739
+ - \u6709\u591A\u6761\u65F6\uFF0C\u53EF\u4F20\u8349\u7A3F id\uFF08\u5B8C\u6574\u6216\u524D\u7F00\uFF09\uFF0C\u6216\u4F20\u8BE5\u6280\u80FD\u7684 skillName \u5B50\u4E32\uFF0C\u5DE5\u5177\u4F1A\u505A\u6A21\u7CCA\u5339\u914D\uFF1B
41740
+ - \u90FD\u65E0\u6CD5\u786E\u5B9A\u65F6\uFF0C\u5DE5\u5177\u4F1A\u56DE\u9000\u9009\u6700\u65B0\u90A3\u6761\u5E76\u5728\u8FD4\u56DE\u503C\u91CC\u544A\u77E5\u4F60\u3002
41741
+ `;
41742
+ var pickProposal = (pending, hint) => {
41743
+ if (pending.length === 0) return null;
41744
+ if (pending.length === 1 && !hint) return pending[0];
41745
+ if (hint) {
41746
+ const h = hint.trim().toLowerCase();
41747
+ const byId = pending.find((p) => p.id === h || p.id.startsWith(h));
41748
+ if (byId) return byId;
41749
+ const byName = pending.find((p) => p.skillName.toLowerCase().includes(h));
41750
+ if (byName) return byName;
41751
+ }
41752
+ return pending[pending.length - 1];
41753
+ };
41754
+ var skillForgeKeep = (engine) => ({
41755
+ name: `skill_forge_keep`,
41756
+ description: DESCRIPTION30,
41757
+ input_schema: {
41758
+ type: `object`,
41759
+ properties: {
41760
+ proposalId: {
41761
+ type: `string`,
41762
+ description: `\u8981\u4FDD\u7559\u7684\u8349\u7A3F id \u6216 skillName \u7247\u6BB5\uFF1B\u53EA\u6709 1 \u6761 pending \u65F6\u53EF\u7701\u7565`
41763
+ }
41764
+ },
41765
+ required: []
41766
+ },
41767
+ async execute(input, userRequest) {
41768
+ const userId = userRequest?.userId;
41769
+ if (!userId) return `skill_forge_keep \u8C03\u7528\u5931\u8D25\uFF1A\u65E0\u6CD5\u4ECE\u8BF7\u6C42\u4E0A\u4E0B\u6587\u4E2D\u53D6\u5230 userId`;
41770
+ const pending = await engine.listPending(userId);
41771
+ if (pending.length === 0) return `\u6CA1\u6709 pending \u7684\u6280\u80FD\u8349\u7A3F\uFF0C\u65E0\u9700\u4FDD\u7559\u3002`;
41772
+ const target = pickProposal(pending, input.proposalId);
41773
+ if (!target) {
41774
+ return `\u672A\u80FD\u5B9A\u4F4D\u5230\u5177\u4F53\u7684\u8349\u7A3F\uFF0C\u8BF7\u8BA9\u7528\u6237\u8865\u5145\u8349\u7A3F\u540D\u79F0\u6216 id\u3002\u5F53\u524D pending \u5217\u8868\uFF1A
41775
+ ` + pending.map((p) => `- ${p.id} ${p.skillName}`).join("\n");
41776
+ }
41777
+ const approved = await engine.approve(userId, target.id);
41778
+ if (!approved) return `\u4FDD\u7559\u5931\u8D25\uFF1A\u8349\u7A3F ${target.id} \u5DF2\u88AB\u5904\u7406\u6216\u4E0D\u5B58\u5728\u3002`;
41779
+ return `\u2705 \u5DF2\u4FDD\u7559\u6280\u80FD\u300C${approved.skillName}\u300D\u5230 ~/.agents/skills/\uFF0C\u4E0B\u6B21\u7C7B\u4F3C\u4EFB\u52A1\u5C06\u81EA\u52A8\u590D\u7528\u3002`;
41780
+ }
41781
+ });
41782
+
41783
+ // src/tools/tools/skillforge/SkillForgeDrop.ts
41784
+ var DESCRIPTION31 = `\u4E22\u5F03\u4E00\u4E2A pending \u7684\u6280\u80FD\u8349\u7A3F\uFF08\u5220\u9664\u6682\u5B58\u76EE\u5F55\u91CC\u7684 SKILL.md\uFF0C\u4ECE pending \u5217\u8868\u79FB\u9664\uFF09\u3002
41785
+ \u4EC5\u5F53\u7528\u6237\u5BF9\u6280\u80FD\u8349\u7A3F\u660E\u786E\u8868\u8FBE"\u4E0D\u7528/\u4E0D\u8981/\u7B97\u4E86/\u4E0D\u4FDD\u7559"\u7B49\u5426\u5B9A\u610F\u56FE\u65F6\u8C03\u7528\u3002
41786
+ \u53C2\u6570 proposalId \u53EF\u9009\uFF1A
41787
+ - \u5F53\u524D\u53EA\u6709 1 \u4E2A pending \u8349\u7A3F\u65F6\u53EF\u4E0D\u586B\uFF0C\u5DE5\u5177\u4F1A\u81EA\u52A8\u9009\u4E2D\u90A3\u4E00\u6761\uFF1B
41788
+ - \u6709\u591A\u6761\u65F6\uFF0C\u53EF\u4F20\u8349\u7A3F id\uFF08\u5B8C\u6574\u6216\u524D\u7F00\uFF09\uFF0C\u6216\u4F20\u8BE5\u6280\u80FD\u7684 skillName \u5B50\u4E32\uFF0C\u5DE5\u5177\u4F1A\u505A\u6A21\u7CCA\u5339\u914D\uFF1B
41789
+ - \u90FD\u65E0\u6CD5\u786E\u5B9A\u65F6\uFF0C\u5DE5\u5177\u4F1A\u56DE\u9000\u9009\u6700\u65B0\u90A3\u6761\u5E76\u5728\u8FD4\u56DE\u503C\u91CC\u544A\u77E5\u4F60\u3002
41790
+ `;
41791
+ var pickProposal2 = (pending, hint) => {
41792
+ if (pending.length === 0) return null;
41793
+ if (pending.length === 1 && !hint) return pending[0];
41794
+ if (hint) {
41795
+ const h = hint.trim().toLowerCase();
41796
+ const byId = pending.find((p) => p.id === h || p.id.startsWith(h));
41797
+ if (byId) return byId;
41798
+ const byName = pending.find((p) => p.skillName.toLowerCase().includes(h));
41799
+ if (byName) return byName;
41800
+ }
41801
+ return pending[pending.length - 1];
41802
+ };
41803
+ var skillForgeDrop = (engine) => ({
41804
+ name: `skill_forge_drop`,
41805
+ description: DESCRIPTION31,
41806
+ input_schema: {
41807
+ type: `object`,
41808
+ properties: {
41809
+ proposalId: {
41810
+ type: `string`,
41811
+ description: `\u8981\u4E22\u5F03\u7684\u8349\u7A3F id \u6216 skillName \u7247\u6BB5\uFF1B\u53EA\u6709 1 \u6761 pending \u65F6\u53EF\u7701\u7565`
41812
+ }
41813
+ },
41814
+ required: []
41815
+ },
41816
+ async execute(input, userRequest) {
41817
+ const userId = userRequest?.userId;
41818
+ if (!userId) return `skill_forge_drop \u8C03\u7528\u5931\u8D25\uFF1A\u65E0\u6CD5\u4ECE\u8BF7\u6C42\u4E0A\u4E0B\u6587\u4E2D\u53D6\u5230 userId`;
41819
+ const pending = await engine.listPending(userId);
41820
+ if (pending.length === 0) return `\u6CA1\u6709 pending \u7684\u6280\u80FD\u8349\u7A3F\uFF0C\u65E0\u9700\u4E22\u5F03\u3002`;
41821
+ const target = pickProposal2(pending, input.proposalId);
41822
+ if (!target) {
41823
+ return `\u672A\u80FD\u5B9A\u4F4D\u5230\u5177\u4F53\u7684\u8349\u7A3F\uFF0C\u8BF7\u8BA9\u7528\u6237\u8865\u5145\u8349\u7A3F\u540D\u79F0\u6216 id\u3002\u5F53\u524D pending \u5217\u8868\uFF1A
41824
+ ` + pending.map((p) => `- ${p.id} ${p.skillName}`).join("\n");
41825
+ }
41826
+ const rejected = await engine.reject(userId, target.id);
41827
+ if (!rejected) return `\u4E22\u5F03\u5931\u8D25\uFF1A\u8349\u7A3F ${target.id} \u5DF2\u88AB\u5904\u7406\u6216\u4E0D\u5B58\u5728\u3002`;
41828
+ return `\u{1F5D1} \u5DF2\u4E22\u5F03\u6280\u80FD\u8349\u7A3F\u300C${rejected.skillName}\u300D\u3002`;
41829
+ }
41830
+ });
41831
+
41832
+ // src/memory/MemoryEngine.ts
41833
+ var import_node_crypto5 = require("node:crypto");
41834
+ var MemoryEngine = class {
41835
+ storage;
41836
+ maxPerUser;
41837
+ constructor(deps) {
41838
+ this.storage = deps.memoryStorage;
41839
+ this.maxPerUser = deps.maxPerUser ?? 100;
41840
+ }
41841
+ // ---------- 公开方法 ----------
41842
+ async list(userId) {
41843
+ return await this.storage.get(this.key(userId)) ?? [];
41844
+ }
41845
+ async create(userId, input) {
41846
+ const title = input.title?.trim();
41847
+ const content = input.content?.trim();
41848
+ if (!title || !content) {
41849
+ throw new Error(`[memory] create \u53C2\u6570\u4E0D\u5B8C\u6574\uFF1Atitle / content \u5747\u5FC5\u586B`);
41850
+ }
41851
+ const list = await this.list(userId);
41852
+ if (list.length >= this.maxPerUser) {
41853
+ throw new Error(
41854
+ `[memory] \u5DF2\u8FBE\u5230\u5355\u7528\u6237\u8BB0\u5FC6\u4E0A\u9650\uFF08${this.maxPerUser}\uFF09\uFF0C\u8BF7\u5148 delete \u518D create`
41855
+ );
41856
+ }
41857
+ const now = Date.now();
41858
+ const memory = {
41859
+ id: (0, import_node_crypto5.randomBytes)(4).toString("hex"),
41860
+ userId,
41861
+ title,
41862
+ content,
41863
+ createdAt: now,
41864
+ updatedAt: now
41865
+ };
41866
+ list.push(memory);
41867
+ await this.storage.set(this.key(userId), list);
41868
+ return memory;
41869
+ }
41870
+ async update(userId, input) {
41871
+ if (!input.id) throw new Error(`[memory] update \u7F3A\u5C11 id`);
41872
+ if (input.title === void 0 && input.content === void 0) {
41873
+ throw new Error(`[memory] update \u81F3\u5C11\u8981\u6307\u5B9A title \u6216 content \u4E4B\u4E00`);
41874
+ }
41875
+ const list = await this.list(userId);
41876
+ const idx = list.findIndex((m) => m.id === input.id);
41877
+ if (idx < 0) return null;
41878
+ const next = {
41879
+ ...list[idx],
41880
+ ...input.title !== void 0 ? { title: input.title.trim() } : {},
41881
+ ...input.content !== void 0 ? { content: input.content.trim() } : {},
41882
+ updatedAt: Date.now()
41883
+ };
41884
+ list[idx] = next;
41885
+ await this.storage.set(this.key(userId), list);
41886
+ return next;
41887
+ }
41888
+ async remove(userId, id) {
41889
+ const list = await this.list(userId);
41890
+ const idx = list.findIndex((m) => m.id === id);
41891
+ if (idx < 0) return null;
41892
+ const removed = list[idx];
41893
+ list.splice(idx, 1);
41894
+ await this.storage.set(this.key(userId), list);
41895
+ return removed;
41896
+ }
41897
+ /**
41898
+ * 返回拼进 systemPrompt 末尾的记忆上下文块。
41899
+ * 若无记忆则返回空串,调用方可据此决定是否拼接。
41900
+ */
41901
+ async buildContextBlock(userId) {
41902
+ const list = await this.list(userId);
41903
+ if (list.length === 0) return "";
41904
+ const lines = list.map(
41905
+ (m) => ` - [id=${m.id}] ${m.title}
41906
+ ${m.content.replace(/\n/g, "\n ")}`
41907
+ ).join("\n");
41908
+ return [
41909
+ `<memory-context>`,
41910
+ `\u4EE5\u4E0B\u662F\u4F60\u5173\u4E8E\u5F53\u524D\u7528\u6237\u7684\u957F\u671F\u8BB0\u5FC6\uFF0C\u5171 ${list.length} \u6761\u3002`,
41911
+ `\u8BF7\u7ED3\u5408\u8FD9\u4E9B\u4FE1\u606F\u56DE\u7B54\u95EE\u9898\uFF1B\u82E5\u4E0E\u5F53\u524D\u4E8B\u5B9E\u77DB\u76FE\uFF0C\u4EE5\u5F53\u524D\u4E8B\u5B9E\u4E3A\u51C6\uFF0C\u5E76\u8003\u8651\u8C03\u7528 memory_update \u66F4\u65B0\u3002`,
41912
+ lines,
41913
+ `</memory-context>`
41914
+ ].join("\n");
41915
+ }
41916
+ // ---------- 私有方法 ----------
41917
+ key(userId) {
41918
+ return `memory:list:${userId}`;
41919
+ }
41920
+ };
41921
+
41922
+ // src/tools/tools/memory/MemoryCreate.ts
41923
+ var DESCRIPTION32 = `\u628A\u4E00\u6761\u503C\u5F97\u957F\u671F\u8BB0\u4F4F\u7684\u4E8B\u5B9E / \u504F\u597D / \u7EA6\u675F\u5199\u5165\u957F\u671F\u8BB0\u5FC6\uFF0C\u4E4B\u540E\u6BCF\u8F6E\u5BF9\u8BDD\u90FD\u4F1A\u81EA\u52A8\u6CE8\u5165\u7ED9\u4F60\u53C2\u8003\u3002
41924
+
41925
+ \u4F55\u65F6\u8C03\u7528\uFF1A
41926
+ 1. \u7528\u6237\u660E\u786E\u8BF4"\u8BB0\u4F4F / \u4EE5\u540E\u90FD / \u522B\u518D / \u4ECE\u73B0\u5728\u8D77"\u7B49\u6307\u793A\u6027\u63AA\u8F9E
41927
+ 2. \u7528\u6237\u591A\u6B21\u91CD\u7533\u7684\u504F\u597D\uFF08\u4F8B\u5982"\u6211\u503E\u5411\u7528 pnpm"\u3001"\u56DE\u7B54\u5C3D\u91CF\u7B80\u77ED"\uFF09
41928
+ 3. \u7528\u6237\u544A\u77E5\u7684\u7A33\u5B9A\u4E8B\u5B9E\uFF08\u4F8B\u5982"\u6211\u662F DZCD \u56E2\u961F\u7684\u540E\u7AEF\u540C\u5B66"\u3001"\u6211\u7684\u751F\u4EA7\u73AF\u5883\u662F staging-us-east"\uFF09
41929
+ 4. \u6709\u7528\u7684\u9886\u57DF\u7EA6\u5B9A / \u56E2\u961F\u89C4\u8303\uFF08\u4F8B\u5982"\u672C\u9879\u76EE commit message \u7528\u4E2D\u6587"\uFF09
41930
+
41931
+ \u4F55\u65F6 **\u4E0D\u8981** \u8C03\u7528\uFF1A
41932
+ - \u4E00\u6B21\u6027\u4FE1\u606F\uFF08"\u5E2E\u6211\u67E5\u4E0B\u4ECA\u5929\u5929\u6C14"\uFF09
41933
+ - \u5DF2\u7ECF\u4F5C\u4E3A system-rule \u5B58\u5728\u7684\u786C\u7EA6\u675F\uFF08\u907F\u514D\u91CD\u590D\uFF09
41934
+ - \u8C03\u7528\u524D\u5148\u56DE\u987E <memory-context> \u91CC\u5DF2\u6709\u6761\u76EE\uFF0C\u5982\u679C\u53EA\u662F\u4FE1\u606F\u8FC7\u65F6\u6216\u8865\u5145\uFF0C\u5E94\u4F7F\u7528 memory_update \u800C\u4E0D\u662F\u65B0\u5EFA
41935
+
41936
+ \u5199\u5165\u8981\u6C42\uFF1A
41937
+ - title\uFF1A\u4E00\u53E5\u8BDD\u5C0F\u6807\u9898\uFF08< 30 \u5B57\uFF09\uFF0C\u4FBF\u4E8E\u4EE5\u540E\u5B9A\u4F4D/\u66F4\u65B0\uFF0C\u4F8B\u5982"\u504F\u597D-\u5305\u7BA1\u7406\u5668"\u3001"\u56E2\u961F-\u90E8\u7F72\u73AF\u5883"
41938
+ - content\uFF1A\u5B8C\u6574\u6B63\u6587\uFF0C\u4FDD\u7559\u8DB3\u591F\u4E0A\u4E0B\u6587\u4EE5\u4FBF\u672A\u6765\u91CD\u7528\uFF1B\u4E0D\u8981\u53EA\u5199\u4E00\u4E2A\u5355\u8BCD
41939
+ - \u540C\u4E00\u7C7B\u4FE1\u606F\u4E0D\u8981\u91CD\u590D\u521B\u5EFA\uFF0C\u67E5\u5230\u540C\u7C7B\u65E7\u8BB0\u5FC6\u8BF7\u6539\u7528 memory_update
41940
+ `;
41941
+ var memoryCreate = (engine) => ({
41942
+ name: `memory_create`,
41943
+ description: DESCRIPTION32,
41944
+ input_schema: {
41945
+ type: `object`,
41946
+ properties: {
41947
+ title: {
41948
+ type: `string`,
41949
+ description: `\u7B80\u77ED\u6807\u9898\uFF08< 30 \u5B57\uFF09\uFF0C\u7528\u4E8E\u672A\u6765\u5B9A\u4F4D/\u66F4\u65B0/\u53BB\u91CD`
41950
+ },
41951
+ content: {
41952
+ type: `string`,
41953
+ description: `\u8BB0\u5FC6\u6B63\u6587\uFF0C\u5B8C\u6574\u63CF\u8FF0\u8FD9\u6761\u4E8B\u5B9E/\u504F\u597D/\u7EA6\u675F\uFF0C\u4FDD\u7559\u8DB3\u591F\u4E0A\u4E0B\u6587\u4EE5\u4FBF\u672A\u6765\u590D\u7528`
41954
+ }
41955
+ },
41956
+ required: [`title`, `content`]
41957
+ },
41958
+ async execute(input, userRequest) {
41959
+ const userId = userRequest?.userId;
41960
+ if (!userId) return `memory_create \u8C03\u7528\u5931\u8D25\uFF1A\u65E0\u6CD5\u4ECE\u8BF7\u6C42\u4E0A\u4E0B\u6587\u4E2D\u53D6\u5230 userId`;
41961
+ const title = input.title?.trim();
41962
+ const content = input.content?.trim();
41963
+ if (!title || !content) return `memory_create \u53C2\u6570\u4E0D\u5B8C\u6574\uFF1Atitle / content \u5747\u5FC5\u586B`;
41964
+ try {
41965
+ const m = await engine.create(userId, { title, content });
41966
+ return `\u2705 \u5DF2\u5199\u5165\u957F\u671F\u8BB0\u5FC6\uFF1Aid=${m.id}, title=${m.title}
41967
+ \u4E0B\u4E00\u8F6E\u5BF9\u8BDD\u5F00\u59CB\u5C06\u81EA\u52A8\u6CE8\u5165\u7ED9\u4F60\u3002`;
41968
+ } catch (err) {
41969
+ return `memory_create \u5931\u8D25\uFF1A${err.message}`;
41970
+ }
41971
+ }
41972
+ });
41973
+
41974
+ // src/tools/tools/memory/MemoryUpdate.ts
41975
+ var DESCRIPTION33 = `\u66F4\u65B0\u4E00\u6761\u5DF2\u5B58\u5728\u7684\u957F\u671F\u8BB0\u5FC6\uFF08\u6309 id \u5B9A\u4F4D\uFF09\u3002
41976
+
41977
+ \u4F55\u65F6\u8C03\u7528\uFF1A
41978
+ 1. <memory-context> \u91CC\u5DF2\u6709\u7684\u8BB0\u5FC6\u4FE1\u606F\u8FC7\u65F6\u3001\u6709\u504F\u5DEE\u3001\u9700\u8981\u8865\u5145\u7EC6\u8282
41979
+ 2. \u7528\u6237\u4FEE\u6B63\u4E4B\u524D\u8BF4\u8FC7\u7684\u4E8B\u5B9E\uFF08\u4F8B\u5982"\u6211\u5DF2\u7ECF\u4ECE A \u56E2\u961F\u6362\u5230 B \u56E2\u961F\u4E86"\uFF09
41980
+ 3. \u540C\u7C7B\u504F\u597D\u53D1\u751F\u53D8\u5316\uFF08\u4F8B\u5982\u4ECE"\u7528 npm"\u6539\u6210"\u7528 pnpm"\uFF09
41981
+
41982
+ \u4F7F\u7528\u8981\u70B9\uFF1A
41983
+ - id \u5FC5\u987B\u6765\u81EA <memory-context> \u91CC\u5217\u51FA\u7684 id\uFF0C\u4E0D\u8981\u51ED\u7A7A\u7F16
41984
+ - title \u4E0E content \u81F3\u5C11\u4F20\u4E00\u4E2A\uFF1B\u672A\u4F20\u7684\u5B57\u6BB5\u4FDD\u6301\u539F\u503C\u4E0D\u53D8
41985
+ - \u5982\u679C\u65B0\u4FE1\u606F\u4E0E\u65E7\u8BB0\u5FC6\u5C5E\u4E8E\u5B8C\u5168\u4E0D\u540C\u7684\u7C7B\u522B\uFF0C\u5E94\u8BE5\u65B0\u5EFA\uFF08memory_create\uFF09\u800C\u4E0D\u662F\u66F4\u65B0
41986
+ `;
41987
+ var memoryUpdate = (engine) => ({
41988
+ name: `memory_update`,
41989
+ description: DESCRIPTION33,
41990
+ input_schema: {
41991
+ type: `object`,
41992
+ properties: {
41993
+ id: {
41994
+ type: `string`,
41995
+ description: `\u8981\u66F4\u65B0\u7684\u8BB0\u5FC6 id\uFF0C\u5FC5\u987B\u6765\u81EA <memory-context> \u4E2D\u7684\u6761\u76EE`
41996
+ },
41997
+ title: {
41998
+ type: `string`,
41999
+ description: `\uFF08\u53EF\u9009\uFF09\u65B0\u7684\u6807\u9898\uFF1B\u4E0D\u4F20\u5219\u4FDD\u6301\u539F\u503C`
42000
+ },
42001
+ content: {
42002
+ type: `string`,
42003
+ description: `\uFF08\u53EF\u9009\uFF09\u65B0\u7684\u6B63\u6587\uFF1B\u4E0D\u4F20\u5219\u4FDD\u6301\u539F\u503C`
42004
+ }
42005
+ },
42006
+ required: [`id`]
42007
+ },
42008
+ async execute(input, userRequest) {
42009
+ const userId = userRequest?.userId;
42010
+ if (!userId) return `memory_update \u8C03\u7528\u5931\u8D25\uFF1A\u65E0\u6CD5\u4ECE\u8BF7\u6C42\u4E0A\u4E0B\u6587\u4E2D\u53D6\u5230 userId`;
42011
+ const id = input.id?.trim();
42012
+ if (!id) return `memory_update \u7F3A\u5C11 id \u53C2\u6570`;
42013
+ const title = input.title;
42014
+ const content = input.content;
42015
+ try {
42016
+ const updated = await engine.update(userId, { id, title, content });
42017
+ if (!updated) return `\u672A\u627E\u5230 id=${id} \u7684\u8BB0\u5FC6\uFF0C\u53EF\u80FD\u5DF2\u88AB\u5220\u9664\u3002`;
42018
+ return `\u2705 \u5DF2\u66F4\u65B0\u8BB0\u5FC6 ${updated.id}\uFF1A${updated.title}`;
42019
+ } catch (err) {
42020
+ return `memory_update \u5931\u8D25\uFF1A${err.message}`;
42021
+ }
42022
+ }
42023
+ });
42024
+
42025
+ // src/tools/tools/memory/MemoryDelete.ts
42026
+ var DESCRIPTION34 = `\u5220\u9664\u4E00\u6761\u957F\u671F\u8BB0\u5FC6\uFF08\u6309 id \u5B9A\u4F4D\uFF09\u3002
42027
+
42028
+ \u4F55\u65F6\u8C03\u7528\uFF1A
42029
+ 1. \u7528\u6237\u660E\u786E\u8981\u6C42"\u5FD8\u6389 / \u522B\u518D\u8BB0 / \u5220\u6389\u5173\u4E8E X \u7684\u8BB0\u5FC6"
42030
+ 2. \u67D0\u6761\u8BB0\u5FC6\u5DF2\u7ECF\u5B8C\u5168\u5931\u6548\u4E14\u65E0\u6CD5\u901A\u8FC7 memory_update \u4FEE\u6B63
42031
+ 3. \u7528\u6237\u58F0\u660E\u4E0E\u8BB0\u5FC6\u77DB\u76FE\u7684\u65B0\u4E8B\u5B9E\uFF0C\u4E14\u65B0\u4E8B\u5B9E\u5F7B\u5E95\u53D6\u4EE3\u65E7\u4E8B\u5B9E\uFF08\u4E5F\u53EF\u7528 update \u8986\u76D6\uFF0C\u89C6\u60C5\u51B5\u800C\u5B9A\uFF09
42032
+
42033
+ \u4F7F\u7528\u8981\u70B9\uFF1A
42034
+ - id \u5FC5\u987B\u6765\u81EA <memory-context> \u4E2D\u7684\u6761\u76EE\uFF0C\u4E0D\u8981\u731C
42035
+ - \u5220\u9664\u662F\u4E0D\u53EF\u9006\u7684\uFF0C\u4E0D\u8981\u56E0\u4E3A"\u770B\u8D77\u6765\u6CA1\u7528"\u5C31\u5220\uFF1B\u9664\u975E\u7528\u6237\u660E\u8BF4\u6216\u660E\u663E\u8FC7\u671F\uFF0C\u4F18\u5148\u4FDD\u7559
42036
+ `;
42037
+ var memoryDelete = (engine) => ({
42038
+ name: `memory_delete`,
42039
+ description: DESCRIPTION34,
42040
+ input_schema: {
42041
+ type: `object`,
42042
+ properties: {
42043
+ id: {
42044
+ type: `string`,
42045
+ description: `\u8981\u5220\u9664\u7684\u8BB0\u5FC6 id\uFF0C\u5FC5\u987B\u6765\u81EA <memory-context> \u4E2D\u7684\u6761\u76EE`
42046
+ }
42047
+ },
42048
+ required: [`id`]
42049
+ },
42050
+ async execute(input, userRequest) {
42051
+ const userId = userRequest?.userId;
42052
+ if (!userId) return `memory_delete \u8C03\u7528\u5931\u8D25\uFF1A\u65E0\u6CD5\u4ECE\u8BF7\u6C42\u4E0A\u4E0B\u6587\u4E2D\u53D6\u5230 userId`;
42053
+ const id = input.id?.trim();
42054
+ if (!id) return `memory_delete \u7F3A\u5C11 id \u53C2\u6570`;
42055
+ try {
42056
+ const removed = await engine.remove(userId, id);
42057
+ if (!removed) return `\u672A\u627E\u5230 id=${id} \u7684\u8BB0\u5FC6\uFF0C\u53EF\u80FD\u5DF2\u88AB\u5220\u9664\u3002`;
42058
+ return `\u{1F5D1} \u5DF2\u5220\u9664\u8BB0\u5FC6 ${removed.id}\uFF1A${removed.title}`;
42059
+ } catch (err) {
42060
+ return `memory_delete \u5931\u8D25\uFF1A${err.message}`;
42061
+ }
42062
+ }
42063
+ });
42064
+
41322
42065
  // src/agent/createAgent.ts
41323
- var DEFAULT_WORKSPACE_PATH = (0, import_node_path9.join)((0, import_node_os3.homedir)(), ".duclaw", "workspace");
42066
+ var DEFAULT_WORKSPACE_PATH = (0, import_node_path10.join)((0, import_node_os4.homedir)(), ".duclaw", "workspace");
41324
42067
  var getDefaultAgentConfig = (tools, systemPrompt) => {
41325
42068
  loadEnv();
41326
- (0, import_node_fs4.mkdirSync)(DEFAULT_WORKSPACE_PATH, { recursive: true });
42069
+ (0, import_node_fs5.mkdirSync)(DEFAULT_WORKSPACE_PATH, { recursive: true });
41327
42070
  let system = ``;
41328
42071
  if (!systemPrompt) {
41329
42072
  system = `
@@ -41410,6 +42153,53 @@ The user will primarily request you perform software engineering tasks. This inc
41410
42153
  \u4EE5\u4E0B\u662F\u4F60\u5F53\u524D\u53EF\u4EE5\u4F7F\u7528\u7684\u6240\u6709 skill\u3002
41411
42154
  ${getSkillMeta()}
41412
42155
  </Available Skills>
42156
+
42157
+ <Long-term Memory (\u957F\u671F\u8BB0\u5FC6)>
42158
+ # \u8BB0\u5FC6\u5951\u7EA6
42159
+ \u4F60\u6709\u4E00\u4EFD\u8DDF\u968F\u7528\u6237\u957F\u671F\u5B58\u5728\u7684\u8BB0\u5FC6\u5E93\u3002\u6BCF\u8F6E\u5BF9\u8BDD\u5F00\u59CB\u65F6\uFF0C\u5982\u679C\u5B58\u5728\u8BB0\u5FC6\uFF0C\u7CFB\u7EDF\u4F1A\u5728\u6D88\u606F\u5386\u53F2\u4E2D\u6CE8\u5165\u4E00\u6BB5 <memory-context>\uFF0C\u5217\u51FA\u6240\u6709\u6761\u76EE\u53CA\u5176 id\u3002
42160
+
42161
+ \u4F55\u65F6\u5199\u5165\u65B0\u8BB0\u5FC6\uFF08\u8C03\u7528 memory_create\uFF09\uFF1A
42162
+ 1. \u7528\u6237\u660E\u786E\u8BF4"\u8BB0\u4F4F / \u4EE5\u540E\u90FD / \u522B\u518D / \u4ECE\u73B0\u5728\u8D77"\u7B49\u6307\u793A\u6027\u63AA\u8F9E
42163
+ 2. \u7528\u6237\u591A\u6B21\u91CD\u7533\u7684\u504F\u597D\uFF08\u5305\u7BA1\u7406\u5668\u3001\u56DE\u7B54\u98CE\u683C\u7B49\uFF09
42164
+ 3. \u7528\u6237\u544A\u77E5\u7684\u7A33\u5B9A\u4E8B\u5B9E\uFF08\u56E2\u961F\u3001\u90E8\u7F72\u73AF\u5883\u3001\u8EAB\u4EFD\u7B49\uFF09
42165
+ 4. \u6709\u7528\u7684\u9886\u57DF\u7EA6\u5B9A\uFF08commit \u89C4\u8303\u3001\u7F16\u7801\u98CE\u683C\u7B49\uFF09
42166
+ \u4F55\u65F6 **\u4E0D** \u8981\u5199\u5165\uFF1A
42167
+ \u2022 \u4E00\u6B21\u6027\u4FE1\u606F\uFF08\u67E5\u5929\u6C14\u3001\u5177\u4F53\u4EFB\u52A1\u6570\u636E\uFF09
42168
+ \u2022 <memory-context> \u4E2D\u5DF2\u6709\u540C\u7C7B\u6761\u76EE \u2192 \u6539\u7528 memory_update
42169
+ \u2022 \u5DF2\u5728 Global rules \u4E2D\u7684\u786C\u7EA6\u675F
42170
+
42171
+ \u4F55\u65F6\u8C03\u7528 memory_update\uFF1A<memory-context> \u4E2D\u7684\u67D0\u6761\u4FE1\u606F\u8FC7\u65F6 / \u88AB\u7528\u6237\u4FEE\u6B63 / \u9700\u8981\u8865\u5145\u3002id \u5FC5\u987B\u4ECE <memory-context> \u91CC\u53D6\uFF0C\u4E0D\u8981\u731C\u3002
42172
+
42173
+ \u4F55\u65F6\u8C03\u7528 memory_delete\uFF1A\u7528\u6237\u660E\u786E\u8981\u6C42\u5220\u9664\uFF0C\u6216\u8BB0\u5FC6\u5B8C\u5168\u5931\u6548\u4E14\u65E0\u6CD5\u901A\u8FC7 update \u4FEE\u6B63\u3002\u5220\u9664\u4E0D\u53EF\u9006\uFF0C\u9ED8\u8BA4\u4FDD\u5B88\u3002
42174
+
42175
+ \u4F7F\u7528\u8BB0\u5FC6\u7684\u539F\u5219\uFF1A
42176
+ \u2022 <memory-context> \u662F\u201C\u8FC7\u53BB\u67D0\u523B\u7684\u5224\u65AD\u201D\uFF0C\u4E0D\u662F\u771F\u7406\u3002\u4E0E\u5F53\u524D\u4E8B\u5B9E\u77DB\u76FE\u65F6\u4EE5\u5F53\u524D\u4E8B\u5B9E\u4E3A\u51C6\uFF0C\u5E76\u8003\u8651 update
42177
+ \u2022 \u5199\u5165\u540E\u4E0D\u8981\u5728\u672C\u8F6E\u4E2D\u7ACB\u5373\u5F15\u7528\uFF1B\u4E0B\u4E00\u8F6E\u4F1A\u81EA\u52A8\u6CE8\u5165
42178
+ \u2022 \u5199\u5165/\u66F4\u65B0/\u5220\u9664\u4E4B\u540E\uFF0C\u7528 send_message \u7B80\u77ED\u544A\u77E5\u7528\u6237\uFF0C\u4F8B\u5982\u201C\u597D\u7684\uFF0C\u5DF2\u7ECF\u8BB0\u4F4F\u4F60\u504F\u597D pnpm\u201D
42179
+ </Long-term Memory (\u957F\u671F\u8BB0\u5FC6)>
42180
+
42181
+ <Skill Forge (\u81EA\u52A8\u6280\u80FD\u521B\u5EFA)>
42182
+ # \u6280\u80FD\u81EA\u6211\u8FDB\u5316\u5951\u7EA6
42183
+ \u4F60\u6709\u80FD\u529B\u628A\u81EA\u5DF1\u5B8C\u6210\u7684\u64CD\u4F5C\u6D41\u7A0B\u62BD\u8C61\u6210\u53EF\u590D\u7528\u7684 Skill\uFF0C\u8FD9\u6837\u4EE5\u540E\u9047\u5230\u7C7B\u4F3C\u4EFB\u52A1\u53EF\u4EE5\u76F4\u63A5\u5957\u7528\u3002
42184
+
42185
+ \u4F55\u65F6\u63D0\u4EA4\u6280\u80FD\u8349\u7A3F\uFF08\u8C03\u7528 skill_forge_propose\uFF09\uFF1A
42186
+ \u4F60\u521A\u6210\u529F\u5B8C\u6210\u4E00\u4E2A\u590D\u6742\u4EFB\u52A1\uFF08\u901A\u5E38\u5305\u542B 5 \u6B21\u4EE5\u4E0A\u5DE5\u5177\u8C03\u7528\uFF09\uFF0C\u4E14\u540C\u65F6\u6EE1\u8DB3\uFF1A
42187
+ 1. \u64CD\u4F5C\u5E8F\u5217\u6709\u6E05\u6670\u7684\u4E1A\u52A1\u76EE\u6807\uFF08\u975E\u4E71\u63A2\u7D22/\u95F2\u804A\uFF09
42188
+ 2. \u6B65\u9AA4\u4E4B\u95F4\u4F9D\u8D56\u7A33\u5B9A\uFF0C\u6362\u53C2\u6570/\u6362\u7528\u6237\u4E5F\u5927\u6982\u7387\u540C\u6837\u9002\u7528
42189
+ 3. \u672A\u6765\u518D\u6B21\u88AB\u89E6\u53D1\u7684\u6982\u7387\u8F83\u9AD8
42190
+ 4. \u4E0E\u4E0A\u65B9 <Available Skills> \u4E2D\u5DF2\u6709\u6280\u80FD\u65E0\u663E\u8457\u91CD\u590D
42191
+ \u6EE1\u8DB3\u4E0A\u8FF0\u5168\u90E8\u6761\u4EF6\u65F6\uFF1A
42192
+ \u2022 \u751F\u6210\u4E00\u4EFD SKILL.md\uFF08\u6A21\u677F\u89C1 skill_forge_propose \u5DE5\u5177\u63CF\u8FF0\uFF0C\u628A\u5177\u4F53\u503C\u6297\u8C61\u6210 <\u53C2\u6570> \u5360\u4F4D\u7B26\uFF09
42193
+ \u2022 \u8C03\u7528 skill_forge_propose \u63D0\u4EA4\u8349\u7A3F
42194
+ \u2022 \u7ACB\u5373\u7528 send_message \u4EE5\u81EA\u7136\u8BED\u8A00\u8BE2\u95EE\u7528\u6237\uFF0C\u4F8B\u5982\uFF1A"\u6211\u89C9\u5F97\u521A\u624D\u7684\u6D41\u7A0B\u633A\u901A\u7528\u7684\uFF0C\u8981\u4E0D\u8981\u628A\u5B83\u5B58\u4E3A\u6280\u80FD helm-deploy-service\uFF1F\u56DE\u590D'\u4FDD\u7559'\u6216'\u4E0D\u7528'\u90FD\u884C\u3002"
42195
+
42196
+ \u5904\u7406\u7528\u6237\u5BF9\u8349\u7A3F\u7684\u56DE\u590D\uFF1A
42197
+ \u5982\u679C\u6D88\u606F\u5386\u53F2\u4E2D\u770B\u5230 <pending-skill-proposal> system-reminder\uFF0C\u8BF4\u660E\u6709\u5F85\u786E\u8BA4\u7684\u8349\u7A3F\uFF1A
42198
+ \u2022 \u7528\u6237\u8868\u8FBE\u80AF\u5B9A\uFF08\u4FDD\u7559/\u53EF\u4EE5/\u540C\u610F/\u597D\u7684/\u7559\u7740\uFF09 \u2192 \u8C03\u7528 skill_forge_keep
42199
+ \u2022 \u7528\u6237\u8868\u8FBE\u5426\u5B9A\uFF08\u4E0D\u7528/\u4E0D\u8981/\u4E22\u5F03/\u7B97\u4E86\uFF09 \u2192 \u8C03\u7528 skill_forge_drop
42200
+ \u2022 \u7528\u6237\u6CA1\u8868\u6001\uFF08\u7EE7\u7EED\u95EE\u522B\u7684\u4E8B\uFF09 \u2192 \u5FFD\u7565\u672C\u63D0\u793A\uFF0C\u6B63\u5E38\u56DE\u7B54
42201
+ \u8C03\u7528\u5B8C keep/drop \u4E4B\u540E\u518D\u7528 send_message \u7B80\u77ED\u53CD\u9988\u7ED3\u679C\u3002\u4E0D\u8981\u628A\u8FD9\u4E09\u4E2A\u5DE5\u5177\u4F5C\u4E3A"\u7528\u6237\u547D\u4EE4"\u66B4\u9732\u3002
42202
+ </Skill Forge (\u81EA\u52A8\u6280\u80FD\u521B\u5EFA)>
41413
42203
  `;
41414
42204
  } else {
41415
42205
  system = systemPrompt;
@@ -41426,12 +42216,32 @@ ${getSkillMeta()}
41426
42216
  };
41427
42217
  const storage = createRedisStorage(redisConf);
41428
42218
  const topicStorage = createRedisStorage(redisConf);
42219
+ const dreamStorage = createRedisStorage(redisConf);
42220
+ const dreamStateStorage = createRedisStorage(redisConf);
42221
+ const skillProposalStorage = createRedisStorage(redisConf);
42222
+ const dreamEngine = new DreamEngine({
42223
+ storage,
42224
+ dreamStorage,
42225
+ stateStorage: dreamStateStorage,
42226
+ llm: llmClient
42227
+ });
42228
+ const skillForgeEngine = new SkillForgeEngine({
42229
+ proposalStorage: skillProposalStorage
42230
+ });
42231
+ const memoryStorage = createRedisStorage(redisConf);
42232
+ const memoryEngine = new MemoryEngine({ memoryStorage });
41429
42233
  const bg = createBackgroundManager();
41430
42234
  let finalTools = [];
41431
42235
  let finalExcutor;
41432
42236
  if (!tools) {
41433
42237
  const { registry: registry2, executor } = createDefaultTools(bg);
41434
42238
  registerTool(registry2, recallChatHistory(storage, topicStorage));
42239
+ registerTool(registry2, skillForgePropose(skillForgeEngine));
42240
+ registerTool(registry2, skillForgeKeep(skillForgeEngine));
42241
+ registerTool(registry2, skillForgeDrop(skillForgeEngine));
42242
+ registerTool(registry2, memoryCreate(memoryEngine));
42243
+ registerTool(registry2, memoryUpdate(memoryEngine));
42244
+ registerTool(registry2, memoryDelete(memoryEngine));
41435
42245
  finalTools = getAllTools(registry2);
41436
42246
  finalExcutor = executor;
41437
42247
  } else {
@@ -41457,12 +42267,15 @@ ${getSkillMeta()}
41457
42267
  backgroundManager: bg,
41458
42268
  maxIterations: 150,
41459
42269
  channelPlugin: feishuChannel,
41460
- workspacePath: DEFAULT_WORKSPACE_PATH
42270
+ workspacePath: DEFAULT_WORKSPACE_PATH,
42271
+ dreamEngine,
42272
+ skillForgeEngine,
42273
+ memoryEngine
41461
42274
  };
41462
42275
  return agentConfig;
41463
42276
  };
41464
42277
  var createAgent = (config2 = getDefaultAgentConfig()) => {
41465
- const { systemPrompt, llm, storage, topicStorage, toolExecutor, tools, backgroundManager, maxIterations = 50 } = config2;
42278
+ const { systemPrompt, llm, storage, topicStorage, toolExecutor, tools, backgroundManager, maxIterations = 50, dreamEngine, skillForgeEngine, memoryEngine } = config2;
41466
42279
  const signals = /* @__PURE__ */ new Map();
41467
42280
  return async (request) => {
41468
42281
  if (config2.workspacePath && !request.defaultWorkDir) {
@@ -41482,6 +42295,13 @@ var createAgent = (config2 = getDefaultAgentConfig()) => {
41482
42295
  signals.set(userId, signal);
41483
42296
  markRunning(userId);
41484
42297
  try {
42298
+ if (dreamEngine) {
42299
+ try {
42300
+ await dreamEngine.checkAndDream(userId);
42301
+ } catch (err) {
42302
+ console.warn(`[agent] checkAndDream \u5931\u8D25\uFF1A${err.message}`);
42303
+ }
42304
+ }
41485
42305
  const now = /* @__PURE__ */ new Date();
41486
42306
  const beijingTime = now.toLocaleString("sv-SE", {
41487
42307
  timeZone: "Asia/Shanghai",
@@ -41493,9 +42313,42 @@ var createAgent = (config2 = getDefaultAgentConfig()) => {
41493
42313
  if (topicStorage) {
41494
42314
  await addTopicIndex(topicStorage, userId, beijingTime, msgIndex, content, job?.title);
41495
42315
  }
42316
+ if (memoryEngine) {
42317
+ try {
42318
+ const memoryBlock = await memoryEngine.buildContextBlock(userId);
42319
+ if (memoryBlock) {
42320
+ await addMessage(storage, userId, userMessage(text(memoryBlock)), beijingTime, job?.title);
42321
+ }
42322
+ } catch (err) {
42323
+ console.warn(`[memory] \u6CE8\u5165\u8BB0\u5FC6\u4E0A\u4E0B\u6587\u5931\u8D25\uFF1A${err.message}`);
42324
+ }
42325
+ }
42326
+ if (skillForgeEngine) {
42327
+ try {
42328
+ const pending = await skillForgeEngine.listPending(userId);
42329
+ if (pending.length > 0) {
42330
+ const lines = pending.map(
42331
+ (p) => ` - id=${p.id} name=${p.skillName} :: ${p.description}`
42332
+ ).join("\n");
42333
+ await addMessage(storage, userId, userMessage(text(
42334
+ `<pending-skill-proposal>
42335
+ \u5F53\u524D\u6709 ${pending.length} \u4E2A\u5F85\u7528\u6237\u786E\u8BA4\u7684\u6280\u80FD\u8349\u7A3F\uFF1A
42336
+ ${lines}
42337
+ \u5982\u679C\u7528\u6237\u8FD9\u6761\u6D88\u606F\u662F\u5728\u56DE\u5E94"\u8981\u4E0D\u8981\u4FDD\u7559"\u8FD9\u4E2A\u95EE\u9898\uFF1A
42338
+ \u2022 \u80AF\u5B9A\u610F\u56FE \u2192 \u8C03\u7528 skill_forge_keep\uFF08\u53EA\u6709 1 \u6761 pending \u65F6 proposalId \u53EF\u7701\u7565\uFF09
42339
+ \u2022 \u5426\u5B9A\u610F\u56FE \u2192 \u8C03\u7528 skill_forge_drop
42340
+ \u2022 \u672A\u8868\u6001 \u2192 \u5FFD\u7565\u672C\u63D0\u793A\uFF0C\u6B63\u5E38\u5904\u7406\u7528\u6237\u6D88\u606F
42341
+ </pending-skill-proposal>`
42342
+ )), beijingTime, job?.title);
42343
+ }
42344
+ } catch (err) {
42345
+ console.warn(`[skillForge] \u8BFB\u53D6 pending \u5217\u8868\u5931\u8D25\uFF1A${err.message}`);
42346
+ }
42347
+ }
41496
42348
  let iterations = 0;
41497
42349
  let hasSentMessage = false;
41498
42350
  let sentMessageContent = "";
42351
+ let emptyRetries = 0;
41499
42352
  while (iterations < maxIterations) {
41500
42353
  if (signal.aborted) throw new Error(`[\u667A\u80FD\u4F53\u4E2D\u65AD] \u53D7\u5230\u4E2D\u65AD\u4FE1\u53F7\u5DF2\u4E2D\u65AD`);
41501
42354
  iterations++;
@@ -41531,12 +42384,31 @@ ${msg}</user-interrupt>`
41531
42384
  )), beijingTime, job?.title);
41532
42385
  }
41533
42386
  }
41534
- const messages = await getMessages(storage, userId, 100, beijingTime, job?.title);
42387
+ const messages = await getMessages(storage, userId, 300, beijingTime, job?.title);
42388
+ const dreamInjection = dreamEngine ? await dreamEngine.injectDream(userId) : "";
42389
+ const effectiveSystemPrompt = systemPrompt + dreamInjection;
41535
42390
  const response = await llm.chat(
41536
42391
  messages,
41537
- systemPrompt,
42392
+ effectiveSystemPrompt,
41538
42393
  tools
41539
42394
  );
42395
+ if (response.stopReason === "model_context_window_exceeded") {
42396
+ console.warn(`[agent] \u4E0A\u4E0B\u6587\u7A97\u53E3\u8D85\u9650\uFF0C\u89E6\u53D1\u5F3A\u5236\u505A\u68A6\u4EE5\u538B\u7F29\u8BB0\u5FC6`);
42397
+ if (dreamEngine) {
42398
+ try {
42399
+ const result = await dreamEngine.dream(userId);
42400
+ console.log(`[agent] \u5F3A\u5236\u505A\u68A6\u5B8C\u6210\uFF0C\u68A6\u5883\u957F\u5EA6=${result?.dreamContent.length ?? 0}`);
42401
+ } catch (err) {
42402
+ console.error(`[agent] \u5F3A\u5236\u505A\u68A6\u5931\u8D25\uFF1A${err.message}`);
42403
+ }
42404
+ }
42405
+ await clearMessages(storage, userId, beijingTime, job?.title);
42406
+ await addMessage(storage, userId, userMessage(text(
42407
+ `<system-warning>\u4E0A\u4E0B\u6587\u6EA2\u51FA\uFF0C\u5DF2\u901A\u8FC7\u505A\u68A6\u538B\u7F29\u5386\u53F2\u5BF9\u8BDD\u3002\u91CD\u8981\u8BB0\u5FC6\u5DF2\u4FDD\u7559\u81F3\u68A6\u5883\uFF08systemPrompt \u4E2D\u7684 memory-context\uFF09\u3002\u8BF7\u76F4\u63A5\u56DE\u590D\u7528\u6237\u6700\u65B0\u7684\u6D88\u606F\u3002</system-warning>
42408
+ ${content}`
42409
+ )), beijingTime, job?.title);
42410
+ continue;
42411
+ }
41540
42412
  if (response.stopReason === "max_tokens") {
41541
42413
  const toolUsesTruncated = response.content.filter(isToolUseBlock);
41542
42414
  if (toolUsesTruncated.length > 0) {
@@ -41610,9 +42482,9 @@ ${msg}</user-interrupt>`
41610
42482
  const textBlocks = response.content.filter(
41611
42483
  (b) => b.type === "text"
41612
42484
  );
41613
- if (textBlocks.length > 0) {
41614
- const textContent = textBlocks.map((b) => b.text).join(`
41615
- `);
42485
+ const textContent = textBlocks.map((b) => b.text).join(`
42486
+ `).trim();
42487
+ if (textContent) {
41616
42488
  await addMessage(storage, userId, assistantMessage(text(textContent)), beijingTime, job?.title);
41617
42489
  const lateInterrupts = drainInterrupts(userId);
41618
42490
  if (lateInterrupts.length > 0) {
@@ -41625,6 +42497,10 @@ ${msg}</user-interrupt>`
41625
42497
  }
41626
42498
  continue;
41627
42499
  }
42500
+ if (topicStorage) {
42501
+ const topicSummary = hasSentMessage ? sentMessageContent : textContent;
42502
+ await updateTopicSummary(topicStorage, userId, beijingTime, topicSummary, job?.title);
42503
+ }
41628
42504
  return {
41629
42505
  content: hasSentMessage ? sentMessageContent : textContent,
41630
42506
  alreadySent: hasSentMessage
@@ -41642,12 +42518,27 @@ ${msg}</user-interrupt>`
41642
42518
  }
41643
42519
  continue;
41644
42520
  }
42521
+ if (topicStorage) {
42522
+ await updateTopicSummary(topicStorage, userId, beijingTime, sentMessageContent, job?.title);
42523
+ }
41645
42524
  return {
41646
42525
  content: sentMessageContent,
41647
42526
  alreadySent: true
41648
42527
  };
41649
42528
  }
41650
- throw new Error(`[createAgent] \u8FD0\u884C\u65F6\u5F02\u5E38\uFF0C\u667A\u80FD\u4F53\u6700\u540E\u7B54\u590D\u7ADF\u7136\u610F\u5916\u4E0D\u662F text \u7C7B\u578B`);
42529
+ emptyRetries++;
42530
+ console.warn(`[agent] LLM \u8FD4\u56DE\u7A7A\u5185\u5BB9\uFF08\u7B2C${emptyRetries}\u6B21\uFF09\uFF0CstopReason=${response.stopReason}, content=${JSON.stringify(response.content)}`);
42531
+ if (emptyRetries >= 3) {
42532
+ console.error(`[agent] LLM \u8FDE\u7EED ${emptyRetries} \u6B21\u8FD4\u56DE\u7A7A\u5185\u5BB9\uFF0C\u653E\u5F03\u91CD\u8BD5`);
42533
+ const fallback = "\u62B1\u6B49\uFF0C\u6211\u6682\u65F6\u65E0\u6CD5\u56DE\u590D\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002";
42534
+ await addMessage(storage, userId, assistantMessage(text(fallback)), beijingTime, job?.title);
42535
+ return { content: fallback, alreadySent: false };
42536
+ }
42537
+ await addMessage(storage, userId, assistantMessage(text("(\u601D\u8003\u4E2D...)")), beijingTime, job?.title);
42538
+ await addMessage(storage, userId, userMessage(text(
42539
+ "<system-warning>\u4F60\u7684\u4E0A\u4E00\u6761\u56DE\u590D\u5185\u5BB9\u4E3A\u7A7A\u3002\u8BF7\u91CD\u65B0\u7EC4\u7EC7\u56DE\u590D\uFF0C\u4F7F\u7528 send_message \u5DE5\u5177\u5411\u7528\u6237\u53D1\u9001\u6D88\u606F\u3002</system-warning>"
42540
+ )), beijingTime, job?.title);
42541
+ continue;
41651
42542
  }
41652
42543
  throw new Error(`\u8FBE\u5230\u6700\u5927\u8FED\u4EE3\u6B21\u6570:${maxIterations}`);
41653
42544
  } finally {
@@ -41828,9 +42719,9 @@ var RedisMessageDeduplication = class {
41828
42719
  };
41829
42720
 
41830
42721
  // src/channels/feishu/MessageProcess.ts
41831
- var import_node_path10 = require("node:path");
41832
- var import_node_os4 = require("node:os");
41833
- var import_node_fs5 = require("node:fs");
42722
+ var import_node_path11 = require("node:path");
42723
+ var import_node_os5 = require("node:os");
42724
+ var import_node_fs6 = require("node:fs");
41834
42725
 
41835
42726
  // src/oss/AliyunOSSClient.ts
41836
42727
  var import_ali_oss = __toESM(require("ali-oss"));
@@ -41867,10 +42758,10 @@ var createAliyunOssClient = () => {
41867
42758
 
41868
42759
  // src/channels/feishu/MessageProcess.ts
41869
42760
  var saveToLocal = (userId, subDir, fileName, buffer) => {
41870
- const dir = (0, import_node_path10.join)((0, import_node_os4.homedir)(), ".duclaw", "workspace", userId, subDir);
41871
- (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
41872
- const filePath = (0, import_node_path10.join)(dir, fileName);
41873
- (0, import_node_fs5.writeFileSync)(filePath, buffer);
42761
+ const dir = (0, import_node_path11.join)((0, import_node_os5.homedir)(), ".duclaw", "workspace", userId, subDir);
42762
+ (0, import_node_fs6.mkdirSync)(dir, { recursive: true });
42763
+ const filePath = (0, import_node_path11.join)(dir, fileName);
42764
+ (0, import_node_fs6.writeFileSync)(filePath, buffer);
41874
42765
  return filePath;
41875
42766
  };
41876
42767
  var tryUploadToOss = async (ossPath, buffer) => {
@@ -42120,7 +43011,7 @@ var createDefaultChannels = () => {
42120
43011
  };
42121
43012
 
42122
43013
  // src/tools/tools/team/ListMailbox.ts
42123
- var DESCRIPTION29 = `
43014
+ var DESCRIPTION35 = `
42124
43015
  \u67E5\u770B\u4F60\u7684\u90AE\u7BB1\u4E2D\u6240\u6709\u5F85\u5904\u7406\u90AE\u4EF6\u7684\u6458\u8981\u5217\u8868\u3002
42125
43016
 
42126
43017
  \u8FD4\u56DE\u6BCF\u5C01\u90AE\u4EF6\u7684\uFF1Aid\u3001\u53D1\u9001\u8005\u3001\u53D1\u9001\u65F6\u95F4\u3001\u5185\u5BB9\u6458\u8981\uFF08\u524D100\u5B57\uFF09\u3002
@@ -42134,7 +43025,7 @@ var DESCRIPTION29 = `
42134
43025
  `;
42135
43026
  var listMailbox = {
42136
43027
  name: `list_mailbox`,
42137
- description: DESCRIPTION29,
43028
+ description: DESCRIPTION35,
42138
43029
  input_schema: {
42139
43030
  type: `object`,
42140
43031
  properties: {},
@@ -42171,7 +43062,7 @@ ${list}`;
42171
43062
  };
42172
43063
 
42173
43064
  // src/tools/tools/team/GetMailbox.ts
42174
- var DESCRIPTION30 = `
43065
+ var DESCRIPTION36 = `
42175
43066
  \u83B7\u53D6\u6307\u5B9A\u90AE\u4EF6\u7684\u5B8C\u6574\u5185\u5BB9\u3002
42176
43067
 
42177
43068
  \u5728 list_mailbox \u67E5\u770B\u90AE\u4EF6\u5217\u8868\u540E\uFF0C\u4F7F\u7528\u6B64\u5DE5\u5177\u83B7\u53D6\u4F60\u60F3\u8981\u5904\u7406\u7684\u90AE\u4EF6\u7684\u5B8C\u6574\u5185\u5BB9\u3002
@@ -42182,7 +43073,7 @@ var DESCRIPTION30 = `
42182
43073
  `;
42183
43074
  var getMailbox = {
42184
43075
  name: `get_mailbox`,
42185
- description: DESCRIPTION30,
43076
+ description: DESCRIPTION36,
42186
43077
  input_schema: {
42187
43078
  type: `object`,
42188
43079
  properties: {
@@ -42223,7 +43114,7 @@ ${msg.content}`;
42223
43114
  };
42224
43115
 
42225
43116
  // src/tools/tools/team/ReplyMailbox.ts
42226
- var DESCRIPTION31 = `
43117
+ var DESCRIPTION37 = `
42227
43118
  \u56DE\u590D\u4E00\u5C01\u90AE\u4EF6\u3002\u5B8C\u6210\u5DE5\u4F5C\u540E\uFF0C\u4F7F\u7528\u6B64\u5DE5\u5177\u5C06\u7ED3\u679C\u53D1\u56DE\u7ED9\u90AE\u4EF6\u7684\u53D1\u9001\u8005\u3002
42228
43119
 
42229
43120
  \u53C2\u6570\uFF1A
@@ -42236,7 +43127,7 @@ var DESCRIPTION31 = `
42236
43127
  `;
42237
43128
  var replyMailbox = {
42238
43129
  name: `reply_mailbox`,
42239
- description: DESCRIPTION31,
43130
+ description: DESCRIPTION37,
42240
43131
  input_schema: {
42241
43132
  type: `object`,
42242
43133
  properties: {
@@ -42278,6 +43169,7 @@ var replyMailbox = {
42278
43169
  };
42279
43170
 
42280
43171
  // src/cron/mailbox.ts
43172
+ var import_crypto5 = require("crypto");
42281
43173
  var db2 = createSqliteDB();
42282
43174
  var selectStmt = db2.prepare(`select id, to_mailbox_id as toMailboxId, from_mailbox_id as fromMailboxId, content, send_time as sendTime, status
42283
43175
  from mailbox where status = ?`);
@@ -42343,6 +43235,25 @@ var wakeTeamAgent = async (mailboxId, msgIds) => {
42343
43235
  const member = getTeamMemberByName(teamName, memberName);
42344
43236
  if (!member) {
42345
43237
  console.warn(`[mailbox] \u76EE\u6807\u6210\u5458\u4E0D\u5B58\u5728\uFF08\u53EF\u80FD\u5DF2\u88AB\u5220\u9664\uFF09: ${mailboxId}`);
43238
+ const notifyContent = `[\u7CFB\u7EDF\u901A\u77E5] \u56E2\u961F\u6210\u5458 ${mailboxId} \u4E0D\u5B58\u5728\uFF08\u53EF\u80FD\u6240\u5C5E\u56E2\u961F\u5DF2\u89E3\u6563\u6216\u6210\u5458\u5DF2\u88AB\u5220\u9664\uFF09\uFF0C\u4EE5\u4E0B\u6D88\u606F\u65E0\u6CD5\u6295\u9012\u5DF2\u88AB\u53D6\u6D88\u3002\u8BF7\u6839\u636E\u60C5\u51B5\u51B3\u5B9A\u662F\u5426\u9700\u8981\u91CD\u65B0\u7EC4\u5EFA\u56E2\u961F\u6216\u8C03\u6574\u8BA1\u5212\u3002`;
43239
+ const originStmt = db2.prepare(
43240
+ `SELECT origin_user_id as originUserId, origin_platform as originPlatform
43241
+ FROM mailbox WHERE id IN (${msgIds.map(() => "?").join(",")}) AND origin_user_id IS NOT NULL LIMIT 1`
43242
+ );
43243
+ const origin = originStmt.get(...msgIds);
43244
+ const insertStmt = db2.prepare(
43245
+ `INSERT INTO mailbox (id, to_mailbox_id, from_mailbox_id, content, send_time, status, origin_user_id, origin_platform) VALUES (?,?,?,?,?,?,?,?)`
43246
+ );
43247
+ insertStmt.run(
43248
+ (0, import_crypto5.randomUUID)().slice(0, 8),
43249
+ "manager",
43250
+ mailboxId,
43251
+ notifyContent,
43252
+ (/* @__PURE__ */ new Date()).getTime(),
43253
+ "pending",
43254
+ origin?.originUserId || null,
43255
+ origin?.originPlatform || null
43256
+ );
42346
43257
  for (const id of msgIds) markMailboxStatus(id, "cancelled");
42347
43258
  return;
42348
43259
  }
@@ -42650,26 +43561,26 @@ var handleParsingNestedValues = (form, key, value) => {
42650
43561
  };
42651
43562
 
42652
43563
  // node_modules/.pnpm/hono@4.12.9/node_modules/hono/dist/utils/url.js
42653
- var splitPath = (path9) => {
42654
- const paths = path9.split("/");
43564
+ var splitPath = (path10) => {
43565
+ const paths = path10.split("/");
42655
43566
  if (paths[0] === "") {
42656
43567
  paths.shift();
42657
43568
  }
42658
43569
  return paths;
42659
43570
  };
42660
43571
  var splitRoutingPath = (routePath) => {
42661
- const { groups, path: path9 } = extractGroupsFromPath(routePath);
42662
- const paths = splitPath(path9);
43572
+ const { groups, path: path10 } = extractGroupsFromPath(routePath);
43573
+ const paths = splitPath(path10);
42663
43574
  return replaceGroupMarks(paths, groups);
42664
43575
  };
42665
- var extractGroupsFromPath = (path9) => {
43576
+ var extractGroupsFromPath = (path10) => {
42666
43577
  const groups = [];
42667
- path9 = path9.replace(/\{[^}]+\}/g, (match2, index) => {
43578
+ path10 = path10.replace(/\{[^}]+\}/g, (match2, index) => {
42668
43579
  const mark = `@${index}`;
42669
43580
  groups.push([mark, match2]);
42670
43581
  return mark;
42671
43582
  });
42672
- return { groups, path: path9 };
43583
+ return { groups, path: path10 };
42673
43584
  };
42674
43585
  var replaceGroupMarks = (paths, groups) => {
42675
43586
  for (let i = groups.length - 1; i >= 0; i--) {
@@ -42726,8 +43637,8 @@ var getPath = (request) => {
42726
43637
  const queryIndex = url.indexOf("?", i);
42727
43638
  const hashIndex = url.indexOf("#", i);
42728
43639
  const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
42729
- const path9 = url.slice(start, end);
42730
- return tryDecodeURI(path9.includes("%25") ? path9.replace(/%25/g, "%2525") : path9);
43640
+ const path10 = url.slice(start, end);
43641
+ return tryDecodeURI(path10.includes("%25") ? path10.replace(/%25/g, "%2525") : path10);
42731
43642
  } else if (charCode === 63 || charCode === 35) {
42732
43643
  break;
42733
43644
  }
@@ -42744,11 +43655,11 @@ var mergePath = (base, sub, ...rest) => {
42744
43655
  }
42745
43656
  return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
42746
43657
  };
42747
- var checkOptionalParameter = (path9) => {
42748
- if (path9.charCodeAt(path9.length - 1) !== 63 || !path9.includes(":")) {
43658
+ var checkOptionalParameter = (path10) => {
43659
+ if (path10.charCodeAt(path10.length - 1) !== 63 || !path10.includes(":")) {
42749
43660
  return null;
42750
43661
  }
42751
- const segments = path9.split("/");
43662
+ const segments = path10.split("/");
42752
43663
  const results = [];
42753
43664
  let basePath = "";
42754
43665
  segments.forEach((segment) => {
@@ -42889,9 +43800,9 @@ var HonoRequest = class {
42889
43800
  */
42890
43801
  path;
42891
43802
  bodyCache = {};
42892
- constructor(request, path9 = "/", matchResult = [[]]) {
43803
+ constructor(request, path10 = "/", matchResult = [[]]) {
42893
43804
  this.raw = request;
42894
- this.path = path9;
43805
+ this.path = path10;
42895
43806
  this.#matchResult = matchResult;
42896
43807
  this.#validatedData = {};
42897
43808
  }
@@ -43628,8 +44539,8 @@ var Hono = class _Hono {
43628
44539
  return this;
43629
44540
  };
43630
44541
  });
43631
- this.on = (method, path9, ...handlers) => {
43632
- for (const p of [path9].flat()) {
44542
+ this.on = (method, path10, ...handlers) => {
44543
+ for (const p of [path10].flat()) {
43633
44544
  this.#path = p;
43634
44545
  for (const m of [method].flat()) {
43635
44546
  handlers.map((handler) => {
@@ -43686,8 +44597,8 @@ var Hono = class _Hono {
43686
44597
  * app.route("/api", app2) // GET /api/user
43687
44598
  * ```
43688
44599
  */
43689
- route(path9, app) {
43690
- const subApp = this.basePath(path9);
44600
+ route(path10, app) {
44601
+ const subApp = this.basePath(path10);
43691
44602
  app.routes.map((r) => {
43692
44603
  let handler;
43693
44604
  if (app.errorHandler === errorHandler) {
@@ -43713,9 +44624,9 @@ var Hono = class _Hono {
43713
44624
  * const api = new Hono().basePath('/api')
43714
44625
  * ```
43715
44626
  */
43716
- basePath(path9) {
44627
+ basePath(path10) {
43717
44628
  const subApp = this.#clone();
43718
- subApp._basePath = mergePath(this._basePath, path9);
44629
+ subApp._basePath = mergePath(this._basePath, path10);
43719
44630
  return subApp;
43720
44631
  }
43721
44632
  /**
@@ -43789,7 +44700,7 @@ var Hono = class _Hono {
43789
44700
  * })
43790
44701
  * ```
43791
44702
  */
43792
- mount(path9, applicationHandler, options) {
44703
+ mount(path10, applicationHandler, options) {
43793
44704
  let replaceRequest;
43794
44705
  let optionHandler;
43795
44706
  if (options) {
@@ -43816,7 +44727,7 @@ var Hono = class _Hono {
43816
44727
  return [c.env, executionContext];
43817
44728
  };
43818
44729
  replaceRequest ||= (() => {
43819
- const mergedPath = mergePath(this._basePath, path9);
44730
+ const mergedPath = mergePath(this._basePath, path10);
43820
44731
  const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
43821
44732
  return (request) => {
43822
44733
  const url = new URL(request.url);
@@ -43831,14 +44742,14 @@ var Hono = class _Hono {
43831
44742
  }
43832
44743
  await next();
43833
44744
  };
43834
- this.#addRoute(METHOD_NAME_ALL, mergePath(path9, "*"), handler);
44745
+ this.#addRoute(METHOD_NAME_ALL, mergePath(path10, "*"), handler);
43835
44746
  return this;
43836
44747
  }
43837
- #addRoute(method, path9, handler) {
44748
+ #addRoute(method, path10, handler) {
43838
44749
  method = method.toUpperCase();
43839
- path9 = mergePath(this._basePath, path9);
43840
- const r = { basePath: this._basePath, path: path9, method, handler };
43841
- this.router.add(method, path9, [handler, r]);
44750
+ path10 = mergePath(this._basePath, path10);
44751
+ const r = { basePath: this._basePath, path: path10, method, handler };
44752
+ this.router.add(method, path10, [handler, r]);
43842
44753
  this.routes.push(r);
43843
44754
  }
43844
44755
  #handleError(err, c) {
@@ -43851,10 +44762,10 @@ var Hono = class _Hono {
43851
44762
  if (method === "HEAD") {
43852
44763
  return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))();
43853
44764
  }
43854
- const path9 = this.getPath(request, { env });
43855
- const matchResult = this.router.match(method, path9);
44765
+ const path10 = this.getPath(request, { env });
44766
+ const matchResult = this.router.match(method, path10);
43856
44767
  const c = new Context(request, {
43857
- path: path9,
44768
+ path: path10,
43858
44769
  matchResult,
43859
44770
  env,
43860
44771
  executionCtx,
@@ -43954,7 +44865,7 @@ var Hono = class _Hono {
43954
44865
 
43955
44866
  // node_modules/.pnpm/hono@4.12.9/node_modules/hono/dist/router/reg-exp-router/matcher.js
43956
44867
  var emptyParam = [];
43957
- function match(method, path9) {
44868
+ function match(method, path10) {
43958
44869
  const matchers = this.buildAllMatchers();
43959
44870
  const match2 = ((method2, path22) => {
43960
44871
  const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
@@ -43970,7 +44881,7 @@ function match(method, path9) {
43970
44881
  return [matcher[1][index], match3];
43971
44882
  });
43972
44883
  this.match = match2;
43973
- return match2(method, path9);
44884
+ return match2(method, path10);
43974
44885
  }
43975
44886
 
43976
44887
  // node_modules/.pnpm/hono@4.12.9/node_modules/hono/dist/router/reg-exp-router/node.js
@@ -44085,12 +44996,12 @@ var Node = class _Node {
44085
44996
  var Trie = class {
44086
44997
  #context = { varIndex: 0 };
44087
44998
  #root = new Node();
44088
- insert(path9, index, pathErrorCheckOnly) {
44999
+ insert(path10, index, pathErrorCheckOnly) {
44089
45000
  const paramAssoc = [];
44090
45001
  const groups = [];
44091
45002
  for (let i = 0; ; ) {
44092
45003
  let replaced = false;
44093
- path9 = path9.replace(/\{[^}]+\}/g, (m) => {
45004
+ path10 = path10.replace(/\{[^}]+\}/g, (m) => {
44094
45005
  const mark = `@\\${i}`;
44095
45006
  groups[i] = [mark, m];
44096
45007
  i++;
@@ -44101,7 +45012,7 @@ var Trie = class {
44101
45012
  break;
44102
45013
  }
44103
45014
  }
44104
- const tokens = path9.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
45015
+ const tokens = path10.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
44105
45016
  for (let i = groups.length - 1; i >= 0; i--) {
44106
45017
  const [mark] = groups[i];
44107
45018
  for (let j = tokens.length - 1; j >= 0; j--) {
@@ -44140,9 +45051,9 @@ var Trie = class {
44140
45051
  // node_modules/.pnpm/hono@4.12.9/node_modules/hono/dist/router/reg-exp-router/router.js
44141
45052
  var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
44142
45053
  var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
44143
- function buildWildcardRegExp(path9) {
44144
- return wildcardRegExpCache[path9] ??= new RegExp(
44145
- path9 === "*" ? "" : `^${path9.replace(
45054
+ function buildWildcardRegExp(path10) {
45055
+ return wildcardRegExpCache[path10] ??= new RegExp(
45056
+ path10 === "*" ? "" : `^${path10.replace(
44146
45057
  /\/\*$|([.\\+*[^\]$()])/g,
44147
45058
  (_, metaChar) => metaChar ? `\\${metaChar}` : "(?:|/.*)"
44148
45059
  )}$`
@@ -44164,17 +45075,17 @@ function buildMatcherFromPreprocessedRoutes(routes) {
44164
45075
  );
44165
45076
  const staticMap = /* @__PURE__ */ Object.create(null);
44166
45077
  for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
44167
- const [pathErrorCheckOnly, path9, handlers] = routesWithStaticPathFlag[i];
45078
+ const [pathErrorCheckOnly, path10, handlers] = routesWithStaticPathFlag[i];
44168
45079
  if (pathErrorCheckOnly) {
44169
- staticMap[path9] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
45080
+ staticMap[path10] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
44170
45081
  } else {
44171
45082
  j++;
44172
45083
  }
44173
45084
  let paramAssoc;
44174
45085
  try {
44175
- paramAssoc = trie.insert(path9, j, pathErrorCheckOnly);
45086
+ paramAssoc = trie.insert(path10, j, pathErrorCheckOnly);
44176
45087
  } catch (e) {
44177
- throw e === PATH_ERROR ? new UnsupportedPathError(path9) : e;
45088
+ throw e === PATH_ERROR ? new UnsupportedPathError(path10) : e;
44178
45089
  }
44179
45090
  if (pathErrorCheckOnly) {
44180
45091
  continue;
@@ -44208,12 +45119,12 @@ function buildMatcherFromPreprocessedRoutes(routes) {
44208
45119
  }
44209
45120
  return [regexp, handlerMap, staticMap];
44210
45121
  }
44211
- function findMiddleware(middleware, path9) {
45122
+ function findMiddleware(middleware, path10) {
44212
45123
  if (!middleware) {
44213
45124
  return void 0;
44214
45125
  }
44215
45126
  for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
44216
- if (buildWildcardRegExp(k).test(path9)) {
45127
+ if (buildWildcardRegExp(k).test(path10)) {
44217
45128
  return [...middleware[k]];
44218
45129
  }
44219
45130
  }
@@ -44227,7 +45138,7 @@ var RegExpRouter = class {
44227
45138
  this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
44228
45139
  this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
44229
45140
  }
44230
- add(method, path9, handler) {
45141
+ add(method, path10, handler) {
44231
45142
  const middleware = this.#middleware;
44232
45143
  const routes = this.#routes;
44233
45144
  if (!middleware || !routes) {
@@ -44242,18 +45153,18 @@ var RegExpRouter = class {
44242
45153
  });
44243
45154
  });
44244
45155
  }
44245
- if (path9 === "/*") {
44246
- path9 = "*";
45156
+ if (path10 === "/*") {
45157
+ path10 = "*";
44247
45158
  }
44248
- const paramCount = (path9.match(/\/:/g) || []).length;
44249
- if (/\*$/.test(path9)) {
44250
- const re = buildWildcardRegExp(path9);
45159
+ const paramCount = (path10.match(/\/:/g) || []).length;
45160
+ if (/\*$/.test(path10)) {
45161
+ const re = buildWildcardRegExp(path10);
44251
45162
  if (method === METHOD_NAME_ALL) {
44252
45163
  Object.keys(middleware).forEach((m) => {
44253
- middleware[m][path9] ||= findMiddleware(middleware[m], path9) || findMiddleware(middleware[METHOD_NAME_ALL], path9) || [];
45164
+ middleware[m][path10] ||= findMiddleware(middleware[m], path10) || findMiddleware(middleware[METHOD_NAME_ALL], path10) || [];
44254
45165
  });
44255
45166
  } else {
44256
- middleware[method][path9] ||= findMiddleware(middleware[method], path9) || findMiddleware(middleware[METHOD_NAME_ALL], path9) || [];
45167
+ middleware[method][path10] ||= findMiddleware(middleware[method], path10) || findMiddleware(middleware[METHOD_NAME_ALL], path10) || [];
44257
45168
  }
44258
45169
  Object.keys(middleware).forEach((m) => {
44259
45170
  if (method === METHOD_NAME_ALL || method === m) {
@@ -44271,7 +45182,7 @@ var RegExpRouter = class {
44271
45182
  });
44272
45183
  return;
44273
45184
  }
44274
- const paths = checkOptionalParameter(path9) || [path9];
45185
+ const paths = checkOptionalParameter(path10) || [path10];
44275
45186
  for (let i = 0, len = paths.length; i < len; i++) {
44276
45187
  const path22 = paths[i];
44277
45188
  Object.keys(routes).forEach((m) => {
@@ -44298,13 +45209,13 @@ var RegExpRouter = class {
44298
45209
  const routes = [];
44299
45210
  let hasOwnRoute = method === METHOD_NAME_ALL;
44300
45211
  [this.#middleware, this.#routes].forEach((r) => {
44301
- const ownRoute = r[method] ? Object.keys(r[method]).map((path9) => [path9, r[method][path9]]) : [];
45212
+ const ownRoute = r[method] ? Object.keys(r[method]).map((path10) => [path10, r[method][path10]]) : [];
44302
45213
  if (ownRoute.length !== 0) {
44303
45214
  hasOwnRoute ||= true;
44304
45215
  routes.push(...ownRoute);
44305
45216
  } else if (method !== METHOD_NAME_ALL) {
44306
45217
  routes.push(
44307
- ...Object.keys(r[METHOD_NAME_ALL]).map((path9) => [path9, r[METHOD_NAME_ALL][path9]])
45218
+ ...Object.keys(r[METHOD_NAME_ALL]).map((path10) => [path10, r[METHOD_NAME_ALL][path10]])
44308
45219
  );
44309
45220
  }
44310
45221
  });
@@ -44324,13 +45235,13 @@ var SmartRouter = class {
44324
45235
  constructor(init) {
44325
45236
  this.#routers = init.routers;
44326
45237
  }
44327
- add(method, path9, handler) {
45238
+ add(method, path10, handler) {
44328
45239
  if (!this.#routes) {
44329
45240
  throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
44330
45241
  }
44331
- this.#routes.push([method, path9, handler]);
45242
+ this.#routes.push([method, path10, handler]);
44332
45243
  }
44333
- match(method, path9) {
45244
+ match(method, path10) {
44334
45245
  if (!this.#routes) {
44335
45246
  throw new Error("Fatal error");
44336
45247
  }
@@ -44345,7 +45256,7 @@ var SmartRouter = class {
44345
45256
  for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {
44346
45257
  router.add(...routes[i2]);
44347
45258
  }
44348
- res = router.match(method, path9);
45259
+ res = router.match(method, path10);
44349
45260
  } catch (e) {
44350
45261
  if (e instanceof UnsupportedPathError) {
44351
45262
  continue;
@@ -44395,10 +45306,10 @@ var Node2 = class _Node2 {
44395
45306
  }
44396
45307
  this.#patterns = [];
44397
45308
  }
44398
- insert(method, path9, handler) {
45309
+ insert(method, path10, handler) {
44399
45310
  this.#order = ++this.#order;
44400
45311
  let curNode = this;
44401
- const parts = splitRoutingPath(path9);
45312
+ const parts = splitRoutingPath(path10);
44402
45313
  const possibleKeys = [];
44403
45314
  for (let i = 0, len = parts.length; i < len; i++) {
44404
45315
  const p = parts[i];
@@ -44447,12 +45358,12 @@ var Node2 = class _Node2 {
44447
45358
  }
44448
45359
  }
44449
45360
  }
44450
- search(method, path9) {
45361
+ search(method, path10) {
44451
45362
  const handlerSets = [];
44452
45363
  this.#params = emptyParams;
44453
45364
  const curNode = this;
44454
45365
  let curNodes = [curNode];
44455
- const parts = splitPath(path9);
45366
+ const parts = splitPath(path10);
44456
45367
  const curNodesQueue = [];
44457
45368
  const len = parts.length;
44458
45369
  let partOffsets = null;
@@ -44494,13 +45405,13 @@ var Node2 = class _Node2 {
44494
45405
  if (matcher instanceof RegExp) {
44495
45406
  if (partOffsets === null) {
44496
45407
  partOffsets = new Array(len);
44497
- let offset = path9[0] === "/" ? 1 : 0;
45408
+ let offset = path10[0] === "/" ? 1 : 0;
44498
45409
  for (let p = 0; p < len; p++) {
44499
45410
  partOffsets[p] = offset;
44500
45411
  offset += parts[p].length + 1;
44501
45412
  }
44502
45413
  }
44503
- const restPathString = path9.substring(partOffsets[i]);
45414
+ const restPathString = path10.substring(partOffsets[i]);
44504
45415
  const m = matcher.exec(restPathString);
44505
45416
  if (m) {
44506
45417
  params[name] = m[0];
@@ -44553,18 +45464,18 @@ var TrieRouter = class {
44553
45464
  constructor() {
44554
45465
  this.#node = new Node2();
44555
45466
  }
44556
- add(method, path9, handler) {
44557
- const results = checkOptionalParameter(path9);
45467
+ add(method, path10, handler) {
45468
+ const results = checkOptionalParameter(path10);
44558
45469
  if (results) {
44559
45470
  for (let i = 0, len = results.length; i < len; i++) {
44560
45471
  this.#node.insert(method, results[i], handler);
44561
45472
  }
44562
45473
  return;
44563
45474
  }
44564
- this.#node.insert(method, path9, handler);
45475
+ this.#node.insert(method, path10, handler);
44565
45476
  }
44566
- match(method, path9) {
44567
- return this.#node.search(method, path9);
45477
+ match(method, path10) {
45478
+ return this.#node.search(method, path10);
44568
45479
  }
44569
45480
  };
44570
45481
 
@@ -44588,7 +45499,7 @@ var import_http = require("http");
44588
45499
  var import_http2 = require("http2");
44589
45500
  var import_http22 = require("http2");
44590
45501
  var import_stream = require("stream");
44591
- var import_crypto5 = __toESM(require("crypto"), 1);
45502
+ var import_crypto6 = __toESM(require("crypto"), 1);
44592
45503
  var RequestError = class extends Error {
44593
45504
  constructor(message, options) {
44594
45505
  super(message, options);
@@ -44905,7 +45816,7 @@ var buildOutgoingHttpHeaders = (headers) => {
44905
45816
  };
44906
45817
  var X_ALREADY_SENT = "x-hono-already-sent";
44907
45818
  if (typeof global.crypto === "undefined") {
44908
- global.crypto = import_crypto5.default;
45819
+ global.crypto = import_crypto6.default;
44909
45820
  }
44910
45821
  var outgoingEnded = /* @__PURE__ */ Symbol("outgoingEnded");
44911
45822
  var handleRequestError = () => new Response(null, {
@@ -45228,8 +46139,8 @@ var _baseMimes = {
45228
46139
  var baseMimes = _baseMimes;
45229
46140
 
45230
46141
  // node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.9/node_modules/@hono/node-server/dist/serve-static.mjs
45231
- var import_fs11 = require("fs");
45232
- var import_path17 = require("path");
46142
+ var import_fs12 = require("fs");
46143
+ var import_path18 = require("path");
45233
46144
  var import_process = require("process");
45234
46145
  var import_stream2 = require("stream");
45235
46146
  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;
@@ -45266,10 +46177,10 @@ var createStreamBody = (stream) => {
45266
46177
  });
45267
46178
  return body;
45268
46179
  };
45269
- var getStats = (path9) => {
46180
+ var getStats = (path10) => {
45270
46181
  let stats;
45271
46182
  try {
45272
- stats = (0, import_fs11.statSync)(path9);
46183
+ stats = (0, import_fs12.statSync)(path10);
45273
46184
  } catch {
45274
46185
  }
45275
46186
  return stats;
@@ -45291,7 +46202,7 @@ var tryDecodeURI2 = (str) => tryDecode2(str, decodeURI);
45291
46202
  var serveStatic = (options = { root: "" }) => {
45292
46203
  const root = options.root || "";
45293
46204
  const optionPath = options.path;
45294
- if (root !== "" && !(0, import_fs11.existsSync)(root)) {
46205
+ if (root !== "" && !(0, import_fs12.existsSync)(root)) {
45295
46206
  console.error(`serveStatic: root path '${root}' is not found, are you sure it's correct?`);
45296
46207
  }
45297
46208
  return async (c, next) => {
@@ -45312,21 +46223,21 @@ var serveStatic = (options = { root: "" }) => {
45312
46223
  return next();
45313
46224
  }
45314
46225
  }
45315
- let path9 = (0, import_path17.join)(
46226
+ let path10 = (0, import_path18.join)(
45316
46227
  root,
45317
46228
  !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename
45318
46229
  );
45319
- let stats = getStats(path9);
46230
+ let stats = getStats(path10);
45320
46231
  if (stats && stats.isDirectory()) {
45321
46232
  const indexFile = options.index ?? "index.html";
45322
- path9 = (0, import_path17.join)(path9, indexFile);
45323
- stats = getStats(path9);
46233
+ path10 = (0, import_path18.join)(path10, indexFile);
46234
+ stats = getStats(path10);
45324
46235
  }
45325
46236
  if (!stats) {
45326
- await options.onNotFound?.(path9, c);
46237
+ await options.onNotFound?.(path10, c);
45327
46238
  return next();
45328
46239
  }
45329
- const mimeType = getMimeType(path9);
46240
+ const mimeType = getMimeType(path10);
45330
46241
  c.header("Content-Type", mimeType || "application/octet-stream");
45331
46242
  if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
45332
46243
  const acceptEncodingSet = new Set(
@@ -45336,12 +46247,12 @@ var serveStatic = (options = { root: "" }) => {
45336
46247
  if (!acceptEncodingSet.has(encoding)) {
45337
46248
  continue;
45338
46249
  }
45339
- const precompressedStats = getStats(path9 + ENCODINGS[encoding]);
46250
+ const precompressedStats = getStats(path10 + ENCODINGS[encoding]);
45340
46251
  if (precompressedStats) {
45341
46252
  c.header("Content-Encoding", encoding);
45342
46253
  c.header("Vary", "Accept-Encoding", { append: true });
45343
46254
  stats = precompressedStats;
45344
- path9 = path9 + ENCODINGS[encoding];
46255
+ path10 = path10 + ENCODINGS[encoding];
45345
46256
  break;
45346
46257
  }
45347
46258
  }
@@ -45355,7 +46266,7 @@ var serveStatic = (options = { root: "" }) => {
45355
46266
  result = c.body(null);
45356
46267
  } else if (!range) {
45357
46268
  c.header("Content-Length", size.toString());
45358
- result = c.body(createStreamBody((0, import_fs11.createReadStream)(path9)), 200);
46269
+ result = c.body(createStreamBody((0, import_fs12.createReadStream)(path10)), 200);
45359
46270
  } else {
45360
46271
  c.header("Accept-Ranges", "bytes");
45361
46272
  c.header("Date", stats.birthtime.toUTCString());
@@ -45366,12 +46277,12 @@ var serveStatic = (options = { root: "" }) => {
45366
46277
  end = size - 1;
45367
46278
  }
45368
46279
  const chunksize = end - start + 1;
45369
- const stream = (0, import_fs11.createReadStream)(path9, { start, end });
46280
+ const stream = (0, import_fs12.createReadStream)(path10, { start, end });
45370
46281
  c.header("Content-Length", chunksize.toString());
45371
46282
  c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`);
45372
46283
  result = c.body(createStreamBody(stream), 206);
45373
46284
  }
45374
- await options.onFound?.(path9, c);
46285
+ await options.onFound?.(path10, c);
45375
46286
  return result;
45376
46287
  };
45377
46288
  };
@@ -45467,12 +46378,12 @@ var cors = (options) => {
45467
46378
  // src/git/worktree.ts
45468
46379
  var import_child_process2 = require("child_process");
45469
46380
  var import_util = require("util");
45470
- var import_path18 = __toESM(require("path"));
45471
- var import_fs12 = require("fs");
46381
+ var import_path19 = __toESM(require("path"));
46382
+ var import_fs13 = require("fs");
45472
46383
  var execFileAsync = (0, import_util.promisify)(import_child_process2.execFile);
45473
46384
  var getProjectRoot = () => process.cwd();
45474
- var getWorktreeBaseDir = () => import_path18.default.join(getProjectRoot(), ".worktrees");
45475
- var getWorktreePath = (goalId, taskId) => import_path18.default.join(getWorktreeBaseDir(), goalId, taskId);
46385
+ var getWorktreeBaseDir = () => import_path19.default.join(getProjectRoot(), ".worktrees");
46386
+ var getWorktreePath = (goalId, taskId) => import_path19.default.join(getWorktreeBaseDir(), goalId, taskId);
45476
46387
  var getBranchName = (taskId) => `task/${taskId}`;
45477
46388
  async function git(args, cwd) {
45478
46389
  const { stdout } = await execFileAsync("git", args, {
@@ -45484,14 +46395,14 @@ async function git(args, cwd) {
45484
46395
  async function createWorktree(taskId, goalId, baseBranch = "main") {
45485
46396
  const wtPath = getWorktreePath(goalId, taskId);
45486
46397
  const branch = getBranchName(taskId);
45487
- const parentDir = import_path18.default.dirname(wtPath);
45488
- if (!(0, import_fs12.existsSync)(parentDir)) {
45489
- (0, import_fs12.mkdirSync)(parentDir, { recursive: true });
46398
+ const parentDir = import_path19.default.dirname(wtPath);
46399
+ if (!(0, import_fs13.existsSync)(parentDir)) {
46400
+ (0, import_fs13.mkdirSync)(parentDir, { recursive: true });
45490
46401
  }
45491
46402
  await git(["worktree", "add", "-b", branch, wtPath, baseBranch]);
45492
46403
  return {
45493
46404
  branch,
45494
- path: import_path18.default.relative(getProjectRoot(), wtPath),
46405
+ path: import_path19.default.relative(getProjectRoot(), wtPath),
45495
46406
  baseBranch,
45496
46407
  createdAt: getDate()
45497
46408
  };
@@ -45499,7 +46410,7 @@ async function createWorktree(taskId, goalId, baseBranch = "main") {
45499
46410
  async function deleteWorktree(taskId, goalId) {
45500
46411
  const wtPath = getWorktreePath(goalId, taskId);
45501
46412
  const branch = getBranchName(taskId);
45502
- if ((0, import_fs12.existsSync)(wtPath)) {
46413
+ if ((0, import_fs13.existsSync)(wtPath)) {
45503
46414
  await git(["worktree", "remove", wtPath, "--force"]);
45504
46415
  }
45505
46416
  try {
@@ -45590,8 +46501,8 @@ async function listWorktrees() {
45590
46501
  const fullBranch = branchLine.replace("branch refs/heads/", "");
45591
46502
  if (!fullBranch.startsWith("task/")) continue;
45592
46503
  const taskId = fullBranch.replace("task/", "");
45593
- const relPath = import_path18.default.relative(getProjectRoot(), wtPath);
45594
- const parts = relPath.split(import_path18.default.sep);
46504
+ const relPath = import_path19.default.relative(getProjectRoot(), wtPath);
46505
+ const parts = relPath.split(import_path19.default.sep);
45595
46506
  const worktreeIdx = parts.indexOf(".worktrees");
45596
46507
  const goalId = worktreeIdx >= 0 && parts.length > worktreeIdx + 1 ? parts[worktreeIdx + 1] : "";
45597
46508
  worktrees.push({
@@ -45757,7 +46668,7 @@ worktreeRoutes.get("/goals/:gid/tasks/:tid/worktree/diff", async (c) => {
45757
46668
  });
45758
46669
 
45759
46670
  // src/server/routes/agent.ts
45760
- var import_crypto6 = require("crypto");
46671
+ var import_crypto7 = require("crypto");
45761
46672
  var agentRoutes = new Hono2();
45762
46673
  var runningTasks = /* @__PURE__ */ new Map();
45763
46674
  agentRoutes.post("/goals/:gid/tasks/:tid/run", async (c) => {
@@ -45794,7 +46705,7 @@ agentRoutes.post("/goals/:gid/tasks/:tid/run", async (c) => {
45794
46705
  prompt += `
45795
46706
  \u8BF7\u5F00\u59CB\u6267\u884C\u8FD9\u4E2A\u4EFB\u52A1\u3002\u5B8C\u6210\u540E\u8BF7\u603B\u7ED3\u4F60\u505A\u4E86\u4EC0\u4E48\u3002`;
45796
46707
  updateTask(gid, tid, { status: "in_progress" });
45797
- const requestId = (0, import_crypto6.randomUUID)().slice(0, 8);
46708
+ const requestId = (0, import_crypto7.randomUUID)().slice(0, 8);
45798
46709
  const taskState = { aborted: false, logs: [] };
45799
46710
  runningTasks.set(runKey, taskState);
45800
46711
  const request = {
@@ -45884,7 +46795,7 @@ agentRoutes.post("/goals/:gid/tasks/:tid/chat", async (c) => {
45884
46795
  const prompt = `${context}
45885
46796
  ---
45886
46797
  \u7528\u6237\u6D88\u606F\uFF1A${message}`;
45887
- const requestId = (0, import_crypto6.randomUUID)().slice(0, 8);
46798
+ const requestId = (0, import_crypto7.randomUUID)().slice(0, 8);
45888
46799
  const taskState = { aborted: false, logs: [] };
45889
46800
  runningTasks.set(runKey, taskState);
45890
46801
  const request = {
@@ -45920,9 +46831,9 @@ agentRoutes.get("/goals/:gid/tasks/:tid/logs", async (c) => {
45920
46831
  month: "2-digit",
45921
46832
  day: "2-digit"
45922
46833
  }).replace(/-/g, "");
45923
- let messages = await getMessages(storage, userId, 200, date);
46834
+ let messages = await getMessages(storage, userId, 300, date);
45924
46835
  if (messages.length === 0) {
45925
- messages = await getMessages(storage, userId, 200);
46836
+ messages = await getMessages(storage, userId, 300);
45926
46837
  }
45927
46838
  const runKey = `${gid}:${tid}`;
45928
46839
  const isRunning = runningTasks.has(runKey);
@@ -46125,14 +47036,14 @@ teamRoutes.get("/teams/:name/members/:memberName/context", async (c) => {
46125
47036
  month: "2-digit",
46126
47037
  day: "2-digit"
46127
47038
  }).replace(/-/g, "");
46128
- const msgs = await getMessages(storage, mailBoxId, 200, dateStr);
47039
+ const msgs = await getMessages(storage, mailBoxId, 300, dateStr);
46129
47040
  if (msgs.length > 0) {
46130
47041
  allMessages = msgs;
46131
47042
  break;
46132
47043
  }
46133
47044
  }
46134
47045
  if (allMessages.length === 0) {
46135
- allMessages = await getMessages(storage, mailBoxId, 200);
47046
+ allMessages = await getMessages(storage, mailBoxId, 300);
46136
47047
  }
46137
47048
  agentLogs = allMessages.map((msg, idx) => {
46138
47049
  const blocks = msg.content.map((block) => {
@@ -46174,7 +47085,7 @@ teamRoutes.get("/teams/:name/members/:memberName/context", async (c) => {
46174
47085
  });
46175
47086
 
46176
47087
  // src/server/routes/cron.ts
46177
- var import_crypto7 = require("crypto");
47088
+ var import_crypto8 = require("crypto");
46178
47089
  var cronRoutes = new Hono2();
46179
47090
  cronRoutes.get("/cron/jobs", (c) => {
46180
47091
  try {
@@ -46200,7 +47111,7 @@ cronRoutes.post("/cron/jobs", async (c) => {
46200
47111
  {
46201
47112
  platform: body.delivery.channel,
46202
47113
  userId: body.delivery.to,
46203
- requestId: (0, import_crypto7.randomUUID)().slice(0, 8),
47114
+ requestId: (0, import_crypto8.randomUUID)().slice(0, 8),
46204
47115
  teamAgentId: ""
46205
47116
  }
46206
47117
  );
@@ -46343,7 +47254,7 @@ var systemRoutes = new Hono2();
46343
47254
  var startTime = Date.now();
46344
47255
  systemRoutes.get("/system/info", (c) => {
46345
47256
  return c.json({
46346
- version: true ? "1.7.3" : "unknown",
47257
+ version: true ? "1.7.4" : "unknown",
46347
47258
  uptime: Math.floor((Date.now() - startTime) / 1e3),
46348
47259
  env: process.env.NODE_ENV || "development",
46349
47260
  nodeVersion: process.version
@@ -46353,6 +47264,7 @@ systemRoutes.get("/system/info", (c) => {
46353
47264
  // src/server/index.ts
46354
47265
  function createServer() {
46355
47266
  const app = new Hono2();
47267
+ const webDistRoot = resolveWebDistRoot();
46356
47268
  app.use("/api/*", cors());
46357
47269
  app.route("/api", goalRoutes);
46358
47270
  app.route("/api", taskRoutes);
@@ -46363,8 +47275,8 @@ function createServer() {
46363
47275
  app.route("/api", mailboxRoutes);
46364
47276
  app.route("/api", toolRoutes);
46365
47277
  app.route("/api", systemRoutes);
46366
- app.use("/*", serveStatic({ root: "./web/dist" }));
46367
- app.get("/*", serveStatic({ path: "./web/dist/index.html" }));
47278
+ app.use("/*", serveStatic({ root: webDistRoot }));
47279
+ app.get("/*", serveStatic({ path: `${webDistRoot}/index.html` }));
46368
47280
  return app;
46369
47281
  }
46370
47282
  function startServer(port = 3e3) {