athena-agent-launcher 0.3.0 → 0.3.1
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/bin/launcher.mjs +69 -18
- package/package.json +1 -1
package/bin/launcher.mjs
CHANGED
|
@@ -139,42 +139,93 @@ async function runSetup() {
|
|
|
139
139
|
process.stdout.write(" Run an agent with: athena-agent run <agent-id>\n\n");
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
// Return the absolute path to `hermes` if it's findable on PATH
|
|
143
|
-
//
|
|
142
|
+
// Return the absolute path to `hermes` if it's findable on PATH or in a few
|
|
143
|
+
// common install locations. Cross-platform (uses `where` on Windows, `which`
|
|
144
|
+
// elsewhere) and never throws if the finder binary is missing. Returns null if
|
|
145
|
+
// not found.
|
|
144
146
|
async function locateHermes() {
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
+
const isWin = process.platform === "win32";
|
|
148
|
+
const home = homedir();
|
|
149
|
+
const candidates = isWin
|
|
150
|
+
? [
|
|
151
|
+
join(home, ".local", "bin", "hermes.exe"),
|
|
152
|
+
join(home, ".local", "bin", "hermes.cmd"),
|
|
153
|
+
join(home, ".local", "bin", "hermes"),
|
|
154
|
+
]
|
|
155
|
+
: [join(home, ".local", "bin", "hermes"), "/usr/local/bin/hermes", "/opt/homebrew/bin/hermes"];
|
|
147
156
|
for (const p of candidates) {
|
|
148
157
|
if (existsSync(p)) return p;
|
|
149
158
|
}
|
|
150
|
-
|
|
151
|
-
|
|
159
|
+
// `where` (Windows) / `which` (POSIX). Wrapped so a missing finder binary
|
|
160
|
+
// surfaces as null instead of an unhandled 'error' event (the ENOENT crash).
|
|
161
|
+
const finder = isWin ? "where" : "which";
|
|
162
|
+
return await new Promise((resolve) => {
|
|
152
163
|
let out = "";
|
|
153
|
-
|
|
154
|
-
|
|
164
|
+
let child;
|
|
165
|
+
try {
|
|
166
|
+
child = spawn(finder, ["hermes"], { stdio: ["ignore", "pipe", "ignore"] });
|
|
167
|
+
} catch {
|
|
168
|
+
return resolve(null);
|
|
169
|
+
}
|
|
170
|
+
child.on("error", () => resolve(null));
|
|
171
|
+
child.stdout.on("data", (d) => (out += d.toString()));
|
|
172
|
+
child.on("exit", () => {
|
|
173
|
+
const first = out
|
|
174
|
+
.split(/\r?\n/)
|
|
175
|
+
.map((s) => s.trim())
|
|
176
|
+
.filter(Boolean)[0];
|
|
177
|
+
resolve(first || null);
|
|
178
|
+
});
|
|
155
179
|
});
|
|
156
|
-
return which || null;
|
|
157
180
|
}
|
|
158
181
|
|
|
159
182
|
async function ensureHermesInstalled() {
|
|
160
183
|
const found = await locateHermes();
|
|
161
184
|
if (found) return found;
|
|
162
185
|
|
|
186
|
+
const isWin = process.platform === "win32";
|
|
163
187
|
process.stderr.write(
|
|
164
|
-
"[athena-agent] Hermes is not installed. Installing
|
|
188
|
+
"[athena-agent] Hermes is not installed. Installing (this is a one-time setup)…\n",
|
|
165
189
|
);
|
|
166
|
-
// `bash -s -- --skip-setup` passes the flag to the install script and
|
|
167
|
-
// suppresses its post-install wizard, so the user only ever sees Athena's UX.
|
|
168
190
|
const code = await new Promise((resolve) => {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
191
|
+
let c;
|
|
192
|
+
try {
|
|
193
|
+
c = isWin
|
|
194
|
+
? // Native Windows installer (PowerShell). Hermes' CLI + ACP run
|
|
195
|
+
// natively; only its own dashboard pane needs WSL2, which we don't use.
|
|
196
|
+
spawn(
|
|
197
|
+
"powershell",
|
|
198
|
+
[
|
|
199
|
+
"-NoProfile",
|
|
200
|
+
"-ExecutionPolicy",
|
|
201
|
+
"Bypass",
|
|
202
|
+
"-Command",
|
|
203
|
+
"iex (irm https://hermes-agent.nousresearch.com/install.ps1)",
|
|
204
|
+
],
|
|
205
|
+
{ stdio: "inherit" },
|
|
206
|
+
)
|
|
207
|
+
: // `bash -s -- --skip-setup` suppresses the installer's wizard so the
|
|
208
|
+
// user only ever sees Athena's UX.
|
|
209
|
+
spawn(
|
|
210
|
+
"bash",
|
|
211
|
+
[
|
|
212
|
+
"-c",
|
|
213
|
+
"curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash -s -- --skip-setup",
|
|
214
|
+
],
|
|
215
|
+
{ stdio: "inherit" },
|
|
216
|
+
);
|
|
217
|
+
} catch {
|
|
218
|
+
return resolve(1);
|
|
219
|
+
}
|
|
220
|
+
c.on("error", () => resolve(1));
|
|
174
221
|
c.on("exit", (code) => resolve(code ?? 1));
|
|
175
222
|
});
|
|
176
223
|
if (code !== 0) {
|
|
177
|
-
process.stderr.write(
|
|
224
|
+
process.stderr.write(
|
|
225
|
+
"[athena-agent] Hermes install failed. On Windows you can also install it manually\n" +
|
|
226
|
+
" (PowerShell): iex (irm https://hermes-agent.nousresearch.com/install.ps1)\n" +
|
|
227
|
+
" then re-run this command. Or use WSL2 for the fully-supported Linux path.\n",
|
|
228
|
+
);
|
|
178
229
|
return null;
|
|
179
230
|
}
|
|
180
231
|
process.stderr.write("[athena-agent] Hermes installed.\n");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "athena-agent-launcher",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Run an Athena-configured agent locally. Resolves runtime + bindings from the Athena control plane and spawns the correct agent binary (Anthropic SDK, OpenClaw, or Hermes).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|