@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/cli.cjs
CHANGED
|
@@ -3679,9 +3679,8 @@ var require_websocket_server = __commonJS({
|
|
|
3679
3679
|
|
|
3680
3680
|
// src/cli.ts
|
|
3681
3681
|
init_cjs_shims();
|
|
3682
|
-
var
|
|
3683
|
-
var
|
|
3684
|
-
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
3682
|
+
var import_node_path23 = __toESM(require("path"), 1);
|
|
3683
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
3685
3684
|
|
|
3686
3685
|
// ../../node_modules/.pnpm/cac@6.7.14/node_modules/cac/dist/index.mjs
|
|
3687
3686
|
init_cjs_shims();
|
|
@@ -5097,11 +5096,11 @@ var RotatingFileStream = class extends import_stream.Writable {
|
|
|
5097
5096
|
timeout;
|
|
5098
5097
|
timeoutPromise;
|
|
5099
5098
|
constructor(generator, options) {
|
|
5100
|
-
const { encoding, history, maxFiles, maxSize, path:
|
|
5099
|
+
const { encoding, history, maxFiles, maxSize, path: path24 } = options;
|
|
5101
5100
|
super({ decodeStrings: true, defaultEncoding: encoding });
|
|
5102
5101
|
this.createGzip = import_zlib.createGzip;
|
|
5103
5102
|
this.exec = import_child_process.exec;
|
|
5104
|
-
this.filename =
|
|
5103
|
+
this.filename = path24 + generator(null);
|
|
5105
5104
|
this.fsCreateReadStream = import_fs.createReadStream;
|
|
5106
5105
|
this.fsCreateWriteStream = import_fs.createWriteStream;
|
|
5107
5106
|
this.fsOpen = import_promises.open;
|
|
@@ -5113,7 +5112,7 @@ var RotatingFileStream = class extends import_stream.Writable {
|
|
|
5113
5112
|
this.options = options;
|
|
5114
5113
|
this.stdout = process.stdout;
|
|
5115
5114
|
if (maxFiles || maxSize)
|
|
5116
|
-
options.history =
|
|
5115
|
+
options.history = path24 + (history ? history : this.generator(null) + ".txt");
|
|
5117
5116
|
this.on("close", () => this.finished ? null : this.emit("finish"));
|
|
5118
5117
|
this.on("finish", () => this.finished = this.clear());
|
|
5119
5118
|
(async () => {
|
|
@@ -5241,9 +5240,9 @@ var RotatingFileStream = class extends import_stream.Writable {
|
|
|
5241
5240
|
return this.move();
|
|
5242
5241
|
}
|
|
5243
5242
|
async findName() {
|
|
5244
|
-
const { interval, path:
|
|
5243
|
+
const { interval, path: path24, intervalBoundary } = this.options;
|
|
5245
5244
|
for (let index = 1; index < 1e3; ++index) {
|
|
5246
|
-
const filename =
|
|
5245
|
+
const filename = path24 + this.generator(interval && intervalBoundary ? new Date(this.prev) : this.rotation, index);
|
|
5247
5246
|
if (!await exists(filename))
|
|
5248
5247
|
return filename;
|
|
5249
5248
|
}
|
|
@@ -5273,11 +5272,11 @@ var RotatingFileStream = class extends import_stream.Writable {
|
|
|
5273
5272
|
return this.unlink(filename);
|
|
5274
5273
|
}
|
|
5275
5274
|
async classical() {
|
|
5276
|
-
const { compress, path:
|
|
5275
|
+
const { compress, path: path24, rotate } = this.options;
|
|
5277
5276
|
let rotatedName = "";
|
|
5278
5277
|
for (let count = rotate; count > 0; --count) {
|
|
5279
|
-
const currName =
|
|
5280
|
-
const prevName = count === 1 ? this.filename :
|
|
5278
|
+
const currName = path24 + this.generator(count);
|
|
5279
|
+
const prevName = count === 1 ? this.filename : path24 + this.generator(count - 1);
|
|
5281
5280
|
if (!await exists(prevName))
|
|
5282
5281
|
continue;
|
|
5283
5282
|
if (!rotatedName)
|
|
@@ -5715,7 +5714,7 @@ function createModuleLogger(module2) {
|
|
|
5715
5714
|
|
|
5716
5715
|
// src/start.ts
|
|
5717
5716
|
init_cjs_shims();
|
|
5718
|
-
var
|
|
5717
|
+
var import_node_path21 = __toESM(require("path"), 1);
|
|
5719
5718
|
|
|
5720
5719
|
// ../shared/src/index.ts
|
|
5721
5720
|
init_cjs_shims();
|
|
@@ -29753,10 +29752,10 @@ function mergeDefs(...defs) {
|
|
|
29753
29752
|
function cloneDef(schema) {
|
|
29754
29753
|
return mergeDefs(schema._zod.def);
|
|
29755
29754
|
}
|
|
29756
|
-
function getElementAtPath(obj,
|
|
29757
|
-
if (!
|
|
29755
|
+
function getElementAtPath(obj, path24) {
|
|
29756
|
+
if (!path24)
|
|
29758
29757
|
return obj;
|
|
29759
|
-
return
|
|
29758
|
+
return path24.reduce((acc, key) => acc?.[key], obj);
|
|
29760
29759
|
}
|
|
29761
29760
|
function promiseAllObject(promisesObj) {
|
|
29762
29761
|
const keys = Object.keys(promisesObj);
|
|
@@ -30165,11 +30164,11 @@ function explicitlyAborted(x2, startIndex = 0) {
|
|
|
30165
30164
|
}
|
|
30166
30165
|
return false;
|
|
30167
30166
|
}
|
|
30168
|
-
function prefixIssues(
|
|
30167
|
+
function prefixIssues(path24, issues) {
|
|
30169
30168
|
return issues.map((iss) => {
|
|
30170
30169
|
var _a3;
|
|
30171
30170
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
30172
|
-
iss.path.unshift(
|
|
30171
|
+
iss.path.unshift(path24);
|
|
30173
30172
|
return iss;
|
|
30174
30173
|
});
|
|
30175
30174
|
}
|
|
@@ -30316,16 +30315,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
30316
30315
|
}
|
|
30317
30316
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
30318
30317
|
const fieldErrors = { _errors: [] };
|
|
30319
|
-
const processError = (error52,
|
|
30318
|
+
const processError = (error52, path24 = []) => {
|
|
30320
30319
|
for (const issue2 of error52.issues) {
|
|
30321
30320
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
30322
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
30321
|
+
issue2.errors.map((issues) => processError({ issues }, [...path24, ...issue2.path]));
|
|
30323
30322
|
} else if (issue2.code === "invalid_key") {
|
|
30324
|
-
processError({ issues: issue2.issues }, [...
|
|
30323
|
+
processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
|
|
30325
30324
|
} else if (issue2.code === "invalid_element") {
|
|
30326
|
-
processError({ issues: issue2.issues }, [...
|
|
30325
|
+
processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
|
|
30327
30326
|
} else {
|
|
30328
|
-
const fullpath = [...
|
|
30327
|
+
const fullpath = [...path24, ...issue2.path];
|
|
30329
30328
|
if (fullpath.length === 0) {
|
|
30330
30329
|
fieldErrors._errors.push(mapper(issue2));
|
|
30331
30330
|
} else {
|
|
@@ -30352,17 +30351,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
30352
30351
|
}
|
|
30353
30352
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
30354
30353
|
const result = { errors: [] };
|
|
30355
|
-
const processError = (error52,
|
|
30354
|
+
const processError = (error52, path24 = []) => {
|
|
30356
30355
|
var _a3, _b2;
|
|
30357
30356
|
for (const issue2 of error52.issues) {
|
|
30358
30357
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
30359
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
30358
|
+
issue2.errors.map((issues) => processError({ issues }, [...path24, ...issue2.path]));
|
|
30360
30359
|
} else if (issue2.code === "invalid_key") {
|
|
30361
|
-
processError({ issues: issue2.issues }, [...
|
|
30360
|
+
processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
|
|
30362
30361
|
} else if (issue2.code === "invalid_element") {
|
|
30363
|
-
processError({ issues: issue2.issues }, [...
|
|
30362
|
+
processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
|
|
30364
30363
|
} else {
|
|
30365
|
-
const fullpath = [...
|
|
30364
|
+
const fullpath = [...path24, ...issue2.path];
|
|
30366
30365
|
if (fullpath.length === 0) {
|
|
30367
30366
|
result.errors.push(mapper(issue2));
|
|
30368
30367
|
continue;
|
|
@@ -30394,8 +30393,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
30394
30393
|
}
|
|
30395
30394
|
function toDotPath(_path) {
|
|
30396
30395
|
const segs = [];
|
|
30397
|
-
const
|
|
30398
|
-
for (const seg of
|
|
30396
|
+
const path24 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
30397
|
+
for (const seg of path24) {
|
|
30399
30398
|
if (typeof seg === "number")
|
|
30400
30399
|
segs.push(`[${seg}]`);
|
|
30401
30400
|
else if (typeof seg === "symbol")
|
|
@@ -43168,13 +43167,13 @@ function resolveRef(ref, ctx) {
|
|
|
43168
43167
|
if (!ref.startsWith("#")) {
|
|
43169
43168
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
43170
43169
|
}
|
|
43171
|
-
const
|
|
43172
|
-
if (
|
|
43170
|
+
const path24 = ref.slice(1).split("/").filter(Boolean);
|
|
43171
|
+
if (path24.length === 0) {
|
|
43173
43172
|
return ctx.rootSchema;
|
|
43174
43173
|
}
|
|
43175
43174
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
43176
|
-
if (
|
|
43177
|
-
const key =
|
|
43175
|
+
if (path24[0] === defsKey) {
|
|
43176
|
+
const key = path24[1];
|
|
43178
43177
|
if (!key || !ctx.defs[key]) {
|
|
43179
43178
|
throw new Error(`Reference not found: ${ref}`);
|
|
43180
43179
|
}
|
|
@@ -49771,8 +49770,8 @@ var HttpAgentRegistry = class {
|
|
|
49771
49770
|
agents = /* @__PURE__ */ new Map();
|
|
49772
49771
|
apiUrl(suffix) {
|
|
49773
49772
|
const base = this.serverApiUrl.replace(/\/$/, "");
|
|
49774
|
-
const
|
|
49775
|
-
return `${base}${
|
|
49773
|
+
const path24 = suffix.startsWith("/") ? suffix : `/${suffix}`;
|
|
49774
|
+
return `${base}${path24}`;
|
|
49776
49775
|
}
|
|
49777
49776
|
async refresh() {
|
|
49778
49777
|
const attempt = async () => {
|
|
@@ -49864,8 +49863,8 @@ var HttpSubscriptionRegistry = class {
|
|
|
49864
49863
|
subscriptions = /* @__PURE__ */ new Map();
|
|
49865
49864
|
apiUrl(suffix) {
|
|
49866
49865
|
const base = this.serverApiUrl.replace(/\/$/, "");
|
|
49867
|
-
const
|
|
49868
|
-
return `${base}${
|
|
49866
|
+
const path24 = suffix.startsWith("/") ? suffix : `/${suffix}`;
|
|
49867
|
+
return `${base}${path24}`;
|
|
49869
49868
|
}
|
|
49870
49869
|
async refresh() {
|
|
49871
49870
|
const attempt = async () => {
|
|
@@ -50753,19 +50752,208 @@ async function dumpAgentContext(agentId, deps) {
|
|
|
50753
50752
|
// src/listDir.ts
|
|
50754
50753
|
init_cjs_shims();
|
|
50755
50754
|
var import_promises10 = __toESM(require("fs/promises"), 1);
|
|
50755
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
50756
|
+
|
|
50757
|
+
// src/runtimeEnv.ts
|
|
50758
|
+
init_cjs_shims();
|
|
50759
|
+
var import_node_child_process2 = require("child_process");
|
|
50760
|
+
var import_node_fs4 = require("fs");
|
|
50761
|
+
var import_node_os8 = __toESM(require("os"), 1);
|
|
50756
50762
|
var import_node_path11 = __toESM(require("path"), 1);
|
|
50763
|
+
var MIN_NODE_MAJOR = 20;
|
|
50764
|
+
function getHomeDir() {
|
|
50765
|
+
return process.env.USERPROFILE || import_node_os8.default.homedir();
|
|
50766
|
+
}
|
|
50767
|
+
function splitPath(value) {
|
|
50768
|
+
if (!value) return [];
|
|
50769
|
+
return value.split(import_node_path11.default.delimiter).filter((entry) => entry.length > 0);
|
|
50770
|
+
}
|
|
50771
|
+
function uniq(values) {
|
|
50772
|
+
return [...new Set(values.filter(Boolean))];
|
|
50773
|
+
}
|
|
50774
|
+
function parseNodeVersionMajor(version2) {
|
|
50775
|
+
const raw = version2.trim().replace(/^v/, "");
|
|
50776
|
+
const [majorRaw] = raw.split(".");
|
|
50777
|
+
if (!majorRaw) return null;
|
|
50778
|
+
const major = Number.parseInt(majorRaw, 10);
|
|
50779
|
+
return Number.isFinite(major) ? major : null;
|
|
50780
|
+
}
|
|
50781
|
+
function joinHomePath(home, suffix) {
|
|
50782
|
+
const parts = suffix.split(/[\\/]+/).filter((part) => part.length > 0);
|
|
50783
|
+
return import_node_path11.default.join(home, ...parts);
|
|
50784
|
+
}
|
|
50785
|
+
function sortNodeVersionDirsDesc(names) {
|
|
50786
|
+
return [...names].sort((a, b2) => {
|
|
50787
|
+
const aParts = a.replace(/^v/, "").split(".").map((p) => Number.parseInt(p, 10) || 0);
|
|
50788
|
+
const bParts = b2.replace(/^v/, "").split(".").map((p) => Number.parseInt(p, 10) || 0);
|
|
50789
|
+
for (let i = 0; i < Math.max(aParts.length, bParts.length); i += 1) {
|
|
50790
|
+
const delta = (bParts[i] ?? 0) - (aParts[i] ?? 0);
|
|
50791
|
+
if (delta !== 0) return delta;
|
|
50792
|
+
}
|
|
50793
|
+
return b2.localeCompare(a);
|
|
50794
|
+
});
|
|
50795
|
+
}
|
|
50796
|
+
function listNodeVersionBins(root, binSuffix) {
|
|
50797
|
+
if (!(0, import_node_fs4.existsSync)(root)) return [];
|
|
50798
|
+
try {
|
|
50799
|
+
return sortNodeVersionDirsDesc((0, import_node_fs4.readdirSync)(root)).map((version2) => import_node_path11.default.join(root, version2, ...binSuffix)).filter((candidate) => (0, import_node_fs4.existsSync)(candidate));
|
|
50800
|
+
} catch {
|
|
50801
|
+
return [];
|
|
50802
|
+
}
|
|
50803
|
+
}
|
|
50804
|
+
function getNodeRuntimeStatus(version2 = process.versions.node) {
|
|
50805
|
+
const major = parseNodeVersionMajor(version2);
|
|
50806
|
+
return {
|
|
50807
|
+
version: version2,
|
|
50808
|
+
major,
|
|
50809
|
+
supported: major !== null && major >= MIN_NODE_MAJOR
|
|
50810
|
+
};
|
|
50811
|
+
}
|
|
50812
|
+
function getNodeToolExtraPathEntries(env2 = process.env) {
|
|
50813
|
+
const home = getHomeDir();
|
|
50814
|
+
const entries = [];
|
|
50815
|
+
if (process.platform === "win32") {
|
|
50816
|
+
for (const envName of ["NVM_SYMLINK", "NVM_HOME"]) {
|
|
50817
|
+
const value = env2[envName];
|
|
50818
|
+
if (value && (0, import_node_fs4.existsSync)(value)) entries.push(value);
|
|
50819
|
+
}
|
|
50820
|
+
for (const candidate of [
|
|
50821
|
+
import_node_path11.default.join(home, "AppData", "Roaming", "npm"),
|
|
50822
|
+
import_node_path11.default.join(home, ".volta", "bin"),
|
|
50823
|
+
import_node_path11.default.join(home, ".asdf", "shims"),
|
|
50824
|
+
import_node_path11.default.join(env2.ProgramFiles ?? "C:\\Program Files", "nodejs"),
|
|
50825
|
+
import_node_path11.default.join(env2.LOCALAPPDATA ?? import_node_path11.default.join(home, "AppData", "Local"), "Programs", "nodejs")
|
|
50826
|
+
]) {
|
|
50827
|
+
if ((0, import_node_fs4.existsSync)(candidate)) entries.push(candidate);
|
|
50828
|
+
}
|
|
50829
|
+
return uniq(entries);
|
|
50830
|
+
}
|
|
50831
|
+
const nvmRoot = env2.NVM_DIR ?? import_node_path11.default.join(home, ".nvm");
|
|
50832
|
+
entries.push(...listNodeVersionBins(import_node_path11.default.join(nvmRoot, "versions", "node"), ["bin"]));
|
|
50833
|
+
const fnmRoots = [
|
|
50834
|
+
import_node_path11.default.join(home, ".fnm", "node-versions"),
|
|
50835
|
+
import_node_path11.default.join(home, ".local", "share", "fnm", "node-versions")
|
|
50836
|
+
];
|
|
50837
|
+
for (const fnmRoot of fnmRoots) {
|
|
50838
|
+
entries.push(...listNodeVersionBins(fnmRoot, ["installation", "bin"]));
|
|
50839
|
+
}
|
|
50840
|
+
for (const candidate of [
|
|
50841
|
+
import_node_path11.default.join(home, ".volta", "bin"),
|
|
50842
|
+
import_node_path11.default.join(home, ".asdf", "shims"),
|
|
50843
|
+
import_node_path11.default.join(home, ".local", "bin"),
|
|
50844
|
+
"/opt/homebrew/bin",
|
|
50845
|
+
"/usr/local/bin"
|
|
50846
|
+
]) {
|
|
50847
|
+
if ((0, import_node_fs4.existsSync)(candidate)) entries.push(candidate);
|
|
50848
|
+
}
|
|
50849
|
+
return uniq(entries);
|
|
50850
|
+
}
|
|
50851
|
+
function buildAugmentedPath(env2 = process.env) {
|
|
50852
|
+
return uniq([...getNodeToolExtraPathEntries(env2), ...splitPath(env2.PATH)]).join(import_node_path11.default.delimiter);
|
|
50853
|
+
}
|
|
50854
|
+
function withAugmentedPathEnv(env2 = process.env) {
|
|
50855
|
+
return { ...env2, PATH: buildAugmentedPath(env2) };
|
|
50856
|
+
}
|
|
50857
|
+
function executableNames(name) {
|
|
50858
|
+
if (process.platform !== "win32") return [name];
|
|
50859
|
+
if (/\.(cmd|exe|bat)$/i.test(name)) return [name];
|
|
50860
|
+
return [`${name}.cmd`, `${name}.exe`, `${name}.bat`, name];
|
|
50861
|
+
}
|
|
50862
|
+
function canExecute(candidate) {
|
|
50863
|
+
try {
|
|
50864
|
+
if (process.platform === "win32") return (0, import_node_fs4.existsSync)(candidate);
|
|
50865
|
+
(0, import_node_fs4.accessSync)(candidate, import_node_fs4.constants.X_OK);
|
|
50866
|
+
return true;
|
|
50867
|
+
} catch {
|
|
50868
|
+
return false;
|
|
50869
|
+
}
|
|
50870
|
+
}
|
|
50871
|
+
function resolveCommand(names, env2 = process.env) {
|
|
50872
|
+
const pathEntries = splitPath(buildAugmentedPath(env2));
|
|
50873
|
+
for (const entry of pathEntries) {
|
|
50874
|
+
for (const name of names) {
|
|
50875
|
+
for (const executableName of executableNames(name)) {
|
|
50876
|
+
const candidate = import_node_path11.default.join(entry, executableName);
|
|
50877
|
+
if (canExecute(candidate)) return { name, path: candidate };
|
|
50878
|
+
}
|
|
50879
|
+
}
|
|
50880
|
+
}
|
|
50881
|
+
return void 0;
|
|
50882
|
+
}
|
|
50883
|
+
function readCommandVersion(executablePath, args = ["--version"], env2 = process.env) {
|
|
50884
|
+
try {
|
|
50885
|
+
return (0, import_node_child_process2.execFileSync)(executablePath, args, {
|
|
50886
|
+
env: withAugmentedPathEnv(env2),
|
|
50887
|
+
timeout: 1e4
|
|
50888
|
+
}).toString().trim();
|
|
50889
|
+
} catch {
|
|
50890
|
+
return void 0;
|
|
50891
|
+
}
|
|
50892
|
+
}
|
|
50893
|
+
function probeCommand(name, args = ["--version"], env2 = process.env) {
|
|
50894
|
+
const resolved = resolveCommand([name], env2);
|
|
50895
|
+
if (!resolved) {
|
|
50896
|
+
return {
|
|
50897
|
+
name,
|
|
50898
|
+
ok: false,
|
|
50899
|
+
message: `${name} was not found on PATH`
|
|
50900
|
+
};
|
|
50901
|
+
}
|
|
50902
|
+
const version2 = readCommandVersion(resolved.path, args, env2);
|
|
50903
|
+
return {
|
|
50904
|
+
name,
|
|
50905
|
+
path: resolved.path,
|
|
50906
|
+
version: version2,
|
|
50907
|
+
ok: Boolean(version2),
|
|
50908
|
+
message: version2 ? void 0 : `${name} was found but did not run successfully`
|
|
50909
|
+
};
|
|
50910
|
+
}
|
|
50911
|
+
function resolveUserPath(input) {
|
|
50912
|
+
const home = getHomeDir();
|
|
50913
|
+
let value = input.trim();
|
|
50914
|
+
if (value === "~") value = home;
|
|
50915
|
+
else if (value.startsWith("~/") || value.startsWith("~\\")) value = joinHomePath(home, value.slice(2));
|
|
50916
|
+
else if (value === "$HOME") value = home;
|
|
50917
|
+
else if (value.startsWith("$HOME/") || value.startsWith("$HOME\\")) value = joinHomePath(home, value.slice(6));
|
|
50918
|
+
else if (value === "${HOME}") value = home;
|
|
50919
|
+
else if (value.startsWith("${HOME}/") || value.startsWith("${HOME}\\")) value = joinHomePath(home, value.slice(8));
|
|
50920
|
+
else if (value === "$env:USERPROFILE") value = home;
|
|
50921
|
+
else if (value.startsWith("$env:USERPROFILE\\") || value.startsWith("$env:USERPROFILE/")) {
|
|
50922
|
+
value = joinHomePath(home, value.slice("$env:USERPROFILE".length + 1));
|
|
50923
|
+
} else if (value === "%USERPROFILE%") value = home;
|
|
50924
|
+
else if (value.startsWith("%USERPROFILE%\\") || value.startsWith("%USERPROFILE%/")) {
|
|
50925
|
+
value = joinHomePath(home, value.slice("%USERPROFILE%".length + 1));
|
|
50926
|
+
}
|
|
50927
|
+
return import_node_path11.default.isAbsolute(value) ? import_node_path11.default.normalize(value) : import_node_path11.default.resolve(value);
|
|
50928
|
+
}
|
|
50929
|
+
function normalizeBridgeServerUrls(rawUrl) {
|
|
50930
|
+
const url2 = new URL(rawUrl);
|
|
50931
|
+
if (url2.protocol === "http:" || url2.protocol === "https:") {
|
|
50932
|
+
url2.protocol = url2.protocol === "https:" ? "wss:" : "ws:";
|
|
50933
|
+
if (url2.pathname === "/" || url2.pathname === "") url2.pathname = "/ws/bridge";
|
|
50934
|
+
}
|
|
50935
|
+
if (url2.protocol !== "ws:" && url2.protocol !== "wss:") {
|
|
50936
|
+
throw new Error(`Unsupported bridge server URL protocol: ${url2.protocol}`);
|
|
50937
|
+
}
|
|
50938
|
+
const serverUrl = url2.toString();
|
|
50939
|
+
const serverApiUrl = `${url2.protocol === "wss:" ? "https" : "http"}://${url2.host}`;
|
|
50940
|
+
return { serverUrl, serverApiUrl };
|
|
50941
|
+
}
|
|
50942
|
+
|
|
50943
|
+
// src/listDir.ts
|
|
50757
50944
|
var logger17 = createModuleLogger("bridge.listDir");
|
|
50758
50945
|
function shouldIncludeEntry(name) {
|
|
50759
50946
|
if (!name.startsWith(".")) return true;
|
|
50760
50947
|
return name === ".ahchat-attachments";
|
|
50761
50948
|
}
|
|
50762
50949
|
async function listDirectoryEntries(dirPath) {
|
|
50763
|
-
|
|
50764
|
-
|
|
50950
|
+
const resolvedDirPath = resolveUserPath(dirPath);
|
|
50951
|
+
logger17.info("listDirectoryEntries start", { path: dirPath, resolvedPath: resolvedDirPath });
|
|
50952
|
+
const raw = await import_promises10.default.readdir(resolvedDirPath, { withFileTypes: true });
|
|
50765
50953
|
const entries = [];
|
|
50766
50954
|
for (const entry of raw) {
|
|
50767
50955
|
if (!shouldIncludeEntry(entry.name)) continue;
|
|
50768
|
-
const fullPath =
|
|
50956
|
+
const fullPath = import_node_path12.default.join(resolvedDirPath, entry.name);
|
|
50769
50957
|
const isDir = entry.isDirectory();
|
|
50770
50958
|
let size;
|
|
50771
50959
|
let mtime;
|
|
@@ -50784,6 +50972,7 @@ async function listDirectoryEntries(dirPath) {
|
|
|
50784
50972
|
});
|
|
50785
50973
|
logger17.info("listDirectoryEntries ok", {
|
|
50786
50974
|
path: dirPath,
|
|
50975
|
+
resolvedPath: resolvedDirPath,
|
|
50787
50976
|
count: entries.length,
|
|
50788
50977
|
dirCount: entries.filter((e7) => e7.type === "dir").length,
|
|
50789
50978
|
fileCount: entries.filter((e7) => e7.type === "file").length
|
|
@@ -50793,9 +50982,9 @@ async function listDirectoryEntries(dirPath) {
|
|
|
50793
50982
|
|
|
50794
50983
|
// src/logScanner.ts
|
|
50795
50984
|
init_cjs_shims();
|
|
50796
|
-
var
|
|
50797
|
-
var
|
|
50798
|
-
var
|
|
50985
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
50986
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
50987
|
+
var import_node_os9 = __toESM(require("os"), 1);
|
|
50799
50988
|
var import_node_readline = __toESM(require("readline"), 1);
|
|
50800
50989
|
var logger18 = createModuleLogger("bridge.logScanner");
|
|
50801
50990
|
var DEFAULT_LIMIT = 500;
|
|
@@ -50803,17 +50992,17 @@ var MAX_LIMIT = 2e3;
|
|
|
50803
50992
|
function listLogFiles(logsDir, baseName) {
|
|
50804
50993
|
let names;
|
|
50805
50994
|
try {
|
|
50806
|
-
names =
|
|
50995
|
+
names = import_node_fs5.default.readdirSync(logsDir);
|
|
50807
50996
|
} catch (e7) {
|
|
50808
50997
|
logger18.warn("listLogFiles: readdir failed", { logsDir, error: e7 });
|
|
50809
50998
|
return [];
|
|
50810
50999
|
}
|
|
50811
51000
|
const pattern = new RegExp(`^${baseName.replace(".", "\\.")}(\\.\\d+)?$`);
|
|
50812
|
-
return names.filter((n2) => pattern.test(n2)).map((n2) =>
|
|
51001
|
+
return names.filter((n2) => pattern.test(n2)).map((n2) => import_node_path13.default.join(logsDir, n2));
|
|
50813
51002
|
}
|
|
50814
51003
|
async function scanFile(filePath, source, filter, limit, state) {
|
|
50815
|
-
const file2 =
|
|
50816
|
-
const stream =
|
|
51004
|
+
const file2 = import_node_path13.default.basename(filePath);
|
|
51005
|
+
const stream = import_node_fs5.default.createReadStream(filePath, { encoding: "utf-8" });
|
|
50817
51006
|
const rl2 = import_node_readline.default.createInterface({ input: stream, crlfDelay: Infinity });
|
|
50818
51007
|
let lineNum = 0;
|
|
50819
51008
|
for await (const line of rl2) {
|
|
@@ -50851,7 +51040,7 @@ async function scanLocalLogs(logsDir, baseName, filter) {
|
|
|
50851
51040
|
};
|
|
50852
51041
|
}
|
|
50853
51042
|
async function scanBridgeLogs(filter) {
|
|
50854
|
-
const logDir =
|
|
51043
|
+
const logDir = import_node_path13.default.join(import_node_os9.default.homedir(), ".ahchat", "logs");
|
|
50855
51044
|
logger18.info("scanBridgeLogs start", {
|
|
50856
51045
|
logDir,
|
|
50857
51046
|
startIso: filter.startIso,
|
|
@@ -50869,15 +51058,15 @@ async function scanBridgeLogs(filter) {
|
|
|
50869
51058
|
|
|
50870
51059
|
// src/skillStore.ts
|
|
50871
51060
|
init_cjs_shims();
|
|
50872
|
-
var
|
|
50873
|
-
var
|
|
51061
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
51062
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
50874
51063
|
var logger19 = createModuleLogger("bridge.skillStore");
|
|
50875
51064
|
var ALLOWED_NAMES = /* @__PURE__ */ new Set(["log-analysis"]);
|
|
50876
51065
|
var SkillStore = class {
|
|
50877
51066
|
skillsDir;
|
|
50878
51067
|
constructor(dataDir) {
|
|
50879
|
-
this.skillsDir =
|
|
50880
|
-
|
|
51068
|
+
this.skillsDir = import_node_path14.default.join(dataDir, "skills");
|
|
51069
|
+
import_node_fs6.default.mkdirSync(this.skillsDir, { recursive: true });
|
|
50881
51070
|
logger19.info("SkillStore initialized", { skillsDir: this.skillsDir });
|
|
50882
51071
|
}
|
|
50883
51072
|
read(name) {
|
|
@@ -50885,9 +51074,9 @@ var SkillStore = class {
|
|
|
50885
51074
|
logger19.warn("Skill read: unknown name", { name, allowed: [...ALLOWED_NAMES] });
|
|
50886
51075
|
return "";
|
|
50887
51076
|
}
|
|
50888
|
-
const filePath =
|
|
51077
|
+
const filePath = import_node_path14.default.join(this.skillsDir, `${name}.md`);
|
|
50889
51078
|
try {
|
|
50890
|
-
const content =
|
|
51079
|
+
const content = import_node_fs6.default.readFileSync(filePath, "utf-8");
|
|
50891
51080
|
logger19.info("Skill read", { name, bytes: content.length });
|
|
50892
51081
|
return content;
|
|
50893
51082
|
} catch (e7) {
|
|
@@ -50900,19 +51089,19 @@ var SkillStore = class {
|
|
|
50900
51089
|
if (!ALLOWED_NAMES.has(name)) {
|
|
50901
51090
|
throw new Error(`Unknown skill name: ${name}`);
|
|
50902
51091
|
}
|
|
50903
|
-
const filePath =
|
|
51092
|
+
const filePath = import_node_path14.default.join(this.skillsDir, `${name}.md`);
|
|
50904
51093
|
const tmpPath = `${filePath}.tmp`;
|
|
50905
51094
|
let existing = "";
|
|
50906
51095
|
try {
|
|
50907
|
-
existing =
|
|
51096
|
+
existing = import_node_fs6.default.readFileSync(filePath, "utf-8");
|
|
50908
51097
|
} catch {
|
|
50909
51098
|
}
|
|
50910
51099
|
if (existing === content) {
|
|
50911
51100
|
logger19.info("Skill already in sync", { name, bytes: content.length });
|
|
50912
51101
|
return;
|
|
50913
51102
|
}
|
|
50914
|
-
|
|
50915
|
-
|
|
51103
|
+
import_node_fs6.default.writeFileSync(tmpPath, content, "utf-8");
|
|
51104
|
+
import_node_fs6.default.renameSync(tmpPath, filePath);
|
|
50916
51105
|
logger19.info("Skill seeded/re-synced", {
|
|
50917
51106
|
name,
|
|
50918
51107
|
bytes: content.length,
|
|
@@ -50923,8 +51112,8 @@ var SkillStore = class {
|
|
|
50923
51112
|
|
|
50924
51113
|
// src/lockfile.ts
|
|
50925
51114
|
init_cjs_shims();
|
|
50926
|
-
var
|
|
50927
|
-
var
|
|
51115
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
51116
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
50928
51117
|
var logger20 = createModuleLogger("bridge.lockfile");
|
|
50929
51118
|
var lockPath = null;
|
|
50930
51119
|
function isProcessAlive(pid) {
|
|
@@ -50938,10 +51127,10 @@ function isProcessAlive(pid) {
|
|
|
50938
51127
|
}
|
|
50939
51128
|
}
|
|
50940
51129
|
function acquireLock(dataDir) {
|
|
50941
|
-
const file2 =
|
|
51130
|
+
const file2 = import_node_path15.default.join(dataDir, "bridge.lock");
|
|
50942
51131
|
lockPath = file2;
|
|
50943
|
-
if (
|
|
50944
|
-
const raw =
|
|
51132
|
+
if (import_node_fs7.default.existsSync(file2)) {
|
|
51133
|
+
const raw = import_node_fs7.default.readFileSync(file2, "utf-8").trim();
|
|
50945
51134
|
const pid = Number.parseInt(raw, 10);
|
|
50946
51135
|
if (Number.isFinite(pid) && pid > 0) {
|
|
50947
51136
|
if (isProcessAlive(pid)) {
|
|
@@ -50950,15 +51139,15 @@ function acquireLock(dataDir) {
|
|
|
50950
51139
|
logger20.warn("Removing stale bridge.lock (process not found)", { pid, path: file2 });
|
|
50951
51140
|
}
|
|
50952
51141
|
}
|
|
50953
|
-
|
|
50954
|
-
|
|
51142
|
+
import_node_fs7.default.mkdirSync(import_node_path15.default.dirname(file2), { recursive: true });
|
|
51143
|
+
import_node_fs7.default.writeFileSync(file2, String(process.pid), "utf-8");
|
|
50955
51144
|
logger20.info("Acquired bridge lock", { path: file2, pid: process.pid });
|
|
50956
51145
|
const release = () => {
|
|
50957
51146
|
try {
|
|
50958
|
-
if (lockPath &&
|
|
50959
|
-
const current =
|
|
51147
|
+
if (lockPath && import_node_fs7.default.existsSync(lockPath)) {
|
|
51148
|
+
const current = import_node_fs7.default.readFileSync(lockPath, "utf-8").trim();
|
|
50960
51149
|
if (current === String(process.pid)) {
|
|
50961
|
-
|
|
51150
|
+
import_node_fs7.default.unlinkSync(lockPath);
|
|
50962
51151
|
logger20.info("Released bridge lock", { path: lockPath });
|
|
50963
51152
|
}
|
|
50964
51153
|
}
|
|
@@ -51319,14 +51508,14 @@ async function handleGroupArchivedPush(deps, payload) {
|
|
|
51319
51508
|
|
|
51320
51509
|
// src/sessionStore.ts
|
|
51321
51510
|
init_cjs_shims();
|
|
51322
|
-
var
|
|
51323
|
-
var
|
|
51511
|
+
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
51512
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
51324
51513
|
var logger23 = createModuleLogger("session.store");
|
|
51325
51514
|
var SessionStore = class {
|
|
51326
51515
|
filePath;
|
|
51327
51516
|
cache;
|
|
51328
51517
|
constructor(dataDir) {
|
|
51329
|
-
this.filePath =
|
|
51518
|
+
this.filePath = import_node_path16.default.join(dataDir, "sessions.json");
|
|
51330
51519
|
this.cache = this.loadFromDisk();
|
|
51331
51520
|
}
|
|
51332
51521
|
cacheKey(agentId, scope) {
|
|
@@ -51361,8 +51550,8 @@ var SessionStore = class {
|
|
|
51361
51550
|
}
|
|
51362
51551
|
loadFromDisk() {
|
|
51363
51552
|
try {
|
|
51364
|
-
if (!
|
|
51365
|
-
const raw =
|
|
51553
|
+
if (!import_node_fs8.default.existsSync(this.filePath)) return {};
|
|
51554
|
+
const raw = import_node_fs8.default.readFileSync(this.filePath, "utf-8");
|
|
51366
51555
|
const parsed = JSON.parse(raw);
|
|
51367
51556
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
|
|
51368
51557
|
const map2 = parsed;
|
|
@@ -51386,9 +51575,9 @@ var SessionStore = class {
|
|
|
51386
51575
|
}
|
|
51387
51576
|
saveToDisk() {
|
|
51388
51577
|
try {
|
|
51389
|
-
const dir =
|
|
51390
|
-
|
|
51391
|
-
|
|
51578
|
+
const dir = import_node_path16.default.dirname(this.filePath);
|
|
51579
|
+
import_node_fs8.default.mkdirSync(dir, { recursive: true });
|
|
51580
|
+
import_node_fs8.default.writeFileSync(this.filePath, JSON.stringify(this.cache, null, 2), "utf-8");
|
|
51392
51581
|
} catch (e7) {
|
|
51393
51582
|
logger23.error("Failed to save sessions file", { error: e7, path: this.filePath });
|
|
51394
51583
|
}
|
|
@@ -51397,9 +51586,9 @@ var SessionStore = class {
|
|
|
51397
51586
|
|
|
51398
51587
|
// src/ensureClaudeCli.ts
|
|
51399
51588
|
init_cjs_shims();
|
|
51400
|
-
var
|
|
51401
|
-
var
|
|
51402
|
-
var
|
|
51589
|
+
var import_node_child_process3 = require("child_process");
|
|
51590
|
+
var import_node_fs9 = require("fs");
|
|
51591
|
+
var import_node_path17 = require("path");
|
|
51403
51592
|
var logger24 = createModuleLogger("bridge.ensureCli");
|
|
51404
51593
|
var DEFAULT_INSTALL_TIMEOUT_MS = 6e5;
|
|
51405
51594
|
function getInstallTimeoutMs() {
|
|
@@ -51408,48 +51597,42 @@ function getInstallTimeoutMs() {
|
|
|
51408
51597
|
const parsed = Number.parseInt(raw, 10);
|
|
51409
51598
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_INSTALL_TIMEOUT_MS;
|
|
51410
51599
|
}
|
|
51411
|
-
function detectClaudeCli() {
|
|
51412
|
-
try {
|
|
51413
|
-
return (0, import_node_child_process2.execFileSync)("claude", ["--version"], { timeout: 1e4 }).toString().trim();
|
|
51414
|
-
} catch {
|
|
51415
|
-
return void 0;
|
|
51416
|
-
}
|
|
51417
|
-
}
|
|
51418
51600
|
function getNpmGlobalBin() {
|
|
51601
|
+
const npm = resolveCommand(["npm"]);
|
|
51602
|
+
if (!npm) return void 0;
|
|
51419
51603
|
try {
|
|
51420
|
-
const bin = (0,
|
|
51604
|
+
const bin = (0, import_node_child_process3.execFileSync)(npm.path, ["bin", "-g"], {
|
|
51605
|
+
env: withAugmentedPathEnv(),
|
|
51606
|
+
timeout: 5e3
|
|
51607
|
+
}).toString().trim() || void 0;
|
|
51421
51608
|
if (bin) return bin;
|
|
51422
51609
|
} catch {
|
|
51423
51610
|
}
|
|
51424
51611
|
try {
|
|
51425
|
-
const prefix = (0,
|
|
51426
|
-
|
|
51612
|
+
const prefix = (0, import_node_child_process3.execFileSync)(npm.path, ["prefix", "-g"], {
|
|
51613
|
+
env: withAugmentedPathEnv(),
|
|
51614
|
+
timeout: 5e3
|
|
51615
|
+
}).toString().trim();
|
|
51616
|
+
if (prefix) return (0, import_node_path17.join)(prefix, "bin");
|
|
51427
51617
|
} catch {
|
|
51428
51618
|
}
|
|
51429
51619
|
return void 0;
|
|
51430
51620
|
}
|
|
51431
51621
|
function resolveClaudeBinary() {
|
|
51432
|
-
|
|
51433
|
-
try {
|
|
51434
|
-
const out = (0, import_node_child_process2.execFileSync)(whichCmd, ["claude"], { timeout: 5e3 }).toString();
|
|
51435
|
-
const first = out.split(/\r?\n/).map((l4) => l4.trim()).find(Boolean);
|
|
51436
|
-
if (first) return first;
|
|
51437
|
-
} catch {
|
|
51438
|
-
}
|
|
51439
|
-
return resolveViaNpmBin();
|
|
51622
|
+
return resolveCommand(["claude", "anthropic-cli"])?.path ?? resolveViaNpmBin();
|
|
51440
51623
|
}
|
|
51441
51624
|
function getNpmClaudeCandidates(bin) {
|
|
51442
51625
|
if (process.platform === "win32") {
|
|
51443
|
-
return ["claude.cmd", "claude.exe", "claude", "anthropic-cli.cmd", "anthropic-cli.exe", "anthropic-cli"].map((name) => (0,
|
|
51626
|
+
return ["claude.cmd", "claude.exe", "claude", "anthropic-cli.cmd", "anthropic-cli.exe", "anthropic-cli"].map((name) => (0, import_node_path17.join)(bin, name));
|
|
51444
51627
|
}
|
|
51445
|
-
return [(0,
|
|
51628
|
+
return [(0, import_node_path17.join)(bin, "claude"), (0, import_node_path17.join)(bin, "anthropic-cli")];
|
|
51446
51629
|
}
|
|
51447
51630
|
function resolveViaNpmBin() {
|
|
51448
51631
|
const bin = getNpmGlobalBin();
|
|
51449
51632
|
if (!bin) return void 0;
|
|
51450
51633
|
for (const candidate of getNpmClaudeCandidates(bin)) {
|
|
51451
51634
|
try {
|
|
51452
|
-
(0,
|
|
51635
|
+
(0, import_node_fs9.accessSync)(candidate, import_node_fs9.constants.X_OK);
|
|
51453
51636
|
return candidate;
|
|
51454
51637
|
} catch {
|
|
51455
51638
|
}
|
|
@@ -51459,40 +51642,32 @@ function resolveViaNpmBin() {
|
|
|
51459
51642
|
function detectViaNpmBin() {
|
|
51460
51643
|
const binPath = resolveViaNpmBin();
|
|
51461
51644
|
if (!binPath) return void 0;
|
|
51462
|
-
|
|
51463
|
-
return (0, import_node_child_process2.execFileSync)(binPath, ["--version"], { timeout: 1e4 }).toString().trim();
|
|
51464
|
-
} catch {
|
|
51465
|
-
}
|
|
51466
|
-
return void 0;
|
|
51645
|
+
return readCommandVersion(binPath);
|
|
51467
51646
|
}
|
|
51468
51647
|
function detectResolvedClaudeCli() {
|
|
51469
|
-
const
|
|
51470
|
-
if (
|
|
51471
|
-
|
|
51472
|
-
}
|
|
51473
|
-
const npmBinPath = resolveViaNpmBin();
|
|
51474
|
-
if (!npmBinPath) return void 0;
|
|
51475
|
-
try {
|
|
51476
|
-
const version2 = (0, import_node_child_process2.execFileSync)(npmBinPath, ["--version"], { timeout: 1e4 }).toString().trim();
|
|
51477
|
-
return { version: version2, path: npmBinPath };
|
|
51478
|
-
} catch {
|
|
51479
|
-
}
|
|
51648
|
+
const resolvedPath = resolveClaudeBinary();
|
|
51649
|
+
if (!resolvedPath) return void 0;
|
|
51650
|
+
const version2 = readCommandVersion(resolvedPath);
|
|
51651
|
+
if (version2) return { version: version2, path: resolvedPath };
|
|
51480
51652
|
return void 0;
|
|
51481
51653
|
}
|
|
51482
51654
|
function detectVersionFromResolvedCandidates() {
|
|
51483
51655
|
const candidates = [resolveClaudeBinary(), resolveViaNpmBin()].filter((p) => Boolean(p));
|
|
51484
51656
|
for (const p of candidates) {
|
|
51485
|
-
|
|
51486
|
-
|
|
51487
|
-
return (0, import_node_child_process2.execFileSync)(p, ["--version"], { timeout: 1e4 }).toString().trim();
|
|
51488
|
-
} catch {
|
|
51489
|
-
}
|
|
51657
|
+
const version2 = readCommandVersion(p);
|
|
51658
|
+
if (version2) return version2;
|
|
51490
51659
|
}
|
|
51491
51660
|
return void 0;
|
|
51492
51661
|
}
|
|
51493
51662
|
function installClaudeCli() {
|
|
51663
|
+
const npm = resolveCommand(["npm"]);
|
|
51664
|
+
if (!npm) {
|
|
51665
|
+
logger24.error("npm not found; cannot install Claude Code CLI");
|
|
51666
|
+
return void 0;
|
|
51667
|
+
}
|
|
51494
51668
|
logger24.info("Installing Claude Code CLI via npm...");
|
|
51495
|
-
const result = (0,
|
|
51669
|
+
const result = (0, import_node_child_process3.spawnSync)(npm.path, ["install", "-g", "@anthropic-ai/claude-code"], {
|
|
51670
|
+
env: withAugmentedPathEnv(),
|
|
51496
51671
|
stdio: "inherit",
|
|
51497
51672
|
timeout: getInstallTimeoutMs()
|
|
51498
51673
|
});
|
|
@@ -51524,7 +51699,10 @@ function installClaudeCli() {
|
|
|
51524
51699
|
logger24.error("claude not found after successful npm install -g", {
|
|
51525
51700
|
npmGlobalBin: npmBin ?? "unknown",
|
|
51526
51701
|
pathDirectories: envPath.split(process.platform === "win32" ? ";" : ":").slice(0, 10),
|
|
51527
|
-
npmPrefix: (0,
|
|
51702
|
+
npmPrefix: (0, import_node_child_process3.execFileSync)(npm.path, ["prefix", "-g"], {
|
|
51703
|
+
env: withAugmentedPathEnv(),
|
|
51704
|
+
timeout: 5e3
|
|
51705
|
+
}).toString().trim() || "unknown"
|
|
51528
51706
|
});
|
|
51529
51707
|
return void 0;
|
|
51530
51708
|
}
|
|
@@ -51554,21 +51732,21 @@ async function ensureClaudeCli() {
|
|
|
51554
51732
|
// src/forkAgentFiles.ts
|
|
51555
51733
|
init_cjs_shims();
|
|
51556
51734
|
var fs11 = __toESM(require("fs/promises"), 1);
|
|
51557
|
-
var
|
|
51735
|
+
var path18 = __toESM(require("path"), 1);
|
|
51558
51736
|
|
|
51559
51737
|
// src/sessionSlug.ts
|
|
51560
51738
|
init_cjs_shims();
|
|
51561
|
-
var
|
|
51562
|
-
var
|
|
51563
|
-
var CLAUDE_PROJECTS_DIR =
|
|
51739
|
+
var import_node_os10 = __toESM(require("os"), 1);
|
|
51740
|
+
var import_node_path18 = __toESM(require("path"), 1);
|
|
51741
|
+
var CLAUDE_PROJECTS_DIR = import_node_path18.default.join(import_node_os10.default.homedir(), ".claude", "projects");
|
|
51564
51742
|
function cwdToSlug(cwd) {
|
|
51565
51743
|
return cwd.replace(/[^a-zA-Z0-9-]/g, "-");
|
|
51566
51744
|
}
|
|
51567
51745
|
function sessionDirForCwd(cwd) {
|
|
51568
|
-
return
|
|
51746
|
+
return import_node_path18.default.join(CLAUDE_PROJECTS_DIR, cwdToSlug(cwd));
|
|
51569
51747
|
}
|
|
51570
51748
|
function sessionFilePath(cwd, sessionId) {
|
|
51571
|
-
return
|
|
51749
|
+
return import_node_path18.default.join(sessionDirForCwd(cwd), `${sessionId}.jsonl`);
|
|
51572
51750
|
}
|
|
51573
51751
|
|
|
51574
51752
|
// src/forkAgentFiles.ts
|
|
@@ -51600,9 +51778,9 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
|
|
|
51600
51778
|
logger25.error("Workdir copy failed", { error: e7 });
|
|
51601
51779
|
throw e7;
|
|
51602
51780
|
}
|
|
51603
|
-
const srcNotebook =
|
|
51604
|
-
const dstNotebookDir =
|
|
51605
|
-
const dstNotebook =
|
|
51781
|
+
const srcNotebook = path18.join(dataDir, "agent-memory", sourceAgentId, "notebook.md");
|
|
51782
|
+
const dstNotebookDir = path18.join(dataDir, "agent-memory", newAgentId);
|
|
51783
|
+
const dstNotebook = path18.join(dstNotebookDir, "notebook.md");
|
|
51606
51784
|
try {
|
|
51607
51785
|
const nbStat = await fs11.stat(srcNotebook).catch(() => null);
|
|
51608
51786
|
if (nbStat?.isFile()) {
|
|
@@ -51629,7 +51807,7 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
|
|
|
51629
51807
|
if (srcStat?.isFile()) {
|
|
51630
51808
|
const dstDir = sessionDirForCwd(newWorkdir);
|
|
51631
51809
|
await fs11.mkdir(dstDir, { recursive: true });
|
|
51632
|
-
const dstPath =
|
|
51810
|
+
const dstPath = path18.join(dstDir, `${sourceSessionId}.jsonl`);
|
|
51633
51811
|
await fs11.copyFile(srcPath, dstPath);
|
|
51634
51812
|
sessionStore.set(newAgentId, { kind: "single" }, sourceSessionId);
|
|
51635
51813
|
sessionCopied = true;
|
|
@@ -51677,12 +51855,12 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
|
|
|
51677
51855
|
// src/modelQuerier.ts
|
|
51678
51856
|
init_cjs_shims();
|
|
51679
51857
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
51680
|
-
var
|
|
51681
|
-
var
|
|
51858
|
+
var import_node_os11 = __toESM(require("os"), 1);
|
|
51859
|
+
var import_node_path19 = __toESM(require("path"), 1);
|
|
51682
51860
|
var logger26 = createModuleLogger("bridge.modelQuerier");
|
|
51683
51861
|
async function listModels(queryFn, opts = {}) {
|
|
51684
51862
|
const t0 = Date.now();
|
|
51685
|
-
const cwd = opts.cwd ??
|
|
51863
|
+
const cwd = opts.cwd ?? import_node_path19.default.join(import_node_os11.default.homedir(), ".ahchat", "workspaces", "_list_models");
|
|
51686
51864
|
await import_promises11.default.mkdir(cwd, { recursive: true });
|
|
51687
51865
|
const fn = queryFn ?? QA$;
|
|
51688
51866
|
const ic2 = new InputController();
|
|
@@ -51745,8 +51923,8 @@ async function listModels(queryFn, opts = {}) {
|
|
|
51745
51923
|
// src/promptOptimizer.ts
|
|
51746
51924
|
init_cjs_shims();
|
|
51747
51925
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
51748
|
-
var
|
|
51749
|
-
var
|
|
51926
|
+
var import_node_os12 = __toESM(require("os"), 1);
|
|
51927
|
+
var import_node_path20 = __toESM(require("path"), 1);
|
|
51750
51928
|
var logger27 = createModuleLogger("bridge.promptOptimizer");
|
|
51751
51929
|
var OPTIMIZER_SYSTEM_PROMPT = `You are an expert prompt editor for AHChat Agent creation.
|
|
51752
51930
|
|
|
@@ -51789,7 +51967,7 @@ async function optimizePrompt(queryFn, opts) {
|
|
|
51789
51967
|
const prompt = opts.systemPrompt.trim();
|
|
51790
51968
|
if (!prompt) throw new Error("systemPrompt is required");
|
|
51791
51969
|
const t0 = Date.now();
|
|
51792
|
-
const cwd = opts.cwd ??
|
|
51970
|
+
const cwd = opts.cwd ?? import_node_path20.default.join(import_node_os12.default.homedir(), ".ahchat", "workspaces", "_prompt_optimizer");
|
|
51793
51971
|
await import_promises12.default.mkdir(cwd, { recursive: true });
|
|
51794
51972
|
const fn = queryFn ?? QA$;
|
|
51795
51973
|
const ic2 = new InputController();
|
|
@@ -51877,7 +52055,7 @@ function isRunningAsRoot2() {
|
|
|
51877
52055
|
}
|
|
51878
52056
|
}
|
|
51879
52057
|
async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
|
|
51880
|
-
const rootClaudeDir =
|
|
52058
|
+
const rootClaudeDir = import_node_path21.default.join(process.env.HOME ?? "/root", ".claude");
|
|
51881
52059
|
const fs16 = await import("fs/promises");
|
|
51882
52060
|
try {
|
|
51883
52061
|
await fs16.access(rootClaudeDir);
|
|
@@ -51887,8 +52065,8 @@ async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
|
|
|
51887
52065
|
}
|
|
51888
52066
|
const filesToSync = [".credentials.json", "settings.json", ".credentials.backup.json"];
|
|
51889
52067
|
for (const file2 of filesToSync) {
|
|
51890
|
-
const src =
|
|
51891
|
-
const dest =
|
|
52068
|
+
const src = import_node_path21.default.join(rootClaudeDir, file2);
|
|
52069
|
+
const dest = import_node_path21.default.join(agentConfigDir, file2);
|
|
51892
52070
|
try {
|
|
51893
52071
|
await fs16.copyFile(src, dest);
|
|
51894
52072
|
logger28.info("Synced credential file", { file: file2, from: src, to: dest });
|
|
@@ -51911,7 +52089,7 @@ async function chownRecursive(dirPath, uid, gid) {
|
|
|
51911
52089
|
return;
|
|
51912
52090
|
}
|
|
51913
52091
|
for (const entry of entries) {
|
|
51914
|
-
const fullPath =
|
|
52092
|
+
const fullPath = import_node_path21.default.join(dirPath, entry.name);
|
|
51915
52093
|
if (entry.isDirectory()) {
|
|
51916
52094
|
await chownRecursive(fullPath, uid, gid);
|
|
51917
52095
|
} else {
|
|
@@ -51926,7 +52104,7 @@ async function chownRecursive(dirPath, uid, gid) {
|
|
|
51926
52104
|
async function startBridge(config2) {
|
|
51927
52105
|
ensureDir(config2.dataDir);
|
|
51928
52106
|
ensureDir(config2.agentConfigDir);
|
|
51929
|
-
const workspacesDir =
|
|
52107
|
+
const workspacesDir = import_node_path21.default.join(config2.dataDir, "workspaces");
|
|
51930
52108
|
ensureDir(workspacesDir);
|
|
51931
52109
|
process.env.CLAUDE_CONFIG_DIR = config2.agentConfigDir;
|
|
51932
52110
|
installBridgeFetchAuth(config2.serverApiUrl, config2.bridgeToken);
|
|
@@ -51955,7 +52133,7 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
|
|
|
51955
52133
|
`);
|
|
51956
52134
|
wsMetrics.start(5e3);
|
|
51957
52135
|
const sessionStore = new SessionStore(config2.dataDir);
|
|
51958
|
-
const memoryRoot =
|
|
52136
|
+
const memoryRoot = import_node_path21.default.join(config2.dataDir, "agent-memory");
|
|
51959
52137
|
const memoryStore = new AgentMemoryStore(memoryRoot);
|
|
51960
52138
|
logger28.info("Agent memory store initialized", { rootDir: memoryRoot });
|
|
51961
52139
|
const smithNotebook = memoryStore.read(SMITH_AGENT_ID);
|
|
@@ -52384,21 +52562,58 @@ function compactEnv(env2) {
|
|
|
52384
52562
|
|
|
52385
52563
|
// src/protocol.ts
|
|
52386
52564
|
init_cjs_shims();
|
|
52387
|
-
var
|
|
52388
|
-
var
|
|
52389
|
-
var
|
|
52390
|
-
var
|
|
52565
|
+
var import_node_child_process4 = require("child_process");
|
|
52566
|
+
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
52567
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
52568
|
+
var import_node_path22 = __toESM(require("path"), 1);
|
|
52391
52569
|
var logger29 = createModuleLogger("bridge.protocol");
|
|
52570
|
+
function shellSingleQuote(value) {
|
|
52571
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
52572
|
+
}
|
|
52573
|
+
function psSingleQuote(value) {
|
|
52574
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
52575
|
+
}
|
|
52576
|
+
function desktopExecQuote(value) {
|
|
52577
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
52578
|
+
}
|
|
52579
|
+
function getStableCliPath() {
|
|
52580
|
+
return import_node_path22.default.join(import_node_os13.default.homedir(), ".ahchat", "bridge", "cli.cjs");
|
|
52581
|
+
}
|
|
52392
52582
|
function getStableExePath() {
|
|
52393
|
-
const bridgeDir =
|
|
52394
|
-
|
|
52395
|
-
const stablePath =
|
|
52396
|
-
|
|
52397
|
-
if (process.platform !== "win32")
|
|
52583
|
+
const bridgeDir = import_node_path22.default.join(import_node_os13.default.homedir(), ".ahchat", "bridge");
|
|
52584
|
+
import_node_fs10.default.mkdirSync(bridgeDir, { recursive: true });
|
|
52585
|
+
const stablePath = getStableCliPath();
|
|
52586
|
+
import_node_fs10.default.copyFileSync(__filename, stablePath);
|
|
52587
|
+
if (process.platform !== "win32") import_node_fs10.default.chmodSync(stablePath, 493);
|
|
52398
52588
|
return stablePath;
|
|
52399
52589
|
}
|
|
52590
|
+
function writePosixLauncher(bridgeDir, stableExePath) {
|
|
52591
|
+
const launchScriptPath = import_node_path22.default.join(bridgeDir, "launch-bridge.sh");
|
|
52592
|
+
const augmentedPath = buildAugmentedPath();
|
|
52593
|
+
import_node_fs10.default.writeFileSync(
|
|
52594
|
+
launchScriptPath,
|
|
52595
|
+
[
|
|
52596
|
+
"#!/bin/bash",
|
|
52597
|
+
"set -e",
|
|
52598
|
+
`export PATH=${shellSingleQuote(augmentedPath)}:"\${PATH:-}"`,
|
|
52599
|
+
`SAVED_NODE=${shellSingleQuote(process.execPath)}`,
|
|
52600
|
+
`BRIDGE_CLI=${shellSingleQuote(stableExePath)}`,
|
|
52601
|
+
'NODE_BIN=""',
|
|
52602
|
+
'if [ -x "$SAVED_NODE" ]; then NODE_BIN="$SAVED_NODE"; fi',
|
|
52603
|
+
'if [ -z "$NODE_BIN" ]; then NODE_BIN="$(command -v node || true)"; fi',
|
|
52604
|
+
'if [ -z "$NODE_BIN" ]; then',
|
|
52605
|
+
` echo "Node.js ${MIN_NODE_MAJOR}+ is required to launch AHChat Bridge. Install Node, then rerun: npx -y @fangyb/ahchat-bridge install" >&2`,
|
|
52606
|
+
" exit 1",
|
|
52607
|
+
"fi",
|
|
52608
|
+
'exec "$NODE_BIN" "$BRIDGE_CLI" launch --url "$1"',
|
|
52609
|
+
""
|
|
52610
|
+
].join("\n")
|
|
52611
|
+
);
|
|
52612
|
+
import_node_fs10.default.chmodSync(launchScriptPath, 493);
|
|
52613
|
+
return launchScriptPath;
|
|
52614
|
+
}
|
|
52400
52615
|
function registerProtocolHandler() {
|
|
52401
|
-
const platform =
|
|
52616
|
+
const platform = import_node_os13.default.platform();
|
|
52402
52617
|
if (platform === "win32") {
|
|
52403
52618
|
registerWindows();
|
|
52404
52619
|
} else if (platform === "darwin") {
|
|
@@ -52411,22 +52626,42 @@ function registerProtocolHandler() {
|
|
|
52411
52626
|
function registerWindows() {
|
|
52412
52627
|
const nodeExe = process.execPath;
|
|
52413
52628
|
const stableExePath = getStableExePath();
|
|
52414
|
-
const bridgeDir =
|
|
52415
|
-
const
|
|
52416
|
-
|
|
52629
|
+
const bridgeDir = import_node_path22.default.join(import_node_os13.default.homedir(), ".ahchat", "bridge");
|
|
52630
|
+
const augmentedPath = buildAugmentedPath();
|
|
52631
|
+
const psLauncherPath = import_node_path22.default.join(bridgeDir, "launch-bridge.ps1");
|
|
52632
|
+
import_node_fs10.default.writeFileSync(
|
|
52417
52633
|
psLauncherPath,
|
|
52418
52634
|
[
|
|
52419
52635
|
`param([string]$url)`,
|
|
52420
|
-
|
|
52636
|
+
`$env:PATH = ${psSingleQuote(augmentedPath)} + [System.IO.Path]::PathSeparator + $env:PATH`,
|
|
52637
|
+
`$candidates = @(`,
|
|
52638
|
+
` ${psSingleQuote(nodeExe)},`,
|
|
52639
|
+
` "$env:NVM_SYMLINK\\node.exe",`,
|
|
52640
|
+
` "$env:ProgramFiles\\nodejs\\node.exe",`,
|
|
52641
|
+
` "$env:LOCALAPPDATA\\Programs\\nodejs\\node.exe"`,
|
|
52642
|
+
`)`,
|
|
52643
|
+
`$node = $null`,
|
|
52644
|
+
`foreach ($candidate in $candidates) {`,
|
|
52645
|
+
` if ($candidate -and (Test-Path $candidate)) { $node = $candidate; break }`,
|
|
52646
|
+
`}`,
|
|
52647
|
+
`if (-not $node) {`,
|
|
52648
|
+
` $cmd = Get-Command node -ErrorAction SilentlyContinue`,
|
|
52649
|
+
` if ($cmd) { $node = $cmd.Source }`,
|
|
52650
|
+
`}`,
|
|
52651
|
+
`if (-not $node) {`,
|
|
52652
|
+
` Write-Error 'Node.js ${MIN_NODE_MAJOR}+ is required to launch AHChat Bridge. Install Node, then rerun: npx -y @fangyb/ahchat-bridge install'`,
|
|
52653
|
+
` exit 1`,
|
|
52654
|
+
`}`,
|
|
52655
|
+
`& $node ${psSingleQuote(stableExePath)} launch --url $url`
|
|
52421
52656
|
].join("\r\n")
|
|
52422
52657
|
);
|
|
52423
52658
|
const handlerValue = `powershell -ExecutionPolicy Bypass -File "${psLauncherPath}" -url "%1"`;
|
|
52424
|
-
const psRegisterPath =
|
|
52425
|
-
|
|
52659
|
+
const psRegisterPath = import_node_path22.default.join(bridgeDir, "register-protocol.ps1");
|
|
52660
|
+
import_node_fs10.default.writeFileSync(
|
|
52426
52661
|
psRegisterPath,
|
|
52427
52662
|
[
|
|
52428
|
-
`$handler =
|
|
52429
|
-
`$icon =
|
|
52663
|
+
`$handler = ${psSingleQuote(handlerValue)}`,
|
|
52664
|
+
`$icon = ${psSingleQuote(nodeExe)}`,
|
|
52430
52665
|
`New-Item -Path 'HKCU:\\Software\\Classes\\ahchat' -Force | Out-Null`,
|
|
52431
52666
|
`Set-ItemProperty -Path 'HKCU:\\Software\\Classes\\ahchat' -Name '(Default)' -Value 'URL:ahchat' -Force`,
|
|
52432
52667
|
`New-ItemProperty -Path 'HKCU:\\Software\\Classes\\ahchat' -Name 'URL Protocol' -Value '' -PropertyType String -Force | Out-Null`,
|
|
@@ -52437,7 +52672,7 @@ function registerWindows() {
|
|
|
52437
52672
|
].join("\r\n")
|
|
52438
52673
|
);
|
|
52439
52674
|
try {
|
|
52440
|
-
(0,
|
|
52675
|
+
(0, import_node_child_process4.execSync)(`powershell -ExecutionPolicy Bypass -File "${psRegisterPath}"`, { stdio: "pipe" });
|
|
52441
52676
|
} catch (e7) {
|
|
52442
52677
|
logger29.error("Failed to register Windows protocol handler", { error: e7 });
|
|
52443
52678
|
throw new Error("Failed to register Windows protocol handler");
|
|
@@ -52445,18 +52680,10 @@ function registerWindows() {
|
|
|
52445
52680
|
logger29.info("Windows protocol handler registered", { psLauncherPath });
|
|
52446
52681
|
}
|
|
52447
52682
|
function registerMacOS() {
|
|
52448
|
-
const appDir =
|
|
52449
|
-
const nodeExe = process.execPath;
|
|
52683
|
+
const appDir = import_node_path22.default.join(import_node_os13.default.homedir(), "Applications", "AHChatBridge.app");
|
|
52450
52684
|
const stableExePath = getStableExePath();
|
|
52451
|
-
const bridgeDir =
|
|
52452
|
-
const launchScriptPath =
|
|
52453
|
-
import_node_fs9.default.writeFileSync(
|
|
52454
|
-
launchScriptPath,
|
|
52455
|
-
`#!/bin/bash
|
|
52456
|
-
exec ${JSON.stringify(nodeExe)} ${JSON.stringify(stableExePath)} launch --url "$1"
|
|
52457
|
-
`
|
|
52458
|
-
);
|
|
52459
|
-
import_node_fs9.default.chmodSync(launchScriptPath, 493);
|
|
52685
|
+
const bridgeDir = import_node_path22.default.join(import_node_os13.default.homedir(), ".ahchat", "bridge");
|
|
52686
|
+
const launchScriptPath = writePosixLauncher(bridgeDir, stableExePath);
|
|
52460
52687
|
const escapedScriptPath = launchScriptPath.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
52461
52688
|
const appleScript = [
|
|
52462
52689
|
`on open location thisURL`,
|
|
@@ -52464,29 +52691,29 @@ exec ${JSON.stringify(nodeExe)} ${JSON.stringify(stableExePath)} launch --url "$
|
|
|
52464
52691
|
` do shell script "/bin/bash " & (quoted form of launchScript) & " " & (quoted form of thisURL) & " >/tmp/ahchat-bridge.log 2>&1 &"`,
|
|
52465
52692
|
`end open location`
|
|
52466
52693
|
].join("\n");
|
|
52467
|
-
const tmpScript =
|
|
52468
|
-
|
|
52694
|
+
const tmpScript = import_node_path22.default.join(import_node_os13.default.tmpdir(), "AHChatBridge.applescript");
|
|
52695
|
+
import_node_fs10.default.writeFileSync(tmpScript, appleScript);
|
|
52469
52696
|
try {
|
|
52470
|
-
|
|
52697
|
+
import_node_fs10.default.rmSync(appDir, { recursive: true, force: true });
|
|
52471
52698
|
} catch {
|
|
52472
52699
|
}
|
|
52473
52700
|
try {
|
|
52474
|
-
(0,
|
|
52701
|
+
(0, import_node_child_process4.execSync)(`osacompile -o ${JSON.stringify(appDir)} ${JSON.stringify(tmpScript)}`, { stdio: "pipe" });
|
|
52475
52702
|
} finally {
|
|
52476
52703
|
try {
|
|
52477
|
-
|
|
52704
|
+
import_node_fs10.default.unlinkSync(tmpScript);
|
|
52478
52705
|
} catch {
|
|
52479
52706
|
}
|
|
52480
52707
|
}
|
|
52481
|
-
const plistPath =
|
|
52708
|
+
const plistPath = import_node_path22.default.join(appDir, "Contents", "Info.plist");
|
|
52482
52709
|
const urlTypes = JSON.stringify([{ CFBundleURLName: "AHChat Bridge", CFBundleURLSchemes: ["ahchat"] }]);
|
|
52483
|
-
(0,
|
|
52710
|
+
(0, import_node_child_process4.execSync)(
|
|
52484
52711
|
`/usr/bin/plutil -insert CFBundleURLTypes -json ${JSON.stringify(urlTypes)} ${JSON.stringify(plistPath)}`,
|
|
52485
52712
|
{ stdio: "pipe" }
|
|
52486
52713
|
);
|
|
52487
52714
|
const lsregister = "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister";
|
|
52488
52715
|
try {
|
|
52489
|
-
(0,
|
|
52716
|
+
(0, import_node_child_process4.execSync)(`${lsregister} -f ${JSON.stringify(appDir)}`, { stdio: "pipe" });
|
|
52490
52717
|
} catch (e7) {
|
|
52491
52718
|
logger29.warn("lsregister failed; URL scheme registration may be delayed", { error: e7 });
|
|
52492
52719
|
}
|
|
@@ -52494,36 +52721,38 @@ exec ${JSON.stringify(nodeExe)} ${JSON.stringify(stableExePath)} launch --url "$
|
|
|
52494
52721
|
}
|
|
52495
52722
|
function registerLinux() {
|
|
52496
52723
|
const stableExePath = getStableExePath();
|
|
52724
|
+
const bridgeDir = import_node_path22.default.join(import_node_os13.default.homedir(), ".ahchat", "bridge");
|
|
52725
|
+
const launchScriptPath = writePosixLauncher(bridgeDir, stableExePath);
|
|
52497
52726
|
const desktopFile = [
|
|
52498
52727
|
`[Desktop Entry]`,
|
|
52499
52728
|
`Name=AHChat Bridge`,
|
|
52500
|
-
`Exec=${
|
|
52729
|
+
`Exec=${desktopExecQuote(launchScriptPath)} %u`,
|
|
52501
52730
|
`Type=Application`,
|
|
52502
52731
|
`NoDisplay=true`,
|
|
52503
52732
|
`MimeType=x-scheme-handler/ahchat;`
|
|
52504
52733
|
].join("\n");
|
|
52505
|
-
const desktopPath =
|
|
52506
|
-
|
|
52507
|
-
|
|
52734
|
+
const desktopPath = import_node_path22.default.join(import_node_os13.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
|
|
52735
|
+
import_node_fs10.default.mkdirSync(import_node_path22.default.dirname(desktopPath), { recursive: true });
|
|
52736
|
+
import_node_fs10.default.writeFileSync(desktopPath, desktopFile);
|
|
52508
52737
|
try {
|
|
52509
|
-
(0,
|
|
52738
|
+
(0, import_node_child_process4.execSync)("update-desktop-database ~/.local/share/applications/", { stdio: "pipe" });
|
|
52510
52739
|
} catch (e7) {
|
|
52511
52740
|
logger29.warn("update-desktop-database not available; run it manually if needed", { error: e7 });
|
|
52512
52741
|
}
|
|
52513
52742
|
logger29.info("Linux protocol handler registered", { desktopPath });
|
|
52514
52743
|
}
|
|
52515
52744
|
function unregisterProtocolHandler() {
|
|
52516
|
-
const platform =
|
|
52745
|
+
const platform = import_node_os13.default.platform();
|
|
52517
52746
|
if (platform === "win32") {
|
|
52518
52747
|
try {
|
|
52519
|
-
(0,
|
|
52748
|
+
(0, import_node_child_process4.execSync)(
|
|
52520
52749
|
`powershell -ExecutionPolicy Bypass -Command "Remove-Item -Path 'HKCU:\\Software\\Classes\\ahchat' -Recurse -Force -ErrorAction SilentlyContinue"`,
|
|
52521
52750
|
{ stdio: "pipe" }
|
|
52522
52751
|
);
|
|
52523
|
-
const bridgeDir =
|
|
52752
|
+
const bridgeDir = import_node_path22.default.join(import_node_os13.default.homedir(), ".ahchat", "bridge");
|
|
52524
52753
|
for (const f7 of ["launch-bridge.ps1", "register-protocol.ps1"]) {
|
|
52525
52754
|
try {
|
|
52526
|
-
|
|
52755
|
+
import_node_fs10.default.unlinkSync(import_node_path22.default.join(bridgeDir, f7));
|
|
52527
52756
|
} catch {
|
|
52528
52757
|
}
|
|
52529
52758
|
}
|
|
@@ -52532,17 +52761,17 @@ function unregisterProtocolHandler() {
|
|
|
52532
52761
|
logger29.warn("Failed to unregister Windows protocol handler", { error: e7 });
|
|
52533
52762
|
}
|
|
52534
52763
|
} else if (platform === "darwin") {
|
|
52535
|
-
const appDir =
|
|
52764
|
+
const appDir = import_node_path22.default.join(import_node_os13.default.homedir(), "Applications", "AHChatBridge.app");
|
|
52536
52765
|
try {
|
|
52537
|
-
|
|
52766
|
+
import_node_fs10.default.rmSync(appDir, { recursive: true, force: true });
|
|
52538
52767
|
logger29.info("macOS protocol handler unregistered");
|
|
52539
52768
|
} catch (e7) {
|
|
52540
52769
|
logger29.warn("Failed to unregister macOS protocol handler", { error: e7 });
|
|
52541
52770
|
}
|
|
52542
52771
|
} else {
|
|
52543
|
-
const desktopPath =
|
|
52772
|
+
const desktopPath = import_node_path22.default.join(import_node_os13.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
|
|
52544
52773
|
try {
|
|
52545
|
-
|
|
52774
|
+
import_node_fs10.default.unlinkSync(desktopPath);
|
|
52546
52775
|
logger29.info("Linux protocol handler unregistered");
|
|
52547
52776
|
} catch (e7) {
|
|
52548
52777
|
logger29.warn("Failed to unregister Linux protocol handler", { error: e7 });
|
|
@@ -52550,20 +52779,21 @@ function unregisterProtocolHandler() {
|
|
|
52550
52779
|
}
|
|
52551
52780
|
}
|
|
52552
52781
|
function isProtocolRegistered() {
|
|
52553
|
-
const platform =
|
|
52782
|
+
const platform = import_node_os13.default.platform();
|
|
52783
|
+
const stableCliExists = import_node_fs10.default.existsSync(getStableCliPath());
|
|
52554
52784
|
if (platform === "win32") {
|
|
52555
52785
|
try {
|
|
52556
|
-
(0,
|
|
52557
|
-
return
|
|
52786
|
+
(0, import_node_child_process4.execSync)('REG QUERY "HKCU\\Software\\Classes\\ahchat" /ve', { stdio: "pipe" });
|
|
52787
|
+
return stableCliExists;
|
|
52558
52788
|
} catch {
|
|
52559
52789
|
return false;
|
|
52560
52790
|
}
|
|
52561
52791
|
} else if (platform === "darwin") {
|
|
52562
|
-
const appDir =
|
|
52563
|
-
return
|
|
52792
|
+
const appDir = import_node_path22.default.join(import_node_os13.default.homedir(), "Applications", "AHChatBridge.app");
|
|
52793
|
+
return stableCliExists && import_node_fs10.default.existsSync(import_node_path22.default.join(appDir, "Contents", "Info.plist"));
|
|
52564
52794
|
} else {
|
|
52565
|
-
const desktopPath =
|
|
52566
|
-
return
|
|
52795
|
+
const desktopPath = import_node_path22.default.join(import_node_os13.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
|
|
52796
|
+
return stableCliExists && import_node_fs10.default.existsSync(desktopPath);
|
|
52567
52797
|
}
|
|
52568
52798
|
}
|
|
52569
52799
|
|
|
@@ -52571,14 +52801,14 @@ function isProtocolRegistered() {
|
|
|
52571
52801
|
var logger30 = createModuleLogger("bridge");
|
|
52572
52802
|
function readCliVersion() {
|
|
52573
52803
|
const candidates = [
|
|
52574
|
-
|
|
52575
|
-
|
|
52576
|
-
|
|
52804
|
+
import_node_path23.default.resolve(__dirname, "../package.json"),
|
|
52805
|
+
import_node_path23.default.resolve(__dirname, "../../package.json"),
|
|
52806
|
+
import_node_path23.default.resolve(process.cwd(), "packages/bridge/package.json")
|
|
52577
52807
|
];
|
|
52578
52808
|
for (const candidate of candidates) {
|
|
52579
|
-
if (!
|
|
52809
|
+
if (!import_node_fs11.default.existsSync(candidate)) continue;
|
|
52580
52810
|
try {
|
|
52581
|
-
const parsed = JSON.parse(
|
|
52811
|
+
const parsed = JSON.parse(import_node_fs11.default.readFileSync(candidate, "utf8"));
|
|
52582
52812
|
if (parsed && typeof parsed === "object" && "version" in parsed && typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
52583
52813
|
return parsed.version;
|
|
52584
52814
|
}
|
|
@@ -52588,25 +52818,6 @@ function readCliVersion() {
|
|
|
52588
52818
|
}
|
|
52589
52819
|
return "0.1.21";
|
|
52590
52820
|
}
|
|
52591
|
-
function resolveDataDir(dataDir) {
|
|
52592
|
-
const userHome = process.env.USERPROFILE || import_node_os13.default.homedir();
|
|
52593
|
-
if (/^~[/\\]/.test(dataDir)) {
|
|
52594
|
-
return import_node_path22.default.join(import_node_os13.default.homedir(), dataDir.slice(2));
|
|
52595
|
-
}
|
|
52596
|
-
if (dataDir === "$env:USERPROFILE") {
|
|
52597
|
-
return userHome;
|
|
52598
|
-
}
|
|
52599
|
-
if (dataDir.startsWith("$env:USERPROFILE\\") || dataDir.startsWith("$env:USERPROFILE/")) {
|
|
52600
|
-
return import_node_path22.default.join(userHome, dataDir.slice("$env:USERPROFILE".length + 1));
|
|
52601
|
-
}
|
|
52602
|
-
if (dataDir === "%USERPROFILE%") {
|
|
52603
|
-
return userHome;
|
|
52604
|
-
}
|
|
52605
|
-
if (dataDir.startsWith("%USERPROFILE%\\") || dataDir.startsWith("%USERPROFILE%/")) {
|
|
52606
|
-
return import_node_path22.default.join(userHome, dataDir.slice("%USERPROFILE%".length + 1));
|
|
52607
|
-
}
|
|
52608
|
-
return dataDir;
|
|
52609
|
-
}
|
|
52610
52821
|
function parseAhchatUrl(url2) {
|
|
52611
52822
|
try {
|
|
52612
52823
|
if (!url2.startsWith("ahchat://")) return null;
|
|
@@ -52620,22 +52831,97 @@ function parseAhchatUrl(url2) {
|
|
|
52620
52831
|
const token = decodeURIComponent(rest.slice(lastTilde + 1));
|
|
52621
52832
|
if (!serverUrl || !token) return null;
|
|
52622
52833
|
return { serverUrl, token };
|
|
52623
|
-
} catch {
|
|
52834
|
+
} catch (e7) {
|
|
52835
|
+
logger30.warn("Unable to parse ahchat launch URL", { error: e7 });
|
|
52624
52836
|
return null;
|
|
52625
52837
|
}
|
|
52626
52838
|
}
|
|
52839
|
+
function assertSupportedNode() {
|
|
52840
|
+
const status = getNodeRuntimeStatus();
|
|
52841
|
+
if (status.supported) return;
|
|
52842
|
+
throw new Error(
|
|
52843
|
+
`Node.js ${MIN_NODE_MAJOR}+ is required to run AHChat Bridge. Current version: ${status.version}`
|
|
52844
|
+
);
|
|
52845
|
+
}
|
|
52627
52846
|
async function run(args) {
|
|
52628
|
-
|
|
52847
|
+
assertSupportedNode();
|
|
52848
|
+
process.env.PATH = buildAugmentedPath();
|
|
52849
|
+
const dataDir = args.dataDir ? resolveUserPath(args.dataDir) : void 0;
|
|
52629
52850
|
let config2 = loadBridgeConfig(dataDir ? { dataDir } : void 0);
|
|
52630
52851
|
if (args.serverUrl) {
|
|
52631
|
-
const
|
|
52632
|
-
|
|
52633
|
-
config2 = { ...config2, serverUrl: args.serverUrl, serverApiUrl: httpBase };
|
|
52852
|
+
const urls = normalizeBridgeServerUrls(args.serverUrl);
|
|
52853
|
+
config2 = { ...config2, serverUrl: urls.serverUrl, serverApiUrl: urls.serverApiUrl };
|
|
52634
52854
|
}
|
|
52635
52855
|
if (args.token) config2 = { ...config2, bridgeToken: args.token };
|
|
52636
52856
|
if (args.logLevel) config2 = { ...config2, logLevel: args.logLevel };
|
|
52637
52857
|
await startBridge(config2);
|
|
52638
52858
|
}
|
|
52859
|
+
function buildDoctorReport(args) {
|
|
52860
|
+
process.env.PATH = buildAugmentedPath();
|
|
52861
|
+
const node = getNodeRuntimeStatus();
|
|
52862
|
+
let server = null;
|
|
52863
|
+
if (args.serverUrl) {
|
|
52864
|
+
try {
|
|
52865
|
+
server = { ok: true, ...normalizeBridgeServerUrls(args.serverUrl) };
|
|
52866
|
+
} catch (e7) {
|
|
52867
|
+
server = {
|
|
52868
|
+
ok: false,
|
|
52869
|
+
error: e7 instanceof Error ? e7.message : String(e7)
|
|
52870
|
+
};
|
|
52871
|
+
}
|
|
52872
|
+
}
|
|
52873
|
+
const claude = resolveCommand(["claude", "anthropic-cli"]);
|
|
52874
|
+
return {
|
|
52875
|
+
node,
|
|
52876
|
+
npm: probeCommand("npm"),
|
|
52877
|
+
npx: probeCommand("npx"),
|
|
52878
|
+
claude: claude ? { ok: true, name: claude.name, path: claude.path } : { ok: false, name: "claude", message: "claude was not found on PATH" },
|
|
52879
|
+
dataDir: args.dataDir ? resolveUserPath(args.dataDir) : resolveUserPath("~/.ahchat"),
|
|
52880
|
+
server,
|
|
52881
|
+
tokenProvided: Boolean(args.token),
|
|
52882
|
+
pathPreview: (process.env.PATH ?? "").split(import_node_path23.default.delimiter).slice(0, 12)
|
|
52883
|
+
};
|
|
52884
|
+
}
|
|
52885
|
+
function writeDoctorText(report) {
|
|
52886
|
+
const node = report.node;
|
|
52887
|
+
const npm = report.npm;
|
|
52888
|
+
const npx = report.npx;
|
|
52889
|
+
const claude = report.claude;
|
|
52890
|
+
const server = report.server;
|
|
52891
|
+
const lines = [
|
|
52892
|
+
"AHChat Bridge doctor",
|
|
52893
|
+
`- Node: ${node.supported ? "ok" : "error"} (${node.version}, requires >=${MIN_NODE_MAJOR})`,
|
|
52894
|
+
`- npm: ${npm.ok ? `ok (${npm.version ?? npm.path})` : `missing (${npm.message ?? "not found"})`}`,
|
|
52895
|
+
`- npx: ${npx.ok ? `ok (${npx.version ?? npx.path})` : `missing (${npx.message ?? "not found"})`}`,
|
|
52896
|
+
`- Claude CLI: ${claude.ok ? `ok (${claude.path})` : `missing (${claude.message ?? "not found"})`}`,
|
|
52897
|
+
`- Data dir: ${String(report.dataDir)}`,
|
|
52898
|
+
`- Token: ${report.tokenProvided ? "provided" : "not provided"}`
|
|
52899
|
+
];
|
|
52900
|
+
if (server) {
|
|
52901
|
+
lines.push(
|
|
52902
|
+
server.ok ? `- Server: ok (${server.serverUrl}, api ${server.serverApiUrl})` : `- Server: error (${server.error ?? "invalid URL"})`
|
|
52903
|
+
);
|
|
52904
|
+
}
|
|
52905
|
+
if (!node.supported) {
|
|
52906
|
+
lines.push(`
|
|
52907
|
+
Install Node.js ${MIN_NODE_MAJOR}+ first, then rerun the bridge command.`);
|
|
52908
|
+
} else if (!npm.ok || !npx.ok) {
|
|
52909
|
+
lines.push("\nNode is installed, but npm/npx is not available on PATH. Reinstall Node.js or fix PATH.");
|
|
52910
|
+
} else if (!claude.ok) {
|
|
52911
|
+
lines.push("\nClaude Code CLI is missing. The bridge can try to install it on first run with npm.");
|
|
52912
|
+
}
|
|
52913
|
+
process.stdout.write(`${lines.join("\n")}
|
|
52914
|
+
`);
|
|
52915
|
+
}
|
|
52916
|
+
function doctor(args) {
|
|
52917
|
+
const report = buildDoctorReport(args);
|
|
52918
|
+
if (args.json) {
|
|
52919
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}
|
|
52920
|
+
`);
|
|
52921
|
+
return;
|
|
52922
|
+
}
|
|
52923
|
+
writeDoctorText(report);
|
|
52924
|
+
}
|
|
52639
52925
|
var cli = dist_default("ahchat-bridge");
|
|
52640
52926
|
cli.command("run", "Start the bridge and connect to server").option("--server-url <url>", "WebSocket URL of the AHChat server").option("--token <token>", "Auth token for server registration").option("--data-dir <dir>", "Data directory (default: ~/.ahchat)").option("--log-level <level>", "Log level (default: INFO)").action((args) => {
|
|
52641
52927
|
void run(args).catch((e7) => {
|
|
@@ -52643,6 +52929,9 @@ cli.command("run", "Start the bridge and connect to server").option("--server-ur
|
|
|
52643
52929
|
process.exit(1);
|
|
52644
52930
|
});
|
|
52645
52931
|
});
|
|
52932
|
+
cli.command("doctor", "Check Node, npm, Claude CLI, PATH, and bridge launch options").option("--server-url <url>", "WebSocket URL of the AHChat server").option("--token <token>", "Auth token for server registration").option("--data-dir <dir>", "Data directory (default: ~/.ahchat)").option("--json", "Print machine-readable JSON").action((args) => {
|
|
52933
|
+
doctor(args);
|
|
52934
|
+
});
|
|
52646
52935
|
cli.command("launch", "Launch bridge from ahchat:// URL (called by OS)").option("--url <url>", "ahchat:// URL with server and token params").action((args) => {
|
|
52647
52936
|
const parsed = parseAhchatUrl(args.url);
|
|
52648
52937
|
if (!parsed) {
|