@cleocode/core 2026.4.48 → 2026.4.49

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/index.js CHANGED
@@ -730,15 +730,15 @@ function getLogDir() {
730
730
  return currentLogDir;
731
731
  }
732
732
  function closeLogger() {
733
- return new Promise((resolve11) => {
733
+ return new Promise((resolve12) => {
734
734
  if (rootLogger) {
735
735
  rootLogger.flush(() => {
736
736
  rootLogger = null;
737
737
  currentLogDir = null;
738
- resolve11();
738
+ resolve12();
739
739
  });
740
740
  } else {
741
- resolve11();
741
+ resolve12();
742
742
  }
743
743
  });
744
744
  }
@@ -1546,10 +1546,10 @@ var init_subquery = __esm({
1546
1546
  init_entity();
1547
1547
  Subquery = class {
1548
1548
  static [entityKind] = "Subquery";
1549
- constructor(sql12, fields, alias, isWith = false, usedTables = []) {
1549
+ constructor(sql14, fields, alias, isWith = false, usedTables = []) {
1550
1550
  this._ = {
1551
1551
  brand: "Subquery",
1552
- sql: sql12,
1552
+ sql: sql14,
1553
1553
  selectedFields: fields,
1554
1554
  alias,
1555
1555
  isWith,
@@ -1900,7 +1900,7 @@ var init_sql = __esm({
1900
1900
  return new SQL([new StringChunk(str)]);
1901
1901
  }
1902
1902
  _sql.raw = raw;
1903
- function join107(chunks, separator) {
1903
+ function join109(chunks, separator) {
1904
1904
  const result = [];
1905
1905
  for (const [i, chunk] of chunks.entries()) {
1906
1906
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -1908,7 +1908,7 @@ var init_sql = __esm({
1908
1908
  }
1909
1909
  return new SQL(result);
1910
1910
  }
1911
- _sql.join = join107;
1911
+ _sql.join = join109;
1912
1912
  function identifier(value) {
1913
1913
  return new Name(value);
1914
1914
  }
@@ -1929,8 +1929,8 @@ var init_sql = __esm({
1929
1929
  isSelectionField = false;
1930
1930
  /** @internal */
1931
1931
  origin;
1932
- constructor(sql12, fieldAlias) {
1933
- this.sql = sql12;
1932
+ constructor(sql14, fieldAlias) {
1933
+ this.sql = sql14;
1934
1934
  this.fieldAlias = fieldAlias;
1935
1935
  }
1936
1936
  getSQL() {
@@ -2634,17 +2634,17 @@ var init_custom = __esm({
2634
2634
  mapFromJsonValue(value) {
2635
2635
  return typeof this.mapJson === "function" ? this.mapJson(value) : this.mapFromDriverValue(value);
2636
2636
  }
2637
- jsonSelectIdentifier(identifier, sql12) {
2638
- if (typeof this.forJsonSelect === "function") return this.forJsonSelect(identifier, sql12);
2637
+ jsonSelectIdentifier(identifier, sql14) {
2638
+ if (typeof this.forJsonSelect === "function") return this.forJsonSelect(identifier, sql14);
2639
2639
  const rawType = this.getSQLType().toLowerCase();
2640
2640
  const parenPos = rawType.indexOf("(");
2641
2641
  switch (parenPos + 1 ? rawType.slice(0, parenPos) : rawType) {
2642
2642
  case "numeric":
2643
2643
  case "decimal":
2644
2644
  case "bigint":
2645
- return sql12`cast(${identifier} as text)`;
2645
+ return sql14`cast(${identifier} as text)`;
2646
2646
  case "blob":
2647
- return sql12`hex(${identifier})`;
2647
+ return sql14`hex(${identifier})`;
2648
2648
  default:
2649
2649
  return identifier;
2650
2650
  }
@@ -3812,8 +3812,8 @@ var init_custom2 = __esm({
3812
3812
  mapFromJsonValue(value) {
3813
3813
  return typeof this.mapJson === "function" ? this.mapJson(value) : this.mapFromDriverValue(value);
3814
3814
  }
3815
- jsonSelectIdentifier(identifier, sql12, arrayDimensions) {
3816
- if (typeof this.forJsonSelect === "function") return this.forJsonSelect(identifier, sql12, arrayDimensions);
3815
+ jsonSelectIdentifier(identifier, sql14, arrayDimensions) {
3816
+ if (typeof this.forJsonSelect === "function") return this.forJsonSelect(identifier, sql14, arrayDimensions);
3817
3817
  const rawType = this.getSQLType().toLowerCase();
3818
3818
  const parenPos = rawType.indexOf("(");
3819
3819
  switch (parenPos + 1 ? rawType.slice(0, parenPos) : rawType) {
@@ -3823,7 +3823,7 @@ var init_custom2 = __esm({
3823
3823
  case "numeric":
3824
3824
  case "bigint": {
3825
3825
  const arrVal = "[]".repeat(arrayDimensions ?? 0);
3826
- return sql12`${identifier}::text${sql12.raw(arrVal).if(arrayDimensions)}`;
3826
+ return sql14`${identifier}::text${sql14.raw(arrVal).if(arrayDimensions)}`;
3827
3827
  }
3828
3828
  default:
3829
3829
  return identifier;
@@ -6682,7 +6682,7 @@ var init_select2 = __esm({
6682
6682
  const baseTableName = this.tableName;
6683
6683
  const tableName = getTableLikeName(table);
6684
6684
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
6685
- if (typeof tableName === "string" && this.config.joins?.some((join107) => join107.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
6685
+ if (typeof tableName === "string" && this.config.joins?.some((join109) => join109.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
6686
6686
  if (!this.isPartialSelect) {
6687
6687
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
6688
6688
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -7704,8 +7704,8 @@ var init_dialect = __esm({
7704
7704
  const returningSql = returning ? sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` : void 0;
7705
7705
  return sql`${withSql}insert into ${table} ${insertOrder} ${valuesSql}${onConflict?.length ? sql.join(onConflict) : void 0}${returningSql}`;
7706
7706
  }
7707
- sqlToQuery(sql12, invokeSource) {
7708
- return sql12.toQuery({
7707
+ sqlToQuery(sql14, invokeSource) {
7708
+ return sql14.toQuery({
7709
7709
  casing: this.casing,
7710
7710
  escapeName: this.escapeName,
7711
7711
  escapeParam: this.escapeParam,
@@ -7967,7 +7967,7 @@ var init_dialect = __esm({
7967
7967
  if (!joins2) return;
7968
7968
  const withEntries = Object.entries(joins2).filter(([_, v]) => v);
7969
7969
  if (!withEntries.length) return;
7970
- return sql.join(withEntries.map(([k, join107]) => {
7970
+ return sql.join(withEntries.map(([k, join109]) => {
7971
7971
  const relation = tableConfig.relations[k];
7972
7972
  const isSingle2 = is(relation, One3);
7973
7973
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -7978,7 +7978,7 @@ var init_dialect = __esm({
7978
7978
  table: targetTable,
7979
7979
  mode: isSingle2 ? "first" : "many",
7980
7980
  schema,
7981
- queryConfig: join107,
7981
+ queryConfig: join109,
7982
7982
  tableConfig: schema[relation.targetTableName],
7983
7983
  relationWhere: filter,
7984
7984
  isNested: true,
@@ -7992,7 +7992,7 @@ var init_dialect = __esm({
7992
7992
  key: k,
7993
7993
  selection: innerQuery.selection,
7994
7994
  isArray: !isSingle2,
7995
- isOptional: (relation.optional ?? false) || join107 !== true && !!join107.where
7995
+ isOptional: (relation.optional ?? false) || join109 !== true && !!join109.where
7996
7996
  });
7997
7997
  const jsonColumns = sql.join(innerQuery.selection.map((s) => {
7998
7998
  return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb2}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
@@ -8391,7 +8391,7 @@ var init_update = __esm({
8391
8391
  createJoin(joinType) {
8392
8392
  return ((table, on) => {
8393
8393
  const tableName = getTableLikeName(table);
8394
- if (typeof tableName === "string" && this.config.joins.some((join107) => join107.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
8394
+ if (typeof tableName === "string" && this.config.joins.some((join109) => join109.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
8395
8395
  if (typeof on === "function") {
8396
8396
  const from = this.config.from ? is(table, SQLiteTable) ? table[Table.Symbol.Columns] : is(table, Subquery) ? table._.selectedFields : is(table, SQLiteViewBase) ? table[ViewBaseConfig].selectedFields : void 0 : void 0;
8397
8397
  on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -8802,8 +8802,8 @@ var init_db = __esm({
8802
8802
  });
8803
8803
 
8804
8804
  // node_modules/.pnpm/drizzle-orm@1.0.0-beta.19-d95b7a4_@sinclair+typebox@0.34.49_@types+mssql@9.1.9_@azure+c_7d603f9dc53f6bedf2f8e8db5954b691/node_modules/drizzle-orm/cache/core/cache.js
8805
- async function hashQuery(sql12, params) {
8806
- const dataToHash = `${sql12}-${JSON.stringify(params, (_, v) => typeof v === "bigint" ? `${v}n` : v)}`;
8805
+ async function hashQuery(sql14, params) {
8806
+ const dataToHash = `${sql14}-${JSON.stringify(params, (_, v) => typeof v === "bigint" ? `${v}n` : v)}`;
8807
8807
  const data = new TextEncoder().encode(dataToHash);
8808
8808
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
8809
8809
  return [...new Uint8Array(hashBuffer)].map((b) => b.toString(16).padStart(2, "0")).join("");
@@ -8982,8 +8982,8 @@ var init_session3 = __esm({
8982
8982
  values(query) {
8983
8983
  return this.prepareOneTimeQuery(this.dialect.sqlToQuery(query), void 0, "run", false).values();
8984
8984
  }
8985
- async count(sql12) {
8986
- return (await this.values(sql12))[0][0];
8985
+ async count(sql14) {
8986
+ return (await this.values(sql14))[0][0];
8987
8987
  }
8988
8988
  /** @internal */
8989
8989
  extractRawValuesValueFromBatchResult(_result) {
@@ -11670,12 +11670,12 @@ function detachAgentFromProject(db, agentId) {
11670
11670
  }
11671
11671
  function listProjectAgentRefs(db, opts) {
11672
11672
  const enabledOnly = opts?.enabledOnly ?? true;
11673
- const sql12 = enabledOnly ? `SELECT agent_id, attached_at, role, capabilities_override, last_used_at, enabled
11673
+ const sql14 = enabledOnly ? `SELECT agent_id, attached_at, role, capabilities_override, last_used_at, enabled
11674
11674
  FROM project_agent_refs WHERE enabled = 1
11675
11675
  ORDER BY attached_at DESC` : `SELECT agent_id, attached_at, role, capabilities_override, last_used_at, enabled
11676
11676
  FROM project_agent_refs
11677
11677
  ORDER BY attached_at DESC`;
11678
- const rows = db.prepare(sql12).all();
11678
+ const rows = db.prepare(sql14).all();
11679
11679
  return rows.map((r) => ({
11680
11680
  agentId: r.agent_id,
11681
11681
  attachedAt: r.attached_at,
@@ -12020,12 +12020,21 @@ var init_nexus_schema = __esm({
12020
12020
  permissions: text("permissions").notNull().default("read"),
12021
12021
  lastSync: text("last_sync").notNull().default(sql3`(datetime('now'))`),
12022
12022
  taskCount: integer("task_count").notNull().default(0),
12023
- labelsJson: text("labels_json").notNull().default("[]")
12023
+ labelsJson: text("labels_json").notNull().default("[]"),
12024
+ /** Absolute path to the project's brain.db file. */
12025
+ brainDbPath: text("brain_db_path"),
12026
+ /** Absolute path to the project's tasks.db file. */
12027
+ tasksDbPath: text("tasks_db_path"),
12028
+ /** ISO 8601 timestamp of the last successful code intelligence index run. */
12029
+ lastIndexed: text("last_indexed"),
12030
+ /** JSON object with per-project code intelligence stats (node_count, relation_count, file_count). */
12031
+ statsJson: text("stats_json").notNull().default("{}")
12024
12032
  },
12025
12033
  (table) => [
12026
12034
  index("idx_project_registry_hash").on(table.projectHash),
12027
12035
  index("idx_project_registry_health").on(table.healthStatus),
12028
- index("idx_project_registry_name").on(table.name)
12036
+ index("idx_project_registry_name").on(table.name),
12037
+ index("idx_project_registry_last_indexed").on(table.lastIndexed)
12029
12038
  ]
12030
12039
  );
12031
12040
  nexusAuditLog = sqliteTable(
@@ -16529,7 +16538,7 @@ async function linkPipelineAdr(projectRoot, taskId) {
16529
16538
  return result;
16530
16539
  }
16531
16540
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
16532
- const { and: and10, eq: eq13 } = await import("drizzle-orm");
16541
+ const { and: and11, eq: eq13 } = await import("drizzle-orm");
16533
16542
  const db = await getDb3(projectRoot);
16534
16543
  const now = (/* @__PURE__ */ new Date()).toISOString();
16535
16544
  for (const filePath of matchingFiles) {
@@ -16564,7 +16573,7 @@ async function linkPipelineAdr(projectRoot, taskId) {
16564
16573
  await db.insert(architectureDecisions).values({ ...rowBase, createdAt: now });
16565
16574
  }
16566
16575
  result.synced++;
16567
- await db.delete(adrTaskLinks).where(and10(eq13(adrTaskLinks.adrId, record2.id), eq13(adrTaskLinks.taskId, taskId)));
16576
+ await db.delete(adrTaskLinks).where(and11(eq13(adrTaskLinks.adrId, record2.id), eq13(adrTaskLinks.taskId, taskId)));
16568
16577
  await db.insert(adrTaskLinks).values({ adrId: record2.id, taskId, linkType: "implements" });
16569
16578
  result.linked.push({ adrId: record2.id, taskId });
16570
16579
  if (fm["Related ADRs"]) {
@@ -17362,7 +17371,7 @@ async function withRetry(fn, policy) {
17362
17371
  if (!shouldRetry(err, attempt, effectivePolicy)) break;
17363
17372
  const delay = calculateDelay(attempt, effectivePolicy);
17364
17373
  totalDelayMs += delay;
17365
- await new Promise((resolve11) => setTimeout(resolve11, delay));
17374
+ await new Promise((resolve12) => setTimeout(resolve12, delay));
17366
17375
  }
17367
17376
  }
17368
17377
  const error48 = lastError instanceof Error ? lastError : new Error(String(lastError));
@@ -18058,7 +18067,7 @@ function analyzeStructure(projectRoot) {
18058
18067
  }
18059
18068
  function countFiles(dir, depth = 0) {
18060
18069
  if (depth > 5) return 0;
18061
- let count2 = 0;
18070
+ let count3 = 0;
18062
18071
  const entries = safeReaddir2(dir);
18063
18072
  for (const entry of entries) {
18064
18073
  if (EXCLUDED_DIRS.has(entry) || entry.startsWith(".")) continue;
@@ -18066,14 +18075,14 @@ function countFiles(dir, depth = 0) {
18066
18075
  try {
18067
18076
  const stat2 = statSync3(entryPath);
18068
18077
  if (stat2.isDirectory()) {
18069
- count2 += countFiles(entryPath, depth + 1);
18078
+ count3 += countFiles(entryPath, depth + 1);
18070
18079
  } else {
18071
- count2++;
18080
+ count3++;
18072
18081
  }
18073
18082
  } catch {
18074
18083
  }
18075
18084
  }
18076
- return count2;
18085
+ return count3;
18077
18086
  }
18078
18087
  function safeReaddir2(dir) {
18079
18088
  try {
@@ -19432,8 +19441,8 @@ function checkFts5Available(nativeDb) {
19432
19441
  }
19433
19442
  return _fts5Available;
19434
19443
  }
19435
- function execDDL(nativeDb, sql12) {
19436
- nativeDb.prepare(sql12).run();
19444
+ function execDDL(nativeDb, sql14) {
19445
+ nativeDb.prepare(sql14).run();
19437
19446
  }
19438
19447
  function ensureFts5Tables(nativeDb) {
19439
19448
  if (!checkFts5Available(nativeDb)) {
@@ -20266,8 +20275,8 @@ __export(memory_bridge_exports, {
20266
20275
  });
20267
20276
  import { existsSync as existsSync27, mkdirSync as mkdirSync7, readFileSync as readFileSync15, writeFileSync as writeFileSync2 } from "node:fs";
20268
20277
  import { join as join30 } from "node:path";
20269
- function typedAll2(db, sql12, ...params) {
20270
- return db.prepare(sql12).all(...params);
20278
+ function typedAll2(db, sql14, ...params) {
20279
+ return db.prepare(sql14).all(...params);
20271
20280
  }
20272
20281
  async function generateMemoryBridgeContent(projectRoot, config2) {
20273
20282
  const cfg = { ...DEFAULT_CONFIG, ...config2 };
@@ -20589,7 +20598,7 @@ async function queryAudit(options) {
20589
20598
  try {
20590
20599
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
20591
20600
  const { auditLog: auditLog2 } = await Promise.resolve().then(() => (init_tasks_schema(), tasks_schema_exports));
20592
- const { and: and10, eq: eq13, gte: gte3, or: or5 } = await import("drizzle-orm");
20601
+ const { and: and11, eq: eq13, gte: gte3, or: or5 } = await import("drizzle-orm");
20593
20602
  const db = await getDb3(process.cwd());
20594
20603
  const conditions = [];
20595
20604
  if (options?.sessionId) conditions.push(eq13(auditLog2.sessionId, options.sessionId));
@@ -20601,7 +20610,7 @@ async function queryAudit(options) {
20601
20610
  if (options?.taskId) conditions.push(eq13(auditLog2.taskId, options.taskId));
20602
20611
  if (options?.since) conditions.push(gte3(auditLog2.timestamp, options.since));
20603
20612
  const limit = options?.limit ?? 1e3;
20604
- const rows = await db.select().from(auditLog2).where(conditions.length > 0 ? and10(...conditions) : void 0).orderBy(auditLog2.timestamp).limit(limit);
20613
+ const rows = await db.select().from(auditLog2).where(conditions.length > 0 ? and11(...conditions) : void 0).orderBy(auditLog2.timestamp).limit(limit);
20605
20614
  return rows.map((row) => ({
20606
20615
  timestamp: row.timestamp,
20607
20616
  sessionId: row.sessionId,
@@ -20729,8 +20738,8 @@ async function gradeSession(sessionId, cwd) {
20729
20738
  );
20730
20739
  let hygieneScore = 20;
20731
20740
  for (const addCall of addCalls) {
20732
- const desc5 = addCall.params?.description;
20733
- if (!desc5 || desc5.trim().length === 0) {
20741
+ const desc6 = addCall.params?.description;
20742
+ if (!desc6 || desc6.trim().length === 0) {
20734
20743
  hygieneScore -= 5;
20735
20744
  result.flags.push(
20736
20745
  `tasks.add without description (taskId: ${addCall.metadata?.taskId ?? "unknown"})`
@@ -20959,9 +20968,9 @@ __export(decisions_exports, {
20959
20968
  async function nextDecisionId(projectRoot) {
20960
20969
  const { getBrainDb: getBrainDb2 } = await Promise.resolve().then(() => (init_brain_sqlite(), brain_sqlite_exports));
20961
20970
  const { brainDecisions: brainDecisions2 } = await Promise.resolve().then(() => (init_brain_schema(), brain_schema_exports));
20962
- const { desc: desc5 } = await import("drizzle-orm");
20971
+ const { desc: desc6 } = await import("drizzle-orm");
20963
20972
  const db = await getBrainDb2(projectRoot);
20964
- const rows = await db.select({ id: brainDecisions2.id }).from(brainDecisions2).orderBy(desc5(brainDecisions2.id)).limit(1);
20973
+ const rows = await db.select({ id: brainDecisions2.id }).from(brainDecisions2).orderBy(desc6(brainDecisions2.id)).limit(1);
20965
20974
  if (rows.length === 0) {
20966
20975
  return "D001";
20967
20976
  }
@@ -21387,7 +21396,7 @@ var init_values = __esm({
21387
21396
  var sleep;
21388
21397
  var init_sleep = __esm({
21389
21398
  "node_modules/.pnpm/@anthropic-ai+sdk@0.88.0_zod@4.3.6/node_modules/@anthropic-ai/sdk/internal/utils/sleep.mjs"() {
21390
- sleep = (ms) => new Promise((resolve11) => setTimeout(resolve11, ms));
21399
+ sleep = (ms) => new Promise((resolve12) => setTimeout(resolve12, ms));
21391
21400
  }
21392
21401
  });
21393
21402
 
@@ -22165,8 +22174,8 @@ var init_api_promise = __esm({
22165
22174
  init_parse2();
22166
22175
  APIPromise = class _APIPromise extends Promise {
22167
22176
  constructor(client, responsePromise, parseResponse = defaultParseResponse) {
22168
- super((resolve11) => {
22169
- resolve11(null);
22177
+ super((resolve12) => {
22178
+ resolve12(null);
22170
22179
  });
22171
22180
  this.responsePromise = responsePromise;
22172
22181
  this.parseResponse = parseResponse;
@@ -23602,12 +23611,12 @@ var init_BetaMessageStream = __esm({
23602
23611
  }
23603
23612
  return this._emit("error", new AnthropicError(String(error48)));
23604
23613
  });
23605
- __classPrivateFieldSet(this, _BetaMessageStream_connectedPromise, new Promise((resolve11, reject) => {
23606
- __classPrivateFieldSet(this, _BetaMessageStream_resolveConnectedPromise, resolve11, "f");
23614
+ __classPrivateFieldSet(this, _BetaMessageStream_connectedPromise, new Promise((resolve12, reject) => {
23615
+ __classPrivateFieldSet(this, _BetaMessageStream_resolveConnectedPromise, resolve12, "f");
23607
23616
  __classPrivateFieldSet(this, _BetaMessageStream_rejectConnectedPromise, reject, "f");
23608
23617
  }), "f");
23609
- __classPrivateFieldSet(this, _BetaMessageStream_endPromise, new Promise((resolve11, reject) => {
23610
- __classPrivateFieldSet(this, _BetaMessageStream_resolveEndPromise, resolve11, "f");
23618
+ __classPrivateFieldSet(this, _BetaMessageStream_endPromise, new Promise((resolve12, reject) => {
23619
+ __classPrivateFieldSet(this, _BetaMessageStream_resolveEndPromise, resolve12, "f");
23611
23620
  __classPrivateFieldSet(this, _BetaMessageStream_rejectEndPromise, reject, "f");
23612
23621
  }), "f");
23613
23622
  __classPrivateFieldGet(this, _BetaMessageStream_connectedPromise, "f").catch(() => {
@@ -23777,11 +23786,11 @@ var init_BetaMessageStream = __esm({
23777
23786
  * const message = await stream.emitted('message') // rejects if the stream errors
23778
23787
  */
23779
23788
  emitted(event) {
23780
- return new Promise((resolve11, reject) => {
23789
+ return new Promise((resolve12, reject) => {
23781
23790
  __classPrivateFieldSet(this, _BetaMessageStream_catchingPromiseCreated, true, "f");
23782
23791
  if (event !== "error")
23783
23792
  this.once("error", reject);
23784
- this.once(event, resolve11);
23793
+ this.once(event, resolve12);
23785
23794
  });
23786
23795
  }
23787
23796
  async done() {
@@ -24124,7 +24133,7 @@ var init_BetaMessageStream = __esm({
24124
24133
  if (done) {
24125
24134
  return { value: void 0, done: true };
24126
24135
  }
24127
- return new Promise((resolve11, reject) => readQueue.push({ resolve: resolve11, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
24136
+ return new Promise((resolve12, reject) => readQueue.push({ resolve: resolve12, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
24128
24137
  }
24129
24138
  const chunk = pushQueue.shift();
24130
24139
  return { value: chunk, done: false };
@@ -24195,13 +24204,13 @@ Wrap your summary in <summary></summary> tags.`;
24195
24204
 
24196
24205
  // node_modules/.pnpm/@anthropic-ai+sdk@0.88.0_zod@4.3.6/node_modules/@anthropic-ai/sdk/lib/tools/BetaToolRunner.mjs
24197
24206
  function promiseWithResolvers() {
24198
- let resolve11;
24207
+ let resolve12;
24199
24208
  let reject;
24200
24209
  const promise2 = new Promise((res, rej) => {
24201
- resolve11 = res;
24210
+ resolve12 = res;
24202
24211
  reject = rej;
24203
24212
  });
24204
- return { promise: promise2, resolve: resolve11, reject };
24213
+ return { promise: promise2, resolve: resolve12, reject };
24205
24214
  }
24206
24215
  async function generateToolResponse(params, lastMessage = params.messages.at(-1), requestOptions) {
24207
24216
  if (!lastMessage || lastMessage.role !== "assistant" || !lastMessage.content || typeof lastMessage.content === "string") {
@@ -26021,12 +26030,12 @@ var init_MessageStream = __esm({
26021
26030
  }
26022
26031
  return this._emit("error", new AnthropicError(String(error48)));
26023
26032
  });
26024
- __classPrivateFieldSet(this, _MessageStream_connectedPromise, new Promise((resolve11, reject) => {
26025
- __classPrivateFieldSet(this, _MessageStream_resolveConnectedPromise, resolve11, "f");
26033
+ __classPrivateFieldSet(this, _MessageStream_connectedPromise, new Promise((resolve12, reject) => {
26034
+ __classPrivateFieldSet(this, _MessageStream_resolveConnectedPromise, resolve12, "f");
26026
26035
  __classPrivateFieldSet(this, _MessageStream_rejectConnectedPromise, reject, "f");
26027
26036
  }), "f");
26028
- __classPrivateFieldSet(this, _MessageStream_endPromise, new Promise((resolve11, reject) => {
26029
- __classPrivateFieldSet(this, _MessageStream_resolveEndPromise, resolve11, "f");
26037
+ __classPrivateFieldSet(this, _MessageStream_endPromise, new Promise((resolve12, reject) => {
26038
+ __classPrivateFieldSet(this, _MessageStream_resolveEndPromise, resolve12, "f");
26030
26039
  __classPrivateFieldSet(this, _MessageStream_rejectEndPromise, reject, "f");
26031
26040
  }), "f");
26032
26041
  __classPrivateFieldGet(this, _MessageStream_connectedPromise, "f").catch(() => {
@@ -26196,11 +26205,11 @@ var init_MessageStream = __esm({
26196
26205
  * const message = await stream.emitted('message') // rejects if the stream errors
26197
26206
  */
26198
26207
  emitted(event) {
26199
- return new Promise((resolve11, reject) => {
26208
+ return new Promise((resolve12, reject) => {
26200
26209
  __classPrivateFieldSet(this, _MessageStream_catchingPromiseCreated, true, "f");
26201
26210
  if (event !== "error")
26202
26211
  this.once("error", reject);
26203
- this.once(event, resolve11);
26212
+ this.once(event, resolve12);
26204
26213
  });
26205
26214
  }
26206
26215
  async done() {
@@ -26518,7 +26527,7 @@ var init_MessageStream = __esm({
26518
26527
  if (done) {
26519
26528
  return { value: void 0, done: true };
26520
26529
  }
26521
- return new Promise((resolve11, reject) => readQueue.push({ resolve: resolve11, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
26530
+ return new Promise((resolve12, reject) => readQueue.push({ resolve: resolve12, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
26522
26531
  }
26523
26532
  const chunk = pushQueue.shift();
26524
26533
  return { value: chunk, done: false };
@@ -30286,8 +30295,8 @@ var init_schemas = __esm({
30286
30295
  });
30287
30296
  $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def2) => {
30288
30297
  $ZodType.init(inst, def2);
30289
- const desc5 = Object.getOwnPropertyDescriptor(def2, "shape");
30290
- if (!desc5?.get) {
30298
+ const desc6 = Object.getOwnPropertyDescriptor(def2, "shape");
30299
+ if (!desc6?.get) {
30291
30300
  const sh = def2.shape;
30292
30301
  Object.defineProperty(def2, "shape", {
30293
30302
  get: () => {
@@ -31529,8 +31538,8 @@ var init_az = __esm({
31529
31538
  });
31530
31539
 
31531
31540
  // node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/be.js
31532
- function getBelarusianPlural(count2, one, few, many) {
31533
- const absCount = Math.abs(count2);
31541
+ function getBelarusianPlural(count3, one, few, many) {
31542
+ const absCount = Math.abs(count3);
31534
31543
  const lastDigit = absCount % 10;
31535
31544
  const lastTwoDigits = absCount % 100;
31536
31545
  if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
@@ -33444,8 +33453,8 @@ var init_hu = __esm({
33444
33453
  });
33445
33454
 
33446
33455
  // node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/hy.js
33447
- function getArmenianPlural(count2, one, many) {
33448
- return Math.abs(count2) === 1 ? one : many;
33456
+ function getArmenianPlural(count3, one, many) {
33457
+ return Math.abs(count3) === 1 ? one : many;
33449
33458
  }
33450
33459
  function withDefiniteArticle(word) {
33451
33460
  if (!word)
@@ -35560,8 +35569,8 @@ var init_pt = __esm({
35560
35569
  });
35561
35570
 
35562
35571
  // node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ru.js
35563
- function getRussianPlural(count2, one, few, many) {
35564
- const absCount = Math.abs(count2);
35572
+ function getRussianPlural(count3, one, few, many) {
35573
+ const absCount = Math.abs(count3);
35565
35574
  const lastDigit = absCount % 10;
35566
35575
  const lastTwoDigits = absCount % 100;
35567
35576
  if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
@@ -43275,8 +43284,8 @@ async function strengthenCoRetrievedEdges(projectRoot) {
43275
43284
  }
43276
43285
  }
43277
43286
  let strengthened = 0;
43278
- for (const [pair, count2] of coOccurrence) {
43279
- if (count2 < 3) continue;
43287
+ for (const [pair, count3] of coOccurrence) {
43288
+ if (count3 < 3) continue;
43280
43289
  const [fromId, toId] = pair.split("|");
43281
43290
  if (!fromId || !toId) continue;
43282
43291
  const nodeFrom = `observation:${fromId}`;
@@ -43624,8 +43633,8 @@ async function runObserver(projectRoot, sessionId) {
43624
43633
  } catch {
43625
43634
  return empty;
43626
43635
  }
43627
- const count2 = countSessionObservations(sessionId);
43628
- if (count2 < cfg.threshold) return empty;
43636
+ const count3 = countSessionObservations(sessionId);
43637
+ if (count3 < cfg.threshold) return empty;
43629
43638
  const observations = fetchSessionObservations(sessionId, OBSERVER_BATCH_LIMIT);
43630
43639
  if (observations.length < 2) return empty;
43631
43640
  const observationList = observations.map(
@@ -50661,14 +50670,14 @@ async function validateEpicCreation(options, cwd) {
50661
50670
  const mode = await getLifecycleMode(cwd);
50662
50671
  if (mode === "off") return { valid: true };
50663
50672
  const ac = options.acceptance ?? [];
50664
- const desc5 = (options.description ?? "").trim();
50673
+ const desc6 = (options.description ?? "").trim();
50665
50674
  const violations = [];
50666
50675
  if (ac.length < EPIC_MIN_AC) {
50667
50676
  violations.push(
50668
50677
  `Epic requires at least ${EPIC_MIN_AC} acceptance criteria (${ac.length} provided). Regular tasks need ${TASK_MIN_AC}.`
50669
50678
  );
50670
50679
  }
50671
- if (!desc5) {
50680
+ if (!desc6) {
50672
50681
  violations.push("Epic must have a non-empty description (used as completion criteria).");
50673
50682
  }
50674
50683
  if (violations.length === 0) return { valid: true };
@@ -51589,7 +51598,7 @@ function migrateAgentOutputs(projectRoot, cleoDir) {
51589
51598
  };
51590
51599
  }
51591
51600
  function copyDirContents(srcDir, dstDir, manifestLines, copiedFiles) {
51592
- let count2 = 0;
51601
+ let count3 = 0;
51593
51602
  const entries = readdirSync21(srcDir);
51594
51603
  for (const entry of entries) {
51595
51604
  if (entry === "MANIFEST.jsonl") {
@@ -51607,7 +51616,7 @@ function copyDirContents(srcDir, dstDir, manifestLines, copiedFiles) {
51607
51616
  try {
51608
51617
  copyFileSync6(join55(srcPath, sf), join55(dstPath, sf));
51609
51618
  copiedFiles.add(sf);
51610
- count2++;
51619
+ count3++;
51611
51620
  } catch {
51612
51621
  }
51613
51622
  }
@@ -51615,12 +51624,12 @@ function copyDirContents(srcDir, dstDir, manifestLines, copiedFiles) {
51615
51624
  } else if (!copiedFiles.has(entry)) {
51616
51625
  copyFileSync6(srcPath, dstPath);
51617
51626
  copiedFiles.add(entry);
51618
- count2++;
51627
+ count3++;
51619
51628
  }
51620
51629
  } catch {
51621
51630
  }
51622
51631
  }
51623
- return count2;
51632
+ return count3;
51624
51633
  }
51625
51634
  function collectManifestLines(manifestPath, out) {
51626
51635
  try {
@@ -51840,13 +51849,14 @@ __export(registry_exports3, {
51840
51849
  nexusSync: () => nexusSync,
51841
51850
  nexusSyncAll: () => nexusSyncAll,
51842
51851
  nexusUnregister: () => nexusUnregister,
51852
+ nexusUpdateIndexStats: () => nexusUpdateIndexStats,
51843
51853
  readRegistry: () => readRegistry,
51844
51854
  readRegistryRequired: () => readRegistryRequired,
51845
51855
  resetNexusDbState: () => resetNexusDbState
51846
51856
  });
51847
51857
  import { randomUUID as randomUUID4 } from "node:crypto";
51848
51858
  import { mkdir as mkdir12 } from "node:fs/promises";
51849
- import { basename as basename9, join as join62 } from "node:path";
51859
+ import { basename as basename9, join as join62, resolve as resolve7 } from "node:path";
51850
51860
  function getNexusHome() {
51851
51861
  return process.env["NEXUS_HOME"] ?? join62(getCleoHome(), "nexus");
51852
51862
  }
@@ -51863,6 +51873,17 @@ function rowToProject(row) {
51863
51873
  } catch {
51864
51874
  labels = [];
51865
51875
  }
51876
+ let stats2 = { nodeCount: 0, relationCount: 0, fileCount: 0 };
51877
+ try {
51878
+ const parsed = JSON.parse(row.statsJson ?? "{}");
51879
+ stats2 = {
51880
+ nodeCount: parsed.nodeCount ?? 0,
51881
+ relationCount: parsed.relationCount ?? 0,
51882
+ fileCount: parsed.fileCount ?? 0
51883
+ };
51884
+ } catch {
51885
+ stats2 = { nodeCount: 0, relationCount: 0, fileCount: 0 };
51886
+ }
51866
51887
  return {
51867
51888
  hash: row.projectHash,
51868
51889
  projectId: row.projectId,
@@ -51875,7 +51896,11 @@ function rowToProject(row) {
51875
51896
  permissions: row.permissions,
51876
51897
  lastSync: row.lastSync,
51877
51898
  taskCount: row.taskCount,
51878
- labels
51899
+ labels,
51900
+ brainDbPath: row.brainDbPath ?? null,
51901
+ tasksDbPath: row.tasksDbPath ?? null,
51902
+ lastIndexed: row.lastIndexed ?? null,
51903
+ stats: stats2
51879
51904
  };
51880
51905
  }
51881
51906
  async function writeNexusAudit(fields) {
@@ -51971,10 +51996,10 @@ async function readProjectMeta(projectPath) {
51971
51996
  }
51972
51997
  async function readProjectId(projectPath) {
51973
51998
  try {
51974
- const { readFileSync: readFileSync78, existsSync: existsSync108 } = await import("node:fs");
51999
+ const { readFileSync: readFileSync79, existsSync: existsSync109 } = await import("node:fs");
51975
52000
  const infoPath = join62(projectPath, ".cleo", "project-info.json");
51976
- if (!existsSync108(infoPath)) return "";
51977
- const data = JSON.parse(readFileSync78(infoPath, "utf-8"));
52001
+ if (!existsSync109(infoPath)) return "";
52002
+ const data = JSON.parse(readFileSync79(infoPath, "utf-8"));
51978
52003
  return typeof data.projectId === "string" ? data.projectId : "";
51979
52004
  } catch {
51980
52005
  return "";
@@ -52015,13 +52040,18 @@ async function nexusRegister(projectPath, name2, permissions = "read") {
52015
52040
  const meta3 = await readProjectMeta(projectPath);
52016
52041
  const now = (/* @__PURE__ */ new Date()).toISOString();
52017
52042
  let projectId = await readProjectId(projectPath);
52043
+ const resolvedPath = resolve7(projectPath);
52044
+ const brainDbPath = join62(resolvedPath, ".cleo", "brain.db");
52045
+ const tasksDbPath = join62(resolvedPath, ".cleo", "tasks.db");
52018
52046
  if (existing) {
52019
52047
  await db.update(projectRegistry).set({
52020
52048
  permissions,
52021
52049
  lastSync: now,
52022
52050
  taskCount: meta3.taskCount,
52023
52051
  labelsJson: JSON.stringify(meta3.labels),
52024
- lastSeen: now
52052
+ lastSeen: now,
52053
+ brainDbPath,
52054
+ tasksDbPath
52025
52055
  }).where(eq13(projectRegistry.projectHash, projectHash));
52026
52056
  } else {
52027
52057
  if (!projectId) {
@@ -52039,7 +52069,10 @@ async function nexusRegister(projectPath, name2, permissions = "read") {
52039
52069
  permissions,
52040
52070
  lastSync: now,
52041
52071
  taskCount: meta3.taskCount,
52042
- labelsJson: JSON.stringify(meta3.labels)
52072
+ labelsJson: JSON.stringify(meta3.labels),
52073
+ brainDbPath,
52074
+ tasksDbPath,
52075
+ statsJson: "{}"
52043
52076
  });
52044
52077
  }
52045
52078
  await writeNexusAudit({
@@ -52155,6 +52188,41 @@ async function nexusSyncAll() {
52155
52188
  });
52156
52189
  return { synced, failed };
52157
52190
  }
52191
+ async function nexusUpdateIndexStats(projectPath, stats2) {
52192
+ if (!projectPath) return;
52193
+ const projectHash = generateProjectHash(projectPath);
52194
+ const now = (/* @__PURE__ */ new Date()).toISOString();
52195
+ try {
52196
+ const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
52197
+ const { eq: eq13 } = await import("drizzle-orm");
52198
+ const db = await getNexusDb2();
52199
+ const rows = await db.select().from(projectRegistry).where(eq13(projectRegistry.projectHash, projectHash));
52200
+ if (rows.length === 0) {
52201
+ try {
52202
+ await nexusRegister(projectPath);
52203
+ } catch {
52204
+ }
52205
+ }
52206
+ await db.update(projectRegistry).set({
52207
+ lastIndexed: now,
52208
+ statsJson: JSON.stringify(stats2),
52209
+ lastSeen: now
52210
+ }).where(eq13(projectRegistry.projectHash, projectHash));
52211
+ await writeNexusAudit({
52212
+ action: "update-index-stats",
52213
+ projectHash,
52214
+ operation: "update-index-stats",
52215
+ success: true,
52216
+ details: {
52217
+ nodeCount: stats2.nodeCount,
52218
+ relationCount: stats2.relationCount,
52219
+ fileCount: stats2.fileCount
52220
+ }
52221
+ });
52222
+ } catch (err) {
52223
+ getLogger("nexus").warn({ err }, "nexus: failed to update index stats");
52224
+ }
52225
+ }
52158
52226
  async function nexusSetPermission(nameOrHash, permission) {
52159
52227
  const project = await nexusGetProject(nameOrHash);
52160
52228
  if (!project) {
@@ -54147,29 +54215,29 @@ var init_dependencies = __esm({
54147
54215
  });
54148
54216
 
54149
54217
  // packages/core/src/discovery.ts
54150
- import { existsSync as existsSync104, readdirSync as readdirSync34, statSync as statSync20 } from "node:fs";
54151
- import { join as join103, resolve as resolve10 } from "node:path";
54218
+ import { existsSync as existsSync105, readdirSync as readdirSync34, statSync as statSync20 } from "node:fs";
54219
+ import { join as join105, resolve as resolve11 } from "node:path";
54152
54220
  function countMeaningfulTopLevelFiles(directory) {
54153
- if (!existsSync104(directory)) return 0;
54221
+ if (!existsSync105(directory)) return 0;
54154
54222
  try {
54155
54223
  const entries = readdirSync34(directory);
54156
- let count2 = 0;
54224
+ let count3 = 0;
54157
54225
  for (const entry of entries) {
54158
54226
  if (entry.startsWith(".") || entry === ".cleo" || entry === "node_modules" || entry === "target" || entry === "dist" || entry === "build") {
54159
54227
  continue;
54160
54228
  }
54161
- count2 += 1;
54229
+ count3 += 1;
54162
54230
  }
54163
- return count2;
54231
+ return count3;
54164
54232
  } catch {
54165
54233
  return 0;
54166
54234
  }
54167
54235
  }
54168
54236
  function classifyProject(directory) {
54169
- const root = resolve10(directory ?? process.cwd());
54237
+ const root = resolve11(directory ?? process.cwd());
54170
54238
  const signals = [];
54171
- const gitPath = join103(root, ".git");
54172
- const hasGit = existsSync104(gitPath);
54239
+ const gitPath = join105(root, ".git");
54240
+ const hasGit = existsSync105(gitPath);
54173
54241
  if (hasGit) {
54174
54242
  signals.push({
54175
54243
  id: "git-dir",
@@ -54178,8 +54246,8 @@ function classifyProject(directory) {
54178
54246
  });
54179
54247
  }
54180
54248
  for (const manifest of MANIFESTS) {
54181
- const manifestPath = join103(root, manifest.file);
54182
- if (existsSync104(manifestPath)) {
54249
+ const manifestPath = join105(root, manifest.file);
54250
+ if (existsSync105(manifestPath)) {
54183
54251
  signals.push({
54184
54252
  id: manifest.signal,
54185
54253
  description: manifest.description,
@@ -54188,8 +54256,8 @@ function classifyProject(directory) {
54188
54256
  }
54189
54257
  }
54190
54258
  for (const dir of SOURCE_DIRS) {
54191
- const srcPath = join103(root, dir);
54192
- if (existsSync104(srcPath) && isNonEmptyDir(srcPath)) {
54259
+ const srcPath = join105(root, dir);
54260
+ if (existsSync105(srcPath) && isNonEmptyDir(srcPath)) {
54193
54261
  signals.push({
54194
54262
  id: "source-dir",
54195
54263
  description: `Source directory ${dir}/ contains files`,
@@ -54199,8 +54267,8 @@ function classifyProject(directory) {
54199
54267
  }
54200
54268
  }
54201
54269
  for (const marker of DOCS_MARKERS) {
54202
- const markerPath = join103(root, marker.path);
54203
- if (existsSync104(markerPath)) {
54270
+ const markerPath = join105(root, marker.path);
54271
+ if (existsSync105(markerPath)) {
54204
54272
  signals.push({
54205
54273
  id: marker.signal,
54206
54274
  description: `${marker.path} present`,
@@ -54273,18 +54341,18 @@ __export(init_exports, {
54273
54341
  resolveSeedAgentsDir: () => resolveSeedAgentsDir,
54274
54342
  updateDocs: () => updateDocs
54275
54343
  });
54276
- import { existsSync as existsSync105, readdirSync as readdirSync35, readFileSync as readFileSync75 } from "node:fs";
54344
+ import { existsSync as existsSync106, readdirSync as readdirSync35, readFileSync as readFileSync76 } from "node:fs";
54277
54345
  import { copyFile as copyFile4, lstat, mkdir as mkdir16, readFile as readFile19, symlink, unlink as unlink4, writeFile as writeFile11 } from "node:fs/promises";
54278
54346
  import { platform as platform4 } from "node:os";
54279
- import { basename as basename17, dirname as dirname22, join as join104 } from "node:path";
54347
+ import { basename as basename17, dirname as dirname23, join as join106 } from "node:path";
54280
54348
  async function resolveSeedAgentsDir() {
54281
54349
  try {
54282
54350
  const { createRequire: createRequire10 } = await import("node:module");
54283
54351
  const req = createRequire10(import.meta.url);
54284
54352
  const agentsPkgMain = req.resolve("@cleocode/agents/package.json");
54285
- const agentsPkgRoot = dirname22(agentsPkgMain);
54286
- const candidate = join104(agentsPkgRoot, "seed-agents");
54287
- if (existsSync105(candidate)) {
54353
+ const agentsPkgRoot = dirname23(agentsPkgMain);
54354
+ const candidate = join106(agentsPkgRoot, "seed-agents");
54355
+ if (existsSync106(candidate)) {
54288
54356
  return candidate;
54289
54357
  }
54290
54358
  } catch {
@@ -54292,17 +54360,17 @@ async function resolveSeedAgentsDir() {
54292
54360
  const packageRoot = getPackageRoot();
54293
54361
  const candidates = [
54294
54362
  // Workspace fallback: bundled alongside core under packages/agents/seed-agents
54295
- join104(packageRoot, "agents", "seed-agents"),
54363
+ join106(packageRoot, "agents", "seed-agents"),
54296
54364
  // Sibling-package layout (e.g. node_modules/@cleocode/core -> ../agents)
54297
- join104(packageRoot, "..", "agents", "seed-agents"),
54365
+ join106(packageRoot, "..", "agents", "seed-agents"),
54298
54366
  // Bundled CLI: packages/cleo/dist -> ../../agents/seed-agents
54299
- join104(packageRoot, "..", "..", "agents", "seed-agents"),
54367
+ join106(packageRoot, "..", "..", "agents", "seed-agents"),
54300
54368
  // Bundled CLI dist subdir: packages/cleo/dist/cli -> ../../../packages/agents
54301
- join104(packageRoot, "..", "..", "packages", "agents", "seed-agents"),
54369
+ join106(packageRoot, "..", "..", "packages", "agents", "seed-agents"),
54302
54370
  // Monorepo workspace from repo root
54303
- join104(packageRoot, "..", "..", "..", "packages", "agents", "seed-agents")
54371
+ join106(packageRoot, "..", "..", "..", "packages", "agents", "seed-agents")
54304
54372
  ];
54305
- return candidates.find((p) => existsSync105(p)) ?? null;
54373
+ return candidates.find((p) => existsSync106(p)) ?? null;
54306
54374
  }
54307
54375
  async function initAgentDefinition(created, warnings) {
54308
54376
  let agentSourceDir = null;
@@ -54310,17 +54378,17 @@ async function initAgentDefinition(created, warnings) {
54310
54378
  const { createRequire: createRequire10 } = await import("node:module");
54311
54379
  const req = createRequire10(import.meta.url);
54312
54380
  const agentsPkgMain = req.resolve("@cleocode/agents/package.json");
54313
- const agentsPkgRoot = dirname22(agentsPkgMain);
54314
- const candidate = join104(agentsPkgRoot, "cleo-subagent");
54315
- if (existsSync105(candidate)) {
54381
+ const agentsPkgRoot = dirname23(agentsPkgMain);
54382
+ const candidate = join106(agentsPkgRoot, "cleo-subagent");
54383
+ if (existsSync106(candidate)) {
54316
54384
  agentSourceDir = candidate;
54317
54385
  }
54318
54386
  } catch {
54319
54387
  }
54320
54388
  if (!agentSourceDir) {
54321
54389
  const packageRoot = getPackageRoot();
54322
- const bundled = join104(packageRoot, "agents", "cleo-subagent");
54323
- if (existsSync105(bundled)) {
54390
+ const bundled = join106(packageRoot, "agents", "cleo-subagent");
54391
+ if (existsSync106(bundled)) {
54324
54392
  agentSourceDir = bundled;
54325
54393
  }
54326
54394
  }
@@ -54328,8 +54396,8 @@ async function initAgentDefinition(created, warnings) {
54328
54396
  warnings.push("agents/cleo-subagent/ not found in package, skipping agent definition install");
54329
54397
  return;
54330
54398
  }
54331
- const globalAgentsDir = join104(getAgentsHome(), "agents", "cleo-subagent");
54332
- await mkdir16(dirname22(globalAgentsDir), { recursive: true });
54399
+ const globalAgentsDir = join106(getAgentsHome(), "agents", "cleo-subagent");
54400
+ await mkdir16(dirname23(globalAgentsDir), { recursive: true });
54333
54401
  try {
54334
54402
  try {
54335
54403
  const stat2 = await lstat(globalAgentsDir);
@@ -54352,7 +54420,7 @@ async function initAgentDefinition(created, warnings) {
54352
54420
  await mkdir16(globalAgentsDir, { recursive: true });
54353
54421
  const files = readdirSync35(agentSourceDir);
54354
54422
  for (const file2 of files) {
54355
- await copyFile4(join104(agentSourceDir, file2), join104(globalAgentsDir, file2));
54423
+ await copyFile4(join106(agentSourceDir, file2), join106(globalAgentsDir, file2));
54356
54424
  }
54357
54425
  created.push("agent: cleo-subagent (copied)");
54358
54426
  } catch (copyErr) {
@@ -54377,20 +54445,20 @@ async function initCoreSkills(created, warnings) {
54377
54445
  const { createRequire: createRequire10 } = await import("node:module");
54378
54446
  const req = createRequire10(import.meta.url);
54379
54447
  const skillsPkgMain = req.resolve("@cleocode/skills/package.json");
54380
- const skillsPkgRoot = dirname22(skillsPkgMain);
54381
- if (existsSync105(join104(skillsPkgRoot, "skills.json"))) {
54448
+ const skillsPkgRoot = dirname23(skillsPkgMain);
54449
+ if (existsSync106(join106(skillsPkgRoot, "skills.json"))) {
54382
54450
  ctSkillsRoot = skillsPkgRoot;
54383
54451
  }
54384
54452
  } catch {
54385
54453
  }
54386
54454
  if (!ctSkillsRoot) {
54387
54455
  try {
54388
- const bundledPath = join104(packageRoot, "packages", "skills");
54389
- if (existsSync105(join104(bundledPath, "skills.json"))) {
54456
+ const bundledPath = join106(packageRoot, "packages", "skills");
54457
+ if (existsSync106(join106(bundledPath, "skills.json"))) {
54390
54458
  ctSkillsRoot = bundledPath;
54391
54459
  } else {
54392
- const ctSkillsPath = join104(packageRoot, "node_modules", "@cleocode", "skills");
54393
- if (existsSync105(join104(ctSkillsPath, "skills.json"))) {
54460
+ const ctSkillsPath = join106(packageRoot, "node_modules", "@cleocode", "skills");
54461
+ if (existsSync106(join106(ctSkillsPath, "skills.json"))) {
54394
54462
  ctSkillsRoot = ctSkillsPath;
54395
54463
  }
54396
54464
  }
@@ -54406,14 +54474,14 @@ async function initCoreSkills(created, warnings) {
54406
54474
  } catch {
54407
54475
  warnings.push("Failed to register skill library with CAAMP");
54408
54476
  }
54409
- const catalogPath = join104(ctSkillsRoot, "skills.json");
54410
- const catalog3 = JSON.parse(readFileSync75(catalogPath, "utf-8"));
54477
+ const catalogPath = join106(ctSkillsRoot, "skills.json");
54478
+ const catalog3 = JSON.parse(readFileSync76(catalogPath, "utf-8"));
54411
54479
  const skills = catalog3.skills ?? [];
54412
54480
  const coreSkills = skills.filter((s) => s.tier <= 2);
54413
54481
  const installed = [];
54414
54482
  for (const skill of coreSkills) {
54415
- const skillSourceDir = dirname22(join104(ctSkillsRoot, skill.path));
54416
- if (!existsSync105(skillSourceDir)) {
54483
+ const skillSourceDir = dirname23(join106(ctSkillsRoot, skill.path));
54484
+ if (!existsSync106(skillSourceDir)) {
54417
54485
  continue;
54418
54486
  }
54419
54487
  try {
@@ -54456,38 +54524,38 @@ async function initNexusRegistration(projectRoot, created, warnings) {
54456
54524
  }
54457
54525
  }
54458
54526
  async function installGitHubTemplates(projectRoot, created, skipped) {
54459
- if (!existsSync105(join104(projectRoot, ".git"))) {
54527
+ if (!existsSync106(join106(projectRoot, ".git"))) {
54460
54528
  return;
54461
54529
  }
54462
- const githubDir = join104(projectRoot, ".github");
54463
- const issueTemplateDir = join104(githubDir, "ISSUE_TEMPLATE");
54530
+ const githubDir = join106(projectRoot, ".github");
54531
+ const issueTemplateDir = join106(githubDir, "ISSUE_TEMPLATE");
54464
54532
  const packageRoot = getPackageRoot();
54465
- const templateSrcDir = join104(packageRoot, "templates", "github");
54466
- if (!existsSync105(templateSrcDir)) {
54533
+ const templateSrcDir = join106(packageRoot, "templates", "github");
54534
+ if (!existsSync106(templateSrcDir)) {
54467
54535
  return;
54468
54536
  }
54469
54537
  await mkdir16(issueTemplateDir, { recursive: true });
54470
- const issueSrcDir = join104(templateSrcDir, "ISSUE_TEMPLATE");
54471
- if (existsSync105(issueSrcDir)) {
54538
+ const issueSrcDir = join106(templateSrcDir, "ISSUE_TEMPLATE");
54539
+ if (existsSync106(issueSrcDir)) {
54472
54540
  const issueFiles = readdirSync35(issueSrcDir);
54473
54541
  for (const file2 of issueFiles) {
54474
- const dest = join104(issueTemplateDir, file2);
54475
- if (existsSync105(dest)) {
54542
+ const dest = join106(issueTemplateDir, file2);
54543
+ if (existsSync106(dest)) {
54476
54544
  skipped.push(`.github/ISSUE_TEMPLATE/${file2}`);
54477
54545
  continue;
54478
54546
  }
54479
- const content = readFileSync75(join104(issueSrcDir, file2), "utf-8");
54547
+ const content = readFileSync76(join106(issueSrcDir, file2), "utf-8");
54480
54548
  await writeFile11(dest, content, "utf-8");
54481
54549
  created.push(`.github/ISSUE_TEMPLATE/${file2}`);
54482
54550
  }
54483
54551
  }
54484
- const prTemplateSrc = join104(templateSrcDir, "pull_request_template.md");
54485
- const prTemplateDest = join104(githubDir, "pull_request_template.md");
54486
- if (existsSync105(prTemplateSrc)) {
54487
- if (existsSync105(prTemplateDest)) {
54552
+ const prTemplateSrc = join106(templateSrcDir, "pull_request_template.md");
54553
+ const prTemplateDest = join106(githubDir, "pull_request_template.md");
54554
+ if (existsSync106(prTemplateSrc)) {
54555
+ if (existsSync106(prTemplateDest)) {
54488
54556
  skipped.push(".github/pull_request_template.md");
54489
54557
  } else {
54490
- const content = readFileSync75(prTemplateSrc, "utf-8");
54558
+ const content = readFileSync76(prTemplateSrc, "utf-8");
54491
54559
  await writeFile11(prTemplateDest, content, "utf-8");
54492
54560
  created.push(".github/pull_request_template.md");
54493
54561
  }
@@ -54517,8 +54585,8 @@ async function updateDocs() {
54517
54585
  }
54518
54586
  async function initProject(opts = {}) {
54519
54587
  const cleoDir = getCleoDirAbsolute();
54520
- const projRoot = dirname22(cleoDir);
54521
- const alreadyInitialized = existsSync105(cleoDir) && (existsSync105(join104(cleoDir, "tasks.db")) || existsSync105(join104(cleoDir, "config.json")));
54588
+ const projRoot = dirname23(cleoDir);
54589
+ const alreadyInitialized = existsSync106(cleoDir) && (existsSync106(join106(cleoDir, "tasks.db")) || existsSync106(join106(cleoDir, "config.json")));
54522
54590
  if (alreadyInitialized && !opts.force) {
54523
54591
  throw new CleoError(
54524
54592
  1 /* GENERAL_ERROR */,
@@ -54550,7 +54618,7 @@ async function initProject(opts = {}) {
54550
54618
  }
54551
54619
  try {
54552
54620
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
54553
- await getDb3(join104(cleoDir, ".."));
54621
+ await getDb3(join106(cleoDir, ".."));
54554
54622
  created.push("tasks.db");
54555
54623
  } catch (err) {
54556
54624
  created.push(`tasks.db (deferred: ${err instanceof Error ? err.message : String(err)})`);
@@ -54580,8 +54648,8 @@ async function initProject(opts = {}) {
54580
54648
  created.push(".gitignore");
54581
54649
  }
54582
54650
  } else {
54583
- const gitignorePath = join104(cleoDir, ".gitignore");
54584
- if (existsSync105(gitignorePath)) {
54651
+ const gitignorePath = join106(cleoDir, ".gitignore");
54652
+ if (existsSync106(gitignorePath)) {
54585
54653
  skipped.push(".gitignore");
54586
54654
  } else {
54587
54655
  const gitignoreResult = await ensureGitignore(projRoot);
@@ -54592,12 +54660,12 @@ async function initProject(opts = {}) {
54592
54660
  }
54593
54661
  }
54594
54662
  }
54595
- const legacySequencePath = join104(cleoDir, ".sequence");
54663
+ const legacySequencePath = join106(cleoDir, ".sequence");
54596
54664
  try {
54597
54665
  await unlink4(legacySequencePath);
54598
54666
  } catch {
54599
54667
  }
54600
- const legacySequenceJsonPath = join104(cleoDir, ".sequence.json");
54668
+ const legacySequenceJsonPath = join106(cleoDir, ".sequence.json");
54601
54669
  try {
54602
54670
  await unlink4(legacySequenceJsonPath);
54603
54671
  } catch {
@@ -54753,15 +54821,15 @@ async function initProject(opts = {}) {
54753
54821
  if (opts.installSeedAgents) {
54754
54822
  try {
54755
54823
  const seedDir = await resolveSeedAgentsDir();
54756
- if (seedDir && existsSync105(seedDir)) {
54757
- const targetDir = join104(projRoot, ".cleo", "agents");
54824
+ if (seedDir && existsSync106(seedDir)) {
54825
+ const targetDir = join106(projRoot, ".cleo", "agents");
54758
54826
  await mkdir16(targetDir, { recursive: true });
54759
54827
  const seeds = readdirSync35(seedDir).filter((f) => f.endsWith(".cant"));
54760
54828
  let installed = 0;
54761
54829
  for (const seed of seeds) {
54762
- const dst = join104(targetDir, seed);
54763
- if (!existsSync105(dst)) {
54764
- await copyFile4(join104(seedDir, seed), dst);
54830
+ const dst = join106(targetDir, seed);
54831
+ if (!existsSync106(dst)) {
54832
+ await copyFile4(join106(seedDir, seed), dst);
54765
54833
  installed++;
54766
54834
  }
54767
54835
  }
@@ -54844,8 +54912,8 @@ function isAutoInitEnabled() {
54844
54912
  }
54845
54913
  async function ensureInitialized(projectRoot) {
54846
54914
  const root = projectRoot ?? getProjectRoot();
54847
- const cleoDir = join104(root, ".cleo");
54848
- const isInit = existsSync105(cleoDir) && (existsSync105(join104(cleoDir, "tasks.db")) || existsSync105(join104(cleoDir, "config.json")));
54915
+ const cleoDir = join106(root, ".cleo");
54916
+ const isInit = existsSync106(cleoDir) && (existsSync106(join106(cleoDir, "tasks.db")) || existsSync106(join106(cleoDir, "config.json")));
54849
54917
  if (isInit) {
54850
54918
  return { initialized: true };
54851
54919
  }
@@ -54857,7 +54925,7 @@ async function ensureInitialized(projectRoot) {
54857
54925
  }
54858
54926
  async function getVersion2(projectRoot) {
54859
54927
  const root = projectRoot ?? getProjectRoot();
54860
- const versionPaths = [join104(root, "VERSION"), join104(root, "..", "VERSION")];
54928
+ const versionPaths = [join106(root, "VERSION"), join106(root, "..", "VERSION")];
54861
54929
  for (const versionPath of versionPaths) {
54862
54930
  try {
54863
54931
  const content = await readFile19(versionPath, "utf-8");
@@ -54868,16 +54936,16 @@ async function getVersion2(projectRoot) {
54868
54936
  } catch {
54869
54937
  }
54870
54938
  }
54871
- const pkg = await readJson(join104(root, "package.json"));
54939
+ const pkg = await readJson(join106(root, "package.json"));
54872
54940
  if (pkg?.version) {
54873
54941
  return { version: pkg.version };
54874
54942
  }
54875
54943
  return { version: "0.0.0" };
54876
54944
  }
54877
54945
  async function deployStarterBundle(cleoDir, created, warnings) {
54878
- const cantDir = join104(cleoDir, "cant");
54879
- const cantAgentsDir = join104(cantDir, "agents");
54880
- const hasCantFiles = existsSync105(cantDir) && readdirSync35(cantDir, { recursive: true }).some(
54946
+ const cantDir = join106(cleoDir, "cant");
54947
+ const cantAgentsDir = join106(cantDir, "agents");
54948
+ const hasCantFiles = existsSync106(cantDir) && readdirSync35(cantDir, { recursive: true }).some(
54881
54949
  (f) => typeof f === "string" && f.endsWith(".cant")
54882
54950
  );
54883
54951
  if (hasCantFiles) return;
@@ -54886,9 +54954,9 @@ async function deployStarterBundle(cleoDir, created, warnings) {
54886
54954
  const { createRequire: createRequire10 } = await import("node:module");
54887
54955
  const req = createRequire10(import.meta.url);
54888
54956
  const cleoOsPkgMain = req.resolve("@cleocode/cleo-os/package.json");
54889
- const cleoOsPkgRoot = dirname22(cleoOsPkgMain);
54890
- const candidate = join104(cleoOsPkgRoot, "starter-bundle");
54891
- if (existsSync105(candidate)) {
54957
+ const cleoOsPkgRoot = dirname23(cleoOsPkgMain);
54958
+ const candidate = join106(cleoOsPkgRoot, "starter-bundle");
54959
+ if (existsSync106(candidate)) {
54892
54960
  starterBundleSrc = candidate;
54893
54961
  }
54894
54962
  } catch {
@@ -54896,10 +54964,10 @@ async function deployStarterBundle(cleoDir, created, warnings) {
54896
54964
  if (!starterBundleSrc) {
54897
54965
  const packageRoot = getPackageRoot();
54898
54966
  const fallbacks = [
54899
- join104(packageRoot, "..", "cleo-os", "starter-bundle"),
54900
- join104(packageRoot, "..", "..", "packages", "cleo-os", "starter-bundle")
54967
+ join106(packageRoot, "..", "cleo-os", "starter-bundle"),
54968
+ join106(packageRoot, "..", "..", "packages", "cleo-os", "starter-bundle")
54901
54969
  ];
54902
- starterBundleSrc = fallbacks.find((p) => existsSync105(p)) ?? null;
54970
+ starterBundleSrc = fallbacks.find((p) => existsSync106(p)) ?? null;
54903
54971
  }
54904
54972
  if (!starterBundleSrc) {
54905
54973
  warnings.push(
@@ -54909,30 +54977,30 @@ async function deployStarterBundle(cleoDir, created, warnings) {
54909
54977
  }
54910
54978
  await mkdir16(cantDir, { recursive: true });
54911
54979
  await mkdir16(cantAgentsDir, { recursive: true });
54912
- const teamSrc = join104(starterBundleSrc, "team.cant");
54913
- const teamDst = join104(cantDir, "team.cant");
54914
- if (existsSync105(teamSrc) && !existsSync105(teamDst)) {
54980
+ const teamSrc = join106(starterBundleSrc, "team.cant");
54981
+ const teamDst = join106(cantDir, "team.cant");
54982
+ if (existsSync106(teamSrc) && !existsSync106(teamDst)) {
54915
54983
  await copyFile4(teamSrc, teamDst);
54916
54984
  }
54917
- const agentsSrc = join104(starterBundleSrc, "agents");
54918
- if (existsSync105(agentsSrc)) {
54985
+ const agentsSrc = join106(starterBundleSrc, "agents");
54986
+ if (existsSync106(agentsSrc)) {
54919
54987
  const agentFiles = readdirSync35(agentsSrc).filter((f) => f.endsWith(".cant"));
54920
54988
  for (const agentFile of agentFiles) {
54921
- const dst = join104(cantAgentsDir, agentFile);
54922
- if (!existsSync105(dst)) {
54923
- await copyFile4(join104(agentsSrc, agentFile), dst);
54989
+ const dst = join106(cantAgentsDir, agentFile);
54990
+ if (!existsSync106(dst)) {
54991
+ await copyFile4(join106(agentsSrc, agentFile), dst);
54924
54992
  }
54925
54993
  }
54926
54994
  }
54927
- const identitySrc = join104(starterBundleSrc, "CLEOOS-IDENTITY.md");
54928
- const identityDst = join104(cleoDir, "CLEOOS-IDENTITY.md");
54929
- if (existsSync105(identitySrc) && !existsSync105(identityDst)) {
54995
+ const identitySrc = join106(starterBundleSrc, "CLEOOS-IDENTITY.md");
54996
+ const identityDst = join106(cleoDir, "CLEOOS-IDENTITY.md");
54997
+ if (existsSync106(identitySrc) && !existsSync106(identityDst)) {
54930
54998
  await copyFile4(identitySrc, identityDst);
54931
54999
  }
54932
55000
  try {
54933
55001
  const { getCleoHome: getCleoHome2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
54934
- const globalIdentityDst = join104(getCleoHome2(), "CLEOOS-IDENTITY.md");
54935
- if (existsSync105(identitySrc) && !existsSync105(globalIdentityDst)) {
55002
+ const globalIdentityDst = join106(getCleoHome2(), "CLEOOS-IDENTITY.md");
55003
+ if (existsSync106(identitySrc) && !existsSync106(globalIdentityDst)) {
54936
55004
  await copyFile4(identitySrc, globalIdentityDst);
54937
55005
  }
54938
55006
  } catch {
@@ -56483,8 +56551,8 @@ function providerInstalled() {
56483
56551
  }
56484
56552
  function providerCount() {
56485
56553
  try {
56486
- const count2 = getProviderCount();
56487
- return { success: true, data: { count: count2 } };
56554
+ const count3 = getProviderCount();
56555
+ return { success: true, data: { count: count3 } };
56488
56556
  } catch (err) {
56489
56557
  return {
56490
56558
  success: false,
@@ -57292,7 +57360,7 @@ var SseTransport = class {
57292
57360
  // --------------------------------------------------------------------------
57293
57361
  /** Establish SSE connection. Resolves when open, rejects on error. */
57294
57362
  connectSse() {
57295
- return new Promise((resolve11, reject) => {
57363
+ return new Promise((resolve12, reject) => {
57296
57364
  if (!this.state) {
57297
57365
  reject(new Error("No state"));
57298
57366
  return;
@@ -57308,7 +57376,7 @@ var SseTransport = class {
57308
57376
  clearTimeout(timeout);
57309
57377
  this.state.connected = true;
57310
57378
  this.state.reconnectAttempts = 0;
57311
- resolve11();
57379
+ resolve12();
57312
57380
  });
57313
57381
  es.addEventListener("message", (event) => {
57314
57382
  this.handleSseMessage(event);
@@ -58290,16 +58358,16 @@ function collectTransitiveDependents(taskId, dependentsMap) {
58290
58358
  return visited;
58291
58359
  }
58292
58360
  function countBlockedWork(taskId, transitiveDependents, taskMap) {
58293
- let count2 = 0;
58361
+ let count3 = 0;
58294
58362
  for (const depId of transitiveDependents) {
58295
58363
  if (depId === taskId) continue;
58296
58364
  const task = taskMap.get(depId);
58297
58365
  if (!task) continue;
58298
58366
  if (task.status !== "done" && task.status !== "cancelled") {
58299
- count2++;
58367
+ count3++;
58300
58368
  }
58301
58369
  }
58302
- return count2;
58370
+ return count3;
58303
58371
  }
58304
58372
  function findAffectedPipelines(taskId, transitiveDependents, tasks2) {
58305
58373
  const affectedEpicIds = /* @__PURE__ */ new Set();
@@ -58908,19 +58976,19 @@ async function extractWorkflowPatterns(accessor, minFrequency) {
58908
58976
  depTargetCounts.set(dep, (depTargetCounts.get(dep) || 0) + 1);
58909
58977
  }
58910
58978
  }
58911
- for (const [taskId, count2] of depTargetCounts) {
58912
- if (count2 >= minFrequency) {
58979
+ for (const [taskId, count3] of depTargetCounts) {
58980
+ if (count3 >= minFrequency) {
58913
58981
  const hubTask = allTasks.find((t) => t.id === taskId);
58914
58982
  const title = hubTask?.title ?? taskId;
58915
58983
  patterns.push({
58916
58984
  type: "workflow",
58917
- pattern: `Task "${title}" (${taskId}) is a dependency hub with ${count2} dependents`,
58985
+ pattern: `Task "${title}" (${taskId}) is a dependency hub with ${count3} dependents`,
58918
58986
  context: "Dependency graph analysis \u2014 hub tasks are critical path candidates",
58919
- frequency: count2,
58987
+ frequency: count3,
58920
58988
  successRate: hubTask?.status === "done" ? 1 : null,
58921
- impact: count2 >= 5 ? "high" : "medium",
58922
- antiPattern: count2 >= 8 ? `Task ${taskId} may be an overly-centralized bottleneck` : null,
58923
- mitigation: count2 >= 8 ? "Consider decomposing this task to reduce coupling" : null,
58989
+ impact: count3 >= 5 ? "high" : "medium",
58990
+ antiPattern: count3 >= 8 ? `Task ${taskId} may be an overly-centralized bottleneck` : null,
58991
+ mitigation: count3 >= 8 ? "Consider decomposing this task to reduce coupling" : null,
58924
58992
  examples: allTasks.filter((t) => t.depends?.includes(taskId)).slice(0, 10).map((t) => t.id),
58925
58993
  confidence: 0.7
58926
58994
  });
@@ -58962,18 +59030,18 @@ async function extractObservationPatterns(brainAccessor, minFrequency) {
58962
59030
  for (const obs of observations) {
58963
59031
  typeCounts.set(obs.type, (typeCounts.get(obs.type) || 0) + 1);
58964
59032
  }
58965
- for (const [type, count2] of typeCounts) {
58966
- if (count2 >= minFrequency) {
59033
+ for (const [type, count3] of typeCounts) {
59034
+ if (count3 >= minFrequency) {
58967
59035
  const patternType = observationTypeToPatternType(type);
58968
59036
  patterns.push({
58969
59037
  type: patternType,
58970
- pattern: `${count2} "${type}" observations recorded`,
59038
+ pattern: `${count3} "${type}" observations recorded`,
58971
59039
  context: "Brain observation frequency analysis",
58972
- frequency: count2,
59040
+ frequency: count3,
58973
59041
  successRate: type === "feature" || type === "refactor" ? 0.8 : null,
58974
- impact: count2 >= 10 ? "high" : count2 >= 5 ? "medium" : "low",
58975
- antiPattern: type === "bugfix" && count2 >= 5 ? "High number of bugfix observations may indicate quality issues" : null,
58976
- mitigation: type === "bugfix" && count2 >= 5 ? "Consider adding more automated tests and code review" : null,
59042
+ impact: count3 >= 10 ? "high" : count3 >= 5 ? "medium" : "low",
59043
+ antiPattern: type === "bugfix" && count3 >= 5 ? "High number of bugfix observations may indicate quality issues" : null,
59044
+ mitigation: type === "bugfix" && count3 >= 5 ? "Consider adding more automated tests and code review" : null,
58977
59045
  examples: observations.filter((o) => o.type === type).slice(0, 5).map((o) => o.id),
58978
59046
  confidence: 0.5
58979
59047
  });
@@ -58985,13 +59053,13 @@ async function extractObservationPatterns(brainAccessor, minFrequency) {
58985
59053
  projectCounts.set(obs.project, (projectCounts.get(obs.project) || 0) + 1);
58986
59054
  }
58987
59055
  }
58988
- for (const [project, count2] of projectCounts) {
58989
- if (count2 >= minFrequency * 2) {
59056
+ for (const [project, count3] of projectCounts) {
59057
+ if (count3 >= minFrequency * 2) {
58990
59058
  patterns.push({
58991
59059
  type: "workflow",
58992
- pattern: `Project "${project}" has ${count2} observations \u2014 high activity area`,
59060
+ pattern: `Project "${project}" has ${count3} observations \u2014 high activity area`,
58993
59061
  context: "Cross-project observation density analysis",
58994
- frequency: count2,
59062
+ frequency: count3,
58995
59063
  successRate: null,
58996
59064
  impact: "medium",
58997
59065
  antiPattern: null,
@@ -59505,7 +59573,7 @@ function augmentError(err, context) {
59505
59573
  }
59506
59574
  }
59507
59575
  function sleep2(ms) {
59508
- return new Promise((resolve11) => setTimeout(resolve11, ms));
59576
+ return new Promise((resolve12) => setTimeout(resolve12, ms));
59509
59577
  }
59510
59578
 
59511
59579
  // packages/core/src/lib/index.ts
@@ -64969,6 +65037,7 @@ __export(nexus_exports, {
64969
65037
  nexusSync: () => nexusSync,
64970
65038
  nexusSyncAll: () => nexusSyncAll,
64971
65039
  nexusUnregister: () => nexusUnregister,
65040
+ nexusUpdateIndexStats: () => nexusUpdateIndexStats,
64972
65041
  orphanDetection: () => orphanDetection,
64973
65042
  parseDirective: () => parseDirective,
64974
65043
  parseQuery: () => parseQuery,
@@ -65118,8 +65187,8 @@ async function resolveProjectPath2(projectName) {
65118
65187
  if (projectName === ".") {
65119
65188
  try {
65120
65189
  const accessor = await getAccessor(process.cwd());
65121
- const count2 = await accessor.countTasks();
65122
- if (count2 >= 0) return process.cwd();
65190
+ const count3 = await accessor.countTasks();
65191
+ if (count3 >= 0) return process.cwd();
65123
65192
  throw new Error("No task data");
65124
65193
  } catch {
65125
65194
  throw new CleoError(
@@ -69887,17 +69956,17 @@ async function generateReleaseChangelog(version2, loadTasksFn, cwd) {
69887
69956
  function buildEntry(task) {
69888
69957
  const cleanTitle = capitalize(stripConventionalPrefix(task.title));
69889
69958
  const safeDesc = task.description?.replace(/\r?\n/g, " ").replace(/\s{2,}/g, " ").trim();
69890
- const desc5 = safeDesc;
69959
+ const desc6 = safeDesc;
69891
69960
  const shouldIncludeDesc = (() => {
69892
- if (!desc5 || desc5.length === 0) return false;
69961
+ if (!desc6 || desc6.length === 0) return false;
69893
69962
  const titleNorm = cleanTitle.toLowerCase().replace(/[^a-z0-9\s]/g, "").trim();
69894
- const descNorm = desc5.toLowerCase().replace(/[^a-z0-9\s]/g, "").trim();
69963
+ const descNorm = desc6.toLowerCase().replace(/[^a-z0-9\s]/g, "").trim();
69895
69964
  if (titleNorm === descNorm) return false;
69896
69965
  if (descNorm.startsWith(titleNorm) && descNorm.length < titleNorm.length * 1.3) return false;
69897
- return desc5.length >= 20;
69966
+ return desc6.length >= 20;
69898
69967
  })();
69899
69968
  if (shouldIncludeDesc) {
69900
- const descDisplay = desc5.length > 150 ? desc5.slice(0, 147) + "..." : desc5;
69969
+ const descDisplay = desc6.length > 150 ? desc6.slice(0, 147) + "..." : desc6;
69901
69970
  return `- **${cleanTitle}**: ${descDisplay} (${task.id})`;
69902
69971
  }
69903
69972
  return `- ${cleanTitle} (${task.id})`;
@@ -70463,11 +70532,11 @@ __export(remote_exports, {
70463
70532
  init_paths();
70464
70533
  init_git_checkpoint();
70465
70534
  import { execFile as execFile5 } from "node:child_process";
70466
- import { resolve as resolve7 } from "node:path";
70535
+ import { resolve as resolve8 } from "node:path";
70467
70536
  import { promisify as promisify5 } from "node:util";
70468
70537
  var execFileAsync5 = promisify5(execFile5);
70469
70538
  async function cleoGitExec(args, cleoDir) {
70470
- const abs = resolve7(cleoDir);
70539
+ const abs = resolve8(cleoDir);
70471
70540
  const result = await execFileAsync5("git", args, {
70472
70541
  cwd: abs,
70473
70542
  env: makeCleoGitEnv(cleoDir),
@@ -72334,7 +72403,7 @@ __export(security_exports, {
72334
72403
  // packages/core/src/security/input-sanitization.ts
72335
72404
  init_src();
72336
72405
  init_tasks_schema();
72337
- import { isAbsolute as isAbsolute2, normalize, relative as relative6, resolve as resolve8 } from "path";
72406
+ import { isAbsolute as isAbsolute2, normalize, relative as relative6, resolve as resolve9 } from "path";
72338
72407
 
72339
72408
  // packages/core/src/tasks/id-generator.ts
72340
72409
  function normalizeTaskId(input) {
@@ -72396,12 +72465,12 @@ function sanitizePath(path4, projectRoot) {
72396
72465
  if (trimmedPath.includes("\0")) {
72397
72466
  throw new SecurityError("Path contains null bytes", "E_PATH_TRAVERSAL", "path");
72398
72467
  }
72399
- const normalizedRoot = resolve8(projectRoot);
72468
+ const normalizedRoot = resolve9(projectRoot);
72400
72469
  let resolvedPath;
72401
72470
  if (isAbsolute2(trimmedPath)) {
72402
72471
  resolvedPath = normalize(trimmedPath);
72403
72472
  } else {
72404
- resolvedPath = resolve8(normalizedRoot, trimmedPath);
72473
+ resolvedPath = resolve9(normalizedRoot, trimmedPath);
72405
72474
  }
72406
72475
  const relativePath = relative6(normalizedRoot, resolvedPath);
72407
72476
  if (relativePath.startsWith("..") || isAbsolute2(relativePath)) {
@@ -74289,7 +74358,7 @@ async function validateOrchestratorCompliance(epicId, cwd) {
74289
74358
 
74290
74359
  // packages/core/src/skills/skill-paths.ts
74291
74360
  import { existsSync as existsSync80, lstatSync, readlinkSync as readlinkSync2, realpathSync } from "node:fs";
74292
- import { delimiter, join as join81, resolve as resolve9 } from "node:path";
74361
+ import { delimiter, join as join81, resolve as resolve10 } from "node:path";
74293
74362
  import { getCanonicalSkillsDir as getCanonicalSkillsDir2 } from "@cleocode/caamp";
74294
74363
  function getCaampCanonical() {
74295
74364
  return getCanonicalSkillsDir2();
@@ -74406,7 +74475,7 @@ function getSkillSourceType(skillDir, projectRoot) {
74406
74475
  }
74407
74476
  } catch {
74408
74477
  }
74409
- if (normalizedDir.startsWith(resolve9(embeddedDir)) || normalizedDir.startsWith(join81(root, "skills"))) {
74478
+ if (normalizedDir.startsWith(resolve10(embeddedDir)) || normalizedDir.startsWith(join81(root, "skills"))) {
74410
74479
  return "embedded";
74411
74480
  }
74412
74481
  if (normalizedDir.startsWith(caampDir)) {
@@ -74937,8 +75006,8 @@ async function initializeSpawnAdapters(manifests) {
74937
75006
  if (!manifest.capabilities?.supportsSpawn) continue;
74938
75007
  if (spawnRegistry.hasAdapterForProvider(manifest.provider)) continue;
74939
75008
  try {
74940
- const { join: join107 } = await import("node:path");
74941
- const modulePath = join107(manifest.packagePath, manifest.entryPoint);
75009
+ const { join: join109 } = await import("node:path");
75010
+ const modulePath = join109(manifest.packagePath, manifest.entryPoint);
74942
75011
  const adapterModule = await import(modulePath);
74943
75012
  let SpawnProviderClass;
74944
75013
  for (const [exportName, exportValue] of Object.entries(adapterModule)) {
@@ -75040,7 +75109,7 @@ async function queryTasks(cwd, since) {
75040
75109
  try {
75041
75110
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
75042
75111
  const { tasks: tasks2 } = await Promise.resolve().then(() => (init_tasks_schema(), tasks_schema_exports));
75043
- const { and: and10, gte: gte3 } = await import("drizzle-orm");
75112
+ const { and: and11, gte: gte3 } = await import("drizzle-orm");
75044
75113
  const db = await getDb3(cwd);
75045
75114
  const conditions = [];
75046
75115
  if (since) {
@@ -75054,7 +75123,7 @@ async function queryTasks(cwd, since) {
75054
75123
  sessionId: tasks2.sessionId,
75055
75124
  completedAt: tasks2.completedAt,
75056
75125
  createdAt: tasks2.createdAt
75057
- }).from(tasks2).where(conditions.length > 0 ? and10(...conditions) : void 0).all();
75126
+ }).from(tasks2).where(conditions.length > 0 ? and11(...conditions) : void 0).all();
75058
75127
  return rows;
75059
75128
  } catch (err) {
75060
75129
  log9.warn({ err }, "Failed to query tasks for workflow telemetry");
@@ -75065,7 +75134,7 @@ async function queryCompletionAuditRows(cwd, since) {
75065
75134
  try {
75066
75135
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
75067
75136
  const { auditLog: auditLog2 } = await Promise.resolve().then(() => (init_tasks_schema(), tasks_schema_exports));
75068
- const { and: and10, gte: gte3 } = await import("drizzle-orm");
75137
+ const { and: and11, gte: gte3 } = await import("drizzle-orm");
75069
75138
  const db = await getDb3(cwd);
75070
75139
  const conditions = [];
75071
75140
  if (since) conditions.push(gte3(auditLog2.timestamp, since));
@@ -75077,7 +75146,7 @@ async function queryCompletionAuditRows(cwd, since) {
75077
75146
  afterJson: auditLog2.afterJson,
75078
75147
  operation: auditLog2.operation,
75079
75148
  domain: auditLog2.domain
75080
- }).from(auditLog2).where(conditions.length > 0 ? and10(...conditions) : void 0).orderBy(auditLog2.timestamp).all();
75149
+ }).from(auditLog2).where(conditions.length > 0 ? and11(...conditions) : void 0).orderBy(auditLog2.timestamp).all();
75081
75150
  return allRows.filter((row) => {
75082
75151
  const isComplete = row.action === "task_completed" || row.action === "complete" || row.operation === "complete" && row.domain === "tasks";
75083
75152
  if (!isComplete && row.afterJson) {
@@ -75532,7 +75601,7 @@ async function getDashboard(opts, accessor) {
75532
75601
  labelMap[label] = (labelMap[label] ?? 0) + 1;
75533
75602
  }
75534
75603
  }
75535
- const topLabels = Object.entries(labelMap).map(([label, count2]) => ({ label, count: count2 })).sort((a, b) => b.count - a.count).slice(0, 8);
75604
+ const topLabels = Object.entries(labelMap).map(([label, count3]) => ({ label, count: count3 })).sort((a, b) => b.count - a.count).slice(0, 8);
75536
75605
  return {
75537
75606
  project,
75538
75607
  currentPhase,
@@ -75570,7 +75639,7 @@ async function getCompletionHistory(opts) {
75570
75639
  const date6 = c.timestamp.split("T")[0];
75571
75640
  byDate[date6] = (byDate[date6] ?? 0) + 1;
75572
75641
  }
75573
- const dailyCounts = Object.entries(byDate).sort(([a], [b]) => a.localeCompare(b)).map(([date6, count2]) => ({ date: date6, count: count2 }));
75642
+ const dailyCounts = Object.entries(byDate).sort(([a], [b]) => a.localeCompare(b)).map(([date6, count3]) => ({ date: date6, count: count3 }));
75574
75643
  const totalCompletions = completions.length;
75575
75644
  const avgPerDay = days > 0 ? Math.round(totalCompletions / days * 100) / 100 : 0;
75576
75645
  const peakDay = dailyCounts.reduce((max, d) => d.count > max.count ? d : max, {
@@ -76067,7 +76136,7 @@ function byLabelReport(tasks2) {
76067
76136
  counts[label] = (counts[label] ?? 0) + 1;
76068
76137
  }
76069
76138
  }
76070
- return Object.entries(counts).map(([label, count2]) => ({ label, count: count2 })).sort((a, b) => b.count - a.count);
76139
+ return Object.entries(counts).map(([label, count3]) => ({ label, count: count3 })).sort((a, b) => b.count - a.count);
76071
76140
  }
76072
76141
  function byPriorityReport(tasks2) {
76073
76142
  const PRIO_ORDER = ["critical", "high", "medium", "low", "unset"];
@@ -76127,15 +76196,15 @@ function trendsReport(tasks2) {
76127
76196
  const date6 = t.archive.archivedAt.slice(0, 10);
76128
76197
  byDay[date6] = (byDay[date6] ?? 0) + 1;
76129
76198
  }
76130
- const dailyEntries = Object.entries(byDay).map(([date6, count2]) => ({ date: date6, count: count2 })).sort((a, b) => a.date.localeCompare(b.date));
76199
+ const dailyEntries = Object.entries(byDay).map(([date6, count3]) => ({ date: date6, count: count3 })).sort((a, b) => a.date.localeCompare(b.date));
76131
76200
  const byMonth = {};
76132
- for (const { date: date6, count: count2 } of dailyEntries) {
76201
+ for (const { date: date6, count: count3 } of dailyEntries) {
76133
76202
  const month = date6.slice(0, 7);
76134
- byMonth[month] = (byMonth[month] ?? 0) + count2;
76203
+ byMonth[month] = (byMonth[month] ?? 0) + count3;
76135
76204
  }
76136
- const monthlyEntries = Object.entries(byMonth).map(([month, count2]) => ({
76205
+ const monthlyEntries = Object.entries(byMonth).map(([month, count3]) => ({
76137
76206
  month,
76138
- count: count2
76207
+ count: count3
76139
76208
  }));
76140
76209
  const totalPeriod = dailyEntries.reduce((sum, d) => sum + d.count, 0);
76141
76210
  return {
@@ -79078,6 +79147,304 @@ async function showTask(taskId, cwd, accessor) {
79078
79147
  // packages/core/src/tasks/index.ts
79079
79148
  init_update2();
79080
79149
 
79150
+ // packages/core/src/telemetry/index.ts
79151
+ var telemetry_exports = {};
79152
+ __export(telemetry_exports, {
79153
+ buildDiagnosticsReport: () => buildDiagnosticsReport,
79154
+ disableTelemetry: () => disableTelemetry,
79155
+ enableTelemetry: () => enableTelemetry,
79156
+ exportTelemetryEvents: () => exportTelemetryEvents,
79157
+ getTelemetryConfigPath: () => getTelemetryConfigPath,
79158
+ getTelemetryDb: () => getTelemetryDb,
79159
+ getTelemetryDbPath: () => getTelemetryDbPath,
79160
+ isTelemetryEnabled: () => isTelemetryEnabled,
79161
+ loadTelemetryConfig: () => loadTelemetryConfig,
79162
+ recordTelemetryEvent: () => recordTelemetryEvent,
79163
+ saveTelemetryConfig: () => saveTelemetryConfig,
79164
+ telemetryEvents: () => telemetryEvents,
79165
+ telemetrySchemaMeta: () => telemetrySchemaMeta
79166
+ });
79167
+ init_paths();
79168
+ import { randomUUID as randomUUID7 } from "node:crypto";
79169
+ import { existsSync as existsSync96, mkdirSync as mkdirSync24, readFileSync as readFileSync68, writeFileSync as writeFileSync16 } from "node:fs";
79170
+ import { join as join99 } from "node:path";
79171
+ import { and as and10, count as count2, desc as desc5, gt as gt2, sql as sql13 } from "drizzle-orm";
79172
+
79173
+ // packages/core/src/telemetry/schema.ts
79174
+ var schema_exports = {};
79175
+ __export(schema_exports, {
79176
+ telemetryEvents: () => telemetryEvents,
79177
+ telemetrySchemaMeta: () => telemetrySchemaMeta
79178
+ });
79179
+ init_sqlite_core();
79180
+ import { sql as sql12 } from "drizzle-orm";
79181
+ var telemetryEvents = sqliteTable(
79182
+ "telemetry_events",
79183
+ {
79184
+ /** UUID primary key. */
79185
+ id: text("id").primaryKey(),
79186
+ /** Anonymous install identifier (UUIDv4, generated once on first enable). */
79187
+ anonymousId: text("anonymous_id").notNull(),
79188
+ /** Canonical domain (e.g. "tasks", "session", "memory", "admin"). */
79189
+ domain: text("domain").notNull(),
79190
+ /** CQRS gateway ("query" or "mutate"). */
79191
+ gateway: text("gateway").notNull(),
79192
+ /** Operation name (e.g. "show", "add", "complete"). */
79193
+ operation: text("operation").notNull(),
79194
+ /** Composed command string "{domain}.{operation}" for easy grouping. */
79195
+ command: text("command").notNull(),
79196
+ /** LAFS exit code (0 = success, non-zero = failure). */
79197
+ exitCode: integer("exit_code").notNull().default(0),
79198
+ /** Wall-clock duration in milliseconds. */
79199
+ durationMs: integer("duration_ms").notNull(),
79200
+ /** Machine-readable error code when exit_code != 0. NULL on success. */
79201
+ errorCode: text("error_code"),
79202
+ /** ISO-8601 timestamp of the invocation. */
79203
+ timestamp: text("timestamp").notNull().default(sql12`(datetime('now'))`)
79204
+ },
79205
+ (table) => [
79206
+ index("idx_telemetry_command").on(table.command),
79207
+ index("idx_telemetry_domain").on(table.domain),
79208
+ index("idx_telemetry_exit_code").on(table.exitCode),
79209
+ index("idx_telemetry_timestamp").on(table.timestamp),
79210
+ index("idx_telemetry_duration").on(table.durationMs)
79211
+ ]
79212
+ );
79213
+ var telemetrySchemaMeta = sqliteTable("telemetry_schema_meta", {
79214
+ /** Config key. */
79215
+ key: text("key").primaryKey(),
79216
+ /** Config value. */
79217
+ value: text("value").notNull()
79218
+ });
79219
+
79220
+ // packages/core/src/telemetry/sqlite.ts
79221
+ init_node_sqlite();
79222
+ init_paths();
79223
+ init_migration_manager();
79224
+ init_sqlite2();
79225
+ import { mkdirSync as mkdirSync23 } from "node:fs";
79226
+ import { dirname as dirname20, join as join98 } from "node:path";
79227
+ import { fileURLToPath as fileURLToPath6 } from "node:url";
79228
+ var DB_FILENAME4 = "telemetry.db";
79229
+ var TELEMETRY_SCHEMA_VERSION = "1.0.0";
79230
+ var _db3 = null;
79231
+ var _nativeDb3 = null;
79232
+ var _dbPath3 = null;
79233
+ var _initPromise3 = null;
79234
+ function getTelemetryDbPath() {
79235
+ return join98(getCleoHome(), DB_FILENAME4);
79236
+ }
79237
+ function resolveTelemetryMigrationsFolder() {
79238
+ const __filename = fileURLToPath6(import.meta.url);
79239
+ const __dir = dirname20(__filename);
79240
+ const isBundled = __dir.endsWith("/dist") || __dir.endsWith("\\dist");
79241
+ const pkgRoot = isBundled ? join98(__dir, "..") : join98(__dir, "..", "..");
79242
+ return join98(pkgRoot, "migrations", "drizzle-telemetry");
79243
+ }
79244
+ function runTelemetryMigrations(nativeDb, db) {
79245
+ const migrationsFolder = resolveTelemetryMigrationsFolder();
79246
+ reconcileJournal(nativeDb, migrationsFolder, "telemetry_events", "telemetry");
79247
+ migrateWithRetry(db, migrationsFolder, nativeDb, "telemetry_events", "telemetry");
79248
+ ensureColumns(
79249
+ nativeDb,
79250
+ "telemetry_events",
79251
+ [
79252
+ { name: "anonymous_id", ddl: "text NOT NULL DEFAULT ''" },
79253
+ { name: "domain", ddl: "text NOT NULL DEFAULT ''" },
79254
+ { name: "gateway", ddl: "text NOT NULL DEFAULT 'query'" },
79255
+ { name: "operation", ddl: "text NOT NULL DEFAULT ''" },
79256
+ { name: "command", ddl: "text NOT NULL DEFAULT ''" },
79257
+ { name: "exit_code", ddl: "integer NOT NULL DEFAULT 0" },
79258
+ { name: "duration_ms", ddl: "integer NOT NULL DEFAULT 0" },
79259
+ { name: "error_code", ddl: "text" }
79260
+ ],
79261
+ "telemetry"
79262
+ );
79263
+ }
79264
+ function resetTelemetryDbState() {
79265
+ try {
79266
+ _nativeDb3?.close();
79267
+ } catch {
79268
+ }
79269
+ _db3 = null;
79270
+ _nativeDb3 = null;
79271
+ _dbPath3 = null;
79272
+ _initPromise3 = null;
79273
+ }
79274
+ async function getTelemetryDb() {
79275
+ const requestedPath = getTelemetryDbPath();
79276
+ if (_db3 && _dbPath3 !== requestedPath) {
79277
+ resetTelemetryDbState();
79278
+ }
79279
+ if (_db3) return _db3;
79280
+ if (_initPromise3) return _initPromise3;
79281
+ _initPromise3 = (async () => {
79282
+ const dbPath = requestedPath;
79283
+ _dbPath3 = dbPath;
79284
+ mkdirSync23(dirname20(dbPath), { recursive: true });
79285
+ const nativeDb = openNativeDatabase(dbPath);
79286
+ _nativeDb3 = nativeDb;
79287
+ const db = drizzle({ client: nativeDb, schema: schema_exports });
79288
+ runTelemetryMigrations(nativeDb, db);
79289
+ nativeDb.prepare(
79290
+ `INSERT OR IGNORE INTO telemetry_schema_meta (key, value) VALUES ('schemaVersion', '${TELEMETRY_SCHEMA_VERSION}')`
79291
+ ).run();
79292
+ _db3 = db;
79293
+ return db;
79294
+ })();
79295
+ return _initPromise3;
79296
+ }
79297
+
79298
+ // packages/core/src/telemetry/index.ts
79299
+ var TELEMETRY_CONFIG_FILENAME = "telemetry-config.json";
79300
+ function getTelemetryConfigPath() {
79301
+ return join99(getCleoHome(), TELEMETRY_CONFIG_FILENAME);
79302
+ }
79303
+ function loadTelemetryConfig() {
79304
+ const path4 = getTelemetryConfigPath();
79305
+ if (!existsSync96(path4)) {
79306
+ return { enabled: false, anonymousId: "" };
79307
+ }
79308
+ try {
79309
+ return JSON.parse(readFileSync68(path4, "utf-8"));
79310
+ } catch {
79311
+ return { enabled: false, anonymousId: "" };
79312
+ }
79313
+ }
79314
+ function saveTelemetryConfig(config2) {
79315
+ const path4 = getTelemetryConfigPath();
79316
+ mkdirSync24(join99(path4, ".."), { recursive: true });
79317
+ writeFileSync16(path4, JSON.stringify(config2, null, 2), "utf-8");
79318
+ }
79319
+ function isTelemetryEnabled() {
79320
+ return loadTelemetryConfig().enabled;
79321
+ }
79322
+ function enableTelemetry() {
79323
+ const existing = loadTelemetryConfig();
79324
+ const config2 = {
79325
+ enabled: true,
79326
+ anonymousId: existing.anonymousId || randomUUID7()
79327
+ };
79328
+ saveTelemetryConfig(config2);
79329
+ return config2;
79330
+ }
79331
+ function disableTelemetry() {
79332
+ const existing = loadTelemetryConfig();
79333
+ const config2 = { ...existing, enabled: false };
79334
+ saveTelemetryConfig(config2);
79335
+ return config2;
79336
+ }
79337
+ async function recordTelemetryEvent(event) {
79338
+ const config2 = loadTelemetryConfig();
79339
+ if (!config2.enabled || !config2.anonymousId) return;
79340
+ try {
79341
+ const db = await getTelemetryDb();
79342
+ const command = `${event.domain}.${event.operation}`;
79343
+ await db.insert(telemetryEvents).values({
79344
+ id: randomUUID7(),
79345
+ anonymousId: config2.anonymousId,
79346
+ domain: event.domain,
79347
+ gateway: event.gateway,
79348
+ operation: event.operation,
79349
+ command,
79350
+ exitCode: event.exitCode,
79351
+ durationMs: event.durationMs,
79352
+ errorCode: event.errorCode ?? null,
79353
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
79354
+ }).run();
79355
+ } catch {
79356
+ }
79357
+ }
79358
+ function daysAgo(n) {
79359
+ const d = /* @__PURE__ */ new Date();
79360
+ d.setDate(d.getDate() - n);
79361
+ return d.toISOString();
79362
+ }
79363
+ async function buildDiagnosticsReport(days = 30) {
79364
+ const config2 = loadTelemetryConfig();
79365
+ if (!config2.enabled) return null;
79366
+ const db = await getTelemetryDb();
79367
+ const from = daysAgo(days);
79368
+ const to = (/* @__PURE__ */ new Date()).toISOString();
79369
+ const [totalRow] = await db.select({ n: count2(telemetryEvents.id) }).from(telemetryEvents).where(gt2(telemetryEvents.timestamp, from)).all();
79370
+ const totalEvents = totalRow?.n ?? 0;
79371
+ if (totalEvents === 0)
79372
+ return {
79373
+ period: { from, to },
79374
+ totalEvents: 0,
79375
+ topFailing: [],
79376
+ topSlow: [],
79377
+ rareCommands: [],
79378
+ observations: []
79379
+ };
79380
+ const rows = await db.select({
79381
+ command: telemetryEvents.command,
79382
+ total: count2(telemetryEvents.id),
79383
+ failures: sql13`SUM(CASE WHEN ${telemetryEvents.exitCode} != 0 THEN 1 ELSE 0 END)`,
79384
+ avgMs: sql13`AVG(${telemetryEvents.durationMs})`,
79385
+ maxMs: sql13`MAX(${telemetryEvents.durationMs})`
79386
+ }).from(telemetryEvents).where(gt2(telemetryEvents.timestamp, from)).groupBy(telemetryEvents.command).all();
79387
+ const errorCodeRows = await db.select({
79388
+ command: telemetryEvents.command,
79389
+ errorCode: telemetryEvents.errorCode,
79390
+ n: count2(telemetryEvents.id)
79391
+ }).from(telemetryEvents).where(and10(gt2(telemetryEvents.timestamp, from), sql13`${telemetryEvents.errorCode} IS NOT NULL`)).groupBy(telemetryEvents.command, telemetryEvents.errorCode).orderBy(desc5(count2(telemetryEvents.id))).all();
79392
+ const topErrorMap = /* @__PURE__ */ new Map();
79393
+ for (const r of errorCodeRows) {
79394
+ if (!topErrorMap.has(r.command)) {
79395
+ topErrorMap.set(r.command, r.errorCode ?? "");
79396
+ }
79397
+ }
79398
+ const stats2 = rows.map((r) => {
79399
+ const failures = Number(r.failures) || 0;
79400
+ const total = Number(r.total) || 0;
79401
+ return {
79402
+ command: r.command,
79403
+ count: total,
79404
+ failureCount: failures,
79405
+ failureRate: total > 0 ? failures / total : 0,
79406
+ avgDurationMs: Math.round(Number(r.avgMs) || 0),
79407
+ maxDurationMs: Math.round(Number(r.maxMs) || 0),
79408
+ topErrorCode: topErrorMap.get(r.command) ?? null
79409
+ };
79410
+ });
79411
+ const topFailing = stats2.filter((s) => s.count >= 5 && s.failureRate > 0).sort((a, b) => b.failureRate - a.failureRate).slice(0, 10);
79412
+ const topSlow = [...stats2].sort((a, b) => b.avgDurationMs - a.avgDurationMs).slice(0, 10);
79413
+ const rareCommands = stats2.filter((s) => s.count === 1).map((s) => s.command);
79414
+ const observations = [];
79415
+ for (const s of topFailing.slice(0, 5)) {
79416
+ const pct = Math.round(s.failureRate * 100);
79417
+ const errPart = s.topErrorCode ? ` (most common error: ${s.topErrorCode})` : "";
79418
+ observations.push(
79419
+ `Command '${s.command}' fails ${pct}% of the time across ${s.count} invocations${errPart}. Investigate root cause.`
79420
+ );
79421
+ }
79422
+ const sortedAvg = stats2.map((s) => s.avgDurationMs).sort((a, b) => a - b);
79423
+ const median = sortedAvg[Math.floor(sortedAvg.length / 2)] ?? 0;
79424
+ for (const s of topSlow.slice(0, 5)) {
79425
+ if (median > 0 && s.avgDurationMs > median * 2) {
79426
+ observations.push(
79427
+ `Command '${s.command}' averages ${s.avgDurationMs}ms \u2014 ${Math.round(s.avgDurationMs / median)}x slower than the ${median}ms median. Profile for performance improvement.`
79428
+ );
79429
+ }
79430
+ }
79431
+ return { period: { from, to }, totalEvents, topFailing, topSlow, rareCommands, observations };
79432
+ }
79433
+ async function exportTelemetryEvents(days) {
79434
+ const config2 = loadTelemetryConfig();
79435
+ if (!config2.enabled) return [];
79436
+ const db = await getTelemetryDb();
79437
+ const rows = days ? await db.select().from(telemetryEvents).where(gt2(telemetryEvents.timestamp, daysAgo(days))).orderBy(desc5(telemetryEvents.timestamp)).all() : await db.select().from(telemetryEvents).orderBy(desc5(telemetryEvents.timestamp)).all();
79438
+ return rows.map((r) => ({
79439
+ domain: r.domain,
79440
+ gateway: r.gateway,
79441
+ operation: r.operation,
79442
+ durationMs: r.durationMs,
79443
+ exitCode: r.exitCode,
79444
+ errorCode: r.errorCode
79445
+ }));
79446
+ }
79447
+
79081
79448
  // packages/core/src/templates/index.ts
79082
79449
  var templates_exports = {};
79083
79450
  __export(templates_exports, {
@@ -79089,8 +79456,8 @@ __export(templates_exports, {
79089
79456
 
79090
79457
  // packages/core/src/templates/parser.ts
79091
79458
  init_platform();
79092
- import { existsSync as existsSync96, readdirSync as readdirSync30, readFileSync as readFileSync68 } from "fs";
79093
- import { join as join98 } from "path";
79459
+ import { existsSync as existsSync97, readdirSync as readdirSync30, readFileSync as readFileSync69 } from "fs";
79460
+ import { join as join100 } from "path";
79094
79461
  import { parse as parseYaml } from "yaml";
79095
79462
  var SUFFIX_PATTERNS = ["_report", "_request", "_question"];
79096
79463
  function deriveSubcommand(filename) {
@@ -79105,8 +79472,8 @@ function deriveSubcommand(filename) {
79105
79472
  return firstWord.toLowerCase();
79106
79473
  }
79107
79474
  function parseTemplateFile2(templateDir, filename) {
79108
- const filePath = join98(templateDir, filename);
79109
- const raw = readFileSync68(filePath, "utf-8");
79475
+ const filePath = join100(templateDir, filename);
79476
+ const raw = readFileSync69(filePath, "utf-8");
79110
79477
  const parsed = parseYaml(raw);
79111
79478
  const name2 = typeof parsed.name === "string" ? parsed.name : filename;
79112
79479
  const titlePrefix = typeof parsed.title === "string" ? parsed.title : "";
@@ -79155,8 +79522,8 @@ function parseTemplateFile2(templateDir, filename) {
79155
79522
  };
79156
79523
  }
79157
79524
  function parseIssueTemplates2(projectRoot) {
79158
- const templateDir = join98(projectRoot, ".github", "ISSUE_TEMPLATE");
79159
- if (!existsSync96(templateDir)) {
79525
+ const templateDir = join100(projectRoot, ".github", "ISSUE_TEMPLATE");
79526
+ if (!existsSync97(templateDir)) {
79160
79527
  return {
79161
79528
  success: false,
79162
79529
  error: { code: "E_NOT_FOUND", message: `Issue template directory not found: ${templateDir}` }
@@ -79303,9 +79670,9 @@ __export(ui_exports, {
79303
79670
  });
79304
79671
 
79305
79672
  // packages/core/src/ui/aliases.ts
79306
- import { existsSync as existsSync97, readFileSync as readFileSync69, writeFileSync as writeFileSync16 } from "node:fs";
79673
+ import { existsSync as existsSync98, readFileSync as readFileSync70, writeFileSync as writeFileSync17 } from "node:fs";
79307
79674
  import { homedir as homedir6, platform as platform3 } from "node:os";
79308
- import { join as join99 } from "node:path";
79675
+ import { join as join101 } from "node:path";
79309
79676
  var MARKER_START = "# CLEO-CLAUDE-ALIASES:START";
79310
79677
  var MARKER_END = "# CLEO-CLAUDE-ALIASES:END";
79311
79678
  var ALIASES_VERSION = "1.0.0";
@@ -79327,22 +79694,22 @@ function getRcFilePath(shell) {
79327
79694
  const sh = shell ?? getCurrentShell();
79328
79695
  switch (sh) {
79329
79696
  case "bash":
79330
- return join99(home, ".bashrc");
79697
+ return join101(home, ".bashrc");
79331
79698
  case "zsh":
79332
- return join99(home, ".zshrc");
79699
+ return join101(home, ".zshrc");
79333
79700
  case "powershell":
79334
- return join99(home, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
79701
+ return join101(home, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
79335
79702
  case "cmd":
79336
79703
  return "";
79337
79704
  // CMD doesn't have a standard RC
79338
79705
  default:
79339
- return join99(home, ".bashrc");
79706
+ return join101(home, ".bashrc");
79340
79707
  }
79341
79708
  }
79342
79709
  function detectAvailableShells() {
79343
79710
  const shells = [];
79344
- if (existsSync97(getRcFilePath("bash")) || existsSync97("/bin/bash")) shells.push("bash");
79345
- if (existsSync97(getRcFilePath("zsh")) || existsSync97("/bin/zsh")) shells.push("zsh");
79711
+ if (existsSync98(getRcFilePath("bash")) || existsSync98("/bin/bash")) shells.push("bash");
79712
+ if (existsSync98(getRcFilePath("zsh")) || existsSync98("/bin/zsh")) shells.push("zsh");
79346
79713
  if (platform3() === "win32") shells.push("powershell");
79347
79714
  return shells;
79348
79715
  }
@@ -79374,47 +79741,47 @@ function generatePowershellAliases(cleoPath) {
79374
79741
  ].join("\n");
79375
79742
  }
79376
79743
  function hasAliasBlock(filePath) {
79377
- if (!existsSync97(filePath)) return false;
79378
- const content = readFileSync69(filePath, "utf-8");
79744
+ if (!existsSync98(filePath)) return false;
79745
+ const content = readFileSync70(filePath, "utf-8");
79379
79746
  return content.includes(MARKER_START) && content.includes(MARKER_END);
79380
79747
  }
79381
79748
  function getInstalledVersion(filePath) {
79382
- if (!existsSync97(filePath)) return null;
79383
- const content = readFileSync69(filePath, "utf-8");
79749
+ if (!existsSync98(filePath)) return null;
79750
+ const content = readFileSync70(filePath, "utf-8");
79384
79751
  const match = content.match(/CLEO CLI aliases \(v([^)]+)\)/);
79385
79752
  return match?.[1] ?? null;
79386
79753
  }
79387
79754
  function injectAliases(filePath, shell = "bash", cleoPath) {
79388
79755
  const content = shell === "powershell" ? generatePowershellAliases(cleoPath) : generateBashAliases(cleoPath);
79389
- if (!existsSync97(filePath)) {
79390
- writeFileSync16(filePath, content + "\n", "utf-8");
79756
+ if (!existsSync98(filePath)) {
79757
+ writeFileSync17(filePath, content + "\n", "utf-8");
79391
79758
  return { action: "created", version: ALIASES_VERSION };
79392
79759
  }
79393
- const existing = readFileSync69(filePath, "utf-8");
79760
+ const existing = readFileSync70(filePath, "utf-8");
79394
79761
  if (hasAliasBlock(filePath)) {
79395
79762
  const startIdx = existing.indexOf(MARKER_START);
79396
79763
  const endIdx = existing.indexOf(MARKER_END) + MARKER_END.length;
79397
79764
  const updated = existing.slice(0, startIdx) + content + existing.slice(endIdx);
79398
- writeFileSync16(filePath, updated, "utf-8");
79765
+ writeFileSync17(filePath, updated, "utf-8");
79399
79766
  return { action: "updated", version: ALIASES_VERSION };
79400
79767
  }
79401
- writeFileSync16(filePath, existing + "\n" + content + "\n", "utf-8");
79768
+ writeFileSync17(filePath, existing + "\n" + content + "\n", "utf-8");
79402
79769
  return { action: "added", version: ALIASES_VERSION };
79403
79770
  }
79404
79771
  function removeAliases(filePath) {
79405
- if (!existsSync97(filePath) || !hasAliasBlock(filePath)) return false;
79406
- const existing = readFileSync69(filePath, "utf-8");
79772
+ if (!existsSync98(filePath) || !hasAliasBlock(filePath)) return false;
79773
+ const existing = readFileSync70(filePath, "utf-8");
79407
79774
  const startIdx = existing.indexOf(MARKER_START);
79408
79775
  const endIdx = existing.indexOf(MARKER_END) + MARKER_END.length;
79409
79776
  const before = existing.slice(0, startIdx).replace(/\n+$/, "\n");
79410
79777
  const after = existing.slice(endIdx).replace(/^\n+/, "\n");
79411
- writeFileSync16(filePath, before + after, "utf-8");
79778
+ writeFileSync17(filePath, before + after, "utf-8");
79412
79779
  return true;
79413
79780
  }
79414
79781
  function checkAliasesStatus(shell) {
79415
79782
  const sh = shell ?? getCurrentShell();
79416
79783
  const rcFile = getRcFilePath(sh);
79417
- if (!rcFile || !existsSync97(rcFile)) {
79784
+ if (!rcFile || !existsSync98(rcFile)) {
79418
79785
  return { shell: sh, rcFile, installed: false, version: null, needsUpdate: false };
79419
79786
  }
79420
79787
  const installed = hasAliasBlock(rcFile);
@@ -79425,7 +79792,7 @@ function checkAliasesStatus(shell) {
79425
79792
 
79426
79793
  // packages/core/src/ui/changelog.ts
79427
79794
  init_data_accessor();
79428
- import { appendFileSync as appendFileSync9, existsSync as existsSync98, readFileSync as readFileSync70, writeFileSync as writeFileSync17 } from "node:fs";
79795
+ import { appendFileSync as appendFileSync9, existsSync as existsSync99, readFileSync as readFileSync71, writeFileSync as writeFileSync18 } from "node:fs";
79429
79796
  var LABEL_CATEGORIES = {
79430
79797
  feature: "Features",
79431
79798
  feat: "Features",
@@ -79526,21 +79893,21 @@ function formatChangelogJson(version2, date6, sections) {
79526
79893
  };
79527
79894
  }
79528
79895
  function writeChangelogFile(filePath, content) {
79529
- writeFileSync17(filePath, content, "utf-8");
79896
+ writeFileSync18(filePath, content, "utf-8");
79530
79897
  }
79531
79898
  function appendToChangelog(filePath, newContent) {
79532
- if (!existsSync98(filePath)) {
79533
- writeFileSync17(filePath, `# Changelog
79899
+ if (!existsSync99(filePath)) {
79900
+ writeFileSync18(filePath, `# Changelog
79534
79901
 
79535
79902
  ${newContent}`, "utf-8");
79536
79903
  return;
79537
79904
  }
79538
- const existing = readFileSync70(filePath, "utf-8");
79905
+ const existing = readFileSync71(filePath, "utf-8");
79539
79906
  const headerMatch = existing.match(/^# .+\n/m);
79540
79907
  if (headerMatch) {
79541
79908
  const insertPos = (headerMatch.index ?? 0) + headerMatch[0].length;
79542
79909
  const updated = existing.slice(0, insertPos) + "\n" + newContent + existing.slice(insertPos);
79543
- writeFileSync17(filePath, updated, "utf-8");
79910
+ writeFileSync18(filePath, updated, "utf-8");
79544
79911
  } else {
79545
79912
  appendFileSync9(filePath, "\n" + newContent);
79546
79913
  }
@@ -79575,13 +79942,13 @@ ${markdown}`);
79575
79942
  }
79576
79943
 
79577
79944
  // packages/core/src/ui/command-registry.ts
79578
- import { existsSync as existsSync99, readdirSync as readdirSync31, readFileSync as readFileSync71 } from "node:fs";
79579
- import { basename as basename16, join as join100 } from "node:path";
79945
+ import { existsSync as existsSync100, readdirSync as readdirSync31, readFileSync as readFileSync72 } from "node:fs";
79946
+ import { basename as basename16, join as join102 } from "node:path";
79580
79947
  var CLEO_HEADER_START = "###CLEO";
79581
79948
  var CLEO_HEADER_END = "###END";
79582
79949
  function parseCommandHeader(scriptPath) {
79583
- if (!existsSync99(scriptPath)) return null;
79584
- const content = readFileSync71(scriptPath, "utf-8");
79950
+ if (!existsSync100(scriptPath)) return null;
79951
+ const content = readFileSync72(scriptPath, "utf-8");
79585
79952
  const lines = content.split("\n");
79586
79953
  let inHeader = false;
79587
79954
  const headerLines = [];
@@ -79659,10 +80026,10 @@ function parseCommandHeader(scriptPath) {
79659
80026
  }
79660
80027
  function scanAllCommands(scriptsDir) {
79661
80028
  const registry2 = /* @__PURE__ */ new Map();
79662
- if (!existsSync99(scriptsDir)) return registry2;
80029
+ if (!existsSync100(scriptsDir)) return registry2;
79663
80030
  for (const file2 of readdirSync31(scriptsDir)) {
79664
80031
  if (!file2.endsWith(".sh") && !file2.endsWith(".ts")) continue;
79665
- const meta3 = parseCommandHeader(join100(scriptsDir, file2));
80032
+ const meta3 = parseCommandHeader(join102(scriptsDir, file2));
79666
80033
  if (meta3) {
79667
80034
  registry2.set(meta3.command, meta3);
79668
80035
  }
@@ -80605,10 +80972,10 @@ function calculateOrchestrationOverhead(orchestratorTokens, totalSubagentTokens,
80605
80972
  }
80606
80973
 
80607
80974
  // packages/core/src/validation/docs-sync.ts
80608
- import { existsSync as existsSync100, readdirSync as readdirSync32, readFileSync as readFileSync72 } from "node:fs";
80609
- import { join as join101 } from "node:path";
80975
+ import { existsSync as existsSync101, readdirSync as readdirSync32, readFileSync as readFileSync73 } from "node:fs";
80976
+ import { join as join103 } from "node:path";
80610
80977
  function getScriptCommands(scriptsDir) {
80611
- if (!existsSync100(scriptsDir)) return [];
80978
+ if (!existsSync101(scriptsDir)) return [];
80612
80979
  try {
80613
80980
  return readdirSync32(scriptsDir).filter((f) => f.endsWith(".sh")).map((f) => f.replace(/\.sh$/, "")).sort();
80614
80981
  } catch {
@@ -80616,9 +80983,9 @@ function getScriptCommands(scriptsDir) {
80616
80983
  }
80617
80984
  }
80618
80985
  function getIndexScripts(indexPath) {
80619
- if (!existsSync100(indexPath)) return [];
80986
+ if (!existsSync101(indexPath)) return [];
80620
80987
  try {
80621
- const content = readFileSync72(indexPath, "utf-8");
80988
+ const content = readFileSync73(indexPath, "utf-8");
80622
80989
  const index2 = JSON.parse(content);
80623
80990
  return index2.commands.map((cmd) => cmd.script ?? "").filter((s) => s).map((s) => s.replace(/\.sh$/, "")).sort();
80624
80991
  } catch {
@@ -80626,9 +80993,9 @@ function getIndexScripts(indexPath) {
80626
80993
  }
80627
80994
  }
80628
80995
  function getIndexCommands(indexPath) {
80629
- if (!existsSync100(indexPath)) return [];
80996
+ if (!existsSync101(indexPath)) return [];
80630
80997
  try {
80631
- const content = readFileSync72(indexPath, "utf-8");
80998
+ const content = readFileSync73(indexPath, "utf-8");
80632
80999
  const index2 = JSON.parse(content);
80633
81000
  return index2.commands.map((cmd) => cmd.name).sort();
80634
81001
  } catch {
@@ -80662,11 +81029,11 @@ function checkCommandsSync(scriptsDir, indexPath) {
80662
81029
  return issues;
80663
81030
  }
80664
81031
  function checkWrapperSync(wrapperPath, indexPath) {
80665
- if (!existsSync100(wrapperPath) || !existsSync100(indexPath)) return [];
81032
+ if (!existsSync101(wrapperPath) || !existsSync101(indexPath)) return [];
80666
81033
  const issues = [];
80667
81034
  try {
80668
- const wrapperContent = readFileSync72(wrapperPath, "utf-8");
80669
- const indexContent = readFileSync72(indexPath, "utf-8");
81035
+ const wrapperContent = readFileSync73(wrapperPath, "utf-8");
81036
+ const indexContent = readFileSync73(indexPath, "utf-8");
80670
81037
  const index2 = JSON.parse(indexContent);
80671
81038
  const match = wrapperContent.match(/_get_all_commands\(\)\s*\{[^}]*echo\s+"([^"]+)"/);
80672
81039
  const wrapperCmds = new Set(match ? match[1].split(/\s+/).filter(Boolean) : []);
@@ -80699,16 +81066,16 @@ var CRITICAL_COMMANDS = [
80699
81066
  ];
80700
81067
  function detectDrift(mode = "full", projectRoot = ".") {
80701
81068
  const issues = [];
80702
- const scriptsDir = join101(projectRoot, "scripts");
80703
- const indexPath = join101(projectRoot, "docs/commands/COMMANDS-INDEX.json");
81069
+ const scriptsDir = join103(projectRoot, "scripts");
81070
+ const indexPath = join103(projectRoot, "docs/commands/COMMANDS-INDEX.json");
80704
81071
  issues.push(...checkCommandsSync(scriptsDir, indexPath));
80705
- const wrapperPath = join101(projectRoot, "installer/lib/link.sh");
81072
+ const wrapperPath = join103(projectRoot, "installer/lib/link.sh");
80706
81073
  issues.push(...checkWrapperSync(wrapperPath, indexPath));
80707
81074
  if (mode === "full") {
80708
- const readmePath = join101(projectRoot, "README.md");
80709
- if (existsSync100(readmePath)) {
81075
+ const readmePath = join103(projectRoot, "README.md");
81076
+ if (existsSync101(readmePath)) {
80710
81077
  try {
80711
- const readme = readFileSync72(readmePath, "utf-8");
81078
+ const readme = readFileSync73(readmePath, "utf-8");
80712
81079
  const readmeCmds = new Set(
80713
81080
  (readme.match(/cleo [a-z-]+/g) ?? []).map((m) => m.replace("cleo ", ""))
80714
81081
  );
@@ -80742,14 +81109,14 @@ function shouldRunDriftDetection(enabled = true, autoCheck = false, command, cri
80742
81109
  // packages/core/src/validation/doctor/project-cache.ts
80743
81110
  init_paths();
80744
81111
  import { createHash as createHash12 } from "node:crypto";
80745
- import { existsSync as existsSync101, mkdirSync as mkdirSync23, readFileSync as readFileSync73, unlinkSync as unlinkSync8, writeFileSync as writeFileSync18 } from "node:fs";
80746
- import { dirname as dirname20, join as join102 } from "node:path";
81112
+ import { existsSync as existsSync102, mkdirSync as mkdirSync25, readFileSync as readFileSync74, unlinkSync as unlinkSync8, writeFileSync as writeFileSync19 } from "node:fs";
81113
+ import { dirname as dirname21, join as join104 } from "node:path";
80747
81114
  var CACHE_VERSION = "1.0.0";
80748
81115
  var CACHE_TTL_SECONDS = 300;
80749
81116
  var CACHE_FILE2 = "doctor-project-cache.json";
80750
81117
  function getCacheFilePath(cleoHome) {
80751
81118
  const home = cleoHome ?? getCleoHome();
80752
- return join102(home, CACHE_FILE2);
81119
+ return join104(home, CACHE_FILE2);
80753
81120
  }
80754
81121
  function initCacheFile(cacheFile) {
80755
81122
  const cache = {
@@ -80757,26 +81124,26 @@ function initCacheFile(cacheFile) {
80757
81124
  lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
80758
81125
  projects: {}
80759
81126
  };
80760
- const dir = dirname20(cacheFile);
80761
- if (!existsSync101(dir)) {
80762
- mkdirSync23(dir, { recursive: true });
81127
+ const dir = dirname21(cacheFile);
81128
+ if (!existsSync102(dir)) {
81129
+ mkdirSync25(dir, { recursive: true });
80763
81130
  }
80764
- writeFileSync18(cacheFile, JSON.stringify(cache, null, 2));
81131
+ writeFileSync19(cacheFile, JSON.stringify(cache, null, 2));
80765
81132
  return cache;
80766
81133
  }
80767
81134
  function loadCache(cacheFile) {
80768
- if (!existsSync101(cacheFile)) return null;
81135
+ if (!existsSync102(cacheFile)) return null;
80769
81136
  try {
80770
- const content = readFileSync73(cacheFile, "utf-8");
81137
+ const content = readFileSync74(cacheFile, "utf-8");
80771
81138
  return JSON.parse(content);
80772
81139
  } catch {
80773
81140
  return null;
80774
81141
  }
80775
81142
  }
80776
81143
  function getFileHash(filePath) {
80777
- if (!existsSync101(filePath)) return "";
81144
+ if (!existsSync102(filePath)) return "";
80778
81145
  try {
80779
- const content = readFileSync73(filePath);
81146
+ const content = readFileSync74(filePath);
80780
81147
  return createHash12("sha256").update(content).digest("hex");
80781
81148
  } catch {
80782
81149
  return "";
@@ -80793,8 +81160,8 @@ function getCachedValidation(projectHash, projectPath, cacheFile) {
80793
81160
  const now = Date.now();
80794
81161
  const age = (now - lastValidated) / 1e3;
80795
81162
  if (age > (entry.ttl || CACHE_TTL_SECONDS)) return null;
80796
- const currentTasksDbHash = getFileHash(join102(projectPath, ".cleo", "tasks.db"));
80797
- const currentConfigHash = getFileHash(join102(projectPath, ".cleo", "config.json"));
81163
+ const currentTasksDbHash = getFileHash(join104(projectPath, ".cleo", "tasks.db"));
81164
+ const currentConfigHash = getFileHash(join104(projectPath, ".cleo", "config.json"));
80798
81165
  if (currentTasksDbHash !== (entry.fileHashes["tasks.db"] ?? "")) return null;
80799
81166
  if (currentConfigHash !== (entry.fileHashes["config.json"] ?? "")) return null;
80800
81167
  return entry;
@@ -80805,8 +81172,8 @@ function cacheValidationResult(projectHash, projectPath, validationStatus, issue
80805
81172
  if (!cache) {
80806
81173
  cache = initCacheFile(cachePath);
80807
81174
  }
80808
- const tasksDbHash = getFileHash(join102(projectPath, ".cleo", "tasks.db"));
80809
- const configHash = getFileHash(join102(projectPath, ".cleo", "config.json"));
81175
+ const tasksDbHash = getFileHash(join104(projectPath, ".cleo", "tasks.db"));
81176
+ const configHash = getFileHash(join104(projectPath, ".cleo", "config.json"));
80810
81177
  const timestamp2 = (/* @__PURE__ */ new Date()).toISOString();
80811
81178
  cache.projects[projectHash] = {
80812
81179
  path: projectPath,
@@ -80821,18 +81188,18 @@ function cacheValidationResult(projectHash, projectPath, validationStatus, issue
80821
81188
  ttl: CACHE_TTL_SECONDS
80822
81189
  };
80823
81190
  cache.lastUpdated = timestamp2;
80824
- writeFileSync18(cachePath, JSON.stringify(cache, null, 2));
81191
+ writeFileSync19(cachePath, JSON.stringify(cache, null, 2));
80825
81192
  }
80826
81193
  function clearProjectCache(projectHash, cacheFile) {
80827
81194
  const cachePath = cacheFile ?? getCacheFilePath();
80828
81195
  const cache = loadCache(cachePath);
80829
81196
  if (!cache) return;
80830
81197
  delete cache.projects[projectHash];
80831
- writeFileSync18(cachePath, JSON.stringify(cache, null, 2));
81198
+ writeFileSync19(cachePath, JSON.stringify(cache, null, 2));
80832
81199
  }
80833
81200
  function clearEntireCache(cacheFile) {
80834
81201
  const cachePath = cacheFile ?? getCacheFilePath();
80835
- if (existsSync101(cachePath)) {
81202
+ if (existsSync102(cachePath)) {
80836
81203
  unlinkSync8(cachePath);
80837
81204
  }
80838
81205
  initCacheFile(cachePath);
@@ -81101,15 +81468,15 @@ function validateTitle2(title) {
81101
81468
  }
81102
81469
  return { valid: errors.length === 0, errors, warnings };
81103
81470
  }
81104
- function validateDescription(desc5) {
81105
- if (!desc5) return { valid: true, errors: [], warnings: [] };
81106
- if (desc5.length > FIELD_LIMITS.MAX_DESCRIPTION_LENGTH) {
81471
+ function validateDescription(desc6) {
81472
+ if (!desc6) return { valid: true, errors: [], warnings: [] };
81473
+ if (desc6.length > FIELD_LIMITS.MAX_DESCRIPTION_LENGTH) {
81107
81474
  return {
81108
81475
  valid: false,
81109
81476
  errors: [
81110
81477
  {
81111
81478
  field: "description",
81112
- message: `Description exceeds ${FIELD_LIMITS.MAX_DESCRIPTION_LENGTH} characters (${desc5.length} provided)`,
81479
+ message: `Description exceeds ${FIELD_LIMITS.MAX_DESCRIPTION_LENGTH} characters (${desc6.length} provided)`,
81113
81480
  severity: "error"
81114
81481
  }
81115
81482
  ],
@@ -81818,9 +82185,9 @@ function formatGapReport(report) {
81818
82185
 
81819
82186
  // packages/core/src/validation/manifest.ts
81820
82187
  init_paths();
81821
- import { existsSync as existsSync102 } from "node:fs";
82188
+ import { existsSync as existsSync103 } from "node:fs";
81822
82189
  import { appendFile as appendFile3, mkdir as mkdir15, readFile as readFile18 } from "node:fs/promises";
81823
- import { dirname as dirname21 } from "node:path";
82190
+ import { dirname as dirname22 } from "node:path";
81824
82191
  var DEFAULT_MANIFEST_PATH = ".cleo/agent-outputs/MANIFEST.jsonl";
81825
82192
  var DEFAULT_COMPLIANCE_PATH = ".cleo/metrics/COMPLIANCE.jsonl";
81826
82193
  async function findManifestEntry(taskId, manifestPath) {
@@ -81831,7 +82198,7 @@ async function findManifestEntry(taskId, manifestPath) {
81831
82198
  manifestPath = DEFAULT_MANIFEST_PATH;
81832
82199
  }
81833
82200
  }
81834
- if (!existsSync102(manifestPath)) return null;
82201
+ if (!existsSync103(manifestPath)) return null;
81835
82202
  const content = await readFile18(manifestPath, "utf-8");
81836
82203
  const lines = content.split("\n").filter((l) => l.trim());
81837
82204
  for (let i = lines.length - 1; i >= 0; i--) {
@@ -81943,7 +82310,7 @@ async function validateManifestEntry(taskId, manifestEntry, manifestPath = DEFAU
81943
82310
  };
81944
82311
  }
81945
82312
  async function logRealCompliance(taskId, validationResult, agentType = "unknown", compliancePath = DEFAULT_COMPLIANCE_PATH) {
81946
- const metricsDir = dirname21(compliancePath);
82313
+ const metricsDir = dirname22(compliancePath);
81947
82314
  await mkdir15(metricsDir, { recursive: true });
81948
82315
  const { score, pass, violations } = validationResult;
81949
82316
  const violationCount = violations.length;
@@ -82003,9 +82370,9 @@ async function validateAndLog(taskId, manifestPath = DEFAULT_MANIFEST_PATH, comp
82003
82370
 
82004
82371
  // packages/core/src/validation/protocol-common.ts
82005
82372
  init_src();
82006
- import { existsSync as existsSync103, readdirSync as readdirSync33, readFileSync as readFileSync74 } from "node:fs";
82373
+ import { existsSync as existsSync104, readdirSync as readdirSync33, readFileSync as readFileSync75 } from "node:fs";
82007
82374
  function checkOutputFileExists(taskId, expectedDir, pattern) {
82008
- if (!existsSync103(expectedDir)) return false;
82375
+ if (!existsSync104(expectedDir)) return false;
82009
82376
  const filePattern = pattern ?? `${taskId}`;
82010
82377
  try {
82011
82378
  const files = readdirSync33(expectedDir);
@@ -82015,9 +82382,9 @@ function checkOutputFileExists(taskId, expectedDir, pattern) {
82015
82382
  }
82016
82383
  }
82017
82384
  function checkDocumentationSections(filePath, sections) {
82018
- if (!existsSync103(filePath)) return false;
82385
+ if (!existsSync104(filePath)) return false;
82019
82386
  try {
82020
- const content = readFileSync74(filePath, "utf-8");
82387
+ const content = readFileSync75(filePath, "utf-8");
82021
82388
  return sections.every((section) => {
82022
82389
  const regex = new RegExp(`^#+ .*${escapeRegex3(section)}`, "m");
82023
82390
  return regex.test(content);
@@ -82110,9 +82477,9 @@ function checkLinkedTasksPresent(entry, requiredIds) {
82110
82477
  return requiredIds.every((id) => linkedTasks.includes(id));
82111
82478
  }
82112
82479
  function checkProvenanceTags(filePath, taskId) {
82113
- if (!existsSync103(filePath)) return false;
82480
+ if (!existsSync104(filePath)) return false;
82114
82481
  try {
82115
- const content = readFileSync74(filePath, "utf-8");
82482
+ const content = readFileSync75(filePath, "utf-8");
82116
82483
  if (taskId) {
82117
82484
  return content.includes(`@task ${taskId}`);
82118
82485
  }
@@ -82771,17 +83138,17 @@ init_logger();
82771
83138
 
82772
83139
  // packages/core/src/output.ts
82773
83140
  init_errors3();
82774
- import { randomUUID as randomUUID7 } from "node:crypto";
83141
+ import { randomUUID as randomUUID8 } from "node:crypto";
82775
83142
 
82776
83143
  // packages/core/src/sessions/context-alert.ts
82777
83144
  init_paths();
82778
- import { existsSync as existsSync106, readFileSync as readFileSync76, writeFileSync as writeFileSync19 } from "node:fs";
82779
- import { join as join105 } from "node:path";
83145
+ import { existsSync as existsSync107, readFileSync as readFileSync77, writeFileSync as writeFileSync20 } from "node:fs";
83146
+ import { join as join107 } from "node:path";
82780
83147
  function getCurrentSessionId(cwd) {
82781
83148
  if (process.env.CLEO_SESSION) return process.env.CLEO_SESSION;
82782
- const sessionFile = join105(getCleoDir(cwd), ".current-session");
82783
- if (existsSync106(sessionFile)) {
82784
- return readFileSync76(sessionFile, "utf-8").trim() || null;
83149
+ const sessionFile = join107(getCleoDir(cwd), ".current-session");
83150
+ if (existsSync107(sessionFile)) {
83151
+ return readFileSync77(sessionFile, "utf-8").trim() || null;
82785
83152
  }
82786
83153
  return null;
82787
83154
  }
@@ -82801,7 +83168,7 @@ function createCliMeta(operation, duration_ms = 0) {
82801
83168
  const warnings = drainWarnings();
82802
83169
  const meta3 = {
82803
83170
  operation,
82804
- requestId: randomUUID7(),
83171
+ requestId: randomUUID8(),
82805
83172
  duration_ms,
82806
83173
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
82807
83174
  };
@@ -82864,10 +83231,10 @@ init_adapters();
82864
83231
  // packages/core/src/bootstrap.ts
82865
83232
  init_paths();
82866
83233
  init_scaffold();
82867
- import { existsSync as existsSync107, readFileSync as readFileSync77 } from "node:fs";
83234
+ import { existsSync as existsSync108, readFileSync as readFileSync78 } from "node:fs";
82868
83235
  import { mkdir as mkdir17, readFile as readFile20, writeFile as writeFile12 } from "node:fs/promises";
82869
83236
  import { homedir as homedir7 } from "node:os";
82870
- import { join as join106 } from "node:path";
83237
+ import { join as join108 } from "node:path";
82871
83238
  async function bootstrapGlobalCleo(options) {
82872
83239
  const ctx = {
82873
83240
  created: [],
@@ -82888,8 +83255,8 @@ async function bootstrapGlobalCleo(options) {
82888
83255
  }
82889
83256
  async function writeTemplateTo(content, destPath, isDryRun) {
82890
83257
  if (isDryRun) return false;
82891
- const { dirname: dirname23 } = await import("node:path");
82892
- await mkdir17(dirname23(destPath), { recursive: true });
83258
+ const { dirname: dirname24 } = await import("node:path");
83259
+ await mkdir17(dirname24(destPath), { recursive: true });
82893
83260
  await writeFile12(destPath, content);
82894
83261
  return true;
82895
83262
  }
@@ -82901,9 +83268,9 @@ async function ensureGlobalTemplatesBootstrap(ctx, packageRootOverride) {
82901
83268
  let templateContent = null;
82902
83269
  try {
82903
83270
  const pkgRoot = packageRootOverride ?? getPackageRoot();
82904
- const templatePath = join106(pkgRoot, "templates", "CLEO-INJECTION.md");
82905
- if (existsSync107(templatePath)) {
82906
- templateContent = readFileSync77(templatePath, "utf-8");
83271
+ const templatePath = join108(pkgRoot, "templates", "CLEO-INJECTION.md");
83272
+ if (existsSync108(templatePath)) {
83273
+ templateContent = readFileSync78(templatePath, "utf-8");
82907
83274
  }
82908
83275
  } catch {
82909
83276
  }
@@ -82920,15 +83287,15 @@ async function ensureGlobalTemplatesBootstrap(ctx, packageRootOverride) {
82920
83287
  ctx.warnings.push("Could not refresh CLEO-INJECTION.md template");
82921
83288
  return;
82922
83289
  }
82923
- const xdgDest = join106(globalTemplatesDir, "CLEO-INJECTION.md");
83290
+ const xdgDest = join108(globalTemplatesDir, "CLEO-INJECTION.md");
82924
83291
  const xdgWritten = await writeTemplateTo(templateContent, xdgDest, ctx.isDryRun);
82925
83292
  ctx.created.push(
82926
83293
  `${getCleoTemplatesTildePath()}/CLEO-INJECTION.md (${xdgWritten ? "refreshed" : "would refresh"})`
82927
83294
  );
82928
83295
  const home = homedir7();
82929
- const legacyTemplatesDir = join106(home, ".cleo", "templates");
82930
- if (legacyTemplatesDir !== globalTemplatesDir && existsSync107(join106(home, ".cleo"))) {
82931
- const legacyDest = join106(legacyTemplatesDir, "CLEO-INJECTION.md");
83296
+ const legacyTemplatesDir = join108(home, ".cleo", "templates");
83297
+ if (legacyTemplatesDir !== globalTemplatesDir && existsSync108(join108(home, ".cleo"))) {
83298
+ const legacyDest = join108(legacyTemplatesDir, "CLEO-INJECTION.md");
82932
83299
  const legacyWritten = await writeTemplateTo(templateContent, legacyDest, ctx.isDryRun);
82933
83300
  if (legacyWritten) {
82934
83301
  ctx.created.push("~/.cleo/templates/CLEO-INJECTION.md (legacy sync)");
@@ -82947,12 +83314,12 @@ function sanitizeCaampFile(content) {
82947
83314
  }
82948
83315
  async function injectAgentsHub(ctx) {
82949
83316
  const globalAgentsDir = getAgentsHome();
82950
- const globalAgentsMd = join106(globalAgentsDir, "AGENTS.md");
83317
+ const globalAgentsMd = join108(globalAgentsDir, "AGENTS.md");
82951
83318
  try {
82952
83319
  const { inject: inject2, getInstalledProviders: getInstalledProviders3, injectAll: injectAll2, buildInjectionContent } = await import("@cleocode/caamp");
82953
83320
  if (!ctx.isDryRun) {
82954
83321
  await mkdir17(globalAgentsDir, { recursive: true });
82955
- if (existsSync107(globalAgentsMd)) {
83322
+ if (existsSync108(globalAgentsMd)) {
82956
83323
  const content = await readFile20(globalAgentsMd, "utf8");
82957
83324
  const stripped = content.replace(
82958
83325
  /\n?<!-- CLEO:START[^>]*-->[\s\S]*?<!-- CLEO:END -->\n?/g,
@@ -82987,8 +83354,8 @@ async function injectAgentsHub(ctx) {
82987
83354
  });
82988
83355
  if (!ctx.isDryRun) {
82989
83356
  for (const provider of providers) {
82990
- const instructFilePath = join106(provider.pathGlobal, provider.instructFile);
82991
- if (existsSync107(instructFilePath)) {
83357
+ const instructFilePath = join108(provider.pathGlobal, provider.instructFile);
83358
+ if (existsSync108(instructFilePath)) {
82992
83359
  const fileContent = await readFile20(instructFilePath, "utf8");
82993
83360
  const stripped = fileContent.replace(
82994
83361
  /\n?<!-- CLEO:START[^>]*-->[\s\S]*?<!-- CLEO:END -->\n?/g,
@@ -83006,7 +83373,7 @@ async function injectAgentsHub(ctx) {
83006
83373
  }
83007
83374
  } else {
83008
83375
  for (const p of providers) {
83009
- const displayPath = join106(p.pathGlobal, p.instructFile).replace(homedir7(), "~");
83376
+ const displayPath = join108(p.pathGlobal, p.instructFile).replace(homedir7(), "~");
83010
83377
  ctx.created.push(`${displayPath} (would update CAAMP block)`);
83011
83378
  }
83012
83379
  }
@@ -83080,17 +83447,17 @@ async function installProviderAdapters(ctx, packageRootOverride) {
83080
83447
  async function verifyBootstrapHealth(ctx) {
83081
83448
  if (ctx.isDryRun) return;
83082
83449
  try {
83083
- const xdgTemplatePath = join106(getCleoTemplatesDir(), "CLEO-INJECTION.md");
83084
- const agentsMd = join106(getAgentsHome(), "AGENTS.md");
83085
- if (!existsSync107(xdgTemplatePath)) {
83450
+ const xdgTemplatePath = join108(getCleoTemplatesDir(), "CLEO-INJECTION.md");
83451
+ const agentsMd = join108(getAgentsHome(), "AGENTS.md");
83452
+ if (!existsSync108(xdgTemplatePath)) {
83086
83453
  ctx.warnings.push("Health: XDG template missing after bootstrap");
83087
83454
  return;
83088
83455
  }
83089
83456
  const xdgContent = await readFile20(xdgTemplatePath, "utf8");
83090
83457
  const xdgVersion = xdgContent.match(/^Version:\s*(.+)$/m)?.[1]?.trim();
83091
83458
  const home = homedir7();
83092
- const legacyTemplatePath = join106(home, ".cleo", "templates", "CLEO-INJECTION.md");
83093
- if (existsSync107(legacyTemplatePath)) {
83459
+ const legacyTemplatePath = join108(home, ".cleo", "templates", "CLEO-INJECTION.md");
83460
+ if (existsSync108(legacyTemplatePath)) {
83094
83461
  const legacyContent = await readFile20(legacyTemplatePath, "utf8");
83095
83462
  const legacyVersion = legacyContent.match(/^Version:\s*(.+)$/m)?.[1]?.trim();
83096
83463
  if (legacyVersion !== xdgVersion) {
@@ -83099,7 +83466,7 @@ async function verifyBootstrapHealth(ctx) {
83099
83466
  );
83100
83467
  }
83101
83468
  }
83102
- if (existsSync107(agentsMd)) {
83469
+ if (existsSync108(agentsMd)) {
83103
83470
  const agentsContent = await readFile20(agentsMd, "utf8");
83104
83471
  const expectedRef = `@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`;
83105
83472
  if (!agentsContent.includes(expectedRef)) {
@@ -83183,13 +83550,13 @@ async function serializeSession(projectRoot, options = {}, accessor) {
83183
83550
  const { tasks: tasks2 } = await acc.queryTasks({});
83184
83551
  const task = tasks2.find((t) => t.id === session.taskWork?.taskId);
83185
83552
  if (task) {
83186
- const desc5 = task.description ?? "";
83553
+ const desc6 = task.description ?? "";
83187
83554
  activeTask = {
83188
83555
  taskId: task.id,
83189
83556
  title: task.title,
83190
83557
  status: task.status,
83191
83558
  priority: task.priority ?? "medium",
83192
- description: desc5.length > maxDescLen ? desc5.slice(0, maxDescLen) + "..." : desc5,
83559
+ description: desc6.length > maxDescLen ? desc6.slice(0, maxDescLen) + "..." : desc6,
83193
83560
  acceptance: Array.isArray(task.acceptance) ? task.acceptance.join("\n") : task.acceptance ?? void 0
83194
83561
  };
83195
83562
  }
@@ -83820,6 +84187,7 @@ export {
83820
84187
  taskTypeSchema,
83821
84188
  task_work_exports as taskWork,
83822
84189
  tasks_exports as tasks,
84190
+ telemetry_exports as telemetry,
83823
84191
  templates_exports as templates,
83824
84192
  timelineBrain,
83825
84193
  tokenUsageConfidenceSchema,