@cleocode/cleo 2026.3.61 → 2026.3.63

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
@@ -10670,6 +10670,25 @@ function runBrainMigrations(nativeDb, db) {
10670
10670
  );
10671
10671
  }
10672
10672
  }
10673
+ if (tableExists(nativeDb, "__drizzle_migrations") && tableExists(nativeDb, "brain_decisions")) {
10674
+ const localMigrations = readMigrationFiles({ migrationsFolder });
10675
+ const localHashes = new Set(localMigrations.map((m) => m.hash));
10676
+ const dbEntries = nativeDb.prepare('SELECT hash FROM "__drizzle_migrations"').all();
10677
+ const hasOrphanedEntries = dbEntries.some((e) => !localHashes.has(e.hash));
10678
+ if (hasOrphanedEntries) {
10679
+ const log11 = getLogger("brain");
10680
+ log11.warn(
10681
+ { orphaned: dbEntries.filter((e) => !localHashes.has(e.hash)).length },
10682
+ "Detected stale migration journal entries from a previous CLEO version. Reconciling brain.db."
10683
+ );
10684
+ nativeDb.exec('DELETE FROM "__drizzle_migrations"');
10685
+ for (const m of localMigrations) {
10686
+ nativeDb.exec(
10687
+ `INSERT INTO "__drizzle_migrations" ("hash", "created_at") VALUES ('${m.hash}', ${m.folderMillis})`
10688
+ );
10689
+ }
10690
+ }
10691
+ }
10673
10692
  const MAX_RETRIES = 5;
10674
10693
  const BASE_DELAY_MS = 100;
10675
10694
  const MAX_DELAY_MS = 2e3;
@@ -10777,6 +10796,7 @@ var init_brain_sqlite = __esm({
10777
10796
  init_migrator();
10778
10797
  init_node_sqlite();
10779
10798
  init_migrator2();
10799
+ init_logger();
10780
10800
  init_paths();
10781
10801
  init_brain_schema();
10782
10802
  init_sqlite2();
@@ -13259,7 +13279,7 @@ async function showSequence(cwd) {
13259
13279
  counter: seq.counter,
13260
13280
  lastId: seq.lastId,
13261
13281
  checksum: seq.checksum,
13262
- nextId: `T${seq.counter + 1}`
13282
+ nextId: `T${String(seq.counter + 1).padStart(3, "0")}`
13263
13283
  };
13264
13284
  }
13265
13285
  async function loadAllTasks(cwd, accessor) {
@@ -41812,6 +41832,58 @@ async function addTask(options, cwd, accessor) {
41812
41832
  if (duplicate) {
41813
41833
  return { task: duplicate, duplicate: true };
41814
41834
  }
41835
+ if (options.dryRun) {
41836
+ const previewNow = (/* @__PURE__ */ new Date()).toISOString();
41837
+ let previewParentForStage = null;
41838
+ if (parentId) {
41839
+ const previewParentTask = await dataAccessor.loadSingleTask(parentId);
41840
+ previewParentForStage = previewParentTask ? { pipelineStage: previewParentTask.pipelineStage, type: previewParentTask.type } : null;
41841
+ }
41842
+ const previewPipelineStage = resolveDefaultPipelineStage({
41843
+ explicitStage: options.pipelineStage,
41844
+ taskType: taskType ?? null,
41845
+ parentTask: previewParentForStage
41846
+ });
41847
+ const previewPosition = options.position !== void 0 ? options.position : await dataAccessor.getNextPosition(parentId);
41848
+ const previewTask = {
41849
+ id: "T???",
41850
+ title: options.title,
41851
+ description: options.description,
41852
+ status,
41853
+ priority,
41854
+ type: taskType,
41855
+ parentId: parentId || null,
41856
+ position: previewPosition,
41857
+ positionVersion: 0,
41858
+ size,
41859
+ pipelineStage: previewPipelineStage,
41860
+ createdAt: previewNow,
41861
+ updatedAt: previewNow
41862
+ };
41863
+ if (phase) previewTask.phase = phase;
41864
+ if (options.labels?.length) previewTask.labels = options.labels.map((l) => l.trim());
41865
+ if (options.files?.length) previewTask.files = options.files.map((f) => f.trim());
41866
+ if (options.acceptance?.length)
41867
+ previewTask.acceptance = options.acceptance.map((a) => a.trim());
41868
+ if (options.depends?.length) previewTask.depends = options.depends.map((d) => d.trim());
41869
+ if (options.notes) {
41870
+ const previewNote = `${(/* @__PURE__ */ new Date()).toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC")}: ${options.notes}`;
41871
+ previewTask.notes = [previewNote];
41872
+ }
41873
+ if (status === "blocked" && options.description) {
41874
+ previewTask.blockedBy = options.description;
41875
+ }
41876
+ if (status === "done") {
41877
+ previewTask.completedAt = previewNow;
41878
+ }
41879
+ if (taskType !== "epic") {
41880
+ const verificationEnabledRaw = await getRawConfigValue("verification.enabled", cwd);
41881
+ if (verificationEnabledRaw === true) {
41882
+ previewTask.verification = buildDefaultVerification(previewNow);
41883
+ }
41884
+ }
41885
+ return { task: previewTask, dryRun: true };
41886
+ }
41815
41887
  const taskId = await allocateNextTaskId(cwd);
41816
41888
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
41817
41889
  let resolvedParentForStage = null;
@@ -41881,9 +41953,6 @@ async function addTask(options, cwd, accessor) {
41881
41953
  task.verification = buildDefaultVerification(now2);
41882
41954
  }
41883
41955
  }
41884
- if (options.dryRun) {
41885
- return { task, dryRun: true };
41886
- }
41887
41956
  await dataAccessor.transaction(async (tx) => {
41888
41957
  if (options.position !== void 0) {
41889
41958
  await dataAccessor.shiftPositions(parentId, options.position, 1);
@@ -47795,8 +47864,9 @@ var init_observability = __esm({
47795
47864
  });
47796
47865
 
47797
47866
  // packages/core/src/phases/deps.ts
47798
- async function loadAllTasks3(_cwd, accessor) {
47799
- const { tasks: tasks2 } = await accessor.queryTasks({});
47867
+ async function loadAllTasks3(cwd, accessor) {
47868
+ const acc = accessor ?? await getAccessor(cwd);
47869
+ const { tasks: tasks2 } = await acc.queryTasks({});
47800
47870
  return tasks2;
47801
47871
  }
47802
47872
  function buildGraph(tasks2) {
@@ -47872,11 +47942,45 @@ async function getExecutionWaves(epicId, cwd, accessor) {
47872
47942
  }
47873
47943
  return waves;
47874
47944
  }
47945
+ async function getCriticalPath2(taskId, cwd, accessor) {
47946
+ const allTasks = await loadAllTasks3(cwd, accessor);
47947
+ const task = allTasks.find((t) => t.id === taskId);
47948
+ if (!task) {
47949
+ throw new CleoError(4 /* NOT_FOUND */, `Task not found: ${taskId}`);
47950
+ }
47951
+ const graph = buildGraph(allTasks);
47952
+ const taskMap = new Map(allTasks.map((t) => [t.id, t]));
47953
+ function findLongestPath(id, visited) {
47954
+ if (visited.has(id)) return [];
47955
+ visited.add(id);
47956
+ const node = graph.get(id);
47957
+ if (!node || node.dependents.length === 0) {
47958
+ return [id];
47959
+ }
47960
+ let longest = [];
47961
+ for (const depId of node.dependents) {
47962
+ const path3 = findLongestPath(depId, new Set(visited));
47963
+ if (path3.length > longest.length) {
47964
+ longest = path3;
47965
+ }
47966
+ }
47967
+ return [id, ...longest];
47968
+ }
47969
+ const path2 = findLongestPath(taskId, /* @__PURE__ */ new Set());
47970
+ return {
47971
+ path: path2.map((id) => {
47972
+ const t = taskMap.get(id);
47973
+ return t ? { id: t.id, title: t.title, status: t.status } : { id, title: "Unknown", status: "unknown" };
47974
+ }),
47975
+ length: path2.length
47976
+ };
47977
+ }
47875
47978
  var init_deps2 = __esm({
47876
47979
  "packages/core/src/phases/deps.ts"() {
47877
47980
  "use strict";
47878
47981
  init_src();
47879
47982
  init_errors3();
47983
+ init_data_accessor();
47880
47984
  }
47881
47985
  });
47882
47986
 
@@ -52678,6 +52782,13 @@ var init_capability_matrix = __esm({
52678
52782
  mode: "native",
52679
52783
  preferredChannel: "either"
52680
52784
  },
52785
+ {
52786
+ domain: "admin",
52787
+ operation: "backup",
52788
+ gateway: "query",
52789
+ mode: "native",
52790
+ preferredChannel: "either"
52791
+ },
52681
52792
  {
52682
52793
  domain: "admin",
52683
52794
  operation: "backup",
@@ -57927,7 +58038,7 @@ async function getProjectStats(opts, accessor) {
57927
58038
  dbAnd(dbEq(tasksTable.status, "archived"), dbEq(tasksTable.archiveReason, "completed"))
57928
58039
  ).get();
57929
58040
  archivedCompleted = archivedDoneRow?.c ?? 0;
57930
- totalCompleted = (statusMap["done"] ?? 0) + archivedCompleted;
58041
+ totalCompleted = entries.filter(isComplete).length;
57931
58042
  } catch {
57932
58043
  totalCreated = entries.filter(isCreate).length;
57933
58044
  totalCompleted = entries.filter(isComplete).length;
@@ -58933,7 +59044,7 @@ var init_audit2 = __esm({
58933
59044
  });
58934
59045
 
58935
59046
  // packages/core/src/system/backup.ts
58936
- import { existsSync as existsSync82, mkdirSync as mkdirSync18, readFileSync as readFileSync59, writeFileSync as writeFileSync11 } from "node:fs";
59047
+ import { existsSync as existsSync82, mkdirSync as mkdirSync18, readdirSync as readdirSync27, readFileSync as readFileSync59, writeFileSync as writeFileSync11 } from "node:fs";
58937
59048
  import { join as join84 } from "node:path";
58938
59049
  function createBackup2(projectRoot, opts) {
58939
59050
  const cleoDir = join84(projectRoot, ".cleo");
@@ -58979,6 +59090,36 @@ function createBackup2(projectRoot, opts) {
58979
59090
  }
58980
59091
  return { backupId, path: backupDir, timestamp: timestamp2, type: btype, files: backedUp };
58981
59092
  }
59093
+ function listSystemBackups(projectRoot) {
59094
+ const cleoDir = join84(projectRoot, ".cleo");
59095
+ const backupTypes = ["snapshot", "safety", "migration"];
59096
+ const entries = [];
59097
+ for (const btype of backupTypes) {
59098
+ const backupDir = join84(cleoDir, "backups", btype);
59099
+ if (!existsSync82(backupDir)) continue;
59100
+ try {
59101
+ const files = readdirSync27(backupDir).filter((f) => f.endsWith(".meta.json"));
59102
+ for (const metaFile of files) {
59103
+ try {
59104
+ const raw = readFileSync59(join84(backupDir, metaFile), "utf-8");
59105
+ const meta = JSON.parse(raw);
59106
+ if (meta.backupId && meta.timestamp) {
59107
+ entries.push({
59108
+ backupId: meta.backupId,
59109
+ type: meta.type ?? btype,
59110
+ timestamp: meta.timestamp,
59111
+ note: meta.note,
59112
+ files: meta.files ?? []
59113
+ });
59114
+ }
59115
+ } catch {
59116
+ }
59117
+ }
59118
+ } catch {
59119
+ }
59120
+ }
59121
+ return entries.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
59122
+ }
58982
59123
  function restoreBackup(projectRoot, params) {
58983
59124
  if (!params.backupId) {
58984
59125
  throw new CleoError(2 /* INVALID_INPUT */, "backupId is required");
@@ -59103,7 +59244,7 @@ var init_audit_prune = __esm({
59103
59244
  });
59104
59245
 
59105
59246
  // packages/core/src/system/cleanup.ts
59106
- import { existsSync as existsSync83, readdirSync as readdirSync27, readFileSync as readFileSync60, unlinkSync as unlinkSync5, writeFileSync as writeFileSync12 } from "node:fs";
59247
+ import { existsSync as existsSync83, readdirSync as readdirSync28, readFileSync as readFileSync60, unlinkSync as unlinkSync5, writeFileSync as writeFileSync12 } from "node:fs";
59107
59248
  import { join as join86 } from "node:path";
59108
59249
  async function cleanupSystem(projectRoot, params) {
59109
59250
  if (!params.target) {
@@ -59151,10 +59292,10 @@ async function cleanupSystem(projectRoot, params) {
59151
59292
  case "backups": {
59152
59293
  const backupBaseDir = join86(cleoDir, "backups");
59153
59294
  if (existsSync83(backupBaseDir)) {
59154
- for (const typeDir of readdirSync27(backupBaseDir)) {
59295
+ for (const typeDir of readdirSync28(backupBaseDir)) {
59155
59296
  const fullDir = join86(backupBaseDir, typeDir);
59156
59297
  try {
59157
- for (const file2 of readdirSync27(fullDir)) {
59298
+ for (const file2 of readdirSync28(fullDir)) {
59158
59299
  if (file2.endsWith(".meta.json")) {
59159
59300
  const metaFilePath = join86(fullDir, file2);
59160
59301
  try {
@@ -59163,7 +59304,7 @@ async function cleanupSystem(projectRoot, params) {
59163
59304
  items.push(file2.replace(".meta.json", ""));
59164
59305
  if (!dryRun) {
59165
59306
  unlinkSync5(metaFilePath);
59166
- for (const bf of readdirSync27(fullDir)) {
59307
+ for (const bf of readdirSync28(fullDir)) {
59167
59308
  if (bf.includes(meta.backupId)) {
59168
59309
  try {
59169
59310
  unlinkSync5(join86(fullDir, bf));
@@ -59193,7 +59334,7 @@ async function cleanupSystem(projectRoot, params) {
59193
59334
  }
59194
59335
  const auditPattern = /^audit-log-.*\.json$/;
59195
59336
  if (existsSync83(cleoDir)) {
59196
- for (const file2 of readdirSync27(cleoDir)) {
59337
+ for (const file2 of readdirSync28(cleoDir)) {
59197
59338
  if (auditPattern.test(file2)) {
59198
59339
  items.push(file2);
59199
59340
  if (!dryRun) {
@@ -59353,7 +59494,7 @@ import { randomBytes as randomBytes12 } from "node:crypto";
59353
59494
  import {
59354
59495
  existsSync as existsSync85,
59355
59496
  mkdirSync as mkdirSync20,
59356
- readdirSync as readdirSync28,
59497
+ readdirSync as readdirSync29,
59357
59498
  readFileSync as readFileSync61,
59358
59499
  renameSync as renameSync6,
59359
59500
  unlinkSync as unlinkSync6,
@@ -62421,7 +62562,7 @@ var init_tasks2 = __esm({
62421
62562
  });
62422
62563
 
62423
62564
  // packages/core/src/templates/parser.ts
62424
- import { existsSync as existsSync93, readdirSync as readdirSync29, readFileSync as readFileSync67 } from "fs";
62565
+ import { existsSync as existsSync93, readdirSync as readdirSync30, readFileSync as readFileSync67 } from "fs";
62425
62566
  import { join as join96 } from "path";
62426
62567
  import { parse as parseYaml } from "yaml";
62427
62568
  function deriveSubcommand(filename) {
@@ -62495,7 +62636,7 @@ function parseIssueTemplates2(projectRoot) {
62495
62636
  }
62496
62637
  let files;
62497
62638
  try {
62498
- files = readdirSync29(templateDir).filter((f) => /\.ya?ml$/i.test(f) && f !== "config.yml");
62639
+ files = readdirSync30(templateDir).filter((f) => /\.ya?ml$/i.test(f) && f !== "config.yml");
62499
62640
  } catch (error40) {
62500
62641
  return {
62501
62642
  success: false,
@@ -62908,7 +63049,7 @@ var init_changelog = __esm({
62908
63049
  });
62909
63050
 
62910
63051
  // packages/core/src/ui/command-registry.ts
62911
- import { existsSync as existsSync96, readdirSync as readdirSync30, readFileSync as readFileSync70 } from "node:fs";
63052
+ import { existsSync as existsSync96, readdirSync as readdirSync31, readFileSync as readFileSync70 } from "node:fs";
62912
63053
  import { basename as basename16, join as join98 } from "node:path";
62913
63054
  function parseCommandHeader(scriptPath) {
62914
63055
  if (!existsSync96(scriptPath)) return null;
@@ -62991,7 +63132,7 @@ function parseCommandHeader(scriptPath) {
62991
63132
  function scanAllCommands(scriptsDir) {
62992
63133
  const registry2 = /* @__PURE__ */ new Map();
62993
63134
  if (!existsSync96(scriptsDir)) return registry2;
62994
- for (const file2 of readdirSync30(scriptsDir)) {
63135
+ for (const file2 of readdirSync31(scriptsDir)) {
62995
63136
  if (!file2.endsWith(".sh") && !file2.endsWith(".ts")) continue;
62996
63137
  const meta = parseCommandHeader(join98(scriptsDir, file2));
62997
63138
  if (meta) {
@@ -63919,12 +64060,12 @@ var init_compliance2 = __esm({
63919
64060
  });
63920
64061
 
63921
64062
  // packages/core/src/validation/docs-sync.ts
63922
- import { existsSync as existsSync97, readdirSync as readdirSync31, readFileSync as readFileSync71 } from "node:fs";
64063
+ import { existsSync as existsSync97, readdirSync as readdirSync32, readFileSync as readFileSync71 } from "node:fs";
63923
64064
  import { join as join99 } from "node:path";
63924
64065
  function getScriptCommands(scriptsDir) {
63925
64066
  if (!existsSync97(scriptsDir)) return [];
63926
64067
  try {
63927
- return readdirSync31(scriptsDir).filter((f) => f.endsWith(".sh")).map((f) => f.replace(/\.sh$/, "")).sort();
64068
+ return readdirSync32(scriptsDir).filter((f) => f.endsWith(".sh")).map((f) => f.replace(/\.sh$/, "")).sort();
63928
64069
  } catch {
63929
64070
  return [];
63930
64071
  }
@@ -65346,12 +65487,12 @@ var init_manifest = __esm({
65346
65487
  });
65347
65488
 
65348
65489
  // packages/core/src/validation/protocol-common.ts
65349
- import { existsSync as existsSync100, readdirSync as readdirSync32, readFileSync as readFileSync73 } from "node:fs";
65490
+ import { existsSync as existsSync100, readdirSync as readdirSync33, readFileSync as readFileSync73 } from "node:fs";
65350
65491
  function checkOutputFileExists(taskId, expectedDir, pattern) {
65351
65492
  if (!existsSync100(expectedDir)) return false;
65352
65493
  const filePattern = pattern ?? `${taskId}`;
65353
65494
  try {
65354
- const files = readdirSync32(expectedDir);
65495
+ const files = readdirSync33(expectedDir);
65355
65496
  return files.some((f) => f.includes(filePattern) && f.endsWith(".md"));
65356
65497
  } catch {
65357
65498
  return false;
@@ -66330,7 +66471,7 @@ __export(init_exports, {
66330
66471
  isAutoInitEnabled: () => isAutoInitEnabled,
66331
66472
  updateDocs: () => updateDocs
66332
66473
  });
66333
- import { existsSync as existsSync101, readdirSync as readdirSync33, readFileSync as readFileSync74 } from "node:fs";
66474
+ import { existsSync as existsSync101, readdirSync as readdirSync34, readFileSync as readFileSync74 } from "node:fs";
66334
66475
  import { copyFile as copyFile3, lstat, mkdir as mkdir16, readFile as readFile17, symlink, unlink as unlink4, writeFile as writeFile11 } from "node:fs/promises";
66335
66476
  import { platform as platform4 } from "node:os";
66336
66477
  import { basename as basename17, dirname as dirname19, join as join101 } from "node:path";
@@ -66380,7 +66521,7 @@ async function initAgentDefinition(created, warnings) {
66380
66521
  } catch (_err) {
66381
66522
  try {
66382
66523
  await mkdir16(globalAgentsDir, { recursive: true });
66383
- const files = readdirSync33(agentSourceDir);
66524
+ const files = readdirSync34(agentSourceDir);
66384
66525
  for (const file2 of files) {
66385
66526
  await copyFile3(join101(agentSourceDir, file2), join101(globalAgentsDir, file2));
66386
66527
  }
@@ -66529,7 +66670,7 @@ async function installGitHubTemplates(projectRoot, created, skipped) {
66529
66670
  await mkdir16(issueTemplateDir, { recursive: true });
66530
66671
  const issueSrcDir = join101(templateSrcDir, "ISSUE_TEMPLATE");
66531
66672
  if (existsSync101(issueSrcDir)) {
66532
- const issueFiles = readdirSync33(issueSrcDir);
66673
+ const issueFiles = readdirSync34(issueSrcDir);
66533
66674
  for (const file2 of issueFiles) {
66534
66675
  const dest = join101(issueTemplateDir, file2);
66535
66676
  if (existsSync101(dest)) {
@@ -71562,7 +71703,7 @@ var init_model_provider_registry = __esm({
71562
71703
 
71563
71704
  // packages/core/src/metrics/token-service.ts
71564
71705
  import { createHash as createHash13, randomUUID as randomUUID8 } from "node:crypto";
71565
- import { existsSync as existsSync107, readdirSync as readdirSync34, readFileSync as readFileSync79 } from "node:fs";
71706
+ import { existsSync as existsSync107, readdirSync as readdirSync35, readFileSync as readFileSync79 } from "node:fs";
71566
71707
  import { join as join106 } from "node:path";
71567
71708
  function normalizeProvider(provider, model, runtimeProvider) {
71568
71709
  const value = (provider ?? "").trim().toLowerCase();
@@ -71647,7 +71788,7 @@ function getOtelDir2() {
71647
71788
  function readOtelJsonl(dir) {
71648
71789
  if (!existsSync107(dir)) return [];
71649
71790
  const entries = [];
71650
- for (const file2 of readdirSync34(dir)) {
71791
+ for (const file2 of readdirSync35(dir)) {
71651
71792
  if (!file2.endsWith(".json") && !file2.endsWith(".jsonl")) continue;
71652
71793
  const filePath = join106(dir, file2);
71653
71794
  const raw = readFileSync79(filePath, "utf-8").trim();
@@ -72039,7 +72180,7 @@ var init_parallel = __esm({
72039
72180
  });
72040
72181
 
72041
72182
  // packages/core/src/orchestration/skill-ops.ts
72042
- import { existsSync as existsSync108, readdirSync as readdirSync35, readFileSync as readFileSync80 } from "node:fs";
72183
+ import { existsSync as existsSync108, readdirSync as readdirSync36, readFileSync as readFileSync80 } from "node:fs";
72043
72184
  import { join as join107 } from "node:path";
72044
72185
  import { getCanonicalSkillsDir as getCanonicalSkillsDir3 } from "@cleocode/caamp";
72045
72186
  function getSkillContent(skillName, projectRoot) {
@@ -72064,7 +72205,7 @@ function getSkillContent(skillName, projectRoot) {
72064
72205
  let references = [];
72065
72206
  if (existsSync108(refsDir)) {
72066
72207
  try {
72067
- references = readdirSync35(refsDir).filter((f) => f.endsWith(".md") || f.endsWith(".txt")).map((f) => ({
72208
+ references = readdirSync36(refsDir).filter((f) => f.endsWith(".md") || f.endsWith(".txt")).map((f) => ({
72068
72209
  name: f,
72069
72210
  path: join107(skillDir, "references", f)
72070
72211
  }));
@@ -74778,7 +74919,7 @@ import {
74778
74919
  copyFileSync as copyFileSync7,
74779
74920
  existsSync as existsSync111,
74780
74921
  mkdirSync as mkdirSync23,
74781
- readdirSync as readdirSync36,
74922
+ readdirSync as readdirSync37,
74782
74923
  readFileSync as readFileSync83,
74783
74924
  writeFileSync as writeFileSync20
74784
74925
  } from "node:fs";
@@ -74991,7 +75132,7 @@ async function runUpgrade(options = {}) {
74991
75132
  const dbPath2 = join109(cleoDir2, "tasks.db");
74992
75133
  const safetyDir = join109(cleoDir2, "backups", "safety");
74993
75134
  if (existsSync111(safetyDir)) {
74994
- const backups = readdirSync36(safetyDir).filter((f) => f.startsWith("tasks.db.pre-migration.")).sort().reverse();
75135
+ const backups = readdirSync37(safetyDir).filter((f) => f.startsWith("tasks.db.pre-migration.")).sort().reverse();
74995
75136
  if (backups.length > 0 && !existsSync111(dbPath2)) {
74996
75137
  copyFileSync7(join109(safetyDir, backups[0]), dbPath2);
74997
75138
  }
@@ -77918,7 +78059,7 @@ var init_bootstrap2 = __esm({
77918
78059
  });
77919
78060
 
77920
78061
  // packages/core/src/orchestration/critical-path.ts
77921
- async function getCriticalPath2(cwd, accessor) {
78062
+ async function getCriticalPath3(cwd, accessor) {
77922
78063
  const acc = accessor ?? await getAccessor(cwd);
77923
78064
  const { tasks: tasks2 } = await acc.queryTasks({});
77924
78065
  if (tasks2.length === 0) {
@@ -78539,6 +78680,7 @@ __export(internal_exports, {
78539
78680
  deletePhase: () => deletePhase,
78540
78681
  deleteTask: () => deleteTask,
78541
78682
  deleteTokenUsage: () => deleteTokenUsage,
78683
+ depsCriticalPath: () => getCriticalPath2,
78542
78684
  deregisterAgent: () => deregisterAgent,
78543
78685
  describeChannel: () => describeChannel,
78544
78686
  detectCrashedAgents: () => detectCrashedAgents,
@@ -78680,6 +78822,7 @@ __export(internal_exports, {
78680
78822
  getSystemInfo: () => getSystemInfo2,
78681
78823
  getSystemMetrics: () => getSystemMetrics,
78682
78824
  getSystemMigrationStatus: () => getMigrationStatus2,
78825
+ getTask: () => getTask,
78683
78826
  getTaskHistory: () => getTaskHistory,
78684
78827
  getTaskPath: () => getTaskPath,
78685
78828
  getTemplateForSubcommand: () => getTemplateForSubcommand2,
@@ -78755,6 +78898,7 @@ __export(internal_exports, {
78755
78898
  listSessions: () => listSessions,
78756
78899
  listStickies: () => listStickies,
78757
78900
  listStrictnessPresets: () => listStrictnessPresets,
78901
+ listSystemBackups: () => listSystemBackups,
78758
78902
  listTasks: () => listTasks,
78759
78903
  listTesseraTemplates: () => listTesseraTemplates,
78760
78904
  listTokenUsage: () => listTokenUsage,
@@ -78815,7 +78959,7 @@ __export(internal_exports, {
78815
78959
  ops: () => operations_exports,
78816
78960
  orchestration: () => orchestration_exports,
78817
78961
  orchestrationAnalyzeDependencies: () => analyzeDependencies,
78818
- orchestrationGetCriticalPath: () => getCriticalPath2,
78962
+ orchestrationGetCriticalPath: () => getCriticalPath3,
78819
78963
  orchestrationGetNextTask: () => getNextTask,
78820
78964
  orchestrationGetReadyTasks: () => getReadyTasks2,
78821
78965
  orphanDetection: () => orphanDetection,
@@ -79049,6 +79193,7 @@ var init_internal = __esm({
79049
79193
  init_waves();
79050
79194
  init_otel();
79051
79195
  init_paths();
79196
+ init_deps2();
79052
79197
  init_phases();
79053
79198
  init_pipeline2();
79054
79199
  init_platform();
@@ -82903,6 +83048,16 @@ var OPERATIONS = [
82903
83048
  }
82904
83049
  ]
82905
83050
  },
83051
+ {
83052
+ gateway: "query",
83053
+ domain: "admin",
83054
+ operation: "backup",
83055
+ description: "admin.backup (query) \u2014 list available backups (read-only)",
83056
+ tier: 1,
83057
+ idempotent: true,
83058
+ sessionRequired: false,
83059
+ requiredParams: []
83060
+ },
82906
83061
  {
82907
83062
  gateway: "mutate",
82908
83063
  domain: "admin",
@@ -84944,7 +85099,7 @@ async function orchestrateCriticalPath(projectRoot) {
84944
85099
  try {
84945
85100
  const root = projectRoot || resolveProjectRoot();
84946
85101
  const accessor = await getAccessor(root);
84947
- const result = await getCriticalPath2(root, accessor);
85102
+ const result = await getCriticalPath3(root, accessor);
84948
85103
  return { success: true, data: result };
84949
85104
  } catch (err) {
84950
85105
  return engineError("E_GENERAL", err.message);
@@ -85700,7 +85855,7 @@ async function releaseShip(params, projectRoot) {
85700
85855
  // packages/cleo/src/dispatch/engines/system-engine.ts
85701
85856
  init_internal();
85702
85857
  init_error();
85703
- import { existsSync as existsSync119, readdirSync as readdirSync37, readFileSync as readFileSync93 } from "node:fs";
85858
+ import { existsSync as existsSync119, readdirSync as readdirSync38, readFileSync as readFileSync93 } from "node:fs";
85704
85859
  import { basename as basename18, join as join112 } from "node:path";
85705
85860
  var HELP_TOPICS = {
85706
85861
  session: {
@@ -86007,7 +86162,7 @@ function systemContext(projectRoot, params) {
86007
86162
  const sessions2 = [];
86008
86163
  const statesDir = join112(cleoDir, "context-states");
86009
86164
  if (existsSync119(statesDir)) {
86010
- for (const file2 of readdirSync37(statesDir)) {
86165
+ for (const file2 of readdirSync38(statesDir)) {
86011
86166
  if (file2.startsWith("context-state-") && file2.endsWith(".json")) {
86012
86167
  try {
86013
86168
  const state = JSON.parse(readFileSync93(join112(statesDir, file2), "utf-8"));
@@ -86144,6 +86299,14 @@ function systemBackup(projectRoot, params) {
86144
86299
  return engineError("E_GENERAL", err.message);
86145
86300
  }
86146
86301
  }
86302
+ function systemListBackups(projectRoot) {
86303
+ try {
86304
+ const result = listSystemBackups(projectRoot);
86305
+ return { success: true, data: result };
86306
+ } catch (err) {
86307
+ return engineError("E_GENERAL", err.message);
86308
+ }
86309
+ }
86147
86310
  function systemRestore(projectRoot, params) {
86148
86311
  try {
86149
86312
  const result = restoreBackup(projectRoot, params);
@@ -86418,14 +86581,19 @@ async function taskCreate(projectRoot, params) {
86418
86581
  size: params.size,
86419
86582
  acceptance: params.acceptance,
86420
86583
  notes: params.notes,
86421
- files: params.files
86584
+ files: params.files,
86585
+ dryRun: params.dryRun
86422
86586
  },
86423
86587
  projectRoot,
86424
86588
  accessor
86425
86589
  );
86426
86590
  return {
86427
86591
  success: true,
86428
- data: { task: taskToRecord(result.task), duplicate: result.duplicate ?? false }
86592
+ data: {
86593
+ task: taskToRecord(result.task),
86594
+ duplicate: result.duplicate ?? false,
86595
+ dryRun: params.dryRun
86596
+ }
86429
86597
  };
86430
86598
  } catch (err) {
86431
86599
  const cleoErr = err;
@@ -87710,6 +87878,16 @@ var AdminHandler = class {
87710
87878
  data: result
87711
87879
  };
87712
87880
  }
87881
+ case "backup": {
87882
+ const result = systemListBackups(projectRoot);
87883
+ return wrapResult(
87884
+ { success: true, data: { backups: result, count: result.length } },
87885
+ "query",
87886
+ "admin",
87887
+ operation,
87888
+ startTime
87889
+ );
87890
+ }
87713
87891
  case "map": {
87714
87892
  const { mapCodebase: mapCodebase3 } = await Promise.resolve().then(() => (init_codebase_map_engine(), codebase_map_engine_exports));
87715
87893
  const result = await mapCodebase3(projectRoot, {
@@ -88199,6 +88377,7 @@ var AdminHandler = class {
88199
88377
  "token",
88200
88378
  "adr.show",
88201
88379
  "adr.find",
88380
+ "backup",
88202
88381
  "export",
88203
88382
  "map"
88204
88383
  ],
@@ -91651,7 +91830,8 @@ var TasksHandler = class {
91651
91830
  phase: params?.phase,
91652
91831
  size: params?.size,
91653
91832
  notes: params?.notes,
91654
- files: params?.files
91833
+ files: params?.files,
91834
+ dryRun: params?.dryRun
91655
91835
  });
91656
91836
  return wrapResult(result, "mutate", "tasks", operation, startTime);
91657
91837
  }
@@ -93741,7 +93921,7 @@ function registerBackupCommand(program) {
93741
93921
  });
93742
93922
  backup.command("list").description("List available backups").action(async () => {
93743
93923
  await dispatchFromCli(
93744
- "mutate",
93924
+ "query",
93745
93925
  "admin",
93746
93926
  "backup",
93747
93927
  {
@@ -94147,7 +94327,7 @@ function registerConsensusCommand(program) {
94147
94327
  // packages/cleo/src/cli/commands/context.ts
94148
94328
  function registerContextCommand(program) {
94149
94329
  const context = program.command("context").description("Monitor context window usage for agent safeguard system");
94150
- context.command("status").description("Show current context state (default)").option("--session <id>", "Check specific CLEO session").action(async (opts) => {
94330
+ context.command("status", { isDefault: true }).description("Show current context state (default)").option("--session <id>", "Check specific CLEO session").action(async (opts) => {
94151
94331
  await dispatchFromCli(
94152
94332
  "query",
94153
94333
  "admin",
@@ -94289,6 +94469,9 @@ function registerDeleteCommand(program) {
94289
94469
  }
94290
94470
 
94291
94471
  // packages/cleo/src/cli/commands/deps.ts
94472
+ init_src();
94473
+ init_internal();
94474
+ init_renderers();
94292
94475
  function registerDepsCommand(program) {
94293
94476
  const deps = program.command("deps").description("Dependency visualization and analysis");
94294
94477
  deps.command("overview").description("Overview of all dependencies").action(async () => {
@@ -94326,15 +94509,15 @@ function registerDepsCommand(program) {
94326
94509
  );
94327
94510
  });
94328
94511
  deps.command("critical-path <taskId>").description("Find longest dependency chain from task").action(async (taskId) => {
94329
- await dispatchFromCli(
94330
- "query",
94331
- "orchestrate",
94332
- "critical.path",
94333
- {
94334
- taskId
94335
- },
94336
- { command: "deps", operation: "tasks.depends" }
94337
- );
94512
+ const cwd = resolveProjectRoot();
94513
+ try {
94514
+ const result = await getCriticalPath2(taskId, cwd);
94515
+ cliOutput(result, { command: "deps", operation: "tasks.criticalPath" });
94516
+ } catch (err) {
94517
+ const msg = err instanceof Error ? err.message : String(err);
94518
+ console.error(`critical-path: ${msg}`);
94519
+ process.exit(4 /* NOT_FOUND */);
94520
+ }
94338
94521
  });
94339
94522
  deps.command("impact <taskId>").description("Find all tasks affected by changes to task").option("--depth <n>", "Maximum depth for impact analysis", "10").action(async (taskId, opts) => {
94340
94523
  await dispatchFromCli(
@@ -94396,7 +94579,7 @@ function registerDetectCommand(program) {
94396
94579
  // packages/cleo/src/cli/commands/detect-drift.ts
94397
94580
  init_src();
94398
94581
  init_renderers();
94399
- import { existsSync as existsSync121, readdirSync as readdirSync38, readFileSync as readFileSync95 } from "node:fs";
94582
+ import { existsSync as existsSync121, readdirSync as readdirSync39, readFileSync as readFileSync95 } from "node:fs";
94400
94583
  import { dirname as dirname22, join as join114 } from "node:path";
94401
94584
  import { fileURLToPath as fileURLToPath5 } from "node:url";
94402
94585
  function findProjectRoot() {
@@ -94548,7 +94731,7 @@ function registerDetectDriftCommand(program) {
94548
94731
  }
94549
94732
  ]);
94550
94733
  } else {
94551
- const files = readdirSync38(cliDir).filter(
94734
+ const files = readdirSync39(cliDir).filter(
94552
94735
  (f) => f.endsWith(".ts") && !f.includes(".test.")
94553
94736
  );
94554
94737
  addCheck("CLI-to-core sync", "pass", `Found ${files.length} CLI command implementations`);
@@ -94568,7 +94751,7 @@ function registerDetectDriftCommand(program) {
94568
94751
  }
94569
94752
  ]);
94570
94753
  } else {
94571
- const files = readdirSync38(domainsDir).filter((f) => f.endsWith(".ts"));
94754
+ const files = readdirSync39(domainsDir).filter((f) => f.endsWith(".ts"));
94572
94755
  addCheck("Domain handler coverage", "pass", `Found ${files.length} domain handlers`);
94573
94756
  }
94574
94757
  } catch (e) {
@@ -95062,24 +95245,29 @@ function registerEnvCommand(program) {
95062
95245
 
95063
95246
  // packages/cleo/src/cli/commands/exists.ts
95064
95247
  init_src();
95248
+ init_internal();
95065
95249
  init_renderers();
95066
95250
  function registerExistsCommand(program) {
95067
- program.command("exists <task-id>").description("Check if a task ID exists (exit 0=exists, 4=not found)").option("--include-archive", "Search archive file too").option("--verbose", "Show which file contains the task").action(async (taskId, opts) => {
95068
- const response = await dispatchRaw("query", "tasks", "exists", {
95069
- taskId,
95070
- includeArchive: opts["includeArchive"],
95071
- verbose: opts["verbose"]
95072
- });
95073
- if (!response.success) {
95074
- handleRawError(response, { command: "exists", operation: "tasks.exists" });
95251
+ program.command("exists <task-id>").description("Check if a task ID exists (exit 0=exists, 4=not found)").option("--verbose", "Show task title and status when found").action(async (taskId, opts) => {
95252
+ const cwd = resolveProjectRoot();
95253
+ let task;
95254
+ try {
95255
+ task = await getTask(taskId, cwd);
95256
+ } catch (err) {
95257
+ console.error(`exists: ${err instanceof Error ? err.message : String(err)}`);
95258
+ process.exit(1 /* GENERAL_ERROR */);
95075
95259
  }
95076
- const data = response.data;
95077
- if (data?.exists) {
95078
- cliOutput(data, { command: "exists" });
95079
- } else {
95080
- cliOutput(data, { command: "exists" });
95260
+ if (!task) {
95261
+ const data2 = { exists: false, taskId };
95262
+ cliOutput(data2, { command: "exists", operation: "tasks.exists" });
95081
95263
  process.exit(4 /* NOT_FOUND */);
95082
95264
  }
95265
+ const data = { exists: true, taskId };
95266
+ if (opts["verbose"]) {
95267
+ data["title"] = task.title;
95268
+ data["status"] = task.status;
95269
+ }
95270
+ cliOutput(data, { command: "exists", operation: "tasks.exists" });
95083
95271
  });
95084
95272
  }
95085
95273
 
@@ -95623,7 +95811,7 @@ async function handleIssueType(issueType, opts) {
95623
95811
  // packages/cleo/src/cli/commands/labels.ts
95624
95812
  function registerLabelsCommand(program) {
95625
95813
  const labels = program.command("labels").description("List all labels with counts or show tasks with specific label");
95626
- labels.command("list").description("List all labels with task counts (default)").action(async () => {
95814
+ labels.command("list", { isDefault: true }).description("List all labels with task counts (default)").action(async () => {
95627
95815
  await dispatchFromCli("query", "tasks", "label.list", {}, { command: "labels" });
95628
95816
  });
95629
95817
  labels.command("show <label>").description("Show tasks with specific label").action(async (label) => {
@@ -96507,7 +96695,7 @@ function registerPhaseCommand(program) {
96507
96695
  // packages/cleo/src/cli/commands/phases.ts
96508
96696
  function registerPhasesCommand(program) {
96509
96697
  const phases = program.command("phases").description("List phases with progress bars and statistics");
96510
- phases.command("list").description("List all phases with progress (default)").action(async () => {
96698
+ phases.command("list", { isDefault: true }).description("List all phases with progress (default)").action(async () => {
96511
96699
  await dispatchFromCli("query", "pipeline", "phase.list", {}, { command: "phases" });
96512
96700
  });
96513
96701
  phases.command("show <phase>").description("Show phase details and task counts").action(async (phase) => {
@@ -97768,6 +97956,20 @@ function registerSessionCommand(program) {
97768
97956
  { command: "session", operation: "session.resume" }
97769
97957
  );
97770
97958
  });
97959
+ session.command("find").description("Find sessions (lightweight discovery \u2014 minimal fields, low context cost)").option("--status <status>", "Filter by status (active|ended|orphaned)").option("--scope <scope>", 'Filter by scope (e.g. "epic:T001" or "global")').option("--query <query>", "Fuzzy match on session name or ID").option("--limit <n>", "Max results", parseInt).action(async (opts) => {
97960
+ await dispatchFromCli(
97961
+ "query",
97962
+ "session",
97963
+ "find",
97964
+ {
97965
+ status: opts["status"],
97966
+ scope: opts["scope"],
97967
+ query: opts["query"],
97968
+ limit: opts["limit"]
97969
+ },
97970
+ { command: "session", operation: "session.find" }
97971
+ );
97972
+ });
97771
97973
  session.command("list").description("List sessions").option("--status <status>", "Filter by status (active|ended|orphaned)").option("--limit <n>", "Max results", parseInt).option("--offset <n>", "Skip first n results", parseInt).action(async (opts) => {
97772
97974
  await dispatchFromCli(
97773
97975
  "query",
@@ -98910,34 +99112,51 @@ function shimToCitty(shim) {
98910
99112
  subCommands2[alias] = shimToCitty(sub);
98911
99113
  }
98912
99114
  }
98913
- return defineCommand({
99115
+ const hasSubCommands = Object.keys(subCommands2).length > 0;
99116
+ const subCommandNames = new Set(
99117
+ shim._subcommands.flatMap((s) => [s._name, ...s._aliases].filter(Boolean))
99118
+ );
99119
+ const runFn = async (context) => {
99120
+ const { args } = context;
99121
+ if (hasSubCommands && context.rawArgs.some((a) => subCommandNames.has(a))) {
99122
+ return;
99123
+ }
99124
+ if (shim._action) {
99125
+ const positionalValues = [];
99126
+ for (const arg of shim._args) {
99127
+ positionalValues.push(args[arg.name]);
99128
+ }
99129
+ const opts = {};
99130
+ for (const opt of shim._options) {
99131
+ const val = args[opt.longName];
99132
+ if (val !== void 0 && val !== false) {
99133
+ if (opt.parseFn && typeof val === "string") {
99134
+ opts[opt.longName] = opt.parseFn(val);
99135
+ } else {
99136
+ opts[opt.longName] = val;
99137
+ }
99138
+ }
99139
+ }
99140
+ await shim._action(...positionalValues, opts, shim);
99141
+ } else if (shim._subcommands.length > 0) {
99142
+ const defaultSub = shim._subcommands.find((s) => s._isDefault);
99143
+ if (defaultSub?._action) {
99144
+ await defaultSub._action({}, defaultSub);
99145
+ } else {
99146
+ await showUsage(context.cmd);
99147
+ }
99148
+ }
99149
+ };
99150
+ const cittyDef = defineCommand({
98914
99151
  meta: {
98915
99152
  name: shim._name,
98916
99153
  description: shim._description
98917
99154
  },
98918
99155
  args: cittyArgs,
98919
- ...Object.keys(subCommands2).length > 0 ? { subCommands: subCommands2 } : {},
98920
- async run({ args }) {
98921
- if (shim._action) {
98922
- const positionalValues = [];
98923
- for (const arg of shim._args) {
98924
- positionalValues.push(args[arg.name]);
98925
- }
98926
- const opts = {};
98927
- for (const opt of shim._options) {
98928
- const val = args[opt.longName];
98929
- if (val !== void 0 && val !== false) {
98930
- if (opt.parseFn && typeof val === "string") {
98931
- opts[opt.longName] = opt.parseFn(val);
98932
- } else {
98933
- opts[opt.longName] = val;
98934
- }
98935
- }
98936
- }
98937
- await shim._action(...positionalValues, opts, shim);
98938
- }
98939
- }
99156
+ ...hasSubCommands ? { subCommands: subCommands2 } : {},
99157
+ run: runFn
98940
99158
  });
99159
+ return cittyDef;
98941
99160
  }
98942
99161
  var subCommands = {};
98943
99162
  subCommands["version"] = defineCommand({