@cleocode/cleo 2026.4.28 → 2026.4.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -1571,10 +1571,10 @@ var init_subquery = __esm({
1571
1571
  init_entity();
1572
1572
  Subquery = class {
1573
1573
  static [entityKind] = "Subquery";
1574
- constructor(sql12, fields, alias, isWith = false, usedTables = []) {
1574
+ constructor(sql13, fields, alias, isWith = false, usedTables = []) {
1575
1575
  this._ = {
1576
1576
  brand: "Subquery",
1577
- sql: sql12,
1577
+ sql: sql13,
1578
1578
  selectedFields: fields,
1579
1579
  alias,
1580
1580
  isWith,
@@ -1925,7 +1925,7 @@ var init_sql = __esm({
1925
1925
  return new SQL([new StringChunk(str)]);
1926
1926
  }
1927
1927
  _sql.raw = raw;
1928
- function join131(chunks, separator) {
1928
+ function join132(chunks, separator) {
1929
1929
  const result = [];
1930
1930
  for (const [i, chunk] of chunks.entries()) {
1931
1931
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -1933,7 +1933,7 @@ var init_sql = __esm({
1933
1933
  }
1934
1934
  return new SQL(result);
1935
1935
  }
1936
- _sql.join = join131;
1936
+ _sql.join = join132;
1937
1937
  function identifier(value) {
1938
1938
  return new Name(value);
1939
1939
  }
@@ -1954,8 +1954,8 @@ var init_sql = __esm({
1954
1954
  isSelectionField = false;
1955
1955
  /** @internal */
1956
1956
  origin;
1957
- constructor(sql12, fieldAlias) {
1958
- this.sql = sql12;
1957
+ constructor(sql13, fieldAlias) {
1958
+ this.sql = sql13;
1959
1959
  this.fieldAlias = fieldAlias;
1960
1960
  }
1961
1961
  getSQL() {
@@ -2659,17 +2659,17 @@ var init_custom = __esm({
2659
2659
  mapFromJsonValue(value) {
2660
2660
  return typeof this.mapJson === "function" ? this.mapJson(value) : this.mapFromDriverValue(value);
2661
2661
  }
2662
- jsonSelectIdentifier(identifier, sql12) {
2663
- if (typeof this.forJsonSelect === "function") return this.forJsonSelect(identifier, sql12);
2662
+ jsonSelectIdentifier(identifier, sql13) {
2663
+ if (typeof this.forJsonSelect === "function") return this.forJsonSelect(identifier, sql13);
2664
2664
  const rawType = this.getSQLType().toLowerCase();
2665
2665
  const parenPos = rawType.indexOf("(");
2666
2666
  switch (parenPos + 1 ? rawType.slice(0, parenPos) : rawType) {
2667
2667
  case "numeric":
2668
2668
  case "decimal":
2669
2669
  case "bigint":
2670
- return sql12`cast(${identifier} as text)`;
2670
+ return sql13`cast(${identifier} as text)`;
2671
2671
  case "blob":
2672
- return sql12`hex(${identifier})`;
2672
+ return sql13`hex(${identifier})`;
2673
2673
  default:
2674
2674
  return identifier;
2675
2675
  }
@@ -3837,8 +3837,8 @@ var init_custom2 = __esm({
3837
3837
  mapFromJsonValue(value) {
3838
3838
  return typeof this.mapJson === "function" ? this.mapJson(value) : this.mapFromDriverValue(value);
3839
3839
  }
3840
- jsonSelectIdentifier(identifier, sql12, arrayDimensions) {
3841
- if (typeof this.forJsonSelect === "function") return this.forJsonSelect(identifier, sql12, arrayDimensions);
3840
+ jsonSelectIdentifier(identifier, sql13, arrayDimensions) {
3841
+ if (typeof this.forJsonSelect === "function") return this.forJsonSelect(identifier, sql13, arrayDimensions);
3842
3842
  const rawType = this.getSQLType().toLowerCase();
3843
3843
  const parenPos = rawType.indexOf("(");
3844
3844
  switch (parenPos + 1 ? rawType.slice(0, parenPos) : rawType) {
@@ -3848,7 +3848,7 @@ var init_custom2 = __esm({
3848
3848
  case "numeric":
3849
3849
  case "bigint": {
3850
3850
  const arrVal = "[]".repeat(arrayDimensions ?? 0);
3851
- return sql12`${identifier}::text${sql12.raw(arrVal).if(arrayDimensions)}`;
3851
+ return sql13`${identifier}::text${sql13.raw(arrVal).if(arrayDimensions)}`;
3852
3852
  }
3853
3853
  default:
3854
3854
  return identifier;
@@ -6707,7 +6707,7 @@ var init_select2 = __esm({
6707
6707
  const baseTableName = this.tableName;
6708
6708
  const tableName = getTableLikeName(table);
6709
6709
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
6710
- if (typeof tableName === "string" && this.config.joins?.some((join131) => join131.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
6710
+ if (typeof tableName === "string" && this.config.joins?.some((join132) => join132.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
6711
6711
  if (!this.isPartialSelect) {
6712
6712
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
6713
6713
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -7729,8 +7729,8 @@ var init_dialect = __esm({
7729
7729
  const returningSql = returning ? sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` : void 0;
7730
7730
  return sql`${withSql}insert into ${table} ${insertOrder} ${valuesSql}${onConflict?.length ? sql.join(onConflict) : void 0}${returningSql}`;
7731
7731
  }
7732
- sqlToQuery(sql12, invokeSource) {
7733
- return sql12.toQuery({
7732
+ sqlToQuery(sql13, invokeSource) {
7733
+ return sql13.toQuery({
7734
7734
  casing: this.casing,
7735
7735
  escapeName: this.escapeName,
7736
7736
  escapeParam: this.escapeParam,
@@ -7992,7 +7992,7 @@ var init_dialect = __esm({
7992
7992
  if (!joins2) return;
7993
7993
  const withEntries = Object.entries(joins2).filter(([_2, v2]) => v2);
7994
7994
  if (!withEntries.length) return;
7995
- return sql.join(withEntries.map(([k2, join131]) => {
7995
+ return sql.join(withEntries.map(([k2, join132]) => {
7996
7996
  const relation = tableConfig.relations[k2];
7997
7997
  const isSingle2 = is(relation, One3);
7998
7998
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -8003,7 +8003,7 @@ var init_dialect = __esm({
8003
8003
  table: targetTable,
8004
8004
  mode: isSingle2 ? "first" : "many",
8005
8005
  schema,
8006
- queryConfig: join131,
8006
+ queryConfig: join132,
8007
8007
  tableConfig: schema[relation.targetTableName],
8008
8008
  relationWhere: filter,
8009
8009
  isNested: true,
@@ -8017,7 +8017,7 @@ var init_dialect = __esm({
8017
8017
  key: k2,
8018
8018
  selection: innerQuery.selection,
8019
8019
  isArray: !isSingle2,
8020
- isOptional: (relation.optional ?? false) || join131 !== true && !!join131.where
8020
+ isOptional: (relation.optional ?? false) || join132 !== true && !!join132.where
8021
8021
  });
8022
8022
  const jsonColumns = sql.join(innerQuery.selection.map((s3) => {
8023
8023
  return sql`${sql.raw(this.escapeString(s3.key))}, ${s3.selection ? sql`${jsonb2}(${sql.identifier(s3.key)})` : sql.identifier(s3.key)}`;
@@ -8416,7 +8416,7 @@ var init_update = __esm({
8416
8416
  createJoin(joinType) {
8417
8417
  return ((table, on) => {
8418
8418
  const tableName = getTableLikeName(table);
8419
- if (typeof tableName === "string" && this.config.joins.some((join131) => join131.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
8419
+ if (typeof tableName === "string" && this.config.joins.some((join132) => join132.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
8420
8420
  if (typeof on === "function") {
8421
8421
  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;
8422
8422
  on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -8827,8 +8827,8 @@ var init_db = __esm({
8827
8827
  });
8828
8828
 
8829
8829
  // 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
8830
- async function hashQuery(sql12, params) {
8831
- const dataToHash = `${sql12}-${JSON.stringify(params, (_2, v2) => typeof v2 === "bigint" ? `${v2}n` : v2)}`;
8830
+ async function hashQuery(sql13, params) {
8831
+ const dataToHash = `${sql13}-${JSON.stringify(params, (_2, v2) => typeof v2 === "bigint" ? `${v2}n` : v2)}`;
8832
8832
  const data = new TextEncoder().encode(dataToHash);
8833
8833
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
8834
8834
  return [...new Uint8Array(hashBuffer)].map((b2) => b2.toString(16).padStart(2, "0")).join("");
@@ -9007,8 +9007,8 @@ var init_session3 = __esm({
9007
9007
  values(query) {
9008
9008
  return this.prepareOneTimeQuery(this.dialect.sqlToQuery(query), void 0, "run", false).values();
9009
9009
  }
9010
- async count(sql12) {
9011
- return (await this.values(sql12))[0][0];
9010
+ async count(sql13) {
9011
+ return (await this.values(sql13))[0][0];
9012
9012
  }
9013
9013
  /** @internal */
9014
9014
  extractRawValuesValueFromBatchResult(_result) {
@@ -11102,8 +11102,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable, logSubsyst
11102
11102
  const dbEntries = nativeDb.prepare('SELECT hash FROM "__drizzle_migrations"').all();
11103
11103
  const hasOrphanedEntries = dbEntries.some((e) => !localHashes.has(e.hash));
11104
11104
  if (hasOrphanedEntries) {
11105
- const log11 = getLogger(logSubsystem);
11106
- log11.warn(
11105
+ const log12 = getLogger(logSubsystem);
11106
+ log12.warn(
11107
11107
  { orphaned: dbEntries.filter((e) => !localHashes.has(e.hash)).length },
11108
11108
  `Detected stale migration journal entries from a previous CLEO version. Reconciling.`
11109
11109
  );
@@ -11135,8 +11135,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable, logSubsyst
11135
11135
  return cols.some((c) => c.name === column);
11136
11136
  });
11137
11137
  if (allColumnsExist) {
11138
- const log11 = getLogger(logSubsystem);
11139
- log11.warn(
11138
+ const log12 = getLogger(logSubsystem);
11139
+ log12.warn(
11140
11140
  { migration: migration.name, columns: alterMatches },
11141
11141
  `Detected partially-applied migration ${migration.name} \u2014 columns exist but journal entry missing. Auto-reconciling.`
11142
11142
  );
@@ -11181,8 +11181,8 @@ function ensureColumns(nativeDb, tableName, requiredColumns, logSubsystem) {
11181
11181
  const existingCols = new Set(columns.map((c) => c.name));
11182
11182
  for (const req of requiredColumns) {
11183
11183
  if (!existingCols.has(req.name)) {
11184
- const log11 = getLogger(logSubsystem);
11185
- log11.warn(
11184
+ const log12 = getLogger(logSubsystem);
11185
+ log12.warn(
11186
11186
  { column: req.name },
11187
11187
  `Adding missing column ${tableName}.${req.name} via ALTER TABLE`
11188
11188
  );
@@ -11301,12 +11301,12 @@ function detachAgentFromProject(db, agentId) {
11301
11301
  }
11302
11302
  function listProjectAgentRefs(db, opts) {
11303
11303
  const enabledOnly = opts?.enabledOnly ?? true;
11304
- const sql12 = enabledOnly ? `SELECT agent_id, attached_at, role, capabilities_override, last_used_at, enabled
11304
+ const sql13 = enabledOnly ? `SELECT agent_id, attached_at, role, capabilities_override, last_used_at, enabled
11305
11305
  FROM project_agent_refs WHERE enabled = 1
11306
11306
  ORDER BY attached_at DESC` : `SELECT agent_id, attached_at, role, capabilities_override, last_used_at, enabled
11307
11307
  FROM project_agent_refs
11308
11308
  ORDER BY attached_at DESC`;
11309
- const rows = db.prepare(sql12).all();
11309
+ const rows = db.prepare(sql13).all();
11310
11310
  return rows.map((r) => ({
11311
11311
  agentId: r.agent_id,
11312
11312
  attachedAt: r.attached_at,
@@ -13395,7 +13395,7 @@ function getDbPath(cwd) {
13395
13395
  return join10(getCleoDirAbsolute(cwd), DB_FILENAME2);
13396
13396
  }
13397
13397
  async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
13398
- const log11 = getLogger("sqlite");
13398
+ const log12 = getLogger("sqlite");
13399
13399
  try {
13400
13400
  const countResult = nativeDb.prepare("SELECT COUNT(*) as cnt FROM tasks").get();
13401
13401
  const taskCount = countResult?.cnt ?? 0;
@@ -13416,7 +13416,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
13416
13416
  if (backupTaskCount < MIN_BACKUP_TASK_COUNT) {
13417
13417
  return;
13418
13418
  }
13419
- log11.warn(
13419
+ log12.warn(
13420
13420
  { dbPath, backupPath: newestBackup.path, backupTasks: backupTaskCount },
13421
13421
  `Empty database detected with ${backupTaskCount}-task backup available. Auto-recovering from backup. This likely happened because git-tracked WAL/SHM files were overwritten during a branch switch (T5188).`
13422
13422
  );
@@ -13434,7 +13434,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
13434
13434
  const tempPath = dbPath + ".recovery-tmp";
13435
13435
  copyFileSync4(newestBackup.path, tempPath);
13436
13436
  renameSync(tempPath, dbPath);
13437
- log11.info(
13437
+ log12.info(
13438
13438
  { dbPath, backupPath: newestBackup.path, restoredTasks: backupTaskCount },
13439
13439
  "Database auto-recovered from backup successfully."
13440
13440
  );
@@ -13444,7 +13444,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
13444
13444
  runMigrations(restoredNativeDb, restoredDb);
13445
13445
  _db = restoredDb;
13446
13446
  } catch (err) {
13447
- log11.error({ err, dbPath }, "Auto-recovery from backup failed. Continuing with empty database.");
13447
+ log12.error({ err, dbPath }, "Auto-recovery from backup failed. Continuing with empty database.");
13448
13448
  }
13449
13449
  }
13450
13450
  async function getDb(cwd) {
@@ -13478,7 +13478,7 @@ async function getDb(cwd) {
13478
13478
  const { execFileSync: execFileSync19 } = await import("node:child_process");
13479
13479
  const gitCwd = resolve3(dbPath, "..", "..");
13480
13480
  const filesToCheck = [dbPath, dbPath + "-wal", dbPath + "-shm"];
13481
- const log11 = getLogger("sqlite");
13481
+ const log12 = getLogger("sqlite");
13482
13482
  for (const fileToCheck of filesToCheck) {
13483
13483
  try {
13484
13484
  execFileSync19("git", ["ls-files", "--error-unmatch", fileToCheck], {
@@ -13487,7 +13487,7 @@ async function getDb(cwd) {
13487
13487
  });
13488
13488
  const basename19 = fileToCheck.split(/[\\/]/).pop();
13489
13489
  const relPath = fileToCheck.replace(gitCwd + sep, "");
13490
- log11.warn(
13490
+ log12.warn(
13491
13491
  { path: fileToCheck },
13492
13492
  `${basename19} is tracked by project git \u2014 this risks data loss on branch switch. Resolution (ADR-013 \xA79): \`git rm --cached ${relPath}\` and rely on \`.cleo/backups/sqlite/\` snapshots + \`cleo backup add\` for recovery.`
13493
13493
  );
@@ -15244,8 +15244,8 @@ async function cleanupMigrationArtifacts(backupPath) {
15244
15244
  }
15245
15245
  async function validateSqliteDatabase(dbPath) {
15246
15246
  try {
15247
- const { createRequire: createRequire13 } = await import("node:module");
15248
- const _req = createRequire13(import.meta.url);
15247
+ const { createRequire: createRequire14 } = await import("node:module");
15248
+ const _req = createRequire14(import.meta.url);
15249
15249
  const { DatabaseSync: DatabaseSync10 } = _req("node:sqlite");
15250
15250
  const db = new DatabaseSync10(dbPath, { readOnly: true });
15251
15251
  const integrityRow = db.prepare("PRAGMA integrity_check").get();
@@ -17270,7 +17270,7 @@ function collectAdrFiles(dir) {
17270
17270
  }
17271
17271
  async function syncAdrsToDb(projectRoot) {
17272
17272
  const adrsDir = join20(projectRoot, ".cleo", "adrs");
17273
- const result = { inserted: 0, updated: 0, skipped: 0, errors: [] };
17273
+ const result = { inserted: 0, updated: 0, skipped: 0, errors: [], warnings: [] };
17274
17274
  if (!existsSync18(adrsDir)) {
17275
17275
  return result;
17276
17276
  }
@@ -17288,9 +17288,36 @@ async function syncAdrsToDb(projectRoot) {
17288
17288
  const fm = record2.frontmatter;
17289
17289
  const dbRelPath = `.cleo/adrs/${relPath}`;
17290
17290
  const content = readFileSync6(filePath, "utf-8");
17291
- const supersedesId = fm.Supersedes ? extractAdrIdFromRef(fm.Supersedes) : null;
17292
- const supersededById = fm["Superseded By"] ? extractAdrIdFromRef(fm["Superseded By"]) : null;
17293
- const amendsId = fm.Amends ? extractAdrIdFromRef(fm.Amends) : null;
17291
+ let supersedesId = fm.Supersedes ? extractAdrIdFromRef(fm.Supersedes) : null;
17292
+ let supersededById = fm["Superseded By"] ? extractAdrIdFromRef(fm["Superseded By"]) : null;
17293
+ let amendsId = fm.Amends ? extractAdrIdFromRef(fm.Amends) : null;
17294
+ if (supersedesId) {
17295
+ const exists2 = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(eq17(architectureDecisions.id, supersedesId)).all();
17296
+ if (exists2.length === 0) {
17297
+ result.warnings.push(
17298
+ `${record2.id}: supersedes target ${supersedesId} not found in DB, setting to null`
17299
+ );
17300
+ supersedesId = null;
17301
+ }
17302
+ }
17303
+ if (supersededById) {
17304
+ const exists2 = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(eq17(architectureDecisions.id, supersededById)).all();
17305
+ if (exists2.length === 0) {
17306
+ result.warnings.push(
17307
+ `${record2.id}: supersededBy target ${supersededById} not found in DB, setting to null`
17308
+ );
17309
+ supersededById = null;
17310
+ }
17311
+ }
17312
+ if (amendsId) {
17313
+ const exists2 = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(eq17(architectureDecisions.id, amendsId)).all();
17314
+ if (exists2.length === 0) {
17315
+ result.warnings.push(
17316
+ `${record2.id}: amends target ${amendsId} not found in DB, setting to null`
17317
+ );
17318
+ amendsId = null;
17319
+ }
17320
+ }
17294
17321
  const rowBase = {
17295
17322
  id: record2.id,
17296
17323
  title: record2.title,
@@ -17320,6 +17347,13 @@ async function syncAdrsToDb(projectRoot) {
17320
17347
  await db.delete(adrTaskLinks).where(eq17(adrTaskLinks.adrId, record2.id));
17321
17348
  if (fm["Related Tasks"]) {
17322
17349
  for (const taskId of parseTaskIds2(fm["Related Tasks"])) {
17350
+ const taskExists2 = await db.select({ id: tasks.id }).from(tasks).where(eq17(tasks.id, taskId)).all();
17351
+ if (taskExists2.length === 0) {
17352
+ result.warnings.push(
17353
+ `${record2.id}: related task ${taskId} not found in DB, skipping link`
17354
+ );
17355
+ continue;
17356
+ }
17323
17357
  await db.insert(adrTaskLinks).values({ adrId: record2.id, taskId, linkType: "related" });
17324
17358
  }
17325
17359
  }
@@ -20687,8 +20721,7 @@ function taskListItemNext(taskId) {
20687
20721
  }
20688
20722
  function sessionListItemNext(sessionId) {
20689
20723
  return {
20690
- show: `cleo session show ${sessionId}`,
20691
- serialize: `cleo session serialize ${sessionId}`
20724
+ show: `cleo session show ${sessionId}`
20692
20725
  };
20693
20726
  }
20694
20727
  function sessionStartNext() {
@@ -20942,8 +20975,8 @@ function checkFts5Available(nativeDb) {
20942
20975
  }
20943
20976
  return _fts5Available;
20944
20977
  }
20945
- function execDDL(nativeDb, sql12) {
20946
- nativeDb.prepare(sql12).run();
20978
+ function execDDL(nativeDb, sql13) {
20979
+ nativeDb.prepare(sql13).run();
20947
20980
  }
20948
20981
  function ensureFts5Tables(nativeDb) {
20949
20982
  if (!checkFts5Available(nativeDb)) {
@@ -22058,8 +22091,8 @@ __export(memory_bridge_exports, {
22058
22091
  });
22059
22092
  import { existsSync as existsSync30, mkdirSync as mkdirSync8, readFileSync as readFileSync17, writeFileSync as writeFileSync3 } from "node:fs";
22060
22093
  import { join as join33 } from "node:path";
22061
- function typedAll2(db, sql12, ...params) {
22062
- return db.prepare(sql12).all(...params);
22094
+ function typedAll2(db, sql13, ...params) {
22095
+ return db.prepare(sql13).all(...params);
22063
22096
  }
22064
22097
  async function generateMemoryBridgeContent(projectRoot, config2) {
22065
22098
  const cfg = { ...DEFAULT_CONFIG, ...config2 };
@@ -38789,9 +38822,9 @@ async function readProjectMeta(projectPath) {
38789
38822
  }
38790
38823
  async function readProjectId(projectPath) {
38791
38824
  try {
38792
- const { readFileSync: readFileSync102, existsSync: existsSync131 } = await import("node:fs");
38825
+ const { readFileSync: readFileSync102, existsSync: existsSync133 } = await import("node:fs");
38793
38826
  const infoPath = join64(projectPath, ".cleo", "project-info.json");
38794
- if (!existsSync131(infoPath)) return "";
38827
+ if (!existsSync133(infoPath)) return "";
38795
38828
  const data = JSON.parse(readFileSync102(infoPath, "utf-8"));
38796
38829
  return typeof data.projectId === "string" ? data.projectId : "";
38797
38830
  } catch {
@@ -40033,7 +40066,7 @@ var init_sharing = __esm({
40033
40066
 
40034
40067
  // packages/core/src/reconciliation/link-store.ts
40035
40068
  import { randomUUID as randomUUID5 } from "node:crypto";
40036
- import { and as and8, eq as eq11 } from "drizzle-orm";
40069
+ import { and as and8, eq as eq11, sql as sql11 } from "drizzle-orm";
40037
40070
  async function getLinksByProvider(providerId, cwd) {
40038
40071
  const db = await getDb(cwd);
40039
40072
  const rows = await db.select().from(externalTaskLinks).where(eq11(externalTaskLinks.providerId, providerId));
@@ -40054,7 +40087,46 @@ async function getLinksByTaskId(taskId, cwd) {
40054
40087
  const rows = await db.select().from(externalTaskLinks).where(eq11(externalTaskLinks.taskId, taskId));
40055
40088
  return rows.map(rowToLink);
40056
40089
  }
40090
+ async function ensureExternalTaskLinksTable(cwd) {
40091
+ const db = await getDb(cwd);
40092
+ try {
40093
+ db.run(
40094
+ sql11.raw(`
40095
+ CREATE TABLE IF NOT EXISTS external_task_links (
40096
+ id text PRIMARY KEY NOT NULL,
40097
+ task_id text NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
40098
+ provider_id text NOT NULL,
40099
+ external_id text NOT NULL,
40100
+ external_url text,
40101
+ external_title text,
40102
+ link_type text NOT NULL,
40103
+ sync_direction text NOT NULL DEFAULT 'inbound',
40104
+ metadata_json text DEFAULT '{}',
40105
+ linked_at text NOT NULL DEFAULT (datetime('now')),
40106
+ last_sync_at text
40107
+ )
40108
+ `)
40109
+ );
40110
+ db.run(
40111
+ sql11.raw(
40112
+ `CREATE UNIQUE INDEX IF NOT EXISTS uq_ext_links_task_provider_external ON external_task_links(task_id, provider_id, external_id)`
40113
+ )
40114
+ );
40115
+ db.run(
40116
+ sql11.raw(`CREATE INDEX IF NOT EXISTS idx_ext_links_task_id ON external_task_links(task_id)`)
40117
+ );
40118
+ db.run(
40119
+ sql11.raw(
40120
+ `CREATE INDEX IF NOT EXISTS idx_ext_links_provider_id ON external_task_links(provider_id)`
40121
+ )
40122
+ );
40123
+ } catch (err) {
40124
+ log6.warn({ err }, "Failed to ensure external_task_links table exists");
40125
+ throw err;
40126
+ }
40127
+ }
40057
40128
  async function createLink(params, cwd) {
40129
+ await ensureExternalTaskLinksTable(cwd);
40058
40130
  const db = await getDb(cwd);
40059
40131
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
40060
40132
  const id = randomUUID5();
@@ -40117,11 +40189,14 @@ function rowToLink(row) {
40117
40189
  lastSyncAt: row.lastSyncAt
40118
40190
  };
40119
40191
  }
40192
+ var log6;
40120
40193
  var init_link_store = __esm({
40121
40194
  "packages/core/src/reconciliation/link-store.ts"() {
40122
40195
  "use strict";
40196
+ init_logger();
40123
40197
  init_sqlite2();
40124
40198
  init_tasks_schema();
40199
+ log6 = getLogger("link-store");
40125
40200
  }
40126
40201
  });
40127
40202
 
@@ -40222,48 +40297,55 @@ async function executeTransferInternal(params) {
40222
40297
  return result;
40223
40298
  }
40224
40299
  let linksCreated = 0;
40225
- const targetAccessor = await getAccessor(targetProject.path);
40226
- const { tasks: targetTasks } = await targetAccessor.queryTasks({});
40227
- const targetTaskIds = new Set(targetTasks.map((t) => t.id));
40228
- for (const entry of entries) {
40229
- if (importResult.idRemap[entry.sourceId] && targetTaskIds.has(entry.targetId)) {
40230
- await createLink(
40231
- {
40232
- taskId: entry.targetId,
40233
- providerId: `nexus:${sourceProject.name}`,
40234
- externalId: entry.sourceId,
40235
- externalTitle: entry.title,
40236
- linkType: "transferred",
40237
- syncDirection: "inbound",
40238
- metadata: {
40239
- transferMode: mode,
40240
- transferScope: scope,
40241
- sourceProject: sourceProject.name,
40242
- transferredAt: (/* @__PURE__ */ new Date()).toISOString()
40243
- }
40244
- },
40245
- targetProject.path
40246
- );
40247
- linksCreated++;
40248
- await createLink(
40249
- {
40250
- taskId: entry.sourceId,
40251
- providerId: `nexus:${targetProject.name}`,
40252
- externalId: entry.targetId,
40253
- externalTitle: entry.title,
40254
- linkType: "transferred",
40255
- syncDirection: "outbound",
40256
- metadata: {
40257
- transferMode: mode,
40258
- transferScope: scope,
40259
- targetProject: targetProject.name,
40260
- transferredAt: (/* @__PURE__ */ new Date()).toISOString()
40261
- }
40262
- },
40263
- sourceProject.path
40264
- );
40265
- linksCreated++;
40300
+ try {
40301
+ const targetAccessor = await getAccessor(targetProject.path);
40302
+ const { tasks: targetTasks } = await targetAccessor.queryTasks({});
40303
+ const targetTaskIds = new Set(targetTasks.map((t) => t.id));
40304
+ for (const entry of entries) {
40305
+ if (importResult.idRemap[entry.sourceId] && targetTaskIds.has(entry.targetId)) {
40306
+ await createLink(
40307
+ {
40308
+ taskId: entry.targetId,
40309
+ providerId: `nexus:${sourceProject.name}`,
40310
+ externalId: entry.sourceId,
40311
+ externalTitle: entry.title,
40312
+ linkType: "transferred",
40313
+ syncDirection: "inbound",
40314
+ metadata: {
40315
+ transferMode: mode,
40316
+ transferScope: scope,
40317
+ sourceProject: sourceProject.name,
40318
+ transferredAt: (/* @__PURE__ */ new Date()).toISOString()
40319
+ }
40320
+ },
40321
+ targetProject.path
40322
+ );
40323
+ linksCreated++;
40324
+ await createLink(
40325
+ {
40326
+ taskId: entry.sourceId,
40327
+ providerId: `nexus:${targetProject.name}`,
40328
+ externalId: entry.targetId,
40329
+ externalTitle: entry.title,
40330
+ linkType: "transferred",
40331
+ syncDirection: "outbound",
40332
+ metadata: {
40333
+ transferMode: mode,
40334
+ transferScope: scope,
40335
+ targetProject: targetProject.name,
40336
+ transferredAt: (/* @__PURE__ */ new Date()).toISOString()
40337
+ }
40338
+ },
40339
+ sourceProject.path
40340
+ );
40341
+ linksCreated++;
40342
+ }
40266
40343
  }
40344
+ } catch (err) {
40345
+ log7.warn(
40346
+ { err, linksCreated },
40347
+ "Failed to create external_task_links during transfer \u2014 tasks were transferred successfully but provenance links could not be written"
40348
+ );
40267
40349
  }
40268
40350
  result.linksCreated = linksCreated;
40269
40351
  try {
@@ -40288,7 +40370,7 @@ async function executeTransferInternal(params) {
40288
40370
  })
40289
40371
  });
40290
40372
  } catch (err) {
40291
- log6.warn({ err }, "nexus transfer audit write failed");
40373
+ log7.warn({ err }, "nexus transfer audit write failed");
40292
40374
  }
40293
40375
  if (mode === "move") {
40294
40376
  let archived = 0;
@@ -40301,7 +40383,7 @@ async function executeTransferInternal(params) {
40301
40383
  });
40302
40384
  archived++;
40303
40385
  } catch (err) {
40304
- log6.warn({ err, taskId: entry.sourceId }, "failed to archive source task after transfer");
40386
+ log7.warn({ err, taskId: entry.sourceId }, "failed to archive source task after transfer");
40305
40387
  }
40306
40388
  }
40307
40389
  }
@@ -40339,14 +40421,14 @@ async function executeTransferInternal(params) {
40339
40421
  }
40340
40422
  }
40341
40423
  } catch (err) {
40342
- log6.warn({ err }, "brain observation transfer failed");
40424
+ log7.warn({ err }, "brain observation transfer failed");
40343
40425
  }
40344
40426
  result.brainObservationsTransferred = brainTransferred;
40345
40427
  result.manifest.brainObservationsTransferred = brainTransferred;
40346
40428
  }
40347
40429
  return result;
40348
40430
  }
40349
- var log6;
40431
+ var log7;
40350
40432
  var init_transfer = __esm({
40351
40433
  "packages/core/src/nexus/transfer.ts"() {
40352
40434
  "use strict";
@@ -40359,7 +40441,7 @@ var init_transfer = __esm({
40359
40441
  init_export2();
40360
40442
  init_permissions();
40361
40443
  init_registry3();
40362
- log6 = getLogger("nexus:transfer");
40444
+ log7 = getLogger("nexus:transfer");
40363
40445
  }
40364
40446
  });
40365
40447
 
@@ -41259,8 +41341,8 @@ async function loadProjectACL(projectPath) {
41259
41341
  async function logAclFailure(projectPath) {
41260
41342
  try {
41261
41343
  const { getLogger: getLogger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
41262
- const log11 = getLogger2("nexus.acl");
41263
- log11.warn({ projectPath }, "Failed to load ACL configuration, defaulting to deny-all");
41344
+ const log12 = getLogger2("nexus.acl");
41345
+ log12.warn({ projectPath }, "Failed to load ACL configuration, defaulting to deny-all");
41264
41346
  } catch {
41265
41347
  }
41266
41348
  }
@@ -41405,9 +41487,9 @@ async function executeOperation(operation, taskId, projectPath, accessor, direct
41405
41487
  async function logRouteAudit(directive, projectName, taskId, operation, success2, error48) {
41406
41488
  try {
41407
41489
  const { getLogger: getLogger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
41408
- const log11 = getLogger2("nexus.route");
41490
+ const log12 = getLogger2("nexus.route");
41409
41491
  const level = success2 ? "info" : "warn";
41410
- log11[level](
41492
+ log12[level](
41411
41493
  {
41412
41494
  directive: directive.verb,
41413
41495
  agentId: directive.agentId,
@@ -47726,8 +47808,11 @@ function sanitizeParams(params, projectRoot, context) {
47726
47808
  continue;
47727
47809
  }
47728
47810
  if (typeof value === "string" && (key === "path" || key === "file") && projectRoot) {
47729
- sanitized[key] = sanitizePath(value, projectRoot);
47730
- continue;
47811
+ const allowExternalPath = context?.domain === "nexus" && (context?.operation === "register" || context?.operation === "reconcile");
47812
+ if (!allowExternalPath) {
47813
+ sanitized[key] = sanitizePath(value, projectRoot);
47814
+ continue;
47815
+ }
47731
47816
  }
47732
47817
  if (typeof value === "string" && (key === "title" || key === "description" || key === "content")) {
47733
47818
  const maxLen = key === "title" ? 200 : DEFAULT_MAX_CONTENT_LENGTH;
@@ -50259,8 +50344,8 @@ async function initializeSpawnAdapters(manifests) {
50259
50344
  if (!manifest.capabilities?.supportsSpawn) continue;
50260
50345
  if (spawnRegistry.hasAdapterForProvider(manifest.provider)) continue;
50261
50346
  try {
50262
- const { join: join131 } = await import("node:path");
50263
- const modulePath = join131(manifest.packagePath, manifest.entryPoint);
50347
+ const { join: join132 } = await import("node:path");
50348
+ const modulePath = join132(manifest.packagePath, manifest.entryPoint);
50264
50349
  const adapterModule = await import(modulePath);
50265
50350
  let SpawnProviderClass;
50266
50351
  for (const [exportName, exportValue] of Object.entries(adapterModule)) {
@@ -50415,7 +50500,7 @@ async function queryTasks(cwd, since) {
50415
50500
  }).from(tasks2).where(conditions.length > 0 ? and13(...conditions) : void 0).all();
50416
50501
  return rows;
50417
50502
  } catch (err) {
50418
- log7.warn({ err }, "Failed to query tasks for workflow telemetry");
50503
+ log8.warn({ err }, "Failed to query tasks for workflow telemetry");
50419
50504
  return [];
50420
50505
  }
50421
50506
  }
@@ -50449,7 +50534,7 @@ async function queryCompletionAuditRows(cwd, since) {
50449
50534
  return isComplete;
50450
50535
  });
50451
50536
  } catch (err) {
50452
- log7.warn({ err }, "Failed to query audit log for workflow telemetry");
50537
+ log8.warn({ err }, "Failed to query audit log for workflow telemetry");
50453
50538
  return [];
50454
50539
  }
50455
50540
  }
@@ -50674,12 +50759,12 @@ async function getWorkflowComplianceReport(opts) {
50674
50759
  }
50675
50760
  };
50676
50761
  }
50677
- var log7;
50762
+ var log8;
50678
50763
  var init_workflow_telemetry = __esm({
50679
50764
  "packages/core/src/stats/workflow-telemetry.ts"() {
50680
50765
  "use strict";
50681
50766
  init_logger();
50682
- log7 = getLogger("workflow-telemetry");
50767
+ log8 = getLogger("workflow-telemetry");
50683
50768
  }
50684
50769
  });
50685
50770
 
@@ -51265,13 +51350,22 @@ function rowToStickyNote3(row) {
51265
51350
  }
51266
51351
  async function listStickies(params, projectRoot) {
51267
51352
  const accessor = await getBrainAccessor(projectRoot);
51353
+ const hasTagFilter = params.tags && params.tags.length > 0;
51268
51354
  const rows = await accessor.findStickyNotes({
51269
51355
  status: params.status,
51270
51356
  color: params.color,
51271
51357
  priority: params.priority,
51272
- limit: params.limit
51358
+ limit: hasTagFilter ? void 0 : params.limit
51273
51359
  });
51274
- return rows.map(rowToStickyNote3);
51360
+ let notes = rows.map(rowToStickyNote3);
51361
+ if (hasTagFilter) {
51362
+ const requiredTags = params.tags;
51363
+ notes = notes.filter((note) => requiredTags.every((t) => note.tags.includes(t)));
51364
+ if (params.limit && notes.length > params.limit) {
51365
+ notes = notes.slice(0, params.limit);
51366
+ }
51367
+ }
51368
+ return notes;
51275
51369
  }
51276
51370
  var init_list2 = __esm({
51277
51371
  "packages/core/src/sticky/list.ts"() {
@@ -51984,7 +52078,7 @@ import { createGzip } from "node:zlib";
51984
52078
  async function pruneAuditLog(cleoDir, config2) {
51985
52079
  try {
51986
52080
  if (!config2.auditRetentionDays || config2.auditRetentionDays <= 0) {
51987
- log8.debug("auditRetentionDays is 0 or unset; skipping audit prune");
52081
+ log9.debug("auditRetentionDays is 0 or unset; skipping audit prune");
51988
52082
  return { rowsArchived: 0, rowsDeleted: 0 };
51989
52083
  }
51990
52084
  const cutoff = new Date(Date.now() - config2.auditRetentionDays * 864e5).toISOString();
@@ -51995,7 +52089,7 @@ async function pruneAuditLog(cleoDir, config2) {
51995
52089
  const db = await getDb4(projectRoot);
51996
52090
  const oldRows = await db.select().from(auditLog2).where(lt4(auditLog2.timestamp, cutoff));
51997
52091
  if (oldRows.length === 0) {
51998
- log8.debug("No audit_log rows older than cutoff; nothing to prune");
52092
+ log9.debug("No audit_log rows older than cutoff; nothing to prune");
51999
52093
  return { rowsArchived: 0, rowsDeleted: 0 };
52000
52094
  }
52001
52095
  let archivePath;
@@ -52013,17 +52107,17 @@ async function pruneAuditLog(cleoDir, config2) {
52013
52107
  const inStream = Readable.from([jsonlContent]);
52014
52108
  await pipeline(inStream, gzip, outStream);
52015
52109
  rowsArchived = oldRows.length;
52016
- log8.info(
52110
+ log9.info(
52017
52111
  { archivePath, rowsArchived },
52018
52112
  `Archived ${rowsArchived} audit rows to ${archivePath}`
52019
52113
  );
52020
52114
  } catch (archiveErr) {
52021
- log8.warn({ err: archiveErr }, "Failed to archive audit rows; continuing with deletion");
52115
+ log9.warn({ err: archiveErr }, "Failed to archive audit rows; continuing with deletion");
52022
52116
  archivePath = void 0;
52023
52117
  }
52024
52118
  }
52025
52119
  await db.delete(auditLog2).where(lt4(auditLog2.timestamp, cutoff)).run();
52026
- log8.info(
52120
+ log9.info(
52027
52121
  { rowsDeleted: oldRows.length, cutoff },
52028
52122
  `Pruned ${oldRows.length} audit_log rows older than ${cutoff}`
52029
52123
  );
@@ -52033,16 +52127,16 @@ async function pruneAuditLog(cleoDir, config2) {
52033
52127
  archivePath
52034
52128
  };
52035
52129
  } catch (err) {
52036
- log8.warn({ err }, "audit log pruning failed");
52130
+ log9.warn({ err }, "audit log pruning failed");
52037
52131
  return { rowsArchived: 0, rowsDeleted: 0 };
52038
52132
  }
52039
52133
  }
52040
- var log8;
52134
+ var log9;
52041
52135
  var init_audit_prune = __esm({
52042
52136
  "packages/core/src/audit-prune.ts"() {
52043
52137
  "use strict";
52044
52138
  init_logger();
52045
- log8 = getLogger("prune");
52139
+ log9 = getLogger("prune");
52046
52140
  }
52047
52141
  });
52048
52142
 
@@ -73615,8 +73709,8 @@ import { platform as platform4 } from "node:os";
73615
73709
  import { basename as basename17, dirname as dirname21, join as join105 } from "node:path";
73616
73710
  async function resolveSeedAgentsDir() {
73617
73711
  try {
73618
- const { createRequire: createRequire13 } = await import("node:module");
73619
- const req = createRequire13(import.meta.url);
73712
+ const { createRequire: createRequire14 } = await import("node:module");
73713
+ const req = createRequire14(import.meta.url);
73620
73714
  const agentsPkgMain = req.resolve("@cleocode/agents/package.json");
73621
73715
  const agentsPkgRoot = dirname21(agentsPkgMain);
73622
73716
  const candidate = join105(agentsPkgRoot, "seed-agents");
@@ -73643,8 +73737,8 @@ async function resolveSeedAgentsDir() {
73643
73737
  async function initAgentDefinition(created, warnings) {
73644
73738
  let agentSourceDir = null;
73645
73739
  try {
73646
- const { createRequire: createRequire13 } = await import("node:module");
73647
- const req = createRequire13(import.meta.url);
73740
+ const { createRequire: createRequire14 } = await import("node:module");
73741
+ const req = createRequire14(import.meta.url);
73648
73742
  const agentsPkgMain = req.resolve("@cleocode/agents/package.json");
73649
73743
  const agentsPkgRoot = dirname21(agentsPkgMain);
73650
73744
  const candidate = join105(agentsPkgRoot, "cleo-subagent");
@@ -73702,7 +73796,7 @@ async function initMcpServer(_projectRoot, _created, _warnings) {
73702
73796
  }
73703
73797
  async function initCoreSkills(created, warnings) {
73704
73798
  try {
73705
- const { getInstalledProviders: getInstalledProviders4, installSkill: installSkill3, registerSkillLibraryFromPath } = await import("@cleocode/caamp");
73799
+ const { getInstalledProviders: getInstalledProviders4, installSkill: installSkill3, registerSkillLibraryFromPath: registerSkillLibraryFromPath2 } = await import("@cleocode/caamp");
73706
73800
  const providers = getInstalledProviders4();
73707
73801
  if (providers.length === 0) {
73708
73802
  return;
@@ -73710,8 +73804,8 @@ async function initCoreSkills(created, warnings) {
73710
73804
  const packageRoot = getPackageRoot();
73711
73805
  let ctSkillsRoot = null;
73712
73806
  try {
73713
- const { createRequire: createRequire13 } = await import("node:module");
73714
- const req = createRequire13(import.meta.url);
73807
+ const { createRequire: createRequire14 } = await import("node:module");
73808
+ const req = createRequire14(import.meta.url);
73715
73809
  const skillsPkgMain = req.resolve("@cleocode/skills/package.json");
73716
73810
  const skillsPkgRoot = dirname21(skillsPkgMain);
73717
73811
  if (existsSync106(join105(skillsPkgRoot, "skills.json"))) {
@@ -73738,13 +73832,13 @@ async function initCoreSkills(created, warnings) {
73738
73832
  return;
73739
73833
  }
73740
73834
  try {
73741
- registerSkillLibraryFromPath(ctSkillsRoot);
73835
+ registerSkillLibraryFromPath2(ctSkillsRoot);
73742
73836
  } catch {
73743
73837
  warnings.push("Failed to register skill library with CAAMP");
73744
73838
  }
73745
73839
  const catalogPath = join105(ctSkillsRoot, "skills.json");
73746
- const catalog4 = JSON.parse(readFileSync74(catalogPath, "utf-8"));
73747
- const skills = catalog4.skills ?? [];
73840
+ const catalog5 = JSON.parse(readFileSync74(catalogPath, "utf-8"));
73841
+ const skills = catalog5.skills ?? [];
73748
73842
  const coreSkills = skills.filter((s3) => s3.tier <= 2);
73749
73843
  const installed = [];
73750
73844
  for (const skill of coreSkills) {
@@ -74090,8 +74184,8 @@ async function initProject(opts = {}) {
74090
74184
  if (!hasCantFiles) {
74091
74185
  let starterBundleSrc = null;
74092
74186
  try {
74093
- const { createRequire: createRequire13 } = await import("node:module");
74094
- const req = createRequire13(import.meta.url);
74187
+ const { createRequire: createRequire14 } = await import("node:module");
74188
+ const req = createRequire14(import.meta.url);
74095
74189
  const cleoOsPkgMain = req.resolve("@cleocode/cleo-os/package.json");
74096
74190
  const cleoOsPkgRoot = dirname21(cleoOsPkgMain);
74097
74191
  const candidate = join105(cleoOsPkgRoot, "starter-bundle");
@@ -74464,8 +74558,8 @@ async function bootstrapGlobalCleo(options) {
74464
74558
  }
74465
74559
  async function writeTemplateTo(content, destPath, isDryRun) {
74466
74560
  if (isDryRun) return false;
74467
- const { dirname: dirname29 } = await import("node:path");
74468
- await mkdir17(dirname29(destPath), { recursive: true });
74561
+ const { dirname: dirname30 } = await import("node:path");
74562
+ await mkdir17(dirname30(destPath), { recursive: true });
74469
74563
  await writeFile12(destPath, content);
74470
74564
  return true;
74471
74565
  }
@@ -75180,7 +75274,6 @@ var init_cleo = __esm({
75180
75274
  // packages/core/src/index.ts
75181
75275
  var init_src2 = __esm({
75182
75276
  "packages/core/src/index.ts"() {
75183
- "use strict";
75184
75277
  init_src();
75185
75278
  init_adapters();
75186
75279
  init_admin();
@@ -77763,8 +77856,8 @@ var init_brain_maintenance = __esm({
77763
77856
  // packages/core/src/memory/claude-mem-migration.ts
77764
77857
  import { existsSync as existsSync110 } from "node:fs";
77765
77858
  import { createRequire as createRequire8 } from "node:module";
77766
- function typedAll3(db, sql12) {
77767
- return db.prepare(sql12).all();
77859
+ function typedAll3(db, sql13) {
77860
+ return db.prepare(sql13).all();
77768
77861
  }
77769
77862
  function mapObservationType(type) {
77770
77863
  if (VALID_OBSERVATION_TYPES.has(type)) {
@@ -83906,7 +83999,7 @@ var init_backup_pack = __esm({
83906
83999
  import fs5 from "node:fs";
83907
84000
  import path4 from "node:path";
83908
84001
  function detectAndRemoveLegacyGlobalFiles(cleoHomeOverride) {
83909
- const log11 = getLogger("cleanup-legacy");
84002
+ const log12 = getLogger("cleanup-legacy");
83910
84003
  const cleoHome = cleoHomeOverride ?? getCleoHome();
83911
84004
  const removed = [];
83912
84005
  const errors = [];
@@ -83916,30 +84009,30 @@ function detectAndRemoveLegacyGlobalFiles(cleoHomeOverride) {
83916
84009
  if (fs5.existsSync(fullPath)) {
83917
84010
  fs5.unlinkSync(fullPath);
83918
84011
  removed.push(fileName);
83919
- log11.info({ file: fullPath }, "Removed legacy global file");
84012
+ log12.info({ file: fullPath }, "Removed legacy global file");
83920
84013
  }
83921
84014
  } catch (err) {
83922
84015
  const message = err instanceof Error ? err.message : String(err);
83923
84016
  errors.push({ file: fileName, error: message });
83924
- log11.warn({ file: fullPath, error: message }, "Failed to remove legacy global file");
84017
+ log12.warn({ file: fullPath, error: message }, "Failed to remove legacy global file");
83925
84018
  }
83926
84019
  }
83927
84020
  return { removed, errors };
83928
84021
  }
83929
84022
  function detectAndRemoveStrayProjectNexus(projectRoot) {
83930
- const log11 = getLogger("cleanup-legacy");
84023
+ const log12 = getLogger("cleanup-legacy");
83931
84024
  const strayPath = path4.join(projectRoot, ".cleo", "nexus.db");
83932
84025
  if (fs5.existsSync(strayPath)) {
83933
84026
  try {
83934
84027
  fs5.unlinkSync(strayPath);
83935
- log11.warn(
84028
+ log12.warn(
83936
84029
  { path: strayPath },
83937
84030
  "Removed stray project-tier nexus.db (violates ADR-036 global-only contract)"
83938
84031
  );
83939
84032
  return { removed: true, path: strayPath };
83940
84033
  } catch (err) {
83941
84034
  const message = err instanceof Error ? err.message : String(err);
83942
- log11.warn(
84035
+ log12.warn(
83943
84036
  { path: strayPath, error: message },
83944
84037
  "Failed to remove stray project-tier nexus.db \u2014 manual deletion may be required"
83945
84038
  );
@@ -84010,7 +84103,7 @@ function brokenTimestamp() {
84010
84103
  return `${now2.getFullYear()}${pad2(now2.getMonth() + 1)}${pad2(now2.getDate())}-${pad2(now2.getHours())}${pad2(now2.getMinutes())}${pad2(now2.getSeconds())}-${pad3(now2.getMilliseconds())}`;
84011
84104
  }
84012
84105
  function migrateSignaldockToConduit(projectRoot) {
84013
- const log11 = getLogger("migrate-signaldock-to-conduit");
84106
+ const log12 = getLogger("migrate-signaldock-to-conduit");
84014
84107
  const legacyPath = join113(projectRoot, ".cleo", "signaldock.db");
84015
84108
  const conduitPath = join113(projectRoot, ".cleo", "conduit.db");
84016
84109
  const globalSignaldockPath = join113(getCleoHome(), "signaldock.db");
@@ -84027,13 +84120,13 @@ function migrateSignaldockToConduit(projectRoot) {
84027
84120
  if (!needsSignaldockToConduitMigration(projectRoot)) {
84028
84121
  return result;
84029
84122
  }
84030
- log11.info({ projectRoot, legacyPath }, "T310 migration: starting signaldock.db \u2192 conduit.db");
84123
+ log12.info({ projectRoot, legacyPath }, "T310 migration: starting signaldock.db \u2192 conduit.db");
84031
84124
  let legacy = null;
84032
84125
  try {
84033
84126
  legacy = new DatabaseSync7(legacyPath, { readOnly: true });
84034
84127
  } catch (err) {
84035
84128
  const message = err instanceof Error ? err.message : String(err);
84036
- log11.error({ legacyPath, error: message }, "T310 migration: cannot open legacy signaldock.db");
84129
+ log12.error({ legacyPath, error: message }, "T310 migration: cannot open legacy signaldock.db");
84037
84130
  result.errors.push({ step: "step-2-open-legacy", error: message });
84038
84131
  result.status = "failed";
84039
84132
  return result;
@@ -84041,7 +84134,7 @@ function migrateSignaldockToConduit(projectRoot) {
84041
84134
  try {
84042
84135
  if (!integrityCheckPasses(legacy)) {
84043
84136
  const msg = "Legacy signaldock.db failed PRAGMA integrity_check. Migration aborted \u2014 no changes written. Recovery: inspect the database with sqlite3 and attempt manual repair before re-running.";
84044
- log11.error({ legacyPath }, msg);
84137
+ log12.error({ legacyPath }, msg);
84045
84138
  result.errors.push({ step: "step-3-legacy-integrity", error: msg });
84046
84139
  result.status = "failed";
84047
84140
  legacy.close();
@@ -84049,7 +84142,7 @@ function migrateSignaldockToConduit(projectRoot) {
84049
84142
  }
84050
84143
  } catch (err) {
84051
84144
  const message = err instanceof Error ? err.message : String(err);
84052
- log11.error({ legacyPath, error: message }, "T310 migration: integrity_check threw on legacy DB");
84145
+ log12.error({ legacyPath, error: message }, "T310 migration: integrity_check threw on legacy DB");
84053
84146
  result.errors.push({ step: "step-3-legacy-integrity", error: message });
84054
84147
  result.status = "failed";
84055
84148
  legacy.close();
@@ -84067,7 +84160,7 @@ function migrateSignaldockToConduit(projectRoot) {
84067
84160
  getGlobalSalt();
84068
84161
  } catch (err) {
84069
84162
  const message = err instanceof Error ? err.message : String(err);
84070
- log11.error({ error: message }, "T310 migration: getGlobalSalt failed \u2014 migration aborted");
84163
+ log12.error({ error: message }, "T310 migration: getGlobalSalt failed \u2014 migration aborted");
84071
84164
  result.errors.push({ step: "step-6-global-salt", error: message });
84072
84165
  result.status = "failed";
84073
84166
  legacy.close();
@@ -84081,7 +84174,7 @@ function migrateSignaldockToConduit(projectRoot) {
84081
84174
  conduit.exec("PRAGMA foreign_keys = OFF");
84082
84175
  } catch (err) {
84083
84176
  const message = err instanceof Error ? err.message : String(err);
84084
- log11.error({ conduitPath, error: message }, "T310 migration: failed to create conduit.db");
84177
+ log12.error({ conduitPath, error: message }, "T310 migration: failed to create conduit.db");
84085
84178
  result.errors.push({ step: "step-7-create-conduit", error: message });
84086
84179
  result.status = "failed";
84087
84180
  legacy.close();
@@ -84127,7 +84220,7 @@ function migrateSignaldockToConduit(projectRoot) {
84127
84220
  result.agentsCopied = agentsCountForConduit;
84128
84221
  } catch (err) {
84129
84222
  const message = err instanceof Error ? err.message : String(err);
84130
- log11.error({ error: message }, "T310 migration: conduit.db write failed \u2014 rolling back");
84223
+ log12.error({ error: message }, "T310 migration: conduit.db write failed \u2014 rolling back");
84131
84224
  result.errors.push({ step: "step-8-conduit-write", error: message });
84132
84225
  result.status = "failed";
84133
84226
  try {
@@ -84148,7 +84241,7 @@ function migrateSignaldockToConduit(projectRoot) {
84148
84241
  try {
84149
84242
  if (!integrityCheckPasses(conduit)) {
84150
84243
  const msg = "conduit.db failed PRAGMA integrity_check after write";
84151
- log11.error({ conduitPath }, msg);
84244
+ log12.error({ conduitPath }, msg);
84152
84245
  result.errors.push({ step: "step-10-conduit-integrity", error: msg });
84153
84246
  result.status = "failed";
84154
84247
  conduit.close();
@@ -84163,7 +84256,7 @@ function migrateSignaldockToConduit(projectRoot) {
84163
84256
  }
84164
84257
  } catch (err) {
84165
84258
  const message = err instanceof Error ? err.message : String(err);
84166
- log11.error({ error: message }, "T310 migration: conduit.db integrity_check threw");
84259
+ log12.error({ error: message }, "T310 migration: conduit.db integrity_check threw");
84167
84260
  result.errors.push({ step: "step-10-conduit-integrity", error: message });
84168
84261
  result.status = "failed";
84169
84262
  if (conduit) {
@@ -84185,7 +84278,7 @@ function migrateSignaldockToConduit(projectRoot) {
84185
84278
  globalDb.exec("PRAGMA foreign_keys = OFF");
84186
84279
  } catch (err) {
84187
84280
  const message = err instanceof Error ? err.message : String(err);
84188
- log11.error(
84281
+ log12.error(
84189
84282
  { globalSignaldockPath, error: message },
84190
84283
  "T310 migration: cannot open global signaldock.db"
84191
84284
  );
@@ -84224,7 +84317,7 @@ function migrateSignaldockToConduit(projectRoot) {
84224
84317
  result.agentsCopied = agentsCopiedToGlobal;
84225
84318
  } catch (err) {
84226
84319
  const message = err instanceof Error ? err.message : String(err);
84227
- log11.error(
84320
+ log12.error(
84228
84321
  { error: message },
84229
84322
  "T310 migration: global signaldock.db write failed \u2014 rolling back"
84230
84323
  );
@@ -84242,7 +84335,7 @@ function migrateSignaldockToConduit(projectRoot) {
84242
84335
  try {
84243
84336
  if (!integrityCheckPasses(globalDb)) {
84244
84337
  const msg = "Global signaldock.db failed PRAGMA integrity_check after write";
84245
- log11.error({ globalSignaldockPath }, msg);
84338
+ log12.error({ globalSignaldockPath }, msg);
84246
84339
  result.errors.push({ step: "step-14-global-integrity", error: msg });
84247
84340
  result.status = "failed";
84248
84341
  globalDb.close();
@@ -84257,7 +84350,7 @@ function migrateSignaldockToConduit(projectRoot) {
84257
84350
  }
84258
84351
  } catch (err) {
84259
84352
  const message = err instanceof Error ? err.message : String(err);
84260
- log11.error({ error: message }, "T310 migration: global signaldock.db integrity_check threw");
84353
+ log12.error({ error: message }, "T310 migration: global signaldock.db integrity_check threw");
84261
84354
  result.errors.push({ step: "step-14-global-integrity", error: message });
84262
84355
  result.status = "failed";
84263
84356
  if (globalDb) {
@@ -84276,21 +84369,21 @@ function migrateSignaldockToConduit(projectRoot) {
84276
84369
  result.bakPath = bakPath;
84277
84370
  } catch (err) {
84278
84371
  const message = err instanceof Error ? err.message : String(err);
84279
- log11.error(
84372
+ log12.error(
84280
84373
  { legacyPath, bakPath, error: message },
84281
84374
  "T310 migration: rename to .pre-t310.bak failed \u2014 legacy file left in place (harmless)"
84282
84375
  );
84283
84376
  result.errors.push({ step: "step-16-rename-bak", error: message });
84284
84377
  }
84285
- log11.info(
84378
+ log12.info(
84286
84379
  { projectRoot, agentsCopied: result.agentsCopied, conduitPath, bakPath: result.bakPath },
84287
84380
  `T310 migration complete: ${result.agentsCopied} agents migrated to global, conduit.db created`
84288
84381
  );
84289
- log11.warn(
84382
+ log12.warn(
84290
84383
  {},
84291
84384
  "T310 migration: API keys have been re-keyed. External systems holding old API keys (CI env vars, remote agent configs) must be updated."
84292
84385
  );
84293
- log11.info(
84386
+ log12.info(
84294
84387
  { legacyPath, bakPath: result.bakPath, conduitPath },
84295
84388
  "T310 migration recovery: if problems occur, rename .pre-t310.bak to signaldock.db and delete conduit.db to re-run migration."
84296
84389
  );
@@ -84524,7 +84617,7 @@ async function validateAndRepairSequence(cwd, config2 = {}) {
84524
84617
  }
84525
84618
  const repair = await repairSequence(cwd);
84526
84619
  if (repair.repaired) {
84527
- log9.warn(
84620
+ log10.warn(
84528
84621
  { oldCounter: repair.oldCounter, newCounter: repair.newCounter },
84529
84622
  "Sequence repaired"
84530
84623
  );
@@ -84553,7 +84646,7 @@ async function triggerCheckpoint(context, cwd, config2 = {}) {
84553
84646
  try {
84554
84647
  await gitCheckpoint("auto", context, cwd);
84555
84648
  } catch (err) {
84556
- log9.warn({ err }, "Checkpoint failed (non-fatal)");
84649
+ log10.warn({ err }, "Checkpoint failed (non-fatal)");
84557
84650
  }
84558
84651
  vacuumIntoBackup({ cwd }).catch(() => {
84559
84652
  });
@@ -84591,16 +84684,16 @@ async function safeDeleteTask(deleteFn, taskId, cwd, config2 = {}) {
84591
84684
  return result;
84592
84685
  }
84593
84686
  async function forceCheckpointBeforeOperation(operation, cwd) {
84594
- log9.info({ operation }, "Forcing checkpoint before operation");
84687
+ log10.info({ operation }, "Forcing checkpoint before operation");
84595
84688
  try {
84596
84689
  await gitCheckpoint("manual", `pre-${operation}`, cwd);
84597
84690
  } catch (err) {
84598
- log9.error({ err }, "Failed to create pre-operation checkpoint");
84691
+ log10.error({ err }, "Failed to create pre-operation checkpoint");
84599
84692
  }
84600
84693
  vacuumIntoBackup({ cwd, force: true }).catch(() => {
84601
84694
  });
84602
84695
  }
84603
- var log9, DEFAULT_CONFIG2, SafetyError;
84696
+ var log10, DEFAULT_CONFIG2, SafetyError;
84604
84697
  var init_data_safety = __esm({
84605
84698
  "packages/core/src/store/data-safety.ts"() {
84606
84699
  "use strict";
@@ -84610,7 +84703,7 @@ var init_data_safety = __esm({
84610
84703
  init_sqlite2();
84611
84704
  init_sqlite_backup();
84612
84705
  init_tasks_schema();
84613
- log9 = getLogger("data-safety");
84706
+ log10 = getLogger("data-safety");
84614
84707
  DEFAULT_CONFIG2 = {
84615
84708
  verifyWrites: true,
84616
84709
  detectCollisions: true,
@@ -84653,7 +84746,7 @@ __export(task_store_exports, {
84653
84746
  updateTask: () => updateTask2,
84654
84747
  updateTaskSafe: () => updateTaskSafe
84655
84748
  });
84656
- import { and as and12, asc as asc4, count as count3, eq as eq16, inArray as inArray6, isNull as isNull5, ne as ne4, sql as sql11 } from "drizzle-orm";
84749
+ import { and as and12, asc as asc4, count as count3, eq as eq16, inArray as inArray6, isNull as isNull5, ne as ne4, sql as sql12 } from "drizzle-orm";
84657
84750
  async function insertTaskRow(task, cwd) {
84658
84751
  const db = await getDb(cwd);
84659
84752
  const row = taskToRow(task);
@@ -84756,7 +84849,7 @@ async function findTasks2(query, limit = 20, cwd) {
84756
84849
  const rows = await db.select().from(tasks).where(
84757
84850
  and12(
84758
84851
  ne4(tasks.status, "archived"),
84759
- sql11`(${tasks.id} LIKE ${pattern} OR ${tasks.title} LIKE ${pattern} OR ${tasks.description} LIKE ${pattern})`
84852
+ sql12`(${tasks.id} LIKE ${pattern} OR ${tasks.title} LIKE ${pattern} OR ${tasks.description} LIKE ${pattern})`
84760
84853
  )
84761
84854
  ).limit(limit).all();
84762
84855
  return rows.map(rowToTask);
@@ -85771,11 +85864,11 @@ async function coreTaskHistory(projectRoot, taskId, limit) {
85771
85864
  try {
85772
85865
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
85773
85866
  const { auditLog: auditLog2 } = await Promise.resolve().then(() => (init_tasks_schema(), tasks_schema_exports));
85774
- const { sql: sql12 } = await import("drizzle-orm");
85867
+ const { sql: sql13 } = await import("drizzle-orm");
85775
85868
  const db = await getDb4(projectRoot);
85776
85869
  const maxRows = limit && limit > 0 ? limit : 100;
85777
85870
  const rows = await db.all(
85778
- sql12`SELECT * FROM ${auditLog2}
85871
+ sql13`SELECT * FROM ${auditLog2}
85779
85872
  WHERE ${auditLog2.taskId} = ${taskId}
85780
85873
  ORDER BY ${auditLog2.timestamp} DESC
85781
85874
  LIMIT ${maxRows}`
@@ -86698,10 +86791,10 @@ async function repairMissingSizes(cwd, dryRun) {
86698
86791
  async function repairMissingCompletedAt(cwd, dryRun) {
86699
86792
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
86700
86793
  const { tasks: tasks2 } = await Promise.resolve().then(() => (init_tasks_schema(), tasks_schema_exports));
86701
- const { sql: sql12 } = await import("drizzle-orm");
86794
+ const { sql: sql13 } = await import("drizzle-orm");
86702
86795
  const db = await getDb4(cwd);
86703
86796
  const affected = await db.select({ id: tasks2.id }).from(tasks2).where(
86704
- sql12`(${tasks2.status} = 'done' OR ${tasks2.status} = 'cancelled') AND ${tasks2.completedAt} IS NULL`
86797
+ sql13`(${tasks2.status} = 'done' OR ${tasks2.status} = 'cancelled') AND ${tasks2.completedAt} IS NULL`
86705
86798
  );
86706
86799
  if (affected.length === 0) {
86707
86800
  return {
@@ -86719,7 +86812,7 @@ async function repairMissingCompletedAt(cwd, dryRun) {
86719
86812
  }
86720
86813
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
86721
86814
  await db.update(tasks2).set({ completedAt: now2 }).where(
86722
- sql12`(${tasks2.status} = 'done' OR ${tasks2.status} = 'cancelled') AND ${tasks2.completedAt} IS NULL`
86815
+ sql13`(${tasks2.status} = 'done' OR ${tasks2.status} = 'cancelled') AND ${tasks2.completedAt} IS NULL`
86723
86816
  );
86724
86817
  return {
86725
86818
  action: "fix_completed_at",
@@ -86730,8 +86823,8 @@ async function repairMissingCompletedAt(cwd, dryRun) {
86730
86823
  async function repairMissingColumns(cwd, dryRun) {
86731
86824
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
86732
86825
  const db = await getDb4(cwd);
86733
- const { sql: sql12 } = await import("drizzle-orm");
86734
- const columns = db.all(sql12`PRAGMA table_info(tasks)`);
86826
+ const { sql: sql13 } = await import("drizzle-orm");
86827
+ const columns = db.all(sql13`PRAGMA table_info(tasks)`);
86735
86828
  const existingCols = new Set(columns.map((c) => c.name));
86736
86829
  const missingCols = ["pipeline_stage"].filter((c) => !existingCols.has(c));
86737
86830
  if (missingCols.length === 0) {
@@ -86749,7 +86842,7 @@ async function repairMissingColumns(cwd, dryRun) {
86749
86842
  };
86750
86843
  }
86751
86844
  for (const col of missingCols) {
86752
- db.run(sql12.raw(`ALTER TABLE tasks ADD COLUMN ${col} text`));
86845
+ db.run(sql13.raw(`ALTER TABLE tasks ADD COLUMN ${col} text`));
86753
86846
  }
86754
86847
  return {
86755
86848
  action: "fix_missing_columns",
@@ -94290,11 +94383,11 @@ var require_core = __commonJS({
94290
94383
  Ajv4.ValidationError = validation_error_1.default;
94291
94384
  Ajv4.MissingRefError = ref_error_1.default;
94292
94385
  exports.default = Ajv4;
94293
- function checkOptions(checkOpts, options, msg, log11 = "error") {
94386
+ function checkOptions(checkOpts, options, msg, log12 = "error") {
94294
94387
  for (const key in checkOpts) {
94295
94388
  const opt = key;
94296
94389
  if (opt in options)
94297
- this.logger[log11](`${msg}: option ${key}. ${checkOpts[opt]}`);
94390
+ this.logger[log12](`${msg}: option ${key}. ${checkOpts[opt]}`);
94298
94391
  }
94299
94392
  }
94300
94393
  function getSchEnv(keyRef) {
@@ -104539,6 +104632,7 @@ var init_error = __esm({
104539
104632
  E_ID_COLLISION: 22,
104540
104633
  // Session Errors (30-39)
104541
104634
  E_SESSION_EXISTS: 30,
104635
+ E_SESSION_CONFLICT: 30,
104542
104636
  E_SESSION_NOT_FOUND: 31,
104543
104637
  E_SCOPE_CONFLICT: 32,
104544
104638
  E_SCOPE_INVALID: 33,
@@ -105140,7 +105234,7 @@ async function taskWorkHistory2(projectRoot) {
105140
105234
  }
105141
105235
  async function sessionStart(projectRoot, params) {
105142
105236
  try {
105143
- let accessor = await getAccessor(projectRoot);
105237
+ const accessor = await getAccessor(projectRoot);
105144
105238
  let scope;
105145
105239
  try {
105146
105240
  scope = parseScope2(params.scope);
@@ -105155,8 +105249,14 @@ async function sessionStart(projectRoot, params) {
105155
105249
  }
105156
105250
  const existingActive = await accessor.getActiveSession();
105157
105251
  if (existingActive) {
105158
- await sessionEnd(projectRoot);
105159
- accessor = await getAccessor(projectRoot);
105252
+ return engineError(
105253
+ "E_SESSION_CONFLICT",
105254
+ `An active session already exists (${existingActive.id}). End it first with 'cleo session end'.`,
105255
+ {
105256
+ fix: "Run 'cleo session end' before starting a new session.",
105257
+ details: { activeSessionId: existingActive.id }
105258
+ }
105259
+ );
105160
105260
  }
105161
105261
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
105162
105262
  const sessionId = generateSessionId2();
@@ -105429,7 +105529,16 @@ async function sessionSuspend(projectRoot, sessionId, reason) {
105429
105529
  }
105430
105530
  async function sessionRecordDecision(projectRoot, params) {
105431
105531
  try {
105432
- const result = await recordDecision(projectRoot, params);
105532
+ let resolvedSessionId = params.sessionId;
105533
+ if (!resolvedSessionId) {
105534
+ const accessor = await getAccessor(projectRoot);
105535
+ const activeSession = await accessor.getActiveSession();
105536
+ resolvedSessionId = activeSession?.id ?? "default";
105537
+ }
105538
+ const result = await recordDecision(projectRoot, {
105539
+ ...params,
105540
+ sessionId: resolvedSessionId
105541
+ });
105433
105542
  return { success: true, data: result };
105434
105543
  } catch (err) {
105435
105544
  return cleoErrorToEngineError(err, "E_INVALID_INPUT", "Failed to record decision");
@@ -105931,8 +106040,7 @@ async function orchestrateParallelStart(epicId, wave, projectRoot) {
105931
106040
  const result = await startParallelExecution(epicId, wave, root, accessor);
105932
106041
  return { success: true, data: result };
105933
106042
  } catch (err) {
105934
- const code = err.code ?? "E_GENERAL";
105935
- return engineError(code, err.message);
106043
+ return cleoErrorToEngineError(err, "E_GENERAL", "Failed to start parallel execution");
105936
106044
  }
105937
106045
  }
105938
106046
  async function orchestrateParallelEnd(epicId, wave, projectRoot) {
@@ -105955,8 +106063,7 @@ async function orchestrateParallelEnd(epicId, wave, projectRoot) {
105955
106063
  }
105956
106064
  return { success: true, data: result };
105957
106065
  } catch (err) {
105958
- const code = err.code ?? "E_GENERAL";
105959
- return engineError(code, err.message);
106066
+ return cleoErrorToEngineError(err, "E_GENERAL", "Failed to end parallel execution");
105960
106067
  }
105961
106068
  }
105962
106069
  async function orchestrateHandoff(params, projectRoot) {
@@ -106879,6 +106986,18 @@ async function systemLabels(projectRoot) {
106879
106986
  async function systemArchiveStats(projectRoot, params) {
106880
106987
  try {
106881
106988
  const accessor = await getAccessor(projectRoot);
106989
+ if (params?.report && params.report !== "summary") {
106990
+ const result2 = await analyzeArchive(
106991
+ {
106992
+ report: params.report,
106993
+ since: params.since,
106994
+ until: params.until,
106995
+ cwd: projectRoot
106996
+ },
106997
+ accessor
106998
+ );
106999
+ return { success: true, data: result2 };
107000
+ }
106882
107001
  const result = await getArchiveStats({ period: params?.period, cwd: projectRoot }, accessor);
106883
107002
  return { success: true, data: result };
106884
107003
  } catch (err) {
@@ -106895,10 +107014,10 @@ async function systemLog(projectRoot, filters) {
106895
107014
  }
106896
107015
  async function queryAuditLogSqlite(projectRoot, filters) {
106897
107016
  try {
106898
- const { join: join131 } = await import("node:path");
106899
- const { existsSync: existsSync131 } = await import("node:fs");
106900
- const dbPath = join131(projectRoot, ".cleo", "tasks.db");
106901
- if (!existsSync131(dbPath)) {
107017
+ const { join: join132 } = await import("node:path");
107018
+ const { existsSync: existsSync133 } = await import("node:fs");
107019
+ const dbPath = join132(projectRoot, ".cleo", "tasks.db");
107020
+ if (!existsSync133(dbPath)) {
106902
107021
  const offset = filters?.offset ?? 0;
106903
107022
  const limit = filters?.limit ?? 20;
106904
107023
  return {
@@ -106908,27 +107027,27 @@ async function queryAuditLogSqlite(projectRoot, filters) {
106908
107027
  }
106909
107028
  const { getDb: getDb4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
106910
107029
  const { auditLog: auditLog2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
106911
- const { sql: sql12 } = await import("drizzle-orm");
107030
+ const { sql: sql13 } = await import("drizzle-orm");
106912
107031
  const db = await getDb4(projectRoot);
106913
107032
  try {
106914
107033
  const conditions = [];
106915
107034
  if (filters?.operation) {
106916
107035
  conditions.push(
106917
- sql12`(${auditLog2.action} = ${filters.operation} OR ${auditLog2.operation} = ${filters.operation})`
107036
+ sql13`(${auditLog2.action} = ${filters.operation} OR ${auditLog2.operation} = ${filters.operation})`
106918
107037
  );
106919
107038
  }
106920
107039
  if (filters?.taskId) {
106921
- conditions.push(sql12`${auditLog2.taskId} = ${filters.taskId}`);
107040
+ conditions.push(sql13`${auditLog2.taskId} = ${filters.taskId}`);
106922
107041
  }
106923
107042
  if (filters?.since) {
106924
- conditions.push(sql12`${auditLog2.timestamp} >= ${filters.since}`);
107043
+ conditions.push(sql13`${auditLog2.timestamp} >= ${filters.since}`);
106925
107044
  }
106926
107045
  if (filters?.until) {
106927
- conditions.push(sql12`${auditLog2.timestamp} <= ${filters.until}`);
107046
+ conditions.push(sql13`${auditLog2.timestamp} <= ${filters.until}`);
106928
107047
  }
106929
- const whereClause = conditions.length > 0 ? sql12.join(conditions, sql12` AND `) : sql12`1=1`;
107048
+ const whereClause = conditions.length > 0 ? sql13.join(conditions, sql13` AND `) : sql13`1=1`;
106930
107049
  const countResult = await db.all(
106931
- sql12`SELECT count(*) as cnt FROM ${auditLog2} WHERE ${whereClause}`
107050
+ sql13`SELECT count(*) as cnt FROM ${auditLog2} WHERE ${whereClause}`
106932
107051
  );
106933
107052
  const total = countResult[0]?.cnt ?? 0;
106934
107053
  if (total === 0) {
@@ -106945,7 +107064,7 @@ async function queryAuditLogSqlite(projectRoot, filters) {
106945
107064
  const offset = filters?.offset ?? 0;
106946
107065
  const limit = filters?.limit ?? 20;
106947
107066
  const rows = await db.all(
106948
- sql12`SELECT * FROM ${auditLog2}
107067
+ sql13`SELECT * FROM ${auditLog2}
106949
107068
  WHERE ${whereClause}
106950
107069
  ORDER BY ${auditLog2.timestamp} DESC
106951
107070
  LIMIT ${limit} OFFSET ${offset}`
@@ -108074,7 +108193,7 @@ async function taskTree(projectRoot, taskId) {
108074
108193
  const result = await coreTaskTree(projectRoot, taskId);
108075
108194
  return { success: true, data: result };
108076
108195
  } catch (err) {
108077
- return cleoErrorToEngineError(err, "E_NOT_INITIALIZED", "Task database not initialized");
108196
+ return cleoErrorToEngineError(err, "E_NOT_FOUND", "Task not found");
108078
108197
  }
108079
108198
  }
108080
108199
  async function taskRelates(projectRoot, taskId) {
@@ -108154,7 +108273,7 @@ async function taskCancel(projectRoot, taskId, reason) {
108154
108273
  const result = await coreTaskCancel(projectRoot, taskId, { reason });
108155
108274
  return { success: true, data: result };
108156
108275
  } catch (err) {
108157
- return cleoErrorToEngineError(err, "E_INTERNAL", "Failed to cancel task");
108276
+ return cleoErrorToEngineError(err, "E_NOT_FOUND", "Failed to cancel task");
108158
108277
  }
108159
108278
  }
108160
108279
  async function taskComplexityEstimate(projectRoot, params) {
@@ -108322,10 +108441,10 @@ var init_template_parser2 = __esm({
108322
108441
  });
108323
108442
 
108324
108443
  // packages/cleo/src/dispatch/engines/validate-engine.ts
108325
- function validateSchemaOp(type, data, projectRoot) {
108444
+ async function validateSchemaOp(type, data, projectRoot) {
108326
108445
  try {
108327
108446
  const root = projectRoot || resolveProjectRoot();
108328
- const result = coreValidateSchema(type, data, root);
108447
+ const result = await coreValidateSchema(type, data, root);
108329
108448
  return { success: true, data: result };
108330
108449
  } catch (err) {
108331
108450
  const message = err instanceof Error ? err.message : String(err);
@@ -109087,7 +109206,7 @@ var init_admin2 = __esm({
109087
109206
  "admin",
109088
109207
  operation,
109089
109208
  "E_NOT_AVAILABLE",
109090
- "Job manager not initialized",
109209
+ "Job manager not available. Background jobs require a running CLEO daemon or long-lived process. Start one with `cleo daemon start` or use `cleo admin health` to check system status.",
109091
109210
  startTime
109092
109211
  );
109093
109212
  }
@@ -109130,7 +109249,7 @@ var init_admin2 = __esm({
109130
109249
  "admin",
109131
109250
  operation,
109132
109251
  "E_NOT_AVAILABLE",
109133
- "Job manager not initialized",
109252
+ "Job manager not available. Background jobs require a running CLEO daemon or long-lived process. Start one with `cleo daemon start` or use `cleo admin health` to check system status.",
109134
109253
  startTime
109135
109254
  );
109136
109255
  }
@@ -109588,7 +109707,7 @@ var init_admin2 = __esm({
109588
109707
  "admin",
109589
109708
  operation,
109590
109709
  "E_NOT_AVAILABLE",
109591
- "Job manager not initialized",
109710
+ "Job manager not available. Background jobs require a running CLEO daemon or long-lived process. Start one with `cleo daemon start` or use `cleo admin health` to check system status.",
109592
109711
  startTime
109593
109712
  );
109594
109713
  }
@@ -109651,10 +109770,17 @@ var init_admin2 = __esm({
109651
109770
  };
109652
109771
  }
109653
109772
  const result = await syncAdrsToDb(projectRoot);
109773
+ const hasErrors2 = result.errors.length > 0;
109654
109774
  return {
109655
109775
  meta: dispatchMeta("mutate", "admin", operation, startTime),
109656
- success: true,
109657
- data: result
109776
+ success: !hasErrors2,
109777
+ data: result,
109778
+ ...hasErrors2 ? {
109779
+ error: {
109780
+ code: "E_ADR_SYNC",
109781
+ message: `${result.errors.length} ADR sync error(s) occurred`
109782
+ }
109783
+ } : {}
109658
109784
  };
109659
109785
  }
109660
109786
  // Merged: import + snapshot.import + import.tasks → import via scope param (T5615)
@@ -109988,7 +110114,7 @@ var init_check = __esm({
109988
110114
  startTime
109989
110115
  );
109990
110116
  }
109991
- const result = validateSchemaOp(type, params?.data, projectRoot);
110117
+ const result = await validateSchemaOp(type, params?.data, projectRoot);
109992
110118
  return wrapResult(result, "query", "check", operation, startTime);
109993
110119
  }
109994
110120
  case "task": {
@@ -110032,12 +110158,26 @@ var init_check = __esm({
110032
110158
  case "compliance.summary": {
110033
110159
  const detail = params?.detail;
110034
110160
  const limit = params?.limit;
110161
+ const summaryType = params?.type ?? "summary";
110035
110162
  if (detail) {
110036
110163
  const result2 = validateComplianceViolations(limit, projectRoot);
110037
110164
  return wrapResult(result2, "query", "check", operation, startTime);
110038
110165
  }
110039
110166
  const result = validateComplianceSummary(projectRoot);
110040
- return wrapResult(result, "query", "check", operation, startTime);
110167
+ if (!result.success || !result.data) {
110168
+ return wrapResult(result, "query", "check", operation, startTime);
110169
+ }
110170
+ const enrichedResult = {
110171
+ ...result,
110172
+ data: {
110173
+ ...result.data,
110174
+ view: summaryType,
110175
+ ...params?.taskId ? { taskId: params.taskId } : {},
110176
+ ...params?.days ? { days: params.days } : {},
110177
+ ...params?.global ? { global: params.global } : {}
110178
+ }
110179
+ };
110180
+ return wrapResult(enrichedResult, "query", "check", operation, startTime);
110041
110181
  }
110042
110182
  case "test": {
110043
110183
  const format = params?.format;
@@ -110222,7 +110362,10 @@ var init_check = __esm({
110222
110362
  }
110223
110363
  case "archive.stats": {
110224
110364
  const result = await systemArchiveStats(projectRoot, {
110225
- period: params?.period
110365
+ period: params?.period,
110366
+ report: params?.report,
110367
+ since: params?.since,
110368
+ until: params?.until
110226
110369
  });
110227
110370
  return wrapResult(result, "query", "check", operation, startTime);
110228
110371
  }
@@ -111267,7 +111410,7 @@ async function nexusUnregisterProject(name2) {
111267
111410
  await nexusUnregister(name2);
111268
111411
  return engineSuccess({ message: `Project unregistered: ${name2}` });
111269
111412
  } catch (error48) {
111270
- return engineError("E_INTERNAL", error48 instanceof Error ? error48.message : String(error48));
111413
+ return cleoErrorToEngineError(error48, "E_INTERNAL", `Failed to unregister project: ${name2}`);
111271
111414
  }
111272
111415
  }
111273
111416
  async function nexusSyncProject(name2) {
@@ -111741,16 +111884,16 @@ var init_nexus2 = __esm({
111741
111884
  async function orchestrateClassify(request, context, projectRoot) {
111742
111885
  try {
111743
111886
  const { getCleoCantWorkflowsDir: getCleoCantWorkflowsDir2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
111744
- const { readFileSync: readFileSync102, readdirSync: readdirSync42, existsSync: existsSync131 } = await import("node:fs");
111745
- const { join: join131 } = await import("node:path");
111887
+ const { readFileSync: readFileSync102, readdirSync: readdirSync42, existsSync: existsSync133 } = await import("node:fs");
111888
+ const { join: join132 } = await import("node:path");
111746
111889
  const workflowsDir = getCleoCantWorkflowsDir2();
111747
111890
  const combined = `${request} ${context ?? ""}`.toLowerCase();
111748
111891
  const matches = [];
111749
- if (existsSync131(workflowsDir)) {
111892
+ if (existsSync133(workflowsDir)) {
111750
111893
  const files = readdirSync42(workflowsDir).filter((f2) => f2.endsWith(".cant"));
111751
111894
  for (const file2 of files) {
111752
111895
  try {
111753
- const src = readFileSync102(join131(workflowsDir, file2), "utf-8");
111896
+ const src = readFileSync102(join132(workflowsDir, file2), "utf-8");
111754
111897
  const teamMatch = /^team\s+(\S+):/m.exec(src);
111755
111898
  if (!teamMatch) continue;
111756
111899
  const teamName = teamMatch[1];
@@ -111765,12 +111908,12 @@ async function orchestrateClassify(request, context, projectRoot) {
111765
111908
  }
111766
111909
  }
111767
111910
  }
111768
- const localCantDir = join131(projectRoot, ".cleo", "workflows");
111769
- if (existsSync131(localCantDir)) {
111911
+ const localCantDir = join132(projectRoot, ".cleo", "workflows");
111912
+ if (existsSync133(localCantDir)) {
111770
111913
  const files = readdirSync42(localCantDir).filter((f2) => f2.endsWith(".cant"));
111771
111914
  for (const file2 of files) {
111772
111915
  try {
111773
- const src = readFileSync102(join131(localCantDir, file2), "utf-8");
111916
+ const src = readFileSync102(join132(localCantDir, file2), "utf-8");
111774
111917
  const teamMatch = /^team\s+(\S+):/m.exec(src);
111775
111918
  if (!teamMatch) continue;
111776
111919
  const teamName = teamMatch[1];
@@ -113828,17 +113971,19 @@ var init_sticky2 = __esm({
113828
113971
  try {
113829
113972
  switch (operation) {
113830
113973
  case "list": {
113974
+ const tags = params?.tags;
113831
113975
  const filters = {
113832
113976
  status: params?.status,
113833
113977
  color: params?.color,
113834
- priority: params?.priority
113978
+ priority: params?.priority,
113979
+ tags
113835
113980
  };
113836
113981
  const result = await stickyList(projectRoot, filters);
113837
113982
  if (!result.success) {
113838
113983
  return wrapResult(result, "query", "sticky", operation, startTime);
113839
113984
  }
113840
113985
  const filteredStickies = result.data?.stickies ?? [];
113841
- const hasFilter = filters.status !== void 0 || filters.color !== void 0 || filters.priority !== void 0;
113986
+ const hasFilter = filters.status !== void 0 || filters.color !== void 0 || filters.priority !== void 0 || tags !== void 0 && tags.length > 0;
113842
113987
  const totalResult = hasFilter ? await stickyList(projectRoot, {}) : result;
113843
113988
  if (!totalResult.success) {
113844
113989
  return wrapResult(totalResult, "query", "sticky", operation, startTime);
@@ -114604,6 +114749,9 @@ async function toolsSkillFind(query) {
114604
114749
  }
114605
114750
  function toolsSkillDispatch(name2) {
114606
114751
  try {
114752
+ if (!catalog3.isCatalogAvailable()) {
114753
+ return engineError("E_CONFIG_ERROR", CATALOG_UNAVAILABLE_MSG, CATALOG_UNAVAILABLE_OPTS);
114754
+ }
114607
114755
  const matrix = catalog3.getDispatchMatrix();
114608
114756
  const entry = {
114609
114757
  byTaskType: Object.entries(matrix.by_task_type).filter(([, skill]) => skill === name2).map(([k2]) => k2),
@@ -114617,6 +114765,9 @@ function toolsSkillDispatch(name2) {
114617
114765
  }
114618
114766
  async function toolsSkillVerify(name2) {
114619
114767
  try {
114768
+ if (!catalog3.isCatalogAvailable()) {
114769
+ return engineError("E_CONFIG_ERROR", CATALOG_UNAVAILABLE_MSG, CATALOG_UNAVAILABLE_OPTS);
114770
+ }
114620
114771
  const installed = await discoverSkill2(`${getCanonicalSkillsDir4()}/${name2}`);
114621
114772
  const catalogEntry = catalog3.getSkill(name2);
114622
114773
  return engineSuccess({
@@ -114631,6 +114782,9 @@ async function toolsSkillVerify(name2) {
114631
114782
  }
114632
114783
  function toolsSkillDependencies(name2) {
114633
114784
  try {
114785
+ if (!catalog3.isCatalogAvailable()) {
114786
+ return engineError("E_CONFIG_ERROR", CATALOG_UNAVAILABLE_MSG, CATALOG_UNAVAILABLE_OPTS);
114787
+ }
114634
114788
  const direct = catalog3.getSkillDependencies(name2);
114635
114789
  const tree = catalog3.resolveDependencyTree([name2]);
114636
114790
  return engineSuccess({ skill: name2, direct, tree });
@@ -115003,6 +115157,9 @@ async function toolsAdapterActivate(projectRoot, id) {
115003
115157
  if (!manager.getManifest(id)) {
115004
115158
  manager.discover();
115005
115159
  }
115160
+ if (!manager.getManifest(id)) {
115161
+ return engineError("E_NOT_FOUND", `Adapter not found: ${id}`);
115162
+ }
115006
115163
  const adapter = await manager.activate(id);
115007
115164
  return engineSuccess({
115008
115165
  id,
@@ -115027,11 +115184,20 @@ async function toolsAdapterDispose(projectRoot, id) {
115027
115184
  return engineError("E_INTERNAL", error48 instanceof Error ? error48.message : String(error48));
115028
115185
  }
115029
115186
  }
115187
+ var CATALOG_UNAVAILABLE_MSG, CATALOG_UNAVAILABLE_OPTS;
115030
115188
  var init_tools_engine = __esm({
115031
115189
  "packages/cleo/src/dispatch/engines/tools-engine.ts"() {
115032
115190
  "use strict";
115033
115191
  init_internal();
115034
115192
  init_error();
115193
+ CATALOG_UNAVAILABLE_MSG = "Skill catalog not available. The CAAMP skill library could not be loaded. Run `cleo init` to set up the skill library, or set CAAMP_SKILL_LIBRARY env var.";
115194
+ CATALOG_UNAVAILABLE_OPTS = {
115195
+ fix: "cleo init",
115196
+ alternatives: [
115197
+ { action: "Set env var", command: "export CAAMP_SKILL_LIBRARY=/path/to/skills" },
115198
+ { action: "Use filesystem-based commands", command: "cleo skills list" }
115199
+ ]
115200
+ };
115035
115201
  }
115036
115202
  });
115037
115203
 
@@ -115887,7 +116053,7 @@ async function writeToSqlite(entry, requestId) {
115887
116053
  };
115888
116054
  const parsed = AuditLogInsertSchema2.safeParse(payload);
115889
116055
  if (!parsed.success) {
115890
- log10.warn(
116056
+ log11.warn(
115891
116057
  { issues: parsed.error.issues },
115892
116058
  "Audit payload failed Zod validation; skipping insert"
115893
116059
  );
@@ -115896,7 +116062,7 @@ async function writeToSqlite(entry, requestId) {
115896
116062
  const db = await getDb4(process.cwd());
115897
116063
  await db.insert(auditLog2).values(parsed.data).run();
115898
116064
  } catch (err) {
115899
- log10.warn({ err }, "Failed to write audit entry to SQLite");
116065
+ log11.warn({ err }, "Failed to write audit entry to SQLite");
115900
116066
  }
115901
116067
  }
115902
116068
  function createAudit() {
@@ -115927,7 +116093,7 @@ function createAudit() {
115927
116093
  },
115928
116094
  error: response.error?.message
115929
116095
  };
115930
- log10.info(
116096
+ log11.info(
115931
116097
  {
115932
116098
  domain: entry.domain,
115933
116099
  operation: entry.operation,
@@ -115944,20 +116110,20 @@ function createAudit() {
115944
116110
  await writeToSqlite(entry, req.requestId);
115945
116111
  } else {
115946
116112
  writeToSqlite(entry, req.requestId).catch((err) => {
115947
- log10.error({ err }, "Failed to persist audit entry to SQLite");
116113
+ log11.error({ err }, "Failed to persist audit entry to SQLite");
115948
116114
  });
115949
116115
  }
115950
116116
  return response;
115951
116117
  };
115952
116118
  }
115953
- var log10, cachedProjectHash;
116119
+ var log11, cachedProjectHash;
115954
116120
  var init_audit3 = __esm({
115955
116121
  "packages/cleo/src/dispatch/middleware/audit.ts"() {
115956
116122
  "use strict";
115957
116123
  init_internal();
115958
116124
  init_config3();
115959
116125
  init_internal();
115960
- log10 = getLogger("audit");
116126
+ log11 = getLogger("audit");
115961
116127
  }
115962
116128
  });
115963
116129
 
@@ -116108,6 +116274,38 @@ __export(cli_exports, {
116108
116274
  resetCliDispatcher: () => resetCliDispatcher
116109
116275
  });
116110
116276
  import { randomUUID as randomUUID13 } from "node:crypto";
116277
+ import { existsSync as existsSync128 } from "node:fs";
116278
+ import { createRequire as createRequire13 } from "node:module";
116279
+ import { dirname as dirname25, join as join124 } from "node:path";
116280
+ import { fileURLToPath as fileURLToPath5 } from "node:url";
116281
+ import { catalog as catalog4, registerSkillLibraryFromPath } from "@cleocode/caamp";
116282
+ function ensureCaampLibrary() {
116283
+ if (catalog4.isCatalogAvailable()) return;
116284
+ try {
116285
+ let skillsRoot = null;
116286
+ try {
116287
+ const req = createRequire13(import.meta.url);
116288
+ const skillsPkgJson = req.resolve("@cleocode/skills/package.json");
116289
+ const candidate = dirname25(skillsPkgJson);
116290
+ if (existsSync128(join124(candidate, "skills.json"))) {
116291
+ skillsRoot = candidate;
116292
+ }
116293
+ } catch {
116294
+ }
116295
+ if (!skillsRoot) {
116296
+ const thisFile = fileURLToPath5(import.meta.url);
116297
+ const packageRoot = join124(dirname25(thisFile), "..", "..", "..", "..", "..");
116298
+ const candidate = join124(packageRoot, "packages", "skills");
116299
+ if (existsSync128(join124(candidate, "skills.json"))) {
116300
+ skillsRoot = candidate;
116301
+ }
116302
+ }
116303
+ if (skillsRoot) {
116304
+ registerSkillLibraryFromPath(skillsRoot);
116305
+ }
116306
+ } catch {
116307
+ }
116308
+ }
116111
116309
  function getCliDispatcher() {
116112
116310
  if (!_dispatcher) {
116113
116311
  _dispatcher = createCliDispatcher();
@@ -116124,6 +116322,7 @@ async function lookupCliSession() {
116124
116322
  }
116125
116323
  }
116126
116324
  function createCliDispatcher() {
116325
+ ensureCaampLibrary();
116127
116326
  const handlers = createDomainHandlers();
116128
116327
  return new Dispatcher({
116129
116328
  handlers,
@@ -116316,8 +116515,8 @@ var init_cli = __esm({
116316
116515
  // packages/cleo/src/cli/index.ts
116317
116516
  init_internal();
116318
116517
  import { readFileSync as readFileSync101 } from "node:fs";
116319
- import { dirname as dirname28, join as join130 } from "node:path";
116320
- import { fileURLToPath as fileURLToPath5 } from "node:url";
116518
+ import { dirname as dirname29, join as join131 } from "node:path";
116519
+ import { fileURLToPath as fileURLToPath6 } from "node:url";
116321
116520
 
116322
116521
  // node_modules/.pnpm/citty@0.2.1/node_modules/citty/dist/_chunks/libs/scule.mjs
116323
116522
  var NUMBER_CHAR_RE = /\d/;
@@ -116912,7 +117111,7 @@ var COMMAND_GROUPS = [
116912
117111
  },
116913
117112
  {
116914
117113
  name: "Memory & Notes",
116915
- commands: ["memory", "brain", "observe", "refresh-memory", "sticky", "reason"]
117114
+ commands: ["memory", "brain", "refresh-memory", "sticky", "reason"]
116916
117115
  },
116917
117116
  {
116918
117117
  name: "Analysis & Stats",
@@ -117473,7 +117672,7 @@ function registerAddCommand(program) {
117473
117672
  // packages/cleo/src/cli/commands/add-batch.ts
117474
117673
  init_cli();
117475
117674
  init_renderers();
117476
- import { readFileSync as readFileSync95 } from "node:fs";
117675
+ import { existsSync as existsSync129, readFileSync as readFileSync95 } from "node:fs";
117477
117676
  function registerAddBatchCommand(program) {
117478
117677
  program.command("add-batch").description("Create multiple tasks atomically from a JSON file").option("--file <path>", "Path to JSON file (array of task objects). Use - for stdin.").option("--parent <parentId>", "Default parent for all tasks (overridden by per-task parent)").option("--dry-run", "Preview what would be created without making changes").action(async (opts) => {
117479
117678
  const filePath = opts["file"];
@@ -117486,7 +117685,33 @@ function registerAddBatchCommand(program) {
117486
117685
  chunks.push(chunk);
117487
117686
  }
117488
117687
  raw = Buffer.concat(chunks).toString("utf-8");
117688
+ if (!raw.trim()) {
117689
+ cliError(
117690
+ "No input provided. Pass --file <path> or pipe JSON to stdin.",
117691
+ "E_VALIDATION",
117692
+ {
117693
+ name: "E_VALIDATION",
117694
+ fix: "cleo add-batch --file tasks.json"
117695
+ },
117696
+ { operation: "tasks.add-batch" }
117697
+ );
117698
+ process.exit(2);
117699
+ return;
117700
+ }
117489
117701
  } else {
117702
+ if (!existsSync129(filePath)) {
117703
+ cliError(
117704
+ `File not found: ${filePath}`,
117705
+ "E_NOT_FOUND",
117706
+ {
117707
+ name: "E_NOT_FOUND",
117708
+ fix: `Verify the file path exists: ${filePath}`
117709
+ },
117710
+ { operation: "tasks.add-batch" }
117711
+ );
117712
+ process.exit(2);
117713
+ return;
117714
+ }
117490
117715
  raw = readFileSync95(filePath, "utf-8");
117491
117716
  }
117492
117717
  let tasks2;
@@ -117494,12 +117719,28 @@ function registerAddBatchCommand(program) {
117494
117719
  const parsed = JSON.parse(raw);
117495
117720
  tasks2 = Array.isArray(parsed) ? parsed : [parsed];
117496
117721
  } catch {
117497
- process.stderr.write("Error: Invalid JSON input. Expected an array of task objects.\n");
117722
+ cliError(
117723
+ "Invalid JSON input. Expected an array of task objects.",
117724
+ "E_VALIDATION",
117725
+ {
117726
+ name: "E_VALIDATION",
117727
+ fix: "Ensure the input is a valid JSON array of task objects"
117728
+ },
117729
+ { operation: "tasks.add-batch" }
117730
+ );
117498
117731
  process.exit(2);
117499
117732
  return;
117500
117733
  }
117501
117734
  if (tasks2.length === 0) {
117502
- process.stderr.write("Error: No tasks in input.\n");
117735
+ cliError(
117736
+ "No tasks in input.",
117737
+ "E_VALIDATION",
117738
+ {
117739
+ name: "E_VALIDATION",
117740
+ fix: "Provide at least one task object in the JSON array"
117741
+ },
117742
+ { operation: "tasks.add-batch" }
117743
+ );
117503
117744
  process.exit(2);
117504
117745
  return;
117505
117746
  }
@@ -117776,12 +118017,12 @@ function registerAgentCommand(program) {
117776
118017
  transportConfig: {},
117777
118018
  isActive: true
117778
118019
  });
117779
- const { existsSync: existsSync131, mkdirSync: mkdirSync31, writeFileSync: writeFileSync24 } = await import("node:fs");
117780
- const { join: join131 } = await import("node:path");
117781
- const cantDir = join131(".cleo", "agents");
117782
- const cantPath = join131(cantDir, `${agentId}.cant`);
118020
+ const { existsSync: existsSync133, mkdirSync: mkdirSync31, writeFileSync: writeFileSync24 } = await import("node:fs");
118021
+ const { join: join132 } = await import("node:path");
118022
+ const cantDir = join132(".cleo", "agents");
118023
+ const cantPath = join132(cantDir, `${agentId}.cant`);
117783
118024
  let cantScaffolded = false;
117784
- if (!existsSync131(cantPath)) {
118025
+ if (!existsSync133(cantPath)) {
117785
118026
  mkdirSync31(cantDir, { recursive: true });
117786
118027
  const role = classification ?? "specialist";
117787
118028
  const cantContent = `---
@@ -117841,7 +118082,7 @@ agent ${agentId}:
117841
118082
  data: {
117842
118083
  agentId: credential.agentId,
117843
118084
  displayName: credential.displayName,
117844
- cantFile: cantScaffolded ? cantPath : existsSync131(cantPath) ? cantPath : null,
118085
+ cantFile: cantScaffolded ? cantPath : existsSync133(cantPath) ? cantPath : null,
117845
118086
  cantScaffolded
117846
118087
  }
117847
118088
  },
@@ -117921,8 +118162,8 @@ agent ${agentId}:
117921
118162
  try {
117922
118163
  const { AgentRegistryAccessor: AgentRegistryAccessor2, getDb: getDb4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
117923
118164
  const { createRuntime } = await import("@cleocode/runtime");
117924
- const { existsSync: existsSync131, readFileSync: readFileSync102 } = await import("node:fs");
117925
- const { join: join131 } = await import("node:path");
118165
+ const { existsSync: existsSync133, readFileSync: readFileSync102 } = await import("node:fs");
118166
+ const { join: join132 } = await import("node:path");
117926
118167
  await getDb4();
117927
118168
  const registry2 = new AgentRegistryAccessor2(process.cwd());
117928
118169
  const credential = await registry2.get(agentId);
@@ -117942,8 +118183,8 @@ agent ${agentId}:
117942
118183
  }
117943
118184
  let profile = null;
117944
118185
  let cantValidation = null;
117945
- const cantPath = opts["cant"] ?? join131(".cleo", "agents", `${agentId}.cant`);
117946
- if (existsSync131(cantPath)) {
118186
+ const cantPath = opts["cant"] ?? join132(".cleo", "agents", `${agentId}.cant`);
118187
+ if (existsSync133(cantPath)) {
117947
118188
  profile = readFileSync102(cantPath, "utf-8");
117948
118189
  try {
117949
118190
  const cantModule = await import("@cleocode/cant");
@@ -118339,8 +118580,8 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
118339
118580
  try {
118340
118581
  const { AgentRegistryAccessor: AgentRegistryAccessor2, getDb: getDb4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
118341
118582
  const { createRuntime } = await import("@cleocode/runtime");
118342
- const { existsSync: existsSync131 } = await import("node:fs");
118343
- const { join: join131 } = await import("node:path");
118583
+ const { existsSync: existsSync133 } = await import("node:fs");
118584
+ const { join: join132 } = await import("node:path");
118344
118585
  const { execFile: execFile9 } = await import("node:child_process");
118345
118586
  const { promisify: promisify9 } = await import("node:util");
118346
118587
  const execFileAsync6 = promisify9(execFile9);
@@ -118360,8 +118601,8 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
118360
118601
  }
118361
118602
  await registry2.update(agentId, { isActive: true });
118362
118603
  await registry2.markUsed(agentId);
118363
- const cantPath = join131(".cleo", "agents", `${agentId}.cant`);
118364
- const hasProfile = existsSync131(cantPath);
118604
+ const cantPath = join132(".cleo", "agents", `${agentId}.cant`);
118605
+ const hasProfile = existsSync133(cantPath);
118365
118606
  const runtime = await createRuntime(registry2, {
118366
118607
  agentId,
118367
118608
  pollIntervalMs: 5e3,
@@ -118984,12 +119225,12 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
118984
119225
  });
118985
119226
  agent.command("install <path>").description("Install an agent from a .cantz archive or agent directory").option("--global", "Install to global tier (~/.local/share/cleo/cant/agents/)").action(async (sourcePath, opts) => {
118986
119227
  try {
118987
- const { existsSync: existsSync131, mkdirSync: mkdirSync31, cpSync, readFileSync: readFileSync102, rmSync: rmSync3, statSync: statSync22 } = await import("node:fs");
118988
- const { join: join131, basename: basename19, resolve: resolve16 } = await import("node:path");
119228
+ const { existsSync: existsSync133, mkdirSync: mkdirSync31, cpSync, readFileSync: readFileSync102, rmSync: rmSync3, statSync: statSync22 } = await import("node:fs");
119229
+ const { join: join132, basename: basename19, resolve: resolve16 } = await import("node:path");
118989
119230
  const { homedir: homedir7 } = await import("node:os");
118990
119231
  const { tmpdir: tmpdir3 } = await import("node:os");
118991
119232
  const resolvedPath = resolve16(sourcePath);
118992
- if (!existsSync131(resolvedPath)) {
119233
+ if (!existsSync133(resolvedPath)) {
118993
119234
  cliOutput(
118994
119235
  {
118995
119236
  success: false,
@@ -119009,7 +119250,7 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119009
119250
  const isCantzArchive = resolvedPath.endsWith(".cantz") && statSync22(resolvedPath).isFile();
119010
119251
  if (isCantzArchive) {
119011
119252
  const { execFileSync: execFileSync19 } = await import("node:child_process");
119012
- tempDir = join131(tmpdir3(), `cleo-agent-install-${Date.now()}`);
119253
+ tempDir = join132(tmpdir3(), `cleo-agent-install-${Date.now()}`);
119013
119254
  mkdirSync31(tempDir, { recursive: true });
119014
119255
  try {
119015
119256
  execFileSync19("unzip", ["-o", "-q", resolvedPath, "-d", tempDir], {
@@ -119033,7 +119274,7 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119033
119274
  }
119034
119275
  const { readdirSync: readdirSync42 } = await import("node:fs");
119035
119276
  const topLevel = readdirSync42(tempDir).filter((entry) => {
119036
- const entryPath = join131(tempDir, entry);
119277
+ const entryPath = join132(tempDir, entry);
119037
119278
  return statSync22(entryPath).isDirectory();
119038
119279
  });
119039
119280
  if (topLevel.length !== 1) {
@@ -119052,7 +119293,7 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119052
119293
  return;
119053
119294
  }
119054
119295
  agentName = topLevel[0];
119055
- agentDir = join131(tempDir, agentName);
119296
+ agentDir = join132(tempDir, agentName);
119056
119297
  } else if (statSync22(resolvedPath).isDirectory()) {
119057
119298
  agentDir = resolvedPath;
119058
119299
  agentName = basename19(resolvedPath);
@@ -119070,8 +119311,8 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119070
119311
  process.exitCode = 6;
119071
119312
  return;
119072
119313
  }
119073
- const personaPath = join131(agentDir, "persona.cant");
119074
- if (!existsSync131(personaPath)) {
119314
+ const personaPath = join132(agentDir, "persona.cant");
119315
+ if (!existsSync133(personaPath)) {
119075
119316
  if (tempDir) rmSync3(tempDir, { recursive: true, force: true });
119076
119317
  cliOutput(
119077
119318
  {
@@ -119090,12 +119331,12 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119090
119331
  let targetRoot;
119091
119332
  if (isGlobal) {
119092
119333
  const home = homedir7();
119093
- const xdgData = process.env["XDG_DATA_HOME"] ?? join131(home, ".local", "share");
119094
- targetRoot = join131(xdgData, "cleo", "cant", "agents");
119334
+ const xdgData = process.env["XDG_DATA_HOME"] ?? join132(home, ".local", "share");
119335
+ targetRoot = join132(xdgData, "cleo", "cant", "agents");
119095
119336
  } else {
119096
- targetRoot = join131(process.cwd(), ".cleo", "cant", "agents");
119337
+ targetRoot = join132(process.cwd(), ".cleo", "cant", "agents");
119097
119338
  }
119098
- const targetDir = join131(targetRoot, agentName);
119339
+ const targetDir = join132(targetRoot, agentName);
119099
119340
  mkdirSync31(targetRoot, { recursive: true });
119100
119341
  cpSync(agentDir, targetDir, { recursive: true, force: true });
119101
119342
  if (tempDir) {
@@ -119103,7 +119344,7 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119103
119344
  }
119104
119345
  let registered = false;
119105
119346
  try {
119106
- const persona = readFileSync102(join131(targetDir, "persona.cant"), "utf-8");
119347
+ const persona = readFileSync102(join132(targetDir, "persona.cant"), "utf-8");
119107
119348
  const descMatch = persona.match(/description:\s*"([^"]+)"/);
119108
119349
  const displayName = descMatch?.[1] ?? agentName;
119109
119350
  const { AgentRegistryAccessor: AgentRegistryAccessor2, getDb: getDb4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
@@ -119150,11 +119391,11 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119150
119391
  });
119151
119392
  agent.command("pack <dir>").description("Package an agent directory as a .cantz archive").action(async (dir) => {
119152
119393
  try {
119153
- const { existsSync: existsSync131, statSync: statSync22 } = await import("node:fs");
119154
- const { resolve: resolve16, basename: basename19, dirname: dirname29 } = await import("node:path");
119394
+ const { existsSync: existsSync133, statSync: statSync22 } = await import("node:fs");
119395
+ const { resolve: resolve16, basename: basename19, dirname: dirname30 } = await import("node:path");
119155
119396
  const { execFileSync: execFileSync19 } = await import("node:child_process");
119156
119397
  const resolvedDir = resolve16(dir);
119157
- if (!existsSync131(resolvedDir) || !statSync22(resolvedDir).isDirectory()) {
119398
+ if (!existsSync133(resolvedDir) || !statSync22(resolvedDir).isDirectory()) {
119158
119399
  cliOutput(
119159
119400
  {
119160
119401
  success: false,
@@ -119168,9 +119409,9 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119168
119409
  process.exitCode = 4;
119169
119410
  return;
119170
119411
  }
119171
- const { join: join131 } = await import("node:path");
119172
- const personaPath = join131(resolvedDir, "persona.cant");
119173
- if (!existsSync131(personaPath)) {
119412
+ const { join: join132 } = await import("node:path");
119413
+ const personaPath = join132(resolvedDir, "persona.cant");
119414
+ if (!existsSync133(personaPath)) {
119174
119415
  cliOutput(
119175
119416
  {
119176
119417
  success: false,
@@ -119187,7 +119428,7 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119187
119428
  const agentName = basename19(resolvedDir);
119188
119429
  const archiveName = `${agentName}.cantz`;
119189
119430
  const archivePath = resolve16(archiveName);
119190
- const parentDir = dirname29(resolvedDir);
119431
+ const parentDir = dirname30(resolvedDir);
119191
119432
  try {
119192
119433
  execFileSync19("zip", ["-r", archivePath, agentName], {
119193
119434
  cwd: parentDir,
@@ -119217,7 +119458,7 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119217
119458
  if (entry.isFile()) {
119218
119459
  fileCount++;
119219
119460
  } else if (entry.isDirectory()) {
119220
- countFiles2(join131(dirPath, entry.name));
119461
+ countFiles2(join132(dirPath, entry.name));
119221
119462
  }
119222
119463
  }
119223
119464
  };
@@ -119244,8 +119485,8 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119244
119485
  });
119245
119486
  agent.command("create").description("Scaffold a new agent package with persona.cant and manifest.json").requiredOption("--name <name>", "Agent name (kebab-case)").requiredOption("--role <role>", "Agent role: orchestrator, lead, worker, or docs-worker").option("--tier <tier>", "Agent tier: low, mid, or high (defaults based on role)").option("--team <teamName>", "Team this agent belongs to").option("--domain <description>", "Domain description for file permissions and context").option("--global", "Create in global tier (~/.local/share/cleo/cant/agents/)").option("--seed-brain", "Create expertise/mental-model-seed.md and seed a BRAIN observation").option("--parent <parentAgent>", "Parent agent name in the hierarchy").action(async (opts) => {
119246
119487
  try {
119247
- const { existsSync: existsSync131, mkdirSync: mkdirSync31, writeFileSync: writeFileSync24 } = await import("node:fs");
119248
- const { join: join131 } = await import("node:path");
119488
+ const { existsSync: existsSync133, mkdirSync: mkdirSync31, writeFileSync: writeFileSync24 } = await import("node:fs");
119489
+ const { join: join132 } = await import("node:path");
119249
119490
  const { homedir: homedir7 } = await import("node:os");
119250
119491
  const name2 = opts["name"];
119251
119492
  const role = opts["role"];
@@ -119305,13 +119546,13 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119305
119546
  let targetRoot;
119306
119547
  if (isGlobal) {
119307
119548
  const home = homedir7();
119308
- const xdgData = process.env["XDG_DATA_HOME"] ?? join131(home, ".local", "share");
119309
- targetRoot = join131(xdgData, "cleo", "cant", "agents");
119549
+ const xdgData = process.env["XDG_DATA_HOME"] ?? join132(home, ".local", "share");
119550
+ targetRoot = join132(xdgData, "cleo", "cant", "agents");
119310
119551
  } else {
119311
- targetRoot = join131(process.cwd(), ".cleo", "cant", "agents");
119552
+ targetRoot = join132(process.cwd(), ".cleo", "cant", "agents");
119312
119553
  }
119313
- const agentDir = join131(targetRoot, name2);
119314
- if (existsSync131(agentDir)) {
119554
+ const agentDir = join132(targetRoot, name2);
119555
+ if (existsSync133(agentDir)) {
119315
119556
  cliOutput(
119316
119557
  {
119317
119558
  success: false,
@@ -119335,29 +119576,29 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119335
119576
  domain: domain2,
119336
119577
  parent
119337
119578
  });
119338
- writeFileSync24(join131(agentDir, "persona.cant"), personaContent, "utf-8");
119579
+ writeFileSync24(join132(agentDir, "persona.cant"), personaContent, "utf-8");
119339
119580
  const manifest = generateManifest2({ name: name2, role, tier, domain: domain2 });
119340
119581
  writeFileSync24(
119341
- join131(agentDir, "manifest.json"),
119582
+ join132(agentDir, "manifest.json"),
119342
119583
  `${JSON.stringify(manifest, null, 2)}
119343
119584
  `,
119344
119585
  "utf-8"
119345
119586
  );
119346
119587
  const createdFiles = [
119347
- join131(agentDir, "persona.cant"),
119348
- join131(agentDir, "manifest.json")
119588
+ join132(agentDir, "persona.cant"),
119589
+ join132(agentDir, "manifest.json")
119349
119590
  ];
119350
119591
  if (team) {
119351
119592
  const teamConfigContent = generateTeamConfig(name2, role, team);
119352
- writeFileSync24(join131(agentDir, "team-config.cant"), teamConfigContent, "utf-8");
119353
- createdFiles.push(join131(agentDir, "team-config.cant"));
119593
+ writeFileSync24(join132(agentDir, "team-config.cant"), teamConfigContent, "utf-8");
119594
+ createdFiles.push(join132(agentDir, "team-config.cant"));
119354
119595
  }
119355
119596
  if (seedBrain) {
119356
- const expertiseDir = join131(agentDir, "expertise");
119597
+ const expertiseDir = join132(agentDir, "expertise");
119357
119598
  mkdirSync31(expertiseDir, { recursive: true });
119358
119599
  const seedContent = generateMentalModelSeed(name2, role, domain2);
119359
- writeFileSync24(join131(expertiseDir, "mental-model-seed.md"), seedContent, "utf-8");
119360
- createdFiles.push(join131(expertiseDir, "mental-model-seed.md"));
119600
+ writeFileSync24(join132(expertiseDir, "mental-model-seed.md"), seedContent, "utf-8");
119601
+ createdFiles.push(join132(expertiseDir, "mental-model-seed.md"));
119361
119602
  try {
119362
119603
  const { execFile: execFile9 } = await import("node:child_process");
119363
119604
  const { promisify: promisify9 } = await import("node:util");
@@ -119813,6 +120054,7 @@ function registerArchiveStatsCommand(program) {
119813
120054
 
119814
120055
  // packages/cleo/src/cli/commands/backfill.ts
119815
120056
  init_internal();
120057
+ init_renderers();
119816
120058
  function registerBackfillCommand(program) {
119817
120059
  program.command("backfill").description(
119818
120060
  "Retroactively add acceptance criteria and verification metadata to existing tasks"
@@ -119847,17 +120089,35 @@ function registerBackfillCommand(program) {
119847
120089
  process.stdout.write("\n");
119848
120090
  }
119849
120091
  if (result.processed === 0 && result.skipped === 0 && result.errors === 0) {
119850
- console.log(
119851
- "No observations to embed (provider unavailable or nothing to backfill)."
120092
+ cliOutput(
120093
+ {
120094
+ processed: 0,
120095
+ skipped: 0,
120096
+ errors: 0,
120097
+ message: "No observations to embed (provider unavailable or nothing to backfill)."
120098
+ },
120099
+ { command: "backfill", operation: "admin.backfill", message: "Nothing to embed" }
119852
120100
  );
119853
120101
  return;
119854
120102
  }
119855
- console.log(
119856
- `Processed ${result.processed}, skipped ${result.skipped}, errors ${result.errors}`
120103
+ cliOutput(
120104
+ { processed: result.processed, skipped: result.skipped, errors: result.errors },
120105
+ {
120106
+ command: "backfill",
120107
+ operation: "admin.backfill",
120108
+ message: `Processed ${result.processed}, skipped ${result.skipped}, errors ${result.errors}`
120109
+ }
119857
120110
  );
119858
120111
  } catch (err) {
119859
120112
  const message = err instanceof Error ? err.message : String(err);
119860
- console.error(`Embedding backfill failed: ${message}`);
120113
+ cliError(
120114
+ `Embedding backfill failed: ${message}`,
120115
+ "E_INTERNAL",
120116
+ {
120117
+ name: "E_INTERNAL"
120118
+ },
120119
+ { operation: "admin.backfill" }
120120
+ );
119861
120121
  process.exit(1);
119862
120122
  }
119863
120123
  return;
@@ -119866,55 +120126,40 @@ function registerBackfillCommand(program) {
119866
120126
  const rollback = !!opts.rollback;
119867
120127
  const taskIds = opts.tasks?.trim() ? opts.tasks.split(",").map((s3) => s3.trim()).filter(Boolean) : void 0;
119868
120128
  if (!dryRun && !rollback && !process.env["CLEO_NONINTERACTIVE"]) {
119869
- console.log(
119870
- "\u26A0 Backfill will modify tasks in-place. Run with --dry-run first to preview changes."
120129
+ process.stderr.write(
120130
+ "Warning: Backfill will modify tasks in-place. Run with --dry-run first to preview changes.\n Set CLEO_NONINTERACTIVE=1 or pass --dry-run to suppress this warning.\n\n"
119871
120131
  );
119872
- console.log(" Set CLEO_NONINTERACTIVE=1 or pass --dry-run to suppress this warning.\n");
119873
- }
119874
- if (dryRun) {
119875
- console.log("[dry run] No changes will be made.\n");
119876
- }
119877
- if (rollback) {
119878
- console.log("[rollback] Reverting previously backfilled tasks.\n");
119879
120132
  }
119880
120133
  try {
119881
120134
  const result = await backfillTasks(root, { dryRun, rollback, taskIds });
119882
- console.log(`Scanned: ${result.tasksScanned} task(s)`);
119883
- console.log(`Changed: ${result.tasksChanged} task(s)`);
120135
+ const output = {
120136
+ dryRun,
120137
+ rollback,
120138
+ tasksScanned: result.tasksScanned,
120139
+ tasksChanged: result.tasksChanged,
120140
+ changes: result.changes
120141
+ };
119884
120142
  if (!rollback) {
119885
- console.log(` AC added: ${result.acAdded}`);
119886
- console.log(` Verification added: ${result.verificationAdded}`);
119887
- }
119888
- if (result.changes.length === 0) {
119889
- console.log("\nNothing to do \u2014 all tasks already have AC and verification metadata.");
119890
- return;
119891
- }
119892
- console.log("\nDetails:");
119893
- for (const change of result.changes) {
119894
- const parts = [];
119895
- if (change.addedAc) parts.push("AC");
119896
- if (change.addedVerification) parts.push("verification");
119897
- if (change.addedNote) parts.push("note");
119898
- if (change.rolledBack && change.rolledBack.length > 0) {
119899
- parts.push(`rolled back [${change.rolledBack.join(", ")}]`);
119900
- }
119901
- console.log(` ${change.taskId}: ${change.title}`);
119902
- console.log(` Actions: ${parts.join(", ")}`);
119903
- if (change.addedAc && change.generatedAc.length > 0) {
119904
- console.log(" Generated AC:");
119905
- for (const ac of change.generatedAc) {
119906
- console.log(` - ${ac}`);
119907
- }
119908
- }
119909
- }
119910
- if (dryRun) {
119911
- console.log("\n[dry run] Run without --dry-run to apply these changes.");
119912
- } else {
119913
- console.log("\nBackfill complete.");
119914
- }
120143
+ output["acAdded"] = result.acAdded;
120144
+ output["verificationAdded"] = result.verificationAdded;
120145
+ }
120146
+ const messagePrefix = dryRun ? "[dry run] " : rollback ? "[rollback] " : "";
120147
+ const messageSuffix = result.changes.length === 0 ? "Nothing to do \u2014 all tasks already have AC and verification metadata." : `Scanned ${result.tasksScanned}, changed ${result.tasksChanged} task(s).`;
120148
+ cliOutput(output, {
120149
+ command: "backfill",
120150
+ operation: "admin.backfill",
120151
+ message: `${messagePrefix}${messageSuffix}`
120152
+ });
119915
120153
  } catch (err) {
119916
120154
  const message = err instanceof Error ? err.message : String(err);
119917
- console.error(`Backfill failed: ${message}`);
120155
+ cliError(
120156
+ `Backfill failed: ${message}`,
120157
+ "E_INTERNAL",
120158
+ {
120159
+ name: "E_INTERNAL"
120160
+ },
120161
+ { operation: "admin.backfill" }
120162
+ );
119918
120163
  process.exit(1);
119919
120164
  }
119920
120165
  }
@@ -120723,8 +120968,8 @@ function registerCancelCommand(program) {
120723
120968
 
120724
120969
  // packages/cleo/src/cli/commands/cant.ts
120725
120970
  init_renderers();
120726
- import { existsSync as existsSync128, mkdirSync as mkdirSync29, readFileSync as readFileSync96, writeFileSync as writeFileSync22 } from "node:fs";
120727
- import { dirname as dirname25, isAbsolute as isAbsolute3, join as join124, resolve as resolve15 } from "node:path";
120971
+ import { existsSync as existsSync130, mkdirSync as mkdirSync29, readFileSync as readFileSync96, writeFileSync as writeFileSync22 } from "node:fs";
120972
+ import { dirname as dirname26, isAbsolute as isAbsolute3, join as join125, resolve as resolve15 } from "node:path";
120728
120973
  function registerCantCommand(program) {
120729
120974
  const cant = program.command("cant").description("CANT DSL tooling");
120730
120975
  cant.command("parse <file>").description("Parse a .cant file and emit the AST").action(async (file2) => {
@@ -120784,21 +121029,12 @@ function registerCantCommand(program) {
120784
121029
  process.exitCode = 1;
120785
121030
  }
120786
121031
  });
120787
- cant.command("migrate <file>").description("Convert markdown instruction files to .cant format").option("--write", "Write .cant files to disk (default: dry-run preview)").option("--dry-run", "Preview conversion without writing files (default behavior)").option("--output-dir <dir>", "Output directory for .cant files (default: .cleo/agents/)").option("--verbose", "Show detailed conversion log").option("--json", "Output results as JSON").action(
121032
+ cant.command("migrate <file>").description("Convert markdown instruction files to .cant format").option("--write", "Write .cant files to disk (default: dry-run preview)").option("--dry-run", "Preview conversion without writing files (default behavior)").option("--output-dir <dir>", "Output directory for .cant files (default: .cleo/agents/)").option("--verbose", "Show detailed conversion log").action(
120788
121033
  async (file2, opts) => {
120789
- const isJson = !!opts.json;
120790
121034
  const isWrite = !!opts.write && !opts.dryRun;
120791
121035
  const isVerbose = !!opts.verbose;
120792
121036
  const filePath = isAbsolute3(file2) ? file2 : resolve15(process.cwd(), file2);
120793
- if (!existsSync128(filePath)) {
120794
- const errMsg = `File not found: ${filePath}`;
120795
- if (isJson) {
120796
- console.log(JSON.stringify({ error: errMsg }));
120797
- } else {
120798
- console.error(errMsg);
120799
- }
120800
- process.exit(1);
120801
- }
121037
+ if (!ensureExists(filePath, "cant.migrate")) return;
120802
121038
  try {
120803
121039
  const mod = await loadMigrateEngine();
120804
121040
  const content = readFileSync96(filePath, "utf-8");
@@ -120807,43 +121043,43 @@ function registerCantCommand(program) {
120807
121043
  verbose: isVerbose,
120808
121044
  outputDir: opts.outputDir
120809
121045
  });
120810
- if (isJson) {
120811
- console.log(JSON.stringify(result, null, 2));
120812
- return;
120813
- }
120814
121046
  if (isWrite) {
120815
121047
  const projectRoot = process.cwd();
120816
121048
  let written = 0;
120817
121049
  for (const outputFile of result.outputFiles) {
120818
- const outputPath = isAbsolute3(outputFile.path) ? outputFile.path : join124(projectRoot, outputFile.path);
120819
- mkdirSync29(dirname25(outputPath), { recursive: true });
121050
+ const outputPath = isAbsolute3(outputFile.path) ? outputFile.path : join125(projectRoot, outputFile.path);
121051
+ mkdirSync29(dirname26(outputPath), { recursive: true });
120820
121052
  writeFileSync22(outputPath, outputFile.content, "utf-8");
120821
121053
  written++;
120822
- if (isVerbose) {
120823
- console.log(` Created: ${outputFile.path} (${outputFile.kind})`);
120824
- }
120825
- }
120826
- console.log(`Wrote ${written} .cant file(s).`);
120827
- console.log(result.summary);
120828
- if (result.unconverted.length > 0) {
120829
- console.log("");
120830
- console.log(`${result.unconverted.length} section(s) need manual conversion.`);
120831
- for (const section of result.unconverted) {
120832
- console.log(` Lines ${section.lineStart}-${section.lineEnd}: ${section.reason}`);
120833
- }
120834
121054
  }
121055
+ cliOutput(
121056
+ {
121057
+ inputFile: result.inputFile,
121058
+ filesWritten: written,
121059
+ outputFiles: result.outputFiles.map((f2) => ({ path: f2.path, kind: f2.kind })),
121060
+ unconverted: result.unconverted,
121061
+ summary: result.summary
121062
+ },
121063
+ { command: "cant-migrate", operation: "cant.migrate" }
121064
+ );
120835
121065
  } else {
120836
- const diffOutput = mod.showDiff(result, process.stdout.isTTY ?? false);
120837
- console.log(diffOutput);
121066
+ cliOutput(
121067
+ {
121068
+ inputFile: result.inputFile,
121069
+ dryRun: true,
121070
+ outputFiles: result.outputFiles.map((f2) => ({
121071
+ path: f2.path,
121072
+ kind: f2.kind
121073
+ })),
121074
+ unconverted: result.unconverted,
121075
+ summary: result.summary
121076
+ },
121077
+ { command: "cant-migrate", operation: "cant.migrate" }
121078
+ );
120838
121079
  }
120839
121080
  } catch (err) {
120840
- const message = err instanceof Error ? err.message : String(err);
120841
- if (isJson) {
120842
- console.log(JSON.stringify({ error: message }));
120843
- } else {
120844
- console.error(`Migration failed: ${message}`);
120845
- }
120846
- process.exit(1);
121081
+ emitFailure("cant.migrate", "E_MIGRATION_FAILED", err);
121082
+ process.exitCode = 1;
120847
121083
  }
120848
121084
  }
120849
121085
  );
@@ -120852,7 +121088,7 @@ function resolveFilePath(file2) {
120852
121088
  return isAbsolute3(file2) ? file2 : resolve15(process.cwd(), file2);
120853
121089
  }
120854
121090
  function ensureExists(filePath, operation) {
120855
- if (existsSync128(filePath)) return true;
121091
+ if (existsSync130(filePath)) return true;
120856
121092
  cliError(`File not found: ${filePath}`, "E_FILE_READ");
120857
121093
  process.exitCode = 3;
120858
121094
  if (process.env["CLEO_DEBUG"]) {
@@ -121169,30 +121405,6 @@ function registerUnclaimCommand(program) {
121169
121405
  });
121170
121406
  }
121171
121407
 
121172
- // packages/cleo/src/cli/commands/commands.ts
121173
- init_cli();
121174
- function registerCommandsCommand(program) {
121175
- program.command("commands [command]").description(
121176
- "DEPRECATED: Use `cleo ops` instead. List and query available CLEO commands (delegates to admin help)"
121177
- ).option("-c, --category <category>", "Filter by category").option("-r, --relevance <level>", "Filter by agent relevance").option("--tier <n>", "Help tier level (0=basic, 1=extended, 2=full)", parseInt).action(async (commandName, opts) => {
121178
- console.error(
121179
- "[DEPRECATED] cleo commands now delegates to admin.help.\nUse: cleo help (CLI)\n"
121180
- );
121181
- await dispatchFromCli(
121182
- "query",
121183
- "admin",
121184
- "help",
121185
- {
121186
- tier: opts["tier"] ?? 0,
121187
- domain: commandName,
121188
- category: opts["category"],
121189
- relevance: opts["relevance"]
121190
- },
121191
- { command: "commands", operation: "admin.help" }
121192
- );
121193
- });
121194
- }
121195
-
121196
121408
  // packages/cleo/src/cli/commands/complete.ts
121197
121409
  init_cli();
121198
121410
  init_renderers();
@@ -121325,14 +121537,14 @@ function registerComplianceCommand(program) {
121325
121537
  { command: "compliance" }
121326
121538
  );
121327
121539
  });
121328
- compliance.command("audit <epicId>").description("Check compliance for specific epic tasks").option("--since <date>", "Filter from date").action(async (epicId, opts) => {
121540
+ compliance.command("audit <taskId>").description("Check compliance for a specific task and its subtasks").option("--since <date>", "Filter from date").action(async (taskId, opts) => {
121329
121541
  await dispatchFromCli(
121330
121542
  "query",
121331
121543
  "check",
121332
121544
  "compliance.summary",
121333
121545
  {
121334
121546
  type: "audit",
121335
- epicId,
121547
+ taskId,
121336
121548
  since: opts["since"]
121337
121549
  },
121338
121550
  { command: "compliance" }
@@ -121379,7 +121591,7 @@ function registerComplianceCommand(program) {
121379
121591
  (val, prev) => [...prev, val],
121380
121592
  []
121381
121593
  ).action(async (taskId, result, opts) => {
121382
- const rawViolations = opts["violation"];
121594
+ const rawViolations = opts["violation"] ?? [];
121383
121595
  const violations = rawViolations.map((v2) => {
121384
121596
  const [code, severity, ...rest] = v2.split(":");
121385
121597
  return {
@@ -121448,46 +121660,20 @@ function registerConfigCommand(program) {
121448
121660
  });
121449
121661
  }
121450
121662
 
121451
- // packages/cleo/src/cli/commands/consensus.ts
121452
- init_cli();
121453
- function registerConsensusCommand(program) {
121454
- const consensus = program.command("consensus").description(
121455
- "Validate consensus protocol compliance (alias for `cleo check protocol consensus`)"
121456
- );
121457
- consensus.command("validate <taskId>").description("Validate consensus protocol compliance for task").option("--strict", "Exit with error code on violations").option("--voting-matrix <file>", "Path to voting matrix JSON file").action(async (taskId, opts) => {
121458
- await dispatchFromCli(
121459
- "query",
121460
- "check",
121461
- "protocol",
121462
- {
121463
- protocolType: "consensus",
121464
- mode: "task",
121465
- taskId,
121466
- strict: opts["strict"],
121467
- votingMatrixFile: opts["votingMatrix"]
121468
- },
121469
- { command: "consensus" }
121470
- );
121471
- });
121472
- consensus.command("check <manifestFile>").description("Validate manifest entry directly").option("--strict", "Exit with error code on violations").option("--voting-matrix <file>", "Path to voting matrix JSON file").action(async (manifestFile, opts) => {
121473
- await dispatchFromCli(
121474
- "query",
121475
- "check",
121476
- "protocol",
121477
- {
121478
- protocolType: "consensus",
121479
- mode: "manifest",
121480
- manifestFile,
121481
- strict: opts["strict"],
121482
- votingMatrixFile: opts["votingMatrix"]
121483
- },
121484
- { command: "consensus" }
121485
- );
121486
- });
121487
- }
121488
-
121489
121663
  // packages/cleo/src/cli/commands/context.ts
121664
+ init_src();
121665
+ init_internal();
121490
121666
  init_cli();
121667
+ init_system_engine();
121668
+ init_renderers();
121669
+ var STATUS_EXIT_CODE = {
121670
+ ok: 0 /* SUCCESS */,
121671
+ warning: 50 /* CONTEXT_WARNING */,
121672
+ caution: 51 /* CONTEXT_CAUTION */,
121673
+ critical: 52 /* CONTEXT_CRITICAL */,
121674
+ emergency: 53 /* CONTEXT_EMERGENCY */,
121675
+ stale: 54 /* CONTEXT_STALE */
121676
+ };
121491
121677
  function registerContextCommand(program) {
121492
121678
  const context = program.command("context").description("Monitor context window usage for agent safeguard system");
121493
121679
  context.command("status", { isDefault: true }).description("Show current context state (default)").option("--session <id>", "Check specific CLEO session").action(async (opts) => {
@@ -121502,64 +121688,29 @@ function registerContextCommand(program) {
121502
121688
  { command: "context" }
121503
121689
  );
121504
121690
  });
121505
- context.command("check").description("Show context window state (same as status)").option("--session <id>", "Check specific CLEO session").action(async (opts) => {
121506
- await dispatchFromCli(
121507
- "query",
121508
- "admin",
121509
- "context",
121510
- {
121511
- action: "check",
121512
- session: opts["session"]
121513
- },
121514
- { command: "context" }
121515
- );
121516
- });
121517
- context.command("list").description("Show context window state including all sessions").action(async () => {
121518
- await dispatchFromCli(
121519
- "query",
121520
- "admin",
121521
- "context",
121522
- {
121523
- action: "list"
121524
- },
121525
- { command: "context" }
121526
- );
121527
- });
121528
- }
121529
-
121530
- // packages/cleo/src/cli/commands/contribution.ts
121531
- init_cli();
121532
- function registerContributionCommand(program) {
121533
- const contribution = program.command("contribution").description(
121534
- "Validate contribution protocol compliance (alias for `cleo check protocol contribution`)"
121535
- );
121536
- contribution.command("validate <taskId>").description("Validate contribution protocol compliance for task").option("--strict", "Exit with error code on violations").action(async (taskId, opts) => {
121537
- await dispatchFromCli(
121538
- "query",
121539
- "check",
121540
- "protocol",
121541
- {
121542
- protocolType: "contribution",
121543
- mode: "task",
121544
- taskId,
121545
- strict: opts["strict"]
121546
- },
121547
- { command: "contribution" }
121548
- );
121549
- });
121550
- contribution.command("check <manifestFile>").description("Validate manifest entry directly").option("--strict", "Exit with error code on violations").action(async (manifestFile, opts) => {
121551
- await dispatchFromCli(
121552
- "query",
121553
- "check",
121554
- "protocol",
121555
- {
121556
- protocolType: "contribution",
121557
- mode: "manifest",
121558
- manifestFile,
121559
- strict: opts["strict"]
121560
- },
121561
- { command: "contribution" }
121562
- );
121691
+ context.command("check").description(
121692
+ "Check context window state \u2014 exits non-zero when threshold exceeded (for scripting)"
121693
+ ).option("--session <id>", "Check specific CLEO session").action(async (opts) => {
121694
+ const cwd = resolveProjectRoot();
121695
+ const result = systemContext(cwd, {
121696
+ session: opts["session"]
121697
+ });
121698
+ if (!result.success) {
121699
+ console.error(result.error?.message ?? "Context check failed");
121700
+ process.exit(1 /* GENERAL_ERROR */);
121701
+ return;
121702
+ }
121703
+ const data = result.data;
121704
+ if (!data) {
121705
+ console.error("Context check returned no data");
121706
+ process.exit(1 /* GENERAL_ERROR */);
121707
+ return;
121708
+ }
121709
+ cliOutput(data, { command: "context", operation: "admin.context" });
121710
+ const exitCode = STATUS_EXIT_CODE[data.status] ?? 0 /* SUCCESS */;
121711
+ if (exitCode !== 0 /* SUCCESS */) {
121712
+ process.exit(exitCode);
121713
+ }
121563
121714
  });
121564
121715
  }
121565
121716
 
@@ -121589,44 +121740,6 @@ function registerDashCommand(program) {
121589
121740
  });
121590
121741
  }
121591
121742
 
121592
- // packages/cleo/src/cli/commands/decomposition.ts
121593
- init_cli();
121594
- function registerDecompositionCommand(program) {
121595
- const decomposition = program.command("decomposition").description(
121596
- "Validate decomposition protocol compliance (alias for `cleo check protocol decomposition`)"
121597
- );
121598
- decomposition.command("validate <taskId>").description("Validate decomposition protocol compliance for task").option("--strict", "Exit with error code on violations").option("--epic <id>", "Specify parent epic ID").action(async (taskId, opts) => {
121599
- await dispatchFromCli(
121600
- "query",
121601
- "check",
121602
- "protocol",
121603
- {
121604
- protocolType: "decomposition",
121605
- mode: "task",
121606
- taskId,
121607
- strict: opts["strict"],
121608
- epicId: opts["epic"]
121609
- },
121610
- { command: "decomposition" }
121611
- );
121612
- });
121613
- decomposition.command("check <manifestFile>").description("Validate manifest entry directly").option("--strict", "Exit with error code on violations").option("--epic <id>", "Specify parent epic ID").action(async (manifestFile, opts) => {
121614
- await dispatchFromCli(
121615
- "query",
121616
- "check",
121617
- "protocol",
121618
- {
121619
- protocolType: "decomposition",
121620
- mode: "manifest",
121621
- manifestFile,
121622
- strict: opts["strict"],
121623
- epicId: opts["epic"]
121624
- },
121625
- { command: "decomposition" }
121626
- );
121627
- });
121628
- }
121629
-
121630
121743
  // packages/cleo/src/cli/commands/delete.ts
121631
121744
  init_cli();
121632
121745
  init_renderers();
@@ -121680,7 +121793,7 @@ function registerDepsCommand(program) {
121680
121793
  { command: "deps", operation: "tasks.depends" }
121681
121794
  );
121682
121795
  });
121683
- deps.command("waves [epicId]").description("Group tasks into parallelizable execution waves").action(async (epicId) => {
121796
+ deps.command("waves <epicId>").description("Group tasks into parallelizable execution waves").action(async (epicId) => {
121684
121797
  await dispatchFromCli(
121685
121798
  "query",
121686
121799
  "orchestrate",
@@ -121758,15 +121871,15 @@ function registerDetectCommand(program) {
121758
121871
  // packages/cleo/src/cli/commands/detect-drift.ts
121759
121872
  init_src();
121760
121873
  init_renderers();
121761
- import { existsSync as existsSync129, readdirSync as readdirSync41, readFileSync as readFileSync98 } from "node:fs";
121762
- import { dirname as dirname26, join as join125 } from "node:path";
121874
+ import { existsSync as existsSync131, readdirSync as readdirSync41, readFileSync as readFileSync98 } from "node:fs";
121875
+ import { dirname as dirname27, join as join126 } from "node:path";
121763
121876
  function findProjectRoot() {
121764
121877
  let currentDir = process.cwd();
121765
121878
  while (currentDir !== "/") {
121766
- if (existsSync129(join125(currentDir, "package.json"))) {
121879
+ if (existsSync131(join126(currentDir, "package.json"))) {
121767
121880
  return currentDir;
121768
121881
  }
121769
- const parent = dirname26(currentDir);
121882
+ const parent = dirname27(currentDir);
121770
121883
  if (parent === currentDir) break;
121771
121884
  currentDir = parent;
121772
121885
  }
@@ -121775,8 +121888,8 @@ function findProjectRoot() {
121775
121888
  function registerDetectDriftCommand(program) {
121776
121889
  program.command("detect-drift").description("Detect documentation drift against TypeScript source of truth").action(async () => {
121777
121890
  const projectRoot = findProjectRoot();
121778
- const isCleoRepo = existsSync129(join125(projectRoot, "packages", "cleo", "src"));
121779
- const cleoSrcRoot = isCleoRepo ? join125(projectRoot, "packages", "cleo", "src") : join125(projectRoot, "src");
121891
+ const isCleoRepo = existsSync131(join126(projectRoot, "packages", "cleo", "src"));
121892
+ const cleoSrcRoot = isCleoRepo ? join126(projectRoot, "packages", "cleo", "src") : join126(projectRoot, "src");
121780
121893
  const safeRead = (filePath) => {
121781
121894
  try {
121782
121895
  return readFileSync98(filePath, "utf-8");
@@ -121790,8 +121903,8 @@ function registerDetectDriftCommand(program) {
121790
121903
  checks: [],
121791
121904
  recommendations: []
121792
121905
  };
121793
- const injPath = join125(projectRoot, ".cleo", "templates", "CLEO-INJECTION.md");
121794
- if (existsSync129(injPath)) {
121906
+ const injPath = join126(projectRoot, ".cleo", "templates", "CLEO-INJECTION.md");
121907
+ if (existsSync131(injPath)) {
121795
121908
  const content = safeRead(injPath);
121796
121909
  userResult.checks.push({
121797
121910
  name: "Agent injection",
@@ -121842,10 +121955,10 @@ function registerDetectDriftCommand(program) {
121842
121955
  }
121843
121956
  };
121844
121957
  try {
121845
- const specPath = join125(projectRoot, "docs", "specs", "CLEO-OPERATION-CONSTITUTION.md");
121846
- const registryPath = join125(cleoSrcRoot, "dispatch", "registry.ts");
121847
- const dispatchDomainsDir = join125(cleoSrcRoot, "dispatch", "domains");
121848
- if (!existsSync129(specPath)) {
121958
+ const specPath = join126(projectRoot, "docs", "specs", "CLEO-OPERATION-CONSTITUTION.md");
121959
+ const registryPath = join126(cleoSrcRoot, "dispatch", "registry.ts");
121960
+ const dispatchDomainsDir = join126(cleoSrcRoot, "dispatch", "domains");
121961
+ if (!existsSync131(specPath)) {
121849
121962
  addCheck("Gateway-to-spec sync", "fail", "CLEO-OPERATION-CONSTITUTION.md missing", [
121850
121963
  {
121851
121964
  severity: "error",
@@ -121855,7 +121968,7 @@ function registerDetectDriftCommand(program) {
121855
121968
  recommendation: "Create docs/specs/CLEO-OPERATION-CONSTITUTION.md with canonical operation definitions"
121856
121969
  }
121857
121970
  ]);
121858
- } else if (!existsSync129(registryPath) || !existsSync129(dispatchDomainsDir)) {
121971
+ } else if (!existsSync131(registryPath) || !existsSync131(dispatchDomainsDir)) {
121859
121972
  addCheck("Gateway-to-spec sync", "fail", "Dispatch registry or domains missing", [
121860
121973
  {
121861
121974
  severity: "error",
@@ -121919,9 +122032,9 @@ function registerDetectDriftCommand(program) {
121919
122032
  ]);
121920
122033
  }
121921
122034
  try {
121922
- const cliDir = join125(cleoSrcRoot, "cli", "commands");
121923
- const coreDir = isCleoRepo ? join125(projectRoot, "packages", "core", "src") : join125(projectRoot, "src", "core");
121924
- if (!existsSync129(cliDir)) {
122035
+ const cliDir = join126(cleoSrcRoot, "cli", "commands");
122036
+ const coreDir = isCleoRepo ? join126(projectRoot, "packages", "core", "src") : join126(projectRoot, "src", "core");
122037
+ if (!existsSync131(cliDir)) {
121925
122038
  addCheck("CLI-to-core sync", "fail", "CLI commands directory missing", [
121926
122039
  {
121927
122040
  severity: "error",
@@ -121930,7 +122043,7 @@ function registerDetectDriftCommand(program) {
121930
122043
  recommendation: "Verify TypeScript source structure is intact"
121931
122044
  }
121932
122045
  ]);
121933
- } else if (!existsSync129(coreDir)) {
122046
+ } else if (!existsSync131(coreDir)) {
121934
122047
  addCheck("CLI-to-core sync", "fail", "Core directory missing", [
121935
122048
  {
121936
122049
  severity: "error",
@@ -121949,8 +122062,8 @@ function registerDetectDriftCommand(program) {
121949
122062
  addCheck("CLI-to-core sync", "fail", `Error: ${getErrorMessage(e)}`);
121950
122063
  }
121951
122064
  try {
121952
- const domainsDir = join125(cleoSrcRoot, "dispatch", "domains");
121953
- if (!existsSync129(domainsDir)) {
122065
+ const domainsDir = join126(cleoSrcRoot, "dispatch", "domains");
122066
+ if (!existsSync131(domainsDir)) {
121954
122067
  addCheck("Domain handler coverage", "fail", "Dispatch domains directory missing", [
121955
122068
  {
121956
122069
  severity: "error",
@@ -121967,8 +122080,8 @@ function registerDetectDriftCommand(program) {
121967
122080
  addCheck("Domain handler coverage", "fail", `Error: ${getErrorMessage(e)}`);
121968
122081
  }
121969
122082
  try {
121970
- const matrixPath = join125(cleoSrcRoot, "dispatch", "lib", "capability-matrix.ts");
121971
- if (!existsSync129(matrixPath)) {
122083
+ const matrixPath = join126(cleoSrcRoot, "dispatch", "lib", "capability-matrix.ts");
122084
+ if (!existsSync131(matrixPath)) {
121972
122085
  addCheck("Capability matrix", "fail", "Capability matrix missing", [
121973
122086
  {
121974
122087
  severity: "error",
@@ -121984,8 +122097,8 @@ function registerDetectDriftCommand(program) {
121984
122097
  addCheck("Capability matrix", "fail", `Error: ${getErrorMessage(e)}`);
121985
122098
  }
121986
122099
  try {
121987
- const schemaPath = join125(projectRoot, "src", "store", "schema.ts");
121988
- if (!existsSync129(schemaPath)) {
122100
+ const schemaPath = join126(projectRoot, "src", "store", "schema.ts");
122101
+ if (!existsSync131(schemaPath)) {
121989
122102
  addCheck("Schema validation", "fail", "Schema definition missing", [
121990
122103
  {
121991
122104
  severity: "error",
@@ -122019,10 +122132,10 @@ function registerDetectDriftCommand(program) {
122019
122132
  addCheck("Schema validation", "fail", `Error: ${getErrorMessage(e)}`);
122020
122133
  }
122021
122134
  try {
122022
- const visionPath = join125(projectRoot, "docs", "concepts", "CLEO-VISION.md");
122023
- const specPath = join125(projectRoot, "docs", "specs", "PORTABLE-BRAIN-SPEC.md");
122135
+ const visionPath = join126(projectRoot, "docs", "concepts", "CLEO-VISION.md");
122136
+ const specPath = join126(projectRoot, "docs", "specs", "PORTABLE-BRAIN-SPEC.md");
122024
122137
  const issues = [];
122025
- if (!existsSync129(visionPath)) {
122138
+ if (!existsSync131(visionPath)) {
122026
122139
  issues.push({
122027
122140
  severity: "error",
122028
122141
  category: "vision",
@@ -122031,7 +122144,7 @@ function registerDetectDriftCommand(program) {
122031
122144
  recommendation: "Create docs/concepts/CLEO-VISION.md with project vision"
122032
122145
  });
122033
122146
  }
122034
- if (!existsSync129(specPath)) {
122147
+ if (!existsSync131(specPath)) {
122035
122148
  issues.push({
122036
122149
  severity: "error",
122037
122150
  category: "spec",
@@ -122075,8 +122188,8 @@ function registerDetectDriftCommand(program) {
122075
122188
  addCheck("Canonical identity", "fail", `Error: ${getErrorMessage(e)}`);
122076
122189
  }
122077
122190
  try {
122078
- const injectionPath = join125(projectRoot, ".cleo", "templates", "CLEO-INJECTION.md");
122079
- if (!existsSync129(injectionPath)) {
122191
+ const injectionPath = join126(projectRoot, ".cleo", "templates", "CLEO-INJECTION.md");
122192
+ if (!existsSync131(injectionPath)) {
122080
122193
  addCheck("Agent injection", "fail", "Agent injection template missing", [
122081
122194
  {
122082
122195
  severity: "error",
@@ -122105,8 +122218,8 @@ function registerDetectDriftCommand(program) {
122105
122218
  addCheck("Agent injection", "fail", `Error: ${getErrorMessage(e)}`);
122106
122219
  }
122107
122220
  try {
122108
- const exitCodesPath = join125(cleoSrcRoot, "dispatch", "lib", "exit-codes.ts");
122109
- if (!existsSync129(exitCodesPath)) {
122221
+ const exitCodesPath = join126(cleoSrcRoot, "dispatch", "lib", "exit-codes.ts");
122222
+ if (!existsSync131(exitCodesPath)) {
122110
122223
  addCheck("Exit codes", "fail", "Exit codes definition missing", [
122111
122224
  {
122112
122225
  severity: "error",
@@ -122141,9 +122254,9 @@ function registerDetectDriftCommand(program) {
122141
122254
  init_internal();
122142
122255
  init_renderers();
122143
122256
  import { readdir as readdir3, readFile as readFile21 } from "node:fs/promises";
122144
- import { join as join126 } from "node:path";
122257
+ import { join as join127 } from "node:path";
122145
122258
  async function getScriptNames(projectRoot) {
122146
- const scriptsDir = join126(projectRoot, "scripts");
122259
+ const scriptsDir = join127(projectRoot, "scripts");
122147
122260
  try {
122148
122261
  const files = await readdir3(scriptsDir);
122149
122262
  return files.filter((f2) => f2.endsWith(".sh")).map((f2) => f2.replace(".sh", "")).sort();
@@ -122152,7 +122265,7 @@ async function getScriptNames(projectRoot) {
122152
122265
  }
122153
122266
  }
122154
122267
  async function getIndexedCommands(projectRoot) {
122155
- const indexPath = join126(projectRoot, "docs", "commands", "COMMANDS-INDEX.json");
122268
+ const indexPath = join127(projectRoot, "docs", "commands", "COMMANDS-INDEX.json");
122156
122269
  const index2 = await readJson(indexPath);
122157
122270
  if (!index2) return [];
122158
122271
  return index2.commands.map((c) => c.name).sort();
@@ -122185,7 +122298,7 @@ async function runGapCheck(_projectRoot, filterId) {
122185
122298
  const reviewFiles = files.filter((f2) => f2.endsWith(".md"));
122186
122299
  for (const file2 of reviewFiles) {
122187
122300
  if (filterId && !file2.includes(filterId)) continue;
122188
- const filePath = join126(reviewDir, file2);
122301
+ const filePath = join127(reviewDir, file2);
122189
122302
  const content = await readFile21(filePath, "utf-8");
122190
122303
  const taskMatch = file2.match(/^(T\d+)/);
122191
122304
  const taskId = taskMatch ? taskMatch[1] : "UNKNOWN";
@@ -122737,8 +122850,8 @@ init_src();
122737
122850
  init_src2();
122738
122851
  init_renderers();
122739
122852
  import { execFileSync as execFileSync16 } from "node:child_process";
122740
- import { existsSync as existsSync130, mkdirSync as mkdirSync30, readFileSync as readFileSync99, writeFileSync as writeFileSync23 } from "node:fs";
122741
- import { dirname as dirname27, join as join127 } from "node:path";
122853
+ import { existsSync as existsSync132, mkdirSync as mkdirSync30, readFileSync as readFileSync99, writeFileSync as writeFileSync23 } from "node:fs";
122854
+ import { dirname as dirname28, join as join128 } from "node:path";
122742
122855
  function getChangelogSource(cwd) {
122743
122856
  const configPath = getConfigPath(cwd);
122744
122857
  try {
@@ -122876,8 +122989,8 @@ function registerGenerateChangelogCommand(program) {
122876
122989
  const targetPlatform = opts["platform"];
122877
122990
  const dryRun = !!opts["dryRun"];
122878
122991
  const sourceFile = getChangelogSource();
122879
- const sourcePath = join127(getProjectRoot(), sourceFile);
122880
- if (!existsSync130(sourcePath)) {
122992
+ const sourcePath = join128(getProjectRoot(), sourceFile);
122993
+ if (!existsSync132(sourcePath)) {
122881
122994
  throw new CleoError(4 /* NOT_FOUND */, `Changelog source not found: ${sourcePath}`);
122882
122995
  }
122883
122996
  const sourceContent = readFileSync99(sourcePath, "utf-8");
@@ -122889,8 +123002,8 @@ function registerGenerateChangelogCommand(program) {
122889
123002
  const outputPath = platformConfig?.path ?? getDefaultOutputPath(targetPlatform);
122890
123003
  const content = generateForPlatform(targetPlatform, sourceContent, repoSlug, limit);
122891
123004
  if (!dryRun) {
122892
- const fullPath = join127(getProjectRoot(), outputPath);
122893
- mkdirSync30(dirname27(fullPath), { recursive: true });
123005
+ const fullPath = join128(getProjectRoot(), outputPath);
123006
+ mkdirSync30(dirname28(fullPath), { recursive: true });
122894
123007
  writeFileSync23(fullPath, content, "utf-8");
122895
123008
  }
122896
123009
  results.push({ platform: targetPlatform, path: outputPath, written: !dryRun });
@@ -122910,8 +123023,8 @@ function registerGenerateChangelogCommand(program) {
122910
123023
  limit
122911
123024
  );
122912
123025
  if (!dryRun) {
122913
- const fullPath = join127(getProjectRoot(), platformConfig.path);
122914
- mkdirSync30(dirname27(fullPath), { recursive: true });
123026
+ const fullPath = join128(getProjectRoot(), platformConfig.path);
123027
+ mkdirSync30(dirname28(fullPath), { recursive: true });
122915
123028
  writeFileSync23(fullPath, content, "utf-8");
122916
123029
  }
122917
123030
  results.push({
@@ -122955,7 +123068,8 @@ function registerGradeCommand(program) {
122955
123068
  // packages/cleo/src/cli/commands/history.ts
122956
123069
  init_cli();
122957
123070
  function registerHistoryCommand(program) {
122958
- const history = program.command("history").description("Completion timeline and productivity analytics").option("--days <n>", "Show last N days", "30").option("--since <date>", "Show completions since date (YYYY-MM-DD)").option("--until <date>", "Show completions until date (YYYY-MM-DD)").option("--no-chart", "Disable bar charts").action(async (opts) => {
123071
+ const history = program.command("history").description("Completion timeline and productivity analytics");
123072
+ history.command("log").description("Show operation audit log").option("--days <n>", "Show last N days", "30").option("--since <date>", "Show completions since date (YYYY-MM-DD)").option("--until <date>", "Show completions until date (YYYY-MM-DD)").option("--no-chart", "Disable bar charts").action(async (opts) => {
122959
123073
  await dispatchFromCli(
122960
123074
  "query",
122961
123075
  "admin",
@@ -122973,42 +123087,6 @@ function registerHistoryCommand(program) {
122973
123087
  });
122974
123088
  }
122975
123089
 
122976
- // packages/cleo/src/cli/commands/implementation.ts
122977
- init_cli();
122978
- function registerImplementationCommand(program) {
122979
- const implementation = program.command("implementation").description(
122980
- "Validate implementation protocol compliance (alias for `cleo check protocol implementation`)"
122981
- );
122982
- implementation.command("validate <taskId>").description("Validate implementation protocol compliance for task").option("--strict", "Exit with error code on violations").action(async (taskId, opts) => {
122983
- await dispatchFromCli(
122984
- "query",
122985
- "check",
122986
- "protocol",
122987
- {
122988
- protocolType: "implementation",
122989
- mode: "task",
122990
- taskId,
122991
- strict: opts["strict"]
122992
- },
122993
- { command: "implementation" }
122994
- );
122995
- });
122996
- implementation.command("check <manifestFile>").description("Validate manifest entry directly").option("--strict", "Exit with error code on violations").action(async (manifestFile, opts) => {
122997
- await dispatchFromCli(
122998
- "query",
122999
- "check",
123000
- "protocol",
123001
- {
123002
- protocolType: "implementation",
123003
- mode: "manifest",
123004
- manifestFile,
123005
- strict: opts["strict"]
123006
- },
123007
- { command: "implementation" }
123008
- );
123009
- });
123010
- }
123011
-
123012
123090
  // packages/cleo/src/cli/commands/import.ts
123013
123091
  init_cli();
123014
123092
  function registerImportCommand(program) {
@@ -123564,7 +123642,7 @@ function registerMemoryBrainCommand(program) {
123564
123642
  );
123565
123643
  }
123566
123644
  });
123567
- memory.command("stats").description("Show BRAIN memory statistics").option("--json", "Output as JSON").action(async () => {
123645
+ memory.command("stats").description("Show BRAIN memory statistics").action(async () => {
123568
123646
  const pResponse = await dispatchRaw("query", "memory", "pattern.find", {
123569
123647
  query: "",
123570
123648
  limit: 0
@@ -123577,10 +123655,10 @@ function registerMemoryBrainCommand(program) {
123577
123655
  if (pResponse.success) result["patterns"] = pResponse.data;
123578
123656
  if (lResponse.success) result["learnings"] = lResponse.data;
123579
123657
  if (!pResponse.success && !lResponse.success) {
123580
- handleRawError(pResponse, { command: "memory", operation: "memory.stats" });
123658
+ handleRawError(pResponse, { command: "memory-stats", operation: "memory.stats" });
123581
123659
  return;
123582
123660
  }
123583
- cliOutput(result, { command: "memory", operation: "memory.stats" });
123661
+ cliOutput(result, { command: "memory-stats", operation: "memory.stats" });
123584
123662
  });
123585
123663
  memory.command("observe <text>").description(
123586
123664
  "Save an observation to brain.db \u2014 captures facts, decisions, and discoveries for cross-session memory"
@@ -123611,7 +123689,7 @@ function registerMemoryBrainCommand(program) {
123611
123689
  { command: "memory", operation: "memory.observe" }
123612
123690
  );
123613
123691
  });
123614
- memory.command("timeline <anchor>").description("Show chronological context around an anchor observation ID").option("--before <n>", "Number of entries before anchor", parseInt).option("--after <n>", "Number of entries after anchor", parseInt).option("--json", "Output as JSON").action(async (anchor, opts) => {
123692
+ memory.command("timeline <anchor>").description("Show chronological context around an anchor observation ID").option("--before <n>", "Number of entries before anchor", parseInt).option("--after <n>", "Number of entries after anchor", parseInt).action(async (anchor, opts) => {
123615
123693
  await dispatchFromCli(
123616
123694
  "query",
123617
123695
  "memory",
@@ -123621,17 +123699,17 @@ function registerMemoryBrainCommand(program) {
123621
123699
  depthBefore: opts["before"],
123622
123700
  depthAfter: opts["after"]
123623
123701
  },
123624
- { command: "memory", operation: "memory.timeline" }
123702
+ { command: "memory-timeline", operation: "memory.timeline" }
123625
123703
  );
123626
123704
  });
123627
- memory.command("fetch <ids>").description("Fetch full details for specific observation IDs").option("--json", "Output as JSON").action(async (idsRaw, _opts) => {
123705
+ memory.command("fetch <ids>").description("Fetch full details for specific observation IDs").action(async (idsRaw) => {
123628
123706
  const ids = idsRaw.split(/[,\s]+/).map((s3) => s3.trim()).filter(Boolean);
123629
123707
  await dispatchFromCli(
123630
123708
  "query",
123631
123709
  "memory",
123632
123710
  "fetch",
123633
123711
  { ids },
123634
- { command: "memory", operation: "memory.fetch" }
123712
+ { command: "memory-fetch", operation: "memory.fetch" }
123635
123713
  );
123636
123714
  });
123637
123715
  memory.command("decision-find [query]").description("Search decisions stored in brain.db").option("--limit <n>", "Maximum results", parseInt).option("--json", "Output as JSON").action(async (query, opts) => {
@@ -123691,16 +123769,17 @@ function registerMemoryBrainCommand(program) {
123691
123769
  { command: "memory", operation: "memory.graph.neighbors" }
123692
123770
  );
123693
123771
  });
123694
- memory.command("graph-add").description("Add a node or edge to the PageIndex graph").option("--node-id <id>", "Node ID to add").option("--label <text>", "Label for the node").option("--from <id>", "Source node ID for an edge").option("--to <id>", "Target node ID for an edge").option("--edge-type <type>", "Edge relationship type").option("--json", "Output as JSON").action(async (opts) => {
123772
+ memory.command("graph-add").description("Add a node or edge to the PageIndex graph").option("--node-id <id>", "Node ID to add").option("--node-type <type>", "Node type (e.g. concept, task, file)").option("--label <text>", "Label for the node").option("--from <id>", "Source node ID for an edge").option("--to <id>", "Target node ID for an edge").option("--edge-type <type>", "Edge relationship type").option("--json", "Output as JSON").action(async (opts) => {
123695
123773
  await dispatchFromCli(
123696
123774
  "mutate",
123697
123775
  "memory",
123698
123776
  "graph.add",
123699
123777
  {
123700
123778
  ...opts["nodeId"] !== void 0 && { nodeId: opts["nodeId"] },
123779
+ ...opts["nodeType"] !== void 0 && { nodeType: opts["nodeType"] },
123701
123780
  ...opts["label"] !== void 0 && { label: opts["label"] },
123702
- ...opts["from"] !== void 0 && { from: opts["from"] },
123703
- ...opts["to"] !== void 0 && { to: opts["to"] },
123781
+ ...opts["from"] !== void 0 && { fromId: opts["from"] },
123782
+ ...opts["to"] !== void 0 && { toId: opts["to"] },
123704
123783
  ...opts["edgeType"] !== void 0 && { edgeType: opts["edgeType"] }
123705
123784
  },
123706
123785
  { command: "memory", operation: "memory.graph.add" }
@@ -123713,8 +123792,8 @@ function registerMemoryBrainCommand(program) {
123713
123792
  "graph.remove",
123714
123793
  {
123715
123794
  ...opts["nodeId"] !== void 0 && { nodeId: opts["nodeId"] },
123716
- ...opts["from"] !== void 0 && { from: opts["from"] },
123717
- ...opts["to"] !== void 0 && { to: opts["to"] }
123795
+ ...opts["from"] !== void 0 && { fromId: opts["from"] },
123796
+ ...opts["to"] !== void 0 && { toId: opts["to"] }
123718
123797
  },
123719
123798
  { command: "memory", operation: "memory.graph.remove" }
123720
123799
  );
@@ -123760,6 +123839,7 @@ function registerMemoryBrainCommand(program) {
123760
123839
  // packages/cleo/src/cli/commands/migrate-claude-mem.ts
123761
123840
  init_internal();
123762
123841
  init_cli();
123842
+ init_renderers();
123763
123843
  function registerMigrateClaudeMemCommand(program) {
123764
123844
  let migrateCmd = program.commands.find((c) => c.name() === "migrate");
123765
123845
  if (!migrateCmd) {
@@ -123786,23 +123866,26 @@ function registerMigrateClaudeMemCommand(program) {
123786
123866
  dryRun: !!opts["dryRun"],
123787
123867
  batchSize: opts["batchSize"] || void 0
123788
123868
  });
123789
- if (result.dryRun) {
123790
- console.log("[dry run] No changes made.");
123791
- }
123792
- console.log(
123793
- `Imported ${result.observationsImported} observations, ${result.learningsImported} learnings, ${result.decisionsImported} decisions (${result.observationsSkipped} skipped)`
123869
+ cliOutput(
123870
+ {
123871
+ dryRun: result.dryRun,
123872
+ observationsImported: result.observationsImported,
123873
+ learningsImported: result.learningsImported,
123874
+ decisionsImported: result.decisionsImported,
123875
+ observationsSkipped: result.observationsSkipped,
123876
+ errors: result.errors
123877
+ },
123878
+ { command: "migrate-claude-mem", operation: "migrate.claude-mem" }
123794
123879
  );
123795
123880
  if (result.errors.length > 0) {
123796
- console.error(`
123797
- ${result.errors.length} error(s):`);
123798
- for (const err of result.errors) {
123799
- console.error(` - ${err}`);
123800
- }
123801
- process.exit(1);
123881
+ process.exitCode = 1;
123802
123882
  }
123803
123883
  } catch (err) {
123804
- console.error(`Error: ${err.message}`);
123805
- process.exit(1);
123884
+ const message = err instanceof Error ? err.message : String(err);
123885
+ cliError(message, "E_MIGRATION_FAILED", void 0, {
123886
+ operation: "migrate.claude-mem"
123887
+ });
123888
+ process.exitCode = 1;
123806
123889
  }
123807
123890
  });
123808
123891
  }
@@ -124035,42 +124118,6 @@ function registerNexusCommand(program) {
124035
124118
  });
124036
124119
  }
124037
124120
 
124038
- // packages/cleo/src/cli/commands/observe.ts
124039
- init_cli();
124040
- function registerObserveCommand(program) {
124041
- program.command("observe <text>").description(
124042
- "Save an observation to brain.db \u2014 captures facts, decisions, and discoveries for cross-session memory"
124043
- ).option(
124044
- "-t, --title <title>",
124045
- "Short title for the observation (defaults to first 120 chars of text)"
124046
- ).option(
124047
- "--type <type>",
124048
- "Category: discovery (found something new), decision (choice made), bugfix (bug found/fixed), refactor (code restructured), feature (feature added), change (general change), pattern (recurring pattern), session_summary (end-of-session recap)"
124049
- ).option(
124050
- "--agent <name>",
124051
- "Name of the agent producing this observation (enables per-agent memory retrieval)"
124052
- ).option(
124053
- "--source-type <sourceType>",
124054
- "How this observation was captured: manual (typed by human/agent), auto (lifecycle hook), transcript (extracted from session)"
124055
- ).action(
124056
- async (text3, opts) => {
124057
- await dispatchFromCli(
124058
- "mutate",
124059
- "memory",
124060
- "observe",
124061
- {
124062
- text: text3,
124063
- title: opts.title,
124064
- ...opts.type !== void 0 && { type: opts.type },
124065
- ...opts.agent !== void 0 && { agent: opts.agent },
124066
- sourceType: opts.sourceType ?? "manual"
124067
- },
124068
- { command: "observe", operation: "memory.observe" }
124069
- );
124070
- }
124071
- );
124072
- }
124073
-
124074
124121
  // packages/cleo/src/cli/commands/ops.ts
124075
124122
  init_cli();
124076
124123
  function registerOpsCommand(program) {
@@ -124184,11 +124231,18 @@ function registerOrchestrateCommand(program) {
124184
124231
  { command: "orchestrate" }
124185
124232
  );
124186
124233
  });
124187
- tessera.command("instantiate <templateId> <epicId>").description("Instantiate a tessera template for an epic").option("--var <pairs...>", "Key=value variable overrides").action(async (templateId, epicId, opts) => {
124234
+ tessera.command("instantiate <templateId> <epicId>").description("Instantiate a tessera template for an epic").option("--var <pairs>", "Comma-separated key=value variable overrides (e.g. foo=bar,baz=qux)").action(async (templateId, epicId, opts) => {
124188
124235
  const variables = {};
124189
- const pairs = opts["var"];
124190
- if (Array.isArray(pairs)) {
124191
- for (const pair of pairs) {
124236
+ const raw = opts["var"];
124237
+ if (typeof raw === "string") {
124238
+ for (const pair of raw.split(",")) {
124239
+ const eqIdx = pair.indexOf("=");
124240
+ if (eqIdx > 0) {
124241
+ variables[pair.slice(0, eqIdx).trim()] = pair.slice(eqIdx + 1).trim();
124242
+ }
124243
+ }
124244
+ } else if (Array.isArray(raw)) {
124245
+ for (const pair of raw) {
124192
124246
  const eqIdx = pair.indexOf("=");
124193
124247
  if (eqIdx > 0) {
124194
124248
  variables[pair.slice(0, eqIdx)] = pair.slice(eqIdx + 1);
@@ -124230,12 +124284,12 @@ function registerOrchestrateCommand(program) {
124230
124284
  { command: "orchestrate" }
124231
124285
  );
124232
124286
  });
124233
- orch.command("fanout-status").description("Get fanout status for an epic").option("--epic <epicId>", "Epic ID to scope fanout status to").action(async (opts) => {
124287
+ orch.command("fanout-status").description("Get fanout status by manifest entry ID").requiredOption("--manifest-entry-id <id>", "Manifest entry ID returned by orchestrate.fanout").action(async (opts) => {
124234
124288
  await dispatchFromCli(
124235
124289
  "query",
124236
124290
  "orchestrate",
124237
124291
  "fanout.status",
124238
- { epicId: opts["epic"] },
124292
+ { manifestEntryId: opts["manifestEntryId"] },
124239
124293
  { command: "orchestrate" }
124240
124294
  );
124241
124295
  });
@@ -124259,11 +124313,12 @@ function registerOrchestrateCommand(program) {
124259
124313
  });
124260
124314
  orch.command("fanout <epicId>").description("Fan out tasks for an epic using parallel spawn").option("--tasks <ids>", "Comma-separated task IDs to fan out").action(async (epicId, opts) => {
124261
124315
  const taskIds = typeof opts["tasks"] === "string" ? opts["tasks"].split(",").map((s3) => s3.trim()) : void 0;
124316
+ const items = taskIds ? taskIds.map((taskId) => ({ taskId, team: "default" })) : void 0;
124262
124317
  await dispatchFromCli(
124263
124318
  "mutate",
124264
124319
  "orchestrate",
124265
124320
  "fanout",
124266
- { epicId, taskIds },
124321
+ { epicId, items },
124267
124322
  { command: "orchestrate" }
124268
124323
  );
124269
124324
  });
@@ -124290,7 +124345,7 @@ function registerOrchestrateCommand(program) {
124290
124345
  "mutate",
124291
124346
  "orchestrate",
124292
124347
  "conduit.start",
124293
- { pollInterval: opts["pollInterval"] },
124348
+ { pollIntervalMs: opts["pollInterval"] },
124294
124349
  { command: "orchestrate" }
124295
124350
  );
124296
124351
  });
@@ -124310,7 +124365,7 @@ function registerOrchestrateCommand(program) {
124310
124365
  "conduit.send",
124311
124366
  {
124312
124367
  content,
124313
- agentId: opts["to"],
124368
+ to: opts["to"],
124314
124369
  conversationId: opts["conversation"]
124315
124370
  },
124316
124371
  { command: "orchestrate" }
@@ -124486,32 +124541,6 @@ function registerPhaseCommand(program) {
124486
124541
  });
124487
124542
  }
124488
124543
 
124489
- // packages/cleo/src/cli/commands/phases.ts
124490
- init_cli();
124491
- function registerPhasesCommand(program) {
124492
- const phases = program.command("phases").description(
124493
- "DEPRECATED: Use `cleo phase` instead. List phases with progress bars and statistics"
124494
- );
124495
- phases.command("list", { isDefault: true }).description("List all phases with progress (default)").action(async () => {
124496
- console.error("[DEPRECATED] cleo phases is deprecated. Use: cleo phase list");
124497
- await dispatchFromCli("query", "pipeline", "phase.list", {}, { command: "phases" });
124498
- });
124499
- phases.command("show <phase>").description("Show phase details and task counts").action(async (phase) => {
124500
- console.error("[DEPRECATED] cleo phases is deprecated. Use: cleo phase show");
124501
- await dispatchFromCli(
124502
- "query",
124503
- "pipeline",
124504
- "phase.show",
124505
- { phaseId: phase },
124506
- { command: "phases" }
124507
- );
124508
- });
124509
- phases.command("stats").description("Show detailed phase statistics").action(async () => {
124510
- console.error("[DEPRECATED] cleo phases is deprecated. Use: cleo phase list");
124511
- await dispatchFromCli("query", "pipeline", "phase.list", {}, { command: "phases" });
124512
- });
124513
- }
124514
-
124515
124544
  // packages/cleo/src/cli/commands/plan.ts
124516
124545
  init_cli();
124517
124546
  function registerPlanCommand(program) {
@@ -124624,28 +124653,7 @@ function registerProviderCommand(program) {
124624
124653
  // packages/cleo/src/cli/commands/reason.ts
124625
124654
  init_cli();
124626
124655
  function registerReasonCommand(program) {
124627
- const reason = program.command("reason").description("Reasoning and intelligence operations (why, similar, impact, timeline)");
124628
- reason.command("why <taskId>").description("Explain why a task exists via causal trace through dependency chains").option("--json", "Output raw JSON envelope").action(async (taskId) => {
124629
- await dispatchFromCli(
124630
- "query",
124631
- "memory",
124632
- "reason.why",
124633
- { taskId },
124634
- { command: "reason", operation: "memory.reason.why" }
124635
- );
124636
- });
124637
- reason.command("similar <taskId>").description("Find BRAIN entries semantically similar to a task or observation ID").option("--limit <n>", "Maximum number of results to return", parseInt).option("--json", "Output raw JSON envelope").action(async (taskId, opts) => {
124638
- await dispatchFromCli(
124639
- "query",
124640
- "memory",
124641
- "reason.similar",
124642
- {
124643
- entryId: taskId,
124644
- limit: opts["limit"]
124645
- },
124646
- { command: "reason", operation: "memory.reason.similar" }
124647
- );
124648
- });
124656
+ const reason = program.command("reason").description("Reasoning and intelligence operations (impact, timeline)");
124649
124657
  reason.command("impact [taskId]").description(
124650
124658
  "Predict impact of a change. Use --change for free-text prediction, or pass a taskId for graph-based analysis."
124651
124659
  ).option("--change <description>", "Free-text description of the proposed change (T043)").option("--limit <n>", "Maximum seed tasks to match when using --change (default: 5)", "5").option("--depth <n>", "Maximum traversal depth when using taskId (default: 10)", "10").option("--json", "Output raw JSON envelope").action(async (taskId, opts) => {
@@ -124992,9 +125000,20 @@ function registerRemoteCommand(program) {
124992
125000
 
124993
125001
  // packages/cleo/src/cli/commands/reorder.ts
124994
125002
  init_cli();
125003
+ var BOTTOM_POSITION = 999999;
124995
125004
  function registerReorderCommand(program) {
124996
- program.command("reorder <task-id>").description("Change task position within sibling group").option("--position <n>", "Move to specific zero-based position among siblings", parseInt).action(async (taskId, opts) => {
124997
- const position = opts["position"];
125005
+ program.command("reorder <task-id>").description("Change task position within sibling group").option("--position <n>", "Move to specific zero-based position among siblings", parseInt).option("--top", "Move to the top (position 0)").option("--bottom", "Move to the bottom").action(async (taskId, opts) => {
125006
+ let position = opts["position"];
125007
+ if (opts["top"]) {
125008
+ position = 0;
125009
+ } else if (opts["bottom"]) {
125010
+ position = BOTTOM_POSITION;
125011
+ }
125012
+ if (position === void 0) {
125013
+ console.error("Error: Must specify --position <n>, --top, or --bottom.");
125014
+ process.exitCode = 2;
125015
+ return;
125016
+ }
124998
125017
  await dispatchFromCli(
124999
125018
  "mutate",
125000
125019
  "tasks",
@@ -125022,22 +125041,36 @@ function registerReparentCommand(program) {
125022
125041
 
125023
125042
  // packages/cleo/src/cli/commands/research.ts
125024
125043
  init_cli();
125044
+ function generateResearchId() {
125045
+ return `res_${Date.now()}`;
125046
+ }
125025
125047
  function registerResearchCommand(program) {
125026
125048
  const research = program.command("research").description("Research commands and manifest operations");
125027
- research.command("add").description("Add a research entry").requiredOption("-t, --task <taskId>", "Task ID to attach research to").requiredOption("--topic <topic>", "Research topic").option("--findings <findings>", "Comma-separated findings").option("--sources <sources>", "Comma-separated sources").action(async (opts) => {
125049
+ research.command("add").description("Add a research entry").requiredOption("-t, --task <taskId>", "Task ID to attach research to").requiredOption("--topic <topic>", "Research topic").option("--findings <findings>", "Comma-separated findings").option("--sources <sources>", "Comma-separated sources").option("--agent-type <agentType>", "Agent type that produced this entry", "researcher").action(async (opts) => {
125050
+ const topic = opts["topic"];
125051
+ const findings = opts["findings"] ? opts["findings"].split(",").map((s3) => s3.trim()) : [];
125052
+ const taskId = opts["task"];
125053
+ const agentType = opts["agentType"] ?? "researcher";
125028
125054
  await dispatchFromCli(
125029
125055
  "mutate",
125030
125056
  "pipeline",
125031
125057
  "manifest.append",
125032
125058
  {
125033
125059
  entry: {
125034
- taskId: opts["task"],
125035
- topic: opts["topic"],
125036
- findings: opts["findings"] ? opts["findings"].split(",").map((s3) => s3.trim()) : void 0,
125037
- sources: opts["sources"] ? opts["sources"].split(",").map((s3) => s3.trim()) : void 0
125060
+ id: generateResearchId(),
125061
+ file: "",
125062
+ title: topic,
125063
+ date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
125064
+ status: "partial",
125065
+ agent_type: agentType,
125066
+ topics: [topic],
125067
+ key_findings: findings,
125068
+ actionable: findings.length > 0,
125069
+ needs_followup: [],
125070
+ linked_tasks: [taskId]
125038
125071
  }
125039
125072
  },
125040
- { command: "research" }
125073
+ { command: "research", operation: "pipeline.manifest.append" }
125041
125074
  );
125042
125075
  });
125043
125076
  research.command("show <id>").description("Show a research entry").action(async (id) => {
@@ -125078,29 +125111,46 @@ function registerResearchCommand(program) {
125078
125111
  "manifest.append",
125079
125112
  {
125080
125113
  entry: {
125081
- type: "link",
125082
- entryId: researchId,
125083
- taskId
125084
- }
125085
- },
125086
- { command: "research" }
125087
- );
125088
- });
125089
- research.command("update <id>").description("Update research findings").option("--findings <findings>", "Comma-separated findings").option("--sources <sources>", "Comma-separated sources").option("-s, --status <status>", "Set status").action(async (id, opts) => {
125114
+ id: researchId,
125115
+ file: "",
125116
+ title: `Link: ${researchId} -> ${taskId}`,
125117
+ date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
125118
+ status: "partial",
125119
+ agent_type: "researcher",
125120
+ topics: [],
125121
+ key_findings: [],
125122
+ actionable: false,
125123
+ needs_followup: [],
125124
+ linked_tasks: [taskId]
125125
+ }
125126
+ },
125127
+ { command: "research", operation: "pipeline.manifest.append" }
125128
+ );
125129
+ });
125130
+ research.command("update <id>").description("Update research findings").option("--findings <findings>", "Comma-separated findings").option("--sources <sources>", "Comma-separated sources").option("-s, --status <status>", "Set status (completed, partial, blocked)").option("--topic <topic>", "Research topic (used as title)").action(async (id, opts) => {
125131
+ const findings = opts["findings"] ? opts["findings"].split(",").map((s3) => s3.trim()) : [];
125132
+ const status = opts["status"] ?? "partial";
125133
+ const topic = opts["topic"] ?? `Updated research: ${id}`;
125090
125134
  await dispatchFromCli(
125091
125135
  "mutate",
125092
125136
  "pipeline",
125093
125137
  "manifest.append",
125094
125138
  {
125095
125139
  entry: {
125096
- type: "update",
125097
- entryId: id,
125098
- findings: opts["findings"] ? opts["findings"].split(",").map((s3) => s3.trim()) : void 0,
125099
- sources: opts["sources"] ? opts["sources"].split(",").map((s3) => s3.trim()) : void 0,
125100
- status: opts["status"]
125140
+ id,
125141
+ file: "",
125142
+ title: topic,
125143
+ date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
125144
+ status,
125145
+ agent_type: "researcher",
125146
+ topics: topic !== `Updated research: ${id}` ? [topic] : [],
125147
+ key_findings: findings,
125148
+ actionable: findings.length > 0,
125149
+ needs_followup: [],
125150
+ linked_tasks: []
125101
125151
  }
125102
125152
  },
125103
- { command: "research" }
125153
+ { command: "research", operation: "pipeline.manifest.append" }
125104
125154
  );
125105
125155
  });
125106
125156
  research.command("stats").description("Show research statistics").action(async () => {
@@ -125341,7 +125391,7 @@ function registerRestoreCommand(program) {
125341
125391
  const fileName = opts["file"] || "tasks.db";
125342
125392
  const scope = opts["scope"] || "project";
125343
125393
  const response = await dispatchRaw("mutate", "admin", "backup", {
125344
- action: "restore",
125394
+ action: "restore.file",
125345
125395
  file: fileName,
125346
125396
  dryRun: opts["dryRun"],
125347
125397
  scope
@@ -125703,7 +125753,7 @@ init_src();
125703
125753
  init_internal();
125704
125754
  import { execFile as execFile8 } from "node:child_process";
125705
125755
  import { readFile as readFile22 } from "node:fs/promises";
125706
- import { join as join128 } from "node:path";
125756
+ import { join as join129 } from "node:path";
125707
125757
  import * as readline2 from "node:readline";
125708
125758
  import { promisify as promisify8 } from "node:util";
125709
125759
  init_renderers();
@@ -125712,7 +125762,7 @@ var GITHUB_REPO = BUILD_CONFIG.repository.fullName;
125712
125762
  async function getCurrentVersion() {
125713
125763
  const cleoHome = getCleoHome();
125714
125764
  try {
125715
- const content = await readFile22(join128(cleoHome, "VERSION"), "utf-8");
125765
+ const content = await readFile22(join129(cleoHome, "VERSION"), "utf-8");
125716
125766
  return (content.split("\n")[0] ?? "unknown").trim();
125717
125767
  } catch {
125718
125768
  return "unknown";
@@ -125766,7 +125816,7 @@ async function writeRuntimeVersionMetadata(mode, source, version2) {
125766
125816
  ];
125767
125817
  await import("node:fs/promises").then(
125768
125818
  ({ writeFile: writeFile15, mkdir: mkdir20 }) => mkdir20(cleoHome, { recursive: true }).then(
125769
- () => writeFile15(join128(cleoHome, "VERSION"), `${lines.join("\n")}
125819
+ () => writeFile15(join129(cleoHome, "VERSION"), `${lines.join("\n")}
125770
125820
  `, "utf-8")
125771
125821
  )
125772
125822
  );
@@ -126079,7 +126129,7 @@ function registerSessionCommand(program) {
126079
126129
  { command: "session", operation: "session.start" }
126080
126130
  );
126081
126131
  });
126082
- session.command("stop").alias("end").description("Stop the current session").option("--session <id>", "Specific session ID to stop").option("--note <note>", "Stop note").option("--next-action <action>", "Suggested next action").action(async (opts) => {
126132
+ session.command("end").alias("stop").description("End the current session").option("--session <id>", "Specific session ID to stop").option("--note <note>", "Stop note").option("--next-action <action>", "Suggested next action").action(async (opts) => {
126083
126133
  await dispatchFromCli(
126084
126134
  "mutate",
126085
126135
  "session",
@@ -126100,7 +126150,7 @@ function registerSessionCommand(program) {
126100
126150
  handleRawError(response, { command: "session handoff", operation: "session.handoff.show" });
126101
126151
  }
126102
126152
  const data = response.data;
126103
- if (!data || !data.handoff) {
126153
+ if (!data?.handoff) {
126104
126154
  cliOutput(
126105
126155
  { handoff: null },
126106
126156
  {
@@ -126244,7 +126294,7 @@ function registerSessionCommand(program) {
126244
126294
  { command: "session", operation: "session.record.assumption" }
126245
126295
  );
126246
126296
  });
126247
- session.command("record-decision").description("Record a decision made during the current session").requiredOption("--session-id <sessionId>", "Session ID").requiredOption("--task-id <taskId>", "Task ID the decision relates to").requiredOption("--decision <decision>", "Decision text").requiredOption("--rationale <rationale>", "Rationale for the decision").option("--alternatives <alternatives>", "Alternatives considered").action(async (opts) => {
126297
+ session.command("record-decision").description("Record a decision made during the current session").option("--session-id <sessionId>", "Session ID (defaults to active session)").requiredOption("--task-id <taskId>", "Task ID the decision relates to").requiredOption("--decision <decision>", "Decision text").requiredOption("--rationale <rationale>", "Rationale for the decision").option("--alternatives <alternatives>", "Alternatives considered").action(async (opts) => {
126248
126298
  await dispatchFromCli(
126249
126299
  "mutate",
126250
126300
  "session",
@@ -126520,44 +126570,6 @@ function registerSnapshotCommand(program) {
126520
126570
  });
126521
126571
  }
126522
126572
 
126523
- // packages/cleo/src/cli/commands/specification.ts
126524
- init_cli();
126525
- function registerSpecificationCommand(program) {
126526
- const specification = program.command("specification").description(
126527
- "Validate specification protocol compliance (alias for `cleo check protocol specification`)"
126528
- );
126529
- specification.command("validate <taskId>").description("Validate specification protocol compliance for task").option("--strict", "Exit with error code on violations").option("--spec-file <file>", "Path to specification file").action(async (taskId, opts) => {
126530
- await dispatchFromCli(
126531
- "query",
126532
- "check",
126533
- "protocol",
126534
- {
126535
- protocolType: "specification",
126536
- mode: "task",
126537
- taskId,
126538
- strict: opts["strict"],
126539
- specFile: opts["specFile"]
126540
- },
126541
- { command: "specification" }
126542
- );
126543
- });
126544
- specification.command("check <manifestFile>").description("Validate manifest entry directly").option("--strict", "Exit with error code on violations").option("--spec-file <file>", "Path to specification file").action(async (manifestFile, opts) => {
126545
- await dispatchFromCli(
126546
- "query",
126547
- "check",
126548
- "protocol",
126549
- {
126550
- protocolType: "specification",
126551
- mode: "manifest",
126552
- manifestFile,
126553
- strict: opts["strict"],
126554
- specFile: opts["specFile"]
126555
- },
126556
- { command: "specification" }
126557
- );
126558
- });
126559
- }
126560
-
126561
126573
  // packages/cleo/src/cli/commands/start.ts
126562
126574
  init_cli();
126563
126575
  function registerStartCommand(program) {
@@ -126601,15 +126613,17 @@ init_cli();
126601
126613
  init_renderers();
126602
126614
  function registerStickyCommand(program) {
126603
126615
  const sticky = program.command("sticky").description("Manage sticky notes - quick project-wide ephemeral captures");
126604
- sticky.command("add <content>").alias("jot").description("Create a new sticky note").option("--tag <tag>", "Add a tag (can be used multiple times)", collect, []).option("--color <color>", "Sticky color: yellow|blue|green|red|purple", "yellow").option("--priority <priority>", "Priority: low|medium|high", "medium").action(async (content, opts) => {
126616
+ sticky.command("add <content>").alias("jot").description("Create a new sticky note").option("--tag <tags>", 'Comma-separated tags (e.g. "bug,urgent")').option("--color <color>", "Sticky color: yellow|blue|green|red|purple", "yellow").option("--priority <priority>", "Priority: low|medium|high", "medium").action(async (content, opts) => {
126605
126617
  try {
126618
+ const rawTag = opts["tag"];
126619
+ const tags = rawTag ? rawTag.split(",").map((t) => t.trim()).filter(Boolean) : [];
126606
126620
  await dispatchFromCli(
126607
126621
  "mutate",
126608
126622
  "sticky",
126609
126623
  "add",
126610
126624
  {
126611
126625
  content,
126612
- tags: opts["tag"],
126626
+ tags,
126613
126627
  color: opts["color"],
126614
126628
  priority: opts["priority"]
126615
126629
  },
@@ -126623,10 +126637,12 @@ function registerStickyCommand(program) {
126623
126637
  throw err;
126624
126638
  }
126625
126639
  });
126626
- sticky.command("list").alias("ls").description("List active sticky notes").option("--tag <tag>", "Filter by tag").option("--color <color>", "Filter by color").option("--status <status>", "Filter by status: active|converted|archived", "active").option("--limit <n>", "Max results", parseInt, 50).action(async (opts) => {
126640
+ sticky.command("list").alias("ls").description("List active sticky notes").option("--tag <tags>", 'Filter by tags (comma-separated, e.g. "bug,urgent")').option("--color <color>", "Filter by color").option("--status <status>", "Filter by status: active|converted|archived", "active").option("--limit <n>", "Max results", parseInt, 50).action(async (opts) => {
126627
126641
  try {
126642
+ const rawTag = opts["tag"];
126643
+ const tags = rawTag ? rawTag.split(",").map((t) => t.trim()).filter(Boolean) : void 0;
126628
126644
  const response = await dispatchRaw("query", "sticky", "list", {
126629
- tag: opts["tag"],
126645
+ tags,
126630
126646
  color: opts["color"],
126631
126647
  status: opts["status"],
126632
126648
  limit: opts["limit"]
@@ -126765,9 +126781,6 @@ function registerStickyCommand(program) {
126765
126781
  }
126766
126782
  });
126767
126783
  }
126768
- function collect(value, previous) {
126769
- return previous.concat([value]);
126770
- }
126771
126784
 
126772
126785
  // packages/cleo/src/cli/commands/stop.ts
126773
126786
  init_cli();
@@ -126780,19 +126793,25 @@ function registerStopCommand(program) {
126780
126793
  }
126781
126794
 
126782
126795
  // packages/cleo/src/cli/commands/sync.ts
126796
+ init_src();
126783
126797
  init_cli();
126784
126798
  function registerSyncCommand(program) {
126785
126799
  const sync = program.command("sync").description("External task synchronisation management");
126786
126800
  const links = sync.command("links").description("List external task links");
126787
126801
  links.command("list").description("List external task links (filter by provider or task)").option("--provider <providerId>", "Filter links by provider (e.g. linear, jira, github)").option("--task <taskId>", "Filter links by CLEO task ID").action(async (opts) => {
126802
+ const providerId = opts["provider"];
126803
+ const taskId = opts["task"];
126804
+ if (!providerId && !taskId) {
126805
+ console.error(
126806
+ "Error: at least one of --provider or --task is required for sync links list"
126807
+ );
126808
+ process.exit(2 /* INVALID_INPUT */);
126809
+ }
126788
126810
  await dispatchFromCli(
126789
126811
  "query",
126790
126812
  "tasks",
126791
126813
  "sync.links",
126792
- {
126793
- providerId: opts["provider"],
126794
- taskId: opts["task"]
126795
- },
126814
+ { providerId, taskId },
126796
126815
  { command: "sync", operation: "tasks.sync.links" }
126797
126816
  );
126798
126817
  });
@@ -127144,26 +127163,6 @@ function registerUpgradeCommand(program) {
127144
127163
  });
127145
127164
  }
127146
127165
 
127147
- // packages/cleo/src/cli/commands/validate.ts
127148
- init_cli();
127149
- function registerValidateCommand(program) {
127150
- program.command("validate").description(
127151
- "DEPRECATED: Use `cleo check schema todo` instead. Validate task data against schema and business rules"
127152
- ).option("--strict", "Treat warnings as errors").action(async (opts) => {
127153
- console.error("[DEPRECATED] cleo validate is deprecated. Use: cleo check schema todo");
127154
- await dispatchFromCli(
127155
- "query",
127156
- "check",
127157
- "schema",
127158
- {
127159
- type: "todo",
127160
- strict: opts["strict"]
127161
- },
127162
- { command: "validate", operation: "check.schema" }
127163
- );
127164
- });
127165
- }
127166
-
127167
127166
  // packages/cleo/src/cli/commands/verify.ts
127168
127167
  init_cli();
127169
127168
  function registerVerifyCommand(program) {
@@ -127192,15 +127191,15 @@ init_src2();
127192
127191
  init_renderers();
127193
127192
  import { execFileSync as execFileSync18, spawn as spawn2 } from "node:child_process";
127194
127193
  import { mkdir as mkdir19, readFile as readFile23, rm as rm3, stat as stat3, writeFile as writeFile14 } from "node:fs/promises";
127195
- import { join as join129 } from "node:path";
127194
+ import { join as join130 } from "node:path";
127196
127195
  var DEFAULT_PORT = 3456;
127197
127196
  var DEFAULT_HOST = "127.0.0.1";
127198
127197
  function getWebPaths() {
127199
127198
  const cleoHome = getCleoHome();
127200
127199
  return {
127201
- pidFile: join129(cleoHome, "web-server.pid"),
127202
- configFile: join129(cleoHome, "web-server.json"),
127203
- logFile: join129(cleoHome, "logs", "web-server.log")
127200
+ pidFile: join130(cleoHome, "web-server.pid"),
127201
+ configFile: join130(cleoHome, "web-server.json"),
127202
+ logFile: join130(cleoHome, "logs", "web-server.log")
127204
127203
  };
127205
127204
  }
127206
127205
  function isProcessRunning(pid) {
@@ -127247,8 +127246,8 @@ function registerWebCommand(program) {
127247
127246
  );
127248
127247
  }
127249
127248
  const projectRoot = process.env["CLEO_ROOT"] ?? process.cwd();
127250
- const distServerDir = join129(projectRoot, "dist", "cli");
127251
- await mkdir19(join129(getCleoHome(), "logs"), { recursive: true });
127249
+ const distServerDir = join130(projectRoot, "dist", "cli");
127250
+ await mkdir19(join130(getCleoHome(), "logs"), { recursive: true });
127252
127251
  await writeFile14(
127253
127252
  configFile,
127254
127253
  JSON.stringify({
@@ -127257,7 +127256,7 @@ function registerWebCommand(program) {
127257
127256
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
127258
127257
  })
127259
127258
  );
127260
- const webIndexPath = join129(distServerDir, "index.js");
127259
+ const webIndexPath = join130(distServerDir, "index.js");
127261
127260
  try {
127262
127261
  await stat3(webIndexPath);
127263
127262
  } catch {
@@ -127423,9 +127422,9 @@ var codeCommand = defineCommand({
127423
127422
  async run({ args }) {
127424
127423
  await requireTreeSitter();
127425
127424
  const { smartOutline: smartOutline2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
127426
- const { join: join131 } = await import("node:path");
127425
+ const { join: join132 } = await import("node:path");
127427
127426
  const root = process.cwd();
127428
- const absPath = args.file.startsWith("/") ? args.file : join131(root, args.file);
127427
+ const absPath = args.file.startsWith("/") ? args.file : join132(root, args.file);
127429
127428
  const result = smartOutline2(absPath, root);
127430
127429
  if (result.errors.length > 0 && result.symbols.length === 0) {
127431
127430
  console.error(`Error: ${result.errors.join(", ")}`);
@@ -127491,9 +127490,9 @@ var codeCommand = defineCommand({
127491
127490
  async run({ args }) {
127492
127491
  await requireTreeSitter();
127493
127492
  const { smartUnfold: smartUnfold2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
127494
- const { join: join131 } = await import("node:path");
127493
+ const { join: join132 } = await import("node:path");
127495
127494
  const root = process.cwd();
127496
- const absPath = args.file.startsWith("/") ? args.file : join131(root, args.file);
127495
+ const absPath = args.file.startsWith("/") ? args.file : join132(root, args.file);
127497
127496
  const result = smartUnfold2(absPath, args.symbol, root);
127498
127497
  if (!result.found) {
127499
127498
  console.error(`Symbol "${args.symbol}" not found in ${args.file}`);
@@ -127512,7 +127511,7 @@ var codeCommand = defineCommand({
127512
127511
 
127513
127512
  // packages/cleo/src/cli/index.ts
127514
127513
  function getPackageVersion() {
127515
- const pkgPath = join130(dirname28(fileURLToPath5(import.meta.url)), "../../package.json");
127514
+ const pkgPath = join131(dirname29(fileURLToPath6(import.meta.url)), "../../package.json");
127516
127515
  const pkg = JSON.parse(readFileSync101(pkgPath, "utf-8"));
127517
127516
  return pkg.version;
127518
127517
  }
@@ -127542,7 +127541,6 @@ registerChainCommand(rootShim);
127542
127541
  registerLifecycleCommand(rootShim);
127543
127542
  registerReleaseCommand(rootShim);
127544
127543
  registerCheckpointCommand(rootShim);
127545
- registerCommandsCommand(rootShim);
127546
127544
  registerDocsCommand(rootShim);
127547
127545
  registerExportTasksCommand(rootShim);
127548
127546
  registerImportTasksCommand(rootShim);
@@ -127570,15 +127568,11 @@ registerBlockersCommand(rootShim);
127570
127568
  registerCheckCommand(rootShim);
127571
127569
  registerComplianceCommand(rootShim);
127572
127570
  registerConfigCommand(rootShim);
127573
- registerConsensusCommand(rootShim);
127574
127571
  registerContextCommand(rootShim);
127575
- registerContributionCommand(rootShim);
127576
127572
  registerDashCommand(rootShim);
127577
- registerDecompositionCommand(rootShim);
127578
127573
  registerDoctorCommand(rootShim);
127579
127574
  registerExportCommand(rootShim);
127580
127575
  registerHistoryCommand(rootShim);
127581
- registerImplementationCommand(rootShim);
127582
127576
  registerImportCommand(rootShim);
127583
127577
  registerInitCommand(rootShim);
127584
127578
  registerInjectCommand(rootShim);
@@ -127588,7 +127582,6 @@ registerNextCommand(rootShim);
127588
127582
  registerPlanCommand(rootShim);
127589
127583
  registerOtelCommand(rootShim);
127590
127584
  registerTokenCommand(rootShim);
127591
- registerPhasesCommand(rootShim);
127592
127585
  registerPromoteCommand(rootShim);
127593
127586
  registerRelatesCommand(rootShim);
127594
127587
  registerReorderCommand(rootShim);
@@ -127597,10 +127590,8 @@ registerRestoreCommand(rootShim);
127597
127590
  registerRoadmapCommand(rootShim);
127598
127591
  registerSelfUpdateCommand(rootShim);
127599
127592
  registerSequenceCommand(rootShim);
127600
- registerSpecificationCommand(rootShim);
127601
127593
  registerStatsCommand(rootShim);
127602
127594
  registerUpgradeCommand(rootShim);
127603
- registerValidateCommand(rootShim);
127604
127595
  registerVerifyCommand(rootShim);
127605
127596
  registerDetectCommand(rootShim);
127606
127597
  registerDetectDriftCommand(rootShim);
@@ -127618,7 +127609,6 @@ registerMigrateClaudeMemCommand(rootShim);
127618
127609
  registerStickyCommand(rootShim);
127619
127610
  registerReasonCommand(rootShim);
127620
127611
  registerRefreshMemoryCommand(rootShim);
127621
- registerObserveCommand(rootShim);
127622
127612
  registerSchemaCommand(rootShim);
127623
127613
  function shimToCitty(shim) {
127624
127614
  const cittyArgs = {};