@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/mcp/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: eq16 } = await import("drizzle-orm");
13166
+ const { eq: eq17 } = await import("drizzle-orm");
13167
13167
  const db = await getDb4(cwd);
13168
- const rows = await db.select().from(schemaMeta).where(eq16(schemaMeta.key, SEQUENCE_META_KEY)).all();
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: and11, eq: eq16 } = await import("drizzle-orm");
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(eq16(architectureDecisions.id, record2.id)).all();
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(eq16(architectureDecisions.id, record2.id));
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(and11(eq16(adrTaskLinks.adrId, record2.id), eq16(adrTaskLinks.taskId, taskId)));
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(eq16(architectureDecisions.id, toId)).all();
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: eq16 } = await import("drizzle-orm");
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(eq16(architectureDecisions.id, record2.id)).all();
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(eq16(architectureDecisions.id, record2.id));
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(eq16(adrTaskLinks.adrId, record2.id));
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 and4, asc as asc2, desc as desc2, eq as eq7, gte as gte2, or as or3 } from "drizzle-orm";
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(eq7(brainDecisions.id, row.id));
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(eq7(brainDecisions.id, id));
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(eq7(brainDecisions.type, params.type));
15691
+ conditions.push(eq5(brainDecisions.type, params.type));
15994
15692
  }
15995
15693
  if (params.confidence) {
15996
- conditions.push(eq7(brainDecisions.confidence, params.confidence));
15694
+ conditions.push(eq5(brainDecisions.confidence, params.confidence));
15997
15695
  }
15998
15696
  if (params.outcome) {
15999
- conditions.push(eq7(brainDecisions.outcome, params.outcome));
15697
+ conditions.push(eq5(brainDecisions.outcome, params.outcome));
16000
15698
  }
16001
15699
  if (params.contextTaskId) {
16002
- conditions.push(eq7(brainDecisions.contextTaskId, params.contextTaskId));
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(and4(...conditions));
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(eq7(brainDecisions.id, id));
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(eq7(brainPatterns.id, row.id));
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(eq7(brainPatterns.id, id));
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(eq7(brainPatterns.type, params.type));
15729
+ conditions.push(eq5(brainPatterns.type, params.type));
16032
15730
  }
16033
15731
  if (params.impact) {
16034
- conditions.push(eq7(brainPatterns.impact, params.impact));
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(and4(...conditions));
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(eq7(brainPatterns.id, id));
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(eq7(brainLearnings.id, row.id));
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(eq7(brainLearnings.id, id));
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(eq7(brainLearnings.actionable, params.actionable));
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(and4(...conditions));
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(eq7(brainLearnings.id, id));
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(eq7(brainObservations.id, row.id));
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(eq7(brainObservations.id, id));
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(eq7(brainObservations.type, params.type));
15796
+ conditions.push(eq5(brainObservations.type, params.type));
16099
15797
  }
16100
15798
  if (params.project) {
16101
- conditions.push(eq7(brainObservations.project, params.project));
15799
+ conditions.push(eq5(brainObservations.project, params.project));
16102
15800
  }
16103
15801
  if (params.sourceType) {
16104
- conditions.push(eq7(brainObservations.sourceType, params.sourceType));
15802
+ conditions.push(eq5(brainObservations.sourceType, params.sourceType));
16105
15803
  }
16106
15804
  if (params.sourceSessionId) {
16107
- conditions.push(eq7(brainObservations.sourceSessionId, params.sourceSessionId));
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(and4(...conditions));
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(eq7(brainObservations.id, id));
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
- and4(
16130
- eq7(brainMemoryLinks.memoryType, memoryType),
16131
- eq7(brainMemoryLinks.memoryId, memoryId)
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(eq7(brainMemoryLinks.taskId, taskId)).orderBy(asc2(brainMemoryLinks.createdAt));
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
- and4(
16141
- eq7(brainMemoryLinks.memoryType, memoryType),
16142
- eq7(brainMemoryLinks.memoryId, memoryId),
16143
- eq7(brainMemoryLinks.taskId, taskId),
16144
- eq7(brainMemoryLinks.linkType, linkType)
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(eq7(brainStickyNotes.id, row.id));
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(eq7(brainStickyNotes.id, id));
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(eq7(brainStickyNotes.status, params.status));
15861
+ conditions.push(eq5(brainStickyNotes.status, params.status));
16164
15862
  }
16165
15863
  if (params.color) {
16166
- conditions.push(eq7(brainStickyNotes.color, params.color));
15864
+ conditions.push(eq5(brainStickyNotes.color, params.color));
16167
15865
  }
16168
15866
  if (params.priority) {
16169
- conditions.push(eq7(brainStickyNotes.priority, params.priority));
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(and4(...conditions));
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(eq7(brainStickyNotes.id, id));
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(eq7(brainStickyNotes.id, id));
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(eq7(brainPageNodes.id, node.id));
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(eq7(brainPageNodes.id, id));
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(eq7(brainPageNodes.nodeType, params.nodeType));
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(and4(...conditions));
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(eq7(brainPageEdges.fromId, id), eq7(brainPageEdges.toId, id))
15912
+ or3(eq5(brainPageEdges.fromId, id), eq5(brainPageEdges.toId, id))
16215
15913
  );
16216
- await this.db.delete(brainPageNodes).where(eq7(brainPageNodes.id, id));
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
- and4(
16225
- eq7(brainPageEdges.fromId, edge.fromId),
16226
- eq7(brainPageEdges.toId, edge.toId),
16227
- eq7(brainPageEdges.edgeType, edge.edgeType)
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(eq7(brainPageEdges.fromId, nodeId)).orderBy(asc2(brainPageEdges.createdAt));
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(eq7(brainPageEdges.toId, nodeId)).orderBy(asc2(brainPageEdges.createdAt));
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
- eq7(brainPageEdges.fromId, nodeId),
16242
- eq7(brainPageEdges.toId, nodeId)
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 = [eq7(brainPageEdges.fromId, nodeId)];
15945
+ const conditions = [eq5(brainPageEdges.fromId, nodeId)];
16248
15946
  if (edgeType) {
16249
- conditions.push(eq7(brainPageEdges.edgeType, edgeType));
15947
+ conditions.push(eq5(brainPageEdges.edgeType, edgeType));
16250
15948
  }
16251
- const edges = await this.db.select().from(brainPageEdges).where(and4(...conditions));
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
- and4(
16264
- eq7(brainPageEdges.fromId, fromId),
16265
- eq7(brainPageEdges.toId, toId),
16266
- eq7(brainPageEdges.edgeType, edgeType)
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 as randomBytes2 } from "node:crypto";
15973
+ import { randomBytes } from "node:crypto";
16276
15974
  function generateDecisionId() {
16277
- return `AGT-${randomBytes2(5).toString("hex")}`;
15975
+ return `AGT-${randomBytes(5).toString("hex")}`;
16278
15976
  }
16279
15977
  function generatePatternId() {
16280
- return `P-agt-${randomBytes2(4).toString("hex")}`;
15978
+ return `P-agt-${randomBytes(4).toString("hex")}`;
16281
15979
  }
16282
15980
  function generateObservationId() {
16283
- return `O-agt-${randomBytes2(4).toString("hex")}`;
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 isTerminal2 = agent.status === "stopped" || agent.status === "crashed";
16511
+ if (isTerminal2) {
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: () => 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: and11, eq: eq16, gte: gte4, or: or6 } = await import("drizzle-orm");
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(eq16(auditLog2.sessionId, options.sessionId));
20605
- if (options?.domain) conditions.push(eq16(auditLog2.domain, options.domain));
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(eq16(auditLog2.operation, options.operation), eq16(auditLog2.action, options.operation))
20787
+ or6(eq17(auditLog2.operation, options.operation), eq17(auditLog2.action, options.operation))
20609
20788
  );
20610
- if (options?.taskId) conditions.push(eq16(auditLog2.taskId, options.taskId));
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 ? and11(...conditions) : void 0).orderBy(auditLog2.timestamp).limit(limit);
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: "Global injection template present",
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 inArray6 = false;
36818
+ let inArray7 = false;
36510
36819
  for (const line2 of lines) {
36511
36820
  if (line2.match(new RegExp(`^${field}:`))) {
36512
- inArray6 = true;
36821
+ inArray7 = true;
36513
36822
  continue;
36514
36823
  }
36515
- if (inArray6) {
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: eq16 } = await import("drizzle-orm");
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, eq16(lifecyclePipelines.taskId, tasks.id)).where(eq16(lifecyclePipelines.taskId, epicId)).limit(1);
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(eq16(lifecycleStages.pipelineId, pipelineId)).orderBy(lifecycleStages.sequence);
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: eq16 } = await import("drizzle-orm");
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(eq16(lifecycleStages.pipelineId, pipelineId));
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(eq16(lifecycleGateResults.stageId, stageIds[0]));
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(eq16(lifecycleGateResults.stageId, stageIds[i]));
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: eq16 } = await import("drizzle-orm");
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(eq16(lifecycleStages.pipelineId, pipelineId));
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(eq16(lifecycleGateResults.stageId, stage.id));
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: eq16 } = await import("drizzle-orm");
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(eq16(lifecyclePipelines.id, pipelineId)).limit(1).all();
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(eq16(lifecycleStages.id, stageId)).limit(1).all();
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(eq16(lifecyclePipelines.id, pipelineId)).run();
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: eq16 } = await import("drizzle-orm");
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(eq16(lifecycleStages.id, stageId)).limit(1).all();
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(eq16(lifecycleStages.id, stageId)).run();
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: eq16 } = await import("drizzle-orm");
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(eq16(lifecycleStages.id, stageId)).run();
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: eq16 } = await import("drizzle-orm");
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(eq16(lifecycleGateResults.id, gateId)).limit(1).all();
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(eq16(lifecycleGateResults.id, gateId)).run();
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: eq16 } = await import("drizzle-orm");
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(eq16(lifecycleGateResults.id, gateId)).limit(1).all();
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(eq16(lifecycleGateResults.id, gateId)).run();
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 eq16 = devLines[i].indexOf("=");
38125
- if (eq16 > 0) devKv[devLines[i].slice(0, eq16).trim()] = devLines[i].slice(eq16 + 1).trim();
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
- "hierarchy.requireAcceptanceCriteria": true,
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
- "hierarchy.requireAcceptanceCriteria": false,
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
- "hierarchy.requireAcceptanceCriteria": false,
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 and5, asc as asc3, desc as desc3, eq as eq8, sql as sql9 } from "drizzle-orm";
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(eq8(lifecyclePipelines.taskId, taskId)).limit(1).all();
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(eq8(lifecyclePipelines.taskId, taskId)).limit(1).all();
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(eq8(lifecycleTransitions.pipelineId, row.id)).all();
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(eq8(lifecyclePipelines.taskId, taskId)).limit(1).all();
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
- and5(
38930
- eq8(lifecycleStages.pipelineId, pipeline2.id),
38931
- eq8(lifecycleStages.stageName, fromStage)
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
- and5(
38943
- eq8(lifecycleStages.pipelineId, pipeline2.id),
38944
- eq8(lifecycleStages.stageName, toStage)
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(eq8(lifecycleStages.id, currentStageRecord.id)).run();
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(eq8(lifecycleStages.id, targetStageRecord.id)).run();
39335
+ }).where(eq9(lifecycleStages.id, targetStageRecord.id)).run();
38962
39336
  await db.update(lifecyclePipelines).set({
38963
39337
  currentStageId: toStage
38964
- }).where(eq8(lifecyclePipelines.id, pipeline2.id)).run();
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(eq8(lifecyclePipelines.taskId, taskId)).limit(1).all();
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
- eq8(
39367
+ eq9(
38994
39368
  lifecyclePipelines.status,
38995
39369
  options.status
38996
39370
  )
38997
39371
  );
38998
39372
  }
38999
39373
  if (options.currentStage) {
39000
- conditions.push(eq8(lifecyclePipelines.currentStageId, options.currentStage));
39374
+ conditions.push(eq9(lifecyclePipelines.currentStageId, options.currentStage));
39001
39375
  }
39002
39376
  if (conditions.length > 0) {
39003
- const whereClause = conditions.length === 1 ? conditions[0] : and5(...conditions);
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 ? and5(...conditions) : void 0).orderBy(order(lifecyclePipelines.startedAt));
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 ? and5(...conditions) : void 0).orderBy(order(lifecyclePipelines.currentStageId));
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 ? and5(...conditions) : void 0).orderBy(desc3(lifecyclePipelines.startedAt));
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 ? and5(...conditions) : void 0).orderBy(desc3(lifecyclePipelines.startedAt)).limit(options.limit);
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 ? and5(...conditions) : void 0).orderBy(desc3(lifecyclePipelines.startedAt)).limit(options.limit || 100).offset(options.offset);
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(eq8(lifecycleTransitions.pipelineId, row.id)).all();
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(eq8(lifecyclePipelines.taskId, taskId)).limit(1).all();
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
- and5(
39064
- eq8(lifecycleStages.pipelineId, pipeline2.id),
39065
- eq8(lifecycleStages.stageName, pipeline2.currentStageId)
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(eq8(lifecyclePipelines.id, pipeline2.id)).run();
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(eq8(lifecyclePipelines.taskId, taskId)).limit(1).all();
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
- and5(
39095
- eq8(lifecycleStages.pipelineId, pipeline2.id),
39096
- eq8(lifecycleStages.stageName, pipeline2.currentStageId)
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(eq8(lifecyclePipelines.id, pipeline2.id)).run();
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(eq8(lifecyclePipelines.taskId, taskId)).all();
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(eq8(lifecyclePipelines.taskId, taskId)).limit(1).all();
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(eq8(lifecycleStages.pipelineId, pipelineId)).orderBy(asc3(lifecycleStages.sequence)).all();
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: eq16 } = await import("drizzle-orm");
45831
+ const { eq: eq17 } = await import("drizzle-orm");
45458
45832
  const db = await getNexusDb2();
45459
- const existingRows = await db.select().from(projectRegistry).where(eq16(projectRegistry.projectHash, projectHash));
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(eq16(projectRegistry.name, projectName));
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(eq16(projectRegistry.projectHash, projectHash));
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: eq16 } = await import("drizzle-orm");
45898
+ const { eq: eq17 } = await import("drizzle-orm");
45525
45899
  const db = await getNexusDb2();
45526
- await db.delete(projectRegistry).where(eq16(projectRegistry.projectHash, project.hash));
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: eq16, or: or6 } = await import("drizzle-orm");
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(eq16(projectRegistry.projectHash, nameOrHash), eq16(projectRegistry.name, nameOrHash)));
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: eq16 } = await import("drizzle-orm");
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(eq16(projectRegistry.projectHash, project.hash));
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: eq16 } = await import("drizzle-orm");
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(eq16(projectRegistry.projectHash, project.hash));
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: eq16 } = await import("drizzle-orm");
45999
+ const { eq: eq17 } = await import("drizzle-orm");
45626
46000
  const db = await getNexusDb2();
45627
- await db.update(projectRegistry).set({ permissions: permission }).where(eq16(projectRegistry.projectHash, project.hash));
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: eq16 } = await import("drizzle-orm");
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(eq16(projectRegistry.projectHash, currentHash));
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(eq16(projectRegistry.projectId, projectId));
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(eq16(projectRegistry.projectId, projectId));
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(eq16(projectRegistry.projectId, projectId));
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(eq16(projectRegistry.projectHash, currentHash));
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(eq16(projectRegistry.projectHash, currentHash));
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 and6, eq as eq9 } from "drizzle-orm";
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(eq9(externalTaskLinks.providerId, providerId));
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
- and6(
46649
- eq9(externalTaskLinks.providerId, providerId),
46650
- eq9(externalTaskLinks.externalId, externalId)
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(eq9(externalTaskLinks.taskId, taskId));
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(eq9(externalTaskLinks.id, linkId));
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(eq9(externalTaskLinks.providerId, providerId));
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 and7, count, desc as desc4, eq as eq10 } from "drizzle-orm";
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(eq10(releaseManifests.status, "pushed")).orderBy(desc4(releaseManifests.pushedAt)).limit(1).all();
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(eq10(releaseManifests.version, normalizedVersion)).limit(1).all();
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(eq10(releaseManifests.version, normalizedVersion)).limit(1).all();
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(eq10(releaseManifests.version, normalizedVersion)).run();
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 ? [eq10(releaseManifests.status, options.status)] : [];
50956
- const whereClause = conditions.length > 0 ? and7(...conditions) : void 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(eq10(releaseManifests.version, normalizedVersion)).limit(1).all();
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(eq10(releaseManifests.version, normalizedVersion)).limit(1).all();
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(eq10(releaseManifests.version, normalizedVersion)).run();
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(eq10(releaseManifests.version, normalizedVersion)).limit(1).all();
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(eq10(releaseManifests.version, normalizedVersion)).run();
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(eq10(releaseManifests.version, normalizedVersion)).limit(1).all();
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(eq10(releaseManifests.version, normalizedVersion)).limit(1).all();
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(eq10(releaseManifests.version, normalizedVersion)).run();
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(eq10(releaseManifests.version, normalizedVersion)).limit(1).all();
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(eq10(releaseManifests.version, normalizedVersion)).run();
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(eq10(releaseManifests.version, normalizedVersion)).run();
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(eq10(releaseManifests.version, r.version)).limit(1).all();
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: and11, gte: gte4 } = await import("drizzle-orm");
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 ? and11(...conditions) : void 0).all();
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: and11, gte: gte4 } = await import("drizzle-orm");
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 ? and11(...conditions) : void 0).orderBy(auditLog2.timestamp).all();
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) {
@@ -66555,46 +66969,68 @@ async function bootstrapGlobalCleo(options) {
66555
66969
  await installSkillsGlobally(ctx);
66556
66970
  await installAgentDefinitionGlobally(ctx);
66557
66971
  await installProviderAdapters(ctx, options?.packageRoot);
66972
+ await verifyBootstrapHealth(ctx);
66558
66973
  return ctx;
66559
66974
  }
66975
+ async function writeTemplateTo(content, destPath, isDryRun) {
66976
+ if (isDryRun) return false;
66977
+ const { dirname: dirname22 } = await import("node:path");
66978
+ await mkdir17(dirname22(destPath), { recursive: true });
66979
+ await writeFile12(destPath, content);
66980
+ return true;
66981
+ }
66560
66982
  async function ensureGlobalTemplatesBootstrap(ctx, packageRootOverride) {
66561
66983
  const globalTemplatesDir = getCleoTemplatesDir();
66562
66984
  if (!ctx.isDryRun) {
66563
66985
  await mkdir17(globalTemplatesDir, { recursive: true });
66564
66986
  }
66987
+ let templateContent = null;
66565
66988
  try {
66566
66989
  const pkgRoot = packageRootOverride ?? getPackageRoot();
66567
66990
  const templatePath = join104(pkgRoot, "templates", "CLEO-INJECTION.md");
66568
66991
  if (existsSync104(templatePath)) {
66569
- const content = readFileSync77(templatePath, "utf-8");
66570
- const destPath = join104(globalTemplatesDir, "CLEO-INJECTION.md");
66571
- if (!ctx.isDryRun) {
66572
- await writeFile12(destPath, content);
66573
- }
66574
- ctx.created.push(
66575
- `~/.cleo/templates/CLEO-INJECTION.md (${ctx.isDryRun ? "would refresh" : "refreshed"})`
66576
- );
66577
- } else {
66578
- try {
66579
- const { getInjectionTemplateContent: getInjectionTemplateContent2 } = await Promise.resolve().then(() => (init_injection(), injection_exports));
66580
- const content = getInjectionTemplateContent2();
66581
- if (content) {
66582
- const destPath = join104(globalTemplatesDir, "CLEO-INJECTION.md");
66583
- if (!ctx.isDryRun) {
66584
- await writeFile12(destPath, content);
66585
- }
66586
- ctx.created.push(
66587
- `~/.cleo/templates/CLEO-INJECTION.md (${ctx.isDryRun ? "would refresh" : "refreshed"} from embedded)`
66588
- );
66589
- }
66590
- } catch {
66591
- ctx.warnings.push("Could not refresh CLEO-INJECTION.md template");
66592
- }
66992
+ templateContent = readFileSync77(templatePath, "utf-8");
66593
66993
  }
66594
66994
  } catch {
66995
+ }
66996
+ if (!templateContent) {
66997
+ try {
66998
+ const { getInjectionTemplateContent: getInjectionTemplateContent2 } = await Promise.resolve().then(() => (init_injection(), injection_exports));
66999
+ templateContent = getInjectionTemplateContent2() ?? null;
67000
+ } catch {
67001
+ ctx.warnings.push("Could not refresh CLEO-INJECTION.md template");
67002
+ return;
67003
+ }
67004
+ }
67005
+ if (!templateContent) {
66595
67006
  ctx.warnings.push("Could not refresh CLEO-INJECTION.md template");
67007
+ return;
67008
+ }
67009
+ const xdgDest = join104(globalTemplatesDir, "CLEO-INJECTION.md");
67010
+ const xdgWritten = await writeTemplateTo(templateContent, xdgDest, ctx.isDryRun);
67011
+ ctx.created.push(
67012
+ `${getCleoTemplatesTildePath()}/CLEO-INJECTION.md (${xdgWritten ? "refreshed" : "would refresh"})`
67013
+ );
67014
+ const home = homedir6();
67015
+ const legacyTemplatesDir = join104(home, ".cleo", "templates");
67016
+ if (legacyTemplatesDir !== globalTemplatesDir && existsSync104(join104(home, ".cleo"))) {
67017
+ const legacyDest = join104(legacyTemplatesDir, "CLEO-INJECTION.md");
67018
+ const legacyWritten = await writeTemplateTo(templateContent, legacyDest, ctx.isDryRun);
67019
+ if (legacyWritten) {
67020
+ ctx.created.push("~/.cleo/templates/CLEO-INJECTION.md (legacy sync)");
67021
+ }
66596
67022
  }
66597
67023
  }
67024
+ function sanitizeCaampFile(content) {
67025
+ let cleaned = content.replace(/(<!-- CAAMP:END -->)\s*(<!-- CAAMP:END -->)/g, "$1");
67026
+ cleaned = cleaned.replace(
67027
+ /<!-- CAAMP:END -->\s*[A-Z][A-Za-z-]*\.md\s*(?:<!-- CAAMP:END -->)?/g,
67028
+ "<!-- CAAMP:END -->"
67029
+ );
67030
+ cleaned = cleaned.replace(/^[A-Z][A-Za-z-]*\.md\s*$/gm, "");
67031
+ cleaned = cleaned.replace(/\n{3,}/g, "\n\n");
67032
+ return cleaned.trim() + "\n";
67033
+ }
66598
67034
  async function injectAgentsHub(ctx) {
66599
67035
  const globalAgentsDir = getAgentsHome();
66600
67036
  const globalAgentsMd = join104(globalAgentsDir, "AGENTS.md");
@@ -66608,13 +67044,23 @@ async function injectAgentsHub(ctx) {
66608
67044
  /\n?<!-- CLEO:START[^>]*-->[\s\S]*?<!-- CLEO:END -->\n?/g,
66609
67045
  ""
66610
67046
  );
66611
- if (stripped !== content) {
66612
- await writeFile12(globalAgentsMd, stripped, "utf8");
67047
+ const sanitized = sanitizeCaampFile(stripped);
67048
+ if (sanitized !== content) {
67049
+ await writeFile12(globalAgentsMd, sanitized, "utf8");
67050
+ ctx.created.push("~/.agents/AGENTS.md (sanitized CAAMP corruption)");
66613
67051
  }
66614
67052
  }
66615
67053
  const templateRef = `@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`;
66616
67054
  const action = await inject2(globalAgentsMd, templateRef);
66617
67055
  ctx.created.push(`~/.agents/AGENTS.md (${action})`);
67056
+ const postContent = await readFile19(globalAgentsMd, "utf8");
67057
+ const caampBlocks = postContent.match(/<!-- CAAMP:START -->/g);
67058
+ const caampEnds = postContent.match(/<!-- CAAMP:END -->/g);
67059
+ if (caampBlocks && caampEnds && caampBlocks.length !== caampEnds.length) {
67060
+ ctx.warnings.push(
67061
+ `~/.agents/AGENTS.md has mismatched CAAMP markers (${caampBlocks.length} START vs ${caampEnds.length} END)`
67062
+ );
67063
+ }
66618
67064
  } else {
66619
67065
  ctx.created.push("~/.agents/AGENTS.md (would create/update CAAMP block)");
66620
67066
  }
@@ -66748,6 +67194,45 @@ async function installProviderAdapters(ctx, packageRootOverride) {
66748
67194
  );
66749
67195
  }
66750
67196
  }
67197
+ async function verifyBootstrapHealth(ctx) {
67198
+ if (ctx.isDryRun) return;
67199
+ try {
67200
+ const xdgTemplatePath = join104(getCleoTemplatesDir(), "CLEO-INJECTION.md");
67201
+ const agentsMd = join104(getAgentsHome(), "AGENTS.md");
67202
+ if (!existsSync104(xdgTemplatePath)) {
67203
+ ctx.warnings.push("Health: XDG template missing after bootstrap");
67204
+ return;
67205
+ }
67206
+ const xdgContent = await readFile19(xdgTemplatePath, "utf8");
67207
+ const xdgVersion = xdgContent.match(/^Version:\s*(.+)$/m)?.[1]?.trim();
67208
+ const home = homedir6();
67209
+ const legacyTemplatePath = join104(home, ".cleo", "templates", "CLEO-INJECTION.md");
67210
+ if (existsSync104(legacyTemplatePath)) {
67211
+ const legacyContent = await readFile19(legacyTemplatePath, "utf8");
67212
+ const legacyVersion = legacyContent.match(/^Version:\s*(.+)$/m)?.[1]?.trim();
67213
+ if (legacyVersion !== xdgVersion) {
67214
+ ctx.warnings.push(
67215
+ `Health: Legacy template version (${legacyVersion}) != XDG version (${xdgVersion})`
67216
+ );
67217
+ }
67218
+ }
67219
+ if (existsSync104(agentsMd)) {
67220
+ const agentsContent = await readFile19(agentsMd, "utf8");
67221
+ const expectedRef = `@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`;
67222
+ if (!agentsContent.includes(expectedRef)) {
67223
+ ctx.warnings.push(`Health: ~/.agents/AGENTS.md does not reference ${expectedRef}`);
67224
+ }
67225
+ const outsideCaamp = agentsContent.replace(
67226
+ /<!-- CAAMP:START -->[\s\S]*?<!-- CAAMP:END -->/g,
67227
+ ""
67228
+ );
67229
+ if (/[A-Z][A-Za-z-]*\.md/.test(outsideCaamp)) {
67230
+ ctx.warnings.push("Health: ~/.agents/AGENTS.md has orphaned content outside CAAMP blocks");
67231
+ }
67232
+ }
67233
+ } catch {
67234
+ }
67235
+ }
66751
67236
  var init_bootstrap = __esm({
66752
67237
  "packages/core/src/bootstrap.ts"() {
66753
67238
  "use strict";
@@ -66764,6 +67249,8 @@ var init_cleo = __esm({
66764
67249
  "use strict";
66765
67250
  init_export();
66766
67251
  init_import();
67252
+ init_agents();
67253
+ init_intelligence();
66767
67254
  init_lifecycle2();
66768
67255
  init_brain_retrieval();
66769
67256
  init_brain_search();
@@ -66778,6 +67265,7 @@ var init_cleo = __esm({
66778
67265
  init_sessions();
66779
67266
  init_sticky();
66780
67267
  init_data_accessor();
67268
+ init_task_work();
66781
67269
  init_add();
66782
67270
  init_archive2();
66783
67271
  init_complete();
@@ -66849,7 +67337,10 @@ var init_cleo = __esm({
66849
67337
  ),
66850
67338
  complete: (p) => completeTask({ taskId: p.taskId, notes: p.notes }, root, store),
66851
67339
  delete: (p) => deleteTask({ taskId: p.taskId, force: p.force }, root, store),
66852
- archive: (p) => archiveTasks({ before: p?.before, taskIds: p?.taskIds, dryRun: p?.dryRun }, root, store)
67340
+ archive: (p) => archiveTasks({ before: p?.before, taskIds: p?.taskIds, dryRun: p?.dryRun }, root, store),
67341
+ start: (taskId) => startTask(taskId, root, store),
67342
+ stop: () => stopTask(root, store),
67343
+ current: () => currentTask(root, store)
66853
67344
  };
66854
67345
  }
66855
67346
  // === Sessions ===
@@ -66857,7 +67348,11 @@ var init_cleo = __esm({
66857
67348
  const root = this.projectRoot;
66858
67349
  const store = this._store ?? void 0;
66859
67350
  return {
66860
- start: (p) => startSession({ name: p.name, scope: p.scope, agent: p.agent }, root, store),
67351
+ start: (p) => startSession(
67352
+ { name: p.name, scope: p.scope, agent: p.agent, startTask: p.startTask },
67353
+ root,
67354
+ store
67355
+ ),
66861
67356
  end: (p) => endSession({ note: p?.note }, root, store),
66862
67357
  status: () => sessionStatus(root, store),
66863
67358
  resume: (id) => resumeSession(id, root, store),
@@ -66995,6 +67490,35 @@ var init_cleo = __esm({
66995
67490
  sharingStatus: () => getSharingStatus()
66996
67491
  };
66997
67492
  }
67493
+ // === Agents ===
67494
+ get agents() {
67495
+ const root = this.projectRoot;
67496
+ return {
67497
+ register: (opts) => registerAgent(opts, root),
67498
+ deregister: (agentId) => deregisterAgent(agentId, root),
67499
+ health: (agentId) => checkAgentHealth2(agentId, void 0, root),
67500
+ detectCrashed: (thresholdMs) => detectCrashedAgents(thresholdMs, root),
67501
+ recordHeartbeat: (agentId) => heartbeat(agentId, root),
67502
+ capacity: (agentId) => getAgentCapacity(agentId, root),
67503
+ isOverloaded: (threshold) => isOverloaded(threshold, root),
67504
+ list: (p) => listAgentInstances(
67505
+ {
67506
+ status: p?.status,
67507
+ agentType: p?.agentType
67508
+ },
67509
+ root
67510
+ )
67511
+ };
67512
+ }
67513
+ // === Intelligence ===
67514
+ get intelligence() {
67515
+ const root = this.projectRoot;
67516
+ const store = this._store ?? void 0;
67517
+ return {
67518
+ predictImpact: (change) => predictImpact(change, root, store ?? void 0),
67519
+ blastRadius: (taskId) => calculateBlastRadius(taskId, store ?? void 0, root)
67520
+ };
67521
+ }
66998
67522
  // === Sync (Task Reconciliation) ===
66999
67523
  get sync() {
67000
67524
  const root = this.projectRoot;
@@ -67037,6 +67561,7 @@ var init_src2 = __esm({
67037
67561
  init_inject();
67038
67562
  init_intelligence();
67039
67563
  init_issue();
67564
+ init_lib();
67040
67565
  init_lifecycle2();
67041
67566
  init_mcp();
67042
67567
  init_memory();
@@ -68426,9 +68951,9 @@ async function addChain(chain, projectRoot) {
68426
68951
  }
68427
68952
  async function showChain(id, projectRoot) {
68428
68953
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
68429
- const { eq: eq16 } = await import("drizzle-orm");
68954
+ const { eq: eq17 } = await import("drizzle-orm");
68430
68955
  const db = await getDb4(projectRoot);
68431
- const rows = await db.select().from(warpChains).where(eq16(warpChains.id, id));
68956
+ const rows = await db.select().from(warpChains).where(eq17(warpChains.id, id));
68432
68957
  if (rows.length === 0) return null;
68433
68958
  return JSON.parse(rows[0].definition);
68434
68959
  }
@@ -68475,9 +69000,9 @@ async function createInstance(params, projectRoot) {
68475
69000
  }
68476
69001
  async function showInstance(id, projectRoot) {
68477
69002
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
68478
- const { eq: eq16 } = await import("drizzle-orm");
69003
+ const { eq: eq17 } = await import("drizzle-orm");
68479
69004
  const db = await getDb4(projectRoot);
68480
- const rows = await db.select().from(warpChainInstances).where(eq16(warpChainInstances.id, id));
69005
+ const rows = await db.select().from(warpChainInstances).where(eq17(warpChainInstances.id, id));
68481
69006
  if (rows.length === 0) return null;
68482
69007
  const row = rows[0];
68483
69008
  return {
@@ -68523,11 +69048,11 @@ async function advanceInstance(id, nextStage, gateResults, projectRoot) {
68523
69048
  }
68524
69049
  }
68525
69050
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
68526
- const { eq: eq16 } = await import("drizzle-orm");
69051
+ const { eq: eq17 } = await import("drizzle-orm");
68527
69052
  const db = await getDb4(projectRoot);
68528
69053
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
68529
69054
  const existingResults = [];
68530
- const row = (await db.select().from(warpChainInstances).where(eq16(warpChainInstances.id, id)))[0];
69055
+ const row = (await db.select().from(warpChainInstances).where(eq17(warpChainInstances.id, id)))[0];
68531
69056
  if (row?.gateResults) {
68532
69057
  existingResults.push(...JSON.parse(row.gateResults));
68533
69058
  }
@@ -68537,7 +69062,7 @@ async function advanceInstance(id, nextStage, gateResults, projectRoot) {
68537
69062
  gateResults: JSON.stringify(allResults),
68538
69063
  status: "active",
68539
69064
  updatedAt: now2
68540
- }).where(eq16(warpChainInstances.id, id));
69065
+ }).where(eq17(warpChainInstances.id, id));
68541
69066
  return {
68542
69067
  ...instance,
68543
69068
  currentStage: nextStage,
@@ -70229,7 +70754,7 @@ var init_engine_compat = __esm({
70229
70754
  import { createHash as createHash12 } from "node:crypto";
70230
70755
  import { existsSync as existsSync106, readFileSync as readFileSync78, renameSync as renameSync7 } from "node:fs";
70231
70756
  import { join as join105 } from "node:path";
70232
- import { and as and8, count as count2, desc as desc5, eq as eq11, gte as gte3, isNull as isNull3, like as like3, lte as lte2, or as or4 } from "drizzle-orm";
70757
+ 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";
70233
70758
  async function getDb3(cwd) {
70234
70759
  const { getDb: _getDb } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
70235
70760
  return _getDb(cwd);
@@ -70251,10 +70776,10 @@ function buildManifestSqlFilters(filter) {
70251
70776
  const conditions = [isNull3(pipelineManifest.archivedAt)];
70252
70777
  if (filter.status) {
70253
70778
  const storedStatus = filter.status === "completed" ? "active" : filter.status;
70254
- conditions.push(eq11(pipelineManifest.status, storedStatus));
70779
+ conditions.push(eq12(pipelineManifest.status, storedStatus));
70255
70780
  }
70256
70781
  if (filter.agent_type) {
70257
- conditions.push(eq11(pipelineManifest.type, filter.agent_type));
70782
+ conditions.push(eq12(pipelineManifest.type, filter.agent_type));
70258
70783
  }
70259
70784
  if (filter.dateAfter) {
70260
70785
  conditions.push(gte3(pipelineManifest.createdAt, `${filter.dateAfter} 00:00:00`));
@@ -70347,7 +70872,7 @@ async function pipelineManifestShow(researchId, projectRoot) {
70347
70872
  }
70348
70873
  try {
70349
70874
  const db = await getDb3(projectRoot);
70350
- const rows = await db.select().from(pipelineManifest).where(eq11(pipelineManifest.id, researchId)).limit(1);
70875
+ const rows = await db.select().from(pipelineManifest).where(eq12(pipelineManifest.id, researchId)).limit(1);
70351
70876
  if (rows.length === 0) {
70352
70877
  return {
70353
70878
  success: false,
@@ -70389,7 +70914,7 @@ async function pipelineManifestList(params, projectRoot) {
70389
70914
  const offset = normalizeOffset2(params.offset);
70390
70915
  const pageLimit = effectivePageLimit2(limit, offset);
70391
70916
  const { conditions, requiresInMemoryFiltering } = buildManifestSqlFilters(filter);
70392
- const whereClause = and8(...conditions);
70917
+ const whereClause = and9(...conditions);
70393
70918
  const totalRow = await db.select({ count: count2() }).from(pipelineManifest).where(isNull3(pipelineManifest.archivedAt)).get();
70394
70919
  const total = totalRow?.count ?? 0;
70395
70920
  if (!requiresInMemoryFiltering) {
@@ -70437,7 +70962,7 @@ async function pipelineManifestFind(query, options, projectRoot) {
70437
70962
  const db = await getDb3(projectRoot);
70438
70963
  const likePattern = `%${query}%`;
70439
70964
  const rows = await db.select().from(pipelineManifest).where(
70440
- and8(
70965
+ and9(
70441
70966
  isNull3(pipelineManifest.archivedAt),
70442
70967
  or4(like3(pipelineManifest.content, likePattern), like3(pipelineManifest.type, likePattern))
70443
70968
  )
@@ -70630,7 +71155,7 @@ async function pipelineManifestArchive(beforeDate, projectRoot) {
70630
71155
  }
70631
71156
  const archivedAt = now();
70632
71157
  for (const row of toArchive) {
70633
- await db.update(pipelineManifest).set({ archivedAt }).where(eq11(pipelineManifest.id, row.id));
71158
+ await db.update(pipelineManifest).set({ archivedAt }).where(eq12(pipelineManifest.id, row.id));
70634
71159
  }
70635
71160
  const remaining = rows.length - toArchive.length;
70636
71161
  return { success: true, data: { archived: toArchive.length, remaining } };
@@ -70979,25 +71504,25 @@ async function measureTokenExchange(input) {
70979
71504
  );
70980
71505
  }
70981
71506
  async function whereClauses(filters) {
70982
- const { eq: eq16, gte: gte4, lte: lte3 } = await import("drizzle-orm");
71507
+ const { eq: eq17, gte: gte4, lte: lte3 } = await import("drizzle-orm");
70983
71508
  const clauses = [];
70984
- if (filters.provider) clauses.push(eq16(tokenUsage.provider, filters.provider));
70985
- if (filters.transport) clauses.push(eq16(tokenUsage.transport, filters.transport));
70986
- if (filters.gateway) clauses.push(eq16(tokenUsage.gateway, filters.gateway));
70987
- if (filters.domain) clauses.push(eq16(tokenUsage.domain, filters.domain));
70988
- if (filters.operation) clauses.push(eq16(tokenUsage.operation, filters.operation));
70989
- if (filters.sessionId) clauses.push(eq16(tokenUsage.sessionId, filters.sessionId));
70990
- if (filters.taskId) clauses.push(eq16(tokenUsage.taskId, filters.taskId));
70991
- if (filters.method) clauses.push(eq16(tokenUsage.method, filters.method));
70992
- if (filters.confidence) clauses.push(eq16(tokenUsage.confidence, filters.confidence));
70993
- if (filters.requestId) clauses.push(eq16(tokenUsage.requestId, filters.requestId));
71509
+ if (filters.provider) clauses.push(eq17(tokenUsage.provider, filters.provider));
71510
+ if (filters.transport) clauses.push(eq17(tokenUsage.transport, filters.transport));
71511
+ if (filters.gateway) clauses.push(eq17(tokenUsage.gateway, filters.gateway));
71512
+ if (filters.domain) clauses.push(eq17(tokenUsage.domain, filters.domain));
71513
+ if (filters.operation) clauses.push(eq17(tokenUsage.operation, filters.operation));
71514
+ if (filters.sessionId) clauses.push(eq17(tokenUsage.sessionId, filters.sessionId));
71515
+ if (filters.taskId) clauses.push(eq17(tokenUsage.taskId, filters.taskId));
71516
+ if (filters.method) clauses.push(eq17(tokenUsage.method, filters.method));
71517
+ if (filters.confidence) clauses.push(eq17(tokenUsage.confidence, filters.confidence));
71518
+ if (filters.requestId) clauses.push(eq17(tokenUsage.requestId, filters.requestId));
70994
71519
  if (filters.since) clauses.push(gte4(tokenUsage.createdAt, filters.since));
70995
71520
  if (filters.until) clauses.push(lte3(tokenUsage.createdAt, filters.until));
70996
71521
  return clauses;
70997
71522
  }
70998
71523
  async function recordTokenExchange(input) {
70999
71524
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
71000
- const { eq: eq16 } = await import("drizzle-orm");
71525
+ const { eq: eq17 } = await import("drizzle-orm");
71001
71526
  const measurement = await measureTokenExchange(input);
71002
71527
  const db = await getDb4(input.cwd);
71003
71528
  const row = {
@@ -71026,22 +71551,22 @@ async function recordTokenExchange(input) {
71026
71551
  })
71027
71552
  };
71028
71553
  await db.insert(tokenUsage).values(row);
71029
- const inserted = await db.select().from(tokenUsage).where(eq16(tokenUsage.id, row.id)).limit(1);
71554
+ const inserted = await db.select().from(tokenUsage).where(eq17(tokenUsage.id, row.id)).limit(1);
71030
71555
  return inserted[0];
71031
71556
  }
71032
71557
  async function showTokenUsage(id, cwd) {
71033
71558
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
71034
- const { eq: eq16 } = await import("drizzle-orm");
71559
+ const { eq: eq17 } = await import("drizzle-orm");
71035
71560
  const db = await getDb4(cwd);
71036
- const rows = await db.select().from(tokenUsage).where(eq16(tokenUsage.id, id)).limit(1);
71561
+ const rows = await db.select().from(tokenUsage).where(eq17(tokenUsage.id, id)).limit(1);
71037
71562
  return rows[0] ?? null;
71038
71563
  }
71039
71564
  async function listTokenUsage(filters = {}, cwd) {
71040
71565
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
71041
- const { and: and11, count: count4, desc: desc7 } = await import("drizzle-orm");
71566
+ const { and: and12, count: count4, desc: desc7 } = await import("drizzle-orm");
71042
71567
  const db = await getDb4(cwd);
71043
71568
  const clauses = await whereClauses(filters);
71044
- const where = clauses.length > 0 ? and11(...clauses) : void 0;
71569
+ const where = clauses.length > 0 ? and12(...clauses) : void 0;
71045
71570
  const totalRows = await db.select({ count: count4() }).from(tokenUsage);
71046
71571
  const filteredRows = await db.select({ count: count4() }).from(tokenUsage).where(where);
71047
71572
  let query = db.select().from(tokenUsage).orderBy(desc7(tokenUsage.createdAt));
@@ -71057,10 +71582,10 @@ async function listTokenUsage(filters = {}, cwd) {
71057
71582
  }
71058
71583
  async function summarizeTokenUsage(filters = {}, cwd) {
71059
71584
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
71060
- const { and: and11, desc: desc7 } = await import("drizzle-orm");
71585
+ const { and: and12, desc: desc7 } = await import("drizzle-orm");
71061
71586
  const db = await getDb4(cwd);
71062
71587
  const clauses = await whereClauses(filters);
71063
- const where = clauses.length > 0 ? and11(...clauses) : void 0;
71588
+ const where = clauses.length > 0 ? and12(...clauses) : void 0;
71064
71589
  const rows = await db.select().from(tokenUsage).where(where).orderBy(desc7(tokenUsage.createdAt));
71065
71590
  const byMethod = /* @__PURE__ */ new Map();
71066
71591
  const byTransport = /* @__PURE__ */ new Map();
@@ -71101,17 +71626,17 @@ async function summarizeTokenUsage(filters = {}, cwd) {
71101
71626
  }
71102
71627
  async function deleteTokenUsage(id, cwd) {
71103
71628
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
71104
- const { eq: eq16 } = await import("drizzle-orm");
71629
+ const { eq: eq17 } = await import("drizzle-orm");
71105
71630
  const db = await getDb4(cwd);
71106
- await db.delete(tokenUsage).where(eq16(tokenUsage.id, id));
71631
+ await db.delete(tokenUsage).where(eq17(tokenUsage.id, id));
71107
71632
  return { deleted: true, id };
71108
71633
  }
71109
71634
  async function clearTokenUsage(filters = {}, cwd) {
71110
71635
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
71111
- const { and: and11, count: count4 } = await import("drizzle-orm");
71636
+ const { and: and12, count: count4 } = await import("drizzle-orm");
71112
71637
  const db = await getDb4(cwd);
71113
71638
  const clauses = await whereClauses(filters);
71114
- const where = clauses.length > 0 ? and11(...clauses) : void 0;
71639
+ const where = clauses.length > 0 ? and12(...clauses) : void 0;
71115
71640
  const countRows = await db.select({ count: count4() }).from(tokenUsage).where(where);
71116
71641
  await db.delete(tokenUsage).where(where);
71117
71642
  return { deleted: countRows[0]?.count ?? 0 };
@@ -71522,7 +72047,7 @@ __export(session_store_exports, {
71522
72047
  updateSession: () => updateSession,
71523
72048
  workHistory: () => workHistory
71524
72049
  });
71525
- import { and as and9, desc as desc6, eq as eq12, isNull as isNull4 } from "drizzle-orm";
72050
+ import { and as and10, desc as desc6, eq as eq13, isNull as isNull4 } from "drizzle-orm";
71526
72051
  async function createSession(session, cwd) {
71527
72052
  const db = await getDb(cwd);
71528
72053
  const tw = session.taskWork;
@@ -71544,7 +72069,7 @@ async function createSession(session, cwd) {
71544
72069
  }
71545
72070
  async function getSession(sessionId, cwd) {
71546
72071
  const db = await getDb(cwd);
71547
- const rows = await db.select().from(sessions).where(eq12(sessions.id, sessionId)).all();
72072
+ const rows = await db.select().from(sessions).where(eq13(sessions.id, sessionId)).all();
71548
72073
  if (rows.length === 0) return null;
71549
72074
  return rowToSession(rows[0]);
71550
72075
  }
@@ -71573,16 +72098,16 @@ async function updateSession(sessionId, updates, cwd) {
71573
72098
  updateRow.handoffConsumedBy = updates.handoffConsumedBy;
71574
72099
  if (updates.debriefJson !== void 0) updateRow.debriefJson = updates.debriefJson;
71575
72100
  if (updates.handoffJson !== void 0) updateRow.handoffJson = updates.handoffJson;
71576
- db.update(sessions).set(updateRow).where(eq12(sessions.id, sessionId)).run();
72101
+ db.update(sessions).set(updateRow).where(eq13(sessions.id, sessionId)).run();
71577
72102
  return getSession(sessionId, cwd);
71578
72103
  }
71579
72104
  async function listSessions2(filters, cwd) {
71580
72105
  const db = await getDb(cwd);
71581
72106
  const conditions = [];
71582
72107
  if (filters?.active) {
71583
- conditions.push(eq12(sessions.status, "active"));
72108
+ conditions.push(eq13(sessions.status, "active"));
71584
72109
  }
71585
- const query = db.select().from(sessions).where(conditions.length > 0 ? and9(...conditions) : void 0).orderBy(desc6(sessions.startedAt));
72110
+ const query = db.select().from(sessions).where(conditions.length > 0 ? and10(...conditions) : void 0).orderBy(desc6(sessions.startedAt));
71586
72111
  const rows = filters?.limit ? await query.limit(filters.limit).all() : await query.all();
71587
72112
  return rows.map(rowToSession);
71588
72113
  }
@@ -71604,20 +72129,20 @@ async function startTask2(sessionId, taskId, cwd) {
71604
72129
  const db = await getDb(cwd);
71605
72130
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
71606
72131
  db.update(taskWorkHistory).set({ clearedAt: now2 }).where(
71607
- and9(
71608
- eq12(taskWorkHistory.sessionId, sessionId),
72132
+ and10(
72133
+ eq13(taskWorkHistory.sessionId, sessionId),
71609
72134
  isNull4(taskWorkHistory.clearedAt)
71610
72135
  )
71611
72136
  ).run();
71612
72137
  db.insert(taskWorkHistory).values({ sessionId, taskId, setAt: now2 }).run();
71613
- db.update(sessions).set({ currentTask: taskId, taskStartedAt: now2 }).where(eq12(sessions.id, sessionId)).run();
72138
+ db.update(sessions).set({ currentTask: taskId, taskStartedAt: now2 }).where(eq13(sessions.id, sessionId)).run();
71614
72139
  }
71615
72140
  async function getCurrentTask(sessionId, cwd) {
71616
72141
  const db = await getDb(cwd);
71617
72142
  const rows = await db.select({
71618
72143
  currentTask: sessions.currentTask,
71619
72144
  taskStartedAt: sessions.taskStartedAt
71620
- }).from(sessions).where(eq12(sessions.id, sessionId)).all();
72145
+ }).from(sessions).where(eq13(sessions.id, sessionId)).all();
71621
72146
  if (rows.length === 0) return { taskId: null, since: null };
71622
72147
  return { taskId: rows[0].currentTask, since: rows[0].taskStartedAt };
71623
72148
  }
@@ -71625,16 +72150,16 @@ async function stopTask2(sessionId, cwd) {
71625
72150
  const db = await getDb(cwd);
71626
72151
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
71627
72152
  db.update(taskWorkHistory).set({ clearedAt: now2 }).where(
71628
- and9(
71629
- eq12(taskWorkHistory.sessionId, sessionId),
72153
+ and10(
72154
+ eq13(taskWorkHistory.sessionId, sessionId),
71630
72155
  isNull4(taskWorkHistory.clearedAt)
71631
72156
  )
71632
72157
  ).run();
71633
- db.update(sessions).set({ currentTask: null, taskStartedAt: null }).where(eq12(sessions.id, sessionId)).run();
72158
+ db.update(sessions).set({ currentTask: null, taskStartedAt: null }).where(eq13(sessions.id, sessionId)).run();
71634
72159
  }
71635
72160
  async function workHistory(sessionId, limit = 50, cwd) {
71636
72161
  const db = await getDb(cwd);
71637
- const rows = await db.select().from(taskWorkHistory).where(eq12(taskWorkHistory.sessionId, sessionId)).orderBy(desc6(taskWorkHistory.setAt), desc6(taskWorkHistory.id)).limit(limit).all();
72162
+ const rows = await db.select().from(taskWorkHistory).where(eq13(taskWorkHistory.sessionId, sessionId)).orderBy(desc6(taskWorkHistory.setAt), desc6(taskWorkHistory.id)).limit(limit).all();
71638
72163
  return rows.map((r) => ({
71639
72164
  taskId: r.taskId,
71640
72165
  setAt: r.setAt,
@@ -71645,16 +72170,16 @@ async function gcSessions2(maxAgeDays = 30, cwd) {
71645
72170
  const db = await getDb(cwd);
71646
72171
  const threshold = /* @__PURE__ */ new Date();
71647
72172
  threshold.setDate(threshold.getDate() - maxAgeDays);
71648
- const before = await db.select({ id: sessions.id }).from(sessions).where(and9(eq12(sessions.status, "ended"))).all();
72173
+ const before = await db.select({ id: sessions.id }).from(sessions).where(and10(eq13(sessions.status, "ended"))).all();
71649
72174
  const toUpdate = before;
71650
72175
  if (toUpdate.length > 0) {
71651
- db.update(sessions).set({ status: "orphaned" }).where(eq12(sessions.status, "ended")).run();
72176
+ db.update(sessions).set({ status: "orphaned" }).where(eq13(sessions.status, "ended")).run();
71652
72177
  }
71653
72178
  return toUpdate.length;
71654
72179
  }
71655
72180
  async function getActiveSession(cwd) {
71656
72181
  const db = await getDb(cwd);
71657
- const rows = await db.select().from(sessions).where(eq12(sessions.status, "active")).orderBy(desc6(sessions.startedAt)).limit(1).all();
72182
+ const rows = await db.select().from(sessions).where(eq13(sessions.status, "active")).orderBy(desc6(sessions.startedAt)).limit(1).all();
71658
72183
  if (rows.length === 0) return null;
71659
72184
  return rowToSession(rows[0]);
71660
72185
  }
@@ -71668,7 +72193,7 @@ var init_session_store = __esm({
71668
72193
  });
71669
72194
 
71670
72195
  // packages/core/src/store/cross-db-cleanup.ts
71671
- import { eq as eq13, or as or5 } from "drizzle-orm";
72196
+ import { eq as eq14, or as or5 } from "drizzle-orm";
71672
72197
  async function cleanupBrainRefsOnTaskDelete(taskId, cwd) {
71673
72198
  let brainDb = null;
71674
72199
  try {
@@ -71678,16 +72203,16 @@ async function cleanupBrainRefsOnTaskDelete(taskId, cwd) {
71678
72203
  }
71679
72204
  const nodeId = `task:${taskId}`;
71680
72205
  try {
71681
- await brainDb.update(brainDecisions).set({ contextEpicId: null }).where(eq13(brainDecisions.contextEpicId, taskId));
71682
- await brainDb.update(brainDecisions).set({ contextTaskId: null }).where(eq13(brainDecisions.contextTaskId, taskId));
71683
- await brainDb.delete(brainMemoryLinks).where(eq13(brainMemoryLinks.taskId, taskId));
72206
+ await brainDb.update(brainDecisions).set({ contextEpicId: null }).where(eq14(brainDecisions.contextEpicId, taskId));
72207
+ await brainDb.update(brainDecisions).set({ contextTaskId: null }).where(eq14(brainDecisions.contextTaskId, taskId));
72208
+ await brainDb.delete(brainMemoryLinks).where(eq14(brainMemoryLinks.taskId, taskId));
71684
72209
  await brainDb.delete(brainPageEdges).where(
71685
72210
  or5(
71686
- eq13(brainPageEdges.fromId, nodeId),
71687
- eq13(brainPageEdges.toId, nodeId)
72211
+ eq14(brainPageEdges.fromId, nodeId),
72212
+ eq14(brainPageEdges.toId, nodeId)
71688
72213
  )
71689
72214
  );
71690
- await brainDb.delete(brainPageNodes).where(eq13(brainPageNodes.id, nodeId));
72215
+ await brainDb.delete(brainPageNodes).where(eq14(brainPageNodes.id, nodeId));
71691
72216
  } catch {
71692
72217
  }
71693
72218
  }
@@ -71700,12 +72225,12 @@ var init_cross_db_cleanup = __esm({
71700
72225
  });
71701
72226
 
71702
72227
  // packages/core/src/store/data-safety.ts
71703
- import { eq as eq14 } from "drizzle-orm";
72228
+ import { eq as eq15 } from "drizzle-orm";
71704
72229
  async function checkTaskExists(taskId, cwd, config2 = {}) {
71705
72230
  const cfg = { ...DEFAULT_CONFIG2, ...config2 };
71706
72231
  if (!cfg.detectCollisions) return false;
71707
72232
  const db = await getDb(cwd);
71708
- const existing = await db.select().from(tasks).where(eq14(tasks.id, taskId)).all();
72233
+ const existing = await db.select().from(tasks).where(eq15(tasks.id, taskId)).all();
71709
72234
  const exists2 = existing.length > 0;
71710
72235
  if (exists2 && cfg.strictMode) {
71711
72236
  throw new SafetyError(
@@ -71853,7 +72378,7 @@ __export(task_store_exports, {
71853
72378
  updateTask: () => updateTask2,
71854
72379
  updateTaskSafe: () => updateTaskSafe
71855
72380
  });
71856
- import { and as and10, asc as asc4, count as count3, eq as eq15, inArray as inArray5, isNull as isNull5, ne as ne3, sql as sql11 } from "drizzle-orm";
72381
+ 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";
71857
72382
  async function insertTaskRow(task, cwd) {
71858
72383
  const db = await getDb(cwd);
71859
72384
  const row = taskToRow(task);
@@ -71867,10 +72392,10 @@ async function insertTaskRow(task, cwd) {
71867
72392
  }
71868
72393
  async function getTask(taskId, cwd) {
71869
72394
  const db = await getDb(cwd);
71870
- const rows = await db.select().from(tasks).where(eq15(tasks.id, taskId)).all();
72395
+ const rows = await db.select().from(tasks).where(eq16(tasks.id, taskId)).all();
71871
72396
  if (rows.length === 0) return null;
71872
72397
  const task = rowToTask(rows[0]);
71873
- const deps = await db.select().from(taskDependencies).where(eq15(taskDependencies.taskId, taskId)).all();
72398
+ const deps = await db.select().from(taskDependencies).where(eq16(taskDependencies.taskId, taskId)).all();
71874
72399
  if (deps.length > 0) {
71875
72400
  task.depends = deps.map((d) => d.dependsOn);
71876
72401
  }
@@ -71906,9 +72431,9 @@ async function updateTask2(taskId, updates, cwd) {
71906
72431
  updateRow.cancellationReason = updates.cancellationReason;
71907
72432
  if (updates.verification !== void 0)
71908
72433
  updateRow.verificationJson = JSON.stringify(updates.verification);
71909
- db.update(tasks).set(updateRow).where(eq15(tasks.id, taskId)).run();
72434
+ db.update(tasks).set(updateRow).where(eq16(tasks.id, taskId)).run();
71910
72435
  if (updates.depends !== void 0) {
71911
- db.delete(taskDependencies).where(eq15(taskDependencies.taskId, taskId)).run();
72436
+ db.delete(taskDependencies).where(eq16(taskDependencies.taskId, taskId)).run();
71912
72437
  for (const depId of updates.depends) {
71913
72438
  db.insert(taskDependencies).values({ taskId, dependsOn: depId }).run();
71914
72439
  }
@@ -71917,9 +72442,9 @@ async function updateTask2(taskId, updates, cwd) {
71917
72442
  }
71918
72443
  async function deleteTask2(taskId, cwd) {
71919
72444
  const db = await getDb(cwd);
71920
- const existing = await db.select({ id: tasks.id }).from(tasks).where(eq15(tasks.id, taskId)).all();
72445
+ const existing = await db.select({ id: tasks.id }).from(tasks).where(eq16(tasks.id, taskId)).all();
71921
72446
  if (existing.length === 0) return false;
71922
- db.delete(tasks).where(eq15(tasks.id, taskId)).run();
72447
+ db.delete(tasks).where(eq16(tasks.id, taskId)).run();
71923
72448
  void cleanupBrainRefsOnTaskDelete(taskId, cwd);
71924
72449
  return true;
71925
72450
  }
@@ -71927,17 +72452,17 @@ async function listTasks2(filters, cwd) {
71927
72452
  const db = await getDb(cwd);
71928
72453
  const conditions = [];
71929
72454
  conditions.push(ne3(tasks.status, "archived"));
71930
- if (filters?.status) conditions.push(eq15(tasks.status, filters.status));
72455
+ if (filters?.status) conditions.push(eq16(tasks.status, filters.status));
71931
72456
  if (filters?.parentId !== void 0) {
71932
72457
  if (filters.parentId === null) {
71933
72458
  conditions.push(isNull5(tasks.parentId));
71934
72459
  } else {
71935
- conditions.push(eq15(tasks.parentId, filters.parentId));
72460
+ conditions.push(eq16(tasks.parentId, filters.parentId));
71936
72461
  }
71937
72462
  }
71938
- if (filters?.type) conditions.push(eq15(tasks.type, filters.type));
71939
- if (filters?.phase) conditions.push(eq15(tasks.phase, filters.phase));
71940
- const query = db.select().from(tasks).where(conditions.length > 0 ? and10(...conditions) : void 0).orderBy(asc4(tasks.position), asc4(tasks.createdAt));
72463
+ if (filters?.type) conditions.push(eq16(tasks.type, filters.type));
72464
+ if (filters?.phase) conditions.push(eq16(tasks.phase, filters.phase));
72465
+ const query = db.select().from(tasks).where(conditions.length > 0 ? and11(...conditions) : void 0).orderBy(asc4(tasks.position), asc4(tasks.createdAt));
71941
72466
  const rows = filters?.limit ? await query.limit(filters.limit).all() : await query.all();
71942
72467
  const tasks2 = rows.map(rowToTask);
71943
72468
  await loadDependencies(tasks2, cwd);
@@ -71947,7 +72472,7 @@ async function findTasks2(query, limit = 20, cwd) {
71947
72472
  const db = await getDb(cwd);
71948
72473
  const pattern = `%${query}%`;
71949
72474
  const rows = await db.select().from(tasks).where(
71950
- and10(
72475
+ and11(
71951
72476
  ne3(tasks.status, "archived"),
71952
72477
  sql11`(${tasks.id} LIKE ${pattern} OR ${tasks.title} LIKE ${pattern} OR ${tasks.description} LIKE ${pattern})`
71953
72478
  )
@@ -71966,14 +72491,14 @@ async function archiveTask(taskId, reason, cwd) {
71966
72491
  archiveReason: reason ?? "completed",
71967
72492
  cycleTimeDays: cycleTime,
71968
72493
  updatedAt: now2
71969
- }).where(eq15(tasks.id, taskId)).run();
72494
+ }).where(eq16(tasks.id, taskId)).run();
71970
72495
  return true;
71971
72496
  }
71972
72497
  async function loadDependencies(tasks2, cwd) {
71973
72498
  if (tasks2.length === 0) return;
71974
72499
  const db = await getDb(cwd);
71975
72500
  const taskIds = tasks2.map((t) => t.id);
71976
- const deps = await db.select().from(taskDependencies).where(inArray5(taskDependencies.taskId, taskIds)).all();
72501
+ const deps = await db.select().from(taskDependencies).where(inArray6(taskDependencies.taskId, taskIds)).all();
71977
72502
  const depMap = /* @__PURE__ */ new Map();
71978
72503
  for (const dep of deps) {
71979
72504
  if (!depMap.has(dep.taskId)) depMap.set(dep.taskId, []);
@@ -71993,9 +72518,9 @@ async function addDependency(taskId, dependsOn, cwd) {
71993
72518
  async function removeDependency(taskId, dependsOn, cwd) {
71994
72519
  const db = await getDb(cwd);
71995
72520
  db.delete(taskDependencies).where(
71996
- and10(
71997
- eq15(taskDependencies.taskId, taskId),
71998
- eq15(taskDependencies.dependsOn, dependsOn)
72521
+ and11(
72522
+ eq16(taskDependencies.taskId, taskId),
72523
+ eq16(taskDependencies.dependsOn, dependsOn)
71999
72524
  )
72000
72525
  ).run();
72001
72526
  }
@@ -72005,7 +72530,7 @@ async function addRelation(taskId, relatedTo, relationType = "related", cwd, rea
72005
72530
  }
72006
72531
  async function getRelations(taskId, cwd) {
72007
72532
  const db = await getDb(cwd);
72008
- const rows = await db.select().from(taskRelations).where(eq15(taskRelations.taskId, taskId)).all();
72533
+ const rows = await db.select().from(taskRelations).where(eq16(taskRelations.taskId, taskId)).all();
72009
72534
  return rows.map((r) => ({
72010
72535
  relatedTo: r.relatedTo,
72011
72536
  type: r.relationType,
@@ -72029,7 +72554,7 @@ async function getBlockerChain(taskId, cwd) {
72029
72554
  }
72030
72555
  async function getChildren2(parentId, cwd) {
72031
72556
  const db = await getDb(cwd);
72032
- const rows = await db.select().from(tasks).where(eq15(tasks.parentId, parentId)).orderBy(asc4(tasks.position), asc4(tasks.createdAt)).all();
72557
+ const rows = await db.select().from(tasks).where(eq16(tasks.parentId, parentId)).orderBy(asc4(tasks.position), asc4(tasks.createdAt)).all();
72033
72558
  return rows.map(rowToTask);
72034
72559
  }
72035
72560
  async function getSubtree(rootId, cwd) {
@@ -73634,10 +74159,10 @@ async function migrateJsonToSqlite2(cwd, options) {
73634
74159
  const jsonCounts = countJsonRecords(cleoDir);
73635
74160
  result.jsonCounts = jsonCounts;
73636
74161
  if (dbExists(cwd)) {
73637
- const { ne: ne4, eq: eq16, count: count4 } = await import("drizzle-orm");
74162
+ const { ne: ne4, eq: eq17, count: count4 } = await import("drizzle-orm");
73638
74163
  const db2 = await getDb(cwd);
73639
74164
  const tasksResult = await db2.select({ count: count4() }).from(tasks).where(ne4(tasks.status, "archived")).get();
73640
- const archivedResult = await db2.select({ count: count4() }).from(tasks).where(eq16(tasks.status, "archived")).get();
74165
+ const archivedResult = await db2.select({ count: count4() }).from(tasks).where(eq17(tasks.status, "archived")).get();
73641
74166
  const sessionsResult = await db2.select({ count: count4() }).from(sessions).get();
73642
74167
  const existingCounts = {
73643
74168
  tasks: tasksResult?.count ?? 0,
@@ -73821,10 +74346,10 @@ async function migrateJsonToSqlite2(cwd, options) {
73821
74346
  async function exportToJson(cwd) {
73822
74347
  const { listTasks: listTasks3 } = await Promise.resolve().then(() => (init_task_store(), task_store_exports));
73823
74348
  const { listSessions: listSessions3 } = await Promise.resolve().then(() => (init_session_store(), session_store_exports));
73824
- const { eq: eq16 } = await import("drizzle-orm");
74349
+ const { eq: eq17 } = await import("drizzle-orm");
73825
74350
  const tasks2 = await listTasks3(void 0, cwd);
73826
74351
  const db = await getDb(cwd);
73827
- const archivedRows = await db.select().from(tasks).where(eq16(tasks.status, "archived")).all();
74352
+ const archivedRows = await db.select().from(tasks).where(eq17(tasks.status, "archived")).all();
73828
74353
  const archived = archivedRows.map((row) => ({
73829
74354
  id: row.id,
73830
74355
  title: row.title,
@@ -76408,7 +76933,7 @@ async function validateSqliteRows(type, projectRoot) {
76408
76933
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
76409
76934
  const schemaTable = await Promise.resolve().then(() => (init_tasks_schema(), tasks_schema_exports));
76410
76935
  const zodSchemas = await Promise.resolve().then(() => (init_validation_schemas(), validation_schemas_exports));
76411
- const { ne: ne4, eq: eq16 } = await import("drizzle-orm");
76936
+ const { ne: ne4, eq: eq17 } = await import("drizzle-orm");
76412
76937
  const db = await getDb4(projectRoot);
76413
76938
  const errors = [];
76414
76939
  switch (type) {
@@ -76420,7 +76945,7 @@ async function validateSqliteRows(type, projectRoot) {
76420
76945
  break;
76421
76946
  }
76422
76947
  case "archive": {
76423
- const rows = await db.select().from(schemaTable.tasks).where(eq16(schemaTable.tasks.status, "archived"));
76948
+ const rows = await db.select().from(schemaTable.tasks).where(eq17(schemaTable.tasks.status, "archived"));
76424
76949
  for (const row of rows) {
76425
76950
  errors.push(...collectZodErrors(zodSchemas.selectTaskSchema.safeParse(row), row.id));
76426
76951
  }
@@ -77496,6 +78021,7 @@ __export(internal_exports, {
77496
78021
  GATE_VALIDATION_RULES: () => GATE_VALIDATION_RULES,
77497
78022
  GateLayer: () => GateLayer,
77498
78023
  GateStatus: () => GateStatus,
78024
+ HEARTBEAT_INTERVAL_MS: () => HEARTBEAT_INTERVAL_MS,
77499
78025
  HookRegistry: () => HookRegistry,
77500
78026
  LIFECYCLE_PIPELINE_STATUSES: () => LIFECYCLE_PIPELINE_STATUSES,
77501
78027
  LIFECYCLE_STAGE_STATUSES: () => LIFECYCLE_STAGE_STATUSES,
@@ -77509,6 +78035,7 @@ __export(internal_exports, {
77509
78035
  RateLimiter: () => RateLimiter,
77510
78036
  SESSION_STATUSES: () => SESSION_STATUSES,
77511
78037
  STAGE_STATUS_ICONS: () => STAGE_STATUS_ICONS,
78038
+ STALE_THRESHOLD_MS: () => STALE_THRESHOLD_MS,
77512
78039
  STATUS_REGISTRY: () => STATUS_REGISTRY,
77513
78040
  STRICTNESS_PRESETS: () => STRICTNESS_PRESETS,
77514
78041
  SecurityError: () => SecurityError,
@@ -77588,7 +78115,7 @@ __export(internal_exports, {
77588
78115
  canRunNatively: () => canRunNatively,
77589
78116
  cancelRelease: () => cancelRelease,
77590
78117
  channelToDistTag: () => channelToDistTag,
77591
- checkAgentHealth: () => checkAgentHealth,
78118
+ checkAgentHealth: () => checkAgentHealth2,
77592
78119
  checkConsensusManifest: () => checkConsensusManifest,
77593
78120
  checkContributionManifest: () => checkContributionManifest,
77594
78121
  checkDecompositionManifest: () => checkDecompositionManifest,
@@ -77620,6 +78147,7 @@ __export(internal_exports, {
77620
78147
  computeBriefing: () => computeBriefing,
77621
78148
  computeChecksum: () => computeChecksum,
77622
78149
  computeDebrief: () => computeDebrief,
78150
+ computeDelay: () => computeDelay,
77623
78151
  computeEpicStatus: () => computeEpicStatus,
77624
78152
  computeHandoff: () => computeHandoff,
77625
78153
  computeHelp: () => computeHelp,
@@ -77692,9 +78220,11 @@ __export(internal_exports, {
77692
78220
  deleteTokenUsage: () => deleteTokenUsage,
77693
78221
  deregisterAgent: () => deregisterAgent,
77694
78222
  describeChannel: () => describeChannel,
78223
+ detectCrashedAgents: () => detectCrashedAgents,
77695
78224
  detectEnvMode: () => detectEnvMode,
77696
78225
  detectPlatform: () => detectPlatform,
77697
78226
  detectProjectType: () => detectProjectType,
78227
+ detectStaleAgents: () => detectStaleAgents,
77698
78228
  detectVersion: () => detectVersion,
77699
78229
  determineInstallationTargets: () => determineInstallationTargets,
77700
78230
  discoverRelated: () => discoverRelated2,
@@ -77724,6 +78254,7 @@ __export(internal_exports, {
77724
78254
  findAdrs: () => findAdrs,
77725
78255
  findLeastLoadedAgent: () => findLeastLoadedAgent,
77726
78256
  findSessions: () => findSessions,
78257
+ findStaleAgentRows: () => checkAgentHealth,
77727
78258
  findTasks: () => findTasks,
77728
78259
  formatError: () => formatError3,
77729
78260
  formatOutput: () => formatOutput,
@@ -77883,6 +78414,7 @@ __export(internal_exports, {
77883
78414
  isValidStatus: () => isValidStatus,
77884
78415
  isValidWorkflowGateName: () => isValidWorkflowGateName,
77885
78416
  issue: () => issue_exports,
78417
+ lib: () => lib_exports,
77886
78418
  lifecycle: () => lifecycle_exports,
77887
78419
  lifecycleEvidenceTypeSchema: () => lifecycleEvidenceTypeSchema,
77888
78420
  lifecycleGateResultSchema: () => lifecycleGateResultSchema,
@@ -77983,6 +78515,7 @@ __export(internal_exports, {
77983
78515
  pipelineManifestPending: () => pipelineManifestPending,
77984
78516
  pipelineManifestShow: () => pipelineManifestShow,
77985
78517
  pipelineManifestStats: () => pipelineManifestStats,
78518
+ predictImpact: () => predictImpact,
77986
78519
  predictValidationOutcome: () => predictValidationOutcome,
77987
78520
  prepareRelease: () => prepareRelease,
77988
78521
  prepareSpawn: () => prepareSpawn,
@@ -78007,6 +78540,7 @@ __export(internal_exports, {
78007
78540
  recordAssumption: () => recordAssumption,
78008
78541
  recordDecision: () => recordDecision,
78009
78542
  recordFailurePattern: () => recordFailurePattern,
78543
+ recordHeartbeat: () => recordHeartbeat,
78010
78544
  recordStageProgress: () => recordStageProgress,
78011
78545
  recordTokenExchange: () => recordTokenExchange,
78012
78546
  recoverCrashedAgents: () => recoverCrashedAgents,
@@ -78143,6 +78677,7 @@ __export(internal_exports, {
78143
78677
  validateWorkflowGateUpdate: () => validateWorkflowGateUpdate,
78144
78678
  validation: () => validation_exports,
78145
78679
  withRetry: () => withRetry,
78680
+ withRetryShared: () => withRetry2,
78146
78681
  writeMemoryBridge: () => writeMemoryBridge,
78147
78682
  writeSnapshot: () => writeSnapshot
78148
78683
  });
@@ -78167,6 +78702,7 @@ var init_internal = __esm({
78167
78702
  init_patterns2();
78168
78703
  init_prediction();
78169
78704
  init_diagnostics();
78705
+ init_retry2();
78170
78706
  init_chain_store();
78171
78707
  init_lifecycle2();
78172
78708
  init_tessera_engine();
@@ -82054,6 +82590,30 @@ var OPERATIONS = [
82054
82590
  sessionRequired: false,
82055
82591
  requiredParams: []
82056
82592
  },
82593
+ {
82594
+ gateway: "query",
82595
+ domain: "tasks",
82596
+ operation: "impact",
82597
+ description: "tasks.impact (query) \u2014 predict downstream effects of a free-text change description using keyword matching and reverse dependency graph traversal",
82598
+ tier: 1,
82599
+ idempotent: true,
82600
+ sessionRequired: false,
82601
+ requiredParams: ["change"],
82602
+ params: [
82603
+ {
82604
+ name: "change",
82605
+ type: "string",
82606
+ required: true,
82607
+ description: 'Free-text description of the proposed change (e.g. "Modify authentication flow")'
82608
+ },
82609
+ {
82610
+ name: "matchLimit",
82611
+ type: "number",
82612
+ required: false,
82613
+ description: "Maximum number of seed tasks to match by keyword (default: 5)"
82614
+ }
82615
+ ]
82616
+ },
82057
82617
  {
82058
82618
  gateway: "query",
82059
82619
  domain: "tasks",
@@ -86406,10 +86966,10 @@ async function releaseShip(params, projectRoot) {
86406
86966
  );
86407
86967
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
86408
86968
  const { releaseManifests: releaseManifests2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
86409
- const { eq: eq16 } = await import("drizzle-orm");
86969
+ const { eq: eq17 } = await import("drizzle-orm");
86410
86970
  const normalizedVer = version2.startsWith("v") ? version2 : `v${version2}`;
86411
86971
  const db = await getDb4(cwd);
86412
- await db.update(releaseManifests2).set({ epicId }).where(eq16(releaseManifests2.version, normalizedVer)).run();
86972
+ await db.update(releaseManifests2).set({ epicId }).where(eq17(releaseManifests2.version, normalizedVer)).run();
86413
86973
  await generateReleaseChangelog(version2, () => loadTasks2(projectRoot), cwd);
86414
86974
  }
86415
86975
  logStep(0, 8, "Auto-prepare release record", true);
@@ -87641,6 +88201,15 @@ async function taskAnalyze(projectRoot, taskId, params) {
87641
88201
  return engineError("E_GENERAL", `Task analysis failed: ${message}`);
87642
88202
  }
87643
88203
  }
88204
+ async function taskImpact(projectRoot, change, matchLimit) {
88205
+ try {
88206
+ const result = await predictImpact(change, projectRoot, void 0, matchLimit);
88207
+ return { success: true, data: result };
88208
+ } catch (err) {
88209
+ const message = err instanceof Error ? err.message : String(err);
88210
+ return engineError("E_GENERAL", `Impact prediction failed: ${message}`);
88211
+ }
88212
+ }
87644
88213
  async function taskRestore(projectRoot, taskId, params) {
87645
88214
  try {
87646
88215
  const result = await coreTaskRestore(projectRoot, taskId, params);
@@ -92539,6 +93108,22 @@ var TasksHandler = class {
92539
93108
  const result = await taskAnalyze(projectRoot, taskId, { tierLimit });
92540
93109
  return wrapResult(result, "query", "tasks", operation, startTime);
92541
93110
  }
93111
+ case "impact": {
93112
+ const change = params?.change;
93113
+ if (!change) {
93114
+ return errorResult(
93115
+ "query",
93116
+ "tasks",
93117
+ operation,
93118
+ "E_INVALID_INPUT",
93119
+ "change is required (free-text description of the proposed change)",
93120
+ startTime
93121
+ );
93122
+ }
93123
+ const matchLimit = params?.matchLimit;
93124
+ const result = await taskImpact(projectRoot, change, matchLimit);
93125
+ return wrapResult(result, "query", "tasks", operation, startTime);
93126
+ }
92542
93127
  case "next": {
92543
93128
  const result = await taskNext(
92544
93129
  projectRoot,
@@ -92787,6 +93372,7 @@ var TasksHandler = class {
92787
93372
  "blockers",
92788
93373
  "depends",
92789
93374
  "analyze",
93375
+ "impact",
92790
93376
  "next",
92791
93377
  "plan",
92792
93378
  "relates",