@songsid/agend 2.0.8-beta.9 → 2.0.9-beta.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/README.md +8 -3
- package/dist/adapter-world.d.ts +1 -1
- package/dist/adapter-world.js +2 -2
- package/dist/adapter-world.js.map +1 -1
- package/dist/agent-endpoint.js +6 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/backend/codex.js +10 -3
- package/dist/backend/codex.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +4 -4
- package/dist/channel/adapters/discord.js +162 -111
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +1 -1
- package/dist/channel/adapters/telegram.js +3 -1
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/tool-router.js +4 -2
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/channel/tool-tracker.js +2 -2
- package/dist/channel/tool-tracker.js.map +1 -1
- package/dist/channel/types.d.ts +14 -6
- package/dist/cli.js +150 -95
- package/dist/cli.js.map +1 -1
- package/dist/daemon.d.ts +25 -1
- package/dist/daemon.js +149 -43
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-manager.d.ts +47 -5
- package/dist/fleet-manager.js +362 -139
- package/dist/fleet-manager.js.map +1 -1
- package/dist/instance-lifecycle.js +9 -0
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/logger.d.ts +9 -1
- package/dist/logger.js +17 -7
- package/dist/logger.js.map +1 -1
- package/dist/outbound-handlers.d.ts +3 -0
- package/dist/outbound-handlers.js +17 -0
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +1 -1
- package/dist/tmux-control.d.ts +10 -0
- package/dist/tmux-control.js +29 -0
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.d.ts +6 -0
- package/dist/tmux-manager.js +17 -0
- package/dist/tmux-manager.js.map +1 -1
- package/dist/topic-commands.d.ts +21 -0
- package/dist/topic-commands.js +73 -6
- package/dist/topic-commands.js.map +1 -1
- package/package.json +3 -1
package/dist/cli.js
CHANGED
|
@@ -131,12 +131,40 @@ fleet
|
|
|
131
131
|
.argument("[instance]", "Specific instance to stop")
|
|
132
132
|
.action(async (instance) => {
|
|
133
133
|
if (instance) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
134
|
+
// Stop a single instance via the RUNNING fleet's HTTP API. Do NOT spawn a
|
|
135
|
+
// detached FleetManager and call stopInstance(): its in-memory daemons map
|
|
136
|
+
// is empty, so lifecycle.stop falls back to reading the instance's
|
|
137
|
+
// daemon.pid — which is the shared fleet process pid (daemons run
|
|
138
|
+
// in-process) — and SIGTERMs the whole fleet.
|
|
139
|
+
const { loadFleetConfig } = await import("./config.js");
|
|
140
|
+
const fleet = loadFleetConfig(FLEET_CONFIG_PATH);
|
|
141
|
+
const port = fleet.health_port ?? 19280;
|
|
142
|
+
let token = "";
|
|
143
|
+
try {
|
|
144
|
+
token = readFileSync(join(DATA_DIR, "web.token"), "utf-8").trim();
|
|
145
|
+
}
|
|
146
|
+
catch { /* fleet may not be running */ }
|
|
147
|
+
try {
|
|
148
|
+
const resp = await fetch(`http://127.0.0.1:${port}/stop/${encodeURIComponent(instance)}`, {
|
|
149
|
+
method: "POST",
|
|
150
|
+
headers: token ? { "X-Agend-Token": token } : {},
|
|
151
|
+
});
|
|
152
|
+
const body = await resp.json().catch(() => ({}));
|
|
153
|
+
if (resp.ok) {
|
|
154
|
+
console.log(`Instance "${instance}" stopped`);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
console.error(`Stop failed: ${body.error ?? resp.statusText}`);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
console.error(`Cannot connect to fleet (port ${port}). Is the fleet running?`);
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
return;
|
|
138
166
|
}
|
|
139
|
-
|
|
167
|
+
{
|
|
140
168
|
const pidPath = join(DATA_DIR, "fleet.pid");
|
|
141
169
|
if (!existsSync(pidPath)) {
|
|
142
170
|
console.error("Fleet is not running (no PID file found)");
|
|
@@ -185,8 +213,16 @@ fleet
|
|
|
185
213
|
const { loadFleetConfig } = await import("./config.js");
|
|
186
214
|
const fleet = loadFleetConfig(FLEET_CONFIG_PATH);
|
|
187
215
|
const port = fleet.health_port ?? 19280;
|
|
216
|
+
let token = "";
|
|
217
|
+
try {
|
|
218
|
+
token = readFileSync(join(DATA_DIR, "web.token"), "utf-8").trim();
|
|
219
|
+
}
|
|
220
|
+
catch { /* fleet may not be running */ }
|
|
188
221
|
try {
|
|
189
|
-
const resp = await fetch(`http://127.0.0.1:${port}/restart/${encodeURIComponent(instance)}`, {
|
|
222
|
+
const resp = await fetch(`http://127.0.0.1:${port}/restart/${encodeURIComponent(instance)}`, {
|
|
223
|
+
method: "POST",
|
|
224
|
+
headers: token ? { "X-Agend-Token": token } : {},
|
|
225
|
+
});
|
|
190
226
|
const body = await resp.json();
|
|
191
227
|
if (resp.ok) {
|
|
192
228
|
console.log(`Instance "${instance}" restarted (immediate)`);
|
|
@@ -1046,8 +1082,7 @@ program
|
|
|
1046
1082
|
.option("--version <ver>", "Specific version to install")
|
|
1047
1083
|
.option("--beta", "Install beta version")
|
|
1048
1084
|
.action(async (opts) => {
|
|
1049
|
-
const {
|
|
1050
|
-
const { spawnSync, spawn: spawnAsync } = await import("node:child_process");
|
|
1085
|
+
const { spawnSync } = await import("node:child_process");
|
|
1051
1086
|
const tag = opts.version ? opts.version : (opts.beta ? "beta" : "latest");
|
|
1052
1087
|
const pkg = `@songsid/agend@${tag}`;
|
|
1053
1088
|
console.log(`\n Updating AgEnD to ${tag}...\n`);
|
|
@@ -1139,7 +1174,6 @@ program
|
|
|
1139
1174
|
const newVersion = (verifyResult.stdout ?? "").trim();
|
|
1140
1175
|
console.log(` ✓ Installed: ${newVersion}`);
|
|
1141
1176
|
// ── Update service file ──
|
|
1142
|
-
const plat = detectPlatform();
|
|
1143
1177
|
if (agendPath) {
|
|
1144
1178
|
try {
|
|
1145
1179
|
// Use the NEW binary to install service (old binary's templates may be deleted)
|
|
@@ -1156,69 +1190,19 @@ program
|
|
|
1156
1190
|
}
|
|
1157
1191
|
}
|
|
1158
1192
|
// ── Restart fleet ──
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
// Kill old fleet process first to prevent duplicate
|
|
1165
|
-
const oldPid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
1166
|
-
if (oldPid) {
|
|
1167
|
-
try {
|
|
1168
|
-
process.kill(oldPid, "SIGTERM");
|
|
1169
|
-
}
|
|
1170
|
-
catch { /* already gone */ }
|
|
1171
|
-
// Wait up to 10s for old process to exit
|
|
1172
|
-
for (let i = 0; i < 20; i++) {
|
|
1173
|
-
try {
|
|
1174
|
-
process.kill(oldPid, 0);
|
|
1175
|
-
}
|
|
1176
|
-
catch {
|
|
1177
|
-
break;
|
|
1178
|
-
}
|
|
1179
|
-
spawnSync("sleep", ["0.5"]);
|
|
1180
|
-
}
|
|
1181
|
-
// Force kill if still alive
|
|
1182
|
-
try {
|
|
1183
|
-
process.kill(oldPid, "SIGKILL");
|
|
1184
|
-
}
|
|
1185
|
-
catch { /* already gone */ }
|
|
1186
|
-
try {
|
|
1187
|
-
unlinkSync(pidPath);
|
|
1188
|
-
}
|
|
1189
|
-
catch { /* best effort */ }
|
|
1190
|
-
}
|
|
1193
|
+
// Run the restart through the NEWLY-INSTALLED binary (agendPath), not inline.
|
|
1194
|
+
// The inline restart would execute the OLD binary's code — exactly the logic
|
|
1195
|
+
// that may be missing or buggy on the version being upgraded from. `agend
|
|
1196
|
+
// restart` (new binary) does the 4-environment service detection (system
|
|
1197
|
+
// systemd → user systemd → launchd → detached pid).
|
|
1191
1198
|
console.log(" Restarting fleet...");
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
try {
|
|
1196
|
-
execSync(`launchctl kickstart -k gui/${uid}/${label}`, { stdio: "inherit", timeout: 15000 });
|
|
1197
|
-
console.log(" ✓ Service restarted\n");
|
|
1198
|
-
return;
|
|
1199
|
-
}
|
|
1200
|
-
catch { /* fall through to manual restart */ }
|
|
1199
|
+
const restartResult = spawnSync(agendPath, ["restart"], { encoding: "utf-8", timeout: 30000, stdio: "inherit" });
|
|
1200
|
+
if (restartResult.status === 0) {
|
|
1201
|
+
console.log(" ✓ Service restarted");
|
|
1201
1202
|
}
|
|
1202
1203
|
else {
|
|
1203
|
-
|
|
1204
|
-
execSync("systemctl --user daemon-reload", { stdio: "pipe", timeout: 5000 });
|
|
1205
|
-
// Reset failed state in case the kill above left systemd confused
|
|
1206
|
-
try {
|
|
1207
|
-
execSync("systemctl --user reset-failed com.agend.fleet", { stdio: "pipe", timeout: 5000 });
|
|
1208
|
-
}
|
|
1209
|
-
catch { }
|
|
1210
|
-
execSync("systemctl --user start com.agend.fleet", { stdio: "inherit", timeout: 15000 });
|
|
1211
|
-
console.log(" ✓ Service restarted\n");
|
|
1212
|
-
return;
|
|
1213
|
-
}
|
|
1214
|
-
catch { /* fall through */ }
|
|
1204
|
+
console.log(" ⚠ Auto-restart failed. Run: agend start");
|
|
1215
1205
|
}
|
|
1216
|
-
// Fallback: start directly using new binary
|
|
1217
|
-
const child = spawnAsync(agendPath, ["fleet", "start"], {
|
|
1218
|
-
detached: true, stdio: "ignore",
|
|
1219
|
-
});
|
|
1220
|
-
child.unref();
|
|
1221
|
-
console.log(" ✓ Fleet restarting in background\n");
|
|
1222
1206
|
});
|
|
1223
1207
|
program
|
|
1224
1208
|
.command("reload")
|
|
@@ -1354,43 +1338,114 @@ program
|
|
|
1354
1338
|
});
|
|
1355
1339
|
program
|
|
1356
1340
|
.command("restart")
|
|
1357
|
-
.description("Restart the AgEnD service")
|
|
1341
|
+
.description("Restart the AgEnD service (auto-detects systemd/launchd/detached)")
|
|
1358
1342
|
.action(async () => {
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1343
|
+
// Try each runtime environment in order and stop at the first that succeeds.
|
|
1344
|
+
// Don't gate on fleet.pid: a fleet under systemd/launchd writes its pid in the
|
|
1345
|
+
// service's own HOME, which may differ from what this command resolves (sudo,
|
|
1346
|
+
// AGEND_HOME) — an absent pid file does NOT mean it's stopped. Ask the service
|
|
1347
|
+
// manager first. This is the canonical restart the `update` flow spawns.
|
|
1348
|
+
const { detectPlatform } = await import("./service-installer.js");
|
|
1349
|
+
const { spawn, spawnSync } = await import("node:child_process");
|
|
1350
|
+
const plat = detectPlatform();
|
|
1364
1351
|
const pidPath = join(DATA_DIR, "fleet.pid");
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1352
|
+
const isActive = (cmd) => {
|
|
1353
|
+
try {
|
|
1354
|
+
return spawnSync("sh", ["-c", cmd], { encoding: "utf-8", timeout: 5000 }).stdout?.trim() === "active";
|
|
1355
|
+
}
|
|
1356
|
+
catch {
|
|
1357
|
+
return false;
|
|
1358
|
+
}
|
|
1359
|
+
};
|
|
1360
|
+
const run = (cmd) => {
|
|
1361
|
+
try {
|
|
1362
|
+
execSync(cmd, { stdio: "inherit", timeout: 15000 });
|
|
1363
|
+
return true;
|
|
1364
|
+
}
|
|
1365
|
+
catch {
|
|
1366
|
+
return false;
|
|
1367
|
+
}
|
|
1368
|
+
};
|
|
1369
|
+
// 1. System-level systemd service "agend"
|
|
1370
|
+
if (plat !== "macos" && isActive("systemctl is-active agend 2>/dev/null")) {
|
|
1371
|
+
run("systemctl daemon-reload");
|
|
1372
|
+
if (run("systemctl restart agend")) {
|
|
1373
|
+
console.log("Service restarted (system).");
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
// 2. User-level systemd service "com.agend.fleet"
|
|
1378
|
+
if (plat !== "macos" && isActive("systemctl --user is-active com.agend.fleet 2>/dev/null")) {
|
|
1379
|
+
run("systemctl --user daemon-reload");
|
|
1380
|
+
try {
|
|
1381
|
+
execSync("systemctl --user reset-failed com.agend.fleet", { stdio: "pipe", timeout: 5000 });
|
|
1382
|
+
}
|
|
1383
|
+
catch { /* best effort */ }
|
|
1384
|
+
if (run("systemctl --user restart com.agend.fleet")) {
|
|
1385
|
+
console.log("Service restarted (user).");
|
|
1386
|
+
return;
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
// 3. launchd (macOS)
|
|
1390
|
+
if (plat === "macos") {
|
|
1391
|
+
const uid = process.getuid?.() ?? 501;
|
|
1392
|
+
const label = "com.agend.fleet";
|
|
1393
|
+
try {
|
|
1394
|
+
// print succeeds only if the service is loaded in launchd
|
|
1395
|
+
execSync(`launchctl print gui/${uid}/${label}`, { stdio: "pipe", timeout: 5000 });
|
|
1396
|
+
if (run(`launchctl kickstart -k gui/${uid}/${label}`)) {
|
|
1397
|
+
console.log("Service restarted.");
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
catch { /* not loaded — fall through */ }
|
|
1402
|
+
}
|
|
1403
|
+
// 4. Detached process tracked by fleet.pid (no service manager)
|
|
1404
|
+
if (existsSync(pidPath)) {
|
|
1405
|
+
const oldPid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
1406
|
+
let alive = false;
|
|
1375
1407
|
if (oldPid) {
|
|
1376
1408
|
try {
|
|
1377
1409
|
process.kill(oldPid, 0);
|
|
1410
|
+
alive = true;
|
|
1378
1411
|
}
|
|
1379
|
-
catch {
|
|
1380
|
-
|
|
1412
|
+
catch { /* dead or not ours */ }
|
|
1413
|
+
}
|
|
1414
|
+
if (alive) {
|
|
1415
|
+
try {
|
|
1416
|
+
process.kill(oldPid, "SIGTERM");
|
|
1417
|
+
}
|
|
1418
|
+
catch { /* already gone */ }
|
|
1419
|
+
for (let i = 0; i < 20; i++) {
|
|
1420
|
+
try {
|
|
1421
|
+
process.kill(oldPid, 0);
|
|
1422
|
+
}
|
|
1423
|
+
catch {
|
|
1424
|
+
break;
|
|
1425
|
+
}
|
|
1426
|
+
spawnSync("sleep", ["0.5"]);
|
|
1381
1427
|
}
|
|
1428
|
+
try {
|
|
1429
|
+
process.kill(oldPid, "SIGKILL");
|
|
1430
|
+
}
|
|
1431
|
+
catch { /* already gone */ }
|
|
1432
|
+
try {
|
|
1433
|
+
unlinkSync(pidPath);
|
|
1434
|
+
}
|
|
1435
|
+
catch { /* best effort */ }
|
|
1436
|
+
const child = spawn("sh", ["-c", "agend fleet start"], { detached: true, stdio: "ignore" });
|
|
1437
|
+
child.unref();
|
|
1438
|
+
console.log("Fleet restarting in background.");
|
|
1439
|
+
return;
|
|
1382
1440
|
}
|
|
1383
|
-
|
|
1384
|
-
|
|
1441
|
+
// Stale pid file (process gone) — clean it up before declaring stopped.
|
|
1442
|
+
try {
|
|
1443
|
+
unlinkSync(pidPath);
|
|
1385
1444
|
}
|
|
1386
|
-
|
|
1387
|
-
}
|
|
1388
|
-
if (startService()) {
|
|
1389
|
-
console.log("Service restarted.");
|
|
1390
|
-
}
|
|
1391
|
-
else {
|
|
1392
|
-
console.log("Failed to restart service.");
|
|
1445
|
+
catch { /* best effort */ }
|
|
1393
1446
|
}
|
|
1447
|
+
// 5. Nothing running anywhere
|
|
1448
|
+
console.log("Fleet not running. Start with: agend start");
|
|
1394
1449
|
});
|
|
1395
1450
|
program
|
|
1396
1451
|
.command("quickstart")
|