@fangyb/ahchat-bridge 0.1.20 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +616 -297
- package/dist/index.js +341 -181
- package/package.json +11 -11
- package/dist/cli.js +0 -51540
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:
|
|
4463
|
+
const { encoding, history, maxFiles, maxSize, path: path22 } = options;
|
|
4464
4464
|
super({ decodeStrings: true, defaultEncoding: encoding });
|
|
4465
4465
|
this.createGzip = createGzip;
|
|
4466
4466
|
this.exec = exec;
|
|
4467
|
-
this.filename =
|
|
4467
|
+
this.filename = path22 + 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 =
|
|
4479
|
+
options.history = path22 + (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:
|
|
4607
|
+
const { interval, path: path22, intervalBoundary } = this.options;
|
|
4608
4608
|
for (let index = 1; index < 1e3; ++index) {
|
|
4609
|
-
const filename =
|
|
4609
|
+
const filename = path22 + 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:
|
|
4639
|
+
const { compress, path: path22, rotate } = this.options;
|
|
4640
4640
|
let rotatedName = "";
|
|
4641
4641
|
for (let count = rotate; count > 0; --count) {
|
|
4642
|
-
const currName =
|
|
4643
|
-
const prevName = count === 1 ? this.filename :
|
|
4642
|
+
const currName = path22 + this.generator(count);
|
|
4643
|
+
const prevName = count === 1 ? this.filename : path22 + 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
|
|
5080
|
+
import path21 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
|
|
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,
|
|
29041
|
-
if (!
|
|
29040
|
+
function getElementAtPath(obj, path22) {
|
|
29041
|
+
if (!path22)
|
|
29042
29042
|
return obj;
|
|
29043
|
-
return
|
|
29043
|
+
return path22.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(
|
|
29452
|
+
function prefixIssues(path22, issues) {
|
|
29453
29453
|
return issues.map((iss) => {
|
|
29454
29454
|
var _a3;
|
|
29455
29455
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
29456
|
-
iss.path.unshift(
|
|
29456
|
+
iss.path.unshift(path22);
|
|
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,
|
|
29603
|
+
const processError = (error52, path22 = []) => {
|
|
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 }, [...
|
|
29606
|
+
issue2.errors.map((issues) => processError({ issues }, [...path22, ...issue2.path]));
|
|
29607
29607
|
} else if (issue2.code === "invalid_key") {
|
|
29608
|
-
processError({ issues: issue2.issues }, [...
|
|
29608
|
+
processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
|
|
29609
29609
|
} else if (issue2.code === "invalid_element") {
|
|
29610
|
-
processError({ issues: issue2.issues }, [...
|
|
29610
|
+
processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
|
|
29611
29611
|
} else {
|
|
29612
|
-
const fullpath = [...
|
|
29612
|
+
const fullpath = [...path22, ...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,
|
|
29639
|
+
const processError = (error52, path22 = []) => {
|
|
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 }, [...
|
|
29643
|
+
issue2.errors.map((issues) => processError({ issues }, [...path22, ...issue2.path]));
|
|
29644
29644
|
} else if (issue2.code === "invalid_key") {
|
|
29645
|
-
processError({ issues: issue2.issues }, [...
|
|
29645
|
+
processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
|
|
29646
29646
|
} else if (issue2.code === "invalid_element") {
|
|
29647
|
-
processError({ issues: issue2.issues }, [...
|
|
29647
|
+
processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
|
|
29648
29648
|
} else {
|
|
29649
|
-
const fullpath = [...
|
|
29649
|
+
const fullpath = [...path22, ...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
|
|
29682
|
-
for (const seg of
|
|
29681
|
+
const path22 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
29682
|
+
for (const seg of path22) {
|
|
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
|
|
42375
|
-
if (
|
|
42374
|
+
const path22 = ref.slice(1).split("/").filter(Boolean);
|
|
42375
|
+
if (path22.length === 0) {
|
|
42376
42376
|
return ctx.rootSchema;
|
|
42377
42377
|
}
|
|
42378
42378
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
42379
|
-
if (
|
|
42380
|
-
const key =
|
|
42379
|
+
if (path22[0] === defsKey) {
|
|
42380
|
+
const key = path22[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 =
|
|
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 =
|
|
46342
|
-
this.agentConfigDir =
|
|
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 =
|
|
46399
|
+
this.dataDir = path9.join(os5.homedir(), ".ahchat");
|
|
46354
46400
|
} else {
|
|
46355
46401
|
this.queryFn = options?.queryFn ?? null;
|
|
46356
|
-
this.workspacesDir = options?.workspacesDir ??
|
|
46357
|
-
this.agentConfigDir = options?.agentConfigDir ??
|
|
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 ??
|
|
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 =
|
|
46427
|
+
const ahchatSuffix = extractAhchatWorkspaceSuffix(normalized);
|
|
46406
46428
|
if (ahchatSuffix) {
|
|
46407
|
-
return
|
|
46429
|
+
return path9.join(this.workspacesDir, ahchatSuffix);
|
|
46408
46430
|
}
|
|
46409
|
-
const basename = normalized ?
|
|
46410
|
-
const suffix = basename && basename !== "." && basename !==
|
|
46411
|
-
return
|
|
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 =
|
|
46415
|
-
|
|
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(
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 ||
|
|
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 ||
|
|
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 =
|
|
47714
|
+
const dir = path9.join(runtime.cwd, ".ahchat-attachments", attachment.id);
|
|
47695
47715
|
await fs4.mkdir(dir, { recursive: true });
|
|
47696
|
-
const filePath =
|
|
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 =
|
|
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 =
|
|
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 ||
|
|
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 ||
|
|
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 ||
|
|
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 =
|
|
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
|
|
48949
|
-
return `${base}${
|
|
48968
|
+
const path22 = suffix.startsWith("/") ? suffix : `/${suffix}`;
|
|
48969
|
+
return `${base}${path22}`;
|
|
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
|
|
49041
|
-
return `${base}${
|
|
49060
|
+
const path22 = suffix.startsWith("/") ? suffix : `/${suffix}`;
|
|
49061
|
+
return `${base}${path22}`;
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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,19 +49941,160 @@ async function dumpAgentContext(agentId, deps) {
|
|
|
49921
49941
|
|
|
49922
49942
|
// src/listDir.ts
|
|
49923
49943
|
import fs6 from "fs/promises";
|
|
49924
|
-
import
|
|
49944
|
+
import path12 from "path";
|
|
49945
|
+
|
|
49946
|
+
// src/runtimeEnv.ts
|
|
49947
|
+
import { execFileSync } from "child_process";
|
|
49948
|
+
import { accessSync, constants as constants2, existsSync as existsSync2, readdirSync as readdirSync2 } from "fs";
|
|
49949
|
+
import os8 from "os";
|
|
49950
|
+
import path11 from "path";
|
|
49951
|
+
function getHomeDir() {
|
|
49952
|
+
return process.env.USERPROFILE || os8.homedir();
|
|
49953
|
+
}
|
|
49954
|
+
function splitPath(value) {
|
|
49955
|
+
if (!value) return [];
|
|
49956
|
+
return value.split(path11.delimiter).filter((entry) => entry.length > 0);
|
|
49957
|
+
}
|
|
49958
|
+
function uniq(values) {
|
|
49959
|
+
return [...new Set(values.filter(Boolean))];
|
|
49960
|
+
}
|
|
49961
|
+
function joinHomePath(home, suffix) {
|
|
49962
|
+
const parts = suffix.split(/[\\/]+/).filter((part) => part.length > 0);
|
|
49963
|
+
return path11.join(home, ...parts);
|
|
49964
|
+
}
|
|
49965
|
+
function sortNodeVersionDirsDesc(names) {
|
|
49966
|
+
return [...names].sort((a, b2) => {
|
|
49967
|
+
const aParts = a.replace(/^v/, "").split(".").map((p) => Number.parseInt(p, 10) || 0);
|
|
49968
|
+
const bParts = b2.replace(/^v/, "").split(".").map((p) => Number.parseInt(p, 10) || 0);
|
|
49969
|
+
for (let i = 0; i < Math.max(aParts.length, bParts.length); i += 1) {
|
|
49970
|
+
const delta = (bParts[i] ?? 0) - (aParts[i] ?? 0);
|
|
49971
|
+
if (delta !== 0) return delta;
|
|
49972
|
+
}
|
|
49973
|
+
return b2.localeCompare(a);
|
|
49974
|
+
});
|
|
49975
|
+
}
|
|
49976
|
+
function listNodeVersionBins(root, binSuffix) {
|
|
49977
|
+
if (!existsSync2(root)) return [];
|
|
49978
|
+
try {
|
|
49979
|
+
return sortNodeVersionDirsDesc(readdirSync2(root)).map((version2) => path11.join(root, version2, ...binSuffix)).filter((candidate) => existsSync2(candidate));
|
|
49980
|
+
} catch {
|
|
49981
|
+
return [];
|
|
49982
|
+
}
|
|
49983
|
+
}
|
|
49984
|
+
function getNodeToolExtraPathEntries(env2 = process.env) {
|
|
49985
|
+
const home = getHomeDir();
|
|
49986
|
+
const entries = [];
|
|
49987
|
+
if (process.platform === "win32") {
|
|
49988
|
+
for (const envName of ["NVM_SYMLINK", "NVM_HOME"]) {
|
|
49989
|
+
const value = env2[envName];
|
|
49990
|
+
if (value && existsSync2(value)) entries.push(value);
|
|
49991
|
+
}
|
|
49992
|
+
for (const candidate of [
|
|
49993
|
+
path11.join(home, "AppData", "Roaming", "npm"),
|
|
49994
|
+
path11.join(home, ".volta", "bin"),
|
|
49995
|
+
path11.join(home, ".asdf", "shims"),
|
|
49996
|
+
path11.join(env2.ProgramFiles ?? "C:\\Program Files", "nodejs"),
|
|
49997
|
+
path11.join(env2.LOCALAPPDATA ?? path11.join(home, "AppData", "Local"), "Programs", "nodejs")
|
|
49998
|
+
]) {
|
|
49999
|
+
if (existsSync2(candidate)) entries.push(candidate);
|
|
50000
|
+
}
|
|
50001
|
+
return uniq(entries);
|
|
50002
|
+
}
|
|
50003
|
+
const nvmRoot = env2.NVM_DIR ?? path11.join(home, ".nvm");
|
|
50004
|
+
entries.push(...listNodeVersionBins(path11.join(nvmRoot, "versions", "node"), ["bin"]));
|
|
50005
|
+
const fnmRoots = [
|
|
50006
|
+
path11.join(home, ".fnm", "node-versions"),
|
|
50007
|
+
path11.join(home, ".local", "share", "fnm", "node-versions")
|
|
50008
|
+
];
|
|
50009
|
+
for (const fnmRoot of fnmRoots) {
|
|
50010
|
+
entries.push(...listNodeVersionBins(fnmRoot, ["installation", "bin"]));
|
|
50011
|
+
}
|
|
50012
|
+
for (const candidate of [
|
|
50013
|
+
path11.join(home, ".volta", "bin"),
|
|
50014
|
+
path11.join(home, ".asdf", "shims"),
|
|
50015
|
+
path11.join(home, ".local", "bin"),
|
|
50016
|
+
"/opt/homebrew/bin",
|
|
50017
|
+
"/usr/local/bin"
|
|
50018
|
+
]) {
|
|
50019
|
+
if (existsSync2(candidate)) entries.push(candidate);
|
|
50020
|
+
}
|
|
50021
|
+
return uniq(entries);
|
|
50022
|
+
}
|
|
50023
|
+
function buildAugmentedPath(env2 = process.env) {
|
|
50024
|
+
return uniq([...getNodeToolExtraPathEntries(env2), ...splitPath(env2.PATH)]).join(path11.delimiter);
|
|
50025
|
+
}
|
|
50026
|
+
function withAugmentedPathEnv(env2 = process.env) {
|
|
50027
|
+
return { ...env2, PATH: buildAugmentedPath(env2) };
|
|
50028
|
+
}
|
|
50029
|
+
function executableNames(name) {
|
|
50030
|
+
if (process.platform !== "win32") return [name];
|
|
50031
|
+
if (/\.(cmd|exe|bat)$/i.test(name)) return [name];
|
|
50032
|
+
return [`${name}.cmd`, `${name}.exe`, `${name}.bat`, name];
|
|
50033
|
+
}
|
|
50034
|
+
function canExecute(candidate) {
|
|
50035
|
+
try {
|
|
50036
|
+
if (process.platform === "win32") return existsSync2(candidate);
|
|
50037
|
+
accessSync(candidate, constants2.X_OK);
|
|
50038
|
+
return true;
|
|
50039
|
+
} catch {
|
|
50040
|
+
return false;
|
|
50041
|
+
}
|
|
50042
|
+
}
|
|
50043
|
+
function resolveCommand(names, env2 = process.env) {
|
|
50044
|
+
const pathEntries = splitPath(buildAugmentedPath(env2));
|
|
50045
|
+
for (const entry of pathEntries) {
|
|
50046
|
+
for (const name of names) {
|
|
50047
|
+
for (const executableName of executableNames(name)) {
|
|
50048
|
+
const candidate = path11.join(entry, executableName);
|
|
50049
|
+
if (canExecute(candidate)) return { name, path: candidate };
|
|
50050
|
+
}
|
|
50051
|
+
}
|
|
50052
|
+
}
|
|
50053
|
+
return void 0;
|
|
50054
|
+
}
|
|
50055
|
+
function readCommandVersion(executablePath, args = ["--version"], env2 = process.env) {
|
|
50056
|
+
try {
|
|
50057
|
+
return execFileSync(executablePath, args, {
|
|
50058
|
+
env: withAugmentedPathEnv(env2),
|
|
50059
|
+
timeout: 1e4
|
|
50060
|
+
}).toString().trim();
|
|
50061
|
+
} catch {
|
|
50062
|
+
return void 0;
|
|
50063
|
+
}
|
|
50064
|
+
}
|
|
50065
|
+
function resolveUserPath(input) {
|
|
50066
|
+
const home = getHomeDir();
|
|
50067
|
+
let value = input.trim();
|
|
50068
|
+
if (value === "~") value = home;
|
|
50069
|
+
else if (value.startsWith("~/") || value.startsWith("~\\")) value = joinHomePath(home, value.slice(2));
|
|
50070
|
+
else if (value === "$HOME") value = home;
|
|
50071
|
+
else if (value.startsWith("$HOME/") || value.startsWith("$HOME\\")) value = joinHomePath(home, value.slice(6));
|
|
50072
|
+
else if (value === "${HOME}") value = home;
|
|
50073
|
+
else if (value.startsWith("${HOME}/") || value.startsWith("${HOME}\\")) value = joinHomePath(home, value.slice(8));
|
|
50074
|
+
else if (value === "$env:USERPROFILE") value = home;
|
|
50075
|
+
else if (value.startsWith("$env:USERPROFILE\\") || value.startsWith("$env:USERPROFILE/")) {
|
|
50076
|
+
value = joinHomePath(home, value.slice("$env:USERPROFILE".length + 1));
|
|
50077
|
+
} else if (value === "%USERPROFILE%") value = home;
|
|
50078
|
+
else if (value.startsWith("%USERPROFILE%\\") || value.startsWith("%USERPROFILE%/")) {
|
|
50079
|
+
value = joinHomePath(home, value.slice("%USERPROFILE%".length + 1));
|
|
50080
|
+
}
|
|
50081
|
+
return path11.isAbsolute(value) ? path11.normalize(value) : path11.resolve(value);
|
|
50082
|
+
}
|
|
50083
|
+
|
|
50084
|
+
// src/listDir.ts
|
|
49925
50085
|
var logger17 = createModuleLogger("bridge.listDir");
|
|
49926
50086
|
function shouldIncludeEntry(name) {
|
|
49927
50087
|
if (!name.startsWith(".")) return true;
|
|
49928
50088
|
return name === ".ahchat-attachments";
|
|
49929
50089
|
}
|
|
49930
50090
|
async function listDirectoryEntries(dirPath) {
|
|
49931
|
-
|
|
49932
|
-
|
|
50091
|
+
const resolvedDirPath = resolveUserPath(dirPath);
|
|
50092
|
+
logger17.info("listDirectoryEntries start", { path: dirPath, resolvedPath: resolvedDirPath });
|
|
50093
|
+
const raw = await fs6.readdir(resolvedDirPath, { withFileTypes: true });
|
|
49933
50094
|
const entries = [];
|
|
49934
50095
|
for (const entry of raw) {
|
|
49935
50096
|
if (!shouldIncludeEntry(entry.name)) continue;
|
|
49936
|
-
const fullPath =
|
|
50097
|
+
const fullPath = path12.join(resolvedDirPath, entry.name);
|
|
49937
50098
|
const isDir = entry.isDirectory();
|
|
49938
50099
|
let size;
|
|
49939
50100
|
let mtime;
|
|
@@ -49952,6 +50113,7 @@ async function listDirectoryEntries(dirPath) {
|
|
|
49952
50113
|
});
|
|
49953
50114
|
logger17.info("listDirectoryEntries ok", {
|
|
49954
50115
|
path: dirPath,
|
|
50116
|
+
resolvedPath: resolvedDirPath,
|
|
49955
50117
|
count: entries.length,
|
|
49956
50118
|
dirCount: entries.filter((e7) => e7.type === "dir").length,
|
|
49957
50119
|
fileCount: entries.filter((e7) => e7.type === "file").length
|
|
@@ -49961,8 +50123,8 @@ async function listDirectoryEntries(dirPath) {
|
|
|
49961
50123
|
|
|
49962
50124
|
// src/logScanner.ts
|
|
49963
50125
|
import fs7 from "fs";
|
|
49964
|
-
import
|
|
49965
|
-
import
|
|
50126
|
+
import path13 from "path";
|
|
50127
|
+
import os9 from "os";
|
|
49966
50128
|
import readline from "readline";
|
|
49967
50129
|
var logger18 = createModuleLogger("bridge.logScanner");
|
|
49968
50130
|
var DEFAULT_LIMIT = 500;
|
|
@@ -49976,10 +50138,10 @@ function listLogFiles(logsDir, baseName) {
|
|
|
49976
50138
|
return [];
|
|
49977
50139
|
}
|
|
49978
50140
|
const pattern = new RegExp(`^${baseName.replace(".", "\\.")}(\\.\\d+)?$`);
|
|
49979
|
-
return names.filter((n2) => pattern.test(n2)).map((n2) =>
|
|
50141
|
+
return names.filter((n2) => pattern.test(n2)).map((n2) => path13.join(logsDir, n2));
|
|
49980
50142
|
}
|
|
49981
50143
|
async function scanFile(filePath, source, filter, limit, state) {
|
|
49982
|
-
const file2 =
|
|
50144
|
+
const file2 = path13.basename(filePath);
|
|
49983
50145
|
const stream = fs7.createReadStream(filePath, { encoding: "utf-8" });
|
|
49984
50146
|
const rl2 = readline.createInterface({ input: stream, crlfDelay: Infinity });
|
|
49985
50147
|
let lineNum = 0;
|
|
@@ -50018,7 +50180,7 @@ async function scanLocalLogs(logsDir, baseName, filter) {
|
|
|
50018
50180
|
};
|
|
50019
50181
|
}
|
|
50020
50182
|
async function scanBridgeLogs(filter) {
|
|
50021
|
-
const logDir =
|
|
50183
|
+
const logDir = path13.join(os9.homedir(), ".ahchat", "logs");
|
|
50022
50184
|
logger18.info("scanBridgeLogs start", {
|
|
50023
50185
|
logDir,
|
|
50024
50186
|
startIso: filter.startIso,
|
|
@@ -50036,13 +50198,13 @@ async function scanBridgeLogs(filter) {
|
|
|
50036
50198
|
|
|
50037
50199
|
// src/skillStore.ts
|
|
50038
50200
|
import fs8 from "fs";
|
|
50039
|
-
import
|
|
50201
|
+
import path14 from "path";
|
|
50040
50202
|
var logger19 = createModuleLogger("bridge.skillStore");
|
|
50041
50203
|
var ALLOWED_NAMES = /* @__PURE__ */ new Set(["log-analysis"]);
|
|
50042
50204
|
var SkillStore = class {
|
|
50043
50205
|
skillsDir;
|
|
50044
50206
|
constructor(dataDir) {
|
|
50045
|
-
this.skillsDir =
|
|
50207
|
+
this.skillsDir = path14.join(dataDir, "skills");
|
|
50046
50208
|
fs8.mkdirSync(this.skillsDir, { recursive: true });
|
|
50047
50209
|
logger19.info("SkillStore initialized", { skillsDir: this.skillsDir });
|
|
50048
50210
|
}
|
|
@@ -50051,7 +50213,7 @@ var SkillStore = class {
|
|
|
50051
50213
|
logger19.warn("Skill read: unknown name", { name, allowed: [...ALLOWED_NAMES] });
|
|
50052
50214
|
return "";
|
|
50053
50215
|
}
|
|
50054
|
-
const filePath =
|
|
50216
|
+
const filePath = path14.join(this.skillsDir, `${name}.md`);
|
|
50055
50217
|
try {
|
|
50056
50218
|
const content = fs8.readFileSync(filePath, "utf-8");
|
|
50057
50219
|
logger19.info("Skill read", { name, bytes: content.length });
|
|
@@ -50066,7 +50228,7 @@ var SkillStore = class {
|
|
|
50066
50228
|
if (!ALLOWED_NAMES.has(name)) {
|
|
50067
50229
|
throw new Error(`Unknown skill name: ${name}`);
|
|
50068
50230
|
}
|
|
50069
|
-
const filePath =
|
|
50231
|
+
const filePath = path14.join(this.skillsDir, `${name}.md`);
|
|
50070
50232
|
const tmpPath = `${filePath}.tmp`;
|
|
50071
50233
|
let existing = "";
|
|
50072
50234
|
try {
|
|
@@ -50089,7 +50251,7 @@ var SkillStore = class {
|
|
|
50089
50251
|
|
|
50090
50252
|
// src/lockfile.ts
|
|
50091
50253
|
import fs9 from "fs";
|
|
50092
|
-
import
|
|
50254
|
+
import path15 from "path";
|
|
50093
50255
|
var logger20 = createModuleLogger("bridge.lockfile");
|
|
50094
50256
|
var lockPath = null;
|
|
50095
50257
|
function isProcessAlive(pid) {
|
|
@@ -50103,7 +50265,7 @@ function isProcessAlive(pid) {
|
|
|
50103
50265
|
}
|
|
50104
50266
|
}
|
|
50105
50267
|
function acquireLock(dataDir) {
|
|
50106
|
-
const file2 =
|
|
50268
|
+
const file2 = path15.join(dataDir, "bridge.lock");
|
|
50107
50269
|
lockPath = file2;
|
|
50108
50270
|
if (fs9.existsSync(file2)) {
|
|
50109
50271
|
const raw = fs9.readFileSync(file2, "utf-8").trim();
|
|
@@ -50115,7 +50277,7 @@ function acquireLock(dataDir) {
|
|
|
50115
50277
|
logger20.warn("Removing stale bridge.lock (process not found)", { pid, path: file2 });
|
|
50116
50278
|
}
|
|
50117
50279
|
}
|
|
50118
|
-
fs9.mkdirSync(
|
|
50280
|
+
fs9.mkdirSync(path15.dirname(file2), { recursive: true });
|
|
50119
50281
|
fs9.writeFileSync(file2, String(process.pid), "utf-8");
|
|
50120
50282
|
logger20.info("Acquired bridge lock", { path: file2, pid: process.pid });
|
|
50121
50283
|
const release = () => {
|
|
@@ -50479,13 +50641,13 @@ async function handleGroupArchivedPush(deps, payload) {
|
|
|
50479
50641
|
|
|
50480
50642
|
// src/sessionStore.ts
|
|
50481
50643
|
import fs10 from "fs";
|
|
50482
|
-
import
|
|
50644
|
+
import path16 from "path";
|
|
50483
50645
|
var logger23 = createModuleLogger("session.store");
|
|
50484
50646
|
var SessionStore = class {
|
|
50485
50647
|
filePath;
|
|
50486
50648
|
cache;
|
|
50487
50649
|
constructor(dataDir) {
|
|
50488
|
-
this.filePath =
|
|
50650
|
+
this.filePath = path16.join(dataDir, "sessions.json");
|
|
50489
50651
|
this.cache = this.loadFromDisk();
|
|
50490
50652
|
}
|
|
50491
50653
|
cacheKey(agentId, scope) {
|
|
@@ -50545,7 +50707,7 @@ var SessionStore = class {
|
|
|
50545
50707
|
}
|
|
50546
50708
|
saveToDisk() {
|
|
50547
50709
|
try {
|
|
50548
|
-
const dir =
|
|
50710
|
+
const dir = path16.dirname(this.filePath);
|
|
50549
50711
|
fs10.mkdirSync(dir, { recursive: true });
|
|
50550
50712
|
fs10.writeFileSync(this.filePath, JSON.stringify(this.cache, null, 2), "utf-8");
|
|
50551
50713
|
} catch (e7) {
|
|
@@ -50555,8 +50717,8 @@ var SessionStore = class {
|
|
|
50555
50717
|
};
|
|
50556
50718
|
|
|
50557
50719
|
// src/ensureClaudeCli.ts
|
|
50558
|
-
import { execFileSync
|
|
50559
|
-
import { accessSync, constants as
|
|
50720
|
+
import { execFileSync as execFileSync2, spawnSync } from "child_process";
|
|
50721
|
+
import { accessSync as accessSync2, constants as constants3 } from "fs";
|
|
50560
50722
|
import { join as join2 } from "path";
|
|
50561
50723
|
var logger24 = createModuleLogger("bridge.ensureCli");
|
|
50562
50724
|
var DEFAULT_INSTALL_TIMEOUT_MS = 6e5;
|
|
@@ -50566,35 +50728,29 @@ function getInstallTimeoutMs() {
|
|
|
50566
50728
|
const parsed = Number.parseInt(raw, 10);
|
|
50567
50729
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_INSTALL_TIMEOUT_MS;
|
|
50568
50730
|
}
|
|
50569
|
-
function detectClaudeCli() {
|
|
50570
|
-
try {
|
|
50571
|
-
return execFileSync("claude", ["--version"], { timeout: 1e4 }).toString().trim();
|
|
50572
|
-
} catch {
|
|
50573
|
-
return void 0;
|
|
50574
|
-
}
|
|
50575
|
-
}
|
|
50576
50731
|
function getNpmGlobalBin() {
|
|
50732
|
+
const npm = resolveCommand(["npm"]);
|
|
50733
|
+
if (!npm) return void 0;
|
|
50577
50734
|
try {
|
|
50578
|
-
const bin =
|
|
50735
|
+
const bin = execFileSync2(npm.path, ["bin", "-g"], {
|
|
50736
|
+
env: withAugmentedPathEnv(),
|
|
50737
|
+
timeout: 5e3
|
|
50738
|
+
}).toString().trim() || void 0;
|
|
50579
50739
|
if (bin) return bin;
|
|
50580
50740
|
} catch {
|
|
50581
50741
|
}
|
|
50582
50742
|
try {
|
|
50583
|
-
const prefix =
|
|
50743
|
+
const prefix = execFileSync2(npm.path, ["prefix", "-g"], {
|
|
50744
|
+
env: withAugmentedPathEnv(),
|
|
50745
|
+
timeout: 5e3
|
|
50746
|
+
}).toString().trim();
|
|
50584
50747
|
if (prefix) return join2(prefix, "bin");
|
|
50585
50748
|
} catch {
|
|
50586
50749
|
}
|
|
50587
50750
|
return void 0;
|
|
50588
50751
|
}
|
|
50589
50752
|
function resolveClaudeBinary() {
|
|
50590
|
-
|
|
50591
|
-
try {
|
|
50592
|
-
const out = execFileSync(whichCmd, ["claude"], { timeout: 5e3 }).toString();
|
|
50593
|
-
const first = out.split(/\r?\n/).map((l4) => l4.trim()).find(Boolean);
|
|
50594
|
-
if (first) return first;
|
|
50595
|
-
} catch {
|
|
50596
|
-
}
|
|
50597
|
-
return resolveViaNpmBin();
|
|
50753
|
+
return resolveCommand(["claude", "anthropic-cli"])?.path ?? resolveViaNpmBin();
|
|
50598
50754
|
}
|
|
50599
50755
|
function getNpmClaudeCandidates(bin) {
|
|
50600
50756
|
if (process.platform === "win32") {
|
|
@@ -50607,7 +50763,7 @@ function resolveViaNpmBin() {
|
|
|
50607
50763
|
if (!bin) return void 0;
|
|
50608
50764
|
for (const candidate of getNpmClaudeCandidates(bin)) {
|
|
50609
50765
|
try {
|
|
50610
|
-
|
|
50766
|
+
accessSync2(candidate, constants3.X_OK);
|
|
50611
50767
|
return candidate;
|
|
50612
50768
|
} catch {
|
|
50613
50769
|
}
|
|
@@ -50617,40 +50773,32 @@ function resolveViaNpmBin() {
|
|
|
50617
50773
|
function detectViaNpmBin() {
|
|
50618
50774
|
const binPath = resolveViaNpmBin();
|
|
50619
50775
|
if (!binPath) return void 0;
|
|
50620
|
-
|
|
50621
|
-
return execFileSync(binPath, ["--version"], { timeout: 1e4 }).toString().trim();
|
|
50622
|
-
} catch {
|
|
50623
|
-
}
|
|
50624
|
-
return void 0;
|
|
50776
|
+
return readCommandVersion(binPath);
|
|
50625
50777
|
}
|
|
50626
50778
|
function detectResolvedClaudeCli() {
|
|
50627
|
-
const
|
|
50628
|
-
if (
|
|
50629
|
-
|
|
50630
|
-
}
|
|
50631
|
-
const npmBinPath = resolveViaNpmBin();
|
|
50632
|
-
if (!npmBinPath) return void 0;
|
|
50633
|
-
try {
|
|
50634
|
-
const version2 = execFileSync(npmBinPath, ["--version"], { timeout: 1e4 }).toString().trim();
|
|
50635
|
-
return { version: version2, path: npmBinPath };
|
|
50636
|
-
} catch {
|
|
50637
|
-
}
|
|
50779
|
+
const resolvedPath = resolveClaudeBinary();
|
|
50780
|
+
if (!resolvedPath) return void 0;
|
|
50781
|
+
const version2 = readCommandVersion(resolvedPath);
|
|
50782
|
+
if (version2) return { version: version2, path: resolvedPath };
|
|
50638
50783
|
return void 0;
|
|
50639
50784
|
}
|
|
50640
50785
|
function detectVersionFromResolvedCandidates() {
|
|
50641
50786
|
const candidates = [resolveClaudeBinary(), resolveViaNpmBin()].filter((p) => Boolean(p));
|
|
50642
50787
|
for (const p of candidates) {
|
|
50643
|
-
|
|
50644
|
-
|
|
50645
|
-
return execFileSync(p, ["--version"], { timeout: 1e4 }).toString().trim();
|
|
50646
|
-
} catch {
|
|
50647
|
-
}
|
|
50788
|
+
const version2 = readCommandVersion(p);
|
|
50789
|
+
if (version2) return version2;
|
|
50648
50790
|
}
|
|
50649
50791
|
return void 0;
|
|
50650
50792
|
}
|
|
50651
50793
|
function installClaudeCli() {
|
|
50794
|
+
const npm = resolveCommand(["npm"]);
|
|
50795
|
+
if (!npm) {
|
|
50796
|
+
logger24.error("npm not found; cannot install Claude Code CLI");
|
|
50797
|
+
return void 0;
|
|
50798
|
+
}
|
|
50652
50799
|
logger24.info("Installing Claude Code CLI via npm...");
|
|
50653
|
-
const result = spawnSync(
|
|
50800
|
+
const result = spawnSync(npm.path, ["install", "-g", "@anthropic-ai/claude-code"], {
|
|
50801
|
+
env: withAugmentedPathEnv(),
|
|
50654
50802
|
stdio: "inherit",
|
|
50655
50803
|
timeout: getInstallTimeoutMs()
|
|
50656
50804
|
});
|
|
@@ -50682,7 +50830,10 @@ function installClaudeCli() {
|
|
|
50682
50830
|
logger24.error("claude not found after successful npm install -g", {
|
|
50683
50831
|
npmGlobalBin: npmBin ?? "unknown",
|
|
50684
50832
|
pathDirectories: envPath.split(process.platform === "win32" ? ";" : ":").slice(0, 10),
|
|
50685
|
-
npmPrefix:
|
|
50833
|
+
npmPrefix: execFileSync2(npm.path, ["prefix", "-g"], {
|
|
50834
|
+
env: withAugmentedPathEnv(),
|
|
50835
|
+
timeout: 5e3
|
|
50836
|
+
}).toString().trim() || "unknown"
|
|
50686
50837
|
});
|
|
50687
50838
|
return void 0;
|
|
50688
50839
|
}
|
|
@@ -50711,20 +50862,20 @@ async function ensureClaudeCli() {
|
|
|
50711
50862
|
|
|
50712
50863
|
// src/forkAgentFiles.ts
|
|
50713
50864
|
import * as fs11 from "fs/promises";
|
|
50714
|
-
import * as
|
|
50865
|
+
import * as path18 from "path";
|
|
50715
50866
|
|
|
50716
50867
|
// src/sessionSlug.ts
|
|
50717
|
-
import
|
|
50718
|
-
import
|
|
50719
|
-
var CLAUDE_PROJECTS_DIR =
|
|
50868
|
+
import os10 from "os";
|
|
50869
|
+
import path17 from "path";
|
|
50870
|
+
var CLAUDE_PROJECTS_DIR = path17.join(os10.homedir(), ".claude", "projects");
|
|
50720
50871
|
function cwdToSlug(cwd) {
|
|
50721
50872
|
return cwd.replace(/[^a-zA-Z0-9-]/g, "-");
|
|
50722
50873
|
}
|
|
50723
50874
|
function sessionDirForCwd(cwd) {
|
|
50724
|
-
return
|
|
50875
|
+
return path17.join(CLAUDE_PROJECTS_DIR, cwdToSlug(cwd));
|
|
50725
50876
|
}
|
|
50726
50877
|
function sessionFilePath(cwd, sessionId) {
|
|
50727
|
-
return
|
|
50878
|
+
return path17.join(sessionDirForCwd(cwd), `${sessionId}.jsonl`);
|
|
50728
50879
|
}
|
|
50729
50880
|
|
|
50730
50881
|
// src/forkAgentFiles.ts
|
|
@@ -50756,9 +50907,9 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
|
|
|
50756
50907
|
logger25.error("Workdir copy failed", { error: e7 });
|
|
50757
50908
|
throw e7;
|
|
50758
50909
|
}
|
|
50759
|
-
const srcNotebook =
|
|
50760
|
-
const dstNotebookDir =
|
|
50761
|
-
const dstNotebook =
|
|
50910
|
+
const srcNotebook = path18.join(dataDir, "agent-memory", sourceAgentId, "notebook.md");
|
|
50911
|
+
const dstNotebookDir = path18.join(dataDir, "agent-memory", newAgentId);
|
|
50912
|
+
const dstNotebook = path18.join(dstNotebookDir, "notebook.md");
|
|
50762
50913
|
try {
|
|
50763
50914
|
const nbStat = await fs11.stat(srcNotebook).catch(() => null);
|
|
50764
50915
|
if (nbStat?.isFile()) {
|
|
@@ -50785,7 +50936,7 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
|
|
|
50785
50936
|
if (srcStat?.isFile()) {
|
|
50786
50937
|
const dstDir = sessionDirForCwd(newWorkdir);
|
|
50787
50938
|
await fs11.mkdir(dstDir, { recursive: true });
|
|
50788
|
-
const dstPath =
|
|
50939
|
+
const dstPath = path18.join(dstDir, `${sourceSessionId}.jsonl`);
|
|
50789
50940
|
await fs11.copyFile(srcPath, dstPath);
|
|
50790
50941
|
sessionStore.set(newAgentId, { kind: "single" }, sourceSessionId);
|
|
50791
50942
|
sessionCopied = true;
|
|
@@ -50832,12 +50983,12 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
|
|
|
50832
50983
|
|
|
50833
50984
|
// src/modelQuerier.ts
|
|
50834
50985
|
import fs12 from "fs/promises";
|
|
50835
|
-
import
|
|
50836
|
-
import
|
|
50986
|
+
import os11 from "os";
|
|
50987
|
+
import path19 from "path";
|
|
50837
50988
|
var logger26 = createModuleLogger("bridge.modelQuerier");
|
|
50838
50989
|
async function listModels(queryFn, opts = {}) {
|
|
50839
50990
|
const t0 = Date.now();
|
|
50840
|
-
const cwd = opts.cwd ??
|
|
50991
|
+
const cwd = opts.cwd ?? path19.join(os11.homedir(), ".ahchat", "workspaces", "_list_models");
|
|
50841
50992
|
await fs12.mkdir(cwd, { recursive: true });
|
|
50842
50993
|
const fn = queryFn ?? QA$;
|
|
50843
50994
|
const ic2 = new InputController();
|
|
@@ -50899,8 +51050,8 @@ async function listModels(queryFn, opts = {}) {
|
|
|
50899
51050
|
|
|
50900
51051
|
// src/promptOptimizer.ts
|
|
50901
51052
|
import fs13 from "fs/promises";
|
|
50902
|
-
import
|
|
50903
|
-
import
|
|
51053
|
+
import os12 from "os";
|
|
51054
|
+
import path20 from "path";
|
|
50904
51055
|
var logger27 = createModuleLogger("bridge.promptOptimizer");
|
|
50905
51056
|
var OPTIMIZER_SYSTEM_PROMPT = `You are an expert prompt editor for AHChat Agent creation.
|
|
50906
51057
|
|
|
@@ -50943,7 +51094,7 @@ async function optimizePrompt(queryFn, opts) {
|
|
|
50943
51094
|
const prompt = opts.systemPrompt.trim();
|
|
50944
51095
|
if (!prompt) throw new Error("systemPrompt is required");
|
|
50945
51096
|
const t0 = Date.now();
|
|
50946
|
-
const cwd = opts.cwd ??
|
|
51097
|
+
const cwd = opts.cwd ?? path20.join(os12.homedir(), ".ahchat", "workspaces", "_prompt_optimizer");
|
|
50947
51098
|
await fs13.mkdir(cwd, { recursive: true });
|
|
50948
51099
|
const fn = queryFn ?? QA$;
|
|
50949
51100
|
const ic2 = new InputController();
|
|
@@ -51031,7 +51182,7 @@ function isRunningAsRoot2() {
|
|
|
51031
51182
|
}
|
|
51032
51183
|
}
|
|
51033
51184
|
async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
|
|
51034
|
-
const rootClaudeDir =
|
|
51185
|
+
const rootClaudeDir = path21.join(process.env.HOME ?? "/root", ".claude");
|
|
51035
51186
|
const fs14 = await import("fs/promises");
|
|
51036
51187
|
try {
|
|
51037
51188
|
await fs14.access(rootClaudeDir);
|
|
@@ -51041,8 +51192,8 @@ async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
|
|
|
51041
51192
|
}
|
|
51042
51193
|
const filesToSync = [".credentials.json", "settings.json", ".credentials.backup.json"];
|
|
51043
51194
|
for (const file2 of filesToSync) {
|
|
51044
|
-
const src =
|
|
51045
|
-
const dest =
|
|
51195
|
+
const src = path21.join(rootClaudeDir, file2);
|
|
51196
|
+
const dest = path21.join(agentConfigDir, file2);
|
|
51046
51197
|
try {
|
|
51047
51198
|
await fs14.copyFile(src, dest);
|
|
51048
51199
|
logger28.info("Synced credential file", { file: file2, from: src, to: dest });
|
|
@@ -51065,7 +51216,7 @@ async function chownRecursive(dirPath, uid, gid) {
|
|
|
51065
51216
|
return;
|
|
51066
51217
|
}
|
|
51067
51218
|
for (const entry of entries) {
|
|
51068
|
-
const fullPath =
|
|
51219
|
+
const fullPath = path21.join(dirPath, entry.name);
|
|
51069
51220
|
if (entry.isDirectory()) {
|
|
51070
51221
|
await chownRecursive(fullPath, uid, gid);
|
|
51071
51222
|
} else {
|
|
@@ -51080,7 +51231,7 @@ async function chownRecursive(dirPath, uid, gid) {
|
|
|
51080
51231
|
async function startBridge(config2) {
|
|
51081
51232
|
ensureDir(config2.dataDir);
|
|
51082
51233
|
ensureDir(config2.agentConfigDir);
|
|
51083
|
-
const workspacesDir =
|
|
51234
|
+
const workspacesDir = path21.join(config2.dataDir, "workspaces");
|
|
51084
51235
|
ensureDir(workspacesDir);
|
|
51085
51236
|
process.env.CLAUDE_CONFIG_DIR = config2.agentConfigDir;
|
|
51086
51237
|
installBridgeFetchAuth(config2.serverApiUrl, config2.bridgeToken);
|
|
@@ -51109,7 +51260,7 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
|
|
|
51109
51260
|
`);
|
|
51110
51261
|
wsMetrics.start(5e3);
|
|
51111
51262
|
const sessionStore = new SessionStore(config2.dataDir);
|
|
51112
|
-
const memoryRoot =
|
|
51263
|
+
const memoryRoot = path21.join(config2.dataDir, "agent-memory");
|
|
51113
51264
|
const memoryStore = new AgentMemoryStore(memoryRoot);
|
|
51114
51265
|
logger28.info("Agent memory store initialized", { rootDir: memoryRoot });
|
|
51115
51266
|
const smithNotebook = memoryStore.read(SMITH_AGENT_ID);
|
|
@@ -51286,7 +51437,16 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
|
|
|
51286
51437
|
const { requestId, path: dirPath } = msg.payload;
|
|
51287
51438
|
logger28.info("list_dir request received", { requestId, path: dirPath });
|
|
51288
51439
|
try {
|
|
51289
|
-
const
|
|
51440
|
+
const resolved = remapServerWorkspacePath(dirPath, workspacesDir);
|
|
51441
|
+
if (resolved.remapped) {
|
|
51442
|
+
ensureDir(resolved.path);
|
|
51443
|
+
logger28.info("list_dir path remapped to local Bridge workspace", {
|
|
51444
|
+
requestId,
|
|
51445
|
+
requested: dirPath,
|
|
51446
|
+
remapped: resolved.path
|
|
51447
|
+
});
|
|
51448
|
+
}
|
|
51449
|
+
const entries = await listDirectoryEntries(resolved.path);
|
|
51290
51450
|
connector?.send({
|
|
51291
51451
|
type: "bridge:list_dir_response",
|
|
51292
51452
|
payload: { requestId, entries }
|