@integrity-labs/agt-cli 0.10.5 → 0.10.7
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-R2DDHROT.js → chunk-VDUA5FEW.js} +198 -14
- package/dist/chunk-VDUA5FEW.js.map +1 -0
- package/dist/lib/manager-worker.js +134 -5
- package/dist/lib/manager-worker.js.map +1 -1
- package/mcp/slack-channel.js +41 -0
- package/package.json +1 -1
- package/dist/chunk-R2DDHROT.js.map +0 -1
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
provisionStopHook,
|
|
11
11
|
requireHost,
|
|
12
12
|
resolveChannels
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-VDUA5FEW.js";
|
|
14
14
|
import {
|
|
15
15
|
findTaskByTemplate,
|
|
16
16
|
getProjectDir,
|
|
@@ -683,6 +683,9 @@ function clearAgentCaches(agentId, codeName) {
|
|
|
683
683
|
lastHarvestAt.delete(codeName);
|
|
684
684
|
claudeSchedulerStates.delete(codeName);
|
|
685
685
|
claudeTaskConcurrency.delete(codeName);
|
|
686
|
+
memoryFileHashes.delete(agentId);
|
|
687
|
+
lastDownloadHash.delete(agentId);
|
|
688
|
+
lastLocalFileHash.delete(agentId);
|
|
686
689
|
for (const key of knownChannelConfigHashes.keys()) {
|
|
687
690
|
if (key.startsWith(`${agentId}:`)) knownChannelConfigHashes.delete(key);
|
|
688
691
|
}
|
|
@@ -1703,13 +1706,20 @@ async function processAgent(agent, agentStates) {
|
|
|
1703
1706
|
if (!pluginName) continue;
|
|
1704
1707
|
const entry = refreshData.channel_configs[channelId];
|
|
1705
1708
|
if (!entry || entry.status !== "active" && entry.status !== "pending") continue;
|
|
1706
|
-
|
|
1707
|
-
|
|
1709
|
+
try {
|
|
1710
|
+
const installedPath = join(homedir(), ".claude", "plugins", "installed_plugins.json");
|
|
1711
|
+
if (existsSync(installedPath)) {
|
|
1712
|
+
const installed = JSON.parse(readFileSync(installedPath, "utf-8"));
|
|
1713
|
+
const pluginKeys = Object.keys(installed.plugins ?? {});
|
|
1714
|
+
if (pluginKeys.some((k) => k.startsWith(`${pluginName}@`))) continue;
|
|
1715
|
+
}
|
|
1716
|
+
} catch {
|
|
1717
|
+
}
|
|
1708
1718
|
try {
|
|
1709
1719
|
const { execFileSync: efs } = await import("child_process");
|
|
1710
1720
|
const claudePath = efs("which", ["claude"], { timeout: 5e3 }).toString().trim();
|
|
1711
1721
|
if (claudePath) {
|
|
1712
|
-
efs(claudePath, ["plugin", "
|
|
1722
|
+
efs(claudePath, ["plugin", "install", pluginName], {
|
|
1713
1723
|
timeout: 3e4,
|
|
1714
1724
|
stdio: "pipe"
|
|
1715
1725
|
});
|
|
@@ -2280,6 +2290,13 @@ In progress for ${age} minutes \u2014 auto-failed`).catch(() => {
|
|
|
2280
2290
|
}
|
|
2281
2291
|
}
|
|
2282
2292
|
}
|
|
2293
|
+
if (frameworkId === "claude-code" && agent.status === "active") {
|
|
2294
|
+
try {
|
|
2295
|
+
await syncMemories(agent, config.configDir, log);
|
|
2296
|
+
} catch (err) {
|
|
2297
|
+
log(`Memory sync failed for '${agent.code_name}': ${err.message}`);
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2283
2300
|
agentStates.push({
|
|
2284
2301
|
agentId: agent.agent_id,
|
|
2285
2302
|
codeName: agent.code_name,
|
|
@@ -3813,11 +3830,123 @@ function generateArtifacts(agent, refreshData, adapter) {
|
|
|
3813
3830
|
timezone: agentTimezone,
|
|
3814
3831
|
reportsTo,
|
|
3815
3832
|
personalitySeed,
|
|
3816
|
-
knowledge: (refreshData.knowledge ?? []).filter((k) => !!k.content)
|
|
3833
|
+
knowledge: (refreshData.knowledge ?? []).filter((k) => !!k.content),
|
|
3834
|
+
teamMembers: refreshData.team_members ?? void 0,
|
|
3835
|
+
people: refreshData.people ?? void 0
|
|
3817
3836
|
};
|
|
3818
3837
|
const provisionOutput = provision(provisionInput, adapter.id);
|
|
3819
3838
|
return provisionOutput.artifacts;
|
|
3820
3839
|
}
|
|
3840
|
+
var memoryFileHashes = /* @__PURE__ */ new Map();
|
|
3841
|
+
var lastDownloadHash = /* @__PURE__ */ new Map();
|
|
3842
|
+
var lastLocalFileHash = /* @__PURE__ */ new Map();
|
|
3843
|
+
function parseMemoryFile(raw, fallbackName) {
|
|
3844
|
+
const trimmed = raw.trim();
|
|
3845
|
+
if (!trimmed) return null;
|
|
3846
|
+
const fmMatch = trimmed.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
3847
|
+
if (fmMatch) {
|
|
3848
|
+
const frontmatter = fmMatch[1] ?? "";
|
|
3849
|
+
const body = (fmMatch[2] ?? "").trim();
|
|
3850
|
+
if (!body) return null;
|
|
3851
|
+
const nameMatch = frontmatter.match(/^name:\s*(.+)$/m);
|
|
3852
|
+
const typeMatch = frontmatter.match(/^type:\s*(.+)$/m);
|
|
3853
|
+
const name = nameMatch?.[1]?.trim().replace(/^["']|["']$/g, "") ?? fallbackName;
|
|
3854
|
+
const rawType = typeMatch?.[1]?.trim().replace(/^["']|["']$/g, "") ?? "user";
|
|
3855
|
+
const typeMap = { user: "user", feedback: "feedback", project: "project", reference: "reference", daily: "daily" };
|
|
3856
|
+
const type = typeMap[rawType] ?? "user";
|
|
3857
|
+
return { name, content: body, type };
|
|
3858
|
+
}
|
|
3859
|
+
const isDaily = /^\d{4}-\d{2}-\d{2}$/.test(fallbackName);
|
|
3860
|
+
return {
|
|
3861
|
+
name: fallbackName,
|
|
3862
|
+
content: trimmed,
|
|
3863
|
+
type: isDaily ? "daily" : "project"
|
|
3864
|
+
};
|
|
3865
|
+
}
|
|
3866
|
+
async function syncMemories(agent, configDir, log2) {
|
|
3867
|
+
const projectDir = join(configDir, agent.code_name, "project");
|
|
3868
|
+
const memoryDir = join(projectDir, "memory");
|
|
3869
|
+
if (existsSync(memoryDir)) {
|
|
3870
|
+
const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
|
|
3871
|
+
const currentHashes = /* @__PURE__ */ new Map();
|
|
3872
|
+
const changedMemories = [];
|
|
3873
|
+
for (const file of readdirSync(memoryDir)) {
|
|
3874
|
+
if (!file.endsWith(".md")) continue;
|
|
3875
|
+
try {
|
|
3876
|
+
const raw = readFileSync(join(memoryDir, file), "utf-8");
|
|
3877
|
+
const fileHash = createHash("sha256").update(raw).digest("hex").slice(0, 16);
|
|
3878
|
+
currentHashes.set(file, fileHash);
|
|
3879
|
+
if (prevHashes.get(file) === fileHash) continue;
|
|
3880
|
+
const parsed = parseMemoryFile(raw, file.replace(/\.md$/, ""));
|
|
3881
|
+
if (parsed) {
|
|
3882
|
+
if (parsed.type === "daily") {
|
|
3883
|
+
parsed.expires_at = new Date(Date.now() + 48 * 60 * 60 * 1e3).toISOString();
|
|
3884
|
+
}
|
|
3885
|
+
changedMemories.push(parsed);
|
|
3886
|
+
}
|
|
3887
|
+
} catch {
|
|
3888
|
+
}
|
|
3889
|
+
}
|
|
3890
|
+
memoryFileHashes.set(agent.agent_id, currentHashes);
|
|
3891
|
+
if (changedMemories.length > 0) {
|
|
3892
|
+
try {
|
|
3893
|
+
await api.post("/host/sync-memories", {
|
|
3894
|
+
agent_id: agent.agent_id,
|
|
3895
|
+
memories: changedMemories
|
|
3896
|
+
});
|
|
3897
|
+
log2(`Synced ${changedMemories.length} changed memories to DB for '${agent.code_name}'`);
|
|
3898
|
+
} catch (err) {
|
|
3899
|
+
for (const mem of changedMemories) {
|
|
3900
|
+
for (const [file, hash] of currentHashes) {
|
|
3901
|
+
const parsed = parseMemoryFile(readFileSync(join(memoryDir, file), "utf-8"), "");
|
|
3902
|
+
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
log2(`Memory upload failed for '${agent.code_name}': ${err.message}`);
|
|
3906
|
+
}
|
|
3907
|
+
}
|
|
3908
|
+
}
|
|
3909
|
+
const localFiles = existsSync(memoryDir) ? readdirSync(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
3910
|
+
const localListHash = createHash("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
3911
|
+
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
3912
|
+
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
3913
|
+
if (prevDownload && prevLocalHash === localListHash) return;
|
|
3914
|
+
try {
|
|
3915
|
+
const dbMemories = await api.post("/host/memories", {
|
|
3916
|
+
agent_id: agent.agent_id
|
|
3917
|
+
});
|
|
3918
|
+
const responseHash = createHash("sha256").update(JSON.stringify(dbMemories.memories ?? [])).digest("hex").slice(0, 16);
|
|
3919
|
+
lastDownloadHash.set(agent.agent_id, responseHash);
|
|
3920
|
+
lastLocalFileHash.set(agent.agent_id, localListHash);
|
|
3921
|
+
if (dbMemories.memories?.length) {
|
|
3922
|
+
mkdirSync(memoryDir, { recursive: true });
|
|
3923
|
+
const existingFileSet = new Set(localFiles.map((f) => f.replace(/\.md$/, "").toLowerCase()));
|
|
3924
|
+
let written = 0;
|
|
3925
|
+
for (const mem of dbMemories.memories) {
|
|
3926
|
+
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
3927
|
+
const slug = rawSlug || `memory-${written}`;
|
|
3928
|
+
if (existingFileSet.has(slug)) continue;
|
|
3929
|
+
const fileContent = `---
|
|
3930
|
+
name: ${JSON.stringify(mem.name)}
|
|
3931
|
+
type: ${mem.type}
|
|
3932
|
+
description: ${JSON.stringify(mem.content.slice(0, 200))}
|
|
3933
|
+
---
|
|
3934
|
+
|
|
3935
|
+
${mem.content}
|
|
3936
|
+
`;
|
|
3937
|
+
writeFileSync(join(memoryDir, `${slug}.md`), fileContent);
|
|
3938
|
+
written++;
|
|
3939
|
+
}
|
|
3940
|
+
if (written > 0) {
|
|
3941
|
+
const updatedFiles = readdirSync(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
3942
|
+
lastLocalFileHash.set(agent.agent_id, createHash("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
3943
|
+
log2(`Exported ${written} DB memories to local files for '${agent.code_name}'`);
|
|
3944
|
+
}
|
|
3945
|
+
}
|
|
3946
|
+
} catch (err) {
|
|
3947
|
+
log2(`Memory download failed for '${agent.code_name}': ${err.message}`);
|
|
3948
|
+
}
|
|
3949
|
+
}
|
|
3821
3950
|
async function cleanupAgentFiles(codeName, agentDir) {
|
|
3822
3951
|
if (existsSync(agentDir)) {
|
|
3823
3952
|
try {
|