@fangyb/ahchat-bridge 0.1.3 → 0.1.4

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.
@@ -1,15 +1,8 @@
1
- // ../../node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.14_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js
2
- import path from "path";
3
- import { fileURLToPath } from "url";
4
- var getFilename = () => fileURLToPath(import.meta.url);
5
- var getDirname = () => path.dirname(getFilename());
6
- var __dirname = /* @__PURE__ */ getDirname();
7
-
8
1
  // src/config.ts
9
2
  import crypto from "crypto";
10
3
  import fs from "fs";
11
4
  import os from "os";
12
- import path2 from "path";
5
+ import path from "path";
13
6
  var DEFAULT_QUERY_CONFIG = {
14
7
  maxActive: 50,
15
8
  idleTimeoutMs: 6e4,
@@ -63,9 +56,9 @@ function mergeQueryConfig(file) {
63
56
  function loadBridgeConfig() {
64
57
  const dataDir = readEnvString(
65
58
  "AHCHAT_DATA_DIR",
66
- path2.join(os.homedir(), ".ahchat")
59
+ path.join(os.homedir(), ".ahchat")
67
60
  );
68
- const fileConfig = tryReadJsonConfig(path2.join(dataDir, "bridge.json"));
61
+ const fileConfig = tryReadJsonConfig(path.join(dataDir, "bridge.json"));
69
62
  return {
70
63
  serverUrl: readEnvString(
71
64
  "AHCHAT_BRIDGE_SERVER_URL",
@@ -82,7 +75,7 @@ function loadBridgeConfig() {
82
75
  dataDir,
83
76
  dbPath: readEnvString(
84
77
  "AHCHAT_DB_PATH",
85
- fileConfig.dbPath ?? path2.join(dataDir, "data.db")
78
+ fileConfig.dbPath ?? path.join(dataDir, "data.db")
86
79
  ),
87
80
  serverApiUrl: readEnvString(
88
81
  "AHCHAT_SERVER_API_URL",
@@ -97,7 +90,7 @@ function ensureDir(dirPath) {
97
90
 
98
91
  // src/logger.ts
99
92
  import os3 from "os";
100
- import path4 from "path";
93
+ import path3 from "path";
101
94
 
102
95
  // ../logger/src/types.ts
103
96
  var LOG_LEVEL_VALUE = {
@@ -717,7 +710,7 @@ function consoleTransport(opts) {
717
710
  }
718
711
 
719
712
  // ../logger/src/transports/file.ts
720
- import path3 from "path";
713
+ import path2 from "path";
721
714
 
722
715
  // ../../node_modules/.pnpm/rotating-file-stream@3.2.9/node_modules/rotating-file-stream/dist/esm/index.js
723
716
  import { exec } from "child_process";
@@ -762,11 +755,11 @@ var RotatingFileStream = class extends Writable {
762
755
  timeout;
763
756
  timeoutPromise;
764
757
  constructor(generator, options) {
765
- const { encoding, history, maxFiles, maxSize, path: path11 } = options;
758
+ const { encoding, history, maxFiles, maxSize, path: path10 } = options;
766
759
  super({ decodeStrings: true, defaultEncoding: encoding });
767
760
  this.createGzip = createGzip;
768
761
  this.exec = exec;
769
- this.filename = path11 + generator(null);
762
+ this.filename = path10 + generator(null);
770
763
  this.fsCreateReadStream = createReadStream;
771
764
  this.fsCreateWriteStream = createWriteStream;
772
765
  this.fsOpen = open;
@@ -778,7 +771,7 @@ var RotatingFileStream = class extends Writable {
778
771
  this.options = options;
779
772
  this.stdout = process.stdout;
780
773
  if (maxFiles || maxSize)
781
- options.history = path11 + (history ? history : this.generator(null) + ".txt");
774
+ options.history = path10 + (history ? history : this.generator(null) + ".txt");
782
775
  this.on("close", () => this.finished ? null : this.emit("finish"));
783
776
  this.on("finish", () => this.finished = this.clear());
784
777
  (async () => {
@@ -906,9 +899,9 @@ var RotatingFileStream = class extends Writable {
906
899
  return this.move();
907
900
  }
908
901
  async findName() {
909
- const { interval, path: path11, intervalBoundary } = this.options;
902
+ const { interval, path: path10, intervalBoundary } = this.options;
910
903
  for (let index = 1; index < 1e3; ++index) {
911
- const filename = path11 + this.generator(interval && intervalBoundary ? new Date(this.prev) : this.rotation, index);
904
+ const filename = path10 + this.generator(interval && intervalBoundary ? new Date(this.prev) : this.rotation, index);
912
905
  if (!await exists(filename))
913
906
  return filename;
914
907
  }
@@ -938,11 +931,11 @@ var RotatingFileStream = class extends Writable {
938
931
  return this.unlink(filename);
939
932
  }
940
933
  async classical() {
941
- const { compress, path: path11, rotate } = this.options;
934
+ const { compress, path: path10, rotate } = this.options;
942
935
  let rotatedName = "";
943
936
  for (let count = rotate; count > 0; --count) {
944
- const currName = path11 + this.generator(count);
945
- const prevName = count === 1 ? this.filename : path11 + this.generator(count - 1);
937
+ const currName = path10 + this.generator(count);
938
+ const prevName = count === 1 ? this.filename : path10 + this.generator(count - 1);
946
939
  if (!await exists(prevName))
947
940
  continue;
948
941
  if (!rotatedName)
@@ -1335,8 +1328,8 @@ function parseSize(maxSize) {
1335
1328
  }
1336
1329
  function fileTransport(opts) {
1337
1330
  const fmt = opts.formatter ?? jsonFormatter;
1338
- const dir = path3.dirname(opts.path);
1339
- const filename = path3.basename(opts.path);
1331
+ const dir = path2.dirname(opts.path);
1332
+ const filename = path2.basename(opts.path);
1340
1333
  const stream = createStream(filename, {
1341
1334
  path: dir,
1342
1335
  size: opts.rotate?.maxSize ? parseSize(opts.rotate.maxSize) : "50M",
@@ -1356,8 +1349,8 @@ function createLogger(config) {
1356
1349
  // src/logger.ts
1357
1350
  var bridgeConfig = loadBridgeConfig();
1358
1351
  var isTest = !!process.env["VITEST"];
1359
- var LOG_DIR = path4.join(os3.homedir(), ".ahchat", "logs");
1360
- var LOG_FILE = path4.join(LOG_DIR, "bridge.log");
1352
+ var LOG_DIR = path3.join(os3.homedir(), ".ahchat", "logs");
1353
+ var LOG_FILE = path3.join(LOG_DIR, "bridge.log");
1361
1354
  if (!isTest) ensureDir(LOG_DIR);
1362
1355
  function createModuleLogger(module) {
1363
1356
  const transports = [consoleTransport({ formatter: prettyFormatter })];
@@ -1755,7 +1748,7 @@ var wsMetrics = new WsMetrics();
1755
1748
  // src/agentManager.ts
1756
1749
  import fs2 from "fs/promises";
1757
1750
  import os4 from "os";
1758
- import path7 from "path";
1751
+ import path6 from "path";
1759
1752
 
1760
1753
  // src/inputController.ts
1761
1754
  var InputController = class {
@@ -1813,17 +1806,17 @@ var InputController = class {
1813
1806
  };
1814
1807
 
1815
1808
  // src/permissionGuard.ts
1816
- import path6 from "path";
1809
+ import path5 from "path";
1817
1810
 
1818
1811
  // ../shared/src/utils/pathSafety.ts
1819
- import path5 from "path";
1812
+ import path4 from "path";
1820
1813
  function isPathInside(parent, child) {
1821
- const resolvedParent = path5.resolve(parent);
1822
- const resolvedChild = path5.resolve(child);
1814
+ const resolvedParent = path4.resolve(parent);
1815
+ const resolvedChild = path4.resolve(child);
1823
1816
  if (resolvedParent === resolvedChild) return true;
1824
- const rel = path5.relative(resolvedParent, resolvedChild);
1817
+ const rel = path4.relative(resolvedParent, resolvedChild);
1825
1818
  if (rel === "") return true;
1826
- return !rel.startsWith("..") && !path5.isAbsolute(rel);
1819
+ return !rel.startsWith("..") && !path4.isAbsolute(rel);
1827
1820
  }
1828
1821
 
1829
1822
  // src/permissionGuard.ts
@@ -1838,7 +1831,7 @@ function makeCwdPermissionGuard(cwd, agentId, scope, log) {
1838
1831
  if (typeof raw !== "string" || raw.length === 0) {
1839
1832
  return { behavior: "allow" };
1840
1833
  }
1841
- const abs = path6.isAbsolute(raw) ? raw : path6.resolve(cwd, raw);
1834
+ const abs = path5.isAbsolute(raw) ? raw : path5.resolve(cwd, raw);
1842
1835
  if (isPathInside(cwd, abs)) {
1843
1836
  return { behavior: "allow" };
1844
1837
  }
@@ -2888,14 +2881,14 @@ var AgentManager = class {
2888
2881
  this.emit = emit;
2889
2882
  if (typeof options === "function") {
2890
2883
  this.queryFn = options;
2891
- this.workspacesDir = path7.join(os4.homedir(), ".ahchat", "workspaces");
2884
+ this.workspacesDir = path6.join(os4.homedir(), ".ahchat", "workspaces");
2892
2885
  this.queryConfig = DEFAULT_QUERY_CONFIG;
2893
2886
  this.askQuestionRegistry = new AskQuestionRegistry();
2894
2887
  this.neuralBusManager = new NeuralBusManager();
2895
2888
  this.groupRegistry = null;
2896
2889
  } else {
2897
2890
  this.queryFn = options?.queryFn ?? null;
2898
- this.workspacesDir = options?.workspacesDir ?? path7.join(os4.homedir(), ".ahchat", "workspaces");
2891
+ this.workspacesDir = options?.workspacesDir ?? path6.join(os4.homedir(), ".ahchat", "workspaces");
2899
2892
  this.queryConfig = options?.queryConfig ?? DEFAULT_QUERY_CONFIG;
2900
2893
  this.askQuestionRegistry = options?.askQuestionRegistry ?? new AskQuestionRegistry();
2901
2894
  this.neuralBusManager = options?.neuralBusManager ?? new NeuralBusManager();
@@ -3364,7 +3357,7 @@ ${relay.message}`,
3364
3357
  status: existingProc.status
3365
3358
  });
3366
3359
  } else {
3367
- const cwd = agentConfig.workingDirectory || path7.join(this.workspacesDir, agentConfig.id);
3360
+ const cwd = agentConfig.workingDirectory || path6.join(this.workspacesDir, agentConfig.id);
3368
3361
  void this.acquire(agentConfig, scope, cwd).then((proc) => {
3369
3362
  if (suppressEmit) proc.internalRelayId = suppressEmit;
3370
3363
  return this.sendMessage({ ...task, agentId: agentConfig.id, scope });
@@ -3499,7 +3492,7 @@ ${relay.message}`,
3499
3492
  break;
3500
3493
  }
3501
3494
  try {
3502
- const cwd = agent.workingDirectory || path7.join(this.workspacesDir, agent.id);
3495
+ const cwd = agent.workingDirectory || path6.join(this.workspacesDir, agent.id);
3503
3496
  await this.acquire(agent, { kind: "single" }, cwd);
3504
3497
  warmed++;
3505
3498
  logger8.info("Agent process pre-created for recovery", { agentId: agent.id });
@@ -3695,8 +3688,8 @@ var HttpAgentRegistry = class {
3695
3688
  agents = /* @__PURE__ */ new Map();
3696
3689
  apiUrl(suffix) {
3697
3690
  const base = this.serverApiUrl.replace(/\/$/, "");
3698
- const path11 = suffix.startsWith("/") ? suffix : `/${suffix}`;
3699
- return `${base}${path11}`;
3691
+ const path10 = suffix.startsWith("/") ? suffix : `/${suffix}`;
3692
+ return `${base}${path10}`;
3700
3693
  }
3701
3694
  async refresh() {
3702
3695
  try {
@@ -4081,11 +4074,11 @@ var ServerConnector = class {
4081
4074
  // src/modelQuerier.ts
4082
4075
  import fs3 from "fs/promises";
4083
4076
  import os5 from "os";
4084
- import path8 from "path";
4077
+ import path7 from "path";
4085
4078
  var logger12 = createModuleLogger("bridge.modelQuerier");
4086
4079
  async function listModels(queryFn, opts = {}) {
4087
4080
  const t0 = Date.now();
4088
- const cwd = opts.cwd ?? path8.join(os5.homedir(), ".ahchat", "workspaces", "_list_models");
4081
+ const cwd = opts.cwd ?? path7.join(os5.homedir(), ".ahchat", "workspaces", "_list_models");
4089
4082
  await fs3.mkdir(cwd, { recursive: true });
4090
4083
  const fn = queryFn ?? (await import("@anthropic-ai/claude-agent-sdk")).query;
4091
4084
  const ic = new InputController();
@@ -4144,7 +4137,7 @@ async function listModels(queryFn, opts = {}) {
4144
4137
 
4145
4138
  // src/lockfile.ts
4146
4139
  import fs4 from "fs";
4147
- import path9 from "path";
4140
+ import path8 from "path";
4148
4141
  var logger13 = createModuleLogger("bridge.lockfile");
4149
4142
  var lockPath = null;
4150
4143
  function isProcessAlive(pid) {
@@ -4158,7 +4151,7 @@ function isProcessAlive(pid) {
4158
4151
  }
4159
4152
  }
4160
4153
  function acquireLock(dataDir) {
4161
- const file = path9.join(dataDir, "bridge.lock");
4154
+ const file = path8.join(dataDir, "bridge.lock");
4162
4155
  lockPath = file;
4163
4156
  if (fs4.existsSync(file)) {
4164
4157
  const raw = fs4.readFileSync(file, "utf-8").trim();
@@ -4170,7 +4163,7 @@ function acquireLock(dataDir) {
4170
4163
  logger13.warn("Removing stale bridge.lock (process not found)", { pid, path: file });
4171
4164
  }
4172
4165
  }
4173
- fs4.mkdirSync(path9.dirname(file), { recursive: true });
4166
+ fs4.mkdirSync(path8.dirname(file), { recursive: true });
4174
4167
  fs4.writeFileSync(file, String(process.pid), "utf-8");
4175
4168
  logger13.info("Acquired bridge lock", { path: file, pid: process.pid });
4176
4169
  const release = () => {
@@ -4438,13 +4431,13 @@ function createGroupTaskDispatchHandler(agentManager, agentRegistry, emit) {
4438
4431
 
4439
4432
  // src/sessionStore.ts
4440
4433
  import fs5 from "fs";
4441
- import path10 from "path";
4434
+ import path9 from "path";
4442
4435
  var logger15 = createModuleLogger("session.store");
4443
4436
  var SessionStore = class {
4444
4437
  filePath;
4445
4438
  cache;
4446
4439
  constructor(dataDir) {
4447
- this.filePath = path10.join(dataDir, "sessions.json");
4440
+ this.filePath = path9.join(dataDir, "sessions.json");
4448
4441
  this.cache = this.loadFromDisk();
4449
4442
  }
4450
4443
  cacheKey(agentId, scope) {
@@ -4504,7 +4497,7 @@ var SessionStore = class {
4504
4497
  }
4505
4498
  saveToDisk() {
4506
4499
  try {
4507
- const dir = path10.dirname(this.filePath);
4500
+ const dir = path9.dirname(this.filePath);
4508
4501
  fs5.mkdirSync(dir, { recursive: true });
4509
4502
  fs5.writeFileSync(this.filePath, JSON.stringify(this.cache, null, 2), "utf-8");
4510
4503
  } catch (e) {
@@ -4514,7 +4507,6 @@ var SessionStore = class {
4514
4507
  };
4515
4508
 
4516
4509
  export {
4517
- __dirname,
4518
4510
  loadBridgeConfig,
4519
4511
  ensureDir,
4520
4512
  createModuleLogger,
package/dist/cli.js CHANGED
@@ -5,7 +5,6 @@ import {
5
5
  HttpAgentRegistry,
6
6
  ServerConnector,
7
7
  SessionStore,
8
- __dirname,
9
8
  acquireLock,
10
9
  createGroupTaskDispatchHandler,
11
10
  createModuleLogger,
@@ -15,7 +14,7 @@ import {
15
14
  listModels,
16
15
  loadBridgeConfig,
17
16
  wsMetrics
18
- } from "./chunk-MO54RNR2.js";
17
+ } from "./chunk-7SODRWIG.js";
19
18
 
20
19
  // src/cli.ts
21
20
  import cac from "cac";
@@ -25,7 +24,10 @@ import { execSync } from "child_process";
25
24
  import fs from "fs";
26
25
  import os from "os";
27
26
  import path from "path";
27
+ import { fileURLToPath } from "url";
28
28
  var logger = createModuleLogger("bridge.protocol");
29
+ var __filename = fileURLToPath(import.meta.url);
30
+ var __dirname = path.dirname(__filename);
29
31
  function getBridgeExePath() {
30
32
  const pkgDir = path.resolve(__dirname, "..");
31
33
  return path.join(pkgDir, "dist", "cli.js");
@@ -43,13 +45,30 @@ function registerProtocolHandler() {
43
45
  }
44
46
  function registerWindows() {
45
47
  const exe = getBridgeExePath();
46
- const handler = `"${process.execPath}" "${exe}" launch --url "%1"`;
47
- const iconPath = process.execPath;
48
+ const nodeExe = process.execPath;
49
+ const ahchatDir = path.join(os.homedir(), ".ahchat");
50
+ const urlFilePath = path.join(ahchatDir, ".bridge-launch-url");
51
+ fs.mkdirSync(ahchatDir, { recursive: true });
52
+ const psScriptPath = path.join(ahchatDir, "launch-bridge.ps1");
53
+ const psContent = `param([string]$url)
54
+ if (-not $url) {
55
+ if (Test-Path '${urlFilePath}') {
56
+ $url = Get-Content '${urlFilePath}' -Raw
57
+ }
58
+ }
59
+ if (-not $url) {
60
+ Write-Error "No URL provided"
61
+ exit 1
62
+ }
63
+ & '${nodeExe}' '${exe}' launch --url $url
64
+ `;
65
+ fs.writeFileSync(psScriptPath, psContent);
66
+ const handler = `powershell -ExecutionPolicy Bypass -File "${psScriptPath}" -url "%1"`;
48
67
  const regCommands = [
49
68
  `REG ADD "HKCU\\Software\\Classes\\ahchat" /ve /d "URL:ahchat" /f`,
50
69
  `REG ADD "HKCU\\Software\\Classes\\ahchat" /v "URL Protocol" /d "" /f`,
51
- `REG ADD "HKCU\\Software\\Classes\\ahchat\\DefaultIcon" /ve /d "${iconPath}" /f`,
52
- `REG ADD "HKCU\\Software\\Classes\\ahchat\\shell\\open\\command" /ve /d ${handler} /f`
70
+ `REG ADD "HKCU\\Software\\Classes\\ahchat\\DefaultIcon" /ve /d "${nodeExe}" /f`,
71
+ `REG ADD "HKCU\\Software\\Classes\\ahchat\\shell\\open\\command" /ve /t REG_SZ /d "${handler}" /f`
53
72
  ];
54
73
  for (const cmd of regCommands) {
55
74
  try {
@@ -59,7 +78,7 @@ function registerWindows() {
59
78
  throw new Error(`Failed to register protocol handler: ${cmd}`);
60
79
  }
61
80
  }
62
- logger.info("Windows protocol handler registered");
81
+ logger.info("Windows protocol handler registered", { psScriptPath });
63
82
  }
64
83
  function registerMacOS() {
65
84
  const appDir = path.join(os.homedir(), "Applications", "AHChatBridge.app");
@@ -132,6 +151,16 @@ function unregisterProtocolHandler() {
132
151
  if (platform === "win32") {
133
152
  try {
134
153
  execSync('REG DELETE "HKCU\\Software\\Classes\\ahchat" /f', { stdio: "pipe" });
154
+ const psScriptPath = path.join(os.homedir(), ".ahchat", "launch-bridge.ps1");
155
+ const urlFilePath = path.join(os.homedir(), ".ahchat", ".bridge-launch-url");
156
+ try {
157
+ fs.unlinkSync(psScriptPath);
158
+ } catch {
159
+ }
160
+ try {
161
+ fs.unlinkSync(urlFilePath);
162
+ } catch {
163
+ }
135
164
  logger.info("Windows protocol handler unregistered");
136
165
  } catch (e) {
137
166
  logger.warn("Failed to unregister Windows protocol handler", { error: e });
@@ -225,10 +254,15 @@ cli.version("0.1.0");
225
254
  cli.parse();
226
255
  function parseAhchatUrl(url) {
227
256
  try {
228
- const parsed = new URL(url);
229
- if (parsed.protocol !== "ahchat:") return null;
230
- const serverUrl = parsed.searchParams.get("server");
231
- const token = parsed.searchParams.get("token");
257
+ if (!url.startsWith("ahchat://")) return null;
258
+ const afterProtocol = url.slice("ahchat://".length);
259
+ const tildeIndex = afterProtocol.indexOf("~");
260
+ if (tildeIndex < 0) return null;
261
+ const rest = afterProtocol.slice(tildeIndex + 1);
262
+ const lastTilde = rest.lastIndexOf("~");
263
+ if (lastTilde < 0) return null;
264
+ const serverUrl = decodeURIComponent(rest.slice(0, lastTilde));
265
+ const token = decodeURIComponent(rest.slice(lastTilde + 1));
232
266
  if (!serverUrl || !token) return null;
233
267
  return { serverUrl, token };
234
268
  } catch {
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  listModels,
15
15
  loadBridgeConfig,
16
16
  wsMetrics
17
- } from "./chunk-MO54RNR2.js";
17
+ } from "./chunk-7SODRWIG.js";
18
18
 
19
19
  // src/index.ts
20
20
  var logger = createModuleLogger("bridge");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fangyb/ahchat-bridge",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "AHChat Bridge CLI — connect your local Claude Code agents to an AHChat server",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",