@bulolo/hermes-link 0.2.6 → 0.2.7

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.
@@ -1529,33 +1529,51 @@ function discoverLanIpsFromInterfaces(interfaces) {
1529
1529
  }
1530
1530
  async function observePublicRoute(options) {
1531
1531
  const fetcher = options.fetchImpl ?? fetch;
1532
- const response = await fetcher(
1533
- `${options.relayBaseUrl.replace(/\/+$/u, "")}/api/v1/relay/public-route/observe`,
1534
- {
1535
- method: "POST",
1536
- headers: {
1537
- "content-type": "application/json",
1538
- ...options.relayBootstrapToken ? { authorization: `Bearer ${options.relayBootstrapToken}` } : {}
1539
- },
1540
- body: JSON.stringify({
1541
- install_id: options.installId,
1542
- link_id: options.linkId,
1543
- public_key_pem: options.publicKeyPem
1544
- })
1545
- }
1546
- );
1547
- const payload = await response.json().catch(() => null);
1548
- const record = typeof payload?.record === "object" && payload.record !== null ? payload.record : null;
1549
- const observed = typeof payload?.observed === "object" && payload.observed !== null ? payload.observed : null;
1550
- const values = [
1551
- readIpRecord(record?.ipv4),
1552
- readIpRecord(record?.ipv6),
1553
- typeof observed?.ip === "string" ? observed.ip : null
1554
- ].filter((v) => Boolean(v));
1555
- return {
1556
- publicIpv4s: unique(values.filter(isUsablePublicIpv4)),
1557
- publicIpv6s: unique(values.filter(isUsablePublicIpv6))
1558
- };
1532
+ const simpleIp = await fetchPublicIpSimple(fetcher).catch(() => null);
1533
+ try {
1534
+ const response = await fetcher(
1535
+ `${options.relayBaseUrl.replace(/\/+$/u, "")}/api/v1/relay/public-route/observe`,
1536
+ {
1537
+ method: "POST",
1538
+ headers: {
1539
+ "content-type": "application/json",
1540
+ ...options.relayBootstrapToken ? { authorization: `Bearer ${options.relayBootstrapToken}` } : {}
1541
+ },
1542
+ body: JSON.stringify({
1543
+ install_id: options.installId,
1544
+ link_id: options.linkId,
1545
+ public_key_pem: options.publicKeyPem
1546
+ }),
1547
+ signal: AbortSignal.timeout(5e3)
1548
+ }
1549
+ );
1550
+ const payload = await response.json().catch(() => null);
1551
+ const record = typeof payload?.record === "object" && payload.record !== null ? payload.record : null;
1552
+ const observed = typeof payload?.observed === "object" && payload.observed !== null ? payload.observed : null;
1553
+ const values = [
1554
+ simpleIp,
1555
+ readIpRecord(record?.ipv4),
1556
+ readIpRecord(record?.ipv6),
1557
+ typeof observed?.ip === "string" ? observed.ip : null
1558
+ ].filter((v) => Boolean(v));
1559
+ return {
1560
+ publicIpv4s: unique(values.filter(isUsablePublicIpv4)),
1561
+ publicIpv6s: unique(values.filter(isUsablePublicIpv6))
1562
+ };
1563
+ } catch {
1564
+ const values = [simpleIp].filter((v) => Boolean(v));
1565
+ return {
1566
+ publicIpv4s: unique(values.filter(isUsablePublicIpv4)),
1567
+ publicIpv6s: []
1568
+ };
1569
+ }
1570
+ }
1571
+ async function fetchPublicIpSimple(fetcher) {
1572
+ const res = await fetcher("https://api.ipify.org?format=json", {
1573
+ signal: AbortSignal.timeout(4e3)
1574
+ });
1575
+ const data = await res.json();
1576
+ return typeof data.ip === "string" && data.ip.trim() ? data.ip.trim() : null;
1559
1577
  }
1560
1578
  function readIpRecord(value) {
1561
1579
  if (typeof value !== "object" || value === null) return null;
@@ -3506,8 +3524,9 @@ async function startLinkService(options) {
3506
3524
  const statsRouter = createStatisticsRouter({ db, paths });
3507
3525
  app.use(statsRouter.routes());
3508
3526
  app.use(statsRouter.allowedMethods());
3527
+ const listenHost = process.env.HERMESLINK_LISTEN_HOST ?? "0.0.0.0";
3509
3528
  const server = await new Promise((resolve, reject) => {
3510
- const s = app.listen(config.port, "127.0.0.1", () => resolve(s));
3529
+ const s = app.listen(config.port, listenHost, () => resolve(s));
3511
3530
  s.once("error", reject);
3512
3531
  });
3513
3532
  const relayClient = new RelayClient({
package/dist/cli/index.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  saveConfig,
24
24
  startLinkService,
25
25
  writeJsonFile
26
- } from "../chunk-YARHXGP4.js";
26
+ } from "../chunk-ZN3XW7FI.js";
27
27
 
28
28
  // src/cli/index.ts
29
29
  import { mkdir as mkdir3 } from "fs/promises";
@@ -275,7 +275,7 @@ async function runPairingPreflight(options) {
275
275
  if (options.openBrowser !== false) {
276
276
  await openSystemBrowser(pairingUrl).catch(() => void 0);
277
277
  }
278
- return { pairingUrl, connectToken: token.token };
278
+ return { pairingUrl, connectToken: token.token, bestUrl };
279
279
  }
280
280
  function buildPairingUrl(params) {
281
281
  const qs = new URLSearchParams({
@@ -288,10 +288,6 @@ function buildPairingUrl(params) {
288
288
  if (params.publicUrls.length > 0) qs.set("public_urls", params.publicUrls.join(","));
289
289
  return `hermesapp://pair?${qs.toString()}`;
290
290
  }
291
- function buildLocalPairingPageUrl(port, connectToken) {
292
- const qs = new URLSearchParams({ connect_token: connectToken });
293
- return `http://127.0.0.1:${port}/pair?${qs.toString()}`;
294
- }
295
291
 
296
292
  // src/cli/index.ts
297
293
  var args = process.argv.slice(2);
@@ -447,13 +443,14 @@ async function cmdPair(paths) {
447
443
  return;
448
444
  }
449
445
  const result = await runPairingPreflight({ identity, config, paths });
450
- const localPageUrl = buildLocalPairingPageUrl(config.port, result.connectToken);
446
+ const pageBase = result.bestUrl.replace(/\/+$/u, "");
447
+ const pageUrl = `${pageBase}/pair?connect_token=${encodeURIComponent(result.connectToken)}`;
451
448
  process.stdout.write("\n");
452
449
  qrcode.generate(result.pairingUrl, { small: true });
453
450
  process.stdout.write(`
454
451
  Pairing URL: ${result.pairingUrl}
455
452
  `);
456
- process.stdout.write(`Pairing page: ${localPageUrl}
453
+ process.stdout.write(`Pairing page: ${pageUrl}
457
454
  `);
458
455
  process.stdout.write(`Connect token: ${result.connectToken}
459
456
  `);
package/dist/http/app.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  startLinkService
3
- } from "../chunk-YARHXGP4.js";
3
+ } from "../chunk-ZN3XW7FI.js";
4
4
  export {
5
5
  startLinkService
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bulolo/hermes-link",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Hermes Link companion service and CLI for connecting hermes-agent through zhiji",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -36,7 +36,7 @@
36
36
  "prepack": "npm run build",
37
37
  "start": "node ./dist/cli/index.js",
38
38
  "test": "vitest",
39
- "publish:npm": "npm publish --access public"
39
+ "publish:npm": "npm publish --access public --registry https://registry.npmjs.org"
40
40
  },
41
41
  "dependencies": {
42
42
  "@koa/cors": "^5.0.0",