@fangyb/ahchat-bridge 0.1.21 → 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 +521 -232
- package/dist/index.js +248 -117
- package/package.json +2 -2
- 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
|
|
@@ -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
|
}
|
|
@@ -48965,8 +48965,8 @@ var HttpAgentRegistry = class {
|
|
|
48965
48965
|
agents = /* @__PURE__ */ new Map();
|
|
48966
48966
|
apiUrl(suffix) {
|
|
48967
48967
|
const base = this.serverApiUrl.replace(/\/$/, "");
|
|
48968
|
-
const
|
|
48969
|
-
return `${base}${
|
|
48968
|
+
const path22 = suffix.startsWith("/") ? suffix : `/${suffix}`;
|
|
48969
|
+
return `${base}${path22}`;
|
|
48970
48970
|
}
|
|
48971
48971
|
async refresh() {
|
|
48972
48972
|
const attempt = async () => {
|
|
@@ -49057,8 +49057,8 @@ var HttpSubscriptionRegistry = class {
|
|
|
49057
49057
|
subscriptions = /* @__PURE__ */ new Map();
|
|
49058
49058
|
apiUrl(suffix) {
|
|
49059
49059
|
const base = this.serverApiUrl.replace(/\/$/, "");
|
|
49060
|
-
const
|
|
49061
|
-
return `${base}${
|
|
49060
|
+
const path22 = suffix.startsWith("/") ? suffix : `/${suffix}`;
|
|
49061
|
+
return `${base}${path22}`;
|
|
49062
49062
|
}
|
|
49063
49063
|
async refresh() {
|
|
49064
49064
|
const attempt = async () => {
|
|
@@ -49941,19 +49941,160 @@ async function dumpAgentContext(agentId, deps) {
|
|
|
49941
49941
|
|
|
49942
49942
|
// src/listDir.ts
|
|
49943
49943
|
import fs6 from "fs/promises";
|
|
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";
|
|
49944
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
|
|
49945
50085
|
var logger17 = createModuleLogger("bridge.listDir");
|
|
49946
50086
|
function shouldIncludeEntry(name) {
|
|
49947
50087
|
if (!name.startsWith(".")) return true;
|
|
49948
50088
|
return name === ".ahchat-attachments";
|
|
49949
50089
|
}
|
|
49950
50090
|
async function listDirectoryEntries(dirPath) {
|
|
49951
|
-
|
|
49952
|
-
|
|
50091
|
+
const resolvedDirPath = resolveUserPath(dirPath);
|
|
50092
|
+
logger17.info("listDirectoryEntries start", { path: dirPath, resolvedPath: resolvedDirPath });
|
|
50093
|
+
const raw = await fs6.readdir(resolvedDirPath, { withFileTypes: true });
|
|
49953
50094
|
const entries = [];
|
|
49954
50095
|
for (const entry of raw) {
|
|
49955
50096
|
if (!shouldIncludeEntry(entry.name)) continue;
|
|
49956
|
-
const fullPath =
|
|
50097
|
+
const fullPath = path12.join(resolvedDirPath, entry.name);
|
|
49957
50098
|
const isDir = entry.isDirectory();
|
|
49958
50099
|
let size;
|
|
49959
50100
|
let mtime;
|
|
@@ -49972,6 +50113,7 @@ async function listDirectoryEntries(dirPath) {
|
|
|
49972
50113
|
});
|
|
49973
50114
|
logger17.info("listDirectoryEntries ok", {
|
|
49974
50115
|
path: dirPath,
|
|
50116
|
+
resolvedPath: resolvedDirPath,
|
|
49975
50117
|
count: entries.length,
|
|
49976
50118
|
dirCount: entries.filter((e7) => e7.type === "dir").length,
|
|
49977
50119
|
fileCount: entries.filter((e7) => e7.type === "file").length
|
|
@@ -49981,8 +50123,8 @@ async function listDirectoryEntries(dirPath) {
|
|
|
49981
50123
|
|
|
49982
50124
|
// src/logScanner.ts
|
|
49983
50125
|
import fs7 from "fs";
|
|
49984
|
-
import
|
|
49985
|
-
import
|
|
50126
|
+
import path13 from "path";
|
|
50127
|
+
import os9 from "os";
|
|
49986
50128
|
import readline from "readline";
|
|
49987
50129
|
var logger18 = createModuleLogger("bridge.logScanner");
|
|
49988
50130
|
var DEFAULT_LIMIT = 500;
|
|
@@ -49996,10 +50138,10 @@ function listLogFiles(logsDir, baseName) {
|
|
|
49996
50138
|
return [];
|
|
49997
50139
|
}
|
|
49998
50140
|
const pattern = new RegExp(`^${baseName.replace(".", "\\.")}(\\.\\d+)?$`);
|
|
49999
|
-
return names.filter((n2) => pattern.test(n2)).map((n2) =>
|
|
50141
|
+
return names.filter((n2) => pattern.test(n2)).map((n2) => path13.join(logsDir, n2));
|
|
50000
50142
|
}
|
|
50001
50143
|
async function scanFile(filePath, source, filter, limit, state) {
|
|
50002
|
-
const file2 =
|
|
50144
|
+
const file2 = path13.basename(filePath);
|
|
50003
50145
|
const stream = fs7.createReadStream(filePath, { encoding: "utf-8" });
|
|
50004
50146
|
const rl2 = readline.createInterface({ input: stream, crlfDelay: Infinity });
|
|
50005
50147
|
let lineNum = 0;
|
|
@@ -50038,7 +50180,7 @@ async function scanLocalLogs(logsDir, baseName, filter) {
|
|
|
50038
50180
|
};
|
|
50039
50181
|
}
|
|
50040
50182
|
async function scanBridgeLogs(filter) {
|
|
50041
|
-
const logDir =
|
|
50183
|
+
const logDir = path13.join(os9.homedir(), ".ahchat", "logs");
|
|
50042
50184
|
logger18.info("scanBridgeLogs start", {
|
|
50043
50185
|
logDir,
|
|
50044
50186
|
startIso: filter.startIso,
|
|
@@ -50056,13 +50198,13 @@ async function scanBridgeLogs(filter) {
|
|
|
50056
50198
|
|
|
50057
50199
|
// src/skillStore.ts
|
|
50058
50200
|
import fs8 from "fs";
|
|
50059
|
-
import
|
|
50201
|
+
import path14 from "path";
|
|
50060
50202
|
var logger19 = createModuleLogger("bridge.skillStore");
|
|
50061
50203
|
var ALLOWED_NAMES = /* @__PURE__ */ new Set(["log-analysis"]);
|
|
50062
50204
|
var SkillStore = class {
|
|
50063
50205
|
skillsDir;
|
|
50064
50206
|
constructor(dataDir) {
|
|
50065
|
-
this.skillsDir =
|
|
50207
|
+
this.skillsDir = path14.join(dataDir, "skills");
|
|
50066
50208
|
fs8.mkdirSync(this.skillsDir, { recursive: true });
|
|
50067
50209
|
logger19.info("SkillStore initialized", { skillsDir: this.skillsDir });
|
|
50068
50210
|
}
|
|
@@ -50071,7 +50213,7 @@ var SkillStore = class {
|
|
|
50071
50213
|
logger19.warn("Skill read: unknown name", { name, allowed: [...ALLOWED_NAMES] });
|
|
50072
50214
|
return "";
|
|
50073
50215
|
}
|
|
50074
|
-
const filePath =
|
|
50216
|
+
const filePath = path14.join(this.skillsDir, `${name}.md`);
|
|
50075
50217
|
try {
|
|
50076
50218
|
const content = fs8.readFileSync(filePath, "utf-8");
|
|
50077
50219
|
logger19.info("Skill read", { name, bytes: content.length });
|
|
@@ -50086,7 +50228,7 @@ var SkillStore = class {
|
|
|
50086
50228
|
if (!ALLOWED_NAMES.has(name)) {
|
|
50087
50229
|
throw new Error(`Unknown skill name: ${name}`);
|
|
50088
50230
|
}
|
|
50089
|
-
const filePath =
|
|
50231
|
+
const filePath = path14.join(this.skillsDir, `${name}.md`);
|
|
50090
50232
|
const tmpPath = `${filePath}.tmp`;
|
|
50091
50233
|
let existing = "";
|
|
50092
50234
|
try {
|
|
@@ -50109,7 +50251,7 @@ var SkillStore = class {
|
|
|
50109
50251
|
|
|
50110
50252
|
// src/lockfile.ts
|
|
50111
50253
|
import fs9 from "fs";
|
|
50112
|
-
import
|
|
50254
|
+
import path15 from "path";
|
|
50113
50255
|
var logger20 = createModuleLogger("bridge.lockfile");
|
|
50114
50256
|
var lockPath = null;
|
|
50115
50257
|
function isProcessAlive(pid) {
|
|
@@ -50123,7 +50265,7 @@ function isProcessAlive(pid) {
|
|
|
50123
50265
|
}
|
|
50124
50266
|
}
|
|
50125
50267
|
function acquireLock(dataDir) {
|
|
50126
|
-
const file2 =
|
|
50268
|
+
const file2 = path15.join(dataDir, "bridge.lock");
|
|
50127
50269
|
lockPath = file2;
|
|
50128
50270
|
if (fs9.existsSync(file2)) {
|
|
50129
50271
|
const raw = fs9.readFileSync(file2, "utf-8").trim();
|
|
@@ -50135,7 +50277,7 @@ function acquireLock(dataDir) {
|
|
|
50135
50277
|
logger20.warn("Removing stale bridge.lock (process not found)", { pid, path: file2 });
|
|
50136
50278
|
}
|
|
50137
50279
|
}
|
|
50138
|
-
fs9.mkdirSync(
|
|
50280
|
+
fs9.mkdirSync(path15.dirname(file2), { recursive: true });
|
|
50139
50281
|
fs9.writeFileSync(file2, String(process.pid), "utf-8");
|
|
50140
50282
|
logger20.info("Acquired bridge lock", { path: file2, pid: process.pid });
|
|
50141
50283
|
const release = () => {
|
|
@@ -50499,13 +50641,13 @@ async function handleGroupArchivedPush(deps, payload) {
|
|
|
50499
50641
|
|
|
50500
50642
|
// src/sessionStore.ts
|
|
50501
50643
|
import fs10 from "fs";
|
|
50502
|
-
import
|
|
50644
|
+
import path16 from "path";
|
|
50503
50645
|
var logger23 = createModuleLogger("session.store");
|
|
50504
50646
|
var SessionStore = class {
|
|
50505
50647
|
filePath;
|
|
50506
50648
|
cache;
|
|
50507
50649
|
constructor(dataDir) {
|
|
50508
|
-
this.filePath =
|
|
50650
|
+
this.filePath = path16.join(dataDir, "sessions.json");
|
|
50509
50651
|
this.cache = this.loadFromDisk();
|
|
50510
50652
|
}
|
|
50511
50653
|
cacheKey(agentId, scope) {
|
|
@@ -50565,7 +50707,7 @@ var SessionStore = class {
|
|
|
50565
50707
|
}
|
|
50566
50708
|
saveToDisk() {
|
|
50567
50709
|
try {
|
|
50568
|
-
const dir =
|
|
50710
|
+
const dir = path16.dirname(this.filePath);
|
|
50569
50711
|
fs10.mkdirSync(dir, { recursive: true });
|
|
50570
50712
|
fs10.writeFileSync(this.filePath, JSON.stringify(this.cache, null, 2), "utf-8");
|
|
50571
50713
|
} catch (e7) {
|
|
@@ -50575,8 +50717,8 @@ var SessionStore = class {
|
|
|
50575
50717
|
};
|
|
50576
50718
|
|
|
50577
50719
|
// src/ensureClaudeCli.ts
|
|
50578
|
-
import { execFileSync
|
|
50579
|
-
import { accessSync, constants as
|
|
50720
|
+
import { execFileSync as execFileSync2, spawnSync } from "child_process";
|
|
50721
|
+
import { accessSync as accessSync2, constants as constants3 } from "fs";
|
|
50580
50722
|
import { join as join2 } from "path";
|
|
50581
50723
|
var logger24 = createModuleLogger("bridge.ensureCli");
|
|
50582
50724
|
var DEFAULT_INSTALL_TIMEOUT_MS = 6e5;
|
|
@@ -50586,35 +50728,29 @@ function getInstallTimeoutMs() {
|
|
|
50586
50728
|
const parsed = Number.parseInt(raw, 10);
|
|
50587
50729
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_INSTALL_TIMEOUT_MS;
|
|
50588
50730
|
}
|
|
50589
|
-
function detectClaudeCli() {
|
|
50590
|
-
try {
|
|
50591
|
-
return execFileSync("claude", ["--version"], { timeout: 1e4 }).toString().trim();
|
|
50592
|
-
} catch {
|
|
50593
|
-
return void 0;
|
|
50594
|
-
}
|
|
50595
|
-
}
|
|
50596
50731
|
function getNpmGlobalBin() {
|
|
50732
|
+
const npm = resolveCommand(["npm"]);
|
|
50733
|
+
if (!npm) return void 0;
|
|
50597
50734
|
try {
|
|
50598
|
-
const bin =
|
|
50735
|
+
const bin = execFileSync2(npm.path, ["bin", "-g"], {
|
|
50736
|
+
env: withAugmentedPathEnv(),
|
|
50737
|
+
timeout: 5e3
|
|
50738
|
+
}).toString().trim() || void 0;
|
|
50599
50739
|
if (bin) return bin;
|
|
50600
50740
|
} catch {
|
|
50601
50741
|
}
|
|
50602
50742
|
try {
|
|
50603
|
-
const prefix =
|
|
50743
|
+
const prefix = execFileSync2(npm.path, ["prefix", "-g"], {
|
|
50744
|
+
env: withAugmentedPathEnv(),
|
|
50745
|
+
timeout: 5e3
|
|
50746
|
+
}).toString().trim();
|
|
50604
50747
|
if (prefix) return join2(prefix, "bin");
|
|
50605
50748
|
} catch {
|
|
50606
50749
|
}
|
|
50607
50750
|
return void 0;
|
|
50608
50751
|
}
|
|
50609
50752
|
function resolveClaudeBinary() {
|
|
50610
|
-
|
|
50611
|
-
try {
|
|
50612
|
-
const out = execFileSync(whichCmd, ["claude"], { timeout: 5e3 }).toString();
|
|
50613
|
-
const first = out.split(/\r?\n/).map((l4) => l4.trim()).find(Boolean);
|
|
50614
|
-
if (first) return first;
|
|
50615
|
-
} catch {
|
|
50616
|
-
}
|
|
50617
|
-
return resolveViaNpmBin();
|
|
50753
|
+
return resolveCommand(["claude", "anthropic-cli"])?.path ?? resolveViaNpmBin();
|
|
50618
50754
|
}
|
|
50619
50755
|
function getNpmClaudeCandidates(bin) {
|
|
50620
50756
|
if (process.platform === "win32") {
|
|
@@ -50627,7 +50763,7 @@ function resolveViaNpmBin() {
|
|
|
50627
50763
|
if (!bin) return void 0;
|
|
50628
50764
|
for (const candidate of getNpmClaudeCandidates(bin)) {
|
|
50629
50765
|
try {
|
|
50630
|
-
|
|
50766
|
+
accessSync2(candidate, constants3.X_OK);
|
|
50631
50767
|
return candidate;
|
|
50632
50768
|
} catch {
|
|
50633
50769
|
}
|
|
@@ -50637,40 +50773,32 @@ function resolveViaNpmBin() {
|
|
|
50637
50773
|
function detectViaNpmBin() {
|
|
50638
50774
|
const binPath = resolveViaNpmBin();
|
|
50639
50775
|
if (!binPath) return void 0;
|
|
50640
|
-
|
|
50641
|
-
return execFileSync(binPath, ["--version"], { timeout: 1e4 }).toString().trim();
|
|
50642
|
-
} catch {
|
|
50643
|
-
}
|
|
50644
|
-
return void 0;
|
|
50776
|
+
return readCommandVersion(binPath);
|
|
50645
50777
|
}
|
|
50646
50778
|
function detectResolvedClaudeCli() {
|
|
50647
|
-
const
|
|
50648
|
-
if (
|
|
50649
|
-
|
|
50650
|
-
}
|
|
50651
|
-
const npmBinPath = resolveViaNpmBin();
|
|
50652
|
-
if (!npmBinPath) return void 0;
|
|
50653
|
-
try {
|
|
50654
|
-
const version2 = execFileSync(npmBinPath, ["--version"], { timeout: 1e4 }).toString().trim();
|
|
50655
|
-
return { version: version2, path: npmBinPath };
|
|
50656
|
-
} catch {
|
|
50657
|
-
}
|
|
50779
|
+
const resolvedPath = resolveClaudeBinary();
|
|
50780
|
+
if (!resolvedPath) return void 0;
|
|
50781
|
+
const version2 = readCommandVersion(resolvedPath);
|
|
50782
|
+
if (version2) return { version: version2, path: resolvedPath };
|
|
50658
50783
|
return void 0;
|
|
50659
50784
|
}
|
|
50660
50785
|
function detectVersionFromResolvedCandidates() {
|
|
50661
50786
|
const candidates = [resolveClaudeBinary(), resolveViaNpmBin()].filter((p) => Boolean(p));
|
|
50662
50787
|
for (const p of candidates) {
|
|
50663
|
-
|
|
50664
|
-
|
|
50665
|
-
return execFileSync(p, ["--version"], { timeout: 1e4 }).toString().trim();
|
|
50666
|
-
} catch {
|
|
50667
|
-
}
|
|
50788
|
+
const version2 = readCommandVersion(p);
|
|
50789
|
+
if (version2) return version2;
|
|
50668
50790
|
}
|
|
50669
50791
|
return void 0;
|
|
50670
50792
|
}
|
|
50671
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
|
+
}
|
|
50672
50799
|
logger24.info("Installing Claude Code CLI via npm...");
|
|
50673
|
-
const result = spawnSync(
|
|
50800
|
+
const result = spawnSync(npm.path, ["install", "-g", "@anthropic-ai/claude-code"], {
|
|
50801
|
+
env: withAugmentedPathEnv(),
|
|
50674
50802
|
stdio: "inherit",
|
|
50675
50803
|
timeout: getInstallTimeoutMs()
|
|
50676
50804
|
});
|
|
@@ -50702,7 +50830,10 @@ function installClaudeCli() {
|
|
|
50702
50830
|
logger24.error("claude not found after successful npm install -g", {
|
|
50703
50831
|
npmGlobalBin: npmBin ?? "unknown",
|
|
50704
50832
|
pathDirectories: envPath.split(process.platform === "win32" ? ";" : ":").slice(0, 10),
|
|
50705
|
-
npmPrefix:
|
|
50833
|
+
npmPrefix: execFileSync2(npm.path, ["prefix", "-g"], {
|
|
50834
|
+
env: withAugmentedPathEnv(),
|
|
50835
|
+
timeout: 5e3
|
|
50836
|
+
}).toString().trim() || "unknown"
|
|
50706
50837
|
});
|
|
50707
50838
|
return void 0;
|
|
50708
50839
|
}
|
|
@@ -50731,20 +50862,20 @@ async function ensureClaudeCli() {
|
|
|
50731
50862
|
|
|
50732
50863
|
// src/forkAgentFiles.ts
|
|
50733
50864
|
import * as fs11 from "fs/promises";
|
|
50734
|
-
import * as
|
|
50865
|
+
import * as path18 from "path";
|
|
50735
50866
|
|
|
50736
50867
|
// src/sessionSlug.ts
|
|
50737
|
-
import
|
|
50738
|
-
import
|
|
50739
|
-
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");
|
|
50740
50871
|
function cwdToSlug(cwd) {
|
|
50741
50872
|
return cwd.replace(/[^a-zA-Z0-9-]/g, "-");
|
|
50742
50873
|
}
|
|
50743
50874
|
function sessionDirForCwd(cwd) {
|
|
50744
|
-
return
|
|
50875
|
+
return path17.join(CLAUDE_PROJECTS_DIR, cwdToSlug(cwd));
|
|
50745
50876
|
}
|
|
50746
50877
|
function sessionFilePath(cwd, sessionId) {
|
|
50747
|
-
return
|
|
50878
|
+
return path17.join(sessionDirForCwd(cwd), `${sessionId}.jsonl`);
|
|
50748
50879
|
}
|
|
50749
50880
|
|
|
50750
50881
|
// src/forkAgentFiles.ts
|
|
@@ -50776,9 +50907,9 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
|
|
|
50776
50907
|
logger25.error("Workdir copy failed", { error: e7 });
|
|
50777
50908
|
throw e7;
|
|
50778
50909
|
}
|
|
50779
|
-
const srcNotebook =
|
|
50780
|
-
const dstNotebookDir =
|
|
50781
|
-
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");
|
|
50782
50913
|
try {
|
|
50783
50914
|
const nbStat = await fs11.stat(srcNotebook).catch(() => null);
|
|
50784
50915
|
if (nbStat?.isFile()) {
|
|
@@ -50805,7 +50936,7 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
|
|
|
50805
50936
|
if (srcStat?.isFile()) {
|
|
50806
50937
|
const dstDir = sessionDirForCwd(newWorkdir);
|
|
50807
50938
|
await fs11.mkdir(dstDir, { recursive: true });
|
|
50808
|
-
const dstPath =
|
|
50939
|
+
const dstPath = path18.join(dstDir, `${sourceSessionId}.jsonl`);
|
|
50809
50940
|
await fs11.copyFile(srcPath, dstPath);
|
|
50810
50941
|
sessionStore.set(newAgentId, { kind: "single" }, sourceSessionId);
|
|
50811
50942
|
sessionCopied = true;
|
|
@@ -50852,12 +50983,12 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
|
|
|
50852
50983
|
|
|
50853
50984
|
// src/modelQuerier.ts
|
|
50854
50985
|
import fs12 from "fs/promises";
|
|
50855
|
-
import
|
|
50856
|
-
import
|
|
50986
|
+
import os11 from "os";
|
|
50987
|
+
import path19 from "path";
|
|
50857
50988
|
var logger26 = createModuleLogger("bridge.modelQuerier");
|
|
50858
50989
|
async function listModels(queryFn, opts = {}) {
|
|
50859
50990
|
const t0 = Date.now();
|
|
50860
|
-
const cwd = opts.cwd ??
|
|
50991
|
+
const cwd = opts.cwd ?? path19.join(os11.homedir(), ".ahchat", "workspaces", "_list_models");
|
|
50861
50992
|
await fs12.mkdir(cwd, { recursive: true });
|
|
50862
50993
|
const fn = queryFn ?? QA$;
|
|
50863
50994
|
const ic2 = new InputController();
|
|
@@ -50919,8 +51050,8 @@ async function listModels(queryFn, opts = {}) {
|
|
|
50919
51050
|
|
|
50920
51051
|
// src/promptOptimizer.ts
|
|
50921
51052
|
import fs13 from "fs/promises";
|
|
50922
|
-
import
|
|
50923
|
-
import
|
|
51053
|
+
import os12 from "os";
|
|
51054
|
+
import path20 from "path";
|
|
50924
51055
|
var logger27 = createModuleLogger("bridge.promptOptimizer");
|
|
50925
51056
|
var OPTIMIZER_SYSTEM_PROMPT = `You are an expert prompt editor for AHChat Agent creation.
|
|
50926
51057
|
|
|
@@ -50963,7 +51094,7 @@ async function optimizePrompt(queryFn, opts) {
|
|
|
50963
51094
|
const prompt = opts.systemPrompt.trim();
|
|
50964
51095
|
if (!prompt) throw new Error("systemPrompt is required");
|
|
50965
51096
|
const t0 = Date.now();
|
|
50966
|
-
const cwd = opts.cwd ??
|
|
51097
|
+
const cwd = opts.cwd ?? path20.join(os12.homedir(), ".ahchat", "workspaces", "_prompt_optimizer");
|
|
50967
51098
|
await fs13.mkdir(cwd, { recursive: true });
|
|
50968
51099
|
const fn = queryFn ?? QA$;
|
|
50969
51100
|
const ic2 = new InputController();
|
|
@@ -51051,7 +51182,7 @@ function isRunningAsRoot2() {
|
|
|
51051
51182
|
}
|
|
51052
51183
|
}
|
|
51053
51184
|
async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
|
|
51054
|
-
const rootClaudeDir =
|
|
51185
|
+
const rootClaudeDir = path21.join(process.env.HOME ?? "/root", ".claude");
|
|
51055
51186
|
const fs14 = await import("fs/promises");
|
|
51056
51187
|
try {
|
|
51057
51188
|
await fs14.access(rootClaudeDir);
|
|
@@ -51061,8 +51192,8 @@ async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
|
|
|
51061
51192
|
}
|
|
51062
51193
|
const filesToSync = [".credentials.json", "settings.json", ".credentials.backup.json"];
|
|
51063
51194
|
for (const file2 of filesToSync) {
|
|
51064
|
-
const src =
|
|
51065
|
-
const dest =
|
|
51195
|
+
const src = path21.join(rootClaudeDir, file2);
|
|
51196
|
+
const dest = path21.join(agentConfigDir, file2);
|
|
51066
51197
|
try {
|
|
51067
51198
|
await fs14.copyFile(src, dest);
|
|
51068
51199
|
logger28.info("Synced credential file", { file: file2, from: src, to: dest });
|
|
@@ -51085,7 +51216,7 @@ async function chownRecursive(dirPath, uid, gid) {
|
|
|
51085
51216
|
return;
|
|
51086
51217
|
}
|
|
51087
51218
|
for (const entry of entries) {
|
|
51088
|
-
const fullPath =
|
|
51219
|
+
const fullPath = path21.join(dirPath, entry.name);
|
|
51089
51220
|
if (entry.isDirectory()) {
|
|
51090
51221
|
await chownRecursive(fullPath, uid, gid);
|
|
51091
51222
|
} else {
|
|
@@ -51100,7 +51231,7 @@ async function chownRecursive(dirPath, uid, gid) {
|
|
|
51100
51231
|
async function startBridge(config2) {
|
|
51101
51232
|
ensureDir(config2.dataDir);
|
|
51102
51233
|
ensureDir(config2.agentConfigDir);
|
|
51103
|
-
const workspacesDir =
|
|
51234
|
+
const workspacesDir = path21.join(config2.dataDir, "workspaces");
|
|
51104
51235
|
ensureDir(workspacesDir);
|
|
51105
51236
|
process.env.CLAUDE_CONFIG_DIR = config2.agentConfigDir;
|
|
51106
51237
|
installBridgeFetchAuth(config2.serverApiUrl, config2.bridgeToken);
|
|
@@ -51129,7 +51260,7 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
|
|
|
51129
51260
|
`);
|
|
51130
51261
|
wsMetrics.start(5e3);
|
|
51131
51262
|
const sessionStore = new SessionStore(config2.dataDir);
|
|
51132
|
-
const memoryRoot =
|
|
51263
|
+
const memoryRoot = path21.join(config2.dataDir, "agent-memory");
|
|
51133
51264
|
const memoryStore = new AgentMemoryStore(memoryRoot);
|
|
51134
51265
|
logger28.info("Agent memory store initialized", { rootDir: memoryRoot });
|
|
51135
51266
|
const smithNotebook = memoryStore.read(SMITH_AGENT_ID);
|