@integrity-labs/agt-cli 0.14.7 → 0.14.10
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/bin/agt.js +211 -548
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-JL4XSENX.js → chunk-4CZUEGNQ.js} +11 -17
- package/dist/chunk-4CZUEGNQ.js.map +1 -0
- package/dist/{chunk-5SFAHM2Z.js → chunk-RMTMETCK.js} +479 -24
- package/dist/chunk-RMTMETCK.js.map +1 -0
- package/dist/lib/manager-worker.js +44 -16
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-SRUW7AWU.js → persistent-session-GBQ3VQK3.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-5SFAHM2Z.js.map +0 -1
- package/dist/chunk-JL4XSENX.js.map +0 -1
- /package/dist/{persistent-session-SRUW7AWU.js.map → persistent-session-GBQ3VQK3.js.map} +0 -0
|
@@ -11,6 +11,7 @@ var EXECUTION_PREAMBLE = [
|
|
|
11
11
|
"\u2022 Do not expose internal bookkeeping to the recipient \u2014 memory files, saved paths, kanban status, or meta-notes about how the work was done. Only the deliverable content belongs in your response.",
|
|
12
12
|
"\u2022 Exception: if your output references a specific kanban card (for example, you just completed, updated, or made progress on a tracked item), include the deep-link URL that the kanban tool returned alongside the card name. The link is part of the deliverable \u2014 it lets the user jump straight to the card \u2014 not meta-bookkeeping.",
|
|
13
13
|
'\u2022 Suppressing delivery (rare, opt-in only): `<no-delivery/>` is a last-resort token that tells the gateway to skip the send. Use it ONLY when the instruction itself contains EXPLICIT opt-out wording the user typed \u2014 literally "DO NOT notify me", "don\'t send anything", "skip delivery", "stay silent", or an explicit "unless"/"only if" that the user typed as a condition on sending (e.g. "notify me ONLY if urgent", "DO NOT notify me if there\'s nothing urgent"). The trigger must be the user\'s words, not your judgement that the result is "empty" or "uneventful". Do NOT use `<no-delivery/>` just because a report has zero items \u2014 "no follow-ups today", "nothing urgent", "all quiet", "no open PRs", "no action items" are VALID deliverables when the task asks for a report or digest. A report of nothing is still a report the user asked for. When in doubt, deliver.',
|
|
14
|
+
'\u2022 If you DO emit `<no-delivery/>`, emit it ALONE \u2014 it must be the entire response, with no other text, no "Nothing urgent.", no attribution, no footer, no `[notes]` block above or below. The sentinel combined with other content leaks an internal token into the recipient\'s chat; the only safe shapes are (a) the sentinel by itself, or (b) a normal deliverable with NO sentinel anywhere in it. Never both.',
|
|
14
15
|
"\u2022 Do not over-deliver. Match the scope and length of the request. A yes/no question gets a one-line answer; a brief request gets the brief, not a dissertation. Long rambling messages are not useful \u2014 cut any section, caveat, or restatement that does not directly answer the instruction.",
|
|
15
16
|
"",
|
|
16
17
|
"Instruction:"
|
|
@@ -1854,11 +1855,11 @@ ${entry.content}`
|
|
|
1854
1855
|
AGENT_PROJECT_DIR: projectDir,
|
|
1855
1856
|
AGENT_FRAMEWORK: "openclaw"
|
|
1856
1857
|
}
|
|
1857
|
-
}, (
|
|
1858
|
+
}, (error2, stdout, stderr) => {
|
|
1858
1859
|
const durationMs = Date.now() - startedAt;
|
|
1859
|
-
const timedOut = !!
|
|
1860
|
+
const timedOut = !!error2 && error2.code === "ETIMEDOUT";
|
|
1860
1861
|
resolve3({
|
|
1861
|
-
exitCode:
|
|
1862
|
+
exitCode: error2 ? typeof error2.code === "number" ? error2.code : 1 : 0,
|
|
1862
1863
|
stdout: stdout?.toString() ?? "",
|
|
1863
1864
|
stderr: stderr?.toString() ?? "",
|
|
1864
1865
|
durationMs,
|
|
@@ -3239,8 +3240,8 @@ ${sections}`
|
|
|
3239
3240
|
const agentDir = getAgentDir(codeName);
|
|
3240
3241
|
const regFile = join4(agentDir, "registration.json");
|
|
3241
3242
|
if (existsSync4(regFile)) {
|
|
3242
|
-
const { unlinkSync:
|
|
3243
|
-
|
|
3243
|
+
const { unlinkSync: unlinkSync4 } = await import("fs");
|
|
3244
|
+
unlinkSync4(regFile);
|
|
3244
3245
|
}
|
|
3245
3246
|
return true;
|
|
3246
3247
|
} catch {
|
|
@@ -3786,11 +3787,11 @@ ${sections}`
|
|
|
3786
3787
|
AGENT_PROJECT_DIR: projectDir,
|
|
3787
3788
|
AGENT_FRAMEWORK: "claude-code"
|
|
3788
3789
|
}
|
|
3789
|
-
}, (
|
|
3790
|
+
}, (error2, stdout, stderr) => {
|
|
3790
3791
|
const durationMs = Date.now() - startedAt;
|
|
3791
|
-
const timedOut = !!
|
|
3792
|
+
const timedOut = !!error2 && error2.code === "ETIMEDOUT";
|
|
3792
3793
|
resolve3({
|
|
3793
|
-
exitCode:
|
|
3794
|
+
exitCode: error2 ? typeof error2.code === "number" ? error2.code : 1 : 0,
|
|
3794
3795
|
stdout: stdout?.toString() ?? "",
|
|
3795
3796
|
stderr: stderr?.toString() ?? "",
|
|
3796
3797
|
durationMs,
|
|
@@ -4084,6 +4085,22 @@ var ManagedAgentsAdapter = {
|
|
|
4084
4085
|
};
|
|
4085
4086
|
registerFramework(ManagedAgentsAdapter);
|
|
4086
4087
|
|
|
4088
|
+
// src/lib/globals.ts
|
|
4089
|
+
import chalk from "chalk";
|
|
4090
|
+
var _jsonMode = false;
|
|
4091
|
+
function setJsonMode(enabled) {
|
|
4092
|
+
_jsonMode = enabled;
|
|
4093
|
+
if (enabled) {
|
|
4094
|
+
chalk.level = 0;
|
|
4095
|
+
}
|
|
4096
|
+
}
|
|
4097
|
+
function isJsonMode() {
|
|
4098
|
+
return _jsonMode;
|
|
4099
|
+
}
|
|
4100
|
+
function jsonOutput(data) {
|
|
4101
|
+
console.log(JSON.stringify(data, null, 2));
|
|
4102
|
+
}
|
|
4103
|
+
|
|
4087
4104
|
// src/lib/config.ts
|
|
4088
4105
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync5 } from "fs";
|
|
4089
4106
|
import { join as join6 } from "path";
|
|
@@ -4795,14 +4812,35 @@ function validateHeadings(body, requiredHeadings = REQUIRED_CHARTER_HEADINGS) {
|
|
|
4795
4812
|
}
|
|
4796
4813
|
|
|
4797
4814
|
// ../../packages/core/dist/scheduled-tasks/suppress.js
|
|
4798
|
-
var
|
|
4799
|
-
function
|
|
4800
|
-
if (output == null)
|
|
4801
|
-
return
|
|
4815
|
+
var SENTINEL_REGEX = /<no-delivery\/>/g;
|
|
4816
|
+
function classifyOutput(output) {
|
|
4817
|
+
if (output == null) {
|
|
4818
|
+
return { action: "suppress", deliverable: "", suppressedNotes: "" };
|
|
4819
|
+
}
|
|
4802
4820
|
const trimmed = output.trim();
|
|
4803
|
-
if (trimmed.length === 0)
|
|
4804
|
-
return
|
|
4805
|
-
|
|
4821
|
+
if (trimmed.length === 0) {
|
|
4822
|
+
return { action: "suppress", deliverable: "", suppressedNotes: "" };
|
|
4823
|
+
}
|
|
4824
|
+
if (!SENTINEL_REGEX.test(trimmed)) {
|
|
4825
|
+
SENTINEL_REGEX.lastIndex = 0;
|
|
4826
|
+
return { action: "deliver", deliverable: output, suppressedNotes: "" };
|
|
4827
|
+
}
|
|
4828
|
+
SENTINEL_REGEX.lastIndex = 0;
|
|
4829
|
+
const withoutSentinel = trimmed.replace(SENTINEL_REGEX, "").trim();
|
|
4830
|
+
if (withoutSentinel.length === 0) {
|
|
4831
|
+
return { action: "suppress", deliverable: "", suppressedNotes: "" };
|
|
4832
|
+
}
|
|
4833
|
+
if (looksLikeNotesOnly(withoutSentinel)) {
|
|
4834
|
+
return { action: "suppress", deliverable: "", suppressedNotes: withoutSentinel };
|
|
4835
|
+
}
|
|
4836
|
+
const cleaned = output.replace(SENTINEL_REGEX, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
4837
|
+
return { action: "strip", deliverable: cleaned, suppressedNotes: "" };
|
|
4838
|
+
}
|
|
4839
|
+
function looksLikeNotesOnly(remainder) {
|
|
4840
|
+
const lines = remainder.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
|
|
4841
|
+
if (lines.length === 0)
|
|
4842
|
+
return false;
|
|
4843
|
+
return lines[0].toLowerCase().startsWith("[notes]");
|
|
4806
4844
|
}
|
|
4807
4845
|
|
|
4808
4846
|
// ../../packages/core/dist/schemas/validators.js
|
|
@@ -5758,13 +5796,13 @@ function buildResult(diagnostics) {
|
|
|
5758
5796
|
}
|
|
5759
5797
|
function lintCharter(content, ctx = {}) {
|
|
5760
5798
|
const diagnostics = [];
|
|
5761
|
-
const { frontmatter, body, error } = extractFrontmatter(content);
|
|
5762
|
-
if (
|
|
5799
|
+
const { frontmatter, body, error: error2 } = extractFrontmatter(content);
|
|
5800
|
+
if (error2 || !frontmatter) {
|
|
5763
5801
|
diagnostics.push({
|
|
5764
5802
|
file: "CHARTER.md",
|
|
5765
5803
|
code: "CHARTER.PARSE.FRONTMATTER",
|
|
5766
5804
|
severity: "error",
|
|
5767
|
-
message:
|
|
5805
|
+
message: error2 ?? "Failed to parse frontmatter"
|
|
5768
5806
|
});
|
|
5769
5807
|
return buildResult(diagnostics);
|
|
5770
5808
|
}
|
|
@@ -5788,13 +5826,13 @@ function lintCharter(content, ctx = {}) {
|
|
|
5788
5826
|
}
|
|
5789
5827
|
function lintTools(content) {
|
|
5790
5828
|
const diagnostics = [];
|
|
5791
|
-
const { frontmatter, error } = extractFrontmatter(content);
|
|
5792
|
-
if (
|
|
5829
|
+
const { frontmatter, error: error2 } = extractFrontmatter(content);
|
|
5830
|
+
if (error2 || !frontmatter) {
|
|
5793
5831
|
diagnostics.push({
|
|
5794
5832
|
file: "TOOLS.md",
|
|
5795
5833
|
code: "TOOLS.PARSE.FRONTMATTER",
|
|
5796
5834
|
severity: "error",
|
|
5797
|
-
message:
|
|
5835
|
+
message: error2 ?? "Failed to parse frontmatter"
|
|
5798
5836
|
});
|
|
5799
5837
|
return buildResult(diagnostics);
|
|
5800
5838
|
}
|
|
@@ -6344,6 +6382,410 @@ function provision(input, frameworkId = "openclaw") {
|
|
|
6344
6382
|
};
|
|
6345
6383
|
}
|
|
6346
6384
|
|
|
6385
|
+
// src/commands/manager.ts
|
|
6386
|
+
import chalk3 from "chalk";
|
|
6387
|
+
import { join as join8 } from "path";
|
|
6388
|
+
import { homedir as homedir6 } from "os";
|
|
6389
|
+
import { spawn as spawn3 } from "child_process";
|
|
6390
|
+
|
|
6391
|
+
// src/lib/watchdog.ts
|
|
6392
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, unlinkSync as unlinkSync3, existsSync as existsSync6, mkdirSync as mkdirSync6, openSync, closeSync, chmodSync as chmodSync5 } from "fs";
|
|
6393
|
+
import { join as join7 } from "path";
|
|
6394
|
+
import { spawn as spawn2 } from "child_process";
|
|
6395
|
+
var DEFAULT_CONFIG_DIR = join7(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
6396
|
+
function getManagerPaths(configDir) {
|
|
6397
|
+
return {
|
|
6398
|
+
pidFile: join7(configDir, "manager.pid"),
|
|
6399
|
+
stateFile: join7(configDir, "manager-state.json"),
|
|
6400
|
+
logFile: join7(configDir, "manager.log")
|
|
6401
|
+
};
|
|
6402
|
+
}
|
|
6403
|
+
function ensureDir2(configDir) {
|
|
6404
|
+
if (!existsSync6(configDir)) {
|
|
6405
|
+
mkdirSync6(configDir, { recursive: true });
|
|
6406
|
+
}
|
|
6407
|
+
}
|
|
6408
|
+
function writePidFile(configDir, pid) {
|
|
6409
|
+
ensureDir2(configDir);
|
|
6410
|
+
writeFileSync6(getManagerPaths(configDir).pidFile, String(pid), { mode: 384 });
|
|
6411
|
+
}
|
|
6412
|
+
function readPidFile(configDir) {
|
|
6413
|
+
try {
|
|
6414
|
+
const raw = readFileSync6(getManagerPaths(configDir).pidFile, "utf-8").trim();
|
|
6415
|
+
const pid = parseInt(raw, 10);
|
|
6416
|
+
return isNaN(pid) ? null : pid;
|
|
6417
|
+
} catch {
|
|
6418
|
+
return null;
|
|
6419
|
+
}
|
|
6420
|
+
}
|
|
6421
|
+
function removePidFile(configDir) {
|
|
6422
|
+
try {
|
|
6423
|
+
unlinkSync3(getManagerPaths(configDir).pidFile);
|
|
6424
|
+
} catch {
|
|
6425
|
+
}
|
|
6426
|
+
}
|
|
6427
|
+
function isProcessAlive2(pid) {
|
|
6428
|
+
try {
|
|
6429
|
+
process.kill(pid, 0);
|
|
6430
|
+
return true;
|
|
6431
|
+
} catch {
|
|
6432
|
+
return false;
|
|
6433
|
+
}
|
|
6434
|
+
}
|
|
6435
|
+
function readStateFile(configDir) {
|
|
6436
|
+
try {
|
|
6437
|
+
const raw = readFileSync6(getManagerPaths(configDir).stateFile, "utf-8");
|
|
6438
|
+
return JSON.parse(raw);
|
|
6439
|
+
} catch {
|
|
6440
|
+
return null;
|
|
6441
|
+
}
|
|
6442
|
+
}
|
|
6443
|
+
function removeStateFile(configDir) {
|
|
6444
|
+
try {
|
|
6445
|
+
unlinkSync3(getManagerPaths(configDir).stateFile);
|
|
6446
|
+
} catch {
|
|
6447
|
+
}
|
|
6448
|
+
}
|
|
6449
|
+
function startWatchdog(opts) {
|
|
6450
|
+
const { configDir } = opts;
|
|
6451
|
+
const existingPid = readPidFile(configDir);
|
|
6452
|
+
if (existingPid !== null) {
|
|
6453
|
+
if (isProcessAlive2(existingPid)) {
|
|
6454
|
+
throw new Error(`Manager already running (PID ${existingPid}). Use \`agt manager stop\` first.`);
|
|
6455
|
+
}
|
|
6456
|
+
removePidFile(configDir);
|
|
6457
|
+
removeStateFile(configDir);
|
|
6458
|
+
}
|
|
6459
|
+
if (opts.detached) {
|
|
6460
|
+
ensureDir2(configDir);
|
|
6461
|
+
const { logFile } = getManagerPaths(configDir);
|
|
6462
|
+
const logFd = openSync(logFile, "a", 384);
|
|
6463
|
+
try {
|
|
6464
|
+
chmodSync5(logFile, 384);
|
|
6465
|
+
} catch {
|
|
6466
|
+
}
|
|
6467
|
+
const intervalSec = String(Math.max(Math.floor(opts.intervalMs / 1e3), 5));
|
|
6468
|
+
const child = spawn2(
|
|
6469
|
+
process.execPath,
|
|
6470
|
+
[process.argv[1], "manager", "start", "--interval", intervalSec, "--config-dir", configDir],
|
|
6471
|
+
{
|
|
6472
|
+
detached: true,
|
|
6473
|
+
stdio: ["ignore", logFd, logFd],
|
|
6474
|
+
env: process.env
|
|
6475
|
+
}
|
|
6476
|
+
);
|
|
6477
|
+
child.unref();
|
|
6478
|
+
closeSync(logFd);
|
|
6479
|
+
if (!child.pid) {
|
|
6480
|
+
throw new Error("Failed to spawn detached manager process");
|
|
6481
|
+
}
|
|
6482
|
+
const { pidFile } = getManagerPaths(configDir);
|
|
6483
|
+
const deadline = Date.now() + 5e3;
|
|
6484
|
+
const sleepBuf = new Int32Array(new SharedArrayBuffer(4));
|
|
6485
|
+
while (Date.now() < deadline) {
|
|
6486
|
+
if (existsSync6(pidFile)) {
|
|
6487
|
+
return { pid: child.pid };
|
|
6488
|
+
}
|
|
6489
|
+
if (child.exitCode !== null) {
|
|
6490
|
+
throw new Error(
|
|
6491
|
+
`Manager exited during startup (code ${child.exitCode}). See ${logFile} for details.`
|
|
6492
|
+
);
|
|
6493
|
+
}
|
|
6494
|
+
Atomics.wait(sleepBuf, 0, 0, 100);
|
|
6495
|
+
}
|
|
6496
|
+
throw new Error(
|
|
6497
|
+
`Manager did not become ready within 5s. See ${logFile} for details.`
|
|
6498
|
+
);
|
|
6499
|
+
}
|
|
6500
|
+
writePidFile(configDir, process.pid);
|
|
6501
|
+
void import("./lib/manager-worker.js").then(({ startManager }) => {
|
|
6502
|
+
startManager({
|
|
6503
|
+
intervalMs: opts.intervalMs,
|
|
6504
|
+
configDir
|
|
6505
|
+
});
|
|
6506
|
+
});
|
|
6507
|
+
process.on("exit", () => {
|
|
6508
|
+
removePidFile(configDir);
|
|
6509
|
+
});
|
|
6510
|
+
return { pid: process.pid };
|
|
6511
|
+
}
|
|
6512
|
+
async function stopWatchdog(configDir = DEFAULT_CONFIG_DIR) {
|
|
6513
|
+
const pid = readPidFile(configDir);
|
|
6514
|
+
if (pid === null) {
|
|
6515
|
+
return { stopped: false };
|
|
6516
|
+
}
|
|
6517
|
+
if (!isProcessAlive2(pid)) {
|
|
6518
|
+
removePidFile(configDir);
|
|
6519
|
+
removeStateFile(configDir);
|
|
6520
|
+
return { stopped: true, pid };
|
|
6521
|
+
}
|
|
6522
|
+
process.kill(pid, "SIGTERM");
|
|
6523
|
+
const deadline = Date.now() + 5e3;
|
|
6524
|
+
while (Date.now() < deadline) {
|
|
6525
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
6526
|
+
if (!isProcessAlive2(pid)) {
|
|
6527
|
+
removePidFile(configDir);
|
|
6528
|
+
return { stopped: true, pid };
|
|
6529
|
+
}
|
|
6530
|
+
}
|
|
6531
|
+
try {
|
|
6532
|
+
process.kill(pid, "SIGKILL");
|
|
6533
|
+
} catch {
|
|
6534
|
+
}
|
|
6535
|
+
removePidFile(configDir);
|
|
6536
|
+
removeStateFile(configDir);
|
|
6537
|
+
return { stopped: true, pid };
|
|
6538
|
+
}
|
|
6539
|
+
function getManagerStatus(configDir = DEFAULT_CONFIG_DIR) {
|
|
6540
|
+
const pid = readPidFile(configDir);
|
|
6541
|
+
if (pid === null) return null;
|
|
6542
|
+
if (!isProcessAlive2(pid)) {
|
|
6543
|
+
removePidFile(configDir);
|
|
6544
|
+
removeStateFile(configDir);
|
|
6545
|
+
return null;
|
|
6546
|
+
}
|
|
6547
|
+
return readStateFile(configDir);
|
|
6548
|
+
}
|
|
6549
|
+
|
|
6550
|
+
// src/lib/output.ts
|
|
6551
|
+
import chalk2 from "chalk";
|
|
6552
|
+
import Table from "cli-table3";
|
|
6553
|
+
function success(msg) {
|
|
6554
|
+
console.log(chalk2.green(`\u2714 ${msg}`));
|
|
6555
|
+
}
|
|
6556
|
+
function error(msg) {
|
|
6557
|
+
console.error(chalk2.red(`\u2718 ${msg}`));
|
|
6558
|
+
}
|
|
6559
|
+
function warn(msg) {
|
|
6560
|
+
console.warn(chalk2.yellow(`\u26A0 ${msg}`));
|
|
6561
|
+
}
|
|
6562
|
+
function info(msg) {
|
|
6563
|
+
console.log(chalk2.cyan(`\u2139 ${msg}`));
|
|
6564
|
+
}
|
|
6565
|
+
function table(headers, rows) {
|
|
6566
|
+
const t = new Table({
|
|
6567
|
+
head: headers.map((h) => chalk2.bold.cyan(h)),
|
|
6568
|
+
style: { head: [], border: [] }
|
|
6569
|
+
});
|
|
6570
|
+
for (const row of rows) {
|
|
6571
|
+
t.push(row);
|
|
6572
|
+
}
|
|
6573
|
+
console.log(t.toString());
|
|
6574
|
+
}
|
|
6575
|
+
|
|
6576
|
+
// src/commands/manager.ts
|
|
6577
|
+
function managerStartCommand(opts) {
|
|
6578
|
+
const json = isJsonMode();
|
|
6579
|
+
const apiKey = getApiKey();
|
|
6580
|
+
if (!apiKey) {
|
|
6581
|
+
const msg = "AGT_API_KEY is not set. Export it with your host API key (tlk_...)";
|
|
6582
|
+
if (json) {
|
|
6583
|
+
jsonOutput({ ok: false, error: msg });
|
|
6584
|
+
} else {
|
|
6585
|
+
error(msg);
|
|
6586
|
+
}
|
|
6587
|
+
process.exitCode = 1;
|
|
6588
|
+
return;
|
|
6589
|
+
}
|
|
6590
|
+
const intervalSec = parseInt(opts.interval ?? "10", 10);
|
|
6591
|
+
if (isNaN(intervalSec) || intervalSec < 5) {
|
|
6592
|
+
if (json) {
|
|
6593
|
+
jsonOutput({ ok: false, error: "Interval must be at least 10 seconds" });
|
|
6594
|
+
} else {
|
|
6595
|
+
error("Interval must be at least 10 seconds.");
|
|
6596
|
+
}
|
|
6597
|
+
process.exitCode = 1;
|
|
6598
|
+
return;
|
|
6599
|
+
}
|
|
6600
|
+
const configDir = opts.configDir ?? join8(homedir6(), ".augmented");
|
|
6601
|
+
if (opts.supervise) {
|
|
6602
|
+
if (json) {
|
|
6603
|
+
jsonOutput({ ok: false, error: "--supervise is not supported with --json" });
|
|
6604
|
+
process.exitCode = 1;
|
|
6605
|
+
return;
|
|
6606
|
+
}
|
|
6607
|
+
runSupervisorLoop(intervalSec, configDir);
|
|
6608
|
+
return;
|
|
6609
|
+
}
|
|
6610
|
+
try {
|
|
6611
|
+
const { pid } = startWatchdog({
|
|
6612
|
+
intervalMs: intervalSec * 1e3,
|
|
6613
|
+
configDir
|
|
6614
|
+
});
|
|
6615
|
+
if (json) {
|
|
6616
|
+
jsonOutput({ ok: true, pid, interval: intervalSec, configDir });
|
|
6617
|
+
} else {
|
|
6618
|
+
success(`Manager started (PID ${pid}, interval ${intervalSec}s)`);
|
|
6619
|
+
info(`Config dir: ${configDir}`);
|
|
6620
|
+
info("Stop with: agt manager stop");
|
|
6621
|
+
}
|
|
6622
|
+
} catch (err) {
|
|
6623
|
+
if (json) {
|
|
6624
|
+
jsonOutput({ ok: false, error: err.message });
|
|
6625
|
+
} else {
|
|
6626
|
+
error(err.message);
|
|
6627
|
+
}
|
|
6628
|
+
process.exitCode = 1;
|
|
6629
|
+
}
|
|
6630
|
+
}
|
|
6631
|
+
var SUPERVISOR_RESTART_EXIT_CODE = 75;
|
|
6632
|
+
function runSupervisorLoop(intervalSec, configDir) {
|
|
6633
|
+
const SUPERVISOR_RESPAWN_DELAY_MS = 2e3;
|
|
6634
|
+
const stdoutWrite = (line) => process.stdout.write(`${line}
|
|
6635
|
+
`);
|
|
6636
|
+
let currentChild = null;
|
|
6637
|
+
let respawnTimer = null;
|
|
6638
|
+
let shutdownRequested = false;
|
|
6639
|
+
const forwardOrExit = (sig) => () => {
|
|
6640
|
+
shutdownRequested = true;
|
|
6641
|
+
if (respawnTimer) {
|
|
6642
|
+
clearTimeout(respawnTimer);
|
|
6643
|
+
respawnTimer = null;
|
|
6644
|
+
}
|
|
6645
|
+
if (currentChild && currentChild.exitCode === null) {
|
|
6646
|
+
currentChild.kill(sig);
|
|
6647
|
+
return;
|
|
6648
|
+
}
|
|
6649
|
+
process.exit(0);
|
|
6650
|
+
};
|
|
6651
|
+
process.on("SIGTERM", forwardOrExit("SIGTERM"));
|
|
6652
|
+
process.on("SIGINT", forwardOrExit("SIGINT"));
|
|
6653
|
+
const runOne = () => {
|
|
6654
|
+
respawnTimer = null;
|
|
6655
|
+
currentChild = spawn3(
|
|
6656
|
+
process.execPath,
|
|
6657
|
+
[process.argv[1], "manager", "start", "--interval", String(intervalSec), "--config-dir", configDir],
|
|
6658
|
+
{ stdio: "inherit", env: process.env }
|
|
6659
|
+
);
|
|
6660
|
+
currentChild.once("error", (err) => {
|
|
6661
|
+
currentChild = null;
|
|
6662
|
+
stdoutWrite(`[supervisor] failed to spawn manager: ${err.message}`);
|
|
6663
|
+
process.exit(1);
|
|
6664
|
+
});
|
|
6665
|
+
currentChild.on("exit", (code, signal) => {
|
|
6666
|
+
currentChild = null;
|
|
6667
|
+
if (shutdownRequested) {
|
|
6668
|
+
stdoutWrite("[supervisor] shutdown requested \u2014 exiting");
|
|
6669
|
+
process.exit(0);
|
|
6670
|
+
return;
|
|
6671
|
+
}
|
|
6672
|
+
if (signal) {
|
|
6673
|
+
stdoutWrite(`[supervisor] manager terminated by signal ${signal} \u2014 exiting`);
|
|
6674
|
+
process.exit(1);
|
|
6675
|
+
return;
|
|
6676
|
+
}
|
|
6677
|
+
if (code === SUPERVISOR_RESTART_EXIT_CODE) {
|
|
6678
|
+
stdoutWrite(`[supervisor] manager requested restart (exit ${code}) \u2014 respawning in ${SUPERVISOR_RESPAWN_DELAY_MS / 1e3}s`);
|
|
6679
|
+
respawnTimer = setTimeout(runOne, SUPERVISOR_RESPAWN_DELAY_MS);
|
|
6680
|
+
return;
|
|
6681
|
+
}
|
|
6682
|
+
if (code === 0) {
|
|
6683
|
+
stdoutWrite("[supervisor] manager exited cleanly (no restart requested) \u2014 exiting");
|
|
6684
|
+
process.exit(0);
|
|
6685
|
+
return;
|
|
6686
|
+
}
|
|
6687
|
+
stdoutWrite(`[supervisor] manager exited with code ${code} \u2014 not respawning`);
|
|
6688
|
+
process.exit(code ?? 1);
|
|
6689
|
+
});
|
|
6690
|
+
};
|
|
6691
|
+
stdoutWrite(`[supervisor] starting manager with respawn-on-restart-code=${SUPERVISOR_RESTART_EXIT_CODE} (interval=${intervalSec}s, configDir=${configDir})`);
|
|
6692
|
+
runOne();
|
|
6693
|
+
}
|
|
6694
|
+
async function managerStopCommand(opts = {}) {
|
|
6695
|
+
const json = isJsonMode();
|
|
6696
|
+
const configDir = opts.configDir ?? join8(homedir6(), ".augmented");
|
|
6697
|
+
try {
|
|
6698
|
+
const result = await stopWatchdog(configDir);
|
|
6699
|
+
if (!result.stopped && !result.pid) {
|
|
6700
|
+
if (json) {
|
|
6701
|
+
jsonOutput({ ok: false, error: "Manager is not running" });
|
|
6702
|
+
} else {
|
|
6703
|
+
error("Manager is not running.");
|
|
6704
|
+
}
|
|
6705
|
+
process.exitCode = 1;
|
|
6706
|
+
return;
|
|
6707
|
+
}
|
|
6708
|
+
if (json) {
|
|
6709
|
+
jsonOutput({ ok: true, stopped: true, pid: result.pid });
|
|
6710
|
+
} else {
|
|
6711
|
+
success(`Manager stopped (PID ${result.pid})`);
|
|
6712
|
+
}
|
|
6713
|
+
} catch (err) {
|
|
6714
|
+
if (json) {
|
|
6715
|
+
jsonOutput({ ok: false, error: err.message });
|
|
6716
|
+
} else {
|
|
6717
|
+
error(err.message);
|
|
6718
|
+
}
|
|
6719
|
+
process.exitCode = 1;
|
|
6720
|
+
}
|
|
6721
|
+
}
|
|
6722
|
+
function managerStatusCommand(opts = {}) {
|
|
6723
|
+
const json = isJsonMode();
|
|
6724
|
+
const configDir = opts.configDir ?? join8(homedir6(), ".augmented");
|
|
6725
|
+
const status = getManagerStatus(configDir);
|
|
6726
|
+
if (!status) {
|
|
6727
|
+
if (json) {
|
|
6728
|
+
jsonOutput({ ok: true, running: false });
|
|
6729
|
+
} else {
|
|
6730
|
+
info("Manager is not running.");
|
|
6731
|
+
}
|
|
6732
|
+
return;
|
|
6733
|
+
}
|
|
6734
|
+
if (json) {
|
|
6735
|
+
jsonOutput({ ok: true, running: true, ...status });
|
|
6736
|
+
return;
|
|
6737
|
+
}
|
|
6738
|
+
console.log(chalk3.bold("\nManager Status\n"));
|
|
6739
|
+
info(`PID: ${status.pid}`);
|
|
6740
|
+
info(`Started: ${status.startedAt}`);
|
|
6741
|
+
info(`Last poll: ${status.lastPollAt ?? chalk3.dim("none")}`);
|
|
6742
|
+
info(`Polls: ${status.pollCount}`);
|
|
6743
|
+
info(`Errors: ${status.errorCount}`);
|
|
6744
|
+
console.log();
|
|
6745
|
+
if (status.agents.length === 0) {
|
|
6746
|
+
info("No agents discovered yet.");
|
|
6747
|
+
return;
|
|
6748
|
+
}
|
|
6749
|
+
const rows = status.agents.map((a) => {
|
|
6750
|
+
let gwStatus = chalk3.dim("\u2014");
|
|
6751
|
+
if (a.gatewayRunning) {
|
|
6752
|
+
gwStatus = chalk3.green(`:${a.gatewayPort} (PID ${a.gatewayPid})`);
|
|
6753
|
+
} else if (a.gatewayPort) {
|
|
6754
|
+
gwStatus = chalk3.red(`:${a.gatewayPort} (down)`);
|
|
6755
|
+
}
|
|
6756
|
+
return [
|
|
6757
|
+
a.codeName,
|
|
6758
|
+
a.status === "active" ? chalk3.green(a.status) : a.status === "paused" ? chalk3.yellow(a.status) : chalk3.dim(a.status ?? "\u2014"),
|
|
6759
|
+
a.charterVersion || chalk3.dim("\u2014"),
|
|
6760
|
+
gwStatus,
|
|
6761
|
+
a.lastProvisionAt ? new Date(a.lastProvisionAt).toLocaleTimeString() : chalk3.dim("\u2014"),
|
|
6762
|
+
a.lastDriftCheckAt ? new Date(a.lastDriftCheckAt).toLocaleTimeString() : chalk3.dim("\u2014")
|
|
6763
|
+
];
|
|
6764
|
+
});
|
|
6765
|
+
table(
|
|
6766
|
+
["Agent", "Status", "Charter", "Gateway", "Last Provision", "Last Drift"],
|
|
6767
|
+
rows
|
|
6768
|
+
);
|
|
6769
|
+
const acpAgents = status.agents.filter((a) => a.acpSessions && a.acpSessions.length > 0);
|
|
6770
|
+
if (acpAgents.length > 0) {
|
|
6771
|
+
console.log(chalk3.bold("\nACP Sessions\n"));
|
|
6772
|
+
const acpRows = acpAgents.flatMap(
|
|
6773
|
+
(a) => a.acpSessions.map((s) => [
|
|
6774
|
+
a.codeName,
|
|
6775
|
+
s.agentCommand,
|
|
6776
|
+
s.sessionName ?? chalk3.dim("default"),
|
|
6777
|
+
s.queueState === "running" ? chalk3.green(s.queueState) : s.queueState === "queued" ? chalk3.yellow(s.queueState) : chalk3.dim(s.queueState),
|
|
6778
|
+
String(s.turnCount),
|
|
6779
|
+
new Date(s.startedAt).toLocaleTimeString()
|
|
6780
|
+
])
|
|
6781
|
+
);
|
|
6782
|
+
table(
|
|
6783
|
+
["Agent", "Coding Agent", "Session", "Queue", "Turns", "Started"],
|
|
6784
|
+
acpRows
|
|
6785
|
+
);
|
|
6786
|
+
}
|
|
6787
|
+
}
|
|
6788
|
+
|
|
6347
6789
|
export {
|
|
6348
6790
|
wrapScheduledTaskPrompt,
|
|
6349
6791
|
parseDeliveryTarget,
|
|
@@ -6358,6 +6800,9 @@ export {
|
|
|
6358
6800
|
getIntegration,
|
|
6359
6801
|
provisionStopHook,
|
|
6360
6802
|
provisionIsolationHook,
|
|
6803
|
+
setJsonMode,
|
|
6804
|
+
isJsonMode,
|
|
6805
|
+
jsonOutput,
|
|
6361
6806
|
getApiKey,
|
|
6362
6807
|
getActiveTeam,
|
|
6363
6808
|
setActiveTeam,
|
|
@@ -6367,6 +6812,11 @@ export {
|
|
|
6367
6812
|
ApiError,
|
|
6368
6813
|
api,
|
|
6369
6814
|
getHostId,
|
|
6815
|
+
success,
|
|
6816
|
+
error,
|
|
6817
|
+
warn,
|
|
6818
|
+
info,
|
|
6819
|
+
table,
|
|
6370
6820
|
resolveChannels,
|
|
6371
6821
|
SLACK_SCOPE_CATEGORY_LABELS,
|
|
6372
6822
|
getDefaultSlackScopes,
|
|
@@ -6386,7 +6836,12 @@ export {
|
|
|
6386
6836
|
DEPLOYMENT_TEMPLATES,
|
|
6387
6837
|
getTemplate,
|
|
6388
6838
|
detectDrift,
|
|
6389
|
-
|
|
6390
|
-
provision
|
|
6839
|
+
classifyOutput,
|
|
6840
|
+
provision,
|
|
6841
|
+
startWatchdog,
|
|
6842
|
+
managerStartCommand,
|
|
6843
|
+
SUPERVISOR_RESTART_EXIT_CODE,
|
|
6844
|
+
managerStopCommand,
|
|
6845
|
+
managerStatusCommand
|
|
6391
6846
|
};
|
|
6392
|
-
//# sourceMappingURL=chunk-
|
|
6847
|
+
//# sourceMappingURL=chunk-RMTMETCK.js.map
|