@fangyb/ahchat-bridge 0.1.20 → 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 (4) hide show
  1. package/dist/cli.cjs +194 -164
  2. package/dist/cli.js +0 -0
  3. package/dist/index.js +161 -132
  4. package/package.json +11 -11
package/dist/index.js CHANGED
@@ -4460,11 +4460,11 @@ var RotatingFileStream = class extends Writable {
4460
4460
  timeout;
4461
4461
  timeoutPromise;
4462
4462
  constructor(generator, options) {
4463
- const { encoding, history, maxFiles, maxSize, path: path20 } = options;
4463
+ const { encoding, history, maxFiles, maxSize, path: path21 } = options;
4464
4464
  super({ decodeStrings: true, defaultEncoding: encoding });
4465
4465
  this.createGzip = createGzip;
4466
4466
  this.exec = exec;
4467
- this.filename = path20 + generator(null);
4467
+ this.filename = path21 + generator(null);
4468
4468
  this.fsCreateReadStream = createReadStream;
4469
4469
  this.fsCreateWriteStream = createWriteStream;
4470
4470
  this.fsOpen = open;
@@ -4476,7 +4476,7 @@ var RotatingFileStream = class extends Writable {
4476
4476
  this.options = options;
4477
4477
  this.stdout = process.stdout;
4478
4478
  if (maxFiles || maxSize)
4479
- options.history = path20 + (history ? history : this.generator(null) + ".txt");
4479
+ options.history = path21 + (history ? history : this.generator(null) + ".txt");
4480
4480
  this.on("close", () => this.finished ? null : this.emit("finish"));
4481
4481
  this.on("finish", () => this.finished = this.clear());
4482
4482
  (async () => {
@@ -4604,9 +4604,9 @@ var RotatingFileStream = class extends Writable {
4604
4604
  return this.move();
4605
4605
  }
4606
4606
  async findName() {
4607
- const { interval, path: path20, intervalBoundary } = this.options;
4607
+ const { interval, path: path21, intervalBoundary } = this.options;
4608
4608
  for (let index = 1; index < 1e3; ++index) {
4609
- const filename = path20 + this.generator(interval && intervalBoundary ? new Date(this.prev) : this.rotation, index);
4609
+ const filename = path21 + this.generator(interval && intervalBoundary ? new Date(this.prev) : this.rotation, index);
4610
4610
  if (!await exists(filename))
4611
4611
  return filename;
4612
4612
  }
@@ -4636,11 +4636,11 @@ var RotatingFileStream = class extends Writable {
4636
4636
  return this.unlink(filename);
4637
4637
  }
4638
4638
  async classical() {
4639
- const { compress, path: path20, rotate } = this.options;
4639
+ const { compress, path: path21, rotate } = this.options;
4640
4640
  let rotatedName = "";
4641
4641
  for (let count = rotate; count > 0; --count) {
4642
- const currName = path20 + this.generator(count);
4643
- const prevName = count === 1 ? this.filename : path20 + this.generator(count - 1);
4642
+ const currName = path21 + this.generator(count);
4643
+ const prevName = count === 1 ? this.filename : path21 + this.generator(count - 1);
4644
4644
  if (!await exists(prevName))
4645
4645
  continue;
4646
4646
  if (!rotatedName)
@@ -5077,7 +5077,7 @@ function createModuleLogger(module) {
5077
5077
  }
5078
5078
 
5079
5079
  // src/start.ts
5080
- import path19 from "path";
5080
+ import path20 from "path";
5081
5081
 
5082
5082
  // ../shared/src/smithContent.ts
5083
5083
  var SMITH_SYSTEM_PROMPT = `\u4F60\u662F\u7279\u5DE5\u53F2\u5BC6\u65AF\uFF08Agent Smith\uFF09\uFF0CAHChat \u7CFB\u7EDF\u7684\u7EC4\u7EC7\u5DE5\u5177\u3002
@@ -6240,7 +6240,7 @@ import { createHash } from "crypto";
6240
6240
  import fsSync from "fs";
6241
6241
  import fs4 from "fs/promises";
6242
6242
  import os5 from "os";
6243
- import path8 from "path";
6243
+ import path9 from "path";
6244
6244
 
6245
6245
  // ../../node_modules/.pnpm/@anthropic-ai+claude-agent-sdk@0.2.141_zod@4.4.3/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
6246
6246
  import { createRequire as $S } from "module";
@@ -29037,10 +29037,10 @@ function mergeDefs(...defs) {
29037
29037
  function cloneDef(schema) {
29038
29038
  return mergeDefs(schema._zod.def);
29039
29039
  }
29040
- function getElementAtPath(obj, path20) {
29041
- if (!path20)
29040
+ function getElementAtPath(obj, path21) {
29041
+ if (!path21)
29042
29042
  return obj;
29043
- return path20.reduce((acc, key) => acc?.[key], obj);
29043
+ return path21.reduce((acc, key) => acc?.[key], obj);
29044
29044
  }
29045
29045
  function promiseAllObject(promisesObj) {
29046
29046
  const keys = Object.keys(promisesObj);
@@ -29449,11 +29449,11 @@ function explicitlyAborted(x2, startIndex = 0) {
29449
29449
  }
29450
29450
  return false;
29451
29451
  }
29452
- function prefixIssues(path20, issues) {
29452
+ function prefixIssues(path21, issues) {
29453
29453
  return issues.map((iss) => {
29454
29454
  var _a3;
29455
29455
  (_a3 = iss).path ?? (_a3.path = []);
29456
- iss.path.unshift(path20);
29456
+ iss.path.unshift(path21);
29457
29457
  return iss;
29458
29458
  });
29459
29459
  }
@@ -29600,16 +29600,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
29600
29600
  }
29601
29601
  function formatError(error51, mapper = (issue2) => issue2.message) {
29602
29602
  const fieldErrors = { _errors: [] };
29603
- const processError = (error52, path20 = []) => {
29603
+ const processError = (error52, path21 = []) => {
29604
29604
  for (const issue2 of error52.issues) {
29605
29605
  if (issue2.code === "invalid_union" && issue2.errors.length) {
29606
- issue2.errors.map((issues) => processError({ issues }, [...path20, ...issue2.path]));
29606
+ issue2.errors.map((issues) => processError({ issues }, [...path21, ...issue2.path]));
29607
29607
  } else if (issue2.code === "invalid_key") {
29608
- processError({ issues: issue2.issues }, [...path20, ...issue2.path]);
29608
+ processError({ issues: issue2.issues }, [...path21, ...issue2.path]);
29609
29609
  } else if (issue2.code === "invalid_element") {
29610
- processError({ issues: issue2.issues }, [...path20, ...issue2.path]);
29610
+ processError({ issues: issue2.issues }, [...path21, ...issue2.path]);
29611
29611
  } else {
29612
- const fullpath = [...path20, ...issue2.path];
29612
+ const fullpath = [...path21, ...issue2.path];
29613
29613
  if (fullpath.length === 0) {
29614
29614
  fieldErrors._errors.push(mapper(issue2));
29615
29615
  } else {
@@ -29636,17 +29636,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
29636
29636
  }
29637
29637
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
29638
29638
  const result = { errors: [] };
29639
- const processError = (error52, path20 = []) => {
29639
+ const processError = (error52, path21 = []) => {
29640
29640
  var _a3, _b2;
29641
29641
  for (const issue2 of error52.issues) {
29642
29642
  if (issue2.code === "invalid_union" && issue2.errors.length) {
29643
- issue2.errors.map((issues) => processError({ issues }, [...path20, ...issue2.path]));
29643
+ issue2.errors.map((issues) => processError({ issues }, [...path21, ...issue2.path]));
29644
29644
  } else if (issue2.code === "invalid_key") {
29645
- processError({ issues: issue2.issues }, [...path20, ...issue2.path]);
29645
+ processError({ issues: issue2.issues }, [...path21, ...issue2.path]);
29646
29646
  } else if (issue2.code === "invalid_element") {
29647
- processError({ issues: issue2.issues }, [...path20, ...issue2.path]);
29647
+ processError({ issues: issue2.issues }, [...path21, ...issue2.path]);
29648
29648
  } else {
29649
- const fullpath = [...path20, ...issue2.path];
29649
+ const fullpath = [...path21, ...issue2.path];
29650
29650
  if (fullpath.length === 0) {
29651
29651
  result.errors.push(mapper(issue2));
29652
29652
  continue;
@@ -29678,8 +29678,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
29678
29678
  }
29679
29679
  function toDotPath(_path) {
29680
29680
  const segs = [];
29681
- const path20 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
29682
- for (const seg of path20) {
29681
+ const path21 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
29682
+ for (const seg of path21) {
29683
29683
  if (typeof seg === "number")
29684
29684
  segs.push(`[${seg}]`);
29685
29685
  else if (typeof seg === "symbol")
@@ -42371,13 +42371,13 @@ function resolveRef(ref, ctx) {
42371
42371
  if (!ref.startsWith("#")) {
42372
42372
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
42373
42373
  }
42374
- const path20 = ref.slice(1).split("/").filter(Boolean);
42375
- if (path20.length === 0) {
42374
+ const path21 = ref.slice(1).split("/").filter(Boolean);
42375
+ if (path21.length === 0) {
42376
42376
  return ctx.rootSchema;
42377
42377
  }
42378
42378
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
42379
- if (path20[0] === defsKey) {
42380
- const key = path20[1];
42379
+ if (path21[0] === defsKey) {
42380
+ const key = path21[1];
42381
42381
  if (!key || !ctx.defs[key]) {
42382
42382
  throw new Error(`Reference not found: ${ref}`);
42383
42383
  }
@@ -46177,6 +46177,52 @@ function buildForkHistorySection(messages) {
46177
46177
  return lines.join("\n");
46178
46178
  }
46179
46179
 
46180
+ // src/workdirMapper.ts
46181
+ import path8 from "path";
46182
+ function extractAhchatWorkspaceParts(requestedPath) {
46183
+ const normalized = requestedPath.trim().replace(/\\/g, "/");
46184
+ const marker = "/.ahchat/users/";
46185
+ const markerIndex = normalized.indexOf(marker);
46186
+ if (markerIndex >= 0) {
46187
+ const afterUsers = normalized.slice(markerIndex + marker.length);
46188
+ const workspaceMarker = "/workspaces/";
46189
+ const workspaceIndex = afterUsers.indexOf(workspaceMarker);
46190
+ if (workspaceIndex >= 0) {
46191
+ const suffix = afterUsers.slice(workspaceIndex + workspaceMarker.length);
46192
+ const parts = suffix.split("/").filter((part) => part && part !== "." && part !== "..");
46193
+ return parts;
46194
+ }
46195
+ const workspacesRootMarker = "/workspaces";
46196
+ const rootIndex = afterUsers.indexOf(workspacesRootMarker);
46197
+ if (rootIndex >= 0 && afterUsers.slice(rootIndex + workspacesRootMarker.length).length === 0) {
46198
+ return [];
46199
+ }
46200
+ }
46201
+ const legacyMarker = "/.ahchat/";
46202
+ const legacyIndex = normalized.indexOf(legacyMarker);
46203
+ if (legacyIndex >= 0) {
46204
+ const firstSegment = normalized.slice(legacyIndex + legacyMarker.length).split("/").find(Boolean);
46205
+ if (firstSegment && /^(Agent|Group)-/.test(firstSegment)) {
46206
+ return [firstSegment];
46207
+ }
46208
+ }
46209
+ return null;
46210
+ }
46211
+ function extractAhchatWorkspaceSuffix(requestedPath) {
46212
+ const parts = extractAhchatWorkspaceParts(requestedPath);
46213
+ if (!parts || parts.length === 0) return null;
46214
+ return path8.join(...parts);
46215
+ }
46216
+ function remapServerWorkspacePath(requestedPath, workspacesDir) {
46217
+ const parts = extractAhchatWorkspaceParts(requestedPath);
46218
+ if (!parts) return { path: requestedPath, remapped: false };
46219
+ const remappedPath = parts.length > 0 ? path8.join(workspacesDir, ...parts) : workspacesDir;
46220
+ return {
46221
+ path: remappedPath,
46222
+ remapped: path8.normalize(requestedPath) !== path8.normalize(remappedPath)
46223
+ };
46224
+ }
46225
+
46180
46226
  // src/wsMetrics.ts
46181
46227
  import { monitorEventLoopDelay } from "perf_hooks";
46182
46228
  var logger9 = createModuleLogger("ws.metrics");
@@ -46270,7 +46316,7 @@ async function chownForRootSpawn(targetPath, target) {
46270
46316
  }
46271
46317
  function readCronLockSnapshot() {
46272
46318
  try {
46273
- const lockPath2 = path8.join(os5.homedir(), ".claude", "scheduled_tasks.lock");
46319
+ const lockPath2 = path9.join(os5.homedir(), ".claude", "scheduled_tasks.lock");
46274
46320
  if (!fsSync.existsSync(lockPath2)) {
46275
46321
  return { exists: false, sessionId: null, pid: null };
46276
46322
  }
@@ -46338,8 +46384,8 @@ var AgentManager = class {
46338
46384
  this.emit = emit;
46339
46385
  if (typeof options === "function") {
46340
46386
  this.queryFn = options;
46341
- this.workspacesDir = path8.join(os5.homedir(), ".ahchat", "workspaces");
46342
- this.agentConfigDir = path8.join(os5.homedir(), ".ahchat", "agent-config");
46387
+ this.workspacesDir = path9.join(os5.homedir(), ".ahchat", "workspaces");
46388
+ this.agentConfigDir = path9.join(os5.homedir(), ".ahchat", "agent-config");
46343
46389
  this.queryConfig = DEFAULT_QUERY_CONFIG;
46344
46390
  this.askQuestionRegistry = new AskQuestionRegistry();
46345
46391
  this.groupRegistry = null;
@@ -46350,11 +46396,11 @@ var AgentManager = class {
46350
46396
  this.serverApiUrl = null;
46351
46397
  this.bridgeToken = null;
46352
46398
  this.defaultModel = null;
46353
- this.dataDir = path8.join(os5.homedir(), ".ahchat");
46399
+ this.dataDir = path9.join(os5.homedir(), ".ahchat");
46354
46400
  } else {
46355
46401
  this.queryFn = options?.queryFn ?? null;
46356
- this.workspacesDir = options?.workspacesDir ?? path8.join(os5.homedir(), ".ahchat", "workspaces");
46357
- this.agentConfigDir = options?.agentConfigDir ?? path8.join(os5.homedir(), ".ahchat", "agent-config");
46402
+ this.workspacesDir = options?.workspacesDir ?? path9.join(os5.homedir(), ".ahchat", "workspaces");
46403
+ this.agentConfigDir = options?.agentConfigDir ?? path9.join(os5.homedir(), ".ahchat", "agent-config");
46358
46404
  this.queryConfig = options?.queryConfig ?? DEFAULT_QUERY_CONFIG;
46359
46405
  this.askQuestionRegistry = options?.askQuestionRegistry ?? new AskQuestionRegistry();
46360
46406
  this.groupRegistry = options?.groupRegistry ?? null;
@@ -46365,7 +46411,7 @@ var AgentManager = class {
46365
46411
  this.serverApiUrl = options?.serverApiUrl ?? null;
46366
46412
  this.bridgeToken = options?.bridgeToken ?? null;
46367
46413
  this.defaultModel = options?.defaultModel ?? null;
46368
- this.dataDir = options?.dataDir ?? path8.join(os5.homedir(), ".ahchat");
46414
+ this.dataDir = options?.dataDir ?? path9.join(os5.homedir(), ".ahchat");
46369
46415
  }
46370
46416
  this.evictionTimer = setInterval(() => {
46371
46417
  void this.evictIdle();
@@ -46376,52 +46422,26 @@ var AgentManager = class {
46376
46422
  this.queryFn = QA$;
46377
46423
  return this.queryFn;
46378
46424
  }
46379
- extractAhchatWorkspaceSuffix(requestedCwd) {
46380
- const normalized = requestedCwd.trim().replace(/\\/g, "/");
46381
- const marker = "/.ahchat/users/";
46382
- const markerIndex = normalized.indexOf(marker);
46383
- if (markerIndex >= 0) {
46384
- const afterUsers = normalized.slice(markerIndex + marker.length);
46385
- const workspaceMarker = "/workspaces/";
46386
- const workspaceIndex = afterUsers.indexOf(workspaceMarker);
46387
- if (workspaceIndex >= 0) {
46388
- const suffix = afterUsers.slice(workspaceIndex + workspaceMarker.length);
46389
- const parts = suffix.split("/").filter((part) => part && part !== "." && part !== "..");
46390
- return parts.length > 0 ? parts.join(path8.sep) : null;
46391
- }
46392
- }
46393
- const legacyMarker = "/.ahchat/";
46394
- const legacyIndex = normalized.indexOf(legacyMarker);
46395
- if (legacyIndex >= 0) {
46396
- const firstSegment = normalized.slice(legacyIndex + legacyMarker.length).split("/").find(Boolean);
46397
- if (firstSegment && /^(Agent|Group)-/.test(firstSegment)) {
46398
- return firstSegment;
46399
- }
46400
- }
46401
- return null;
46402
- }
46403
46425
  fallbackCwd(agentConfig, scope, requestedCwd) {
46404
46426
  const normalized = requestedCwd.trim();
46405
- const ahchatSuffix = this.extractAhchatWorkspaceSuffix(normalized);
46427
+ const ahchatSuffix = extractAhchatWorkspaceSuffix(normalized);
46406
46428
  if (ahchatSuffix) {
46407
- return path8.join(this.workspacesDir, ahchatSuffix);
46429
+ return path9.join(this.workspacesDir, ahchatSuffix);
46408
46430
  }
46409
- const basename = normalized ? path8.basename(path8.normalize(normalized)) : "";
46410
- const suffix = basename && basename !== "." && basename !== path8.sep ? basename : scope.kind === "group" ? `Group-${scope.groupId}` : agentConfig.id;
46411
- return path8.join(this.workspacesDir, suffix);
46431
+ const basename = normalized ? path9.basename(path9.normalize(normalized)) : "";
46432
+ const suffix = basename && basename !== "." && basename !== path9.sep ? basename : scope.kind === "group" ? `Group-${scope.groupId}` : agentConfig.id;
46433
+ return path9.join(this.workspacesDir, suffix);
46412
46434
  }
46413
46435
  remapServerWorkspaceCwd(agentConfig, scope, requestedCwd) {
46414
- const remapped = this.fallbackCwd(agentConfig, scope, requestedCwd);
46415
- const normalizedRequested = path8.normalize(requestedCwd);
46416
- const normalizedRemapped = path8.normalize(remapped);
46417
- if (this.extractAhchatWorkspaceSuffix(requestedCwd) && normalizedRequested !== normalizedRemapped) {
46436
+ const remapped = remapServerWorkspacePath(requestedCwd, this.workspacesDir);
46437
+ if (remapped.remapped) {
46418
46438
  logger10.info("Server working directory remapped to local Bridge workspace", {
46419
46439
  agentId: agentConfig.id,
46420
46440
  scope: scopeKey(scope),
46421
46441
  requested: requestedCwd,
46422
- remapped
46442
+ remapped: remapped.path
46423
46443
  });
46424
- return remapped;
46444
+ return remapped.path;
46425
46445
  }
46426
46446
  return requestedCwd;
46427
46447
  }
@@ -46662,12 +46682,12 @@ var AgentManager = class {
46662
46682
  const agentCwd = await this.resolveRuntimeCwd(agentConfig, scope, cwd);
46663
46683
  const cfg = await this.resolveAgentConfig(agentConfig);
46664
46684
  if (cfg.instructions?.trim()) {
46665
- await fs4.writeFile(path8.join(agentCwd, "CLAUDE.md"), cfg.instructions.trim(), "utf-8");
46685
+ await fs4.writeFile(path9.join(agentCwd, "CLAUDE.md"), cfg.instructions.trim(), "utf-8");
46666
46686
  logger10.info("CLAUDE.md written", { agentId: agentConfig.id, bytes: cfg.instructions.trim().length });
46667
46687
  }
46668
46688
  let effectiveConfigDir = this.agentConfigDir;
46669
46689
  if (cfg.subscriptionType !== "system" && cfg.apiKey) {
46670
- effectiveConfigDir = path8.join(this.agentConfigDir, "api-key-agents", agentConfig.id);
46690
+ effectiveConfigDir = path9.join(this.agentConfigDir, "api-key-agents", agentConfig.id);
46671
46691
  let isNew = false;
46672
46692
  try {
46673
46693
  await fs4.access(effectiveConfigDir);
@@ -46680,7 +46700,7 @@ var AgentManager = class {
46680
46700
  this.dispatchMemory.deleteScope(agentConfig.id, scope);
46681
46701
  logger10.info("New API-key agent config dir; cleared stale session", { agentId: agentConfig.id });
46682
46702
  }
46683
- const settingsPath = path8.join(effectiveConfigDir, "settings.json");
46703
+ const settingsPath = path9.join(effectiveConfigDir, "settings.json");
46684
46704
  const envEntries = {};
46685
46705
  if (cfg.apiKey) envEntries.ANTHROPIC_API_KEY = cfg.apiKey;
46686
46706
  if (cfg.apiBaseUrl) envEntries.ANTHROPIC_BASE_URL = cfg.apiBaseUrl;
@@ -46987,7 +47007,7 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
46987
47007
  settings: (() => {
46988
47008
  const isolated = cfg.subscriptionType === "project" && Boolean(cfg.apiKey ?? cfg.apiBaseUrl);
46989
47009
  if (!isolated) return void 0;
46990
- return path8.join(effectiveConfigDir, "settings.json");
47010
+ return path9.join(effectiveConfigDir, "settings.json");
46991
47011
  })(),
46992
47012
  canUseTool: async (toolName, input) => {
46993
47013
  if (toolName === "AskUserQuestion") {
@@ -47061,7 +47081,7 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
47061
47081
  if (isRunningAsRoot()) {
47062
47082
  await chownForRootSpawn(effectiveConfigDir, "configDir");
47063
47083
  await chownForRootSpawn(agentCwd, "agentCwd");
47064
- const settingsFilePath = path8.join(effectiveConfigDir, "settings.json");
47084
+ const settingsFilePath = path9.join(effectiveConfigDir, "settings.json");
47065
47085
  await chownForRootSpawn(settingsFilePath, "settingsFile");
47066
47086
  options.spawnClaudeCodeProcess = (spawnOptions) => {
47067
47087
  const env2 = { ...spawnOptions.env, HOME: "/home/node" };
@@ -47228,7 +47248,7 @@ ${trimmed}`;
47228
47248
  lines.push(` workdir: ${currentCwd}`);
47229
47249
  } else {
47230
47250
  const a = this.agentRegistry?.getById(agentId);
47231
- const singleCwd = a?.workingDirectory || path8.join(this.workspacesDir, agentId);
47251
+ const singleCwd = a?.workingDirectory || path9.join(this.workspacesDir, agentId);
47232
47252
  lines.push(` workdir: ${singleCwd}`);
47233
47253
  }
47234
47254
  let rosterCount = 0;
@@ -47240,7 +47260,7 @@ ${trimmed}`;
47240
47260
  if (key === curKey) {
47241
47261
  lines.push(` workdir: ${currentCwd}`);
47242
47262
  } else {
47243
- const groupCwd = g2.workingDirectory || path8.join(this.workspacesDir, g2.groupId);
47263
+ const groupCwd = g2.workingDirectory || path9.join(this.workspacesDir, g2.groupId);
47244
47264
  lines.push(` workdir: ${groupCwd}`);
47245
47265
  }
47246
47266
  const others = g2.members.filter((id) => id !== agentId).map((id) => {
@@ -47691,14 +47711,14 @@ ${lines.join("\n")}`;
47691
47711
  }
47692
47712
  async materializeAttachment(runtime, attachment, buffer) {
47693
47713
  const safeFileName = this.safeAttachmentFileName(attachment.fileName);
47694
- const dir = path8.join(runtime.cwd, ".ahchat-attachments", attachment.id);
47714
+ const dir = path9.join(runtime.cwd, ".ahchat-attachments", attachment.id);
47695
47715
  await fs4.mkdir(dir, { recursive: true });
47696
- const filePath = path8.join(dir, safeFileName);
47716
+ const filePath = path9.join(dir, safeFileName);
47697
47717
  await fs4.writeFile(filePath, buffer);
47698
47718
  return filePath;
47699
47719
  }
47700
47720
  safeAttachmentFileName(fileName) {
47701
- const baseName = path8.basename(fileName).replace(/[\0/:\\]/g, "_").trim();
47721
+ const baseName = path9.basename(fileName).replace(/[\0/:\\]/g, "_").trim();
47702
47722
  return baseName || "attachment";
47703
47723
  }
47704
47724
  /**
@@ -47713,7 +47733,7 @@ ${lines.join("\n")}`;
47713
47733
  async detectVisionSupport() {
47714
47734
  if (process.env.ANTHROPIC_BASE_URL) return false;
47715
47735
  try {
47716
- const settingsPath = path8.join(os5.homedir(), ".claude", "settings.json");
47736
+ const settingsPath = path9.join(os5.homedir(), ".claude", "settings.json");
47717
47737
  const raw = await fs4.readFile(settingsPath, "utf-8");
47718
47738
  const parsed = JSON.parse(raw);
47719
47739
  if (parsed.env?.ANTHROPIC_BASE_URL) return false;
@@ -48079,7 +48099,7 @@ ${lines.join("\n")}`;
48079
48099
  }
48080
48100
  cwd = payload.targetCwd;
48081
48101
  } else {
48082
- cwd = agentConfig.workingDirectory || path8.join(this.workspacesDir, agentConfig.id);
48102
+ cwd = agentConfig.workingDirectory || path9.join(this.workspacesDir, agentConfig.id);
48083
48103
  }
48084
48104
  void this.acquire(agentConfig, targetScope, cwd).then(() => {
48085
48105
  logger10.info("Neural send new runtime acquired", {
@@ -48185,7 +48205,7 @@ ${lines.join("\n")}`;
48185
48205
  conversationId,
48186
48206
  traceId
48187
48207
  });
48188
- const cwd = newAgent.workingDirectory || path8.join(this.workspacesDir, newAgent.id);
48208
+ const cwd = newAgent.workingDirectory || path9.join(this.workspacesDir, newAgent.id);
48189
48209
  const scope = { kind: "single" };
48190
48210
  try {
48191
48211
  await this.acquire(newAgent, scope, cwd);
@@ -48467,12 +48487,12 @@ ${lines.join("\n")}`;
48467
48487
  break;
48468
48488
  }
48469
48489
  try {
48470
- let cwd = agent.workingDirectory || path8.join(this.workspacesDir, agent.id);
48490
+ let cwd = agent.workingDirectory || path9.join(this.workspacesDir, agent.id);
48471
48491
  if (agent.workingDirectory) {
48472
48492
  try {
48473
48493
  await fs4.mkdir(cwd, { recursive: true });
48474
48494
  } catch {
48475
- cwd = path8.join(this.workspacesDir, agent.id);
48495
+ cwd = path9.join(this.workspacesDir, agent.id);
48476
48496
  logger10.warn("Stored workingDirectory inaccessible, falling back", {
48477
48497
  agentId: agent.id,
48478
48498
  stored: agent.workingDirectory,
@@ -48945,8 +48965,8 @@ var HttpAgentRegistry = class {
48945
48965
  agents = /* @__PURE__ */ new Map();
48946
48966
  apiUrl(suffix) {
48947
48967
  const base = this.serverApiUrl.replace(/\/$/, "");
48948
- const path20 = suffix.startsWith("/") ? suffix : `/${suffix}`;
48949
- return `${base}${path20}`;
48968
+ const path21 = suffix.startsWith("/") ? suffix : `/${suffix}`;
48969
+ return `${base}${path21}`;
48950
48970
  }
48951
48971
  async refresh() {
48952
48972
  const attempt = async () => {
@@ -49037,8 +49057,8 @@ var HttpSubscriptionRegistry = class {
49037
49057
  subscriptions = /* @__PURE__ */ new Map();
49038
49058
  apiUrl(suffix) {
49039
49059
  const base = this.serverApiUrl.replace(/\/$/, "");
49040
- const path20 = suffix.startsWith("/") ? suffix : `/${suffix}`;
49041
- return `${base}${path20}`;
49060
+ const path21 = suffix.startsWith("/") ? suffix : `/${suffix}`;
49061
+ return `${base}${path21}`;
49042
49062
  }
49043
49063
  async refresh() {
49044
49064
  const attempt = async () => {
@@ -49521,7 +49541,7 @@ var ServerConnector = class {
49521
49541
  // src/contextDumper.ts
49522
49542
  import fs5 from "fs/promises";
49523
49543
  import os7 from "os";
49524
- import path9 from "path";
49544
+ import path10 from "path";
49525
49545
  var logger16 = createModuleLogger("bridge.contextDumper");
49526
49546
  var TRUNCATE_THRESHOLD = 5e4;
49527
49547
  var TRUNCATE_HEAD = 8e3;
@@ -49550,7 +49570,7 @@ function cwdToProjectSlug(cwd) {
49550
49570
  }
49551
49571
  function resolveJsonlPath(sessionId, cwd) {
49552
49572
  const slug = cwdToProjectSlug(cwd);
49553
- return path9.join(os7.homedir(), ".claude", "projects", slug, `${sessionId}.jsonl`);
49573
+ return path10.join(os7.homedir(), ".claude", "projects", slug, `${sessionId}.jsonl`);
49554
49574
  }
49555
49575
  var RENDERABLE_TYPES = /* @__PURE__ */ new Set(["user", "assistant", "system", "attachment"]);
49556
49576
  async function readJsonlEntries(filePath) {
@@ -49810,7 +49830,7 @@ async function dumpAgentContext(agentId, deps) {
49810
49830
  if (!workdir) {
49811
49831
  return { ok: false, files: [], scopeErrors: [], error: "agent has no working directory" };
49812
49832
  }
49813
- const dumpDir = path9.join(workdir, "sessioninfo");
49833
+ const dumpDir = path10.join(workdir, "sessioninfo");
49814
49834
  await fs5.mkdir(dumpDir, { recursive: true });
49815
49835
  const prefix = `${agentId}::`;
49816
49836
  const scopeEntries = [];
@@ -49880,7 +49900,7 @@ async function dumpAgentContext(agentId, deps) {
49880
49900
  jsonlPath
49881
49901
  });
49882
49902
  const filename = scopeFilename(agent.name, scopeKey2, groupName);
49883
- const filePath = path9.join(dumpDir, filename);
49903
+ const filePath = path10.join(dumpDir, filename);
49884
49904
  await fs5.writeFile(filePath, html, "utf-8");
49885
49905
  dumpedFiles.push(filename);
49886
49906
  const stat3 = await fs5.stat(filePath);
@@ -49921,7 +49941,7 @@ async function dumpAgentContext(agentId, deps) {
49921
49941
 
49922
49942
  // src/listDir.ts
49923
49943
  import fs6 from "fs/promises";
49924
- import path10 from "path";
49944
+ import path11 from "path";
49925
49945
  var logger17 = createModuleLogger("bridge.listDir");
49926
49946
  function shouldIncludeEntry(name) {
49927
49947
  if (!name.startsWith(".")) return true;
@@ -49933,7 +49953,7 @@ async function listDirectoryEntries(dirPath) {
49933
49953
  const entries = [];
49934
49954
  for (const entry of raw) {
49935
49955
  if (!shouldIncludeEntry(entry.name)) continue;
49936
- const fullPath = path10.join(dirPath, entry.name);
49956
+ const fullPath = path11.join(dirPath, entry.name);
49937
49957
  const isDir = entry.isDirectory();
49938
49958
  let size;
49939
49959
  let mtime;
@@ -49961,7 +49981,7 @@ async function listDirectoryEntries(dirPath) {
49961
49981
 
49962
49982
  // src/logScanner.ts
49963
49983
  import fs7 from "fs";
49964
- import path11 from "path";
49984
+ import path12 from "path";
49965
49985
  import os8 from "os";
49966
49986
  import readline from "readline";
49967
49987
  var logger18 = createModuleLogger("bridge.logScanner");
@@ -49976,10 +49996,10 @@ function listLogFiles(logsDir, baseName) {
49976
49996
  return [];
49977
49997
  }
49978
49998
  const pattern = new RegExp(`^${baseName.replace(".", "\\.")}(\\.\\d+)?$`);
49979
- return names.filter((n2) => pattern.test(n2)).map((n2) => path11.join(logsDir, n2));
49999
+ return names.filter((n2) => pattern.test(n2)).map((n2) => path12.join(logsDir, n2));
49980
50000
  }
49981
50001
  async function scanFile(filePath, source, filter, limit, state) {
49982
- const file2 = path11.basename(filePath);
50002
+ const file2 = path12.basename(filePath);
49983
50003
  const stream = fs7.createReadStream(filePath, { encoding: "utf-8" });
49984
50004
  const rl2 = readline.createInterface({ input: stream, crlfDelay: Infinity });
49985
50005
  let lineNum = 0;
@@ -50018,7 +50038,7 @@ async function scanLocalLogs(logsDir, baseName, filter) {
50018
50038
  };
50019
50039
  }
50020
50040
  async function scanBridgeLogs(filter) {
50021
- const logDir = path11.join(os8.homedir(), ".ahchat", "logs");
50041
+ const logDir = path12.join(os8.homedir(), ".ahchat", "logs");
50022
50042
  logger18.info("scanBridgeLogs start", {
50023
50043
  logDir,
50024
50044
  startIso: filter.startIso,
@@ -50036,13 +50056,13 @@ async function scanBridgeLogs(filter) {
50036
50056
 
50037
50057
  // src/skillStore.ts
50038
50058
  import fs8 from "fs";
50039
- import path12 from "path";
50059
+ import path13 from "path";
50040
50060
  var logger19 = createModuleLogger("bridge.skillStore");
50041
50061
  var ALLOWED_NAMES = /* @__PURE__ */ new Set(["log-analysis"]);
50042
50062
  var SkillStore = class {
50043
50063
  skillsDir;
50044
50064
  constructor(dataDir) {
50045
- this.skillsDir = path12.join(dataDir, "skills");
50065
+ this.skillsDir = path13.join(dataDir, "skills");
50046
50066
  fs8.mkdirSync(this.skillsDir, { recursive: true });
50047
50067
  logger19.info("SkillStore initialized", { skillsDir: this.skillsDir });
50048
50068
  }
@@ -50051,7 +50071,7 @@ var SkillStore = class {
50051
50071
  logger19.warn("Skill read: unknown name", { name, allowed: [...ALLOWED_NAMES] });
50052
50072
  return "";
50053
50073
  }
50054
- const filePath = path12.join(this.skillsDir, `${name}.md`);
50074
+ const filePath = path13.join(this.skillsDir, `${name}.md`);
50055
50075
  try {
50056
50076
  const content = fs8.readFileSync(filePath, "utf-8");
50057
50077
  logger19.info("Skill read", { name, bytes: content.length });
@@ -50066,7 +50086,7 @@ var SkillStore = class {
50066
50086
  if (!ALLOWED_NAMES.has(name)) {
50067
50087
  throw new Error(`Unknown skill name: ${name}`);
50068
50088
  }
50069
- const filePath = path12.join(this.skillsDir, `${name}.md`);
50089
+ const filePath = path13.join(this.skillsDir, `${name}.md`);
50070
50090
  const tmpPath = `${filePath}.tmp`;
50071
50091
  let existing = "";
50072
50092
  try {
@@ -50089,7 +50109,7 @@ var SkillStore = class {
50089
50109
 
50090
50110
  // src/lockfile.ts
50091
50111
  import fs9 from "fs";
50092
- import path13 from "path";
50112
+ import path14 from "path";
50093
50113
  var logger20 = createModuleLogger("bridge.lockfile");
50094
50114
  var lockPath = null;
50095
50115
  function isProcessAlive(pid) {
@@ -50103,7 +50123,7 @@ function isProcessAlive(pid) {
50103
50123
  }
50104
50124
  }
50105
50125
  function acquireLock(dataDir) {
50106
- const file2 = path13.join(dataDir, "bridge.lock");
50126
+ const file2 = path14.join(dataDir, "bridge.lock");
50107
50127
  lockPath = file2;
50108
50128
  if (fs9.existsSync(file2)) {
50109
50129
  const raw = fs9.readFileSync(file2, "utf-8").trim();
@@ -50115,7 +50135,7 @@ function acquireLock(dataDir) {
50115
50135
  logger20.warn("Removing stale bridge.lock (process not found)", { pid, path: file2 });
50116
50136
  }
50117
50137
  }
50118
- fs9.mkdirSync(path13.dirname(file2), { recursive: true });
50138
+ fs9.mkdirSync(path14.dirname(file2), { recursive: true });
50119
50139
  fs9.writeFileSync(file2, String(process.pid), "utf-8");
50120
50140
  logger20.info("Acquired bridge lock", { path: file2, pid: process.pid });
50121
50141
  const release = () => {
@@ -50479,13 +50499,13 @@ async function handleGroupArchivedPush(deps, payload) {
50479
50499
 
50480
50500
  // src/sessionStore.ts
50481
50501
  import fs10 from "fs";
50482
- import path14 from "path";
50502
+ import path15 from "path";
50483
50503
  var logger23 = createModuleLogger("session.store");
50484
50504
  var SessionStore = class {
50485
50505
  filePath;
50486
50506
  cache;
50487
50507
  constructor(dataDir) {
50488
- this.filePath = path14.join(dataDir, "sessions.json");
50508
+ this.filePath = path15.join(dataDir, "sessions.json");
50489
50509
  this.cache = this.loadFromDisk();
50490
50510
  }
50491
50511
  cacheKey(agentId, scope) {
@@ -50545,7 +50565,7 @@ var SessionStore = class {
50545
50565
  }
50546
50566
  saveToDisk() {
50547
50567
  try {
50548
- const dir = path14.dirname(this.filePath);
50568
+ const dir = path15.dirname(this.filePath);
50549
50569
  fs10.mkdirSync(dir, { recursive: true });
50550
50570
  fs10.writeFileSync(this.filePath, JSON.stringify(this.cache, null, 2), "utf-8");
50551
50571
  } catch (e7) {
@@ -50711,20 +50731,20 @@ async function ensureClaudeCli() {
50711
50731
 
50712
50732
  // src/forkAgentFiles.ts
50713
50733
  import * as fs11 from "fs/promises";
50714
- import * as path16 from "path";
50734
+ import * as path17 from "path";
50715
50735
 
50716
50736
  // src/sessionSlug.ts
50717
50737
  import os9 from "os";
50718
- import path15 from "path";
50719
- var CLAUDE_PROJECTS_DIR = path15.join(os9.homedir(), ".claude", "projects");
50738
+ import path16 from "path";
50739
+ var CLAUDE_PROJECTS_DIR = path16.join(os9.homedir(), ".claude", "projects");
50720
50740
  function cwdToSlug(cwd) {
50721
50741
  return cwd.replace(/[^a-zA-Z0-9-]/g, "-");
50722
50742
  }
50723
50743
  function sessionDirForCwd(cwd) {
50724
- return path15.join(CLAUDE_PROJECTS_DIR, cwdToSlug(cwd));
50744
+ return path16.join(CLAUDE_PROJECTS_DIR, cwdToSlug(cwd));
50725
50745
  }
50726
50746
  function sessionFilePath(cwd, sessionId) {
50727
- return path15.join(sessionDirForCwd(cwd), `${sessionId}.jsonl`);
50747
+ return path16.join(sessionDirForCwd(cwd), `${sessionId}.jsonl`);
50728
50748
  }
50729
50749
 
50730
50750
  // src/forkAgentFiles.ts
@@ -50756,9 +50776,9 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
50756
50776
  logger25.error("Workdir copy failed", { error: e7 });
50757
50777
  throw e7;
50758
50778
  }
50759
- const srcNotebook = path16.join(dataDir, "agent-memory", sourceAgentId, "notebook.md");
50760
- const dstNotebookDir = path16.join(dataDir, "agent-memory", newAgentId);
50761
- const dstNotebook = path16.join(dstNotebookDir, "notebook.md");
50779
+ const srcNotebook = path17.join(dataDir, "agent-memory", sourceAgentId, "notebook.md");
50780
+ const dstNotebookDir = path17.join(dataDir, "agent-memory", newAgentId);
50781
+ const dstNotebook = path17.join(dstNotebookDir, "notebook.md");
50762
50782
  try {
50763
50783
  const nbStat = await fs11.stat(srcNotebook).catch(() => null);
50764
50784
  if (nbStat?.isFile()) {
@@ -50785,7 +50805,7 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
50785
50805
  if (srcStat?.isFile()) {
50786
50806
  const dstDir = sessionDirForCwd(newWorkdir);
50787
50807
  await fs11.mkdir(dstDir, { recursive: true });
50788
- const dstPath = path16.join(dstDir, `${sourceSessionId}.jsonl`);
50808
+ const dstPath = path17.join(dstDir, `${sourceSessionId}.jsonl`);
50789
50809
  await fs11.copyFile(srcPath, dstPath);
50790
50810
  sessionStore.set(newAgentId, { kind: "single" }, sourceSessionId);
50791
50811
  sessionCopied = true;
@@ -50833,11 +50853,11 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
50833
50853
  // src/modelQuerier.ts
50834
50854
  import fs12 from "fs/promises";
50835
50855
  import os10 from "os";
50836
- import path17 from "path";
50856
+ import path18 from "path";
50837
50857
  var logger26 = createModuleLogger("bridge.modelQuerier");
50838
50858
  async function listModels(queryFn, opts = {}) {
50839
50859
  const t0 = Date.now();
50840
- const cwd = opts.cwd ?? path17.join(os10.homedir(), ".ahchat", "workspaces", "_list_models");
50860
+ const cwd = opts.cwd ?? path18.join(os10.homedir(), ".ahchat", "workspaces", "_list_models");
50841
50861
  await fs12.mkdir(cwd, { recursive: true });
50842
50862
  const fn = queryFn ?? QA$;
50843
50863
  const ic2 = new InputController();
@@ -50900,7 +50920,7 @@ async function listModels(queryFn, opts = {}) {
50900
50920
  // src/promptOptimizer.ts
50901
50921
  import fs13 from "fs/promises";
50902
50922
  import os11 from "os";
50903
- import path18 from "path";
50923
+ import path19 from "path";
50904
50924
  var logger27 = createModuleLogger("bridge.promptOptimizer");
50905
50925
  var OPTIMIZER_SYSTEM_PROMPT = `You are an expert prompt editor for AHChat Agent creation.
50906
50926
 
@@ -50943,7 +50963,7 @@ async function optimizePrompt(queryFn, opts) {
50943
50963
  const prompt = opts.systemPrompt.trim();
50944
50964
  if (!prompt) throw new Error("systemPrompt is required");
50945
50965
  const t0 = Date.now();
50946
- const cwd = opts.cwd ?? path18.join(os11.homedir(), ".ahchat", "workspaces", "_prompt_optimizer");
50966
+ const cwd = opts.cwd ?? path19.join(os11.homedir(), ".ahchat", "workspaces", "_prompt_optimizer");
50947
50967
  await fs13.mkdir(cwd, { recursive: true });
50948
50968
  const fn = queryFn ?? QA$;
50949
50969
  const ic2 = new InputController();
@@ -51031,7 +51051,7 @@ function isRunningAsRoot2() {
51031
51051
  }
51032
51052
  }
51033
51053
  async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
51034
- const rootClaudeDir = path19.join(process.env.HOME ?? "/root", ".claude");
51054
+ const rootClaudeDir = path20.join(process.env.HOME ?? "/root", ".claude");
51035
51055
  const fs14 = await import("fs/promises");
51036
51056
  try {
51037
51057
  await fs14.access(rootClaudeDir);
@@ -51041,8 +51061,8 @@ async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
51041
51061
  }
51042
51062
  const filesToSync = [".credentials.json", "settings.json", ".credentials.backup.json"];
51043
51063
  for (const file2 of filesToSync) {
51044
- const src = path19.join(rootClaudeDir, file2);
51045
- const dest = path19.join(agentConfigDir, file2);
51064
+ const src = path20.join(rootClaudeDir, file2);
51065
+ const dest = path20.join(agentConfigDir, file2);
51046
51066
  try {
51047
51067
  await fs14.copyFile(src, dest);
51048
51068
  logger28.info("Synced credential file", { file: file2, from: src, to: dest });
@@ -51065,7 +51085,7 @@ async function chownRecursive(dirPath, uid, gid) {
51065
51085
  return;
51066
51086
  }
51067
51087
  for (const entry of entries) {
51068
- const fullPath = path19.join(dirPath, entry.name);
51088
+ const fullPath = path20.join(dirPath, entry.name);
51069
51089
  if (entry.isDirectory()) {
51070
51090
  await chownRecursive(fullPath, uid, gid);
51071
51091
  } else {
@@ -51080,7 +51100,7 @@ async function chownRecursive(dirPath, uid, gid) {
51080
51100
  async function startBridge(config2) {
51081
51101
  ensureDir(config2.dataDir);
51082
51102
  ensureDir(config2.agentConfigDir);
51083
- const workspacesDir = path19.join(config2.dataDir, "workspaces");
51103
+ const workspacesDir = path20.join(config2.dataDir, "workspaces");
51084
51104
  ensureDir(workspacesDir);
51085
51105
  process.env.CLAUDE_CONFIG_DIR = config2.agentConfigDir;
51086
51106
  installBridgeFetchAuth(config2.serverApiUrl, config2.bridgeToken);
@@ -51109,7 +51129,7 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
51109
51129
  `);
51110
51130
  wsMetrics.start(5e3);
51111
51131
  const sessionStore = new SessionStore(config2.dataDir);
51112
- const memoryRoot = path19.join(config2.dataDir, "agent-memory");
51132
+ const memoryRoot = path20.join(config2.dataDir, "agent-memory");
51113
51133
  const memoryStore = new AgentMemoryStore(memoryRoot);
51114
51134
  logger28.info("Agent memory store initialized", { rootDir: memoryRoot });
51115
51135
  const smithNotebook = memoryStore.read(SMITH_AGENT_ID);
@@ -51286,7 +51306,16 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
51286
51306
  const { requestId, path: dirPath } = msg.payload;
51287
51307
  logger28.info("list_dir request received", { requestId, path: dirPath });
51288
51308
  try {
51289
- const entries = await listDirectoryEntries(dirPath);
51309
+ const resolved = remapServerWorkspacePath(dirPath, workspacesDir);
51310
+ if (resolved.remapped) {
51311
+ ensureDir(resolved.path);
51312
+ logger28.info("list_dir path remapped to local Bridge workspace", {
51313
+ requestId,
51314
+ requested: dirPath,
51315
+ remapped: resolved.path
51316
+ });
51317
+ }
51318
+ const entries = await listDirectoryEntries(resolved.path);
51290
51319
  connector?.send({
51291
51320
  type: "bridge:list_dir_response",
51292
51321
  payload: { requestId, entries }