@openagents-org/agent-launcher 0.2.139 → 0.2.141
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/package.json +1 -1
- package/registry.json +1 -1
- package/src/adapters/claude.js +35 -2
- package/src/adapters/hermes.js +21 -9
- package/src/paths.js +9 -0
package/package.json
CHANGED
package/registry.json
CHANGED
|
@@ -616,7 +616,7 @@
|
|
|
616
616
|
"requires": ["python3"],
|
|
617
617
|
"macos": "curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash -s -- --skip-setup",
|
|
618
618
|
"linux": "curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash -s -- --skip-setup",
|
|
619
|
-
"windows": "
|
|
619
|
+
"windows": "\"%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoProfile -ExecutionPolicy Bypass -Command \"Invoke-RestMethod -UseBasicParsing 'https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.ps1' | Invoke-Expression\""
|
|
620
620
|
},
|
|
621
621
|
"launch": {
|
|
622
622
|
"args": []
|
package/src/adapters/claude.js
CHANGED
|
@@ -305,6 +305,15 @@ class ClaudeAdapter extends BaseAdapter {
|
|
|
305
305
|
if (jsMatch) {
|
|
306
306
|
return [nodeBin, path.resolve(cmdDir, jsMatch[1])];
|
|
307
307
|
}
|
|
308
|
+
// .cmd shims that forward to a native .exe (e.g. Claude Code's
|
|
309
|
+
// claude.cmd → @anthropic-ai/claude-code/bin/claude.exe). Resolve to the
|
|
310
|
+
// exe and spawn it directly. Wrapping such a .cmd in `cmd.exe /c` caps the
|
|
311
|
+
// command line at cmd.exe's 8191-char limit, which truncates the ~14KB
|
|
312
|
+
// --append-system-prompt and makes the agent hang ("command line too long").
|
|
313
|
+
const exeMatch = cmdContent.match(/%dp0%\\([^\s"*?]+\.exe)/i);
|
|
314
|
+
if (exeMatch) {
|
|
315
|
+
return [path.resolve(cmdDir, exeMatch[1])];
|
|
316
|
+
}
|
|
308
317
|
} else {
|
|
309
318
|
// Unix: symlink → resolve to actual .js file
|
|
310
319
|
try {
|
|
@@ -564,7 +573,7 @@ class ClaudeAdapter extends BaseAdapter {
|
|
|
564
573
|
const resolved = this._resolveToNodeCmd(oaBin);
|
|
565
574
|
if (resolved) {
|
|
566
575
|
mcpCommand = resolved[0];
|
|
567
|
-
mcpFinalArgs = [resolved
|
|
576
|
+
mcpFinalArgs = [...resolved.slice(1), ...mcpArgs];
|
|
568
577
|
} else {
|
|
569
578
|
mcpCommand = oaBin;
|
|
570
579
|
}
|
|
@@ -689,7 +698,7 @@ class ClaudeAdapter extends BaseAdapter {
|
|
|
689
698
|
const resolved = this._resolveToNodeCmd(filteredCmd[0]);
|
|
690
699
|
let finalCmd = filteredCmd;
|
|
691
700
|
if (resolved) {
|
|
692
|
-
finalCmd = [resolved
|
|
701
|
+
finalCmd = [...resolved, ...filteredCmd.slice(1)];
|
|
693
702
|
} else if (IS_WINDOWS && filteredCmd[0].toLowerCase().endsWith('.cmd')) {
|
|
694
703
|
finalCmd = ['cmd.exe', '/c', ...filteredCmd];
|
|
695
704
|
}
|
|
@@ -999,6 +1008,30 @@ class ClaudeAdapter extends BaseAdapter {
|
|
|
999
1008
|
}
|
|
1000
1009
|
}
|
|
1001
1010
|
|
|
1011
|
+
// Third-party Anthropic-compatible relays (the common reason a custom
|
|
1012
|
+
// ANTHROPIC_BASE_URL is set) authenticate via `Authorization: Bearer`, which
|
|
1013
|
+
// the Claude CLI only sends when ANTHROPIC_AUTH_TOKEN is set. With just
|
|
1014
|
+
// ANTHROPIC_API_KEY the CLI sends `x-api-key`, which most relays ignore — the
|
|
1015
|
+
// relay then rejects every request as 401 "invalid token / 无效的令牌". When a
|
|
1016
|
+
// non-official base URL is configured and no auth token was provided, mirror
|
|
1017
|
+
// the API key into ANTHROPIC_AUTH_TOKEN (it outranks the API key in Claude
|
|
1018
|
+
// Code's auth precedence) so the CLI uses Bearer auth. The launcher normally
|
|
1019
|
+
// sets this when saving env; this is the runtime backstop for envs saved by
|
|
1020
|
+
// an older launcher or coming from any other source. The official
|
|
1021
|
+
// api.anthropic.com endpoint keeps x-api-key, so it is left untouched.
|
|
1022
|
+
const anthropicBase = (cleanEnv.ANTHROPIC_BASE_URL || '').trim();
|
|
1023
|
+
const anthropicKey = (cleanEnv.ANTHROPIC_API_KEY || '').trim();
|
|
1024
|
+
if (anthropicKey && anthropicBase && !(cleanEnv.ANTHROPIC_AUTH_TOKEN || '').trim()) {
|
|
1025
|
+
let officialAnthropic = false;
|
|
1026
|
+
try {
|
|
1027
|
+
const host = new URL(anthropicBase).hostname.toLowerCase();
|
|
1028
|
+
officialAnthropic = host === 'anthropic.com' || host.endsWith('.anthropic.com');
|
|
1029
|
+
} catch { officialAnthropic = false; }
|
|
1030
|
+
if (!officialAnthropic) {
|
|
1031
|
+
cleanEnv.ANTHROPIC_AUTH_TOKEN = anthropicKey;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1002
1035
|
// Spawn a persistent process and send the first message via stdin
|
|
1003
1036
|
let effectiveContent = content;
|
|
1004
1037
|
for (let attempt = 0; attempt < 2; attempt++) {
|
package/src/adapters/hermes.js
CHANGED
|
@@ -24,6 +24,9 @@ const { buildOpenclawSystemPrompt } = require('./workspace-prompt');
|
|
|
24
24
|
const { whichBinary, getEnhancedEnv } = require('../paths');
|
|
25
25
|
|
|
26
26
|
const IS_WINDOWS = process.platform === 'win32';
|
|
27
|
+
const HERMES_INSTALL_HINT = IS_WINDOWS
|
|
28
|
+
? 'powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.ps1 | iex"'
|
|
29
|
+
: 'curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash';
|
|
27
30
|
const SESSION_ID_RE = /session_id:\s*(\S+)/;
|
|
28
31
|
const MAX_HISTORY_ENTRIES = 12;
|
|
29
32
|
|
|
@@ -56,7 +59,7 @@ class HermesAdapter extends BaseAdapter {
|
|
|
56
59
|
if (this._hermesBin) {
|
|
57
60
|
this._log(`Using Hermes binary: ${this._hermesBin} (profile=${this.hermesProfile})`);
|
|
58
61
|
} else {
|
|
59
|
-
this._log(
|
|
62
|
+
this._log(`Warning: hermes CLI not found. Install: ${HERMES_INSTALL_HINT}`);
|
|
60
63
|
}
|
|
61
64
|
}
|
|
62
65
|
|
|
@@ -76,7 +79,9 @@ class HermesAdapter extends BaseAdapter {
|
|
|
76
79
|
try {
|
|
77
80
|
const env = getEnhancedEnv();
|
|
78
81
|
if (IS_WINDOWS) {
|
|
79
|
-
// Native Windows
|
|
82
|
+
// Native Windows is supported (install.ps1). The installer adds
|
|
83
|
+
// venv\Scripts to the user PATH; a running daemon won't see that update,
|
|
84
|
+
// hence the enriched env + the explicit candidates in Tier 2.
|
|
80
85
|
const r = execSync('where hermes.exe 2>nul || where hermes.cmd 2>nul || where hermes 2>nul', {
|
|
81
86
|
encoding: 'utf-8', timeout: 5000, windowsHide: true, env,
|
|
82
87
|
});
|
|
@@ -88,9 +93,16 @@ class HermesAdapter extends BaseAdapter {
|
|
|
88
93
|
}
|
|
89
94
|
} catch {}
|
|
90
95
|
|
|
91
|
-
// Tier 2: Common install locations. The
|
|
92
|
-
//
|
|
96
|
+
// Tier 2: Common install locations. The native Windows installer
|
|
97
|
+
// (install.ps1) provisions a portable venv and drops hermes.exe under
|
|
98
|
+
// %LOCALAPPDATA%\hermes\hermes-agent\venv\Scripts (with the uv shim in
|
|
99
|
+
// %LOCALAPPDATA%\hermes\bin). The Unix installer uses ~/.local/bin.
|
|
100
|
+
const localAppData = process.env.LOCALAPPDATA || path.join(home, 'AppData', 'Local');
|
|
93
101
|
const candidates = IS_WINDOWS ? [
|
|
102
|
+
path.join(localAppData, 'hermes', 'hermes-agent', 'venv', 'Scripts', 'hermes.exe'),
|
|
103
|
+
path.join(localAppData, 'hermes', 'hermes-agent', 'venv', 'Scripts', 'hermes.cmd'),
|
|
104
|
+
path.join(localAppData, 'hermes', 'bin', 'hermes.exe'),
|
|
105
|
+
path.join(localAppData, 'hermes', 'bin', 'hermes.cmd'),
|
|
94
106
|
path.join(home, '.hermes', 'bin', 'hermes.exe'),
|
|
95
107
|
path.join(home, '.hermes', 'bin', 'hermes.cmd'),
|
|
96
108
|
path.join(home, '.hermes', 'bin', 'hermes'),
|
|
@@ -111,10 +123,10 @@ class HermesAdapter extends BaseAdapter {
|
|
|
111
123
|
const viaWhich = whichBinary('hermes');
|
|
112
124
|
if (viaWhich) return viaWhich;
|
|
113
125
|
|
|
114
|
-
// Tier 4 (Windows only):
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
// `wsl -e <path> …`.
|
|
126
|
+
// Tier 4 (Windows only): fall back to a WSL install if one exists. Native
|
|
127
|
+
// Windows (Tiers 1-3) is preferred, but a user who set hermes up inside
|
|
128
|
+
// WSL2 still works — resolve its absolute in-WSL path; _runHermes then
|
|
129
|
+
// invokes it as `wsl -e <path> …`.
|
|
118
130
|
if (IS_WINDOWS) {
|
|
119
131
|
const wslPath = this._resolveWslHermes();
|
|
120
132
|
if (wslPath) {
|
|
@@ -283,7 +295,7 @@ class HermesAdapter extends BaseAdapter {
|
|
|
283
295
|
|
|
284
296
|
_buildHermesCmd(prompt, resumeSessionId) {
|
|
285
297
|
if (!this._hermesBin) {
|
|
286
|
-
throw new Error(
|
|
298
|
+
throw new Error(`hermes CLI not found. Install with: ${HERMES_INSTALL_HINT}`);
|
|
287
299
|
}
|
|
288
300
|
const args = [];
|
|
289
301
|
if (this.hermesProfile && this.hermesProfile !== 'default') {
|
package/src/paths.js
CHANGED
|
@@ -197,6 +197,15 @@ function _addWindowsPaths(dirs) {
|
|
|
197
197
|
if (localAppData) _push(dirs, path.join(localAppData, 'cursor-agent'));
|
|
198
198
|
_push(dirs, path.join(HOME, '.local', 'bin'));
|
|
199
199
|
|
|
200
|
+
// Hermes CLI native (no-WSL) installer drops hermes.exe in the portable
|
|
201
|
+
// venv's Scripts dir and the uv shim in %LOCALAPPDATA%\hermes\bin. Same
|
|
202
|
+
// registry-PATH staleness as Cursor — add explicitly so an already-running
|
|
203
|
+
// daemon resolves hermes via `where` without a reboot.
|
|
204
|
+
if (localAppData) {
|
|
205
|
+
_push(dirs, path.join(localAppData, 'hermes', 'hermes-agent', 'venv', 'Scripts'));
|
|
206
|
+
_push(dirs, path.join(localAppData, 'hermes', 'bin'));
|
|
207
|
+
}
|
|
208
|
+
|
|
200
209
|
// Node.js install
|
|
201
210
|
_push(dirs, path.join(programFiles, 'nodejs'));
|
|
202
211
|
|