@hermespilot/link 0.7.0 → 0.7.2

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.
@@ -5621,7 +5621,7 @@ function isConversationMissingError(error) {
5621
5621
  }
5622
5622
 
5623
5623
  // src/constants.ts
5624
- var LINK_VERSION = "0.7.0";
5624
+ var LINK_VERSION = "0.7.2";
5625
5625
  var LINK_COMMAND = "hermeslink";
5626
5626
  var LINK_DEFAULT_PORT = 52379;
5627
5627
  var LINK_RUNTIME_DIR_NAME = ".hermeslink";
@@ -16127,6 +16127,7 @@ function normalizeProfileForCompare(value) {
16127
16127
  // src/hermes/stt.ts
16128
16128
  import { execFile as execFile3 } from "child_process";
16129
16129
  import { access as access2, readFile as readFile11, stat as stat11 } from "fs/promises";
16130
+ import os4 from "os";
16130
16131
  import path18 from "path";
16131
16132
  import { promisify as promisify3 } from "util";
16132
16133
  var execFileAsync3 = promisify3(execFile3);
@@ -16143,8 +16144,8 @@ async function transcribeAudioWithHermesProfile(input) {
16143
16144
  "\u8BED\u97F3\u8F6C\u5199\u672A\u542F\u7528\u3002\u8BF7\u5728 App \u7684 Profile \u5DE5\u5177\u7BA1\u7406\u4E2D\u542F\u7528\u8BED\u97F3\u8F6C\u5199 (STT)\u3002"
16144
16145
  );
16145
16146
  }
16146
- const python = await resolveHermesPythonCommand();
16147
- const env = await buildHermesSttEnv(profileName);
16147
+ const python = await resolveHermesPythonRuntime();
16148
+ const env = await buildHermesSttEnv(profileName, python.sourceRoot);
16148
16149
  const script = [
16149
16150
  "import json, sys",
16150
16151
  "try:",
@@ -16211,7 +16212,7 @@ async function transcribeAudioWithHermesProfile(input) {
16211
16212
  });
16212
16213
  return { transcript, provider: result.provider };
16213
16214
  }
16214
- async function buildHermesSttEnv(profileName) {
16215
+ async function buildHermesSttEnv(profileName, hermesSourceRoot) {
16215
16216
  const hermesEnv = await readHermesEnvFile(profileName);
16216
16217
  const hermesHome = resolveHermesProfileDir(profileName);
16217
16218
  const env = {
@@ -16220,9 +16221,9 @@ async function buildHermesSttEnv(profileName) {
16220
16221
  HERMES_HOME: hermesHome,
16221
16222
  PYTHONIOENCODING: "utf-8"
16222
16223
  };
16223
- const devSource = await findDevHermesAgentSource();
16224
- if (devSource) {
16225
- env.PYTHONPATH = [devSource, env.PYTHONPATH].filter(Boolean).join(path18.delimiter);
16224
+ const sourceRoot = hermesSourceRoot ?? await findDevHermesAgentSource();
16225
+ if (sourceRoot) {
16226
+ env.PYTHONPATH = [sourceRoot, env.PYTHONPATH].filter(Boolean).join(path18.delimiter);
16226
16227
  }
16227
16228
  return env;
16228
16229
  }
@@ -16250,22 +16251,63 @@ function parseSttResult(stdout) {
16250
16251
  return { success: false, error: "Invalid STT JSON result" };
16251
16252
  }
16252
16253
  }
16253
- async function resolveHermesPythonCommand() {
16254
+ async function resolveHermesPythonRuntime() {
16254
16255
  const explicit = process.env.HERMES_PYTHON?.trim();
16255
16256
  if (explicit) {
16256
- return { command: explicit, args: [] };
16257
+ return {
16258
+ command: explicit,
16259
+ args: [],
16260
+ sourceRoot: await findExplicitHermesSourceRoot() ?? await findHermesSourceRoot(explicit)
16261
+ };
16257
16262
  }
16258
16263
  const hermesBin = await resolveExecutablePath2(resolveHermesBin());
16264
+ let shebangRuntime = null;
16259
16265
  if (hermesBin) {
16266
+ const installRoot = await findHermesSourceRoot(hermesBin);
16260
16267
  const shebang = await readShebang(hermesBin);
16261
16268
  const command = shebangToPythonCommand(shebang);
16262
16269
  if (command) {
16263
- return command;
16270
+ const sourceRoot = await findHermesSourceRoot(command.command) ?? installRoot;
16271
+ if (sourceRoot) {
16272
+ return {
16273
+ ...command,
16274
+ sourceRoot
16275
+ };
16276
+ }
16277
+ shebangRuntime = {
16278
+ ...command,
16279
+ sourceRoot: null
16280
+ };
16281
+ }
16282
+ const installPython = installRoot ? await findHermesVenvPython(installRoot) : null;
16283
+ if (installPython) {
16284
+ return {
16285
+ command: installPython,
16286
+ args: [],
16287
+ sourceRoot: installRoot
16288
+ };
16289
+ }
16290
+ }
16291
+ for (const sourceRoot of hermesSourceRootCandidates()) {
16292
+ if (!await isHermesAgentSourceRoot(sourceRoot)) {
16293
+ continue;
16294
+ }
16295
+ const installPython = await findHermesVenvPython(sourceRoot);
16296
+ if (installPython) {
16297
+ return {
16298
+ command: installPython,
16299
+ args: [],
16300
+ sourceRoot
16301
+ };
16264
16302
  }
16265
16303
  }
16304
+ if (shebangRuntime) {
16305
+ return shebangRuntime;
16306
+ }
16266
16307
  return {
16267
16308
  command: process.platform === "win32" ? "python" : "python3",
16268
- args: []
16309
+ args: [],
16310
+ sourceRoot: await findExplicitHermesSourceRoot() ?? await findDevHermesAgentSource()
16269
16311
  };
16270
16312
  }
16271
16313
  async function resolveExecutablePath2(command) {
@@ -16296,6 +16338,21 @@ async function isExecutableFile(filePath) {
16296
16338
  return false;
16297
16339
  }
16298
16340
  }
16341
+ async function findHermesVenvPython(sourceRoot) {
16342
+ const candidates = process.platform === "win32" ? [
16343
+ path18.join(sourceRoot, "venv", "Scripts", "python.exe"),
16344
+ path18.join(sourceRoot, ".venv", "Scripts", "python.exe")
16345
+ ] : [
16346
+ path18.join(sourceRoot, "venv", "bin", "python"),
16347
+ path18.join(sourceRoot, ".venv", "bin", "python")
16348
+ ];
16349
+ for (const candidate of candidates) {
16350
+ if (await isExecutableFile(candidate)) {
16351
+ return candidate;
16352
+ }
16353
+ }
16354
+ return null;
16355
+ }
16299
16356
  async function readShebang(filePath) {
16300
16357
  const raw = await readFile11(filePath, "utf8").catch(() => "");
16301
16358
  const firstLine = raw.split(/\r?\n/u)[0]?.trim() ?? "";
@@ -16320,12 +16377,48 @@ async function findDevHermesAgentSource() {
16320
16377
  path18.resolve(process.cwd(), "../../reference/hermes-agent")
16321
16378
  ];
16322
16379
  for (const candidate of candidates) {
16323
- if (await isDirectory(candidate)) {
16380
+ if (await isHermesAgentSourceRoot(candidate)) {
16324
16381
  return candidate;
16325
16382
  }
16326
16383
  }
16327
16384
  return null;
16328
16385
  }
16386
+ async function findHermesSourceRoot(executablePath) {
16387
+ let cursor = path18.dirname(path18.resolve(executablePath));
16388
+ for (let index = 0; index < 6; index += 1) {
16389
+ if (await isHermesAgentSourceRoot(cursor)) {
16390
+ return cursor;
16391
+ }
16392
+ const parent = path18.dirname(cursor);
16393
+ if (parent === cursor) {
16394
+ break;
16395
+ }
16396
+ cursor = parent;
16397
+ }
16398
+ return null;
16399
+ }
16400
+ function hermesSourceRootCandidates() {
16401
+ const candidates = [
16402
+ process.env.HERMES_PYTHON_SRC_ROOT?.trim(),
16403
+ path18.join(os4.homedir(), ".hermes", "hermes-agent"),
16404
+ "/usr/local/lib/hermes-agent",
16405
+ "/opt/hermes"
16406
+ ].filter((candidate) => Boolean(candidate));
16407
+ if (process.platform === "win32") {
16408
+ const localAppData = process.env.LOCALAPPDATA?.trim();
16409
+ if (localAppData) {
16410
+ candidates.unshift(path18.join(localAppData, "hermes", "hermes-agent"));
16411
+ }
16412
+ }
16413
+ return candidates;
16414
+ }
16415
+ async function findExplicitHermesSourceRoot() {
16416
+ const explicit = process.env.HERMES_PYTHON_SRC_ROOT?.trim();
16417
+ return explicit && await isHermesAgentSourceRoot(explicit) ? explicit : null;
16418
+ }
16419
+ async function isHermesAgentSourceRoot(candidate) {
16420
+ return await isDirectory(candidate) && await isDirectory(path18.join(candidate, "tools")) && await isDirectory(path18.join(candidate, "hermes_cli"));
16421
+ }
16329
16422
  async function isDirectory(candidate) {
16330
16423
  return stat11(candidate).then((info) => info.isDirectory()).catch(() => false);
16331
16424
  }
@@ -24480,7 +24573,7 @@ import YAML5 from "yaml";
24480
24573
 
24481
24574
  // src/hermes/link-skill.ts
24482
24575
  import { readFile as readFile16, stat as stat16 } from "fs/promises";
24483
- import os4 from "os";
24576
+ import os5 from "os";
24484
24577
  import path23 from "path";
24485
24578
  import YAML4 from "yaml";
24486
24579
  var HERMES_LINK_SKILL_ROOT_DIR = "hermes-skills";
@@ -24762,10 +24855,10 @@ function resolveExternalDirEntry(entry, hermesHome) {
24762
24855
  }
24763
24856
  function expandHome(value) {
24764
24857
  if (value === "~") {
24765
- return os4.homedir();
24858
+ return os5.homedir();
24766
24859
  }
24767
24860
  if (value.startsWith(`~${path23.sep}`) || value.startsWith("~/")) {
24768
- return path23.join(os4.homedir(), value.slice(2));
24861
+ return path23.join(os5.homedir(), value.slice(2));
24769
24862
  }
24770
24863
  return value;
24771
24864
  }
@@ -29746,7 +29839,7 @@ function normalizeMessage(value) {
29746
29839
  // src/runtime/system-info.ts
29747
29840
  import { execFileSync } from "child_process";
29748
29841
  import { readFileSync } from "fs";
29749
- import os5 from "os";
29842
+ import os6 from "os";
29750
29843
  function readLinkSystemInfo() {
29751
29844
  const platform = process.platform;
29752
29845
  const hostname = readHostname(platform);
@@ -29785,7 +29878,7 @@ function readHostname(platform) {
29785
29878
  return computerName;
29786
29879
  }
29787
29880
  }
29788
- return normalizeText(os5.hostname());
29881
+ return normalizeText(os6.hostname());
29789
29882
  }
29790
29883
  function readOsLabel(platform) {
29791
29884
  if (platform === "darwin") {
@@ -29793,12 +29886,12 @@ function readOsLabel(platform) {
29793
29886
  return version ? `macOS ${version}` : "macOS";
29794
29887
  }
29795
29888
  if (platform === "linux") {
29796
- return readLinuxOsRelease() ?? `Linux ${os5.release()}`;
29889
+ return readLinuxOsRelease() ?? `Linux ${os6.release()}`;
29797
29890
  }
29798
29891
  if (platform === "win32") {
29799
- return `Windows ${os5.release()}`;
29892
+ return `Windows ${os6.release()}`;
29800
29893
  }
29801
- return `${os5.type()} ${os5.release()}`.trim();
29894
+ return `${os6.type()} ${os6.release()}`.trim();
29802
29895
  }
29803
29896
  function readLinuxOsRelease() {
29804
29897
  for (const file of ["/etc/os-release", "/usr/lib/os-release"]) {
@@ -29845,11 +29938,11 @@ function truncateText(value, maxLength) {
29845
29938
  }
29846
29939
 
29847
29940
  // src/topology/network.ts
29848
- import os7 from "os";
29941
+ import os8 from "os";
29849
29942
 
29850
29943
  // src/topology/environment.ts
29851
29944
  import { existsSync, readFileSync as readFileSync2 } from "fs";
29852
- import os6 from "os";
29945
+ import os7 from "os";
29853
29946
  function detectRuntimeEnvironment(env = process.env) {
29854
29947
  if (isWsl(env)) {
29855
29948
  return {
@@ -29878,7 +29971,7 @@ function isWsl(env) {
29878
29971
  if (env.WSL_DISTRO_NAME || env.WSL_INTEROP) {
29879
29972
  return true;
29880
29973
  }
29881
- const release = os6.release().toLowerCase();
29974
+ const release = os7.release().toLowerCase();
29882
29975
  return release.includes("microsoft") || release.includes("wsl");
29883
29976
  }
29884
29977
  function isContainer(env) {
@@ -29923,7 +30016,7 @@ async function discoverRouteCandidates(options) {
29923
30016
  };
29924
30017
  }
29925
30018
  function discoverLanIps() {
29926
- return discoverLanIpsFromInterfaces(os7.networkInterfaces());
30019
+ return discoverLanIpsFromInterfaces(os8.networkInterfaces());
29927
30020
  }
29928
30021
  function discoverLanIpsFromInterfaces(interfaces) {
29929
30022
  const result = /* @__PURE__ */ new Set();
@@ -31850,6 +31943,7 @@ async function buildOfficialInstallCommand(options, targetVersion) {
31850
31943
  });
31851
31944
  const env = {
31852
31945
  HERMESLINK_VERSION: targetVersion,
31946
+ HERMESLINK_NODE_PATH: process.execPath,
31853
31947
  HERMESLINK_YES: "1",
31854
31948
  HERMESLINK_NO_PROFILE_EDIT: "1",
31855
31949
  HERMESLINK_NO_PATH_PROMPT: "1",
@@ -31876,6 +31970,7 @@ async function buildOfficialInstallCommand(options, targetVersion) {
31876
31970
  };
31877
31971
  }
31878
31972
  function buildUnixInstallCommand(installerUrl) {
31973
+ const nodeBinDir = path29.dirname(process.execPath);
31879
31974
  const fetchScript = [
31880
31975
  quoteShellToken(process.execPath),
31881
31976
  "--input-type=module",
@@ -31886,6 +31981,7 @@ function buildUnixInstallCommand(installerUrl) {
31886
31981
  ].join(" ");
31887
31982
  return [
31888
31983
  "set -e;",
31984
+ `PATH=${quoteShellToken(nodeBinDir)}:"$PATH"; export PATH;`,
31889
31985
  'tmp="${TMPDIR:-/tmp}/hermespilot-link-install.$$.sh";',
31890
31986
  `trap 'rm -f "$tmp"' EXIT;`,
31891
31987
  "umask 077;",
@@ -32049,6 +32145,7 @@ function buildWindowsDetachedUpdaterScript(input) {
32049
32145
  ' Add-UpdateLog "=> Downloading official installer"',
32050
32146
  ' Invoke-RestMethod -Uri $InstallerUrl -Headers @{ "User-Agent" = "HermesPilot-Link-Updater" } -OutFile $InstallerPath',
32051
32147
  " $env:HERMESLINK_VERSION = $TargetVersion",
32148
+ " $env:HERMESLINK_NODE_PATH = $NodePath",
32052
32149
  ' $env:HERMESLINK_YES = "1"',
32053
32150
  ' $env:HERMESLINK_NO_PATH_PROMPT = "1"',
32054
32151
  ' $env:HERMESLINK_SKIP_DOCTOR = "1"',
package/dist/cli/index.js CHANGED
@@ -53,7 +53,7 @@ import {
53
53
  stopDaemonProcess,
54
54
  summarizeUsageProbeEnsure,
55
55
  translate
56
- } from "../chunk-XWQRIQVR.js";
56
+ } from "../chunk-YPY6JEZN.js";
57
57
 
58
58
  // src/cli/index.ts
59
59
  import { Command } from "commander";
@@ -264,6 +264,14 @@ function autostartEnvironment() {
264
264
  if (hermesBin) {
265
265
  environment.HERMES_BIN = hermesBin;
266
266
  }
267
+ const hermesPython = process.env.HERMES_PYTHON?.trim();
268
+ if (hermesPython) {
269
+ environment.HERMES_PYTHON = hermesPython;
270
+ }
271
+ const hermesPythonSourceRoot = process.env.HERMES_PYTHON_SRC_ROOT?.trim();
272
+ if (hermesPythonSourceRoot) {
273
+ environment.HERMES_PYTHON_SRC_ROOT = hermesPythonSourceRoot;
274
+ }
267
275
  return environment;
268
276
  }
269
277
  function buildAutostartPath() {
package/dist/http/app.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApp
3
- } from "../chunk-XWQRIQVR.js";
3
+ } from "../chunk-YPY6JEZN.js";
4
4
  export {
5
5
  createApp
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hermespilot/link",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "private": false,
5
5
  "description": "Hermes Link companion service and CLI for connecting hermes-agent through HermesPilot",
6
6
  "license": "MIT",