@openape/nest 1.1.1 → 1.1.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.
- package/dist/index.mjs +59 -9
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -264,6 +264,21 @@ module.exports = {
|
|
|
264
264
|
}
|
|
265
265
|
`;
|
|
266
266
|
}
|
|
267
|
+
function startScriptPath(agentName) {
|
|
268
|
+
return join3(AGENTS_DIR, agentName, "start.sh");
|
|
269
|
+
}
|
|
270
|
+
function startScriptContents(agentName) {
|
|
271
|
+
const ecosystem = ecosystemPath(agentName);
|
|
272
|
+
const log2 = `/var/log/openape/${agentName}-pm2.log`;
|
|
273
|
+
return `#!/bin/bash
|
|
274
|
+
# Auto-generated by Pm2Supervisor for agent '${agentName}'.
|
|
275
|
+
set -e
|
|
276
|
+
export HOME="/Users/${agentName}"
|
|
277
|
+
export PM2_HOME="$HOME/.pm2"
|
|
278
|
+
mkdir -p "$(dirname "${log2}")"
|
|
279
|
+
exec pm2 startOrReload ${ecosystem} >> ${log2} 2>&1 < /dev/null
|
|
280
|
+
`;
|
|
281
|
+
}
|
|
267
282
|
var Pm2Supervisor = class {
|
|
268
283
|
constructor(deps) {
|
|
269
284
|
this.deps = deps;
|
|
@@ -278,7 +293,7 @@ var Pm2Supervisor = class {
|
|
|
278
293
|
try {
|
|
279
294
|
await this.startOrReload(agent.name);
|
|
280
295
|
} catch (err) {
|
|
281
|
-
this.deps.log(`pm2-supervisor: ${agent.name}
|
|
296
|
+
this.deps.log(`pm2-supervisor: ${agent.name} reconcile errored: ${err instanceof Error ? err.message.split("\n")[0] : String(err)}`);
|
|
282
297
|
} finally {
|
|
283
298
|
this.inflight.delete(agent.name);
|
|
284
299
|
}
|
|
@@ -305,17 +320,52 @@ var Pm2Supervisor = class {
|
|
|
305
320
|
mkdirSync3(dir, { recursive: true, mode: 493 });
|
|
306
321
|
const path = ecosystemPath(agentName);
|
|
307
322
|
writeFileSync3(path, ecosystemContents(this.deps.apesBin, agentName), { mode: 420 });
|
|
308
|
-
|
|
309
|
-
|
|
323
|
+
const startPath = startScriptPath(agentName);
|
|
324
|
+
writeFileSync3(startPath, startScriptContents(agentName), { mode: 493 });
|
|
325
|
+
void path;
|
|
326
|
+
try {
|
|
327
|
+
await this.runAsAgent(agentName, ["bash", startPath]);
|
|
328
|
+
} catch {
|
|
329
|
+
}
|
|
330
|
+
let online = false;
|
|
331
|
+
try {
|
|
332
|
+
const { stdout } = await this.runAsAgent(agentName, ["pm2", "jlist"]);
|
|
333
|
+
const json = stdout.match(/\[\s*\{.*\}\s*\]/s)?.[0];
|
|
334
|
+
if (json) {
|
|
335
|
+
const list = JSON.parse(json);
|
|
336
|
+
online = list.some((p) => p.name === pm2AppName(agentName) && p.pm2_env?.status === "online");
|
|
337
|
+
}
|
|
338
|
+
} catch {
|
|
339
|
+
}
|
|
340
|
+
if (online) {
|
|
341
|
+
this.deps.log(`pm2-supervisor: ${agentName} bridge online (pm2)`);
|
|
342
|
+
} else {
|
|
343
|
+
this.deps.log(`pm2-supervisor: ${agentName} bridge NOT online \u2014 see /var/log/openape/${agentName}-pm2.log`);
|
|
344
|
+
}
|
|
310
345
|
}
|
|
311
346
|
/** Run a pm2 subcommand AS the agent — escapes-helper does the
|
|
312
|
-
* setuid switch, then exec's pm2 in the agent's uid.
|
|
347
|
+
* setuid switch, then exec's pm2 in the agent's uid.
|
|
348
|
+
*
|
|
349
|
+
* cwd: the agent process inherits cwd from the spawning Nest
|
|
350
|
+
* daemon, whose cwd is /var/openape/nest (mode 750, no access for
|
|
351
|
+
* other uids). Without setting cwd to a world-readable dir, the
|
|
352
|
+
* child's first `process.cwd()` call (which Node does internally
|
|
353
|
+
* during module loading) throws EACCES. /tmp is the most portable
|
|
354
|
+
* always-writable location.
|
|
355
|
+
*/
|
|
313
356
|
async runAsAgent(agentName, args) {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
357
|
+
try {
|
|
358
|
+
return await execFileAsync2(
|
|
359
|
+
this.deps.apesBin,
|
|
360
|
+
["run", "--as", agentName, "--wait", "--", ...args],
|
|
361
|
+
{ maxBuffer: 1024 * 1024, env: process.env, timeout: 6e4, cwd: "/tmp" }
|
|
362
|
+
);
|
|
363
|
+
} catch (err) {
|
|
364
|
+
const e = err;
|
|
365
|
+
const detail = (e.stderr ?? "").trim().split("\n").slice(-3).join(" / ");
|
|
366
|
+
const stdoutDetail = (e.stdout ?? "").trim().split("\n").slice(-2).join(" / ");
|
|
367
|
+
throw new Error(`${e.message?.split("\n")[0] ?? "execFile failed"} | stderr: ${detail || "<empty>"} | stdout: ${stdoutDetail || "<empty>"}`);
|
|
368
|
+
}
|
|
319
369
|
}
|
|
320
370
|
};
|
|
321
371
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openape/nest",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "OpenApe Nest — local control-plane daemon that supervises agent processes on this computer. Talks to troop SP for ownership state, spawns/destroys agents via DDISA always-grants, supervises chat-bridge children (replacing per-agent launchd plists).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"ofetch": "^1.4.1",
|
|
20
|
-
"@openape/
|
|
21
|
-
"@openape/
|
|
20
|
+
"@openape/cli-auth": "0.4.0",
|
|
21
|
+
"@openape/core": "0.16.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@antfu/eslint-config": "^7.6.1",
|