@cleocode/cleo 2026.3.58 → 2026.3.60
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/cli/index.js +1377 -635
- package/dist/cli/index.js.map +4 -4
- package/dist/mcp/index.js +1220 -634
- package/dist/mcp/index.js.map +4 -4
- package/package.json +3 -3
package/dist/cli/index.js
CHANGED
|
@@ -13163,9 +13163,9 @@ async function readSequenceFromDb(cwd, accessor) {
|
|
|
13163
13163
|
return isValidSequenceState(value) ? value : null;
|
|
13164
13164
|
}
|
|
13165
13165
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
13166
|
-
const { eq:
|
|
13166
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
13167
13167
|
const db = await getDb4(cwd);
|
|
13168
|
-
const rows = await db.select().from(schemaMeta).where(
|
|
13168
|
+
const rows = await db.select().from(schemaMeta).where(eq17(schemaMeta.key, SEQUENCE_META_KEY)).all();
|
|
13169
13169
|
const raw = rows[0]?.value;
|
|
13170
13170
|
if (!raw) return null;
|
|
13171
13171
|
try {
|
|
@@ -15276,7 +15276,7 @@ async function linkPipelineAdr(projectRoot, taskId) {
|
|
|
15276
15276
|
return result;
|
|
15277
15277
|
}
|
|
15278
15278
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
15279
|
-
const { and:
|
|
15279
|
+
const { and: and12, eq: eq17 } = await import("drizzle-orm");
|
|
15280
15280
|
const db = await getDb4(projectRoot);
|
|
15281
15281
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
15282
15282
|
for (const filePath of matchingFiles) {
|
|
@@ -15286,7 +15286,7 @@ async function linkPipelineAdr(projectRoot, taskId) {
|
|
|
15286
15286
|
const fm = record2.frontmatter;
|
|
15287
15287
|
const content = readFileSync5(filePath, "utf-8");
|
|
15288
15288
|
const relativePath = `.cleo/adrs/${filename}`;
|
|
15289
|
-
const existing = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(
|
|
15289
|
+
const existing = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(eq17(architectureDecisions.id, record2.id)).all();
|
|
15290
15290
|
const rowBase = {
|
|
15291
15291
|
id: record2.id,
|
|
15292
15292
|
title: record2.title,
|
|
@@ -15306,19 +15306,19 @@ async function linkPipelineAdr(projectRoot, taskId) {
|
|
|
15306
15306
|
updatedAt: now2
|
|
15307
15307
|
};
|
|
15308
15308
|
if (existing.length > 0) {
|
|
15309
|
-
await db.update(architectureDecisions).set(rowBase).where(
|
|
15309
|
+
await db.update(architectureDecisions).set(rowBase).where(eq17(architectureDecisions.id, record2.id));
|
|
15310
15310
|
} else {
|
|
15311
15311
|
await db.insert(architectureDecisions).values({ ...rowBase, createdAt: now2 });
|
|
15312
15312
|
}
|
|
15313
15313
|
result.synced++;
|
|
15314
|
-
await db.delete(adrTaskLinks).where(
|
|
15314
|
+
await db.delete(adrTaskLinks).where(and12(eq17(adrTaskLinks.adrId, record2.id), eq17(adrTaskLinks.taskId, taskId)));
|
|
15315
15315
|
await db.insert(adrTaskLinks).values({ adrId: record2.id, taskId, linkType: "implements" });
|
|
15316
15316
|
result.linked.push({ adrId: record2.id, taskId });
|
|
15317
15317
|
if (fm["Related ADRs"]) {
|
|
15318
15318
|
const relatedIds = fm["Related ADRs"].split(",").map((r) => r.trim()).filter((r) => /^ADR-\d+$/.test(r));
|
|
15319
15319
|
for (const toId of relatedIds) {
|
|
15320
15320
|
try {
|
|
15321
|
-
const targetExists = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(
|
|
15321
|
+
const targetExists = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(eq17(architectureDecisions.id, toId)).all();
|
|
15322
15322
|
if (targetExists.length > 0) {
|
|
15323
15323
|
await db.insert(adrRelations).values({ fromAdrId: record2.id, toAdrId: toId, relationType: "related" }).onConflictDoNothing();
|
|
15324
15324
|
}
|
|
@@ -15479,7 +15479,7 @@ async function syncAdrsToDb(projectRoot) {
|
|
|
15479
15479
|
return result;
|
|
15480
15480
|
}
|
|
15481
15481
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
15482
|
-
const { eq:
|
|
15482
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
15483
15483
|
const db = await getDb4(projectRoot);
|
|
15484
15484
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
15485
15485
|
const allFiles = collectAdrFiles(adrsDir);
|
|
@@ -15513,15 +15513,15 @@ async function syncAdrsToDb(projectRoot) {
|
|
|
15513
15513
|
topics: fm.Topics ?? null,
|
|
15514
15514
|
updatedAt: now2
|
|
15515
15515
|
};
|
|
15516
|
-
const existing = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(
|
|
15516
|
+
const existing = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(eq17(architectureDecisions.id, record2.id)).all();
|
|
15517
15517
|
if (existing.length > 0) {
|
|
15518
|
-
await db.update(architectureDecisions).set(rowBase).where(
|
|
15518
|
+
await db.update(architectureDecisions).set(rowBase).where(eq17(architectureDecisions.id, record2.id));
|
|
15519
15519
|
result.updated++;
|
|
15520
15520
|
} else {
|
|
15521
15521
|
await db.insert(architectureDecisions).values({ ...rowBase, createdAt: now2 });
|
|
15522
15522
|
result.inserted++;
|
|
15523
15523
|
}
|
|
15524
|
-
await db.delete(adrTaskLinks).where(
|
|
15524
|
+
await db.delete(adrTaskLinks).where(eq17(adrTaskLinks.adrId, record2.id));
|
|
15525
15525
|
if (fm["Related Tasks"]) {
|
|
15526
15526
|
for (const taskId of parseTaskIds2(fm["Related Tasks"])) {
|
|
15527
15527
|
await db.insert(adrTaskLinks).values({ adrId: record2.id, taskId, linkType: "related" });
|
|
@@ -15657,310 +15657,8 @@ var init_adrs = __esm({
|
|
|
15657
15657
|
}
|
|
15658
15658
|
});
|
|
15659
15659
|
|
|
15660
|
-
// packages/core/src/agents/registry.ts
|
|
15661
|
-
var registry_exports2 = {};
|
|
15662
|
-
__export(registry_exports2, {
|
|
15663
|
-
checkAgentHealth: () => checkAgentHealth,
|
|
15664
|
-
classifyError: () => classifyError,
|
|
15665
|
-
deregisterAgent: () => deregisterAgent,
|
|
15666
|
-
generateAgentId: () => generateAgentId,
|
|
15667
|
-
getAgentErrorHistory: () => getAgentErrorHistory,
|
|
15668
|
-
getAgentInstance: () => getAgentInstance,
|
|
15669
|
-
getHealthReport: () => getHealthReport,
|
|
15670
|
-
heartbeat: () => heartbeat,
|
|
15671
|
-
incrementTasksCompleted: () => incrementTasksCompleted,
|
|
15672
|
-
listAgentInstances: () => listAgentInstances,
|
|
15673
|
-
markCrashed: () => markCrashed,
|
|
15674
|
-
registerAgent: () => registerAgent,
|
|
15675
|
-
updateAgentStatus: () => updateAgentStatus
|
|
15676
|
-
});
|
|
15677
|
-
import { randomBytes } from "node:crypto";
|
|
15678
|
-
import { and as and3, eq as eq5, inArray as inArray4, lt as lt2, sql as sql8 } from "drizzle-orm";
|
|
15679
|
-
function generateAgentId() {
|
|
15680
|
-
const now2 = /* @__PURE__ */ new Date();
|
|
15681
|
-
const ts = now2.toISOString().replace(/[-:T]/g, "").substring(0, 14);
|
|
15682
|
-
const hex = randomBytes(3).toString("hex");
|
|
15683
|
-
return `agt_${ts}_${hex}`;
|
|
15684
|
-
}
|
|
15685
|
-
async function registerAgent(opts, cwd) {
|
|
15686
|
-
const db = await getDb(cwd);
|
|
15687
|
-
const id = generateAgentId();
|
|
15688
|
-
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
15689
|
-
const row = {
|
|
15690
|
-
id,
|
|
15691
|
-
agentType: opts.agentType,
|
|
15692
|
-
status: "starting",
|
|
15693
|
-
sessionId: opts.sessionId ?? null,
|
|
15694
|
-
taskId: opts.taskId ?? null,
|
|
15695
|
-
startedAt: now2,
|
|
15696
|
-
lastHeartbeat: now2,
|
|
15697
|
-
stoppedAt: null,
|
|
15698
|
-
errorCount: 0,
|
|
15699
|
-
totalTasksCompleted: 0,
|
|
15700
|
-
capacity: "1.0",
|
|
15701
|
-
metadataJson: opts.metadata ? JSON.stringify(opts.metadata) : "{}",
|
|
15702
|
-
parentAgentId: opts.parentAgentId ?? null
|
|
15703
|
-
};
|
|
15704
|
-
await db.insert(agentInstances).values(row);
|
|
15705
|
-
return row;
|
|
15706
|
-
}
|
|
15707
|
-
async function deregisterAgent(id, cwd) {
|
|
15708
|
-
const db = await getDb(cwd);
|
|
15709
|
-
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
15710
|
-
const existing = await db.select().from(agentInstances).where(eq5(agentInstances.id, id)).get();
|
|
15711
|
-
if (!existing) return null;
|
|
15712
|
-
if (existing.status === "stopped") return existing;
|
|
15713
|
-
await db.update(agentInstances).set({ status: "stopped", stoppedAt: now2 }).where(eq5(agentInstances.id, id));
|
|
15714
|
-
return { ...existing, status: "stopped", stoppedAt: now2 };
|
|
15715
|
-
}
|
|
15716
|
-
async function heartbeat(id, cwd) {
|
|
15717
|
-
const db = await getDb(cwd);
|
|
15718
|
-
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
15719
|
-
const existing = await db.select().from(agentInstances).where(eq5(agentInstances.id, id)).get();
|
|
15720
|
-
if (!existing) return null;
|
|
15721
|
-
if (existing.status === "stopped" || existing.status === "crashed") {
|
|
15722
|
-
return existing.status;
|
|
15723
|
-
}
|
|
15724
|
-
await db.update(agentInstances).set({ lastHeartbeat: now2 }).where(eq5(agentInstances.id, id));
|
|
15725
|
-
return existing.status;
|
|
15726
|
-
}
|
|
15727
|
-
async function updateAgentStatus(id, opts, cwd) {
|
|
15728
|
-
const db = await getDb(cwd);
|
|
15729
|
-
const existing = await db.select().from(agentInstances).where(eq5(agentInstances.id, id)).get();
|
|
15730
|
-
if (!existing) return null;
|
|
15731
|
-
const updates = {
|
|
15732
|
-
status: opts.status
|
|
15733
|
-
};
|
|
15734
|
-
if (opts.taskId !== void 0) {
|
|
15735
|
-
updates.taskId = opts.taskId;
|
|
15736
|
-
}
|
|
15737
|
-
if (opts.status === "active") {
|
|
15738
|
-
updates.lastHeartbeat = (/* @__PURE__ */ new Date()).toISOString();
|
|
15739
|
-
}
|
|
15740
|
-
if (opts.status === "error" || opts.status === "crashed") {
|
|
15741
|
-
updates.errorCount = existing.errorCount + 1;
|
|
15742
|
-
if (opts.error) {
|
|
15743
|
-
const errorType = classifyError(new Error(opts.error));
|
|
15744
|
-
await db.insert(agentErrorLog).values({
|
|
15745
|
-
agentId: id,
|
|
15746
|
-
errorType,
|
|
15747
|
-
message: opts.error,
|
|
15748
|
-
occurredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
15749
|
-
});
|
|
15750
|
-
}
|
|
15751
|
-
}
|
|
15752
|
-
if (opts.status === "stopped") {
|
|
15753
|
-
updates.stoppedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
15754
|
-
}
|
|
15755
|
-
await db.update(agentInstances).set(updates).where(eq5(agentInstances.id, id));
|
|
15756
|
-
return { ...existing, ...updates };
|
|
15757
|
-
}
|
|
15758
|
-
async function incrementTasksCompleted(id, cwd) {
|
|
15759
|
-
const db = await getDb(cwd);
|
|
15760
|
-
await db.update(agentInstances).set({ totalTasksCompleted: sql8`${agentInstances.totalTasksCompleted} + 1` }).where(eq5(agentInstances.id, id));
|
|
15761
|
-
}
|
|
15762
|
-
async function listAgentInstances(filters, cwd) {
|
|
15763
|
-
const db = await getDb(cwd);
|
|
15764
|
-
const conditions = [];
|
|
15765
|
-
if (filters?.status) {
|
|
15766
|
-
const statuses = Array.isArray(filters.status) ? filters.status : [filters.status];
|
|
15767
|
-
conditions.push(inArray4(agentInstances.status, statuses));
|
|
15768
|
-
}
|
|
15769
|
-
if (filters?.agentType) {
|
|
15770
|
-
const types = Array.isArray(filters.agentType) ? filters.agentType : [filters.agentType];
|
|
15771
|
-
conditions.push(inArray4(agentInstances.agentType, types));
|
|
15772
|
-
}
|
|
15773
|
-
if (filters?.sessionId) {
|
|
15774
|
-
conditions.push(eq5(agentInstances.sessionId, filters.sessionId));
|
|
15775
|
-
}
|
|
15776
|
-
if (filters?.parentAgentId) {
|
|
15777
|
-
conditions.push(eq5(agentInstances.parentAgentId, filters.parentAgentId));
|
|
15778
|
-
}
|
|
15779
|
-
if (conditions.length === 0) {
|
|
15780
|
-
return db.select().from(agentInstances).all();
|
|
15781
|
-
}
|
|
15782
|
-
return db.select().from(agentInstances).where(and3(...conditions)).all();
|
|
15783
|
-
}
|
|
15784
|
-
async function getAgentInstance(id, cwd) {
|
|
15785
|
-
const db = await getDb(cwd);
|
|
15786
|
-
const row = await db.select().from(agentInstances).where(eq5(agentInstances.id, id)).get();
|
|
15787
|
-
return row ?? null;
|
|
15788
|
-
}
|
|
15789
|
-
function classifyError(error40) {
|
|
15790
|
-
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
15791
|
-
for (const pattern of RETRIABLE_PATTERNS) {
|
|
15792
|
-
if (pattern.test(message)) return "retriable";
|
|
15793
|
-
}
|
|
15794
|
-
for (const pattern of PERMANENT_PATTERNS) {
|
|
15795
|
-
if (pattern.test(message)) return "permanent";
|
|
15796
|
-
}
|
|
15797
|
-
return "unknown";
|
|
15798
|
-
}
|
|
15799
|
-
async function getAgentErrorHistory(agentId, cwd) {
|
|
15800
|
-
const db = await getDb(cwd);
|
|
15801
|
-
return db.select().from(agentErrorLog).where(eq5(agentErrorLog.agentId, agentId)).all();
|
|
15802
|
-
}
|
|
15803
|
-
async function checkAgentHealth(thresholdMs = 3e4, cwd) {
|
|
15804
|
-
const db = await getDb(cwd);
|
|
15805
|
-
const cutoff = new Date(Date.now() - thresholdMs).toISOString();
|
|
15806
|
-
return db.select().from(agentInstances).where(
|
|
15807
|
-
and3(
|
|
15808
|
-
inArray4(agentInstances.status, ["active", "idle", "starting"]),
|
|
15809
|
-
lt2(agentInstances.lastHeartbeat, cutoff)
|
|
15810
|
-
)
|
|
15811
|
-
).all();
|
|
15812
|
-
}
|
|
15813
|
-
async function markCrashed(id, reason, cwd) {
|
|
15814
|
-
return updateAgentStatus(
|
|
15815
|
-
id,
|
|
15816
|
-
{ status: "crashed", error: reason ?? "Heartbeat timeout \u2014 agent presumed crashed" },
|
|
15817
|
-
cwd
|
|
15818
|
-
);
|
|
15819
|
-
}
|
|
15820
|
-
async function getHealthReport(thresholdMs = 3e4, cwd) {
|
|
15821
|
-
const allAgents = await listAgentInstances(void 0, cwd);
|
|
15822
|
-
const staleAgents = await checkAgentHealth(thresholdMs, cwd);
|
|
15823
|
-
const report = {
|
|
15824
|
-
total: allAgents.length,
|
|
15825
|
-
active: 0,
|
|
15826
|
-
idle: 0,
|
|
15827
|
-
starting: 0,
|
|
15828
|
-
error: 0,
|
|
15829
|
-
crashed: 0,
|
|
15830
|
-
stopped: 0,
|
|
15831
|
-
totalErrors: 0,
|
|
15832
|
-
staleAgents
|
|
15833
|
-
};
|
|
15834
|
-
for (const agent of allAgents) {
|
|
15835
|
-
switch (agent.status) {
|
|
15836
|
-
case "active":
|
|
15837
|
-
report.active++;
|
|
15838
|
-
break;
|
|
15839
|
-
case "idle":
|
|
15840
|
-
report.idle++;
|
|
15841
|
-
break;
|
|
15842
|
-
case "starting":
|
|
15843
|
-
report.starting++;
|
|
15844
|
-
break;
|
|
15845
|
-
case "error":
|
|
15846
|
-
report.error++;
|
|
15847
|
-
break;
|
|
15848
|
-
case "crashed":
|
|
15849
|
-
report.crashed++;
|
|
15850
|
-
break;
|
|
15851
|
-
case "stopped":
|
|
15852
|
-
report.stopped++;
|
|
15853
|
-
break;
|
|
15854
|
-
}
|
|
15855
|
-
report.totalErrors += agent.errorCount;
|
|
15856
|
-
}
|
|
15857
|
-
return report;
|
|
15858
|
-
}
|
|
15859
|
-
var RETRIABLE_PATTERNS, PERMANENT_PATTERNS;
|
|
15860
|
-
var init_registry2 = __esm({
|
|
15861
|
-
"packages/core/src/agents/registry.ts"() {
|
|
15862
|
-
"use strict";
|
|
15863
|
-
init_sqlite2();
|
|
15864
|
-
init_agent_schema();
|
|
15865
|
-
RETRIABLE_PATTERNS = [
|
|
15866
|
-
/timeout/i,
|
|
15867
|
-
/ECONNREFUSED/,
|
|
15868
|
-
/ECONNRESET/,
|
|
15869
|
-
/EPIPE/,
|
|
15870
|
-
/ETIMEDOUT/,
|
|
15871
|
-
/rate.?limit/i,
|
|
15872
|
-
/429/,
|
|
15873
|
-
/503/,
|
|
15874
|
-
/502/,
|
|
15875
|
-
/SQLITE_BUSY/i,
|
|
15876
|
-
/database is locked/i,
|
|
15877
|
-
/temporarily unavailable/i,
|
|
15878
|
-
/too many requests/i,
|
|
15879
|
-
/network/i,
|
|
15880
|
-
/socket hang up/i
|
|
15881
|
-
];
|
|
15882
|
-
PERMANENT_PATTERNS = [
|
|
15883
|
-
/permission denied/i,
|
|
15884
|
-
/EACCES/,
|
|
15885
|
-
/authentication/i,
|
|
15886
|
-
/unauthorized/i,
|
|
15887
|
-
/401/,
|
|
15888
|
-
/403/,
|
|
15889
|
-
/404/,
|
|
15890
|
-
/not found/i,
|
|
15891
|
-
/invalid.*token/i,
|
|
15892
|
-
/SQLITE_CONSTRAINT/i,
|
|
15893
|
-
/syntax error/i,
|
|
15894
|
-
/type error/i,
|
|
15895
|
-
/reference error/i
|
|
15896
|
-
];
|
|
15897
|
-
}
|
|
15898
|
-
});
|
|
15899
|
-
|
|
15900
|
-
// packages/core/src/agents/capacity.ts
|
|
15901
|
-
import { eq as eq6 } from "drizzle-orm";
|
|
15902
|
-
async function updateCapacity(id, capacity, cwd) {
|
|
15903
|
-
if (capacity < 0 || capacity > 1) {
|
|
15904
|
-
throw new Error(`Capacity must be between 0.0 and 1.0, got ${capacity}`);
|
|
15905
|
-
}
|
|
15906
|
-
const db = await getDb(cwd);
|
|
15907
|
-
const existing = await db.select().from(agentInstances).where(eq6(agentInstances.id, id)).get();
|
|
15908
|
-
if (!existing) return null;
|
|
15909
|
-
const capacityStr = capacity.toFixed(4);
|
|
15910
|
-
await db.update(agentInstances).set({ capacity: capacityStr }).where(eq6(agentInstances.id, id));
|
|
15911
|
-
return { ...existing, capacity: capacityStr };
|
|
15912
|
-
}
|
|
15913
|
-
async function getAvailableCapacity(cwd) {
|
|
15914
|
-
const agents = await listAgentInstances({ status: ["active", "idle"] }, cwd);
|
|
15915
|
-
return agents.reduce((sum, agent) => sum + parseCapacity(agent.capacity), 0);
|
|
15916
|
-
}
|
|
15917
|
-
async function findLeastLoadedAgent(agentType, cwd) {
|
|
15918
|
-
const filters = agentType ? { status: ["active", "idle"], agentType } : { status: ["active", "idle"] };
|
|
15919
|
-
const agents = await listAgentInstances(filters, cwd);
|
|
15920
|
-
if (agents.length === 0) return null;
|
|
15921
|
-
let best = agents[0];
|
|
15922
|
-
let bestCapacity = parseCapacity(best.capacity);
|
|
15923
|
-
for (let i = 1; i < agents.length; i++) {
|
|
15924
|
-
const cap = parseCapacity(agents[i].capacity);
|
|
15925
|
-
if (cap > bestCapacity) {
|
|
15926
|
-
best = agents[i];
|
|
15927
|
-
bestCapacity = cap;
|
|
15928
|
-
}
|
|
15929
|
-
}
|
|
15930
|
-
return best;
|
|
15931
|
-
}
|
|
15932
|
-
async function isOverloaded(threshold = 0.1, cwd) {
|
|
15933
|
-
const capacity = await getAvailableCapacity(cwd);
|
|
15934
|
-
return capacity < threshold;
|
|
15935
|
-
}
|
|
15936
|
-
async function getCapacitySummary(threshold = 0.1, cwd) {
|
|
15937
|
-
const agents = await listAgentInstances({ status: ["active", "idle"] }, cwd);
|
|
15938
|
-
const totalCapacity = agents.reduce((sum, a) => sum + parseCapacity(a.capacity), 0);
|
|
15939
|
-
const activeAgentCount = agents.length;
|
|
15940
|
-
return {
|
|
15941
|
-
totalCapacity,
|
|
15942
|
-
activeAgentCount,
|
|
15943
|
-
averageCapacity: activeAgentCount > 0 ? totalCapacity / activeAgentCount : 0,
|
|
15944
|
-
overloaded: totalCapacity < threshold,
|
|
15945
|
-
threshold
|
|
15946
|
-
};
|
|
15947
|
-
}
|
|
15948
|
-
function parseCapacity(value) {
|
|
15949
|
-
if (!value) return 0;
|
|
15950
|
-
const parsed = parseFloat(value);
|
|
15951
|
-
return Number.isNaN(parsed) ? 0 : Math.max(0, Math.min(1, parsed));
|
|
15952
|
-
}
|
|
15953
|
-
var init_capacity = __esm({
|
|
15954
|
-
"packages/core/src/agents/capacity.ts"() {
|
|
15955
|
-
"use strict";
|
|
15956
|
-
init_sqlite2();
|
|
15957
|
-
init_agent_schema();
|
|
15958
|
-
init_registry2();
|
|
15959
|
-
}
|
|
15960
|
-
});
|
|
15961
|
-
|
|
15962
15660
|
// packages/core/src/store/brain-accessor.ts
|
|
15963
|
-
import { and as
|
|
15661
|
+
import { and as and3, asc as asc2, desc as desc2, eq as eq5, gte as gte2, or as or3 } from "drizzle-orm";
|
|
15964
15662
|
async function getBrainAccessor(cwd) {
|
|
15965
15663
|
const db = await getBrainDb(cwd);
|
|
15966
15664
|
return new BrainDataAccessor(db);
|
|
@@ -15980,30 +15678,30 @@ var init_brain_accessor = __esm({
|
|
|
15980
15678
|
// =========================================================================
|
|
15981
15679
|
async addDecision(row) {
|
|
15982
15680
|
await this.db.insert(brainDecisions).values(row);
|
|
15983
|
-
const result = await this.db.select().from(brainDecisions).where(
|
|
15681
|
+
const result = await this.db.select().from(brainDecisions).where(eq5(brainDecisions.id, row.id));
|
|
15984
15682
|
return result[0];
|
|
15985
15683
|
}
|
|
15986
15684
|
async getDecision(id) {
|
|
15987
|
-
const result = await this.db.select().from(brainDecisions).where(
|
|
15685
|
+
const result = await this.db.select().from(brainDecisions).where(eq5(brainDecisions.id, id));
|
|
15988
15686
|
return result[0] ?? null;
|
|
15989
15687
|
}
|
|
15990
15688
|
async findDecisions(params = {}) {
|
|
15991
15689
|
const conditions = [];
|
|
15992
15690
|
if (params.type) {
|
|
15993
|
-
conditions.push(
|
|
15691
|
+
conditions.push(eq5(brainDecisions.type, params.type));
|
|
15994
15692
|
}
|
|
15995
15693
|
if (params.confidence) {
|
|
15996
|
-
conditions.push(
|
|
15694
|
+
conditions.push(eq5(brainDecisions.confidence, params.confidence));
|
|
15997
15695
|
}
|
|
15998
15696
|
if (params.outcome) {
|
|
15999
|
-
conditions.push(
|
|
15697
|
+
conditions.push(eq5(brainDecisions.outcome, params.outcome));
|
|
16000
15698
|
}
|
|
16001
15699
|
if (params.contextTaskId) {
|
|
16002
|
-
conditions.push(
|
|
15700
|
+
conditions.push(eq5(brainDecisions.contextTaskId, params.contextTaskId));
|
|
16003
15701
|
}
|
|
16004
15702
|
let query = this.db.select().from(brainDecisions).orderBy(desc2(brainDecisions.createdAt));
|
|
16005
15703
|
if (conditions.length > 0) {
|
|
16006
|
-
query = query.where(
|
|
15704
|
+
query = query.where(and3(...conditions));
|
|
16007
15705
|
}
|
|
16008
15706
|
if (params.limit) {
|
|
16009
15707
|
query = query.limit(params.limit);
|
|
@@ -16011,34 +15709,34 @@ var init_brain_accessor = __esm({
|
|
|
16011
15709
|
return query;
|
|
16012
15710
|
}
|
|
16013
15711
|
async updateDecision(id, updates) {
|
|
16014
|
-
await this.db.update(brainDecisions).set({ ...updates, updatedAt: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19) }).where(
|
|
15712
|
+
await this.db.update(brainDecisions).set({ ...updates, updatedAt: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19) }).where(eq5(brainDecisions.id, id));
|
|
16015
15713
|
}
|
|
16016
15714
|
// =========================================================================
|
|
16017
15715
|
// Patterns CRUD
|
|
16018
15716
|
// =========================================================================
|
|
16019
15717
|
async addPattern(row) {
|
|
16020
15718
|
await this.db.insert(brainPatterns).values(row);
|
|
16021
|
-
const result = await this.db.select().from(brainPatterns).where(
|
|
15719
|
+
const result = await this.db.select().from(brainPatterns).where(eq5(brainPatterns.id, row.id));
|
|
16022
15720
|
return result[0];
|
|
16023
15721
|
}
|
|
16024
15722
|
async getPattern(id) {
|
|
16025
|
-
const result = await this.db.select().from(brainPatterns).where(
|
|
15723
|
+
const result = await this.db.select().from(brainPatterns).where(eq5(brainPatterns.id, id));
|
|
16026
15724
|
return result[0] ?? null;
|
|
16027
15725
|
}
|
|
16028
15726
|
async findPatterns(params = {}) {
|
|
16029
15727
|
const conditions = [];
|
|
16030
15728
|
if (params.type) {
|
|
16031
|
-
conditions.push(
|
|
15729
|
+
conditions.push(eq5(brainPatterns.type, params.type));
|
|
16032
15730
|
}
|
|
16033
15731
|
if (params.impact) {
|
|
16034
|
-
conditions.push(
|
|
15732
|
+
conditions.push(eq5(brainPatterns.impact, params.impact));
|
|
16035
15733
|
}
|
|
16036
15734
|
if (params.minFrequency !== void 0) {
|
|
16037
15735
|
conditions.push(gte2(brainPatterns.frequency, params.minFrequency));
|
|
16038
15736
|
}
|
|
16039
15737
|
let query = this.db.select().from(brainPatterns).orderBy(desc2(brainPatterns.frequency));
|
|
16040
15738
|
if (conditions.length > 0) {
|
|
16041
|
-
query = query.where(
|
|
15739
|
+
query = query.where(and3(...conditions));
|
|
16042
15740
|
}
|
|
16043
15741
|
if (params.limit) {
|
|
16044
15742
|
query = query.limit(params.limit);
|
|
@@ -16046,18 +15744,18 @@ var init_brain_accessor = __esm({
|
|
|
16046
15744
|
return query;
|
|
16047
15745
|
}
|
|
16048
15746
|
async updatePattern(id, updates) {
|
|
16049
|
-
await this.db.update(brainPatterns).set({ ...updates, updatedAt: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19) }).where(
|
|
15747
|
+
await this.db.update(brainPatterns).set({ ...updates, updatedAt: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19) }).where(eq5(brainPatterns.id, id));
|
|
16050
15748
|
}
|
|
16051
15749
|
// =========================================================================
|
|
16052
15750
|
// Learnings CRUD
|
|
16053
15751
|
// =========================================================================
|
|
16054
15752
|
async addLearning(row) {
|
|
16055
15753
|
await this.db.insert(brainLearnings).values(row);
|
|
16056
|
-
const result = await this.db.select().from(brainLearnings).where(
|
|
15754
|
+
const result = await this.db.select().from(brainLearnings).where(eq5(brainLearnings.id, row.id));
|
|
16057
15755
|
return result[0];
|
|
16058
15756
|
}
|
|
16059
15757
|
async getLearning(id) {
|
|
16060
|
-
const result = await this.db.select().from(brainLearnings).where(
|
|
15758
|
+
const result = await this.db.select().from(brainLearnings).where(eq5(brainLearnings.id, id));
|
|
16061
15759
|
return result[0] ?? null;
|
|
16062
15760
|
}
|
|
16063
15761
|
async findLearnings(params = {}) {
|
|
@@ -16066,11 +15764,11 @@ var init_brain_accessor = __esm({
|
|
|
16066
15764
|
conditions.push(gte2(brainLearnings.confidence, params.minConfidence));
|
|
16067
15765
|
}
|
|
16068
15766
|
if (params.actionable !== void 0) {
|
|
16069
|
-
conditions.push(
|
|
15767
|
+
conditions.push(eq5(brainLearnings.actionable, params.actionable));
|
|
16070
15768
|
}
|
|
16071
15769
|
let query = this.db.select().from(brainLearnings).orderBy(desc2(brainLearnings.confidence));
|
|
16072
15770
|
if (conditions.length > 0) {
|
|
16073
|
-
query = query.where(
|
|
15771
|
+
query = query.where(and3(...conditions));
|
|
16074
15772
|
}
|
|
16075
15773
|
if (params.limit) {
|
|
16076
15774
|
query = query.limit(params.limit);
|
|
@@ -16078,37 +15776,37 @@ var init_brain_accessor = __esm({
|
|
|
16078
15776
|
return query;
|
|
16079
15777
|
}
|
|
16080
15778
|
async updateLearning(id, updates) {
|
|
16081
|
-
await this.db.update(brainLearnings).set({ ...updates, updatedAt: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19) }).where(
|
|
15779
|
+
await this.db.update(brainLearnings).set({ ...updates, updatedAt: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19) }).where(eq5(brainLearnings.id, id));
|
|
16082
15780
|
}
|
|
16083
15781
|
// =========================================================================
|
|
16084
15782
|
// Observations CRUD
|
|
16085
15783
|
// =========================================================================
|
|
16086
15784
|
async addObservation(row) {
|
|
16087
15785
|
await this.db.insert(brainObservations).values(row);
|
|
16088
|
-
const result = await this.db.select().from(brainObservations).where(
|
|
15786
|
+
const result = await this.db.select().from(brainObservations).where(eq5(brainObservations.id, row.id));
|
|
16089
15787
|
return result[0];
|
|
16090
15788
|
}
|
|
16091
15789
|
async getObservation(id) {
|
|
16092
|
-
const result = await this.db.select().from(brainObservations).where(
|
|
15790
|
+
const result = await this.db.select().from(brainObservations).where(eq5(brainObservations.id, id));
|
|
16093
15791
|
return result[0] ?? null;
|
|
16094
15792
|
}
|
|
16095
15793
|
async findObservations(params = {}) {
|
|
16096
15794
|
const conditions = [];
|
|
16097
15795
|
if (params.type) {
|
|
16098
|
-
conditions.push(
|
|
15796
|
+
conditions.push(eq5(brainObservations.type, params.type));
|
|
16099
15797
|
}
|
|
16100
15798
|
if (params.project) {
|
|
16101
|
-
conditions.push(
|
|
15799
|
+
conditions.push(eq5(brainObservations.project, params.project));
|
|
16102
15800
|
}
|
|
16103
15801
|
if (params.sourceType) {
|
|
16104
|
-
conditions.push(
|
|
15802
|
+
conditions.push(eq5(brainObservations.sourceType, params.sourceType));
|
|
16105
15803
|
}
|
|
16106
15804
|
if (params.sourceSessionId) {
|
|
16107
|
-
conditions.push(
|
|
15805
|
+
conditions.push(eq5(brainObservations.sourceSessionId, params.sourceSessionId));
|
|
16108
15806
|
}
|
|
16109
15807
|
let query = this.db.select().from(brainObservations).orderBy(desc2(brainObservations.createdAt));
|
|
16110
15808
|
if (conditions.length > 0) {
|
|
16111
|
-
query = query.where(
|
|
15809
|
+
query = query.where(and3(...conditions));
|
|
16112
15810
|
}
|
|
16113
15811
|
if (params.limit) {
|
|
16114
15812
|
query = query.limit(params.limit);
|
|
@@ -16116,7 +15814,7 @@ var init_brain_accessor = __esm({
|
|
|
16116
15814
|
return query;
|
|
16117
15815
|
}
|
|
16118
15816
|
async updateObservation(id, updates) {
|
|
16119
|
-
await this.db.update(brainObservations).set({ ...updates, updatedAt: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19) }).where(
|
|
15817
|
+
await this.db.update(brainObservations).set({ ...updates, updatedAt: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19) }).where(eq5(brainObservations.id, id));
|
|
16120
15818
|
}
|
|
16121
15819
|
// =========================================================================
|
|
16122
15820
|
// Memory Links CRUD
|
|
@@ -16126,22 +15824,22 @@ var init_brain_accessor = __esm({
|
|
|
16126
15824
|
}
|
|
16127
15825
|
async getLinksForMemory(memoryType, memoryId) {
|
|
16128
15826
|
return this.db.select().from(brainMemoryLinks).where(
|
|
16129
|
-
|
|
16130
|
-
|
|
16131
|
-
|
|
15827
|
+
and3(
|
|
15828
|
+
eq5(brainMemoryLinks.memoryType, memoryType),
|
|
15829
|
+
eq5(brainMemoryLinks.memoryId, memoryId)
|
|
16132
15830
|
)
|
|
16133
15831
|
).orderBy(asc2(brainMemoryLinks.createdAt));
|
|
16134
15832
|
}
|
|
16135
15833
|
async getLinksForTask(taskId) {
|
|
16136
|
-
return this.db.select().from(brainMemoryLinks).where(
|
|
15834
|
+
return this.db.select().from(brainMemoryLinks).where(eq5(brainMemoryLinks.taskId, taskId)).orderBy(asc2(brainMemoryLinks.createdAt));
|
|
16137
15835
|
}
|
|
16138
15836
|
async removeLink(memoryType, memoryId, taskId, linkType) {
|
|
16139
15837
|
await this.db.delete(brainMemoryLinks).where(
|
|
16140
|
-
|
|
16141
|
-
|
|
16142
|
-
|
|
16143
|
-
|
|
16144
|
-
|
|
15838
|
+
and3(
|
|
15839
|
+
eq5(brainMemoryLinks.memoryType, memoryType),
|
|
15840
|
+
eq5(brainMemoryLinks.memoryId, memoryId),
|
|
15841
|
+
eq5(brainMemoryLinks.taskId, taskId),
|
|
15842
|
+
eq5(brainMemoryLinks.linkType, linkType)
|
|
16145
15843
|
)
|
|
16146
15844
|
);
|
|
16147
15845
|
}
|
|
@@ -16150,27 +15848,27 @@ var init_brain_accessor = __esm({
|
|
|
16150
15848
|
// =========================================================================
|
|
16151
15849
|
async addStickyNote(row) {
|
|
16152
15850
|
await this.db.insert(brainStickyNotes).values(row);
|
|
16153
|
-
const result = await this.db.select().from(brainStickyNotes).where(
|
|
15851
|
+
const result = await this.db.select().from(brainStickyNotes).where(eq5(brainStickyNotes.id, row.id));
|
|
16154
15852
|
return result[0];
|
|
16155
15853
|
}
|
|
16156
15854
|
async getStickyNote(id) {
|
|
16157
|
-
const result = await this.db.select().from(brainStickyNotes).where(
|
|
15855
|
+
const result = await this.db.select().from(brainStickyNotes).where(eq5(brainStickyNotes.id, id));
|
|
16158
15856
|
return result[0] ?? null;
|
|
16159
15857
|
}
|
|
16160
15858
|
async findStickyNotes(params = {}) {
|
|
16161
15859
|
const conditions = [];
|
|
16162
15860
|
if (params.status) {
|
|
16163
|
-
conditions.push(
|
|
15861
|
+
conditions.push(eq5(brainStickyNotes.status, params.status));
|
|
16164
15862
|
}
|
|
16165
15863
|
if (params.color) {
|
|
16166
|
-
conditions.push(
|
|
15864
|
+
conditions.push(eq5(brainStickyNotes.color, params.color));
|
|
16167
15865
|
}
|
|
16168
15866
|
if (params.priority) {
|
|
16169
|
-
conditions.push(
|
|
15867
|
+
conditions.push(eq5(brainStickyNotes.priority, params.priority));
|
|
16170
15868
|
}
|
|
16171
15869
|
let query = this.db.select().from(brainStickyNotes).orderBy(desc2(brainStickyNotes.createdAt));
|
|
16172
15870
|
if (conditions.length > 0) {
|
|
16173
|
-
query = query.where(
|
|
15871
|
+
query = query.where(and3(...conditions));
|
|
16174
15872
|
}
|
|
16175
15873
|
if (params.limit) {
|
|
16176
15874
|
query = query.limit(params.limit);
|
|
@@ -16178,31 +15876,31 @@ var init_brain_accessor = __esm({
|
|
|
16178
15876
|
return query;
|
|
16179
15877
|
}
|
|
16180
15878
|
async updateStickyNote(id, updates) {
|
|
16181
|
-
await this.db.update(brainStickyNotes).set({ ...updates, updatedAt: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19) }).where(
|
|
15879
|
+
await this.db.update(brainStickyNotes).set({ ...updates, updatedAt: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19) }).where(eq5(brainStickyNotes.id, id));
|
|
16182
15880
|
}
|
|
16183
15881
|
async deleteStickyNote(id) {
|
|
16184
|
-
await this.db.delete(brainStickyNotes).where(
|
|
15882
|
+
await this.db.delete(brainStickyNotes).where(eq5(brainStickyNotes.id, id));
|
|
16185
15883
|
}
|
|
16186
15884
|
// =========================================================================
|
|
16187
15885
|
// PageIndex Node CRUD (T5383)
|
|
16188
15886
|
// =========================================================================
|
|
16189
15887
|
async addPageNode(node) {
|
|
16190
15888
|
await this.db.insert(brainPageNodes).values(node);
|
|
16191
|
-
const result = await this.db.select().from(brainPageNodes).where(
|
|
15889
|
+
const result = await this.db.select().from(brainPageNodes).where(eq5(brainPageNodes.id, node.id));
|
|
16192
15890
|
return result[0];
|
|
16193
15891
|
}
|
|
16194
15892
|
async getPageNode(id) {
|
|
16195
|
-
const result = await this.db.select().from(brainPageNodes).where(
|
|
15893
|
+
const result = await this.db.select().from(brainPageNodes).where(eq5(brainPageNodes.id, id));
|
|
16196
15894
|
return result[0] ?? null;
|
|
16197
15895
|
}
|
|
16198
15896
|
async findPageNodes(params = {}) {
|
|
16199
15897
|
const conditions = [];
|
|
16200
15898
|
if (params.nodeType) {
|
|
16201
|
-
conditions.push(
|
|
15899
|
+
conditions.push(eq5(brainPageNodes.nodeType, params.nodeType));
|
|
16202
15900
|
}
|
|
16203
15901
|
let query = this.db.select().from(brainPageNodes).orderBy(desc2(brainPageNodes.createdAt));
|
|
16204
15902
|
if (conditions.length > 0) {
|
|
16205
|
-
query = query.where(
|
|
15903
|
+
query = query.where(and3(...conditions));
|
|
16206
15904
|
}
|
|
16207
15905
|
if (params.limit) {
|
|
16208
15906
|
query = query.limit(params.limit);
|
|
@@ -16211,9 +15909,9 @@ var init_brain_accessor = __esm({
|
|
|
16211
15909
|
}
|
|
16212
15910
|
async removePageNode(id) {
|
|
16213
15911
|
await this.db.delete(brainPageEdges).where(
|
|
16214
|
-
or3(
|
|
15912
|
+
or3(eq5(brainPageEdges.fromId, id), eq5(brainPageEdges.toId, id))
|
|
16215
15913
|
);
|
|
16216
|
-
await this.db.delete(brainPageNodes).where(
|
|
15914
|
+
await this.db.delete(brainPageNodes).where(eq5(brainPageNodes.id, id));
|
|
16217
15915
|
}
|
|
16218
15916
|
// =========================================================================
|
|
16219
15917
|
// PageIndex Edge CRUD (T5383)
|
|
@@ -16221,34 +15919,34 @@ var init_brain_accessor = __esm({
|
|
|
16221
15919
|
async addPageEdge(edge) {
|
|
16222
15920
|
await this.db.insert(brainPageEdges).values(edge);
|
|
16223
15921
|
const result = await this.db.select().from(brainPageEdges).where(
|
|
16224
|
-
|
|
16225
|
-
|
|
16226
|
-
|
|
16227
|
-
|
|
15922
|
+
and3(
|
|
15923
|
+
eq5(brainPageEdges.fromId, edge.fromId),
|
|
15924
|
+
eq5(brainPageEdges.toId, edge.toId),
|
|
15925
|
+
eq5(brainPageEdges.edgeType, edge.edgeType)
|
|
16228
15926
|
)
|
|
16229
15927
|
);
|
|
16230
15928
|
return result[0];
|
|
16231
15929
|
}
|
|
16232
15930
|
async getPageEdges(nodeId, direction = "both") {
|
|
16233
15931
|
if (direction === "out") {
|
|
16234
|
-
return this.db.select().from(brainPageEdges).where(
|
|
15932
|
+
return this.db.select().from(brainPageEdges).where(eq5(brainPageEdges.fromId, nodeId)).orderBy(asc2(brainPageEdges.createdAt));
|
|
16235
15933
|
}
|
|
16236
15934
|
if (direction === "in") {
|
|
16237
|
-
return this.db.select().from(brainPageEdges).where(
|
|
15935
|
+
return this.db.select().from(brainPageEdges).where(eq5(brainPageEdges.toId, nodeId)).orderBy(asc2(brainPageEdges.createdAt));
|
|
16238
15936
|
}
|
|
16239
15937
|
return this.db.select().from(brainPageEdges).where(
|
|
16240
15938
|
or3(
|
|
16241
|
-
|
|
16242
|
-
|
|
15939
|
+
eq5(brainPageEdges.fromId, nodeId),
|
|
15940
|
+
eq5(brainPageEdges.toId, nodeId)
|
|
16243
15941
|
)
|
|
16244
15942
|
).orderBy(asc2(brainPageEdges.createdAt));
|
|
16245
15943
|
}
|
|
16246
15944
|
async getNeighbors(nodeId, edgeType) {
|
|
16247
|
-
const conditions = [
|
|
15945
|
+
const conditions = [eq5(brainPageEdges.fromId, nodeId)];
|
|
16248
15946
|
if (edgeType) {
|
|
16249
|
-
conditions.push(
|
|
15947
|
+
conditions.push(eq5(brainPageEdges.edgeType, edgeType));
|
|
16250
15948
|
}
|
|
16251
|
-
const edges = await this.db.select().from(brainPageEdges).where(
|
|
15949
|
+
const edges = await this.db.select().from(brainPageEdges).where(and3(...conditions));
|
|
16252
15950
|
if (edges.length === 0) return [];
|
|
16253
15951
|
const neighborIds = edges.map((e) => e.toId);
|
|
16254
15952
|
const nodes = [];
|
|
@@ -16260,10 +15958,10 @@ var init_brain_accessor = __esm({
|
|
|
16260
15958
|
}
|
|
16261
15959
|
async removePageEdge(fromId, toId, edgeType) {
|
|
16262
15960
|
await this.db.delete(brainPageEdges).where(
|
|
16263
|
-
|
|
16264
|
-
|
|
16265
|
-
|
|
16266
|
-
|
|
15961
|
+
and3(
|
|
15962
|
+
eq5(brainPageEdges.fromId, fromId),
|
|
15963
|
+
eq5(brainPageEdges.toId, toId),
|
|
15964
|
+
eq5(brainPageEdges.edgeType, edgeType)
|
|
16267
15965
|
)
|
|
16268
15966
|
);
|
|
16269
15967
|
}
|
|
@@ -16272,15 +15970,15 @@ var init_brain_accessor = __esm({
|
|
|
16272
15970
|
});
|
|
16273
15971
|
|
|
16274
15972
|
// packages/core/src/agents/execution-learning.ts
|
|
16275
|
-
import { randomBytes
|
|
15973
|
+
import { randomBytes } from "node:crypto";
|
|
16276
15974
|
function generateDecisionId() {
|
|
16277
|
-
return `AGT-${
|
|
15975
|
+
return `AGT-${randomBytes(5).toString("hex")}`;
|
|
16278
15976
|
}
|
|
16279
15977
|
function generatePatternId() {
|
|
16280
|
-
return `P-agt-${
|
|
15978
|
+
return `P-agt-${randomBytes(4).toString("hex")}`;
|
|
16281
15979
|
}
|
|
16282
15980
|
function generateObservationId() {
|
|
16283
|
-
return `O-agt-${
|
|
15981
|
+
return `O-agt-${randomBytes(4).toString("hex")}`;
|
|
16284
15982
|
}
|
|
16285
15983
|
function nowSql() {
|
|
16286
15984
|
return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
@@ -16563,6 +16261,473 @@ var init_execution_learning = __esm({
|
|
|
16563
16261
|
}
|
|
16564
16262
|
});
|
|
16565
16263
|
|
|
16264
|
+
// packages/core/src/agents/registry.ts
|
|
16265
|
+
var registry_exports2 = {};
|
|
16266
|
+
__export(registry_exports2, {
|
|
16267
|
+
checkAgentHealth: () => checkAgentHealth,
|
|
16268
|
+
classifyError: () => classifyError,
|
|
16269
|
+
deregisterAgent: () => deregisterAgent,
|
|
16270
|
+
generateAgentId: () => generateAgentId,
|
|
16271
|
+
getAgentErrorHistory: () => getAgentErrorHistory,
|
|
16272
|
+
getAgentInstance: () => getAgentInstance,
|
|
16273
|
+
getHealthReport: () => getHealthReport,
|
|
16274
|
+
heartbeat: () => heartbeat,
|
|
16275
|
+
incrementTasksCompleted: () => incrementTasksCompleted,
|
|
16276
|
+
listAgentInstances: () => listAgentInstances,
|
|
16277
|
+
markCrashed: () => markCrashed,
|
|
16278
|
+
registerAgent: () => registerAgent,
|
|
16279
|
+
updateAgentStatus: () => updateAgentStatus
|
|
16280
|
+
});
|
|
16281
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
16282
|
+
import { and as and4, eq as eq6, inArray as inArray4, lt as lt2, sql as sql8 } from "drizzle-orm";
|
|
16283
|
+
function generateAgentId() {
|
|
16284
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
16285
|
+
const ts = now2.toISOString().replace(/[-:T]/g, "").substring(0, 14);
|
|
16286
|
+
const hex = randomBytes2(3).toString("hex");
|
|
16287
|
+
return `agt_${ts}_${hex}`;
|
|
16288
|
+
}
|
|
16289
|
+
async function registerAgent(opts, cwd) {
|
|
16290
|
+
const db = await getDb(cwd);
|
|
16291
|
+
const id = generateAgentId();
|
|
16292
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
16293
|
+
const row = {
|
|
16294
|
+
id,
|
|
16295
|
+
agentType: opts.agentType,
|
|
16296
|
+
status: "starting",
|
|
16297
|
+
sessionId: opts.sessionId ?? null,
|
|
16298
|
+
taskId: opts.taskId ?? null,
|
|
16299
|
+
startedAt: now2,
|
|
16300
|
+
lastHeartbeat: now2,
|
|
16301
|
+
stoppedAt: null,
|
|
16302
|
+
errorCount: 0,
|
|
16303
|
+
totalTasksCompleted: 0,
|
|
16304
|
+
capacity: "1.0",
|
|
16305
|
+
metadataJson: opts.metadata ? JSON.stringify(opts.metadata) : "{}",
|
|
16306
|
+
parentAgentId: opts.parentAgentId ?? null
|
|
16307
|
+
};
|
|
16308
|
+
await db.insert(agentInstances).values(row);
|
|
16309
|
+
return row;
|
|
16310
|
+
}
|
|
16311
|
+
async function deregisterAgent(id, cwd) {
|
|
16312
|
+
const db = await getDb(cwd);
|
|
16313
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
16314
|
+
const existing = await db.select().from(agentInstances).where(eq6(agentInstances.id, id)).get();
|
|
16315
|
+
if (!existing) return null;
|
|
16316
|
+
if (existing.status === "stopped") return existing;
|
|
16317
|
+
await db.update(agentInstances).set({ status: "stopped", stoppedAt: now2 }).where(eq6(agentInstances.id, id));
|
|
16318
|
+
return { ...existing, status: "stopped", stoppedAt: now2 };
|
|
16319
|
+
}
|
|
16320
|
+
async function heartbeat(id, cwd) {
|
|
16321
|
+
const db = await getDb(cwd);
|
|
16322
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
16323
|
+
const existing = await db.select().from(agentInstances).where(eq6(agentInstances.id, id)).get();
|
|
16324
|
+
if (!existing) return null;
|
|
16325
|
+
if (existing.status === "stopped" || existing.status === "crashed") {
|
|
16326
|
+
return existing.status;
|
|
16327
|
+
}
|
|
16328
|
+
await db.update(agentInstances).set({ lastHeartbeat: now2 }).where(eq6(agentInstances.id, id));
|
|
16329
|
+
return existing.status;
|
|
16330
|
+
}
|
|
16331
|
+
async function updateAgentStatus(id, opts, cwd) {
|
|
16332
|
+
const db = await getDb(cwd);
|
|
16333
|
+
const existing = await db.select().from(agentInstances).where(eq6(agentInstances.id, id)).get();
|
|
16334
|
+
if (!existing) return null;
|
|
16335
|
+
const updates = {
|
|
16336
|
+
status: opts.status
|
|
16337
|
+
};
|
|
16338
|
+
if (opts.taskId !== void 0) {
|
|
16339
|
+
updates.taskId = opts.taskId;
|
|
16340
|
+
}
|
|
16341
|
+
if (opts.status === "active") {
|
|
16342
|
+
updates.lastHeartbeat = (/* @__PURE__ */ new Date()).toISOString();
|
|
16343
|
+
}
|
|
16344
|
+
if (opts.status === "error" || opts.status === "crashed") {
|
|
16345
|
+
updates.errorCount = existing.errorCount + 1;
|
|
16346
|
+
if (opts.error) {
|
|
16347
|
+
const errorType = classifyError(new Error(opts.error));
|
|
16348
|
+
await db.insert(agentErrorLog).values({
|
|
16349
|
+
agentId: id,
|
|
16350
|
+
errorType,
|
|
16351
|
+
message: opts.error,
|
|
16352
|
+
occurredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
16353
|
+
});
|
|
16354
|
+
}
|
|
16355
|
+
}
|
|
16356
|
+
if (opts.status === "stopped") {
|
|
16357
|
+
updates.stoppedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
16358
|
+
}
|
|
16359
|
+
await db.update(agentInstances).set(updates).where(eq6(agentInstances.id, id));
|
|
16360
|
+
return { ...existing, ...updates };
|
|
16361
|
+
}
|
|
16362
|
+
async function incrementTasksCompleted(id, cwd) {
|
|
16363
|
+
const db = await getDb(cwd);
|
|
16364
|
+
await db.update(agentInstances).set({ totalTasksCompleted: sql8`${agentInstances.totalTasksCompleted} + 1` }).where(eq6(agentInstances.id, id));
|
|
16365
|
+
}
|
|
16366
|
+
async function listAgentInstances(filters, cwd) {
|
|
16367
|
+
const db = await getDb(cwd);
|
|
16368
|
+
const conditions = [];
|
|
16369
|
+
if (filters?.status) {
|
|
16370
|
+
const statuses = Array.isArray(filters.status) ? filters.status : [filters.status];
|
|
16371
|
+
conditions.push(inArray4(agentInstances.status, statuses));
|
|
16372
|
+
}
|
|
16373
|
+
if (filters?.agentType) {
|
|
16374
|
+
const types = Array.isArray(filters.agentType) ? filters.agentType : [filters.agentType];
|
|
16375
|
+
conditions.push(inArray4(agentInstances.agentType, types));
|
|
16376
|
+
}
|
|
16377
|
+
if (filters?.sessionId) {
|
|
16378
|
+
conditions.push(eq6(agentInstances.sessionId, filters.sessionId));
|
|
16379
|
+
}
|
|
16380
|
+
if (filters?.parentAgentId) {
|
|
16381
|
+
conditions.push(eq6(agentInstances.parentAgentId, filters.parentAgentId));
|
|
16382
|
+
}
|
|
16383
|
+
if (conditions.length === 0) {
|
|
16384
|
+
return db.select().from(agentInstances).all();
|
|
16385
|
+
}
|
|
16386
|
+
return db.select().from(agentInstances).where(and4(...conditions)).all();
|
|
16387
|
+
}
|
|
16388
|
+
async function getAgentInstance(id, cwd) {
|
|
16389
|
+
const db = await getDb(cwd);
|
|
16390
|
+
const row = await db.select().from(agentInstances).where(eq6(agentInstances.id, id)).get();
|
|
16391
|
+
return row ?? null;
|
|
16392
|
+
}
|
|
16393
|
+
function classifyError(error40) {
|
|
16394
|
+
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
16395
|
+
for (const pattern of RETRIABLE_PATTERNS) {
|
|
16396
|
+
if (pattern.test(message)) return "retriable";
|
|
16397
|
+
}
|
|
16398
|
+
for (const pattern of PERMANENT_PATTERNS) {
|
|
16399
|
+
if (pattern.test(message)) return "permanent";
|
|
16400
|
+
}
|
|
16401
|
+
return "unknown";
|
|
16402
|
+
}
|
|
16403
|
+
async function getAgentErrorHistory(agentId, cwd) {
|
|
16404
|
+
const db = await getDb(cwd);
|
|
16405
|
+
return db.select().from(agentErrorLog).where(eq6(agentErrorLog.agentId, agentId)).all();
|
|
16406
|
+
}
|
|
16407
|
+
async function checkAgentHealth(thresholdMs = 3e4, cwd) {
|
|
16408
|
+
const db = await getDb(cwd);
|
|
16409
|
+
const cutoff = new Date(Date.now() - thresholdMs).toISOString();
|
|
16410
|
+
return db.select().from(agentInstances).where(
|
|
16411
|
+
and4(
|
|
16412
|
+
inArray4(agentInstances.status, ["active", "idle", "starting"]),
|
|
16413
|
+
lt2(agentInstances.lastHeartbeat, cutoff)
|
|
16414
|
+
)
|
|
16415
|
+
).all();
|
|
16416
|
+
}
|
|
16417
|
+
async function markCrashed(id, reason, cwd) {
|
|
16418
|
+
return updateAgentStatus(
|
|
16419
|
+
id,
|
|
16420
|
+
{ status: "crashed", error: reason ?? "Heartbeat timeout \u2014 agent presumed crashed" },
|
|
16421
|
+
cwd
|
|
16422
|
+
);
|
|
16423
|
+
}
|
|
16424
|
+
async function getHealthReport(thresholdMs = 3e4, cwd) {
|
|
16425
|
+
const allAgents = await listAgentInstances(void 0, cwd);
|
|
16426
|
+
const staleAgents = await checkAgentHealth(thresholdMs, cwd);
|
|
16427
|
+
const report = {
|
|
16428
|
+
total: allAgents.length,
|
|
16429
|
+
active: 0,
|
|
16430
|
+
idle: 0,
|
|
16431
|
+
starting: 0,
|
|
16432
|
+
error: 0,
|
|
16433
|
+
crashed: 0,
|
|
16434
|
+
stopped: 0,
|
|
16435
|
+
totalErrors: 0,
|
|
16436
|
+
staleAgents
|
|
16437
|
+
};
|
|
16438
|
+
for (const agent of allAgents) {
|
|
16439
|
+
switch (agent.status) {
|
|
16440
|
+
case "active":
|
|
16441
|
+
report.active++;
|
|
16442
|
+
break;
|
|
16443
|
+
case "idle":
|
|
16444
|
+
report.idle++;
|
|
16445
|
+
break;
|
|
16446
|
+
case "starting":
|
|
16447
|
+
report.starting++;
|
|
16448
|
+
break;
|
|
16449
|
+
case "error":
|
|
16450
|
+
report.error++;
|
|
16451
|
+
break;
|
|
16452
|
+
case "crashed":
|
|
16453
|
+
report.crashed++;
|
|
16454
|
+
break;
|
|
16455
|
+
case "stopped":
|
|
16456
|
+
report.stopped++;
|
|
16457
|
+
break;
|
|
16458
|
+
}
|
|
16459
|
+
report.totalErrors += agent.errorCount;
|
|
16460
|
+
}
|
|
16461
|
+
return report;
|
|
16462
|
+
}
|
|
16463
|
+
var RETRIABLE_PATTERNS, PERMANENT_PATTERNS;
|
|
16464
|
+
var init_registry2 = __esm({
|
|
16465
|
+
"packages/core/src/agents/registry.ts"() {
|
|
16466
|
+
"use strict";
|
|
16467
|
+
init_sqlite2();
|
|
16468
|
+
init_agent_schema();
|
|
16469
|
+
RETRIABLE_PATTERNS = [
|
|
16470
|
+
/timeout/i,
|
|
16471
|
+
/ECONNREFUSED/,
|
|
16472
|
+
/ECONNRESET/,
|
|
16473
|
+
/EPIPE/,
|
|
16474
|
+
/ETIMEDOUT/,
|
|
16475
|
+
/rate.?limit/i,
|
|
16476
|
+
/429/,
|
|
16477
|
+
/503/,
|
|
16478
|
+
/502/,
|
|
16479
|
+
/SQLITE_BUSY/i,
|
|
16480
|
+
/database is locked/i,
|
|
16481
|
+
/temporarily unavailable/i,
|
|
16482
|
+
/too many requests/i,
|
|
16483
|
+
/network/i,
|
|
16484
|
+
/socket hang up/i
|
|
16485
|
+
];
|
|
16486
|
+
PERMANENT_PATTERNS = [
|
|
16487
|
+
/permission denied/i,
|
|
16488
|
+
/EACCES/,
|
|
16489
|
+
/authentication/i,
|
|
16490
|
+
/unauthorized/i,
|
|
16491
|
+
/401/,
|
|
16492
|
+
/403/,
|
|
16493
|
+
/404/,
|
|
16494
|
+
/not found/i,
|
|
16495
|
+
/invalid.*token/i,
|
|
16496
|
+
/SQLITE_CONSTRAINT/i,
|
|
16497
|
+
/syntax error/i,
|
|
16498
|
+
/type error/i,
|
|
16499
|
+
/reference error/i
|
|
16500
|
+
];
|
|
16501
|
+
}
|
|
16502
|
+
});
|
|
16503
|
+
|
|
16504
|
+
// packages/core/src/agents/agent-registry.ts
|
|
16505
|
+
import { and as and5, eq as eq7, inArray as inArray5 } from "drizzle-orm";
|
|
16506
|
+
async function getAgentCapacity(agentId, cwd) {
|
|
16507
|
+
const db = await getDb(cwd);
|
|
16508
|
+
const agent = await db.select().from(agentInstances).where(eq7(agentInstances.id, agentId)).get();
|
|
16509
|
+
if (!agent) return null;
|
|
16510
|
+
const isTerminal = agent.status === "stopped" || agent.status === "crashed";
|
|
16511
|
+
if (isTerminal) {
|
|
16512
|
+
return {
|
|
16513
|
+
agentId: agent.id,
|
|
16514
|
+
agentType: agent.agentType,
|
|
16515
|
+
status: agent.status,
|
|
16516
|
+
activeTasks: 0,
|
|
16517
|
+
remainingCapacity: 0,
|
|
16518
|
+
maxCapacity: MAX_TASKS_PER_AGENT,
|
|
16519
|
+
available: false
|
|
16520
|
+
};
|
|
16521
|
+
}
|
|
16522
|
+
const children = await db.select({ id: agentInstances.id }).from(agentInstances).where(
|
|
16523
|
+
and5(
|
|
16524
|
+
eq7(agentInstances.parentAgentId, agentId),
|
|
16525
|
+
inArray5(agentInstances.status, ["starting", "active", "idle", "error"])
|
|
16526
|
+
)
|
|
16527
|
+
).all();
|
|
16528
|
+
const selfTask = agent.taskId != null ? 1 : 0;
|
|
16529
|
+
const activeTasks = selfTask + children.length;
|
|
16530
|
+
const remainingCapacity = Math.max(0, MAX_TASKS_PER_AGENT - activeTasks);
|
|
16531
|
+
return {
|
|
16532
|
+
agentId: agent.id,
|
|
16533
|
+
agentType: agent.agentType,
|
|
16534
|
+
status: agent.status,
|
|
16535
|
+
activeTasks,
|
|
16536
|
+
remainingCapacity,
|
|
16537
|
+
maxCapacity: MAX_TASKS_PER_AGENT,
|
|
16538
|
+
available: remainingCapacity > 0
|
|
16539
|
+
};
|
|
16540
|
+
}
|
|
16541
|
+
async function getAgentsByCapacity(agentType, cwd) {
|
|
16542
|
+
const filters = agentType ? { status: ["active", "idle"], agentType } : { status: ["active", "idle"] };
|
|
16543
|
+
const activeAgents = await listAgentInstances(filters, cwd);
|
|
16544
|
+
const capacities = await Promise.all(
|
|
16545
|
+
activeAgents.map((agent) => getAgentCapacity(agent.id, cwd))
|
|
16546
|
+
);
|
|
16547
|
+
return capacities.filter((c) => c !== null).sort((a, b) => b.remainingCapacity - a.remainingCapacity);
|
|
16548
|
+
}
|
|
16549
|
+
async function getAgentSpecializations(agentId, cwd) {
|
|
16550
|
+
const db = await getDb(cwd);
|
|
16551
|
+
const agent = await db.select({ metadataJson: agentInstances.metadataJson }).from(agentInstances).where(eq7(agentInstances.id, agentId)).get();
|
|
16552
|
+
if (!agent) return [];
|
|
16553
|
+
try {
|
|
16554
|
+
const meta = JSON.parse(agent.metadataJson ?? "{}");
|
|
16555
|
+
const specs = meta.specializations;
|
|
16556
|
+
if (!Array.isArray(specs)) return [];
|
|
16557
|
+
return specs.filter((s) => typeof s === "string");
|
|
16558
|
+
} catch {
|
|
16559
|
+
return [];
|
|
16560
|
+
}
|
|
16561
|
+
}
|
|
16562
|
+
async function updateAgentSpecializations(agentId, specializations, cwd) {
|
|
16563
|
+
const db = await getDb(cwd);
|
|
16564
|
+
const agent = await db.select({ metadataJson: agentInstances.metadataJson }).from(agentInstances).where(eq7(agentInstances.id, agentId)).get();
|
|
16565
|
+
if (!agent) return null;
|
|
16566
|
+
let existing = {};
|
|
16567
|
+
try {
|
|
16568
|
+
existing = JSON.parse(agent.metadataJson ?? "{}");
|
|
16569
|
+
} catch {
|
|
16570
|
+
}
|
|
16571
|
+
const updated = { ...existing, specializations };
|
|
16572
|
+
await db.update(agentInstances).set({ metadataJson: JSON.stringify(updated) }).where(eq7(agentInstances.id, agentId));
|
|
16573
|
+
return specializations;
|
|
16574
|
+
}
|
|
16575
|
+
async function recordAgentPerformance(agentId, metrics, cwd) {
|
|
16576
|
+
const db = await getDb(cwd);
|
|
16577
|
+
const agent = await db.select({ agentType: agentInstances.agentType, sessionId: agentInstances.sessionId }).from(agentInstances).where(eq7(agentInstances.id, agentId)).get();
|
|
16578
|
+
if (!agent) return null;
|
|
16579
|
+
const event = {
|
|
16580
|
+
agentId,
|
|
16581
|
+
agentType: agent.agentType,
|
|
16582
|
+
taskId: metrics.taskId,
|
|
16583
|
+
taskType: metrics.taskType,
|
|
16584
|
+
outcome: metrics.outcome,
|
|
16585
|
+
taskLabels: metrics.taskLabels,
|
|
16586
|
+
sessionId: metrics.sessionId ?? agent.sessionId ?? void 0,
|
|
16587
|
+
durationMs: metrics.durationMs,
|
|
16588
|
+
errorMessage: metrics.errorMessage,
|
|
16589
|
+
errorType: metrics.errorType
|
|
16590
|
+
};
|
|
16591
|
+
const decision = await recordAgentExecution(event, cwd);
|
|
16592
|
+
return decision?.id ?? null;
|
|
16593
|
+
}
|
|
16594
|
+
var MAX_TASKS_PER_AGENT;
|
|
16595
|
+
var init_agent_registry = __esm({
|
|
16596
|
+
"packages/core/src/agents/agent-registry.ts"() {
|
|
16597
|
+
"use strict";
|
|
16598
|
+
init_sqlite2();
|
|
16599
|
+
init_agent_schema();
|
|
16600
|
+
init_execution_learning();
|
|
16601
|
+
init_registry2();
|
|
16602
|
+
MAX_TASKS_PER_AGENT = 5;
|
|
16603
|
+
}
|
|
16604
|
+
});
|
|
16605
|
+
|
|
16606
|
+
// packages/core/src/agents/capacity.ts
|
|
16607
|
+
import { eq as eq8 } from "drizzle-orm";
|
|
16608
|
+
async function updateCapacity(id, capacity, cwd) {
|
|
16609
|
+
if (capacity < 0 || capacity > 1) {
|
|
16610
|
+
throw new Error(`Capacity must be between 0.0 and 1.0, got ${capacity}`);
|
|
16611
|
+
}
|
|
16612
|
+
const db = await getDb(cwd);
|
|
16613
|
+
const existing = await db.select().from(agentInstances).where(eq8(agentInstances.id, id)).get();
|
|
16614
|
+
if (!existing) return null;
|
|
16615
|
+
const capacityStr = capacity.toFixed(4);
|
|
16616
|
+
await db.update(agentInstances).set({ capacity: capacityStr }).where(eq8(agentInstances.id, id));
|
|
16617
|
+
return { ...existing, capacity: capacityStr };
|
|
16618
|
+
}
|
|
16619
|
+
async function getAvailableCapacity(cwd) {
|
|
16620
|
+
const agents = await listAgentInstances({ status: ["active", "idle"] }, cwd);
|
|
16621
|
+
return agents.reduce((sum, agent) => sum + parseCapacity(agent.capacity), 0);
|
|
16622
|
+
}
|
|
16623
|
+
async function findLeastLoadedAgent(agentType, cwd) {
|
|
16624
|
+
const filters = agentType ? { status: ["active", "idle"], agentType } : { status: ["active", "idle"] };
|
|
16625
|
+
const agents = await listAgentInstances(filters, cwd);
|
|
16626
|
+
if (agents.length === 0) return null;
|
|
16627
|
+
let best = agents[0];
|
|
16628
|
+
let bestCapacity = parseCapacity(best.capacity);
|
|
16629
|
+
for (let i = 1; i < agents.length; i++) {
|
|
16630
|
+
const cap = parseCapacity(agents[i].capacity);
|
|
16631
|
+
if (cap > bestCapacity) {
|
|
16632
|
+
best = agents[i];
|
|
16633
|
+
bestCapacity = cap;
|
|
16634
|
+
}
|
|
16635
|
+
}
|
|
16636
|
+
return best;
|
|
16637
|
+
}
|
|
16638
|
+
async function isOverloaded(threshold = 0.1, cwd) {
|
|
16639
|
+
const capacity = await getAvailableCapacity(cwd);
|
|
16640
|
+
return capacity < threshold;
|
|
16641
|
+
}
|
|
16642
|
+
async function getCapacitySummary(threshold = 0.1, cwd) {
|
|
16643
|
+
const agents = await listAgentInstances({ status: ["active", "idle"] }, cwd);
|
|
16644
|
+
const totalCapacity = agents.reduce((sum, a) => sum + parseCapacity(a.capacity), 0);
|
|
16645
|
+
const activeAgentCount = agents.length;
|
|
16646
|
+
return {
|
|
16647
|
+
totalCapacity,
|
|
16648
|
+
activeAgentCount,
|
|
16649
|
+
averageCapacity: activeAgentCount > 0 ? totalCapacity / activeAgentCount : 0,
|
|
16650
|
+
overloaded: totalCapacity < threshold,
|
|
16651
|
+
threshold
|
|
16652
|
+
};
|
|
16653
|
+
}
|
|
16654
|
+
function parseCapacity(value) {
|
|
16655
|
+
if (!value) return 0;
|
|
16656
|
+
const parsed = parseFloat(value);
|
|
16657
|
+
return Number.isNaN(parsed) ? 0 : Math.max(0, Math.min(1, parsed));
|
|
16658
|
+
}
|
|
16659
|
+
var init_capacity = __esm({
|
|
16660
|
+
"packages/core/src/agents/capacity.ts"() {
|
|
16661
|
+
"use strict";
|
|
16662
|
+
init_sqlite2();
|
|
16663
|
+
init_agent_schema();
|
|
16664
|
+
init_registry2();
|
|
16665
|
+
}
|
|
16666
|
+
});
|
|
16667
|
+
|
|
16668
|
+
// packages/core/src/agents/health-monitor.ts
|
|
16669
|
+
async function recordHeartbeat(agentId, cwd) {
|
|
16670
|
+
return heartbeat(agentId, cwd);
|
|
16671
|
+
}
|
|
16672
|
+
async function checkAgentHealth2(agentId, thresholdMs = STALE_THRESHOLD_MS, cwd) {
|
|
16673
|
+
const all = await listAgentInstances(void 0, cwd);
|
|
16674
|
+
const agent = all.find((a) => a.id === agentId);
|
|
16675
|
+
if (!agent) return null;
|
|
16676
|
+
return buildHealthStatus(agent, thresholdMs);
|
|
16677
|
+
}
|
|
16678
|
+
async function detectStaleAgents(thresholdMs = STALE_THRESHOLD_MS, cwd) {
|
|
16679
|
+
const agents = await listAgentInstances({ status: ALIVE_STATUSES }, cwd);
|
|
16680
|
+
return agents.map((a) => buildHealthStatus(a, thresholdMs)).filter((s) => s.stale).sort((a, b) => b.heartbeatAgeMs - a.heartbeatAgeMs);
|
|
16681
|
+
}
|
|
16682
|
+
async function detectCrashedAgents(thresholdMs = STALE_THRESHOLD_MS, cwd) {
|
|
16683
|
+
const activeAgents = await listAgentInstances({ status: "active" }, cwd);
|
|
16684
|
+
const cutoff = new Date(Date.now() - thresholdMs).toISOString();
|
|
16685
|
+
const crashed = [];
|
|
16686
|
+
for (const agent of activeAgents) {
|
|
16687
|
+
if (agent.lastHeartbeat < cutoff) {
|
|
16688
|
+
const updated = await markCrashed(
|
|
16689
|
+
agent.id,
|
|
16690
|
+
`Heartbeat timeout \u2014 no heartbeat for >${Math.round(thresholdMs / 1e3)}s`,
|
|
16691
|
+
cwd
|
|
16692
|
+
);
|
|
16693
|
+
if (updated) {
|
|
16694
|
+
crashed.push(updated);
|
|
16695
|
+
}
|
|
16696
|
+
}
|
|
16697
|
+
}
|
|
16698
|
+
crashed.sort((a, b) => {
|
|
16699
|
+
const aHb = a.lastHeartbeat ?? "";
|
|
16700
|
+
const bHb = b.lastHeartbeat ?? "";
|
|
16701
|
+
return aHb < bHb ? -1 : aHb > bHb ? 1 : 0;
|
|
16702
|
+
});
|
|
16703
|
+
return crashed;
|
|
16704
|
+
}
|
|
16705
|
+
function buildHealthStatus(agent, thresholdMs) {
|
|
16706
|
+
const lastHeartbeatMs = new Date(agent.lastHeartbeat).getTime();
|
|
16707
|
+
const heartbeatAgeMs = Date.now() - lastHeartbeatMs;
|
|
16708
|
+
const stale = ALIVE_STATUSES.includes(agent.status) ? heartbeatAgeMs > thresholdMs : false;
|
|
16709
|
+
const healthy = !stale && ALIVE_STATUSES.includes(agent.status);
|
|
16710
|
+
return {
|
|
16711
|
+
agentId: agent.id,
|
|
16712
|
+
status: agent.status,
|
|
16713
|
+
lastHeartbeat: agent.lastHeartbeat,
|
|
16714
|
+
heartbeatAgeMs,
|
|
16715
|
+
healthy,
|
|
16716
|
+
stale,
|
|
16717
|
+
thresholdMs
|
|
16718
|
+
};
|
|
16719
|
+
}
|
|
16720
|
+
var HEARTBEAT_INTERVAL_MS, STALE_THRESHOLD_MS, ALIVE_STATUSES;
|
|
16721
|
+
var init_health_monitor = __esm({
|
|
16722
|
+
"packages/core/src/agents/health-monitor.ts"() {
|
|
16723
|
+
"use strict";
|
|
16724
|
+
init_registry2();
|
|
16725
|
+
HEARTBEAT_INTERVAL_MS = 3e4;
|
|
16726
|
+
STALE_THRESHOLD_MS = 3 * 6e4;
|
|
16727
|
+
ALIVE_STATUSES = ["starting", "active", "idle"];
|
|
16728
|
+
}
|
|
16729
|
+
});
|
|
16730
|
+
|
|
16566
16731
|
// packages/core/src/agents/retry.ts
|
|
16567
16732
|
function createRetryPolicy(overrides) {
|
|
16568
16733
|
return { ...DEFAULT_RETRY_POLICY, ...overrides };
|
|
@@ -16689,18 +16854,27 @@ __export(agents_exports, {
|
|
|
16689
16854
|
AGENT_INSTANCE_STATUSES: () => AGENT_INSTANCE_STATUSES,
|
|
16690
16855
|
AGENT_TYPES: () => AGENT_TYPES,
|
|
16691
16856
|
DEFAULT_RETRY_POLICY: () => DEFAULT_RETRY_POLICY,
|
|
16857
|
+
HEARTBEAT_INTERVAL_MS: () => HEARTBEAT_INTERVAL_MS,
|
|
16858
|
+
MAX_TASKS_PER_AGENT: () => MAX_TASKS_PER_AGENT,
|
|
16859
|
+
STALE_THRESHOLD_MS: () => STALE_THRESHOLD_MS,
|
|
16692
16860
|
agentErrorLog: () => agentErrorLog,
|
|
16693
16861
|
agentInstances: () => agentInstances,
|
|
16694
16862
|
calculateDelay: () => calculateDelay,
|
|
16695
|
-
checkAgentHealth: () =>
|
|
16863
|
+
checkAgentHealth: () => checkAgentHealth2,
|
|
16696
16864
|
classifyError: () => classifyError,
|
|
16697
16865
|
createRetryPolicy: () => createRetryPolicy,
|
|
16698
16866
|
deregisterAgent: () => deregisterAgent,
|
|
16867
|
+
detectCrashedAgents: () => detectCrashedAgents,
|
|
16868
|
+
detectStaleAgents: () => detectStaleAgents,
|
|
16699
16869
|
findLeastLoadedAgent: () => findLeastLoadedAgent,
|
|
16870
|
+
findStaleAgentRows: () => checkAgentHealth,
|
|
16700
16871
|
generateAgentId: () => generateAgentId,
|
|
16872
|
+
getAgentCapacity: () => getAgentCapacity,
|
|
16701
16873
|
getAgentErrorHistory: () => getAgentErrorHistory,
|
|
16702
16874
|
getAgentInstance: () => getAgentInstance,
|
|
16703
16875
|
getAgentPerformanceHistory: () => getAgentPerformanceHistory,
|
|
16876
|
+
getAgentSpecializations: () => getAgentSpecializations,
|
|
16877
|
+
getAgentsByCapacity: () => getAgentsByCapacity,
|
|
16704
16878
|
getAvailableCapacity: () => getAvailableCapacity,
|
|
16705
16879
|
getCapacitySummary: () => getCapacitySummary,
|
|
16706
16880
|
getHealthReport: () => getHealthReport,
|
|
@@ -16712,11 +16886,14 @@ __export(agents_exports, {
|
|
|
16712
16886
|
markCrashed: () => markCrashed,
|
|
16713
16887
|
processAgentLifecycleEvent: () => processAgentLifecycleEvent,
|
|
16714
16888
|
recordAgentExecution: () => recordAgentExecution,
|
|
16889
|
+
recordAgentPerformance: () => recordAgentPerformance,
|
|
16715
16890
|
recordFailurePattern: () => recordFailurePattern,
|
|
16891
|
+
recordHeartbeat: () => recordHeartbeat,
|
|
16716
16892
|
recoverCrashedAgents: () => recoverCrashedAgents,
|
|
16717
16893
|
registerAgent: () => registerAgent,
|
|
16718
16894
|
shouldRetry: () => shouldRetry,
|
|
16719
16895
|
storeHealingStrategy: () => storeHealingStrategy,
|
|
16896
|
+
updateAgentSpecializations: () => updateAgentSpecializations,
|
|
16720
16897
|
updateAgentStatus: () => updateAgentStatus,
|
|
16721
16898
|
updateCapacity: () => updateCapacity,
|
|
16722
16899
|
withRetry: () => withRetry
|
|
@@ -16724,9 +16901,11 @@ __export(agents_exports, {
|
|
|
16724
16901
|
var init_agents = __esm({
|
|
16725
16902
|
"packages/core/src/agents/index.ts"() {
|
|
16726
16903
|
"use strict";
|
|
16904
|
+
init_agent_registry();
|
|
16727
16905
|
init_agent_schema();
|
|
16728
16906
|
init_capacity();
|
|
16729
16907
|
init_execution_learning();
|
|
16908
|
+
init_health_monitor();
|
|
16730
16909
|
init_registry2();
|
|
16731
16910
|
init_retry();
|
|
16732
16911
|
}
|
|
@@ -20598,19 +20777,19 @@ async function queryAudit(options) {
|
|
|
20598
20777
|
try {
|
|
20599
20778
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
20600
20779
|
const { auditLog: auditLog2 } = await Promise.resolve().then(() => (init_tasks_schema(), tasks_schema_exports));
|
|
20601
|
-
const { and:
|
|
20780
|
+
const { and: and12, eq: eq17, gte: gte4, or: or6 } = await import("drizzle-orm");
|
|
20602
20781
|
const db = await getDb4(process.cwd());
|
|
20603
20782
|
const conditions = [];
|
|
20604
|
-
if (options?.sessionId) conditions.push(
|
|
20605
|
-
if (options?.domain) conditions.push(
|
|
20783
|
+
if (options?.sessionId) conditions.push(eq17(auditLog2.sessionId, options.sessionId));
|
|
20784
|
+
if (options?.domain) conditions.push(eq17(auditLog2.domain, options.domain));
|
|
20606
20785
|
if (options?.operation)
|
|
20607
20786
|
conditions.push(
|
|
20608
|
-
or6(
|
|
20787
|
+
or6(eq17(auditLog2.operation, options.operation), eq17(auditLog2.action, options.operation))
|
|
20609
20788
|
);
|
|
20610
|
-
if (options?.taskId) conditions.push(
|
|
20789
|
+
if (options?.taskId) conditions.push(eq17(auditLog2.taskId, options.taskId));
|
|
20611
20790
|
if (options?.since) conditions.push(gte4(auditLog2.timestamp, options.since));
|
|
20612
20791
|
const limit = options?.limit ?? 1e3;
|
|
20613
|
-
const rows = await db.select().from(auditLog2).where(conditions.length > 0 ?
|
|
20792
|
+
const rows = await db.select().from(auditLog2).where(conditions.length > 0 ? and12(...conditions) : void 0).orderBy(auditLog2.timestamp).limit(limit);
|
|
20614
20793
|
return rows.map((row) => ({
|
|
20615
20794
|
timestamp: row.timestamp,
|
|
20616
20795
|
sessionId: row.sessionId,
|
|
@@ -34355,6 +34534,116 @@ function generateRecommendation2(changeType, affectedCount, cascadeDepth, taskId
|
|
|
34355
34534
|
return `${severity} impact: reprioritizing ${taskId} may reorder ${affectedCount} downstream task(s) across ${cascadeDepth} level(s) of dependencies.`;
|
|
34356
34535
|
}
|
|
34357
34536
|
}
|
|
34537
|
+
function scoreTaskMatch(change, task) {
|
|
34538
|
+
const STOP_WORDS3 = /* @__PURE__ */ new Set([
|
|
34539
|
+
"a",
|
|
34540
|
+
"an",
|
|
34541
|
+
"the",
|
|
34542
|
+
"and",
|
|
34543
|
+
"or",
|
|
34544
|
+
"in",
|
|
34545
|
+
"of",
|
|
34546
|
+
"to",
|
|
34547
|
+
"for",
|
|
34548
|
+
"with",
|
|
34549
|
+
"on",
|
|
34550
|
+
"at",
|
|
34551
|
+
"by",
|
|
34552
|
+
"is",
|
|
34553
|
+
"it",
|
|
34554
|
+
"be",
|
|
34555
|
+
"as",
|
|
34556
|
+
"if",
|
|
34557
|
+
"do",
|
|
34558
|
+
"not"
|
|
34559
|
+
]);
|
|
34560
|
+
const tokenise = (text3) => text3.toLowerCase().split(/\W+/).filter((t) => t.length > 2 && !STOP_WORDS3.has(t));
|
|
34561
|
+
const changeTokens = new Set(tokenise(change));
|
|
34562
|
+
if (changeTokens.size === 0) return 0;
|
|
34563
|
+
const taskText = `${task.title ?? ""} ${task.description ?? ""}`;
|
|
34564
|
+
const taskTokens = new Set(tokenise(taskText));
|
|
34565
|
+
let matches = 0;
|
|
34566
|
+
for (const token of changeTokens) {
|
|
34567
|
+
if (taskTokens.has(token)) matches++;
|
|
34568
|
+
}
|
|
34569
|
+
return matches / changeTokens.size;
|
|
34570
|
+
}
|
|
34571
|
+
async function predictImpact(change, cwd, accessor, matchLimit = 5) {
|
|
34572
|
+
const acc = accessor ?? await getAccessor(cwd);
|
|
34573
|
+
const tasks2 = await loadAllTasks2(acc);
|
|
34574
|
+
const taskMap = new Map(tasks2.map((t) => [t.id, t]));
|
|
34575
|
+
const dependentsMap = buildDependentsMap(tasks2);
|
|
34576
|
+
const scored = tasks2.map((t) => ({ task: t, score: scoreTaskMatch(change, t) })).filter(({ score }) => score > 0).sort((a, b) => b.score - a.score);
|
|
34577
|
+
const seeds = scored.slice(0, matchLimit).map(({ task }) => task);
|
|
34578
|
+
if (seeds.length === 0) {
|
|
34579
|
+
return {
|
|
34580
|
+
change,
|
|
34581
|
+
matchedTasks: [],
|
|
34582
|
+
affectedTasks: [],
|
|
34583
|
+
totalAffected: 0,
|
|
34584
|
+
summary: `No tasks matched the change description "${change}".`
|
|
34585
|
+
};
|
|
34586
|
+
}
|
|
34587
|
+
const directMatchIds = new Set(seeds.map((t) => t.id));
|
|
34588
|
+
const exposureMap = /* @__PURE__ */ new Map();
|
|
34589
|
+
for (const id of directMatchIds) {
|
|
34590
|
+
exposureMap.set(id, "direct");
|
|
34591
|
+
}
|
|
34592
|
+
for (const seed of seeds) {
|
|
34593
|
+
const transitive = collectTransitiveDependents(seed.id, dependentsMap);
|
|
34594
|
+
for (const depId of transitive) {
|
|
34595
|
+
if (!exposureMap.has(depId)) {
|
|
34596
|
+
const isDirectDependent = (dependentsMap.get(seed.id) ?? /* @__PURE__ */ new Set()).has(depId);
|
|
34597
|
+
exposureMap.set(depId, isDirectDependent ? "dependent" : "transitive");
|
|
34598
|
+
}
|
|
34599
|
+
}
|
|
34600
|
+
}
|
|
34601
|
+
const EXPOSURE_ORDER = {
|
|
34602
|
+
direct: 0,
|
|
34603
|
+
dependent: 1,
|
|
34604
|
+
transitive: 2
|
|
34605
|
+
};
|
|
34606
|
+
const affectedTasks = [];
|
|
34607
|
+
for (const [id, exposure] of exposureMap) {
|
|
34608
|
+
const task = taskMap.get(id);
|
|
34609
|
+
if (!task) continue;
|
|
34610
|
+
const downstreamTransitive = collectTransitiveDependents(id, dependentsMap);
|
|
34611
|
+
const downstreamCount = downstreamTransitive.size;
|
|
34612
|
+
let reason;
|
|
34613
|
+
if (exposure === "direct") {
|
|
34614
|
+
reason = `Task title/description matched "${change}".`;
|
|
34615
|
+
} else if (exposure === "dependent") {
|
|
34616
|
+
const seedNames = seeds.filter((s) => (dependentsMap.get(s.id) ?? /* @__PURE__ */ new Set()).has(id)).map((s) => s.id).join(", ");
|
|
34617
|
+
reason = `Directly depends on matched task(s): ${seedNames}.`;
|
|
34618
|
+
} else {
|
|
34619
|
+
reason = "Downstream of a matched task via transitive dependency chain.";
|
|
34620
|
+
}
|
|
34621
|
+
affectedTasks.push({
|
|
34622
|
+
id,
|
|
34623
|
+
title: task.title,
|
|
34624
|
+
status: task.status,
|
|
34625
|
+
priority: task.priority,
|
|
34626
|
+
exposure,
|
|
34627
|
+
downstreamCount,
|
|
34628
|
+
reason
|
|
34629
|
+
});
|
|
34630
|
+
}
|
|
34631
|
+
affectedTasks.sort((a, b) => {
|
|
34632
|
+
const expDiff = EXPOSURE_ORDER[a.exposure] - EXPOSURE_ORDER[b.exposure];
|
|
34633
|
+
if (expDiff !== 0) return expDiff;
|
|
34634
|
+
return b.downstreamCount - a.downstreamCount;
|
|
34635
|
+
});
|
|
34636
|
+
const matchedTasks = affectedTasks.filter((t) => t.exposure === "direct");
|
|
34637
|
+
const totalAffected = affectedTasks.length;
|
|
34638
|
+
const summary = matchedTasks.length === 0 ? `No tasks matched "${change}".` : `${matchedTasks.length} task(s) matched "${change}"; ${totalAffected} total task(s) affected (including downstream).`;
|
|
34639
|
+
return {
|
|
34640
|
+
change,
|
|
34641
|
+
matchedTasks,
|
|
34642
|
+
affectedTasks,
|
|
34643
|
+
totalAffected,
|
|
34644
|
+
summary
|
|
34645
|
+
};
|
|
34646
|
+
}
|
|
34358
34647
|
var init_impact = __esm({
|
|
34359
34648
|
"packages/core/src/intelligence/impact.ts"() {
|
|
34360
34649
|
"use strict";
|
|
@@ -34758,6 +35047,7 @@ __export(intelligence_exports, {
|
|
|
34758
35047
|
gatherLearningContext: () => gatherLearningContext,
|
|
34759
35048
|
matchPatterns: () => matchPatterns,
|
|
34760
35049
|
predictAndStore: () => predictAndStore,
|
|
35050
|
+
predictImpact: () => predictImpact,
|
|
34761
35051
|
predictValidationOutcome: () => predictValidationOutcome,
|
|
34762
35052
|
scoreVerificationConfidence: () => scoreVerificationConfidence,
|
|
34763
35053
|
storeDetectedPattern: () => storeDetectedPattern,
|
|
@@ -35572,6 +35862,7 @@ import { execFile as execFile3 } from "node:child_process";
|
|
|
35572
35862
|
import { randomUUID } from "node:crypto";
|
|
35573
35863
|
import { existsSync as existsSync34, constants as fsConstants3, readFileSync as readFileSync22, statSync as statSync8 } from "node:fs";
|
|
35574
35864
|
import { access as access3, mkdir as mkdir5, readFile as readFile6, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
|
|
35865
|
+
import { homedir as getHomedir } from "node:os";
|
|
35575
35866
|
import { dirname as dirname8, join as join37, resolve as resolve5 } from "node:path";
|
|
35576
35867
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
35577
35868
|
import { promisify as promisify3 } from "node:util";
|
|
@@ -36383,12 +36674,30 @@ function checkGlobalTemplates() {
|
|
|
36383
36674
|
fix: "cleo init (or restart MCP server)"
|
|
36384
36675
|
};
|
|
36385
36676
|
}
|
|
36677
|
+
const xdgContent = readFileSync22(injectionPath, "utf-8");
|
|
36678
|
+
const xdgVersion = xdgContent.match(/^Version:\s*(.+)$/m)?.[1]?.trim();
|
|
36679
|
+
const home = getHomedir();
|
|
36680
|
+
const legacyPath = join37(home, ".cleo", "templates", "CLEO-INJECTION.md");
|
|
36681
|
+
if (existsSync34(legacyPath)) {
|
|
36682
|
+
const legacyContent = readFileSync22(legacyPath, "utf-8");
|
|
36683
|
+
const legacyVersion = legacyContent.match(/^Version:\s*(.+)$/m)?.[1]?.trim();
|
|
36684
|
+
if (legacyVersion && xdgVersion && legacyVersion !== xdgVersion) {
|
|
36685
|
+
return {
|
|
36686
|
+
id: "global_templates",
|
|
36687
|
+
category: "global",
|
|
36688
|
+
status: "warning",
|
|
36689
|
+
message: `Legacy template version (${legacyVersion}) out of sync with XDG (${xdgVersion})`,
|
|
36690
|
+
details: { path: injectionPath, exists: true, xdgVersion, legacyVersion, legacyPath },
|
|
36691
|
+
fix: "npm install -g @cleocode/cleo (reinstall syncs both paths)"
|
|
36692
|
+
};
|
|
36693
|
+
}
|
|
36694
|
+
}
|
|
36386
36695
|
return {
|
|
36387
36696
|
id: "global_templates",
|
|
36388
36697
|
category: "global",
|
|
36389
36698
|
status: "passed",
|
|
36390
|
-
message:
|
|
36391
|
-
details: { path: injectionPath, exists: true },
|
|
36699
|
+
message: `Global injection template present (v${xdgVersion ?? "unknown"})`,
|
|
36700
|
+
details: { path: injectionPath, exists: true, version: xdgVersion },
|
|
36392
36701
|
fix: null
|
|
36393
36702
|
};
|
|
36394
36703
|
}
|
|
@@ -36506,13 +36815,13 @@ function extractYamlArray(content, field) {
|
|
|
36506
36815
|
}
|
|
36507
36816
|
const lines = content.split("\n");
|
|
36508
36817
|
const items = [];
|
|
36509
|
-
let
|
|
36818
|
+
let inArray7 = false;
|
|
36510
36819
|
for (const line2 of lines) {
|
|
36511
36820
|
if (line2.match(new RegExp(`^${field}:`))) {
|
|
36512
|
-
|
|
36821
|
+
inArray7 = true;
|
|
36513
36822
|
continue;
|
|
36514
36823
|
}
|
|
36515
|
-
if (
|
|
36824
|
+
if (inArray7) {
|
|
36516
36825
|
const itemMatch = line2.match(/^\s+-\s+["']?(.+?)["']?\s*$/);
|
|
36517
36826
|
if (itemMatch) {
|
|
36518
36827
|
items.push(itemMatch[1].trim());
|
|
@@ -36808,6 +37117,71 @@ var init_issue = __esm({
|
|
|
36808
37117
|
}
|
|
36809
37118
|
});
|
|
36810
37119
|
|
|
37120
|
+
// packages/core/src/lib/retry.ts
|
|
37121
|
+
async function withRetry2(fn, options) {
|
|
37122
|
+
const maxAttempts = options?.maxAttempts ?? 3;
|
|
37123
|
+
const baseDelayMs = options?.baseDelayMs ?? 2e3;
|
|
37124
|
+
const maxDelayMs = options?.maxDelayMs ?? 3e4;
|
|
37125
|
+
const retryableErrors = options?.retryableErrors;
|
|
37126
|
+
let lastError;
|
|
37127
|
+
let totalDelayMs = 0;
|
|
37128
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
37129
|
+
try {
|
|
37130
|
+
return await fn();
|
|
37131
|
+
} catch (err) {
|
|
37132
|
+
lastError = err;
|
|
37133
|
+
const isLastAttempt = attempt === maxAttempts;
|
|
37134
|
+
if (isLastAttempt) break;
|
|
37135
|
+
if (retryableErrors !== void 0 && !isRetryable(err, retryableErrors)) break;
|
|
37136
|
+
const delay = computeDelay(attempt, baseDelayMs, maxDelayMs);
|
|
37137
|
+
totalDelayMs += delay;
|
|
37138
|
+
await sleep2(delay);
|
|
37139
|
+
}
|
|
37140
|
+
}
|
|
37141
|
+
const context = { attempts: maxAttempts, totalDelayMs };
|
|
37142
|
+
augmentError(lastError, context);
|
|
37143
|
+
throw lastError;
|
|
37144
|
+
}
|
|
37145
|
+
function computeDelay(attempt, baseDelayMs, maxDelayMs) {
|
|
37146
|
+
const exponential = baseDelayMs * 2 ** (attempt - 1);
|
|
37147
|
+
return Math.min(exponential, maxDelayMs);
|
|
37148
|
+
}
|
|
37149
|
+
function isRetryable(err, predicates) {
|
|
37150
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
37151
|
+
return predicates.some((predicate) => {
|
|
37152
|
+
if (predicate instanceof RegExp) return predicate.test(message);
|
|
37153
|
+
return predicate(err);
|
|
37154
|
+
});
|
|
37155
|
+
}
|
|
37156
|
+
function augmentError(err, context) {
|
|
37157
|
+
if (err instanceof Error) {
|
|
37158
|
+
const mutableErr = err;
|
|
37159
|
+
mutableErr.attempts = context.attempts;
|
|
37160
|
+
mutableErr.totalDelayMs = context.totalDelayMs;
|
|
37161
|
+
}
|
|
37162
|
+
}
|
|
37163
|
+
function sleep2(ms) {
|
|
37164
|
+
return new Promise((resolve13) => setTimeout(resolve13, ms));
|
|
37165
|
+
}
|
|
37166
|
+
var init_retry2 = __esm({
|
|
37167
|
+
"packages/core/src/lib/retry.ts"() {
|
|
37168
|
+
"use strict";
|
|
37169
|
+
}
|
|
37170
|
+
});
|
|
37171
|
+
|
|
37172
|
+
// packages/core/src/lib/index.ts
|
|
37173
|
+
var lib_exports = {};
|
|
37174
|
+
__export(lib_exports, {
|
|
37175
|
+
computeDelay: () => computeDelay,
|
|
37176
|
+
withRetry: () => withRetry2
|
|
37177
|
+
});
|
|
37178
|
+
var init_lib = __esm({
|
|
37179
|
+
"packages/core/src/lib/index.ts"() {
|
|
37180
|
+
"use strict";
|
|
37181
|
+
init_retry2();
|
|
37182
|
+
}
|
|
37183
|
+
});
|
|
37184
|
+
|
|
36811
37185
|
// packages/core/src/lifecycle/evidence.ts
|
|
36812
37186
|
import { basename as basename5, relative as relative2 } from "node:path";
|
|
36813
37187
|
async function recordEvidence(epicId, stage, uri, type, options) {
|
|
@@ -37647,12 +38021,12 @@ async function getEnforcementMode(cwd) {
|
|
|
37647
38021
|
}
|
|
37648
38022
|
async function getLifecycleStatus(epicId, cwd) {
|
|
37649
38023
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
37650
|
-
const { eq:
|
|
38024
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
37651
38025
|
const db = await getDb4(cwd);
|
|
37652
38026
|
const pipelineResult = await db.select({
|
|
37653
38027
|
pipeline: lifecyclePipelines,
|
|
37654
38028
|
task: tasks
|
|
37655
|
-
}).from(lifecyclePipelines).innerJoin(tasks,
|
|
38029
|
+
}).from(lifecyclePipelines).innerJoin(tasks, eq17(lifecyclePipelines.taskId, tasks.id)).where(eq17(lifecyclePipelines.taskId, epicId)).limit(1);
|
|
37656
38030
|
if (pipelineResult.length === 0) {
|
|
37657
38031
|
return {
|
|
37658
38032
|
epicId,
|
|
@@ -37665,7 +38039,7 @@ async function getLifecycleStatus(epicId, cwd) {
|
|
|
37665
38039
|
}
|
|
37666
38040
|
const task = pipelineResult[0].task;
|
|
37667
38041
|
const pipelineId = `pipeline-${epicId}`;
|
|
37668
|
-
const stageRows = await db.select().from(lifecycleStages).where(
|
|
38042
|
+
const stageRows = await db.select().from(lifecycleStages).where(eq17(lifecycleStages.pipelineId, pipelineId)).orderBy(lifecycleStages.sequence);
|
|
37669
38043
|
const stageDataMap = /* @__PURE__ */ new Map();
|
|
37670
38044
|
for (const row of stageRows) {
|
|
37671
38045
|
let parsedChain;
|
|
@@ -37734,10 +38108,10 @@ async function getLifecycleStatus(epicId, cwd) {
|
|
|
37734
38108
|
}
|
|
37735
38109
|
async function getLifecycleHistory(epicId, cwd) {
|
|
37736
38110
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
37737
|
-
const { eq:
|
|
38111
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
37738
38112
|
const db = await getDb4(cwd);
|
|
37739
38113
|
const pipelineId = `pipeline-${epicId}`;
|
|
37740
|
-
const stages = await db.select().from(lifecycleStages).where(
|
|
38114
|
+
const stages = await db.select().from(lifecycleStages).where(eq17(lifecycleStages.pipelineId, pipelineId));
|
|
37741
38115
|
if (stages.length === 0) {
|
|
37742
38116
|
return { epicId, history: [] };
|
|
37743
38117
|
}
|
|
@@ -37767,7 +38141,7 @@ async function getLifecycleHistory(epicId, cwd) {
|
|
|
37767
38141
|
}
|
|
37768
38142
|
const stageIds = stages.map((s) => s.id);
|
|
37769
38143
|
if (stageIds.length > 0) {
|
|
37770
|
-
const gateResults = await db.select().from(lifecycleGateResults).where(
|
|
38144
|
+
const gateResults = await db.select().from(lifecycleGateResults).where(eq17(lifecycleGateResults.stageId, stageIds[0]));
|
|
37771
38145
|
for (const gate of gateResults) {
|
|
37772
38146
|
const stageName = stageIdToName.get(gate.stageId);
|
|
37773
38147
|
if (stageName) {
|
|
@@ -37780,7 +38154,7 @@ async function getLifecycleHistory(epicId, cwd) {
|
|
|
37780
38154
|
}
|
|
37781
38155
|
}
|
|
37782
38156
|
for (let i = 1; i < stageIds.length; i++) {
|
|
37783
|
-
const additionalGates = await db.select().from(lifecycleGateResults).where(
|
|
38157
|
+
const additionalGates = await db.select().from(lifecycleGateResults).where(eq17(lifecycleGateResults.stageId, stageIds[i]));
|
|
37784
38158
|
for (const gate of additionalGates) {
|
|
37785
38159
|
const stageName = stageIdToName.get(gate.stageId);
|
|
37786
38160
|
if (stageName) {
|
|
@@ -37799,16 +38173,16 @@ async function getLifecycleHistory(epicId, cwd) {
|
|
|
37799
38173
|
}
|
|
37800
38174
|
async function getLifecycleGates(epicId, cwd) {
|
|
37801
38175
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
37802
|
-
const { eq:
|
|
38176
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
37803
38177
|
const db = await getDb4(cwd);
|
|
37804
38178
|
const pipelineId = `pipeline-${epicId}`;
|
|
37805
|
-
const stages = await db.select().from(lifecycleStages).where(
|
|
38179
|
+
const stages = await db.select().from(lifecycleStages).where(eq17(lifecycleStages.pipelineId, pipelineId));
|
|
37806
38180
|
if (stages.length === 0) {
|
|
37807
38181
|
return {};
|
|
37808
38182
|
}
|
|
37809
38183
|
const gates = {};
|
|
37810
38184
|
for (const stage of stages) {
|
|
37811
|
-
const gateRows = await db.select().from(lifecycleGateResults).where(
|
|
38185
|
+
const gateRows = await db.select().from(lifecycleGateResults).where(eq17(lifecycleGateResults.stageId, stage.id));
|
|
37812
38186
|
if (gateRows.length > 0) {
|
|
37813
38187
|
gates[stage.stageName] = {};
|
|
37814
38188
|
for (const gateRow of gateRows) {
|
|
@@ -37872,7 +38246,7 @@ async function checkStagePrerequisites(epicId, targetStage, cwd) {
|
|
|
37872
38246
|
}
|
|
37873
38247
|
async function ensureLifecycleContext(epicId, stageName, cwd, options) {
|
|
37874
38248
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
37875
|
-
const { eq:
|
|
38249
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
37876
38250
|
const db = await getDb4(cwd);
|
|
37877
38251
|
const pipelineId = `pipeline-${epicId}`;
|
|
37878
38252
|
const stageId = `stage-${epicId}-${stageName}`;
|
|
@@ -37880,7 +38254,7 @@ async function ensureLifecycleContext(epicId, stageName, cwd, options) {
|
|
|
37880
38254
|
getNativeDb3().prepare(
|
|
37881
38255
|
`INSERT OR IGNORE INTO tasks (id, title, status, priority, created_at) VALUES (?, ?, 'pending', 'medium', datetime('now'))`
|
|
37882
38256
|
).run(epicId, `Task ${epicId}`);
|
|
37883
|
-
const existingPipeline = await db.select().from(lifecyclePipelines).where(
|
|
38257
|
+
const existingPipeline = await db.select().from(lifecyclePipelines).where(eq17(lifecyclePipelines.id, pipelineId)).limit(1).all();
|
|
37884
38258
|
if (existingPipeline.length === 0) {
|
|
37885
38259
|
await db.insert(lifecyclePipelines).values({
|
|
37886
38260
|
id: pipelineId,
|
|
@@ -37890,7 +38264,7 @@ async function ensureLifecycleContext(epicId, stageName, cwd, options) {
|
|
|
37890
38264
|
startedAt: options.now
|
|
37891
38265
|
}).run();
|
|
37892
38266
|
}
|
|
37893
|
-
const existingStage = await db.select().from(lifecycleStages).where(
|
|
38267
|
+
const existingStage = await db.select().from(lifecycleStages).where(eq17(lifecycleStages.id, stageId)).limit(1).all();
|
|
37894
38268
|
if (existingStage.length === 0) {
|
|
37895
38269
|
const sequence = isValidStage(stageName) ? STAGE_ORDER[stageName] : 0;
|
|
37896
38270
|
await db.insert(lifecycleStages).values({
|
|
@@ -37903,7 +38277,7 @@ async function ensureLifecycleContext(epicId, stageName, cwd, options) {
|
|
|
37903
38277
|
}).run();
|
|
37904
38278
|
}
|
|
37905
38279
|
if (options.updateCurrentStage) {
|
|
37906
|
-
await db.update(lifecyclePipelines).set({ currentStageId: stageId }).where(
|
|
38280
|
+
await db.update(lifecyclePipelines).set({ currentStageId: stageId }).where(eq17(lifecyclePipelines.id, pipelineId)).run();
|
|
37907
38281
|
}
|
|
37908
38282
|
return { db, pipelineId, stageId };
|
|
37909
38283
|
}
|
|
@@ -37918,7 +38292,7 @@ async function recordStageProgress(epicId, stage, status, notes, cwd) {
|
|
|
37918
38292
|
`Invalid status: ${status}. Valid: ${validStatuses.join(", ")}`
|
|
37919
38293
|
);
|
|
37920
38294
|
}
|
|
37921
|
-
const { eq:
|
|
38295
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
37922
38296
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
37923
38297
|
const stageName = stage;
|
|
37924
38298
|
const { db, stageId, pipelineId } = await ensureLifecycleContext(epicId, stage, cwd, {
|
|
@@ -37934,7 +38308,7 @@ async function recordStageProgress(epicId, stage, status, notes, cwd) {
|
|
|
37934
38308
|
status,
|
|
37935
38309
|
related: artifact.related
|
|
37936
38310
|
};
|
|
37937
|
-
const existingStage = await db.select().from(lifecycleStages).where(
|
|
38311
|
+
const existingStage = await db.select().from(lifecycleStages).where(eq17(lifecycleStages.id, stageId)).limit(1).all();
|
|
37938
38312
|
const sequence = STAGE_ORDER[stage];
|
|
37939
38313
|
const stageValues = {
|
|
37940
38314
|
status,
|
|
@@ -37961,7 +38335,7 @@ async function recordStageProgress(epicId, stage, status, notes, cwd) {
|
|
|
37961
38335
|
provenanceChainJson: JSON.stringify(provenanceChain)
|
|
37962
38336
|
}).run();
|
|
37963
38337
|
} else {
|
|
37964
|
-
await db.update(lifecycleStages).set(stageValues).where(
|
|
38338
|
+
await db.update(lifecycleStages).set(stageValues).where(eq17(lifecycleStages.id, stageId)).run();
|
|
37965
38339
|
}
|
|
37966
38340
|
if (status === "completed") {
|
|
37967
38341
|
await linkProvenance(epicId, stageName, artifact.absolutePath, cwd);
|
|
@@ -37981,7 +38355,7 @@ async function resetStage(epicId, stage, reason, cwd) {
|
|
|
37981
38355
|
if (!PIPELINE_STAGES.includes(stage)) {
|
|
37982
38356
|
throw new CleoError(2 /* INVALID_INPUT */, `Invalid stage: ${stage}`);
|
|
37983
38357
|
}
|
|
37984
|
-
const { eq:
|
|
38358
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
37985
38359
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
37986
38360
|
const { db, stageId } = await ensureLifecycleContext(epicId, stage, cwd, {
|
|
37987
38361
|
now: now2,
|
|
@@ -37994,11 +38368,11 @@ async function resetStage(epicId, stage, reason, cwd) {
|
|
|
37994
38368
|
skippedAt: null,
|
|
37995
38369
|
skipReason: null,
|
|
37996
38370
|
notesJson: JSON.stringify([`Reset: ${reason}`])
|
|
37997
|
-
}).where(
|
|
38371
|
+
}).where(eq17(lifecycleStages.id, stageId)).run();
|
|
37998
38372
|
return { epicId, stage, reason };
|
|
37999
38373
|
}
|
|
38000
38374
|
async function passGate(epicId, gateName, agent, notes, cwd) {
|
|
38001
|
-
const { eq:
|
|
38375
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
38002
38376
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
38003
38377
|
const stageName = gateName.split("-")[0];
|
|
38004
38378
|
const gateId = `gate-${epicId}-${stageName}-${gateName}`;
|
|
@@ -38007,7 +38381,7 @@ async function passGate(epicId, gateName, agent, notes, cwd) {
|
|
|
38007
38381
|
stageStatusOnCreate: "in_progress",
|
|
38008
38382
|
updateCurrentStage: true
|
|
38009
38383
|
});
|
|
38010
|
-
const existingGate = await db.select().from(lifecycleGateResults).where(
|
|
38384
|
+
const existingGate = await db.select().from(lifecycleGateResults).where(eq17(lifecycleGateResults.id, gateId)).limit(1).all();
|
|
38011
38385
|
const gateValues = {
|
|
38012
38386
|
id: gateId,
|
|
38013
38387
|
stageId,
|
|
@@ -38019,14 +38393,14 @@ async function passGate(epicId, gateName, agent, notes, cwd) {
|
|
|
38019
38393
|
reason: null
|
|
38020
38394
|
};
|
|
38021
38395
|
if (existingGate.length > 0) {
|
|
38022
|
-
await db.update(lifecycleGateResults).set(gateValues).where(
|
|
38396
|
+
await db.update(lifecycleGateResults).set(gateValues).where(eq17(lifecycleGateResults.id, gateId)).run();
|
|
38023
38397
|
} else {
|
|
38024
38398
|
await db.insert(lifecycleGateResults).values(gateValues).run();
|
|
38025
38399
|
}
|
|
38026
38400
|
return { epicId, gateName, timestamp: now2 };
|
|
38027
38401
|
}
|
|
38028
38402
|
async function failGate(epicId, gateName, reason, cwd) {
|
|
38029
|
-
const { eq:
|
|
38403
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
38030
38404
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
38031
38405
|
const stageName = gateName.split("-")[0];
|
|
38032
38406
|
const gateId = `gate-${epicId}-${stageName}-${gateName}`;
|
|
@@ -38035,7 +38409,7 @@ async function failGate(epicId, gateName, reason, cwd) {
|
|
|
38035
38409
|
stageStatusOnCreate: "in_progress",
|
|
38036
38410
|
updateCurrentStage: true
|
|
38037
38411
|
});
|
|
38038
|
-
const existingGate = await db.select().from(lifecycleGateResults).where(
|
|
38412
|
+
const existingGate = await db.select().from(lifecycleGateResults).where(eq17(lifecycleGateResults.id, gateId)).limit(1).all();
|
|
38039
38413
|
const gateValues = {
|
|
38040
38414
|
id: gateId,
|
|
38041
38415
|
stageId,
|
|
@@ -38047,7 +38421,7 @@ async function failGate(epicId, gateName, reason, cwd) {
|
|
|
38047
38421
|
reason: reason ?? null
|
|
38048
38422
|
};
|
|
38049
38423
|
if (existingGate.length > 0) {
|
|
38050
|
-
await db.update(lifecycleGateResults).set(gateValues).where(
|
|
38424
|
+
await db.update(lifecycleGateResults).set(gateValues).where(eq17(lifecycleGateResults.id, gateId)).run();
|
|
38051
38425
|
} else {
|
|
38052
38426
|
await db.insert(lifecycleGateResults).values(gateValues).run();
|
|
38053
38427
|
}
|
|
@@ -38121,8 +38495,8 @@ function detectEnvMode() {
|
|
|
38121
38495
|
const devKv = {};
|
|
38122
38496
|
const devLines = devContent.trim().split("\n");
|
|
38123
38497
|
for (let i = 1; i < devLines.length; i++) {
|
|
38124
|
-
const
|
|
38125
|
-
if (
|
|
38498
|
+
const eq17 = devLines[i].indexOf("=");
|
|
38499
|
+
if (eq17 > 0) devKv[devLines[i].slice(0, eq17).trim()] = devLines[i].slice(eq17 + 1).trim();
|
|
38126
38500
|
}
|
|
38127
38501
|
if (devKv["mode"] === "dev-ts" && devKv["source"]) {
|
|
38128
38502
|
const devSource = devKv["source"].replace(/\\/g, "/");
|
|
@@ -38435,7 +38809,7 @@ var init_config = __esm({
|
|
|
38435
38809
|
"session.autoStart": false,
|
|
38436
38810
|
"session.requireNotes": true,
|
|
38437
38811
|
"session.multiSession": false,
|
|
38438
|
-
"
|
|
38812
|
+
"enforcement.acceptance.mode": "block",
|
|
38439
38813
|
"lifecycle.mode": "strict"
|
|
38440
38814
|
}
|
|
38441
38815
|
},
|
|
@@ -38445,7 +38819,7 @@ var init_config = __esm({
|
|
|
38445
38819
|
"session.autoStart": false,
|
|
38446
38820
|
"session.requireNotes": false,
|
|
38447
38821
|
"session.multiSession": true,
|
|
38448
|
-
"
|
|
38822
|
+
"enforcement.acceptance.mode": "warn",
|
|
38449
38823
|
"lifecycle.mode": "advisory"
|
|
38450
38824
|
}
|
|
38451
38825
|
},
|
|
@@ -38455,7 +38829,7 @@ var init_config = __esm({
|
|
|
38455
38829
|
"session.autoStart": false,
|
|
38456
38830
|
"session.requireNotes": false,
|
|
38457
38831
|
"session.multiSession": true,
|
|
38458
|
-
"
|
|
38832
|
+
"enforcement.acceptance.mode": "off",
|
|
38459
38833
|
"lifecycle.mode": "off"
|
|
38460
38834
|
}
|
|
38461
38835
|
}
|
|
@@ -38834,13 +39208,13 @@ __export(pipeline_exports, {
|
|
|
38834
39208
|
listPipelines: () => listPipelines,
|
|
38835
39209
|
pipelineExists: () => pipelineExists
|
|
38836
39210
|
});
|
|
38837
|
-
import { and as
|
|
39211
|
+
import { and as and6, asc as asc3, desc as desc3, eq as eq9, sql as sql9 } from "drizzle-orm";
|
|
38838
39212
|
async function initializePipeline(taskId, options = {}) {
|
|
38839
39213
|
const db = await getDb();
|
|
38840
39214
|
const now2 = /* @__PURE__ */ new Date();
|
|
38841
39215
|
const startStage2 = options.startStage || "research";
|
|
38842
39216
|
const initialStatus = options.initialStatus || "active";
|
|
38843
|
-
const existing = await db.select().from(lifecyclePipelines).where(
|
|
39217
|
+
const existing = await db.select().from(lifecyclePipelines).where(eq9(lifecyclePipelines.taskId, taskId)).limit(1).all();
|
|
38844
39218
|
if (existing.length > 0) {
|
|
38845
39219
|
throw new CleoError(101 /* ALREADY_EXISTS */, `Pipeline already exists for task ${taskId}`);
|
|
38846
39220
|
}
|
|
@@ -38889,13 +39263,13 @@ async function initializePipeline(taskId, options = {}) {
|
|
|
38889
39263
|
}
|
|
38890
39264
|
async function getPipeline(taskId) {
|
|
38891
39265
|
const db = await getDb();
|
|
38892
|
-
const result = await db.select().from(lifecyclePipelines).where(
|
|
39266
|
+
const result = await db.select().from(lifecyclePipelines).where(eq9(lifecyclePipelines.taskId, taskId)).limit(1).all();
|
|
38893
39267
|
if (result.length === 0) {
|
|
38894
39268
|
return null;
|
|
38895
39269
|
}
|
|
38896
39270
|
const row = result[0];
|
|
38897
39271
|
const isActive = row.status === "active";
|
|
38898
|
-
const transitionResult = await db.select({ count: sql9`count(*)` }).from(lifecycleTransitions).where(
|
|
39272
|
+
const transitionResult = await db.select({ count: sql9`count(*)` }).from(lifecycleTransitions).where(eq9(lifecycleTransitions.pipelineId, row.id)).all();
|
|
38899
39273
|
const transitionCount = Number(transitionResult[0]?.count || 0);
|
|
38900
39274
|
return {
|
|
38901
39275
|
id: taskId,
|
|
@@ -38918,7 +39292,7 @@ async function advanceStage(taskId, options) {
|
|
|
38918
39292
|
if (!options.initiatedBy) {
|
|
38919
39293
|
throw new CleoError(2 /* INVALID_INPUT */, "advanceStage() requires initiatedBy agent/user");
|
|
38920
39294
|
}
|
|
38921
|
-
const pipelineResult = await db.select().from(lifecyclePipelines).where(
|
|
39295
|
+
const pipelineResult = await db.select().from(lifecyclePipelines).where(eq9(lifecyclePipelines.taskId, taskId)).limit(1).all();
|
|
38922
39296
|
if (pipelineResult.length === 0) {
|
|
38923
39297
|
throw new CleoError(4 /* NOT_FOUND */, `No pipeline found for task ${taskId}`);
|
|
38924
39298
|
}
|
|
@@ -38926,9 +39300,9 @@ async function advanceStage(taskId, options) {
|
|
|
38926
39300
|
const fromStage = pipeline2.currentStageId;
|
|
38927
39301
|
const toStage = options.toStage;
|
|
38928
39302
|
const currentStageResult = await db.select().from(lifecycleStages).where(
|
|
38929
|
-
|
|
38930
|
-
|
|
38931
|
-
|
|
39303
|
+
and6(
|
|
39304
|
+
eq9(lifecycleStages.pipelineId, pipeline2.id),
|
|
39305
|
+
eq9(lifecycleStages.stageName, fromStage)
|
|
38932
39306
|
)
|
|
38933
39307
|
).limit(1).all();
|
|
38934
39308
|
if (currentStageResult.length === 0) {
|
|
@@ -38939,9 +39313,9 @@ async function advanceStage(taskId, options) {
|
|
|
38939
39313
|
}
|
|
38940
39314
|
const currentStageRecord = currentStageResult[0];
|
|
38941
39315
|
const targetStageResult = await db.select().from(lifecycleStages).where(
|
|
38942
|
-
|
|
38943
|
-
|
|
38944
|
-
|
|
39316
|
+
and6(
|
|
39317
|
+
eq9(lifecycleStages.pipelineId, pipeline2.id),
|
|
39318
|
+
eq9(lifecycleStages.stageName, toStage)
|
|
38945
39319
|
)
|
|
38946
39320
|
).limit(1).all();
|
|
38947
39321
|
if (targetStageResult.length === 0) {
|
|
@@ -38954,14 +39328,14 @@ async function advanceStage(taskId, options) {
|
|
|
38954
39328
|
await db.update(lifecycleStages).set({
|
|
38955
39329
|
status: "completed",
|
|
38956
39330
|
completedAt: now2.toISOString()
|
|
38957
|
-
}).where(
|
|
39331
|
+
}).where(eq9(lifecycleStages.id, currentStageRecord.id)).run();
|
|
38958
39332
|
await db.update(lifecycleStages).set({
|
|
38959
39333
|
status: "in_progress",
|
|
38960
39334
|
startedAt: now2.toISOString()
|
|
38961
|
-
}).where(
|
|
39335
|
+
}).where(eq9(lifecycleStages.id, targetStageRecord.id)).run();
|
|
38962
39336
|
await db.update(lifecyclePipelines).set({
|
|
38963
39337
|
currentStageId: toStage
|
|
38964
|
-
}).where(
|
|
39338
|
+
}).where(eq9(lifecyclePipelines.id, pipeline2.id)).run();
|
|
38965
39339
|
await db.insert(lifecycleTransitions).values({
|
|
38966
39340
|
id: `${pipeline2.id}_${now2.getTime()}_${Math.random().toString(36).slice(2, 7)}`,
|
|
38967
39341
|
pipelineId: pipeline2.id,
|
|
@@ -38978,7 +39352,7 @@ async function advanceStage(taskId, options) {
|
|
|
38978
39352
|
}
|
|
38979
39353
|
async function getCurrentStage(taskId) {
|
|
38980
39354
|
const db = await getDb();
|
|
38981
|
-
const result = await db.select({ currentStageId: lifecyclePipelines.currentStageId }).from(lifecyclePipelines).where(
|
|
39355
|
+
const result = await db.select({ currentStageId: lifecyclePipelines.currentStageId }).from(lifecyclePipelines).where(eq9(lifecyclePipelines.taskId, taskId)).limit(1).all();
|
|
38982
39356
|
if (result.length === 0) {
|
|
38983
39357
|
throw new CleoError(4 /* NOT_FOUND */, `No pipeline found for task ${taskId}`);
|
|
38984
39358
|
}
|
|
@@ -38990,43 +39364,43 @@ async function listPipelines(options = {}) {
|
|
|
38990
39364
|
const conditions = [];
|
|
38991
39365
|
if (options.status) {
|
|
38992
39366
|
conditions.push(
|
|
38993
|
-
|
|
39367
|
+
eq9(
|
|
38994
39368
|
lifecyclePipelines.status,
|
|
38995
39369
|
options.status
|
|
38996
39370
|
)
|
|
38997
39371
|
);
|
|
38998
39372
|
}
|
|
38999
39373
|
if (options.currentStage) {
|
|
39000
|
-
conditions.push(
|
|
39374
|
+
conditions.push(eq9(lifecyclePipelines.currentStageId, options.currentStage));
|
|
39001
39375
|
}
|
|
39002
39376
|
if (conditions.length > 0) {
|
|
39003
|
-
const whereClause = conditions.length === 1 ? conditions[0] :
|
|
39377
|
+
const whereClause = conditions.length === 1 ? conditions[0] : and6(...conditions);
|
|
39004
39378
|
query = db.select().from(lifecyclePipelines).where(whereClause);
|
|
39005
39379
|
}
|
|
39006
39380
|
if (options.orderBy) {
|
|
39007
39381
|
const order = options.order === "asc" ? asc3 : desc3;
|
|
39008
39382
|
switch (options.orderBy) {
|
|
39009
39383
|
case "createdAt":
|
|
39010
|
-
query = db.select().from(lifecyclePipelines).where(conditions.length > 0 ?
|
|
39384
|
+
query = db.select().from(lifecyclePipelines).where(conditions.length > 0 ? and6(...conditions) : void 0).orderBy(order(lifecyclePipelines.startedAt));
|
|
39011
39385
|
break;
|
|
39012
39386
|
case "currentStage":
|
|
39013
|
-
query = db.select().from(lifecyclePipelines).where(conditions.length > 0 ?
|
|
39387
|
+
query = db.select().from(lifecyclePipelines).where(conditions.length > 0 ? and6(...conditions) : void 0).orderBy(order(lifecyclePipelines.currentStageId));
|
|
39014
39388
|
break;
|
|
39015
39389
|
}
|
|
39016
39390
|
} else {
|
|
39017
|
-
query = db.select().from(lifecyclePipelines).where(conditions.length > 0 ?
|
|
39391
|
+
query = db.select().from(lifecyclePipelines).where(conditions.length > 0 ? and6(...conditions) : void 0).orderBy(desc3(lifecyclePipelines.startedAt));
|
|
39018
39392
|
}
|
|
39019
39393
|
if (options.limit) {
|
|
39020
|
-
query = db.select().from(lifecyclePipelines).where(conditions.length > 0 ?
|
|
39394
|
+
query = db.select().from(lifecyclePipelines).where(conditions.length > 0 ? and6(...conditions) : void 0).orderBy(desc3(lifecyclePipelines.startedAt)).limit(options.limit);
|
|
39021
39395
|
}
|
|
39022
39396
|
if (options.offset) {
|
|
39023
|
-
query = db.select().from(lifecyclePipelines).where(conditions.length > 0 ?
|
|
39397
|
+
query = db.select().from(lifecyclePipelines).where(conditions.length > 0 ? and6(...conditions) : void 0).orderBy(desc3(lifecyclePipelines.startedAt)).limit(options.limit || 100).offset(options.offset);
|
|
39024
39398
|
}
|
|
39025
39399
|
const results = await query.all();
|
|
39026
39400
|
return Promise.all(
|
|
39027
39401
|
results.map(async (row) => {
|
|
39028
39402
|
const isActive = row.status === "active";
|
|
39029
|
-
const transitionResult = await db.select({ count: sql9`count(*)` }).from(lifecycleTransitions).where(
|
|
39403
|
+
const transitionResult = await db.select({ count: sql9`count(*)` }).from(lifecycleTransitions).where(eq9(lifecycleTransitions.pipelineId, row.id)).all();
|
|
39030
39404
|
const transitionCount = Number(transitionResult[0]?.count || 0);
|
|
39031
39405
|
return {
|
|
39032
39406
|
id: row.taskId,
|
|
@@ -39045,7 +39419,7 @@ async function listPipelines(options = {}) {
|
|
|
39045
39419
|
async function completePipeline(taskId, reason) {
|
|
39046
39420
|
const db = await getDb();
|
|
39047
39421
|
const now2 = /* @__PURE__ */ new Date();
|
|
39048
|
-
const pipelineResult = await db.select().from(lifecyclePipelines).where(
|
|
39422
|
+
const pipelineResult = await db.select().from(lifecyclePipelines).where(eq9(lifecyclePipelines.taskId, taskId)).limit(1).all();
|
|
39049
39423
|
if (pipelineResult.length === 0) {
|
|
39050
39424
|
throw new CleoError(4 /* NOT_FOUND */, `No pipeline found for task ${taskId}`);
|
|
39051
39425
|
}
|
|
@@ -39060,21 +39434,21 @@ async function completePipeline(taskId, reason) {
|
|
|
39060
39434
|
stageUpdate.metadataJson = JSON.stringify({ completionReason: reason });
|
|
39061
39435
|
}
|
|
39062
39436
|
await db.update(lifecycleStages).set(stageUpdate).where(
|
|
39063
|
-
|
|
39064
|
-
|
|
39065
|
-
|
|
39437
|
+
and6(
|
|
39438
|
+
eq9(lifecycleStages.pipelineId, pipeline2.id),
|
|
39439
|
+
eq9(lifecycleStages.stageName, pipeline2.currentStageId)
|
|
39066
39440
|
)
|
|
39067
39441
|
).run();
|
|
39068
39442
|
}
|
|
39069
39443
|
await db.update(lifecyclePipelines).set({
|
|
39070
39444
|
status: "completed",
|
|
39071
39445
|
completedAt: now2.toISOString()
|
|
39072
|
-
}).where(
|
|
39446
|
+
}).where(eq9(lifecyclePipelines.id, pipeline2.id)).run();
|
|
39073
39447
|
}
|
|
39074
39448
|
async function cancelPipeline(taskId, reason) {
|
|
39075
39449
|
const db = await getDb();
|
|
39076
39450
|
const now2 = /* @__PURE__ */ new Date();
|
|
39077
|
-
const pipelineResult = await db.select().from(lifecyclePipelines).where(
|
|
39451
|
+
const pipelineResult = await db.select().from(lifecyclePipelines).where(eq9(lifecyclePipelines.taskId, taskId)).limit(1).all();
|
|
39078
39452
|
if (pipelineResult.length === 0) {
|
|
39079
39453
|
throw new CleoError(4 /* NOT_FOUND */, `No pipeline found for task ${taskId}`);
|
|
39080
39454
|
}
|
|
@@ -39091,20 +39465,20 @@ async function cancelPipeline(taskId, reason) {
|
|
|
39091
39465
|
blockedAt: now2.toISOString(),
|
|
39092
39466
|
blockReason: `Pipeline cancelled: ${reason}`
|
|
39093
39467
|
}).where(
|
|
39094
|
-
|
|
39095
|
-
|
|
39096
|
-
|
|
39468
|
+
and6(
|
|
39469
|
+
eq9(lifecycleStages.pipelineId, pipeline2.id),
|
|
39470
|
+
eq9(lifecycleStages.stageName, pipeline2.currentStageId)
|
|
39097
39471
|
)
|
|
39098
39472
|
).run();
|
|
39099
39473
|
}
|
|
39100
39474
|
await db.update(lifecyclePipelines).set({
|
|
39101
39475
|
status: "cancelled",
|
|
39102
39476
|
completedAt: now2.toISOString()
|
|
39103
|
-
}).where(
|
|
39477
|
+
}).where(eq9(lifecyclePipelines.id, pipeline2.id)).run();
|
|
39104
39478
|
}
|
|
39105
39479
|
async function pipelineExists(taskId) {
|
|
39106
39480
|
const db = await getDb();
|
|
39107
|
-
const result = await db.select({ count: sql9`count(*)` }).from(lifecyclePipelines).where(
|
|
39481
|
+
const result = await db.select({ count: sql9`count(*)` }).from(lifecyclePipelines).where(eq9(lifecyclePipelines.taskId, taskId)).all();
|
|
39108
39482
|
return (result[0]?.count || 0) > 0;
|
|
39109
39483
|
}
|
|
39110
39484
|
async function getPipelineStatistics() {
|
|
@@ -39148,12 +39522,12 @@ async function getPipelineStatistics() {
|
|
|
39148
39522
|
}
|
|
39149
39523
|
async function getPipelineStages(taskId) {
|
|
39150
39524
|
const db = await getDb();
|
|
39151
|
-
const pipelineResult = await db.select({ id: lifecyclePipelines.id }).from(lifecyclePipelines).where(
|
|
39525
|
+
const pipelineResult = await db.select({ id: lifecyclePipelines.id }).from(lifecyclePipelines).where(eq9(lifecyclePipelines.taskId, taskId)).limit(1).all();
|
|
39152
39526
|
if (pipelineResult.length === 0) {
|
|
39153
39527
|
throw new CleoError(4 /* NOT_FOUND */, `No pipeline found for task ${taskId}`);
|
|
39154
39528
|
}
|
|
39155
39529
|
const pipelineId = pipelineResult[0].id;
|
|
39156
|
-
const stages = await db.select().from(lifecycleStages).where(
|
|
39530
|
+
const stages = await db.select().from(lifecycleStages).where(eq9(lifecycleStages.pipelineId, pipelineId)).orderBy(asc3(lifecycleStages.sequence)).all();
|
|
39157
39531
|
return stages.map((stage) => ({
|
|
39158
39532
|
id: stage.id,
|
|
39159
39533
|
pipelineId: stage.pipelineId,
|
|
@@ -45454,9 +45828,9 @@ async function nexusRegister(projectPath, name2, permissions = "read") {
|
|
|
45454
45828
|
const projectHash = generateProjectHash(projectPath);
|
|
45455
45829
|
await nexusInit();
|
|
45456
45830
|
const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
45457
|
-
const { eq:
|
|
45831
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
45458
45832
|
const db = await getNexusDb2();
|
|
45459
|
-
const existingRows = await db.select().from(projectRegistry).where(
|
|
45833
|
+
const existingRows = await db.select().from(projectRegistry).where(eq17(projectRegistry.projectHash, projectHash));
|
|
45460
45834
|
const existing = existingRows[0];
|
|
45461
45835
|
if (existing?.permissions) {
|
|
45462
45836
|
throw new CleoError(
|
|
@@ -45465,7 +45839,7 @@ async function nexusRegister(projectPath, name2, permissions = "read") {
|
|
|
45465
45839
|
);
|
|
45466
45840
|
}
|
|
45467
45841
|
if (!existing) {
|
|
45468
|
-
const nameConflictRows = await db.select().from(projectRegistry).where(
|
|
45842
|
+
const nameConflictRows = await db.select().from(projectRegistry).where(eq17(projectRegistry.name, projectName));
|
|
45469
45843
|
if (nameConflictRows.length > 0) {
|
|
45470
45844
|
throw new CleoError(
|
|
45471
45845
|
6 /* VALIDATION_ERROR */,
|
|
@@ -45483,7 +45857,7 @@ async function nexusRegister(projectPath, name2, permissions = "read") {
|
|
|
45483
45857
|
taskCount: meta.taskCount,
|
|
45484
45858
|
labelsJson: JSON.stringify(meta.labels),
|
|
45485
45859
|
lastSeen: now2
|
|
45486
|
-
}).where(
|
|
45860
|
+
}).where(eq17(projectRegistry.projectHash, projectHash));
|
|
45487
45861
|
} else {
|
|
45488
45862
|
if (!projectId) {
|
|
45489
45863
|
projectId = randomUUID3();
|
|
@@ -45521,9 +45895,9 @@ async function nexusUnregister(nameOrHash) {
|
|
|
45521
45895
|
throw new CleoError(4 /* NOT_FOUND */, `Project not found in registry: ${nameOrHash}`);
|
|
45522
45896
|
}
|
|
45523
45897
|
const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
45524
|
-
const { eq:
|
|
45898
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
45525
45899
|
const db = await getNexusDb2();
|
|
45526
|
-
await db.delete(projectRegistry).where(
|
|
45900
|
+
await db.delete(projectRegistry).where(eq17(projectRegistry.projectHash, project.hash));
|
|
45527
45901
|
await writeNexusAudit({
|
|
45528
45902
|
action: "unregister",
|
|
45529
45903
|
projectHash: project.hash,
|
|
@@ -45545,9 +45919,9 @@ async function nexusList() {
|
|
|
45545
45919
|
async function nexusGetProject(nameOrHash) {
|
|
45546
45920
|
try {
|
|
45547
45921
|
const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
45548
|
-
const { eq:
|
|
45922
|
+
const { eq: eq17, or: or6 } = await import("drizzle-orm");
|
|
45549
45923
|
const db = await getNexusDb2();
|
|
45550
|
-
const rows = await db.select().from(projectRegistry).where(or6(
|
|
45924
|
+
const rows = await db.select().from(projectRegistry).where(or6(eq17(projectRegistry.projectHash, nameOrHash), eq17(projectRegistry.name, nameOrHash)));
|
|
45551
45925
|
const row = rows[0];
|
|
45552
45926
|
if (!row) return null;
|
|
45553
45927
|
return rowToProject(row);
|
|
@@ -45570,14 +45944,14 @@ async function nexusSync(nameOrHash) {
|
|
|
45570
45944
|
const meta = await readProjectMeta(project.path);
|
|
45571
45945
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
45572
45946
|
const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
45573
|
-
const { eq:
|
|
45947
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
45574
45948
|
const db = await getNexusDb2();
|
|
45575
45949
|
await db.update(projectRegistry).set({
|
|
45576
45950
|
taskCount: meta.taskCount,
|
|
45577
45951
|
labelsJson: JSON.stringify(meta.labels),
|
|
45578
45952
|
lastSync: now2,
|
|
45579
45953
|
lastSeen: now2
|
|
45580
|
-
}).where(
|
|
45954
|
+
}).where(eq17(projectRegistry.projectHash, project.hash));
|
|
45581
45955
|
await writeNexusAudit({
|
|
45582
45956
|
action: "sync",
|
|
45583
45957
|
projectHash: project.hash,
|
|
@@ -45591,7 +45965,7 @@ async function nexusSyncAll() {
|
|
|
45591
45965
|
let synced = 0;
|
|
45592
45966
|
let failed = 0;
|
|
45593
45967
|
const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
45594
|
-
const { eq:
|
|
45968
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
45595
45969
|
const db = await getNexusDb2();
|
|
45596
45970
|
for (const project of projects) {
|
|
45597
45971
|
try {
|
|
@@ -45602,7 +45976,7 @@ async function nexusSyncAll() {
|
|
|
45602
45976
|
labelsJson: JSON.stringify(meta.labels),
|
|
45603
45977
|
lastSync: now2,
|
|
45604
45978
|
lastSeen: now2
|
|
45605
|
-
}).where(
|
|
45979
|
+
}).where(eq17(projectRegistry.projectHash, project.hash));
|
|
45606
45980
|
synced++;
|
|
45607
45981
|
} catch {
|
|
45608
45982
|
failed++;
|
|
@@ -45622,9 +45996,9 @@ async function nexusSetPermission(nameOrHash, permission) {
|
|
|
45622
45996
|
throw new CleoError(4 /* NOT_FOUND */, `Project not found in registry: ${nameOrHash}`);
|
|
45623
45997
|
}
|
|
45624
45998
|
const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
45625
|
-
const { eq:
|
|
45999
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
45626
46000
|
const db = await getNexusDb2();
|
|
45627
|
-
await db.update(projectRegistry).set({ permissions: permission }).where(
|
|
46001
|
+
await db.update(projectRegistry).set({ permissions: permission }).where(eq17(projectRegistry.projectHash, project.hash));
|
|
45628
46002
|
await writeNexusAudit({
|
|
45629
46003
|
action: "set-permission",
|
|
45630
46004
|
projectHash: project.hash,
|
|
@@ -45640,12 +46014,12 @@ async function nexusReconcile(projectRoot) {
|
|
|
45640
46014
|
}
|
|
45641
46015
|
await nexusInit();
|
|
45642
46016
|
const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
|
|
45643
|
-
const { eq:
|
|
46017
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
45644
46018
|
const db = await getNexusDb2();
|
|
45645
46019
|
const projectId = await readProjectId(projectRoot);
|
|
45646
46020
|
const currentHash = generateProjectHash(projectRoot);
|
|
45647
46021
|
if (projectId) {
|
|
45648
|
-
const hashRows2 = await db.select().from(projectRegistry).where(
|
|
46022
|
+
const hashRows2 = await db.select().from(projectRegistry).where(eq17(projectRegistry.projectHash, currentHash));
|
|
45649
46023
|
const hashMatch2 = hashRows2[0];
|
|
45650
46024
|
if (hashMatch2 && hashMatch2.projectId !== projectId) {
|
|
45651
46025
|
await writeNexusAudit({
|
|
@@ -45664,12 +46038,12 @@ async function nexusReconcile(projectRoot) {
|
|
|
45664
46038
|
}
|
|
45665
46039
|
}
|
|
45666
46040
|
if (projectId) {
|
|
45667
|
-
const idRows = await db.select().from(projectRegistry).where(
|
|
46041
|
+
const idRows = await db.select().from(projectRegistry).where(eq17(projectRegistry.projectId, projectId));
|
|
45668
46042
|
const existing = idRows[0];
|
|
45669
46043
|
if (existing) {
|
|
45670
46044
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
45671
46045
|
if (existing.projectPath === projectRoot) {
|
|
45672
|
-
await db.update(projectRegistry).set({ lastSeen: now2 }).where(
|
|
46046
|
+
await db.update(projectRegistry).set({ lastSeen: now2 }).where(eq17(projectRegistry.projectId, projectId));
|
|
45673
46047
|
await writeNexusAudit({
|
|
45674
46048
|
action: "reconcile",
|
|
45675
46049
|
projectHash: currentHash,
|
|
@@ -45685,7 +46059,7 @@ async function nexusReconcile(projectRoot) {
|
|
|
45685
46059
|
projectPath: projectRoot,
|
|
45686
46060
|
projectHash: currentHash,
|
|
45687
46061
|
lastSeen: now2
|
|
45688
|
-
}).where(
|
|
46062
|
+
}).where(eq17(projectRegistry.projectId, projectId));
|
|
45689
46063
|
await writeNexusAudit({
|
|
45690
46064
|
action: "reconcile",
|
|
45691
46065
|
projectHash: currentHash,
|
|
@@ -45697,11 +46071,11 @@ async function nexusReconcile(projectRoot) {
|
|
|
45697
46071
|
return { status: "path_updated", oldPath, newPath: projectRoot };
|
|
45698
46072
|
}
|
|
45699
46073
|
}
|
|
45700
|
-
const hashRows = await db.select().from(projectRegistry).where(
|
|
46074
|
+
const hashRows = await db.select().from(projectRegistry).where(eq17(projectRegistry.projectHash, currentHash));
|
|
45701
46075
|
const hashMatch = hashRows[0];
|
|
45702
46076
|
if (hashMatch) {
|
|
45703
46077
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
45704
|
-
await db.update(projectRegistry).set({ lastSeen: now2 }).where(
|
|
46078
|
+
await db.update(projectRegistry).set({ lastSeen: now2 }).where(eq17(projectRegistry.projectHash, currentHash));
|
|
45705
46079
|
await writeNexusAudit({
|
|
45706
46080
|
action: "reconcile",
|
|
45707
46081
|
projectHash: currentHash,
|
|
@@ -46556,6 +46930,30 @@ function collectCleoFiles(cleoDir) {
|
|
|
46556
46930
|
walk(cleoDir);
|
|
46557
46931
|
return files.sort();
|
|
46558
46932
|
}
|
|
46933
|
+
async function getCleoGitRemotes(cleoDir) {
|
|
46934
|
+
const result = await cleoGitCommand(["remote"], cleoDir);
|
|
46935
|
+
if (!result.success || !result.stdout) return [];
|
|
46936
|
+
return result.stdout.split("\n").map((r) => r.trim()).filter(Boolean);
|
|
46937
|
+
}
|
|
46938
|
+
async function hasCleoGitPendingChanges(cleoDir) {
|
|
46939
|
+
const result = await cleoGitCommand(["status", "--porcelain"], cleoDir);
|
|
46940
|
+
if (!result.success) return false;
|
|
46941
|
+
return result.stdout.length > 0;
|
|
46942
|
+
}
|
|
46943
|
+
async function getLastSyncTimestamp(cleoDir) {
|
|
46944
|
+
const result = await cleoGitCommand(["reflog", "--format=%gs %ci", "HEAD"], cleoDir);
|
|
46945
|
+
if (!result.success || !result.stdout) return null;
|
|
46946
|
+
for (const line2 of result.stdout.split("\n")) {
|
|
46947
|
+
const trimmed = line2.trim();
|
|
46948
|
+
if (/^(fetch|push|pull)\b/i.test(trimmed)) {
|
|
46949
|
+
const isoMatch = trimmed.match(/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [+-]\d{4})$/);
|
|
46950
|
+
if (isoMatch?.[1]) {
|
|
46951
|
+
return new Date(isoMatch[1]).toISOString();
|
|
46952
|
+
}
|
|
46953
|
+
}
|
|
46954
|
+
}
|
|
46955
|
+
return null;
|
|
46956
|
+
}
|
|
46559
46957
|
async function getSharingStatus(cwd) {
|
|
46560
46958
|
const config2 = await loadConfig(cwd);
|
|
46561
46959
|
const sharing = config2.sharing;
|
|
@@ -46572,12 +46970,27 @@ async function getSharingStatus(cwd) {
|
|
|
46572
46970
|
ignored.push(file2);
|
|
46573
46971
|
}
|
|
46574
46972
|
}
|
|
46973
|
+
const hasGit = isCleoGitInitialized(cleoDir);
|
|
46974
|
+
let remotes = [];
|
|
46975
|
+
let pendingChanges = false;
|
|
46976
|
+
let lastSync = null;
|
|
46977
|
+
if (hasGit) {
|
|
46978
|
+
[remotes, pendingChanges, lastSync] = await Promise.all([
|
|
46979
|
+
getCleoGitRemotes(cleoDir),
|
|
46980
|
+
hasCleoGitPendingChanges(cleoDir),
|
|
46981
|
+
getLastSyncTimestamp(cleoDir)
|
|
46982
|
+
]);
|
|
46983
|
+
}
|
|
46575
46984
|
return {
|
|
46576
46985
|
mode: sharing.mode,
|
|
46577
46986
|
allowlist: sharing.commitAllowlist,
|
|
46578
46987
|
denylist: sharing.denylist,
|
|
46579
46988
|
tracked,
|
|
46580
|
-
ignored
|
|
46989
|
+
ignored,
|
|
46990
|
+
hasGit,
|
|
46991
|
+
remotes,
|
|
46992
|
+
pendingChanges,
|
|
46993
|
+
lastSync
|
|
46581
46994
|
};
|
|
46582
46995
|
}
|
|
46583
46996
|
function generateGitignoreEntries(sharing) {
|
|
@@ -46629,6 +47042,7 @@ var init_sharing = __esm({
|
|
|
46629
47042
|
"use strict";
|
|
46630
47043
|
init_config();
|
|
46631
47044
|
init_paths();
|
|
47045
|
+
init_git_checkpoint();
|
|
46632
47046
|
GITIGNORE_START = "# CLEO:SHARING:START - Auto-managed by cleo sharing sync";
|
|
46633
47047
|
GITIGNORE_END = "# CLEO:SHARING:END";
|
|
46634
47048
|
}
|
|
@@ -46636,25 +47050,25 @@ var init_sharing = __esm({
|
|
|
46636
47050
|
|
|
46637
47051
|
// packages/core/src/reconciliation/link-store.ts
|
|
46638
47052
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
46639
|
-
import { and as
|
|
47053
|
+
import { and as and7, eq as eq10 } from "drizzle-orm";
|
|
46640
47054
|
async function getLinksByProvider(providerId, cwd) {
|
|
46641
47055
|
const db = await getDb(cwd);
|
|
46642
|
-
const rows = await db.select().from(externalTaskLinks).where(
|
|
47056
|
+
const rows = await db.select().from(externalTaskLinks).where(eq10(externalTaskLinks.providerId, providerId));
|
|
46643
47057
|
return rows.map(rowToLink);
|
|
46644
47058
|
}
|
|
46645
47059
|
async function getLinkByExternalId(providerId, externalId, cwd) {
|
|
46646
47060
|
const db = await getDb(cwd);
|
|
46647
47061
|
const rows = await db.select().from(externalTaskLinks).where(
|
|
46648
|
-
|
|
46649
|
-
|
|
46650
|
-
|
|
47062
|
+
and7(
|
|
47063
|
+
eq10(externalTaskLinks.providerId, providerId),
|
|
47064
|
+
eq10(externalTaskLinks.externalId, externalId)
|
|
46651
47065
|
)
|
|
46652
47066
|
);
|
|
46653
47067
|
return rows.length > 0 ? rowToLink(rows[0]) : null;
|
|
46654
47068
|
}
|
|
46655
47069
|
async function getLinksByTaskId(taskId, cwd) {
|
|
46656
47070
|
const db = await getDb(cwd);
|
|
46657
|
-
const rows = await db.select().from(externalTaskLinks).where(
|
|
47071
|
+
const rows = await db.select().from(externalTaskLinks).where(eq10(externalTaskLinks.taskId, taskId));
|
|
46658
47072
|
return rows.map(rowToLink);
|
|
46659
47073
|
}
|
|
46660
47074
|
async function createLink(params, cwd) {
|
|
@@ -46698,11 +47112,11 @@ async function touchLink(linkId, updates, cwd) {
|
|
|
46698
47112
|
if (updates?.metadata !== void 0) {
|
|
46699
47113
|
values.metadataJson = JSON.stringify(updates.metadata);
|
|
46700
47114
|
}
|
|
46701
|
-
await db.update(externalTaskLinks).set(values).where(
|
|
47115
|
+
await db.update(externalTaskLinks).set(values).where(eq10(externalTaskLinks.id, linkId));
|
|
46702
47116
|
}
|
|
46703
47117
|
async function removeLinksByProvider(providerId, cwd) {
|
|
46704
47118
|
const db = await getDb(cwd);
|
|
46705
|
-
const result = await db.delete(externalTaskLinks).where(
|
|
47119
|
+
const result = await db.delete(externalTaskLinks).where(eq10(externalTaskLinks.providerId, providerId));
|
|
46706
47120
|
return Number(result.changes);
|
|
46707
47121
|
}
|
|
46708
47122
|
function rowToLink(row) {
|
|
@@ -50656,7 +51070,7 @@ import { execFileSync as execFileSync7 } from "node:child_process";
|
|
|
50656
51070
|
import { existsSync as existsSync64, renameSync as renameSync5 } from "node:fs";
|
|
50657
51071
|
import { readFile as readFile12 } from "node:fs/promises";
|
|
50658
51072
|
import { join as join67 } from "node:path";
|
|
50659
|
-
import { and as
|
|
51073
|
+
import { and as and8, count, desc as desc4, eq as eq11 } from "drizzle-orm";
|
|
50660
51074
|
async function getDb2(cwd) {
|
|
50661
51075
|
const { getDb: _getDb } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
50662
51076
|
return _getDb(cwd);
|
|
@@ -50725,7 +51139,7 @@ function rowToManifest(row) {
|
|
|
50725
51139
|
}
|
|
50726
51140
|
async function findLatestPushedVersion(cwd) {
|
|
50727
51141
|
const db = await getDb2(cwd);
|
|
50728
|
-
const rows = await db.select({ version: releaseManifests.version }).from(releaseManifests).where(
|
|
51142
|
+
const rows = await db.select({ version: releaseManifests.version }).from(releaseManifests).where(eq11(releaseManifests.status, "pushed")).orderBy(desc4(releaseManifests.pushedAt)).limit(1).all();
|
|
50729
51143
|
return rows[0]?.version;
|
|
50730
51144
|
}
|
|
50731
51145
|
async function prepareRelease(version2, tasks2, notes, loadTasksFn, cwd) {
|
|
@@ -50737,7 +51151,7 @@ async function prepareRelease(version2, tasks2, notes, loadTasksFn, cwd) {
|
|
|
50737
51151
|
}
|
|
50738
51152
|
const normalizedVersion = normalizeVersion(version2);
|
|
50739
51153
|
const db = await getDb2(cwd);
|
|
50740
|
-
const existing = await db.select().from(releaseManifests).where(
|
|
51154
|
+
const existing = await db.select().from(releaseManifests).where(eq11(releaseManifests.version, normalizedVersion)).limit(1).all();
|
|
50741
51155
|
if (existing.length > 0) {
|
|
50742
51156
|
throw new Error(`Release ${normalizedVersion} already exists (status: ${existing[0].status})`);
|
|
50743
51157
|
}
|
|
@@ -50777,7 +51191,7 @@ async function generateReleaseChangelog(version2, loadTasksFn, cwd) {
|
|
|
50777
51191
|
}
|
|
50778
51192
|
const normalizedVersion = normalizeVersion(version2);
|
|
50779
51193
|
const db = await getDb2(cwd);
|
|
50780
|
-
const rows = await db.select().from(releaseManifests).where(
|
|
51194
|
+
const rows = await db.select().from(releaseManifests).where(eq11(releaseManifests.version, normalizedVersion)).limit(1).all();
|
|
50781
51195
|
if (rows.length === 0) {
|
|
50782
51196
|
throw new Error(`Release ${normalizedVersion} not found`);
|
|
50783
51197
|
}
|
|
@@ -50914,7 +51328,7 @@ async function generateReleaseChangelog(version2, loadTasksFn, cwd) {
|
|
|
50914
51328
|
sections.push("");
|
|
50915
51329
|
}
|
|
50916
51330
|
const changelog = sections.join("\n");
|
|
50917
|
-
await db.update(releaseManifests).set({ changelog }).where(
|
|
51331
|
+
await db.update(releaseManifests).set({ changelog }).where(eq11(releaseManifests.version, normalizedVersion)).run();
|
|
50918
51332
|
const changelogPath = join67(cwd ?? process.cwd(), "CHANGELOG.md");
|
|
50919
51333
|
let existingChangelogContent = "";
|
|
50920
51334
|
try {
|
|
@@ -50952,8 +51366,8 @@ async function listManifestReleases(optionsOrCwd, cwd) {
|
|
|
50952
51366
|
const db = await getDb2(effectiveCwd);
|
|
50953
51367
|
const totalRow = await db.select({ count: count() }).from(releaseManifests).get();
|
|
50954
51368
|
const total = totalRow?.count ?? 0;
|
|
50955
|
-
const conditions = options.status ? [
|
|
50956
|
-
const whereClause = conditions.length > 0 ?
|
|
51369
|
+
const conditions = options.status ? [eq11(releaseManifests.status, options.status)] : [];
|
|
51370
|
+
const whereClause = conditions.length > 0 ? and8(...conditions) : void 0;
|
|
50957
51371
|
const filteredRow = await db.select({ count: count() }).from(releaseManifests).where(whereClause).get();
|
|
50958
51372
|
const filtered = filteredRow?.count ?? 0;
|
|
50959
51373
|
let query = db.select().from(releaseManifests).where(whereClause).orderBy(desc4(releaseManifests.createdAt));
|
|
@@ -50984,7 +51398,7 @@ async function showManifestRelease(version2, cwd) {
|
|
|
50984
51398
|
}
|
|
50985
51399
|
const normalizedVersion = normalizeVersion(version2);
|
|
50986
51400
|
const db = await getDb2(cwd);
|
|
50987
|
-
const rows = await db.select().from(releaseManifests).where(
|
|
51401
|
+
const rows = await db.select().from(releaseManifests).where(eq11(releaseManifests.version, normalizedVersion)).limit(1).all();
|
|
50988
51402
|
if (rows.length === 0) {
|
|
50989
51403
|
throw new Error(`Release ${normalizedVersion} not found`);
|
|
50990
51404
|
}
|
|
@@ -50996,7 +51410,7 @@ async function commitRelease(version2, cwd) {
|
|
|
50996
51410
|
}
|
|
50997
51411
|
const normalizedVersion = normalizeVersion(version2);
|
|
50998
51412
|
const db = await getDb2(cwd);
|
|
50999
|
-
const rows = await db.select().from(releaseManifests).where(
|
|
51413
|
+
const rows = await db.select().from(releaseManifests).where(eq11(releaseManifests.version, normalizedVersion)).limit(1).all();
|
|
51000
51414
|
if (rows.length === 0) {
|
|
51001
51415
|
throw new Error(`Release ${normalizedVersion} not found`);
|
|
51002
51416
|
}
|
|
@@ -51006,7 +51420,7 @@ async function commitRelease(version2, cwd) {
|
|
|
51006
51420
|
);
|
|
51007
51421
|
}
|
|
51008
51422
|
const committedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
51009
|
-
await db.update(releaseManifests).set({ status: "committed", committedAt }).where(
|
|
51423
|
+
await db.update(releaseManifests).set({ status: "committed", committedAt }).where(eq11(releaseManifests.version, normalizedVersion)).run();
|
|
51010
51424
|
return { version: normalizedVersion, status: "committed", committedAt };
|
|
51011
51425
|
}
|
|
51012
51426
|
async function tagRelease(version2, cwd) {
|
|
@@ -51015,12 +51429,12 @@ async function tagRelease(version2, cwd) {
|
|
|
51015
51429
|
}
|
|
51016
51430
|
const normalizedVersion = normalizeVersion(version2);
|
|
51017
51431
|
const db = await getDb2(cwd);
|
|
51018
|
-
const rows = await db.select().from(releaseManifests).where(
|
|
51432
|
+
const rows = await db.select().from(releaseManifests).where(eq11(releaseManifests.version, normalizedVersion)).limit(1).all();
|
|
51019
51433
|
if (rows.length === 0) {
|
|
51020
51434
|
throw new Error(`Release ${normalizedVersion} not found`);
|
|
51021
51435
|
}
|
|
51022
51436
|
const taggedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
51023
|
-
await db.update(releaseManifests).set({ status: "tagged", taggedAt }).where(
|
|
51437
|
+
await db.update(releaseManifests).set({ status: "tagged", taggedAt }).where(eq11(releaseManifests.version, normalizedVersion)).run();
|
|
51024
51438
|
return { version: normalizedVersion, status: "tagged", taggedAt };
|
|
51025
51439
|
}
|
|
51026
51440
|
async function runReleaseGates(version2, loadTasksFn, cwd, opts) {
|
|
@@ -51029,7 +51443,7 @@ async function runReleaseGates(version2, loadTasksFn, cwd, opts) {
|
|
|
51029
51443
|
}
|
|
51030
51444
|
const normalizedVersion = normalizeVersion(version2);
|
|
51031
51445
|
const db = await getDb2(cwd);
|
|
51032
|
-
const rows = await db.select().from(releaseManifests).where(
|
|
51446
|
+
const rows = await db.select().from(releaseManifests).where(eq11(releaseManifests.version, normalizedVersion)).limit(1).all();
|
|
51033
51447
|
if (rows.length === 0) {
|
|
51034
51448
|
throw new Error(`Release ${normalizedVersion} not found`);
|
|
51035
51449
|
}
|
|
@@ -51177,7 +51591,7 @@ async function cancelRelease(version2, projectRoot) {
|
|
|
51177
51591
|
}
|
|
51178
51592
|
const normalizedVersion = normalizeVersion(version2);
|
|
51179
51593
|
const db = await getDb2(projectRoot);
|
|
51180
|
-
const rows = await db.select().from(releaseManifests).where(
|
|
51594
|
+
const rows = await db.select().from(releaseManifests).where(eq11(releaseManifests.version, normalizedVersion)).limit(1).all();
|
|
51181
51595
|
if (rows.length === 0) {
|
|
51182
51596
|
return {
|
|
51183
51597
|
success: false,
|
|
@@ -51194,7 +51608,7 @@ async function cancelRelease(version2, projectRoot) {
|
|
|
51194
51608
|
version: normalizedVersion
|
|
51195
51609
|
};
|
|
51196
51610
|
}
|
|
51197
|
-
await db.delete(releaseManifests).where(
|
|
51611
|
+
await db.delete(releaseManifests).where(eq11(releaseManifests.version, normalizedVersion)).run();
|
|
51198
51612
|
return {
|
|
51199
51613
|
success: true,
|
|
51200
51614
|
message: `Release ${normalizedVersion} cancelled and removed`,
|
|
@@ -51207,12 +51621,12 @@ async function rollbackRelease(version2, reason, cwd) {
|
|
|
51207
51621
|
}
|
|
51208
51622
|
const normalizedVersion = normalizeVersion(version2);
|
|
51209
51623
|
const db = await getDb2(cwd);
|
|
51210
|
-
const rows = await db.select().from(releaseManifests).where(
|
|
51624
|
+
const rows = await db.select().from(releaseManifests).where(eq11(releaseManifests.version, normalizedVersion)).limit(1).all();
|
|
51211
51625
|
if (rows.length === 0) {
|
|
51212
51626
|
throw new Error(`Release ${normalizedVersion} not found`);
|
|
51213
51627
|
}
|
|
51214
51628
|
const previousStatus = rows[0].status;
|
|
51215
|
-
await db.update(releaseManifests).set({ status: "rolled_back" }).where(
|
|
51629
|
+
await db.update(releaseManifests).set({ status: "rolled_back" }).where(eq11(releaseManifests.version, normalizedVersion)).run();
|
|
51216
51630
|
return {
|
|
51217
51631
|
version: normalizedVersion,
|
|
51218
51632
|
previousStatus,
|
|
@@ -51322,7 +51736,7 @@ async function markReleasePushed(version2, pushedAt, cwd, provenance) {
|
|
|
51322
51736
|
pushedAt,
|
|
51323
51737
|
...provenance?.commitSha != null ? { commitSha: provenance.commitSha } : {},
|
|
51324
51738
|
...provenance?.gitTag != null ? { gitTag: provenance.gitTag } : {}
|
|
51325
|
-
}).where(
|
|
51739
|
+
}).where(eq11(releaseManifests.version, normalizedVersion)).run();
|
|
51326
51740
|
}
|
|
51327
51741
|
async function migrateReleasesJsonToSqlite(projectRoot) {
|
|
51328
51742
|
const releasesPath = join67(getCleoDirAbsolute(projectRoot), "releases.json");
|
|
@@ -51342,7 +51756,7 @@ async function migrateReleasesJsonToSqlite(projectRoot) {
|
|
|
51342
51756
|
const db = await getDb2(projectRoot);
|
|
51343
51757
|
let migrated = 0;
|
|
51344
51758
|
for (const r of raw.releases) {
|
|
51345
|
-
const existing = await db.select({ id: releaseManifests.id }).from(releaseManifests).where(
|
|
51759
|
+
const existing = await db.select({ id: releaseManifests.id }).from(releaseManifests).where(eq11(releaseManifests.version, r.version)).limit(1).all();
|
|
51346
51760
|
if (existing.length > 0) continue;
|
|
51347
51761
|
const id = `rel-${r.version.replace(/[^a-z0-9]/gi, "-")}`;
|
|
51348
51762
|
await db.insert(releaseManifests).values({
|
|
@@ -57098,7 +57512,7 @@ async function queryTasks(cwd, since) {
|
|
|
57098
57512
|
try {
|
|
57099
57513
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
57100
57514
|
const { tasks: tasks2 } = await Promise.resolve().then(() => (init_tasks_schema(), tasks_schema_exports));
|
|
57101
|
-
const { and:
|
|
57515
|
+
const { and: and12, gte: gte4 } = await import("drizzle-orm");
|
|
57102
57516
|
const db = await getDb4(cwd);
|
|
57103
57517
|
const conditions = [];
|
|
57104
57518
|
if (since) {
|
|
@@ -57112,7 +57526,7 @@ async function queryTasks(cwd, since) {
|
|
|
57112
57526
|
sessionId: tasks2.sessionId,
|
|
57113
57527
|
completedAt: tasks2.completedAt,
|
|
57114
57528
|
createdAt: tasks2.createdAt
|
|
57115
|
-
}).from(tasks2).where(conditions.length > 0 ?
|
|
57529
|
+
}).from(tasks2).where(conditions.length > 0 ? and12(...conditions) : void 0).all();
|
|
57116
57530
|
return rows;
|
|
57117
57531
|
} catch (err) {
|
|
57118
57532
|
log7.warn({ err }, "Failed to query tasks for workflow telemetry");
|
|
@@ -57123,7 +57537,7 @@ async function queryCompletionAuditRows(cwd, since) {
|
|
|
57123
57537
|
try {
|
|
57124
57538
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
57125
57539
|
const { auditLog: auditLog2 } = await Promise.resolve().then(() => (init_tasks_schema(), tasks_schema_exports));
|
|
57126
|
-
const { and:
|
|
57540
|
+
const { and: and12, gte: gte4 } = await import("drizzle-orm");
|
|
57127
57541
|
const db = await getDb4(cwd);
|
|
57128
57542
|
const conditions = [];
|
|
57129
57543
|
if (since) conditions.push(gte4(auditLog2.timestamp, since));
|
|
@@ -57135,7 +57549,7 @@ async function queryCompletionAuditRows(cwd, since) {
|
|
|
57135
57549
|
afterJson: auditLog2.afterJson,
|
|
57136
57550
|
operation: auditLog2.operation,
|
|
57137
57551
|
domain: auditLog2.domain
|
|
57138
|
-
}).from(auditLog2).where(conditions.length > 0 ?
|
|
57552
|
+
}).from(auditLog2).where(conditions.length > 0 ? and12(...conditions) : void 0).orderBy(auditLog2.timestamp).all();
|
|
57139
57553
|
return allRows.filter((row) => {
|
|
57140
57554
|
const isComplete = row.action === "task_completed" || row.action === "complete" || row.operation === "complete" && row.domain === "tasks";
|
|
57141
57555
|
if (!isComplete && row.afterJson) {
|
|
@@ -66584,46 +66998,68 @@ async function bootstrapGlobalCleo(options) {
|
|
|
66584
66998
|
await installSkillsGlobally(ctx);
|
|
66585
66999
|
await installAgentDefinitionGlobally(ctx);
|
|
66586
67000
|
await installProviderAdapters(ctx, options?.packageRoot);
|
|
67001
|
+
await verifyBootstrapHealth(ctx);
|
|
66587
67002
|
return ctx;
|
|
66588
67003
|
}
|
|
67004
|
+
async function writeTemplateTo(content, destPath, isDryRun) {
|
|
67005
|
+
if (isDryRun) return false;
|
|
67006
|
+
const { dirname: dirname25 } = await import("node:path");
|
|
67007
|
+
await mkdir17(dirname25(destPath), { recursive: true });
|
|
67008
|
+
await writeFile12(destPath, content);
|
|
67009
|
+
return true;
|
|
67010
|
+
}
|
|
66589
67011
|
async function ensureGlobalTemplatesBootstrap(ctx, packageRootOverride) {
|
|
66590
67012
|
const globalTemplatesDir = getCleoTemplatesDir();
|
|
66591
67013
|
if (!ctx.isDryRun) {
|
|
66592
67014
|
await mkdir17(globalTemplatesDir, { recursive: true });
|
|
66593
67015
|
}
|
|
67016
|
+
let templateContent = null;
|
|
66594
67017
|
try {
|
|
66595
67018
|
const pkgRoot = packageRootOverride ?? getPackageRoot();
|
|
66596
67019
|
const templatePath = join104(pkgRoot, "templates", "CLEO-INJECTION.md");
|
|
66597
67020
|
if (existsSync104(templatePath)) {
|
|
66598
|
-
|
|
66599
|
-
const destPath = join104(globalTemplatesDir, "CLEO-INJECTION.md");
|
|
66600
|
-
if (!ctx.isDryRun) {
|
|
66601
|
-
await writeFile12(destPath, content);
|
|
66602
|
-
}
|
|
66603
|
-
ctx.created.push(
|
|
66604
|
-
`~/.cleo/templates/CLEO-INJECTION.md (${ctx.isDryRun ? "would refresh" : "refreshed"})`
|
|
66605
|
-
);
|
|
66606
|
-
} else {
|
|
66607
|
-
try {
|
|
66608
|
-
const { getInjectionTemplateContent: getInjectionTemplateContent2 } = await Promise.resolve().then(() => (init_injection(), injection_exports));
|
|
66609
|
-
const content = getInjectionTemplateContent2();
|
|
66610
|
-
if (content) {
|
|
66611
|
-
const destPath = join104(globalTemplatesDir, "CLEO-INJECTION.md");
|
|
66612
|
-
if (!ctx.isDryRun) {
|
|
66613
|
-
await writeFile12(destPath, content);
|
|
66614
|
-
}
|
|
66615
|
-
ctx.created.push(
|
|
66616
|
-
`~/.cleo/templates/CLEO-INJECTION.md (${ctx.isDryRun ? "would refresh" : "refreshed"} from embedded)`
|
|
66617
|
-
);
|
|
66618
|
-
}
|
|
66619
|
-
} catch {
|
|
66620
|
-
ctx.warnings.push("Could not refresh CLEO-INJECTION.md template");
|
|
66621
|
-
}
|
|
67021
|
+
templateContent = readFileSync77(templatePath, "utf-8");
|
|
66622
67022
|
}
|
|
66623
67023
|
} catch {
|
|
67024
|
+
}
|
|
67025
|
+
if (!templateContent) {
|
|
67026
|
+
try {
|
|
67027
|
+
const { getInjectionTemplateContent: getInjectionTemplateContent2 } = await Promise.resolve().then(() => (init_injection(), injection_exports));
|
|
67028
|
+
templateContent = getInjectionTemplateContent2() ?? null;
|
|
67029
|
+
} catch {
|
|
67030
|
+
ctx.warnings.push("Could not refresh CLEO-INJECTION.md template");
|
|
67031
|
+
return;
|
|
67032
|
+
}
|
|
67033
|
+
}
|
|
67034
|
+
if (!templateContent) {
|
|
66624
67035
|
ctx.warnings.push("Could not refresh CLEO-INJECTION.md template");
|
|
67036
|
+
return;
|
|
67037
|
+
}
|
|
67038
|
+
const xdgDest = join104(globalTemplatesDir, "CLEO-INJECTION.md");
|
|
67039
|
+
const xdgWritten = await writeTemplateTo(templateContent, xdgDest, ctx.isDryRun);
|
|
67040
|
+
ctx.created.push(
|
|
67041
|
+
`${getCleoTemplatesTildePath()}/CLEO-INJECTION.md (${xdgWritten ? "refreshed" : "would refresh"})`
|
|
67042
|
+
);
|
|
67043
|
+
const home = homedir6();
|
|
67044
|
+
const legacyTemplatesDir = join104(home, ".cleo", "templates");
|
|
67045
|
+
if (legacyTemplatesDir !== globalTemplatesDir && existsSync104(join104(home, ".cleo"))) {
|
|
67046
|
+
const legacyDest = join104(legacyTemplatesDir, "CLEO-INJECTION.md");
|
|
67047
|
+
const legacyWritten = await writeTemplateTo(templateContent, legacyDest, ctx.isDryRun);
|
|
67048
|
+
if (legacyWritten) {
|
|
67049
|
+
ctx.created.push("~/.cleo/templates/CLEO-INJECTION.md (legacy sync)");
|
|
67050
|
+
}
|
|
66625
67051
|
}
|
|
66626
67052
|
}
|
|
67053
|
+
function sanitizeCaampFile(content) {
|
|
67054
|
+
let cleaned = content.replace(/(<!-- CAAMP:END -->)\s*(<!-- CAAMP:END -->)/g, "$1");
|
|
67055
|
+
cleaned = cleaned.replace(
|
|
67056
|
+
/<!-- CAAMP:END -->\s*[A-Z][A-Za-z-]*\.md\s*(?:<!-- CAAMP:END -->)?/g,
|
|
67057
|
+
"<!-- CAAMP:END -->"
|
|
67058
|
+
);
|
|
67059
|
+
cleaned = cleaned.replace(/^[A-Z][A-Za-z-]*\.md\s*$/gm, "");
|
|
67060
|
+
cleaned = cleaned.replace(/\n{3,}/g, "\n\n");
|
|
67061
|
+
return cleaned.trim() + "\n";
|
|
67062
|
+
}
|
|
66627
67063
|
async function injectAgentsHub(ctx) {
|
|
66628
67064
|
const globalAgentsDir = getAgentsHome();
|
|
66629
67065
|
const globalAgentsMd = join104(globalAgentsDir, "AGENTS.md");
|
|
@@ -66637,13 +67073,23 @@ async function injectAgentsHub(ctx) {
|
|
|
66637
67073
|
/\n?<!-- CLEO:START[^>]*-->[\s\S]*?<!-- CLEO:END -->\n?/g,
|
|
66638
67074
|
""
|
|
66639
67075
|
);
|
|
66640
|
-
|
|
66641
|
-
|
|
67076
|
+
const sanitized = sanitizeCaampFile(stripped);
|
|
67077
|
+
if (sanitized !== content) {
|
|
67078
|
+
await writeFile12(globalAgentsMd, sanitized, "utf8");
|
|
67079
|
+
ctx.created.push("~/.agents/AGENTS.md (sanitized CAAMP corruption)");
|
|
66642
67080
|
}
|
|
66643
67081
|
}
|
|
66644
67082
|
const templateRef = `@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`;
|
|
66645
67083
|
const action = await inject2(globalAgentsMd, templateRef);
|
|
66646
67084
|
ctx.created.push(`~/.agents/AGENTS.md (${action})`);
|
|
67085
|
+
const postContent = await readFile19(globalAgentsMd, "utf8");
|
|
67086
|
+
const caampBlocks = postContent.match(/<!-- CAAMP:START -->/g);
|
|
67087
|
+
const caampEnds = postContent.match(/<!-- CAAMP:END -->/g);
|
|
67088
|
+
if (caampBlocks && caampEnds && caampBlocks.length !== caampEnds.length) {
|
|
67089
|
+
ctx.warnings.push(
|
|
67090
|
+
`~/.agents/AGENTS.md has mismatched CAAMP markers (${caampBlocks.length} START vs ${caampEnds.length} END)`
|
|
67091
|
+
);
|
|
67092
|
+
}
|
|
66647
67093
|
} else {
|
|
66648
67094
|
ctx.created.push("~/.agents/AGENTS.md (would create/update CAAMP block)");
|
|
66649
67095
|
}
|
|
@@ -66777,6 +67223,45 @@ async function installProviderAdapters(ctx, packageRootOverride) {
|
|
|
66777
67223
|
);
|
|
66778
67224
|
}
|
|
66779
67225
|
}
|
|
67226
|
+
async function verifyBootstrapHealth(ctx) {
|
|
67227
|
+
if (ctx.isDryRun) return;
|
|
67228
|
+
try {
|
|
67229
|
+
const xdgTemplatePath = join104(getCleoTemplatesDir(), "CLEO-INJECTION.md");
|
|
67230
|
+
const agentsMd = join104(getAgentsHome(), "AGENTS.md");
|
|
67231
|
+
if (!existsSync104(xdgTemplatePath)) {
|
|
67232
|
+
ctx.warnings.push("Health: XDG template missing after bootstrap");
|
|
67233
|
+
return;
|
|
67234
|
+
}
|
|
67235
|
+
const xdgContent = await readFile19(xdgTemplatePath, "utf8");
|
|
67236
|
+
const xdgVersion = xdgContent.match(/^Version:\s*(.+)$/m)?.[1]?.trim();
|
|
67237
|
+
const home = homedir6();
|
|
67238
|
+
const legacyTemplatePath = join104(home, ".cleo", "templates", "CLEO-INJECTION.md");
|
|
67239
|
+
if (existsSync104(legacyTemplatePath)) {
|
|
67240
|
+
const legacyContent = await readFile19(legacyTemplatePath, "utf8");
|
|
67241
|
+
const legacyVersion = legacyContent.match(/^Version:\s*(.+)$/m)?.[1]?.trim();
|
|
67242
|
+
if (legacyVersion !== xdgVersion) {
|
|
67243
|
+
ctx.warnings.push(
|
|
67244
|
+
`Health: Legacy template version (${legacyVersion}) != XDG version (${xdgVersion})`
|
|
67245
|
+
);
|
|
67246
|
+
}
|
|
67247
|
+
}
|
|
67248
|
+
if (existsSync104(agentsMd)) {
|
|
67249
|
+
const agentsContent = await readFile19(agentsMd, "utf8");
|
|
67250
|
+
const expectedRef = `@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`;
|
|
67251
|
+
if (!agentsContent.includes(expectedRef)) {
|
|
67252
|
+
ctx.warnings.push(`Health: ~/.agents/AGENTS.md does not reference ${expectedRef}`);
|
|
67253
|
+
}
|
|
67254
|
+
const outsideCaamp = agentsContent.replace(
|
|
67255
|
+
/<!-- CAAMP:START -->[\s\S]*?<!-- CAAMP:END -->/g,
|
|
67256
|
+
""
|
|
67257
|
+
);
|
|
67258
|
+
if (/[A-Z][A-Za-z-]*\.md/.test(outsideCaamp)) {
|
|
67259
|
+
ctx.warnings.push("Health: ~/.agents/AGENTS.md has orphaned content outside CAAMP blocks");
|
|
67260
|
+
}
|
|
67261
|
+
}
|
|
67262
|
+
} catch {
|
|
67263
|
+
}
|
|
67264
|
+
}
|
|
66780
67265
|
var init_bootstrap = __esm({
|
|
66781
67266
|
"packages/core/src/bootstrap.ts"() {
|
|
66782
67267
|
"use strict";
|
|
@@ -66793,6 +67278,8 @@ var init_cleo = __esm({
|
|
|
66793
67278
|
"use strict";
|
|
66794
67279
|
init_export();
|
|
66795
67280
|
init_import();
|
|
67281
|
+
init_agents();
|
|
67282
|
+
init_intelligence();
|
|
66796
67283
|
init_lifecycle2();
|
|
66797
67284
|
init_brain_retrieval();
|
|
66798
67285
|
init_brain_search();
|
|
@@ -66807,6 +67294,7 @@ var init_cleo = __esm({
|
|
|
66807
67294
|
init_sessions();
|
|
66808
67295
|
init_sticky();
|
|
66809
67296
|
init_data_accessor();
|
|
67297
|
+
init_task_work();
|
|
66810
67298
|
init_add();
|
|
66811
67299
|
init_archive2();
|
|
66812
67300
|
init_complete();
|
|
@@ -66878,7 +67366,10 @@ var init_cleo = __esm({
|
|
|
66878
67366
|
),
|
|
66879
67367
|
complete: (p) => completeTask({ taskId: p.taskId, notes: p.notes }, root, store),
|
|
66880
67368
|
delete: (p) => deleteTask({ taskId: p.taskId, force: p.force }, root, store),
|
|
66881
|
-
archive: (p) => archiveTasks({ before: p?.before, taskIds: p?.taskIds, dryRun: p?.dryRun }, root, store)
|
|
67369
|
+
archive: (p) => archiveTasks({ before: p?.before, taskIds: p?.taskIds, dryRun: p?.dryRun }, root, store),
|
|
67370
|
+
start: (taskId) => startTask(taskId, root, store),
|
|
67371
|
+
stop: () => stopTask(root, store),
|
|
67372
|
+
current: () => currentTask(root, store)
|
|
66882
67373
|
};
|
|
66883
67374
|
}
|
|
66884
67375
|
// === Sessions ===
|
|
@@ -66886,7 +67377,11 @@ var init_cleo = __esm({
|
|
|
66886
67377
|
const root = this.projectRoot;
|
|
66887
67378
|
const store = this._store ?? void 0;
|
|
66888
67379
|
return {
|
|
66889
|
-
start: (p) => startSession(
|
|
67380
|
+
start: (p) => startSession(
|
|
67381
|
+
{ name: p.name, scope: p.scope, agent: p.agent, startTask: p.startTask },
|
|
67382
|
+
root,
|
|
67383
|
+
store
|
|
67384
|
+
),
|
|
66890
67385
|
end: (p) => endSession({ note: p?.note }, root, store),
|
|
66891
67386
|
status: () => sessionStatus(root, store),
|
|
66892
67387
|
resume: (id) => resumeSession(id, root, store),
|
|
@@ -67024,6 +67519,35 @@ var init_cleo = __esm({
|
|
|
67024
67519
|
sharingStatus: () => getSharingStatus()
|
|
67025
67520
|
};
|
|
67026
67521
|
}
|
|
67522
|
+
// === Agents ===
|
|
67523
|
+
get agents() {
|
|
67524
|
+
const root = this.projectRoot;
|
|
67525
|
+
return {
|
|
67526
|
+
register: (opts) => registerAgent(opts, root),
|
|
67527
|
+
deregister: (agentId) => deregisterAgent(agentId, root),
|
|
67528
|
+
health: (agentId) => checkAgentHealth2(agentId, void 0, root),
|
|
67529
|
+
detectCrashed: (thresholdMs) => detectCrashedAgents(thresholdMs, root),
|
|
67530
|
+
recordHeartbeat: (agentId) => heartbeat(agentId, root),
|
|
67531
|
+
capacity: (agentId) => getAgentCapacity(agentId, root),
|
|
67532
|
+
isOverloaded: (threshold) => isOverloaded(threshold, root),
|
|
67533
|
+
list: (p) => listAgentInstances(
|
|
67534
|
+
{
|
|
67535
|
+
status: p?.status,
|
|
67536
|
+
agentType: p?.agentType
|
|
67537
|
+
},
|
|
67538
|
+
root
|
|
67539
|
+
)
|
|
67540
|
+
};
|
|
67541
|
+
}
|
|
67542
|
+
// === Intelligence ===
|
|
67543
|
+
get intelligence() {
|
|
67544
|
+
const root = this.projectRoot;
|
|
67545
|
+
const store = this._store ?? void 0;
|
|
67546
|
+
return {
|
|
67547
|
+
predictImpact: (change) => predictImpact(change, root, store ?? void 0),
|
|
67548
|
+
blastRadius: (taskId) => calculateBlastRadius(taskId, store ?? void 0, root)
|
|
67549
|
+
};
|
|
67550
|
+
}
|
|
67027
67551
|
// === Sync (Task Reconciliation) ===
|
|
67028
67552
|
get sync() {
|
|
67029
67553
|
const root = this.projectRoot;
|
|
@@ -67191,6 +67715,7 @@ __export(src_exports, {
|
|
|
67191
67715
|
isSuccessCode: () => isSuccessCode,
|
|
67192
67716
|
isValidStatus: () => isValidStatus,
|
|
67193
67717
|
issue: () => issue_exports,
|
|
67718
|
+
lib: () => lib_exports,
|
|
67194
67719
|
lifecycle: () => lifecycle_exports,
|
|
67195
67720
|
lifecycleEvidenceTypeSchema: () => lifecycleEvidenceTypeSchema,
|
|
67196
67721
|
lifecycleGateResultSchema: () => lifecycleGateResultSchema,
|
|
@@ -67292,6 +67817,7 @@ var init_src2 = __esm({
|
|
|
67292
67817
|
init_inject();
|
|
67293
67818
|
init_intelligence();
|
|
67294
67819
|
init_issue();
|
|
67820
|
+
init_lib();
|
|
67295
67821
|
init_lifecycle2();
|
|
67296
67822
|
init_mcp();
|
|
67297
67823
|
init_memory();
|
|
@@ -68681,9 +69207,9 @@ async function addChain(chain, projectRoot) {
|
|
|
68681
69207
|
}
|
|
68682
69208
|
async function showChain(id, projectRoot) {
|
|
68683
69209
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
68684
|
-
const { eq:
|
|
69210
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
68685
69211
|
const db = await getDb4(projectRoot);
|
|
68686
|
-
const rows = await db.select().from(warpChains).where(
|
|
69212
|
+
const rows = await db.select().from(warpChains).where(eq17(warpChains.id, id));
|
|
68687
69213
|
if (rows.length === 0) return null;
|
|
68688
69214
|
return JSON.parse(rows[0].definition);
|
|
68689
69215
|
}
|
|
@@ -68730,9 +69256,9 @@ async function createInstance(params, projectRoot) {
|
|
|
68730
69256
|
}
|
|
68731
69257
|
async function showInstance(id, projectRoot) {
|
|
68732
69258
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
68733
|
-
const { eq:
|
|
69259
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
68734
69260
|
const db = await getDb4(projectRoot);
|
|
68735
|
-
const rows = await db.select().from(warpChainInstances).where(
|
|
69261
|
+
const rows = await db.select().from(warpChainInstances).where(eq17(warpChainInstances.id, id));
|
|
68736
69262
|
if (rows.length === 0) return null;
|
|
68737
69263
|
const row = rows[0];
|
|
68738
69264
|
return {
|
|
@@ -68778,11 +69304,11 @@ async function advanceInstance(id, nextStage, gateResults, projectRoot) {
|
|
|
68778
69304
|
}
|
|
68779
69305
|
}
|
|
68780
69306
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
68781
|
-
const { eq:
|
|
69307
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
68782
69308
|
const db = await getDb4(projectRoot);
|
|
68783
69309
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
68784
69310
|
const existingResults = [];
|
|
68785
|
-
const row = (await db.select().from(warpChainInstances).where(
|
|
69311
|
+
const row = (await db.select().from(warpChainInstances).where(eq17(warpChainInstances.id, id)))[0];
|
|
68786
69312
|
if (row?.gateResults) {
|
|
68787
69313
|
existingResults.push(...JSON.parse(row.gateResults));
|
|
68788
69314
|
}
|
|
@@ -68792,7 +69318,7 @@ async function advanceInstance(id, nextStage, gateResults, projectRoot) {
|
|
|
68792
69318
|
gateResults: JSON.stringify(allResults),
|
|
68793
69319
|
status: "active",
|
|
68794
69320
|
updatedAt: now2
|
|
68795
|
-
}).where(
|
|
69321
|
+
}).where(eq17(warpChainInstances.id, id));
|
|
68796
69322
|
return {
|
|
68797
69323
|
...instance,
|
|
68798
69324
|
currentStage: nextStage,
|
|
@@ -70484,7 +71010,7 @@ var init_engine_compat = __esm({
|
|
|
70484
71010
|
import { createHash as createHash12 } from "node:crypto";
|
|
70485
71011
|
import { existsSync as existsSync106, readFileSync as readFileSync78, renameSync as renameSync7 } from "node:fs";
|
|
70486
71012
|
import { join as join105 } from "node:path";
|
|
70487
|
-
import { and as
|
|
71013
|
+
import { and as and9, count as count2, desc as desc5, eq as eq12, gte as gte3, isNull as isNull3, like as like3, lte as lte2, or as or4 } from "drizzle-orm";
|
|
70488
71014
|
async function getDb3(cwd) {
|
|
70489
71015
|
const { getDb: _getDb } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
70490
71016
|
return _getDb(cwd);
|
|
@@ -70506,10 +71032,10 @@ function buildManifestSqlFilters(filter) {
|
|
|
70506
71032
|
const conditions = [isNull3(pipelineManifest.archivedAt)];
|
|
70507
71033
|
if (filter.status) {
|
|
70508
71034
|
const storedStatus = filter.status === "completed" ? "active" : filter.status;
|
|
70509
|
-
conditions.push(
|
|
71035
|
+
conditions.push(eq12(pipelineManifest.status, storedStatus));
|
|
70510
71036
|
}
|
|
70511
71037
|
if (filter.agent_type) {
|
|
70512
|
-
conditions.push(
|
|
71038
|
+
conditions.push(eq12(pipelineManifest.type, filter.agent_type));
|
|
70513
71039
|
}
|
|
70514
71040
|
if (filter.dateAfter) {
|
|
70515
71041
|
conditions.push(gte3(pipelineManifest.createdAt, `${filter.dateAfter} 00:00:00`));
|
|
@@ -70602,7 +71128,7 @@ async function pipelineManifestShow(researchId, projectRoot) {
|
|
|
70602
71128
|
}
|
|
70603
71129
|
try {
|
|
70604
71130
|
const db = await getDb3(projectRoot);
|
|
70605
|
-
const rows = await db.select().from(pipelineManifest).where(
|
|
71131
|
+
const rows = await db.select().from(pipelineManifest).where(eq12(pipelineManifest.id, researchId)).limit(1);
|
|
70606
71132
|
if (rows.length === 0) {
|
|
70607
71133
|
return {
|
|
70608
71134
|
success: false,
|
|
@@ -70644,7 +71170,7 @@ async function pipelineManifestList(params, projectRoot) {
|
|
|
70644
71170
|
const offset = normalizeOffset2(params.offset);
|
|
70645
71171
|
const pageLimit = effectivePageLimit2(limit, offset);
|
|
70646
71172
|
const { conditions, requiresInMemoryFiltering } = buildManifestSqlFilters(filter);
|
|
70647
|
-
const whereClause =
|
|
71173
|
+
const whereClause = and9(...conditions);
|
|
70648
71174
|
const totalRow = await db.select({ count: count2() }).from(pipelineManifest).where(isNull3(pipelineManifest.archivedAt)).get();
|
|
70649
71175
|
const total = totalRow?.count ?? 0;
|
|
70650
71176
|
if (!requiresInMemoryFiltering) {
|
|
@@ -70692,7 +71218,7 @@ async function pipelineManifestFind(query, options, projectRoot) {
|
|
|
70692
71218
|
const db = await getDb3(projectRoot);
|
|
70693
71219
|
const likePattern = `%${query}%`;
|
|
70694
71220
|
const rows = await db.select().from(pipelineManifest).where(
|
|
70695
|
-
|
|
71221
|
+
and9(
|
|
70696
71222
|
isNull3(pipelineManifest.archivedAt),
|
|
70697
71223
|
or4(like3(pipelineManifest.content, likePattern), like3(pipelineManifest.type, likePattern))
|
|
70698
71224
|
)
|
|
@@ -70885,7 +71411,7 @@ async function pipelineManifestArchive(beforeDate, projectRoot) {
|
|
|
70885
71411
|
}
|
|
70886
71412
|
const archivedAt = now();
|
|
70887
71413
|
for (const row of toArchive) {
|
|
70888
|
-
await db.update(pipelineManifest).set({ archivedAt }).where(
|
|
71414
|
+
await db.update(pipelineManifest).set({ archivedAt }).where(eq12(pipelineManifest.id, row.id));
|
|
70889
71415
|
}
|
|
70890
71416
|
const remaining = rows.length - toArchive.length;
|
|
70891
71417
|
return { success: true, data: { archived: toArchive.length, remaining } };
|
|
@@ -71234,25 +71760,25 @@ async function measureTokenExchange(input) {
|
|
|
71234
71760
|
);
|
|
71235
71761
|
}
|
|
71236
71762
|
async function whereClauses(filters) {
|
|
71237
|
-
const { eq:
|
|
71763
|
+
const { eq: eq17, gte: gte4, lte: lte3 } = await import("drizzle-orm");
|
|
71238
71764
|
const clauses = [];
|
|
71239
|
-
if (filters.provider) clauses.push(
|
|
71240
|
-
if (filters.transport) clauses.push(
|
|
71241
|
-
if (filters.gateway) clauses.push(
|
|
71242
|
-
if (filters.domain) clauses.push(
|
|
71243
|
-
if (filters.operation) clauses.push(
|
|
71244
|
-
if (filters.sessionId) clauses.push(
|
|
71245
|
-
if (filters.taskId) clauses.push(
|
|
71246
|
-
if (filters.method) clauses.push(
|
|
71247
|
-
if (filters.confidence) clauses.push(
|
|
71248
|
-
if (filters.requestId) clauses.push(
|
|
71765
|
+
if (filters.provider) clauses.push(eq17(tokenUsage.provider, filters.provider));
|
|
71766
|
+
if (filters.transport) clauses.push(eq17(tokenUsage.transport, filters.transport));
|
|
71767
|
+
if (filters.gateway) clauses.push(eq17(tokenUsage.gateway, filters.gateway));
|
|
71768
|
+
if (filters.domain) clauses.push(eq17(tokenUsage.domain, filters.domain));
|
|
71769
|
+
if (filters.operation) clauses.push(eq17(tokenUsage.operation, filters.operation));
|
|
71770
|
+
if (filters.sessionId) clauses.push(eq17(tokenUsage.sessionId, filters.sessionId));
|
|
71771
|
+
if (filters.taskId) clauses.push(eq17(tokenUsage.taskId, filters.taskId));
|
|
71772
|
+
if (filters.method) clauses.push(eq17(tokenUsage.method, filters.method));
|
|
71773
|
+
if (filters.confidence) clauses.push(eq17(tokenUsage.confidence, filters.confidence));
|
|
71774
|
+
if (filters.requestId) clauses.push(eq17(tokenUsage.requestId, filters.requestId));
|
|
71249
71775
|
if (filters.since) clauses.push(gte4(tokenUsage.createdAt, filters.since));
|
|
71250
71776
|
if (filters.until) clauses.push(lte3(tokenUsage.createdAt, filters.until));
|
|
71251
71777
|
return clauses;
|
|
71252
71778
|
}
|
|
71253
71779
|
async function recordTokenExchange(input) {
|
|
71254
71780
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
71255
|
-
const { eq:
|
|
71781
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
71256
71782
|
const measurement = await measureTokenExchange(input);
|
|
71257
71783
|
const db = await getDb4(input.cwd);
|
|
71258
71784
|
const row = {
|
|
@@ -71281,22 +71807,22 @@ async function recordTokenExchange(input) {
|
|
|
71281
71807
|
})
|
|
71282
71808
|
};
|
|
71283
71809
|
await db.insert(tokenUsage).values(row);
|
|
71284
|
-
const inserted = await db.select().from(tokenUsage).where(
|
|
71810
|
+
const inserted = await db.select().from(tokenUsage).where(eq17(tokenUsage.id, row.id)).limit(1);
|
|
71285
71811
|
return inserted[0];
|
|
71286
71812
|
}
|
|
71287
71813
|
async function showTokenUsage(id, cwd) {
|
|
71288
71814
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
71289
|
-
const { eq:
|
|
71815
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
71290
71816
|
const db = await getDb4(cwd);
|
|
71291
|
-
const rows = await db.select().from(tokenUsage).where(
|
|
71817
|
+
const rows = await db.select().from(tokenUsage).where(eq17(tokenUsage.id, id)).limit(1);
|
|
71292
71818
|
return rows[0] ?? null;
|
|
71293
71819
|
}
|
|
71294
71820
|
async function listTokenUsage(filters = {}, cwd) {
|
|
71295
71821
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
71296
|
-
const { and:
|
|
71822
|
+
const { and: and12, count: count4, desc: desc7 } = await import("drizzle-orm");
|
|
71297
71823
|
const db = await getDb4(cwd);
|
|
71298
71824
|
const clauses = await whereClauses(filters);
|
|
71299
|
-
const where = clauses.length > 0 ?
|
|
71825
|
+
const where = clauses.length > 0 ? and12(...clauses) : void 0;
|
|
71300
71826
|
const totalRows = await db.select({ count: count4() }).from(tokenUsage);
|
|
71301
71827
|
const filteredRows = await db.select({ count: count4() }).from(tokenUsage).where(where);
|
|
71302
71828
|
let query = db.select().from(tokenUsage).orderBy(desc7(tokenUsage.createdAt));
|
|
@@ -71312,10 +71838,10 @@ async function listTokenUsage(filters = {}, cwd) {
|
|
|
71312
71838
|
}
|
|
71313
71839
|
async function summarizeTokenUsage(filters = {}, cwd) {
|
|
71314
71840
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
71315
|
-
const { and:
|
|
71841
|
+
const { and: and12, desc: desc7 } = await import("drizzle-orm");
|
|
71316
71842
|
const db = await getDb4(cwd);
|
|
71317
71843
|
const clauses = await whereClauses(filters);
|
|
71318
|
-
const where = clauses.length > 0 ?
|
|
71844
|
+
const where = clauses.length > 0 ? and12(...clauses) : void 0;
|
|
71319
71845
|
const rows = await db.select().from(tokenUsage).where(where).orderBy(desc7(tokenUsage.createdAt));
|
|
71320
71846
|
const byMethod = /* @__PURE__ */ new Map();
|
|
71321
71847
|
const byTransport = /* @__PURE__ */ new Map();
|
|
@@ -71356,17 +71882,17 @@ async function summarizeTokenUsage(filters = {}, cwd) {
|
|
|
71356
71882
|
}
|
|
71357
71883
|
async function deleteTokenUsage(id, cwd) {
|
|
71358
71884
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
71359
|
-
const { eq:
|
|
71885
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
71360
71886
|
const db = await getDb4(cwd);
|
|
71361
|
-
await db.delete(tokenUsage).where(
|
|
71887
|
+
await db.delete(tokenUsage).where(eq17(tokenUsage.id, id));
|
|
71362
71888
|
return { deleted: true, id };
|
|
71363
71889
|
}
|
|
71364
71890
|
async function clearTokenUsage(filters = {}, cwd) {
|
|
71365
71891
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
71366
|
-
const { and:
|
|
71892
|
+
const { and: and12, count: count4 } = await import("drizzle-orm");
|
|
71367
71893
|
const db = await getDb4(cwd);
|
|
71368
71894
|
const clauses = await whereClauses(filters);
|
|
71369
|
-
const where = clauses.length > 0 ?
|
|
71895
|
+
const where = clauses.length > 0 ? and12(...clauses) : void 0;
|
|
71370
71896
|
const countRows = await db.select({ count: count4() }).from(tokenUsage).where(where);
|
|
71371
71897
|
await db.delete(tokenUsage).where(where);
|
|
71372
71898
|
return { deleted: countRows[0]?.count ?? 0 };
|
|
@@ -71777,7 +72303,7 @@ __export(session_store_exports, {
|
|
|
71777
72303
|
updateSession: () => updateSession,
|
|
71778
72304
|
workHistory: () => workHistory
|
|
71779
72305
|
});
|
|
71780
|
-
import { and as
|
|
72306
|
+
import { and as and10, desc as desc6, eq as eq13, isNull as isNull4 } from "drizzle-orm";
|
|
71781
72307
|
async function createSession(session, cwd) {
|
|
71782
72308
|
const db = await getDb(cwd);
|
|
71783
72309
|
const tw = session.taskWork;
|
|
@@ -71799,7 +72325,7 @@ async function createSession(session, cwd) {
|
|
|
71799
72325
|
}
|
|
71800
72326
|
async function getSession(sessionId, cwd) {
|
|
71801
72327
|
const db = await getDb(cwd);
|
|
71802
|
-
const rows = await db.select().from(sessions).where(
|
|
72328
|
+
const rows = await db.select().from(sessions).where(eq13(sessions.id, sessionId)).all();
|
|
71803
72329
|
if (rows.length === 0) return null;
|
|
71804
72330
|
return rowToSession(rows[0]);
|
|
71805
72331
|
}
|
|
@@ -71828,16 +72354,16 @@ async function updateSession(sessionId, updates, cwd) {
|
|
|
71828
72354
|
updateRow.handoffConsumedBy = updates.handoffConsumedBy;
|
|
71829
72355
|
if (updates.debriefJson !== void 0) updateRow.debriefJson = updates.debriefJson;
|
|
71830
72356
|
if (updates.handoffJson !== void 0) updateRow.handoffJson = updates.handoffJson;
|
|
71831
|
-
db.update(sessions).set(updateRow).where(
|
|
72357
|
+
db.update(sessions).set(updateRow).where(eq13(sessions.id, sessionId)).run();
|
|
71832
72358
|
return getSession(sessionId, cwd);
|
|
71833
72359
|
}
|
|
71834
72360
|
async function listSessions2(filters, cwd) {
|
|
71835
72361
|
const db = await getDb(cwd);
|
|
71836
72362
|
const conditions = [];
|
|
71837
72363
|
if (filters?.active) {
|
|
71838
|
-
conditions.push(
|
|
72364
|
+
conditions.push(eq13(sessions.status, "active"));
|
|
71839
72365
|
}
|
|
71840
|
-
const query = db.select().from(sessions).where(conditions.length > 0 ?
|
|
72366
|
+
const query = db.select().from(sessions).where(conditions.length > 0 ? and10(...conditions) : void 0).orderBy(desc6(sessions.startedAt));
|
|
71841
72367
|
const rows = filters?.limit ? await query.limit(filters.limit).all() : await query.all();
|
|
71842
72368
|
return rows.map(rowToSession);
|
|
71843
72369
|
}
|
|
@@ -71859,20 +72385,20 @@ async function startTask2(sessionId, taskId, cwd) {
|
|
|
71859
72385
|
const db = await getDb(cwd);
|
|
71860
72386
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
71861
72387
|
db.update(taskWorkHistory).set({ clearedAt: now2 }).where(
|
|
71862
|
-
|
|
71863
|
-
|
|
72388
|
+
and10(
|
|
72389
|
+
eq13(taskWorkHistory.sessionId, sessionId),
|
|
71864
72390
|
isNull4(taskWorkHistory.clearedAt)
|
|
71865
72391
|
)
|
|
71866
72392
|
).run();
|
|
71867
72393
|
db.insert(taskWorkHistory).values({ sessionId, taskId, setAt: now2 }).run();
|
|
71868
|
-
db.update(sessions).set({ currentTask: taskId, taskStartedAt: now2 }).where(
|
|
72394
|
+
db.update(sessions).set({ currentTask: taskId, taskStartedAt: now2 }).where(eq13(sessions.id, sessionId)).run();
|
|
71869
72395
|
}
|
|
71870
72396
|
async function getCurrentTask(sessionId, cwd) {
|
|
71871
72397
|
const db = await getDb(cwd);
|
|
71872
72398
|
const rows = await db.select({
|
|
71873
72399
|
currentTask: sessions.currentTask,
|
|
71874
72400
|
taskStartedAt: sessions.taskStartedAt
|
|
71875
|
-
}).from(sessions).where(
|
|
72401
|
+
}).from(sessions).where(eq13(sessions.id, sessionId)).all();
|
|
71876
72402
|
if (rows.length === 0) return { taskId: null, since: null };
|
|
71877
72403
|
return { taskId: rows[0].currentTask, since: rows[0].taskStartedAt };
|
|
71878
72404
|
}
|
|
@@ -71880,16 +72406,16 @@ async function stopTask2(sessionId, cwd) {
|
|
|
71880
72406
|
const db = await getDb(cwd);
|
|
71881
72407
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
71882
72408
|
db.update(taskWorkHistory).set({ clearedAt: now2 }).where(
|
|
71883
|
-
|
|
71884
|
-
|
|
72409
|
+
and10(
|
|
72410
|
+
eq13(taskWorkHistory.sessionId, sessionId),
|
|
71885
72411
|
isNull4(taskWorkHistory.clearedAt)
|
|
71886
72412
|
)
|
|
71887
72413
|
).run();
|
|
71888
|
-
db.update(sessions).set({ currentTask: null, taskStartedAt: null }).where(
|
|
72414
|
+
db.update(sessions).set({ currentTask: null, taskStartedAt: null }).where(eq13(sessions.id, sessionId)).run();
|
|
71889
72415
|
}
|
|
71890
72416
|
async function workHistory(sessionId, limit = 50, cwd) {
|
|
71891
72417
|
const db = await getDb(cwd);
|
|
71892
|
-
const rows = await db.select().from(taskWorkHistory).where(
|
|
72418
|
+
const rows = await db.select().from(taskWorkHistory).where(eq13(taskWorkHistory.sessionId, sessionId)).orderBy(desc6(taskWorkHistory.setAt), desc6(taskWorkHistory.id)).limit(limit).all();
|
|
71893
72419
|
return rows.map((r) => ({
|
|
71894
72420
|
taskId: r.taskId,
|
|
71895
72421
|
setAt: r.setAt,
|
|
@@ -71900,16 +72426,16 @@ async function gcSessions2(maxAgeDays = 30, cwd) {
|
|
|
71900
72426
|
const db = await getDb(cwd);
|
|
71901
72427
|
const threshold = /* @__PURE__ */ new Date();
|
|
71902
72428
|
threshold.setDate(threshold.getDate() - maxAgeDays);
|
|
71903
|
-
const before = await db.select({ id: sessions.id }).from(sessions).where(
|
|
72429
|
+
const before = await db.select({ id: sessions.id }).from(sessions).where(and10(eq13(sessions.status, "ended"))).all();
|
|
71904
72430
|
const toUpdate = before;
|
|
71905
72431
|
if (toUpdate.length > 0) {
|
|
71906
|
-
db.update(sessions).set({ status: "orphaned" }).where(
|
|
72432
|
+
db.update(sessions).set({ status: "orphaned" }).where(eq13(sessions.status, "ended")).run();
|
|
71907
72433
|
}
|
|
71908
72434
|
return toUpdate.length;
|
|
71909
72435
|
}
|
|
71910
72436
|
async function getActiveSession(cwd) {
|
|
71911
72437
|
const db = await getDb(cwd);
|
|
71912
|
-
const rows = await db.select().from(sessions).where(
|
|
72438
|
+
const rows = await db.select().from(sessions).where(eq13(sessions.status, "active")).orderBy(desc6(sessions.startedAt)).limit(1).all();
|
|
71913
72439
|
if (rows.length === 0) return null;
|
|
71914
72440
|
return rowToSession(rows[0]);
|
|
71915
72441
|
}
|
|
@@ -71923,7 +72449,7 @@ var init_session_store = __esm({
|
|
|
71923
72449
|
});
|
|
71924
72450
|
|
|
71925
72451
|
// packages/core/src/store/cross-db-cleanup.ts
|
|
71926
|
-
import { eq as
|
|
72452
|
+
import { eq as eq14, or as or5 } from "drizzle-orm";
|
|
71927
72453
|
async function cleanupBrainRefsOnTaskDelete(taskId, cwd) {
|
|
71928
72454
|
let brainDb = null;
|
|
71929
72455
|
try {
|
|
@@ -71933,16 +72459,16 @@ async function cleanupBrainRefsOnTaskDelete(taskId, cwd) {
|
|
|
71933
72459
|
}
|
|
71934
72460
|
const nodeId = `task:${taskId}`;
|
|
71935
72461
|
try {
|
|
71936
|
-
await brainDb.update(brainDecisions).set({ contextEpicId: null }).where(
|
|
71937
|
-
await brainDb.update(brainDecisions).set({ contextTaskId: null }).where(
|
|
71938
|
-
await brainDb.delete(brainMemoryLinks).where(
|
|
72462
|
+
await brainDb.update(brainDecisions).set({ contextEpicId: null }).where(eq14(brainDecisions.contextEpicId, taskId));
|
|
72463
|
+
await brainDb.update(brainDecisions).set({ contextTaskId: null }).where(eq14(brainDecisions.contextTaskId, taskId));
|
|
72464
|
+
await brainDb.delete(brainMemoryLinks).where(eq14(brainMemoryLinks.taskId, taskId));
|
|
71939
72465
|
await brainDb.delete(brainPageEdges).where(
|
|
71940
72466
|
or5(
|
|
71941
|
-
|
|
71942
|
-
|
|
72467
|
+
eq14(brainPageEdges.fromId, nodeId),
|
|
72468
|
+
eq14(brainPageEdges.toId, nodeId)
|
|
71943
72469
|
)
|
|
71944
72470
|
);
|
|
71945
|
-
await brainDb.delete(brainPageNodes).where(
|
|
72471
|
+
await brainDb.delete(brainPageNodes).where(eq14(brainPageNodes.id, nodeId));
|
|
71946
72472
|
} catch {
|
|
71947
72473
|
}
|
|
71948
72474
|
}
|
|
@@ -71955,12 +72481,12 @@ var init_cross_db_cleanup = __esm({
|
|
|
71955
72481
|
});
|
|
71956
72482
|
|
|
71957
72483
|
// packages/core/src/store/data-safety.ts
|
|
71958
|
-
import { eq as
|
|
72484
|
+
import { eq as eq15 } from "drizzle-orm";
|
|
71959
72485
|
async function checkTaskExists(taskId, cwd, config2 = {}) {
|
|
71960
72486
|
const cfg = { ...DEFAULT_CONFIG2, ...config2 };
|
|
71961
72487
|
if (!cfg.detectCollisions) return false;
|
|
71962
72488
|
const db = await getDb(cwd);
|
|
71963
|
-
const existing = await db.select().from(tasks).where(
|
|
72489
|
+
const existing = await db.select().from(tasks).where(eq15(tasks.id, taskId)).all();
|
|
71964
72490
|
const exists2 = existing.length > 0;
|
|
71965
72491
|
if (exists2 && cfg.strictMode) {
|
|
71966
72492
|
throw new SafetyError(
|
|
@@ -72108,7 +72634,7 @@ __export(task_store_exports, {
|
|
|
72108
72634
|
updateTask: () => updateTask2,
|
|
72109
72635
|
updateTaskSafe: () => updateTaskSafe
|
|
72110
72636
|
});
|
|
72111
|
-
import { and as
|
|
72637
|
+
import { and as and11, asc as asc4, count as count3, eq as eq16, inArray as inArray6, isNull as isNull5, ne as ne3, sql as sql11 } from "drizzle-orm";
|
|
72112
72638
|
async function insertTaskRow(task, cwd) {
|
|
72113
72639
|
const db = await getDb(cwd);
|
|
72114
72640
|
const row = taskToRow(task);
|
|
@@ -72122,10 +72648,10 @@ async function insertTaskRow(task, cwd) {
|
|
|
72122
72648
|
}
|
|
72123
72649
|
async function getTask(taskId, cwd) {
|
|
72124
72650
|
const db = await getDb(cwd);
|
|
72125
|
-
const rows = await db.select().from(tasks).where(
|
|
72651
|
+
const rows = await db.select().from(tasks).where(eq16(tasks.id, taskId)).all();
|
|
72126
72652
|
if (rows.length === 0) return null;
|
|
72127
72653
|
const task = rowToTask(rows[0]);
|
|
72128
|
-
const deps = await db.select().from(taskDependencies).where(
|
|
72654
|
+
const deps = await db.select().from(taskDependencies).where(eq16(taskDependencies.taskId, taskId)).all();
|
|
72129
72655
|
if (deps.length > 0) {
|
|
72130
72656
|
task.depends = deps.map((d) => d.dependsOn);
|
|
72131
72657
|
}
|
|
@@ -72161,9 +72687,9 @@ async function updateTask2(taskId, updates, cwd) {
|
|
|
72161
72687
|
updateRow.cancellationReason = updates.cancellationReason;
|
|
72162
72688
|
if (updates.verification !== void 0)
|
|
72163
72689
|
updateRow.verificationJson = JSON.stringify(updates.verification);
|
|
72164
|
-
db.update(tasks).set(updateRow).where(
|
|
72690
|
+
db.update(tasks).set(updateRow).where(eq16(tasks.id, taskId)).run();
|
|
72165
72691
|
if (updates.depends !== void 0) {
|
|
72166
|
-
db.delete(taskDependencies).where(
|
|
72692
|
+
db.delete(taskDependencies).where(eq16(taskDependencies.taskId, taskId)).run();
|
|
72167
72693
|
for (const depId of updates.depends) {
|
|
72168
72694
|
db.insert(taskDependencies).values({ taskId, dependsOn: depId }).run();
|
|
72169
72695
|
}
|
|
@@ -72172,9 +72698,9 @@ async function updateTask2(taskId, updates, cwd) {
|
|
|
72172
72698
|
}
|
|
72173
72699
|
async function deleteTask2(taskId, cwd) {
|
|
72174
72700
|
const db = await getDb(cwd);
|
|
72175
|
-
const existing = await db.select({ id: tasks.id }).from(tasks).where(
|
|
72701
|
+
const existing = await db.select({ id: tasks.id }).from(tasks).where(eq16(tasks.id, taskId)).all();
|
|
72176
72702
|
if (existing.length === 0) return false;
|
|
72177
|
-
db.delete(tasks).where(
|
|
72703
|
+
db.delete(tasks).where(eq16(tasks.id, taskId)).run();
|
|
72178
72704
|
void cleanupBrainRefsOnTaskDelete(taskId, cwd);
|
|
72179
72705
|
return true;
|
|
72180
72706
|
}
|
|
@@ -72182,17 +72708,17 @@ async function listTasks2(filters, cwd) {
|
|
|
72182
72708
|
const db = await getDb(cwd);
|
|
72183
72709
|
const conditions = [];
|
|
72184
72710
|
conditions.push(ne3(tasks.status, "archived"));
|
|
72185
|
-
if (filters?.status) conditions.push(
|
|
72711
|
+
if (filters?.status) conditions.push(eq16(tasks.status, filters.status));
|
|
72186
72712
|
if (filters?.parentId !== void 0) {
|
|
72187
72713
|
if (filters.parentId === null) {
|
|
72188
72714
|
conditions.push(isNull5(tasks.parentId));
|
|
72189
72715
|
} else {
|
|
72190
|
-
conditions.push(
|
|
72716
|
+
conditions.push(eq16(tasks.parentId, filters.parentId));
|
|
72191
72717
|
}
|
|
72192
72718
|
}
|
|
72193
|
-
if (filters?.type) conditions.push(
|
|
72194
|
-
if (filters?.phase) conditions.push(
|
|
72195
|
-
const query = db.select().from(tasks).where(conditions.length > 0 ?
|
|
72719
|
+
if (filters?.type) conditions.push(eq16(tasks.type, filters.type));
|
|
72720
|
+
if (filters?.phase) conditions.push(eq16(tasks.phase, filters.phase));
|
|
72721
|
+
const query = db.select().from(tasks).where(conditions.length > 0 ? and11(...conditions) : void 0).orderBy(asc4(tasks.position), asc4(tasks.createdAt));
|
|
72196
72722
|
const rows = filters?.limit ? await query.limit(filters.limit).all() : await query.all();
|
|
72197
72723
|
const tasks2 = rows.map(rowToTask);
|
|
72198
72724
|
await loadDependencies(tasks2, cwd);
|
|
@@ -72202,7 +72728,7 @@ async function findTasks2(query, limit = 20, cwd) {
|
|
|
72202
72728
|
const db = await getDb(cwd);
|
|
72203
72729
|
const pattern = `%${query}%`;
|
|
72204
72730
|
const rows = await db.select().from(tasks).where(
|
|
72205
|
-
|
|
72731
|
+
and11(
|
|
72206
72732
|
ne3(tasks.status, "archived"),
|
|
72207
72733
|
sql11`(${tasks.id} LIKE ${pattern} OR ${tasks.title} LIKE ${pattern} OR ${tasks.description} LIKE ${pattern})`
|
|
72208
72734
|
)
|
|
@@ -72221,14 +72747,14 @@ async function archiveTask(taskId, reason, cwd) {
|
|
|
72221
72747
|
archiveReason: reason ?? "completed",
|
|
72222
72748
|
cycleTimeDays: cycleTime,
|
|
72223
72749
|
updatedAt: now2
|
|
72224
|
-
}).where(
|
|
72750
|
+
}).where(eq16(tasks.id, taskId)).run();
|
|
72225
72751
|
return true;
|
|
72226
72752
|
}
|
|
72227
72753
|
async function loadDependencies(tasks2, cwd) {
|
|
72228
72754
|
if (tasks2.length === 0) return;
|
|
72229
72755
|
const db = await getDb(cwd);
|
|
72230
72756
|
const taskIds = tasks2.map((t) => t.id);
|
|
72231
|
-
const deps = await db.select().from(taskDependencies).where(
|
|
72757
|
+
const deps = await db.select().from(taskDependencies).where(inArray6(taskDependencies.taskId, taskIds)).all();
|
|
72232
72758
|
const depMap = /* @__PURE__ */ new Map();
|
|
72233
72759
|
for (const dep of deps) {
|
|
72234
72760
|
if (!depMap.has(dep.taskId)) depMap.set(dep.taskId, []);
|
|
@@ -72248,9 +72774,9 @@ async function addDependency(taskId, dependsOn, cwd) {
|
|
|
72248
72774
|
async function removeDependency(taskId, dependsOn, cwd) {
|
|
72249
72775
|
const db = await getDb(cwd);
|
|
72250
72776
|
db.delete(taskDependencies).where(
|
|
72251
|
-
|
|
72252
|
-
|
|
72253
|
-
|
|
72777
|
+
and11(
|
|
72778
|
+
eq16(taskDependencies.taskId, taskId),
|
|
72779
|
+
eq16(taskDependencies.dependsOn, dependsOn)
|
|
72254
72780
|
)
|
|
72255
72781
|
).run();
|
|
72256
72782
|
}
|
|
@@ -72260,7 +72786,7 @@ async function addRelation(taskId, relatedTo, relationType = "related", cwd, rea
|
|
|
72260
72786
|
}
|
|
72261
72787
|
async function getRelations(taskId, cwd) {
|
|
72262
72788
|
const db = await getDb(cwd);
|
|
72263
|
-
const rows = await db.select().from(taskRelations).where(
|
|
72789
|
+
const rows = await db.select().from(taskRelations).where(eq16(taskRelations.taskId, taskId)).all();
|
|
72264
72790
|
return rows.map((r) => ({
|
|
72265
72791
|
relatedTo: r.relatedTo,
|
|
72266
72792
|
type: r.relationType,
|
|
@@ -72284,7 +72810,7 @@ async function getBlockerChain(taskId, cwd) {
|
|
|
72284
72810
|
}
|
|
72285
72811
|
async function getChildren2(parentId, cwd) {
|
|
72286
72812
|
const db = await getDb(cwd);
|
|
72287
|
-
const rows = await db.select().from(tasks).where(
|
|
72813
|
+
const rows = await db.select().from(tasks).where(eq16(tasks.parentId, parentId)).orderBy(asc4(tasks.position), asc4(tasks.createdAt)).all();
|
|
72288
72814
|
return rows.map(rowToTask);
|
|
72289
72815
|
}
|
|
72290
72816
|
async function getSubtree(rootId, cwd) {
|
|
@@ -73889,10 +74415,10 @@ async function migrateJsonToSqlite2(cwd, options) {
|
|
|
73889
74415
|
const jsonCounts = countJsonRecords(cleoDir);
|
|
73890
74416
|
result.jsonCounts = jsonCounts;
|
|
73891
74417
|
if (dbExists(cwd)) {
|
|
73892
|
-
const { ne: ne4, eq:
|
|
74418
|
+
const { ne: ne4, eq: eq17, count: count4 } = await import("drizzle-orm");
|
|
73893
74419
|
const db2 = await getDb(cwd);
|
|
73894
74420
|
const tasksResult = await db2.select({ count: count4() }).from(tasks).where(ne4(tasks.status, "archived")).get();
|
|
73895
|
-
const archivedResult = await db2.select({ count: count4() }).from(tasks).where(
|
|
74421
|
+
const archivedResult = await db2.select({ count: count4() }).from(tasks).where(eq17(tasks.status, "archived")).get();
|
|
73896
74422
|
const sessionsResult = await db2.select({ count: count4() }).from(sessions).get();
|
|
73897
74423
|
const existingCounts = {
|
|
73898
74424
|
tasks: tasksResult?.count ?? 0,
|
|
@@ -74076,10 +74602,10 @@ async function migrateJsonToSqlite2(cwd, options) {
|
|
|
74076
74602
|
async function exportToJson(cwd) {
|
|
74077
74603
|
const { listTasks: listTasks3 } = await Promise.resolve().then(() => (init_task_store(), task_store_exports));
|
|
74078
74604
|
const { listSessions: listSessions3 } = await Promise.resolve().then(() => (init_session_store(), session_store_exports));
|
|
74079
|
-
const { eq:
|
|
74605
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
74080
74606
|
const tasks2 = await listTasks3(void 0, cwd);
|
|
74081
74607
|
const db = await getDb(cwd);
|
|
74082
|
-
const archivedRows = await db.select().from(tasks).where(
|
|
74608
|
+
const archivedRows = await db.select().from(tasks).where(eq17(tasks.status, "archived")).all();
|
|
74083
74609
|
const archived = archivedRows.map((row) => ({
|
|
74084
74610
|
id: row.id,
|
|
74085
74611
|
title: row.title,
|
|
@@ -76663,7 +77189,7 @@ async function validateSqliteRows(type, projectRoot) {
|
|
|
76663
77189
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
76664
77190
|
const schemaTable = await Promise.resolve().then(() => (init_tasks_schema(), tasks_schema_exports));
|
|
76665
77191
|
const zodSchemas = await Promise.resolve().then(() => (init_validation_schemas(), validation_schemas_exports));
|
|
76666
|
-
const { ne: ne4, eq:
|
|
77192
|
+
const { ne: ne4, eq: eq17 } = await import("drizzle-orm");
|
|
76667
77193
|
const db = await getDb4(projectRoot);
|
|
76668
77194
|
const errors = [];
|
|
76669
77195
|
switch (type) {
|
|
@@ -76675,7 +77201,7 @@ async function validateSqliteRows(type, projectRoot) {
|
|
|
76675
77201
|
break;
|
|
76676
77202
|
}
|
|
76677
77203
|
case "archive": {
|
|
76678
|
-
const rows = await db.select().from(schemaTable.tasks).where(
|
|
77204
|
+
const rows = await db.select().from(schemaTable.tasks).where(eq17(schemaTable.tasks.status, "archived"));
|
|
76679
77205
|
for (const row of rows) {
|
|
76680
77206
|
errors.push(...collectZodErrors(zodSchemas.selectTaskSchema.safeParse(row), row.id));
|
|
76681
77207
|
}
|
|
@@ -77751,6 +78277,7 @@ __export(internal_exports, {
|
|
|
77751
78277
|
GATE_VALIDATION_RULES: () => GATE_VALIDATION_RULES,
|
|
77752
78278
|
GateLayer: () => GateLayer,
|
|
77753
78279
|
GateStatus: () => GateStatus,
|
|
78280
|
+
HEARTBEAT_INTERVAL_MS: () => HEARTBEAT_INTERVAL_MS,
|
|
77754
78281
|
HookRegistry: () => HookRegistry,
|
|
77755
78282
|
LIFECYCLE_PIPELINE_STATUSES: () => LIFECYCLE_PIPELINE_STATUSES,
|
|
77756
78283
|
LIFECYCLE_STAGE_STATUSES: () => LIFECYCLE_STAGE_STATUSES,
|
|
@@ -77764,6 +78291,7 @@ __export(internal_exports, {
|
|
|
77764
78291
|
RateLimiter: () => RateLimiter,
|
|
77765
78292
|
SESSION_STATUSES: () => SESSION_STATUSES,
|
|
77766
78293
|
STAGE_STATUS_ICONS: () => STAGE_STATUS_ICONS,
|
|
78294
|
+
STALE_THRESHOLD_MS: () => STALE_THRESHOLD_MS,
|
|
77767
78295
|
STATUS_REGISTRY: () => STATUS_REGISTRY,
|
|
77768
78296
|
STRICTNESS_PRESETS: () => STRICTNESS_PRESETS,
|
|
77769
78297
|
SecurityError: () => SecurityError,
|
|
@@ -77843,7 +78371,7 @@ __export(internal_exports, {
|
|
|
77843
78371
|
canRunNatively: () => canRunNatively,
|
|
77844
78372
|
cancelRelease: () => cancelRelease,
|
|
77845
78373
|
channelToDistTag: () => channelToDistTag,
|
|
77846
|
-
checkAgentHealth: () =>
|
|
78374
|
+
checkAgentHealth: () => checkAgentHealth2,
|
|
77847
78375
|
checkConsensusManifest: () => checkConsensusManifest,
|
|
77848
78376
|
checkContributionManifest: () => checkContributionManifest,
|
|
77849
78377
|
checkDecompositionManifest: () => checkDecompositionManifest,
|
|
@@ -77875,6 +78403,7 @@ __export(internal_exports, {
|
|
|
77875
78403
|
computeBriefing: () => computeBriefing,
|
|
77876
78404
|
computeChecksum: () => computeChecksum,
|
|
77877
78405
|
computeDebrief: () => computeDebrief,
|
|
78406
|
+
computeDelay: () => computeDelay,
|
|
77878
78407
|
computeEpicStatus: () => computeEpicStatus,
|
|
77879
78408
|
computeHandoff: () => computeHandoff,
|
|
77880
78409
|
computeHelp: () => computeHelp,
|
|
@@ -77947,9 +78476,11 @@ __export(internal_exports, {
|
|
|
77947
78476
|
deleteTokenUsage: () => deleteTokenUsage,
|
|
77948
78477
|
deregisterAgent: () => deregisterAgent,
|
|
77949
78478
|
describeChannel: () => describeChannel,
|
|
78479
|
+
detectCrashedAgents: () => detectCrashedAgents,
|
|
77950
78480
|
detectEnvMode: () => detectEnvMode,
|
|
77951
78481
|
detectPlatform: () => detectPlatform,
|
|
77952
78482
|
detectProjectType: () => detectProjectType,
|
|
78483
|
+
detectStaleAgents: () => detectStaleAgents,
|
|
77953
78484
|
detectVersion: () => detectVersion,
|
|
77954
78485
|
determineInstallationTargets: () => determineInstallationTargets,
|
|
77955
78486
|
discoverRelated: () => discoverRelated2,
|
|
@@ -77979,6 +78510,7 @@ __export(internal_exports, {
|
|
|
77979
78510
|
findAdrs: () => findAdrs,
|
|
77980
78511
|
findLeastLoadedAgent: () => findLeastLoadedAgent,
|
|
77981
78512
|
findSessions: () => findSessions,
|
|
78513
|
+
findStaleAgentRows: () => checkAgentHealth,
|
|
77982
78514
|
findTasks: () => findTasks,
|
|
77983
78515
|
formatError: () => formatError3,
|
|
77984
78516
|
formatOutput: () => formatOutput,
|
|
@@ -78138,6 +78670,7 @@ __export(internal_exports, {
|
|
|
78138
78670
|
isValidStatus: () => isValidStatus,
|
|
78139
78671
|
isValidWorkflowGateName: () => isValidWorkflowGateName,
|
|
78140
78672
|
issue: () => issue_exports,
|
|
78673
|
+
lib: () => lib_exports,
|
|
78141
78674
|
lifecycle: () => lifecycle_exports,
|
|
78142
78675
|
lifecycleEvidenceTypeSchema: () => lifecycleEvidenceTypeSchema,
|
|
78143
78676
|
lifecycleGateResultSchema: () => lifecycleGateResultSchema,
|
|
@@ -78238,6 +78771,7 @@ __export(internal_exports, {
|
|
|
78238
78771
|
pipelineManifestPending: () => pipelineManifestPending,
|
|
78239
78772
|
pipelineManifestShow: () => pipelineManifestShow,
|
|
78240
78773
|
pipelineManifestStats: () => pipelineManifestStats,
|
|
78774
|
+
predictImpact: () => predictImpact,
|
|
78241
78775
|
predictValidationOutcome: () => predictValidationOutcome,
|
|
78242
78776
|
prepareRelease: () => prepareRelease,
|
|
78243
78777
|
prepareSpawn: () => prepareSpawn,
|
|
@@ -78262,6 +78796,7 @@ __export(internal_exports, {
|
|
|
78262
78796
|
recordAssumption: () => recordAssumption,
|
|
78263
78797
|
recordDecision: () => recordDecision,
|
|
78264
78798
|
recordFailurePattern: () => recordFailurePattern,
|
|
78799
|
+
recordHeartbeat: () => recordHeartbeat,
|
|
78265
78800
|
recordStageProgress: () => recordStageProgress,
|
|
78266
78801
|
recordTokenExchange: () => recordTokenExchange,
|
|
78267
78802
|
recoverCrashedAgents: () => recoverCrashedAgents,
|
|
@@ -78398,6 +78933,7 @@ __export(internal_exports, {
|
|
|
78398
78933
|
validateWorkflowGateUpdate: () => validateWorkflowGateUpdate,
|
|
78399
78934
|
validation: () => validation_exports,
|
|
78400
78935
|
withRetry: () => withRetry,
|
|
78936
|
+
withRetryShared: () => withRetry2,
|
|
78401
78937
|
writeMemoryBridge: () => writeMemoryBridge,
|
|
78402
78938
|
writeSnapshot: () => writeSnapshot
|
|
78403
78939
|
});
|
|
@@ -78422,6 +78958,7 @@ var init_internal = __esm({
|
|
|
78422
78958
|
init_patterns2();
|
|
78423
78959
|
init_prediction();
|
|
78424
78960
|
init_diagnostics();
|
|
78961
|
+
init_retry2();
|
|
78425
78962
|
init_chain_store();
|
|
78426
78963
|
init_lifecycle2();
|
|
78427
78964
|
init_tessera_engine();
|
|
@@ -80441,6 +80978,30 @@ var OPERATIONS = [
|
|
|
80441
80978
|
sessionRequired: false,
|
|
80442
80979
|
requiredParams: []
|
|
80443
80980
|
},
|
|
80981
|
+
{
|
|
80982
|
+
gateway: "query",
|
|
80983
|
+
domain: "tasks",
|
|
80984
|
+
operation: "impact",
|
|
80985
|
+
description: "tasks.impact (query) \u2014 predict downstream effects of a free-text change description using keyword matching and reverse dependency graph traversal",
|
|
80986
|
+
tier: 1,
|
|
80987
|
+
idempotent: true,
|
|
80988
|
+
sessionRequired: false,
|
|
80989
|
+
requiredParams: ["change"],
|
|
80990
|
+
params: [
|
|
80991
|
+
{
|
|
80992
|
+
name: "change",
|
|
80993
|
+
type: "string",
|
|
80994
|
+
required: true,
|
|
80995
|
+
description: 'Free-text description of the proposed change (e.g. "Modify authentication flow")'
|
|
80996
|
+
},
|
|
80997
|
+
{
|
|
80998
|
+
name: "matchLimit",
|
|
80999
|
+
type: "number",
|
|
81000
|
+
required: false,
|
|
81001
|
+
description: "Maximum number of seed tasks to match by keyword (default: 5)"
|
|
81002
|
+
}
|
|
81003
|
+
]
|
|
81004
|
+
},
|
|
80444
81005
|
{
|
|
80445
81006
|
gateway: "query",
|
|
80446
81007
|
domain: "tasks",
|
|
@@ -84781,10 +85342,10 @@ async function releaseShip(params, projectRoot) {
|
|
|
84781
85342
|
);
|
|
84782
85343
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
|
|
84783
85344
|
const { releaseManifests: releaseManifests2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
|
|
84784
|
-
const { eq:
|
|
85345
|
+
const { eq: eq17 } = await import("drizzle-orm");
|
|
84785
85346
|
const normalizedVer = version2.startsWith("v") ? version2 : `v${version2}`;
|
|
84786
85347
|
const db = await getDb4(cwd);
|
|
84787
|
-
await db.update(releaseManifests2).set({ epicId }).where(
|
|
85348
|
+
await db.update(releaseManifests2).set({ epicId }).where(eq17(releaseManifests2.version, normalizedVer)).run();
|
|
84788
85349
|
await generateReleaseChangelog(version2, () => loadTasks2(projectRoot), cwd);
|
|
84789
85350
|
}
|
|
84790
85351
|
logStep(0, 8, "Auto-prepare release record", true);
|
|
@@ -86016,6 +86577,15 @@ async function taskAnalyze(projectRoot, taskId, params) {
|
|
|
86016
86577
|
return engineError("E_GENERAL", `Task analysis failed: ${message}`);
|
|
86017
86578
|
}
|
|
86018
86579
|
}
|
|
86580
|
+
async function taskImpact(projectRoot, change, matchLimit) {
|
|
86581
|
+
try {
|
|
86582
|
+
const result = await predictImpact(change, projectRoot, void 0, matchLimit);
|
|
86583
|
+
return { success: true, data: result };
|
|
86584
|
+
} catch (err) {
|
|
86585
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
86586
|
+
return engineError("E_GENERAL", `Impact prediction failed: ${message}`);
|
|
86587
|
+
}
|
|
86588
|
+
}
|
|
86019
86589
|
async function taskRestore(projectRoot, taskId, params) {
|
|
86020
86590
|
try {
|
|
86021
86591
|
const result = await coreTaskRestore(projectRoot, taskId, params);
|
|
@@ -90914,6 +91484,22 @@ var TasksHandler = class {
|
|
|
90914
91484
|
const result = await taskAnalyze(projectRoot, taskId, { tierLimit });
|
|
90915
91485
|
return wrapResult(result, "query", "tasks", operation, startTime);
|
|
90916
91486
|
}
|
|
91487
|
+
case "impact": {
|
|
91488
|
+
const change = params?.change;
|
|
91489
|
+
if (!change) {
|
|
91490
|
+
return errorResult(
|
|
91491
|
+
"query",
|
|
91492
|
+
"tasks",
|
|
91493
|
+
operation,
|
|
91494
|
+
"E_INVALID_INPUT",
|
|
91495
|
+
"change is required (free-text description of the proposed change)",
|
|
91496
|
+
startTime
|
|
91497
|
+
);
|
|
91498
|
+
}
|
|
91499
|
+
const matchLimit = params?.matchLimit;
|
|
91500
|
+
const result = await taskImpact(projectRoot, change, matchLimit);
|
|
91501
|
+
return wrapResult(result, "query", "tasks", operation, startTime);
|
|
91502
|
+
}
|
|
90917
91503
|
case "next": {
|
|
90918
91504
|
const result = await taskNext(
|
|
90919
91505
|
projectRoot,
|
|
@@ -91162,6 +91748,7 @@ var TasksHandler = class {
|
|
|
91162
91748
|
"blockers",
|
|
91163
91749
|
"depends",
|
|
91164
91750
|
"analyze",
|
|
91751
|
+
"impact",
|
|
91165
91752
|
"next",
|
|
91166
91753
|
"plan",
|
|
91167
91754
|
"relates",
|
|
@@ -92884,6 +93471,87 @@ function registerAdrCommand(program) {
|
|
|
92884
93471
|
});
|
|
92885
93472
|
}
|
|
92886
93473
|
|
|
93474
|
+
// packages/cleo/src/cli/commands/agents.ts
|
|
93475
|
+
init_internal();
|
|
93476
|
+
init_renderers();
|
|
93477
|
+
function registerAgentsCommand(program) {
|
|
93478
|
+
const agents = program.command("agents").description("Agent management and health monitoring");
|
|
93479
|
+
agents.command("health").description("Check agent health and detect stale or crashed agents").option("--id <agentId>", "Check health for a specific agent ID").option(
|
|
93480
|
+
"--threshold <ms>",
|
|
93481
|
+
"Staleness threshold in milliseconds (default: 180000 = 3 minutes)",
|
|
93482
|
+
String(STALE_THRESHOLD_MS)
|
|
93483
|
+
).option("--detect-crashed", "Detect and mark crashed agents (write operation \u2014 updates DB)").action(async (opts) => {
|
|
93484
|
+
const thresholdMs = typeof opts["threshold"] === "string" ? Number(opts["threshold"]) : STALE_THRESHOLD_MS;
|
|
93485
|
+
const agentId = opts["id"];
|
|
93486
|
+
const detectCrashed = Boolean(opts["detectCrashed"]);
|
|
93487
|
+
if (agentId) {
|
|
93488
|
+
const health = await checkAgentHealth2(agentId, thresholdMs);
|
|
93489
|
+
if (!health) {
|
|
93490
|
+
cliOutput(
|
|
93491
|
+
{
|
|
93492
|
+
success: false,
|
|
93493
|
+
error: { code: "E_NOT_FOUND", message: `Agent not found: ${agentId}` }
|
|
93494
|
+
},
|
|
93495
|
+
{ command: "agents health" }
|
|
93496
|
+
);
|
|
93497
|
+
process.exitCode = 4;
|
|
93498
|
+
return;
|
|
93499
|
+
}
|
|
93500
|
+
cliOutput({ success: true, data: health }, { command: "agents health" });
|
|
93501
|
+
return;
|
|
93502
|
+
}
|
|
93503
|
+
if (detectCrashed) {
|
|
93504
|
+
const crashed = await detectCrashedAgents(thresholdMs);
|
|
93505
|
+
cliOutput(
|
|
93506
|
+
{
|
|
93507
|
+
success: true,
|
|
93508
|
+
data: {
|
|
93509
|
+
detectedCrashed: crashed.length,
|
|
93510
|
+
agents: crashed.map((a) => ({
|
|
93511
|
+
id: a.id,
|
|
93512
|
+
agentType: a.agentType,
|
|
93513
|
+
lastHeartbeat: a.lastHeartbeat,
|
|
93514
|
+
status: a.status
|
|
93515
|
+
}))
|
|
93516
|
+
}
|
|
93517
|
+
},
|
|
93518
|
+
{ command: "agents health" }
|
|
93519
|
+
);
|
|
93520
|
+
return;
|
|
93521
|
+
}
|
|
93522
|
+
const [report, stale] = await Promise.all([
|
|
93523
|
+
getHealthReport(thresholdMs),
|
|
93524
|
+
detectStaleAgents(thresholdMs)
|
|
93525
|
+
]);
|
|
93526
|
+
cliOutput(
|
|
93527
|
+
{
|
|
93528
|
+
success: true,
|
|
93529
|
+
data: {
|
|
93530
|
+
summary: {
|
|
93531
|
+
total: report.total,
|
|
93532
|
+
active: report.active,
|
|
93533
|
+
idle: report.idle,
|
|
93534
|
+
starting: report.starting,
|
|
93535
|
+
error: report.error,
|
|
93536
|
+
crashed: report.crashed,
|
|
93537
|
+
stopped: report.stopped,
|
|
93538
|
+
totalErrors: report.totalErrors
|
|
93539
|
+
},
|
|
93540
|
+
staleAgents: stale.map((s) => ({
|
|
93541
|
+
id: s.agentId,
|
|
93542
|
+
status: s.status,
|
|
93543
|
+
heartbeatAgeMs: s.heartbeatAgeMs,
|
|
93544
|
+
lastHeartbeat: s.lastHeartbeat,
|
|
93545
|
+
thresholdMs: s.thresholdMs
|
|
93546
|
+
})),
|
|
93547
|
+
thresholdMs
|
|
93548
|
+
}
|
|
93549
|
+
},
|
|
93550
|
+
{ command: "agents health" }
|
|
93551
|
+
);
|
|
93552
|
+
});
|
|
93553
|
+
}
|
|
93554
|
+
|
|
92887
93555
|
// packages/cleo/src/cli/commands/analyze.ts
|
|
92888
93556
|
function registerAnalyzeCommand(program) {
|
|
92889
93557
|
program.command("analyze").description("Task triage with leverage scoring and bottleneck detection").option("--auto-start", "Automatically start working on recommended task").action(async () => {
|
|
@@ -92940,7 +93608,7 @@ function registerBackfillCommand(program) {
|
|
|
92940
93608
|
const root = getProjectRoot();
|
|
92941
93609
|
const dryRun = !!opts.dryRun;
|
|
92942
93610
|
const rollback = !!opts.rollback;
|
|
92943
|
-
const taskIds = opts.tasks
|
|
93611
|
+
const taskIds = opts.tasks?.trim() ? opts.tasks.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
92944
93612
|
if (dryRun) {
|
|
92945
93613
|
console.log("[dry run] No changes will be made.\n");
|
|
92946
93614
|
}
|
|
@@ -95812,6 +96480,78 @@ function registerPromoteCommand(program) {
|
|
|
95812
96480
|
});
|
|
95813
96481
|
}
|
|
95814
96482
|
|
|
96483
|
+
// packages/cleo/src/cli/commands/reason.ts
|
|
96484
|
+
function registerReasonCommand(program) {
|
|
96485
|
+
const reason = program.command("reason").description("Reasoning and intelligence operations (why, similar, impact, timeline)");
|
|
96486
|
+
reason.command("why <taskId>").description("Explain why a task exists via causal trace through dependency chains").option("--json", "Output raw JSON envelope").action(async (taskId) => {
|
|
96487
|
+
await dispatchFromCli(
|
|
96488
|
+
"query",
|
|
96489
|
+
"memory",
|
|
96490
|
+
"reason.why",
|
|
96491
|
+
{ taskId },
|
|
96492
|
+
{ command: "reason", operation: "memory.reason.why" }
|
|
96493
|
+
);
|
|
96494
|
+
});
|
|
96495
|
+
reason.command("similar <taskId>").description("Find BRAIN entries semantically similar to a task or observation ID").option("--limit <n>", "Maximum number of results to return", parseInt).option("--json", "Output raw JSON envelope").action(async (taskId, opts) => {
|
|
96496
|
+
await dispatchFromCli(
|
|
96497
|
+
"query",
|
|
96498
|
+
"memory",
|
|
96499
|
+
"reason.similar",
|
|
96500
|
+
{
|
|
96501
|
+
entryId: taskId,
|
|
96502
|
+
limit: opts["limit"]
|
|
96503
|
+
},
|
|
96504
|
+
{ command: "reason", operation: "memory.reason.similar" }
|
|
96505
|
+
);
|
|
96506
|
+
});
|
|
96507
|
+
reason.command("impact [taskId]").description(
|
|
96508
|
+
"Predict impact of a change. Use --change for free-text prediction, or pass a taskId for graph-based analysis."
|
|
96509
|
+
).option("--change <description>", "Free-text description of the proposed change (T043)").option("--limit <n>", "Maximum seed tasks to match when using --change (default: 5)", "5").option("--depth <n>", "Maximum traversal depth when using taskId (default: 10)", "10").option("--json", "Output raw JSON envelope").action(async (taskId, opts) => {
|
|
96510
|
+
const change = opts["change"];
|
|
96511
|
+
if (change) {
|
|
96512
|
+
await dispatchFromCli(
|
|
96513
|
+
"query",
|
|
96514
|
+
"tasks",
|
|
96515
|
+
"impact",
|
|
96516
|
+
{
|
|
96517
|
+
change,
|
|
96518
|
+
matchLimit: parseInt(opts["limit"], 10)
|
|
96519
|
+
},
|
|
96520
|
+
{ command: "reason", operation: "tasks.impact" }
|
|
96521
|
+
);
|
|
96522
|
+
} else if (taskId) {
|
|
96523
|
+
await dispatchFromCli(
|
|
96524
|
+
"query",
|
|
96525
|
+
"tasks",
|
|
96526
|
+
"depends",
|
|
96527
|
+
{
|
|
96528
|
+
taskId,
|
|
96529
|
+
action: "impact",
|
|
96530
|
+
depth: parseInt(opts["depth"], 10)
|
|
96531
|
+
},
|
|
96532
|
+
{ command: "reason", operation: "tasks.depends" }
|
|
96533
|
+
);
|
|
96534
|
+
} else {
|
|
96535
|
+
process.stderr.write(
|
|
96536
|
+
"Error: reason impact requires either --change <description> or a <taskId>\n"
|
|
96537
|
+
);
|
|
96538
|
+
process.exit(1);
|
|
96539
|
+
}
|
|
96540
|
+
});
|
|
96541
|
+
reason.command("timeline <taskId>").description("Show history and audit trail for a task").option("--limit <n>", "Maximum number of history entries", parseInt).option("--json", "Output raw JSON envelope").action(async (taskId, opts) => {
|
|
96542
|
+
await dispatchFromCli(
|
|
96543
|
+
"query",
|
|
96544
|
+
"tasks",
|
|
96545
|
+
"history",
|
|
96546
|
+
{
|
|
96547
|
+
taskId,
|
|
96548
|
+
limit: opts["limit"]
|
|
96549
|
+
},
|
|
96550
|
+
{ command: "reason", operation: "tasks.history" }
|
|
96551
|
+
);
|
|
96552
|
+
});
|
|
96553
|
+
}
|
|
96554
|
+
|
|
95815
96555
|
// packages/cleo/src/cli/commands/refresh-memory.ts
|
|
95816
96556
|
init_src2();
|
|
95817
96557
|
function registerRefreshMemoryCommand(program) {
|
|
@@ -97984,6 +98724,7 @@ function getPackageVersion() {
|
|
|
97984
98724
|
}
|
|
97985
98725
|
var CLI_VERSION = getPackageVersion();
|
|
97986
98726
|
var rootShim = new ShimCommand();
|
|
98727
|
+
registerAgentsCommand(rootShim);
|
|
97987
98728
|
registerAddCommand(rootShim);
|
|
97988
98729
|
registerListCommand(rootShim);
|
|
97989
98730
|
registerShowCommand(rootShim);
|
|
@@ -98070,6 +98811,7 @@ registerBackfillCommand(rootShim);
|
|
|
98070
98811
|
registerMemoryBrainCommand(rootShim);
|
|
98071
98812
|
registerMigrateClaudeMemCommand(rootShim);
|
|
98072
98813
|
registerStickyCommand(rootShim);
|
|
98814
|
+
registerReasonCommand(rootShim);
|
|
98073
98815
|
registerRefreshMemoryCommand(rootShim);
|
|
98074
98816
|
registerObserveCommand(rootShim);
|
|
98075
98817
|
function shimToCitty(shim) {
|