@integrity-labs/agt-cli 0.14.8 → 0.14.12
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-5SFAHM2Z.js → chunk-NSHSUWZQ.js} +488 -24
- package/dist/chunk-NSHSUWZQ.js.map +1 -0
- package/dist/lib/manager-worker.js +39 -10
- package/dist/lib/manager-worker.js.map +1 -1
- package/mcp/slack-channel.js +66 -3
- package/package.json +1 -1
- package/dist/chunk-5SFAHM2Z.js.map +0 -1
|
@@ -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,44 @@ 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
|
+
var NON_DELIVERABLE_REMAINDER_PATTERNS = [
|
|
4840
|
+
/^\[notes\]/i,
|
|
4841
|
+
// Operator-facing notes block.
|
|
4842
|
+
/^[—–-]\s*scheduled by\b/i,
|
|
4843
|
+
// Default delivery-pipeline footer.
|
|
4844
|
+
/^sent (?:from|via)\b/i,
|
|
4845
|
+
// Mobile-style signatures.
|
|
4846
|
+
/^—?\s*automated (?:brief|report|message)\b/i
|
|
4847
|
+
];
|
|
4848
|
+
function looksLikeNotesOnly(remainder) {
|
|
4849
|
+
const lines = remainder.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
|
|
4850
|
+
if (lines.length === 0)
|
|
4851
|
+
return false;
|
|
4852
|
+
return lines.every((line) => NON_DELIVERABLE_REMAINDER_PATTERNS.some((pattern) => pattern.test(line)));
|
|
4806
4853
|
}
|
|
4807
4854
|
|
|
4808
4855
|
// ../../packages/core/dist/schemas/validators.js
|
|
@@ -5758,13 +5805,13 @@ function buildResult(diagnostics) {
|
|
|
5758
5805
|
}
|
|
5759
5806
|
function lintCharter(content, ctx = {}) {
|
|
5760
5807
|
const diagnostics = [];
|
|
5761
|
-
const { frontmatter, body, error } = extractFrontmatter(content);
|
|
5762
|
-
if (
|
|
5808
|
+
const { frontmatter, body, error: error2 } = extractFrontmatter(content);
|
|
5809
|
+
if (error2 || !frontmatter) {
|
|
5763
5810
|
diagnostics.push({
|
|
5764
5811
|
file: "CHARTER.md",
|
|
5765
5812
|
code: "CHARTER.PARSE.FRONTMATTER",
|
|
5766
5813
|
severity: "error",
|
|
5767
|
-
message:
|
|
5814
|
+
message: error2 ?? "Failed to parse frontmatter"
|
|
5768
5815
|
});
|
|
5769
5816
|
return buildResult(diagnostics);
|
|
5770
5817
|
}
|
|
@@ -5788,13 +5835,13 @@ function lintCharter(content, ctx = {}) {
|
|
|
5788
5835
|
}
|
|
5789
5836
|
function lintTools(content) {
|
|
5790
5837
|
const diagnostics = [];
|
|
5791
|
-
const { frontmatter, error } = extractFrontmatter(content);
|
|
5792
|
-
if (
|
|
5838
|
+
const { frontmatter, error: error2 } = extractFrontmatter(content);
|
|
5839
|
+
if (error2 || !frontmatter) {
|
|
5793
5840
|
diagnostics.push({
|
|
5794
5841
|
file: "TOOLS.md",
|
|
5795
5842
|
code: "TOOLS.PARSE.FRONTMATTER",
|
|
5796
5843
|
severity: "error",
|
|
5797
|
-
message:
|
|
5844
|
+
message: error2 ?? "Failed to parse frontmatter"
|
|
5798
5845
|
});
|
|
5799
5846
|
return buildResult(diagnostics);
|
|
5800
5847
|
}
|
|
@@ -6344,6 +6391,410 @@ function provision(input, frameworkId = "openclaw") {
|
|
|
6344
6391
|
};
|
|
6345
6392
|
}
|
|
6346
6393
|
|
|
6394
|
+
// src/commands/manager.ts
|
|
6395
|
+
import chalk3 from "chalk";
|
|
6396
|
+
import { join as join8 } from "path";
|
|
6397
|
+
import { homedir as homedir6 } from "os";
|
|
6398
|
+
import { spawn as spawn3 } from "child_process";
|
|
6399
|
+
|
|
6400
|
+
// src/lib/watchdog.ts
|
|
6401
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, unlinkSync as unlinkSync3, existsSync as existsSync6, mkdirSync as mkdirSync6, openSync, closeSync, chmodSync as chmodSync5 } from "fs";
|
|
6402
|
+
import { join as join7 } from "path";
|
|
6403
|
+
import { spawn as spawn2 } from "child_process";
|
|
6404
|
+
var DEFAULT_CONFIG_DIR = join7(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
6405
|
+
function getManagerPaths(configDir) {
|
|
6406
|
+
return {
|
|
6407
|
+
pidFile: join7(configDir, "manager.pid"),
|
|
6408
|
+
stateFile: join7(configDir, "manager-state.json"),
|
|
6409
|
+
logFile: join7(configDir, "manager.log")
|
|
6410
|
+
};
|
|
6411
|
+
}
|
|
6412
|
+
function ensureDir2(configDir) {
|
|
6413
|
+
if (!existsSync6(configDir)) {
|
|
6414
|
+
mkdirSync6(configDir, { recursive: true });
|
|
6415
|
+
}
|
|
6416
|
+
}
|
|
6417
|
+
function writePidFile(configDir, pid) {
|
|
6418
|
+
ensureDir2(configDir);
|
|
6419
|
+
writeFileSync6(getManagerPaths(configDir).pidFile, String(pid), { mode: 384 });
|
|
6420
|
+
}
|
|
6421
|
+
function readPidFile(configDir) {
|
|
6422
|
+
try {
|
|
6423
|
+
const raw = readFileSync6(getManagerPaths(configDir).pidFile, "utf-8").trim();
|
|
6424
|
+
const pid = parseInt(raw, 10);
|
|
6425
|
+
return isNaN(pid) ? null : pid;
|
|
6426
|
+
} catch {
|
|
6427
|
+
return null;
|
|
6428
|
+
}
|
|
6429
|
+
}
|
|
6430
|
+
function removePidFile(configDir) {
|
|
6431
|
+
try {
|
|
6432
|
+
unlinkSync3(getManagerPaths(configDir).pidFile);
|
|
6433
|
+
} catch {
|
|
6434
|
+
}
|
|
6435
|
+
}
|
|
6436
|
+
function isProcessAlive2(pid) {
|
|
6437
|
+
try {
|
|
6438
|
+
process.kill(pid, 0);
|
|
6439
|
+
return true;
|
|
6440
|
+
} catch {
|
|
6441
|
+
return false;
|
|
6442
|
+
}
|
|
6443
|
+
}
|
|
6444
|
+
function readStateFile(configDir) {
|
|
6445
|
+
try {
|
|
6446
|
+
const raw = readFileSync6(getManagerPaths(configDir).stateFile, "utf-8");
|
|
6447
|
+
return JSON.parse(raw);
|
|
6448
|
+
} catch {
|
|
6449
|
+
return null;
|
|
6450
|
+
}
|
|
6451
|
+
}
|
|
6452
|
+
function removeStateFile(configDir) {
|
|
6453
|
+
try {
|
|
6454
|
+
unlinkSync3(getManagerPaths(configDir).stateFile);
|
|
6455
|
+
} catch {
|
|
6456
|
+
}
|
|
6457
|
+
}
|
|
6458
|
+
function startWatchdog(opts) {
|
|
6459
|
+
const { configDir } = opts;
|
|
6460
|
+
const existingPid = readPidFile(configDir);
|
|
6461
|
+
if (existingPid !== null) {
|
|
6462
|
+
if (isProcessAlive2(existingPid)) {
|
|
6463
|
+
throw new Error(`Manager already running (PID ${existingPid}). Use \`agt manager stop\` first.`);
|
|
6464
|
+
}
|
|
6465
|
+
removePidFile(configDir);
|
|
6466
|
+
removeStateFile(configDir);
|
|
6467
|
+
}
|
|
6468
|
+
if (opts.detached) {
|
|
6469
|
+
ensureDir2(configDir);
|
|
6470
|
+
const { logFile } = getManagerPaths(configDir);
|
|
6471
|
+
const logFd = openSync(logFile, "a", 384);
|
|
6472
|
+
try {
|
|
6473
|
+
chmodSync5(logFile, 384);
|
|
6474
|
+
} catch {
|
|
6475
|
+
}
|
|
6476
|
+
const intervalSec = String(Math.max(Math.floor(opts.intervalMs / 1e3), 5));
|
|
6477
|
+
const child = spawn2(
|
|
6478
|
+
process.execPath,
|
|
6479
|
+
[process.argv[1], "manager", "start", "--interval", intervalSec, "--config-dir", configDir],
|
|
6480
|
+
{
|
|
6481
|
+
detached: true,
|
|
6482
|
+
stdio: ["ignore", logFd, logFd],
|
|
6483
|
+
env: process.env
|
|
6484
|
+
}
|
|
6485
|
+
);
|
|
6486
|
+
child.unref();
|
|
6487
|
+
closeSync(logFd);
|
|
6488
|
+
if (!child.pid) {
|
|
6489
|
+
throw new Error("Failed to spawn detached manager process");
|
|
6490
|
+
}
|
|
6491
|
+
const { pidFile } = getManagerPaths(configDir);
|
|
6492
|
+
const deadline = Date.now() + 5e3;
|
|
6493
|
+
const sleepBuf = new Int32Array(new SharedArrayBuffer(4));
|
|
6494
|
+
while (Date.now() < deadline) {
|
|
6495
|
+
if (existsSync6(pidFile)) {
|
|
6496
|
+
return { pid: child.pid };
|
|
6497
|
+
}
|
|
6498
|
+
if (child.exitCode !== null) {
|
|
6499
|
+
throw new Error(
|
|
6500
|
+
`Manager exited during startup (code ${child.exitCode}). See ${logFile} for details.`
|
|
6501
|
+
);
|
|
6502
|
+
}
|
|
6503
|
+
Atomics.wait(sleepBuf, 0, 0, 100);
|
|
6504
|
+
}
|
|
6505
|
+
throw new Error(
|
|
6506
|
+
`Manager did not become ready within 5s. See ${logFile} for details.`
|
|
6507
|
+
);
|
|
6508
|
+
}
|
|
6509
|
+
writePidFile(configDir, process.pid);
|
|
6510
|
+
void import("./lib/manager-worker.js").then(({ startManager }) => {
|
|
6511
|
+
startManager({
|
|
6512
|
+
intervalMs: opts.intervalMs,
|
|
6513
|
+
configDir
|
|
6514
|
+
});
|
|
6515
|
+
});
|
|
6516
|
+
process.on("exit", () => {
|
|
6517
|
+
removePidFile(configDir);
|
|
6518
|
+
});
|
|
6519
|
+
return { pid: process.pid };
|
|
6520
|
+
}
|
|
6521
|
+
async function stopWatchdog(configDir = DEFAULT_CONFIG_DIR) {
|
|
6522
|
+
const pid = readPidFile(configDir);
|
|
6523
|
+
if (pid === null) {
|
|
6524
|
+
return { stopped: false };
|
|
6525
|
+
}
|
|
6526
|
+
if (!isProcessAlive2(pid)) {
|
|
6527
|
+
removePidFile(configDir);
|
|
6528
|
+
removeStateFile(configDir);
|
|
6529
|
+
return { stopped: true, pid };
|
|
6530
|
+
}
|
|
6531
|
+
process.kill(pid, "SIGTERM");
|
|
6532
|
+
const deadline = Date.now() + 5e3;
|
|
6533
|
+
while (Date.now() < deadline) {
|
|
6534
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
6535
|
+
if (!isProcessAlive2(pid)) {
|
|
6536
|
+
removePidFile(configDir);
|
|
6537
|
+
return { stopped: true, pid };
|
|
6538
|
+
}
|
|
6539
|
+
}
|
|
6540
|
+
try {
|
|
6541
|
+
process.kill(pid, "SIGKILL");
|
|
6542
|
+
} catch {
|
|
6543
|
+
}
|
|
6544
|
+
removePidFile(configDir);
|
|
6545
|
+
removeStateFile(configDir);
|
|
6546
|
+
return { stopped: true, pid };
|
|
6547
|
+
}
|
|
6548
|
+
function getManagerStatus(configDir = DEFAULT_CONFIG_DIR) {
|
|
6549
|
+
const pid = readPidFile(configDir);
|
|
6550
|
+
if (pid === null) return null;
|
|
6551
|
+
if (!isProcessAlive2(pid)) {
|
|
6552
|
+
removePidFile(configDir);
|
|
6553
|
+
removeStateFile(configDir);
|
|
6554
|
+
return null;
|
|
6555
|
+
}
|
|
6556
|
+
return readStateFile(configDir);
|
|
6557
|
+
}
|
|
6558
|
+
|
|
6559
|
+
// src/lib/output.ts
|
|
6560
|
+
import chalk2 from "chalk";
|
|
6561
|
+
import Table from "cli-table3";
|
|
6562
|
+
function success(msg) {
|
|
6563
|
+
console.log(chalk2.green(`\u2714 ${msg}`));
|
|
6564
|
+
}
|
|
6565
|
+
function error(msg) {
|
|
6566
|
+
console.error(chalk2.red(`\u2718 ${msg}`));
|
|
6567
|
+
}
|
|
6568
|
+
function warn(msg) {
|
|
6569
|
+
console.warn(chalk2.yellow(`\u26A0 ${msg}`));
|
|
6570
|
+
}
|
|
6571
|
+
function info(msg) {
|
|
6572
|
+
console.log(chalk2.cyan(`\u2139 ${msg}`));
|
|
6573
|
+
}
|
|
6574
|
+
function table(headers, rows) {
|
|
6575
|
+
const t = new Table({
|
|
6576
|
+
head: headers.map((h) => chalk2.bold.cyan(h)),
|
|
6577
|
+
style: { head: [], border: [] }
|
|
6578
|
+
});
|
|
6579
|
+
for (const row of rows) {
|
|
6580
|
+
t.push(row);
|
|
6581
|
+
}
|
|
6582
|
+
console.log(t.toString());
|
|
6583
|
+
}
|
|
6584
|
+
|
|
6585
|
+
// src/commands/manager.ts
|
|
6586
|
+
function managerStartCommand(opts) {
|
|
6587
|
+
const json = isJsonMode();
|
|
6588
|
+
const apiKey = getApiKey();
|
|
6589
|
+
if (!apiKey) {
|
|
6590
|
+
const msg = "AGT_API_KEY is not set. Export it with your host API key (tlk_...)";
|
|
6591
|
+
if (json) {
|
|
6592
|
+
jsonOutput({ ok: false, error: msg });
|
|
6593
|
+
} else {
|
|
6594
|
+
error(msg);
|
|
6595
|
+
}
|
|
6596
|
+
process.exitCode = 1;
|
|
6597
|
+
return;
|
|
6598
|
+
}
|
|
6599
|
+
const intervalSec = parseInt(opts.interval ?? "10", 10);
|
|
6600
|
+
if (isNaN(intervalSec) || intervalSec < 5) {
|
|
6601
|
+
if (json) {
|
|
6602
|
+
jsonOutput({ ok: false, error: "Interval must be at least 10 seconds" });
|
|
6603
|
+
} else {
|
|
6604
|
+
error("Interval must be at least 10 seconds.");
|
|
6605
|
+
}
|
|
6606
|
+
process.exitCode = 1;
|
|
6607
|
+
return;
|
|
6608
|
+
}
|
|
6609
|
+
const configDir = opts.configDir ?? join8(homedir6(), ".augmented");
|
|
6610
|
+
if (opts.supervise) {
|
|
6611
|
+
if (json) {
|
|
6612
|
+
jsonOutput({ ok: false, error: "--supervise is not supported with --json" });
|
|
6613
|
+
process.exitCode = 1;
|
|
6614
|
+
return;
|
|
6615
|
+
}
|
|
6616
|
+
runSupervisorLoop(intervalSec, configDir);
|
|
6617
|
+
return;
|
|
6618
|
+
}
|
|
6619
|
+
try {
|
|
6620
|
+
const { pid } = startWatchdog({
|
|
6621
|
+
intervalMs: intervalSec * 1e3,
|
|
6622
|
+
configDir
|
|
6623
|
+
});
|
|
6624
|
+
if (json) {
|
|
6625
|
+
jsonOutput({ ok: true, pid, interval: intervalSec, configDir });
|
|
6626
|
+
} else {
|
|
6627
|
+
success(`Manager started (PID ${pid}, interval ${intervalSec}s)`);
|
|
6628
|
+
info(`Config dir: ${configDir}`);
|
|
6629
|
+
info("Stop with: agt manager stop");
|
|
6630
|
+
}
|
|
6631
|
+
} catch (err) {
|
|
6632
|
+
if (json) {
|
|
6633
|
+
jsonOutput({ ok: false, error: err.message });
|
|
6634
|
+
} else {
|
|
6635
|
+
error(err.message);
|
|
6636
|
+
}
|
|
6637
|
+
process.exitCode = 1;
|
|
6638
|
+
}
|
|
6639
|
+
}
|
|
6640
|
+
var SUPERVISOR_RESTART_EXIT_CODE = 75;
|
|
6641
|
+
function runSupervisorLoop(intervalSec, configDir) {
|
|
6642
|
+
const SUPERVISOR_RESPAWN_DELAY_MS = 2e3;
|
|
6643
|
+
const stdoutWrite = (line) => process.stdout.write(`${line}
|
|
6644
|
+
`);
|
|
6645
|
+
let currentChild = null;
|
|
6646
|
+
let respawnTimer = null;
|
|
6647
|
+
let shutdownRequested = false;
|
|
6648
|
+
const forwardOrExit = (sig) => () => {
|
|
6649
|
+
shutdownRequested = true;
|
|
6650
|
+
if (respawnTimer) {
|
|
6651
|
+
clearTimeout(respawnTimer);
|
|
6652
|
+
respawnTimer = null;
|
|
6653
|
+
}
|
|
6654
|
+
if (currentChild && currentChild.exitCode === null) {
|
|
6655
|
+
currentChild.kill(sig);
|
|
6656
|
+
return;
|
|
6657
|
+
}
|
|
6658
|
+
process.exit(0);
|
|
6659
|
+
};
|
|
6660
|
+
process.on("SIGTERM", forwardOrExit("SIGTERM"));
|
|
6661
|
+
process.on("SIGINT", forwardOrExit("SIGINT"));
|
|
6662
|
+
const runOne = () => {
|
|
6663
|
+
respawnTimer = null;
|
|
6664
|
+
currentChild = spawn3(
|
|
6665
|
+
process.execPath,
|
|
6666
|
+
[process.argv[1], "manager", "start", "--interval", String(intervalSec), "--config-dir", configDir],
|
|
6667
|
+
{ stdio: "inherit", env: process.env }
|
|
6668
|
+
);
|
|
6669
|
+
currentChild.once("error", (err) => {
|
|
6670
|
+
currentChild = null;
|
|
6671
|
+
stdoutWrite(`[supervisor] failed to spawn manager: ${err.message}`);
|
|
6672
|
+
process.exit(1);
|
|
6673
|
+
});
|
|
6674
|
+
currentChild.on("exit", (code, signal) => {
|
|
6675
|
+
currentChild = null;
|
|
6676
|
+
if (shutdownRequested) {
|
|
6677
|
+
stdoutWrite("[supervisor] shutdown requested \u2014 exiting");
|
|
6678
|
+
process.exit(0);
|
|
6679
|
+
return;
|
|
6680
|
+
}
|
|
6681
|
+
if (signal) {
|
|
6682
|
+
stdoutWrite(`[supervisor] manager terminated by signal ${signal} \u2014 exiting`);
|
|
6683
|
+
process.exit(1);
|
|
6684
|
+
return;
|
|
6685
|
+
}
|
|
6686
|
+
if (code === SUPERVISOR_RESTART_EXIT_CODE) {
|
|
6687
|
+
stdoutWrite(`[supervisor] manager requested restart (exit ${code}) \u2014 respawning in ${SUPERVISOR_RESPAWN_DELAY_MS / 1e3}s`);
|
|
6688
|
+
respawnTimer = setTimeout(runOne, SUPERVISOR_RESPAWN_DELAY_MS);
|
|
6689
|
+
return;
|
|
6690
|
+
}
|
|
6691
|
+
if (code === 0) {
|
|
6692
|
+
stdoutWrite("[supervisor] manager exited cleanly (no restart requested) \u2014 exiting");
|
|
6693
|
+
process.exit(0);
|
|
6694
|
+
return;
|
|
6695
|
+
}
|
|
6696
|
+
stdoutWrite(`[supervisor] manager exited with code ${code} \u2014 not respawning`);
|
|
6697
|
+
process.exit(code ?? 1);
|
|
6698
|
+
});
|
|
6699
|
+
};
|
|
6700
|
+
stdoutWrite(`[supervisor] starting manager with respawn-on-restart-code=${SUPERVISOR_RESTART_EXIT_CODE} (interval=${intervalSec}s, configDir=${configDir})`);
|
|
6701
|
+
runOne();
|
|
6702
|
+
}
|
|
6703
|
+
async function managerStopCommand(opts = {}) {
|
|
6704
|
+
const json = isJsonMode();
|
|
6705
|
+
const configDir = opts.configDir ?? join8(homedir6(), ".augmented");
|
|
6706
|
+
try {
|
|
6707
|
+
const result = await stopWatchdog(configDir);
|
|
6708
|
+
if (!result.stopped && !result.pid) {
|
|
6709
|
+
if (json) {
|
|
6710
|
+
jsonOutput({ ok: false, error: "Manager is not running" });
|
|
6711
|
+
} else {
|
|
6712
|
+
error("Manager is not running.");
|
|
6713
|
+
}
|
|
6714
|
+
process.exitCode = 1;
|
|
6715
|
+
return;
|
|
6716
|
+
}
|
|
6717
|
+
if (json) {
|
|
6718
|
+
jsonOutput({ ok: true, stopped: true, pid: result.pid });
|
|
6719
|
+
} else {
|
|
6720
|
+
success(`Manager stopped (PID ${result.pid})`);
|
|
6721
|
+
}
|
|
6722
|
+
} catch (err) {
|
|
6723
|
+
if (json) {
|
|
6724
|
+
jsonOutput({ ok: false, error: err.message });
|
|
6725
|
+
} else {
|
|
6726
|
+
error(err.message);
|
|
6727
|
+
}
|
|
6728
|
+
process.exitCode = 1;
|
|
6729
|
+
}
|
|
6730
|
+
}
|
|
6731
|
+
function managerStatusCommand(opts = {}) {
|
|
6732
|
+
const json = isJsonMode();
|
|
6733
|
+
const configDir = opts.configDir ?? join8(homedir6(), ".augmented");
|
|
6734
|
+
const status = getManagerStatus(configDir);
|
|
6735
|
+
if (!status) {
|
|
6736
|
+
if (json) {
|
|
6737
|
+
jsonOutput({ ok: true, running: false });
|
|
6738
|
+
} else {
|
|
6739
|
+
info("Manager is not running.");
|
|
6740
|
+
}
|
|
6741
|
+
return;
|
|
6742
|
+
}
|
|
6743
|
+
if (json) {
|
|
6744
|
+
jsonOutput({ ok: true, running: true, ...status });
|
|
6745
|
+
return;
|
|
6746
|
+
}
|
|
6747
|
+
console.log(chalk3.bold("\nManager Status\n"));
|
|
6748
|
+
info(`PID: ${status.pid}`);
|
|
6749
|
+
info(`Started: ${status.startedAt}`);
|
|
6750
|
+
info(`Last poll: ${status.lastPollAt ?? chalk3.dim("none")}`);
|
|
6751
|
+
info(`Polls: ${status.pollCount}`);
|
|
6752
|
+
info(`Errors: ${status.errorCount}`);
|
|
6753
|
+
console.log();
|
|
6754
|
+
if (status.agents.length === 0) {
|
|
6755
|
+
info("No agents discovered yet.");
|
|
6756
|
+
return;
|
|
6757
|
+
}
|
|
6758
|
+
const rows = status.agents.map((a) => {
|
|
6759
|
+
let gwStatus = chalk3.dim("\u2014");
|
|
6760
|
+
if (a.gatewayRunning) {
|
|
6761
|
+
gwStatus = chalk3.green(`:${a.gatewayPort} (PID ${a.gatewayPid})`);
|
|
6762
|
+
} else if (a.gatewayPort) {
|
|
6763
|
+
gwStatus = chalk3.red(`:${a.gatewayPort} (down)`);
|
|
6764
|
+
}
|
|
6765
|
+
return [
|
|
6766
|
+
a.codeName,
|
|
6767
|
+
a.status === "active" ? chalk3.green(a.status) : a.status === "paused" ? chalk3.yellow(a.status) : chalk3.dim(a.status ?? "\u2014"),
|
|
6768
|
+
a.charterVersion || chalk3.dim("\u2014"),
|
|
6769
|
+
gwStatus,
|
|
6770
|
+
a.lastProvisionAt ? new Date(a.lastProvisionAt).toLocaleTimeString() : chalk3.dim("\u2014"),
|
|
6771
|
+
a.lastDriftCheckAt ? new Date(a.lastDriftCheckAt).toLocaleTimeString() : chalk3.dim("\u2014")
|
|
6772
|
+
];
|
|
6773
|
+
});
|
|
6774
|
+
table(
|
|
6775
|
+
["Agent", "Status", "Charter", "Gateway", "Last Provision", "Last Drift"],
|
|
6776
|
+
rows
|
|
6777
|
+
);
|
|
6778
|
+
const acpAgents = status.agents.filter((a) => a.acpSessions && a.acpSessions.length > 0);
|
|
6779
|
+
if (acpAgents.length > 0) {
|
|
6780
|
+
console.log(chalk3.bold("\nACP Sessions\n"));
|
|
6781
|
+
const acpRows = acpAgents.flatMap(
|
|
6782
|
+
(a) => a.acpSessions.map((s) => [
|
|
6783
|
+
a.codeName,
|
|
6784
|
+
s.agentCommand,
|
|
6785
|
+
s.sessionName ?? chalk3.dim("default"),
|
|
6786
|
+
s.queueState === "running" ? chalk3.green(s.queueState) : s.queueState === "queued" ? chalk3.yellow(s.queueState) : chalk3.dim(s.queueState),
|
|
6787
|
+
String(s.turnCount),
|
|
6788
|
+
new Date(s.startedAt).toLocaleTimeString()
|
|
6789
|
+
])
|
|
6790
|
+
);
|
|
6791
|
+
table(
|
|
6792
|
+
["Agent", "Coding Agent", "Session", "Queue", "Turns", "Started"],
|
|
6793
|
+
acpRows
|
|
6794
|
+
);
|
|
6795
|
+
}
|
|
6796
|
+
}
|
|
6797
|
+
|
|
6347
6798
|
export {
|
|
6348
6799
|
wrapScheduledTaskPrompt,
|
|
6349
6800
|
parseDeliveryTarget,
|
|
@@ -6358,6 +6809,9 @@ export {
|
|
|
6358
6809
|
getIntegration,
|
|
6359
6810
|
provisionStopHook,
|
|
6360
6811
|
provisionIsolationHook,
|
|
6812
|
+
setJsonMode,
|
|
6813
|
+
isJsonMode,
|
|
6814
|
+
jsonOutput,
|
|
6361
6815
|
getApiKey,
|
|
6362
6816
|
getActiveTeam,
|
|
6363
6817
|
setActiveTeam,
|
|
@@ -6367,6 +6821,11 @@ export {
|
|
|
6367
6821
|
ApiError,
|
|
6368
6822
|
api,
|
|
6369
6823
|
getHostId,
|
|
6824
|
+
success,
|
|
6825
|
+
error,
|
|
6826
|
+
warn,
|
|
6827
|
+
info,
|
|
6828
|
+
table,
|
|
6370
6829
|
resolveChannels,
|
|
6371
6830
|
SLACK_SCOPE_CATEGORY_LABELS,
|
|
6372
6831
|
getDefaultSlackScopes,
|
|
@@ -6386,7 +6845,12 @@ export {
|
|
|
6386
6845
|
DEPLOYMENT_TEMPLATES,
|
|
6387
6846
|
getTemplate,
|
|
6388
6847
|
detectDrift,
|
|
6389
|
-
|
|
6390
|
-
provision
|
|
6848
|
+
classifyOutput,
|
|
6849
|
+
provision,
|
|
6850
|
+
startWatchdog,
|
|
6851
|
+
managerStartCommand,
|
|
6852
|
+
SUPERVISOR_RESTART_EXIT_CODE,
|
|
6853
|
+
managerStopCommand,
|
|
6854
|
+
managerStatusCommand
|
|
6391
6855
|
};
|
|
6392
|
-
//# sourceMappingURL=chunk-
|
|
6856
|
+
//# sourceMappingURL=chunk-NSHSUWZQ.js.map
|