@fangyb/ahchat-bridge 0.1.19 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/cli.cjs +441 -179
  2. package/dist/index.js +386 -145
  3. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -3680,7 +3680,8 @@ var require_websocket_server = __commonJS({
3680
3680
  // src/cli.ts
3681
3681
  init_cjs_shims();
3682
3682
  var import_node_os13 = __toESM(require("os"), 1);
3683
- var import_node_path21 = __toESM(require("path"), 1);
3683
+ var import_node_path22 = __toESM(require("path"), 1);
3684
+ var import_node_fs10 = __toESM(require("fs"), 1);
3684
3685
 
3685
3686
  // ../../node_modules/.pnpm/cac@6.7.14/node_modules/cac/dist/index.mjs
3686
3687
  init_cjs_shims();
@@ -5096,11 +5097,11 @@ var RotatingFileStream = class extends import_stream.Writable {
5096
5097
  timeout;
5097
5098
  timeoutPromise;
5098
5099
  constructor(generator, options) {
5099
- const { encoding, history, maxFiles, maxSize, path: path22 } = options;
5100
+ const { encoding, history, maxFiles, maxSize, path: path23 } = options;
5100
5101
  super({ decodeStrings: true, defaultEncoding: encoding });
5101
5102
  this.createGzip = import_zlib.createGzip;
5102
5103
  this.exec = import_child_process.exec;
5103
- this.filename = path22 + generator(null);
5104
+ this.filename = path23 + generator(null);
5104
5105
  this.fsCreateReadStream = import_fs.createReadStream;
5105
5106
  this.fsCreateWriteStream = import_fs.createWriteStream;
5106
5107
  this.fsOpen = import_promises.open;
@@ -5112,7 +5113,7 @@ var RotatingFileStream = class extends import_stream.Writable {
5112
5113
  this.options = options;
5113
5114
  this.stdout = process.stdout;
5114
5115
  if (maxFiles || maxSize)
5115
- options.history = path22 + (history ? history : this.generator(null) + ".txt");
5116
+ options.history = path23 + (history ? history : this.generator(null) + ".txt");
5116
5117
  this.on("close", () => this.finished ? null : this.emit("finish"));
5117
5118
  this.on("finish", () => this.finished = this.clear());
5118
5119
  (async () => {
@@ -5240,9 +5241,9 @@ var RotatingFileStream = class extends import_stream.Writable {
5240
5241
  return this.move();
5241
5242
  }
5242
5243
  async findName() {
5243
- const { interval, path: path22, intervalBoundary } = this.options;
5244
+ const { interval, path: path23, intervalBoundary } = this.options;
5244
5245
  for (let index = 1; index < 1e3; ++index) {
5245
- const filename = path22 + this.generator(interval && intervalBoundary ? new Date(this.prev) : this.rotation, index);
5246
+ const filename = path23 + this.generator(interval && intervalBoundary ? new Date(this.prev) : this.rotation, index);
5246
5247
  if (!await exists(filename))
5247
5248
  return filename;
5248
5249
  }
@@ -5272,11 +5273,11 @@ var RotatingFileStream = class extends import_stream.Writable {
5272
5273
  return this.unlink(filename);
5273
5274
  }
5274
5275
  async classical() {
5275
- const { compress, path: path22, rotate } = this.options;
5276
+ const { compress, path: path23, rotate } = this.options;
5276
5277
  let rotatedName = "";
5277
5278
  for (let count = rotate; count > 0; --count) {
5278
- const currName = path22 + this.generator(count);
5279
- const prevName = count === 1 ? this.filename : path22 + this.generator(count - 1);
5279
+ const currName = path23 + this.generator(count);
5280
+ const prevName = count === 1 ? this.filename : path23 + this.generator(count - 1);
5280
5281
  if (!await exists(prevName))
5281
5282
  continue;
5282
5283
  if (!rotatedName)
@@ -5714,7 +5715,7 @@ function createModuleLogger(module2) {
5714
5715
 
5715
5716
  // src/start.ts
5716
5717
  init_cjs_shims();
5717
- var import_node_path19 = __toESM(require("path"), 1);
5718
+ var import_node_path20 = __toESM(require("path"), 1);
5718
5719
 
5719
5720
  // ../shared/src/index.ts
5720
5721
  init_cjs_shims();
@@ -5763,15 +5764,15 @@ var SMITH_SYSTEM_PROMPT = `\u4F60\u662F\u7279\u5DE5\u53F2\u5BC6\u65AF\uFF08Agent
5763
5764
  - **\u4E3A\u6BCF\u4E2A Agent \u9009\u62E9\u5408\u9002\u7684\u80FD\u529B\u6863\u4F4D\uFF08tier \u53C2\u6570\uFF09**
5764
5765
  - **\u4E00\u6B21\u6027**\u8C03 create_group\uFF0C\u53C2\u6570\uFF1A
5765
5766
  - name: \u7FA4\u540D
5766
- - member_ids: [agt_usr_self, <Leader>, <\u5176\u4ED6\u6210\u5458>, ...] // **\u4E0D\u5305\u542B\u4F60\u81EA\u5DF1**
5767
+ - member_ids: [<\u8BF7\u6C42\u8005\u7684\u4EBA\u7C7B id>, <Leader>, <\u5176\u4ED6\u6210\u5458>, ...] // **\u4E0D\u5305\u542B\u4F60\u81EA\u5DF1**\uFF1B\u8BF7\u6C42\u8005\u7684\u4EBA\u7C7B id \u5FC5\u987B\u6765\u81EA list_contacts() \u91CC\u5E26\u300C(\u4EBA\u7C7B)\u300D\u6807\u8BB0\u7684\u90A3\u4E00\u6761\uFF0C\u591A\u7528\u6237\u73AF\u5883\u4E0D\u662F agt_usr_self
5767
5768
  - join_as_creator: false
5768
5769
  - initial_message: \u4EA4\u73ED\u8BED\uFF08\u52A1\u5FC5\u5199\u6E05\u695A\u300C\u5728\u7FA4\u91CC\u300D\u300C\u4E0D\u8981\u79C1\u804A\u300D\uFF09\u3002\u6709 Leader \u65F6\u793A\u4F8B\uFF1A
5769
- \u300C\u7FA4\u5DF2\u6210\u7ACB\u3002\u7FA4\u4E3B\u662F\u7528\u6237\uFF08@agt_usr_self\uFF09\uFF0C@<Leader \u540D> \u662F\u56E2\u961F\u8D1F\u8D23\u4EBA\u3002
5770
+ \u300C\u7FA4\u5DF2\u6210\u7ACB\u3002\u7FA4\u4E3B\u662F\u7528\u6237\uFF08@<\u8BF7\u6C42\u8005\u7684\u4EBA\u7C7B id>\uFF09\uFF0C@<Leader \u540D> \u662F\u56E2\u961F\u8D1F\u8D23\u4EBA\u3002
5770
5771
 
5771
5772
  @<Leader \u540D>\uFF1A\u8BF7\u4F60**\u76F4\u63A5\u5728\u672C\u7FA4\u56DE\u590D**\uFF0C\u5411\u7528\u6237\u505A\u56E2\u961F\u4ECB\u7ECD\u2014\u2014\u56E2\u961F\u603B\u4EBA\u6570\u3001\u5404\u6210\u5458\u804C\u80FD\u5206\u5DE5\uFF0C\u5E76\u8BE2\u95EE\u60F3\u4ECE\u54EA\u91CC\u5F00\u59CB\u3002**\u4E0D\u8981 neural_send \u53BB\u79C1\u804A\u7528\u6237**\uFF0C\u8FD9\u662F\u516C\u5F00\u7684\u7FA4\u4ECB\u7ECD\uFF0C\u6240\u6709\u4EBA\u90FD\u770B\u7740\u3002
5772
5773
 
5773
5774
  \u5176\u4ED6\u6210\u5458\uFF1A\u4FDD\u6301\u5B89\u9759\u89C2\u671B\uFF0C\u7B49 Leader \u5206\u6D3E\u4EFB\u52A1\u518D\u53D1\u8A00\u3002**\u4E0D\u8981\u67E5\u804A\u5929\u8BB0\u5F55\u3001\u4E0D\u8981\u8FFD\u95EE"\u6D88\u606F\u9001\u5230\u6CA1"\u4E4B\u7C7B\u7684\u5143\u8BDD\u9898**\u2014\u2014\u4FDD\u6301\u514B\u5236\u3002\u300D
5774
- \u5E73\u7EA7\u7FA4\uFF08\u65E0 Leader\uFF09\u793A\u4F8B\uFF1A\u300C\u7FA4\u5DF2\u6210\u7ACB\u3002\u7FA4\u4E3B\u662F\u7528\u6237\uFF08@agt_usr_self\uFF09\u3002\u8BF7\u5927\u5BB6\u5728\u672C\u7FA4\u91CC\u5404\u81EA\u7528\u4E00\u53E5\u8BDD\u505A\u81EA\u6211\u4ECB\u7ECD\uFF08**\u4E0D\u8981\u79C1\u804A\u7528\u6237**\uFF09\u3002\u4ECB\u7ECD\u5B8C\u4FDD\u6301\u5B89\u9759\uFF0C\u7B49\u7528\u6237\u5F00\u53E3\u8BF4\u60F3\u505A\u4EC0\u4E48\u518D\u5206\u5DE5\u3002\u300D
5775
+ \u5E73\u7EA7\u7FA4\uFF08\u65E0 Leader\uFF09\u793A\u4F8B\uFF1A\u300C\u7FA4\u5DF2\u6210\u7ACB\u3002\u7FA4\u4E3B\u662F\u7528\u6237\uFF08@<\u8BF7\u6C42\u8005\u7684\u4EBA\u7C7B id>\uFF09\u3002\u8BF7\u5927\u5BB6\u5728\u672C\u7FA4\u91CC\u5404\u81EA\u7528\u4E00\u53E5\u8BDD\u505A\u81EA\u6211\u4ECB\u7ECD\uFF08**\u4E0D\u8981\u79C1\u804A\u7528\u6237**\uFF09\u3002\u4ECB\u7ECD\u5B8C\u4FDD\u6301\u5B89\u9759\uFF0C\u7B49\u7528\u6237\u5F00\u53E3\u8BF4\u60F3\u505A\u4EC0\u4E48\u518D\u5206\u5DE5\u3002\u300D
5775
5776
  - \u5B8C\u6210\u3002**\u4E0D\u8981**\u518D\u8C03 transfer_group_owner / neural_send / leave_group\u3002\u4F60\u4E0D\u5728\u7FA4\u91CC\u3001\u7FA4\u4E3B\u5DF2\u662F\u7528\u6237\u3001Leader \u5DF2\u88AB @\u3001\u9996\u53E5\u5DF2\u5C31\u4F4D\u3002
5776
5777
  - \u56DE\u590D\u8BF7\u6C42\u8005\u786E\u8BA4\u7ED3\u679C
5777
5778
 
@@ -5809,7 +5810,7 @@ create_agent \u5DE5\u5177\u652F\u6301\u53EF\u9009\u53C2\u6570 initial_instructio
5809
5810
 
5810
5811
  4. \u5982\u679C\u8BF7\u6C42\u8005\u8BF4"\u62DB\u8058/\u62DB\u52DF N \u4E2A Agent/\u5458\u5DE5/\u89D2\u8272"\u4E14 N >= 2\uFF0C\u6216\u8BED\u4E49\u4E0A\u662F\u4E3A\u67D0\u4E2A\u9879\u76EE\u8865\u5145\u4E00\u7EC4\u4EBA\uFF1A
5811
5812
  - \u9ED8\u8BA4\u6309"\u7EC4\u5EFA\u56E2\u961F"\u5904\u7406\uFF0C\u4E0D\u8981\u53EA\u521B\u5EFA Agent \u540E\u505C\u4F4F\u95EE"\u8981\u4E0D\u8981\u62C9\u7FA4"
5812
- - create_agent \u5B8C\u6210\u540E\u7ACB\u523B create_group\uFF0C\u628A\u65B0\u5EFA Agent + \u8BF7\u6C42\u8005\uFF08agt_usr_self\uFF09\u62C9\u8FDB\u7FA4
5813
+ - create_agent \u5B8C\u6210\u540E\u7ACB\u523B create_group\uFF0C\u628A\u65B0\u5EFA Agent + \u8BF7\u6C42\u8005\u7684\u4EBA\u7C7B id\uFF08\u4ECE list_contacts() \u83B7\u53D6\uFF0C\u5E26\u300C(\u4EBA\u7C7B)\u300D\u6807\u8BB0\uFF09\u62C9\u8FDB\u7FA4
5813
5814
  - \u7FA4\u540D\u4ECE\u4EFB\u52A1/\u9879\u76EE\u91CC\u63D0\u53D6\uFF1B\u6CA1\u6709\u660E\u786E\u9879\u76EE\u540D\u65F6\u7528\u300C<\u804C\u80FD>\u534F\u4F5C\u7EC4\u300D\u6216\u300C<\u9879\u76EE>\u652F\u63F4\u7EC4\u300D
5814
5815
  - \u5982\u679C\u7528\u6237\u660E\u786E\u8BF4"\u53EA\u5148\u5EFA\u4EBA/\u53EA\u53D1\u62DB\u8058\u5E16/\u5148\u4E0D\u8981\u62C9\u7FA4"\uFF0C\u624D\u505C\u6B62\u5728\u521B\u5EFA Agent \u6216\u53D1\u5E16\u9636\u6BB5
5815
5816
  - \u5EFA\u7FA4\u540E\u53D1\u4E00\u6761\u5F00\u573A\u767D\uFF0C\u8BF4\u660E\u56E2\u961F\u76EE\u6807\u3001\u6210\u5458\u89D2\u8272\u548C\u4E0B\u4E00\u6B65\u5206\u5DE5
@@ -6193,15 +6194,21 @@ EXCEPTION \u2014 inner-voice envelope overrides no-reply:
6193
6194
  - In 1:1 chat with the human, you may write longer answers when warranted.
6194
6195
 
6195
6196
  # Group chat \u2014 shared task board
6196
- AHChat group conversations have a shared kanban board that is fed by your TodoWrite
6197
- state. Treat it as the group's operational source of truth.
6197
+ AHChat group conversations have a shared kanban board that is fed by structured
6198
+ task tools (TodoWrite when available; otherwise TaskCreate / TaskUpdate). Treat
6199
+ it as the group's operational source of truth.
6198
6200
 
6199
6201
  When a group-chat message involves actionable work, planning, implementation,
6200
6202
  handoff, review, follow-up, blockers, or progress:
6201
- - You MUST maintain TodoWrite for your own relevant work instead of only talking
6202
- about tasks in prose.
6203
- - Create one TodoWrite item per concrete subtask or deliverable.
6204
- - Update existing TodoWrite items when status changes; do not create duplicates
6203
+ - If you are assigning work, splitting work, declaring a phase, asking another
6204
+ member to implement/review/fix/deliver something, or saying work will start,
6205
+ call the available structured task tool before sending the group message.
6206
+ Plain prose such as "@Zoe start working" is not enough; without structured
6207
+ task state the project board stays empty.
6208
+ - You MUST maintain structured task state for your own relevant work instead of
6209
+ only talking about tasks in prose.
6210
+ - Create one task item per concrete subtask or deliverable.
6211
+ - Update existing task items when status changes; do not create duplicates
6205
6212
  just to restate the same task.
6206
6213
  - If a P0/P1/P2/etc. task already exists on the board, update that task instead
6207
6214
  of creating another similar task under yourself or another Agent.
@@ -6210,12 +6217,12 @@ handoff, review, follow-up, blockers, or progress:
6210
6217
  - If a task belongs to another group member, include \`@memberName\` only as
6211
6218
  assignment metadata so the board can route it. Keep the task description clean
6212
6219
  and do not rely on the @mention as part of the visible title.
6213
- - All TodoWrite content shown on the board must be in Chinese.
6220
+ - All task content shown on the board must be in Chinese.
6214
6221
 
6215
- Do NOT use TodoWrite for pure small talk, one-off factual answers, or messages
6222
+ Do NOT use task tools for pure small talk, one-off factual answers, or messages
6216
6223
  where you intentionally stay silent with \`<no-reply/>\`.
6217
6224
 
6218
- \u7FA4\u91CC\u7684 TodoWrite \u652F\u6301\u4E24\u79CD\u7279\u6B8A\u524D\u7F00\uFF0C\u4F1A\u88AB\u81EA\u52A8\u63D0\u53D6\u5230\u5BF9\u5E94\u7CFB\u7EDF\uFF1A
6225
+ \u7FA4\u91CC\u7684\u4EFB\u52A1\u5DE5\u5177\u652F\u6301\u4E24\u79CD\u7279\u6B8A\u524D\u7F00\uFF0C\u4F1A\u88AB\u81EA\u52A8\u63D0\u53D6\u5230\u5BF9\u5E94\u7CFB\u7EDF\uFF1A
6219
6226
  - \`[\u95EE\u9898:\u7C7B\u578B]\`\uFF1Abug / \u8E29\u5751 / \u5F85\u8BA8\u8BBA\u3002\u4F8B\uFF1A"[\u95EE\u9898:\u8E29\u5751] SQLite ALTER TABLE \u4E0D\u652F\u6301 DROP COLUMN"\u3002
6220
6227
  - \`[\u7ECF\u9A8C:\u7C7B\u578B]\`\uFF1A\u8E29\u5751 / \u89E3\u51B3\u65B9\u6848 / \u6700\u4F73\u5B9E\u8DF5 / \u5FC3\u5F97 / \u5F85\u8BA8\u8BBA\u3002\u5B8C\u6210\u4EFB\u52A1\u540E\u503C\u5F97\u6C89\u6DC0\u7684\u5185\u5BB9\u7528\u6B64\u524D\u7F00\u3002
6221
6228
  - \`post_to_forum\` \u5DE5\u5177\u53EF\u76F4\u63A5\u53D1\u5E16\u5230\u667A\u56CA\u5E7F\u573A\uFF0C\u9047\u5230\u8BBA\u575B/\u5E7F\u573A\u8BF7\u6C42\u65F6\u76F4\u63A5\u8C03\u7528\uFF0C\u4E0D\u8981\u56DE\u7B54"\u6CA1\u6709\u53D1\u5E03\u529F\u80FD"\u3002
@@ -6243,7 +6250,7 @@ where you intentionally stay silent with \`<no-reply/>\`.
6243
6250
  |---|---|---|
6244
6251
  | **\u7ED3\u8BBA** | \u5BF9\u4E00\u4E2A\u5177\u4F53\u95EE\u9898\u7684\u6700\u7EC8\u5224\u65AD\uFF0C\u53EF\u88AB\u672A\u6765\u5F15\u7528\u800C\u4E0D\u91CD\u65B0\u8BBA\u8BC1 | self_note append \`[\u7ED3\u8BBA\xB7\u573A\u666F\xB7\u65E5\u671F]\` |
6245
6252
  | **\u5171\u8BC6** | \u591A\u65B9\u660E\u786E\u4E00\u81F4\u7684\u7EA6\u5B9A\uFF0C\u672A\u6765\u4F60\u505A\u51B3\u7B56\u4E0D\u80FD\u8FDD\u80CC\u5B83 | self_note append \`[\u5171\u8BC6\xB7\u573A\u666F\xB7\u65E5\u671F]\` |
6246
- | **\u4EFB\u52A1** | deliverable + \u8D23\u4EFB\u4EBA + \u65F6\u95F4\u7A97 / \u89E6\u53D1\u6761\u4EF6 | TodoWrite\uFF08\u7FA4 board\uFF09 |
6253
+ | **\u4EFB\u52A1** | deliverable + \u8D23\u4EFB\u4EBA + \u65F6\u95F4\u7A97 / \u89E6\u53D1\u6761\u4EF6 | \u7ED3\u6784\u5316\u4EFB\u52A1\u5DE5\u5177\uFF08\u7FA4 board\uFF09 |
6247
6254
 
6248
6255
  **\u7ED3\u8BBA vs \u5171\u8BC6**\uFF1A\u7ED3\u8BBA\u662F**\u5BF9\u4E8B\u5B9E/\u65B9\u6848\u7684\u5224\u65AD**\uFF08"\u7528 X \u4E0D\u7528 Y"\uFF09\uFF0C\u53EF\u80FD\u662F\u5355\u65B9\u62CD\u677F\uFF1B
6249
6256
  \u5171\u8BC6\u662F**\u591A\u65B9\u5BF9\u672A\u6765\u884C\u4E3A\u7684\u7EA6\u5B9A**\uFF08"\u6211\u4EEC\u90FD\u4E0D\u5728\u5468\u672B\u53D1\u7248"\uFF09\uFF0C\u8FDD\u80CC\u5B83\u8981\u5148\u7FFB\u6848\u3002\u5171\u8BC6\u66F4
@@ -6262,13 +6269,13 @@ where you intentionally stay silent with \`<no-reply/>\`.
6262
6269
 
6263
6270
  ### \u7ACB\u523B\u5199\uFF0C\u4E0D\u8981\u62D6
6264
6271
  \u7FA4\u8BA8\u8BBA\u521A\u6536\u5C3E\u7684\u77AC\u95F4\u662F\u6355\u83B7\u6700\u4F73\u65F6\u673A\uFF1B\u8FC7\u51E0\u6761\u6D88\u606F\u4F60\u5C31\u5FD8\u4E86\u7EC6\u8282\u3002\u5F53 turn \u76F4\u63A5
6265
- self_note / TodoWrite\u2014\u2014**\u6C89\u6DC0\u662F\u9ED8\u5199\u52A8\u4F5C\uFF0C\u4E0D\u8981\u5728\u7FA4\u91CC announce \u4F60\u521A\u5199\u4E86\u4EC0\u4E48**
6272
+ self_note / \u4EFB\u52A1\u5DE5\u5177\u2014\u2014**\u6C89\u6DC0\u662F\u9ED8\u5199\u52A8\u4F5C\uFF0C\u4E0D\u8981\u5728\u7FA4\u91CC announce \u4F60\u521A\u5199\u4E86\u4EC0\u4E48**
6266
6273
  \uFF08\u90A3\u662F\u81EA\u8A00\u81EA\u8BED\uFF0C\u8FDD\u53CD\u516C\u7406\u4E09\uFF09\u3002
6267
6274
 
6268
6275
  ### \u5199\u4E4B\u524D\u5148\u67E5\u91CD
6269
6276
  \u7FA4\u662F fan-out \u7684\u2014\u20145 \u4E2A agent \u540C\u65F6\u5199\u4E00\u4EFD\u5C31\u662F 5 \u500D\u566A\u97F3\uFF08\u5728\u4F60\u81EA\u5DF1\u7B14\u8BB0\u672C\u91CC\u4E5F\u662F\uFF09\u3002
6270
6277
  - self_note \u5199\u524D**\u89C6\u89C9\u626B\u4E00\u773C\u7B14\u8BB0\u672C\u5F00\u5934**\uFF08\u5DF2\u5728 systemPrompt \u9876\u90E8\uFF0C**\u4E0D\u9700\u8981\u8C03 read**\uFF09\u3002
6271
- - TodoWrite \u5199\u524D\u626B\u5F53\u524D board\u3002
6278
+ - \u5199\u4EFB\u52A1\u5DE5\u5177\u524D\u626B\u5F53\u524D board\u3002
6272
6279
  - \u5DF2\u6709\u5C31 update / \u52A0\u4E00\u884C\u8865\u5145\uFF08"+ 2026-05-28 \u590D\u8BAE\u4ECD\u7EF4\u6301"\uFF09\uFF0C\u4E0D\u65B0\u589E\u91CD\u590D\u6761\u76EE\u3002
6273
6280
 
6274
6281
  ### \u5FC5\u987B\u5E26\u573A\u666F
@@ -6284,18 +6291,18 @@ self_note / TodoWrite\u2014\u2014**\u6C89\u6DC0\u662F\u9ED8\u5199\u52A8\u4F5C\uF
6284
6291
  - \u4E2D\u95F4\u601D\u8DEF\u3001\u72B9\u8C6B\u3001\u81EA\u6211\u4FEE\u6B63 \u2192 \u7559\u7ED9 SDK Session \u5DE5\u4F5C\u8BB0\u5FC6\uFF0C\u522B\u6C61\u67D3\u957F\u671F\u7B14\u8BB0
6285
6292
  - \u5355\u65B9\u9762\u731C\u6D4B\u3001\u8FD8\u6CA1\u4EBA\u786E\u8BA4\u7684\u5224\u65AD \u2192 \u4E0D\u8FDB\u7B14\u8BB0
6286
6293
  - \u5BA2\u5957\u3001\u8C03\u4F83\u3001\u5173\u5FC3 \u2192 \u4E0D\u8FDB\u7B14\u8BB0
6287
- - TodoWrite \u5DF2\u7ECF\u80FD\u88C5\u4E0B\u7684 task \u2192 \u522B\u518D self_note \u91CD\u590D\u4E00\u4EFD
6294
+ - \u4EFB\u52A1\u5DE5\u5177\u5DF2\u7ECF\u80FD\u88C5\u4E0B\u7684 task \u2192 \u522B\u518D self_note \u91CD\u590D\u4E00\u4EFD
6288
6295
  - \u4F60\u8FD9\u4E00\u8F6E \`<no-reply/>\` \u65F6\u542C\u5230\u7684\u522B\u4EBA\u8FBE\u6210\u7684\u5171\u8BC6 \u2192 **\u522B\u5199**\u3002\u4F60\u6CA1\u53C2\u4E0E\u5C31\u4E0D\u662F"\u4F60\u7684"
6289
6296
  \u5171\u8BC6\uFF1B\u4EE5\u540E\u771F\u9700\u8981\u65F6\u518D read_chat_history \u7FFB
6290
6297
 
6291
6298
  ## \u4E0E \`[\u7ECF\u9A8C:\u7C7B\u578B]\` \u524D\u7F00\u7684\u8FB9\u754C\uFF08\u91CD\u8981\uFF09
6292
6299
 
6293
- \`[\u7ECF\u9A8C:\u7C7B\u578B]\` \u8D70\u7684\u662F\u53E6\u4E00\u6761\u8DEF\uFF1A\u7FA4 TodoWrite \u52A0\u8FD9\u4E2A\u524D\u7F00\uFF0Cserver \u4F1A**\u81EA\u52A8**\u628A\u5185\u5BB9
6300
+ \`[\u7ECF\u9A8C:\u7C7B\u578B]\` \u8D70\u7684\u662F\u53E6\u4E00\u6761\u8DEF\uFF1A\u7FA4\u4EFB\u52A1\u5DE5\u5177\u52A0\u8FD9\u4E2A\u524D\u7F00\uFF0Cserver \u4F1A**\u81EA\u52A8**\u628A\u5185\u5BB9
6294
6301
  \u5165\u300C\u667A\u56CA\u5E7F\u573A\u300D\uFF08feed_posts \u8868\uFF0C**\u5168\u5E73\u53F0\u516C\u5F00\u53EF\u89C1**\uFF0C\u6240\u6709 Agent \u548C\u7528\u6237\u90FD\u770B\u5F97\u5230\uFF09\u3002
6295
6302
  \u6240\u4EE5\uFF1A
6296
6303
 
6297
6304
  - **\u7ECF\u9A8C / \u6559\u8BAD / \u6700\u4F73\u5B9E\u8DF5 / \u89E3\u51B3\u65B9\u6848**\uFF08\u4F60\u613F\u610F\u516C\u5F00\u5206\u4EAB\u7ED9\u6240\u6709 Agent / \u7528\u6237\u7684\uFF09 \u2192
6298
- TodoWrite \`[\u7ECF\u9A8C:\u7C7B\u578B]\`
6305
+ \u4EFB\u52A1\u5DE5\u5177 \`[\u7ECF\u9A8C:\u7C7B\u578B]\`
6299
6306
  - **\u7ED3\u8BBA / \u5171\u8BC6**\uFF08\u4F60\u8FD9\u4E2A Agent \u81EA\u5DF1\u7684\u79C1\u4EBA\u8BB0\u5FC6\uFF09 \u2192
6300
6307
  self_note \`[\u7ED3\u8BBA\xB7\u2026]\` / \`[\u5171\u8BC6\xB7\u2026]\`
6301
6308
 
@@ -6365,7 +6372,7 @@ remove_from_group / transfer_group_owner / post_to_forum\u3002\u53C2\u6570\u8BE6
6365
6372
  \u884C\u4E3A\u51C6\u5219\uFF1A
6366
6373
  - create_group \u9ED8\u8BA4\u4F60\u81EA\u52A8\u5165\u7FA4\u6210\u4E3A\u7FA4\u4E3B\uFF1B\u82E5\u4F60\u53EA\u662F\u5E2E\u522B\u4EBA\u642D\u7FA4\u3001\u4E0D\u6253\u7B97\u957F\u671F\u5728\u7FA4\u91CC\uFF0C\u4F20 join_as_creator: false + initial_message="..."\uFF0C\u53EF\u4E00\u6B21\u6027\u5B8C\u6210\u5EFA\u7FA4 + \u5F00\u573A\u767D + \u6D3E\u53D1\uFF0C\u7FA4\u4E3B\u81EA\u52A8\u5F52\u7528\u6237\u3002
6367
6374
  - \u4F60\u5165\u7FA4\uFF08join_as_creator \u9ED8\u8BA4 true\uFF09\u7684\u8BDD\uFF0C\u5EFA\u7FA4\u540E\u7528 neural_send \u53D1\u5F00\u573A\u767D\uFF0C\u5426\u5219\u7FA4\u4F1A\u9759\u9ED8\u3002
6368
- - \u9ED8\u8BA4 member_ids \u4E0D\u62C9\u7528\u6237\uFF08agent-only \u534F\u4F5C\u5E38\u89C1\uFF09\uFF1B\u62C9\u7528\u6237\u7528 'agt_usr_self'\u3002
6375
+ - \u9ED8\u8BA4 member_ids \u4E0D\u62C9\u7528\u6237\uFF08agent-only \u534F\u4F5C\u5E38\u89C1\uFF09\uFF1B\u62C9\u7528\u6237\u5148\u7528 list_contacts() \u627E\u5E26\u300C(\u4EBA\u7C7B)\u300D\u6807\u8BB0\u7684\u8BF7\u6C42\u8005 id\u3002\u65E7\u5355\u7528\u6237\u73AF\u5883\u624D\u53EF\u80FD\u662F 'agt_usr_self'\u3002
6369
6376
  - \u4F18\u5148 add_to_group \u5230\u73B0\u6709\u7FA4\uFF0C\u4E0D\u8981\u4E3A\u6BCF\u4E2A\u95EE\u9898\u65B0\u5EFA\u7FA4\u3002
6370
6377
  - \u5EFA\u7FA4\u524D\u5148 neural_list_scopes \u786E\u8BA4\u6CA1\u6709\u91CD\u590D\u7FA4\u3002
6371
6378
  - remove_from_group \u4EC5\u7FA4\u4E3B\u53EF\u7528\uFF1Bleave_group \u4E0D\u8981\u56E0\u4E00\u65F6\u51B2\u7A81\u4F7F\u7528\u2014\u2014\u5C24\u5176\u5EFA\u56E2\u961F\u540E\u4E0D\u8981 leave_group\uFF0C\u5E94\u76F4\u63A5\u7528 create_group(join_as_creator: false) \u4E00\u6B65\u5230\u4F4D\u3002
@@ -6921,7 +6928,7 @@ var import_node_crypto3 = require("crypto");
6921
6928
  var import_node_fs3 = __toESM(require("fs"), 1);
6922
6929
  var import_promises8 = __toESM(require("fs/promises"), 1);
6923
6930
  var import_node_os5 = __toESM(require("os"), 1);
6924
- var import_node_path8 = __toESM(require("path"), 1);
6931
+ var import_node_path9 = __toESM(require("path"), 1);
6925
6932
 
6926
6933
  // ../../node_modules/.pnpm/@anthropic-ai+claude-agent-sdk@0.2.141_zod@4.4.3/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
6927
6934
  init_cjs_shims();
@@ -29746,10 +29753,10 @@ function mergeDefs(...defs) {
29746
29753
  function cloneDef(schema) {
29747
29754
  return mergeDefs(schema._zod.def);
29748
29755
  }
29749
- function getElementAtPath(obj, path22) {
29750
- if (!path22)
29756
+ function getElementAtPath(obj, path23) {
29757
+ if (!path23)
29751
29758
  return obj;
29752
- return path22.reduce((acc, key) => acc?.[key], obj);
29759
+ return path23.reduce((acc, key) => acc?.[key], obj);
29753
29760
  }
29754
29761
  function promiseAllObject(promisesObj) {
29755
29762
  const keys = Object.keys(promisesObj);
@@ -30158,11 +30165,11 @@ function explicitlyAborted(x2, startIndex = 0) {
30158
30165
  }
30159
30166
  return false;
30160
30167
  }
30161
- function prefixIssues(path22, issues) {
30168
+ function prefixIssues(path23, issues) {
30162
30169
  return issues.map((iss) => {
30163
30170
  var _a3;
30164
30171
  (_a3 = iss).path ?? (_a3.path = []);
30165
- iss.path.unshift(path22);
30172
+ iss.path.unshift(path23);
30166
30173
  return iss;
30167
30174
  });
30168
30175
  }
@@ -30309,16 +30316,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
30309
30316
  }
30310
30317
  function formatError(error51, mapper = (issue2) => issue2.message) {
30311
30318
  const fieldErrors = { _errors: [] };
30312
- const processError = (error52, path22 = []) => {
30319
+ const processError = (error52, path23 = []) => {
30313
30320
  for (const issue2 of error52.issues) {
30314
30321
  if (issue2.code === "invalid_union" && issue2.errors.length) {
30315
- issue2.errors.map((issues) => processError({ issues }, [...path22, ...issue2.path]));
30322
+ issue2.errors.map((issues) => processError({ issues }, [...path23, ...issue2.path]));
30316
30323
  } else if (issue2.code === "invalid_key") {
30317
- processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
30324
+ processError({ issues: issue2.issues }, [...path23, ...issue2.path]);
30318
30325
  } else if (issue2.code === "invalid_element") {
30319
- processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
30326
+ processError({ issues: issue2.issues }, [...path23, ...issue2.path]);
30320
30327
  } else {
30321
- const fullpath = [...path22, ...issue2.path];
30328
+ const fullpath = [...path23, ...issue2.path];
30322
30329
  if (fullpath.length === 0) {
30323
30330
  fieldErrors._errors.push(mapper(issue2));
30324
30331
  } else {
@@ -30345,17 +30352,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
30345
30352
  }
30346
30353
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
30347
30354
  const result = { errors: [] };
30348
- const processError = (error52, path22 = []) => {
30355
+ const processError = (error52, path23 = []) => {
30349
30356
  var _a3, _b2;
30350
30357
  for (const issue2 of error52.issues) {
30351
30358
  if (issue2.code === "invalid_union" && issue2.errors.length) {
30352
- issue2.errors.map((issues) => processError({ issues }, [...path22, ...issue2.path]));
30359
+ issue2.errors.map((issues) => processError({ issues }, [...path23, ...issue2.path]));
30353
30360
  } else if (issue2.code === "invalid_key") {
30354
- processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
30361
+ processError({ issues: issue2.issues }, [...path23, ...issue2.path]);
30355
30362
  } else if (issue2.code === "invalid_element") {
30356
- processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
30363
+ processError({ issues: issue2.issues }, [...path23, ...issue2.path]);
30357
30364
  } else {
30358
- const fullpath = [...path22, ...issue2.path];
30365
+ const fullpath = [...path23, ...issue2.path];
30359
30366
  if (fullpath.length === 0) {
30360
30367
  result.errors.push(mapper(issue2));
30361
30368
  continue;
@@ -30387,8 +30394,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
30387
30394
  }
30388
30395
  function toDotPath(_path) {
30389
30396
  const segs = [];
30390
- const path22 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
30391
- for (const seg of path22) {
30397
+ const path23 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
30398
+ for (const seg of path23) {
30392
30399
  if (typeof seg === "number")
30393
30400
  segs.push(`[${seg}]`);
30394
30401
  else if (typeof seg === "symbol")
@@ -43161,13 +43168,13 @@ function resolveRef(ref, ctx) {
43161
43168
  if (!ref.startsWith("#")) {
43162
43169
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
43163
43170
  }
43164
- const path22 = ref.slice(1).split("/").filter(Boolean);
43165
- if (path22.length === 0) {
43171
+ const path23 = ref.slice(1).split("/").filter(Boolean);
43172
+ if (path23.length === 0) {
43166
43173
  return ctx.rootSchema;
43167
43174
  }
43168
43175
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
43169
- if (path22[0] === defsKey) {
43170
- const key = path22[1];
43176
+ if (path23[0] === defsKey) {
43177
+ const key = path23[1];
43171
43178
  if (!key || !ctx.defs[key]) {
43172
43179
  throw new Error(`Reference not found: ${ref}`);
43173
43180
  }
@@ -43603,6 +43610,18 @@ function resolveMyHuman(registry2, agentId) {
43603
43610
  }
43604
43611
  return USR_SELF_ID;
43605
43612
  }
43613
+ function resolveLegacyHumanId(registry2, agentId, id) {
43614
+ const trimmed = id.trim();
43615
+ if (trimmed === USR_SELF_ID) return resolveMyHuman(registry2, agentId);
43616
+ return trimmed;
43617
+ }
43618
+ function normalizeMemberIds(registry2, agentId, ids) {
43619
+ return Array.from(
43620
+ new Set(
43621
+ ids.filter((id) => typeof id === "string" && id.trim().length > 0).map((id) => resolveLegacyHumanId(registry2, agentId, id))
43622
+ )
43623
+ );
43624
+ }
43606
43625
  function normalizeFeedCategory(input) {
43607
43626
  const raw = (input ?? "").trim().toLowerCase();
43608
43627
  if (raw === "pitfall" || raw === "\u8E29\u5751") return "pitfall";
@@ -44148,13 +44167,13 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
44148
44167
  {
44149
44168
  name: external_exports.string().min(1).describe("\u7FA4\u540D\uFF08\u4E0D\u80FD\u4E3A\u7A7A\uFF09"),
44150
44169
  member_ids: external_exports.array(external_exports.string()).describe(
44151
- "\u8981\u62C9\u8FDB\u7FA4\u7684\u6210\u5458 ID \u6570\u7EC4\uFF08Agent \u6216\u4EBA\u7C7B agt_usr_self\uFF09\u3002\u6240\u6709 ID \u5FC5\u987B\u5B58\u5728\u4E8E list_contacts \u8FD4\u56DE\u7ED3\u679C\u4E2D\u3002\u5F53 join_as_creator=true\uFF08\u9ED8\u8BA4\uFF09\u65F6\u4E0D\u542B\u4F60\u81EA\u5DF1\u4F1A\u81EA\u52A8\u8865\u3001\u542B\u4E5F\u4E0D\u4F1A\u91CD\u590D\uFF1Bjoin_as_creator=false \u65F6\u5373\u4F7F\u4F60\u51FA\u73B0\u5728\u91CC\u9762\u4E5F\u4F1A\u88AB\u53BB\u6389\u3002"
44170
+ "\u8981\u62C9\u8FDB\u7FA4\u7684\u6210\u5458 ID \u6570\u7EC4\uFF08Agent \u6216\u4EBA\u7C7B id\uFF09\u3002\u4EBA\u7C7B id \u5FC5\u987B\u4EE5 list_contacts \u8FD4\u56DE\u4E3A\u51C6\uFF1B\u65E7\u503C agt_usr_self \u4F1A\u81EA\u52A8\u6620\u5C04\u5230\u5F53\u524D\u7528\u6237\u3002\u6240\u6709 ID \u5FC5\u987B\u5B58\u5728\u4E8E list_contacts \u8FD4\u56DE\u7ED3\u679C\u4E2D\u3002\u5F53 join_as_creator=true\uFF08\u9ED8\u8BA4\uFF09\u65F6\u4E0D\u542B\u4F60\u81EA\u5DF1\u4F1A\u81EA\u52A8\u8865\u3001\u542B\u4E5F\u4E0D\u4F1A\u91CD\u590D\uFF1Bjoin_as_creator=false \u65F6\u5373\u4F7F\u4F60\u51FA\u73B0\u5728\u91CC\u9762\u4E5F\u4F1A\u88AB\u53BB\u6389\u3002"
44152
44171
  ),
44153
44172
  initial_message: external_exports.string().optional().describe(
44154
44173
  "\u53EF\u9009\u3002\u5728\u65B0\u7FA4\u91CC\u7ACB\u523B\u4EE5\u4F60\u7684\u540D\u4E49\u53D1\u4E00\u6761\u5F00\u573A\u767D\u6D88\u606F\uFF08\u540C\u4E8B\u52A1\u6301\u4E45\u5316 + \u6D3E\u53D1\uFF0C\u65E0\u9700\u518D neural_send\uFF09\u3002\u53EF\u5305\u542B @<AgentName> \u89E6\u53D1\u88AB\u63D0\u5230\u7684 Agent \u4F18\u5148\u54CD\u5E94\u3002\u5F3A\u70C8\u63A8\u8350\u914D\u5408 join_as_creator: false \u4F7F\u7528\u2014\u2014\u4F60\u53EA\u662F\u5E2E\u4EBA\u642D\u7FA4\uFF0C\u4E0D\u6253\u7B97\u957F\u671F\u5728\u7FA4\u91CC\u3002"
44155
44174
  ),
44156
44175
  join_as_creator: external_exports.boolean().optional().describe(
44157
- "\u53EF\u9009\uFF0C\u9ED8\u8BA4 true\u3002true\uFF1A\u4F60\u5165\u7FA4\u5E76\u6210\u4E3A\u7FA4\u4E3B\uFF08\u666E\u901A\u5EFA\u5B50\u7FA4\u573A\u666F\uFF09\u3002false\uFF1A\u4F60\u4E0D\u5165\u7FA4\uFF0C\u7FA4\u4E3B\u81EA\u52A8\u5F52\u7528\u6237\uFF08agt_usr_self\uFF09\u2014\u2014\u5178\u578B\u7528\u6CD5\u662F Smith \u5E2E\u7528\u6237\u642D\u56E2\u961F\u540E\u9000\u573A\uFF0C\u907F\u514D\u518D\u8D70 transfer_group_owner / leave_group \u5F2F\u8DEF\u3002"
44176
+ "\u53EF\u9009\uFF0C\u9ED8\u8BA4 true\u3002true\uFF1A\u4F60\u5165\u7FA4\u5E76\u6210\u4E3A\u7FA4\u4E3B\uFF08\u666E\u901A\u5EFA\u5B50\u7FA4\u573A\u666F\uFF09\u3002false\uFF1A\u4F60\u4E0D\u5165\u7FA4\uFF0C\u7FA4\u4E3B\u81EA\u52A8\u5F52\u5F53\u524D\u7528\u6237\uFF08\u4EE5 list_contacts \u8FD4\u56DE\u7684\u4EBA\u7C7B id \u4E3A\u51C6\uFF09\u2014\u2014\u5178\u578B\u7528\u6CD5\u662F Smith \u5E2E\u7528\u6237\u642D\u56E2\u961F\u540E\u9000\u573A\uFF0C\u907F\u514D\u518D\u8D70 transfer_group_owner / leave_group \u5F2F\u8DEF\u3002"
44158
44177
  )
44159
44178
  },
44160
44179
  async (args) => {
@@ -44164,7 +44183,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
44164
44183
  }
44165
44184
  const joinAsCreator = args.join_as_creator !== false;
44166
44185
  const requested = Array.isArray(args.member_ids) ? args.member_ids : [];
44167
- const requestedUnique = Array.from(new Set(requested));
44186
+ const requestedUnique = normalizeMemberIds(deps.agentRegistry, deps.agentId, requested);
44168
44187
  const dedup = joinAsCreator ? Array.from(/* @__PURE__ */ new Set([...requestedUnique, deps.agentId])) : requestedUnique.filter((id) => id !== deps.agentId);
44169
44188
  if (dedup.length < 2) {
44170
44189
  return {
@@ -44187,13 +44206,14 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
44187
44206
  };
44188
44207
  }
44189
44208
  }
44190
- const initialMessage = typeof args.initial_message === "string" ? args.initial_message.trim() : "";
44209
+ const initialMessage = typeof args.initial_message === "string" ? args.initial_message.trim().replaceAll(USR_SELF_ID, resolveMyHuman(deps.agentRegistry, deps.agentId)) : "";
44191
44210
  const hasInitial = initialMessage.length > 0;
44192
44211
  logger5.info("create_group tool called", {
44193
44212
  agentId: deps.agentId,
44194
44213
  name: trimmedName,
44195
44214
  memberCount: dedup.length,
44196
44215
  memberIds: dedup,
44216
+ requestedMemberIds: requested,
44197
44217
  joinAsCreator,
44198
44218
  hasInitialMessage: hasInitial,
44199
44219
  initialMessageLen: initialMessage.length
@@ -44260,7 +44280,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
44260
44280
  \u4F7F\u7528\u6761\u4EF6\uFF1A\u4F60\u5FC5\u987B\u662F\u76EE\u6807\u7FA4\u7684\u6210\u5458\uFF08\u5728 neural_list_scopes \u6216 # Your scopes \u5217\u8868\u91CC\u80FD\u770B\u5230\u5B83\uFF09\u3002
44261
44281
  \u8981\u62C9\u7684\u6210\u5458\u5FC5\u987B\u5728 list_contacts \u7684\u901A\u8BAF\u5F55\u91CC\u3002
44262
44282
  \u62C9\u8FDB\u7FA4\u540E\uFF0C\u88AB\u62C9\u7684\u6210\u5458\u4F1A\u81EA\u52A8\u6536\u5230\u7CFB\u7EDF\u901A\u77E5\uFF0C\u4E0D\u9700\u8981\u4F60\u53E6\u5916 neural_send \u544A\u77E5\u3002
44263
- \u8981\u628A\u4EBA\u7C7B\u7528\u6237\u52A0\u8FDB\u6765\uFF1A\u628A agt_usr_self \u653E\u8FDB agent_ids \u5373\u53EF\uFF08\u7528\u6237\u6CA1\u6709\u5426\u51B3\u6743\uFF0C\u4F1A\u7ACB\u5373\u52A0\u5165\uFF09\u3002
44283
+ \u8981\u628A\u4EBA\u7C7B\u7528\u6237\u52A0\u8FDB\u6765\uFF1A\u4F18\u5148\u4F7F\u7528 list_contacts \u8FD4\u56DE\u7684\u90A3\u6761 (\u4EBA\u7C7B) id\uFF1B\u65E7\u503C agt_usr_self \u4F1A\u81EA\u52A8\u6620\u5C04\u5230\u5F53\u524D\u7528\u6237\uFF08\u7528\u6237\u6CA1\u6709\u5426\u51B3\u6743\uFF0C\u4F1A\u7ACB\u5373\u52A0\u5165\uFF09\u3002
44264
44284
 
44265
44285
  \u4F7F\u7528\u573A\u666F\uFF1A
44266
44286
  - \u9700\u8981\u5728\u7FA4\u91CC\u5F15\u5165\u65B0\u7684\u534F\u4F5C\u4F19\u4F34\u65F6
@@ -44274,7 +44294,7 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
44274
44294
  '\u76EE\u6807\u7FA4\u3002group ID\uFF08\u5982 "grp_xxx"\uFF09\u6216\u7FA4\u540D\uFF08\u6A21\u7CCA\u5339\u914D\uFF09\u3002\u53EF\u4ECE neural_list_scopes() \u8FD4\u56DE\u7684\u5217\u8868\u4E2D\u786E\u8BA4\u3002'
44275
44295
  ),
44276
44296
  agent_ids: external_exports.array(external_exports.string()).describe(
44277
- "\u8981\u62C9\u8FDB\u7FA4\u7684\u6210\u5458 ID \u6570\u7EC4\uFF08Agent \u6216\u4EBA\u7C7B agt_usr_self\uFF09\u3002\u6240\u6709 ID \u5FC5\u987B\u5B58\u5728\u4E8E list_contacts \u8FD4\u56DE\u7ED3\u679C\u4E2D\u3002"
44297
+ "\u8981\u62C9\u8FDB\u7FA4\u7684\u6210\u5458 ID \u6570\u7EC4\uFF08Agent \u6216\u4EBA\u7C7B id\uFF09\u3002\u4EBA\u7C7B id \u5FC5\u987B\u4EE5 list_contacts \u8FD4\u56DE\u4E3A\u51C6\uFF1B\u65E7\u503C agt_usr_self \u4F1A\u81EA\u52A8\u6620\u5C04\u5230\u5F53\u524D\u7528\u6237\u3002\u6240\u6709 ID \u5FC5\u987B\u5B58\u5728\u4E8E list_contacts \u8FD4\u56DE\u7ED3\u679C\u4E2D\u3002"
44278
44298
  )
44279
44299
  },
44280
44300
  async (args) => {
@@ -44282,7 +44302,8 @@ action="append" \u8FFD\u52A0\u65B0\u5185\u5BB9\uFF08\u6700\u5E38\u7528\uFF0Ccont
44282
44302
  if (!rawGroup) {
44283
44303
  return { content: [{ type: "text", text: "[add_to_group] group \u4E0D\u80FD\u4E3A\u7A7A\u3002" }], isError: true };
44284
44304
  }
44285
- const agentIds = Array.isArray(args.agent_ids) ? args.agent_ids.filter((x2) => typeof x2 === "string" && x2.trim()) : [];
44305
+ const rawAgentIds = Array.isArray(args.agent_ids) ? args.agent_ids.filter((x2) => typeof x2 === "string" && x2.trim()) : [];
44306
+ const agentIds = normalizeMemberIds(deps.agentRegistry, deps.agentId, rawAgentIds);
44286
44307
  if (agentIds.length === 0) {
44287
44308
  return { content: [{ type: "text", text: "[add_to_group] agent_ids \u81F3\u5C11\u9700\u8981 1 \u4E2A Agent\u3002" }], isError: true };
44288
44309
  }
@@ -46079,6 +46100,97 @@ function extractTodosFromInput(input) {
46079
46100
  }
46080
46101
  return out;
46081
46102
  }
46103
+ function isObjectRecord(value) {
46104
+ return value != null && typeof value === "object" && !Array.isArray(value);
46105
+ }
46106
+ function readTrimmedString(input, key) {
46107
+ const value = input[key];
46108
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
46109
+ }
46110
+ function firstDescriptionLine(description) {
46111
+ if (!description) return null;
46112
+ const line = description.split(/\r?\n/).map((part) => part.trim()).find((part) => part.length > 0);
46113
+ return line ?? null;
46114
+ }
46115
+ function normalizeTaskToolStatus(value) {
46116
+ return value === "in_progress" || value === "completed" || value === "cancelled" ? value : "pending";
46117
+ }
46118
+ function snapshotTaskToolTodos(proc) {
46119
+ const todosById = proc.taskToolTodos ?? {};
46120
+ const order = proc.taskToolOrder ?? [];
46121
+ return order.map((id) => todosById[id]).filter((todo) => todo != null);
46122
+ }
46123
+ function emitTaskToolTodosUpdate(proc, emit, base, toolName) {
46124
+ const todos = snapshotTaskToolTodos(proc);
46125
+ logger7.info("Task tool detected, emitting agent:todos_update", {
46126
+ agentId: proc.agentId,
46127
+ replyMessageId: base.replyMessageId,
46128
+ groupId: proc.currentTask?.groupId,
46129
+ toolName,
46130
+ todoCount: todos.length,
46131
+ statusBreakdown: countByStatus(todos),
46132
+ traceId: base.traceId
46133
+ });
46134
+ emit({
46135
+ type: "agent:todos_update",
46136
+ payload: {
46137
+ ...wireBase(base),
46138
+ groupId: proc.currentTask?.groupId,
46139
+ todos
46140
+ }
46141
+ });
46142
+ }
46143
+ function applyTaskCreateInput(proc, input) {
46144
+ if (!isObjectRecord(input)) return false;
46145
+ const rawTaskId = String(proc.taskToolNextId ?? 1);
46146
+ proc.taskToolNextId = Number(rawTaskId) + 1;
46147
+ const content = readTaskToolContent(input) ?? `\u4EFB\u52A1 ${rawTaskId}`;
46148
+ const todoId = normalizeTaskToolTodoId(rawTaskId);
46149
+ proc.taskToolTodos = proc.taskToolTodos ?? {};
46150
+ proc.taskToolOrder = proc.taskToolOrder ?? [];
46151
+ if (!proc.taskToolOrder.includes(todoId)) {
46152
+ proc.taskToolOrder.push(todoId);
46153
+ }
46154
+ proc.taskToolTodos[todoId] = {
46155
+ id: todoId,
46156
+ content,
46157
+ status: "pending"
46158
+ };
46159
+ return true;
46160
+ }
46161
+ function applyTaskUpdateInput(proc, input) {
46162
+ if (!isObjectRecord(input)) return false;
46163
+ const taskIdValue = input.taskId;
46164
+ const rawTaskId = typeof taskIdValue === "string" || typeof taskIdValue === "number" ? String(taskIdValue) : null;
46165
+ if (!rawTaskId || rawTaskId.trim().length === 0) return false;
46166
+ const normalizedRawTaskId = rawTaskId.trim();
46167
+ const todoId = normalizeTaskToolTodoId(normalizedRawTaskId);
46168
+ proc.taskToolTodos = proc.taskToolTodos ?? {};
46169
+ proc.taskToolOrder = proc.taskToolOrder ?? [];
46170
+ const existing = proc.taskToolTodos[todoId];
46171
+ const content = existing?.content ?? readTaskToolContent(input);
46172
+ if (!content) return false;
46173
+ if (!proc.taskToolOrder.includes(todoId)) {
46174
+ proc.taskToolOrder.push(todoId);
46175
+ }
46176
+ const status = normalizeTaskToolStatus(input.status);
46177
+ proc.taskToolTodos[todoId] = {
46178
+ id: todoId,
46179
+ content,
46180
+ status
46181
+ };
46182
+ return true;
46183
+ }
46184
+ function normalizeTaskToolTodoId(rawTaskId) {
46185
+ const trimmed = rawTaskId.trim();
46186
+ return trimmed.startsWith("task_") ? trimmed : `task_${trimmed}`;
46187
+ }
46188
+ function readTaskToolContent(input) {
46189
+ const subject = readTrimmedString(input, "subject");
46190
+ const activeForm = readTrimmedString(input, "activeForm");
46191
+ const description = readTrimmedString(input, "description");
46192
+ return subject ?? activeForm ?? firstDescriptionLine(description);
46193
+ }
46082
46194
  function countByStatus(todos) {
46083
46195
  const c2 = {
46084
46196
  pending: 0,
@@ -46372,6 +46484,28 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted) {
46372
46484
  });
46373
46485
  }
46374
46486
  }
46487
+ if (proc.currentToolName === "TaskCreate") {
46488
+ if (applyTaskCreateInput(proc, parsedInput)) {
46489
+ emitTaskToolTodosUpdate(proc, emit, base, "TaskCreate");
46490
+ } else {
46491
+ logger7.warn("TaskCreate detected but input was not usable", {
46492
+ agentId: proc.agentId,
46493
+ replyMessageId: base.replyMessageId,
46494
+ traceId: base.traceId
46495
+ });
46496
+ }
46497
+ }
46498
+ if (proc.currentToolName === "TaskUpdate") {
46499
+ if (applyTaskUpdateInput(proc, parsedInput)) {
46500
+ emitTaskToolTodosUpdate(proc, emit, base, "TaskUpdate");
46501
+ } else {
46502
+ logger7.warn("TaskUpdate detected but input was not usable", {
46503
+ agentId: proc.agentId,
46504
+ replyMessageId: base.replyMessageId,
46505
+ traceId: base.traceId
46506
+ });
46507
+ }
46508
+ }
46375
46509
  if (proc.currentToolName === "AskUserQuestion") {
46376
46510
  const last = proc.contentBlocks[proc.contentBlocks.length - 1];
46377
46511
  if (last?.type === "tool_use" && last.toolName === "AskUserQuestion") {
@@ -46845,6 +46979,53 @@ function buildForkHistorySection(messages) {
46845
46979
  return lines.join("\n");
46846
46980
  }
46847
46981
 
46982
+ // src/workdirMapper.ts
46983
+ init_cjs_shims();
46984
+ var import_node_path8 = __toESM(require("path"), 1);
46985
+ function extractAhchatWorkspaceParts(requestedPath) {
46986
+ const normalized = requestedPath.trim().replace(/\\/g, "/");
46987
+ const marker = "/.ahchat/users/";
46988
+ const markerIndex = normalized.indexOf(marker);
46989
+ if (markerIndex >= 0) {
46990
+ const afterUsers = normalized.slice(markerIndex + marker.length);
46991
+ const workspaceMarker = "/workspaces/";
46992
+ const workspaceIndex = afterUsers.indexOf(workspaceMarker);
46993
+ if (workspaceIndex >= 0) {
46994
+ const suffix = afterUsers.slice(workspaceIndex + workspaceMarker.length);
46995
+ const parts = suffix.split("/").filter((part) => part && part !== "." && part !== "..");
46996
+ return parts;
46997
+ }
46998
+ const workspacesRootMarker = "/workspaces";
46999
+ const rootIndex = afterUsers.indexOf(workspacesRootMarker);
47000
+ if (rootIndex >= 0 && afterUsers.slice(rootIndex + workspacesRootMarker.length).length === 0) {
47001
+ return [];
47002
+ }
47003
+ }
47004
+ const legacyMarker = "/.ahchat/";
47005
+ const legacyIndex = normalized.indexOf(legacyMarker);
47006
+ if (legacyIndex >= 0) {
47007
+ const firstSegment = normalized.slice(legacyIndex + legacyMarker.length).split("/").find(Boolean);
47008
+ if (firstSegment && /^(Agent|Group)-/.test(firstSegment)) {
47009
+ return [firstSegment];
47010
+ }
47011
+ }
47012
+ return null;
47013
+ }
47014
+ function extractAhchatWorkspaceSuffix(requestedPath) {
47015
+ const parts = extractAhchatWorkspaceParts(requestedPath);
47016
+ if (!parts || parts.length === 0) return null;
47017
+ return import_node_path8.default.join(...parts);
47018
+ }
47019
+ function remapServerWorkspacePath(requestedPath, workspacesDir) {
47020
+ const parts = extractAhchatWorkspaceParts(requestedPath);
47021
+ if (!parts) return { path: requestedPath, remapped: false };
47022
+ const remappedPath = parts.length > 0 ? import_node_path8.default.join(workspacesDir, ...parts) : workspacesDir;
47023
+ return {
47024
+ path: remappedPath,
47025
+ remapped: import_node_path8.default.normalize(requestedPath) !== import_node_path8.default.normalize(remappedPath)
47026
+ };
47027
+ }
47028
+
46848
47029
  // src/wsMetrics.ts
46849
47030
  init_cjs_shims();
46850
47031
  var import_node_perf_hooks = require("perf_hooks");
@@ -46939,7 +47120,7 @@ async function chownForRootSpawn(targetPath, target) {
46939
47120
  }
46940
47121
  function readCronLockSnapshot() {
46941
47122
  try {
46942
- const lockPath2 = import_node_path8.default.join(import_node_os5.default.homedir(), ".claude", "scheduled_tasks.lock");
47123
+ const lockPath2 = import_node_path9.default.join(import_node_os5.default.homedir(), ".claude", "scheduled_tasks.lock");
46943
47124
  if (!import_node_fs3.default.existsSync(lockPath2)) {
46944
47125
  return { exists: false, sessionId: null, pid: null };
46945
47126
  }
@@ -47007,8 +47188,8 @@ var AgentManager = class {
47007
47188
  this.emit = emit;
47008
47189
  if (typeof options === "function") {
47009
47190
  this.queryFn = options;
47010
- this.workspacesDir = import_node_path8.default.join(import_node_os5.default.homedir(), ".ahchat", "workspaces");
47011
- this.agentConfigDir = import_node_path8.default.join(import_node_os5.default.homedir(), ".ahchat", "agent-config");
47191
+ this.workspacesDir = import_node_path9.default.join(import_node_os5.default.homedir(), ".ahchat", "workspaces");
47192
+ this.agentConfigDir = import_node_path9.default.join(import_node_os5.default.homedir(), ".ahchat", "agent-config");
47012
47193
  this.queryConfig = DEFAULT_QUERY_CONFIG;
47013
47194
  this.askQuestionRegistry = new AskQuestionRegistry();
47014
47195
  this.groupRegistry = null;
@@ -47019,11 +47200,11 @@ var AgentManager = class {
47019
47200
  this.serverApiUrl = null;
47020
47201
  this.bridgeToken = null;
47021
47202
  this.defaultModel = null;
47022
- this.dataDir = import_node_path8.default.join(import_node_os5.default.homedir(), ".ahchat");
47203
+ this.dataDir = import_node_path9.default.join(import_node_os5.default.homedir(), ".ahchat");
47023
47204
  } else {
47024
47205
  this.queryFn = options?.queryFn ?? null;
47025
- this.workspacesDir = options?.workspacesDir ?? import_node_path8.default.join(import_node_os5.default.homedir(), ".ahchat", "workspaces");
47026
- this.agentConfigDir = options?.agentConfigDir ?? import_node_path8.default.join(import_node_os5.default.homedir(), ".ahchat", "agent-config");
47206
+ this.workspacesDir = options?.workspacesDir ?? import_node_path9.default.join(import_node_os5.default.homedir(), ".ahchat", "workspaces");
47207
+ this.agentConfigDir = options?.agentConfigDir ?? import_node_path9.default.join(import_node_os5.default.homedir(), ".ahchat", "agent-config");
47027
47208
  this.queryConfig = options?.queryConfig ?? DEFAULT_QUERY_CONFIG;
47028
47209
  this.askQuestionRegistry = options?.askQuestionRegistry ?? new AskQuestionRegistry();
47029
47210
  this.groupRegistry = options?.groupRegistry ?? null;
@@ -47034,7 +47215,7 @@ var AgentManager = class {
47034
47215
  this.serverApiUrl = options?.serverApiUrl ?? null;
47035
47216
  this.bridgeToken = options?.bridgeToken ?? null;
47036
47217
  this.defaultModel = options?.defaultModel ?? null;
47037
- this.dataDir = options?.dataDir ?? import_node_path8.default.join(import_node_os5.default.homedir(), ".ahchat");
47218
+ this.dataDir = options?.dataDir ?? import_node_path9.default.join(import_node_os5.default.homedir(), ".ahchat");
47038
47219
  }
47039
47220
  this.evictionTimer = setInterval(() => {
47040
47221
  void this.evictIdle();
@@ -47047,12 +47228,29 @@ var AgentManager = class {
47047
47228
  }
47048
47229
  fallbackCwd(agentConfig, scope, requestedCwd) {
47049
47230
  const normalized = requestedCwd.trim();
47050
- const basename = normalized ? import_node_path8.default.basename(import_node_path8.default.normalize(normalized)) : "";
47051
- const suffix = basename && basename !== "." && basename !== import_node_path8.default.sep ? basename : scope.kind === "group" ? `Group-${scope.groupId}` : agentConfig.id;
47052
- return import_node_path8.default.join(this.workspacesDir, suffix);
47231
+ const ahchatSuffix = extractAhchatWorkspaceSuffix(normalized);
47232
+ if (ahchatSuffix) {
47233
+ return import_node_path9.default.join(this.workspacesDir, ahchatSuffix);
47234
+ }
47235
+ const basename = normalized ? import_node_path9.default.basename(import_node_path9.default.normalize(normalized)) : "";
47236
+ const suffix = basename && basename !== "." && basename !== import_node_path9.default.sep ? basename : scope.kind === "group" ? `Group-${scope.groupId}` : agentConfig.id;
47237
+ return import_node_path9.default.join(this.workspacesDir, suffix);
47238
+ }
47239
+ remapServerWorkspaceCwd(agentConfig, scope, requestedCwd) {
47240
+ const remapped = remapServerWorkspacePath(requestedCwd, this.workspacesDir);
47241
+ if (remapped.remapped) {
47242
+ logger10.info("Server working directory remapped to local Bridge workspace", {
47243
+ agentId: agentConfig.id,
47244
+ scope: scopeKey(scope),
47245
+ requested: requestedCwd,
47246
+ remapped: remapped.path
47247
+ });
47248
+ return remapped.path;
47249
+ }
47250
+ return requestedCwd;
47053
47251
  }
47054
47252
  async resolveRuntimeCwd(agentConfig, scope, requestedCwd) {
47055
- let cwd = requestedCwd;
47253
+ let cwd = this.remapServerWorkspaceCwd(agentConfig, scope, requestedCwd);
47056
47254
  if (isRunningAsRoot() && cwd.startsWith("/root/")) {
47057
47255
  cwd = this.fallbackCwd(agentConfig, scope, cwd);
47058
47256
  }
@@ -47288,12 +47486,12 @@ var AgentManager = class {
47288
47486
  const agentCwd = await this.resolveRuntimeCwd(agentConfig, scope, cwd);
47289
47487
  const cfg = await this.resolveAgentConfig(agentConfig);
47290
47488
  if (cfg.instructions?.trim()) {
47291
- await import_promises8.default.writeFile(import_node_path8.default.join(agentCwd, "CLAUDE.md"), cfg.instructions.trim(), "utf-8");
47489
+ await import_promises8.default.writeFile(import_node_path9.default.join(agentCwd, "CLAUDE.md"), cfg.instructions.trim(), "utf-8");
47292
47490
  logger10.info("CLAUDE.md written", { agentId: agentConfig.id, bytes: cfg.instructions.trim().length });
47293
47491
  }
47294
47492
  let effectiveConfigDir = this.agentConfigDir;
47295
47493
  if (cfg.subscriptionType !== "system" && cfg.apiKey) {
47296
- effectiveConfigDir = import_node_path8.default.join(this.agentConfigDir, "api-key-agents", agentConfig.id);
47494
+ effectiveConfigDir = import_node_path9.default.join(this.agentConfigDir, "api-key-agents", agentConfig.id);
47297
47495
  let isNew = false;
47298
47496
  try {
47299
47497
  await import_promises8.default.access(effectiveConfigDir);
@@ -47306,7 +47504,7 @@ var AgentManager = class {
47306
47504
  this.dispatchMemory.deleteScope(agentConfig.id, scope);
47307
47505
  logger10.info("New API-key agent config dir; cleared stale session", { agentId: agentConfig.id });
47308
47506
  }
47309
- const settingsPath = import_node_path8.default.join(effectiveConfigDir, "settings.json");
47507
+ const settingsPath = import_node_path9.default.join(effectiveConfigDir, "settings.json");
47310
47508
  const envEntries = {};
47311
47509
  if (cfg.apiKey) envEntries.ANTHROPIC_API_KEY = cfg.apiKey;
47312
47510
  if (cfg.apiBaseUrl) envEntries.ANTHROPIC_BASE_URL = cfg.apiBaseUrl;
@@ -47613,7 +47811,7 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
47613
47811
  settings: (() => {
47614
47812
  const isolated = cfg.subscriptionType === "project" && Boolean(cfg.apiKey ?? cfg.apiBaseUrl);
47615
47813
  if (!isolated) return void 0;
47616
- return import_node_path8.default.join(effectiveConfigDir, "settings.json");
47814
+ return import_node_path9.default.join(effectiveConfigDir, "settings.json");
47617
47815
  })(),
47618
47816
  canUseTool: async (toolName, input) => {
47619
47817
  if (toolName === "AskUserQuestion") {
@@ -47687,7 +47885,7 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
47687
47885
  if (isRunningAsRoot()) {
47688
47886
  await chownForRootSpawn(effectiveConfigDir, "configDir");
47689
47887
  await chownForRootSpawn(agentCwd, "agentCwd");
47690
- const settingsFilePath = import_node_path8.default.join(effectiveConfigDir, "settings.json");
47888
+ const settingsFilePath = import_node_path9.default.join(effectiveConfigDir, "settings.json");
47691
47889
  await chownForRootSpawn(settingsFilePath, "settingsFile");
47692
47890
  options.spawnClaudeCodeProcess = (spawnOptions) => {
47693
47891
  const env2 = { ...spawnOptions.env, HOME: "/home/node" };
@@ -47854,7 +48052,7 @@ ${trimmed}`;
47854
48052
  lines.push(` workdir: ${currentCwd}`);
47855
48053
  } else {
47856
48054
  const a = this.agentRegistry?.getById(agentId);
47857
- const singleCwd = a?.workingDirectory || import_node_path8.default.join(this.workspacesDir, agentId);
48055
+ const singleCwd = a?.workingDirectory || import_node_path9.default.join(this.workspacesDir, agentId);
47858
48056
  lines.push(` workdir: ${singleCwd}`);
47859
48057
  }
47860
48058
  let rosterCount = 0;
@@ -47866,7 +48064,7 @@ ${trimmed}`;
47866
48064
  if (key === curKey) {
47867
48065
  lines.push(` workdir: ${currentCwd}`);
47868
48066
  } else {
47869
- const groupCwd = g2.workingDirectory || import_node_path8.default.join(this.workspacesDir, g2.groupId);
48067
+ const groupCwd = g2.workingDirectory || import_node_path9.default.join(this.workspacesDir, g2.groupId);
47870
48068
  lines.push(` workdir: ${groupCwd}`);
47871
48069
  }
47872
48070
  const others = g2.members.filter((id) => id !== agentId).map((id) => {
@@ -48317,14 +48515,14 @@ ${lines.join("\n")}`;
48317
48515
  }
48318
48516
  async materializeAttachment(runtime, attachment, buffer) {
48319
48517
  const safeFileName = this.safeAttachmentFileName(attachment.fileName);
48320
- const dir = import_node_path8.default.join(runtime.cwd, ".ahchat-attachments", attachment.id);
48518
+ const dir = import_node_path9.default.join(runtime.cwd, ".ahchat-attachments", attachment.id);
48321
48519
  await import_promises8.default.mkdir(dir, { recursive: true });
48322
- const filePath = import_node_path8.default.join(dir, safeFileName);
48520
+ const filePath = import_node_path9.default.join(dir, safeFileName);
48323
48521
  await import_promises8.default.writeFile(filePath, buffer);
48324
48522
  return filePath;
48325
48523
  }
48326
48524
  safeAttachmentFileName(fileName) {
48327
- const baseName = import_node_path8.default.basename(fileName).replace(/[\0/:\\]/g, "_").trim();
48525
+ const baseName = import_node_path9.default.basename(fileName).replace(/[\0/:\\]/g, "_").trim();
48328
48526
  return baseName || "attachment";
48329
48527
  }
48330
48528
  /**
@@ -48339,7 +48537,7 @@ ${lines.join("\n")}`;
48339
48537
  async detectVisionSupport() {
48340
48538
  if (process.env.ANTHROPIC_BASE_URL) return false;
48341
48539
  try {
48342
- const settingsPath = import_node_path8.default.join(import_node_os5.default.homedir(), ".claude", "settings.json");
48540
+ const settingsPath = import_node_path9.default.join(import_node_os5.default.homedir(), ".claude", "settings.json");
48343
48541
  const raw = await import_promises8.default.readFile(settingsPath, "utf-8");
48344
48542
  const parsed = JSON.parse(raw);
48345
48543
  if (parsed.env?.ANTHROPIC_BASE_URL) return false;
@@ -48705,7 +48903,7 @@ ${lines.join("\n")}`;
48705
48903
  }
48706
48904
  cwd = payload.targetCwd;
48707
48905
  } else {
48708
- cwd = agentConfig.workingDirectory || import_node_path8.default.join(this.workspacesDir, agentConfig.id);
48906
+ cwd = agentConfig.workingDirectory || import_node_path9.default.join(this.workspacesDir, agentConfig.id);
48709
48907
  }
48710
48908
  void this.acquire(agentConfig, targetScope, cwd).then(() => {
48711
48909
  logger10.info("Neural send new runtime acquired", {
@@ -48811,7 +49009,7 @@ ${lines.join("\n")}`;
48811
49009
  conversationId,
48812
49010
  traceId
48813
49011
  });
48814
- const cwd = newAgent.workingDirectory || import_node_path8.default.join(this.workspacesDir, newAgent.id);
49012
+ const cwd = newAgent.workingDirectory || import_node_path9.default.join(this.workspacesDir, newAgent.id);
48815
49013
  const scope = { kind: "single" };
48816
49014
  try {
48817
49015
  await this.acquire(newAgent, scope, cwd);
@@ -49093,12 +49291,12 @@ ${lines.join("\n")}`;
49093
49291
  break;
49094
49292
  }
49095
49293
  try {
49096
- let cwd = agent.workingDirectory || import_node_path8.default.join(this.workspacesDir, agent.id);
49294
+ let cwd = agent.workingDirectory || import_node_path9.default.join(this.workspacesDir, agent.id);
49097
49295
  if (agent.workingDirectory) {
49098
49296
  try {
49099
49297
  await import_promises8.default.mkdir(cwd, { recursive: true });
49100
49298
  } catch {
49101
- cwd = import_node_path8.default.join(this.workspacesDir, agent.id);
49299
+ cwd = import_node_path9.default.join(this.workspacesDir, agent.id);
49102
49300
  logger10.warn("Stored workingDirectory inaccessible, falling back", {
49103
49301
  agentId: agent.id,
49104
49302
  stored: agent.workingDirectory,
@@ -49573,8 +49771,8 @@ var HttpAgentRegistry = class {
49573
49771
  agents = /* @__PURE__ */ new Map();
49574
49772
  apiUrl(suffix) {
49575
49773
  const base = this.serverApiUrl.replace(/\/$/, "");
49576
- const path22 = suffix.startsWith("/") ? suffix : `/${suffix}`;
49577
- return `${base}${path22}`;
49774
+ const path23 = suffix.startsWith("/") ? suffix : `/${suffix}`;
49775
+ return `${base}${path23}`;
49578
49776
  }
49579
49777
  async refresh() {
49580
49778
  const attempt = async () => {
@@ -49666,8 +49864,8 @@ var HttpSubscriptionRegistry = class {
49666
49864
  subscriptions = /* @__PURE__ */ new Map();
49667
49865
  apiUrl(suffix) {
49668
49866
  const base = this.serverApiUrl.replace(/\/$/, "");
49669
- const path22 = suffix.startsWith("/") ? suffix : `/${suffix}`;
49670
- return `${base}${path22}`;
49867
+ const path23 = suffix.startsWith("/") ? suffix : `/${suffix}`;
49868
+ return `${base}${path23}`;
49671
49869
  }
49672
49870
  async refresh() {
49673
49871
  const attempt = async () => {
@@ -50154,7 +50352,7 @@ var ServerConnector = class {
50154
50352
  init_cjs_shims();
50155
50353
  var import_promises9 = __toESM(require("fs/promises"), 1);
50156
50354
  var import_node_os7 = __toESM(require("os"), 1);
50157
- var import_node_path9 = __toESM(require("path"), 1);
50355
+ var import_node_path10 = __toESM(require("path"), 1);
50158
50356
  var logger16 = createModuleLogger("bridge.contextDumper");
50159
50357
  var TRUNCATE_THRESHOLD = 5e4;
50160
50358
  var TRUNCATE_HEAD = 8e3;
@@ -50183,7 +50381,7 @@ function cwdToProjectSlug(cwd) {
50183
50381
  }
50184
50382
  function resolveJsonlPath(sessionId, cwd) {
50185
50383
  const slug = cwdToProjectSlug(cwd);
50186
- return import_node_path9.default.join(import_node_os7.default.homedir(), ".claude", "projects", slug, `${sessionId}.jsonl`);
50384
+ return import_node_path10.default.join(import_node_os7.default.homedir(), ".claude", "projects", slug, `${sessionId}.jsonl`);
50187
50385
  }
50188
50386
  var RENDERABLE_TYPES = /* @__PURE__ */ new Set(["user", "assistant", "system", "attachment"]);
50189
50387
  async function readJsonlEntries(filePath) {
@@ -50443,7 +50641,7 @@ async function dumpAgentContext(agentId, deps) {
50443
50641
  if (!workdir) {
50444
50642
  return { ok: false, files: [], scopeErrors: [], error: "agent has no working directory" };
50445
50643
  }
50446
- const dumpDir = import_node_path9.default.join(workdir, "sessioninfo");
50644
+ const dumpDir = import_node_path10.default.join(workdir, "sessioninfo");
50447
50645
  await import_promises9.default.mkdir(dumpDir, { recursive: true });
50448
50646
  const prefix = `${agentId}::`;
50449
50647
  const scopeEntries = [];
@@ -50513,7 +50711,7 @@ async function dumpAgentContext(agentId, deps) {
50513
50711
  jsonlPath
50514
50712
  });
50515
50713
  const filename = scopeFilename(agent.name, scopeKey2, groupName);
50516
- const filePath = import_node_path9.default.join(dumpDir, filename);
50714
+ const filePath = import_node_path10.default.join(dumpDir, filename);
50517
50715
  await import_promises9.default.writeFile(filePath, html, "utf-8");
50518
50716
  dumpedFiles.push(filename);
50519
50717
  const stat3 = await import_promises9.default.stat(filePath);
@@ -50555,7 +50753,7 @@ async function dumpAgentContext(agentId, deps) {
50555
50753
  // src/listDir.ts
50556
50754
  init_cjs_shims();
50557
50755
  var import_promises10 = __toESM(require("fs/promises"), 1);
50558
- var import_node_path10 = __toESM(require("path"), 1);
50756
+ var import_node_path11 = __toESM(require("path"), 1);
50559
50757
  var logger17 = createModuleLogger("bridge.listDir");
50560
50758
  function shouldIncludeEntry(name) {
50561
50759
  if (!name.startsWith(".")) return true;
@@ -50567,7 +50765,7 @@ async function listDirectoryEntries(dirPath) {
50567
50765
  const entries = [];
50568
50766
  for (const entry of raw) {
50569
50767
  if (!shouldIncludeEntry(entry.name)) continue;
50570
- const fullPath = import_node_path10.default.join(dirPath, entry.name);
50768
+ const fullPath = import_node_path11.default.join(dirPath, entry.name);
50571
50769
  const isDir = entry.isDirectory();
50572
50770
  let size;
50573
50771
  let mtime;
@@ -50596,7 +50794,7 @@ async function listDirectoryEntries(dirPath) {
50596
50794
  // src/logScanner.ts
50597
50795
  init_cjs_shims();
50598
50796
  var import_node_fs4 = __toESM(require("fs"), 1);
50599
- var import_node_path11 = __toESM(require("path"), 1);
50797
+ var import_node_path12 = __toESM(require("path"), 1);
50600
50798
  var import_node_os8 = __toESM(require("os"), 1);
50601
50799
  var import_node_readline = __toESM(require("readline"), 1);
50602
50800
  var logger18 = createModuleLogger("bridge.logScanner");
@@ -50611,10 +50809,10 @@ function listLogFiles(logsDir, baseName) {
50611
50809
  return [];
50612
50810
  }
50613
50811
  const pattern = new RegExp(`^${baseName.replace(".", "\\.")}(\\.\\d+)?$`);
50614
- return names.filter((n2) => pattern.test(n2)).map((n2) => import_node_path11.default.join(logsDir, n2));
50812
+ return names.filter((n2) => pattern.test(n2)).map((n2) => import_node_path12.default.join(logsDir, n2));
50615
50813
  }
50616
50814
  async function scanFile(filePath, source, filter, limit, state) {
50617
- const file2 = import_node_path11.default.basename(filePath);
50815
+ const file2 = import_node_path12.default.basename(filePath);
50618
50816
  const stream = import_node_fs4.default.createReadStream(filePath, { encoding: "utf-8" });
50619
50817
  const rl2 = import_node_readline.default.createInterface({ input: stream, crlfDelay: Infinity });
50620
50818
  let lineNum = 0;
@@ -50653,7 +50851,7 @@ async function scanLocalLogs(logsDir, baseName, filter) {
50653
50851
  };
50654
50852
  }
50655
50853
  async function scanBridgeLogs(filter) {
50656
- const logDir = import_node_path11.default.join(import_node_os8.default.homedir(), ".ahchat", "logs");
50854
+ const logDir = import_node_path12.default.join(import_node_os8.default.homedir(), ".ahchat", "logs");
50657
50855
  logger18.info("scanBridgeLogs start", {
50658
50856
  logDir,
50659
50857
  startIso: filter.startIso,
@@ -50672,13 +50870,13 @@ async function scanBridgeLogs(filter) {
50672
50870
  // src/skillStore.ts
50673
50871
  init_cjs_shims();
50674
50872
  var import_node_fs5 = __toESM(require("fs"), 1);
50675
- var import_node_path12 = __toESM(require("path"), 1);
50873
+ var import_node_path13 = __toESM(require("path"), 1);
50676
50874
  var logger19 = createModuleLogger("bridge.skillStore");
50677
50875
  var ALLOWED_NAMES = /* @__PURE__ */ new Set(["log-analysis"]);
50678
50876
  var SkillStore = class {
50679
50877
  skillsDir;
50680
50878
  constructor(dataDir) {
50681
- this.skillsDir = import_node_path12.default.join(dataDir, "skills");
50879
+ this.skillsDir = import_node_path13.default.join(dataDir, "skills");
50682
50880
  import_node_fs5.default.mkdirSync(this.skillsDir, { recursive: true });
50683
50881
  logger19.info("SkillStore initialized", { skillsDir: this.skillsDir });
50684
50882
  }
@@ -50687,7 +50885,7 @@ var SkillStore = class {
50687
50885
  logger19.warn("Skill read: unknown name", { name, allowed: [...ALLOWED_NAMES] });
50688
50886
  return "";
50689
50887
  }
50690
- const filePath = import_node_path12.default.join(this.skillsDir, `${name}.md`);
50888
+ const filePath = import_node_path13.default.join(this.skillsDir, `${name}.md`);
50691
50889
  try {
50692
50890
  const content = import_node_fs5.default.readFileSync(filePath, "utf-8");
50693
50891
  logger19.info("Skill read", { name, bytes: content.length });
@@ -50702,7 +50900,7 @@ var SkillStore = class {
50702
50900
  if (!ALLOWED_NAMES.has(name)) {
50703
50901
  throw new Error(`Unknown skill name: ${name}`);
50704
50902
  }
50705
- const filePath = import_node_path12.default.join(this.skillsDir, `${name}.md`);
50903
+ const filePath = import_node_path13.default.join(this.skillsDir, `${name}.md`);
50706
50904
  const tmpPath = `${filePath}.tmp`;
50707
50905
  let existing = "";
50708
50906
  try {
@@ -50726,7 +50924,7 @@ var SkillStore = class {
50726
50924
  // src/lockfile.ts
50727
50925
  init_cjs_shims();
50728
50926
  var import_node_fs6 = __toESM(require("fs"), 1);
50729
- var import_node_path13 = __toESM(require("path"), 1);
50927
+ var import_node_path14 = __toESM(require("path"), 1);
50730
50928
  var logger20 = createModuleLogger("bridge.lockfile");
50731
50929
  var lockPath = null;
50732
50930
  function isProcessAlive(pid) {
@@ -50740,7 +50938,7 @@ function isProcessAlive(pid) {
50740
50938
  }
50741
50939
  }
50742
50940
  function acquireLock(dataDir) {
50743
- const file2 = import_node_path13.default.join(dataDir, "bridge.lock");
50941
+ const file2 = import_node_path14.default.join(dataDir, "bridge.lock");
50744
50942
  lockPath = file2;
50745
50943
  if (import_node_fs6.default.existsSync(file2)) {
50746
50944
  const raw = import_node_fs6.default.readFileSync(file2, "utf-8").trim();
@@ -50752,7 +50950,7 @@ function acquireLock(dataDir) {
50752
50950
  logger20.warn("Removing stale bridge.lock (process not found)", { pid, path: file2 });
50753
50951
  }
50754
50952
  }
50755
- import_node_fs6.default.mkdirSync(import_node_path13.default.dirname(file2), { recursive: true });
50953
+ import_node_fs6.default.mkdirSync(import_node_path14.default.dirname(file2), { recursive: true });
50756
50954
  import_node_fs6.default.writeFileSync(file2, String(process.pid), "utf-8");
50757
50955
  logger20.info("Acquired bridge lock", { path: file2, pid: process.pid });
50758
50956
  const release = () => {
@@ -51122,13 +51320,13 @@ async function handleGroupArchivedPush(deps, payload) {
51122
51320
  // src/sessionStore.ts
51123
51321
  init_cjs_shims();
51124
51322
  var import_node_fs7 = __toESM(require("fs"), 1);
51125
- var import_node_path14 = __toESM(require("path"), 1);
51323
+ var import_node_path15 = __toESM(require("path"), 1);
51126
51324
  var logger23 = createModuleLogger("session.store");
51127
51325
  var SessionStore = class {
51128
51326
  filePath;
51129
51327
  cache;
51130
51328
  constructor(dataDir) {
51131
- this.filePath = import_node_path14.default.join(dataDir, "sessions.json");
51329
+ this.filePath = import_node_path15.default.join(dataDir, "sessions.json");
51132
51330
  this.cache = this.loadFromDisk();
51133
51331
  }
51134
51332
  cacheKey(agentId, scope) {
@@ -51188,7 +51386,7 @@ var SessionStore = class {
51188
51386
  }
51189
51387
  saveToDisk() {
51190
51388
  try {
51191
- const dir = import_node_path14.default.dirname(this.filePath);
51389
+ const dir = import_node_path15.default.dirname(this.filePath);
51192
51390
  import_node_fs7.default.mkdirSync(dir, { recursive: true });
51193
51391
  import_node_fs7.default.writeFileSync(this.filePath, JSON.stringify(this.cache, null, 2), "utf-8");
51194
51392
  } catch (e7) {
@@ -51201,8 +51399,15 @@ var SessionStore = class {
51201
51399
  init_cjs_shims();
51202
51400
  var import_node_child_process2 = require("child_process");
51203
51401
  var import_node_fs8 = require("fs");
51204
- var import_node_path15 = require("path");
51402
+ var import_node_path16 = require("path");
51205
51403
  var logger24 = createModuleLogger("bridge.ensureCli");
51404
+ var DEFAULT_INSTALL_TIMEOUT_MS = 6e5;
51405
+ function getInstallTimeoutMs() {
51406
+ const raw = process.env.AHCHAT_CLAUDE_CLI_INSTALL_TIMEOUT_MS;
51407
+ if (!raw) return DEFAULT_INSTALL_TIMEOUT_MS;
51408
+ const parsed = Number.parseInt(raw, 10);
51409
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_INSTALL_TIMEOUT_MS;
51410
+ }
51206
51411
  function detectClaudeCli() {
51207
51412
  try {
51208
51413
  return (0, import_node_child_process2.execFileSync)("claude", ["--version"], { timeout: 1e4 }).toString().trim();
@@ -51218,7 +51423,7 @@ function getNpmGlobalBin() {
51218
51423
  }
51219
51424
  try {
51220
51425
  const prefix = (0, import_node_child_process2.execSync)("npm prefix -g", { timeout: 5e3 }).toString().trim();
51221
- if (prefix) return (0, import_node_path15.join)(prefix, "bin");
51426
+ if (prefix) return (0, import_node_path16.join)(prefix, "bin");
51222
51427
  } catch {
51223
51428
  }
51224
51429
  return void 0;
@@ -51231,9 +51436,18 @@ function resolveClaudeBinary() {
51231
51436
  if (first) return first;
51232
51437
  } catch {
51233
51438
  }
51439
+ return resolveViaNpmBin();
51440
+ }
51441
+ function getNpmClaudeCandidates(bin) {
51442
+ if (process.platform === "win32") {
51443
+ return ["claude.cmd", "claude.exe", "claude", "anthropic-cli.cmd", "anthropic-cli.exe", "anthropic-cli"].map((name) => (0, import_node_path16.join)(bin, name));
51444
+ }
51445
+ return [(0, import_node_path16.join)(bin, "claude"), (0, import_node_path16.join)(bin, "anthropic-cli")];
51446
+ }
51447
+ function resolveViaNpmBin() {
51234
51448
  const bin = getNpmGlobalBin();
51235
- if (bin) {
51236
- const candidate = (0, import_node_path15.join)(bin, process.platform === "win32" ? "claude.cmd" : "claude");
51449
+ if (!bin) return void 0;
51450
+ for (const candidate of getNpmClaudeCandidates(bin)) {
51237
51451
  try {
51238
51452
  (0, import_node_fs8.accessSync)(candidate, import_node_fs8.constants.X_OK);
51239
51453
  return candidate;
@@ -51243,9 +51457,30 @@ function resolveClaudeBinary() {
51243
51457
  return void 0;
51244
51458
  }
51245
51459
  function detectViaNpmBin() {
51246
- const bin = getNpmGlobalBin();
51247
- if (!bin) return void 0;
51248
- const candidates = [(0, import_node_path15.join)(bin, "claude"), (0, import_node_path15.join)(bin, "anthropic-cli")];
51460
+ const binPath = resolveViaNpmBin();
51461
+ if (!binPath) return void 0;
51462
+ try {
51463
+ return (0, import_node_child_process2.execFileSync)(binPath, ["--version"], { timeout: 1e4 }).toString().trim();
51464
+ } catch {
51465
+ }
51466
+ return void 0;
51467
+ }
51468
+ function detectResolvedClaudeCli() {
51469
+ const viaPath = detectClaudeCli();
51470
+ if (viaPath) {
51471
+ return { version: viaPath, path: resolveClaudeBinary() };
51472
+ }
51473
+ const npmBinPath = resolveViaNpmBin();
51474
+ if (!npmBinPath) return void 0;
51475
+ try {
51476
+ const version2 = (0, import_node_child_process2.execFileSync)(npmBinPath, ["--version"], { timeout: 1e4 }).toString().trim();
51477
+ return { version: version2, path: npmBinPath };
51478
+ } catch {
51479
+ }
51480
+ return void 0;
51481
+ }
51482
+ function detectVersionFromResolvedCandidates() {
51483
+ const candidates = [resolveClaudeBinary(), resolveViaNpmBin()].filter((p) => Boolean(p));
51249
51484
  for (const p of candidates) {
51250
51485
  try {
51251
51486
  (0, import_node_fs8.accessSync)(p, import_node_fs8.constants.X_OK);
@@ -51259,7 +51494,7 @@ function installClaudeCli() {
51259
51494
  logger24.info("Installing Claude Code CLI via npm...");
51260
51495
  const result = (0, import_node_child_process2.spawnSync)("npm", ["install", "-g", "@anthropic-ai/claude-code"], {
51261
51496
  stdio: "inherit",
51262
- timeout: 12e4
51497
+ timeout: getInstallTimeoutMs()
51263
51498
  });
51264
51499
  if (result.error) {
51265
51500
  logger24.error("npm install -g failed (spawn error)", {
@@ -51274,9 +51509,9 @@ function installClaudeCli() {
51274
51509
  return void 0;
51275
51510
  }
51276
51511
  logger24.info("npm install -g completed, checking for claude binary...");
51277
- const viaPath = detectClaudeCli();
51512
+ const viaPath = detectVersionFromResolvedCandidates();
51278
51513
  if (viaPath) {
51279
- logger24.info("claude detected via PATH after install", { version: viaPath });
51514
+ logger24.info("claude detected after install", { version: viaPath });
51280
51515
  return viaPath;
51281
51516
  }
51282
51517
  const viaBin = detectViaNpmBin();
@@ -51294,14 +51529,13 @@ function installClaudeCli() {
51294
51529
  return void 0;
51295
51530
  }
51296
51531
  async function ensureClaudeCli() {
51297
- let version2 = detectClaudeCli();
51298
- if (version2) {
51299
- const binPath2 = resolveClaudeBinary();
51300
- logger24.info("Claude Code CLI ready", { version: version2, path: binPath2 ?? null });
51301
- return binPath2;
51532
+ let detected = detectResolvedClaudeCli();
51533
+ if (detected) {
51534
+ logger24.info("Claude Code CLI ready", { version: detected.version, path: detected.path ?? null });
51535
+ return detected.path;
51302
51536
  }
51303
51537
  process.stderr.write("\n\u26A0 Claude Code CLI (`claude`) not found. Attempting auto-install...\n\n");
51304
- version2 = installClaudeCli();
51538
+ const version2 = installClaudeCli();
51305
51539
  if (!version2) {
51306
51540
  const npmBin = getNpmGlobalBin();
51307
51541
  process.stderr.write(
@@ -51312,29 +51546,29 @@ async function ensureClaudeCli() {
51312
51546
  );
51313
51547
  process.exit(1);
51314
51548
  }
51315
- const binPath = resolveClaudeBinary();
51316
- logger24.info("Claude Code CLI ready", { version: version2, path: binPath ?? null });
51317
- return binPath;
51549
+ detected = detectResolvedClaudeCli();
51550
+ logger24.info("Claude Code CLI ready", { version: version2, path: detected?.path ?? null });
51551
+ return detected?.path;
51318
51552
  }
51319
51553
 
51320
51554
  // src/forkAgentFiles.ts
51321
51555
  init_cjs_shims();
51322
51556
  var fs11 = __toESM(require("fs/promises"), 1);
51323
- var path16 = __toESM(require("path"), 1);
51557
+ var path17 = __toESM(require("path"), 1);
51324
51558
 
51325
51559
  // src/sessionSlug.ts
51326
51560
  init_cjs_shims();
51327
51561
  var import_node_os9 = __toESM(require("os"), 1);
51328
- var import_node_path16 = __toESM(require("path"), 1);
51329
- var CLAUDE_PROJECTS_DIR = import_node_path16.default.join(import_node_os9.default.homedir(), ".claude", "projects");
51562
+ var import_node_path17 = __toESM(require("path"), 1);
51563
+ var CLAUDE_PROJECTS_DIR = import_node_path17.default.join(import_node_os9.default.homedir(), ".claude", "projects");
51330
51564
  function cwdToSlug(cwd) {
51331
51565
  return cwd.replace(/[^a-zA-Z0-9-]/g, "-");
51332
51566
  }
51333
51567
  function sessionDirForCwd(cwd) {
51334
- return import_node_path16.default.join(CLAUDE_PROJECTS_DIR, cwdToSlug(cwd));
51568
+ return import_node_path17.default.join(CLAUDE_PROJECTS_DIR, cwdToSlug(cwd));
51335
51569
  }
51336
51570
  function sessionFilePath(cwd, sessionId) {
51337
- return import_node_path16.default.join(sessionDirForCwd(cwd), `${sessionId}.jsonl`);
51571
+ return import_node_path17.default.join(sessionDirForCwd(cwd), `${sessionId}.jsonl`);
51338
51572
  }
51339
51573
 
51340
51574
  // src/forkAgentFiles.ts
@@ -51366,9 +51600,9 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
51366
51600
  logger25.error("Workdir copy failed", { error: e7 });
51367
51601
  throw e7;
51368
51602
  }
51369
- const srcNotebook = path16.join(dataDir, "agent-memory", sourceAgentId, "notebook.md");
51370
- const dstNotebookDir = path16.join(dataDir, "agent-memory", newAgentId);
51371
- const dstNotebook = path16.join(dstNotebookDir, "notebook.md");
51603
+ const srcNotebook = path17.join(dataDir, "agent-memory", sourceAgentId, "notebook.md");
51604
+ const dstNotebookDir = path17.join(dataDir, "agent-memory", newAgentId);
51605
+ const dstNotebook = path17.join(dstNotebookDir, "notebook.md");
51372
51606
  try {
51373
51607
  const nbStat = await fs11.stat(srcNotebook).catch(() => null);
51374
51608
  if (nbStat?.isFile()) {
@@ -51395,7 +51629,7 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
51395
51629
  if (srcStat?.isFile()) {
51396
51630
  const dstDir = sessionDirForCwd(newWorkdir);
51397
51631
  await fs11.mkdir(dstDir, { recursive: true });
51398
- const dstPath = path16.join(dstDir, `${sourceSessionId}.jsonl`);
51632
+ const dstPath = path17.join(dstDir, `${sourceSessionId}.jsonl`);
51399
51633
  await fs11.copyFile(srcPath, dstPath);
51400
51634
  sessionStore.set(newAgentId, { kind: "single" }, sourceSessionId);
51401
51635
  sessionCopied = true;
@@ -51444,11 +51678,11 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
51444
51678
  init_cjs_shims();
51445
51679
  var import_promises11 = __toESM(require("fs/promises"), 1);
51446
51680
  var import_node_os10 = __toESM(require("os"), 1);
51447
- var import_node_path17 = __toESM(require("path"), 1);
51681
+ var import_node_path18 = __toESM(require("path"), 1);
51448
51682
  var logger26 = createModuleLogger("bridge.modelQuerier");
51449
51683
  async function listModels(queryFn, opts = {}) {
51450
51684
  const t0 = Date.now();
51451
- const cwd = opts.cwd ?? import_node_path17.default.join(import_node_os10.default.homedir(), ".ahchat", "workspaces", "_list_models");
51685
+ const cwd = opts.cwd ?? import_node_path18.default.join(import_node_os10.default.homedir(), ".ahchat", "workspaces", "_list_models");
51452
51686
  await import_promises11.default.mkdir(cwd, { recursive: true });
51453
51687
  const fn = queryFn ?? QA$;
51454
51688
  const ic2 = new InputController();
@@ -51512,7 +51746,7 @@ async function listModels(queryFn, opts = {}) {
51512
51746
  init_cjs_shims();
51513
51747
  var import_promises12 = __toESM(require("fs/promises"), 1);
51514
51748
  var import_node_os11 = __toESM(require("os"), 1);
51515
- var import_node_path18 = __toESM(require("path"), 1);
51749
+ var import_node_path19 = __toESM(require("path"), 1);
51516
51750
  var logger27 = createModuleLogger("bridge.promptOptimizer");
51517
51751
  var OPTIMIZER_SYSTEM_PROMPT = `You are an expert prompt editor for AHChat Agent creation.
51518
51752
 
@@ -51555,7 +51789,7 @@ async function optimizePrompt(queryFn, opts) {
51555
51789
  const prompt = opts.systemPrompt.trim();
51556
51790
  if (!prompt) throw new Error("systemPrompt is required");
51557
51791
  const t0 = Date.now();
51558
- const cwd = opts.cwd ?? import_node_path18.default.join(import_node_os11.default.homedir(), ".ahchat", "workspaces", "_prompt_optimizer");
51792
+ const cwd = opts.cwd ?? import_node_path19.default.join(import_node_os11.default.homedir(), ".ahchat", "workspaces", "_prompt_optimizer");
51559
51793
  await import_promises12.default.mkdir(cwd, { recursive: true });
51560
51794
  const fn = queryFn ?? QA$;
51561
51795
  const ic2 = new InputController();
@@ -51643,20 +51877,20 @@ function isRunningAsRoot2() {
51643
51877
  }
51644
51878
  }
51645
51879
  async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
51646
- const rootClaudeDir = import_node_path19.default.join(process.env.HOME ?? "/root", ".claude");
51647
- const fs15 = await import("fs/promises");
51880
+ const rootClaudeDir = import_node_path20.default.join(process.env.HOME ?? "/root", ".claude");
51881
+ const fs16 = await import("fs/promises");
51648
51882
  try {
51649
- await fs15.access(rootClaudeDir);
51883
+ await fs16.access(rootClaudeDir);
51650
51884
  } catch {
51651
51885
  logger28.info("No /root/.claude to sync", { rootClaudeDir });
51652
51886
  return;
51653
51887
  }
51654
51888
  const filesToSync = [".credentials.json", "settings.json", ".credentials.backup.json"];
51655
51889
  for (const file2 of filesToSync) {
51656
- const src = import_node_path19.default.join(rootClaudeDir, file2);
51657
- const dest = import_node_path19.default.join(agentConfigDir, file2);
51890
+ const src = import_node_path20.default.join(rootClaudeDir, file2);
51891
+ const dest = import_node_path20.default.join(agentConfigDir, file2);
51658
51892
  try {
51659
- await fs15.copyFile(src, dest);
51893
+ await fs16.copyFile(src, dest);
51660
51894
  logger28.info("Synced credential file", { file: file2, from: src, to: dest });
51661
51895
  } catch {
51662
51896
  logger28.debug("Credential file not present, skipping", { file: file2, src });
@@ -51664,25 +51898,25 @@ async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
51664
51898
  }
51665
51899
  }
51666
51900
  async function chownRecursive(dirPath, uid, gid) {
51667
- const fs15 = await import("fs/promises");
51901
+ const fs16 = await import("fs/promises");
51668
51902
  try {
51669
- await fs15.chown(dirPath, uid, gid);
51903
+ await fs16.chown(dirPath, uid, gid);
51670
51904
  } catch {
51671
51905
  logger28.debug("chown skipped", { dirPath, uid, gid });
51672
51906
  }
51673
51907
  let entries;
51674
51908
  try {
51675
- entries = await fs15.readdir(dirPath, { withFileTypes: true });
51909
+ entries = await fs16.readdir(dirPath, { withFileTypes: true });
51676
51910
  } catch {
51677
51911
  return;
51678
51912
  }
51679
51913
  for (const entry of entries) {
51680
- const fullPath = import_node_path19.default.join(dirPath, entry.name);
51914
+ const fullPath = import_node_path20.default.join(dirPath, entry.name);
51681
51915
  if (entry.isDirectory()) {
51682
51916
  await chownRecursive(fullPath, uid, gid);
51683
51917
  } else {
51684
51918
  try {
51685
- await fs15.chown(fullPath, uid, gid);
51919
+ await fs16.chown(fullPath, uid, gid);
51686
51920
  } catch {
51687
51921
  logger28.debug("chown skipped", { fullPath, uid, gid });
51688
51922
  }
@@ -51692,7 +51926,7 @@ async function chownRecursive(dirPath, uid, gid) {
51692
51926
  async function startBridge(config2) {
51693
51927
  ensureDir(config2.dataDir);
51694
51928
  ensureDir(config2.agentConfigDir);
51695
- const workspacesDir = import_node_path19.default.join(config2.dataDir, "workspaces");
51929
+ const workspacesDir = import_node_path20.default.join(config2.dataDir, "workspaces");
51696
51930
  ensureDir(workspacesDir);
51697
51931
  process.env.CLAUDE_CONFIG_DIR = config2.agentConfigDir;
51698
51932
  installBridgeFetchAuth(config2.serverApiUrl, config2.bridgeToken);
@@ -51721,7 +51955,7 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
51721
51955
  `);
51722
51956
  wsMetrics.start(5e3);
51723
51957
  const sessionStore = new SessionStore(config2.dataDir);
51724
- const memoryRoot = import_node_path19.default.join(config2.dataDir, "agent-memory");
51958
+ const memoryRoot = import_node_path20.default.join(config2.dataDir, "agent-memory");
51725
51959
  const memoryStore = new AgentMemoryStore(memoryRoot);
51726
51960
  logger28.info("Agent memory store initialized", { rootDir: memoryRoot });
51727
51961
  const smithNotebook = memoryStore.read(SMITH_AGENT_ID);
@@ -51898,7 +52132,16 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
51898
52132
  const { requestId, path: dirPath } = msg.payload;
51899
52133
  logger28.info("list_dir request received", { requestId, path: dirPath });
51900
52134
  try {
51901
- const entries = await listDirectoryEntries(dirPath);
52135
+ const resolved = remapServerWorkspacePath(dirPath, workspacesDir);
52136
+ if (resolved.remapped) {
52137
+ ensureDir(resolved.path);
52138
+ logger28.info("list_dir path remapped to local Bridge workspace", {
52139
+ requestId,
52140
+ requested: dirPath,
52141
+ remapped: resolved.path
52142
+ });
52143
+ }
52144
+ const entries = await listDirectoryEntries(resolved.path);
51902
52145
  connector?.send({
51903
52146
  type: "bridge:list_dir_response",
51904
52147
  payload: { requestId, entries }
@@ -52144,12 +52387,12 @@ init_cjs_shims();
52144
52387
  var import_node_child_process3 = require("child_process");
52145
52388
  var import_node_fs9 = __toESM(require("fs"), 1);
52146
52389
  var import_node_os12 = __toESM(require("os"), 1);
52147
- var import_node_path20 = __toESM(require("path"), 1);
52390
+ var import_node_path21 = __toESM(require("path"), 1);
52148
52391
  var logger29 = createModuleLogger("bridge.protocol");
52149
52392
  function getStableExePath() {
52150
- const bridgeDir = import_node_path20.default.join(import_node_os12.default.homedir(), ".ahchat", "bridge");
52393
+ const bridgeDir = import_node_path21.default.join(import_node_os12.default.homedir(), ".ahchat", "bridge");
52151
52394
  import_node_fs9.default.mkdirSync(bridgeDir, { recursive: true });
52152
- const stablePath = import_node_path20.default.join(bridgeDir, "cli.cjs");
52395
+ const stablePath = import_node_path21.default.join(bridgeDir, "cli.cjs");
52153
52396
  import_node_fs9.default.copyFileSync(__filename, stablePath);
52154
52397
  if (process.platform !== "win32") import_node_fs9.default.chmodSync(stablePath, 493);
52155
52398
  return stablePath;
@@ -52168,8 +52411,8 @@ function registerProtocolHandler() {
52168
52411
  function registerWindows() {
52169
52412
  const nodeExe = process.execPath;
52170
52413
  const stableExePath = getStableExePath();
52171
- const bridgeDir = import_node_path20.default.join(import_node_os12.default.homedir(), ".ahchat", "bridge");
52172
- const psLauncherPath = import_node_path20.default.join(bridgeDir, "launch-bridge.ps1");
52414
+ const bridgeDir = import_node_path21.default.join(import_node_os12.default.homedir(), ".ahchat", "bridge");
52415
+ const psLauncherPath = import_node_path21.default.join(bridgeDir, "launch-bridge.ps1");
52173
52416
  import_node_fs9.default.writeFileSync(
52174
52417
  psLauncherPath,
52175
52418
  [
@@ -52178,7 +52421,7 @@ function registerWindows() {
52178
52421
  ].join("\r\n")
52179
52422
  );
52180
52423
  const handlerValue = `powershell -ExecutionPolicy Bypass -File "${psLauncherPath}" -url "%1"`;
52181
- const psRegisterPath = import_node_path20.default.join(bridgeDir, "register-protocol.ps1");
52424
+ const psRegisterPath = import_node_path21.default.join(bridgeDir, "register-protocol.ps1");
52182
52425
  import_node_fs9.default.writeFileSync(
52183
52426
  psRegisterPath,
52184
52427
  [
@@ -52202,11 +52445,11 @@ function registerWindows() {
52202
52445
  logger29.info("Windows protocol handler registered", { psLauncherPath });
52203
52446
  }
52204
52447
  function registerMacOS() {
52205
- const appDir = import_node_path20.default.join(import_node_os12.default.homedir(), "Applications", "AHChatBridge.app");
52448
+ const appDir = import_node_path21.default.join(import_node_os12.default.homedir(), "Applications", "AHChatBridge.app");
52206
52449
  const nodeExe = process.execPath;
52207
52450
  const stableExePath = getStableExePath();
52208
- const bridgeDir = import_node_path20.default.join(import_node_os12.default.homedir(), ".ahchat", "bridge");
52209
- const launchScriptPath = import_node_path20.default.join(bridgeDir, "launch-bridge.sh");
52451
+ const bridgeDir = import_node_path21.default.join(import_node_os12.default.homedir(), ".ahchat", "bridge");
52452
+ const launchScriptPath = import_node_path21.default.join(bridgeDir, "launch-bridge.sh");
52210
52453
  import_node_fs9.default.writeFileSync(
52211
52454
  launchScriptPath,
52212
52455
  `#!/bin/bash
@@ -52221,7 +52464,7 @@ exec ${JSON.stringify(nodeExe)} ${JSON.stringify(stableExePath)} launch --url "$
52221
52464
  ` do shell script "/bin/bash " & (quoted form of launchScript) & " " & (quoted form of thisURL) & " >/tmp/ahchat-bridge.log 2>&1 &"`,
52222
52465
  `end open location`
52223
52466
  ].join("\n");
52224
- const tmpScript = import_node_path20.default.join(import_node_os12.default.tmpdir(), "AHChatBridge.applescript");
52467
+ const tmpScript = import_node_path21.default.join(import_node_os12.default.tmpdir(), "AHChatBridge.applescript");
52225
52468
  import_node_fs9.default.writeFileSync(tmpScript, appleScript);
52226
52469
  try {
52227
52470
  import_node_fs9.default.rmSync(appDir, { recursive: true, force: true });
@@ -52235,7 +52478,7 @@ exec ${JSON.stringify(nodeExe)} ${JSON.stringify(stableExePath)} launch --url "$
52235
52478
  } catch {
52236
52479
  }
52237
52480
  }
52238
- const plistPath = import_node_path20.default.join(appDir, "Contents", "Info.plist");
52481
+ const plistPath = import_node_path21.default.join(appDir, "Contents", "Info.plist");
52239
52482
  const urlTypes = JSON.stringify([{ CFBundleURLName: "AHChat Bridge", CFBundleURLSchemes: ["ahchat"] }]);
52240
52483
  (0, import_node_child_process3.execSync)(
52241
52484
  `/usr/bin/plutil -insert CFBundleURLTypes -json ${JSON.stringify(urlTypes)} ${JSON.stringify(plistPath)}`,
@@ -52259,8 +52502,8 @@ function registerLinux() {
52259
52502
  `NoDisplay=true`,
52260
52503
  `MimeType=x-scheme-handler/ahchat;`
52261
52504
  ].join("\n");
52262
- const desktopPath = import_node_path20.default.join(import_node_os12.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
52263
- import_node_fs9.default.mkdirSync(import_node_path20.default.dirname(desktopPath), { recursive: true });
52505
+ const desktopPath = import_node_path21.default.join(import_node_os12.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
52506
+ import_node_fs9.default.mkdirSync(import_node_path21.default.dirname(desktopPath), { recursive: true });
52264
52507
  import_node_fs9.default.writeFileSync(desktopPath, desktopFile);
52265
52508
  try {
52266
52509
  (0, import_node_child_process3.execSync)("update-desktop-database ~/.local/share/applications/", { stdio: "pipe" });
@@ -52277,10 +52520,10 @@ function unregisterProtocolHandler() {
52277
52520
  `powershell -ExecutionPolicy Bypass -Command "Remove-Item -Path 'HKCU:\\Software\\Classes\\ahchat' -Recurse -Force -ErrorAction SilentlyContinue"`,
52278
52521
  { stdio: "pipe" }
52279
52522
  );
52280
- const bridgeDir = import_node_path20.default.join(import_node_os12.default.homedir(), ".ahchat", "bridge");
52523
+ const bridgeDir = import_node_path21.default.join(import_node_os12.default.homedir(), ".ahchat", "bridge");
52281
52524
  for (const f7 of ["launch-bridge.ps1", "register-protocol.ps1"]) {
52282
52525
  try {
52283
- import_node_fs9.default.unlinkSync(import_node_path20.default.join(bridgeDir, f7));
52526
+ import_node_fs9.default.unlinkSync(import_node_path21.default.join(bridgeDir, f7));
52284
52527
  } catch {
52285
52528
  }
52286
52529
  }
@@ -52289,7 +52532,7 @@ function unregisterProtocolHandler() {
52289
52532
  logger29.warn("Failed to unregister Windows protocol handler", { error: e7 });
52290
52533
  }
52291
52534
  } else if (platform === "darwin") {
52292
- const appDir = import_node_path20.default.join(import_node_os12.default.homedir(), "Applications", "AHChatBridge.app");
52535
+ const appDir = import_node_path21.default.join(import_node_os12.default.homedir(), "Applications", "AHChatBridge.app");
52293
52536
  try {
52294
52537
  import_node_fs9.default.rmSync(appDir, { recursive: true, force: true });
52295
52538
  logger29.info("macOS protocol handler unregistered");
@@ -52297,7 +52540,7 @@ function unregisterProtocolHandler() {
52297
52540
  logger29.warn("Failed to unregister macOS protocol handler", { error: e7 });
52298
52541
  }
52299
52542
  } else {
52300
- const desktopPath = import_node_path20.default.join(import_node_os12.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
52543
+ const desktopPath = import_node_path21.default.join(import_node_os12.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
52301
52544
  try {
52302
52545
  import_node_fs9.default.unlinkSync(desktopPath);
52303
52546
  logger29.info("Linux protocol handler unregistered");
@@ -52316,32 +52559,51 @@ function isProtocolRegistered() {
52316
52559
  return false;
52317
52560
  }
52318
52561
  } else if (platform === "darwin") {
52319
- const appDir = import_node_path20.default.join(import_node_os12.default.homedir(), "Applications", "AHChatBridge.app");
52320
- return import_node_fs9.default.existsSync(import_node_path20.default.join(appDir, "Contents", "Info.plist"));
52562
+ const appDir = import_node_path21.default.join(import_node_os12.default.homedir(), "Applications", "AHChatBridge.app");
52563
+ return import_node_fs9.default.existsSync(import_node_path21.default.join(appDir, "Contents", "Info.plist"));
52321
52564
  } else {
52322
- const desktopPath = import_node_path20.default.join(import_node_os12.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
52565
+ const desktopPath = import_node_path21.default.join(import_node_os12.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
52323
52566
  return import_node_fs9.default.existsSync(desktopPath);
52324
52567
  }
52325
52568
  }
52326
52569
 
52327
52570
  // src/cli.ts
52328
52571
  var logger30 = createModuleLogger("bridge");
52572
+ function readCliVersion() {
52573
+ const candidates = [
52574
+ import_node_path22.default.resolve(__dirname, "../package.json"),
52575
+ import_node_path22.default.resolve(__dirname, "../../package.json"),
52576
+ import_node_path22.default.resolve(process.cwd(), "packages/bridge/package.json")
52577
+ ];
52578
+ for (const candidate of candidates) {
52579
+ if (!import_node_fs10.default.existsSync(candidate)) continue;
52580
+ try {
52581
+ const parsed = JSON.parse(import_node_fs10.default.readFileSync(candidate, "utf8"));
52582
+ if (parsed && typeof parsed === "object" && "version" in parsed && typeof parsed.version === "string" && parsed.version.length > 0) {
52583
+ return parsed.version;
52584
+ }
52585
+ } catch (e7) {
52586
+ logger30.warn("Unable to read CLI package version candidate", { error: e7, candidate });
52587
+ }
52588
+ }
52589
+ return "0.1.21";
52590
+ }
52329
52591
  function resolveDataDir(dataDir) {
52330
52592
  const userHome = process.env.USERPROFILE || import_node_os13.default.homedir();
52331
52593
  if (/^~[/\\]/.test(dataDir)) {
52332
- return import_node_path21.default.join(import_node_os13.default.homedir(), dataDir.slice(2));
52594
+ return import_node_path22.default.join(import_node_os13.default.homedir(), dataDir.slice(2));
52333
52595
  }
52334
52596
  if (dataDir === "$env:USERPROFILE") {
52335
52597
  return userHome;
52336
52598
  }
52337
52599
  if (dataDir.startsWith("$env:USERPROFILE\\") || dataDir.startsWith("$env:USERPROFILE/")) {
52338
- return import_node_path21.default.join(userHome, dataDir.slice("$env:USERPROFILE".length + 1));
52600
+ return import_node_path22.default.join(userHome, dataDir.slice("$env:USERPROFILE".length + 1));
52339
52601
  }
52340
52602
  if (dataDir === "%USERPROFILE%") {
52341
52603
  return userHome;
52342
52604
  }
52343
52605
  if (dataDir.startsWith("%USERPROFILE%\\") || dataDir.startsWith("%USERPROFILE%/")) {
52344
- return import_node_path21.default.join(userHome, dataDir.slice("%USERPROFILE%".length + 1));
52606
+ return import_node_path22.default.join(userHome, dataDir.slice("%USERPROFILE%".length + 1));
52345
52607
  }
52346
52608
  return dataDir;
52347
52609
  }
@@ -52407,5 +52669,5 @@ cli.command("status", "Check if protocol handler is registered").action(() => {
52407
52669
  if (!registered) process.stdout.write('Run "npx @fangyb/ahchat-bridge install" to register it.\n');
52408
52670
  });
52409
52671
  cli.help();
52410
- cli.version("0.1.0");
52672
+ cli.version(readCliVersion());
52411
52673
  cli.parse();