@cleocode/cleo 2026.4.25 → 2026.4.27

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
@@ -54643,33 +54643,23 @@ var init_runtime = __esm({
54643
54643
  });
54644
54644
 
54645
54645
  // packages/core/src/system/safestop.ts
54646
- import { existsSync as existsSync96, readFileSync as readFileSync67, writeFileSync as writeFileSync15 } from "node:fs";
54646
+ import { existsSync as existsSync96 } from "node:fs";
54647
54647
  import { join as join98 } from "node:path";
54648
- function safestop(projectRoot, opts) {
54648
+ async function safestop(projectRoot, opts) {
54649
54649
  const dryRun = opts?.dryRun ?? false;
54650
54650
  const reason = opts?.reason ?? "Manual safestop";
54651
54651
  let sessionEnded = false;
54652
54652
  if (!dryRun && !opts?.noSessionEnd) {
54653
- const sessPath = join98(projectRoot, ".cleo", "sessions.json");
54654
- if (existsSync96(sessPath)) {
54655
- try {
54656
- const data = JSON.parse(readFileSync67(sessPath, "utf-8"));
54657
- const sessions2 = data.sessions ?? [];
54658
- let changed = false;
54659
- for (const s3 of sessions2) {
54660
- if (s3.status === "active") {
54661
- s3.status = "ended";
54662
- s3.endedAt = (/* @__PURE__ */ new Date()).toISOString();
54663
- s3.endNote = `Safestop: ${reason}`;
54664
- changed = true;
54665
- sessionEnded = true;
54666
- }
54667
- }
54668
- if (changed) {
54669
- writeFileSync15(sessPath, JSON.stringify(data, null, 2), "utf-8");
54670
- }
54671
- } catch {
54653
+ try {
54654
+ const accessor = await getAccessor(projectRoot);
54655
+ const activeSession = await accessor.getActiveSession();
54656
+ if (activeSession && activeSession.id !== "default") {
54657
+ activeSession.status = "ended";
54658
+ activeSession.endedAt = (/* @__PURE__ */ new Date()).toISOString();
54659
+ await accessor.upsertSingleSession(activeSession);
54660
+ sessionEnded = true;
54672
54661
  }
54662
+ } catch {
54673
54663
  }
54674
54664
  }
54675
54665
  return { stopped: !dryRun, reason, sessionEnded, handoff: opts?.handoff, dryRun };
@@ -55260,7 +55250,7 @@ var init_tasks2 = __esm({
55260
55250
  });
55261
55251
 
55262
55252
  // packages/core/src/templates/parser.ts
55263
- import { existsSync as existsSync97, readdirSync as readdirSync31, readFileSync as readFileSync68 } from "fs";
55253
+ import { existsSync as existsSync97, readdirSync as readdirSync31, readFileSync as readFileSync67 } from "fs";
55264
55254
  import { join as join99 } from "path";
55265
55255
  import { parse as parseYaml } from "yaml";
55266
55256
  function deriveSubcommand(filename) {
@@ -55276,7 +55266,7 @@ function deriveSubcommand(filename) {
55276
55266
  }
55277
55267
  function parseTemplateFile2(templateDir, filename) {
55278
55268
  const filePath = join99(templateDir, filename);
55279
- const raw = readFileSync68(filePath, "utf-8");
55269
+ const raw = readFileSync67(filePath, "utf-8");
55280
55270
  const parsed = parseYaml(raw);
55281
55271
  const name2 = typeof parsed.name === "string" ? parsed.name : filename;
55282
55272
  const titlePrefix = typeof parsed.title === "string" ? parsed.title : "";
@@ -55463,7 +55453,7 @@ var init_templates = __esm({
55463
55453
  });
55464
55454
 
55465
55455
  // packages/core/src/ui/aliases.ts
55466
- import { existsSync as existsSync98, readFileSync as readFileSync69, writeFileSync as writeFileSync16 } from "node:fs";
55456
+ import { existsSync as existsSync98, readFileSync as readFileSync68, writeFileSync as writeFileSync15 } from "node:fs";
55467
55457
  import { homedir as homedir5, platform as platform3 } from "node:os";
55468
55458
  import { join as join100 } from "node:path";
55469
55459
  function getCurrentShell() {
@@ -55526,40 +55516,40 @@ function generatePowershellAliases(cleoPath) {
55526
55516
  }
55527
55517
  function hasAliasBlock(filePath) {
55528
55518
  if (!existsSync98(filePath)) return false;
55529
- const content = readFileSync69(filePath, "utf-8");
55519
+ const content = readFileSync68(filePath, "utf-8");
55530
55520
  return content.includes(MARKER_START) && content.includes(MARKER_END);
55531
55521
  }
55532
55522
  function getInstalledVersion(filePath) {
55533
55523
  if (!existsSync98(filePath)) return null;
55534
- const content = readFileSync69(filePath, "utf-8");
55524
+ const content = readFileSync68(filePath, "utf-8");
55535
55525
  const match = content.match(/CLEO CLI aliases \(v([^)]+)\)/);
55536
55526
  return match?.[1] ?? null;
55537
55527
  }
55538
55528
  function injectAliases(filePath, shell = "bash", cleoPath) {
55539
55529
  const content = shell === "powershell" ? generatePowershellAliases(cleoPath) : generateBashAliases(cleoPath);
55540
55530
  if (!existsSync98(filePath)) {
55541
- writeFileSync16(filePath, content + "\n", "utf-8");
55531
+ writeFileSync15(filePath, content + "\n", "utf-8");
55542
55532
  return { action: "created", version: ALIASES_VERSION };
55543
55533
  }
55544
- const existing = readFileSync69(filePath, "utf-8");
55534
+ const existing = readFileSync68(filePath, "utf-8");
55545
55535
  if (hasAliasBlock(filePath)) {
55546
55536
  const startIdx = existing.indexOf(MARKER_START);
55547
55537
  const endIdx = existing.indexOf(MARKER_END) + MARKER_END.length;
55548
55538
  const updated = existing.slice(0, startIdx) + content + existing.slice(endIdx);
55549
- writeFileSync16(filePath, updated, "utf-8");
55539
+ writeFileSync15(filePath, updated, "utf-8");
55550
55540
  return { action: "updated", version: ALIASES_VERSION };
55551
55541
  }
55552
- writeFileSync16(filePath, existing + "\n" + content + "\n", "utf-8");
55542
+ writeFileSync15(filePath, existing + "\n" + content + "\n", "utf-8");
55553
55543
  return { action: "added", version: ALIASES_VERSION };
55554
55544
  }
55555
55545
  function removeAliases(filePath) {
55556
55546
  if (!existsSync98(filePath) || !hasAliasBlock(filePath)) return false;
55557
- const existing = readFileSync69(filePath, "utf-8");
55547
+ const existing = readFileSync68(filePath, "utf-8");
55558
55548
  const startIdx = existing.indexOf(MARKER_START);
55559
55549
  const endIdx = existing.indexOf(MARKER_END) + MARKER_END.length;
55560
55550
  const before = existing.slice(0, startIdx).replace(/\n+$/, "\n");
55561
55551
  const after = existing.slice(endIdx).replace(/^\n+/, "\n");
55562
- writeFileSync16(filePath, before + after, "utf-8");
55552
+ writeFileSync15(filePath, before + after, "utf-8");
55563
55553
  return true;
55564
55554
  }
55565
55555
  function checkAliasesStatus(shell) {
@@ -55590,7 +55580,7 @@ var init_aliases = __esm({
55590
55580
  });
55591
55581
 
55592
55582
  // packages/core/src/ui/changelog.ts
55593
- import { appendFileSync as appendFileSync9, existsSync as existsSync99, readFileSync as readFileSync70, writeFileSync as writeFileSync17 } from "node:fs";
55583
+ import { appendFileSync as appendFileSync9, existsSync as existsSync99, readFileSync as readFileSync69, writeFileSync as writeFileSync16 } from "node:fs";
55594
55584
  async function discoverReleaseTasks(options = {}, cwd, accessor) {
55595
55585
  const tasks2 = [];
55596
55586
  const dataSources = [];
@@ -55673,21 +55663,21 @@ function formatChangelogJson(version2, date6, sections) {
55673
55663
  };
55674
55664
  }
55675
55665
  function writeChangelogFile(filePath, content) {
55676
- writeFileSync17(filePath, content, "utf-8");
55666
+ writeFileSync16(filePath, content, "utf-8");
55677
55667
  }
55678
55668
  function appendToChangelog(filePath, newContent) {
55679
55669
  if (!existsSync99(filePath)) {
55680
- writeFileSync17(filePath, `# Changelog
55670
+ writeFileSync16(filePath, `# Changelog
55681
55671
 
55682
55672
  ${newContent}`, "utf-8");
55683
55673
  return;
55684
55674
  }
55685
- const existing = readFileSync70(filePath, "utf-8");
55675
+ const existing = readFileSync69(filePath, "utf-8");
55686
55676
  const headerMatch = existing.match(/^# .+\n/m);
55687
55677
  if (headerMatch) {
55688
55678
  const insertPos = (headerMatch.index ?? 0) + headerMatch[0].length;
55689
55679
  const updated = existing.slice(0, insertPos) + "\n" + newContent + existing.slice(insertPos);
55690
- writeFileSync17(filePath, updated, "utf-8");
55680
+ writeFileSync16(filePath, updated, "utf-8");
55691
55681
  } else {
55692
55682
  appendFileSync9(filePath, "\n" + newContent);
55693
55683
  }
@@ -55747,11 +55737,11 @@ var init_changelog = __esm({
55747
55737
  });
55748
55738
 
55749
55739
  // packages/core/src/ui/command-registry.ts
55750
- import { existsSync as existsSync100, readdirSync as readdirSync32, readFileSync as readFileSync71 } from "node:fs";
55740
+ import { existsSync as existsSync100, readdirSync as readdirSync32, readFileSync as readFileSync70 } from "node:fs";
55751
55741
  import { basename as basename16, join as join101 } from "node:path";
55752
55742
  function parseCommandHeader(scriptPath) {
55753
55743
  if (!existsSync100(scriptPath)) return null;
55754
- const content = readFileSync71(scriptPath, "utf-8");
55744
+ const content = readFileSync70(scriptPath, "utf-8");
55755
55745
  const lines = content.split("\n");
55756
55746
  let inHeader = false;
55757
55747
  const headerLines = [];
@@ -71081,7 +71071,7 @@ var init_compliance2 = __esm({
71081
71071
  });
71082
71072
 
71083
71073
  // packages/core/src/validation/docs-sync.ts
71084
- import { existsSync as existsSync101, readdirSync as readdirSync33, readFileSync as readFileSync72 } from "node:fs";
71074
+ import { existsSync as existsSync101, readdirSync as readdirSync33, readFileSync as readFileSync71 } from "node:fs";
71085
71075
  import { join as join102 } from "node:path";
71086
71076
  function getScriptCommands(scriptsDir) {
71087
71077
  if (!existsSync101(scriptsDir)) return [];
@@ -71094,7 +71084,7 @@ function getScriptCommands(scriptsDir) {
71094
71084
  function getIndexScripts(indexPath) {
71095
71085
  if (!existsSync101(indexPath)) return [];
71096
71086
  try {
71097
- const content = readFileSync72(indexPath, "utf-8");
71087
+ const content = readFileSync71(indexPath, "utf-8");
71098
71088
  const index2 = JSON.parse(content);
71099
71089
  return index2.commands.map((cmd) => cmd.script ?? "").filter((s3) => s3).map((s3) => s3.replace(/\.sh$/, "")).sort();
71100
71090
  } catch {
@@ -71104,7 +71094,7 @@ function getIndexScripts(indexPath) {
71104
71094
  function getIndexCommands(indexPath) {
71105
71095
  if (!existsSync101(indexPath)) return [];
71106
71096
  try {
71107
- const content = readFileSync72(indexPath, "utf-8");
71097
+ const content = readFileSync71(indexPath, "utf-8");
71108
71098
  const index2 = JSON.parse(content);
71109
71099
  return index2.commands.map((cmd) => cmd.name).sort();
71110
71100
  } catch {
@@ -71141,8 +71131,8 @@ function checkWrapperSync(wrapperPath, indexPath) {
71141
71131
  if (!existsSync101(wrapperPath) || !existsSync101(indexPath)) return [];
71142
71132
  const issues = [];
71143
71133
  try {
71144
- const wrapperContent = readFileSync72(wrapperPath, "utf-8");
71145
- const indexContent = readFileSync72(indexPath, "utf-8");
71134
+ const wrapperContent = readFileSync71(wrapperPath, "utf-8");
71135
+ const indexContent = readFileSync71(indexPath, "utf-8");
71146
71136
  const index2 = JSON.parse(indexContent);
71147
71137
  const match = wrapperContent.match(/_get_all_commands\(\)\s*\{[^}]*echo\s+"([^"]+)"/);
71148
71138
  const wrapperCmds = new Set(match ? match[1].split(/\s+/).filter(Boolean) : []);
@@ -71173,7 +71163,7 @@ function detectDrift(mode = "full", projectRoot = ".") {
71173
71163
  const readmePath = join102(projectRoot, "README.md");
71174
71164
  if (existsSync101(readmePath)) {
71175
71165
  try {
71176
- const readme = readFileSync72(readmePath, "utf-8");
71166
+ const readme = readFileSync71(readmePath, "utf-8");
71177
71167
  const readmeCmds = new Set(
71178
71168
  (readme.match(/cleo [a-z-]+/g) ?? []).map((m2) => m2.replace("cleo ", ""))
71179
71169
  );
@@ -71223,7 +71213,7 @@ var init_docs_sync = __esm({
71223
71213
 
71224
71214
  // packages/core/src/validation/doctor/project-cache.ts
71225
71215
  import { createHash as createHash11 } from "node:crypto";
71226
- import { existsSync as existsSync102, mkdirSync as mkdirSync23, readFileSync as readFileSync73, unlinkSync as unlinkSync8, writeFileSync as writeFileSync18 } from "node:fs";
71216
+ import { existsSync as existsSync102, mkdirSync as mkdirSync23, readFileSync as readFileSync72, unlinkSync as unlinkSync8, writeFileSync as writeFileSync17 } from "node:fs";
71227
71217
  import { dirname as dirname19, join as join103 } from "node:path";
71228
71218
  function getCacheFilePath(cleoHome) {
71229
71219
  const home = cleoHome ?? getCleoHome();
@@ -71239,13 +71229,13 @@ function initCacheFile(cacheFile) {
71239
71229
  if (!existsSync102(dir)) {
71240
71230
  mkdirSync23(dir, { recursive: true });
71241
71231
  }
71242
- writeFileSync18(cacheFile, JSON.stringify(cache, null, 2));
71232
+ writeFileSync17(cacheFile, JSON.stringify(cache, null, 2));
71243
71233
  return cache;
71244
71234
  }
71245
71235
  function loadCache(cacheFile) {
71246
71236
  if (!existsSync102(cacheFile)) return null;
71247
71237
  try {
71248
- const content = readFileSync73(cacheFile, "utf-8");
71238
+ const content = readFileSync72(cacheFile, "utf-8");
71249
71239
  return JSON.parse(content);
71250
71240
  } catch {
71251
71241
  return null;
@@ -71254,7 +71244,7 @@ function loadCache(cacheFile) {
71254
71244
  function getFileHash(filePath) {
71255
71245
  if (!existsSync102(filePath)) return "";
71256
71246
  try {
71257
- const content = readFileSync73(filePath);
71247
+ const content = readFileSync72(filePath);
71258
71248
  return createHash11("sha256").update(content).digest("hex");
71259
71249
  } catch {
71260
71250
  return "";
@@ -71299,14 +71289,14 @@ function cacheValidationResult(projectHash, projectPath, validationStatus, issue
71299
71289
  ttl: CACHE_TTL_SECONDS
71300
71290
  };
71301
71291
  cache.lastUpdated = timestamp2;
71302
- writeFileSync18(cachePath, JSON.stringify(cache, null, 2));
71292
+ writeFileSync17(cachePath, JSON.stringify(cache, null, 2));
71303
71293
  }
71304
71294
  function clearProjectCache(projectHash, cacheFile) {
71305
71295
  const cachePath = cacheFile ?? getCacheFilePath();
71306
71296
  const cache = loadCache(cachePath);
71307
71297
  if (!cache) return;
71308
71298
  delete cache.projects[projectHash];
71309
- writeFileSync18(cachePath, JSON.stringify(cache, null, 2));
71299
+ writeFileSync17(cachePath, JSON.stringify(cache, null, 2));
71310
71300
  }
71311
71301
  function clearEntireCache(cacheFile) {
71312
71302
  const cachePath = cacheFile ?? getCacheFilePath();
@@ -72523,7 +72513,7 @@ var init_manifest = __esm({
72523
72513
  });
72524
72514
 
72525
72515
  // packages/core/src/validation/protocol-common.ts
72526
- import { existsSync as existsSync104, readdirSync as readdirSync34, readFileSync as readFileSync74 } from "node:fs";
72516
+ import { existsSync as existsSync104, readdirSync as readdirSync34, readFileSync as readFileSync73 } from "node:fs";
72527
72517
  function checkOutputFileExists(taskId, expectedDir, pattern) {
72528
72518
  if (!existsSync104(expectedDir)) return false;
72529
72519
  const filePattern = pattern ?? `${taskId}`;
@@ -72537,7 +72527,7 @@ function checkOutputFileExists(taskId, expectedDir, pattern) {
72537
72527
  function checkDocumentationSections(filePath, sections) {
72538
72528
  if (!existsSync104(filePath)) return false;
72539
72529
  try {
72540
- const content = readFileSync74(filePath, "utf-8");
72530
+ const content = readFileSync73(filePath, "utf-8");
72541
72531
  return sections.every((section) => {
72542
72532
  const regex = new RegExp(`^#+ .*${escapeRegex3(section)}`, "m");
72543
72533
  return regex.test(content);
@@ -72608,7 +72598,7 @@ function checkLinkedTasksPresent(entry, requiredIds) {
72608
72598
  function checkProvenanceTags(filePath, taskId) {
72609
72599
  if (!existsSync104(filePath)) return false;
72610
72600
  try {
72611
- const content = readFileSync74(filePath, "utf-8");
72601
+ const content = readFileSync73(filePath, "utf-8");
72612
72602
  if (taskId) {
72613
72603
  return content.includes(`@task ${taskId}`);
72614
72604
  }
@@ -73619,7 +73609,7 @@ __export(init_exports, {
73619
73609
  resolveSeedAgentsDir: () => resolveSeedAgentsDir,
73620
73610
  updateDocs: () => updateDocs
73621
73611
  });
73622
- import { existsSync as existsSync106, readdirSync as readdirSync36, readFileSync as readFileSync75 } from "node:fs";
73612
+ import { existsSync as existsSync106, readdirSync as readdirSync36, readFileSync as readFileSync74 } from "node:fs";
73623
73613
  import { copyFile as copyFile4, lstat, mkdir as mkdir16, readFile as readFile17, symlink, unlink as unlink4, writeFile as writeFile11 } from "node:fs/promises";
73624
73614
  import { platform as platform4 } from "node:os";
73625
73615
  import { basename as basename17, dirname as dirname21, join as join105 } from "node:path";
@@ -73753,7 +73743,7 @@ async function initCoreSkills(created, warnings) {
73753
73743
  warnings.push("Failed to register skill library with CAAMP");
73754
73744
  }
73755
73745
  const catalogPath = join105(ctSkillsRoot, "skills.json");
73756
- const catalog4 = JSON.parse(readFileSync75(catalogPath, "utf-8"));
73746
+ const catalog4 = JSON.parse(readFileSync74(catalogPath, "utf-8"));
73757
73747
  const skills = catalog4.skills ?? [];
73758
73748
  const coreSkills = skills.filter((s3) => s3.tier <= 2);
73759
73749
  const installed = [];
@@ -73822,7 +73812,7 @@ async function installGitHubTemplates(projectRoot, created, skipped) {
73822
73812
  skipped.push(`.github/ISSUE_TEMPLATE/${file2}`);
73823
73813
  continue;
73824
73814
  }
73825
- const content = readFileSync75(join105(issueSrcDir, file2), "utf-8");
73815
+ const content = readFileSync74(join105(issueSrcDir, file2), "utf-8");
73826
73816
  await writeFile11(dest, content, "utf-8");
73827
73817
  created.push(`.github/ISSUE_TEMPLATE/${file2}`);
73828
73818
  }
@@ -73833,7 +73823,7 @@ async function installGitHubTemplates(projectRoot, created, skipped) {
73833
73823
  if (existsSync106(prTemplateDest)) {
73834
73824
  skipped.push(".github/pull_request_template.md");
73835
73825
  } else {
73836
- const content = readFileSync75(prTemplateSrc, "utf-8");
73826
+ const content = readFileSync74(prTemplateSrc, "utf-8");
73837
73827
  await writeFile11(prTemplateDest, content, "utf-8");
73838
73828
  created.push(".github/pull_request_template.md");
73839
73829
  }
@@ -74286,13 +74276,13 @@ var init_init = __esm({
74286
74276
  });
74287
74277
 
74288
74278
  // packages/core/src/sessions/context-alert.ts
74289
- import { existsSync as existsSync107, readFileSync as readFileSync76, writeFileSync as writeFileSync19 } from "node:fs";
74279
+ import { existsSync as existsSync107, readFileSync as readFileSync75, writeFileSync as writeFileSync18 } from "node:fs";
74290
74280
  import { join as join106 } from "node:path";
74291
74281
  function getCurrentSessionId(cwd) {
74292
74282
  if (process.env.CLEO_SESSION) return process.env.CLEO_SESSION;
74293
74283
  const sessionFile = join106(getCleoDir(cwd), ".current-session");
74294
74284
  if (existsSync107(sessionFile)) {
74295
- return readFileSync76(sessionFile, "utf-8").trim() || null;
74285
+ return readFileSync75(sessionFile, "utf-8").trim() || null;
74296
74286
  }
74297
74287
  return null;
74298
74288
  }
@@ -74388,7 +74378,7 @@ __export(project_info_exports, {
74388
74378
  getProjectInfoSync: () => getProjectInfoSync,
74389
74379
  updateProjectName: () => updateProjectName
74390
74380
  });
74391
- import { existsSync as existsSync108, readFileSync as readFileSync77, writeFileSync as writeFileSync20 } from "node:fs";
74381
+ import { existsSync as existsSync108, readFileSync as readFileSync76, writeFileSync as writeFileSync19 } from "node:fs";
74392
74382
  import { readFile as readFile18 } from "node:fs/promises";
74393
74383
  import { join as join107 } from "node:path";
74394
74384
  async function getProjectInfo(cwd) {
@@ -74415,7 +74405,7 @@ function getProjectInfoSync(cwd) {
74415
74405
  const infoPath = join107(cleoDir, "project-info.json");
74416
74406
  if (!existsSync108(infoPath)) return null;
74417
74407
  try {
74418
- const raw = readFileSync77(infoPath, "utf-8");
74408
+ const raw = readFileSync76(infoPath, "utf-8");
74419
74409
  const data = JSON.parse(raw);
74420
74410
  if (typeof data.projectHash !== "string" || data.projectHash.length === 0) {
74421
74411
  return null;
@@ -74436,10 +74426,10 @@ function updateProjectName(cwd, name2) {
74436
74426
  const cleoDir = getCleoDirAbsolute(cwd);
74437
74427
  const infoPath = join107(cleoDir, "project-info.json");
74438
74428
  if (!existsSync108(infoPath)) return;
74439
- const data = JSON.parse(readFileSync77(infoPath, "utf-8"));
74429
+ const data = JSON.parse(readFileSync76(infoPath, "utf-8"));
74440
74430
  data.projectName = name2;
74441
74431
  data.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
74442
- writeFileSync20(infoPath, `${JSON.stringify(data, null, 2)}
74432
+ writeFileSync19(infoPath, `${JSON.stringify(data, null, 2)}
74443
74433
  `);
74444
74434
  }
74445
74435
  var init_project_info = __esm({
@@ -74450,7 +74440,7 @@ var init_project_info = __esm({
74450
74440
  });
74451
74441
 
74452
74442
  // packages/core/src/bootstrap.ts
74453
- import { existsSync as existsSync109, readFileSync as readFileSync78 } from "node:fs";
74443
+ import { existsSync as existsSync109, readFileSync as readFileSync77 } from "node:fs";
74454
74444
  import { mkdir as mkdir17, readFile as readFile19, writeFile as writeFile12 } from "node:fs/promises";
74455
74445
  import { homedir as homedir6 } from "node:os";
74456
74446
  import { join as join108 } from "node:path";
@@ -74489,7 +74479,7 @@ async function ensureGlobalTemplatesBootstrap(ctx, packageRootOverride) {
74489
74479
  const pkgRoot = packageRootOverride ?? getPackageRoot();
74490
74480
  const templatePath = join108(pkgRoot, "templates", "CLEO-INJECTION.md");
74491
74481
  if (existsSync109(templatePath)) {
74492
- templateContent = readFileSync78(templatePath, "utf-8");
74482
+ templateContent = readFileSync77(templatePath, "utf-8");
74493
74483
  }
74494
74484
  } catch {
74495
74485
  }
@@ -75190,6 +75180,7 @@ var init_cleo = __esm({
75190
75180
  // packages/core/src/index.ts
75191
75181
  var init_src2 = __esm({
75192
75182
  "packages/core/src/index.ts"() {
75183
+ "use strict";
75193
75184
  init_src();
75194
75185
  init_adapters();
75195
75186
  init_admin();
@@ -79174,7 +79165,7 @@ var init_engine_compat = __esm({
79174
79165
 
79175
79166
  // packages/core/src/memory/pipeline-manifest-sqlite.ts
79176
79167
  import { createHash as createHash12 } from "node:crypto";
79177
- import { existsSync as existsSync111, readFileSync as readFileSync79, renameSync as renameSync8 } from "node:fs";
79168
+ import { existsSync as existsSync111, readFileSync as readFileSync78, renameSync as renameSync8 } from "node:fs";
79178
79169
  import { join as join109 } from "node:path";
79179
79170
  import { and as and10, count as count2, desc as desc5, eq as eq13, gte as gte3, isNull as isNull3, like as like3, lte as lte2, or as or5 } from "drizzle-orm";
79180
79171
  async function getDb3(cwd) {
@@ -79307,7 +79298,7 @@ async function pipelineManifestShow(researchId, projectRoot) {
79307
79298
  try {
79308
79299
  const filePath = join109(root, entry.file);
79309
79300
  if (existsSync111(filePath)) {
79310
- fileContent = readFileSync79(filePath, "utf-8");
79301
+ fileContent = readFileSync78(filePath, "utf-8");
79311
79302
  }
79312
79303
  } catch {
79313
79304
  }
@@ -79696,7 +79687,7 @@ var init_model_provider_registry = __esm({
79696
79687
 
79697
79688
  // packages/core/src/metrics/token-service.ts
79698
79689
  import { createHash as createHash13, randomUUID as randomUUID9 } from "node:crypto";
79699
- import { existsSync as existsSync112, readdirSync as readdirSync37, readFileSync as readFileSync80 } from "node:fs";
79690
+ import { existsSync as existsSync112, readdirSync as readdirSync37, readFileSync as readFileSync79 } from "node:fs";
79700
79691
  import { join as join110 } from "node:path";
79701
79692
  function normalizeProvider(provider, model, runtimeProvider) {
79702
79693
  const value = (provider ?? "").trim().toLowerCase();
@@ -79784,7 +79775,7 @@ function readOtelJsonl(dir) {
79784
79775
  for (const file2 of readdirSync37(dir)) {
79785
79776
  if (!file2.endsWith(".json") && !file2.endsWith(".jsonl")) continue;
79786
79777
  const filePath = join110(dir, file2);
79787
- const raw = readFileSync80(filePath, "utf-8").trim();
79778
+ const raw = readFileSync79(filePath, "utf-8").trim();
79788
79779
  if (!raw) continue;
79789
79780
  for (const line2 of raw.split("\n")) {
79790
79781
  try {
@@ -80173,7 +80164,7 @@ var init_parallel = __esm({
80173
80164
  });
80174
80165
 
80175
80166
  // packages/core/src/orchestration/skill-ops.ts
80176
- import { existsSync as existsSync113, readdirSync as readdirSync38, readFileSync as readFileSync81 } from "node:fs";
80167
+ import { existsSync as existsSync113, readdirSync as readdirSync38, readFileSync as readFileSync80 } from "node:fs";
80177
80168
  import { join as join111 } from "node:path";
80178
80169
  import { getCanonicalSkillsDir as getCanonicalSkillsDir3 } from "@cleocode/caamp";
80179
80170
  function getSkillContent(skillName, projectRoot) {
@@ -80193,7 +80184,7 @@ function getSkillContent(skillName, projectRoot) {
80193
80184
  if (!existsSync113(skillFilePath)) {
80194
80185
  throw new CleoError(4 /* NOT_FOUND */, `Skill file not found: ${skillFilePath}`);
80195
80186
  }
80196
- const content = readFileSync81(skillFilePath, "utf-8");
80187
+ const content = readFileSync80(skillFilePath, "utf-8");
80197
80188
  const refsDir = join111(skillDir, "references");
80198
80189
  let references = [];
80199
80190
  if (existsSync113(refsDir)) {
@@ -80388,7 +80379,7 @@ var init_validate_spawn = __esm({
80388
80379
  });
80389
80380
 
80390
80381
  // packages/core/src/sessions/context-inject.ts
80391
- import { existsSync as existsSync114, readFileSync as readFileSync82 } from "node:fs";
80382
+ import { existsSync as existsSync114, readFileSync as readFileSync81 } from "node:fs";
80392
80383
  import { resolve as resolve11 } from "node:path";
80393
80384
  function resolveRoot2(projectRoot) {
80394
80385
  return projectRoot || getProjectRoot();
@@ -80408,7 +80399,7 @@ function injectContext(protocolType, params, projectRoot) {
80408
80399
  for (const loc of protocolLocations) {
80409
80400
  if (existsSync114(loc)) {
80410
80401
  try {
80411
- protocolContent = readFileSync82(loc, "utf-8");
80402
+ protocolContent = readFileSync81(loc, "utf-8");
80412
80403
  protocolPath = loc.replace(root + "/", "");
80413
80404
  break;
80414
80405
  } catch {
@@ -86108,7 +86099,7 @@ __export(migration_sqlite_exports, {
86108
86099
  migrateJsonToSqlite: () => migrateJsonToSqlite2,
86109
86100
  migrateJsonToSqliteAtomic: () => migrateJsonToSqliteAtomic
86110
86101
  });
86111
- import { existsSync as existsSync117, mkdirSync as mkdirSync25, readFileSync as readFileSync83 } from "node:fs";
86102
+ import { existsSync as existsSync117, mkdirSync as mkdirSync25, readFileSync as readFileSync82 } from "node:fs";
86112
86103
  import { dirname as dirname22, join as join114 } from "node:path";
86113
86104
  function topoSortTasks(tasks2) {
86114
86105
  const taskMap = new Map(tasks2.map((t) => [t.id, t]));
@@ -86147,7 +86138,7 @@ function countJsonRecords(cleoDir) {
86147
86138
  const todoPath = join114(cleoDir, "todo.json");
86148
86139
  if (existsSync117(todoPath)) {
86149
86140
  try {
86150
- const data = JSON.parse(readFileSync83(todoPath, "utf-8"));
86141
+ const data = JSON.parse(readFileSync82(todoPath, "utf-8"));
86151
86142
  tasks2 = (data.tasks ?? []).length;
86152
86143
  } catch {
86153
86144
  }
@@ -86155,7 +86146,7 @@ function countJsonRecords(cleoDir) {
86155
86146
  const archivePath = join114(cleoDir, "todo-archive.json");
86156
86147
  if (existsSync117(archivePath)) {
86157
86148
  try {
86158
- const data = JSON.parse(readFileSync83(archivePath, "utf-8"));
86149
+ const data = JSON.parse(readFileSync82(archivePath, "utf-8"));
86159
86150
  archived = (data.tasks ?? data.archivedTasks ?? []).length;
86160
86151
  } catch {
86161
86152
  }
@@ -86163,7 +86154,7 @@ function countJsonRecords(cleoDir) {
86163
86154
  const sessionsPath = join114(cleoDir, "sessions.json");
86164
86155
  if (existsSync117(sessionsPath)) {
86165
86156
  try {
86166
- const data = JSON.parse(readFileSync83(sessionsPath, "utf-8"));
86157
+ const data = JSON.parse(readFileSync82(sessionsPath, "utf-8"));
86167
86158
  sessions2 = (data.sessions ?? []).length;
86168
86159
  } catch {
86169
86160
  }
@@ -86236,7 +86227,7 @@ async function runMigrationDataImport(db, cleoDir, result, logger) {
86236
86227
  logger?.info("import", "read-todo", "Reading todo.json", {
86237
86228
  path: todoPath.replace(cleoDir, ".")
86238
86229
  });
86239
- const todoData = JSON.parse(readFileSync83(todoPath, "utf-8"));
86230
+ const todoData = JSON.parse(readFileSync82(todoPath, "utf-8"));
86240
86231
  const tasks2 = topoSortTasks(todoData.tasks ?? []);
86241
86232
  const totalTasks = tasks2.length;
86242
86233
  logger?.info("import", "tasks-start", `Starting import of ${totalTasks} tasks`, {
@@ -86316,7 +86307,7 @@ async function runMigrationDataImport(db, cleoDir, result, logger) {
86316
86307
  logger?.info("import", "read-archive", "Reading todo-archive.json", {
86317
86308
  path: archivePath.replace(cleoDir, ".")
86318
86309
  });
86319
- const archiveData = JSON.parse(readFileSync83(archivePath, "utf-8"));
86310
+ const archiveData = JSON.parse(readFileSync82(archivePath, "utf-8"));
86320
86311
  const archivedTasks = topoSortTasks(archiveData.tasks ?? archiveData.archivedTasks ?? []);
86321
86312
  const totalArchived = archivedTasks.length;
86322
86313
  logger?.info(
@@ -86385,7 +86376,7 @@ async function runMigrationDataImport(db, cleoDir, result, logger) {
86385
86376
  logger?.info("import", "read-sessions", "Reading sessions.json", {
86386
86377
  path: sessionsPath.replace(cleoDir, ".")
86387
86378
  });
86388
- const sessionsData = JSON.parse(readFileSync83(sessionsPath, "utf-8"));
86379
+ const sessionsData = JSON.parse(readFileSync82(sessionsPath, "utf-8"));
86389
86380
  const sessions2 = sessionsData.sessions ?? [];
86390
86381
  const totalSessions = sessions2.length;
86391
86382
  logger?.info("import", "sessions-start", `Starting import of ${totalSessions} sessions`, {
@@ -86515,7 +86506,7 @@ async function migrateJsonToSqlite2(cwd, options) {
86515
86506
  const todoPath = join114(cleoDir, "todo.json");
86516
86507
  if (existsSync117(todoPath)) {
86517
86508
  try {
86518
- const todoData = JSON.parse(readFileSync83(todoPath, "utf-8"));
86509
+ const todoData = JSON.parse(readFileSync82(todoPath, "utf-8"));
86519
86510
  const tasks2 = topoSortTasks(todoData.tasks ?? []);
86520
86511
  for (const task of tasks2) {
86521
86512
  try {
@@ -86567,7 +86558,7 @@ async function migrateJsonToSqlite2(cwd, options) {
86567
86558
  const archivePath = join114(cleoDir, "todo-archive.json");
86568
86559
  if (existsSync117(archivePath)) {
86569
86560
  try {
86570
- const archiveData = JSON.parse(readFileSync83(archivePath, "utf-8"));
86561
+ const archiveData = JSON.parse(readFileSync82(archivePath, "utf-8"));
86571
86562
  const archivedTasks = topoSortTasks(archiveData.tasks ?? archiveData.archivedTasks ?? []);
86572
86563
  for (const task of archivedTasks) {
86573
86564
  try {
@@ -86605,7 +86596,7 @@ async function migrateJsonToSqlite2(cwd, options) {
86605
86596
  const sessionsPath = join114(cleoDir, "sessions.json");
86606
86597
  if (existsSync117(sessionsPath)) {
86607
86598
  try {
86608
- const sessionsData = JSON.parse(readFileSync83(sessionsPath, "utf-8"));
86599
+ const sessionsData = JSON.parse(readFileSync82(sessionsPath, "utf-8"));
86609
86600
  const sessions2 = sessionsData.sessions ?? [];
86610
86601
  for (const session of sessions2) {
86611
86602
  try {
@@ -86786,8 +86777,8 @@ import {
86786
86777
  existsSync as existsSync118,
86787
86778
  mkdirSync as mkdirSync26,
86788
86779
  readdirSync as readdirSync39,
86789
- readFileSync as readFileSync84,
86790
- writeFileSync as writeFileSync21
86780
+ readFileSync as readFileSync83,
86781
+ writeFileSync as writeFileSync20
86791
86782
  } from "node:fs";
86792
86783
  import { join as join115 } from "node:path";
86793
86784
  async function runUpgrade(options = {}) {
@@ -86877,8 +86868,8 @@ async function runUpgrade(options = {}) {
86877
86868
  }
86878
86869
  copyFileSync9(dbPath2, dbBackupPath);
86879
86870
  const { createHash: createHash14 } = await import("node:crypto");
86880
- const origChecksum = createHash14("sha256").update(readFileSync84(dbPath2)).digest("hex");
86881
- const backupChecksum = createHash14("sha256").update(readFileSync84(dbBackupPath)).digest("hex");
86871
+ const origChecksum = createHash14("sha256").update(readFileSync83(dbPath2)).digest("hex");
86872
+ const backupChecksum = createHash14("sha256").update(readFileSync83(dbBackupPath)).digest("hex");
86882
86873
  if (origChecksum !== backupChecksum) {
86883
86874
  throw new Error(
86884
86875
  `Backup verification failed: checksum mismatch. Aborting migration to prevent data loss.`
@@ -86902,7 +86893,7 @@ async function runUpgrade(options = {}) {
86902
86893
  const configPath = join115(cleoDir2, "config.json");
86903
86894
  let configBackup = null;
86904
86895
  if (existsSync118(configPath)) {
86905
- configBackup = readFileSync84(configPath, "utf-8");
86896
+ configBackup = readFileSync83(configPath, "utf-8");
86906
86897
  }
86907
86898
  const { resetDbState: resetDbState2 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
86908
86899
  resetDbState2();
@@ -86933,7 +86924,7 @@ async function runUpgrade(options = {}) {
86933
86924
  if (totalImported === 0 && existsSync118(dbBackupPath)) {
86934
86925
  copyFileSync9(dbBackupPath, dbPath2);
86935
86926
  if (configBackup) {
86936
- writeFileSync21(configPath, configBackup);
86927
+ writeFileSync20(configPath, configBackup);
86937
86928
  }
86938
86929
  actions.push({
86939
86930
  action: "storage_migration",
@@ -86946,7 +86937,7 @@ async function runUpgrade(options = {}) {
86946
86937
  let config2 = {};
86947
86938
  if (existsSync118(configPath)) {
86948
86939
  try {
86949
- config2 = JSON.parse(readFileSync84(configPath, "utf-8"));
86940
+ config2 = JSON.parse(readFileSync83(configPath, "utf-8"));
86950
86941
  } catch {
86951
86942
  }
86952
86943
  }
@@ -86954,7 +86945,7 @@ async function runUpgrade(options = {}) {
86954
86945
  config2.storage = {};
86955
86946
  }
86956
86947
  config2.storage.engine = "sqlite";
86957
- writeFileSync21(configPath, JSON.stringify(config2, null, 2));
86948
+ writeFileSync20(configPath, JSON.stringify(config2, null, 2));
86958
86949
  actions.push({
86959
86950
  action: "storage_migration",
86960
86951
  status: "applied",
@@ -86976,7 +86967,7 @@ async function runUpgrade(options = {}) {
86976
86967
  copyFileSync9(dbBackupPath, dbPath2);
86977
86968
  }
86978
86969
  if (configBackup) {
86979
- writeFileSync21(configPath, configBackup);
86970
+ writeFileSync20(configPath, configBackup);
86980
86971
  }
86981
86972
  await updateMigrationPhase2(cleoDir2, "failed");
86982
86973
  for (const error48 of result.errors) {
@@ -87204,7 +87195,7 @@ async function runUpgrade(options = {}) {
87204
87195
  });
87205
87196
  } else {
87206
87197
  try {
87207
- const context = JSON.parse(readFileSync84(contextPath, "utf-8"));
87198
+ const context = JSON.parse(readFileSync83(contextPath, "utf-8"));
87208
87199
  if (context.detectedAt) {
87209
87200
  const daysSince = (Date.now() - new Date(context.detectedAt).getTime()) / (1e3 * 60 * 60 * 24);
87210
87201
  if (daysSince > 30) {
@@ -88887,10 +88878,10 @@ var init_param_utils = __esm({
88887
88878
  });
88888
88879
 
88889
88880
  // packages/core/src/validation/protocols/_shared.ts
88890
- import { existsSync as existsSync119, readFileSync as readFileSync85 } from "node:fs";
88881
+ import { existsSync as existsSync119, readFileSync as readFileSync84 } from "node:fs";
88891
88882
  function findManifestEntry2(taskId, manifestPath) {
88892
88883
  if (!existsSync119(manifestPath)) return null;
88893
- const content = readFileSync85(manifestPath, "utf-8").trim();
88884
+ const content = readFileSync84(manifestPath, "utf-8").trim();
88894
88885
  if (content.length === 0) return null;
88895
88886
  const lines = content.split("\n");
88896
88887
  for (let i = lines.length - 1; i >= 0; i--) {
@@ -88917,7 +88908,7 @@ function loadManifestEntryFromFile(manifestFile) {
88917
88908
  details: { field: "manifestFile", actual: manifestFile }
88918
88909
  });
88919
88910
  }
88920
- return JSON.parse(readFileSync85(manifestFile, "utf-8"));
88911
+ return JSON.parse(readFileSync84(manifestFile, "utf-8"));
88921
88912
  }
88922
88913
  function throwIfStrictFailed(result, opts, protocol, taskId) {
88923
88914
  if (!opts.strict || result.valid) return;
@@ -88987,10 +88978,10 @@ var init_artifact_publish = __esm({
88987
88978
  });
88988
88979
 
88989
88980
  // packages/core/src/validation/protocols/consensus.ts
88990
- import { existsSync as existsSync120, readFileSync as readFileSync86 } from "node:fs";
88981
+ import { existsSync as existsSync120, readFileSync as readFileSync85 } from "node:fs";
88991
88982
  function loadVotingMatrix(votingMatrixFile) {
88992
88983
  if (!votingMatrixFile || !existsSync120(votingMatrixFile)) return { options: [] };
88993
- const raw = JSON.parse(readFileSync86(votingMatrixFile, "utf-8"));
88984
+ const raw = JSON.parse(readFileSync85(votingMatrixFile, "utf-8"));
88994
88985
  const options = Array.isArray(raw.options) ? raw.options : Object.values(raw.options ?? {});
88995
88986
  return {
88996
88987
  options: options.filter(
@@ -89155,10 +89146,10 @@ var init_research4 = __esm({
89155
89146
  });
89156
89147
 
89157
89148
  // packages/core/src/validation/protocols/specification.ts
89158
- import { existsSync as existsSync121, readFileSync as readFileSync87 } from "node:fs";
89149
+ import { existsSync as existsSync121, readFileSync as readFileSync86 } from "node:fs";
89159
89150
  async function validateSpecificationTask(taskId, opts) {
89160
89151
  const entry = loadManifestEntryByTaskId(taskId);
89161
- const specContent = opts.specFile && existsSync121(opts.specFile) ? readFileSync87(opts.specFile, "utf-8") : void 0;
89152
+ const specContent = opts.specFile && existsSync121(opts.specFile) ? readFileSync86(opts.specFile, "utf-8") : void 0;
89162
89153
  const result = validateSpecificationProtocol(entry, specContent);
89163
89154
  throwIfStrictFailed(result, opts, "specification", taskId);
89164
89155
  return result;
@@ -89166,7 +89157,7 @@ async function validateSpecificationTask(taskId, opts) {
89166
89157
  async function checkSpecificationManifest(manifestFile, opts) {
89167
89158
  const entry = loadManifestEntryFromFile(manifestFile);
89168
89159
  const taskId = entry.linked_tasks?.[0] ?? "UNKNOWN";
89169
- const specContent = opts.specFile && existsSync121(opts.specFile) ? readFileSync87(opts.specFile, "utf-8") : void 0;
89160
+ const specContent = opts.specFile && existsSync121(opts.specFile) ? readFileSync86(opts.specFile, "utf-8") : void 0;
89170
89161
  const result = validateSpecificationProtocol(entry, specContent);
89171
89162
  throwIfStrictFailed(result, opts, "specification", taskId);
89172
89163
  return result;
@@ -89226,7 +89217,7 @@ var init_validation3 = __esm({
89226
89217
  // packages/core/src/validation/schema-validator.ts
89227
89218
  import AjvModule from "ajv";
89228
89219
  import addFormatsModule from "ajv-formats";
89229
- import { readFileSync as readFileSync88 } from "fs";
89220
+ import { readFileSync as readFileSync87 } from "fs";
89230
89221
  function createAjv() {
89231
89222
  const ajv = new Ajv3({
89232
89223
  allErrors: true,
@@ -89255,7 +89246,7 @@ function getValidator(schemaType) {
89255
89246
  return null;
89256
89247
  }
89257
89248
  try {
89258
- const schemaContent = readFileSync88(schemaPath, "utf-8");
89249
+ const schemaContent = readFileSync87(schemaPath, "utf-8");
89259
89250
  const schema = JSON.parse(schemaContent);
89260
89251
  const ajv = getAjv2();
89261
89252
  const validate = ajv.compile(schema);
@@ -89309,11 +89300,11 @@ var init_schema_validator = __esm({
89309
89300
 
89310
89301
  // packages/core/src/validation/validate-ops.ts
89311
89302
  import { execFileSync as execFileSync12 } from "node:child_process";
89312
- import { appendFileSync as appendFileSync10, existsSync as existsSync122, mkdirSync as mkdirSync27, readFileSync as readFileSync89 } from "node:fs";
89303
+ import { appendFileSync as appendFileSync10, existsSync as existsSync122, mkdirSync as mkdirSync27, readFileSync as readFileSync88 } from "node:fs";
89313
89304
  import { dirname as dirname23, join as join116, resolve as resolve12 } from "node:path";
89314
89305
  function readJsonFile2(filePath) {
89315
89306
  try {
89316
- const raw = readFileSync89(filePath, "utf-8");
89307
+ const raw = readFileSync88(filePath, "utf-8");
89317
89308
  return JSON.parse(raw);
89318
89309
  } catch {
89319
89310
  return null;
@@ -89478,7 +89469,7 @@ function coreValidateManifest(projectRoot) {
89478
89469
  message: "No manifest file found"
89479
89470
  };
89480
89471
  }
89481
- const content = readFileSync89(manifestPath, "utf-8");
89472
+ const content = readFileSync88(manifestPath, "utf-8");
89482
89473
  const lines = content.split("\n").filter((l) => l.trim());
89483
89474
  let validCount = 0;
89484
89475
  let invalidCount = 0;
@@ -89522,7 +89513,7 @@ function coreValidateOutput(filePath, taskId, projectRoot) {
89522
89513
  if (!existsSync122(fullPath)) {
89523
89514
  throw new Error(`Output file not found: ${filePath}`);
89524
89515
  }
89525
- const content = readFileSync89(fullPath, "utf-8");
89516
+ const content = readFileSync88(fullPath, "utf-8");
89526
89517
  const issues = [];
89527
89518
  if (!content.includes("# ")) {
89528
89519
  issues.push({
@@ -89558,7 +89549,7 @@ function parseComplianceEntries(projectRoot) {
89558
89549
  if (!existsSync122(compliancePath)) {
89559
89550
  return [];
89560
89551
  }
89561
- const content = readFileSync89(compliancePath, "utf-8");
89552
+ const content = readFileSync88(compliancePath, "utf-8");
89562
89553
  const entries = [];
89563
89554
  for (const line2 of content.split("\n")) {
89564
89555
  const trimmed = line2.trim();
@@ -89905,7 +89896,7 @@ var init_validate_ops = __esm({
89905
89896
  });
89906
89897
 
89907
89898
  // packages/core/src/orchestration/bootstrap.ts
89908
- import { existsSync as existsSync123, readFileSync as readFileSync90 } from "node:fs";
89899
+ import { existsSync as existsSync123, readFileSync as readFileSync89 } from "node:fs";
89909
89900
  import { join as join117 } from "node:path";
89910
89901
  async function buildBrainState(projectRoot, opts, accessor) {
89911
89902
  const speed = opts?.speed || "fast";
@@ -89974,7 +89965,7 @@ async function buildBrainState(projectRoot, opts, accessor) {
89974
89965
  try {
89975
89966
  const decisionLogPath = join117(projectRoot, ".cleo", "decision-log.jsonl");
89976
89967
  if (existsSync123(decisionLogPath)) {
89977
- const content = readFileSync90(decisionLogPath, "utf-8").trim();
89968
+ const content = readFileSync89(decisionLogPath, "utf-8").trim();
89978
89969
  if (content) {
89979
89970
  const entries = content.split("\n").filter((l) => l.trim()).map((l) => {
89980
89971
  try {
@@ -89996,7 +89987,7 @@ async function buildBrainState(projectRoot, opts, accessor) {
89996
89987
  try {
89997
89988
  const contextStatePath = join117(projectRoot, ".cleo", ".context-state.json");
89998
89989
  if (existsSync123(contextStatePath)) {
89999
- const state = JSON.parse(readFileSync90(contextStatePath, "utf-8"));
89990
+ const state = JSON.parse(readFileSync89(contextStatePath, "utf-8"));
90000
89991
  const percentage = state.contextWindow?.percentage ?? 0;
90001
89992
  const factors = [];
90002
89993
  if (percentage > 80) factors.push("high_context_usage");
@@ -97342,13 +97333,13 @@ var init_backup_unpack = __esm({
97342
97333
 
97343
97334
  // packages/core/src/store/regenerators.ts
97344
97335
  import { randomUUID as randomUUID10 } from "node:crypto";
97345
- import { existsSync as existsSync124, readFileSync as readFileSync91 } from "node:fs";
97336
+ import { existsSync as existsSync124, readFileSync as readFileSync90 } from "node:fs";
97346
97337
  import { join as join118, resolve as resolve13 } from "node:path";
97347
97338
  function isContributorProject(projectRoot) {
97348
97339
  const at2 = (p2) => existsSync124(join118(projectRoot, p2));
97349
97340
  if (!at2("src/dispatch") || !at2("src/core")) return false;
97350
97341
  try {
97351
- const pkg = JSON.parse(readFileSync91(join118(projectRoot, "package.json"), "utf-8"));
97342
+ const pkg = JSON.parse(readFileSync90(join118(projectRoot, "package.json"), "utf-8"));
97352
97343
  return pkg.name === "@cleocode/cleo";
97353
97344
  } catch {
97354
97345
  return false;
@@ -98354,7 +98345,7 @@ var init_api_key_kdf = __esm({
98354
98345
 
98355
98346
  // packages/core/src/store/agent-registry-accessor.ts
98356
98347
  import { randomBytes as randomBytes16 } from "node:crypto";
98357
- import { existsSync as existsSync125, mkdirSync as mkdirSync28, readFileSync as readFileSync92, statSync as statSync21, writeFileSync as writeFileSync22 } from "node:fs";
98348
+ import { existsSync as existsSync125, mkdirSync as mkdirSync28, readFileSync as readFileSync91, statSync as statSync21, writeFileSync as writeFileSync21 } from "node:fs";
98358
98349
  import { createRequire as createRequire12 } from "node:module";
98359
98350
  import { join as join120 } from "node:path";
98360
98351
  function readMachineKey() {
@@ -98365,7 +98356,7 @@ function readMachineKey() {
98365
98356
  mkdirSync28(cleoHome, { recursive: true });
98366
98357
  }
98367
98358
  const key2 = randomBytes16(MACHINE_KEY_LENGTH);
98368
- writeFileSync22(keyPath, key2, { mode: 384 });
98359
+ writeFileSync21(keyPath, key2, { mode: 384 });
98369
98360
  return key2;
98370
98361
  }
98371
98362
  if (process.platform !== "win32") {
@@ -98377,7 +98368,7 @@ function readMachineKey() {
98377
98368
  );
98378
98369
  }
98379
98370
  }
98380
- const key = readFileSync92(keyPath);
98371
+ const key = readFileSync91(keyPath);
98381
98372
  if (key.length !== MACHINE_KEY_LENGTH) {
98382
98373
  throw new Error(
98383
98374
  `Machine key at ${keyPath} has wrong length: expected ${MACHINE_KEY_LENGTH} bytes, got ${key.length}.`
@@ -102133,6 +102124,30 @@ var init_registry5 = __esm({
102133
102124
  sessionRequired: false,
102134
102125
  requiredParams: []
102135
102126
  },
102127
+ {
102128
+ gateway: "query",
102129
+ domain: "admin",
102130
+ operation: "roadmap",
102131
+ description: "admin.roadmap (query) \u2014 project roadmap from task provenance, epics grouped by status with progress",
102132
+ tier: 1,
102133
+ idempotent: true,
102134
+ sessionRequired: false,
102135
+ requiredParams: [],
102136
+ params: [
102137
+ {
102138
+ name: "includeHistory",
102139
+ type: "boolean",
102140
+ required: false,
102141
+ description: "Include release history from CHANGELOG.md"
102142
+ },
102143
+ {
102144
+ name: "upcomingOnly",
102145
+ type: "boolean",
102146
+ required: false,
102147
+ description: "Only show pending/upcoming epics (exclude completed)"
102148
+ }
102149
+ ]
102150
+ },
102136
102151
  {
102137
102152
  gateway: "query",
102138
102153
  domain: "admin",
@@ -102595,13 +102610,19 @@ var init_registry5 = __esm({
102595
102610
  tier: 0,
102596
102611
  idempotent: false,
102597
102612
  sessionRequired: true,
102598
- requiredParams: ["id"],
102613
+ requiredParams: ["taskId", "agentId"],
102599
102614
  params: [
102600
102615
  {
102601
- name: "id",
102616
+ name: "taskId",
102602
102617
  type: "string",
102603
102618
  required: true,
102604
102619
  description: "Task ID to claim"
102620
+ },
102621
+ {
102622
+ name: "agentId",
102623
+ type: "string",
102624
+ required: true,
102625
+ description: "Agent ID to assign the task to"
102605
102626
  }
102606
102627
  ]
102607
102628
  },
@@ -102613,10 +102634,10 @@ var init_registry5 = __esm({
102613
102634
  tier: 0,
102614
102635
  idempotent: false,
102615
102636
  sessionRequired: true,
102616
- requiredParams: ["id"],
102637
+ requiredParams: ["taskId"],
102617
102638
  params: [
102618
102639
  {
102619
- name: "id",
102640
+ name: "taskId",
102620
102641
  type: "string",
102621
102642
  required: true,
102622
102643
  description: "Task ID to unclaim"
@@ -106236,7 +106257,7 @@ var init_pipeline_engine = __esm({
106236
106257
 
106237
106258
  // packages/cleo/src/dispatch/engines/release-engine.ts
106238
106259
  import { execFileSync as execFileSync14 } from "node:child_process";
106239
- import { readFileSync as readFileSync93 } from "node:fs";
106260
+ import { readFileSync as readFileSync92 } from "node:fs";
106240
106261
  async function loadTasks2(projectRoot) {
106241
106262
  const root = projectRoot ?? resolveProjectRoot();
106242
106263
  try {
@@ -106487,7 +106508,7 @@ async function releaseShip(params, projectRoot) {
106487
106508
  const changelogPath = `${cwd}/CHANGELOG.md`;
106488
106509
  const cleanVersion = version2.replace(/^v/, "");
106489
106510
  try {
106490
- const changelogContent = readFileSync93(changelogPath, "utf8");
106511
+ const changelogContent = readFileSync92(changelogPath, "utf8");
106491
106512
  if (!changelogContent.includes(`## [${cleanVersion}]`)) {
106492
106513
  logStep(
106493
106514
  4,
@@ -106741,7 +106762,7 @@ __export(system_engine_exports, {
106741
106762
  systemSync: () => systemSync,
106742
106763
  systemUncancel: () => systemUncancel
106743
106764
  });
106744
- import { existsSync as existsSync126, readdirSync as readdirSync40, readFileSync as readFileSync94 } from "node:fs";
106765
+ import { existsSync as existsSync126, readdirSync as readdirSync40, readFileSync as readFileSync93 } from "node:fs";
106745
106766
  import { basename as basename18, join as join121 } from "node:path";
106746
106767
  async function systemDash(projectRoot, params) {
106747
106768
  try {
@@ -106980,7 +107001,7 @@ function systemContext(projectRoot, params) {
106980
107001
  } else {
106981
107002
  const currentSessionPath = join121(cleoDir, ".current-session");
106982
107003
  if (existsSync126(currentSessionPath)) {
106983
- const currentSession2 = readFileSync94(currentSessionPath, "utf-8").trim();
107004
+ const currentSession2 = readFileSync93(currentSessionPath, "utf-8").trim();
106984
107005
  if (currentSession2) {
106985
107006
  const sessionFile = join121(
106986
107007
  cleoDir,
@@ -107001,7 +107022,7 @@ function systemContext(projectRoot, params) {
107001
107022
  for (const file2 of readdirSync40(statesDir)) {
107002
107023
  if (file2.startsWith("context-state-") && file2.endsWith(".json")) {
107003
107024
  try {
107004
- const state = JSON.parse(readFileSync94(join121(statesDir, file2), "utf-8"));
107025
+ const state = JSON.parse(readFileSync93(join121(statesDir, file2), "utf-8"));
107005
107026
  sessions2.push({
107006
107027
  file: basename18(file2),
107007
107028
  sessionId: state.sessionId ?? null,
@@ -107017,7 +107038,7 @@ function systemContext(projectRoot, params) {
107017
107038
  const singletonFile = join121(cleoDir, ".context-state.json");
107018
107039
  if (existsSync126(singletonFile)) {
107019
107040
  try {
107020
- const state = JSON.parse(readFileSync94(singletonFile, "utf-8"));
107041
+ const state = JSON.parse(readFileSync93(singletonFile, "utf-8"));
107021
107042
  sessions2.push({
107022
107043
  file: ".context-state.json",
107023
107044
  sessionId: state.sessionId ?? "global",
@@ -107044,7 +107065,7 @@ function systemContext(projectRoot, params) {
107044
107065
  };
107045
107066
  }
107046
107067
  try {
107047
- const state = JSON.parse(readFileSync94(stateFile, "utf-8"));
107068
+ const state = JSON.parse(readFileSync93(stateFile, "utf-8"));
107048
107069
  const timestamp2 = state.timestamp;
107049
107070
  const staleMs = state.staleAfterMs ?? 5e3;
107050
107071
  const percentage = state.contextWindow?.percentage ?? 0;
@@ -107199,7 +107220,7 @@ function systemCompliance(projectRoot, params) {
107199
107220
  const compliancePath2 = join121(projectRoot, ".cleo", "metrics", "COMPLIANCE.jsonl");
107200
107221
  let entries2 = [];
107201
107222
  if (existsSync126(compliancePath2)) {
107202
- const content = readFileSync94(compliancePath2, "utf-8").trim();
107223
+ const content = readFileSync93(compliancePath2, "utf-8").trim();
107203
107224
  if (content) {
107204
107225
  entries2 = content.split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
107205
107226
  }
@@ -107266,7 +107287,7 @@ function systemCompliance(projectRoot, params) {
107266
107287
  const compliancePath = join121(projectRoot, ".cleo", "metrics", "COMPLIANCE.jsonl");
107267
107288
  let entries = [];
107268
107289
  if (existsSync126(compliancePath)) {
107269
- const content = readFileSync94(compliancePath, "utf-8").trim();
107290
+ const content = readFileSync93(compliancePath, "utf-8").trim();
107270
107291
  if (content) {
107271
107292
  entries = content.split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
107272
107293
  }
@@ -107412,9 +107433,9 @@ function systemSync(_projectRoot, params) {
107412
107433
  }
107413
107434
  };
107414
107435
  }
107415
- function systemSafestop(projectRoot, params) {
107436
+ async function systemSafestop(projectRoot, params) {
107416
107437
  try {
107417
- const result = safestop(projectRoot, params);
107438
+ const result = await safestop(projectRoot, params);
107418
107439
  return { success: true, data: result };
107419
107440
  } catch (err) {
107420
107441
  return cleoErrorToEngineError(err, "E_GENERAL", "Sync failed");
@@ -108007,13 +108028,16 @@ async function taskDelete(projectRoot, taskId, force) {
108007
108028
  return cleoErrorToEngineError(err, "E_NOT_INITIALIZED", "Task database not initialized");
108008
108029
  }
108009
108030
  }
108010
- async function taskArchive(projectRoot, taskId, before) {
108031
+ async function taskArchive(projectRoot, taskId, before, opts) {
108011
108032
  try {
108012
108033
  const accessor = await getAccessor(projectRoot);
108034
+ const taskIds = opts?.taskIds ?? (taskId ? [taskId] : void 0);
108013
108035
  const result = await archiveTasks(
108014
108036
  {
108015
- taskIds: taskId ? [taskId] : void 0,
108016
- before
108037
+ taskIds,
108038
+ before,
108039
+ includeCancelled: opts?.includeCancelled,
108040
+ dryRun: opts?.dryRun
108017
108041
  },
108018
108042
  projectRoot,
108019
108043
  accessor
@@ -109397,6 +109421,13 @@ var init_admin2 = __esm({
109397
109421
  });
109398
109422
  return wrapResult(result, "query", "admin", operation, startTime);
109399
109423
  }
109424
+ case "roadmap": {
109425
+ const result = await systemRoadmap(projectRoot, {
109426
+ includeHistory: params?.includeHistory,
109427
+ upcomingOnly: params?.upcomingOnly
109428
+ });
109429
+ return wrapResult(result, "query", "admin", operation, startTime);
109430
+ }
109400
109431
  case "smoke": {
109401
109432
  const result = await systemSmoke();
109402
109433
  return wrapResult(result, "query", "admin", operation, startTime);
@@ -109592,7 +109623,7 @@ var init_admin2 = __esm({
109592
109623
  );
109593
109624
  }
109594
109625
  case "safestop": {
109595
- const result = systemSafestop(
109626
+ const result = await systemSafestop(
109596
109627
  projectRoot,
109597
109628
  params
109598
109629
  );
@@ -109897,6 +109928,7 @@ var init_admin2 = __esm({
109897
109928
  "backup",
109898
109929
  "export",
109899
109930
  "map",
109931
+ "roadmap",
109900
109932
  "smoke",
109901
109933
  "hooks.matrix"
109902
109934
  ],
@@ -114237,7 +114269,12 @@ var init_tasks4 = __esm({
114237
114269
  const result = await taskArchive(
114238
114270
  projectRoot,
114239
114271
  params?.taskId,
114240
- params?.before
114272
+ params?.before,
114273
+ {
114274
+ taskIds: params?.taskIds,
114275
+ includeCancelled: params?.includeCancelled,
114276
+ dryRun: params?.dryRun
114277
+ }
114241
114278
  );
114242
114279
  return wrapResult(result, "mutate", "tasks", operation, startTime);
114243
114280
  }
@@ -115624,7 +115661,7 @@ var init_defaults = __esm({
115624
115661
  });
115625
115662
 
115626
115663
  // packages/cleo/src/dispatch/lib/config-loader.ts
115627
- import { existsSync as existsSync127, readFileSync as readFileSync95 } from "fs";
115664
+ import { existsSync as existsSync127, readFileSync as readFileSync94 } from "fs";
115628
115665
  import { join as join123 } from "path";
115629
115666
  function loadFromEnv(key) {
115630
115667
  const envKey = `${ENV_PREFIX}${key.toUpperCase()}`;
@@ -115651,7 +115688,7 @@ function loadFromFile(projectRoot) {
115651
115688
  return {};
115652
115689
  }
115653
115690
  try {
115654
- const content = readFileSync95(configPath, "utf-8");
115691
+ const content = readFileSync94(configPath, "utf-8");
115655
115692
  const config2 = JSON.parse(content);
115656
115693
  const result = {};
115657
115694
  if (config2.lifecycleEnforcement) {
@@ -117432,7 +117469,7 @@ function registerAddCommand(program) {
117432
117469
  // packages/cleo/src/cli/commands/add-batch.ts
117433
117470
  init_cli();
117434
117471
  init_renderers();
117435
- import { readFileSync as readFileSync96 } from "node:fs";
117472
+ import { readFileSync as readFileSync95 } from "node:fs";
117436
117473
  function registerAddBatchCommand(program) {
117437
117474
  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) => {
117438
117475
  const filePath = opts["file"];
@@ -117446,7 +117483,7 @@ function registerAddBatchCommand(program) {
117446
117483
  }
117447
117484
  raw = Buffer.concat(chunks).toString("utf-8");
117448
117485
  } else {
117449
- raw = readFileSync96(filePath, "utf-8");
117486
+ raw = readFileSync95(filePath, "utf-8");
117450
117487
  }
117451
117488
  let tasks2;
117452
117489
  try {
@@ -117619,6 +117656,13 @@ function registerAdminCommand(program) {
117619
117656
  admin.command("context-inject <protocolType>").description(
117620
117657
  "Inject protocol content into session context (e.g. cleo-base, ct-orchestrator, ct-cleo)"
117621
117658
  ).option("--task <id>", "Scope injection to a specific task ID").option("--variant <variant>", "Select a named protocol variant").action(async (protocolType, opts) => {
117659
+ if (!protocolType || typeof protocolType !== "string" || protocolType.trim() === "") {
117660
+ console.error("Error: missing required argument <protocolType>");
117661
+ console.error(
117662
+ "Usage: cleo admin context-inject <protocolType> [--task <id>] [--variant <variant>]"
117663
+ );
117664
+ process.exit(1);
117665
+ }
117622
117666
  await dispatchFromCli(
117623
117667
  "mutate",
117624
117668
  "admin",
@@ -117728,7 +117772,7 @@ function registerAgentCommand(program) {
117728
117772
  transportConfig: {},
117729
117773
  isActive: true
117730
117774
  });
117731
- const { existsSync: existsSync131, mkdirSync: mkdirSync31, writeFileSync: writeFileSync25 } = await import("node:fs");
117775
+ const { existsSync: existsSync131, mkdirSync: mkdirSync31, writeFileSync: writeFileSync24 } = await import("node:fs");
117732
117776
  const { join: join131 } = await import("node:path");
117733
117777
  const cantDir = join131(".cleo", "agents");
117734
117778
  const cantPath = join131(cantDir, `${agentId}.cant`);
@@ -117784,7 +117828,7 @@ agent ${agentId}:
117784
117828
  enforcement:
117785
117829
  1: TODO \u2014 what does this agent push back on?
117786
117830
  `;
117787
- writeFileSync25(cantPath, cantContent, "utf-8");
117831
+ writeFileSync24(cantPath, cantContent, "utf-8");
117788
117832
  cantScaffolded = true;
117789
117833
  }
117790
117834
  cliOutput(
@@ -119196,7 +119240,7 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119196
119240
  });
119197
119241
  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) => {
119198
119242
  try {
119199
- const { existsSync: existsSync131, mkdirSync: mkdirSync31, writeFileSync: writeFileSync25 } = await import("node:fs");
119243
+ const { existsSync: existsSync131, mkdirSync: mkdirSync31, writeFileSync: writeFileSync24 } = await import("node:fs");
119200
119244
  const { join: join131 } = await import("node:path");
119201
119245
  const { homedir: homedir7 } = await import("node:os");
119202
119246
  const name2 = opts["name"];
@@ -119287,9 +119331,9 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119287
119331
  domain: domain2,
119288
119332
  parent
119289
119333
  });
119290
- writeFileSync25(join131(agentDir, "persona.cant"), personaContent, "utf-8");
119334
+ writeFileSync24(join131(agentDir, "persona.cant"), personaContent, "utf-8");
119291
119335
  const manifest = generateManifest2({ name: name2, role, tier, domain: domain2 });
119292
- writeFileSync25(
119336
+ writeFileSync24(
119293
119337
  join131(agentDir, "manifest.json"),
119294
119338
  `${JSON.stringify(manifest, null, 2)}
119295
119339
  `,
@@ -119301,14 +119345,14 @@ Task ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId}
119301
119345
  ];
119302
119346
  if (team) {
119303
119347
  const teamConfigContent = generateTeamConfig(name2, role, team);
119304
- writeFileSync25(join131(agentDir, "team-config.cant"), teamConfigContent, "utf-8");
119348
+ writeFileSync24(join131(agentDir, "team-config.cant"), teamConfigContent, "utf-8");
119305
119349
  createdFiles.push(join131(agentDir, "team-config.cant"));
119306
119350
  }
119307
119351
  if (seedBrain) {
119308
119352
  const expertiseDir = join131(agentDir, "expertise");
119309
119353
  mkdirSync31(expertiseDir, { recursive: true });
119310
119354
  const seedContent = generateMentalModelSeed(name2, role, domain2);
119311
- writeFileSync25(join131(expertiseDir, "mental-model-seed.md"), seedContent, "utf-8");
119355
+ writeFileSync24(join131(expertiseDir, "mental-model-seed.md"), seedContent, "utf-8");
119312
119356
  createdFiles.push(join131(expertiseDir, "mental-model-seed.md"));
119313
119357
  try {
119314
119358
  const { execFile: execFile9 } = await import("node:child_process");
@@ -119821,6 +119865,12 @@ function registerBackfillCommand(program) {
119821
119865
  const dryRun = !!opts.dryRun;
119822
119866
  const rollback = !!opts.rollback;
119823
119867
  const taskIds = opts.tasks?.trim() ? opts.tasks.split(",").map((s3) => s3.trim()).filter(Boolean) : void 0;
119868
+ 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."
119871
+ );
119872
+ console.log(" Set CLEO_NONINTERACTIVE=1 or pass --dry-run to suppress this warning.\n");
119873
+ }
119824
119874
  if (dryRun) {
119825
119875
  console.log("[dry run] No changes will be made.\n");
119826
119876
  }
@@ -120671,7 +120721,7 @@ function registerCancelCommand(program) {
120671
120721
 
120672
120722
  // packages/cleo/src/cli/commands/cant.ts
120673
120723
  init_renderers();
120674
- import { existsSync as existsSync128, mkdirSync as mkdirSync29, readFileSync as readFileSync97, writeFileSync as writeFileSync23 } from "node:fs";
120724
+ import { existsSync as existsSync128, mkdirSync as mkdirSync29, readFileSync as readFileSync96, writeFileSync as writeFileSync22 } from "node:fs";
120675
120725
  import { dirname as dirname25, isAbsolute as isAbsolute3, join as join124, resolve as resolve15 } from "node:path";
120676
120726
  function registerCantCommand(program) {
120677
120727
  const cant = program.command("cant").description("CANT DSL tooling");
@@ -120749,7 +120799,7 @@ function registerCantCommand(program) {
120749
120799
  }
120750
120800
  try {
120751
120801
  const mod = await loadMigrateEngine();
120752
- const content = readFileSync97(filePath, "utf-8");
120802
+ const content = readFileSync96(filePath, "utf-8");
120753
120803
  const result = mod.migrateMarkdown(content, filePath, {
120754
120804
  write: isWrite,
120755
120805
  verbose: isVerbose,
@@ -120765,7 +120815,7 @@ function registerCantCommand(program) {
120765
120815
  for (const outputFile of result.outputFiles) {
120766
120816
  const outputPath = isAbsolute3(outputFile.path) ? outputFile.path : join124(projectRoot, outputFile.path);
120767
120817
  mkdirSync29(dirname25(outputPath), { recursive: true });
120768
- writeFileSync23(outputPath, outputFile.content, "utf-8");
120818
+ writeFileSync22(outputPath, outputFile.content, "utf-8");
120769
120819
  written++;
120770
120820
  if (isVerbose) {
120771
120821
  console.log(` Created: ${outputFile.path} (${outputFile.kind})`);
@@ -120840,6 +120890,47 @@ async function loadMigrateEngine() {
120840
120890
  throw new Error("Cannot load CANT migration engine. Ensure @cleocode/cant is installed.");
120841
120891
  }
120842
120892
 
120893
+ // packages/cleo/src/cli/commands/chain.ts
120894
+ init_cli();
120895
+ import { readFileSync as readFileSync97 } from "node:fs";
120896
+ function registerChainCommand(program) {
120897
+ const chain = program.command("chain").description("WarpChain pipeline management (tier-2 orchestrator)");
120898
+ chain.command("show <chainId>").description("Show details for a WarpChain definition").action(async (chainId) => {
120899
+ await dispatchFromCli("query", "pipeline", "chain.show", { chainId }, { command: "chain" });
120900
+ });
120901
+ chain.command("list").description("List all WarpChain definitions").action(async () => {
120902
+ await dispatchFromCli("query", "pipeline", "chain.list", {}, { command: "chain" });
120903
+ });
120904
+ chain.command("add <file>").description("Add a new WarpChain definition from a JSON file").action(async (file2) => {
120905
+ const chainJson = JSON.parse(readFileSync97(file2, "utf-8"));
120906
+ await dispatchFromCli(
120907
+ "mutate",
120908
+ "pipeline",
120909
+ "chain.add",
120910
+ { chain: chainJson },
120911
+ { command: "chain" }
120912
+ );
120913
+ });
120914
+ chain.command("instantiate <chainId> <epicId>").description("Instantiate a WarpChain for an epic").action(async (chainId, epicId) => {
120915
+ await dispatchFromCli(
120916
+ "mutate",
120917
+ "pipeline",
120918
+ "chain.instantiate",
120919
+ { chainId, epicId },
120920
+ { command: "chain" }
120921
+ );
120922
+ });
120923
+ chain.command("advance <instanceId> <nextStage>").description("Advance a WarpChain instance to the next stage").action(async (instanceId, nextStage) => {
120924
+ await dispatchFromCli(
120925
+ "mutate",
120926
+ "pipeline",
120927
+ "chain.advance",
120928
+ { instanceId, nextStage },
120929
+ { command: "chain" }
120930
+ );
120931
+ });
120932
+ }
120933
+
120843
120934
  // packages/cleo/src/cli/commands/check.ts
120844
120935
  init_cli();
120845
120936
  var SUPPORTED_PROTOCOL_TYPES = [
@@ -121051,7 +121142,7 @@ function registerCheckpointCommand(program) {
121051
121142
  // packages/cleo/src/cli/commands/claim.ts
121052
121143
  init_cli();
121053
121144
  function registerClaimCommand(program) {
121054
- program.command("claim <taskId>").description("Claim a task by assigning it to an agent").option("--agent <agentId>", "Agent ID to assign the task to (required)").action(async (taskId, opts) => {
121145
+ program.command("claim <taskId>").description("Claim a task by assigning it to an agent").requiredOption("--agent <agentId>", "Agent ID to assign the task to").action(async (taskId, opts) => {
121055
121146
  await dispatchFromCli(
121056
121147
  "mutate",
121057
121148
  "tasks",
@@ -121571,7 +121662,7 @@ function registerDepsCommand(program) {
121571
121662
  {
121572
121663
  epicId
121573
121664
  },
121574
- { command: "deps", operation: "tasks.depends" }
121665
+ { command: "deps", operation: "orchestrate.waves" }
121575
121666
  );
121576
121667
  });
121577
121668
  deps.command("critical-path <taskId>").description("Find longest dependency chain from task").action(async (taskId) => {
@@ -122396,27 +122487,6 @@ function registerDoctorCommand(program) {
122396
122487
  });
122397
122488
  }
122398
122489
 
122399
- // packages/cleo/src/cli/commands/env.ts
122400
- init_internal();
122401
- init_renderers();
122402
- async function getEnvStatus() {
122403
- return getRuntimeDiagnostics({ detailed: false });
122404
- }
122405
- async function getEnvInfo() {
122406
- return getRuntimeDiagnostics({ detailed: true });
122407
- }
122408
- function registerEnvCommand(program) {
122409
- const env = program.command("env").description("Environment and mode inspection");
122410
- env.command("status", { isDefault: true }).description("Show current environment mode and runtime info").action(async () => {
122411
- const result = await getEnvStatus();
122412
- cliOutput(result, { command: "env" });
122413
- });
122414
- env.command("info").description("Show detailed environment info including binary paths and compilation status").action(async () => {
122415
- const result = await getEnvInfo();
122416
- cliOutput(result, { command: "env" });
122417
- });
122418
- }
122419
-
122420
122490
  // packages/cleo/src/cli/commands/exists.ts
122421
122491
  init_src();
122422
122492
  init_internal();
@@ -122487,7 +122557,7 @@ function registerExportTasksCommand(program) {
122487
122557
  program.command("export-tasks [taskIds...]").description("Export tasks to portable .cleo-export.json package for cross-project transfer").option("-o, --output <file>", "Output file path (stdout if omitted)").option("--subtree", "Include all descendants of specified task(s)").option("--filter <filters...>", "Filter tasks by criteria (key=value, repeatable)").option("--include-deps", "Auto-include task dependencies").option("--dry-run", "Preview selection without creating export file").action(async (taskIds, opts) => {
122488
122558
  const hasOutput = !!opts["output"];
122489
122559
  const params = {
122490
- taskIds: taskIds.length > 0 ? taskIds : void 0,
122560
+ taskIds: taskIds && taskIds.length > 0 ? taskIds : void 0,
122491
122561
  output: opts["output"],
122492
122562
  subtree: opts["subtree"],
122493
122563
  filter: opts["filter"],
@@ -122641,7 +122711,7 @@ init_src();
122641
122711
  init_src2();
122642
122712
  init_renderers();
122643
122713
  import { execFileSync as execFileSync16 } from "node:child_process";
122644
- import { existsSync as existsSync130, mkdirSync as mkdirSync30, readFileSync as readFileSync99, writeFileSync as writeFileSync24 } from "node:fs";
122714
+ import { existsSync as existsSync130, mkdirSync as mkdirSync30, readFileSync as readFileSync99, writeFileSync as writeFileSync23 } from "node:fs";
122645
122715
  import { dirname as dirname27, join as join127 } from "node:path";
122646
122716
  function getChangelogSource(cwd) {
122647
122717
  const configPath = getConfigPath(cwd);
@@ -122795,7 +122865,7 @@ function registerGenerateChangelogCommand(program) {
122795
122865
  if (!dryRun) {
122796
122866
  const fullPath = join127(getProjectRoot(), outputPath);
122797
122867
  mkdirSync30(dirname27(fullPath), { recursive: true });
122798
- writeFileSync24(fullPath, content, "utf-8");
122868
+ writeFileSync23(fullPath, content, "utf-8");
122799
122869
  }
122800
122870
  results.push({ platform: targetPlatform, path: outputPath, written: !dryRun });
122801
122871
  } else {
@@ -122816,7 +122886,7 @@ function registerGenerateChangelogCommand(program) {
122816
122886
  if (!dryRun) {
122817
122887
  const fullPath = join127(getProjectRoot(), platformConfig.path);
122818
122888
  mkdirSync30(dirname27(fullPath), { recursive: true });
122819
- writeFileSync24(fullPath, content, "utf-8");
122889
+ writeFileSync23(fullPath, content, "utf-8");
122820
122890
  }
122821
122891
  results.push({
122822
122892
  platform: platformConfig.platform,
@@ -123476,9 +123546,20 @@ function registerMemoryBrainCommand(program) {
123476
123546
  }
123477
123547
  cliOutput(result, { command: "memory", operation: "memory.stats" });
123478
123548
  });
123479
- memory.command("observe <text>").description("Save an observation to brain.db").option("--title <title>", "Short title for the observation").option(
123549
+ memory.command("observe <text>").description(
123550
+ "Save an observation to brain.db \u2014 captures facts, decisions, and discoveries for cross-session memory"
123551
+ ).option(
123552
+ "--title <title>",
123553
+ "Short title for the observation (defaults to first 120 chars of text)"
123554
+ ).option(
123555
+ "--type <type>",
123556
+ "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)"
123557
+ ).option(
123480
123558
  "--agent <name>",
123481
- "Tag this observation with the producing agent name (Wave 8 mental models)"
123559
+ "Name of the agent producing this observation (enables per-agent memory retrieval)"
123560
+ ).option(
123561
+ "--source-type <sourceType>",
123562
+ "How this observation was captured: manual (typed by human/agent), auto (lifecycle hook), transcript (extracted from session)"
123482
123563
  ).action(async (text3, opts) => {
123483
123564
  await dispatchFromCli(
123484
123565
  "mutate",
@@ -123487,7 +123568,9 @@ function registerMemoryBrainCommand(program) {
123487
123568
  {
123488
123569
  text: text3,
123489
123570
  title: opts["title"],
123490
- ...opts["agent"] !== void 0 && { agent: opts["agent"] }
123571
+ ...opts["agent"] !== void 0 && { agent: opts["agent"] },
123572
+ ...opts["type"] !== void 0 && { type: opts["type"] },
123573
+ sourceType: opts["sourceType"] ?? "manual"
123491
123574
  },
123492
123575
  { command: "memory", operation: "memory.observe" }
123493
123576
  );
@@ -123515,7 +123598,7 @@ function registerMemoryBrainCommand(program) {
123515
123598
  { command: "memory", operation: "memory.fetch" }
123516
123599
  );
123517
123600
  });
123518
- 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) => {
123601
+ 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) => {
123519
123602
  await dispatchFromCli(
123520
123603
  "query",
123521
123604
  "memory",
@@ -123527,7 +123610,7 @@ function registerMemoryBrainCommand(program) {
123527
123610
  { command: "memory", operation: "memory.decision.find" }
123528
123611
  );
123529
123612
  });
123530
- memory.command("decision store").description("Store a decision to brain.db").requiredOption("--decision <text>", "The decision that was made").requiredOption("--rationale <text>", "Rationale behind the decision").option("--alternatives <text>", "Alternatives that were considered").option("--linked-task <id>", "Task ID to associate with this decision").option("--json", "Output as JSON").action(async (opts) => {
123613
+ memory.command("decision-store").description("Store a decision to brain.db").requiredOption("--decision <text>", "The decision that was made").requiredOption("--rationale <text>", "Rationale behind the decision").option("--alternatives <text>", "Alternatives that were considered").option("--linked-task <id>", "Task ID to associate with this decision").option("--json", "Output as JSON").action(async (opts) => {
123531
123614
  await dispatchFromCli(
123532
123615
  "mutate",
123533
123616
  "memory",
@@ -123550,7 +123633,7 @@ function registerMemoryBrainCommand(program) {
123550
123633
  { command: "memory", operation: "memory.link" }
123551
123634
  );
123552
123635
  });
123553
- memory.command("graph show <nodeId>").description("Get a PageIndex graph node and its edges").option("--json", "Output as JSON").action(async (nodeId, _opts) => {
123636
+ memory.command("graph-show <nodeId>").description("Get a PageIndex graph node and its edges").option("--json", "Output as JSON").action(async (nodeId, _opts) => {
123554
123637
  await dispatchFromCli(
123555
123638
  "query",
123556
123639
  "memory",
@@ -123559,7 +123642,7 @@ function registerMemoryBrainCommand(program) {
123559
123642
  { command: "memory", operation: "memory.graph.show" }
123560
123643
  );
123561
123644
  });
123562
- memory.command("graph neighbors <nodeId>").description("Get neighbor nodes from the PageIndex graph").option("--depth <n>", "Traversal depth", parseInt).option("--limit <n>", "Maximum neighbors", parseInt).option("--json", "Output as JSON").action(async (nodeId, opts) => {
123645
+ memory.command("graph-neighbors <nodeId>").description("Get neighbor nodes from the PageIndex graph").option("--depth <n>", "Traversal depth", parseInt).option("--limit <n>", "Maximum neighbors", parseInt).option("--json", "Output as JSON").action(async (nodeId, opts) => {
123563
123646
  await dispatchFromCli(
123564
123647
  "query",
123565
123648
  "memory",
@@ -123572,7 +123655,7 @@ function registerMemoryBrainCommand(program) {
123572
123655
  { command: "memory", operation: "memory.graph.neighbors" }
123573
123656
  );
123574
123657
  });
123575
- 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) => {
123658
+ 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) => {
123576
123659
  await dispatchFromCli(
123577
123660
  "mutate",
123578
123661
  "memory",
@@ -123587,7 +123670,7 @@ function registerMemoryBrainCommand(program) {
123587
123670
  { command: "memory", operation: "memory.graph.add" }
123588
123671
  );
123589
123672
  });
123590
- memory.command("graph remove").description("Remove a node or edge from the PageIndex graph").option("--node-id <id>", "Node ID to remove").option("--from <id>", "Source node ID of the edge to remove").option("--to <id>", "Target node ID of the edge to remove").option("--json", "Output as JSON").action(async (opts) => {
123673
+ memory.command("graph-remove").description("Remove a node or edge from the PageIndex graph").option("--node-id <id>", "Node ID to remove").option("--from <id>", "Source node ID of the edge to remove").option("--to <id>", "Target node ID of the edge to remove").option("--json", "Output as JSON").action(async (opts) => {
123591
123674
  await dispatchFromCli(
123592
123675
  "mutate",
123593
123676
  "memory",
@@ -123600,7 +123683,7 @@ function registerMemoryBrainCommand(program) {
123600
123683
  { command: "memory", operation: "memory.graph.remove" }
123601
123684
  );
123602
123685
  });
123603
- memory.command("reason why <taskId>").description("Causal trace through task dependency chains").option("--depth <n>", "Maximum trace depth", parseInt).option("--json", "Output as JSON").action(async (taskId, opts) => {
123686
+ memory.command("reason-why <taskId>").description("Causal trace through task dependency chains").option("--depth <n>", "Maximum trace depth", parseInt).option("--json", "Output as JSON").action(async (taskId, opts) => {
123604
123687
  await dispatchFromCli(
123605
123688
  "query",
123606
123689
  "memory",
@@ -123612,7 +123695,7 @@ function registerMemoryBrainCommand(program) {
123612
123695
  { command: "memory", operation: "memory.reason.why" }
123613
123696
  );
123614
123697
  });
123615
- memory.command("reason similar <entryId>").description("Find semantically similar brain entries").option("--limit <n>", "Maximum results", parseInt).option("--json", "Output as JSON").action(async (entryId, opts) => {
123698
+ memory.command("reason-similar <entryId>").description("Find semantically similar brain entries").option("--limit <n>", "Maximum results", parseInt).option("--json", "Output as JSON").action(async (entryId, opts) => {
123616
123699
  await dispatchFromCli(
123617
123700
  "query",
123618
123701
  "memory",
@@ -123624,7 +123707,7 @@ function registerMemoryBrainCommand(program) {
123624
123707
  { command: "memory", operation: "memory.reason.similar" }
123625
123708
  );
123626
123709
  });
123627
- memory.command("search hybrid <query>").description("Hybrid search across FTS5, vector, and graph indexes").option("--limit <n>", "Maximum results", parseInt).option("--json", "Output as JSON").action(async (query, opts) => {
123710
+ memory.command("search-hybrid <query>").description("Hybrid search across FTS5, vector, and graph indexes").option("--limit <n>", "Maximum results", parseInt).option("--json", "Output as JSON").action(async (query, opts) => {
123628
123711
  await dispatchFromCli(
123629
123712
  "query",
123630
123713
  "memory",
@@ -123919,23 +124002,37 @@ function registerNexusCommand(program) {
123919
124002
  // packages/cleo/src/cli/commands/observe.ts
123920
124003
  init_cli();
123921
124004
  function registerObserveCommand(program) {
123922
- program.command("observe <text>").description("Save an observation to brain.db").option("-t, --title <title>", "Optional title (defaults to first 120 chars of text)").option(
124005
+ program.command("observe <text>").description(
124006
+ "Save an observation to brain.db \u2014 captures facts, decisions, and discoveries for cross-session memory"
124007
+ ).option(
124008
+ "-t, --title <title>",
124009
+ "Short title for the observation (defaults to first 120 chars of text)"
124010
+ ).option(
123923
124011
  "--type <type>",
123924
- "Observation type (discovery, decision, bugfix, refactor, feature, change, pattern, session_summary)"
123925
- ).action(async (text3, opts) => {
123926
- await dispatchFromCli(
123927
- "mutate",
123928
- "memory",
123929
- "observe",
123930
- {
123931
- text: text3,
123932
- title: opts.title,
123933
- ...opts.type !== void 0 && { type: opts.type },
123934
- sourceType: "manual"
123935
- },
123936
- { command: "observe", operation: "memory.observe" }
123937
- );
123938
- });
124012
+ "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)"
124013
+ ).option(
124014
+ "--agent <name>",
124015
+ "Name of the agent producing this observation (enables per-agent memory retrieval)"
124016
+ ).option(
124017
+ "--source-type <sourceType>",
124018
+ "How this observation was captured: manual (typed by human/agent), auto (lifecycle hook), transcript (extracted from session)"
124019
+ ).action(
124020
+ async (text3, opts) => {
124021
+ await dispatchFromCli(
124022
+ "mutate",
124023
+ "memory",
124024
+ "observe",
124025
+ {
124026
+ text: text3,
124027
+ title: opts.title,
124028
+ ...opts.type !== void 0 && { type: opts.type },
124029
+ ...opts.agent !== void 0 && { agent: opts.agent },
124030
+ sourceType: opts.sourceType ?? "manual"
124031
+ },
124032
+ { command: "observe", operation: "memory.observe" }
124033
+ );
124034
+ }
124035
+ );
123939
124036
  }
123940
124037
 
123941
124038
  // packages/cleo/src/cli/commands/ops.ts
@@ -124079,6 +124176,110 @@ function registerOrchestrateCommand(program) {
124079
124176
  { command: "orchestrate" }
124080
124177
  );
124081
124178
  });
124179
+ orch.command("bootstrap").description("Load brain state for agent bootstrapping").option("--epic <epicId>", "Epic ID to scope bootstrap context to").action(async (opts) => {
124180
+ await dispatchFromCli(
124181
+ "query",
124182
+ "orchestrate",
124183
+ "bootstrap",
124184
+ { epicId: opts["epic"] },
124185
+ { command: "orchestrate" }
124186
+ );
124187
+ });
124188
+ orch.command("classify <request>").description("Classify a request using CANT prompt-based team routing").action(async (request) => {
124189
+ await dispatchFromCli(
124190
+ "query",
124191
+ "orchestrate",
124192
+ "classify",
124193
+ { request },
124194
+ { command: "orchestrate" }
124195
+ );
124196
+ });
124197
+ orch.command("fanout-status").description("Get fanout status for an epic").option("--epic <epicId>", "Epic ID to scope fanout status to").action(async (opts) => {
124198
+ await dispatchFromCli(
124199
+ "query",
124200
+ "orchestrate",
124201
+ "fanout.status",
124202
+ { epicId: opts["epic"] },
124203
+ { command: "orchestrate" }
124204
+ );
124205
+ });
124206
+ orch.command("handoff <taskId>").description("Perform session handoff and spawn successor for a task").requiredOption("--protocol <type>", "Protocol type for handoff").action(async (taskId, opts) => {
124207
+ await dispatchFromCli(
124208
+ "mutate",
124209
+ "orchestrate",
124210
+ "handoff",
124211
+ { taskId, protocolType: opts["protocol"] },
124212
+ { command: "orchestrate" }
124213
+ );
124214
+ });
124215
+ orch.command("spawn-execute <taskId>").description("Execute spawn for a task via the adapter registry").action(async (taskId) => {
124216
+ await dispatchFromCli(
124217
+ "mutate",
124218
+ "orchestrate",
124219
+ "spawn.execute",
124220
+ { taskId },
124221
+ { command: "orchestrate" }
124222
+ );
124223
+ });
124224
+ 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) => {
124225
+ const taskIds = typeof opts["tasks"] === "string" ? opts["tasks"].split(",").map((s3) => s3.trim()) : void 0;
124226
+ await dispatchFromCli(
124227
+ "mutate",
124228
+ "orchestrate",
124229
+ "fanout",
124230
+ { epicId, taskIds },
124231
+ { command: "orchestrate" }
124232
+ );
124233
+ });
124234
+ orch.command("conduit-status").description("Get conduit messaging status").action(async () => {
124235
+ await dispatchFromCli(
124236
+ "query",
124237
+ "orchestrate",
124238
+ "conduit.status",
124239
+ {},
124240
+ { command: "orchestrate" }
124241
+ );
124242
+ });
124243
+ orch.command("conduit-peek").description("Peek at queued conduit messages").option("--limit <n>", "Maximum number of messages to return", parseInt).action(async (opts) => {
124244
+ await dispatchFromCli(
124245
+ "query",
124246
+ "orchestrate",
124247
+ "conduit.peek",
124248
+ { limit: opts["limit"] },
124249
+ { command: "orchestrate" }
124250
+ );
124251
+ });
124252
+ orch.command("conduit-start").description("Start the conduit message loop").option("--poll-interval <ms>", "Polling interval in milliseconds", parseInt).action(async (opts) => {
124253
+ await dispatchFromCli(
124254
+ "mutate",
124255
+ "orchestrate",
124256
+ "conduit.start",
124257
+ { pollInterval: opts["pollInterval"] },
124258
+ { command: "orchestrate" }
124259
+ );
124260
+ });
124261
+ orch.command("conduit-stop").description("Stop the conduit message loop").action(async () => {
124262
+ await dispatchFromCli(
124263
+ "mutate",
124264
+ "orchestrate",
124265
+ "conduit.stop",
124266
+ {},
124267
+ { command: "orchestrate" }
124268
+ );
124269
+ });
124270
+ orch.command("conduit-send <content>").description("Send a message via conduit to an agent or conversation").option("--to <agentId>", "Target agent ID").option("--conversation <id>", "Conversation ID to send into").action(async (content, opts) => {
124271
+ await dispatchFromCli(
124272
+ "mutate",
124273
+ "orchestrate",
124274
+ "conduit.send",
124275
+ {
124276
+ content,
124277
+ agentId: opts["to"],
124278
+ conversationId: opts["conversation"]
124279
+ },
124280
+ { command: "orchestrate" }
124281
+ );
124282
+ });
124082
124283
  }
124083
124284
 
124084
124285
  // packages/cleo/src/cli/commands/otel.ts
@@ -125322,17 +125523,18 @@ function registerRestoreCommand(program) {
125322
125523
  // packages/cleo/src/cli/commands/roadmap.ts
125323
125524
  init_cli();
125324
125525
  function registerRoadmapCommand(program) {
125325
- program.command("roadmap").description("Generate roadmap from pending epics and CHANGELOG history").option("--include-history", "Include release history from CHANGELOG").option("--upcoming-only", "Only show upcoming/planned releases").action(async (opts) => {
125526
+ program.command("roadmap").description(
125527
+ "Generate project roadmap from task provenance \u2014 epics grouped by status with progress"
125528
+ ).option("--include-history", "Include release history from CHANGELOG.md").option("--upcoming-only", "Only show pending/upcoming epics (exclude completed)").action(async (opts) => {
125326
125529
  await dispatchFromCli(
125327
125530
  "query",
125328
125531
  "admin",
125329
- "dash",
125532
+ "roadmap",
125330
125533
  {
125331
- type: "roadmap",
125332
125534
  includeHistory: opts["includeHistory"],
125333
125535
  upcomingOnly: opts["upcomingOnly"]
125334
125536
  },
125335
- { command: "roadmap" }
125537
+ { command: "roadmap", operation: "admin.roadmap" }
125336
125538
  );
125337
125539
  });
125338
125540
  }
@@ -126057,7 +126259,7 @@ function registerShowCommand(program) {
126057
126259
  // packages/cleo/src/cli/commands/skills.ts
126058
126260
  init_cli();
126059
126261
  function registerSkillsCommand(program) {
126060
- const skillsCmd = program.command("skills").description("Skill management: list, discover, validate, info, install");
126262
+ const skillsCmd = program.command("skills").description("Skill management: list, search, validate, info, install");
126061
126263
  skillsCmd.command("list").description("List installed skills").option("--global", "Use global skills directory").action(async (opts) => {
126062
126264
  await dispatchFromCli(
126063
126265
  "query",
@@ -126081,17 +126283,6 @@ function registerSkillsCommand(program) {
126081
126283
  { command: "skills", operation: "tools.skill.find" }
126082
126284
  );
126083
126285
  });
126084
- skillsCmd.command("discover").description("Scan and discover available skills").action(async () => {
126085
- await dispatchFromCli(
126086
- "query",
126087
- "tools",
126088
- "skill.list",
126089
- {
126090
- scope: "project"
126091
- },
126092
- { command: "skills", operation: "tools.skill.list" }
126093
- );
126094
- });
126095
126286
  skillsCmd.command("validate <skill-name>").description("Validate skill against protocol").action(async (skillName) => {
126096
126287
  await dispatchFromCli(
126097
126288
  "query",
@@ -126577,6 +126768,36 @@ function registerSyncCommand(program) {
126577
126768
  { command: "sync", operation: "tasks.sync.links" }
126578
126769
  );
126579
126770
  });
126771
+ sync.command("reconcile <file>").description("Reconcile external tasks from a JSON file against CLEO tasks").requiredOption("--provider <providerId>", "Provider ID (e.g. linear, jira, github)").option(
126772
+ "--conflict-policy <policy>",
126773
+ "How to resolve conflicts: keep-cleo, keep-external, or newest (default: keep-cleo)",
126774
+ "keep-cleo"
126775
+ ).action(async (file2, opts) => {
126776
+ const { readFileSync: readFileSync102 } = await import("node:fs");
126777
+ let externalTasks;
126778
+ try {
126779
+ externalTasks = JSON.parse(readFileSync102(file2, "utf8"));
126780
+ } catch (err) {
126781
+ const message = err instanceof Error ? err.message : String(err);
126782
+ console.error(`Failed to read or parse external tasks file: ${message}`);
126783
+ process.exit(2);
126784
+ }
126785
+ if (!Array.isArray(externalTasks)) {
126786
+ console.error("External tasks file must contain a JSON array");
126787
+ process.exit(2);
126788
+ }
126789
+ await dispatchFromCli(
126790
+ "mutate",
126791
+ "tasks",
126792
+ "sync.reconcile",
126793
+ {
126794
+ providerId: opts["provider"],
126795
+ externalTasks,
126796
+ conflictPolicy: opts["conflictPolicy"]
126797
+ },
126798
+ { command: "sync", operation: "tasks.sync.reconcile" }
126799
+ );
126800
+ });
126580
126801
  }
126581
126802
 
126582
126803
  // packages/cleo/src/cli/commands/testing.ts
@@ -126587,13 +126808,14 @@ function registerTestingCommand(program) {
126587
126808
  await dispatchFromCli(
126588
126809
  "query",
126589
126810
  "check",
126590
- "manifest",
126811
+ "protocol",
126591
126812
  {
126813
+ protocolType: "testing",
126814
+ mode: "task",
126592
126815
  taskId,
126593
- strict: !!opts["strict"],
126594
- type: "testing"
126816
+ strict: !!opts["strict"]
126595
126817
  },
126596
- { command: "testing", operation: "check.manifest" }
126818
+ { command: "testing", operation: "check.protocol" }
126597
126819
  );
126598
126820
  });
126599
126821
  testingCmd.command("check <manifestFile>").description("Validate testing protocol from a manifest file").option("--strict", "Exit with error code on violations").action(async (manifestFile, opts) => {
@@ -127266,9 +127488,9 @@ registerDepsCommand(rootShim);
127266
127488
  registerTreeCommand(rootShim);
127267
127489
  registerResearchCommand(rootShim);
127268
127490
  registerOrchestrateCommand(rootShim);
127491
+ registerChainCommand(rootShim);
127269
127492
  registerLifecycleCommand(rootShim);
127270
127493
  registerReleaseCommand(rootShim);
127271
- registerEnvCommand(rootShim);
127272
127494
  registerCheckpointCommand(rootShim);
127273
127495
  registerCommandsCommand(rootShim);
127274
127496
  registerDocsCommand(rootShim);