@cleocode/cleo 2026.5.121 → 2026.5.122

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
@@ -10600,6 +10600,7 @@ var init_exit_codes = __esm({
10600
10600
  ExitCode2[ExitCode2["LAFS_VIOLATION"] = 104] = "LAFS_VIOLATION";
10601
10601
  ExitCode2[ExitCode2["DECISION_VALIDATOR_FAILED"] = 106] = "DECISION_VALIDATOR_FAILED";
10602
10602
  ExitCode2[ExitCode2["LEAD_BYPASS_DETECTED"] = 107] = "LEAD_BYPASS_DETECTED";
10603
+ ExitCode2[ExitCode2["AC_COVERAGE_INCOMPLETE"] = 108] = "AC_COVERAGE_INCOMPLETE";
10603
10604
  return ExitCode2;
10604
10605
  })(ExitCode || {});
10605
10606
  }
@@ -10627,7 +10628,7 @@ var init_errors = __esm({
10627
10628
 
10628
10629
  // packages/contracts/src/evidence-atom-schema.ts
10629
10630
  import { z as z6 } from "zod";
10630
- var commitAtomSchema, filesAtomSchema, testRunAtomSchema, toolAtomSchema, urlAtomSchema, noteAtomSchema, decisionAtomSchema, prAtomSchema, locDropAtomSchema, callsiteCoverageAtomSchema, EvidenceAtomSchema, GATE_EVIDENCE_REQUIREMENTS, ATOM_EXAMPLES;
10631
+ var commitAtomSchema, filesAtomSchema, testRunAtomSchema, toolAtomSchema, urlAtomSchema, noteAtomSchema, decisionAtomSchema, prAtomSchema, locDropAtomSchema, callsiteCoverageAtomSchema, AC_UUID_REGEX, AC_ALIAS_REGEX, SATISFIES_TASK_ID_REGEX, SATISFIES_VERSION_PIN_REGEX, satisfiesAtomSchema, EvidenceAtomSchema, GATE_EVIDENCE_REQUIREMENTS, ATOM_EXAMPLES;
10631
10632
  var init_evidence_atom_schema = __esm({
10632
10633
  "packages/contracts/src/evidence-atom-schema.ts"() {
10633
10634
  "use strict";
@@ -10673,6 +10674,24 @@ var init_evidence_atom_schema = __esm({
10673
10674
  symbolName: z6.string().min(1, "callsite-coverage atom requires a non-empty symbolName"),
10674
10675
  relativeSourcePath: z6.string().min(1, "callsite-coverage atom requires a non-empty relativeSourcePath")
10675
10676
  });
10677
+ AC_UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
10678
+ AC_ALIAS_REGEX = /^AC[0-9]{1,4}$/;
10679
+ SATISFIES_TASK_ID_REGEX = /^T[0-9]{1,7}$/;
10680
+ SATISFIES_VERSION_PIN_REGEX = /^[0-9]{14}$/;
10681
+ satisfiesAtomSchema = z6.object({
10682
+ kind: z6.literal("satisfies"),
10683
+ /** Target task ID — `T<1-7 digits>` per ADR-079-r2 §2.1. */
10684
+ targetTaskId: z6.string().regex(SATISFIES_TASK_ID_REGEX, "satisfies atom targetTaskId must match /^T[0-9]{1,7}$/"),
10685
+ /** Lowercase UUIDv4 — populated for the canonical form; undefined for alias form. */
10686
+ targetAcId: z6.string().regex(AC_UUID_REGEX, "satisfies atom targetAcId must be a lowercase UUIDv4").optional(),
10687
+ /** Positional alias `AC<1-4 digits>` — populated for alias form; undefined for UUID form. */
10688
+ targetAcAlias: z6.string().regex(AC_ALIAS_REGEX, "satisfies atom targetAcAlias must match /^AC[0-9]{1,4}$/").optional(),
10689
+ /** Optional `@<14-digit YYYYMMDDhhmmss>` pin captured at mint time. */
10690
+ versionPin: z6.string().regex(
10691
+ SATISFIES_VERSION_PIN_REGEX,
10692
+ "satisfies atom versionPin must be 14 digits (YYYYMMDDhhmmss)"
10693
+ ).optional()
10694
+ });
10676
10695
  EvidenceAtomSchema = z6.discriminatedUnion("kind", [
10677
10696
  commitAtomSchema,
10678
10697
  filesAtomSchema,
@@ -10683,7 +10702,8 @@ var init_evidence_atom_schema = __esm({
10683
10702
  decisionAtomSchema,
10684
10703
  prAtomSchema,
10685
10704
  locDropAtomSchema,
10686
- callsiteCoverageAtomSchema
10705
+ callsiteCoverageAtomSchema,
10706
+ satisfiesAtomSchema
10687
10707
  ]);
10688
10708
  GATE_EVIDENCE_REQUIREMENTS = Object.freeze({
10689
10709
  implemented: {
@@ -10712,7 +10732,8 @@ var init_evidence_atom_schema = __esm({
10712
10732
  decision: "decision:D-arch-001",
10713
10733
  pr: "pr:357",
10714
10734
  "loc-drop": "loc-drop:<fromLines>:<toLines>",
10715
- "callsite-coverage": "callsite-coverage:<symbolName>:<relativeSourcePath>"
10735
+ "callsite-coverage": "callsite-coverage:<symbolName>:<relativeSourcePath>",
10736
+ satisfies: "satisfies:T1234#AC2"
10716
10737
  });
10717
10738
  }
10718
10739
  });
@@ -12528,6 +12549,52 @@ var init_manifest2 = __esm({
12528
12549
  }
12529
12550
  });
12530
12551
 
12552
+ // packages/contracts/src/validator/index.ts
12553
+ import { z as z14 } from "zod";
12554
+ var VALIDATOR_ID_REGEX, validatorFindingSchema, validatorAttestationSchema, validatorRejectionSchema, validatorVerdictSchema;
12555
+ var init_validator = __esm({
12556
+ "packages/contracts/src/validator/index.ts"() {
12557
+ "use strict";
12558
+ VALIDATOR_ID_REGEX = /^validator-[a-z0-9][a-z0-9-]*$/;
12559
+ validatorFindingSchema = z14.object({
12560
+ acId: z14.string().min(1, "acId must be non-empty"),
12561
+ status: z14.enum(["pass", "fail", "inconclusive"]),
12562
+ reasoning: z14.string().min(1, "reasoning must be non-empty"),
12563
+ evidenceRefs: z14.array(z14.string()).optional(),
12564
+ checkedAt: z14.string().min(1, "checkedAt must be a non-empty ISO-8601 string")
12565
+ });
12566
+ validatorAttestationSchema = z14.object({
12567
+ verdict: z14.literal("attest"),
12568
+ taskId: z14.string().min(1),
12569
+ validatorId: z14.string().regex(VALIDATOR_ID_REGEX, "validatorId must match the pattern validator-<discriminator>"),
12570
+ findings: z14.array(validatorFindingSchema).min(1, "attestation must contain at least one finding").refine(
12571
+ (findings) => findings.every((f) => f.status === "pass"),
12572
+ 'attestation requires every finding to have status="pass"'
12573
+ ),
12574
+ summary: z14.string().optional(),
12575
+ attestedAt: z14.string().min(1),
12576
+ schemaVersion: z14.literal("1")
12577
+ });
12578
+ validatorRejectionSchema = z14.object({
12579
+ verdict: z14.literal("reject"),
12580
+ taskId: z14.string().min(1),
12581
+ validatorId: z14.string().regex(VALIDATOR_ID_REGEX, "validatorId must match the pattern validator-<discriminator>"),
12582
+ findings: z14.array(validatorFindingSchema).min(1, "rejection must contain at least one finding").refine(
12583
+ (findings) => findings.some((f) => f.status !== "pass"),
12584
+ 'rejection requires at least one finding with status "fail" or "inconclusive"'
12585
+ ),
12586
+ summary: z14.string().min(1, "rejection summary must be non-empty"),
12587
+ remediationHints: z14.array(z14.string()).optional(),
12588
+ rejectedAt: z14.string().min(1),
12589
+ schemaVersion: z14.literal("1")
12590
+ });
12591
+ validatorVerdictSchema = z14.discriminatedUnion("verdict", [
12592
+ validatorAttestationSchema,
12593
+ validatorRejectionSchema
12594
+ ]);
12595
+ }
12596
+ });
12597
+
12531
12598
  // packages/contracts/src/index.ts
12532
12599
  var init_src2 = __esm({
12533
12600
  "packages/contracts/src/index.ts"() {
@@ -12571,6 +12638,7 @@ var init_src2 = __esm({
12571
12638
  init_task_evidence();
12572
12639
  init_archive();
12573
12640
  init_manifest2();
12641
+ init_validator();
12574
12642
  }
12575
12643
  });
12576
12644
 
@@ -15010,8 +15078,8 @@ var init_admin2 = __esm({
15010
15078
  const projectRoot = getProjectRoot2();
15011
15079
  const taskId = params.taskId;
15012
15080
  try {
15013
- const { getTaskAccessor: getTaskAccessor4, getLastHandoff, retrieveWithBudget } = await import("@cleocode/core/internal");
15014
- const accessor = await getTaskAccessor4(projectRoot);
15081
+ const { getTaskAccessor: getTaskAccessor5, getLastHandoff, retrieveWithBudget } = await import("@cleocode/core/internal");
15082
+ const accessor = await getTaskAccessor5(projectRoot);
15015
15083
  const task = await accessor.loadSingleTask(taskId);
15016
15084
  if (!task) {
15017
15085
  return lafsError("E_NOT_FOUND", `Task ${taskId} not found`, "context.pull");
@@ -26823,8 +26891,8 @@ async function loadPlaybookByName(name) {
26823
26891
  return null;
26824
26892
  }
26825
26893
  try {
26826
- const { getProjectRoot: getProjectRoot54 } = await import("@cleocode/core/internal");
26827
- const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot54();
26894
+ const { getProjectRoot: getProjectRoot56 } = await import("@cleocode/core/internal");
26895
+ const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot56();
26828
26896
  const resolved = resolvePlaybook(name, {
26829
26897
  projectRoot,
26830
26898
  globalPlaybooksDir: __playbookRuntimeOverrides.globalPlaybooksDir,
@@ -26868,8 +26936,8 @@ async function acquireDb() {
26868
26936
  async function buildDefaultDispatcher() {
26869
26937
  if (__playbookRuntimeOverrides.dispatcher) return __playbookRuntimeOverrides.dispatcher;
26870
26938
  const { orchestrateSpawnExecute: orchestrateSpawnExecute2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
26871
- const { getProjectRoot: getProjectRoot54 } = await import("@cleocode/core/internal");
26872
- const projectRoot = getProjectRoot54();
26939
+ const { getProjectRoot: getProjectRoot56 } = await import("@cleocode/core/internal");
26940
+ const projectRoot = getProjectRoot56();
26873
26941
  return {
26874
26942
  async dispatch(input2) {
26875
26943
  try {
@@ -27059,8 +27127,8 @@ var init_playbook2 = __esm({
27059
27127
  projectRoot = __playbookRuntimeOverrides.projectRoot;
27060
27128
  } else {
27061
27129
  try {
27062
- const { getProjectRoot: getProjectRoot54 } = await import("@cleocode/core/internal");
27063
- projectRoot = getProjectRoot54();
27130
+ const { getProjectRoot: getProjectRoot56 } = await import("@cleocode/core/internal");
27131
+ projectRoot = getProjectRoot56();
27064
27132
  } catch {
27065
27133
  projectRoot = void 0;
27066
27134
  }
@@ -27124,14 +27192,14 @@ var init_playbook2 = __esm({
27124
27192
  const dispatcher = await buildDefaultDispatcher();
27125
27193
  let result;
27126
27194
  try {
27127
- const { getProjectRoot: getProjectRoot54 } = await import("@cleocode/core/internal");
27195
+ const { getProjectRoot: getProjectRoot56 } = await import("@cleocode/core/internal");
27128
27196
  const opts = {
27129
27197
  db,
27130
27198
  playbook: parsed.definition,
27131
27199
  playbookHash: parsed.sourceHash,
27132
27200
  initialContext,
27133
27201
  dispatcher,
27134
- projectRoot: getProjectRoot54()
27202
+ projectRoot: getProjectRoot56()
27135
27203
  };
27136
27204
  if (__playbookRuntimeOverrides.approvalSecret !== void 0) {
27137
27205
  opts.approvalSecret = __playbookRuntimeOverrides.approvalSecret;
@@ -27667,8 +27735,8 @@ async function orchestrateAnalyzeParallelSafety(taskIds, projectRoot) {
27667
27735
  return !closureA.has(b) && !closureB.has(a);
27668
27736
  };
27669
27737
  var transitiveClose = transitiveClose2, parallelSafe = parallelSafe2;
27670
- const { getTaskAccessor: getTaskAccessor4 } = await import("@cleocode/core/internal");
27671
- const accessor = await getTaskAccessor4(projectRoot);
27738
+ const { getTaskAccessor: getTaskAccessor5 } = await import("@cleocode/core/internal");
27739
+ const accessor = await getTaskAccessor5(projectRoot);
27672
27740
  const result = await accessor.queryTasks({});
27673
27741
  const allTasks = result?.tasks ?? [];
27674
27742
  const depMap = /* @__PURE__ */ new Map();
@@ -30754,7 +30822,7 @@ var init_sticky2 = __esm({
30754
30822
 
30755
30823
  // packages/cleo/src/dispatch/domains/tasks.ts
30756
30824
  import { getLogger as getLogger15, getProjectRoot as getProjectRoot18, TASKS_SUGGESTED_NEXT_BUILDERS } from "@cleocode/core";
30757
- import { createAttachmentStore as createAttachmentStore4 } from "@cleocode/core/internal";
30825
+ import { createAttachmentStore as createAttachmentStore4, getTaskAccessor as getTaskAccessor3 } from "@cleocode/core/internal";
30758
30826
  import {
30759
30827
  sagaAdd as coreSagaAdd,
30760
30828
  sagaCreate as coreSagaCreate,
@@ -30785,6 +30853,20 @@ async function fetchTaskAttachments(projectRoot, taskId) {
30785
30853
  return [];
30786
30854
  }
30787
30855
  }
30856
+ async function fetchTaskAcRows(projectRoot, taskId) {
30857
+ try {
30858
+ const accessor = await getTaskAccessor3(projectRoot);
30859
+ const rows = await accessor.getAcRows(taskId);
30860
+ return rows.map((row) => ({
30861
+ id: row.id,
30862
+ alias: `AC${row.ordinal}`,
30863
+ ordinal: row.ordinal,
30864
+ text: row.text
30865
+ }));
30866
+ } catch {
30867
+ return [];
30868
+ }
30869
+ }
30788
30870
  async function sagaCreate(params) {
30789
30871
  const title = typeof params.title === "string" ? params.title : "";
30790
30872
  const description = typeof params.description === "string" ? params.description : void 0;
@@ -30869,9 +30951,10 @@ var init_tasks2 = __esm({
30869
30951
  if (params.history) {
30870
30952
  return wrapCoreResult(await taskShowWithHistory(projectRoot, params.taskId, true), "show");
30871
30953
  }
30872
- const [coreResult, attachments] = await Promise.all([
30954
+ const [coreResult, attachments, acRows] = await Promise.all([
30873
30955
  taskShow(projectRoot, params.taskId),
30874
- fetchTaskAttachments(projectRoot, params.taskId)
30956
+ fetchTaskAttachments(projectRoot, params.taskId),
30957
+ fetchTaskAcRows(projectRoot, params.taskId)
30875
30958
  ]);
30876
30959
  if (!coreResult.success) {
30877
30960
  return wrapCoreResult(coreResult, "show");
@@ -30879,7 +30962,8 @@ var init_tasks2 = __esm({
30879
30962
  const showResult = {
30880
30963
  task: coreResult.data.task,
30881
30964
  view: coreResult.data.view,
30882
- attachments
30965
+ attachments,
30966
+ ...acRows.length > 0 ? { acRows } : {}
30883
30967
  };
30884
30968
  return { success: true, data: showResult };
30885
30969
  },
@@ -31137,7 +31221,10 @@ var init_tasks2 = __esm({
31137
31221
  const result = await completeTaskStrict(projectRoot, params.taskId, {
31138
31222
  notes: params.notes,
31139
31223
  overrideReason: params.overrideReason,
31140
- acknowledgeRisk: params.acknowledgeRisk
31224
+ acknowledgeRisk: params.acknowledgeRisk,
31225
+ // T10509 — AC-coverage gate waiver path
31226
+ waiveAc: params.waiveAc,
31227
+ waiveReason: params.waiveReason
31141
31228
  });
31142
31229
  setImmediate(async () => {
31143
31230
  try {
@@ -32305,7 +32392,8 @@ import {
32305
32392
  getLogger as getLogger18,
32306
32393
  getProjectRoot as getProjectRoot21,
32307
32394
  listWorktrees,
32308
- pruneOrphanedWorktreesByStatus
32395
+ pruneOrphanedWorktreesByStatus,
32396
+ recoverPartialWorktree
32309
32397
  } from "@cleocode/core/internal";
32310
32398
  function coerceStatusFilter(value) {
32311
32399
  if (value === void 0 || value === null) return void 0;
@@ -32380,7 +32468,7 @@ var init_worktree2 = __esm({
32380
32468
  *
32381
32469
  * Supported operations:
32382
32470
  * - `adopt` — register an externally-created worktree in the SSoT. Params:
32383
- * `{ worktreePath, source?, taskId?, actor? }`. Returns an
32471
+ * `{ worktreePath, source?, taskId?, actor?, recover? }`. Returns an
32384
32472
  * {@link AdoptWorktreeResult} envelope. (T9804)
32385
32473
  * - `destroy` — explicitly destroy a single agent worktree. Params:
32386
32474
  * `{ taskId, force?, deleteBranch?, reason? }`. Returns a
@@ -32416,14 +32504,44 @@ var init_worktree2 = __esm({
32416
32504
  const source = typeof rawSource === "string" && validSources.includes(rawSource) ? rawSource : void 0;
32417
32505
  const rawTaskId = params?.["taskId"];
32418
32506
  const taskId = rawTaskId === null ? null : typeof rawTaskId === "string" && rawTaskId.length > 0 ? rawTaskId : void 0;
32507
+ const projectRoot = getProjectRoot21();
32419
32508
  const opts = {
32420
- projectRoot: getProjectRoot21(),
32509
+ projectRoot,
32421
32510
  worktreePath,
32422
32511
  ...source !== void 0 ? { source } : {},
32423
32512
  ...taskId !== void 0 ? { taskId } : {},
32424
32513
  ...typeof params?.["actor"] === "string" && params["actor"].length > 0 ? { actor: params["actor"] } : {}
32425
32514
  };
32426
32515
  const result = await adoptWorktree(opts);
32516
+ if (result.success && params?.["recover"] === true) {
32517
+ const recovery = recoverPartialWorktree(
32518
+ projectRoot,
32519
+ worktreePath,
32520
+ result.data.taskId ?? taskId ?? "unknown"
32521
+ );
32522
+ const recoveredResult = recovery.success ? {
32523
+ success: true,
32524
+ data: {
32525
+ ...result.data,
32526
+ recovery
32527
+ }
32528
+ } : {
32529
+ success: false,
32530
+ error: {
32531
+ code: "E_WORKTREE_RECOVERY_FAILED",
32532
+ message: recovery.error ?? "Partial worktree recovery failed.",
32533
+ fix: "Inspect the worktree, then rerun `cleo worktree adopt <path> --recover` after resolving the reported recovery error.",
32534
+ details: { adopt: result.data, recovery }
32535
+ }
32536
+ };
32537
+ return wrapResult(
32538
+ recoveredResult,
32539
+ "mutate",
32540
+ "worktree",
32541
+ operation,
32542
+ startTime
32543
+ );
32544
+ }
32427
32545
  return wrapResult(
32428
32546
  result,
32429
32547
  "mutate",
@@ -33105,11 +33223,11 @@ var init_security = __esm({
33105
33223
  });
33106
33224
 
33107
33225
  // packages/cleo/src/dispatch/middleware/sanitizer.ts
33108
- function createSanitizer(getProjectRoot54) {
33226
+ function createSanitizer(getProjectRoot56) {
33109
33227
  return async (req, next) => {
33110
33228
  if (req.params) {
33111
33229
  try {
33112
- const root = getProjectRoot54 ? getProjectRoot54() : void 0;
33230
+ const root = getProjectRoot56 ? getProjectRoot56() : void 0;
33113
33231
  req.params = sanitizeParams(req.params, root, {
33114
33232
  domain: req.domain,
33115
33233
  operation: req.operation
@@ -38727,9 +38845,9 @@ var init_backup = __esm({
38727
38845
  async run({ args }) {
38728
38846
  const scope = args.scope;
38729
38847
  const { packBundle } = await import("@cleocode/core/store/backup-pack.js");
38730
- const { getProjectRoot: getProjectRoot54 } = await import("@cleocode/core");
38848
+ const { getProjectRoot: getProjectRoot56 } = await import("@cleocode/core");
38731
38849
  const includesProject = scope === "project" || scope === "all";
38732
- const projectRoot = includesProject ? getProjectRoot54() : void 0;
38850
+ const projectRoot = includesProject ? getProjectRoot56() : void 0;
38733
38851
  let passphrase;
38734
38852
  if (args.encrypt === true) {
38735
38853
  passphrase = process.env["CLEO_BACKUP_PASSPHRASE"];
@@ -38805,12 +38923,12 @@ var init_backup = __esm({
38805
38923
  },
38806
38924
  async run({ args }) {
38807
38925
  const bundlePath = args.bundle;
38808
- const { getProjectRoot: getProjectRoot54, getCleoHome: getCleoHome6, getCleoVersion } = await import("@cleocode/core");
38926
+ const { getProjectRoot: getProjectRoot56, getCleoHome: getCleoHome6, getCleoVersion } = await import("@cleocode/core");
38809
38927
  const { BundleError, cleanupStaging, unpackBundle } = await import("@cleocode/core/store/backup-unpack.js");
38810
38928
  const { regenerateConfigJson, regenerateProjectContextJson, regenerateProjectInfoJson } = await import("@cleocode/core/store/regenerators.js");
38811
38929
  const { regenerateAndCompare } = await import("@cleocode/core/store/restore-json-merge.js");
38812
38930
  const { buildConflictReport, writeConflictReport } = await import("@cleocode/core/store/restore-conflict-report.js");
38813
- const projectRoot = getProjectRoot54();
38931
+ const projectRoot = getProjectRoot56();
38814
38932
  if (args.force !== true) {
38815
38933
  const existing = checkForExistingData(projectRoot, getCleoHome6());
38816
38934
  if (existing.length > 0) {
@@ -41275,6 +41393,15 @@ var init_complete = __esm({
41275
41393
  "override-reason": {
41276
41394
  type: "string",
41277
41395
  description: "Reason for bypassing E_EPIC_HAS_PENDING_CHILDREN guard (audited to .cleo/audit/premature-close.jsonl)"
41396
+ },
41397
+ // T10509 — AC-coverage gate (load-bearing IVTR closure)
41398
+ "waive-ac": {
41399
+ type: "string",
41400
+ description: "Comma-separated AC tokens (UUIDs or AC<n> aliases) to waive from the AC-coverage gate. Requires --waive-reason. Audited to .cleo/audit/ac-waiver.jsonl."
41401
+ },
41402
+ "waive-reason": {
41403
+ type: "string",
41404
+ description: "Mandatory justification text for --waive-ac. Captured verbatim in the audit row."
41278
41405
  }
41279
41406
  },
41280
41407
  async run({ args }) {
@@ -41284,7 +41411,10 @@ var init_complete = __esm({
41284
41411
  changeset: args.changeset,
41285
41412
  verificationNote: args["verification-note"],
41286
41413
  acknowledgeRisk: args["acknowledge-risk"],
41287
- overrideReason: args["override-reason"]
41414
+ overrideReason: args["override-reason"],
41415
+ // T10509 — AC-coverage gate waiver path
41416
+ waiveAc: args["waive-ac"],
41417
+ waiveReason: args["waive-reason"]
41288
41418
  });
41289
41419
  if (!response.success) {
41290
41420
  handleRawError(response, { command: "complete", operation: "tasks.complete" });
@@ -47381,129 +47511,11 @@ var init_doctor_projects = __esm({
47381
47511
  }
47382
47512
  });
47383
47513
 
47384
- // packages/cleo/src/cli/progress.ts
47385
- import { stderr } from "node:process";
47386
- function createSelfUpdateProgress(enabled) {
47387
- return new ProgressTracker({
47388
- enabled,
47389
- prefix: "CLEO",
47390
- steps: [
47391
- "Detecting installation type",
47392
- "Checking current version",
47393
- "Querying npm registry",
47394
- "Comparing versions",
47395
- "Running post-update checks",
47396
- "Finalizing"
47397
- ]
47398
- });
47399
- }
47400
- function createDoctorProgress(enabled) {
47401
- return new ProgressTracker({
47402
- enabled,
47403
- prefix: "CLEO Doctor",
47404
- steps: [
47405
- "Checking CLEO directory",
47406
- "Verifying tasks database",
47407
- "Checking configuration",
47408
- "Validating schemas",
47409
- "Running health checks"
47410
- ]
47411
- });
47412
- }
47413
- function createUpgradeProgress(enabled) {
47414
- return new ProgressTracker({
47415
- enabled,
47416
- prefix: "CLEO Upgrade",
47417
- steps: [
47418
- "Analyzing current state",
47419
- "Checking storage migration needs",
47420
- "Validating schemas",
47421
- "Applying fixes",
47422
- "Verifying results"
47423
- ]
47424
- });
47425
- }
47426
- var ProgressTracker;
47427
- var init_progress = __esm({
47428
- "packages/cleo/src/cli/progress.ts"() {
47429
- "use strict";
47430
- init_format_context();
47431
- ProgressTracker = class {
47432
- enabled;
47433
- prefix;
47434
- currentStep = 0;
47435
- totalSteps;
47436
- steps;
47437
- constructor(options) {
47438
- this.enabled = options.enabled;
47439
- this.prefix = options.prefix ?? "CLEO";
47440
- this.steps = options.steps;
47441
- this.totalSteps = options.steps.length;
47442
- }
47443
- /**
47444
- * Start the progress tracker.
47445
- */
47446
- start() {
47447
- if (!this.enabled || isQuiet()) return;
47448
- this.currentStep = 0;
47449
- stderr.write(`
47450
- ${this.prefix}: Starting...
47451
- `);
47452
- }
47453
- /**
47454
- * Update to a specific step.
47455
- */
47456
- step(index, message) {
47457
- if (!this.enabled || isQuiet()) return;
47458
- this.currentStep = index;
47459
- const stepName = this.steps[index] ?? message ?? "Working...";
47460
- const progress = `[${index + 1}/${this.totalSteps}]`;
47461
- stderr.write(` ${progress} ${stepName}...
47462
- `);
47463
- }
47464
- /**
47465
- * Move to next step.
47466
- */
47467
- next(message) {
47468
- this.step(this.currentStep + 1, message);
47469
- }
47470
- /**
47471
- * Mark as complete with optional summary.
47472
- *
47473
- * @remarks
47474
- * Writes to stderr (not stdout) so that progress messages never pollute
47475
- * the machine-readable JSON envelope on stdout. Stdout MUST contain exactly
47476
- * one JSON object per CLI invocation (ADR-039 / T927).
47477
- */
47478
- complete(summary) {
47479
- if (!this.enabled || isQuiet()) return;
47480
- if (summary) {
47481
- stderr.write(`
47482
- ${this.prefix}: \u2713 ${summary}
47483
-
47484
- `);
47485
- } else {
47486
- stderr.write(`
47487
- ${this.prefix}: \u2713 Complete
47488
-
47489
- `);
47490
- }
47491
- }
47492
- /**
47493
- * Report an error.
47494
- */
47495
- error(message) {
47496
- if (!this.enabled || isQuiet()) return;
47497
- stderr.write(`
47498
- ${this.prefix}: \u2717 ${message}
47499
-
47500
- `);
47501
- }
47502
- };
47503
- }
47504
- });
47505
-
47506
47514
  // packages/cleo/src/cli/commands/doctor-release-readiness.ts
47515
+ var doctor_release_readiness_exports = {};
47516
+ __export(doctor_release_readiness_exports, {
47517
+ doctorReleaseReadinessCommand: () => doctorReleaseReadinessCommand
47518
+ });
47507
47519
  import { existsSync as existsSync13 } from "node:fs";
47508
47520
  import { join as join22, resolve as resolve6 } from "node:path";
47509
47521
  async function runCheck(name, cmd, args, cwd) {
@@ -47591,16 +47603,27 @@ var init_doctor_release_readiness = __esm({
47591
47603
  const pkg = JSON.parse(
47592
47604
  await import("node:fs").then((m) => m.readFileSync(packageJsonPath, "utf8"))
47593
47605
  );
47594
- const hasPublishConfig = typeof pkg.publishConfig === "object" && pkg.publishConfig !== null;
47595
- const accessPublic = hasPublishConfig && pkg.publishConfig.access === "public";
47596
- oidcCheck = {
47597
- name: "npm-oidc-sanity",
47598
- status: accessPublic ? "pass" : "fail",
47599
- exitCode: accessPublic ? 0 : 1,
47600
- durationMs: 0,
47601
- stdout: accessPublic ? "package.json has publishConfig.access=public" : "",
47602
- stderr: accessPublic ? "" : "package.json missing publishConfig.access=public \u2014 required for npm OIDC Trusted Publishing"
47603
- };
47606
+ if (pkg.private === true) {
47607
+ oidcCheck = {
47608
+ name: "npm-oidc-sanity",
47609
+ status: "pass",
47610
+ exitCode: 0,
47611
+ durationMs: 0,
47612
+ stdout: "root package.json is private \u2014 skipping (per-package check applies at publish time)",
47613
+ stderr: ""
47614
+ };
47615
+ } else {
47616
+ const hasPublishConfig = typeof pkg.publishConfig === "object" && pkg.publishConfig !== null;
47617
+ const accessPublic = hasPublishConfig && pkg.publishConfig.access === "public";
47618
+ oidcCheck = {
47619
+ name: "npm-oidc-sanity",
47620
+ status: accessPublic ? "pass" : "fail",
47621
+ exitCode: accessPublic ? 0 : 1,
47622
+ durationMs: 0,
47623
+ stdout: accessPublic ? "package.json has publishConfig.access=public" : "",
47624
+ stderr: accessPublic ? "" : "package.json missing publishConfig.access=public \u2014 required for npm OIDC Trusted Publishing"
47625
+ };
47626
+ }
47604
47627
  } catch {
47605
47628
  oidcCheck = {
47606
47629
  name: "npm-oidc-sanity",
@@ -47751,6 +47774,128 @@ var init_doctor_release_readiness = __esm({
47751
47774
  }
47752
47775
  });
47753
47776
 
47777
+ // packages/cleo/src/cli/progress.ts
47778
+ import { stderr } from "node:process";
47779
+ function createSelfUpdateProgress(enabled) {
47780
+ return new ProgressTracker({
47781
+ enabled,
47782
+ prefix: "CLEO",
47783
+ steps: [
47784
+ "Detecting installation type",
47785
+ "Checking current version",
47786
+ "Querying npm registry",
47787
+ "Comparing versions",
47788
+ "Running post-update checks",
47789
+ "Finalizing"
47790
+ ]
47791
+ });
47792
+ }
47793
+ function createDoctorProgress(enabled) {
47794
+ return new ProgressTracker({
47795
+ enabled,
47796
+ prefix: "CLEO Doctor",
47797
+ steps: [
47798
+ "Checking CLEO directory",
47799
+ "Verifying tasks database",
47800
+ "Checking configuration",
47801
+ "Validating schemas",
47802
+ "Running health checks"
47803
+ ]
47804
+ });
47805
+ }
47806
+ function createUpgradeProgress(enabled) {
47807
+ return new ProgressTracker({
47808
+ enabled,
47809
+ prefix: "CLEO Upgrade",
47810
+ steps: [
47811
+ "Analyzing current state",
47812
+ "Checking storage migration needs",
47813
+ "Validating schemas",
47814
+ "Applying fixes",
47815
+ "Verifying results"
47816
+ ]
47817
+ });
47818
+ }
47819
+ var ProgressTracker;
47820
+ var init_progress = __esm({
47821
+ "packages/cleo/src/cli/progress.ts"() {
47822
+ "use strict";
47823
+ init_format_context();
47824
+ ProgressTracker = class {
47825
+ enabled;
47826
+ prefix;
47827
+ currentStep = 0;
47828
+ totalSteps;
47829
+ steps;
47830
+ constructor(options) {
47831
+ this.enabled = options.enabled;
47832
+ this.prefix = options.prefix ?? "CLEO";
47833
+ this.steps = options.steps;
47834
+ this.totalSteps = options.steps.length;
47835
+ }
47836
+ /**
47837
+ * Start the progress tracker.
47838
+ */
47839
+ start() {
47840
+ if (!this.enabled || isQuiet()) return;
47841
+ this.currentStep = 0;
47842
+ stderr.write(`
47843
+ ${this.prefix}: Starting...
47844
+ `);
47845
+ }
47846
+ /**
47847
+ * Update to a specific step.
47848
+ */
47849
+ step(index, message) {
47850
+ if (!this.enabled || isQuiet()) return;
47851
+ this.currentStep = index;
47852
+ const stepName = this.steps[index] ?? message ?? "Working...";
47853
+ const progress = `[${index + 1}/${this.totalSteps}]`;
47854
+ stderr.write(` ${progress} ${stepName}...
47855
+ `);
47856
+ }
47857
+ /**
47858
+ * Move to next step.
47859
+ */
47860
+ next(message) {
47861
+ this.step(this.currentStep + 1, message);
47862
+ }
47863
+ /**
47864
+ * Mark as complete with optional summary.
47865
+ *
47866
+ * @remarks
47867
+ * Writes to stderr (not stdout) so that progress messages never pollute
47868
+ * the machine-readable JSON envelope on stdout. Stdout MUST contain exactly
47869
+ * one JSON object per CLI invocation (ADR-039 / T927).
47870
+ */
47871
+ complete(summary) {
47872
+ if (!this.enabled || isQuiet()) return;
47873
+ if (summary) {
47874
+ stderr.write(`
47875
+ ${this.prefix}: \u2713 ${summary}
47876
+
47877
+ `);
47878
+ } else {
47879
+ stderr.write(`
47880
+ ${this.prefix}: \u2713 Complete
47881
+
47882
+ `);
47883
+ }
47884
+ }
47885
+ /**
47886
+ * Report an error.
47887
+ */
47888
+ error(message) {
47889
+ if (!this.enabled || isQuiet()) return;
47890
+ stderr.write(`
47891
+ ${this.prefix}: \u2717 ${message}
47892
+
47893
+ `);
47894
+ }
47895
+ };
47896
+ }
47897
+ });
47898
+
47754
47899
  // packages/cleo/src/cli/commands/migrate-agents-v2.ts
47755
47900
  var migrate_agents_v2_exports = {};
47756
47901
  __export(migrate_agents_v2_exports, {
@@ -50821,6 +50966,50 @@ var init_history = __esm({
50821
50966
  }
50822
50967
  });
50823
50968
 
50969
+ // packages/cleo/src/cli/commands/hygiene.ts
50970
+ var hygiene_exports = {};
50971
+ __export(hygiene_exports, {
50972
+ hygieneCommand: () => hygieneCommand
50973
+ });
50974
+ import { getProjectRoot as getProjectRoot43 } from "@cleocode/core";
50975
+ import { runSpawnReadinessHygieneCli } from "@cleocode/core/hygiene/validate-spawn-readiness.js";
50976
+ var hygieneCommand;
50977
+ var init_hygiene = __esm({
50978
+ "packages/cleo/src/cli/commands/hygiene.ts"() {
50979
+ "use strict";
50980
+ init_dist();
50981
+ hygieneCommand = defineCommand({
50982
+ meta: {
50983
+ name: "hygiene",
50984
+ description: "Run spawn-readiness hygiene checks"
50985
+ },
50986
+ subCommands: {
50987
+ "validate-spawn-readiness": defineCommand({
50988
+ meta: {
50989
+ name: "validate-spawn-readiness",
50990
+ description: "Run all pre-spawn hygiene gates (changeset lint, changelog drift, worktree location)"
50991
+ },
50992
+ args: {
50993
+ "project-root": {
50994
+ type: "string",
50995
+ description: "Project root directory (default: auto-detect)"
50996
+ },
50997
+ "worktree-path": {
50998
+ type: "string",
50999
+ description: "Expected worktree path for location validation"
51000
+ }
51001
+ },
51002
+ async run({ args }) {
51003
+ const projectRoot = args["project-root"] || getProjectRoot43() || process.cwd();
51004
+ const worktreePath = args["worktree-path"];
51005
+ await runSpawnReadinessHygieneCli(projectRoot, worktreePath);
51006
+ }
51007
+ })
51008
+ }
51009
+ });
51010
+ }
51011
+ });
51012
+
50824
51013
  // packages/cleo/src/cli/commands/import-tasks.ts
50825
51014
  var import_tasks_exports = {};
50826
51015
  __export(import_tasks_exports, {
@@ -51973,7 +52162,7 @@ var llm_cost_exports = {};
51973
52162
  __export(llm_cost_exports, {
51974
52163
  costCommand: () => costCommand
51975
52164
  });
51976
- import { getProjectRoot as getProjectRoot43 } from "@cleocode/core/internal";
52165
+ import { getProjectRoot as getProjectRoot44 } from "@cleocode/core/internal";
51977
52166
  import { computeCost } from "@cleocode/core/llm/usage-pricing";
51978
52167
  function resolveSessionId(raw) {
51979
52168
  if (raw === "current") {
@@ -52046,7 +52235,7 @@ var init_llm_cost = __esm({
52046
52235
  process.exit(6);
52047
52236
  }
52048
52237
  const sessionId = resolveSessionId(rawSessionId);
52049
- const projectRoot = getProjectRoot43(process.cwd());
52238
+ const projectRoot = getProjectRoot44(process.cwd());
52050
52239
  let breakdown;
52051
52240
  try {
52052
52241
  breakdown = await loadSessionCostBreakdown(projectRoot, sessionId);
@@ -53593,7 +53782,7 @@ var memory_exports = {};
53593
53782
  __export(memory_exports, {
53594
53783
  memoryCommand: () => memoryCommand
53595
53784
  });
53596
- import { getProjectRoot as getProjectRoot44 } from "@cleocode/core";
53785
+ import { getProjectRoot as getProjectRoot45 } from "@cleocode/core";
53597
53786
  import {
53598
53787
  getBrainDb as getBrainDb2,
53599
53788
  getDreamStatus,
@@ -54517,7 +54706,7 @@ var init_memory3 = __esm({
54517
54706
  },
54518
54707
  args: {},
54519
54708
  async run() {
54520
- const root = getProjectRoot44();
54709
+ const root = getProjectRoot45();
54521
54710
  try {
54522
54711
  const result = await runConsolidation(root);
54523
54712
  cliOutput(result, { command: "memory-consolidate", operation: "memory.consolidate" });
@@ -54541,7 +54730,7 @@ var init_memory3 = __esm({
54541
54730
  }
54542
54731
  },
54543
54732
  async run({ args }) {
54544
- const root = getProjectRoot44();
54733
+ const root = getProjectRoot45();
54545
54734
  if (args.status) {
54546
54735
  try {
54547
54736
  const status = await getDreamStatus(root);
@@ -54578,7 +54767,7 @@ var init_memory3 = __esm({
54578
54767
  }
54579
54768
  },
54580
54769
  async run({ args }) {
54581
- const root = getProjectRoot44();
54770
+ const root = getProjectRoot45();
54582
54771
  try {
54583
54772
  const { runObserver, runReflector } = await import("@cleocode/core/memory");
54584
54773
  const observerResult = await runObserver(root, args.session, {
@@ -54618,7 +54807,7 @@ var init_memory3 = __esm({
54618
54807
  }
54619
54808
  },
54620
54809
  async run({ args }) {
54621
- const root = getProjectRoot44();
54810
+ const root = getProjectRoot45();
54622
54811
  try {
54623
54812
  await getBrainDb2(root);
54624
54813
  const { totalDuplicateRows, groups } = await scanDuplicateEntries();
@@ -54664,7 +54853,7 @@ var init_memory3 = __esm({
54664
54853
  async run({ args }) {
54665
54854
  const sourceDir = args.from;
54666
54855
  const isDryRun = !!args["dry-run"];
54667
- const projectRoot = getProjectRoot44();
54856
+ const projectRoot = getProjectRoot45();
54668
54857
  try {
54669
54858
  const result = await importMemoryFiles({
54670
54859
  sourceDir,
@@ -54815,7 +55004,7 @@ var init_memory3 = __esm({
54815
55004
  },
54816
55005
  args: {},
54817
55006
  async run() {
54818
- const root = getProjectRoot44();
55007
+ const root = getProjectRoot45();
54819
55008
  try {
54820
55009
  await getBrainDb2(root);
54821
55010
  const result = await getTierStats(root);
@@ -54858,7 +55047,7 @@ var init_memory3 = __esm({
54858
55047
  }
54859
55048
  },
54860
55049
  async run({ args }) {
54861
- const root = getProjectRoot44();
55050
+ const root = getProjectRoot45();
54862
55051
  const targetTier = args.to;
54863
55052
  const reason = args.reason;
54864
55053
  const validTiers = ["medium", "long"];
@@ -54924,7 +55113,7 @@ var init_memory3 = __esm({
54924
55113
  }
54925
55114
  },
54926
55115
  async run({ args }) {
54927
- const root = getProjectRoot44();
55116
+ const root = getProjectRoot45();
54928
55117
  const targetTier = args.to;
54929
55118
  const reason = args.reason;
54930
55119
  const validTiers = ["short", "medium"];
@@ -55384,7 +55573,7 @@ var migrate_claude_mem_exports = {};
55384
55573
  __export(migrate_claude_mem_exports, {
55385
55574
  migrateClaudeMemCommand: () => migrateClaudeMemCommand
55386
55575
  });
55387
- import { getProjectRoot as getProjectRoot45, migrateClaudeMem } from "@cleocode/core/internal";
55576
+ import { getProjectRoot as getProjectRoot46, migrateClaudeMem } from "@cleocode/core/internal";
55388
55577
  import { ingestLooseAgentOutputs, ingestRcasdDirectories } from "@cleocode/core/memory";
55389
55578
  import { getDb as getDb2 } from "@cleocode/core/store/sqlite";
55390
55579
  var storageCommand, claudeMemCommand, manifestIngestCommand, migrateClaudeMemCommand;
@@ -55447,7 +55636,7 @@ var init_migrate_claude_mem = __esm({
55447
55636
  }
55448
55637
  },
55449
55638
  async run({ args }) {
55450
- const root = getProjectRoot45();
55639
+ const root = getProjectRoot46();
55451
55640
  try {
55452
55641
  const result = await migrateClaudeMem(root, {
55453
55642
  sourcePath: args.source,
@@ -55496,7 +55685,7 @@ var init_migrate_claude_mem = __esm({
55496
55685
  }
55497
55686
  },
55498
55687
  async run({ args }) {
55499
- const projectRoot = getProjectRoot45();
55688
+ const projectRoot = getProjectRoot46();
55500
55689
  try {
55501
55690
  const db = await getDb2(projectRoot);
55502
55691
  const rcasdFlag = Boolean(args.rcasd);
@@ -55600,7 +55789,7 @@ __export(nexus_exports, {
55600
55789
  import { appendFile as appendFile2, mkdir as mkdir3 } from "node:fs/promises";
55601
55790
  import { homedir as homedir5 } from "node:os";
55602
55791
  import path4 from "node:path";
55603
- import { getProjectRoot as getProjectRoot46 } from "@cleocode/core";
55792
+ import { getProjectRoot as getProjectRoot47 } from "@cleocode/core";
55604
55793
  import { getSymbolImpact } from "@cleocode/core/nexus";
55605
55794
  import { runNexusAnalysis } from "@cleocode/core/nexus/analyze-orchestrator.js";
55606
55795
  import { exportNexusGraph } from "@cleocode/core/nexus/export.js";
@@ -55715,7 +55904,7 @@ var init_nexus3 = __esm({
55715
55904
  async run({ args }) {
55716
55905
  applyJsonFlag2(args.json);
55717
55906
  const projectIdOverride = args["project-id"];
55718
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot46();
55907
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot47();
55719
55908
  const startTime = Date.now();
55720
55909
  try {
55721
55910
  const [{ getNexusDb, nexusSchema }, { getIndexStats }] = await Promise.all([
@@ -56230,7 +56419,7 @@ var init_nexus3 = __esm({
56230
56419
  applyJsonFlag2(args.json);
56231
56420
  const startTime = Date.now();
56232
56421
  const projectIdOverride = args["project-id"];
56233
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot46();
56422
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot47();
56234
56423
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
56235
56424
  const response = await dispatchRaw("query", "nexus", "clusters", { projectId, repoPath });
56236
56425
  const durationMs = Date.now() - startTime;
@@ -56274,7 +56463,7 @@ var init_nexus3 = __esm({
56274
56463
  applyJsonFlag2(args.json);
56275
56464
  const startTime = Date.now();
56276
56465
  const projectIdOverride = args["project-id"];
56277
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot46();
56466
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot47();
56278
56467
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
56279
56468
  const response = await dispatchRaw("query", "nexus", "flows", { projectId, repoPath });
56280
56469
  const durationMs = Date.now() - startTime;
@@ -56317,7 +56506,7 @@ var init_nexus3 = __esm({
56317
56506
  void appendDeprecationTelemetry("nexus.context", "cleo graph context");
56318
56507
  const startTime = Date.now();
56319
56508
  const projectIdOverride = args["project-id"];
56320
- const repoPath = getProjectRoot46();
56509
+ const repoPath = getProjectRoot47();
56321
56510
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
56322
56511
  const limit = parseInt(args.limit, 10);
56323
56512
  const symbolName = args.symbol;
@@ -56380,7 +56569,7 @@ var init_nexus3 = __esm({
56380
56569
  const startTime = Date.now();
56381
56570
  const whyFlag = !!args.why;
56382
56571
  const projectIdOverride = args["project-id"];
56383
- const repoPath = getProjectRoot46();
56572
+ const repoPath = getProjectRoot47();
56384
56573
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
56385
56574
  const maxDepth = Math.min(parseInt(args.depth, 10), 5);
56386
56575
  const symbolName = args.symbol;
@@ -56452,7 +56641,7 @@ var init_nexus3 = __esm({
56452
56641
  const projectIdOverride = args["project-id"];
56453
56642
  const isIncremental = !!args.incremental;
56454
56643
  const ctx = getFormatContext();
56455
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot46();
56644
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot47();
56456
56645
  humanInfo(`[nexus] Analyzing: ${repoPath}${isIncremental ? " (incremental)" : ""}`);
56457
56646
  if (!isIncremental) humanInfo("[nexus] Clearing existing index for project...");
56458
56647
  try {
@@ -56555,7 +56744,7 @@ var init_nexus3 = __esm({
56555
56744
  async run({ args }) {
56556
56745
  applyJsonFlag2(args.json);
56557
56746
  const startTime = Date.now();
56558
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot46();
56747
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot47();
56559
56748
  const name = args.name;
56560
56749
  const response = await dispatchRaw("mutate", "nexus", "projects.register", {
56561
56750
  path: repoPath,
@@ -56913,7 +57102,7 @@ var init_nexus3 = __esm({
56913
57102
  applyJsonFlag2(args.json);
56914
57103
  const startTime = Date.now();
56915
57104
  const projectIdOverride = args["project-id"];
56916
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot46();
57105
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot47();
56917
57106
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
56918
57107
  const response = await dispatchRaw("mutate", "nexus", "refresh-bridge", {
56919
57108
  repoPath,
@@ -57019,7 +57208,7 @@ var init_nexus3 = __esm({
57019
57208
  async run({ args }) {
57020
57209
  applyJsonFlag2(args.json);
57021
57210
  const startTime = Date.now();
57022
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot46();
57211
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot47();
57023
57212
  const projectIdOverride = args["project-id"];
57024
57213
  const beforeRef = args.before ?? "HEAD~1";
57025
57214
  const afterRef = args.after ?? "HEAD";
@@ -57137,7 +57326,7 @@ var init_nexus3 = __esm({
57137
57326
  applyJsonFlag2(args.json);
57138
57327
  const startTime = Date.now();
57139
57328
  const projectIdOverride = args["project-id"];
57140
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot46();
57329
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot47();
57141
57330
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
57142
57331
  const response = await dispatchRaw("query", "nexus", "route-map", { projectId });
57143
57332
  const durationMs = Date.now() - startTime;
@@ -57193,7 +57382,7 @@ var init_nexus3 = __esm({
57193
57382
  const startTime = Date.now();
57194
57383
  const routeSymbol = args.routeSymbol;
57195
57384
  const projectIdOverride = args["project-id"];
57196
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot46();
57385
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot47();
57197
57386
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
57198
57387
  const response = await dispatchRaw("query", "nexus", "shape-check", { routeSymbol, projectId });
57199
57388
  const durationMs = Date.now() - startTime;
@@ -57583,7 +57772,7 @@ var init_nexus3 = __esm({
57583
57772
  async run({ args }) {
57584
57773
  applyJsonFlag2(args.json);
57585
57774
  const startTime = Date.now();
57586
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot46();
57775
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot47();
57587
57776
  const projectIdOverride = args["project-id"];
57588
57777
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
57589
57778
  const response = await dispatchRaw("mutate", "nexus", "contracts-sync", {
@@ -57687,7 +57876,7 @@ var init_nexus3 = __esm({
57687
57876
  async run({ args }) {
57688
57877
  applyJsonFlag2(args.json);
57689
57878
  const startTime = Date.now();
57690
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot46();
57879
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot47();
57691
57880
  const projectId = Buffer.from(repoPath).toString("base64url").slice(0, 32);
57692
57881
  const response = await dispatchRaw("mutate", "nexus", "contracts-link-tasks", {
57693
57882
  projectId,
@@ -57768,7 +57957,7 @@ var init_nexus3 = __esm({
57768
57957
  const isIncremental = !!args.incremental;
57769
57958
  try {
57770
57959
  const result = await runNexusWiki({
57771
- projectRoot: getProjectRoot46(),
57960
+ projectRoot: getProjectRoot47(),
57772
57961
  outputDir,
57773
57962
  communityFilter,
57774
57963
  incremental: isIncremental
@@ -58118,7 +58307,7 @@ __export(orchestrate_exports, {
58118
58307
  });
58119
58308
  import { execFileSync as execFileSync3 } from "node:child_process";
58120
58309
  import { orchestration } from "@cleocode/core";
58121
- import { BUILD_CONFIG as BUILD_CONFIG2 } from "@cleocode/core/internal";
58310
+ import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as getProjectRoot48 } from "@cleocode/core/internal";
58122
58311
  function formatRollupTable(rollup) {
58123
58312
  const waves = "waves" in rollup ? rollup.waves : [rollup];
58124
58313
  const lines = [];
@@ -58153,7 +58342,7 @@ function formatRollupTable(rollup) {
58153
58342
  }
58154
58343
  return lines.join("\n");
58155
58344
  }
58156
- var rollupCommand, startCommand5, statusCommand11, analyzeCommand4, readyCommand, nextCommand2, wavesCommand2, planCommand, spawnCommand2, validateCommand6, contextCommand5, ivtrCommand, parallelCommand, tesseraListCommand, tesseraInstantiateCommand, tesseraCommand, unblockCommand, bootstrapCommand, classifyCommand, fanoutStatusCommand, handoffCommand, spawnExecuteCommand, fanoutCommand, pruneCommand, worktreeCompleteCommand, conduitStatusCommand, conduitPeekCommand, conduitStartCommand, conduitStopCommand, approveCommand, rejectCommand, pendingCommand, conduitSendCommand, orchestrateCommand;
58345
+ var rollupCommand, startCommand5, statusCommand11, dashboardCommand, analyzeCommand4, readyCommand, nextCommand2, wavesCommand2, planCommand, spawnCommand2, validateCommand6, contextCommand5, ivtrCommand, parallelCommand, tesseraListCommand, tesseraInstantiateCommand, tesseraCommand, unblockCommand, bootstrapCommand, classifyCommand, fanoutStatusCommand, handoffCommand, spawnExecuteCommand, fanoutCommand, pruneCommand, worktreeCompleteCommand, conduitStatusCommand, conduitPeekCommand, conduitStartCommand, conduitStopCommand, approveCommand, rejectCommand, pendingCommand, conduitSendCommand, orchestrateCommand;
58157
58346
  var init_orchestrate3 = __esm({
58158
58347
  "packages/cleo/src/cli/commands/orchestrate.ts"() {
58159
58348
  "use strict";
@@ -58248,6 +58437,28 @@ var init_orchestrate3 = __esm({
58248
58437
  );
58249
58438
  }
58250
58439
  });
58440
+ dashboardCommand = defineCommand({
58441
+ meta: {
58442
+ name: "dashboard",
58443
+ description: "Show queue depth, admin-merge rate, force-bypass rate, and active worktree count"
58444
+ },
58445
+ args: {
58446
+ window: {
58447
+ type: "string",
58448
+ description: "Audit rate window in hours (default: 24)"
58449
+ }
58450
+ },
58451
+ async run({ args }) {
58452
+ const rateWindowHours = args.window !== void 0 ? Number.parseFloat(String(args.window)) : void 0;
58453
+ const metrics = await orchestration.collectOrchestrateDashboard(getProjectRoot48(), {
58454
+ ...rateWindowHours !== void 0 && Number.isFinite(rateWindowHours) && rateWindowHours > 0 ? { rateWindowHours } : {}
58455
+ });
58456
+ cliOutput(metrics, {
58457
+ command: "orchestrate-dashboard",
58458
+ operation: "orchestrate.dashboard"
58459
+ });
58460
+ }
58461
+ });
58251
58462
  analyzeCommand4 = defineCommand({
58252
58463
  meta: { name: "analyze", description: "Analyze epic dependency structure" },
58253
58464
  args: {
@@ -59004,6 +59215,7 @@ var init_orchestrate3 = __esm({
59004
59215
  subCommands: {
59005
59216
  start: startCommand5,
59006
59217
  status: statusCommand11,
59218
+ dashboard: dashboardCommand,
59007
59219
  "roll-up": rollupCommand,
59008
59220
  analyze: analyzeCommand4,
59009
59221
  ready: readyCommand,
@@ -60228,7 +60440,7 @@ var refresh_memory_exports = {};
60228
60440
  __export(refresh_memory_exports, {
60229
60441
  refreshMemoryCommand: () => refreshMemoryCommand
60230
60442
  });
60231
- import { getProjectRoot as getProjectRoot47 } from "@cleocode/core";
60443
+ import { getProjectRoot as getProjectRoot49 } from "@cleocode/core";
60232
60444
  var refreshMemoryCommand;
60233
60445
  var init_refresh_memory = __esm({
60234
60446
  "packages/cleo/src/cli/commands/refresh-memory.ts"() {
@@ -60241,7 +60453,7 @@ var init_refresh_memory = __esm({
60241
60453
  description: "Regenerate .cleo/memory-bridge.md from brain.db"
60242
60454
  },
60243
60455
  async run() {
60244
- const projectDir = getProjectRoot47();
60456
+ const projectDir = getProjectRoot49();
60245
60457
  const { writeMemoryBridge } = await import("@cleocode/core/internal");
60246
60458
  const result = await writeMemoryBridge(projectDir);
60247
60459
  if (result.written) {
@@ -60716,8 +60928,8 @@ var init_release3 = __esm({
60716
60928
  },
60717
60929
  async run({ args }) {
60718
60930
  if (args["skip-readiness"] !== true) {
60719
- const { runSpawnReadinessHygieneCli } = await import("@cleocode/core/hygiene/validate-spawn-readiness.js");
60720
- await runSpawnReadinessHygieneCli();
60931
+ const { runSpawnReadinessHygieneCli: runSpawnReadinessHygieneCli2 } = await import("@cleocode/core/hygiene/validate-spawn-readiness.js");
60932
+ await runSpawnReadinessHygieneCli2();
60721
60933
  }
60722
60934
  await dispatchFromCli(
60723
60935
  "mutate",
@@ -61682,8 +61894,8 @@ import fs3 from "node:fs";
61682
61894
  import path5 from "node:path";
61683
61895
  import {
61684
61896
  CleoError as CleoError7,
61685
- getProjectRoot as getProjectRoot48,
61686
- getTaskAccessor as getTaskAccessor3,
61897
+ getProjectRoot as getProjectRoot50,
61898
+ getTaskAccessor as getTaskAccessor4,
61687
61899
  parseConflictReport,
61688
61900
  setAtPath
61689
61901
  } from "@cleocode/core";
@@ -61703,7 +61915,7 @@ var init_restore = __esm({
61703
61915
  description: "Apply manually-resolved conflicts from .cleo/restore-conflicts.md"
61704
61916
  },
61705
61917
  async run() {
61706
- const projectRoot = getProjectRoot48();
61918
+ const projectRoot = getProjectRoot50();
61707
61919
  const reportPath = path5.join(projectRoot, CLEO_DIR_NAME, RESTORE_CONFLICTS_MD);
61708
61920
  if (!fs3.existsSync(reportPath)) {
61709
61921
  humanLine("No pending restore conflicts. Nothing to finalize.");
@@ -61881,7 +62093,7 @@ var init_restore = __esm({
61881
62093
  if (!idPattern.test(taskId)) {
61882
62094
  throw new CleoError7(2 /* INVALID_INPUT */, `Invalid task ID: ${taskId}`);
61883
62095
  }
61884
- const accessor = await getTaskAccessor3();
62096
+ const accessor = await getTaskAccessor4();
61885
62097
  const activeTask = await accessor.loadSingleTask(taskId);
61886
62098
  if (activeTask) {
61887
62099
  if (activeTask.status === "cancelled") {
@@ -64341,7 +64553,7 @@ var sequence_exports = {};
64341
64553
  __export(sequence_exports, {
64342
64554
  sequenceCommand: () => sequenceCommand
64343
64555
  });
64344
- import { getProjectRoot as getProjectRoot49 } from "@cleocode/core/internal";
64556
+ import { getProjectRoot as getProjectRoot51 } from "@cleocode/core/internal";
64345
64557
  var showCommand12, checkCommand6, repairCommand2, sequenceCommand;
64346
64558
  var init_sequence = __esm({
64347
64559
  "packages/cleo/src/cli/commands/sequence.ts"() {
@@ -64377,7 +64589,7 @@ var init_sequence = __esm({
64377
64589
  meta: { name: "repair", description: "Reset counter to max + 1 if behind" },
64378
64590
  async run() {
64379
64591
  const { repairSequence } = await import("@cleocode/core/internal");
64380
- const projectRoot = getProjectRoot49();
64592
+ const projectRoot = getProjectRoot51();
64381
64593
  const repair = await repairSequence(projectRoot);
64382
64594
  const result = {
64383
64595
  repaired: repair.repaired,
@@ -64832,8 +65044,8 @@ var init_session4 = __esm({
64832
65044
  "audit-scope": { type: "string", description: "Audit log scope (global|local)" }
64833
65045
  },
64834
65046
  async run({ args }) {
64835
- const { detectSessionDrift, getProjectRoot: getProjectRoot54 } = await import("@cleocode/core");
64836
- const projectRoot = await getProjectRoot54();
65047
+ const { detectSessionDrift, getProjectRoot: getProjectRoot56 } = await import("@cleocode/core");
65048
+ const projectRoot = await getProjectRoot56();
64837
65049
  const scope = args["audit-scope"] === "local" ? "local" : "global";
64838
65050
  const report = await detectSessionDrift({ projectRoot, auditScope: scope });
64839
65051
  cliOutput(report, { command: "session drift", operation: "session.drift" });
@@ -67488,13 +67700,13 @@ var init_telemetry2 = __esm({
67488
67700
  // packages/cleo/src/cli/commands/templates/lib.ts
67489
67701
  import { readFileSync as readFileSync15 } from "node:fs";
67490
67702
  import { isAbsolute as isAbsolute3, resolve as resolve7 } from "node:path";
67491
- import { getProjectRoot as getProjectRoot50 } from "@cleocode/core";
67703
+ import { getProjectRoot as getProjectRoot52 } from "@cleocode/core";
67492
67704
  import { resolveSourcePathAbsolute } from "@cleocode/core/templates/registry";
67493
67705
  function resolveProjectRoot7(raw) {
67494
67706
  if (typeof raw === "string" && raw.length > 0) {
67495
67707
  return isAbsolute3(raw) ? raw : resolve7(process.cwd(), raw);
67496
67708
  }
67497
- return getProjectRoot50();
67709
+ return getProjectRoot52();
67498
67710
  }
67499
67711
  function readTemplateSource(entry) {
67500
67712
  const sourceAbsolute = resolveSourcePathAbsolute(entry);
@@ -68278,7 +68490,7 @@ __export(token_exports, {
68278
68490
  tokenCommand: () => tokenCommand
68279
68491
  });
68280
68492
  import { readFileSync as readFileSync19 } from "node:fs";
68281
- import { getProjectRoot as getProjectRoot51, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
68493
+ import { getProjectRoot as getProjectRoot53, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
68282
68494
  function readPayload(args, textKey, fileKey) {
68283
68495
  const text = args[textKey];
68284
68496
  const file = args[fileKey];
@@ -68442,7 +68654,7 @@ var init_token = __esm({
68442
68654
  domain: args.domain,
68443
68655
  operation: args.operation
68444
68656
  };
68445
- const result = args.record ? await recordTokenExchange2(getProjectRoot51(), input2) : await measureTokenExchange(input2);
68657
+ const result = args.record ? await recordTokenExchange2(getProjectRoot53(), input2) : await measureTokenExchange(input2);
68446
68658
  cliOutput(result, {
68447
68659
  command: "token",
68448
68660
  operation: args.record ? "admin.token.record" : "token.estimate"
@@ -68478,7 +68690,7 @@ __export(transcript_exports, {
68478
68690
  });
68479
68691
  import { homedir as homedir6 } from "node:os";
68480
68692
  import { join as join34 } from "node:path";
68481
- import { getProjectRoot as getProjectRoot52 } from "@cleocode/core";
68693
+ import { getProjectRoot as getProjectRoot54 } from "@cleocode/core";
68482
68694
  import {
68483
68695
  parseDurationMs,
68484
68696
  pruneTranscripts,
@@ -68508,7 +68720,7 @@ var init_transcript = __esm({
68508
68720
  async run({ args }) {
68509
68721
  if (args.pending) {
68510
68722
  try {
68511
- const projectRoot = getProjectRoot52();
68723
+ const projectRoot = getProjectRoot54();
68512
68724
  const { scanPendingTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
68513
68725
  const pending = await scanPendingTranscripts(projectRoot);
68514
68726
  cliOutput(
@@ -68605,7 +68817,7 @@ var init_transcript = __esm({
68605
68817
  async run({ args }) {
68606
68818
  const tier = args.tier ?? "warm";
68607
68819
  const dryRun = args["dry-run"] ?? false;
68608
- const projectRoot = getProjectRoot52();
68820
+ const projectRoot = getProjectRoot54();
68609
68821
  try {
68610
68822
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
68611
68823
  const { findSessionTranscriptPath, listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -68717,7 +68929,7 @@ var init_transcript = __esm({
68717
68929
  const dryRun = args["dry-run"] ?? false;
68718
68930
  const olderThanHours = args["older-than-hours"] ? Number.parseInt(args["older-than-hours"], 10) : 24;
68719
68931
  const limit = args.limit ? Number.parseInt(args.limit, 10) : void 0;
68720
- const projectRoot = getProjectRoot52();
68932
+ const projectRoot = getProjectRoot54();
68721
68933
  try {
68722
68934
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
68723
68935
  const { listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -70000,7 +70212,7 @@ __export(worktree_exports, {
70000
70212
  worktreeCommand: () => worktreeCommand
70001
70213
  });
70002
70214
  import readline4 from "node:readline";
70003
- import { getProjectRoot as getProjectRoot53, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
70215
+ import { getProjectRoot as getProjectRoot55, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
70004
70216
  async function promptYesNo2(question) {
70005
70217
  return new Promise((resolve9) => {
70006
70218
  const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
@@ -70105,7 +70317,7 @@ var init_worktree3 = __esm({
70105
70317
  const staleDays = staleDaysRaw !== void 0 ? Number.parseInt(staleDaysRaw, 10) : void 0;
70106
70318
  const idleDaysRaw = typeof args["idle-days"] === "string" ? args["idle-days"] : void 0;
70107
70319
  const idleDays = idleDaysRaw !== void 0 ? Number.parseInt(idleDaysRaw, 10) : void 0;
70108
- const projectRoot = getProjectRoot53();
70320
+ const projectRoot = getProjectRoot55();
70109
70321
  const listResult = await listWorktrees2({
70110
70322
  projectRoot,
70111
70323
  ...staleDays !== void 0 && !Number.isNaN(staleDays) ? { staleDays } : {}
@@ -70284,6 +70496,11 @@ var init_worktree3 = __esm({
70284
70496
  actor: {
70285
70497
  type: "string",
70286
70498
  description: "Override actor name written to the audit log."
70499
+ },
70500
+ recover: {
70501
+ type: "boolean",
70502
+ description: "After adopting, recover a partial ETIMEDOUT worktree by running pnpm install and clearing stale git locks.",
70503
+ default: false
70287
70504
  }
70288
70505
  },
70289
70506
  async run({ args }) {
@@ -70305,7 +70522,8 @@ var init_worktree3 = __esm({
70305
70522
  worktreePath: rawPath,
70306
70523
  ...source !== void 0 ? { source } : {},
70307
70524
  ...rawTaskId !== void 0 ? { taskId: rawTaskId } : {},
70308
- ...rawActor !== void 0 ? { actor: rawActor } : {}
70525
+ ...rawActor !== void 0 ? { actor: rawActor } : {},
70526
+ recover: args["recover"] === true
70309
70527
  },
70310
70528
  { command: "worktree-adopt", operation: "worktree.adopt" }
70311
70529
  );
@@ -70658,6 +70876,12 @@ var COMMAND_MANIFEST = [
70658
70876
  description: "Probe every registered project (nexus.db) for DB + config health",
70659
70877
  load: async () => (await Promise.resolve().then(() => (init_doctor_projects(), doctor_projects_exports))).doctorProjectsCommand
70660
70878
  },
70879
+ {
70880
+ exportName: "doctorReleaseReadinessCommand",
70881
+ name: "release-readiness",
70882
+ description: "Pre-flight release readiness check \u2014 lint matrix + changelog + changeset + npm OIDC + tag-trigger sanity (T10458)",
70883
+ load: async () => (await Promise.resolve().then(() => (init_doctor_release_readiness(), doctor_release_readiness_exports))).doctorReleaseReadinessCommand
70884
+ },
70661
70885
  {
70662
70886
  exportName: "doctorCommand",
70663
70887
  name: "doctor",
@@ -70742,6 +70966,12 @@ var COMMAND_MANIFEST = [
70742
70966
  description: "Completion timeline and productivity analytics",
70743
70967
  load: async () => (await Promise.resolve().then(() => (init_history(), history_exports))).historyCommand
70744
70968
  },
70969
+ {
70970
+ exportName: "hygieneCommand",
70971
+ name: "hygiene",
70972
+ description: "Run spawn-readiness hygiene checks",
70973
+ load: async () => (await Promise.resolve().then(() => (init_hygiene(), hygiene_exports))).hygieneCommand
70974
+ },
70745
70975
  {
70746
70976
  exportName: "importTasksCommand",
70747
70977
  name: "import-tasks",
@@ -71657,7 +71887,7 @@ async function runStartupMaintenance() {
71657
71887
  detectAndRemoveStrayProjectNexus,
71658
71888
  getGlobalSalt,
71659
71889
  getLogger: getLogger21,
71660
- getProjectRoot: getProjectRoot54,
71890
+ getProjectRoot: getProjectRoot56,
71661
71891
  isCleanupMarkerSet,
71662
71892
  migrateSignaldockToConduit,
71663
71893
  needsSignaldockToConduitMigration,
@@ -71666,7 +71896,7 @@ async function runStartupMaintenance() {
71666
71896
  } = await import("@cleocode/core/internal");
71667
71897
  let projectRootForCleanup = "";
71668
71898
  try {
71669
- projectRootForCleanup = getProjectRoot54();
71899
+ projectRootForCleanup = getProjectRoot56();
71670
71900
  } catch {
71671
71901
  }
71672
71902
  if (!isCleanupMarkerSet(CLI_VERSION, projectRootForCleanup)) {
@@ -71686,7 +71916,7 @@ async function runStartupMaintenance() {
71686
71916
  const isInitInvocation = process.argv.slice(2).some((a) => a === "init");
71687
71917
  if (!isInitInvocation) {
71688
71918
  try {
71689
- const _projectRootForMigration = getProjectRoot54();
71919
+ const _projectRootForMigration = getProjectRoot56();
71690
71920
  if (needsSignaldockToConduitMigration(_projectRootForMigration)) {
71691
71921
  const migrationResult = migrateSignaldockToConduit(_projectRootForMigration);
71692
71922
  if (migrationResult.status === "failed") {