@cleocode/cleo 2026.5.20 → 2026.5.22

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
@@ -15781,13 +15781,19 @@ var init_memory2 = __esm({
15781
15781
  startTime
15782
15782
  );
15783
15783
  }
15784
+ const confirmationStateRaw = paramString(params, "confirmationState");
15785
+ const decidedByRaw = paramString(params, "decidedBy");
15784
15786
  const result = await memoryDecisionStore(
15785
15787
  {
15786
15788
  decision,
15787
15789
  rationale,
15788
15790
  alternatives: paramStringArray(params, "alternatives"),
15789
15791
  taskId: paramString(params, "taskId"),
15790
- sessionId: paramString(params, "sessionId")
15792
+ sessionId: paramString(params, "sessionId"),
15793
+ adrPath: paramString(params, "adrPath"),
15794
+ supersedes: paramString(params, "supersedes"),
15795
+ confirmationState: confirmationStateRaw === "proposed" || confirmationStateRaw === "accepted" || confirmationStateRaw === "superseded" ? confirmationStateRaw : void 0,
15796
+ decidedBy: decidedByRaw === "owner" || decidedByRaw === "council" || decidedByRaw === "agent" ? decidedByRaw : void 0
15791
15797
  },
15792
15798
  projectRoot
15793
15799
  );
@@ -22047,8 +22053,8 @@ async function acquireDb() {
22047
22053
  async function buildDefaultDispatcher() {
22048
22054
  if (__playbookRuntimeOverrides.dispatcher) return __playbookRuntimeOverrides.dispatcher;
22049
22055
  const { orchestrateSpawnExecute: orchestrateSpawnExecute2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
22050
- const { getProjectRoot: getProjectRoot32 } = await import("@cleocode/core/internal");
22051
- const projectRoot = getProjectRoot32();
22056
+ const { getProjectRoot: getProjectRoot33 } = await import("@cleocode/core/internal");
22057
+ const projectRoot = getProjectRoot33();
22052
22058
  return {
22053
22059
  async dispatch(input) {
22054
22060
  try {
@@ -22266,14 +22272,14 @@ var init_playbook2 = __esm({
22266
22272
  const dispatcher = await buildDefaultDispatcher();
22267
22273
  let result;
22268
22274
  try {
22269
- const { getProjectRoot: getProjectRoot32 } = await import("@cleocode/core/internal");
22275
+ const { getProjectRoot: getProjectRoot33 } = await import("@cleocode/core/internal");
22270
22276
  const opts = {
22271
22277
  db,
22272
22278
  playbook: parsed.definition,
22273
22279
  playbookHash: parsed.sourceHash,
22274
22280
  initialContext,
22275
22281
  dispatcher,
22276
- projectRoot: getProjectRoot32()
22282
+ projectRoot: getProjectRoot33()
22277
22283
  };
22278
22284
  if (__playbookRuntimeOverrides.approvalSecret !== void 0) {
22279
22285
  opts.approvalSecret = __playbookRuntimeOverrides.approvalSecret;
@@ -27132,11 +27138,11 @@ var init_security = __esm({
27132
27138
  });
27133
27139
 
27134
27140
  // packages/cleo/src/dispatch/middleware/sanitizer.ts
27135
- function createSanitizer(getProjectRoot32) {
27141
+ function createSanitizer(getProjectRoot33) {
27136
27142
  return async (req, next) => {
27137
27143
  if (req.params) {
27138
27144
  try {
27139
- const root = getProjectRoot32 ? getProjectRoot32() : void 0;
27145
+ const root = getProjectRoot33 ? getProjectRoot33() : void 0;
27140
27146
  req.params = sanitizeParams(req.params, root, {
27141
27147
  domain: req.domain,
27142
27148
  operation: req.operation
@@ -27508,9 +27514,10 @@ import {
27508
27514
  ensureGlobalSignaldockDb,
27509
27515
  getGlobalSalt,
27510
27516
  getLogger as getLogger17,
27511
- getProjectRoot as getProjectRoot31,
27517
+ getProjectRoot as getProjectRoot32,
27512
27518
  migrateSignaldockToConduit,
27513
27519
  needsSignaldockToConduitMigration,
27520
+ runWithWorktreeScopeFromEnv,
27514
27521
  validateGlobalSalt
27515
27522
  } from "@cleocode/core/internal";
27516
27523
 
@@ -27605,11 +27612,11 @@ var CLIError = class extends Error {
27605
27612
  function parseRawArgs(args = [], opts = {}) {
27606
27613
  const booleans = new Set(opts.boolean || []);
27607
27614
  const strings = new Set(opts.string || []);
27608
- const aliasMap2 = opts.alias || {};
27615
+ const aliasMap = opts.alias || {};
27609
27616
  const defaults = opts.default || {};
27610
27617
  const aliasToMain = /* @__PURE__ */ new Map();
27611
27618
  const mainToAliases = /* @__PURE__ */ new Map();
27612
- for (const [key, value] of Object.entries(aliasMap2)) {
27619
+ for (const [key, value] of Object.entries(aliasMap)) {
27613
27620
  const targets = value;
27614
27621
  for (const target of targets) {
27615
27622
  aliasToMain.set(key, target);
@@ -27630,15 +27637,15 @@ function parseRawArgs(args = [], opts = {}) {
27630
27637
  const allOptions = /* @__PURE__ */ new Set([
27631
27638
  ...booleans,
27632
27639
  ...strings,
27633
- ...Object.keys(aliasMap2),
27634
- ...Object.values(aliasMap2).flat(),
27640
+ ...Object.keys(aliasMap),
27641
+ ...Object.values(aliasMap).flat(),
27635
27642
  ...Object.keys(defaults)
27636
27643
  ]);
27637
27644
  for (const name of allOptions) if (!options[name]) options[name] = {
27638
27645
  type: getType(name),
27639
27646
  default: defaults[name]
27640
27647
  };
27641
- for (const [alias, main2] of aliasToMain.entries()) if (alias.length === 1 && options[main2] && !options[main2].short) options[main2].short = alias;
27648
+ for (const [alias, main] of aliasToMain.entries()) if (alias.length === 1 && options[main] && !options[main].short) options[main].short = alias;
27642
27649
  const processedArgs = [];
27643
27650
  const negatedFlags = {};
27644
27651
  for (let i = 0; i < args.length; i++) {
@@ -27678,9 +27685,9 @@ function parseRawArgs(args = [], opts = {}) {
27678
27685
  const aliases = mainToAliases.get(name);
27679
27686
  if (aliases) for (const alias of aliases) out[alias] = false;
27680
27687
  }
27681
- for (const [alias, main2] of aliasToMain.entries()) {
27682
- if (out[alias] !== void 0 && out[main2] === void 0) out[main2] = out[alias];
27683
- if (out[main2] !== void 0 && out[alias] === void 0) out[alias] = out[main2];
27688
+ for (const [alias, main] of aliasToMain.entries()) {
27689
+ if (out[alias] !== void 0 && out[main] === void 0) out[main] = out[alias];
27690
+ if (out[main] !== void 0 && out[alias] === void 0) out[alias] = out[main];
27684
27691
  }
27685
27692
  return out;
27686
27693
  }
@@ -28035,15 +28042,15 @@ function getShortDescription(desc) {
28035
28042
  const firstLine = desc.split("\n").find((l) => l.trim().length > 0);
28036
28043
  return firstLine?.trim() ?? desc.trim();
28037
28044
  }
28038
- function renderGroupedHelp(version, subCommands2, aliasMap2) {
28045
+ function renderGroupedHelp(version, subCommands2, aliasMap) {
28039
28046
  const descMap = /* @__PURE__ */ new Map();
28040
28047
  for (const [key, def] of Object.entries(subCommands2)) {
28041
- if (aliasMap2.has(key)) continue;
28048
+ if (aliasMap.has(key)) continue;
28042
28049
  const meta = resolveMeta(def);
28043
28050
  descMap.set(key, getShortDescription(meta.description));
28044
28051
  }
28045
28052
  const cmdAliases = /* @__PURE__ */ new Map();
28046
- for (const [alias, primary] of aliasMap2) {
28053
+ for (const [alias, primary] of aliasMap) {
28047
28054
  const existing = cmdAliases.get(primary) ?? [];
28048
28055
  existing.push(alias);
28049
28056
  cmdAliases.set(primary, existing);
@@ -28052,7 +28059,7 @@ function renderGroupedHelp(version, subCommands2, aliasMap2) {
28052
28059
  const allGroupedCmds = COMMAND_GROUPS.flatMap((g) => g.commands);
28053
28060
  const allCmds = [.../* @__PURE__ */ new Set([...allGroupedCmds, ...descMap.keys()])];
28054
28061
  for (const cmd of allCmds) {
28055
- if (!descMap.has(cmd) || aliasMap2.has(cmd)) continue;
28062
+ if (!descMap.has(cmd) || aliasMap.has(cmd)) continue;
28056
28063
  const aliases = cmdAliases.get(cmd);
28057
28064
  const display = aliases && aliases.length > 0 ? `${cmd} (${aliases.join(", ")})` : cmd;
28058
28065
  if (display.length > maxCmdWidth) maxCmdWidth = display.length;
@@ -28081,7 +28088,7 @@ function renderGroupedHelp(version, subCommands2, aliasMap2) {
28081
28088
  }
28082
28089
  const ungrouped = [];
28083
28090
  for (const key of descMap.keys()) {
28084
- if (!rendered.has(key) && !aliasMap2.has(key)) {
28091
+ if (!rendered.has(key) && !aliasMap.has(key)) {
28085
28092
  ungrouped.push(key);
28086
28093
  }
28087
28094
  }
@@ -28098,12 +28105,12 @@ function renderGroupedHelp(version, subCommands2, aliasMap2) {
28098
28105
  lines.push(`Use ${cyan2("cleo <command> --help")} for more information about a command.`);
28099
28106
  return lines.join("\n");
28100
28107
  }
28101
- function createCustomShowUsage(version, subCommands2, aliasMap2) {
28108
+ function createCustomShowUsage(version, subCommands2, aliasMap) {
28102
28109
  return async (cmd, parent) => {
28103
28110
  if (!parent) {
28104
28111
  const meta = await (typeof cmd.meta === "function" ? cmd.meta() : cmd.meta);
28105
28112
  if (meta?.name === "cleo") {
28106
- console.log(renderGroupedHelp(version, subCommands2, aliasMap2) + "\n");
28113
+ console.log(renderGroupedHelp(version, subCommands2, aliasMap) + "\n");
28107
28114
  return;
28108
28115
  }
28109
28116
  }
@@ -28445,6 +28452,21 @@ var addCommand = defineCommand({
28445
28452
  "force-duplicate": {
28446
28453
  type: "boolean",
28447
28454
  description: "Bypass BRAIN duplicate-task rejection (audited to .cleo/audit/duplicate-bypass.jsonl) (T1633)"
28455
+ },
28456
+ /**
28457
+ * Waiver for the critical-priority dependency declaration requirement.
28458
+ *
28459
+ * Critical-priority tasks without declared dependencies silently break
28460
+ * wave-order spawning when downstream work assumes they are load-bearing.
28461
+ * Provide a justification string to waive the `--depends` requirement.
28462
+ * The waiver is stored in task metadata for auditability.
28463
+ *
28464
+ * @task T1856
28465
+ * @epic T1855
28466
+ */
28467
+ "depends-waiver": {
28468
+ type: "string",
28469
+ description: "Justification for creating a critical-priority task without --depends (T1856). Records waiver in task metadata."
28448
28470
  }
28449
28471
  },
28450
28472
  async run({ args, cmd }) {
@@ -28480,6 +28502,20 @@ var addCommand = defineCommand({
28480
28502
  if (args.scope !== void 0) params["scope"] = args.scope;
28481
28503
  if (args.severity !== void 0) params["severity"] = args.severity;
28482
28504
  if (args["force-duplicate"] !== void 0) params["forceDuplicate"] = args["force-duplicate"];
28505
+ if (args.priority === "critical" && !args.depends && args["depends-waiver"] === void 0) {
28506
+ cliError(
28507
+ 'Critical-priority tasks must declare at least one dependency (--depends) or provide a waiver (--depends-waiver "<reason>").',
28508
+ "E_VALIDATION",
28509
+ {
28510
+ name: "E_VALIDATION",
28511
+ fix: 'Add --depends <taskId> to declare a dependency, or use --depends-waiver "<reason>" to waive the requirement. Use `cleo find "<topic>"` to discover candidate dependencies.'
28512
+ },
28513
+ { operation: "tasks.add" }
28514
+ );
28515
+ process.exit(6);
28516
+ return;
28517
+ }
28518
+ if (args["depends-waiver"] !== void 0) params["dependsWaiver"] = args["depends-waiver"];
28483
28519
  const inferred = await inferTaskAddParams(getProjectRoot18(), {
28484
28520
  title: args.title,
28485
28521
  description: args.description ?? args.desc,
@@ -32657,9 +32693,9 @@ var exportCommand = defineCommand({
32657
32693
  },
32658
32694
  async run({ args }) {
32659
32695
  const scope = args.scope;
32660
- const { packBundle, getProjectRoot: getProjectRoot32 } = await import("@cleocode/core/internal");
32696
+ const { packBundle, getProjectRoot: getProjectRoot33 } = await import("@cleocode/core/internal");
32661
32697
  const includesProject = scope === "project" || scope === "all";
32662
- const projectRoot = includesProject ? getProjectRoot32() : void 0;
32698
+ const projectRoot = includesProject ? getProjectRoot33() : void 0;
32663
32699
  let passphrase;
32664
32700
  if (args.encrypt === true) {
32665
32701
  passphrase = process.env["CLEO_BACKUP_PASSPHRASE"];
@@ -37356,6 +37392,7 @@ var docsCommand = defineCommand({
37356
37392
  });
37357
37393
 
37358
37394
  // packages/cleo/src/cli/commands/doctor.ts
37395
+ import { getProjectRoot as getProjectRoot23, quarantineRogueCleoDir, scanRogueCleoDirs } from "@cleocode/core/internal";
37359
37396
  init_cli();
37360
37397
 
37361
37398
  // packages/cleo/src/cli/progress.ts
@@ -37653,6 +37690,37 @@ Provider Hook Matrix (CAAMP ${caampVersion} canonical taxonomy)
37653
37690
 
37654
37691
  `);
37655
37692
  }
37693
+ function renderRogueReportHuman(report) {
37694
+ const totalKb = (report.totalSize / 1024).toFixed(1);
37695
+ process.stdout.write(`
37696
+ Package: ${report.packageName}
37697
+ `);
37698
+ process.stdout.write(` Path: ${report.path}
37699
+ `);
37700
+ process.stdout.write(` Size: ${totalKb} KB (${report.fileManifest.length} files)
37701
+ `);
37702
+ process.stdout.write(
37703
+ ` Marker: ${report.hasProjectInfoMarker ? "has project-info.json (unexpected!)" : "no project-info.json (rogue)"}
37704
+ `
37705
+ );
37706
+ const { tasks, brain_observations, brain_decisions } = report.dbRowCounts;
37707
+ if (tasks !== void 0 || brain_observations !== void 0) {
37708
+ const parts = [];
37709
+ if (tasks !== void 0) parts.push(`tasks=${tasks}`);
37710
+ if (brain_observations !== void 0) parts.push(`brain_observations=${brain_observations}`);
37711
+ if (brain_decisions !== void 0) parts.push(`brain_decisions=${brain_decisions}`);
37712
+ process.stdout.write(` DB rows: ${parts.join(", ")}
37713
+ `);
37714
+ }
37715
+ if (report.drizzleMigrations.length > 0) {
37716
+ process.stdout.write(` Migrations (${report.drizzleMigrations.length}):
37717
+ `);
37718
+ for (const m of report.drizzleMigrations) {
37719
+ process.stdout.write(` [${m.id}] ${m.name ?? m.hash.slice(0, 16)}
37720
+ `);
37721
+ }
37722
+ }
37723
+ }
37656
37724
  var doctorCommand2 = defineCommand({
37657
37725
  meta: { name: "doctor", description: "Run system diagnostics and health checks" },
37658
37726
  args: {
@@ -37688,6 +37756,18 @@ var doctorCommand2 = defineCommand({
37688
37756
  type: "boolean",
37689
37757
  description: "When used with --all-projects, exit 1 instead of 2 on unreachable projects"
37690
37758
  },
37759
+ "scan-rogue-cleo-dirs": {
37760
+ type: "boolean",
37761
+ description: "Scan for rogue .cleo/ directories inside sub-packages and print forensic report"
37762
+ },
37763
+ "quarantine-rogue-cleo-dirs": {
37764
+ type: "boolean",
37765
+ description: "Move all rogue .cleo/ sub-package directories to .cleo/quarantine/ (never deletes)"
37766
+ },
37767
+ "dry-run": {
37768
+ type: "boolean",
37769
+ description: "With --quarantine-rogue-cleo-dirs: print what would be moved without moving"
37770
+ },
37691
37771
  // Global output format flags — read directly from args (no optsWithGlobals in citty)
37692
37772
  json: {
37693
37773
  type: "boolean",
@@ -37781,6 +37861,105 @@ var doctorCommand2 = defineCommand({
37781
37861
  { command: "doctor", operation: "admin.health" }
37782
37862
  );
37783
37863
  progress.complete("Comprehensive diagnostics complete");
37864
+ } else if (args["scan-rogue-cleo-dirs"]) {
37865
+ progress.step(0, "Scanning for rogue .cleo/ directories");
37866
+ const projectRoot = getProjectRoot23();
37867
+ const reports = scanRogueCleoDirs(projectRoot);
37868
+ progress.complete(
37869
+ `Found ${reports.length} rogue .cleo/ director${reports.length === 1 ? "y" : "ies"}`
37870
+ );
37871
+ if (args.json) {
37872
+ process.stdout.write(JSON.stringify({ success: true, data: reports }, null, 2) + "\n");
37873
+ } else {
37874
+ if (reports.length === 0) {
37875
+ process.stdout.write("\nNo rogue .cleo/ directories found.\n");
37876
+ } else {
37877
+ process.stdout.write(`
37878
+ Rogue .cleo/ directories (${reports.length}):
37879
+ `);
37880
+ for (const report of reports) {
37881
+ renderRogueReportHuman(report);
37882
+ }
37883
+ process.stdout.write("\n");
37884
+ }
37885
+ }
37886
+ } else if (args["quarantine-rogue-cleo-dirs"]) {
37887
+ const isDryRun = args["dry-run"] === true;
37888
+ progress.step(0, `${isDryRun ? "[DRY RUN] " : ""}Scanning for rogue .cleo/ directories`);
37889
+ const projectRoot = getProjectRoot23();
37890
+ const reports = scanRogueCleoDirs(projectRoot);
37891
+ if (reports.length === 0) {
37892
+ progress.complete("No rogue .cleo/ directories found \u2014 nothing to quarantine");
37893
+ if (!args.json) {
37894
+ process.stdout.write("\nNo rogue .cleo/ directories found.\n");
37895
+ } else {
37896
+ process.stdout.write(
37897
+ JSON.stringify({ success: true, data: { quarantined: [] } }, null, 2) + "\n"
37898
+ );
37899
+ }
37900
+ return;
37901
+ }
37902
+ const quarantined = [];
37903
+ const errors = [];
37904
+ for (const report of reports) {
37905
+ if (isDryRun) {
37906
+ const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
37907
+ const targetPath = `${projectRoot}/.cleo/quarantine/${report.packageName}-${timestamp2}`;
37908
+ quarantined.push({
37909
+ packageName: report.packageName,
37910
+ from: report.path,
37911
+ to: targetPath
37912
+ });
37913
+ } else {
37914
+ try {
37915
+ const { quarantinePath } = quarantineRogueCleoDir(report, projectRoot);
37916
+ quarantined.push({
37917
+ packageName: report.packageName,
37918
+ from: report.path,
37919
+ to: quarantinePath
37920
+ });
37921
+ } catch (err) {
37922
+ errors.push({
37923
+ packageName: report.packageName,
37924
+ path: report.path,
37925
+ error: err instanceof Error ? err.message : String(err)
37926
+ });
37927
+ }
37928
+ }
37929
+ }
37930
+ const verb = isDryRun ? "Would quarantine" : "Quarantined";
37931
+ progress.complete(
37932
+ `${verb} ${quarantined.length} director${quarantined.length === 1 ? "y" : "ies"}${errors.length > 0 ? `, ${errors.length} failed` : ""}`
37933
+ );
37934
+ if (args.json) {
37935
+ process.stdout.write(
37936
+ JSON.stringify(
37937
+ { success: errors.length === 0, data: { dryRun: isDryRun, quarantined, errors } },
37938
+ null,
37939
+ 2
37940
+ ) + "\n"
37941
+ );
37942
+ } else {
37943
+ process.stdout.write(`
37944
+ ${verb}:
37945
+ `);
37946
+ for (const q of quarantined) {
37947
+ process.stdout.write(` ${q.packageName}: ${q.from}
37948
+ -> ${q.to}
37949
+ `);
37950
+ }
37951
+ if (errors.length > 0) {
37952
+ process.stdout.write(`
37953
+ Errors (${errors.length}):
37954
+ `);
37955
+ for (const e of errors) {
37956
+ process.stdout.write(` ${e.packageName}: ${e.error}
37957
+ `);
37958
+ }
37959
+ process.exitCode = 1;
37960
+ }
37961
+ process.stdout.write("\n");
37962
+ }
37784
37963
  } else {
37785
37964
  progress.step(0, "Checking CLEO directory");
37786
37965
  await dispatchFromCli(
@@ -38149,7 +38328,7 @@ init_src();
38149
38328
  import { execFileSync as execFileSync2 } from "node:child_process";
38150
38329
  import { existsSync as existsSync10, mkdirSync as mkdirSync3, readFileSync as readFileSync10, writeFileSync as writeFileSync3 } from "node:fs";
38151
38330
  import { dirname as dirname8, join as join13 } from "node:path";
38152
- import { CleoError as CleoError4, formatError as formatError6, getConfigPath as getConfigPath2, getProjectRoot as getProjectRoot23 } from "@cleocode/core";
38331
+ import { CleoError as CleoError4, formatError as formatError6, getConfigPath as getConfigPath2, getProjectRoot as getProjectRoot24 } from "@cleocode/core";
38153
38332
  init_renderers();
38154
38333
  function getChangelogSource(cwd) {
38155
38334
  const configPath = getConfigPath2(cwd);
@@ -38181,7 +38360,7 @@ function getDefaultOutputPath(platform) {
38181
38360
  }
38182
38361
  }
38183
38362
  function getGitHubRepoSlug(cwd) {
38184
- const projectRoot = getProjectRoot23(cwd);
38363
+ const projectRoot = getProjectRoot24(cwd);
38185
38364
  try {
38186
38365
  const remoteUrl = execFileSync2("git", ["remote", "get-url", "origin"], {
38187
38366
  cwd: projectRoot,
@@ -38307,7 +38486,7 @@ var generateChangelogCommand = defineCommand({
38307
38486
  const targetPlatform = args.platform;
38308
38487
  const dryRun = args["dry-run"] === true;
38309
38488
  const sourceFile = getChangelogSource();
38310
- const sourcePath = join13(getProjectRoot23(), sourceFile);
38489
+ const sourcePath = join13(getProjectRoot24(), sourceFile);
38311
38490
  if (!existsSync10(sourcePath)) {
38312
38491
  throw new CleoError4(4 /* NOT_FOUND */, `Changelog source not found: ${sourcePath}`);
38313
38492
  }
@@ -38320,7 +38499,7 @@ var generateChangelogCommand = defineCommand({
38320
38499
  const outputPath = platformConfig?.path ?? getDefaultOutputPath(targetPlatform);
38321
38500
  const content = generateForPlatform(targetPlatform, sourceContent, repoSlug, limit);
38322
38501
  if (!dryRun) {
38323
- const fullPath = join13(getProjectRoot23(), outputPath);
38502
+ const fullPath = join13(getProjectRoot24(), outputPath);
38324
38503
  mkdirSync3(dirname8(fullPath), { recursive: true });
38325
38504
  writeFileSync3(fullPath, content, "utf-8");
38326
38505
  }
@@ -38341,7 +38520,7 @@ var generateChangelogCommand = defineCommand({
38341
38520
  limit
38342
38521
  );
38343
38522
  if (!dryRun) {
38344
- const fullPath = join13(getProjectRoot23(), platformConfig.path);
38523
+ const fullPath = join13(getProjectRoot24(), platformConfig.path);
38345
38524
  mkdirSync3(dirname8(fullPath), { recursive: true });
38346
38525
  writeFileSync3(fullPath, content, "utf-8");
38347
38526
  }
@@ -39765,7 +39944,7 @@ import { join as join14 } from "node:path";
39765
39944
  import {
39766
39945
  getBrainDb as getBrainDb2,
39767
39946
  getBrainNativeDb as getBrainNativeDb3,
39768
- getProjectRoot as getProjectRoot24,
39947
+ getProjectRoot as getProjectRoot25,
39769
39948
  runConsolidation,
39770
39949
  triggerManualDream
39771
39950
  } from "@cleocode/core/internal";
@@ -40166,6 +40345,26 @@ var decisionStoreCommand = defineCommand({
40166
40345
  type: "string",
40167
40346
  description: "Task ID to associate with this decision"
40168
40347
  },
40348
+ "adr-path": {
40349
+ type: "string",
40350
+ description: "Path to the ADR document on disk (e.g. docs/adr/ADR-027.md)"
40351
+ },
40352
+ supersedes: {
40353
+ type: "string",
40354
+ description: "Decision ID that this decision supersedes (e.g. D001)"
40355
+ },
40356
+ "superseded-by": {
40357
+ type: "string",
40358
+ description: "Decision ID that has superseded this decision (e.g. D002)"
40359
+ },
40360
+ "confirmation-state": {
40361
+ type: "string",
40362
+ description: "Lifecycle state: proposed | accepted | superseded (default: proposed)"
40363
+ },
40364
+ "decided-by": {
40365
+ type: "string",
40366
+ description: "Who originated this decision: owner | council | agent (default: agent)"
40367
+ },
40169
40368
  json: {
40170
40369
  type: "boolean",
40171
40370
  description: "Output as JSON"
@@ -40180,7 +40379,14 @@ var decisionStoreCommand = defineCommand({
40180
40379
  decision: args.decision,
40181
40380
  rationale: args.rationale,
40182
40381
  ...args.alternatives !== void 0 && { alternatives: args.alternatives },
40183
- ...args["linked-task"] !== void 0 && { taskId: args["linked-task"] }
40382
+ ...args["linked-task"] !== void 0 && { taskId: args["linked-task"] },
40383
+ ...args["adr-path"] !== void 0 && { adrPath: args["adr-path"] },
40384
+ ...args.supersedes !== void 0 && { supersedes: args.supersedes },
40385
+ ...args["superseded-by"] !== void 0 && { supersededBy: args["superseded-by"] },
40386
+ ...args["confirmation-state"] !== void 0 && {
40387
+ confirmationState: args["confirmation-state"]
40388
+ },
40389
+ ...args["decided-by"] !== void 0 && { decidedBy: args["decided-by"] }
40184
40390
  },
40185
40391
  { command: "memory", operation: "memory.decision.store" }
40186
40392
  );
@@ -40671,7 +40877,7 @@ var consolidateCommand = defineCommand({
40671
40877
  },
40672
40878
  args: {},
40673
40879
  async run() {
40674
- const root = getProjectRoot24();
40880
+ const root = getProjectRoot25();
40675
40881
  try {
40676
40882
  const result = await runConsolidation(root);
40677
40883
  cliOutput(result, { command: "memory-consolidate", operation: "memory.consolidate" });
@@ -40689,7 +40895,7 @@ var dreamCommand = defineCommand({
40689
40895
  },
40690
40896
  args: {},
40691
40897
  async run() {
40692
- const root = getProjectRoot24();
40898
+ const root = getProjectRoot25();
40693
40899
  try {
40694
40900
  const result = await triggerManualDream(root);
40695
40901
  cliOutput(result, { command: "memory-dream", operation: "memory.dream" });
@@ -40712,7 +40918,7 @@ var reflectCommand = defineCommand({
40712
40918
  }
40713
40919
  },
40714
40920
  async run({ args }) {
40715
- const root = getProjectRoot24();
40921
+ const root = getProjectRoot25();
40716
40922
  try {
40717
40923
  const { runObserver, runReflector } = await import("@cleocode/core/internal");
40718
40924
  const observerResult = await runObserver(root, args.session, {
@@ -40752,7 +40958,7 @@ var dedupScanCommand = defineCommand({
40752
40958
  }
40753
40959
  },
40754
40960
  async run({ args }) {
40755
- const root = getProjectRoot24();
40961
+ const root = getProjectRoot25();
40756
40962
  try {
40757
40963
  const { getBrainDb: getBrainDbInner, getBrainNativeDb: getBrainNativeDbInner } = await import("@cleocode/core/internal");
40758
40964
  await getBrainDbInner(root);
@@ -40850,7 +41056,7 @@ var importCommand3 = defineCommand({
40850
41056
  async run({ args }) {
40851
41057
  const sourceDir = args.from ?? join14(homedir4(), ".claude", "projects", "-mnt-projects-cleocode", "memory");
40852
41058
  const isDryRun = !!args["dry-run"];
40853
- const projectRoot = getProjectRoot24();
41059
+ const projectRoot = getProjectRoot25();
40854
41060
  const stateFile = join14(projectRoot, CLEO_DIR_NAME, MIGRATE_MEMORY_HASHES_JSON);
40855
41061
  if (!existsSync11(sourceDir)) {
40856
41062
  cliError(`Source directory not found: ${sourceDir}`, "E_NOT_FOUND", { name: "E_NOT_FOUND" });
@@ -41063,7 +41269,7 @@ var tierStatsCommand = defineCommand({
41063
41269
  },
41064
41270
  args: {},
41065
41271
  async run() {
41066
- const root = getProjectRoot24();
41272
+ const root = getProjectRoot25();
41067
41273
  try {
41068
41274
  await getBrainDb2(root);
41069
41275
  const nativeDb = getBrainNativeDb3();
@@ -41162,7 +41368,7 @@ var tierPromoteCommand = defineCommand({
41162
41368
  }
41163
41369
  },
41164
41370
  async run({ args }) {
41165
- const root = getProjectRoot24();
41371
+ const root = getProjectRoot25();
41166
41372
  const targetTier = args.to;
41167
41373
  const reason = args.reason;
41168
41374
  const validTiers = ["medium", "long"];
@@ -41266,7 +41472,7 @@ var tierDemoteCommand = defineCommand({
41266
41472
  }
41267
41473
  },
41268
41474
  async run({ args }) {
41269
- const root = getProjectRoot24();
41475
+ const root = getProjectRoot25();
41270
41476
  const targetTier = args.to;
41271
41477
  const reason = args.reason;
41272
41478
  const validTiers = ["short", "medium"];
@@ -41791,7 +41997,7 @@ var memoryCommand = defineCommand({
41791
41997
  });
41792
41998
 
41793
41999
  // packages/cleo/src/cli/commands/migrate-claude-mem.ts
41794
- import { getProjectRoot as getProjectRoot25, migrateClaudeMem } from "@cleocode/core/internal";
42000
+ import { getProjectRoot as getProjectRoot26, migrateClaudeMem } from "@cleocode/core/internal";
41795
42001
  import { ingestLooseAgentOutputs, ingestRcasdDirectories } from "@cleocode/core/memory";
41796
42002
  import { getDb as getDb2 } from "@cleocode/core/store/sqlite";
41797
42003
  init_cli();
@@ -41848,7 +42054,7 @@ var claudeMemCommand = defineCommand({
41848
42054
  }
41849
42055
  },
41850
42056
  async run({ args }) {
41851
- const root = getProjectRoot25();
42057
+ const root = getProjectRoot26();
41852
42058
  try {
41853
42059
  const result = await migrateClaudeMem(root, {
41854
42060
  sourcePath: args.source,
@@ -41897,7 +42103,7 @@ var manifestIngestCommand = defineCommand({
41897
42103
  }
41898
42104
  },
41899
42105
  async run({ args }) {
41900
- const projectRoot = getProjectRoot25();
42106
+ const projectRoot = getProjectRoot26();
41901
42107
  try {
41902
42108
  const db = await getDb2(projectRoot);
41903
42109
  const rcasdFlag = Boolean(args.rcasd);
@@ -42812,7 +43018,7 @@ var analyzeCommand3 = defineCommand({
42812
43018
  );
42813
43019
  }
42814
43020
  try {
42815
- const [{ getNexusDb, nexusSchema }, { runPipeline }, { getProjectRoot: getProjectRoot32 }, { eq: eq2 }] = await Promise.all([
43021
+ const [{ getNexusDb, nexusSchema }, { runPipeline }, { getProjectRoot: getProjectRoot33 }, { eq: eq2 }] = await Promise.all([
42816
43022
  import("@cleocode/core/store/nexus-sqlite"),
42817
43023
  import("@cleocode/nexus/pipeline"),
42818
43024
  import("@cleocode/core/internal"),
@@ -42904,7 +43110,7 @@ var analyzeCommand3 = defineCommand({
42904
43110
  extensions: { duration_ms: durationMs }
42905
43111
  }
42906
43112
  );
42907
- void getProjectRoot32;
43113
+ void getProjectRoot33;
42908
43114
  } catch (err) {
42909
43115
  const msg = err instanceof Error ? err.message : String(err);
42910
43116
  cliError(
@@ -46268,14 +46474,14 @@ var reconcileCommand2 = defineCommand({
46268
46474
  });
46269
46475
 
46270
46476
  // packages/cleo/src/cli/commands/refresh-memory.ts
46271
- import { getProjectRoot as getProjectRoot26 } from "@cleocode/core";
46477
+ import { getProjectRoot as getProjectRoot27 } from "@cleocode/core";
46272
46478
  var refreshMemoryCommand = defineCommand({
46273
46479
  meta: {
46274
46480
  name: "refresh-memory",
46275
46481
  description: "Regenerate .cleo/memory-bridge.md from brain.db"
46276
46482
  },
46277
46483
  async run() {
46278
- const projectDir = getProjectRoot26();
46484
+ const projectDir = getProjectRoot27();
46279
46485
  const { writeMemoryBridge } = await import("@cleocode/core/internal");
46280
46486
  const result = await writeMemoryBridge(projectDir);
46281
46487
  if (result.written) {
@@ -47438,7 +47644,7 @@ init_src();
47438
47644
  import fs3 from "node:fs";
47439
47645
  import path4 from "node:path";
47440
47646
  import { CleoError as CleoError8, formatError as formatError10, getAccessor as getAccessor3 } from "@cleocode/core";
47441
- import { getProjectRoot as getProjectRoot27 } from "@cleocode/core/internal";
47647
+ import { getProjectRoot as getProjectRoot28 } from "@cleocode/core/internal";
47442
47648
  init_cli();
47443
47649
  init_paths();
47444
47650
  init_renderers();
@@ -47552,7 +47758,7 @@ var finalizeCommand = defineCommand({
47552
47758
  description: "Apply manually-resolved conflicts from .cleo/restore-conflicts.md"
47553
47759
  },
47554
47760
  async run() {
47555
- const projectRoot = getProjectRoot27();
47761
+ const projectRoot = getProjectRoot28();
47556
47762
  const reportPath = path4.join(projectRoot, CLEO_DIR_NAME, RESTORE_CONFLICTS_MD);
47557
47763
  if (!fs3.existsSync(reportPath)) {
47558
47764
  console.log("No pending restore conflicts. Nothing to finalize.");
@@ -49182,7 +49388,7 @@ var sentientCommand = defineCommand({
49182
49388
  });
49183
49389
 
49184
49390
  // packages/cleo/src/cli/commands/sequence.ts
49185
- import { getProjectRoot as getProjectRoot28 } from "@cleocode/core/internal";
49391
+ import { getProjectRoot as getProjectRoot29 } from "@cleocode/core/internal";
49186
49392
  init_cli();
49187
49393
  init_renderers();
49188
49394
  var showCommand12 = defineCommand({
@@ -49213,7 +49419,7 @@ var repairCommand = defineCommand({
49213
49419
  meta: { name: "repair", description: "Reset counter to max + 1 if behind" },
49214
49420
  async run() {
49215
49421
  const { repairSequence } = await import("@cleocode/core/internal");
49216
- const projectRoot = getProjectRoot28();
49422
+ const projectRoot = getProjectRoot29();
49217
49423
  const repair = await repairSequence(projectRoot);
49218
49424
  const result = {
49219
49425
  repaired: repair.repaired,
@@ -49640,8 +49846,8 @@ var driftCommand = defineCommand({
49640
49846
  "audit-scope": { type: "string", description: "Audit log scope (global|local)" }
49641
49847
  },
49642
49848
  async run({ args }) {
49643
- const { detectSessionDrift, getProjectRoot: getProjectRoot32 } = await import("@cleocode/core");
49644
- const projectRoot = await getProjectRoot32();
49849
+ const { detectSessionDrift, getProjectRoot: getProjectRoot33 } = await import("@cleocode/core");
49850
+ const projectRoot = await getProjectRoot33();
49645
49851
  const scope = args["audit-scope"] === "local" ? "local" : "global";
49646
49852
  const report = await detectSessionDrift({ projectRoot, auditScope: scope });
49647
49853
  cliOutput(report, { command: "session drift", operation: "session.drift" });
@@ -50913,7 +51119,7 @@ var testingCommand = defineCommand({
50913
51119
 
50914
51120
  // packages/cleo/src/cli/commands/token.ts
50915
51121
  import { readFileSync as readFileSync12 } from "node:fs";
50916
- import { getProjectRoot as getProjectRoot29, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
51122
+ import { getProjectRoot as getProjectRoot30, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
50917
51123
  init_cli();
50918
51124
  init_renderers();
50919
51125
  function readPayload(args, textKey, fileKey) {
@@ -51072,7 +51278,7 @@ var estimateCommand = defineCommand({
51072
51278
  domain: args.domain,
51073
51279
  operation: args.operation
51074
51280
  };
51075
- const result = args.record ? await recordTokenExchange2(getProjectRoot29(), input) : await measureTokenExchange(input);
51281
+ const result = args.record ? await recordTokenExchange2(getProjectRoot30(), input) : await measureTokenExchange(input);
51076
51282
  cliOutput(result, {
51077
51283
  command: "token",
51078
51284
  operation: args.record ? "admin.token.record" : "token.estimate"
@@ -51102,7 +51308,7 @@ var tokenCommand = defineCommand({
51102
51308
  // packages/cleo/src/cli/commands/transcript.ts
51103
51309
  import { homedir as homedir5 } from "node:os";
51104
51310
  import { join as join17 } from "node:path";
51105
- import { getProjectRoot as getProjectRoot30 } from "@cleocode/core";
51311
+ import { getProjectRoot as getProjectRoot31 } from "@cleocode/core";
51106
51312
  import {
51107
51313
  parseDurationMs,
51108
51314
  pruneTranscripts,
@@ -51127,7 +51333,7 @@ var scanCommand = defineCommand({
51127
51333
  async run({ args }) {
51128
51334
  if (args.pending) {
51129
51335
  try {
51130
- const projectRoot = getProjectRoot30();
51336
+ const projectRoot = getProjectRoot31();
51131
51337
  const { scanPendingTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
51132
51338
  const pending = await scanPendingTranscripts(projectRoot);
51133
51339
  cliOutput(
@@ -51224,7 +51430,7 @@ var extractCommand = defineCommand({
51224
51430
  async run({ args }) {
51225
51431
  const tier = args.tier ?? "warm";
51226
51432
  const dryRun = args["dry-run"] ?? false;
51227
- const projectRoot = getProjectRoot30();
51433
+ const projectRoot = getProjectRoot31();
51228
51434
  try {
51229
51435
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
51230
51436
  const { findSessionTranscriptPath, listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -51333,7 +51539,7 @@ var migrateCommand2 = defineCommand({
51333
51539
  const dryRun = args["dry-run"] ?? false;
51334
51540
  const olderThanHours = args["older-than-hours"] ? Number.parseInt(args["older-than-hours"], 10) : 24;
51335
51541
  const limit = args.limit ? Number.parseInt(args.limit, 10) : void 0;
51336
- const projectRoot = getProjectRoot30();
51542
+ const projectRoot = getProjectRoot31();
51337
51543
  try {
51338
51544
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
51339
51545
  const { listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -51507,6 +51713,7 @@ var transcriptCommand = defineCommand({
51507
51713
 
51508
51714
  // packages/cleo/src/cli/commands/update.ts
51509
51715
  init_cli();
51716
+ init_renderers();
51510
51717
  var updateCommand2 = defineCommand({
51511
51718
  meta: { name: "update", description: "Update a task" },
51512
51719
  args: {
@@ -51647,6 +51854,21 @@ var updateCommand2 = defineCommand({
51647
51854
  reason: {
51648
51855
  type: "string",
51649
51856
  description: "Operator override reason for AC-immutability guard (required to mutate --acceptance once stage >= implementation; T1590)"
51857
+ },
51858
+ /**
51859
+ * Waiver for the critical-priority dependency declaration requirement.
51860
+ *
51861
+ * Critical-priority tasks without declared dependencies silently break
51862
+ * wave-order spawning when downstream work assumes they are load-bearing.
51863
+ * Provide a justification string to waive the `--depends` requirement.
51864
+ * The waiver is stored in task metadata for auditability.
51865
+ *
51866
+ * @task T1856
51867
+ * @epic T1855
51868
+ */
51869
+ "depends-waiver": {
51870
+ type: "string",
51871
+ description: "Justification for promoting a task to critical priority without --depends (T1856). Records waiver in task metadata."
51650
51872
  }
51651
51873
  },
51652
51874
  async run({ args, cmd }) {
@@ -51686,6 +51908,28 @@ var updateCommand2 = defineCommand({
51686
51908
  if (args.kind !== void 0) params["role"] = params["role"] ?? args.kind;
51687
51909
  if (args.scope !== void 0) params["scope"] = args.scope;
51688
51910
  if (args.reason !== void 0) params["reason"] = args.reason;
51911
+ if (args.priority === "critical" && !args.depends && !args["add-depends"] && args["depends-waiver"] === void 0) {
51912
+ const showResponse = await dispatchRaw("query", "tasks", "show", {
51913
+ taskId: args.taskId
51914
+ });
51915
+ const existingTask = showResponse.success ? showResponse.data : void 0;
51916
+ const existingDepends = existingTask?.["depends"];
51917
+ const hasDependencies = Array.isArray(existingDepends) && existingDepends.length > 0;
51918
+ if (!hasDependencies) {
51919
+ cliError(
51920
+ 'Critical-priority tasks must declare at least one dependency (--depends) or provide a waiver (--depends-waiver "<reason>").',
51921
+ "E_VALIDATION",
51922
+ {
51923
+ name: "E_VALIDATION",
51924
+ fix: 'Add --depends <taskId> to declare a dependency, or use --depends-waiver "<reason>" to waive the requirement. Use `cleo find "<topic>"` to discover candidate dependencies.'
51925
+ },
51926
+ { operation: "tasks.update" }
51927
+ );
51928
+ process.exit(6);
51929
+ return;
51930
+ }
51931
+ }
51932
+ if (args["depends-waiver"] !== void 0) params["dependsWaiver"] = args["depends-waiver"];
51689
51933
  await dispatchFromCli("mutate", "tasks", "update", params, { command: "update" });
51690
51934
  }
51691
51935
  });
@@ -52363,7 +52607,7 @@ subCommands["rm"] = deleteCommand;
52363
52607
  subCommands["ls"] = listCommand9;
52364
52608
  subCommands["tags"] = labelsCommand;
52365
52609
  subCommands["pipeline"] = phaseCommand;
52366
- {
52610
+ async function startCli() {
52367
52611
  const argv = process.argv.slice(2);
52368
52612
  const rawOpts = {};
52369
52613
  for (let i = 0; i < argv.length; i++) {
@@ -52387,12 +52631,12 @@ subCommands["pipeline"] = phaseCommand;
52387
52631
  } catch {
52388
52632
  }
52389
52633
  try {
52390
- detectAndRemoveStrayProjectNexus(getProjectRoot31());
52634
+ detectAndRemoveStrayProjectNexus(getProjectRoot32());
52391
52635
  } catch {
52392
52636
  }
52393
52637
  const _startupLog = getLogger17("cli-startup");
52394
52638
  try {
52395
- const _projectRootForMigration = getProjectRoot31();
52639
+ const _projectRootForMigration = getProjectRoot32();
52396
52640
  if (needsSignaldockToConduitMigration(_projectRootForMigration)) {
52397
52641
  const migrationResult = migrateSignaldockToConduit(_projectRootForMigration);
52398
52642
  if (migrationResult.status === "failed") {
@@ -52412,7 +52656,7 @@ subCommands["pipeline"] = phaseCommand;
52412
52656
  }
52413
52657
  }
52414
52658
  try {
52415
- ensureConduitDb(getProjectRoot31());
52659
+ ensureConduitDb(getProjectRoot32());
52416
52660
  } catch {
52417
52661
  }
52418
52662
  try {
@@ -52439,38 +52683,41 @@ subCommands["pipeline"] = phaseCommand;
52439
52683
  cliOutput2({ version: CLI_VERSION }, { command: "version" });
52440
52684
  process.exit(0);
52441
52685
  }
52442
- }
52443
- var main = defineCommand({
52444
- meta: {
52445
- name: "cleo",
52446
- version: CLI_VERSION,
52447
- description: "CLEO V2 - Task management for AI coding agents"
52448
- },
52449
- subCommands
52450
- });
52451
- var aliasMap = buildAliasMap(subCommands);
52452
- var customShowUsage = createCustomShowUsage(CLI_VERSION, subCommands, aliasMap);
52453
- {
52454
- const rawArgs = process.argv.slice(2);
52455
- const firstArg = rawArgs[0];
52456
- if (firstArg && !firstArg.startsWith("-") && firstArg !== "--help" && firstArg !== "-h" && firstArg !== "--version" && firstArg !== "-V") {
52457
- const availableCommands = Object.keys(subCommands);
52458
- if (!availableCommands.includes(firstArg)) {
52459
- const suggestions = didYouMean(firstArg, availableCommands, 3);
52460
- process.stderr.write(`Unknown command ${firstArg}
52686
+ const main = defineCommand({
52687
+ meta: {
52688
+ name: "cleo",
52689
+ version: CLI_VERSION,
52690
+ description: "CLEO V2 - Task management for AI coding agents"
52691
+ },
52692
+ subCommands
52693
+ });
52694
+ const aliasMap = buildAliasMap(subCommands);
52695
+ const customShowUsage = createCustomShowUsage(CLI_VERSION, subCommands, aliasMap);
52696
+ {
52697
+ const rawArgs = process.argv.slice(2);
52698
+ const firstArg = rawArgs[0];
52699
+ if (firstArg && !firstArg.startsWith("-") && firstArg !== "--help" && firstArg !== "-h" && firstArg !== "--version" && firstArg !== "-V") {
52700
+ const availableCommands = Object.keys(subCommands);
52701
+ if (!availableCommands.includes(firstArg)) {
52702
+ const suggestions = didYouMean(firstArg, availableCommands, 3);
52703
+ process.stderr.write(`Unknown command ${firstArg}
52461
52704
  `);
52462
- if (suggestions.length > 0) {
52463
- process.stderr.write("\nDid you mean one of:\n");
52464
- for (const suggestion of suggestions) {
52465
- process.stderr.write(` cleo ${suggestion}
52705
+ if (suggestions.length > 0) {
52706
+ process.stderr.write("\nDid you mean one of:\n");
52707
+ for (const suggestion of suggestions) {
52708
+ process.stderr.write(` cleo ${suggestion}
52466
52709
  `);
52710
+ }
52467
52711
  }
52712
+ process.exit(127);
52468
52713
  }
52469
- process.exit(127);
52470
52714
  }
52471
52715
  }
52716
+ runMain(main, { showUsage: customShowUsage });
52472
52717
  }
52473
- runMain(main, { showUsage: customShowUsage });
52718
+ runWithWorktreeScopeFromEnv(() => {
52719
+ void startCli();
52720
+ });
52474
52721
  /*! Bundled license information:
52475
52722
 
52476
52723
  js-yaml/dist/js-yaml.mjs: