@integrity-labs/agt-cli 0.16.1 → 0.16.3
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 +3 -3
- package/dist/{chunk-QYG5LUTP.js → chunk-EG5D3KUV.js} +121 -9
- package/dist/chunk-EG5D3KUV.js.map +1 -0
- package/dist/{chunk-ITLXAEXI.js → chunk-ZQFCMUNR.js} +187 -13
- package/dist/chunk-ZQFCMUNR.js.map +1 -0
- package/dist/{claude-pair-runtime-FEUHTZXZ.js → claude-pair-runtime-Q7PNH3ZK.js} +2 -2
- package/dist/lib/manager-worker.js +114 -21
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-RZWMTEZY.js → persistent-session-YEUFJMWF.js} +6 -2
- package/package.json +1 -1
- package/dist/chunk-ITLXAEXI.js.map +0 -1
- package/dist/chunk-QYG5LUTP.js.map +0 -1
- /package/dist/{claude-pair-runtime-FEUHTZXZ.js.map → claude-pair-runtime-Q7PNH3ZK.js.map} +0 -0
- /package/dist/{persistent-session-RZWMTEZY.js.map → persistent-session-YEUFJMWF.js.map} +0 -0
|
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
|
|
|
100
100
|
return { ok: true };
|
|
101
101
|
} catch {
|
|
102
102
|
}
|
|
103
|
-
const { resolveClaudeBinary } = await import("./persistent-session-
|
|
103
|
+
const { resolveClaudeBinary } = await import("./persistent-session-YEUFJMWF.js");
|
|
104
104
|
const claudeBin = resolveClaudeBinary();
|
|
105
105
|
try {
|
|
106
106
|
await execFileAsync("tmux", [
|
|
@@ -357,4 +357,4 @@ export {
|
|
|
357
357
|
startClaudePair,
|
|
358
358
|
submitClaudePairCode
|
|
359
359
|
};
|
|
360
|
-
//# sourceMappingURL=claude-pair-runtime-
|
|
360
|
+
//# sourceMappingURL=claude-pair-runtime-Q7PNH3ZK.js.map
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
resolveChannels,
|
|
23
23
|
resolveDmTarget,
|
|
24
24
|
wrapScheduledTaskPrompt
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-ZQFCMUNR.js";
|
|
26
26
|
import {
|
|
27
27
|
findTaskByTemplate,
|
|
28
28
|
getProjectDir,
|
|
@@ -33,23 +33,25 @@ import {
|
|
|
33
33
|
} from "../chunk-M6FSTVGG.js";
|
|
34
34
|
import {
|
|
35
35
|
buildAllowedTools,
|
|
36
|
+
getLastFailureContext,
|
|
36
37
|
getProjectDir as getProjectDir2,
|
|
37
38
|
injectMessage,
|
|
38
39
|
isAgentIdle,
|
|
39
40
|
isSessionHealthy,
|
|
40
41
|
isStaleForToday,
|
|
41
42
|
peekCurrentSession,
|
|
43
|
+
prepareForRespawn,
|
|
42
44
|
resetRestartCount,
|
|
43
45
|
resolveClaudeBinary,
|
|
44
46
|
sanitizeMcpJson,
|
|
45
47
|
startPersistentSession,
|
|
46
48
|
stopAllSessionsAndWait,
|
|
47
49
|
stopPersistentSession
|
|
48
|
-
} from "../chunk-
|
|
50
|
+
} from "../chunk-EG5D3KUV.js";
|
|
49
51
|
|
|
50
52
|
// src/lib/manager-worker.ts
|
|
51
53
|
import { createHash } from "crypto";
|
|
52
|
-
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, chmodSync, existsSync as existsSync2, rmSync as rmSync2, readdirSync as readdirSync2, statSync, unlinkSync, copyFileSync } from "fs";
|
|
54
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, appendFileSync, mkdirSync as mkdirSync2, chmodSync, existsSync as existsSync2, rmSync as rmSync2, readdirSync as readdirSync2, statSync, unlinkSync, copyFileSync } from "fs";
|
|
53
55
|
import https from "https";
|
|
54
56
|
import { execFileSync as syncExecFile } from "child_process";
|
|
55
57
|
import { join as join3, dirname } from "path";
|
|
@@ -1402,6 +1404,12 @@ var lastChannelSweepAt = 0;
|
|
|
1402
1404
|
var config = null;
|
|
1403
1405
|
var running = false;
|
|
1404
1406
|
var pollTimer = null;
|
|
1407
|
+
var PANE_TAIL_PREVIEW_LINES = 5;
|
|
1408
|
+
function truncateForLog(s) {
|
|
1409
|
+
const lines = s.split("\n").filter((l) => l.length > 0);
|
|
1410
|
+
return lines.slice(-PANE_TAIL_PREVIEW_LINES).map((l) => ` | ${l}`).join("\n");
|
|
1411
|
+
}
|
|
1412
|
+
var KNOWN_SAFE_TAIL_SIGNATURES = /* @__PURE__ */ new Set(["session_id_in_use"]);
|
|
1405
1413
|
var knownVersions = /* @__PURE__ */ new Map();
|
|
1406
1414
|
var knownStatuses = /* @__PURE__ */ new Map();
|
|
1407
1415
|
var knownChannels = /* @__PURE__ */ new Map();
|
|
@@ -1476,7 +1484,7 @@ function clearAgentCaches(agentId, codeName) {
|
|
|
1476
1484
|
var cachedFrameworkVersion = null;
|
|
1477
1485
|
var lastVersionCheckAt = 0;
|
|
1478
1486
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
1479
|
-
var agtCliVersion = true ? "0.16.
|
|
1487
|
+
var agtCliVersion = true ? "0.16.3" : "dev";
|
|
1480
1488
|
function resolveBrewPath(execFileSync2) {
|
|
1481
1489
|
try {
|
|
1482
1490
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -1948,6 +1956,7 @@ function send(msg) {
|
|
|
1948
1956
|
}
|
|
1949
1957
|
}
|
|
1950
1958
|
var managerLogPath = null;
|
|
1959
|
+
var managerLogWritable = true;
|
|
1951
1960
|
function redactForDiskLog(value) {
|
|
1952
1961
|
try {
|
|
1953
1962
|
return value.replace(/\b(Bearer\s+)[A-Za-z0-9._-]+\b/gi, "$1[REDACTED]").replace(/\bxox[baprs]-[A-Za-z0-9-]+\b/g, "[REDACTED-SLACK]").replace(/\btlk_[A-Za-z0-9._-]+\b/g, "[REDACTED-HOST]").replace(/\bsk-ant-[A-Za-z0-9_-]+\b/g, "[REDACTED-ANTHROPIC]").replace(/\b\d{8,12}:[A-Za-z0-9_-]{30,}\b/g, "[REDACTED-TELEGRAM]").replace(
|
|
@@ -1961,8 +1970,8 @@ function redactForDiskLog(value) {
|
|
|
1961
1970
|
function log(msg) {
|
|
1962
1971
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
1963
1972
|
const safeMsg = redactForDiskLog(msg);
|
|
1964
|
-
|
|
1965
|
-
|
|
1973
|
+
const line = `[manager-worker ${ts}] ${safeMsg}
|
|
1974
|
+
`;
|
|
1966
1975
|
if (!managerLogPath) {
|
|
1967
1976
|
try {
|
|
1968
1977
|
managerLogPath = join3(homedir3(), ".augmented", "manager.log");
|
|
@@ -1973,6 +1982,22 @@ function log(msg) {
|
|
|
1973
1982
|
} catch {
|
|
1974
1983
|
}
|
|
1975
1984
|
}
|
|
1985
|
+
let appendedToFile = false;
|
|
1986
|
+
if (managerLogPath && managerLogWritable) {
|
|
1987
|
+
try {
|
|
1988
|
+
appendFileSync(managerLogPath, line, { encoding: "utf-8", mode: 384 });
|
|
1989
|
+
appendedToFile = true;
|
|
1990
|
+
} catch (err) {
|
|
1991
|
+
managerLogWritable = false;
|
|
1992
|
+
process.stderr.write(
|
|
1993
|
+
`[manager-worker ${ts}] [log] manager.log append failed; falling back to stderr-only: ${err.message}
|
|
1994
|
+
`
|
|
1995
|
+
);
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
if (!appendedToFile || process.stderr.isTTY === true) {
|
|
1999
|
+
process.stderr.write(line);
|
|
2000
|
+
}
|
|
1976
2001
|
}
|
|
1977
2002
|
function sha256(content) {
|
|
1978
2003
|
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
@@ -2353,7 +2378,7 @@ async function pollCycle() {
|
|
|
2353
2378
|
}
|
|
2354
2379
|
try {
|
|
2355
2380
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
2356
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
2381
|
+
const { collectDiagnostics } = await import("../persistent-session-YEUFJMWF.js");
|
|
2357
2382
|
const diagCodeNames = [...persistentSessionAgents];
|
|
2358
2383
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
|
|
2359
2384
|
let tailscaleHostname;
|
|
@@ -3827,6 +3852,24 @@ async function finishRun(runId, outcome, options = {}) {
|
|
|
3827
3852
|
log(`[runs] finish failed for run_id=${runId} outcome=${outcome} error_id=${errId}`);
|
|
3828
3853
|
}
|
|
3829
3854
|
}
|
|
3855
|
+
var MAX_PRIOR_RUNS = 5;
|
|
3856
|
+
async function fetchPriorScheduledRuns(agentId, taskId) {
|
|
3857
|
+
try {
|
|
3858
|
+
const data = await api.post("/host/scheduled-tasks/recent-outputs", {
|
|
3859
|
+
agent_id: agentId,
|
|
3860
|
+
task_id: taskId,
|
|
3861
|
+
since_hours: 24,
|
|
3862
|
+
limit: MAX_PRIOR_RUNS
|
|
3863
|
+
});
|
|
3864
|
+
const rows = Array.isArray(data?.runs) ? data.runs.slice(0, MAX_PRIOR_RUNS) : [];
|
|
3865
|
+
return rows.filter((r) => typeof r.output_text === "string" && r.output_text.length > 0).map((r) => ({ startedAt: r.started_at, output: r.output_text }));
|
|
3866
|
+
} catch (err) {
|
|
3867
|
+
const errText = err instanceof Error ? err.message : String(err);
|
|
3868
|
+
const errId = createHash("sha256").update(errText).digest("hex").slice(0, 12);
|
|
3869
|
+
log(`[runs] prior-runs lookup failed for task_id=${taskId} error_id=${errId}`);
|
|
3870
|
+
return [];
|
|
3871
|
+
}
|
|
3872
|
+
}
|
|
3830
3873
|
async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
|
|
3831
3874
|
const projectDir = getProjectDir(codeName);
|
|
3832
3875
|
const mcpConfigPath = join3(projectDir, ".mcp.json");
|
|
@@ -3834,7 +3877,8 @@ async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
|
|
|
3834
3877
|
let kanbanItemId = null;
|
|
3835
3878
|
let taskResult;
|
|
3836
3879
|
sanitizeMcpJson(mcpConfigPath, requireHost());
|
|
3837
|
-
|
|
3880
|
+
const priorRuns = await fetchPriorScheduledRuns(agentId, task.taskId);
|
|
3881
|
+
prompt = wrapScheduledTaskPrompt(prompt, { priorRuns });
|
|
3838
3882
|
try {
|
|
3839
3883
|
const claudeMdPath = join3(projectDir, "CLAUDE.md");
|
|
3840
3884
|
const serverNames = [];
|
|
@@ -4129,7 +4173,15 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
4129
4173
|
}
|
|
4130
4174
|
if (!isSessionHealthy(codeName)) {
|
|
4131
4175
|
if (persistentSessionAgents.has(codeName)) {
|
|
4132
|
-
|
|
4176
|
+
const ctx = getLastFailureContext(codeName);
|
|
4177
|
+
const recovery = prepareForRespawn(codeName);
|
|
4178
|
+
const tailSummary = !ctx.tail ? "" : KNOWN_SAFE_TAIL_SIGNATURES.has(ctx.signature) ? `; last pane output (${PANE_TAIL_PREVIEW_LINES} of ~20 lines):
|
|
4179
|
+
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash("sha256").update(ctx.tail).digest("hex").slice(0, 12)} (raw at ~/.augmented/${codeName}/pane.log)`;
|
|
4180
|
+
const sigSummary = ctx.signature !== "unknown" ? `; signature=${ctx.signature}` : "";
|
|
4181
|
+
const recoverySummary = recovery ? `; recovery=${recovery}` : "";
|
|
4182
|
+
log(
|
|
4183
|
+
`[persistent-session] Session for '${codeName}' is unhealthy (restart #${ctx.restartCount}${sigSummary}${recoverySummary}), will restart${tailSummary}`
|
|
4184
|
+
);
|
|
4133
4185
|
}
|
|
4134
4186
|
try {
|
|
4135
4187
|
provisionStopHook(codeName);
|
|
@@ -4354,6 +4406,7 @@ function ensureRealtimeAssignStarted(agentStates) {
|
|
|
4354
4406
|
hostId: exchange.hostId,
|
|
4355
4407
|
onAssign: (payload) => {
|
|
4356
4408
|
log(`[realtime] Agent ${payload.agent_id} assigned \u2014 will pick up next cycle`);
|
|
4409
|
+
markAgentForFreshMemorySync(payload.agent_id);
|
|
4357
4410
|
},
|
|
4358
4411
|
onUnassign: (payload) => {
|
|
4359
4412
|
log(`[realtime] Agent ${payload.agent_id} unassigned`);
|
|
@@ -5442,7 +5495,7 @@ async function processClaudePairSessions(agents) {
|
|
|
5442
5495
|
killPairSession,
|
|
5443
5496
|
pairTmuxSession,
|
|
5444
5497
|
finalizeClaudePairOnboarding
|
|
5445
|
-
} = await import("../claude-pair-runtime-
|
|
5498
|
+
} = await import("../claude-pair-runtime-Q7PNH3ZK.js");
|
|
5446
5499
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
5447
5500
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
5448
5501
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -5687,6 +5740,13 @@ function generateArtifacts(agent, refreshData, adapter) {
|
|
|
5687
5740
|
var memoryFileHashes = /* @__PURE__ */ new Map();
|
|
5688
5741
|
var lastDownloadHash = /* @__PURE__ */ new Map();
|
|
5689
5742
|
var lastLocalFileHash = /* @__PURE__ */ new Map();
|
|
5743
|
+
var pendingFreshMemorySync = /* @__PURE__ */ new Set();
|
|
5744
|
+
function markAgentForFreshMemorySync(agentId) {
|
|
5745
|
+
pendingFreshMemorySync.add(agentId);
|
|
5746
|
+
memoryFileHashes.delete(agentId);
|
|
5747
|
+
lastDownloadHash.delete(agentId);
|
|
5748
|
+
lastLocalFileHash.delete(agentId);
|
|
5749
|
+
}
|
|
5690
5750
|
function parseMemoryFile(raw, fallbackName) {
|
|
5691
5751
|
const trimmed = raw.trim();
|
|
5692
5752
|
if (!trimmed) return null;
|
|
@@ -5713,6 +5773,16 @@ function parseMemoryFile(raw, fallbackName) {
|
|
|
5713
5773
|
async function syncMemories(agent, configDir, log2) {
|
|
5714
5774
|
const projectDir = join3(configDir, agent.code_name, "project");
|
|
5715
5775
|
const memoryDir = join3(projectDir, "memory");
|
|
5776
|
+
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
5777
|
+
if (isFreshSync) {
|
|
5778
|
+
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
5779
|
+
const ok = await downloadMemories(agent, memoryDir, log2, { force: true });
|
|
5780
|
+
if (!ok) {
|
|
5781
|
+
log2(`[memory-sync] Fresh-sync download failed for '${agent.code_name}' \u2014 skipping upload, will retry next tick`);
|
|
5782
|
+
return;
|
|
5783
|
+
}
|
|
5784
|
+
pendingFreshMemorySync.delete(agent.agent_id);
|
|
5785
|
+
}
|
|
5716
5786
|
if (existsSync2(memoryDir)) {
|
|
5717
5787
|
const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
|
|
5718
5788
|
const currentHashes = /* @__PURE__ */ new Map();
|
|
@@ -5753,6 +5823,11 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
5753
5823
|
}
|
|
5754
5824
|
}
|
|
5755
5825
|
}
|
|
5826
|
+
if (!isFreshSync) {
|
|
5827
|
+
await downloadMemories(agent, memoryDir, log2, { force: false });
|
|
5828
|
+
}
|
|
5829
|
+
}
|
|
5830
|
+
async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
5756
5831
|
const localFiles = existsSync2(memoryDir) ? readdirSync2(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
5757
5832
|
const localListHash = createHash("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
5758
5833
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
@@ -5762,20 +5837,21 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
5762
5837
|
agent_id: agent.agent_id
|
|
5763
5838
|
});
|
|
5764
5839
|
const responseHash = createHash("sha256").update(JSON.stringify(dbMemories.memories ?? [])).digest("hex").slice(0, 16);
|
|
5765
|
-
if (prevDownload && prevLocalHash === localListHash && lastDownloadHash.get(agent.agent_id) === responseHash) {
|
|
5766
|
-
return;
|
|
5840
|
+
if (!force && prevDownload && prevLocalHash === localListHash && lastDownloadHash.get(agent.agent_id) === responseHash) {
|
|
5841
|
+
return true;
|
|
5767
5842
|
}
|
|
5768
5843
|
lastDownloadHash.set(agent.agent_id, responseHash);
|
|
5769
5844
|
lastLocalFileHash.set(agent.agent_id, localListHash);
|
|
5770
5845
|
if (dbMemories.memories?.length) {
|
|
5771
5846
|
mkdirSync2(memoryDir, { recursive: true });
|
|
5772
|
-
const existingFileSet = new Set(localFiles.map((f) => f.replace(/\.md$/, "").toLowerCase()));
|
|
5773
5847
|
let written = 0;
|
|
5774
|
-
|
|
5848
|
+
let overwritten = 0;
|
|
5849
|
+
for (let i = 0; i < dbMemories.memories.length; i++) {
|
|
5850
|
+
const mem = dbMemories.memories[i];
|
|
5775
5851
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
5776
|
-
const slug = rawSlug || `memory-${
|
|
5777
|
-
|
|
5778
|
-
const
|
|
5852
|
+
const slug = rawSlug || `memory-${i}`;
|
|
5853
|
+
const filePath = join3(memoryDir, `${slug}.md`);
|
|
5854
|
+
const desired = `---
|
|
5779
5855
|
name: ${JSON.stringify(mem.name)}
|
|
5780
5856
|
type: ${mem.type}
|
|
5781
5857
|
description: ${JSON.stringify(mem.content.slice(0, 200))}
|
|
@@ -5783,17 +5859,30 @@ description: ${JSON.stringify(mem.content.slice(0, 200))}
|
|
|
5783
5859
|
|
|
5784
5860
|
${mem.content}
|
|
5785
5861
|
`;
|
|
5786
|
-
|
|
5787
|
-
|
|
5862
|
+
if (existsSync2(filePath)) {
|
|
5863
|
+
let existing = "";
|
|
5864
|
+
try {
|
|
5865
|
+
existing = readFileSync2(filePath, "utf-8");
|
|
5866
|
+
} catch {
|
|
5867
|
+
}
|
|
5868
|
+
if (existing === desired) continue;
|
|
5869
|
+
writeFileSync2(filePath, desired);
|
|
5870
|
+
overwritten++;
|
|
5871
|
+
} else {
|
|
5872
|
+
writeFileSync2(filePath, desired);
|
|
5873
|
+
written++;
|
|
5874
|
+
}
|
|
5788
5875
|
}
|
|
5789
|
-
if (written > 0) {
|
|
5876
|
+
if (written > 0 || overwritten > 0) {
|
|
5790
5877
|
const updatedFiles = readdirSync2(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
5791
5878
|
lastLocalFileHash.set(agent.agent_id, createHash("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
5792
|
-
log2(`
|
|
5879
|
+
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
5793
5880
|
}
|
|
5794
5881
|
}
|
|
5882
|
+
return true;
|
|
5795
5883
|
} catch (err) {
|
|
5796
5884
|
log2(`Memory download failed for '${agent.code_name}': ${err.message}`);
|
|
5885
|
+
return false;
|
|
5797
5886
|
}
|
|
5798
5887
|
}
|
|
5799
5888
|
async function cleanupAgentFiles(codeName, agentDir) {
|
|
@@ -5963,6 +6052,9 @@ async function stopPolling(opts = {}) {
|
|
|
5963
6052
|
}
|
|
5964
6053
|
function startManager(opts) {
|
|
5965
6054
|
config = opts;
|
|
6055
|
+
log(
|
|
6056
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join3(homedir3(), ".augmented", "manager.log")}`
|
|
6057
|
+
);
|
|
5966
6058
|
deployMcpAssets();
|
|
5967
6059
|
void ensureHostFrameworkBinaries();
|
|
5968
6060
|
startPolling();
|
|
@@ -6127,6 +6219,7 @@ process.on("disconnect", () => {
|
|
|
6127
6219
|
});
|
|
6128
6220
|
export {
|
|
6129
6221
|
ChildProcessError,
|
|
6222
|
+
markAgentForFreshMemorySync,
|
|
6130
6223
|
startManager,
|
|
6131
6224
|
stopManager
|
|
6132
6225
|
};
|