@integrity-labs/agt-cli 0.24.3 → 0.24.4
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
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
success,
|
|
27
27
|
table,
|
|
28
28
|
warn
|
|
29
|
-
} from "../chunk-
|
|
29
|
+
} from "../chunk-3TYBPBDA.js";
|
|
30
30
|
import {
|
|
31
31
|
CHANNEL_REGISTRY,
|
|
32
32
|
DEPLOYMENT_TEMPLATES,
|
|
@@ -3736,7 +3736,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
3736
3736
|
import { existsSync as existsSync5, realpathSync } from "fs";
|
|
3737
3737
|
import chalk17 from "chalk";
|
|
3738
3738
|
import ora15 from "ora";
|
|
3739
|
-
var cliVersion = true ? "0.24.
|
|
3739
|
+
var cliVersion = true ? "0.24.4" : "dev";
|
|
3740
3740
|
async function fetchLatestVersion() {
|
|
3741
3741
|
const host2 = getHost();
|
|
3742
3742
|
if (!host2) return null;
|
|
@@ -4268,7 +4268,7 @@ function handleError(err) {
|
|
|
4268
4268
|
}
|
|
4269
4269
|
|
|
4270
4270
|
// src/bin/agt.ts
|
|
4271
|
-
var cliVersion2 = true ? "0.24.
|
|
4271
|
+
var cliVersion2 = true ? "0.24.4" : "dev";
|
|
4272
4272
|
var program = new Command();
|
|
4273
4273
|
program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
|
|
4274
4274
|
program.hook("preAction", (thisCommand) => {
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
provisionOrientHook,
|
|
13
13
|
provisionStopHook,
|
|
14
14
|
requireHost
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-3TYBPBDA.js";
|
|
16
16
|
import {
|
|
17
17
|
findTaskByTemplate,
|
|
18
18
|
getProjectDir as getProjectDir2,
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
} from "../chunk-ECDTRQLA.js";
|
|
70
70
|
|
|
71
71
|
// src/lib/manager-worker.ts
|
|
72
|
-
import { createHash as
|
|
72
|
+
import { createHash as createHash3 } from "crypto";
|
|
73
73
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, appendFileSync, mkdirSync as mkdirSync2, chmodSync, existsSync as existsSync4, rmSync as rmSync2, readdirSync as readdirSync3, statSync as statSync2, unlinkSync, copyFileSync } from "fs";
|
|
74
74
|
import https from "https";
|
|
75
75
|
import { execFileSync as syncExecFile } from "child_process";
|
|
@@ -78,15 +78,30 @@ import { homedir as homedir4 } from "os";
|
|
|
78
78
|
import { fileURLToPath } from "url";
|
|
79
79
|
|
|
80
80
|
// src/lib/mcp-config-drift.ts
|
|
81
|
+
import { createHash } from "crypto";
|
|
81
82
|
function decideMcpDriftAction(currentHash, knownHash) {
|
|
82
83
|
if (!currentHash) return { kind: "no-config" };
|
|
83
84
|
if (!knownHash) return { kind: "baseline", hash: currentHash };
|
|
84
85
|
if (knownHash === currentHash) return { kind: "no-drift" };
|
|
85
86
|
return { kind: "drift", previous: knownHash, current: currentHash };
|
|
86
87
|
}
|
|
88
|
+
function decideMcpRestartOnDrift(previousKeys, currentKeys) {
|
|
89
|
+
if (!previousKeys || !currentKeys) {
|
|
90
|
+
return { restart: true, membershipUnknown: true, addedOrRemoved: [] };
|
|
91
|
+
}
|
|
92
|
+
const addedOrRemoved = [];
|
|
93
|
+
for (const k of currentKeys) if (!previousKeys.has(k)) addedOrRemoved.push(k);
|
|
94
|
+
for (const k of previousKeys) if (!currentKeys.has(k)) addedOrRemoved.push(k);
|
|
95
|
+
addedOrRemoved.sort();
|
|
96
|
+
return { restart: addedOrRemoved.length > 0, membershipUnknown: false, addedOrRemoved };
|
|
97
|
+
}
|
|
98
|
+
function managedMcpStructureHash(entries) {
|
|
99
|
+
const basis = entries.slice().sort((a, b) => a.serverId.localeCompare(b.serverId)).map((e) => `${e.serverId}|${Object.keys(e.headers ?? {}).sort().join(",")}`).join("\n");
|
|
100
|
+
return createHash("sha256").update(basis).digest("hex").slice(0, 16);
|
|
101
|
+
}
|
|
87
102
|
|
|
88
103
|
// src/lib/integration-hash.ts
|
|
89
|
-
import { createHash } from "crypto";
|
|
104
|
+
import { createHash as createHash2 } from "crypto";
|
|
90
105
|
function canonicalize(value) {
|
|
91
106
|
if (Array.isArray(value)) return value.map(canonicalize);
|
|
92
107
|
if (value && typeof value === "object") {
|
|
@@ -103,7 +118,7 @@ function computeIntegrationsHash(integrations) {
|
|
|
103
118
|
const payload = integrations.map(
|
|
104
119
|
(i) => `${i.definition_id}:${JSON.stringify(canonicalize(i.credentials ?? {}))}:${JSON.stringify(canonicalize(i.config ?? {}))}`
|
|
105
120
|
);
|
|
106
|
-
return
|
|
121
|
+
return createHash2("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
|
|
107
122
|
}
|
|
108
123
|
|
|
109
124
|
// src/lib/stale-mcp-reaper.ts
|
|
@@ -2627,7 +2642,7 @@ var runningMcpServerKeys = /* @__PURE__ */ new Map();
|
|
|
2627
2642
|
function projectMcpHash(_codeName, projectDir) {
|
|
2628
2643
|
try {
|
|
2629
2644
|
const raw = readFileSync5(join6(projectDir, ".mcp.json"), "utf-8");
|
|
2630
|
-
return
|
|
2645
|
+
return createHash3("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
2631
2646
|
} catch {
|
|
2632
2647
|
return null;
|
|
2633
2648
|
}
|
|
@@ -2671,33 +2686,34 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
|
|
|
2671
2686
|
}
|
|
2672
2687
|
case "drift": {
|
|
2673
2688
|
log(
|
|
2674
|
-
`[hot-reload] .mcp.json content changed for '${codeName}' (${action.previous.slice(0, 12)} \u2192 ${action.current.slice(0, 12)})
|
|
2689
|
+
`[hot-reload] .mcp.json content changed for '${codeName}' (${action.previous.slice(0, 12)} \u2192 ${action.current.slice(0, 12)}) (ENG-4897)`
|
|
2675
2690
|
);
|
|
2676
2691
|
const previousKeys = runningMcpServerKeys.get(codeName);
|
|
2677
2692
|
const currentKeys = projectMcpKeys(codeName, projectDir);
|
|
2678
|
-
|
|
2693
|
+
const decision = decideMcpRestartOnDrift(previousKeys, currentKeys);
|
|
2694
|
+
if (decision.membershipUnknown) {
|
|
2679
2695
|
clearPresenceReaperState(codeName);
|
|
2680
2696
|
log(
|
|
2681
|
-
`[hot-reload] .mcp.json key membership unavailable for '${codeName}' \u2014 clearing full presence-reaper state (ENG-5285)`
|
|
2697
|
+
`[hot-reload] .mcp.json key membership unavailable for '${codeName}' \u2014 clearing full presence-reaper state and restarting (ENG-5285/ENG-5537)`
|
|
2698
|
+
);
|
|
2699
|
+
} else if (decision.restart) {
|
|
2700
|
+
clearPresenceReaperStateForKeys(codeName, new Set(decision.addedOrRemoved));
|
|
2701
|
+
log(
|
|
2702
|
+
`[hot-reload] .mcp.json membership changed for '${codeName}': ${decision.addedOrRemoved.length} key(s) added/removed [${decision.addedOrRemoved.join(", ")}] \u2014 reaper state cleared for those keys only (ENG-5285)`
|
|
2682
2703
|
);
|
|
2683
2704
|
} else {
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
);
|
|
2696
|
-
}
|
|
2705
|
+
log(
|
|
2706
|
+
`[hot-reload] .mcp.json value-only drift for '${codeName}' \u2014 preserving presence-reaper state and NOT restarting (ENG-5285/ENG-5537)`
|
|
2707
|
+
);
|
|
2708
|
+
}
|
|
2709
|
+
if (decision.restart) {
|
|
2710
|
+
scheduleSessionRestart(codeName, 0, ".mcp.json content change (ENG-4897)");
|
|
2711
|
+
runningMcpHashes.delete(codeName);
|
|
2712
|
+
runningMcpServerKeys.delete(codeName);
|
|
2713
|
+
} else {
|
|
2714
|
+
runningMcpHashes.set(codeName, action.current);
|
|
2715
|
+
if (currentKeys) runningMcpServerKeys.set(codeName, currentKeys);
|
|
2697
2716
|
}
|
|
2698
|
-
scheduleSessionRestart(codeName, 0, ".mcp.json content change (ENG-4897)");
|
|
2699
|
-
runningMcpHashes.delete(codeName);
|
|
2700
|
-
runningMcpServerKeys.delete(codeName);
|
|
2701
2717
|
return;
|
|
2702
2718
|
}
|
|
2703
2719
|
}
|
|
@@ -2707,6 +2723,7 @@ var knownModels = /* @__PURE__ */ new Map();
|
|
|
2707
2723
|
var knownTasksHashes = /* @__PURE__ */ new Map();
|
|
2708
2724
|
var knownIntegrationHashes = /* @__PURE__ */ new Map();
|
|
2709
2725
|
var knownManagedMcpHashes = /* @__PURE__ */ new Map();
|
|
2726
|
+
var knownManagedMcpStructure = /* @__PURE__ */ new Map();
|
|
2710
2727
|
var knownSkillHashes = /* @__PURE__ */ new Map();
|
|
2711
2728
|
var managedToolkitIdByAgentAndServerId = /* @__PURE__ */ new Map();
|
|
2712
2729
|
function managedToolkitMapKey(agentId, serverId) {
|
|
@@ -2758,6 +2775,7 @@ function clearAgentCaches(agentId, codeName) {
|
|
|
2758
2775
|
knownTasksHashes.delete(agentId);
|
|
2759
2776
|
knownIntegrationHashes.delete(agentId);
|
|
2760
2777
|
knownManagedMcpHashes.delete(agentId);
|
|
2778
|
+
knownManagedMcpStructure.delete(agentId);
|
|
2761
2779
|
agentDisplayNames.delete(codeName);
|
|
2762
2780
|
codeNameToAgentId.delete(codeName);
|
|
2763
2781
|
agentFrameworkCache.delete(codeName);
|
|
@@ -2788,7 +2806,7 @@ var cachedFrameworkVersion = null;
|
|
|
2788
2806
|
var lastVersionCheckAt = 0;
|
|
2789
2807
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
2790
2808
|
var lastResponsivenessProbeAt = 0;
|
|
2791
|
-
var agtCliVersion = true ? "0.24.
|
|
2809
|
+
var agtCliVersion = true ? "0.24.4" : "dev";
|
|
2792
2810
|
function resolveBrewPath(execFileSync4) {
|
|
2793
2811
|
try {
|
|
2794
2812
|
const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -3367,7 +3385,7 @@ function log(msg) {
|
|
|
3367
3385
|
}
|
|
3368
3386
|
}
|
|
3369
3387
|
function sha256(content) {
|
|
3370
|
-
return
|
|
3388
|
+
return createHash3("sha256").update(content, "utf8").digest("hex");
|
|
3371
3389
|
}
|
|
3372
3390
|
function hashFile(filePath) {
|
|
3373
3391
|
try {
|
|
@@ -3777,7 +3795,7 @@ async function pollCycle() {
|
|
|
3777
3795
|
claudeAuth = await detectClaudeAuth();
|
|
3778
3796
|
} catch (err) {
|
|
3779
3797
|
const errText = err instanceof Error ? err.message : String(err);
|
|
3780
|
-
const errId =
|
|
3798
|
+
const errId = createHash3("sha256").update(errText).digest("hex").slice(0, 12);
|
|
3781
3799
|
log(`Claude auth detection failed (error_id=${errId})`);
|
|
3782
3800
|
}
|
|
3783
3801
|
await api.post("/host/heartbeat", {
|
|
@@ -4497,7 +4515,7 @@ async function processAgent(agent, agentStates) {
|
|
|
4497
4515
|
const peersForHash = channelId === "telegram" ? extractCharterTelegramPeers(refreshData.charter?.raw_content ?? "", gateContext) : channelId === "slack" ? extractCharterSlackPeers(refreshData.charter?.raw_content ?? "", gateContext) : null;
|
|
4498
4516
|
const sessionModeForHash = refreshData.agent.session_mode;
|
|
4499
4517
|
const CHANNEL_WRITE_VERSION = 5;
|
|
4500
|
-
const configHash =
|
|
4518
|
+
const configHash = createHash3("sha256").update(
|
|
4501
4519
|
canonicalJson({
|
|
4502
4520
|
writeVersion: CHANNEL_WRITE_VERSION,
|
|
4503
4521
|
config: entry.config,
|
|
@@ -4759,15 +4777,17 @@ async function processAgent(agent, agentStates) {
|
|
|
4759
4777
|
desiredEntries.push({ serverId, url, headers: mcpHeaders, name: tk.toolkit_name });
|
|
4760
4778
|
}
|
|
4761
4779
|
const hashBasis = desiredEntries.slice().sort((a, b) => a.serverId.localeCompare(b.serverId)).map((e) => {
|
|
4762
|
-
const headersHash =
|
|
4780
|
+
const headersHash = createHash3("sha256").update(canonicalJson(e.headers ?? {})).digest("hex").slice(0, 16);
|
|
4763
4781
|
return `${e.serverId}|${e.url}|${headersHash}`;
|
|
4764
4782
|
}).join("\n");
|
|
4765
|
-
const mcpHash =
|
|
4783
|
+
const mcpHash = createHash3("sha256").update(hashBasis).digest("hex").slice(0, 16);
|
|
4766
4784
|
const prevMcpHash = knownManagedMcpHashes.get(agent.agent_id);
|
|
4785
|
+
const structureHash = managedMcpStructureHash(desiredEntries);
|
|
4786
|
+
const prevStructureHash = knownManagedMcpStructure.get(agent.agent_id);
|
|
4767
4787
|
if (mcpHash !== prevMcpHash) {
|
|
4768
4788
|
for (const e of desiredEntries) {
|
|
4769
4789
|
frameworkAdapter.writeMcpServer(agent.code_name, e.serverId, { url: e.url, headers: e.headers });
|
|
4770
|
-
const urlHash =
|
|
4790
|
+
const urlHash = createHash3("sha256").update(e.url).digest("hex").slice(0, 12);
|
|
4771
4791
|
log(`[managed-toolkit] ${agent.code_name}: wrote '${e.name}' (serverId=${e.serverId}, url_hash=${urlHash})`);
|
|
4772
4792
|
}
|
|
4773
4793
|
if (frameworkAdapter.removeMcpServer && frameworkAdapter.getMcpPath) {
|
|
@@ -4801,7 +4821,8 @@ async function processAgent(agent, agentStates) {
|
|
|
4801
4821
|
}
|
|
4802
4822
|
}
|
|
4803
4823
|
knownManagedMcpHashes.set(agent.agent_id, mcpHash);
|
|
4804
|
-
|
|
4824
|
+
knownManagedMcpStructure.set(agent.agent_id, structureHash);
|
|
4825
|
+
if (prevStructureHash !== void 0 && structureHash !== prevStructureHash && fwForMcp === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
4805
4826
|
const mcpNames = agentToolkits.map((tk) => tk.toolkit_name).join(", ") || "none (all removed)";
|
|
4806
4827
|
log(`[hot-reload] MCP servers changed for '${agent.code_name}': ${mcpNames} \u2014 restarting session`);
|
|
4807
4828
|
const restartNotice = agentToolkits.length > 0 ? `New MCP tool servers have been configured: ${mcpNames}. Note: MCP servers require a session restart to connect. Your manager will restart your session shortly.` : "Managed MCP tool servers were removed. Your manager will restart your session shortly so the session drops those tools.";
|
|
@@ -4889,7 +4910,7 @@ async function processAgent(agent, agentStates) {
|
|
|
4889
4910
|
if (frameworkAdapter.installSkillFiles) {
|
|
4890
4911
|
const currentIntegrationSkillIds = /* @__PURE__ */ new Set();
|
|
4891
4912
|
const installedIntegrationSkills = [];
|
|
4892
|
-
const { createHash:
|
|
4913
|
+
const { createHash: createHash4 } = await import("crypto");
|
|
4893
4914
|
const refreshAny = refreshData;
|
|
4894
4915
|
const contexts = refreshAny.integration_contexts ?? refreshAny.plugin_contexts ?? [];
|
|
4895
4916
|
const contextBySlug = /* @__PURE__ */ new Map();
|
|
@@ -4918,7 +4939,7 @@ async function processAgent(agent, agentStates) {
|
|
|
4918
4939
|
)
|
|
4919
4940
|
}));
|
|
4920
4941
|
const bundle = buildIntegrationBundle(renderedScopes);
|
|
4921
|
-
const contentHash =
|
|
4942
|
+
const contentHash = createHash4("sha256").update(bundleFingerprint(bundle.files)).digest("hex").slice(0, 12);
|
|
4922
4943
|
const hashKey = `plugin-skill:${agent.agent_id}:${integrationSkillId}`;
|
|
4923
4944
|
if (knownSkillHashes.get(hashKey) === contentHash) continue;
|
|
4924
4945
|
frameworkAdapter.installSkillFiles(agent.code_name, integrationSkillId, bundle.files);
|
|
@@ -4987,7 +5008,7 @@ async function processAgent(agent, agentStates) {
|
|
|
4987
5008
|
const slug = hook.integration_slug ?? hook.plugin_slug;
|
|
4988
5009
|
if (!slug) continue;
|
|
4989
5010
|
try {
|
|
4990
|
-
const scriptHash =
|
|
5011
|
+
const scriptHash = createHash4("sha256").update(hook.script).digest("hex").slice(0, 12);
|
|
4991
5012
|
const hookKey = `${agent.agent_id}:${frameworkAdapter.id}:plugin-hook:${slug}:on_install`;
|
|
4992
5013
|
if (knownSkillHashes.get(hookKey) === scriptHash) continue;
|
|
4993
5014
|
const result = await frameworkAdapter.executePluginHook({
|
|
@@ -5002,9 +5023,9 @@ async function processAgent(agent, agentStates) {
|
|
|
5002
5023
|
} else if (result.timedOut) {
|
|
5003
5024
|
log(`Integration hook on_install '${slug}' TIMED OUT for '${agent.code_name}' after ${result.durationMs}ms`);
|
|
5004
5025
|
} else {
|
|
5005
|
-
const stderrHash =
|
|
5026
|
+
const stderrHash = createHash4("sha256").update(result.stderr).digest("hex").slice(0, 12);
|
|
5006
5027
|
const missingCmd = result.exitCode === 127 ? extractCommandNotFound(result.stderr) : null;
|
|
5007
|
-
const missingCmdHash = missingCmd ?
|
|
5028
|
+
const missingCmdHash = missingCmd ? createHash4("sha256").update(missingCmd).digest("hex").slice(0, 8) : null;
|
|
5008
5029
|
log(
|
|
5009
5030
|
`Integration hook on_install '${slug}' exited ${result.exitCode} for '${agent.code_name}' ` + (missingCmdHash ? `[missing_command_hash=${missingCmdHash}] ` : "") + `[stderr_hash=${stderrHash} stderr_len=${result.stderr.length}]`
|
|
5010
5031
|
);
|
|
@@ -5194,10 +5215,10 @@ async function processAgent(agent, agentStates) {
|
|
|
5194
5215
|
} else if (agentFw === "claude-code" && tasks.length > 0) {
|
|
5195
5216
|
await syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData);
|
|
5196
5217
|
} else if (frameworkAdapter.syncScheduledTasks && gatewayRunning && gatewayPort) {
|
|
5197
|
-
const stableTasksHash =
|
|
5198
|
-
const boardHash = boardItems.length > 0 ?
|
|
5218
|
+
const stableTasksHash = createHash3("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
5219
|
+
const boardHash = boardItems.length > 0 ? createHash3("sha256").update(JSON.stringify(boardItems.map((b) => ({ id: b.id, title: b.title, status: b.status, priority: b.priority, deliverable: b.deliverable })))).digest("hex").slice(0, 16) : "empty";
|
|
5199
5220
|
const resolvedModels = resolveModelChain(refreshData);
|
|
5200
|
-
const modelsHash =
|
|
5221
|
+
const modelsHash = createHash3("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
|
|
5201
5222
|
const combinedHash = `${stableTasksHash}:${boardHash}:${modelsHash}`;
|
|
5202
5223
|
const prevTasksHash = knownTasksHashes.get(agent.agent_id);
|
|
5203
5224
|
if (combinedHash !== prevTasksHash) {
|
|
@@ -5577,10 +5598,10 @@ var MAX_CLAUDE_CONCURRENCY = 2;
|
|
|
5577
5598
|
var claudeSchedulerStates = /* @__PURE__ */ new Map();
|
|
5578
5599
|
async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData) {
|
|
5579
5600
|
const codeName = agent.code_name;
|
|
5580
|
-
const stableTasksHash =
|
|
5581
|
-
const boardHash = boardItems.length > 0 ?
|
|
5601
|
+
const stableTasksHash = createHash3("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
5602
|
+
const boardHash = boardItems.length > 0 ? createHash3("sha256").update(JSON.stringify(boardItems.map((b) => ({ id: b.id, title: b.title, status: b.status, priority: b.priority, deliverable: b.deliverable })))).digest("hex").slice(0, 16) : "empty";
|
|
5582
5603
|
const resolvedModels = resolveModelChain(refreshData);
|
|
5583
|
-
const modelsHash =
|
|
5604
|
+
const modelsHash = createHash3("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
|
|
5584
5605
|
const combinedHash = `${stableTasksHash}:${boardHash}:${modelsHash}`;
|
|
5585
5606
|
const prevHash = knownTasksHashes.get(agent.agent_id);
|
|
5586
5607
|
if (combinedHash !== prevHash) {
|
|
@@ -5658,7 +5679,7 @@ async function startRun(opts) {
|
|
|
5658
5679
|
return { run_id: res.run_id ?? null, kanban_item_id: res.kanban_item_id ?? null };
|
|
5659
5680
|
} catch (err) {
|
|
5660
5681
|
const errText = err instanceof Error ? err.message : String(err);
|
|
5661
|
-
const errId =
|
|
5682
|
+
const errId = createHash3("sha256").update(errText).digest("hex").slice(0, 12);
|
|
5662
5683
|
log(`[runs] start failed for agent_id=${opts.agent_id} source_type=${opts.source_type} error_id=${errId}`);
|
|
5663
5684
|
return { run_id: null, kanban_item_id: null };
|
|
5664
5685
|
}
|
|
@@ -5675,7 +5696,7 @@ async function finishRun(runId, outcome, options = {}) {
|
|
|
5675
5696
|
});
|
|
5676
5697
|
} catch (err) {
|
|
5677
5698
|
const errText = err instanceof Error ? err.message : String(err);
|
|
5678
|
-
const errId =
|
|
5699
|
+
const errId = createHash3("sha256").update(errText).digest("hex").slice(0, 12);
|
|
5679
5700
|
log(`[runs] finish failed for run_id=${runId} outcome=${outcome} error_id=${errId}`);
|
|
5680
5701
|
}
|
|
5681
5702
|
}
|
|
@@ -5692,7 +5713,7 @@ async function fetchPriorScheduledRuns(agentId, taskId) {
|
|
|
5692
5713
|
return rows.filter((r) => typeof r.output_text === "string" && r.output_text.length > 0).map((r) => ({ startedAt: r.started_at, output: r.output_text }));
|
|
5693
5714
|
} catch (err) {
|
|
5694
5715
|
const errText = err instanceof Error ? err.message : String(err);
|
|
5695
|
-
const errId =
|
|
5716
|
+
const errId = createHash3("sha256").update(errText).digest("hex").slice(0, 12);
|
|
5696
5717
|
log(`[runs] prior-runs lookup failed for task_id=${taskId} error_id=${errId}`);
|
|
5697
5718
|
return [];
|
|
5698
5719
|
}
|
|
@@ -5826,10 +5847,10 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
5826
5847
|
const classification = classifyOutput(rawOutput);
|
|
5827
5848
|
if (classification.action === "suppress") {
|
|
5828
5849
|
const trimmed = (rawOutput ?? "").trim();
|
|
5829
|
-
const outputHash = trimmed.length === 0 ? "empty" :
|
|
5850
|
+
const outputHash = trimmed.length === 0 ? "empty" : createHash3("sha256").update(trimmed).digest("hex").slice(0, 12);
|
|
5830
5851
|
log(`[claude-scheduler] Suppressing delivery for '${codeName}' (template=${templateId}, task=${delivery?.taskId ?? "n/a"}) \u2014 output_len=${trimmed.length} output_hash=${outputHash}`);
|
|
5831
5852
|
if (classification.suppressedNotes) {
|
|
5832
|
-
const notesHash =
|
|
5853
|
+
const notesHash = createHash3("sha256").update(classification.suppressedNotes).digest("hex").slice(0, 12);
|
|
5833
5854
|
log(`[claude-scheduler] Suppressed notes for '${codeName}' (task=${delivery?.taskId ?? "n/a"}) \u2014 notes_len=${classification.suppressedNotes.length} notes_hash=${notesHash}`);
|
|
5834
5855
|
}
|
|
5835
5856
|
if (delivery?.mode === "announce" && delivery.to) {
|
|
@@ -6051,7 +6072,7 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
6051
6072
|
const ctx = getLastFailureContext(codeName);
|
|
6052
6073
|
const recovery = prepareForRespawn(codeName);
|
|
6053
6074
|
const tailSummary = !ctx.tail ? "" : KNOWN_SAFE_TAIL_SIGNATURES.has(ctx.signature) ? `; last pane output (${PANE_TAIL_PREVIEW_LINES} of ~20 lines):
|
|
6054
|
-
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${
|
|
6075
|
+
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash3("sha256").update(ctx.tail).digest("hex").slice(0, 12)} (raw at ~/.augmented/${codeName}/pane.log)`;
|
|
6055
6076
|
const sigSummary = ctx.signature !== "unknown" ? `; signature=${ctx.signature}` : "";
|
|
6056
6077
|
const recoverySummary = recovery ? `; recovery=${recovery}` : "";
|
|
6057
6078
|
log(
|
|
@@ -6065,7 +6086,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash2("sha256").
|
|
|
6065
6086
|
);
|
|
6066
6087
|
getHostId().then((hostId) => {
|
|
6067
6088
|
if (!hostId) return;
|
|
6068
|
-
const paneTailHash = zombie.paneTail ? `sha256:${
|
|
6089
|
+
const paneTailHash = zombie.paneTail ? `sha256:${createHash3("sha256").update(zombie.paneTail).digest("hex").slice(0, 12)}` : null;
|
|
6069
6090
|
return api.post("/host/events", {
|
|
6070
6091
|
host_id: hostId,
|
|
6071
6092
|
agent_code_name: codeName,
|
|
@@ -6132,7 +6153,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash2("sha256").
|
|
|
6132
6153
|
if (!claudeAuthTupleBySession.has(codeName)) {
|
|
6133
6154
|
claudeAuthTupleBySession.set(codeName, currentAuthTuple);
|
|
6134
6155
|
}
|
|
6135
|
-
const stableTasksHash =
|
|
6156
|
+
const stableTasksHash = createHash3("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
6136
6157
|
const prevHash = knownTasksHashes.get(agent.agent_id);
|
|
6137
6158
|
if (stableTasksHash !== prevHash) {
|
|
6138
6159
|
const taskInputs = tasks.map((t) => ({
|
|
@@ -6616,7 +6637,7 @@ ${escapeXml(msg.content)}
|
|
|
6616
6637
|
log(`[direct-chat] Reply sent for '${agent.codeName}'`);
|
|
6617
6638
|
} catch (err) {
|
|
6618
6639
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
6619
|
-
const errorId =
|
|
6640
|
+
const errorId = createHash3("sha256").update(errMsg).digest("hex").slice(0, 12);
|
|
6620
6641
|
log(`[direct-chat] Failed to process message for '${agent.codeName}': error_id=${errorId} error=${errMsg.slice(0, 500)}`);
|
|
6621
6642
|
try {
|
|
6622
6643
|
await api.post("/host/direct-chat/reply", {
|
|
@@ -7847,7 +7868,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
7847
7868
|
if (!file.endsWith(".md")) continue;
|
|
7848
7869
|
try {
|
|
7849
7870
|
const raw = readFileSync5(join6(memoryDir, file), "utf-8");
|
|
7850
|
-
const fileHash =
|
|
7871
|
+
const fileHash = createHash3("sha256").update(raw).digest("hex").slice(0, 16);
|
|
7851
7872
|
currentHashes.set(file, fileHash);
|
|
7852
7873
|
if (prevHashes.get(file) === fileHash) continue;
|
|
7853
7874
|
const parsed = parseMemoryFile(raw, file.replace(/\.md$/, ""));
|
|
@@ -7885,14 +7906,14 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
7885
7906
|
}
|
|
7886
7907
|
async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
7887
7908
|
const localFiles = existsSync4(memoryDir) ? readdirSync3(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
7888
|
-
const localListHash =
|
|
7909
|
+
const localListHash = createHash3("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
7889
7910
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
7890
7911
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
7891
7912
|
try {
|
|
7892
7913
|
const dbMemories = await api.post("/host/memories", {
|
|
7893
7914
|
agent_id: agent.agent_id
|
|
7894
7915
|
});
|
|
7895
|
-
const responseHash =
|
|
7916
|
+
const responseHash = createHash3("sha256").update(JSON.stringify(dbMemories.memories ?? [])).digest("hex").slice(0, 16);
|
|
7896
7917
|
if (!force && prevDownload && prevLocalHash === localListHash && lastDownloadHash.get(agent.agent_id) === responseHash) {
|
|
7897
7918
|
return true;
|
|
7898
7919
|
}
|
|
@@ -7931,7 +7952,7 @@ ${mem.content}
|
|
|
7931
7952
|
}
|
|
7932
7953
|
if (written > 0 || overwritten > 0) {
|
|
7933
7954
|
const updatedFiles = readdirSync3(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
7934
|
-
lastLocalFileHash.set(agent.agent_id,
|
|
7955
|
+
lastLocalFileHash.set(agent.agent_id, createHash3("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
7935
7956
|
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
7936
7957
|
}
|
|
7937
7958
|
}
|
|
@@ -8216,7 +8237,7 @@ function deployMcpAssets() {
|
|
|
8216
8237
|
const fileHash = (p) => {
|
|
8217
8238
|
try {
|
|
8218
8239
|
if (!existsSync4(p)) return null;
|
|
8219
|
-
return
|
|
8240
|
+
return createHash3("sha256").update(readFileSync5(p)).digest("hex");
|
|
8220
8241
|
} catch {
|
|
8221
8242
|
return null;
|
|
8222
8243
|
}
|